Linux内存从0到1学习笔记(二,ARM64 物理内存)
Posted 高桐@BILL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux内存从0到1学习笔记(二,ARM64 物理内存)相关的知识,希望对你有一定的参考价值。
写在前面
我们先通过一张图来里哦啊接下ARM处理器的内存管理架构;
2.1 ARM处理器的内存管理架构
ARM处理器内核:是指ARM架构的CPU中间的核心芯片,由单晶硅制成,用来完成所有的计算、接受/存储命令、处理数据等,是数字处理核心。
MMU:Memory Mangerment Unit (内存管理单元),有时称作分页内存管理单元。它是一种负责处理CPU内存访问请求的计算机硬件。用于完成虚拟内存和物理内存的映射,位于CPU内部;MMU将虚拟内存映射到物理内存,以及设置修改CPU的访问级别,如printf函数,要调用系统函数write,要进入内核空间,此时CPU的访问级别由3级用户空间转换到0级内核空间。
TLB:Translation Lookaside Buffer (页表缓存)。作为CPU的一种缓存,由存储器管理单元用于改进虚拟地址到物理地址的转译速度。
高速缓存:Cache。其原始意义是指存取速度比一般随机存取记忆体(RAM)来得快的一种RAM,一般而言它不像系统主记忆体那样使用DRAM技术,而使用昂贵但较快速的SRAM技术,也有快取记忆体的名称。
页表或分页表:(Page Table),一种特殊的数据结构,用于存储虚拟地址到物理地址间的映射。
页表项:(PTE, Page Table Entry),用来描述一个虚拟页号如何映射到物理页号的。
一、ARM内存管理简介
ARM处理器内核的MMU包括TLB和页表遍历单元(Table Walk Unit)两个部件;TLB是一个高速缓存,用于缓存页表转换的结果,从而减少页表查询的时间。当TLB未命中时,MMU才会查询页表,从而得到翻译后的物理地址。页表通常存储在主存储器中,也就是内存中,在kernel初始化的时候创建。
那么进程地址空间如何映射到物理地址空间呢?这就需要处理器MMU提供页表映射和管理的功能。如下图:
2.2进程地址空间和物理地址空间的映射关系
二、页表及页表映射
在AArch64中MMU支持单一页表转化(VA to PA),也支持虚拟化扩展的两阶段页表转化(VA to IPA to PA)。
在ARrch64架构中,地址总线位宽最多支持48位,所以VA(Virtual Address)被划分为两个空间,每个空间最多支持256TB。在此架构下的页表最多支持4级页表,翻译的页面粒度可以是4KB,16KB或64KB。默认为4KB。
2.1查表或地址翻译
处理器查表过程,我们称之为Translation Table Walk,这个过程是由MMU硬件完成的,如下:
- 处理器根据页表基地址控制寄存器(页表基地址寄存器(PTBR):CPU有一个专门的页表基地址寄存器,指向当前页表的基地址,也就是起始地址.)和虚拟地址来判断使用哪个页表基地址寄存器。在页表基地址寄存器中存放着一级页表(L0页表)的基地址(起始地址)。
- 处理器将[47:39]作为L0索引,L0页表的页表项中存放着L1页表的物理基地址,L0页表有512个页表项。
- 处理器将[38:30]作为L1索引,L1页表的页表项中存放着L2页表的物理基地址。L1页表有512个页表项。
- 处理器将[29:31]作为L2索引,L2页表的页表项中存放着L3页表的物理基地址。L2页表有512个页表项。
- 处理器将[20:12]作为L3索引,L3页表有512个页表项,每个页表项存放着4KB页面的物理基地址,然后再加上[11:0],就构成了新的物理地址。
至此,处理器就完成了也表的查询和翻译工作。那么一次查表寻址的过程需要访问5次物理内存。这个过程实际上是很耗时的。TLB的存在可以大大加快查表或者地址翻译的速度。这里先剧透下,后面会详细介绍TLB的工作原理。TLB会把虚拟地址到物理地址的翻译结果或者查表结果保存到TLB表项中,这样当处理器需要访问内存时就会首先从TLB中查询是否有相应的表项,如果TLB命中就不需要去MMU中查表了。因此TLB也被称之为快表。
2.2 页表描述符
在AArch64架构中的4级页表都有512页表项。每个页表项我们又称之为页表描述符,其占8个字节。
L0~L2的页表项共有3类,第一类是无效页表项,第二类是块类型的页表项,第三类是页表类型的页表项。
L3的页表项共有5类,分别是无效类,保留的页表项,4KB粒度,16KB粒度和64KB粒度的页表项。
2.3 Linux内核中的页表
ARM64的Linux内核中采用了4级分页模型,包括页全局目录(PGD,Page Global Directory),页上级目录(PUD,Page Upper Directory)、页中间目录(PMD,Page Middle Directory),页表(PT,Page Table)。那么前面说的4级分页模型在64位虚拟地址的划分如下图:
2.3 4级分页模型在64位虚拟地址的划分
页表的作用就是通过VPN找到PFN,那么页表最基本的组成部分需要包含如下内容:
- PFN物理页帧号;
- 有效位(valid),用于标记页面是否有效;
- 存在位(present),指示该页是否存在于物理内存,用于页面换入换出(swap);
- 特权标记,指示页面访问的特权等级;
- Dirty位,写操作时设置该位,表示页面被写过,页面交换时使用;
最后一张图来总结下MMU的寻址映射过程,如下:
2.4 基于ARM64的页表映射过程内核源码解读
参考源码:mmu.c « mm « arm64 « arch - kernel/git/stable/linux.git - Linux kernel stable tree
由于在head.S文件中,已经对内核映像文件做了块映射,那么在内核架构初始化的时候,paging_init函数会对内核空间的页表进行重新映射。
pgd_set_fixmap():主要负责固定映射,全局变量swapper_pg_dir即内页页表的PGD页表基地址。该函数会将swapper_pg_dir页表重新映射到固定映射区域,并返回PGD页表的虚拟地址。
map_kernel(pgdp):主要负责内核映像文件各个块的重新映射;
map_mem(pgdp):主要负责物理内存的线性映射;
pgd_clear_fixmap():解除固定映射;
写在最后:
参考资料:
《奔跑吧Linux内核 第二版》
《深入Linux内核架构》
以上是关于Linux内存从0到1学习笔记(二,ARM64 物理内存)的主要内容,如果未能解决你的问题,请参考以下文章
Linux内存从0到1学习笔记(8.14 dma-buf内存调试二 bufinfo介绍)-- 更新中
Linux内存从0到1学习笔记(8.14 dma-buf内存调试二 bufinfo介绍)-- 更新中
Linux内存从0到1学习笔记(8.14 dma-buf内存调试二 bufinfo介绍)-- 更新中