单片机
返回首页

2.1MMU的知识

2024-10-22 来源:cnblogs

2.1MMU的知识

Loop.c的代码是:

Loop.c的代码是:

最后两个程序的运行结果:

我们看到两个程序里的地址是一样的。这是怎么回事呢!?

这就是我们今天的重点:MMU内存管理单元。

 

 

 

 

 

MMU的作用:两个

上面是虚拟地址和物理地址的转化。

在上面的两个程序中,输出的都是虚拟地址,MMU会将虚拟地址转化为对应的物理地址。上面的两个虚拟地址是相同的。为什么转化后会变成不同的物理地址呢?这是因为我们的MMU对于不同的进程,他是有不同的转化和映射关系的。如上图。

 

 

 

 

 

 

 

 

 

 

深入剖析地址转化

 

  1. 段式转化分析

 

 

 

 

4.细页转化:

 

配置与使用MMU

在上节课中,我们知道我们的MMU能够把我们的虚拟地址映射成我们的物理的地址:

  1. 粗页

  2. 细页

    我们以段的方式为例子:

     

    高20~31,取出作为表的偏移,TTB,加上后20的虚拟偏移,就是物理地址。

    我们要让我们的MMU工作:

     

    段式映射的20~31位保存的是段的物理基地址的高十二位。12~19位固定是为0的。10-11位AP控制访问权限和domain一起工作的。9位固定为0。第4位固定为1.第三位表示我们访问这段物理区域的时候是否使用cache,B位表示我们是否使用write buffer的。最后两位10是表示段式映射。

    AP-10~11位11的时候,都是可读可写的。页表象的位置是物理基地址加上虚拟地址的高12位。

    Cp15的c3寄存器是用来控制域的访问权限的:

    从最后一行知道,我们可以设置这两位为11,表示当我们去访问物理区间的时候,不用去理他的访问权限。这是简单的设置方法:

    Mmu.c的代码:

    上面就是我们的mmu.c,然后在Makefile加mmu.o,执行make后就可以烧写测试了。

    测试是可行的。

     

    Mmu.c的代码:

    #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)

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

     

     

    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;

     

    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;

    }

    1. 建立一级页表。

    2. 写入TTB

    3. 打开MMU


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

  • SOC系统级芯片设计实验

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

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

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

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

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

  • RS-485基础知识:处理空闲总线条件的两种常见方法

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

  • 如何构建一个触摸传感器电路

  • 如何调制IC555振荡器

  • 基于ICL296的大电流开关稳压器电源电路

    相关电子头条文章