最近有同事在 Linux 上遇到問題,想要找類似 ADU/RU/SE 之類的 Linux 工具. 我們Software 同事果然找到一個不錯的軟體套件: 由 Merck 所開發的 LFDK Linux firemware debug kit .
Google 加場 : 作者 Merck 2009 年演講時的資料 LFDK Merck Hung COSCUP 2009.pdf
以我的理解, LFDK 是在 Linux kernel 裡埋一個 lfdd driver ,透過它來提供 lfdk 底層的 ioctrl function. 讓使用者可以對系統PCI Register/Memory/IO 做修改控制.
以前曾經有看過這 code, 但是當時沒有 build 成功. 這次看到,不由得手癢....想不到這次順利很多! (其實是看到人家build 成功後才..)
試過後可以在我的 Ubuntu 10.04 LTS X64 上執行(嗯,除了特定位置 memory 會當掉以外!) 這裡紀錄一下自己研究後的成果.
使用系統 Ubuntu 10.04 LTS - Lucid Lynx desktop x64 版
1.當然是取得 LFDK, 可在這裡 取得.
2.確認 kernel 版本:
$uname -r
我看到的是:
2.6.32-41-generic
這表示可以不修改直接 build 成功.
但,高於 2.6.35 版的因為 file_operations 結構被改了, 得修一下 code.
3.安裝需要的 package
嗯,..這裡我只遇到,若是出現 ncurses.h 或 panel.h 找不到,請加裝 libncurses5-dev
4.Build (假設解開到 ~/lfdk)
~$ cd lfdk
~/lfdk$ make all
成功的話,會看到以下字串
cp -f lfdd/lfdd_drv.ko bin
cp -f lfdk/lfdk bin
Ps. 若要清除, 用 make clean
5.裝載 lfdd driver, 這部份搞很久, 大約 10 分鐘...最後也是拜讀 Jeremy 大作才知道這樣作就好.
~/lfdd$ cd bin
~/lfdd/bin$ insmod lfdd_drv.ko
想多知道一點 insmod ? 可以看這篇 from Jollen 的 Blog.
Ps. 要卸載 lfdd driver , 可以用 rmmod lfdd_drv. 要列出現有 mod ,用 lsmod
6.lfdk 有參數可以帶入, 參考一下
lfdk version 0.1.0, Linux Firmware Debug Kit
Copyright (C) 2006 - 2009, Merck Hung
Usage: lfdk [-h] [-d /dev/lfdd] [-n ./pci.ids] [-b 255]
-n Filename of PCI Name Database, default is /usr/share/misc/pci.ids
-d Device name of Linux Firmware Debug Driver, default is /dev/lfdd
-b Maximum PCI Bus number to scan, default is 255
-h print this message.
Copyright (C) 2006 - 2009, Merck Hung
Usage: lfdk [-h] [-d /dev/lfdd] [-n ./pci.ids] [-b 255]
-n Filename of PCI Name Database, default is /usr/share/misc/pci.ids
-d Device name of Linux Firmware Debug Driver, default is /dev/lfdd
-b Maximum PCI Bus number to scan, default is 255
-h print this message.
7.給耐心看到完的同學,本篇其實寫好很久,(2012/08/01 就寫了)
不過因為新版 kernel 的問題一直沒搞定,故沒發表.
最近(2013/01/29) 相同機器改使用 Ubuntu 11.04 (Kernal 為 2.6.38-16-generic-pae)
要重 build lfdk 還是得面對 struct file_operations 改變的事實,一定得修改 code.
所以廢話不多說: 本著原作者的 GPL 精神,公佈修改後的 code
a.修改 lfdd.c,
(不改會有 warning: initialization from incompatible pointer type
且 lfdk 無法執行.)
static int lfdd_ioctl( struct inode *inode, struct file *file
, unsigned int cmd, unsigned long arg ) {
改為
static long lfdd_ioctl( struct file *file
, unsigned int cmd, unsigned long arg ) {
b.一樣,改 lfdd.c
static struct file_operations lfdd_fops = {
.owner = THIS_MODULE,
.ioctl = lfdd_ioctl,
.open = lfdd_open,
.release = lfdd_release,
};
把 .ioctl 改為 .unlocked_ioctl
c. 沒有了, 除了再次感謝 Merck 提供的好 Source 外.
就是直接照上面步驟 make 後, 掛 driver 後執行它吧,下課!
不過因為新版 kernel 的問題一直沒搞定,故沒發表.
最近(2013/01/29) 相同機器改使用 Ubuntu 11.04 (Kernal 為 2.6.38-16-generic-pae)
要重 build lfdk 還是得面對 struct file_operations 改變的事實,一定得修改 code.
所以廢話不多說: 本著原作者的 GPL 精神,公佈修改後的 code
a.修改 lfdd.c,
(不改會有 warning: initialization from incompatible pointer type
且 lfdk 無法執行.)
static int lfdd_ioctl( struct inode *inode, struct file *file
, unsigned int cmd, unsigned long arg ) {
改為
static long lfdd_ioctl( struct file *file
, unsigned int cmd, unsigned long arg ) {
b.一樣,改 lfdd.c
static struct file_operations lfdd_fops = {
.owner = THIS_MODULE,
.ioctl = lfdd_ioctl,
.open = lfdd_open,
.release = lfdd_release,
};
把 .ioctl 改為 .unlocked_ioctl
c. 沒有了, 除了再次感謝 Merck 提供的好 Source 外.
就是直接照上面步驟 make 後, 掛 driver 後執行它吧,下課!