《深度探索Linux操作系统》笔记 第5章 从内核空间到用户空间

PS上电或复位后,处理器跳转到BIOS,开始执行BIOS,BIOS进行加电自检,初始化相关硬件,然后加载MBR到内存0X7C00处并跳转到该处,接由MBR中的程序完成操作系统的加载工作。

MBR只有512个字节大小,所以GRUB采用分阶段的策略,MBR中保存GRUB的第一阶段的代码,MBR中的代码不择把GRUB中剩余的部分加载到内存。

历史原因,磁盘第一个分区并不是紧挨着MBR,而是直接从下一个柱面的边界开始。于是GRUB的开发人员就利用这段空余把GRUB嵌入里面,但不是必须的。

GRUB在嵌入的镜像中包括了硬件以及文件系统的驱动,所以一旦嵌入的镜像加载到内存,BRU就可以访问文件系统,所以其他模块完全可以存储在文件系统上,通过文件系统的接口访问这些模块。所以GRUB镜像分为三个部分,MBR中的boot.img,嵌入空闲扇区的core.iimg,以及保存在系统系统中的模块。boot.img, core.img以读写磁盘扇区的方式访问,他们不属于任何一个磁盘分区,所以不会受到文件系统的影响。

boot.img的主要功能就是将core.img的第一个扇区载入内存,原因还是因为MBR只占用一个扇区512个字节。core.img的其余部分由core.img的第一个扇区加载。

boot.img利用BIOS提供的中断向量为0X13的基于扇区的磁盘读写服务。BIOS将kernel_sector扇区的内容载入内存,boot.img最后把读入的扇区内容移动到符号kernel_address所指示地址,并跳转到那里执行。

boot.img所在第一个扇区的内容为diskboot.img,diskboot.img用来加载core.img中除了自己之外的其他部分。diskboot.img需要知道core.img的其他部分所在的扇区,而只有在GRUB安装到磁盘时,才能知道core.img实际所占据的扇区。diskboot.img的最后12字节记录的一个blocklist,每个blocklist代表一个连续的扇区,记录这个扇区的起始扇区,扇区数量,以及扇区加载到内存的段地址。

如果GRUB采用的是嵌入式的安装放去,那么只要有一个blocklist就足够了,但如果使用非嵌入式的安装方式,core.img可能分块存储在磁盘其其他位置,因此diskboot.img可能存在多个blocklist。第一个blocklist位于diskboot.img的最后,每增加一个blocklist,向着diskboot.img开始的方向延伸。

为了控制core.img的大小,GRUB对core.img进行了压缩。因为boot.img中没有任何的解压代码,所以diskboot.img是不能被压缩的。GRUB只是将core.img中的kernel.img和其他模块进行了压缩。对于基于X86架构的PC,GRUB默认使用的是LZMA压缩算法。

GRUB将解压缩代码编译为lzma_decomress.img,链接在diskboot.img后面,diskboot.img将core.img加载进内存后,就跳转到lzma_decompress.img,执行其中的代码,解压缩core.img后面的压缩部分。

diskboot.img后跟的压缩模块中,紧跟kernel.img的为磁盘驱动模块biosdisk.mod,MBR分区模式模块part_msdos.mod,以及文件系统的驱动模块ext2.mod。

boot.img将diskboot.img加载到了0X8000处,diskboot.img加载完core.img剩余部分后,diskboot.img跳转到了地址0x8000+0x200处。

kernel.img的主入口函数是grub_main.

旅行是一种病。一旦感染了,你就再也无法摆脱。

《深度探索Linux操作系统》笔记 第5章  从内核空间到用户空间

相关文章:

你感兴趣的文章:

标签云: