第一次写读书笔记,有什么套路呢?还没来得及去学习。《linux kernel的设计与实现》真的是一本好书,里面的东西解答了很多工作中的疑问。如显示地调用schedule()进行调度,系统调用__syscalln(),一些数据结构函数经常在kernel 协议栈中遇到,中断注册和中断上下文,软中断,tasklet,锁,定时器,内存管理slab...
第15章 进程地址空间
进程只能访问有效内存区域内的内存地址。每个内存区域也具有相关权限如对相关进程有可读、可写、可执行属性。如果一个进程访问了不在有效范围中的内存区域,或以不正确的方式访问来有有效地址,那么内核就会终止该进程,并返回“Segmentation Fault”这个经典的错误。内存区域包含内存对象如:
-可执行文件代码的内存映射,称为代码段(text section);
-可执行文件的已初始化全局变量的内存映射,称为数据段(data section);
-包含未初始化全局变量,也就是bss段的零页(页面中的信息全部为0值,所以可用于映射bss段等目的)的内存映射;(bss段,因为未初始化的变量没有对应的值,所以并不需要存放在可执行对象中,但是C标准强制规定未初始化的全局变量要被赋予特殊的默认值,所以内核要将变量(未被赋值的)从可执行代码载入内存中,然后将零页映射到该片内存上,于是这些未初始化变量就被赋予了0值,这样做避免了在目标文件中显示地进行初始化,减少了空间浪费)。
-用于进程用户空间栈的零页的内存映射;
-每一个诸如C库或动态连接程序等共享库的代码段、数据段和bss段也会被载入进程的地址空间。
内核使用内存描述符结构体表示进程的地址空间,该结构包含了和进程地址空间有关的全部信息。内存描述符由mm_struct结构体表示,定义在文件<linux/sched.h>中,所有的mm_struct结构体通过自身的mmlist域连接中一个双向链表中,该链表的首元素是init_mm内存描述符,代表init进程的地址空间。
内存区域(VMA)由vm_area_struct结构体描述,包含相关的mm_struct结构体域。进程的地址空间通过mmap和mm_rb(红-黑树)描述包含的全部内存区域。
可以使用/proc文件系统和pmap(1)工具查看给定进程的内存空间和其中包含的内存区域。
mmap()和do_mmap()创建进程的地址空间。内核使用do_mmap(),用户空间使用mmap()。
当用程序访问一个虚拟地址时,必须将虚拟地址转化为物理地址,地址的转换通过页表才能完成。Linux中使用三级页表转换地址。
未完待续...