历史上的今天
返回首页

历史上的今天

今天是:2025年07月20日(星期日)

2021年07月20日 | S3C2410 MMU(存储器管理单元)详述

2021-07-20 来源:eefocus

  MMU,全称Memory Manage Unit, 中文名——存储器管理单元。


  许多年以前,当人们还在使用DOS或是更古老的操作系统的时候,计算机的内存还非常小,一般都是以K为单位进行计算,相应的,当时的程序规模也不大,所以内存容量虽然小,但还是可以容纳当时的程序。但随着图形界面的兴起还用用户需求的不断增大,应用程序的规模也随之膨胀起来,终于一个难题出现在程序员的面前,那就是应用程序太大以至于内存容纳不下该程序,通常解决的办法是把程序分割成许多称为覆盖块(overlay)的片段。覆盖块0首先运行,结束时他将调用另一个覆盖块。虽然覆盖块的交换是由OS完成的,但是必须先由程序员把程序先进行分割,这是一个费时费力的工作,而且相当枯燥。


  人们必须找到更好的办法从根本上解决这个问题。不久人们找到了一个办法,这就是虚拟存储器(virtual memory).虚拟存储器的基本思想是程序,数据,堆栈的总的大小可以超过物理存储器的大小,操作系统把当前使用的部分保留在内存中,而把其他未被使用的部分保存在磁盘上。比如对一个16MB的程序和一个内存只有4MB的机器,OS通过选择,可以决定各个时刻将哪4M的内容保留在内存中,并在需要时在内存和磁盘间交换程序片段,这样就可以把这个16M的程序运行在一个只具有4M内存机器上了。而这个16M的程序在运行前不必由程序员进行分割。


  任何时候,计算机上都存在一个程序能够产生的地址集合,我们称之为地址范围。这个范围的大小由CPU的位数决定,例如一个32位的CPU,它的地址范围是0~0xFFFFFFFF (4G),而对于一个64位的CPU,它的地址范围为0~0xFFFFFFFFFFFFFFFF (64T).这个范围就是我们的程序能够产生的地址范围,我们把这个地址范围称为虚拟地址空间,该空间中的某一个地址我们称之为虚拟地址。与虚拟地址空间和虚拟地址相对应的则是物理地址空间和物理地址,大多数时候我们的系统所具备的物理地址空间只是虚拟地址空间的一个子集,这里举一个最简单的例子直观地说明这两者,对于一台内存为256MB的32bit x86主机来说,它的虚拟地址空间范围是0~ 0xFFFFFFFF(4G),而物理地址空间范围是0x000000000~0x0FFFFFFF(256MB)。


  在没有使用虚拟存储器的机器上,虚拟地址被直接送到内存总线上,使具有相同地址的物理存储器被读写。而在使用了虚拟存储器的情况下,虚拟地址不是被直接送到内存地址总线上,而是送到内存管理单元——MMU(主角终于出现了)。他由一个或一组芯片组成,一般存在与协处理器中,其功能是把虚拟地址映射为物理地址。


  大多数使用虚拟存储器的系统都使用一种称为分页(paging)。虚拟地址空间划分成称为页(page)的单位,而相应的物理地址空间也被进行划分,单位是页框(frame).页和页框的大小必须相同。接下来配合图片我以一个例子说明页与页框之间在MMU的调度下是如何进行映射的
在这里插入图片描述

  在这个例子中我们有一台可以生成16位地址的机器,它的虚拟地址范围从0x0000~0xFFFF(64K),而这台机器只有32K的物理地址,因此他可以运行64K的程序,但该程序不能一次性调入内存运行。这台机器必须有一个达到可以存放64K程序的外部存储器(例如磁盘或是FLASH),以保证程序片段在需要时可以被调用。在这个例子中,页的大小为4K,页框大小与页相同(这点是必须保证的,内存和外围存储器之间的传输总是以页为单位的),对应64K的虚拟地址和32K的物理存储器,他们分别包含了16个页和8个页框。


  我们先根据上图解释一下分页后要用到的几个术语,在上面我们已经接触了页和页框,上图中绿色部分是物理空间,其中每一格表示一个物理页框。橘黄色部分是虚拟空间,每一格表示一个页,它由两部分组成,分别是Frame Index(页框索引)和位p(present 存在位),Frame Index的意义很明显,它指出本页是往哪个物理页框进行映射的,位p的意义则是指出本页的映射是否有效,如上图,当某个页并没有被映射时(或称“映射无效”,Frame Index部分为X),该位为0,映射有效则该位为1。


  我们执行下面这些指令(本例子的指令不针对任何特定机型,都是伪指令)

例1:

