|
鸿蒙内核源码分析:虚拟地址与物理地址之间是如何映射的,
MMU的本质 虚拟地址(VA): 就是线性地址, 鸿蒙内存部分全是VA的身影, 是由编译器和链接器在定位程序时分配的,每个应用程序都使用相同的虚拟内存地址空间,而这些虚拟内存地址空间实际上分别映射到不同的实际物理内存空间上。CPU只知道虚拟地址,向虚拟地址要数据,但在其保护模式下很悲催地址信号在路上被MMU拦截了,MMU把虚拟地址换成了物理地址,从而拿到了真正的数据。
物理地址(PA):程序的指令和常量数据,全局变量数据以及运行时动态申请内存所分配的实际物理内存存放位置。
MMU采用页表(page table)来实现虚实地址转换,页表项除了描述虚拟页到物理页直接的转换外,还提供了页的访问权限(读,写,可执行)和存储属性。 MMU的本质是拿虚拟地址的高位(20位)做文章,低12位是页内偏移地址不会变。也就是说虚拟地址和物理地址的低12位是一样的,本篇详细讲述MMU是如何变戏法的。
MMU是通过两级页表结构:L1和L2来实现映射功能的,鸿蒙内核当然也实现了这两级页表转换的实现。本篇是系列篇关于内存部分最满意的一篇,也是最不好理解的一篇, 强烈建议结合源码看, 鸿蒙内核源码注释中文版 【 Gitee仓 | CSDN仓 | Github仓 | Coding仓 】内存部分的注释已经基本完成 。
一级页表L1 L1页表将全部的4G地址空间划分为4096个1M的节,页表中每一项(页表项)32位,其内容是L2页表基地址或某个1M物理内存的基地址。虚拟地址的高12位用于对页表项定位,也就是4096个页面项的索引,L1页表的基地址,也叫转换表基地址,存放在CP15的C2(TTB)寄存器中,鸿蒙内核源码分析(内存汇编篇)中有详细的描述,自行翻看。 L1页表项有三种描述格式,鸿蒙源码如下:
- /* L1 descriptor type */
- #define MMU_DESCRIPTOR_L1_TYPE_INVALID (0x0 << 0)
- #define MMU_DESCRIPTOR_L1_TYPE_PAGE_TABLE (0x1 << 0)
- #define MMU_DESCRIPTOR_L1_TYPE_SECtiON (0x2 << 0)
- #define MMU_DESCRIPTOR_L1_TYPE_MASK (0x3 << 0)
第一种:Fault(INVALID)页表项,表示对应虚拟地址未被映射,访问将产生一个数据中止异常。 第二种:PAGE_TABLE页表项,指向L2页表的页表项,意思就是把1M分成更多的页(256*4K) 第三种:SECTION页表项 ,指向1M节的页表项 |
|