Linux内核探讨-- 第七章
本文是个人分析《Linux内核设计与实现》而写的总结,欢迎转载,请注明出处:
http://blog.csdn.net/dlutbrucezhang/article/details/13621133
第七章--进程地址空间
内核运行在内核地址空间中,相应的,用户程序需要运行,肯定也需要地址空间,这其实是属于资源的。进程运行在自己的地址空间中,进程描述符中有指向这一地址的指针。线程没有自己独立的地址空间,所以,它和进程共享地址空间,也就是说线程的地址空间字段也是指向它所在进程的地址空间。
1.地址空间
内存区域也称为虚拟内存区域,它包含多个不同的内存对象。
代码段:可执行文件的内存映射
数据段:可执行文件已初始化的全局变量的内存映射
bss 段:可执行文件未初始化的全局变量的内存映射
进程的用户空间栈的零页内存映射
共享库的代码段,数据段和bss段也会包含在进程的地址空间中
。。。。。。
2.内存描述符
为了更好的理解进程的地址空间,首先贴出它的数据结构,之后再简单的介绍其中的字段。
struct mm_struct { struct vm_area_struct *mmap; //list of VMA rb_root_t mm_rb; //指向vma段红黑树的指针 struct vm_area_struct *mmap_cache; //last find_vma result 存储上一次查询的操作的结果 pgd_t *pgd; //进程页目录的起始地址 atomic_t mm_users; //how many users with user space atomic_t mm_count; //how many reference to "struct mm_struct" int map_count; //Number of VMA struct rw_semaphore mmap_sem; //对mmap操作的互赤信号量 spinlock_t page_table_lock; //Protects task page tables and mm->rss struct list_head mmlist; //list of all active mm's. These are globally together off init_mm.mmlist,and are protected by mmlist_lock unsigned long start_code,end_code,start_data,end_data; unsigned long start_brk,brk,start_stack; unsigned long arg_start,arg_end,env_start,env_end; unsigned long rss,total_vm,locked_vm; //rss进程内容驻留在物理内存的页面地址 unsigned long def_flags; unsigned long cpu_vm_mask; unsigned long swap_address; //页面换出过程用到交换空间地址 unsigned dumpable:1; //Architecture-specific MM context mm_context_t context; //存放着当前进程使用的段起始地址 };
从中我们可以看出,进程中确实包含了代码段,数据段,bss端,栈等内存区域。对于每一个内存区域,都有着一致的属性描述,例如,映射的物理内存,权限(可读,可写,可执行)等。
3.mm_struct 和内核线程
由于内核线程不会访问用户的地址空间,所以,它并不存在地址空间,但是这个字段又不能为空,所以,为了效率,Linux的设计方案是一旦内核线程执行,那么它就用前一个执行进程的地址空间字段,这当然包含了进程的页表,内核线程虽然不会访问用户地址空间,但是仍然需要与内核交互。