HNU-2024操作系统实验-Lab8-内存管理

一、 实验目的

  1. 全面深入地理解分页式内存管理的基本方法

  2. 理解页表的访问、完成地址转换等的方法

  3. 在操作系统内核中实现一个内存管理系统

二、 实验过程

1.首先需要理解Armv8架构的地址转换:

Armv8架构中存在着几个页表基址寄存器:TTBR0_ELn,TTBR1_ELn。TTBR0指向整个虚拟空间下半部分通常用于应用程序的空间,TTBR1指向虚拟空间的上半部分通常用于内核的空间。其中TTBR0除了在EL1中存在外,也在EL2 and EL3中存在,但TTBR1只在EL1中存在。

高位是1的虚拟地址空间,使用TTBR1_ELx基地址寄存器进行页表翻译;高位是0的虚拟地址空间,使用TTBR0_ELx基地址寄存器页表翻译。所以不应该说,因为你使用了哪个寄存器(TTBR0/TTBR1),然后决定了你使用的哪套虚拟地址空间;应该说,你操作系统(或软件)使用了哪套虚拟地址空间,决定了使用哪个哪个基地址寄存器(TTBR0/TTBR1)进行翻译。

下图是一个经典的48bit 虚拟地址,4级页表,页表大小为 4Kb的地址转换示例:

在这里插入图片描述

页表从左到右依次为0级页表到3级页表。

比如输入虚拟地址:

四级页表的查询过程

输入va:0xFFFF FFFF F000

使用bit[47:39]作为index 从页表基地址查询下一级页表的基地址为(0x1000)

使用bit[38:30]作为index,从页表基地址(0x1000)查找下一级的页表基地址(0x2000)

使用bit[29:21]作为index,从页表基地址(0x2000)查找下一级页表基地址(0x3000)

使用bit[20:12]作为index,从页表基地址(0x3000)获取页地址(0x80000000)

物理地址结果为 页地址 + 页偏移地址 0x80000000 + 0x0000 = 0x80000000

输出pa:0x80000000

这里列出了使用4级页表的模式下,映射地址 0xFFFF FFFF F000 到物理地址 0X80000000的映射与查找过程。这里使用的了4份页表,每一个页表最多包含512个表项目。完成上述映射占用了 512 * 8 * 4 byte = 16kByte 的内存空间与一级页表相比,占用的空间数量大大减少。

2.接着分版块对本实验的核心代码mmu.c进行分析:

在这里插入图片描述

这个数组g_mem_map_info定义了虚拟地址到物理地址映射的参数,数组中每个元素都是一个内存映射区域,包括虚拟地址起始点、物理地址起始点、大小、最大级别和属性。

在这里插入图片描述

这个函数基于给定的内存映射信息 g_mem_map_info计算并构建用于配置ARM处理器的MMU(内存管理单元)的TCR(Translation Control Register,翻译控制寄存器)的值。这个函数的目的是为了设置内存管理单元的虚拟地址翻译机制,并返回构建好的TCR寄存器的值。

这里基于Armv8用户手册,对TCR的功能进行分析:

比特位长度解释说明
IPSb001 << 3236bits address space - 64GB

36位地址空间,共64GB
TG1b10 << 304KB granule size for TTBR1_EL1

页大小为4KB
SH1b11 << 28页表所在memory: Inner shareable内部可共享
ORGN1b01 << 26页表所在memory: Normal, Outer Wr.Back Rd.alloc Wr.alloc Cacheble可写回缓存
IRGN1b01 << 24页表所在memory: Normal, Inner Wr.Back Rd.alloc Wr.alloc Cacheble可写回缓存
EPD1b0 << 23Perform translation table walk using TTBR1_EL1
A1b1 << 22TTBR1_EL1.ASID defined the ASID
T1SZb011100 << 16虚拟地址为(64-n)=(64-28)=36位
TG0b00 << 144KB granule size

页大小为4KB
SH0b11 << 12页表所在memory: Inner Sharebale内部可共享
ORGN0b01 << 10页表所在memory: Normal, Outer Wr.Back Rd.alloc Wr.alloc Cacheble可写回缓存
IRGN0b01 << 8页表所在memory: Normal, Inner Wr.Back Rd.alloc Wr.alloc Cacheble可写回缓存
EPD0b0 << 7Perform translation table walk using TTBR0_EL1
0b0 << 6Zero field (reserve)
T0SZb011100 << 0虚拟地址为(64-n)=(64-28)=36位

在这里插入图片描述

第一个函数返回页表项的类型,第二个函数则是根据页表的级别返回对应的位移值,以计算每个页表项表示的地址范围。

在这里插入图片描述

这个函数则是在页表中找到给定地址和级别的页表项地址。

在这里插入图片描述

这个mmu_creat_table函数根据页表粒度(4k或64k)在页表区域创建一个新的页表,由于页表刚创建时为空页表,因此所有的页表项均为PTE_TYPE_FAULT,最后返回该页表的起始位置

在这里插入图片描述

这其中的第一个函数设置页表项指向一个页表,用于创建多级页表,第二个函数则是根据映射指定的级别来填充对应的页表项。

在这里插入图片描述

这个函数向MMU中添加映射:首先通过一个循环,从起始级别开始,为给定的地址范围添加映射。在每一级别,它会尝试找到对应的页表项(通过调用 mmu_find_pte 函数),如果找不到则返回错误,对于找到的页表项,调用先前定义的mmu_add_map_pte_process函数来进行填充。这包括创建新的下一级页表(如果当前页表项无效且不是最低级页表项)或直接设置页表项的值(如果是最低级页表项或已到达设定的级别)在成功添加映射后,函数会更新虚拟地址、物理地址和已映射的大小,为下一个块做准备。循环一直重复直到整个映射的大小都被处理完毕。

在这里插入图片描述

这个函数嵌入式汇编指令来直接操作处理器的寄存器,用于设置TTBR、TCR和MAIR寄存器的值。这些寄存器用于配置处理器的内存管理单元(MMU),控制虚拟内存到物理内存的转换。

根据Armv8用户手册对MAIR寄存器进行分析:

MAIR 支持定义八种预设的内存属性,可以分类为 memory 类型和 device 类型,每一种类型还包含了一些细节的控制,对于 memory 类型的内存,主要进行一些cache的分配策略的配置 如write back、write through等,device 类型是不可cache的地址空间,主要用于对外设寄存器访问等。

主要包含了3种属性 G/R/E:

G 表示 Gathering,即是否允许访问合并,比如2个8bit的地址连续的访问请求、合并成为一个16bit的访问请求

R 表示 Re-ordering,即表示对地址空间的访问请求是否支持重新排序,如分别读取2个地址的数据,在访问时顺序可能与程序定义不完全一致

E 表示 Early Write Acknowledgement,即对总线发起写操作时,是否允许总线提前返回写响应,而不需要等待写数据真的写入到了最终的位置。在总线上可能会存在并经过多个节点,提前返回可以提前完成写数据指令的执行。

在这里插入图片描述

这个函数主要用于初始化和设置内存管理单元(MMU)的页表,从而实现在ARM架构的处理器上完成虚拟地址到物理地址的转换,首先接收一系列内存映射区域、页表的基地址和长度、以及页表粒度作为参数,并根据这些参数构建起始级别的页表,最后将内存映射添加到这些页表中。

在这里插入图片描述

这个函数为操作系统内核设置页表,并根据预定义的内存映射信息来初始化MMU,以便系统能够使用虚拟内存管理。

在这里插入图片描述

最后就是初始化函数,首先调用mmu_setup函数来设置页表,然后无效化数据和指令缓存以及TLB,最后设置系统控制寄存器(SCTLR)来启用缓存和MMU。

3.启用MMU

在这里插入图片描述

三、测试及分析

执行程序,可以正常运行:

在这里插入图片描述

通过调试发现已启用MMU:

在这里插入图片描述

四、 Lab8作业

启用 TTBR1 ,将地址映射到虚拟地址的高半部分,使用高地址访问串口,修改后:

1.在src/bsp目录下的print.c文件中添加宏定义:

在这里插入图片描述

2.在src/bsp目录下的hwi_init.c文件中添加宏定义:

在这里插入图片描述

此处定义了dist和cpu的基址,GIC_DIST_BASE 和 GIC_CPU_BASE 的高位多少个f与MMU的配置有关,此处设置为8个f

3.更改g_mem_map_info,使得进行映射时,将地址映射到高半部分:

在这里插入图片描述

4.取消mmu_set_ttbr_tcr_mair函数中的注释, 启用ttbr1_el1:

在这里插入图片描述

ttbr1_el1 是 ARM 架构中的一个系统寄存器,全称为 “Translation Table Base Register 1 - EL1”,用于存放转换表基址,在内存管理单元(MMU)中用来控制地址空间的转换。

5.最后,Init函数、write函数以及read函数中的基址被更改为新定义的地址:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

6.最后执行程序,发现能够正常运行:

在这里插入图片描述

五、心得体会

  1. 更加清楚在具体的armv8架构中,页表是如何将虚拟地址映射到物理地址的,这其中涉及多个寄存器的相互配合。

  2. 能了解这多个寄存器的作用,在依托手册的基础上正确的配置寄存器以实现内存管理。

  3. 了解了多种页表映射方案,如块映射,多级页表映射等。

  • 17
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值