深入理解 GNU GRUB - 01

转载注明出处(cppgp: http://blog.csdn.net/cppgp )

 

1. 概述

1.1 GRUB是什么
GNU GRUB是一款多重引导程序。简单来讲,引导程序是计算机开机运行的第一个软件,它的使命是装载操作系统并运行。实际上,由于平台、存储介质、操作系统、文件系统等的多样性,引导程序都很复杂,同时,引导程序要求有更高安全性、健壮性。
GNU GRUB支持多平台(例如X86、PowerPC等)、多存储介质(例如硬盘、软盘、光盘、U盘)、多操作系统(例如Linux、Gnu Hurd等)、多重引导(例如Windows等)、多文件系统(例如Ext2、Ext3、Ext4、FAT32、NTFS)。支持模块化扩展,可按照配置文件及命令行方式加载操作系统。以下是一些设计引导程序基本概念及标准的文档:
•    Multiboot: http://www.gnu.org/software/grub/manual/multiboot/
•    Multiboot-with-GRUB : http://tldp.org/HOWTO/Multiboot-with-GRUB.html
本文对GRUB (grub-1.98) 实现进行跟踪和分析。为简化流程,我们做如下假定:
•    Intel i386兼容系列CPU;
•    硬盘引导, GRUB安装在硬盘中,并且使用主引导记录MBSR(Master Boot Record)。

1.2 系统启动过程

当计算机开机时,所有电子元器件都处于随机状态。此时一个特殊的硬件电路产生复位脉冲信号RESET,经CPU复位引脚进入CPU,CPU检测到RESET信号后,设置某些寄存器为预定值,其中寄存器CS和IP被预置为CS:IP=0xF000:FFF0,并让CPU在实模式下运行,可知CPU将执行地址0xFFFF0处代码。硬件电路把地址0xFFFF0映射到ROM中, ROM上保存有BIOS(Basic Input/Output System)例程。BIOS例程完成通电自检(POST,Power-on-self-test)、硬件初始化、读取CMOS配置,并提供一组中断驱动的低级过程供操作系统启动时使用。BIOS初始化完成后,将搜索一个操作系统来启动,按照用户配置,这个过程试图访问软盘、光盘、磁盘、USB、FLASH等存储芯片。在找到一个有效设备后,BIOS把该设备主引导记录(MBR,或者称作分区扇区,是0柱面0磁头1扇区,LBA下称为0扇区,512字节)的内容拷贝到RAM中物理地址为0x7C00的位置,然后跳转至CS:IP=0x0000:0x7C00执行来自MBR的代码。一个有效设备MBR中最后两个字节的值为0x AA 55。MBR分为三部分,分别是指令代码、分区表DPT (Disk Partition Table) 、幻数0x AA 55。 一般在MBR中存放引导程序的一部分,由这部分指令读取引导程序剩余部分,加载整个引导程序到内存并继续运行引导程序。引导程序查询可引导的操作系统列表,提供给用户选择,或者在超过一个预设的时间值后,加载默认的操作系统项。操作系统加载完毕后,计算机执行权限交给操作系统,而引导程序则功成身退。

1.3 GRUB 1.98加载流程
安装在硬盘中的GRUB,完整的加载到内存中需要三步:
1.    BIOS加载主引导记录MBR(512字节)到内存0x7C00~0x7DFF位置,并跳转执行0x7C00处指令。这些指令设置堆栈(SP=0x2000),探测硬盘/软盘读取模式(LBA/CHS)并保存。无论LBA或者CHS,都将加载另一扇区(该扇区位置在安装过程中确定)代码到内存0x7000位置,然后拷贝到内存0x8000处。跳转至0x8000执行。这部分指令由grub-1.98/boot/i386/pc/boot.S生成。
2.    0x8000~0x81FF处存放第一步中加载的扇区。这部分代码利用第一步中保存的读取模式(mode)、以及堆栈(0x2000),以及安装时指定的扇区位置和扇区数,循环加载GRUB剩余部分到内存0x8200开始的位置。在循环加载时,对于每次迭代,都是先加载到内存0x7000处,然后拷贝到从0x8200开始的正确位置。这部分指令由grub-1.98/boot/i386/pc/diskboot.S生成,在安装过程中,grub-mkimage更改扇区参数块值(0x1F4~0x1FF)为实际参数。
3.    0x8200~x(x<0x10000) 处存放第二步中加载的指令。这部分指令是一个包含自解压算法lzma的压缩包(启动和解压缩部分是未压缩的,对应为startup.S和lzma_decode.S文件)。GRUB在这里进入CPU保护模式,自解压并释放到0x10000开始内存处,解压完成后再拷贝回原来位置,然后调用grub_main,grub_main位于未见grub-1.98/kern/main.c,grub_main初始化系统,加载模块,并进入normal或者rescue模式。GRUB将根据配置文件或者用户输入,加载操作系统并运行。
如果主引导记录MBR被别的引导程序(或者操作系统)占用,则由这个引导程序(或者操作系统)负责加载GRUB所在分区的首扇区到内存0x7C00~0x7DFF,此后的处理完全一致。例如通过Windows引导Linux的双系统,假定GRUB安装在sda6(扩展分区),Windows允许配置引导部分,加载sda6分区表所在扇区到内存0x7C00~0x7DFF并执行,此后的情况和前面所述就完全一致了。至于Windows下配置引导的方法比较简单, Win7下使用EasyBCD,XP下直接编辑C:/boot.ini文件并使用GRUB4DOS(只需要grldr、menu.ls两个文件)就可实现,网上资料很多,这里就不再深入描述了。

  • 1
    点赞
  • 0
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

打赏
文章很值,打赏犒劳作者一下
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页

打赏

cppgp

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者