ARM 裸机开发学习笔记(3)内存管理单元MMU

本文介绍了Linux中的MMU如何处理虚拟地址与物理地址的映射,以及在ARM裸机开发中如何启用和配置MMU。通过实验验证,通过虚拟地址在SDRAM中执行代码来驱动LED,阐述了MMU在初始化和进程通信中的作用。
摘要由CSDN通过智能技术生成

ARM 裸机开发学习笔记(3)内存管理单元MMU

在学习ARM裸机中的内存管理单元MMU时,又回头翻看了在学习linux进程时学到的关于MMU的知识。在此,对两者进行一个小结。

1. linux中的MMU

在这里插入图片描述

  • 如上图所示:对于程序计数器位数为32位的处理器来说,他的地址发生器所能发出的地址数目为2^32=4G个,于是这个处理器所能访问的最大内存空间就是4G。而实际的物理内存可能为1G,小于这个数目。
  • 但是,程序总是逐段被运行的,而且在一段时间内会稳定运行在某一段程序里实际上,一个程序在运行之前,没有必要全部装入内存,而仅需要将那些当前要运行的部分先装入内存,其余部分在用到时再从磁盘调入,而当内存耗光时再将暂时不用的部分调出到磁盘。这使得一个大程序可以在较小的内存空间中运行,也使得内存中可以同时装入更多的程序并发执行,从用户的角度看,该系统所具有的内存容量将比实际内存容量大得多,人们把这样的存储器称为虚拟存储器。所具有的地址称为虚拟地址。
  • 从虚拟地址到物理地址的映射记录由内存管理单元MMU完成。映射的地址转换表记录在进程控制块pcb中。
  • 由此,即使多个进程中的变量可能是同一虚拟地址,但具体映射到物理内存上时不同的地址。实现了多个进程之间互不干扰,各自执行。
  • 其中不同进程的3g-4g内核空间映射到的是物理内存中的相同一片区域,由此可以实现进程之间的通信。

2.ARM裸机中的MMU使用

在linux中MMU的具体映射不用程序员设置,而在ARM裸机开发中,需要建立映射,开启MMU。下图为映射原理框图:在这里插入图片描述

  • 连接1处,即CPU发出的地址。站在CPU角度分析,不会区分虚拟地址和物理地址。如果MMU没有使能的话,那么CPU发出的地址就直接到达存储管理器,是物理地址。而如果MMU使能的情况,CPU发出地址为虚拟地址,经过MMU转换为物理地址。并送到存储管理器。

  • 连接2处,即MMU转换完成(如果MMU使能)的物理地址,或者存储管理器接收的物理地址。因此,存储管理器操作的都是物理地址。

  • 连接3处,需要存储管理器对于SDRAM需要的信息进行初始化配置,在前面一节已具体描述。

3 实验验证

期望结果:通过虚拟地址点亮led灯。
实验流程:sc2440通过nand flash烧写程序,烧写到片内的sram中。其中,将程序分成两部分:第一部分的运行地址设为0,它用来初始化SDRAM、复制第二部分的代码到SDRAM中(存放在0x30004000开始处)、设置页表、启动MMU,最后跳到SDRAM中(地址0xB0004000)去继续执行。第二部分的运行地址设为0xB0004000,它用来驱动LED。

@*************************************************************************
@ File:head.S
@ 功能:设置SDRAM,将第二部分代码复制到SDRAM,设置页表,启动MMU,
@       然后跳到SDRAM继续执行
@*************************************************************************       

.text
.global _start
_start:
    ldr sp, =4096                       @ 设置栈指针,以下都是C函数,调用前需要设好栈
    bl  disable_watch_dog               @ 关闭WATCHDOG,否则CPU会不断重启
    bl  memsetup                        @ 设置存储控制器以使用SDRAM
    bl  copy_2th_to_sdram               @ 将第二部分代码复制到SDRAM
    bl  create_page_table               @ 设置页表
    bl  mmu_init                        @ 启动MMU
    ldr sp, =0xB4000000                 @ 重设栈指针,指向SDRAM顶端(使用虚拟地址)
    ldr pc, =0xB0004000                 @ 跳到SDRAM中继续执行第二部分代码
halt_loop:
    b   halt_loop

初始化程序如下:

/*
 * init.c: 进行一些初始化,在Steppingstone中运行
 * 它和head.S同属第一部分程序,此时MMU未开启,使用物理地址
 */ 

/* WATCHDOG寄存器 */
#define WTCON           (*(volatile unsigned long *)0x53000000)
/* 存储控制器的寄存器起始地址 */
#define MEM_CTL_BASE    0x48000000


/*
 * 关闭WATCHDOG,否则CPU会不断重启
 */
void disable_watch_dog(void)
{
   
    WTCON = 0;  // 关闭WATCHDOG很简单,往这个寄存器写0即可
}

/*
 * 设置存储控制器以使用SDRAM
 */
void memsetup(void)
{
   
    /* SDRAM 13个寄存器的值 */
    unsigned long  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值