天涯共此良辰时

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

一、Grub2的基本认识

(1)Grub2的起源

  GRUB起源于1995年,当时Erich Boleyn想尝试使用Utah大学研发的Mach4微内核(现在被称为GNU Mach)引导GNU Hurd。由于当时互不兼容的个人计算机引导方案,Erich和Brain Ford一起设计出了多重引导规范。

  Erich刚开始去修改FreeBSD的引导加载器让其能兼容多重启动,但他很快就意识到应当自己编写一个更容易且简单的引导加载程序,而不是继续坚持在FreeBSD的引导加载器上做改动,因此GRUB诞生了。Erich给GRUB添加了许多特性,但是它与生俱来的优势使得其能够迅速满足扩大的用户需求。1999年,Gorden Matzigkeit和Yoshinori K.Okuji采用GRUB作为正式的GNU软件包,并通过匿名CVS去开放它的源代码从而让项目去发展更新。接下来的几年里,GRUB与它的扩展也满足了许多要求,但很快GRUB就暴露出它固有的缺陷(本身并不能很好的兼容其扩展设计的问题),同时GRUB的维护者们也意识到很难在不破坏现有功能的基础上进行修补。于是大约在2002年,Yoshinori K.Okuji开始了PUPA(初步通用编程体系架构GNU GRUB)的工作,就是为了重写GRUB的核心以使其更简洁,更安全,更健壮,更强大。PUPA最终被命名为GRUB2,以前的GRUB版本被重新命名为Grub Legacy。少量的人员被继续留下来开发Grub Legacy,但是最后一个版本是2005年(0.97),也基本成为了最终版本。

  在2007年左右,GNU/Linux发行版开始使用Grub2,2009年之后大多数发行版厂商默认安装Grub2。

(2)Grub2的优点

  1)认识并支持更多的文件系统,并且可以通过Grub2的主程序直接在文件系统中搜寻kernel文件;

  2)开机的时候,可以“自行编辑与修改开机设置项目”,即在线编辑功能;

  3)可以动态搜寻配置文件,而不需要在修改配置文件后重新加载Grub2,即下次开机之后就会生效;

