ARM-Linux (临时,正式) 建立页表的比较【转】

 

很久没有写博客了,由于之前的写关于OMAP3530文章还没有整理。再加上一直在找工作,找到工作后又投入到另外的平台去工作。始终在忙忙碌碌,但是对于代码确实渐渐疏远。

在做项目的时候要使用DDR3分配内存,不经意间使用要和MMU以及TLB打交道。因此特地写下这篇文章以备后用。(工作就是在和遗忘作斗争)!

 

Linux在启动之初会建立临时页表,但是在start_kerne函数中setup_arch又会建立正真的页表和页目录。那么两套方案是如何过渡的?假如在MMU开启的时候把之前的临时页表给覆盖了或者修改了,会不会影响后续的启动过程?带着这些问题分析一下。

 


首先来看一下基于ARM的页表管理和MMU的行为分析:

 

Arm上的linux(正式)页表采用的是一级粗页表结合二级小页表实现4G空间的访问。如上图说明。

 

一级表 (1024 Entrys)

 

二级表 (1024 Entrys)

 

虚拟地址后12位Offset寻址空间是4096B 4k的空间

 

Arm上的linux(临时)页表采用的是段式页表,每一个entry可以映射1M的空间,结合后面的20bits位(寻址空间正好是1M)

 

一级表 (4096 Entrys)

 

虚拟地址的后20位offset寻址空间是1M


接着来看一下linux如何建立页表的过程。

 

Head.S中有一段使用汇编编写的初始化代码。Mmu.c中有一段使用c语言写的建立页表的代码。C语言的代码很经典,可能汇编更经典。这里不多分析了。可以百度文章很多分析。

 

关键问题在于一个变量swap_pgdir

 

1..macro    pgtbl, rd  

 

2.  

 

3.       ldr   \rd, =(KERNEL_RAM_PADDR - 0x4000)  

 

4.  

 

5..endm  

 

KERNEL_RAM_PADDR = 0 x XXXXXXXX这是内存的物理地址,那么页表的建立也在这物理地址相关的区域内。

 

临时页表使用的是段式映射,也称之为平坦映射。那么4G的空间划分为1M为单位的访问单元,需要4096个Entrys。应为Arm采用32位的数据线,因此每一个Entry占用一个32位的区段,也就是4B。

 

正式页表建立的过程分为二级映射也寻找index的过程。每次把线性地址划分为两段,每一段都作为索引根据TLB BASE的便宜寻找下一级的索引项。最后结合虚拟地址的最后偏移(10 bit)作为依据在4K的空间内寻址。

 

 

问题来了,这两种映射会不会应为后一种映射的建立把之前的映射破坏掉,导致linux一个复杂的寻址系统无法正常工作呢?答案肯定不会。

 

图示比文字描述来的直接,还是直接上两张图说明问题:

 

由上图可知:临时页表建立的空间和正式页表建立的空间分别部署于不同的空间,因此不会出现覆盖或者修改等现象。同时一二级页表项目录中的内容页值得研究。最后两位同时表现出来的控制逻辑,让MMU翻译地址的过程中有章可循。结合MMU中的AP位规定了访问空间的属性,是否可以访问拒绝访问等。

 

    最后希望图示可以帮助读者理解映射的意图。文中难免有些地方会引起歧义或者不足之初,希望linux大侠指正点评。










本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sky-heaven/p/5567478.html,如需转载请自行联系原作者

