MIT6.828-Lab1-Part3-Exercise7-跟踪JOS内核并理解

 

涉及内存映射的过程

跟踪JOS内核

  1. 使用QEMU和GDB跟踪内核文件。在执行 movl %eax %cr0 前后,内存地址 0x0010|00000xf010|0000 存放着什么?
  2. 如果上面的指令没执行,而是被跳过,那么第一条出错的指令会是什么?可以通过注释 kern/entry.S 文件的这一行来进行验证。

问题1

根据前文描述,可以先设置断点在 0x0010|000C 处,这是kernel的entry point。然后一步步运行到 movl %eax %cr0 之前。查看运行它前后的内存地址 0x0010|00000xf010|0000 处存放的32-bit,4字节分别是啥。

Screenshot from 2023-04-24 23-36-50

可以发现一开始是不相等的,后面变成相等了。下面解释2

在实验指导中,也明确写着一旦 CR0_PG 被设置(Once CR0_PG is set),就会发生内存映射的行为,具体看原文档。

上面的指令可以看到 (new cr0) = (old cr0) or $0x80010001,最终得到最高位为1,查阅资料3可知最高位即为PG位。因此运行完 movl %eax %cr0 后,就开启了内存映射。

另外gdb在调试时访问的内存都是虚拟内存,因此 x/4xb 0xf010|0000 其实是访问物理内存 0x0010|0000,因此不奇怪二者的内容是一样的。

问题2

如果注释了这一句,那就没有开启内存映射,影响肯定是影响后面的内容,我们直接在上面调试的时候继续执行后面的几条语句如下:

Screenshot from 2023-04-24 23-48-31

可以发现后两条语句实现的功能是跳转到 0xf010002f 这个位置,由于没有内存映射。肯定是无法访问到这个地址空间的。如果真的注释了,也可以发现在 qemu 窗口能看到报错信息 qemu: fatal: Trying to execute code outside RAM or ROM at 0xf010002c

参考资料

  1. cnblog-fatsheep9146
  2. csdn-yiichan
  3. csdn-epluguo