使用UML調試linux內核
來自專欄 Linux I/O40 人贊了文章
概述
UML這裡不是統一建模語言,而是UserMode Linux的縮寫,從字面上看,是在用戶態運行
linux內核,即將內核當作一個應用程序在跑,這樣我們就可以用調試應用層程序的方法調試內
核了,應用層的強大調試工具gdb就派上用場了。很多時候我們寫內核代碼,當遇到演算法比較
複雜但又不涉及底層結構的時候總是喜歡現在應用層實現並調試,然後在寫到內核層。為什
么,就是因為用戶層調試比內核調試方便。但是UML的最大局限性就是不能調試硬體關聯性強
的代碼,但是還是有很多方面可以應用的,比如調度演算法、VFS等。用gdb像跟蹤用戶程序一
樣跟蹤這樣的代碼,相信你一定非常感興趣,那麼讓我們馬上開始第一步:搭建一個UML測試
環境。
安裝
下載編譯內核代碼
1. 首先從網上下載你感興趣的內核代碼版本,比如我下載的版本是2.6.36.4。
2. 編譯內核
在真正進入編譯之前(make linux ARCH=um之前),需要先進行內核配置,具體配置可參考下圖:
注意ARCH=um是必不可少的,否則就不是編譯UML平台的內核了。如果編譯過正常平台下
(如amd64, i386,ppc等)的內核的人會發現,這個配置列表和以往的有一些不同,這就是
ARCH=um的作用,我們現在要配置的是一個要跑在應用層的內核。除了選上你需要的功能對
應選項以外,還有一些選項是必要為UML選的:
* 在UML-specific options--->Host Processor typefeatures--->Processor family里選擇你的處理器平台,如果你發現有Generic x86 support配置(不一定會出現),請保證它不生效。
* Character devices中的stderr console, Virtual serial line, nullchannel support, port channel support, pty channel support, tty channelsupport, xterm channel support等是需要選中的。* Enable loadable module support 在UML中一般是不需要的,可以取消它,當然你不取消也沒關係。* Networking support 里的Amateur Radio support, IrDA (infrared)subsystem support, Bluetooth subsystem support等的也是可以去掉的。而UML Network Devices里的東西是需要依據具體情況而定的,我這裡就使用了默認的配置,如果你有特殊需求還請根據自己的需求選。NetLabel subsystem support我選了,因為我需要調試網路標籤。* Block Devices---> Virtual block devices需要選中。* File systems嘛……這個就比較複雜了,你需要什麼就自己選吧。* SCSI device support中可以不需要。* Multiple devices driver support也可以不需要。* Kernel Hacking是一個比較重要的,需要選中Kernel debugging, Compile the kernel with debuginfo這兩個需要選上,Show timing information on printks可以選上,其它的選項根據你要調試需求自己選擇。
好了,配置好後你就可以保存退出了。
構建運行環境
讓uml的內核跑在一個獨立出來的運行環境中,我們需要一塊磁碟,並在這塊磁碟上作一個文
件系統,即根文件系統,再在上面作一個可運行的最小系統(因為要讓系統可運行,需要的不
僅僅是一個內核,還有一些相關的運行環境的支持)。這裡可以自己製作帶最小系統的根文件
系統,也可以從網上直接下載一個現成的,剛開始的時候我採用了自己製作的方法,但是系統
運行沒有成功,我便從網上下載了一個現成的,最終算是大功告成。我在這裡分別給出兩種辦
法,任各位自己挑選。
手動製作方法:
1. 首先創建一個設備用來作為文件系統的載體並格式化成想要的文件系統:
mkdir disk dd if=/dev/zero of=disk/um-rootbs=1024K count=1000 mkfs.ext3 disk/um-root
2. 掛載設備:創建目錄掛載點目錄並將上面已格式化的設備掛載
mkdir -p mnt/mount -o loop disk/um-rootmnt/
3. 構建最小化系統
debootstrap squeeze mnt/ http://ftp.debian.org/debian(ubuntu上)
4. 等到一切就緒以後,系統運行所需的一切條件就已經具備了。
網上下載辦法:(推薦)
上面我們介紹了自己手動製作根文件系統的辦法,這種辦法可能會讓你對系統有更深入的理
解,但是出錯的可能性也更大,我在第一次嘗試的時候就出錯了,而且找不到出錯的原因,讓
我很是鬱悶,於是選擇了這種方法。這種辦法非常簡單,只需要從網上下載適合你的root_fs即
可。下載地址為:
Distribution Disk Images比如,我下載的就是DebianSqueeze。
運行UML
準備工作就緒以後,就可以讓UML跑起來了。再次申明,讓UML跑起來需要的兩個條件:1.編
譯好的內核;2. 製作好的根文件系統,在我自己的系統中,我將他們存儲在不同的目錄下,編
譯好的內核位於目錄kernel/linux-2.6.36.4下,而製作好的根文件系統位於disk下,名為
root_fs。
運行UML很簡單,直接輸入下面的命令即可:./kernel/linux-2.6.36.4/linux ubda=disk/root_fs mem=256m
UML執行的結果是會彈出一個登陸對話框,提示你輸入用戶名和密碼,
網上下載的根文件系統,默認用戶名是root,密碼為空,如下圖所示:
和普通操作系統的所有功能。
使用UML調試內核
搞清楚了如何使用UML以後,利用UML調試內核也就變得易如反掌了,我們使用的工具還是
強大的GDB 。
使用GDB載入編譯好的內核,然後設置斷點,用法與gdb調試普通應用程序無異。這裡不妨給
出我的gdb調試截圖:
Q&A
在編譯使用和調試UML的過程中,可能會遇到很多意想不到的麻煩,這部分我將自己遇到過的
意外貼在這裡,希望對初學者有所幫助,如果你有任何的補充,希望你能給出問題以及行得通
的解決方案並留言,我會不斷補充。
1. 在debug UML的時候,會遇到如下問題:
解決辦法:tell gdb to ignore SIGSEGV: 告訴gdb忽略SIGSEGV。
在gdb命令框中輸入:handle SIGSEGV noprint nostop pass
2. Debug UML的時候遇到一個問題:
Program received signal SIGTRAP, Trace/breakpoint trap.
0x08066a4c in get_signals () atarch/um/os-Linux/signal.c:284
解決辦法:
在gdb命令框中輸入:handle SIGTRAP nostop noprint
參考
實踐過程中參考了以下兩篇博客,對博主表示感謝,這裡給出鏈接:
http://blog.csdn.net/zr_lang/article/details/8102328
http://blog.csdn.net/ztz0223/article/details/7874759
推薦閱讀:
※Android-x86和Linux的通用內核
※嵌入式Linux系統開發學習步驟
※【乾貨整理】Docker,從入門說起……
※Linux使用
※如何在 Linux 中的特定時間運行命令