打印

用 gdb 和 qemu 调试 grub

[复制链接]
8572|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主


因为qemu内置了gdbserver,所以我们可以用gdb调试qemu虚拟机上执行的代码,而且不受客户机系统限制。
以下内容是我调试 grub 0.97 时的一份笔记。
准备
qemu, gdb,以及一份带grub的虚拟机镜像,一份grub源码。
调试过程
启动虚拟机
$ sudo qemu-system-x86_64 -s -S -m 256 -hda test.img
然后使用gdb连接
$ gdb(gdb) target remote localhost:1234(gdb) set architecture i8086(gdb) break *0x7c00(gdb) cont
一开始CPU是工作在实模式下,为了gdb显示正常我们把架构设置为i8086
BIOS会把MBR加载到内存0x7c00处,我们在这里下断点,然后执行
查看一下当前的反汇编代码
(gdb) x/4i $pc=>  0x7c00:        jmp        0x7c4a    0x7c02:        nop    0x7c03:        add        %al,(%bx,%si)    0x7c05:        add        %al,(%bx,%si)
显示的是 att 风格的汇编代码,如果不习惯可以切换成 intel 风格的。
(gdb) set disassembly-flavor intel(gdb) x/4i $pc=>  0x7c00:        jmp        0x7c4a    0x7c02:        nop    0x7c03:        add        BYTE PTR [bx+si],al    0x7c05:        add        BYTE PTR [bx+si],al
上来就是一个无条件跳转,我们先执行一步,再查看下代码。
[url=] [/url]
(gdb) ni(gdb) x/8i $pc=>  0x7c4a:        cli    0x7c4b:        nop    0x7c4c:        nop    0x7c4d:        test       dl,0x80    0x7c50:        jne        0x7c54    0x7c52:        mov        dl,0x80    0x7c54:        jmp        0x0:0x7c59    0x7c59:        xor        ax,ax[url=] [/url]

在gdb里查看汇编代码不够方便,我们试着把MBR提取出来,再用IDA打开。
$ sudo dd if=/dev/sda of=mbr.hex bs=512 count=1
对照一下grub的源码,大致能推断出这个就是stage1的代码。
其他几个常用的gdb命令
单步步入
(gdb) si
查看断点
(gdb) info breakpoints
删除断点
(gdb) delete
grub 启动过程总结
阶段:stage1
数据来源:MBR
内存地址:0x7c00
源码:/stage1/stage1.S
这段代码的作用就是加载MBR之后的1个扇区到0x2000处。
阶段:stage1.5
数据来源:MBR之后的几个扇区
内存地址:0x2000
源码:/stage2/start.S
这段代码的作用是把stage1.5剩余的扇区加载到0x2200,因为stage1只加载了stage1.5的第一个扇区。
源码:/stage2/asm.S
这段代码的作用是初始化部分环境,最后调用 init_bios_info
源码:/stage2/common.c
这段代码的作用是初始化c语音环境,最后调用 cmain
源码:/stage2/stage1_5.c
这段代码的作用是加载stage2到0x8000处,然后跳转到0x8200执行。
阶段:stage2
数据来源:/boot/grub/stage2
内存地址:0x8000
源码:/stage2/stage2.c等
后面就是grub的主要功能,显示菜单,启动客户系统等。
客户机的Linux内核是加载到0x100000内存地址。



使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:qq群:49734243 Email:zukeqiang@gmail.com

1349

主题

12426

帖子

53

粉丝