基于Grub 2.00的x86内核引导流程--源代码情景分析(2)

2. 基于Grub2.00的x86内核引导流程

有了磁盘简介的铺垫,现切入主题Grub 2.00内核引导源代码分析。整个分析过程基本都是一个逆向分析的过程,先介绍其用法及相关描述[1],然后分析Makefile以确定生成某个可执行文件的依赖链,从而得出其对应的源文件,最后分析源文件解析其动作。

 


[1]对描述中涉及到英文的部分,为保留原意不致扭曲而不做翻译。毕竟在GNU Grub和Linux内核源代码中,所有文档注释都是英文描述。所以,英语,x86汇编语言,Makefile是内核开发过程中绕不过去的坎。

基于Grub 2.00的x86内核引导流程--源代码情景分析(2)_第1张图片

  • Stage 1: boot.img is stored in the master bootrecord (MBR) or optionally in any of the volume boot records (VBRs), because a PC bootsector is 512 bytes, the size of boot.img is exactly 512 bytes. And it addressesthe next stage by an LBA48 address (For LBA 48bit addressing, the1024-cylinder limitation of GRUB legacy is avoided); the sole function of`boot.img' is to load the first sector of core.img from a local disk andjump to it.
  • Stage 1.5: core.img is by default written to thesectors between the MBR and the first partition, when these sectors are freeand available. For legacy reasons, the first partition of a hard drive does notbegin at sector 1 (counting begins with 0) but at sector 63, leaving a gap of62 sectors of empty space. That space is not part of any partition or filesystem, and therefore not prone to any problems related with it. Onceexecuted, core.img will load its configuration file and any othermodules needed, particularly file system drivers; at installation time, it is generatedfrom diskboot.img and configured to load the stage 2 byits file path.
  • Stage 2: files belonging to the stage 2 areall being held in the /boot/grub directory, which is a subdirectory ofthe /boot directory specified by the Filesystem Hierarchy Standard (FHS).

Grub的x86源代码主要分为四个部分,分别为位于目录grub-core/boot/i386/pc下的boot.S, diskboot.S, startup_raw.S,以及grub-core/kern目录下的Grub main.c主模块相关代码 。

2.1 Stage 1: boot.img分析

GNU的软件工程基本都依赖于Makefile去描述一个可执行文件的来龙去脉,由其编译过程可以整理出某个可执行文件的诞生过程:由哪些源文件编译,然后链接哪些库,以及还可能额外存在的二进制文件操作,比如objcopy,strip等等。为了弄清楚boot.img的来龙去脉,需要理顺boot.img在Makefile中的依赖链:

基于Grub 2.00的x86内核引导流程--源代码情景分析(2)_第2张图片

基于Grub 2.00的x86内核引导流程--源代码情景分析(2)_第3张图片

由Makefile中的依赖链条可知:MBR中存放的bootloader的源代码就是boot.S,当然在编译过程中还涉及到一些其他细节,在此就不再展开。

 

先来分析boot.S。我原本打算摘一些重要的代码片段出来分析,但是之后发现boot.S中的代码是一个一气呵成的执行流,彼此之间相互铺垫但又甚是简洁明了。鉴于boot.S是MBR中的bootloader,我们有时候好奇在加电开机的瞬间到底发生了什么,操作系统到底是怎么一步步被引导起来的,下面就是加电开机“宇宙大爆炸”的瞬间:

基于Grub 2.00的x86内核引导流程--源代码情景分析(2)_第4张图片

基于Grub 2.00的x86内核引导流程--源代码情景分析(2)_第5张图片

基于Grub 2.00的x86内核引导流程--源代码情景分析(2)_第6张图片

基于Grub 2.00的x86内核引导流程--源代码情景分析(2)_第7张图片

基于Grub 2.00的x86内核引导流程--源代码情景分析(2)_第8张图片

基于Grub 2.00的x86内核引导流程--源代码情景分析(2)_第9张图片

基于Grub 2.00的x86内核引导流程--源代码情景分析(2)_第10张图片

基于Grub 2.00的x86内核引导流程--源代码情景分析(2)_第11张图片

基于Grub 2.00的x86内核引导流程--源代码情景分析(2)_第12张图片

基于Grub 2.00的x86内核引导流程--源代码情景分析(2)_第13张图片

基于Grub 2.00的x86内核引导流程--源代码情景分析(2)_第14张图片

结论:MBR中的boot.S,其唯一功能是加载硬盘第二个扇区的内容到内存中,并跳转至其入口函数继续执行。如是更加深入理解之前Stage1中对boot.img的描述:”the sole function of `boot.img' is to load the first sectorof core.img from a local disk and jump to it”



你可能感兴趣的:(Linux,Kernel)