news 2026/8/27 19:45:54

phys_pud_init、phys_pmd_init、phys_pte_init

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
phys_pud_init、phys_pmd_init、phys_pte_init

phys_pud_init

phys_pud_init是 x86 架构 Linux 内核中,负责在 PUD(Page Upper Directory,页上级目录)层级填充页表项的核心函数,其实现原理是一套精密的内存映射“流水线”。

它的工作,可以看作是在__kernel_physical_mapping_init的统筹下,作为“分包商”承接并处理一个具体的物理地址区间,为其建立或更新内存映射。

核心实现逻辑:分层填充

该函数从虚拟地址的角度出发,遍历指定 PUD 页表中的每一个条目,为每一个需要映射的物理地址范围选择最高效的方式建立映射。

关键设计演进与细节

  1. 引入init参数phys_pud_init新增了init参数,用于在启动早期内存热插拔等运行时场景之间进行区分。这允许内核在修改页表时,根据场景选择不同的同步策略,例如避免在启动初期进行耗时操作或改变锁的使用方式。

  2. 1GB 大页拆分时的 Bug 修复:当函数需要将一个已存在的 1GB 大页拆分为 2MB 小页时,会触发一个警告。原因是拆分前未清除旧的 PUD 条目,而后续的set_pud_safe()函数会检测到冲突并报出WARN_ON_ONCE。修复方法是在拆分前增加pud_clear(pud)调用,清除旧的大页映射条目,使新的 PMD 页表能顺利链接。

  3. KASLR 支持:在内核地址空间随机化(KASLR)引入时,phys_pud_init曾被修正。由于 KASLR 使得PAGE_OFFSET不再是 PUD 对齐的,原先直接对物理地址使用pud_index的逻辑会失效。修正方法是在计算 PUD 索引前,先将物理地址通过__va转换为虚拟地址,以确保pud_index总能得到正确的结果。

异常处理与内存空洞

函数内部还会检查区间内是否存在内存空洞(非 RAM 区域)。若检测到,它会清除对应的 PUD 条目,保证映射的精确性,防止内核访问到不应映射的物理地址。

phys_pmd_init

phys_pmd_init是 x86 架构 Linux 内核在启动阶段,负责在PMD(页中间目录)层级建立物理内存直接映射的核心函数。它的作用可以看作是前序phys_pud_init工作的“分包商”,专门处理一个具体的物理地址区间,并决策使用2MB 大页还是4KB 标准页来完成映射,以平衡性能与内存效率。

核心实现逻辑:PMD 层级的映射决策

phys_pmd_init的实现原理是一个高度结构化的遍历过程。它在给定的 PMD 页表中,从当前物理地址paddr对应的条目开始,逐项处理,直到超出目标区间paddr_end

其核心决策树如下:

  1. 遍历与边界检查:函数遍历 PMD 页表。如果当前地址paddr已经达到或超过终点paddr_end,则停止映射,并清除该条目(set_pmd_init(pmd, __pmd(0), init))。一个早期的补丁确保了这项清理操作只在after_bootmem之前执行,避免破坏已建立的映射。

  2. 处理已存在的映射:如果 PMD 条目已经存在(!pmd_none(*pmd)):

    • 若已是大页:检查page_size_mask。如果允许 2MB 大页,则直接复用该映射,统计页面数量并继续。

    • 若不是大页:意味着这是更精细的 4KB 页表。此时会调用phys_pte_init递归处理下一级 PTE,以处理已有映射。

  3. 建立新映射:对于空的 PMD 条目,根据条件选择映射方式:

    • 使用 2MB 大页映射:如果地址按 2MB 对齐且page_size_mask允许,则设置 PMD 条目为 2MB 大页映射。注:该条目不经过 PTE,直接指向物理内存。

    • 降级为 4KB 小页映射:如果条件不满足(例如地址不对齐,或调试配置禁用大页),则调用alloc_low_page分配一个 PTE 页表,然后调用phys_pte_init填充该表,最后将 PMD 条目指向这个新分配的 PTE 页表。

关键特性与演进

  • init参数init参数用于区分启动早期内存热插拔等运行时场景,允许在不同场景下采取不同的同步或策略行为。例如,在热插拔场景下,可能不需要像启动时那样强制清除越界的 PMD 条目。

  • TLB 一致性保证:当需要将一个已有的 2MB 大页拆分为 4KB 小页时,为了避免违反 Intel 的 TLB 应用规范(即改变页面大小时,新旧转换在页框和属性上不能有差异),代码会使用新页面的保护属性,并继承原大页的保护位。

