- 论坛徽章:
- 0
|
Gdb调试内核的启动
http://www.alivepea.me/kernel/gdb-kernel-startup/
“调试是通过某种办法发现BUG进行修正的过程” – 《Debug Hacks》
在做Kdump时,发现crashkernel区域位于某些位置时,vmcore初始化总是失败。原 因是Dump-Capture kernel启动后已经不在crashkernel的区域内了,这显然是不对 的。原来是Dump-Capture kernel的映像zImage启动解压时重定向,将内核解压到非 crashkernel的区域,使用Image替代zImage来做Dump-Capture kernel就可以解决这个 问题了。
分享一下自己Gdb调试zImage/Image启动的一些方法,以更方便理解了内核启动中一 些魔法。以下方法可在Qemu下的vexpress-a9目标演示。
Gdb调试zImage的启动
像日志Qemu下调试内核一样启动Qemu.Gdb连接到Qemu.
(gdb) target remote tcp:localhost:1234
vexpress-a9的”BIOS”会在RAM的起始地址0x60000000处开始执行,初始化atags和 processor id,并跳转到0x60010000
(gdb) b * 0x60010000
(gdb) c
手工加载内核调试映像。zImage对应的ELF文件是 $output/arch/arm/boot/compressed/vmlinux,由于这个映像地址无关,手工添加符号表 到指定位置。
(gdb) load vmlinux 0x60010000
(gdb) add-symbol-file vmlinux 0x60010000
(gdb) b start
(gdb) c
至此,可以在源代码下单步调试zImage了。如果代码重定位了,再 add-symbol-file到指定位置就可以了。
Gdb调试Image的启动
Image是自解压之后的内核映像,刚启动时,MMU还没有将内存映射到vmlinux的链接 地址。Image对应的ELF文件是$output/vmlinux, 需要加载映像到 0x60008000的内存位置。
(gdb) target remote tcp:localhost:1234
(gdb) b * 0x60010000
(gdb) c
(gdb) load vmlinux -0x60000000
通过$ arm-linux-readelf -S vmlinux得到符号表段的偏移后,加载符号表到相应的 内存物理地址。
(gdb) add-symbol-file vmlinux 0x60008240 -s .head.text 0x60008000 -s .rodata 0x60479000
修改pc地址以修正load指令更新的默认pc地址。
(gdb) set $pc=0x60008000
(gdb) b stext
(gdb) c
至些,像调试普通应用一样,可以一直调试到打开MMU __enable_mmu为止。此后,就 要重新add-symbol-file到相应的虚拟地址,即vmlinux的链接地址。
在真实的目标机中,如使用Trace32调试内核的启动代码,方法也是一样的。
另外,使用调试器查看汇编代码,似乎也是学习汇编代码一个好途径。
~EOF~ |
|