2020/07/24
继续完成lab3
问题一:在 os/src/entry.asm
中,boot_page_table
的意义是什么?当跳转执行 rust_main
时,不考虑缓存,硬件通过哪些地址找到了 rust_main
的第一条指令?
boot_page_table
是一个用二进制表示的根页表,其中包含两个 1GB 大页,分别是将虚拟地址 0x8000_0000
至 0xc000_0000
映射到物理地址 0x8000_0000
至 0xc000_0000
,以及将虚拟地址 0xffff_ffff_8000_0000
至 0xffff_ffff_c000_0000
映射到物理地址 0x8000_0000
至 0xc000_0000
。
由于我们在 linker.ld
中指定了起始地址为 0xffff_ffff_8020_0000
,操作系统执行文件会认为所有的符号都是在这个高地址上的。但是我们在硬件上只能将内核加载到 0x8020_0000
开始的内存空间上,此时的 pc
也会调转到这里。
为了让程序能够正确跳转至高地址的 rust_main
,我们需要在 entry.asm
中先应用内核重映射,即将高地址映射到低地址。但我们不可能在替换页表的同时修改 pc
,此时 pc
仍然处于低地址。所以,页表中的另一项(低地址的恒等映射)则保证程序替换页表后的短暂时间内,pc
仍然可以顺着低地址去执行内存中的指令。
这是一个二级页表结构,mapped_pairs本身也需要占用多个页,page_tables中记录了它的映射,而mapped_pairs中则记录了进程空间的映射。
建立映射不需要访问B,只需要修改页表内容即可。一定要访问B的话,也可以通过内核映像的线性偏移来访问。
由于还没有lab3分支,只能滞后做。