(3)Centos7中GRUB2初探

  1.   查看GRUB2的版本

      [root@lnmp ~]$ rpm -qa |grep 'grub2'          # 查看系统Grub2的版本
       grub2-2.02-0.65.el7.centos.2.x86_64

  2.   查看GRUB2相关文件(/boot/grub2/*)   

    [root@lnmp /boot/grub2/i386-pc]$ ls -lhrt *.img        # Grub由几个image组成
    -rw-r--r--. 1 root root 27K Sep 7 2020 core.img
    -rw-r--r--. 1 root root 512 Sep 7 2020 boot.img       # boot.img大小固定为512Byte

    

    [root@lnmp /boot/grub2/i386-pc]$ file boot.img          # 查看img文件类型
    boot.img: x86 boot sector; partition 4: ID=0xd4, starthead 205, startsector 4277266767, 0 sectors, code offset 0x63         # x86 boot sector 表明x86架构下的boot sector

(4)GRUB2的bootstrap image文件初探

   Centos7系统/boot/grub2/i386-pc/*目录下存在许多image镜像文件,这些文件会被grub2-install命令安装到硬盘的相应位置。当BIOS执行完毕后,就会被加载并引导系统完成启动。

   1.   boot.img

    boot.img是Grub2第一个被运行的程序,它被写入到MBR(Master Boot Record),固定大小为512B。boot.img功能很简单,主要是读取磁盘中core.img中的第一个扇区(sector)到内存中并执行相应的代码,因为仅有512B,boot.img不能够加载文件系统,并且只能从硬盘固定的位置加载。

   2.  diskboot.img

    当从硬盘启动的时候这是core.img第一个扇区(sector)的内容,主要功能是读取剩下的core.img到内存中并开始运行kernel.img。同样diskboot.img没有文件系统的功能,当读取剩余的core.img时候,依然从硬盘固定位置读取。

   3.  kernel.img

    GRUB2正确运行的基本组成:对设备及文件的处理框架,环境变量,恢复模式下的命令行等等。此模块很少被直接使用,一般是core.img中必不可少的一部分。

   4.  core.img

    core.img是GRUB2的核心,包含了kernel.img及一些必要的modules,通常core.img包含了足够的模块(modules)为了访问xfs/ext4文件系统/boot/grub2目录,并且从/boot/grub2下加载所有剩余的模块,这些模块包含了启动目录处理,加载操作系统等等功能。目前disk限制core.img安装必须小于32KB,core.img一般被安装在硬盘特殊区域:embedding area。

   5.  *.mod

    大部分模块会被core.img在运行时自动动态加载,其中小部分被整合到core.img中,比如文件系统xfs.mod等。

(5)GRUB2与GRUB Legacy之间的对比

   很多人都熟悉 GRUB2 Legacy里面的stage1、stage1.5、stage2等概念,而在GRUB2里面,这些都被各种bootstrap image文件代替。

  1.  stage1相当于boot.img完成的功能。
  2.  stage1.5相当于core.img,但是core.img功能更加强大,在不加载其他模块的情况下,提供修复shell操作。
  3.  state2相当于加载modules。

 二、磁盘的基本认识

(1)磁盘的两种寻址方式

  1. CHS(cylinders-heads-sectors):CHS寻址模式将磁盘划分为磁头(Heads)、柱面(Cylinder)、扇区(Sector),其中MBR地址为0柱面、0磁头、1扇区。【基本不再使用】
  2. LBA(Logical Block Address):LBA是非常简单的一种寻址方式(从0开始编号来定位区块,依次类推),其中MBR地址为LBA0。

(2)boot.img和core.img安装

  1. 拷贝boot.img到LBA0的MBR引导代码中
  2. 拷贝core.img到LBA1-LBA31中空闲代码中

(3)硬盘的逻辑结构

 

三、Grub2启动过程

(1)boot.img

  •  Step1 无条件跳转  jmp short 0x7c65
  •     Step2  初始化    

    DL初始化为0x80

    ax清零,ds赋值0,ss赋值0

    sp初始化化为0x2000

  •    Step3  判断硬盘是否支持LBA还是只支持CHS

    在加载后续GRUB2 core.img之前,系统必须判断硬盘是否支持LBA还是只支持CHS。备注目前普遍采用LBA模式,因此本文只讨论此模式。

  •     Step4 采用LBA加载core.img第一个扇区

    调用BIOS INT14把硬盘LBA1的512字节传输到内存0x7000:[0x0000]位置

  •     Step5 拷贝core.img第一个扇区到内存的指定位置

    把core.img第一个扇区从内存0x7000位置拷贝到0x8000位置

 Q:为啥不直接将MBR加载到内存的0x80000位置?

 A:在多个位置使用相同的代码或者将多个代码加载到同一个位置

  1)多个位置重用相同的代码可以减少维护的成本负担

  2)某些特定的机器或者媒介不仅仅只加载512个字节,比如CD代码总是加载2048字节的倍数,那么调用者可以只需复制它所需要的量,也可以选择使用偏移量

  •   Step6 执行core.img第一条语句

  总结:

  boot.img的主要功能就是将硬盘LBA1(0柱面,0磁道,2扇区)的512字节加载到内存0x80000处。这部分代码就是core.img的第一个扇区内容,一般都是GRUB2的diskboot.img。

(2)core.img

  其中core.img包含diskboot.img,kernel.img以及*.mod模块

  •  diskboot.img

  1)Step1  初始化

  2)Step2  从硬盘读取core.img第二个扇区开始的其余若干扇区。该部分的数据依然拷贝至内存0x7000:[0x0000]处-【物理地址:0x70000】

  3)Step3  拷贝缓冲区。将Step2部门的内存数据拷贝至0x0820:[0x0000]处-【物理地址:0x8200】

  4)Step4  跳转至core.img其实地址0x8200开始执行

  总结:disboot.img主要功能就是件LBA2-LBA67的硬盘内容拷贝至内存0x8200位置。

  那么LBA2-LBA67这部分内容是什么?

  1)开始部分是startup的代码

  2)后一部分是压缩的core.img核心代码

  至此,diskboot.img完成任务,由core.img中的startup接收

  • GRUB2 core Startup包括两部分:Startup_raw和Startup

  1)Startup_raw - 此段代码必须加载至0x8200

    I   Step1  初始化

    II  Step2   进入保护模式

    III Step3   解压core.img

    IV Step4   跳转核心代码

  2)Startup - 此段代码必须加载到0x00100000

    I   Step1  初始化

    II  Step2  调用grub_main进入grub的主函数

  • GRUB主函数main.c,即GRUB主要功能

    I   各种模块的加载

    II  读取 /boot/grub2/grub.cfg 显示启动菜单

    III  根据以上菜单配置加载 linux kernel

menuentry 'My_CentOS Linux (3.10.0-862.el7.x86_64) 7 (Core)' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-862.el7.x86_64-advanced-a9b65ac9-e434-4628-b5eb-0d547de76ce9' {
load_video
set gfxpayload=keep
insmod gzio
insmod part_msdos
insmod xfs
set root='hd0,msdos1'
if [ x$feature_platform_search_hint = xy ]; then
search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1' 6798c33b-1978-4b25-a465-189df158ff27
else
search --no-floppy --fs-uuid --set=root 6798c33b-1978-4b25-a465-189df158ff27
fi
linux16 /vmlinuz-3.10.0-862.el7.x86_64 root=/dev/mapper/centos_centos-root ro rd.lvm.lv=centos_centos/root  # 加载内核 rd.lvm.lv=centos_centos/swap biosdevname=0 net.ifnames=0 rhgb quiet LANG=en_US.UTF-8
initrd16 /initramfs-3.10.0-862.el7.x86_64.img  # 加载虚拟文件系统
}

备注:加载的这两个文件都在/boot目录下,可以用file命令查看文件类型。可以肯定,这个GRUB已经有了文件系统(Centos07的XFS)驱动,不会调用BIOS INT13去加载这两个文件,而是直接在XFS文件系统/boot目录下加载。

/* 实际上准备linux内核启动参数,在配置文件后面的参数都是可以传到内核中

* root:指出启动的根文件系统

* rhgb:redhat graphics boot就是会看到图片来代替启动过程中显示的文件信息

* quet:将kernel log level设置为KERN_WARNING

* lang:缺省语言

*/

  1)Step1 linux16  加载内核与自定义配置参数

  2)Step2 initrd16   加载虚拟文件系统

  3)Step3 boot  加载

  •     kernel.img

    Linux kernel的start()是当Kernel被grub2加载后,kernel的第一个入口方法,其地址为the kernel entry point is 9020:0000。

    

 

    本文仅仅是对https://max.book118.com/html/2017/0918/134263842.shtm的整理,感谢原创!

posted on 2022-06-08 22:20  天涯共此良辰时  阅读(337)  评论(0编辑  收藏  举报