文档介绍:《计算机操作系统》课程设计报告
课题名称:
Linux操作系统初始化过程分析
姓名(学号):
史苏豪(0830332120)
同组人:
江耀(0830332114)
杨毅(0830332123)
完成时间:
2011-6-28
一、课题目的
Linux初始化过程分析
二、个人承担的任务
Linux初始化(第一阶段)分析
三、分析过程
从startp_32开始的汇编代码在arch/i386/kemel/,这就是初始化的第一阶段。
首先将CPU中除CS以外所有的段寄存器。即%ds、%cs。%fs以及%gs,设置成__KERNEL_DS,,而RPL则为0。引导辅助程序在转入startup_32之前转杯下了一个个临时的全局段描述表,表中相应的描述项给出基地址为0,也就是使用线性地址。
不管是主CPU还是次CPU,在Linux内核中都要进入页式映射模式运行。暂时以物理地址取指令虽然是可以的,但足不能在代码中向符号地址作绝对转移或调用于程序,因此终非长久之计,所以,要尽快准备好页面映射表并开启CPU的页面映射机制。代码中的86~。这个页而表在内存中,是由所有CPU公用的,所以只由丰CPU进行初始化,次CPU则要跳过这一小段代代码(见57--58 行以及76和8O行)。此外,对于次CPU这里还有个小插曲,那就是如果系统支持PSF/PAE,即36位地址模式的话还要相应地设置其控制寄存器%cr4(77--79行)。
常数__PAGE__OFFSET为系统空间的虚拟地址与物理地址之间的差距,定义于include/asm-i386/:
可见,pg0在地址(相对于程序的起点,见下面)为Ox2000的地方。这个页面映射表中的表项依次设置为0x7、0x1007、0x2007等等。其中最低的三位均为1,表示页面为用户页面,可写,并且页面的内容在内存中。映射的目标,即物理页面的某地址,则分别为0x0、0x10000、0x2000等等,也就是物理内存中的页面0、1、2等等。映射表的大小是两个页面,即2K个表项,所以代表着一块8MB的存储空问,这就是Linux内核对内存大小的最低限度要求。
这里的392行利用汇编提供的功能在其所在的位置上填入776个目录项,每个目录项的大小为4个字节,内容为 0。同样,397行业填入254个这样的目录项。这里引用的几个常数均定义于include/asm-i386/
这里的常数__PAGE_OFFSET是0xC000000,所以BOOT_USER_PGD_PTRS为768,而BOOT_KERNEL_PGD_PTRS则为256。一个页面目录的大小是4KB,含有1024个日录项,共代表着4GB的虚存空间。Linux内核以3GB为界把整个虚存空间分成用户空间和系统空间两部分。所以,页面目录中的低768个目录项用于用户空间的映射,而高256个目录项用于系统空间的映射。在初始的页面目录swapper_pg_dir 中,用户空间和系统空间都只映射了开头的两个目录项(390--391行以及394--395行),即8MB的空间,而且有着相同的映射,即指向相同的面州映射表。这样,以符号地址empty_zero .page为例,在连接内核映像时这个地址显然是安排在0xC0000000以上的空间,而物理上却是装入在(cmpty_zero_page - OxC0000000)的地址上。所以,若在未开启页式映射之前要引用这个符号,就要从中减击位移量__PAGE_OFFSET见86行和9l行。可见,一旦开启页式映射以后,冉要引用这个符号时就可以(而且应该)直接引用了。冉来看日录顶的内容,以394行为例,这个目录项指向物理地址0x00102000,这是在1MB以上的区间中,实际上就是pg0的物理地址。前面403和404指定pg0的起点地址为0x2000,那是假定整个内核映像是从地址0开始时的起点,而现在内核映像放在从地址0x00100000开始的地方,pg0的起点也就相应地变成了
0x00102000。
那么,为什么在虚存空间的低区,即本来应该属于用户空问的位置上(390-391行)也要放上同样的目录项呢?简而言之是为了平稳过渡。如上所述,CPU进入startup_32()以后是以物理地址来取指令的。在这种情况下,如果映射目录只包括系统空问,即虚存空间高区的映射,而不包括虚存空间低区的映射,则一旦开启页式映射以后就不能继续执行了,因为此时CPU中的取指令指针IP仍指向低区,