GDB調(diào)試CentOS內(nèi)核

通過GDB和QEMU調(diào)試Linux內(nèi)核已經(jīng)有很多介紹了笨蚁,但基本都是制作簡單的根文件系統(tǒng)凶朗。有時候需要調(diào)試的模塊或者場景需要用到發(fā)行版的Linux致稀,因此本文介紹調(diào)試CentOS內(nèi)核的步驟。

GDB調(diào)試Linux內(nèi)核關(guān)鍵步驟

debug_kernel.jpg
  1. 首先需要有一個可以啟動運行Cent OS 7的虛擬機
    • 準備一個qcow2格式的磁盤鏡像文件centos.img.qcow2俱尼,通過CentOS的光盤iso將系統(tǒng)安裝到這個磁盤鏡像中。
  2. 虛擬機需要連接外部網(wǎng)絡(luò)(例如mount nfs文件系統(tǒng)萎攒、調(diào)試內(nèi)核的網(wǎng)絡(luò)代碼等)遇八,所以我們要為QEMU虛擬機選擇合適的網(wǎng)絡(luò)方案
    • 通過將tap和物理網(wǎng)卡加入到bridge
  3. GDB的調(diào)試需要源代碼和編譯生成的原始文件vmlinux,因此我們要下載Linux內(nèi)核源代碼耍休,完成patch刃永、configure和編譯等工作;
  4. 編譯Linux內(nèi)核的最終產(chǎn)品為bzImage,因此要能夠更新虛擬機中的內(nèi)核bzImage以及GRUB配置羊精;
  5. QEMU內(nèi)置一個gdbserver斯够,通過”-s -S”選項來開啟并等待GDB的連接,默認端口為1234
    • -S freeze CPU at startup (use 'c' to start execution)
    • -s shorthand for -gdb tcp::1234
    • 也可以在QEMU命令行中通過gdbserver tcp::1234來指定gdbserver的端口號

安裝CentOS 7.1到虛擬磁盤

從CentOS網(wǎng)站上下載CentOS 7的安裝包CentOS-7-x86_64-DVD-1503-01.iso

qemu-img create centos.img.qcow2 -f qcow2 40G

qemu-system-x86_64 -cdrom CentOS-7-x86_64-DVD-1503-01.iso -hda centos.img.qcow2 -boot d -net nic -net user -m 4096 -vnc 0.0.0.0:1 -enable-kvm -smp 2
  • 通過VNC View連接ip:5901進入虛擬機的控制臺喧锦,在控制臺中完成CentOS 7.1的安裝過程
  • 安裝完成后得到虛擬機的磁盤鏡像centos.img.qcow2
  • 重新啟動QEMU虛擬機:
qemu-system-x86_64 -m 4096 -vnc 0.0.0.0:1 centos.img.qcow2

通過VNC Viewer連接到虛擬機的控制臺读规,確認CentOS 7正常啟動

VNC

QEMU虛擬機網(wǎng)絡(luò)配置

QEMU支持多種方式的網(wǎng)絡(luò)配置,對于需要訪問外部網(wǎng)絡(luò)的虛擬機燃少,最合適的方式是tap橋接模式束亏,即將虛擬機網(wǎng)卡對應(yīng)的tap網(wǎng)卡和Host的物理網(wǎng)卡加入到同一個bridge中

  • 創(chuàng)建bridge并將物理網(wǎng)卡加入到該bridge中
/home/gj/virt/qemu-kernel/net_config.sh
#!/bin/sh
ifconfig enp2s0 0.0.0.0
brctl addbr br0
brctl addif br0 enp2s0
dhclient br0
  • QEMU創(chuàng)建虛擬機時指定-net nic -net tap,script=/etc/qemu-ifup1,其中qemu-ifup1由QEMU初始化虛擬機網(wǎng)卡時調(diào)用阵具,它負責(zé)將tap網(wǎng)卡加入到bridge中
/etc/qemu-ifup1
#! /bin/sh
# TAP interface will be passed in $1
ifconfig $1 up
brctl addif br0 $1

虛擬機啟動之后可以看到其已經(jīng)通過DHCP的方式自動獲取到ip

編譯Linux內(nèi)核源代碼

下載Linux內(nèi)核的源代碼可以在Linux內(nèi)核網(wǎng)站上下載“干凈”的版本碍遍,但是需要自己來配置內(nèi)核定铜,更簡單的辦法是在CentOS網(wǎng)站上下載對應(yīng)版本的rpm源碼包,這樣不需要關(guān)心patch和內(nèi)核配置怕敬,比如CentOS 7.1對應(yīng)的源碼包kernel-3.10.0-229.1.2.el7.src.rpm

  • 安裝源碼包
