Chinaunix首页 | 论坛 | 博客
  • 博客访问: 469145
  • 博文数量: 134
  • 博客积分: 3056
  • 博客等级: 中校
  • 技术积分: 1150
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-14 15:53
文章分类
文章存档

2013年(1)

2010年(133)

我的朋友

分类: 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页中的偏移量.

阅读(1516) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~