lab1提到bootloader的c文件最后会加载内核到物理地址0x10000处(64K)处,然后再执行内核的入口entry.S函数。
这里要特别注意:在此之前,所有的都是直接操作物理地址(怎么做到的?实时模式就不用说了,16位寻址1MB, 进入保护模式后,32位,bootloader把所有段寄存器设成0,除了esp,这个必须设置到正确的物理地址。 而且分页机制也没有使能,所以线性地址就是物理地址)。
在编译image时,kernel.ld会将内核的c代码的(entry.S仍在物理地址空间执行)起始地址链接到0xF0100000,也就是当内核执行c代码main时, 所有的指令的寻址都是以这个为基础,但是内核的实际物理地址是在0x100000,所以进入内核后第一件事就是要建立一个映射: 将起始地址为0xF0100000映射到物理地址0x100000(为以后的c代码执行准备好)。
内核入口函数entry.S中(仍在物理地址空间0x100000执行),一开始就是做这件事,使能分页机制(设置CR0):
# Load the physical address of entry_pgdir into cr3. entry_pgdir
# is defined in entrypgdir.c …