场景1:BIOS+MBR+GRUB2
首先,BIOS是什么,存在什么地方,起什么作用?
BIOS 是主板的Flash memory(早期是ROM)上存放的程序。在现代的计算机中,其作用是加载操作系统。上电后,BIOS程序就会被加载到内存中并执行。BIOS程序会提供配置界面,设置启动设备的顺序。当然,还有其他的一些配置功能。
图片来源:What BIOS Does - How BIOS Works | HowStuffWorks
MBR又是什么呢?
MBR全名Master Boot Record,是启动盘的第一个扇区中的数据。第一个扇区即sector 0,每个扇区的大小为512字节,因此MBR的大小即为512字节。MBR中存放了Bootloader和分区表的信息。
MBR 512字节的数据分布
GRUB2
GRUB2是GRUB(GRand Unified Bootloader)的第二个版本。GRUB是当前通用的Bootloader,其作用是加载操作系统。
GRUB 有Stage1, Stage1.5和Stage2.0 这3个阶段的bootloader
GRUB2 只有Stage1和Stage2两个阶段的Bootloader。Stage1.5和Stage2一起合并成为Stage2了
Grub install的时候,会把boot.img和core.img分别安装到磁盘对应的位置上
如何判断磁盘分区类型是MBR的?
如果Disk label type是 dos的,这说明是使用MBR
BIOS+MBR+GRUB2的启动流程
BIOS+ MBR+GRUB2 启动过程 | ||
大阶段 | 小阶段 | 解释 |
BIOS | POST(上电自检) | 上电后,CPU执行NVRAM 或ROM固件中的程序(BIOS),BIOS首先会对硬件进行检查 |
加载BootLoader | 最后BIOS找到启动盘的第一个sector(512字节),加载其中的Bootloader程序到内存中,并让CPU执行此程序。 BIOS中可设置启动顺序。 | |
GRUB2 | Stage1 | 执行BIOS中配置的启动盘MBR中的primary boot loader程序(512字节长的MBR的前446 字节),primary boot loader程序即为Grub Stage1 boot loader,其中包含GRUB的位置信息,名字叫boot.img,此信息是grub-setup 写道磁盘的第一个sector中的。 Stage1很小,无法识别文件系统,其任务是加载Stage2 |
Stage2(grub2去掉了stage1.5) | GRUB Stage1.5 Boot loader一般安装在MBR和第一个分区之间。MBR是第一个sector,它和第一个分区的起始sector之间,还有62个空闲的sector,这里一般放置GRUB;或者在磁盘的某个特定位置。 GRUB1.5名字叫core.img,能识别到标准的文件系统如ext4等,但是不能识别逻辑卷。 core.img是GRUB2的内核镜像,它根据diskboot.img、kernel.img和一系列的模块被grub2-mkimage程序动态创建,一般情况下他已经包含足够的模块去访问/boot/grub,模块机制使得内核镜像能保持很小的尺寸。在某种程度上,它可以被视为 GRUB 中的 stage2。 diskboot.img:从硬盘启动时,core.img中的第一个扇区的内容就是diskboot.img。diskboo.img的作用是读取core.img中剩余的部分到内存中,并将控制权交给kernel.img,由于此时还不识别文件系统,所以将core.img的全部位置以block列表的方式编码,使得diskboot.img能够找到剩余的内容。 kernel.img:kernel.img文件包含了grub的基本运行时环境:设备框架、文件句柄、环境变量、救援模式下的命令行解析器等等。很少直接使用它,因为它们已经整个嵌入到了core.img中了。注意,kernel.img是grub的kernel,和操作系统的内核无关 Stage2能识别到ext4文件系统,根据/boot/grub2/grub.cfg显示启动项,然后根据对应的启动项加载内核和initrd到内存,之后让CPU执行内核的程序 | |
内核启动...(略) |
BIOS和MBR是80年代计算机技术的产物,沿用至今,自然有很多不足之处。
BIOS的缺点:
1) 启动时只能使用MBR中的512字节,由于空间原因,启动项等信息,也无法存在放在MBR中,而必须另外加载其他的代码来呈现启动选择项。
2) BIOS本身无法读取文件系统。
MBR的缺点:
1,使用第0个扇区中的64字节来保存分区表,只能最多有4个分区,如果要超过4个分区只能使用扩展分区;每个分区记录中有4个字节用于记录起始sector号,因此最大的起始sector只能是2^32 sector即4294967296个sectors,每个sector 512字节,则总大小为2199023255552字节,大约为2TB。所以,MBR限制了磁盘大小为2TB,大于2TB的磁盘空间,实际就浪费了。
2,分区表仅有一份,一旦损坏则无法恢复。
因为有如上缺点,所以才需要推出新一代的技术。这个新一代的技术则是UEFI+GPT
场景2:UEFI+GPT+GRUB2
UEFI也是存在在主板Flash存储上的一段程序,用于取代BIOS,作为上电后启动计算机的初始程序。UEFI是一套指定计算机固件和操作系统交互接口的标准。
UEFI主要改进点:
1,UEFI可识别分区表和文件系统。
2,UEFI允许多个bootloader
3,支持安全启动(Secure Boot)
4,支持在操作系统内直接配置UEFI启动项,而不只是在启动操作系统前才能配置。
GPT对应于MBR,全名 GUID Partition Table,它是一种新的分区表的标准。GPT是EFI标准的一部分。
GPT主要改进点:
1,使用第2到第33扇区一共32个扇区共16384 字节来记录分区表的条目,每个条目占128字节,在这128字节中,有8个字节来表示起始的扇区号。因此,GPT上的分区数目可以有128个,可以使用的磁盘大小可以达到2的64次方个扇区大小,即 18446744073709551616个扇区,每个扇区512字节,达到8ZB。 ZB对于现在的硬盘来说,几乎是无限大,具体可见下图:
2,GPT使用在磁盘的开头有主分区表,在磁盘的最末尾还有备份分区表;而且GPT还对分区表做CRC校验,如果分区表损坏了可以检查出来。
如何判断一个磁盘是不是GPT分区表的磁盘?
可以直接用fdisk或者parted命令查看,如果分区表是GPT,则会在Partition Table字段显示。
如果是不是UEFI启动的?
两种方式,如果fdisk 或者parted查到有一个分区是EFI System Partition,则说明是UEFI启动方式
或者使用efibootmgr命令能查到到当前启动的BOOT选择项,则说明是UEFI启动的
UEFI+ GPT+GRUB2 启动过程
UEFI+ GPT+GRUB2 启动过程 | ||
大阶段 | 小阶段 | 解释 |
UEFI | POST(上电自检) | 上电后,CPU执行NVRAM 的程序(UEFI),UEFI首先会对硬件进行检查 |
加载BootLoader | UEFI可以识别分区以及FAT文件系统如FAT32,UEFI启动条目中可定义分区上创建的FAT文件系统中bootloader文件的路径。UEFI会加载此bootloader到内存,并让CPU执行此bootloader程序。如果找不到bootloader,fallback的bootloader是EFI分区的:EFI/BOOT/bootx64.efi GPT分区表中可以设置分区的类别和名称,设置为EFI System Partition的分区,会被Firmware用于启动。 如: # Start End Size Type Name 1 2048 411647 200M EFI System EFI System Partition | |
GRUB2 | 不区分Stage | Bootloader根据同目录下的grub.cfg文件,显示启动项,然后根据使用的启动项加载内核和initrd到内存,然后执行内核程序。 |
内核启动...(略) |
UEFI BOOT Manager
在操作系统中可以使用efibootmgr查看和管理UEFI的启动项。具体的使用方法可以查看此命令的手册
这跟在启动OS前,在Boot Manager中可以进行管理是等效的
为什么可以在操作系统里对固件程序进行操作呢?
Efibootmgr对UEFI的管理是通过/sys/firmware/efi/vars,这些变量对应于 NVRAM variables. 因此,UEFI支持在OS中直接配置UEFI的启动项,这种能力对BIOS来说是不存在的。
Boot000是第一个磁盘的第一个分区,但是没执行具体的bootloader文件路径。UEFI会到这个分区去找/EFI/BOOT/BOOT{machine type short-name}.EFI文件。
可以查看0004启动项的内容
可以看到这个就是启动项0004
另外,还可以在操作查看固件是多少位的
UEFI SHELL
相比BIOS,UEFI提供了一个SHELL界面,可以在找不到可用启动项时使用。
尝试构造一个问题,把EFI目录给重命名了:
[root@localhost efi]# mv EFI/ EFI_bak
[root@localhost efi]# sync
[root@localhost efi]# reboot
由于找不到启动盘,系统进入如下界面:
选择EFI SHELL
然后就进入UEFI SHELL界面(VMWARE虚拟机需要选择一下,泰山服务器会直接到这界面):
fs0就是efi分区,进入此分区
可以看到目录被重命名了,所以UEFI按照启动项中指定的路径,找不到bootloader
尝试将目录改名回来后,执行BootLoader启动
系统就正常启动了
UEFI SHELL还有很多命令可以使用,有兴趣可以参考
UEFI常见命令:
https://www.cadnetwork.de/attachments/article/30/EFI_Instructions.pdf
故障处理
故障1:MBR中Stage1 Bootloader丢失
故障构造
破坏MBR中的stage1 grub bootloader(boot.img)
查看
破坏前446字节,保留分区表,只破坏Stage1 bootloader
恢复方法
挂载光盘后重启,由于无法通过硬盘启动,虚拟机会启动到如下界面
选择Troubleshooting
再选择进入救援模式
救援模式会使用挂载的ISO中的内核启动
选择1,继续
回车,进入SHELL
改变root目录到/mnt/sysimage
然后安装grub2的boot loader
在重启虚拟机,之后就正常了
故障2: GRUB2的Stage2 Bootloader被破坏
故障构造
将第1到第62扇区的数据全部写成0,保留第0扇区数据。
重启后,因为BIOS能找到启动盘,所以会进入启动流程;但是由于Stage2的Bootloader有问题,因此虚拟机会一直卡在这里:
恢复方法
挂在ISO后,在启动界面按Esc进入bios 启动管理菜单
进入bios 启动菜单,选择CD ROM,回车
然后选择Troubleshooting
再选择进入救援模式
其他进入方式一样
修复方式也一样:
重启虚拟机
就能看到GRUB的启动项页面了
故障3:MBR 分区表损坏
本来没有想构造这一场景,由于命令用错,导致分区表被清空。不过正好试一下恢复方法,成功恢复,现网如遇到就可以直接用了。
故障构造
这里的skip是指跳过input的第一个block。实际上,应该把skip改为seek。所以,0-62扇区的内容全部都被清空了,包括0号扇区中的分区表。
所以,当我进入救援模式恢复时,看到提示说没有分区,同时切换root目录的操作也失败了。
恢复方法
执行fdisk /dev/sda
然后参考原来保存的fdisk -l /dev/sda结果添加分区
检查是否添加OK
重启后,再次进入救援模式,就能挂上了。
然后重装grub2 bootloader
重启:
检查文件都还是在的
故障4 UEFI的bootloader丢失
故障构造
直接重命名或者删除shimx64.efi文件
启动时报如下错误
恢复方法
情况1 服务器可登录时
1,上传ISO到服务器上,创建一个本地的yum源,方法简单,可百度。
2,执行如下命令修复
# yum reinstall grub2-efi grub2-efi-modules shim
命令执行完了可以看到文件已经重新生成
如果grub.cfg文件也丢失,可以执行如下命令重新生成
情况2 服务器不可登录时
挂载ISO,光盘启动,进入Troubleshooting
选择进入救援模式
进入SHELL
创建一个目录,将ISO挂载上去
切换root目录到/mnt/sysimage
修改yum repo的配置文件
清理
然后重新生成grub2的EFI文件系统中的bootloader文件
然后重启虚拟机后就恢复了