Lab 1:Part 2: exercise 4 - 6
exercise 4
阅读有关使用C进行指针编程的信息。后下载pointers.c的代码,运行它,并确保您了解所有打印值的来源。特别是,请确保您了解输出的第1和第6行中的指针地址来自何处,输出的2至4行中的所有值如何到达那里,以及为什么第5行中打印的值看起来被破坏了。
exercise 5
然后将boot / Makefrag 中的链接地址更改为错误的地址,运行make clean,使用make重新编译 lab,再次遍历引导加载程序的前几条指令,并确定第一条可能“中断”或执行错误操作的指令。
我这里将链接地址改为 0x7000
,在执行 lgdtw
处的加载地址变为了 0x7064
,接着后面的运行就会报错。修改地址后,导致引导加载器的段描述符表 gdt
加载出错。
exercise 6
在 elf header 中,e_entry 字段保存这程序入口点的链接地址,可以使用 objdrum -f
查看入口地址。 总的来说, bootmian 先加载 elf 文件的前 4096 字节(elf header)进入内存,在根据 elf header 的字段从磁盘中将内核各部分加载到内存中,最后跳转到内核的入口处,将控制权交给内核。
练习:
重置机器(退出QEMU / GDB并重新启动它们)。在BIOS进入引导加载程序时,检查 0x00100000
处的8个内存字,然后在引导加载程序进入内核时再次检查。他们为什么不同?第二个断点有什么? (您实际上并不需要使用QEMU来回答这个问题。只需考虑一下即可。)
使用 x/Nx addr
打印地址为 addr 处的 N 个字(字长 16bit)。
分别在引导加载程序的开始 0x7c00
和 内核程序的开始 0x1000c
处设置断点。
-
进入引导加载程序时,
0x00100000
处存储的内容: -
进入内核程序时:
该处的内容不一是因为 bootmian 将内核的 .text
段内容加载到了此处。
.text
的 load address (LMA)
为该地址。