15.1
进程只能访问有效内存区域的内存地址,每个内存地址都有相关权限可以让相关进程可读、可写、可执行。如果一个内存访问了不在有效范围内的内存区域时,或以不正确的方式访问内存区域,内核会终止该进程。并报段错误。
有效内存中的对象有:
-可执行文件代码的内存映射,称为代码段/文本段。
-已初始化的全局或静态变量的内存映射,称为数据段;
-未初始化的全局或静态数据的零页映射,称为bss段;
-用于进程用户空间栈的零页内存映射,栈段;
-每一个诸如C库或动态链接库等共享库的代码段、数据段和bss段也会被载入进程地址空间;
-任何内存映射文件;
-任何共享内存段;
-任何匿名的内存映射,比如由malloc()申请的内存;
其中后4个都是堆区。
15.2 内存描述符
mm_struct
内核使用内存描述符结构体表示进程的地址空间,该结构包含了和进程地址空间有关的全部信息。用mm_struct表示。
其中mm_users成员表示该地址空间的进程引用数;
其中mmap和mm_rb都表示地址空间的各个内存对象,前者用链表表示,后者用红黑树表示;
所有的mm_struct结构体都通过自身的mmlist域连接在一个双向链表中,该链表首元素是init_mm内存描述符,它表示init的地址空间;
mmlist_lock用于访问上述链表时的同步控制。
task_struct的mm域指向了进程的内存描述符,current->mm,mm_struct结构体也存储在slab高速缓存中。
共享mm_struct即共享了地址空间。
内核线程没有地址空间,它们的mm域为NULL。
当进程调度时,context_switch()调用switch_mm(),即新调度进程的mm域指向的地址空间被载入内存。内核线程设为NULL。
地址空间由多个虚拟地址区域组成:vm_area_struct,上述的mm_struct的mmap和mm_rb成员即时这种对象的链表和红黑树结构。
创建地址空间:mmap()和do_mmap()
Unix接口的mmap与之类似。
do_mmap系统调用,指定了文件、文件偏移、地址空间地址、长度、权限标志、flag等。
访问权限有:可读、可写、可执行、不可访问;PROT_READ,PROT_WRITE,PROT_EXEC,PROT_NONE
flag有:共享、不共享、可执行、锁住、在IO操作上不阻塞等;MAP_SHARED,MAP_PRIVATE,MAP_EXECUTABLE,MAP_LOCKED,MAP_NONBLOCK。
删除地址空间:do_munmap和munmap
页表: