本系列参考《奔跑吧linux内核》第二版,进行汇总和精简,如有错误还请指正。
ARM内存管理
ARM的内存管理单元(mmu——memory manage unit)包括TLB和页表遍历单元。
TLB
TLB是mmu的一个高速缓存,mmu接受到需要转换的虚拟地址准备根据页表进行转换时,会先查询这个缓存,如果命中了该虚拟地址,则直接将缓存中该虚拟地址的物理地址作为结果。如果没有命中,则按照正常步骤转换。
页表
ARMv8架构支持长描述符页表格式,支持4KB,16KB和64KB这三种页面大小(一般操作系统设定一个页是4KB)。
页表查询(虚拟地址访转化到物理地址)
在TLB没有命中的时候,就会进行页表查询。
假设目前一个页面为4kb,下面用数组表示一个64位操作系统的虚拟地址virtual address,VA[ ];
①根据VA[63]和页表基地址控制器选择页表基地址寄存器,该寄存器指向一级页表L0
②VA[47:39]作为L0的偏移,在L0找到对应的L1
③VA[30:38]作为L1的偏移,在L1中找到L2
④同理VA[29:21] VA[20:12]分别找出L3和L3里面对应的页是哪个
⑤VA[11:0]对应这4k的页大小,刚好能找到最终的物理地址
进程的虚拟地址到物理地址的过程
由于每个进程的虚拟地址都是一样的,所以得给每一个进程都设置一个页表。这样,不同的进程即使要访问相同的虚拟地址,也会因为页表的不同而访问到不同的物理地址。避免了冲突。
但是TLB机制只判断虚拟内存是否命中,这就会有问题,如果前一个线程的虚拟地址VA能在TLB中命中到对应物理地址,新切换运行的线程也需要访问这个虚拟地址,但是由于命中了TLB,实际访问的是之前线程VA对应的物理地址。
所以,TLB添加一项ASID(Address Space ID)的匹配。ASID就类似进程ID一样,用来区分不同进程的TLB表项。这样在进程切换的时候就不需要flush TLB。但是仍然需要软件管理和分配ASID。