【问题标题】:How kernel page table get initialized?内核页表如何初始化?
【发布时间】:2011-10-18 21:52:16
【问题描述】:

我正在关注 Gorman 的虚拟内存管理书。

有一节是关于内核表页初始化的,据说分为两个阶段,bootstrapping 和 finalizing。

这是关于引导阶段的内容。

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

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

  2. 为什么我们必须在启用分页单元之前进行减法?内核虚拟地址映射到物理内存地址不是一直都是用减法吗?

  3. 为什么是 8MB?

谢谢,

【问题讨论】:

    标签: linux memory-management kernel


    【解决方案1】:

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

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

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

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

    【讨论】:

    • 谢谢亚历克斯,这真的很有帮助
    猜你喜欢
    • 2011-09-07
    • 1970-01-01
    • 2016-01-30
    • 1970-01-01
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多