- 論壇徽章:
- 0
|
Gdb調(diào)試內(nèi)核的啟動
http://www.alivepea.me/kernel/gdb-kernel-startup/
“調(diào)試是通過某種辦法發(fā)現(xiàn)BUG進(jìn)行修正的過程” – 《Debug Hacks》
在做Kdump時,發(fā)現(xiàn)crashkernel區(qū)域位于某些位置時,vmcore初始化總是失敗。原 因是Dump-Capture kernel啟動后已經(jīng)不在crashkernel的區(qū)域內(nèi)了,這顯然是不對 的。原來是Dump-Capture kernel的映像zImage啟動解壓時重定向,將內(nèi)核解壓到非 crashkernel的區(qū)域,使用Image替代zImage來做Dump-Capture kernel就可以解決這個 問題了。
分享一下自己Gdb調(diào)試zImage/Image啟動的一些方法,以更方便理解了內(nèi)核啟動中一 些魔法。以下方法可在Qemu下的vexpress-a9目標(biāo)演示。
Gdb調(diào)試zImage的啟動
像日志Qemu下調(diào)試內(nèi)核一樣啟動Qemu.Gdb連接到Qemu.
(gdb) target remote tcp:localhost:1234
vexpress-a9的”BIOS”會在RAM的起始地址0x60000000處開始執(zhí)行,初始化atags和 processor id,并跳轉(zhuǎn)到0x60010000
(gdb) b * 0x60010000
(gdb) c
手工加載內(nèi)核調(diào)試映像。zImage對應(yīng)的ELF文件是 $output/arch/arm/boot/compressed/vmlinux,由于這個映像地址無關(guān),手工添加符號表 到指定位置。
(gdb) load vmlinux 0x60010000
(gdb) add-symbol-file vmlinux 0x60010000
(gdb) b start
(gdb) c
至此,可以在源代碼下單步調(diào)試zImage了。如果代碼重定位了,再 add-symbol-file到指定位置就可以了。
Gdb調(diào)試Image的啟動
Image是自解壓之后的內(nèi)核映像,剛啟動時,MMU還沒有將內(nèi)存映射到vmlinux的鏈接 地址。Image對應(yīng)的ELF文件是$output/vmlinux, 需要加載映像到 0x60008000的內(nèi)存位置。
(gdb) target remote tcp:localhost:1234
(gdb) b * 0x60010000
(gdb) c
(gdb) load vmlinux -0x60000000
通過$ arm-linux-readelf -S vmlinux得到符號表段的偏移后,加載符號表到相應(yīng)的 內(nèi)存物理地址。
(gdb) add-symbol-file vmlinux 0x60008240 -s .head.text 0x60008000 -s .rodata 0x60479000
修改pc地址以修正load指令更新的默認(rèn)pc地址。
(gdb) set $pc=0x60008000
(gdb) b stext
(gdb) c
至些,像調(diào)試普通應(yīng)用一樣,可以一直調(diào)試到打開MMU __enable_mmu為止。此后,就 要重新add-symbol-file到相應(yīng)的虛擬地址,即vmlinux的鏈接地址。
在真實的目標(biāo)機中,如使用Trace32調(diào)試內(nèi)核的啟動代碼,方法也是一樣的。
另外,使用調(diào)試器查看匯編代碼,似乎也是學(xué)習(xí)匯編代碼一個好途徑。
~EOF~ |
|