1. 进程虚拟地址空间
进程的虚拟地址空间记录在其task_struct结构的指针成员mm中(struct mm_struct),这是用户态进程才有的,里面包含pgd、代码段、堆、栈地址等信息。(kernel不需要mm,因为kernel不需要引用动态库,内核线程有自己的栈空间,虚拟地址映射关系也是全局可见的,注意vmalloc和kmap产生的映射是由内核中的全局变量swapper_pg_dir和pkmap_page_table记录的,无论当前哪个用户进程处于活动状态,虚拟地址空间内核部分的内容总是相同的。)
mm有一个名为mmap的指针,它指向一个链表,链表每一个元素都是vm_area_struct结构,称为VMA。这个链表的每一段(每个元素)都是这个进程的一个虚拟地址空间。
也就是说,一个进程的地址空间都是一段一段的,通过pmap pid命令、/proc/pid/maps、/proc/pid/smaps都能看出一个进程的虚拟地址空间分布情况,第三个看得最仔细,其中的每一个(虚拟地址)连续的段都对应一个VMA,例如代码段、数据段、BSS、堆、动态库的内存映射、栈空间等。
root@jac:~# cat /proc/1750/maps
00008000-0000b000 r-xp 00000000 1f:06 537 /bin/test
00013000-00014000 rw-p 00003000 1f:06 537 /bin/test
0186a000-0187c000 rw-p 00000000 00:00 0 [heap]
4004b000-40052000 r-xp 00000000 1f:06 436 /lib/ld-uClibc.so.0
40059000-4005a000 rw-p 00006000 1f:06