$ tar jxvf linux-2.6.26.tar.bz2 $ cd linux-2.6.26剩下就是 make menuconfig 即可,過去的繁瑣動作,全都免了!需要留意的是 kernel configuration 的方式,關鍵部份如下圖:
$ make bzImage建構好核心後,是否躍躍欲試呢?不,必須考慮到 kgdb 的「非本地端」偵錯、除錯本質,要作些額外準備。首先,來看看整個系統示意:
$ sudo apt-get install bridge-utils uml-utilities vtun並且為了簡化後續操作,建立一個專屬的設定 script,名稱為 "/etc/init.d/kvm-network",以下是其內容:
#!/bin/bash-x # id of the user running qemu (kvm). Make sure you change it appropriately. USERID=1000 # number of TUN/TAP devices to setup NUM_OF_DEVICES=1 case $1 in start) modprobe tun /etc/init.d/vtun start chmod a+rw /dev/net/tun echo -n "Setting up bridge device br0" brctl addbr br0 ifconfig br0 192.168.99.1 netmask 255.255.255.0 up for ((i=0; i < NUM_OF_DEVICES ; i++)); do echo -n "Setting up " tunctl -b -u $USERID -t qtap$i brctl addif br0 qtap$i ifconfig qtap$i up 0.0.0.0 promisc done ;; stop) for ((i=0; i < NUM_OF_DEVICES ; i++)); do ifconfig qtap$i down brctl delif br0 qtap$i tunctl -d qtap$i done ifconfig br0 down brctl delbr br0 /etc/init.d/vtun stop ;; *) echo "Usage: $(basename $0) (start|stop)" ;; esac需注意的是,以上的 "USERID" 值要正確設定,端視現在的 user ID 而定,若採用 Ubuntu 預設安裝,應該都是 "1000",表示第一位系統使用者。編輯此檔後,作 chmod +x 的動作,然後以 root 身份啟動 TAP/VTUN/Bridge 的服務:
# /etc/init.d/kvm-network stop # /etc/init.d/kvm-network start也應依據實際網路狀態,避開 192.168.99.1/24 的網段,這要保留給 vtun/bridge 所用。準備就緒後,我們就可試著啟動剛剛編譯出的 kernel image,指令如下:
qemu -kernel arch/i386/boot/bzImage \ -hda /dev/zero \ -net nic -net tap,ifname=qtap0,script=no其中 "-net tap,ifname=qtap0" 就是指定 qemu 透過 TAP/TUN 的模式存取網路,其執行畫面如下圖:
# ifconfig eth0 192.168.99.2/24 # route add default gw 192.168.99.1 eth0 # ping -c 5 192.168.99.1圖中可見,筆者為確保網路可正確運作,以 ping 查驗虛擬與實體網路裝置間的橋接 (bridge),也該從 Host 端反過來 ping 192.168.99.2 (Target 端的 IP)。下一步就是多傳遞啟動 kgdb 所需的參數,如下:
$ qemu \ -no-acpi \ -kernel arch/i386/boot/bzImage -hda /dev/zero \ -net nic \ -net tap,ifname=qtap0,script=no \ -serial "stdio" -serial "pty" \ -append '$console kgdbwait kgdboc=ttyS1'注意到上述指令列多了一行:
-serial "stdio" -serial "pty"執行畫面大致如下:
-append '$console kgdbwait kgdboc=ttyS1'這行就是告訴 kgdb,欲開啟的 serial 裝置為 ttyS1,並要求完成必要的初始化後,等待來自 host 端的 gdb 連線,所以,我們可在上圖看到系統執行後,印出以下訊息並等待:
kgdb: Registered I/O driver kgdboc... kgdb: Waiting for connection from remote gdb...看來一切就緒,就待我們從 host 端來作遠端除錯了。建議開啟新的終端機,並切換到編譯核心的 linux-2.6.26 目錄下,我們要載入包含 debug info 的 Linux kernel image 是 "vmlinux",而非壓縮過的 "arch/x86/boot/bzImage" (qemu 內建 kernel loader,所以要提供已壓縮過的 kernel image),很容易從檔案長度看出彼此的差異:
$ ls -lh arch/x86/boot/bzImage vmlinux -rw-r--r-- 1 jserv jserv 1.6M 2008-06-02 01:37 arch/x86/boot/bzImage -rwxr-xr-x 1 jserv jserv 21M 2008-06-02 01:37 vmlinux載入 gdb 的方式如下:
$ gdb ./vmlinux GNU gdb 6.8-debian Copyright (C) 2008 Free Software Foundation, Inc. [...] This GDB was configured as "i486-linux-gnu"... (gdb) shell echo -e "\003" > /dev/ttyp9 (gdb) set remotebaud 115200 (gdb) target remote /dev/ttyp9 Remote debugging using /dev/ttyp9 kgdb_register_io_module (new_kgdb_io_ops=0xc028f914) at kernel/kgdb.c:1677 1677 wmb(); /* Sync point after breakpoint */ (gdb)其中粗體字表示將由我們鍵入的指令 (以下皆以此標示),首先是要求 gdb 載入包含除錯資訊的 "vmlinux",再來,測試 serial 連線是否通暢,即以輸入 ASCII 0x03 字元處理、設定 baud rate 為 115200 bps,不過,這對於 pty 來說,總是會成功,但真實情況下就難說了,在此仍列入模擬的情境。最後一個指令就是重點:
(gdb) target remote /dev/ttyp9這要求 host gdb 經由 serial 送達遠端除錯的指令,這時候,原本暫停執行的 target/kgdb 就會依據 remote gdb 通訊協定 (即 GDB Remote Serial Protocol,縮寫為 RSP) 之中的指令,做出因應的動作,而由上可知,就是取得 breakpoint 的資訊,當然,這裡不細談其具體動作。我們可查看目前的程式行為:
(gdb) list 1672 void kgdb_breakpoint(void) 1673 { 1674 atomic_set(&kgdb_setting_breakpoint, 1); 1675 wmb(); /* Sync point before breakpoint */ 1676 arch_kgdb_breakpoint(); 1677 wmb(); /* Sync point after breakpoint */ 1678 atomic_set(&kgdb_setting_breakpoint, 0); 1679 } 1680 EXPORT_SYMBOL_GPL(kgdb_breakpoint); 1681 (gdb)由 gdb 列出的程式碼即 kgdb 設定 breakpoint 的行為,我們可單步執行看看:
(gdb) n [New Thread 1] 1678 atomic_set(&kgdb_setting_breakpoint, 0); (gdb) n 1632 }至此,我們執行過 kgdb_breakpoint() 函式。透過 kgdb 得以窺見運作中 Linux kernel 的每一個面向,筆者挑選一個自 0.0.1 版的 Linux 即有的變數 "jiffies" 作為觀察。jiffies 為 Linux 的核心變數,長度為 32 位元 (unsigned long),用以紀錄系統自開幾以來,已過多少的 tick 數量。當系統觸發一次 timer interrupt 時,jiffies 變數值即會遞增一。需要留意的是,系統開機時,jiffies 變數值並非為零,而是一個特定的負數值 (稍後再詳述),而在 x86 架構下,另行定義一個與 jiffies 相關的變數為 "jiffies_64",顧名思義,此變數為 64 位元。以下就來觀察這兩個變數的值:
(gdb) p jiffies $1 = -74817 (gdb) p jiffies_64 $2 = 4294892479 (gdb)(待續)
Great hacking , I estimated those ICE device for linux debugging vendors will lost many customers
由 MaoYang 發表於 July 18, 2008 11:30 AMI think unless the emulator can talk to the bus/hardware directly, ICE is still a very powerful tool for the device driver developer.
由 Chain-Wu Lee 發表於 July 23, 2008 10:31 AM如果我想调试动态加载的模块,我应该怎么做, 请多多指教。
由 niehanzi 發表於 July 29, 2008 04:15 PM'stdio 予以導向到本機 (執行 qemu 的環境) 上的 pty (p = pseduo,虛擬之意),也就是 "/dev/ttyp?"'
这里的设备节点应该是/dev/pts/x,其中x是数字。比如,我的gnome-terminal对应的虚拟终端设备可以用ps命令确认,结果如下:
$ ps -o tty,cmd
TT CMD
pts/0 bash
pts/0 emacs
pts/0 ps -o tty,cmd
在Qemu里面执行 ifconfig eth0 192.168.99.2/24 的时候提示: "ifconfig: SIOCSIFADDR: No such device".
发现在执行 /etc/init.d/kvm-network 脚本的时候,有错误:
sudo /etc/init.d/kvm-network start
* Starting virtual tunnel daemon server vtun vtund[22068]: No hosts defined
Setting up bridge device br0Setting up qtap0
中间的“vtund[22068]: No hosts defined”是在执行/etc/init.d/vtun start 的时候报的错,用Google搜了也没有找到相应的解决方法。
To Bian Jiang,
請加入 qemu 所支援的 NIC device driver 到 kernel image 中,再行上述流程,謝謝!
由 jserv 發表於 September 6, 2009 10:58 PM感谢你的回复。
但是无论我在ubuntu 9.04 (2.6.28-15-generic)还是在我编译的最新内核(2.6.30-5 )都加上了
"Universal TUN/TAP device driver support" 选项。并且在两个系统(ubuntu 和 Qemu 运行2.6.30-5)上可以得到以下信息:
dmesg | grep tun
[ 144.671331] tun: Universal TUN/TAP device driver, 1.6
[ 144.671334] tun: (C) 1999-2004 Max Krasnyansky
自己可以手动加载tun.ko
border@wifihack:~$ ls /lib/modules/`uname -r`/kernel/drivers/net/tun.ko
/lib/modules/2.6.28-15-generic/kernel/drivers/net/tun.ko
但是在Qemu(2.6.30-5)还是出现 No such device的错误信息.
ifconfig: SIOCSIFADDR: No such device
我在另一台机器ubuntu 8.04 上运行Qemu 并编译2.6.30-5内核,在执行 sudo /etc/init.d/vtun start 的时候,没有报"vtund[13195]: No hosts defined" 的错误信息, 我想这个应该是ubuntu 9.04 tun 的一个Bug。但是在 ubuntu 8.04 里面运行 Qemu, 用ifconfig配置IP的时候还是出现No such device的错误信息.
PS: 是不是自己要在文件系统里面自己增加网络设备信息?
非常感谢
--
Bian Jiang
早上起来我再试试 VDE(http://wiki.virtualsquare.org/index.php/VDE_Basic_Networking).
由 Bian Jiang 發表於 September 8, 2009 12:39 AM