对于i386体系结构,要求分段。linux的处理方式是分为了内核代码段(__kernel_cs),内核数据段(__kernel_ds), 用户代码段(__user_cs),用户数据段(__user_ds).
为了填充i386的段寄存器,这4个段对应的段描述符存放在GDT中。2,3,4,5对应是GDT[2],GDT[3],GDT[4],GDT[5]就是填充段寄存器的内容。段寄存器在linux里面主要用于指明当前的代码执行级别0是内核,执行级别3是用户,还指明了是内核还是用户段。
对于某个进程的一个虚拟地址:
0000 1000 0000 0100 1000 0101 0110 1000
|
- 首先,从task_struct中取出mm_struct * mm,
- 然后,mm_struct 取出pgd_t *pgd 这个页表地址数组的地址。用虚拟地址的高10位作为下标32,去查询对应的页表的地址,就是pt=pgd[32],
- 然后,用虚拟地址的接下来的10位做为下标72,去查询页表,得到pt[72],里面存的就是物理页框号。
- 最后,同虚拟地址的最低12位和已经查到的页框号得出物理地址,pt[72]<<12 +
0101 0110 1000.
层次关系:
task_struct
mm_struct
vm_area_struct
|
在系统初始化的阶段,内核根据检测到的物理内存大小,为每一个页面都建立一个page结构,形成一个page结构的数组,并使用一个全局变量mem_map指向这个数组。同时,又按照需要将这些页面拼合成物理地址连续的许多内存页面的“块”,再根据块的大小建立起若干“管理区”zone,而在每个管理区设置一些空闲块队列,以便物理内存页面的分配使用。
阅读(1000) | 评论(0) | 转发(1) |