rpm –ivh kernel-3.10.0-229.1.2.el7.src.rpm
  • 通過rpmbuild -bp完成源碼的patch和config工作(-bp表示prepare)
rpmbuild -bp ~/rpmbuild/SPECS/kernel.spec

完成之后我們就得到了一套準備好的待編譯的源代碼揣炕,此時完全可以將這一套源代碼打包拷貝到別處重復(fù)使用。rpmbuild -bb可以完成代碼的prepare和編譯打包的全部工作东跪,直接生成新內(nèi)核的rpm安裝包畸陡。

  • 進入Linux內(nèi)核源碼目錄
cd ~/rpmbuild/BUILD/kernel-3.10.0-229.1.2.el7/linux-3.10.0-229.1.2.el7.centos.x86_64/
make bzImage && make modules

生成gdb需要的vmlinux和待安裝的新內(nèi)核bzImage(arch/x86_64/boot/bzImage)

安裝新內(nèi)核

編譯完成需要將生成的內(nèi)核(bzImage)和modules安裝到虛擬機中去,一種方式是制作rpm包然后拷貝到虛擬機中去安裝:

make binrpm-pkg INSTALL_MOD_STRIP=1

另外一種方式:在host中將內(nèi)核源碼通過nfs共享給虛擬機越庇,由虛擬機自己來完成install的工作

  1. 進入源碼目錄罩锐,修改代碼后編譯
cd ~/rpmbuild/BUILD/kernel-3.10.0-229.1.2.el7/linux-3.10.0-229.1.2.el7.centos.x86_64
make bzImage
make modules (第一次編譯安裝新內(nèi)核時需要)
  1. QEMU啟動虛擬機
qemu-system-x86_64 -m 4096 -vnc 0.0.0.0:1 centos.img.qcow2 -net nic -net tap,script=/etc/qemu-ifup1 -enable-kvm -smp 2

*注意此時不需要’-s -S’選項,同時可以新增’-enable-kvm’和’-smp 2’來提高虛擬機的性能卤唉;

  1. 在虛擬機中mount Host導(dǎo)出的源碼目錄
showmount -e 192.168.10.115
Export list for 192.168.10.115:
/root/rpmbuild/BUILD 192.168.10.0/24
mount -t nfs 192.168.10.115:/root/rpmbuild/BUILD /mnt/nfs/
  1. 進入源碼目錄安裝新編譯的內(nèi)核
make modules_install INSTALL_MOD_STRIP=1    (第一次編譯安裝新內(nèi)核時需要)
make install

安裝成功后重啟虛擬機后通過uname -a確認內(nèi)核更新成功

開始調(diào)試內(nèi)核

  1. 檢查網(wǎng)絡(luò)配置
  2. 在會話1中通過QEMU創(chuàng)建虛擬機
cd /home/gj/virt/qemu-kernel
qemu-system-x86_64 -m 4096 -vnc 0.0.0.0:1 centos.img.qcow2 -net nic -net tap,script=/etc/qemu-ifup1 -s -S

使用VNC viewer連接ip:5901

  1. 會話2中進入源碼目錄并gdb
cd ~/rpmbuild/BUILD/kernel-3.10.0-229.1.2.el7/linux-3.10.0-229.1.2.el7.centos.x86_64
gdb vmlinux
  1. 在gdb中連接QEMU的gdbserver并設(shè)置斷點
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
0x0000000000000000 in irq_stack_union ()
(gdb) break yfs_mount
Breakpoint 1 at 0xffffffff812b259f: file fs/yfs/super.c, line 777.
(gdb) c
Continuing.

此時通過VNC Viewer連接到虛擬機的控制臺涩惑,應(yīng)該可以看到啟動的輸出

  1. 在虛擬機中執(zhí)行調(diào)試代碼的操作,然后會話2中會被break住桑驱,此時像普通程序一樣進行g(shù)db調(diào)試竭恬;

附一:gdb編譯

GDB在調(diào)試64位Linux內(nèi)核時會出錯:

Remote ‘g’ packet reply is too long

解決辦法是下載GDB的源代碼,如下所示修改remote.c

if (buf_len > 2 * rsa->sizeof_g_packet)
    error (_("Remote 'g' packet reply is too long: %s"), rs->buf);

修改為:

