GRUB2在UEFI下引导系统

关于UEFI的启动流程

  1. UEFI主机开机后会搜索所有磁盘的第一个fat32分区下看是否存在/efi/boot/bootia32.efi或者bootx64.efi,如果存在则添加这个启动项

  2. UEFI通过执行磁盘的第一个fat32分区下的/efi/boot/bootia32.efi或者bootx64.efi来实现对系统的引导

  3. boot[ia32][x64].efi它只是一个规定,任意efi文件改成boot[ia32][x64].efi都会在启动项被选择时加载并执行

  4. Windows是由bootmgfw.efi引导启动,Linux一般是由grubx64.efi引导启动

  5. 当然你也可以使用efibootmgr之类的工具手动创建efi文件在其他路径的启动项

  6. 有的UEFI默认 startup.nsh 为初始启动脚本,内容可以为:fs0:\efi\boot\bootx64.efi

Debian下GRUB的安装

  1. 安装grub的管理工具及本体
1
sudo apt install grub-common grub2-common grub-efi-amd64-bin grub-efi-ia32-bin
  1. 使用grub-install安装GRUB到指定位置
1
2
3
4
5
6
7
8
9
10
11
sudo grub-install --target=x86_64-efi --efi-directory=/mnt/ --removable	

--target=x86_64-efi # 要安装的架构,x86_64-efi和i386-efi
--efi-directory=/mnt/ # 安装到哪里,有bootloader-id的话是/mnt/EFI/<bootloader-id>/下
--bootloader-id=GRUB # 使用efibootmgr添加一个名叫GRUB的启动项
--removable # 安装到/EFI/BOOT/下以便在多台设备上运行
--directory= # 模块所在路径,Debian默认/usr/lib/grub/<platform>

# 安装后的shimx64.efi和BOOTX64.EFI其实是同一个东西
# /mnt/EFI/GRUB/BOOTX64.CSV grub.cfg fbx64.efi grubx64.efi mmx64.efi shimx64.efi
# /mnt/EFI/BOOT/BOOTX64.CSV grub.cfg fbx64.efi grubx64.efi mmx64.efi BOOTX64.EFI

Win32系统下制作GRUB单文件

  1. 可使用grub-mkimage命令将bootia32.efi或bootx64.efi与其所需的模块合并成为单文件

  2. 下载解压后在grub-2.04-for-windows文件夹下打开命令提示符执行下面命令

1
grub-mkimage.exe -d x86_64-efi -c grub.cfg -p /efi/boot -o bootx64.efi -O x86_64-efi boot linux linux16 chain loopback search net disk part_gpt part_msdos disk blocklist btrfs cpio exfat ext2 f2fs fat hfs hfsplus iso9660 jfs ntfs procfs squash4 tar xfs zfs date echo ls configfile normal file sleep true minicmd play read acpi reboot halt efifwsetup efi_gop efi_uga video_bochs video_cirrus gfxmenu gfxterm gfxterm_background gfxterm_menu font jpeg png
  1. 命令参数所代表的含义
1
2
3
4
5
6
7
32位:grub-mkimage.exe -d i386-efi -c grub.cfg -p /efi/boot -o bootia32.efi -O i386-efi 
64位:grub-mkimage.exe -d x86_64-efi -c grub.cfg -p /efi/boot -o bootx64.efi -O x86_64-efi

-d 表示指定查找模块目录,32位:i386-efi,64位:x86_64-efi
-c 指定集成到efi文件内默认执行的配置文件,当前路径下的grub.cfg中的内容:configfile ($root)/efi/boot/grub.cfg
-p 指定prefix文件夹,即grub安装后的目录,目录下包含所有的grub模块字体主题语言文件
-o 生成的目标文件,-O 表示集成的模块
  1. 要集成的模块名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 部分模块,集成下面的模块可胜任大部分的引导工作
引导相关:boot linux linux16 chain loopback search net disk part_gpt part_msdos disk blocklist
文件系统:btrfs cpio exfat ext2 f2fs fat hfs hfsplus iso9660 jfs ntfs procfs squash4 tar xfs zfs
其他工具:date echo ls configfile normal file sleep true minicmd play read acpi reboot halt efifwsetup
图形支持:efi_gop efi_uga video_bochs video_cirrus gfxmenu gfxterm gfxterm_background gfxterm_menu font jpeg png

