内核页表如何初始化?

时间:2011-10-18 21:52:16

标签: linux memory-management kernel

我正在关注戈尔曼的虚拟内存管理书。

有一个关于内核表页面初始化的部分,据说分为两个阶段,自举和最终确定。

以下是有关自举阶段的内容。

  

汇编程序函数startup_32()负责启用分页单元   弓/ I386 /内核/ head.S中。虽然编译了 vmlinuz 中的所有正常内核代码   使用PAGE_OFFSET + 1MiB的基址,实际加载内核   在第一兆字节(0x00100000)的内存。使用第一兆字节   通过一些设备与BIOS通信并被跳过。 引导程序   此文件中的代码通过从中减去__PAGE_OFFSET将1MiB视为其基址   任何地址,直到寻呼单元被启用。因此在寻呼单元之前   启用后,必须建立一个页表映射,以转换 8MiB   物理内存到虚拟地址PAGE_OFFSET。

  1. 为什么我们要减去__PAGE_OFFEST?出于什么目的?

  2. 为什么我们必须在启用寻呼单元之前进行减法?是不是我们总是使用减法来将内核虚拟地址映射到物理内存地址?

  3. 为什么是8MB?

  4. 谢谢,

1 个答案:

答案 0 :(得分:3)

由于x86代码通常与位置无关,如果它被编译为在地址X(__PAGE_OFFSET + 1MB)执行但在地址Y(1MB)处加载,则其内部的所有地址都需要递减YX(__PAGE_OFFSET +它可以工作1MB - 1MB = __PAGE_OFFSET。

例如,如果有一条指令从内核开始读取一个字节的内存,__PAGE_OFFSET + 1MB,则地址减少__PAGE_OFFSET,实际读取位置变为1MB,正好是内核在内存中启动的位置。

当最终启用页面转换时,__PAGE_OFFSET可以并且我相信,通过将一系列虚拟地址映射到一个较小的__PAGE_OFFSET物理地址范围(即,physical = virtual),页面转换机制可以有效地减去__PAGE_OFFSET -__ PAGE_OFFSET每页表格。)

除非涉及一些额外的内核重定位,否则8MB可能只是映射范围的大小,足以映射整个内核。