雖然使用UML或者Qemu可以調試Linux內核,但UML和Qemu畢竟是一個模擬,調試硬件驅動總是用虛擬硬件總不成事,而且Qemu據傳聞 對於時鐘和中斷的處理也有問題,所以對於處理真實硬件的問題,最完美的調試方式就是雙機調試,被調試內核在完全真實的環境中運行,排除虛擬機制的不穩定因素,而且使用內核自帶的KGDB機制,更具有可靠性,類似Windows下的WinDbg調試方式。這裡使用VirtualBox虛擬機進行調試,但所提 及的方法完全適用於諸如VMWare、Qemu虛擬機或者真實機器,只是相關的串口配置方式有些許不同而已。
首先需要編譯配置KGDB選項的內核,編譯方式也比較簡單:
# 配置內核選項
[cpp@dark linux-2.6.34]$ make menucofnig
# Kernel hacking --->
# [*] Compile the kernel with debug info
# [*] KGDB: kernel debugging with remote gdb --->
# 編譯
[cpp@dark linux-2.6.34]$ make
編譯完成之後需要在目標機器部署自己的內核,需要修改grub.conf,或者lilo的配置,這決定於Linux使用哪種引導程序,這裡修改grub.conf,首先拷貝編譯好未壓縮內核鏡像至目標機器boot分區,命名為linux-2.6.34。
# 配置文件路徑 /boot/grub/grub.conf
# 默認啟動內核
default 0
# 選擇超時時間
timeout 30
# 添加以下內容,以增加一個新的啟動項
title Linux 2.6.34 (Debug)
root (hd0,0)
kernel /boot/linux-2.6.34 root=/dev/sdb
對於lilo,修改配置文件/etc/lilo.conf,之後必須使用lilo -C /etc/lilo.conf使配置生效。
啟 動系統後,首先出現grub引導畫面,選擇Debug內核啟動,不論真機還是虛擬機,時常有系統無法啟動的問題,是因為內核配置過小,最基本的啟動都無法 支持,如果出現找不到sdb1類似錯誤,需要檢查sdb1是否正確,IDE/ATA硬盤以h打頭,為hda等,SATA和SCIS以s打頭,為sda等 等,後綴a,b分別為第幾塊硬盤,sda為第一塊,sdb為第二塊,其後的數字1、2指明第幾個分區,另外需要檢查的是硬盤驅動是否正確安裝,這個可參閱 Linux安裝配置說明,結合google,應該能夠解決。
能夠啟動系統後,在目標Linux內核啟動選項append命令 ro kgdboc=ttyS0,115200 kgdbwait,如此目標機器啟動到一定時機停止,出現kgdb: Waiting for connection from remote gdb…的字句,這樣對於目標機器的配置已經完成,再來看主機配置,啟動gdb配置串口:
# 加載 vmlinux
cpp@dark:~/linux-2.6.34$ gdb vmlinux
GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-slackware-linux"...
# 設置遠程端口 波特率
(gdb) set remotebaud 115200
# 連接遠程串口
(gdb) target remote /dev/pts/3
Remote debugging using /dev/pts/3
kgdb_register_io_module (new_kgdb_io_ops=)
at kernel/kgdb.c:1749
1749 wmb(); /* Sync point after breakpoint */
# 至此便可任意調試
(gdb)
這裡串口我使用的是 /dev/pts/3 是因為我在linux下使用virtualbox虛擬機的管道串口,再利用socat虛擬串口,有條件的可以直接利用主機串口,這裡的設備便成為 /dev/ttyS0,使用socat 虛擬串口的命令如下:
# vboxS0 為virtualbox的串口管道
cpp@dark:~/kernel/socat-2.0.0-b4$ ./socat -d -d /tmp/vboxS0 pty:1
2010/12/10 23:24:14 socat[3962.3082070656] N opening connection to AF=1 "/tmp/vboxS0"
2010/12/10 23:24:14 socat[3962.3082070656] N successfully connected from local address AF=1 "\x04\b\x94\x18\x@C\xAE\xB4\x@7\xE2\xA7\a"
2010/12/10 23:24:14 socat[3962.3082070656] N successfully connected via
2010/12/10 23:24:14 socat[3962.3082070656] N PTY is /dev/pts/3
2010/12/10 23:24:14 socat[3962.3082070656] N starting data transfer loop with FDs [3,3] and [4,4]
至此便可使用kgdb進行串口雙機調試,這裡使用linux主機和虛擬機實現,當然相同的思路可以很容易知道如何進行兩個虛擬機或者兩個真實機調試。
kgdb 也支持網絡調試,使用tcp協議,但是串口應該是最理想的方式,如果需要調試網絡程序,再通過網絡傳輸調試指令,會不會混亂呢?關於kgdb,在 linux內核源碼的文檔部分 /linux-2.6.34/Documentation/DocBook/kgdb.tmpl ,有一分文檔說明,配置時可參閱之。
相關系列文章:
Linux 內核調試1-UML http://www.linuxidc.com/Linux/2012-07/66410.htm
Linux 內核調試2-UML調試內核 http://www.linuxidc.com/Linux/2012-07/66411.htm
Linux 內核調試3-UML網絡配置 http://www.linuxidc.com/Linux/2012-07/66412.htm
Linux 內核調試4-Qemu調試Linux內核 http://www.linuxidc.com/Linux/2012-07/66413.htm
Linux 內核調試5-UML和Qemu調試模塊 http://www.linuxidc.com/Linux/2012-07/66414.htm
Linux 內核調試6-使用KGDB雙機調試 http://www.linuxidc.com/Linux/2012-07/66415.htm