LiNUX内存原理的一点理解

最近看了一点关于内核的书籍,有些收获,现在拿出来与大家分享,不当之处请指教

模式转换

linux在引导的过程的前半段运行于实时模式,程序运行使用的是物理地址,如0X9000,指的就是物理地址的
0X9000。后半段转入保护模式使用的是虚拟地址。虚拟地址转化的开关在CR1寄存器,虚拟地址转化的基础是程序建立了页目录,页表机制。就是虚拟地址通过页目录,页表映射到相应的物理地址。

虚拟地址
   32位机的寻址空间(虚拟地址)为4G,其中0-3G为用户空间,3G-4G为系统空间。在用户看来,我们的程序就像是运行在4G空间的内存上。而且各个进程可以使用相同的虚拟地址,而不会互相干扰。其实就是操作系统在玩的一个把戏,偷梁换柱,例如程序甲用的是 0x1000,程序乙用的也是 0x1000
而操作系统可能把甲用的0x1000指向了物理内存的0X01000000,而将乙用的0x1000指向了物理内存的0X02000000。

转换原理
   Linux采用的是三级映射机制即:页目录,中间页表,页表。而i386支持是两级,所以中间页表
不起作用,视为透明。虚拟地址转换为实际的物理地址是由硬件MMU自动完成的,具体的过程是,由寄存器CR3取得页目录的地址,按照虚拟地址的22-31位数值(作为位移)取得页表的地址,按照页表地址加上虚拟地址的12-21位(作为位移)取得页表的数值(物理页地址),按照物理页地址加上虚拟地址0-11位数值(作为位移)取得相应的物理地址,完成转换。

虚拟地址的状态
   每一个进程都有一套自己的页表,页表描述的空间为0-4G。系统空间也有自己的页表,描述空间
为0-4G,但是0-3G全部初始化为0,只在3G-4G进行了映射,采用的方式为线形映射,如0xC0009000指的就是物理内存的0x00009000,xC0029000指的就是物理内存的0x00029000。

   进程在运行过程中不论在系统空间运行还是在用户空间运行均使用自己的页表,而所有的进程的页表 3G-4G空间均为相同映射。

   在进程切换的时候CR3会由下一个进程的页目录地址进驻。从而当切换为下一个因为而所有的进程的页表 3G-4G空间均为相同映射,所以不论CR3怎样切换,那么内核都能正常运行。

虚拟内存的管理

   为了对虚拟内存进行管理,每个进程有一个mm_struct结构和一些vm_area_struct,前者是对一个
进程的虚拟内存的一个总体描述,后者是对进程的各个内存区域的描述。

由于LINUX采用的是分页制,而对于CPU提供的分段制,可以理解系统进行了直接的穿透

以上参考了 毛德操 胡希明的《Linux内核源代码情景分析》,真是一本好书

你可能感兴趣的:(Linux内核探索)