phys_pmd_init通过这套决策机制,将上层(PUD)传递下来的、粒度更粗的映射请求(1GB 或 2MB),在 PMD 层级进一步细化为更精确的 2MB 大页或 4KB 小页映射,是构建高效、精确的内核直接映射的关键一环。

phys_pte_init

phys_pte_init是 x86 内核启动过程中,负责在PTE(页表项)层级建立物理内存直接映射的最终执行者。它处理的是最细粒度的4KB 标准页的映射,是整个页表填充流水线的最后一环。

实现原理

phys_pte_init的实现原理是一个简单的遍历和填充过程。它接收一个 PTE 页表(pte_page),将其覆盖的物理地址区间[paddr, paddr_end)内的每一个页表项逐个映射到对应的物理页。

关键设计细节

  • 返回值的一致性phys_pte_init返回的paddr_last表示已映射的最后一个物理地址。这个返回值被上层函数用于追踪映射进度。一个重要的补丁修正了该函数返回值的一致性:在遇到已存在映射时,它也会更新paddr_last,使其行为与上层phys_*_init函数保持一致。这确保了在混合使用新映射和复用已有映射时,kernel_physical_mapping_init能够获得正确的进度信息。

  • 对已有映射的处理:当函数发现某个 PTE 条目已经被映射时,它会选择复用该条目,而不是覆盖或重建。代码注释提到,Xen 虚拟化环境对此有特殊要求,例如可能需要特殊的映射属性。

  • 页表计数:函数在映射完成后会调用update_page_count(PG_LEVEL_4K, pages)更新内核维护的 4KB 页表项计数,便于后续统计和调试。

phys_pte_init作为页面映射流水线的最后一级,通过逐个填充 PTE 条目,完成了从物理地址到虚拟地址的 4KB 粒度映射,是内核直接映射区的基石。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/27 19:44:04

NVIDIA GPU环境搭建与排错实战:驱动、CUDA、Docker和NIM

消息称 NVIDIA 考虑向 Perplexity AI 投资“数十亿美元”:AI 算力生态背后,开发者真正该关注什么? 这两天科技圈最热的消息之一,就是 NVIDIA 考虑向 Perplexity AI 投资“数十亿美元”。虽然投资金额、估值细节还没有官方统一口径…

作者头像 李华
网站建设 2026/8/27 19:43:24

数字电源赋能LED驱动:从PFC到LLC的效率革命

1. 从标题到项目全貌:一张“数字化电源”背后的LED能效路线图 我先说一句大实话:看到这个标题的人,很容易被“Infineon”这个名字吸引,但真正值钱的其实是“Digitizes power”这三个词。做LED驱动电源的朋友都知道,这几…

作者头像 李华
网站建设 2026/8/27 19:42:12

响应渲染 render(render/ 包)

render 包负责把 Go 对象序列化到 HTTP 响应。和 binding 对称,这里也是接口 多实现的设计。1.1 Render 接口源码位置:render/render.go:9-15// Render interface is to be implemented by JSON, XML, HTML, YAML and so on. type Render interface {// Render writes data wi…

作者头像 李华
网站建设 2026/8/27 19:36:05

Open-Spec i.MX6 UL DAQ板卡:从硬件选型到Linux驱动实战指南

这块板子我盯了一段时间,看到"Open-Spec、i.MX6 UL、DAQ、Wireless"这几个关键词凑在一起,第一反应是:这玩意儿的目标用户太明确了。就是给那些受够了封闭式数据采集方案、又不想在x86工控机上浪费功耗和成本的嵌入式工程师准备的。…

作者头像 李华
网站建设 2026/8/27 19:35:36

AI服务器内存优化实战:从显存估算到系统排查

最近,AI服务器被曝涨价超过15%的话题在开发圈里讨论得不少。很多人第一反应是GPU太贵,但真正让整机成本跳涨的,还有内存和显存。对于做AI平台、大模型推理或者基础设施建设的人来说,与其被动接受涨价,不如把内存优化能…

作者头像 李华
网站建设 2026/8/27 19:35:28

跨境ETF套利策略实战:从均值回复原理到Python回测全解析

1. 项目概述:从一道赛题到一套实战策略 去年年底,我带着团队几个小伙伴一起参加了大湾区杯数学建模竞赛。拿到题目的时候,A题“跨境ETF套利策略设计”一下子就把我们吸引住了。这玩意儿听起来高大上,什么“跨境”、“套利”&#…

作者头像 李华