ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

init_top_pgt

init_top_pgt NEXT_PGD_PAGE(init_top_pgt) /* L4 -- pgt */.fill 512,8,0.fill PTI_USER_PGD_FILL,8,0 /* 512 */这段代码是 Linux 内核启动时定义和初始化另一个关键顶层页表init_top_pgt的核心部分它位于arch/x86/kernel/head_64.S文件中。init_top_pgt与之前定义的early_top_pgt在功能上有所区别但它们的定义方式非常相似都使用了NEXT_PGD_PAGE宏并预留了用于 PTI页表隔离的空间。代码逐段解析NEXT_PGD_PAGE(init_top_pgt)这个宏将init_top_pgt对齐到2 个页8192 字节的边界并声明为一个全局可见的符号。数据填充指令.fill 512,8,0填充 512 个 8 字节的条目初始化为 0。这构成了init_top_pgt页表的主体部分共占用一个页。.fill PTI_USER_PGD_FILL,8,0再次填充PTI_USER_PGD_FILL个 8 字节条目初始化为 0。PTI_USER_PGD_FILL通常也是一个常量这确保了整个init_top_pgt页表正好占用2 个页的大小。init_top_pgt与early_top_pgt的区别尽管定义方式相同但这两个页表在启动流程中扮演着不同的角色其区别主要体现在使用时机和目的上特性early_top_pgtinit_top_pgt使用阶段用于启动非常早期在__startup_64()之前被使用。在__startup_64()执行过程中被设置并在之后被启用。主要目的提供临时的恒等映射identity mapping确保内核在开启分页后能立即运行。作为正式的初始化页表包含内核最终运行所需的完整映射。内容初始时全零由__startup_64()填充。初始时全零同样由__startup_64()填充但基于early_top_pgt构建。简单来说early_top_pgt是一个临时的“跳板”而init_top_pgt是最终的“桥梁”。__startup_64()函数会先修正并启用early_top_pgt然后在其基础上构建出init_top_pgt最后将%cr3切换为init_top_pgt的地址完成从临时页表到正式页表的过渡。这种设计保证了启动过程从物理地址空间到虚拟地址空间的安全、平滑切换。init_top_pgt用处init_top_pgt是 Linux 内核在 x86_64 架构启动过程中最终稳定运行的“官方”内核页表在系统完成初始化后成为全局的swapper_pg_dir是所有进程页表的蓝本。它替代了在启动早期为满足特殊需求而使用的临时页表early_top_pgt。init_top_pgt作为内核页表的根其声明位于arch/x86/include/asm/pgtable_64.h而定义和初始化则在arch/x86/kernel/head_64.S中完成。在最终的链接脚本中它被赋予了全局页表的身份#define swapper_pg_dir init_top_pgt对比 early_top_pgt这两个页表在启动流程中扮演着不同阶段的关键角色。下表整理了它们的核心区别特征early_top_pgtinit_top_pgt使用阶段极早期启动开启分页的瞬间内核初始化早期被正式使用核心映射包含恒等映射 (identity mapping)和内核映射主要包含内核映射不包含完整的恒等映射主要用途使 CPU 开启分页后能立刻继续运行作为内核的永久页表管理所有内存这个过程的关键在于BSP引导处理器在启动时会先使用包含恒等映射的early_top_pgt以确保CPU在开启分页的瞬间其执行的指令地址物理地址与虚拟地址一致从而不发生错误。完成这个过渡后系统才切换并最终依赖于init_top_pgt。init_top_pgt的核心用途一旦系统完成从临时页表的切换init_top_pgt就承担起内核内存管理的核心职责提供内核空间的稳定映射它负责将内核自身的代码段、数据段以及所有内核管理的物理内存映射到内核的虚拟地址空间中。例如当内核初始化espfix机制时会直接修改init_top_pgt中的条目来建立所需的映射。作为所有进程页表的模板作为swapper_pg_dirinit_top_pgt是所有用户空间进程页表的内核部分即内核空间的模板。当创建新进程时其页表的内核部分会直接复制自init_top_pgt从而确保所有进程都能正确访问内核空间。参与关键特性的初始化KASAN等内存调试工具在初始化其早期影子内存映射时也会直接操作init_top_pgt的条目。init_top_pgt的意义在于让系统从“为了启动而临时搭建”的状态过渡到“拥有一个全局、统一、面向整个生命周期”的内存映射视图它为后续所有内存管理操作奠定了基础。
返回列表