You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

操作系统如何处理虚拟地址与物理地址?页表结构管理探究

关于Intel x86架构下操作系统分页与物理地址管理的解析

Great question—this cuts straight to the low-level memory management logic that every x86 OS has to handle, especially given Intel's all-or-nothing approach to enabling paging (via the PG bit in the CR0 register). Let's break down how this works, including the two scenarios you mentioned and real-world practices:

1. 禁用分页操作页表:仅适用于启动初期或极端场景

  • 早期系统启动阶段(刚进入32位保护模式,还未启用分页)是唯一安全的无分页操作窗口。此时,虚拟地址直接等同于物理地址,OS可以直接读写物理内存来构建初始页表结构——比如创建一个恒等映射(虚拟地址=物理地址)的页表,或者提前映射内核镜像到固定的虚拟高地址。
  • 一旦分页开启,几乎不会再全局关闭它。原因很简单:现代OS内核依赖虚拟地址空间的固定布局(比如Linux内核常驻虚拟地址的高半区),关闭分页后这些虚拟地址会直接指向物理内存的对应位置,而内核代码、数据根本不在那里,系统会立即崩溃。只有极少数调试或特殊恢复场景会这么做,生产环境完全避免。

2. 分页开启状态下管理页表:主流生产级做法

这是所有成熟OS的标准操作方式,核心依赖内核虚拟地址空间的物理内存直接映射能力:

  • 内核会预留一块虚拟地址范围,将其恒等映射到物理内存(或者通过固定偏移映射,比如Linux中phys_to_virt宏)。这样,即使分页开启,内核也能通过这些虚拟地址直接访问任意物理页框——包括页表本身所在的物理页。
  • 举个具体流程:当OS需要为进程分配新的页表时:
    • 先从物理内存中分配一个空闲页框;
    • 通过内核的物理映射虚拟地址,直接向这个页框写入页表项(设置物理地址、权限位、缓存属性等);
    • 将该页框的物理地址写入上级页表(比如页目录项PDE);
    • 最后执行invlpg指令刷新单个TLB条目,或者切换CR3寄存器刷新整个TLB,确保CPU加载新的页表内容。
  • 整个过程完全在分页开启状态下完成,不需要中断系统运行,也不会破坏内核的虚拟地址上下文。

补充:启动阶段的分页过渡流程

大多数x86 OS的启动流程是这样的:

实模式 → 进入32位保护模式 → 构建临时恒等映射页表 → 开启分页 → 切换到最终内核虚拟地址布局(修改页表并刷新TLB) → 初始化内核服务

从开启分页后,就再也不会回到无分页状态了——所有后续的页表维护、物理内存管理都通过内核的物理映射虚拟地址完成。

内容的提问来源于stack exchange,提问作者Kay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:32:25