MOVE REG,0 //将0号地址的值传递进寄存器REG.

  虚拟地址0将被送往MMU,MMU看到该虚地址落在页0范围内(页0范围是0到4095),从上图我们看到页0所对应(映射)的页框为2(页框2的地址范围是8192到12287),因此MMU将该虚拟地址转化为物理地址8192,并把地址8192送到地址总线上。内存对MMU的映射一无所知,它只看到一个对地址8192的读请求并执行它。MMU从而把0到4096的虚拟地址映射到8192到12287的物理地址。


例2:

MOVE REG,8192

被转换为

MOVE REG,24576

因为虚拟地址8192在页2中,而页2被映射到页框6(物理地址从24576到28671)

例3:

MOVE REG,20500

被转换为

MOVE REG,12308

  虚拟地址20500在虚页5(虚拟地址范围是20480到24575)距开头20个字节处,虚页5映射到页框3(页框3的地址范围是 12288到16383),于是被映射到物理地址12288+20=12308。


  通过适当的设置MMU,可以把16个虚页隐射到8个页框中的任何一个,但是这个方法并没有有效的解决虚拟地址空间比物理地址空间大的问题。从上图中我们可以看到,我们只有8个页框(物理地址),但我们有16个页(虚拟地址),所以我们只能把16个页中的8个进行有效的映射。我们看看例4会发生什么情况

MOV REG,32780

  虚拟地址32780落在页8的范围内,从上图总我们看到页8没有被有效的进行映射(该页被打上X),这是又会发生什么?MMU注意到这个页没有被映射,于是通知CPU发生一个缺页故障(page fault).这种情况下操作系统必须处理这个页故障,它必须从8个物理页框中找到1个当前很少被使用的页框并把该页框的内容写入外围存储器(这个动作被称为page copy),随后把需要引用的页(例4中是页8)映射到刚才释放的页框中(这个动作称为修改映射关系),然后从新执行产生故障的指令(MOV REG,32780)。假设操作系统决定释放页框1,那么它将把虚页8装入物理地址的4-8K,并做两处修改:首先把标记虚页1未被映射(原来虚页1是被影射到页框1的),以使以后任何对虚拟地址4K到8K的访问都引起页故障而使操作系统做出适当的动作(这个动作正是我们现在在讨论的),其次他把虚页8对应的页框号由X变为1,因此重新执行MOV REG,32780时,MMU将把32780映射为4108。


  我们大致了解了MMU在我们的机器中扮演了什么角色以及它基本的工作内容是什么,下面我们将举例子说明它究竟是如何工作的(注意,本例中的MMU并无针对某种特定的机型,它是所有MMU工作的一个抽象)。


  首先明确一点,MMU的主要工作只有一个,就是把虚拟地址映射到物理地址。


  我们已经知道,大多数使用虚拟存储器的系统都使用一种称为分页(paging)的技术,就象我们刚才所举的例子,虚拟地址空间被分成大小相同的一组页,每个页有一个用来标示它的页号(这个页号一般是它在该组中的索引,这点和C/C++中的数组相似)。在上面的例子中0~ 4K的页号为0,4 ~8K的页号为1,8 ~12K的页号为2,以此类推。而虚拟地址(注意:是一个确定的地址,不是一个空间)被MMU分为2个部分,第一部分是页号索引(page Index).第二部分则是相对该页首地址的偏移量(offset). 。我们还是以刚才那个16位机器结合下图进行一个实例说明,该实例中,虚拟地址8196被送进MMU,MMU把它映射成物理地址。16位的CPU总共能产生的地址范围是0~64K,按每页4K的大小计算,该空间必须被分成16个页。而我们的虚拟地址第一部分所能够表达的范围也必须等于16(这样才能索引到该页组中的每一个页),也就是说这个部分至少需要4个bit。一个页的大小是4K(4096),也就是说偏移部分必须使用12个bit来表示(2^12=4096,这样才能访问到一个页中的所有地址),8196的二进制码如下图所示:
在这里插入图片描述

  该地址的页号索引为0010(二进制码),既索引的页为页2,第二部分为000000000100(二进制),偏移量为4。页2中的页框号为6(页2映射在页框6,见上图),我们看到页框6的物理地址是24~ 28K。于是MMU计算出虚拟地址8196应该被映射成物理地址24580(页框首地址+偏移量=24576+4=24580)。同样的,若我们对虚拟地址1026进行读取,1026的二进制码为0000010000000010,page index=0000=0,offset=010000000010=1026。页号为0,该页映射的页框号为2,页框2的物理地址范围是8192~12287,故MMU将虚拟地址1026映射为物理地址9218(页框首地址+偏移量=8192+1026=9218)


  以上就是MMU的工作过程。

推荐阅读

史海拾趣

e2v technologies公司的发展小趣事

为了进一步提升整体实力,e2v在发展过程中进行了多次收购与整合。这些收购不仅增强了公司的技术实力和市场竞争力,也为其带来了更多的客户资源。例如,e2v曾收购了一家专注于医疗成像技术的公司,这一举措使其在医疗成像领域取得了显著的进展。

BAHCO公司的发展小趣事