<think> 嗯,用户这次的问题非常聚焦,直接询问ARM架构下Linux的内存管理策略,以及用户空间与内核空间管理机制的异同。结合之前的对话历史,用户显然已经理解了x86架构的段页式管理特点,现在想横向对比ARM架构的实现差异。 从用户引用[1][3]的内容看,ta特别关注ARM32的具体实现细节,比如内存区域划分和页表建立流程。用户可能正在研究嵌入式系统开发或内核移植,需要了解不同架构下的内存管理差异。ta的提问方式很专业,说明有一定操作系统基础。 关于ARM架构的内存管理策略,需要分几个维度回答: 第一是硬件基础,ARM的MMU只支持纯页式管理,这与x86强制使用段机制有本质区别。第二是软件实现,LinuxARM32和ARM64的页表层级不同(两级vs四级),但核心思想都是基于页的虚拟内存管理。第三要强调用户空间和内核空间的管理差异,这是用户明确提出的重点。 用户空间通过缺页异常实现按需分配这个点很重要,因为很多开发者不理解为什么malloc()能快速分配大内存。而内核空间的slab分配器优化对驱动开发很有参考价值,值得展开说明。内存区域划分的数据(如vmalloc范围)可以直接引用[3]的具体数字增强说服力。 考虑到用户的研究深度,相关问题的设计需要更技术向:比如ARM64的虚拟地址扩展如何影响内存管理,或者用户空间缺页异常的具体处理流程。不过要避免问题过于底层,毕竟用户还没问到寄存器级别的内容。 </think> ARM架构下Linux的内存管理采用**纯页式策略**,用户空间与内核空间的管理策略存在显著差异,主要体现在地址映射机制、内存分配方式和权限控制等方面。 ### 一、ARM架构内存管理核心策略 1. **硬件基础** ARM的MMU(内存管理单元)**仅支持页式管理**,不涉及段机制: * 虚拟地址通过页表直接映射物理地址 * 页表层级依架构版本不同: - **ARM32**:两级页表(PGD→PTE),页大小支持$4\text{KB}$/$64\text{KB}$ $$ \text{虚拟地址} \xrightarrow{\text{PGD}} \xrightarrow{\text{PTE}} \text{物理地址} $$ - **ARM64**:四级页表(PGD→PUD→PMD→PTE),默认页大小$4\text{KB}$[^1][^3] 2. **内存区域划分(以ARM32为例)** ```plaintext 内核空间布局(32位): vector : 0xffff0000 - 0xffff1000 (4 kB) // 中断向量表 fixmap : 0xffc00000 - 0xfff00000 (3072 kB) // 固定映射区 vmalloc : 0xf0800000 - 0xff800000 (240 MB) // 动态映射区 lowmem : 0xc0000000 - 0xf0000000 (768 MB) // 线性映射区 pkmap : 0xbfe00000 - 0xc0000000 (2 MB) // 高端内存映射 modules : 0xbf000000 - 0xbfe00000 (14 MB) // 内核模块区 ```[^3] ### 二、用户空间 vs 内核空间管理差异 | **特性** | **用户空间** | **内核空间** | |------------------|---------------------------------------|---------------------------------------| | **地址映射** | 按需分配,缺页异常触发物理页分配 | 线性映射(lowmem区) + 动态映射(vmalloc)[^1] | | **分配机制** | `brk`/`mmap`系统调用 + Glibc管理 | `kmalloc`(小对象) + `vmalloc`(大块)| | **页表管理** | 进程私有页表,切换时更新TTBR0 | 内核共享页表,全局地址空间 | | **权限控制** | 用户态无权访问内核页(MMU拦截) | 内核态可访问全部空间 | | **内存回收** | 页面换出(swap) + OOM Killer | 不可换出,依赖slab回收机制 | #### 关键差异解析: 1. **地址映射机制** * 用户空间:采用**延迟分配**策略,`malloc()`仅扩展虚拟地址范围,真正访问时触发缺页异常分配物理页[^1]。 * 内核空间: - `lowmem`区采用**线性映射**:物理地址 = 虚拟地址 - $0\text{x}c0000000$ - `vmalloc`区动态建立虚拟连续但物理不连续的映射 2. **内存分配优化** ```c // 内核空间小对象分配(kmalloc基于slab) void *buffer = kmalloc(128, GFP_KERNEL); // 用户空间分配由Glibc管理 void *ptr = malloc(1024); // 触发brk/mmap系统调用 ``` 内核通过**slab分配器**管理常用对象(如task_struct),减少碎片[^1]。 3. **页表隔离性** * 用户进程崩溃不会破坏内核:因**内核页表项标记为特权访问**(ARM的AP位)[^3] * 内核直接访问用户数据需`copy_from_user()`:通过临时映射确保安全性 ### 三、ARM32/ARM64关键差异 | **项目** | **ARM32** | **ARM64** | |----------------|--------------------------------------|--------------------------------------| | **地址空间** | 3:1分割(用户3GB/内核1GB) | 用户/内核各占$2^{48}\text{字节}$ | | **页表层级** | 两级(PGD→PTE) | 四级(PGD→PUD→PMD→PTE) | | **高端内存** | 需`pkmap`动态映射(物理内存>768MB) | 无高端内存概念(地址空间充足) | | **初始化流程** | `paging_init()`建立内核线性映射[^1] | `paging_init()`启用MMU并建立映射 | > 注:ARM64取消高端内存是因$48$位地址空间($256\text{TB}$)足够映射所有物理内存[^1]。 ### 四、结论 1. **管理策略**:ARM架构使用**纯页式管理**,无段机制介入。 2. **空间差异**: - 用户空间:按需分配 + 进程隔离 - 内核空间:线性/动态映射 + 全局共享 3. **本质相同**:均依赖MMU页表换,但**内核具备直接访问物理内存的能力**,而用户空间需经系统调用中--- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值