单片机
返回首页

MMU配置和使用

2022-05-30 来源:eefocus

一:初识MMU

MMU是memory managerment unit 即内存管理单元,是把虚拟内存转化为物理内存的一个“介质”,为什么要用到虚拟内存呢,因为在嵌入式系统中,进程和程序是很多的,物理内存根本不够用,所以使用MMU可以最大限度减少物理内存的使用,提高运行效率。MMU也是嵌入式和单片机两者中不同点最大的地方,单片机是没有MMU这个概念的。在这里,我们尝试去做一个简单的程序。假设保存为a。


#include

int a=1;

void main()

{

   while(1)

{

printf('&a=%p,a=%dn',&a,a);

sleep(3);

}

}


首先在虚拟机上运行这个程序后在我的主机上显示的是0x80496a4 a=1

再将此文件复制一次保存为b。修改b,将int a=1改为int b=2。


#include

int b=1;

void main()

{

   while(1)

{

printf('&b=%p,b=%dn',&b,b);

sleep(3);

}

}


运行后发现显示的是0x80496a4 b=2

为什么读出来的地址一样,一个读出的是1,一个读出的是2呢?

这就是MMU的作用了,这个地址0x80496a4其实是虚拟地址,MMU需要将其转化为物理地址。


二:MMU深入学习

MMU 页表描述

为了支持段和页的映射方式,MMU使用两级页表描述符,一级页表描述符决定访问的是一个分段还是一个分页式的表,如果访问的是一个分页式的页表,处理器MMU决定页表类型是大页还是小页并找到二级页表。


一级页表描述符格式分析

这里写图片描述

如上图所示:

bit[1:0]: 映射类型,分段式还是分页式。

00 忽略

11 无效,返回Translation fault

10 分段式

01 分页式

nG : 0 转换表被标记为全局的; 1 转换表属于特定进程

S : 共享位,0 非共享; 1 共享内存

XN: 0 包含可执行代码; 1 不包含可执行代码

APX,AP位: 权限访问控制位

Doman : 域标识,属于哪个域

P: ECC校验

TEX,C,B: 此区域是否采用缓冲buffer,cache,还是直接访问,一般外设采用无缓冲,内存采用缓冲方式(个人理解)

NS:No-Secure 属性


二级页表描述符格式分析

这里写图片描述

bit[1:0] : 01 时,采用粗粒度大页64K进行映射 1X时,采用小(细)页4K进行映射


1M分段式映射

这里写图片描述

页表基地址(TTBRx寄存器中)18bits[31:14]+虚拟地址12bits[31:20] +2[00] 构成了一级页表描述符的地址

取得了一级页表描述符的地址,访问这个地址从中可以得到真实的物理段基地址[31:20]

将得到的物理段基地址[31:20]加上虚拟地址中的[19:0]位偏移地址构成了真正的物理地址

每个虚拟地址可以索引 2^12 个一级描述符地址,每个一级描述符可以包含 2^20 个物理地址,总共可以索引4G空间


三:代码实现

所需要进行的工作包括以下三点

1 建立一级页表

2 写入TTB (写入TTB,因为MMU通过cp15寄存器的c2找到表项,来进行后续的工作)

3 打开MMU


一:

根据一级页表描述符,表的基地址在内存起始位置,表项的前十二位Section base address为物理基地址,段描述:section base address是物理地址高十二位,SBZ为should be zero,AP为访问权限(access peimission) ,Domain为域,C为cache,B为write buffer,最后两位10表示段式映射。表项需要设置段式还是分页式,权限,域这里选择为0,由于访问GPIO是很简单的,所以不需要cache和write buffer。


二:

这里写图片描述

c2是设置TTB的寄存器。TTB实际上是页表的基地址,在这里页表放在内存首地址上,写入c2寄存器中。所以这里只要把首地址写入c2寄存器中即可。


三:

使能MMU,cp15的C1寄存器的第0位使能MMU,将其设置为1即可。

这里写图片描述

设置域的访问权限,每个域的访问权限是由c3寄存器控制的,决定每个域的S和R位,在这里设置为11,意思是不去检查他的访问权限,这里把所有的位都设置为1即可。以下是c3寄存器的描述。

这里写图片描述

这里写图片描述

参考:http://www.jianshu.com/p/faebd7feb218


以下为代码实现:


虚拟地址 找到物理地址,然后通过物理地址点亮led

在这里虚拟地址选择为0xA0000000,映射到物理地址0x7f000000,需要页表建立映射关系,一般放在内存的起始地址,6410为0x50000000,


#define GPKCON (volatile unsigned long*)0xA0008820

#define GPKDAT (volatile unsigned long*)0xA0008824


/* 

 * 用于段描述符的一些宏定义

 */ 

#define MMU_FULL_ACCESS     (3 << 10)   /* 访问权限 */

#define MMU_DOMAIN          (0 << 5)    /* 属于哪个域 */

#define MMU_SPECIAL         (1 << 4)    /* 必须是1 */

#define MMU_CACHEABLE       (1 << 3)    /* cacheable */

#define MMU_BUFFERABLE      (1 << 2)    /* bufferable */

#define MMU_SECTION         (2)         /* 表示这是段描述符 */

#define MMU_SECDESC         (MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL | MMU_SECTION)   //这里访问GPIO是很简单的不需要cache和write buffer

#define MMU_SECDESC_WB      (MMU_FULL_ACCESS | MMU_DOMAIN | MMU_SPECIAL | MMU_CACHEABLE | MMU_BUFFERABLE | MMU_SECTION)


//对GPIO进行映射

void create_page_table(void)

{

    unsigned long *ttb = (unsigned long *)0x50000000;

    unsigned long vaddr, paddr;


    vaddr = 0xA0000000;

    paddr = 0x7f000000;

    *(ttb + (vaddr >> 20)) = (paddr & 0xFFF00000) | MMU_SECDESC;//取虚拟地址的高20位,物理基地址高十二位,


//内存映射,采用虚拟地址和物理地址相同,用while循环这里选择映射64M空间(不需要太多),这里需要打开cache和write buffer,每次映射好后加上1M,对下一段地址进行映射

    vaddr = 0x50000000;

    paddr = 0x50000000;

    while (vaddr < 0x54000000)

    {

        *(ttb + (vaddr >> 20)) = (paddr & 0xFFF00000) | MMU_SECDESC_WB;

        vaddr += 0x100000;

        paddr += 0x100000;

    }


}



void mmu_init()

{

   __asm__(


    /*设置TTB*/

    'ldr    r0, =0x50000000n'                  

    'mcr    p15, 0, r0, c2, c0, 0n'    


    /*不进行权限检查*/

    'mvn    r0, #0n'                   

    'mcr    p15, 0, r0, c3, c0, 0n'    



   /*使能MMU*/

    'mrc    p15, 0, r0, c1, c0, 0n'    

    'orr    r0, r0, #0x0001n'          

    'mcr    p15, 0, r0, c1, c0, 0n'    

    : 

    : 

  );

}


int gboot_main()

{

    create_page_table();

    mmu_init();


    *(GPKCON) = 0x1111;

    *(GPKDAT) = 0xe;


    return 0;    

}

进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • 红外线探测报警器

  • 短波AM发射器电路设计图

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 开关电源的基本组成及工作原理

  • 带有短路保护系统的5V直流稳压电源电路图

    相关电子头条文章