修改link address 查看结果
- 将
boot/Makefrag
中的-Ttext 0x7C00
改为-Ttext 0x7E00
- 备份原先的
obj/boot/boot.asm
文件 - 在lab目录下执行
make clean && make
- 对比前面备份的 boot.asm 和新产生的 boot.asm
修改前 v.s. 修改后
可以看到boot loader的VMA,执行时的链接地址(link address)不同。原先是从7c00开始,变成了现在的7e00。
将断点设置在 0x7c00
,即BIOS默认进入boot loader 的地址,是一个默认的设计。
可以看到下一条会执行的指令仍然是 cli
,接下来的指令也很正常,就是设置寄存器,使能A20地址线等。接下来来到了如下这条指令:
由Exercise3的分析可知 0x7e64
在内的连续6个字节表示GDTR(全局段描述符表寄存器),它记录了全局段描述符表的首地址和大小。进行保护模式后就需要段选择子来索引这里面的表项,每个表项记录了段的起始地址、大小和权限。因此查看 0x7e64
在内的6个字节:
可以看到所有的内存地址空间存放的内容都是0x00。但是真正的GDTR内的值应该存储在 0x7c64
处。GDTR的错误会导致去错误的位置寻找GDT,会导致段选择子找到错误的表项,会导致段的起始位置不对,会导致跳转指令(段起始位置+段偏移)跳转到错误的位置
当一步步执行后,来到 ljmp
这个跳转指令后,发现指令完之后无法跳转到正确的指令。在运行make qemu-nox-gdb
的窗口会提示 triple default
,三振出局,没有修复的机会,系统会直接关机。