今天帮同学改引导,原本打算改为开机grub引导的,没想到后来把他引导给搞没了233,特记这文章留念(误)
既然要讲grub,我们先把系统的启动流程说一下(注:现在基本都用efi,不讲mbr)
UEFI
EFI(Extensible Firmware Interface,可扩展硬件接口)有英特尔主导开发,是用模块化,高级语言(主要是C)构建的一个小型化系统,它和BIOS一样,主要在启动过程中完成硬件初始化
EFI发展至2.0时,英特尔将其转交给一个叫做Unified EFI Form
的国际组织,并改称为UEFI
或许比起UEFI,我们应该更熟悉BIOS这个名词.事实上,UEFI可以理解为BIOS的升级版
UEFI往往与GPT相配合使用,UEFI会寻找GPT硬盘中的ESP分区,并加载里面的efi文件,从而把控制权转交给bootloader
总的来说,UEFI为我们提供了这样的规范:
- 读取分区表(GPT或MBR)
- 访问某些特定文件系统中的文件(FAT系列文件系统,/EFI/SYSTEMNAME/XXX.efi文件)
- 执行特定格式的代码(efi文件固定规范的代码)
UEFI启动管理器
UEFI规范定义了名为UEFI启动管理器的一项功能,它的定义如下:”UEFI启动管理器是一种固件策略引擎,可通过修改固件架构中定义的全局NVRAM变量来进行配置.启动管理器将尝试按全局NVRAM变量定义的顺序依次加载UEFI驱动和UEFI应用程序(包括UEFI操作系统启动装载程序).”
简单来说,UEFI启动管理器可以管理UEFI的启动菜单,例如调整顺序,删除,添加.它最大的优点就是可以从上层系统修改UEFI的行为.在Linux中UEFI启动管理器叫做efibootmgr
例如:查看当前启动顺序
1 | # zhanghuidinah @ study in /boot/EFI [23:41:34] |
如上,可以看出启动顺序从前到后分别是:grub,Windows Boot Manager,USB等等
我的同学的情况是Windows Boot Manager的启动顺序先于grub,因此他的电脑一开机就直接进入Windows.如果想要默认进入grub的话,那么可以禁用Windows Boot Manager,或者调整grub优先于Windows Boot Manager
例:暂时禁用Windows Boot Manager:
1 | # zhanghuidinah @ study in /boot/EFI [23:41:39] |
例:调整Windows Boot Manager优先于grub
1 | $ sudo efibootmgr -o 0002,0001,3001,2001 |
GPT
GPT(GUID Partition Table,全局唯一标识磁盘分区表)是一个实体硬盘的分区表的结构布局的标准.它是可扩展固件接口(EFI)标准的一部分,被用于替代BIOS系统中的(MBR)分区表.UEFI规范要求UEFI兼容固件必须能识别GPT
GPT按LBA(逻辑区块地址,即扇区)划分,一般分为保护MBR部分和EFI部分;而EFI部分又可以分为4个区域:EFI信息区(GPT头),分区表,GPT分区,备份区域
ESP
MBR分区表使用前446个字节来存放bootloader,而GPT分区表则使用一个单独的分区,即ESP(EFI System Partition)分区
ESP是一个有着FAT文件系统的物理分区.支持EFI的电脑可以从ESP启动系统,EFI固件能从ESP中加载EFI启动程序
ESP分区有一个特殊的GUID号,EFI借此识别引导分区并使用此分区的bootloader引导系统:
1 | # zhanghuidinah @ study in /boot/EFI [23:20:02] |
可以看到,第2个分区就是ESP.因此,成为ESP有两个条件:
- code号为EF00
- 分区格式为FAT相关(这里是FAT32)
grub
grub(GRand Unified Bootloader)是一个GNU项目的多操作系统启动程序,也是目前使用最广泛的bootloader.注:bootloader的根本目的是启动内核
grub有grub和grub2两个版本,grub2是grub的重写改进版,已广泛应用于各类计算机,现在只能手机,嵌入式设备等小型计算机还在使用grub.以下grub即代指grub2
UEFI会在/EFI
文件夹中查找所有文件夹,并搜寻efi文件:
1 | # zhanghuidinah @ study in /boot/EFI [23:57:00] |
如上,除了Boot文件夹,还有grub文件夹和Microsoft文件夹,这也是开机启动顺序所显示的名称.而这两个文件夹则分别存放着grub和Windows Boot Manager这两个bootloader的efi文件:/EFI/grub/grubx64.efi
和/EFI/Miscosoft/Boot/bootmgfw.efi
当grubx64.efi
把grub程序加载至内存后,计算机将显示grub的主界面
安装grub
安装grub首先要确定有ESP,并将其挂载到一个目录中,例如/efi
然后,使用grub-install
命令生成grubx64.efi
文件,并将grub的模块放在/boot/grub/x86_64-efi/
:
1 | ]# grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id=grub_dir |
如上,将会生成/efi/EFI/grub_dir/grubx64.efi
文件
在安装后,还需要生成grub.cfg
文件.注意生成的行为实际上是综合了/etc/default/grub
的选项和/etc/grub.d/
里的脚本:
1 | ]# grub-mkconfig -o /boot/grub/grub.cfg |
往往不需要自己手动更新Windows的引导,grub-mkconfig
会执行/etc/grub.d/30_os-prober
脚本文件,该文件会搜寻所有可加载的内核,并生成启动项
小结
这次复习了一遍操作系统启动相关的知识,下次配置引导时应该不会失败了吧orz
最后用一张图总结一下:
1 | +-----+ |
补充
后来发现UEFI并非一定要需要/EFI/Boot/bootx64.efi
文件.当出现开机启动顺序时,可以看到一个叫做Internal Hard Disk or Solid State Disk
的选项,也就是从硬盘启动.如果选择从硬盘启动的话,那么UEFI才会加载该文件.它是计算机默认引导文件
事实上,bootx64.efi
是通用名,任何其他的引导文件都可以改成这个名称,放在/EFI/Boot
目录下,从而成为计算机默认引导文件.由于我的电脑最初安装的是Windows,所以bootx64.efi
就是bootmgfw.efi
1 | # zhanghuidinah @ study in /boot/EFI [8:10:00] |
如果是在U盘上写入grub的话,在使用grub-install
时需要添加--removable
选项(将grubx64.efi文件改名为bootx64.efi);如果之前已经安装过grub需要重装时,则需要添加--recheck
选项(删除原有grub相关的所有文件,再安装)
grub-install默认生成的grub文件夹在/boot目录下.又由于grub文件夹必须在esp中,这样esp就只能是/boot目录
如果想要esp和/boot目录相互独立,需要在使用grub-install命令时添加--boot-directory=DIR
参数,将grub文件夹指定于DIR/grub
目录