分类: LINUX
2010-07-14 16:56:51
一)进程与虚拟内存的概念
1)Linux中的每个进程都有它自己的私有虚拟空间,内核空间对所有的进程是公共的.运行在内核模式下的进程都可以看到同样的内存空间.
2)每个进程都有自己的用户空间,用户空间从0开始,有一个固定的上限,在32位体系的计算机预留3GB给用户空间,1GB给内核空间.
3)3G(用户空间)/1G(内核空间)的限制只限于32位且没有启用PAE的系统.
二)pmap与内存映射分析
新建测试程序pause.c,这个程序什么都不做,以便我们查看它的内存映像.
[root@test1 ~]# vi pause.c
int main ()
{
return pause();
}
编译pause.c
[root@test1 ~]# gcc pause.c -o pause
执行pause程序
[root@test1 ~]# ./pause &
[2] 2955
查看PID为2955的内存映射
[root@test1 ~]# pmap -x 2955
2955: ./pause
Address Kbytes RSS Anon Locked Mode Mapping
00110000 4 - - - r-x-- [ anon ]
00b51000 100 - - - r-x-- ld-2.5.so
00b6a000 4 - - - r-x-- ld-2.5.so
00b6b000 4 - - - rwx-- ld-2.5.so
00b6e000 1244 - - - r-x-- libc-2.5.so
00ca5000 8 - - - r-x-- libc-2.5.so
00ca7000 4 - - - rwx-- libc-2.5.so
00ca8000 12 - - - rwx-- [ anon ]
08048000 4 - - - r-x-- pause
08049000 4 - - - rw--- pause
b7ef9000 4 - - - rw--- [ anon ]
b7f0e000 4 - - - rw--- [ anon ]
bfb0c000 88 - - - rw--- [ stack ]
-------- ------- ------- ------- -------
total kB 1484 - - -
分析:
pmap命令列出了所涉及到的虚拟地址和这些段的大小,Address是段的起始地址,Kbytes为段的大小,最小为4KB.
mode表示权限,mapping是与进程相关的文件.
虽然进程什么也没做,但它还是占用了1.4MB的虚拟内存,其中大部分都是C的标准库.
这里的libc-2.5.so占用了1.2MB的虚拟内存,而且是只读的,但是它被整个系统的所有进程所共享.也就是说,整个系统中这个库只占用了1.1MB的物理内存.
如果用pmap -x 1来打印init进程的映射关系,你将会发现,进程加载libc-2.5.so库的内存物理地址也是00b6e000,与pause程序一致.
另外,在00ca8000和08048000地址之间有一个巨大的裂缝,这表明进程实际要用的空间比能申请到的空间要大.
新建汇编程序pause.s测试,与上一例不同的是这里是手动的系统调用.
[root@test1 ~]# vi pause.s
.text
.global _start
.type _start, @function
sighdlr:
ret
_start:
movl $sighdlr, %ecx
movl $18, %ebx
movl $48, %eax
int $0x80
movl $29, %eax
int $0x80
movl $0,%ebx
movl $1,%eax
int $0x80
编译pause.s汇编程序
[root@test1 ~]# gcc -nostdlib -o pause pause.s
[root@test1 ~]# ./pause &
[1] 30203
查看PID为30203的进程映射
[root@test1 ~]# pmap -x 30203
30203: ./pause
Address Kbytes RSS Anon Locked Mode Mapping
00fc6000 4 - - - r-x-- [ anon ]
08048000 4 - - - r-x-- pause
bf860000 84 - - - rwx-- [ stack ]
-------- ------- ------- ------- -------
total kB 92 - - -
这里我们看到了映射了三个段.
pause是exec的系统调用,exec将代码映射到一个只读的页内,页地址为0x08048000.
[ stack ]是这个进程分配最大的一块,为84KB,它是exec建立的一个栈.
[ anon ]是anonymous映射Linux2.6中新的部分,用于在IA32上更有效地进行系统调用.
通过pmap -d PID可以查看映射文件所处的device信息,如下
[root@test1 ~]# pmap -d 2965
2965: ./pause
Address Kbytes Mode Offset Device Mapping
00110000 4 r-x-- 0000000000110000 000:00000 [ anon ]
00b51000 100 r-x-- 0000000000000000 008:00001 ld-2.5.so
00b6a000 4 r-x-- 0000000000018000 008:00001 ld-2.5.so
00b6b000 4 rwx-- 0000000000019000 008:00001 ld-2.5.so
00b6e000 1244 r-x-- 0000000000000000 008:00001 libc-2.5.so
00ca5000 8 r-x-- 0000000000137000 008:00001 libc-2.5.so
00ca7000 4 rwx-- 0000000000139000 008:00001 libc-2.5.so
00ca8000 12 rwx-- 0000000000ca8000 000:00000 [ anon ]
08048000 4 r-x-- 0000000000000000 008:00001 pause
08049000 4 rw--- 0000000000000000 008:00001 pause
b7ef9000 4 rw--- 00000000b7ef9000 000:00000 [ anon ]
b7f0e000 4 rw--- 00000000b7f0e000 000:00000 [ anon ]
bfb0c000 88 rw--- 00000000bfb0c000 000:00000 [ stack ]
mapped: 1484K writeable/private: 120K shared: 0K
分析
008:00001是指主设备节点8,从设备节点1,也就是sda1设备.
[ anon ]和[ stack ]没有设备节点.
同样的,我们查看/proc/PID/maps也可以看到相关的进程信息.
cat /proc/2965/maps
00110000-00111000 r-xp 00110000 00:00 0 [vdso]
00b51000-00b6a000 r-xp 00000000 08:01 3704501 /lib/ld-2.5.so
00b6a000-00b6b000 r-xp 00018000 08:01 3704501 /lib/ld-2.5.so
00b6b000-00b6c000 rwxp 00019000 08:01 3704501 /lib/ld-2.5.so
00b6e000-00ca5000 r-xp 00000000 08:01 3704502 /lib/libc-2.5.so
00ca5000-00ca7000 r-xp 00137000 08:01 3704502 /lib/libc-2.5.so
00ca7000-00ca8000 rwxp 00139000 08:01 3704502 /lib/libc-2.5.so
00ca8000-00cab000 rwxp 00ca8000 00:00 0
08048000-08049000 r-xp 00000000 08:01 327684 /root/pause
08049000-0804a000 rw-p 00000000 08:01 327684 /root/pause
b7ef9000-b7efa000 rw-p b7ef9000 00:00 0
b7f0e000-b7f0f000 rw-p b7f0e000 00:00 0
bfb0c000-bfb22000 rw-p bfb0c000 00:00 0 [stack]
三)PAE技术
最后我们说下PAE技术,PAE技术是Intel公司推出的,全称是Physical Address Extensions,也就是物理地址扩展.
它有以下的特点:
1)页面地址从20bit扩大到24bit,偏移量仍然是12bit,有效物理地址是36bit
2)总的寻址为64GB(2的36次方)的RAM.
3)CR3在非PAE系统上指向页目录表在PAE系统中,它指向目录指针表的基地址(目录指针表是新的页表级别,简称PDPT).
4)在启用PAE系统时,一个物理地址映射要经过页目录指针表/页目录/页表/页表项,最后找到其物理地址.
5)在启用PAE寻址时,虚拟地址/线性地址还是32位,物理地址为36位,虚拟地址的格式为:
位31和30:指向PDPT中4项中的一项.
位29-21:指向页目录中512个项中的一个.
位20-12:指向页表中512项中的一个.
位11-0:4KB页中的偏移量.