# 在i386-efi或x86_64-efi文件夹下的如下文件中有更多模块极其所支持的功能
fs.lst 支持的文件系统
command.lst 命令及所属的包
crypto.lst 加密解密的算法
moddep.lst 命令所依赖的包
partmap.lst 支持的分区列表
video.lst 显示相关
parttool.lst 分区工具
terminal.lst 终端工具

用efibootmgr管理固件中的启动项

  1. 安装:sudo apt install efibootmgr

  2. 显示现有的启动项

1
2
3
4
5
6
7
8
leux@Debian:~$ efibootmgr
BootCurrent: 0086
Timeout: 1 seconds
BootOrder: 0001,0000,0085,0086
Boot0000* Windows Boot Manager
Boot0001* GRUB
Boot0085* debian
Boot0086* UEFI: Generic-SD/MMC 1.00, Partition 1
  1. 添加自定义启动项
1
2
3
4
5
6
7
8
sudo efibootmgr -c -w -L "GRUB" -d /dev/sda -p 1 -l \\EFI\\Boot\\bootx64.efi

-c 创建并写入启动项
-w 如果需要,将唯一的sig写入MBR
-L 自定义的启动项名称(默认"Linux"
-d 启动分区所在的硬盘(默认为/dev/sda)
-p 后面是vfat分区位置(默认为1)
-l 启动的efi文件路径。请注意使用"\\"表示目录的分级(默认"\EFI\debian\grub.efi"
  1. 开关及删除和修改启动顺序操作
1
2
3
4
sudo efibootmgr -a -b 0000	# 启用标号为0000的启动项
sudo efibootmgr -A -b 0000 # 禁用标号为0000的启动项
sudo efibootmgr -b 0001 -B # 删除刚才添加的GRUB启动项,对应的编号为0001
sudo efibootmgr -o 0001,0000,0085,0086 # 修改boot顺序,如果要设置第一启动,把相应的编号放到命令后的最前面,如0001样

使用GRUB引导系统的极简配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# /efi/boot/grub.cfg
set timeout=3
set menu_color_normal=cyan/blue
set menu_color_highlight=white/blue

# 普通引导Linux系统
menuentry "Debian GNU/Linux (kernel 4.19.0-6-amd64)" {
echo 'Set root ...'
set root=(hd0,gpt2)
echo 'Loading kernel ...'
linux /vmlinuz root=/dev/sda2 quiet
echo 'Loading initial ramdisk ...'
initrd /initrd.img
}

# 使用UUID来引导Linux系统
menuentry "Debian GNU/Linux Buster (kernel 4.19.0-9-amd64)" {
search --no-floppy --fs-uuid --set=root 004e6e14-b1bd-384b-84a5-93d03fdcf964
linux /vmlinuz root=UUID=004e6e14-b1bd-384b-84a5-93d03fdcf964 quiet
initrd /initrd.img
}

# 引导ISO镜像文件,有的用findiso=${isofile},有的是iso-scan/filename=${isofile}
menuentry "Debian Live ISO (efi/boot/grub.cfg)" {
echo 'Set root and isofile ...'
set root=(hd0,gpt1)
set isofile="/debian-live-10.2.0-amd64-gnome.iso"
loopback loop $isofile
echo 'Loading kernel ...'
linux (loop)/live/vmlinuz-4.19.0-6-amd64 boot=live findiso=${isofile} components quiet
echo 'Loading initial ramdisk ...'
initrd (loop)/live/initrd.img-4.19.0-6-amd64
}

# 引导UEFI/GPT模式的Windows
menuentry "Microsoft Windows Vista/7/8/8.1/10 UEFI/GPT" {
echo 'Set root ...'
set root=(hd0,gpt1)
echo 'Loading Windows Boot Manager ...'
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}

# 关机和重启及进BIOS设置
submenu "Advanced Options" {

set menu_color_normal=cyan/blue
set menu_color_highlight=white/blue

menuentry "Halt" {
echo 'Now Poweroff ...'
halt
}

menuentry "Reboot" {
echo 'Now Reboot ...'
reboot
}

menuentry "Setup" {
echo 'UEFI Firmware Setup ...'
fwsetup
}
}