一直以来,BAHCO都秉持着创新的设计理念和对品质的极致追求。其鱼和鱼钩的商标不仅代表了公司的品牌形象,更是品质的保证。通过不断的研发和技术创新,BAHCO的产品在功能性、耐用性和舒适性等方面都达到了行业领先水平。这种对品质的不懈追求,使得BAHCO在全球工具市场上获得了广泛的认可和好评。

Fortiming Corporation公司的发展小趣事

背景:随着电子技术的快速发展,客户对频率控制产品的要求越来越高。

发展:Fortiming不断投入研发资源,进行技术创新和产品升级。公司成功开发出了一系列高精度、高稳定性的晶振产品,满足了市场对高品质频率控制产品的需求。同时,Fortiming还积极探索新的应用领域,如通信、汽车电子、物联网等,不断拓展市场边界。

CMOSIS公司的发展小趣事

在CMOS图像传感器市场竞争日益激烈的背景下,CMOSIS公司凭借其深厚的技术积累,成功研发出一款新型CMOS图像传感器,具有更高的分辨率和更低的噪声水平。这一技术突破使得CMOSIS的产品在市场上脱颖而出,赢得了众多客户的青睐。公司通过不断优化生产工艺和降低成本,逐渐扩大了市场份额,成为行业内的佼佼者。

Cobham Semiconductor Solutions公司的发展小趣事

随着技术的不断成熟和市场需求的增长,Cobham Semiconductor Solutions意识到拓展市场的重要性。公司积极寻求国际合作,与多家知名企业建立了战略合作关系。通过合作,Cobham不仅获得了更多的市场机会,还进一步提升了自身的技术实力。同时,公司还积极开拓新兴市场,将产品推向全球,实现了业务的快速增长。

ADI(亚德诺半导体)公司的发展小趣事

随着技术的不断成熟和市场需求的增长,Cobham Semiconductor Solutions意识到拓展市场的重要性。公司积极寻求国际合作,与多家知名企业建立了战略合作关系。通过合作,Cobham不仅获得了更多的市场机会,还进一步提升了自身的技术实力。同时,公司还积极开拓新兴市场,将产品推向全球,实现了业务的快速增长。

问答坊 | AI 解惑

ad603的自激振荡消除

本帖最后由 paulhyde 于 2014-9-15 08:53 编辑 ad603的自激振荡如何消除 ??!!  …

查看全部问答>

数字移动通信原理

数字移动通信原理…

查看全部问答>

wince5.0中,GetServiceHandle函数的使用问题

为什么我在APP中用GetServiceHandle函数时,不能得到服务程序的句柄呢?返回值是0xffffffff. 在WINCE5.0下面,要怎么样来获得一个独立服务程序的句柄啊?急啊,请高手指教啊,谢谢了.…

查看全部问答>

MSP430学习笔记之五:定时器

Timer_A的寄存器 寄存器                      缩写            &nbs ...…

查看全部问答>

开始STM32,两点不爽

1.32bit的MCU居然只有16bitTimeer,人家dsPIC才16bit都有32bit Timer2.开发环境需要做很多设置,人家MPLAB那叫一个简单啊(习惯了)…

查看全部问答>

wince集成驱动和不集成驱动得出结果为啥不一样

wince5.0 系统下 我做了一个max541驱动 是基于spi通信协议的 1.NK.bin不集成max541驱动 使用DM动态加载该驱动时 使用应用程序调试没有问题 结果正确2.NK.bin集成max541驱动   使用应用程序调试 结果不正确 有偏差这是为什么呢 很不解…

查看全部问答>

关于用KEIL 进行C8051F021仿真调试

我用KEIL  uvision3 连接新华龙的UEC-6进行C8051F021仿真调试时  发现按调试按钮后   修改过的程序直接烧进了FLASH里  这样直接修改了程序,我想问下怎么可以在不改变原程序的情况下进行在线调试?是不是KEIL里哪个按键可以呢 [ ...…

查看全部问答>

兼职PCB和原理图设计,包括封装制作

本人工程师一枚,从事过DVD,嵌入式、zigbee无线通信研发工作,设计过音视频信号、以太网接口、天线及天线前端的PCB,闲暇时间想赚点钱,所以寻做PCB设计的兼职的工作,也可以做PCB的库文件等,设计软件有PADS,PROTEL,allegro只会做库文件,我会认 ...…

查看全部问答>

最常用的随机算法(转载)

最常用的随机算法,C语言标准库函数的结果和这个一致这里是32位机用的,8位机自己加UL,改int为longint seed;void srand(int s){    seed = s;}int rand(){    seed = seed * 22695477 + 1;}…

查看全部问答>

前装行车记录仪电源设计方案

1、24V车、前装、车规试验; 2、外部完全断电情况下锂电池维持整机正常工作10分钟; 3、负载有...GPS、GPRS、语音播报、人界界面、SD卡、IC卡等等 …

查看全部问答>