s3c2440_MMU(1)

来源:互联网 发布:澳洲工资算法 编辑:程序博客网 时间:2024/06/08 00:26

MMU(Memory Management Unit)的功能作用:

1.实现虚拟内存:将系统的物理存储器重新编址,可将其看成一个独立于系统物理存储器的虚拟存储空间。因此,可以将MMU看做是一种转换器,把程序和数据的虚拟地址(编译时的连接地址)转换成实际的物理地址。这种虚拟内存管理让每一个任务(进程)都认为自己拥有整块虚拟地址空间。

我们知道windows和Linux操作系统都可以实现多任务同时进行,其实这里的“同时”只是相对的,一个时刻,CPU上只能有一个程序在跑。这个“同时”可以靠时钟中断来实现。在一个时钟中断(事先设定好响应时间周期)到来时,若有另外一个任务要执行,调用一次任务调度函数,从上一刻执行的A任务进入B任务实现任务(进程)的切换,相当于两个任务轮流进行,这样就完成宏观上的“同时”。在切换任务时需要把现场保存到任务状态段中(TTS)以便下次的继续加载。当然在时钟中断未到来其间CPU为了能够及时响应外部信号的中断,它会每执行完一条指令就检查一次一些标记状态的寄存器的值。

看下面这两个程序:这两个打印变量的值和虚拟地址的任务同时在进行,打印结果a的值不一样,说明这两段代码分别放在内存的不同区域,而虚拟地址都是0x18ff44,这反映出相同的虚拟地址是可以映射到不同的物理地址的,因为这相同的虚拟地址不在同一个时刻发生映射。如果遇到这样一种情况,就是不仅有下面这两个小的进程在不断地跑,还有几个很大的进程也要跑,可是我的内存空间不够一次性装载所有进程的代码,怎么保证所有的进程都能够顺利进行呢?我们知道一个时刻只有一个进程,这个进程的虚拟地址映射到一块物理内存上,因此可以借助这个虚拟地址将物理内存上不常用到的数据临时保存到磁盘上,这就腾出了一些内存空间。

printf_1.c

#include<stdio.h>int main(void){int a;a=1;printf("a=%d  ,  a_addr=%x\n",a,&a);while(1);//保证一直在执行return 0;}
执行结果:



printf_2.c

#include<stdio.h>int main(void){int a;a=2;printf("a=%d  ,  a_addr=%x\n",a,&a);while(1);return 0;}
执行结果:

此外,虚拟地址到物理地址的映射还可以解决一个问题:通常情况下有足够大的内存空间,却没有足够大的连续的内存空间,这时就可以将这些分散的大小不一的内存空间映射到一块连续的够大的虚拟地址上。



2.实现内存的保护:将某一块内存进行保护,以此来实现只读、只写和可读可写。我想这是嵌入式系统中MMU的主要功能了。

32位的Linux操作系统的虚拟地址空间是0x0000,0000~0xffff,ffff,共4G。可以将0x0000,0000~0xbfff,ffff的3G地址空间用来加载用户模式下的程序,而后面1G的地址空间用来加载特权模式下的处理程序(即内核文件)。各种工作模式只能访问对应的地址,一旦访问非法地址就会造成该程序的崩溃。

关于实现内存的保护这里不做多讲,可以参考李云的博客——“至简李云”:MMU的作用http://yunli.blog.51cto.com/831344/189787


0 0