首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

嵌入式Linux之我行——ARM MMU工作原理剖析

嵌入式Linux之我行——ARM MMU工作原理剖析

虚拟地址和物理地址的概念
    CPU通过地址来访问内存中的单元,地址有虚拟地址和物理地址之分,如果CPU没有MMU(Memory Management Unit,内存管理单元),或者有MMU但没有启用,CPU核在取指令或访问内存时发出的地址将直接传到CPU芯片的外部地址引脚上,直接被内存芯片(以下称为物理内存,以便与虚拟内存区分)接收,这称为物理地址(Physical Address,以下简称PA),如下图所示。

    图 1. 物理地址示意图

    如果CPU启用了MMU,CPU核发出的地址将被MMU截获,从CPU到MMU的地址称为虚拟地址(Virtual Address,以下简称VA),而MMU将这个地址翻译成另一个地址发到CPU芯片的外部地址引脚上,也就是将虚拟地址映射成物理地址,如下图所示[1]。

    图 2. 虚拟地址示意图

    MMU将虚拟地址映射到物理地址是以页(Page)为单位的,对于32位CPU通常一页为4K。例如,虚拟地址0xb700 1000~0xb700 1fff是一个页,可能被MMU映射到物理地址0x2000~0x2fff,物理内存中的一个物理页面也称为一个页框(Page Frame)。
    思考与练习
    1 以下程序中用到的BASEADDR是虚拟地址还是物理地址?
#define BASEADDR 0x00008000;
int i;
unsigned int *p;
p = (unsigned int *)BASEADDR;
for(i=0;i<100;i++)
{
*(p + i) = i;
}
    2 下图中内存芯片的地址范围是多少?这个地址范围是指虚拟地址还是物理地址的范围?

    图 3. 练习题

虚拟内存管理
    现代操作系统充分利用MMU提供的VA到PA的映射机制来做内存管理,以下称为虚拟内存管理(Virtual Memory Management)。首先看下面的例子:
$ ps
PID TTY TIME CMD
9612 pts/2 00:00:00 bash
32070 pts/2 00:00:00 ps
$ pmap 9612
9612: bash
08048000 668K r-x-- /bin/bash
080ef000 24K rw--- /bin/bash
080f5000 2056K rw--- [ anon ]
b7c6d000 36K r-x-- /lib/tls/i686/cmov/libnss_files-2.7.so
b7c76000 8K rw--- /lib/tls/i686/cmov/libnss_files-2.7.so
b7c78000 32K r-x-- /lib/tls/i686/cmov/libnss_nis-2.7.so
b7c80000 8K rw--- /lib/tls/i686/cmov/libnss_nis-2.7.so
b7c82000 80K r-x-- /lib/tls/i686/cmov/libnsl-2.7.so
b7c96000 8K rw--- /lib/tls/i686/cmov/libnsl-2.7.so
b7c98000 8K rw--- [ anon ]
b7c9a000 28K r-x-- /lib/tls/i686/cmov/libnss_compat-2.7.so
b7ca1000 8K rw--- /lib/tls/i686/cmov/libnss_compat-2.7.so
b7cb4000 252K r---- /usr/lib/locale/en_US.utf8/LC_CTYPE
b7cf3000 900K r---- /usr/lib/locale/en_US.utf8/LC_COLLATE
b7dd4000 4K rw--- [ anon ]
b7dd5000 1316K r-x-- /lib/tls/i686/cmov/libc-2.7.so
b7f1e000 4K r---- /lib/tls/i686/cmov/libc-2.7.so
b7f1f000 8K rw--- /lib/tls/i686/cmov/libc-2.7.so
b7f21000 16K rw--- [ anon ]
b7f25000 8K r-x-- /lib/tls/i686/cmov/libdl-2.7.so
b7f27000 8K rw--- /lib/tls/i686/cmov/libdl-2.7.so
b7f29000 180K r-x-- /lib/libncurses.so.5.6
b7f56000 12K rw--- /lib/libncurses.so.5.6
b7f59000 4K r---- /usr/lib/locale/en_US.utf8/LC_NUMERIC
b7f5a000 4K r---- /usr/lib/locale/en_US.utf8/LC_TIME
b7f5b000 4K r---- /usr/lib/locale/en_US.utf8/LC_MONETARY
b7f5c000 4K r---- /usr/lib/locale/en_US.utf8/LC_MESSAGES/SYS_LC_MESSAGES
b7f5d000 4K r---- /usr/lib/locale/en_US.utf8/LC_PAPER
b7f5e000 4K r---- /usr/lib/locale/en_US.utf8/LC_NAME
b7f5f000 4K r---- /usr/lib/locale/en_US.utf8/LC_ADDRESS
b7f60000 4K r---- /usr/lib/locale/en_US.utf8/LC_TELEPHONE
b7f61000 4K r---- /usr/lib/locale/en_US.utf8/LC_MEASUREMENT
b7f62000 28K r--s- /usr/lib/gconv/gconv-modules.cache
b7f69000 4K r---- /usr/lib/locale/en_US.utf8/LC_IDENTIFICATION
b7f6a000 8K rw--- [ anon ]
b7f6c000 4K r-x-- [ anon ]
b7f6d000 104K r-x-- /lib/ld-2.7.so
b7f87000 8K rw--- /lib/ld-2.7.so
bfad4000 84K rw--- [ stack ]
total 5948K
    例 1. 进程的地址空间
    这是bash进程的虚拟地址空间,32位CPU的虚拟地址空间是4GB,也就是0x0000 0000-0xffff ffff,该进程占用的地址范围近似为0x0000 0000-0xbfff ffff,地址范围0xc000 0000-0xffff ffff由内核占用,用户进程不允许访问。在这个bash进程的地址空间中,从0x0804 8000开始的668K的权限为r-x--,表示代码段,从0x080e f000开始的24K的权限是rw---,表示数据段,从0x080f 5000开始的2056K的权限也是rw---,但是没有对应任何磁盘文件,而是用[ anon ](anonymous,匿名)来表示,这是堆所占的空间,从0xb7c6 d000开始是共享库和资源文件的映射空间,每个共享库也分为代码段和数据段,用不同的权限表示,可以看到,从堆空间到下面的共享库映射空间之间有很大的地址空洞,最末从0xbfad 4000开始的84K是栈空间。
继承事业,薪火相传
返回列表