您的位置首页 >科技要闻 >

Linux 内核自身也在用分页机制,原理、页表与启动流程详解

很多人误以为分页只是给用户进程准备的,实际上 Linux 内核代码、内核数据同样跑在分页机制之上,内核拥有一套常驻的内核页表 swapper_pg_dir,不管当前 CPU 在执行内核态还是用户态,内存访问全部走 MMU 地址翻译;区别只是用户进程各自持有独立页表,切换任务时更换 CR3,而内核空间映射在所有进程页表里共享,内核依靠这套分级页表完成虚拟地址到物理页帧的转换,同时拿到内存保护、按需分配、大页映射、物理内存隔离这些能力,如果没有分页,高地址内核虚拟空间、高端内存映射、内存隔离都没法实现。早期启动阶段内核还没打开分页,只用恒等映射临时跑代码,一旦准备好初始页表,设置 CR0 的分页位之后,内核自己就进入虚拟地址世界,后续所有内核代码、内核栈、slab、vmalloc、直接映射区,全部由分页进行管理;如果内核不使用分页,就只能在有限物理地址空间裸跑,无法支持 64 位巨大地址空间,也没法使用大页降低 TLB 压力。整套流程从启动临时恒等映射开始,搭建 swapper_pg_dir,建立内核直接映射区、vmalloc 区域、固定映射区,之后每一次内核内存分配,都会填充或者修改页表项,缺页异常处理函数也同时服务内核侧与用户侧;内核页表同样支持大页,对内核代码段使用 2M、1G 大页,可以减少页表层级,降低 TLB miss,提升访问速度。就算内核使用共享内核映射,内核态访问内存依然会触发页故障、TLB 刷新,并不是绕过 MMU。

  • Linux 内核分页核心组件清单
  • swapper_pg_dir:内核主全局页目录,也就是内核基础页表,所有进程页表都会挂载这份内核映射
  • PGD / P4D / PUD / PMD / PTE:五级分级页表,现代 Linux 默认五级分页,硬件不支持时层级会折叠
  • PFN:页帧号,用来标记物理内存页,内核绝大部分内存管理逻辑基于 PFN 运转
  • 直接映射区:线性映射物理内存,虚拟地址减去固定偏移就能拿到物理地址
  • vmalloc 区域:用于非连续物理内存分配,依靠分页把零散物理页拼成连续虚拟地址
  • 固定映射区:少量需要精确虚拟地址的内核结构,比如 IO 寄存器映射
  • 用户进程页表与内核页表对比表
  • 内核开启分页的启动步骤
项目用户进程页表内核常驻分页(swapper_pg_dir)
归属每个进程一份,存放在 mm_struct全局唯一内核页目录,永久存在
切换进程切换更换 CR3,页表随之切换内核空间映射在全部页表共享
访问权限可执行、可读、可写,按页做保护内核页默认高权限,禁止用户态访问
缺页来源程序代码、堆、栈、文件映射vmalloc、设备映射、内核大页、缺页加载
大页支持支持透明巨页 THP支持内核内置大页,用于代码段、直接映射区
  1. 刚上电时 CPU 在实模式,没有分页,直接使用物理地址。
  2. 进入保护模式,搭建临时恒等映射,虚拟地址等于物理地址,用来准备初始页表。
  3. 初始化 swapper_pg_dir,填充直接映射区,把物理内存映射到内核虚拟地址空间。
  4. 将页目录基址写入 CR3,打开 CR0 的分页标记,MMU 正式启用分页翻译。
  5. 调用 start_kernel,继续初始化内存管理、slab、vmalloc、缺页异常处理。
  6. 创建第一个用户进程,复制内核侧共享映射,再单独填充用户私有页表。
  • 内核分页的四大作用
  • 地址空间扩展:依靠虚拟地址,突破物理内存限制,支持 64 位超大寻址空间。
  • 内存隔离保护:内核空间对用户态不可访问,防止用户程序篡改内核数据。
  • 非连续内存组装:vmalloc 使用分页,把分散的物理页拼成连续虚拟内存。
  • TLB 优化:使用内核大页,减少页表条目,降低 TLB 缺失带来的性能损耗。
  • 容易踩的认知误区
  • 误区一:内核跑在物理地址,不经过 MMU。只要分页打开,内核所有内存访问都走 MMU。
  • 误区二:切换进程的时候,内核页表会重建。内核映射是共享的,只切换用户侧部分。
  • 误区三:直接映射区就等于关闭分页。直接映射只是线性映射,依然是页表管理。
  • 误区四:内核不会触发缺页。vmalloc、按需加载、设备映射都可以触发内核缺页异常。

常见问题

问题 1:Linux 内核自身使用分页机制,内核的基础页表叫什么?

回答 1:Linux 内核自身使用分页机制,内核基础全局页目录名为 swapper_pg_dir,它保存内核空间的基础映射,每一个用户进程的页表都会复用这份内核映射。

问题 2:Linux 内核开启分页机制之后,直接映射区还属于分页管理吗?

回答 2:属于,Linux 内核开启分页机制之后,直接映射区只是虚拟地址和物理地址保持固定偏移,底层依然由分级页表管理,并不是绕过分页。

问题 3:Linux 内核自身使用分页机制,切换进程时内核映射会跟着更换吗?

回答 3:不会,Linux 内核自身使用分页机制,内核空间映射在所有进程页表里共享;进程切换只会更换用户私有映射,内核部分保持不变。

问题 4:Linux 内核自身使用分页机制,能不能在内核侧使用大页优化性能?

回答 4:可以,Linux 内核自身使用分页机制,内核代码段、直接映射区都可以配置大页,减少页表项数量,降低 TLB 缺失,加快内核内存访问。

参考资料

[2026-10-11](Linux 五级分页与 swapper_pg_dir 详解)内核之旅

[2026-09-22](Linux 页表官方文档)The Linux Kernel Archives

[2026-08-05](x86 内核启动与分页开启流程)LWN.net

[2026-06-18](Linux 内核虚拟内存与分页原理)21ic 电子网

免责声明

本文全部内容来自 Linux 官方内核文档、开源内核资料与技术社区解读,仅作为 Linux 分页机制学习参考;不同架构、内核版本分页层级、内存布局存在差异,x86、ARM、RISC-V 的页表流程不完全一致;如果用于驱动开发、内核调试,请以对应版本内核源码以及官方文档为准。

今日大家都在搜的词: