MMU内存管理单元学习

1、内存管理单元(Memory Manager Unit)

内存管理单元的功能是:虚拟地址映射和权限管理

2、虚拟地址概念

我们在Linux类型操作系统中看到的(利用printf打印出来的地址)都是虚拟地址,都是经过MMU加工映射的。比如两个代码

hello1.c:

#include <stdio.h>

int a = 1;

int main(void)
{
    printf("0x%x\n",&a);
    while(1);
    return 0;
}

hello2.c:

#include <stdio.h>

int a = 3;

int main(void)
{
    printf("0x%x\n",&a);
    while(1);
    return 0;
}

你会发现同时运行起来,两个程序打印出来的a的地址都是一样的,这就说明两个程序运行的地址是一样的。

这样对于CPU来说,不用管程序的地址是虚拟地址还是物理地址,CPU只用关心我要从这个地址中去获取数据,至于这个地址是物理地址还是虚拟地址,就看你是否使用了MMU,如果使用了MMU,那就说明这是虚拟地址,否则就是物理地址。

3、虚拟地址和物理地址转化

虚拟地址用VA表示,物理地址使用PA表示,那么物理地址和虚拟地址映射关系可以抽象成一个关系式:VA = func(PA)。在MIPS架构中,这和个func实际功能就是VA = PA + 固定偏移。而在arm中,func就是MMU的映射功能,MMU常见映射方法就是段映射:将4G虚拟内存和实际物理内存之间的映射(对应关系)通过一张页表来表示(也可以是二级映射)。而页表的每一个页表项就表示的是虚拟地址和物理地址之间的映射关系:一个页表项表示1M虚拟内存和物理地址的关系。

4、MMU实质

MMU的功能实质就是一段结构固定的内存地址空间,当中存放的是以1M为单位(一块)的虚拟地址和物理地址映射关系。比如你在内存中的一段空间,大小是4GB(虚拟内存)/  1MB  =  4096,也就是4K个表项,每一个表项按顺序存放的是当前这1MB的虚拟地址对应的1M物理地址空间。例如,你现在的虚拟地址是0xa0000000,那么他对应的虚拟页表项是0xa0000000/1M = 0xa00,在虚拟页表中对应的页表项地址就是:页表首地址+0xa00 * 4(因为一个页表项存放的就是一个32位地址占4字节)。

5、MMU实验

程序一上电的时候就会先从flash加载到SOC的片内RAM,然后开始在SOC片内RAM中运行,这时候,我们要在程序开始运行之前先初始化好C语言的运行环境(其实就是栈指针初始化),接下来关闭看门狗(否则程序会处在一直重启状态),接下来初始化SDRAM(因为片内RAM大小有限,而SDRAM要想使用必须先初始化),接下来才是设置映射页表,使用MMU。

测试实验描述:使用虚拟地址(每个寄存器地址、程序链接地址)完成LED流水灯实验。设计验证MMU的映射功能实验的思路就是:

(1)初始化C语言栈指针

(2)关闭WDT看门狗

(3)初始化SDRAM

(4)创建页表

其实就是在指定的虚拟地址的页表项添加对应物理空间地址。比如你去控制一个LED灯,就必须要设置相关寄存器,而寄存器地址本身是物理地址,你就需要找到自己想要映射的虚拟地址对应的页表项的位置处,加入虚拟地址,但是要注意,你添加的虚拟地址只能是1M的整数倍。

(5)将页表地址告诉MMU

需要初始化MMU,其实就是将你存放页表的物理地址告诉MMU,以后MMU添加或者查找虚拟地址和物理地址的映射关系的时候直接去定位。

(6)启动MMU

一旦MMU启动了,那么CPU所有读写内存用到的地址就都会被MMU当成虚拟地址去查找页表映射关系进而定位实际物理内存地址。也就是说,CPU只知道自己访问的是地址,不关心是物理地址还是虚拟地址,如果MMU启动了,那么这个地址就是虚拟地址,否则就是物理地址。

猜你喜欢

转载自blog.csdn.net/CSDNmianfeixiazai001/article/details/81453359