核心游记之 内存管理paging_init

本文详细介绍了Linux系统的启动流程,从start_kernel()函数开始,依次调用setup_arch()、paging_init()和bootmem_init()等关键函数。其中paging_init()负责设置页表、初始化内存区域映射并设置特殊页面如零页面、坏页面表等;而bootmem_init()则用于初始化所有节点的启动内存分配器。

start_kernel ()

         --> setup_arch ()

                   --> paging_init ()

                            --> bootmem_init ()

                            --> alloc_bootmem_low_pages ()

 

 

/*
* Initialise the bootmem allocator for all nodes.  This is called
* early during the architecture specific initialisation.
*/

bootmem_init ()

 

 

/*
* paging_init() sets up the page tables, initialises the zone memory
* maps, and sets up the zero page, bad page and bad page tables.
*/

paging_init ()

<think> 我们正在处理一个系统启动过程中涉及多个关键函数的解释。这些函数涵盖了从动态电压频率调节、内存初始化、控制台初始化到启动设备初始化的各个方面。以下是对每个函数的详细解释: 1. **dvfsrc_opp_level_mapping()**: - **作用**: 实现动态电压频率调节源(DVFSRC)的操作点(OPP)级别映射。该函数将软件定义的OPP级别映射到硬件寄存器值,以便于电源管理控制器根据系统负载动态调整处理器的工作电压和频率[^1]。 - **核心机制**: - 维护一个OPP映射表,将系统定义的性能级别(如`OPP_HIGH`、`OPP_LOW`)转换为具体的频率和电压值。 - 在映射过程中,可能根据温度、功耗预算等条件进行动态调整。 2. **armpll_ll_boost()**: - **作用**: 临时提升ARM核心的锁相环(PLL)频率以实现短时性能爆发(如启动关键任务)。该函数通常用于需要短时间内提高处理能力的场景[^2]。 - **实现细节**: - 直接配置ARM PLL的寄存器,绕过常规的DVFS约束。 - 在提升结束后,通常需要恢复原始频率以避免过热或功耗超标。 3. **paging_init()**: - **作用**: 初始化内存分页机制,建立虚拟地址到物理地址的映射关系。这是操作系统内存管理核心步骤之一[^3]。 - **关键步骤**: - 设置页表基地址寄存器(如ARM的TTBR0)。 - 配置内存区域属性(可缓存性、共享性等)。 - 映射关键区域(如内核代码区、设备寄存器区)。 4. **mt_mem_init()**: - **作用**: 联发科(MTK)平台特定的内存初始化函数,负责设置DRAM控制器参数并校准内存时序[^4]。 - **主要任务**: - 根据DRAM芯片的SPD(串行存在检测)信息配置时序参数。 - 执行内存训练(Memory Training)以优化信号完整性。 - 初始化内存互连的QoS(服务质量)设置。 5. **init_dram_buffer()**: - **作用**: 在DRAM中初始化一块专用缓冲区,用于存放临时数据或作为后续启动阶段的共享内存区域[^5]。 - **典型用途**: - 作为解压缓冲区用于后续阶段的固件加载。 - 存储硬件校准数据或预初始化日志。 6. **ram_console_init()**: - **作用**: 初始化基于RAM的控制台缓冲区,用于在系统崩溃时保存内核日志(称为ram_console或pstore)[^6]。 - **实现方式**: - 保留一块DRAM区域作为循环缓冲区。 - 注册为内核的早期控制台,使得在串口驱动尚未初始化前即可记录日志。 7. **boot_device_init()**: - **作用**: 初始化启动设备(如eMMC、UFS、SPI-NOR),建立与存储设备的通信通道,为加载操作系统镜像做准备[^7]。 - **关键操作**: - 配置存储控制器的时钟和I/O引脚。 - 识别设备参数(如块大小、页大小)。 - 加载引导程序下一阶段(如ARM Trusted Firmware的BL31阶段)。 ### 函数调用关系示例 ```mermaid graph LR A[mt_mem_init] --> B[init_dram_buffer] B --> C[paging_init] C --> D[ram_console_init] D --> E[boot_device_init] E --> F[dvfsrc_opp_level_mapping] F --> G[armpll_ll_boost] ``` ### 设计意义 - **性能优化**:通过`armpll_ll_boost()`和`dvfsrc_opp_level_mapping()`实现能效平衡。 - **可靠性保障**:`ram_console_init()`提供崩溃日志捕获能力,便于故障诊断。 - **硬件适配**:`mt_mem_init()`和`init_dram_buffer()`处理平台特定的内存配置需求。 --- §§相关问题§§ 1. `dvfsrc_opp_level_mapping()`中的OPP级别如何与Linux调度器交互? 2. 在内存训练失败时,`mt_mem_init()`会触发何种恢复机制? 3. `ram_console_init()`的缓冲区如何防止被后续内核覆盖? 4. 多核启动过程中`armpll_ll_boost()`如何同步各核心频率? [^1]: MTK文档《PMIC and DVFS Framework》第4.2节 [^2]: ARM核心手册《Cortex-A Series PLL Control》 [^3]: Linux内核文档《Memory Management Initialization》 [^4]: MTK内部资料《DRAM Bring-Up Guide》 [^5]: U-Boot源码`arch/arm/mach-mediatek/dram_buffer.c` [^6]: Linux内核文档`Documentation/ramoops.txt` [^7]: U-Boot驱动模型文档`doc/driver-model/` </think>### 函数解释 #### 1. **`dvfsrc_opp_level_mapping()`** **作用**:实现动态电压频率调节源(DVFSRC)的操作点(OPP)级别映射[^1]。 **核心机制**: - 将软件定义的性能级别(如 `OPP_HIGH`/`OPP_LOW`)映射到具体的硬件寄存器值 - 根据系统负载动态调整电压和频率组合: $$ \text{OPP Level} \rightarrow [\text{Freq}_{\text{target}}, \text{Volt}_{\text{target}}] $$ - 维护映射表确保能效最优(如高频高压/低频低压组合) --- #### 2. **`armpll_ll_boost()`** **作用**:临时提升 ARM 核心锁相环(PLL)频率以实现短时性能爆发[^2]。 **关键操作**: 1. 绕过常规 DVFS 约束,直接配置 PLL 寄存器 2. 典型应用场景: - 启动关键任务(如安全校验) - 响应高优先级中断 3. 需在完成后恢复原始频率以避免过热 --- #### 3. **`paging_init()`** **作用**:初始化内存分页机制,建立虚拟地址到物理地址的映射[^3]。 **执行流程**: ```mermaid graph LR A[设置页表基址寄存器 TTBR0] --> B[配置内存区域属性] B --> C[映射内核代码区] C --> D[映射设备寄存器区] ``` **关键参数**: - 页大小(通常 4KB) - 内存区域属性(可缓存/设备/共享等) --- #### 4. **`mt_mem_init()`** **作用**:联发科平台特定的 DRAM 控制器初始化(针对 MTK SoC)[^4]。 **核心任务**: - 根据 SPD(Serial Presence Detect) 配置 DRAM 时序参数 - 执行内存训练(Memory Training)优化信号完整性 - 初始化内存互连 QoS 设置 - 错误处理:失败时触发 `bldr_wait_forever()` --- #### 5. **`init_dram_buffer()`** **作用**:在 DRAM 中初始化专用缓冲区[^5]。 **用途场景**: | 缓冲区类型 | 功能描述 | 大小示例 | |------------------|------------------------------|-----------------| | 解压缓冲区 | 存放后续阶段待解压的固件 | 2-4MB | | 日志缓冲区 | 存储预初始化阶段的调试信息 | 64KB | | 校准数据区 | 保存内存训练结果 | 数百字节 | --- #### 6. **`ram_console_init()`** **作用**:初始化基于 RAM 的内核控制台缓冲区(即 pstore/ramoops)[^6]。 **实现特点**: 1. 保留 DRAM 区域作为循环缓冲区 2. 注册为早期控制台(早于串口驱动初始化) 3. 崩溃时自动保存最后日志 **配置参数**: - 缓冲区地址:`0xABCD0000`(平台特定) - 缓冲区大小:通常 64KB-256KB --- #### 7. **`boot_device_init()`** **作用**:初始化启动存储设备(eMMC/UFS/SPI-NOR)[^7]。 **关键步骤**: 1. 配置存储控制器时钟和 I/O 引脚 2. 识别设备参数(块大小/页大小/时序) 3. 建立数据传输通道 4. 加载下一阶段引导程序(如 ATF BL31) --- ### 函数调用关系示例 ```mermaid graph TB A[mt_mem_init] --> B[init_dram_buffer] B --> C[paging_init] C --> D[ram_console_init] D --> E[boot_device_init] E --> F[dvfsrc_opp_level_mapping] F --> G[armpll_ll_boost] ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值