-
从 CPU 加电后执行的第一条指令开始,单步跟踪 BIOS 的执行。
题目要求从CPU加电后执行的第一条指令开始单步跟踪BIOS执行,所以应该将continue命令去掉。然后执行make lab1-mon
命令,接下来只需要一直next进行单步调试即可。 -
. 在初始化位置 0x7c00 设置实地址断点,测试断点正常。
因为在tools文件夹中,初始调试代码已经写好,并且执行了continue指令,所以如果要在初始化位置0x7c00设置时地址断点,必须也在初始调试代码中写好在初始位置0x7c00处设置断点。
所以,只需要在tools目录下的gdbinit文件中加上代码:b *0x7c00 c x/2i &pc
即可完成在初始位置设置断点。 执行`make`命令:
Breakpoint 2, 0x00007c00 in ?? () => 0x7c00: cli 0x7c01: cld 0x7c02: xor %eax,%eax 0x7c04: mov %eax,%ds 0x7c06: mov %eax,%es 0x7c08: mov %eax,%ss 0x7c0a: in $0x64,%al 0x7c0c: test $0x2,%al 0x7c0e: jne 0x7c0a 0x7c10: mov $0xd1,%al
-
从 0x7c00 开始跟踪代码运行,将单步跟踪反汇编得到的代码与 bootasm.S 和 bootblock.asm 进行比较。
为了得到单步跟踪反汇编得到的代码,在带哦用Qemu时必须加上参数-d in_asm -D q.log
,才能将运行的汇编代码保存在q.log中。
同样执行命令:
0x00007c00: cli
0x00007c01: cld
0x00007c02: xor %ax,%ax
0x00007c04: mov %ax,%ds
0x00007c06: mov %ax,%es
0x00007c08: mov %ax,%ss
0x00007c0a: in $0x64,%al
0x00007c0c: test $0x2,%al
0x00007c0e: jne 0x7c0a
0x00007c10: mov $0xd1,%al
0x00007c12: out %al,$0x64
0x00007c14: in $0x64,%al
0x00007c16: test $0x2,%al
0x00007c18: jne 0x7c14
0x00007c1a: mov $0xdf,%al
0x00007c1c: out %al,$0x60
0x00007c1e: lgdtw 0x7c6c
0x00007c23: mov %cr0,%eax
0x00007c26: or $0x1,%eax
0x00007c2a: mov %eax,%c
0x00007c2d: ljmp $0x8,$0x7c32
0x00007c32: mov $0x10,%ax
0x00007c36: mov %eax,%ds
0x00007c38: mov %eax,%es
0x00007c3a: mov %eax,%fs
0x00007c3c: mov %eax,%gs
0x00007c3e: mov %eax,%ss
0x00007c40: mov $0x0,%ebp
0x00007c45: mov $0x7c00,%esp
0x00007c4a: call 0x7d0d
比较代码:使用diff即可。
经比较,单步跟踪反汇编得到的代码与bootasm.S和bootblock.asm完全相同。
- 自己找一个 bootloader 或内核中的代码位置,设置断点并进行测试