如果你走入我们的内核之旅网站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文件的另一部分虚存映射,因为许可权指定这个私有区域可以被写,我们可以推断出它映射了程序的数据段。
类似地,从0x40000000、0x40015000开始的虚存区分别对应动态链接库/lib/ld-2.3.2.so的 代码段和数据段。从40016000开始的虚存区是匿名的,也就是说,它与任何文件都无关,可以推断出它映射了连接程序的bbs段(未初始化的数据段)。紧接着的三个区映射了C库程序/lib/libc-2.3.2.so的代码段、数据段和bss段。最后一个虚拟区是进程的堆栈。
通过这个简单的例子可以看出,一个进程的虚拟地址空间是由一个个的虚存区组成。对进程用户空间的管理在很大程度上依赖于对虚存区的管理,或者说,虚存区是虚存管理的基本单位。
相关阅读:
- 走入Linux内核社区 (陈莉君, 2008-6-04)
- 中断处理的tasklet(小任务)机制-不过如此 (陈莉君, 2008-6-11)
- 中断处理的工作队列机制-原来如此 (陈莉君, 2008-6-11)
- 解惑—Linux中的地址空间(一) (陈莉君, 2008-7-06)
- 解惑-Linux中的地址空间(二) (陈莉君, 2008-7-07)
- 解惑-Linux内核空间(二) (陈莉君, 2008-7-07)
- 解惑-Linux中的I/O空间 (陈莉君, 2008-7-14)
- 解惑-驱动开发中的I/O地址空间(三) (陈莉君, 2008-7-16)
- Linux中的段 (陈莉君, 2008-7-17)
- 挑战,一起分析Linux2.6设备驱动模型 (陈莉君, 2008-7-19)
论坛模式
推荐
收藏
分享给好友
管理
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 !!