if (buf_len > 2 * rsa->sizeof_g_packet) {
//error (_("Remote 'g' packet reply is too long: %s"), rs->buf);
    rsa->sizeof_g_packet = buf_len ;
    for (i = 0; i < gdbarch_num_regs (gdbarch); i++) {
        if (rsa->regs->pnum == -1)
            continue;
        if (rsa->regs->offset >= rsa->sizeof_g_packet)
            rsa->regs->in_g_packet = 0;
        else
            rsa->regs->in_g_packet = 1;
    } 
}

重新編譯并安裝GDB

./configure
make && make install

附二:qemu編譯

Redhat/CentOS不推薦直接使用qemu-kvm熬的,而是需要通過libvirt的接口來創(chuàng)建虛擬機痊硕,因此要使用QEMU推薦下載QEMU源代碼編譯安裝,編譯安裝也很簡單:

./configure --target-list=x86_64-softmmu
make && make install

附三:虛擬機組網(wǎng)

橋接

上文介紹中QEMU虛擬機是通過橋接方式連接外部網(wǎng)絡(luò)押框,其將虛擬機對應(yīng)的tap網(wǎng)卡和物理網(wǎng)卡加入到同一個bridge中岔绸,將物理網(wǎng)卡的ip分配到bridge上,這樣從邏輯上看虛擬機的報文都是通過bridge進出

Bridge

橋接方式的好處是每個VM都可以獲取到物理機同網(wǎng)段的ip,因此也可以訪問物理機所屬的網(wǎng)絡(luò)

NAT

有時虛擬機不需要訪問物理機所屬的網(wǎng)絡(luò)(比如受ip沖突影響)橡伞,虛擬機只需要能夠互相訪問同時可以訪問外網(wǎng)盒揉,這時NAT方式是比較適合的。其將所有VM對應(yīng)的tap網(wǎng)卡加入到同一個bridge中兑徘,這個bridge作為這個私有網(wǎng)段的網(wǎng)關(guān)刚盈,每個VM啟動后配置一個同網(wǎng)段的ip;然后物理網(wǎng)卡為這個bridge做NAT挂脑。

NAT

配置方式如下:

  1. Host網(wǎng)絡(luò)初始化腳本
#!/bin/sh
# create bridge
brctl addbr br0-qemu 
ifconfig br0-qemu 192.168.125.1
iptables -t nat -A POSTROUTING -o enp2s0 -j MASQUERADE
iptables -A FORWARD -i enp2s0 -o br0-qemu -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i br0-qemu -o enp2s0 -j ACCEPT

echo 1 > /proc/sys/net/ipv4/ip_forward
  1. qemu初始化腳本 /etc/qemu-ifup-nat
#! /bin/sh
# TAP interface will be passed in $1
ifconfig $1 promisc up
brctl addif br0 $1

上述方式中所有VM的ip, gateway和DNS都需要配置成固定的藕漱。如果要實現(xiàn)VM自動分配私有ip那么還需要在host上安裝一個本地的DHCP Server

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市崭闲,隨后出現(xiàn)的幾起案子肋联,更是在濱河造成了極大的恐慌,老刑警劉巖刁俭,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件牺蹄,死亡現(xiàn)場離奇詭異,居然都是意外死亡薄翅,警方通過查閱死者的電腦和手機沙兰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門氓奈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鼎天,你說我怎么就攤上這事舀奶。” “怎么了斋射?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵育勺,是天一觀的道長。 經(jīng)常有香客問我罗岖,道長涧至,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任桑包,我火速辦了婚禮南蓬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘哑了。我一直安慰自己赘方,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布弱左。 她就那樣靜靜地躺著窄陡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拆火。 梳的紋絲不亂的頭發(fā)上跳夭,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音们镜,去河邊找鬼优妙。 笑死,一個胖子當(dāng)著我的面吹牛憎账,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播卡辰,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼胞皱,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了九妈?” 一聲冷哼從身側(cè)響起反砌,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎萌朱,沒想到半個月后宴树,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡晶疼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年酒贬,在試婚紗的時候發(fā)現(xiàn)自己被綠了又憨。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡锭吨,死狀恐怖蠢莺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情零如,我是刑警寧澤躏将,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站考蕾,受9級特大地震影響祸憋,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜肖卧,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一蚯窥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧喜命,春花似錦沟沙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至牌里,卻和暖如春颊咬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背牡辽。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工喳篇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人态辛。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓麸澜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親奏黑。 傳聞我的和親對象是個殘疾皇子炊邦,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容