如果你走入我们的内核之旅网站http://www.kerneltravel.net/ ,静下心阅读并动手实践,或许,流逝的时间,让你手捧沉甸甸的果实。 欢迎在讨论区http://www.lupaworld.com/bbs/forum-255-1.html提问。 如果你希望加入Linux内核学习圈,请到http://blog.chinaunix.net/group/group_1475.html

进程的虚存区VMA-虚存管理的基本单元

上一篇 / 下一篇  2008-07-21 17:32:12 / 个人分类:释义Linux内核

查看( 887 ) / 评论( 3 )
问:高级语言编程中所说的全局变量区,栈区,代码区,未初始化数据区是不是就是靠x86中的段来管理的?对于一个进程来说他们在逻辑上是不是连续的?

答:   高级语言编程中所说的全局变量区,栈区,代码区,未初始化数据区,其实在Linux对应的不是Intel的这种段(因为Linux几乎没怎么理会Intel的段机制),而是对应虚拟地址空间的VMA(Virtual  memory Area),在内核中对应vma_area_struct结构。


下面举例说明(摘自《Linux操作系统原理与应用》一书)

如前所述,进程的用户空间中包含代码段、数据段、堆栈段等程序段。mm_struct结构中相应域描述了各个段的起始地址和终止地址。现在,我们通过一个简单的例子来描述Linux内核是如何把共享库及各个程序段映射到进程的用户空间的。我们照样假设用户进程的地址空间范围从0x00000000 到0xbfffffff。我们考虑一个最简单的C程序exam.c:
int main()
{
     printf(“ virtual area test!”);
}
  假定这个程序编译连接后的可执行代码位于/home/test/目录下, 则这个进程对应的虚存区如表1所示(可以从/proc/[pid]/maps 得到这些信息,pid为该进程的标识号)。注意,这里列出的所有区都是私有虚存映射(在许可权列出现的字母p)。这是因为,这些虚存区的存在仅仅是为了给进程提供数据;当进程执行指令时,可以修改这些虚存区的内容,但与它们相关的磁盘上的文件保持不变,这就是私有虚存映射所起的保护作用。

表1exam进程的虚存区

地址范围


许可权


偏移量


所映射的文件


08048000-08049000


r-xp


00000000


/home/test/exam


08049000-0804a000


rw-p


00001000


/home/test/exam


40000000-40015000


r-xp


00000000


/lib/ld-2.3.2.so


40015000-40016000


rw-p


00015000

/lib/ld-2.3.2.so


40016000-40017000


rw-p


00000000

匿名


4002a000-40159000


r-xp


00000000

/lib/libc-2.3.2.so


40159000-4015e000


rw-p


0012f000

/lib/libc-2.3.2.so


4015e000-40160000


rw-p


00000000

匿名


bfffe000-c0000000


rwxp


fffff000

匿名



    从0x8048000开始的虚存区是/home/test/exam文件的某一部分的虚存映射,范围从0到0x1000字节。许可权指定这个区域是可执行的(包含目标代码)、只读的(不可写,因为指令执行期间不能改变),并且是私有的,因此我们可以猜出这个区域映射了程序的代码段。
    从0x8049000开始的虚存区是/home/test/exam文件的另一部分虚存映射,因为许可权指定这个私有区域可以被写,我们可以推断出它映射了程序的数据段。

     类似地,从0x400000000x40015000开始的虚存区分别对应动态链接库/lib/ld-2.3.2.so 代码段和数据段。从40016000开始的虚存区是匿名的,也就是说,它与任何文件都无关,可以推断出它映射了连接程序的bbs段(未初始化的数据段)。紧接着的三个区映射了C库程序/lib/libc-2.3.2.so的代码段、数据段和bss段。最后一个虚拟区是进程的堆栈。



   通过这个简单的例子可以看出,一个进程的虚拟地址空间是由一个个的虚存区组成。对进程用户空间的管理在很大程度上依赖于对虚存区的管理,或者说,虚存区是虚存管理的基本单位。






TAG:

0xjdeng324发布于2008-07-22 22:24:02
多谢陈老师的解惑,弄明白这个问题了,这个社区很好。正在看陈老师您翻译的那本书ulk3.
lizhaohui1120发布于2008-07-27 15:03:00
疑问?
陈老师,你上一篇提到:在elf格式的可执行代码中,ld总是从0x8000000开始安排程序的“代码段”,那0x8000000是什么地址啊?那程序执行时在物理内存中的实际地址如何分配的?每个进程的实际分配的物理内存如何避免冲突?谢谢!
小刺猬发布于2008-08-09 17:49:27
恩 不错  楼上那位lizhaohui1120兄弟  这个问题就是Linux 内存管理解决的主要问题啊  RFSC !!
我来说两句

(可选)

Open Toolbar