尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
early_alloc_pgt_buf
early_alloc_pgt_buf()是 Linux 内核启动早期在setup_arch()中被调用的一个关键函数。它的核心作用非常直接为内核初始化阶段建立直接内存映射direct mapping所需的早期页表分配一个临时的内存池buffer。页表内存池的来源BRK 区域这个页表内存池的物理内存来自内核的BRKBreak区域。你可以把BRK区域理解为内核启动早期的一段动态内存空间。预留空间代码通过RESERVE_BRK(early_pgt_alloc, INIT_PGT_BUF_SIZE)宏在链接脚本定义的 BRK 区域中为页表池预留了一块空间。这个预留的大小由INIT_PGT_BUF_SIZE定义在不同版本的内核中其值有所调整例如曾经从5 * PAGE_SIZE增加到12 * PAGE_SIZE以满足更复杂的映射需求。分配与初始化early_alloc_pgt_buf()函数通过调用extend_brk()从刚才预留的 BRK 区域中“切出”所需的内存并将其地址转换为物理地址用来初始化几个关键的全局变量pgt_buf_start页表池的起始物理页号PFN。pgt_buf_end当前已使用的页表池尾部的物理页号初始时与pgt_buf_start相同表示尚未使用。pgt_buf_top页表池的结束物理页号即内存池的边界。角色与运作一个临时的“内存批发商”early_alloc_pgt_buf()初始化完成后内核就拥有了一个暂时的“页表批发商”其运作方式如下优先使用 BRK 池在初始化init_mem_mapping()等需要建立内核页表的过程中分配页表例如通过alloc_low_pages()函数会优先从这个 BRK 内存池中获取空间。一个典型的注释提到“step_size need to be small so pgt_buf from BRK could cover it”步进值需要足够小以便 BRK 中的 pgt_buf 能够覆盖它说明初期映射的粒度会受限于这个池的大小。耗尽可能后启用后备方案这个初始内存池的大小是有限的。当pgt_buf_end触及pgt_buf_top即池子被用完后内核后续若还需要分配新页表就会转而使用更通用的memblock分配器来获取内存。这确保了页表映射工作能够持续进行。特殊的“免重叠”保护代码中有一个名为can_use_brk_pgt的标志其设计初衷是为了避免用 BRK 池中的页表去映射它自身所在的内存区域以防止可能出现的 MMU 问题。不过也有讨论认为这种担心在当前实现下可能已不再必要。early_alloc_pgt_buf()函数的代码实现非常简洁其核心逻辑是在 Linux 内核启动早期从内核的 BRK 区域分配一块连续内存作为构建初始页表的内存池。这个分配动作是一次性的并有相应的防重复机制。代码位置与数据结构该函数定义在arch/x86/mm/init.c文件中其实现依赖于三个关键的全局变量static unsigned long pgt_buf_start, pgt_buf_end, pgt_buf_top;pgt_buf_start记录页表内存池的起始页帧号 (PFN)。pgt_buf_end记录当前已使用的内存池末尾页帧号 (PFN)初始时与pgt_buf_start相等。pgt_buf_top记录内存池的结束页帧号 (PFN)即内存池的边界。代码实现演变该函数的定义在不同内核版本中有所变化主要区别在于池的大小和防重复逻辑。初始版本在最初引入该功能时代码相对简单RESERVE_BRK(early_pgt_alloc, 16384); void __init early_alloc_pgt_buf(void) { unsigned long tables 16384; phys_addr_t base; base __pa(extend_brk(tables, PAGE_SIZE)); pgt_buf_start base PAGE_SHIFT; pgt_buf_end pgt_buf_start; pgt_buf_top pgt_buf_start (tables PAGE_SHIFT); }内存池大小固定此处通过RESERVE_BRK在 BRK 区域预占了 16KB即 4 个页面的空间。通过extend_brk分配extend_brk(tables, PAGE_SIZE)从预留的 BRK 区域中“切出”所需内存并返回其虚拟地址。转换为物理地址__pa()负责将此虚拟地址转换为物理地址base。计算页帧号将物理地址base除以页大小PAGE_SHIFT得到起始页帧号并相应计算出结束页帧号pgt_buf_top。演进版本随后的补丁对该函数进行了完善主要是增加了缓冲区大小和防重复调用的保护。/* need 4 4k for initial PMD_SIZE, 4k for 0-ISA_END_ADDRESS, 4 4k for kernel */ #define INIT_PGT_BUF_SIZE (9 * PAGE_SIZE) RESERVE_BRK(early_pgt_alloc, INIT_PGT_BUF_SIZE); void __init early_alloc_pgt_buf(void) { unsigned long tables INIT_PGT_BUF_SIZE; phys_addr_t base; /* already set ? */ if (pgt_buf_end) return; base __pa(extend_brk(tables, PAGE_SIZE)); pgt_buf_start base PAGE_SHIFT; pgt_buf_end pgt_buf_start; pgt_buf_top pgt_buf_start (tables PAGE_SHIFT); }INIT_PGT_BUF_SIZE宏为了满足更复杂的早期内存映射需求如内核本身的映射池的大小从最初的 16KB 增加到了9 个页面。历史补丁记录显示这个值是根据需求动态调整的例如在特定配置下从 5 个页面增加到 6 个页面。防重复调用检查添加了if (pgt_buf_end) return;判断。如果pgt_buf_end非零说明缓冲池已被分配函数会直接返回避免了重复分配导致的内存浪费或指针异常。函数的作用与背景early_alloc_pgt_buf()创建的内存池为紧接着执行的init_mem_mapping()函数提供了构建初始页表所需的内存。init_mem_mapping()会调用alloc_low_pages()来分配页表页而该分配器会优先从这个 BRK 内存池中获取空间。一个相关的注释提到“step_size need to be small so pgt_buf from BRK could cover it”说明了早期映射的粒度step_size会受到这个池子大小的制约以确保初期映射能在这个有限的缓冲区中完成。它的代码实现十分精巧通过RESERVE_BRK预先在链接脚本层面“圈地”再通过extend_brk在运行时“挂牌”最终为内核页表搭建了一个早期、临时的“工作台”。
RELATED

相关推荐

番茄钟真正难的不是倒计时:启动、暂停、重置与页面销毁

番茄钟真正难的不是倒计时:启动、暂停、重置与页面销毁

番茄钟的界面只有一个大数字,但真正需要控制的是计时器生命周期。开始后每秒递减,暂停时必须停住,切换时长要重置,页面离开后也不能让旧定时器继续在后台修改状态。 private roundById(id: number): FocusRecord | undefined {ret…

📅 2026/10/12 15:23:10
Supabase 实战指南:从登录、RLS 到 Storage 签名链接

Supabase 实战指南:从登录、RLS 到 Storage 签名链接

Supabase 实战指南:从登录、RLS 到 Storage 签名链接 本文不依赖特定的项目代码,侧重于梳理使用 Supabase 过程中通用的核心逻辑与踩坑记录。无论你是在做班级同学录、个人博客还是其他小应用,这些经验都值得参考。 本文源于作者一次制作同学…

📅 2026/10/11 1:29:01
Z型钢直销厂家排行榜新鲜出炉,这份榜单帮你避开选购陷阱

Z型钢直销厂家排行榜新鲜出炉,这份榜单帮你避开选购陷阱

近期,网络上各类“Z型钢直销厂家排行榜”层出不穷,为采购方提供了参考,但也因信息真伪难辨,让不少工程负责人挑花了眼。榜单看似直观,实则隐藏着商业推广逻辑与信息滞后风险。对于需要大宗采购或长期合作的单位而言&am…

📅 2026/9/21 0:56:50
MORE NEWS

更多资讯

📰

基于监督学习的Web入侵检测毕设源码:从数据到模型全流程解析

简介:这份资源是面向计算机相关专业学生与从业者的高分毕业设计源码包,主题为基于监督学习的Web入侵检测系统,采用Python实现,评审得分达97分,可直接用于毕业设计、期末课程设计或课程大作业等场景。压缩包共60个文件&…

📰

AI与脑能思维链:破解孩子学习难题的科学方法

1. 项目概述:当AI遇上育儿难题去年辅导小侄女数学作业时,我发现一个有趣现象:她总在相似题型上反复出错,但当我用游戏化的方式拆解问题后,她竟能举一反三。这让我意识到,传统"填鸭式"辅导就像给老…

📰

OpenAPI自动生成DeepSeek工具定义:告别手写50个函数

1. 从手写 50 个工具函数说起:这个项目到底在解决什么问题如果你最近在折腾大模型应用,尤其是想让模型调用外部 REST API 来完成实际任务,那你大概率经历过这样一个阶段:打开编辑器,新建一个tools.py,然后开…

📰

DeepSeek新手入门指南:从零基础到高效使用AI对话平台

简介:《DeepSeek从入门到精通》是一份面向希望借助AI助手提升生产效率的实用指南,不限于专业开发者或数据科学家,教育工作者与技术爱好者同样可将其作为参考。内容从账户注册、控制台操作等入门基础讲起,逐步过渡到提问优化、文档…

📰

DeepSeek提示词工程实战:四要素改造、模板化与稳定性验证

简介:面向职场人士、学生、创业者及技术爱好者的DeepSeek高阶提示词合集,围绕自然语言处理与自动化办公场景,帮助读者解决提问无思路、AI输出不稳定和工作流程提效难的问题。包内仅含1个docx文档,约46KB,按十大类别组织…

📰

SuperSplat:面向工业落地的轻量化高斯溅射三维重建框架

简介:本资源是一个基于 Node.js 的前端开发项目压缩包,面向 Web 开发初学者与中级工程师,聚焦于模块化构建与本地开发环境快速启动。项目以 supersplat 为核心命名,已预配置完整依赖与开发脚本,开发者仅需安装 Node.js…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