Grub2入门教程
—
LinuxUser001
—
看完你就知道该怎么写grub.cfg
- grub全称GNURand Unified Bootloader
- 友情链接:金步国的grub.cfg讲解(这个门槛太高,建议看完本文章再去)、GNU grub2官方文档、grub官方下载地址(源码安装包都有)
- 以下的测试均在VMware+Arch Linux测试(别的不说,<a href=“https://archlinux.org” >Arch Linux yyds!</a>)
- 请不要再自己的电脑实践,不然启动失败或者安装报错的<a href=“mailto:2185726244@qq.com” >来找我玩吧</a>!
- 好了,那么我们现在,开始游戏吧!
—
安装和使用
Windows系统
通过上面的下载链接,我们已经下载了Windows的版本。那么该怎么用呢?
首先,我们用管理员身份打开cmd,接着
::Grub2 帮助
> grub-install.exe --help
Usage: grub-install.exe [OPTION...] [OPTION] [INSTALL_DEVICE]
Install GRUB on your drive.
--compress=no|xz|gz|lzo compress GRUB files [optional]
--disable-shim-lock disable shim_lock verifier
--dtb=FILE embed a specific DTB
-d, --directory=DIR use images and modules under DIR
[default=C:\Users\liaol\Desktop\grub-2.06-for-windows/<platform>]
--fonts=FONTS install FONTS [default=unicode]
--install-modules=MODULES install only MODULES and their dependencies
[default=all]
-k, --pubkey=FILE embed FILE as public key for signature checking
--locale-directory=DIR use translations under DIR
[default=C:\Users\liaol\Desktop\grub-2.06-for-windows/locale]
--locales=LOCALES install only LOCALES [default=all]
--modules=MODULES pre-load specified modules MODULES
--sbat=FILE SBAT metadata
--themes=THEMES install THEMES [default=starfield]
-v, --verbose print verbose messages.
--allow-floppy make the drive also bootable as floppy (default
for fdX devices). May break on some BIOSes.
--boot-directory=DIR install GRUB images under the directory DIR/grub
instead of the boot/grub directory
--bootloader-id=ID the ID of bootloader. This option is only
available on EFI and Macs.
--core-compress=xz|none|auto
choose the compression to use for core image
--disk-module=MODULE disk module to use (biosdisk or native). This
option is only available on BIOS target.
--efi-directory=DIR use DIR as the EFI System Partition root.
--force install even if problems are detected
--force-file-id use identifier file even if UUID is available
--label-bgcolor=COLOR use COLOR for label background
--label-color=COLOR use COLOR for label
--label-font=FILE use FILE as font for label
--macppc-directory=DIR use DIR for PPC MAC install.
--no-bootsector do not install bootsector
--no-nvram don't update the `boot-device'/`Boot*' NVRAM
variables. This option is only available on EFI
and IEEE1275 targets.
--no-rs-codes Do not apply any reed-solomon codes when
embedding core.img. This option is only available
on x86 BIOS targets.
--product-version=STRING use STRING as product version
--recheck delete device map if it already exists
--removable the installation device is removable. This option
is only available on EFI.
-s, --skip-fs-probe do not probe for filesystems in DEVICE
--target=TARGET install GRUB for TARGET platform
[default=x86_64-efi]; available targets:
arm-coreboot, arm-efi, arm-uboot, arm64-efi,
i386-coreboot, i386-efi, i386-ieee1275,
i386-multiboot, i386-pc, i386-qemu, i386-xen,
i386-xen_pvh, ia64-efi, mips-arc, mips-qemu_mips,
mipsel-arc, mipsel-loongson, mipsel-qemu_mips,
powerpc-ieee1275, riscv32-efi, riscv64-efi,
sparc64-ieee1275, x86_64-efi, x86_64-xen
-?, --help give this help list
-V, --version print program version
--usage give a short usage message
Mandatory or optional arguments to long options are also mandatory or optional
for any corresponding short options.
INSTALL_DEVICE must be system device filename.
C:\grub-2.06-for-windows\grub-install.exe copies GRUB
images into boot/grub. On some platforms, it may also install GRUB into the
boot sector.
Report bugs to <bug-grub@gnu.org>.
—
是不是被这么巨量的输出吓到了?
- 别慌,待我逐行为您解读
--compress
:这是对安装后的grub启动器压缩的功能,一般不建议使用。
--disable-shim-lock
:禁用填充码支持,此选项一般用于uefi,一般不用管。
--dtb=FILE
:Linux设备树文件,这涉及到内核层面,Windows玩不来,不用管。
--directory=DIR
:grub复制文件的源目录,如果不是故意的话一般都在运行目录,不用管。
--font=FONT
:使用一个字体,若无这个参数则默认unicode.pf2(grub2沿用许久的字体)
--install-modules=MODULES
:特指安装的模块,不管则为全部。(放心,占用空间不大)
--pubkey=FILE
:使用RSA密匙文件作为签名,一般不用管。
--locale-directory=DIR
和--locales=LOCALES
:两个参数如果用的话建议配套使用,第一个是选择grub各国语言字符串的路径,而第二个就是选择语言,格式为zh_CN或en_US。不管则默认en_US。这个后面可以在cfg文件修改。
--sbat=FILE
:这个我也弄不清楚是什么,不过是跟uefi安全启动有关,涉及uefi操作系统机制,一般不用管。
--themes=FILE
:主题,不管默认为空。后面的cfg文件可以修改
--verbose
:安装时打印冗长的消息
--allow-floppy
:软盘支持,不过现在都不用了吧,不用管。
--boot-directory=DIR
:将grub释放至该目录的grub下,不指定则根目录。
--bootloader-id=ID
:启动器名字。一般不用管。
--core-compress
:这个参数跟第一条有点相似,不过第一条是全部压缩,这条是只压缩核心镜像。
--disk-module=MODULE
:用于grub访问磁盘的模块,如果是硬盘启动则不用管。(光盘启动则是iso9660,磁盘一般是biosdisk)
--efi-firectory=DIR
:指定EFI分区的根目录,文件系统只能是FAT32或vFAT
--force
:《无视风险继续安装》(?)
--force-file-id
:这个不知道是什么,最好不要管。
--label-bgcolor
、--label-color
和--label-font=FILE
:分别是标签(不知道是什么标签)背景颜色、字体颜色、字体样式。虚拟机环境的可以试试。
--macppc-directory=DIR
:令人啧啧称奇的功能:grub竟然支持在ppc的麦金塔机器安装grub,反正我们现在是Windows系统玩不来,不用管。
--no-bootsector
:不安装引导扇区,这个是主引导记录分区表的硬盘才能用的功能,适用于以前安装过grub的再次安装,第一次安装的请勿使用,一般不用管。
--no-nvram
:不添加条目至主板,uefi bios特色,一般及Legacy bios用户不用管。
--no-rs-codes
:禁止坏块启动功能,文档描述的是禁止一个能让grub在坏扇区的分区中启动(真的有那么神奇吗?)的功能。这么神奇的功能为什么还要专门弄个参数去禁止?不得而知,一般不用管。
--product-version=STRING
:自定义版本号,可以一试。
--recheck
:给grub添加自动检查设备映射的功能,简单说就是实时查看何时添加了新硬件,强烈建议添加这个参数。
--removable
:字面意思,即将目标设备当作可移动设备来安装grub,视情况而定。
--skip-fs-probe
:不探测磁盘中的文件系统,这个参数风险较大,不建议加。
--target=TARGET
:这个非常重要,是决定架构和固件类型的参数,但是不应该混乱使用,所以不用管(Legacy bios默认i386-pc,uefi bios默认x86_64-efi。可以自动识别)。
--help
、--version
和--usage
:分别是:显示帮助信息、显示版本号和显示简短的帮助信息。
—
另外,后面它还有一句:INSTALL_DEVICE必须是系统设备文件名,这句话是什么意思呢?
简单说,Windows系统内核曾经也做过像Linux系统一样,设备皆文件,不过Windows注册的设备文件比Linux的少多了。但是我们怎么看呢?
没错,grub所说的设备名正是设备ID!
因此,完整的安装命令应该是(在我的uefi设备,而且要管理员权限)
> grub-install.exe --boot-directory=C:\ --recheck --target=x86_64-efi --verbose --locales=zh_CN \\.\PhysicalDrive0
REM grub存放的根目录在C盘
REM 实时监测设备增减
REM uefi grub
REM 详细输出
REM 中文
REM 物理磁盘0(也就是第一个磁盘)
Linux系统
- 在Linux系统安装则更为简单
首先,各位Linux玩家,你们能走到这一步,应该已经知道如何更新源及安装软件包了吧。
所以,我忽略grub的下载,只讲安装。
首先,获取磁盘信息(这是作者的Arch Linux的运行结果)
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sr0 11:0 1 1024M 0 rom
nvme0n1 259:0 0 60G 0 disk
└-nvme0n1p1 259:1 0 512M 0 part /boot
└-nvme0n1p2 259:2 0 200M 0 part /boot/EFI
└-name0n1p3 259:3 0 59.3G 0 part /
说实话,各位看到这里,说不定就已经知道该怎么做了,所以完整的安装命令应该是
$ sudo grub-install --boot-directory=/boot --verbose --target=x86_64-efi --recheck --locales=zh_CN
#/boot作为grub存放的位置
#详细输出
#uefi grub
#实时检测硬件增减
#中文
—
配置
- 这大概就是最难的一个部分了,请大家耐心看完。
- 我们已经安装好grub了,但是开机却只有一个grub>,怎么办呢?
Linux
首先我们输入ls,然后将ls精确到分区,最后再精确到文件
## DISK
grub> ls
(hd0) (hs0,msdos1) (hd0,msdos2) (hd0,msdos3) (cd0)
grub> ls (hd0,msdos1)
分区 hd0,msdos1:文件系统类型 ext* - 最近更改 2022-05-03 13:22:43 星期二,UUID 804d0075-ed9e-4fb6-99e6-3a3b82471604 - 分区始于 1024KiB - 总量 524288KiB
grub> ls (hd0,msdos1)/
lost+found/ EFI/ vmlinuz-linux initrd-linux.img initrd-linux-fallback.img grub/
grub>
- 第一个ls,显示所有存储设备及分区,其中(hdx,ptxx)是磁盘分区,hdx指的是磁盘设备号,ptxx是分区编号及分区表(就像主引导记录MBR显示msdosx一样,GUID分区表显示的是gptx),(cdx)则是光盘,如果可能,(fdx)或者(fpx)是软盘
- 第二个ls,我们得到了该分区的基本信息,大小,文件系统,UUID什么的
- 第三个ls,我们则得到了该分区里面的文件
那么,现在我们开始启动这个系统吧!
正如我在qemu命令行教程的内核启动讲的一样,grub也提供了必不可少的内核挂载功能,格式非常简单(不要盲目复制命令,不然就<a href=“mailto:2185726244@qq.com” >来找我玩吧</a>!)
## grub> linux (hdx,ptxx)/kernel argu
grub> linux (hd0,msdos1)/vmlinuz-linux root=UUID=44ddf494-6462-4795-96be-e4c0321a05b5 quiet systemd.unit=graphical.target
## grub> initrd (hdx,ptxx)/initramfs
grub> initrd (hd0,msdos1)/initrd-linux.img
grub> boot
## 启动成功
开始讲解
- linux命令:这个是用来加载linux内核文件的,第一个参数为linux内核文件路径,后面的参数均为传给内核的参数,比如我通过grub> ls查到了我的根分区是这么一串UUID,那么我就可以传进去给内核挂载(其中root参数非常重要,这是告诉内核根分区的位置)。
- initrd命令:加载初始化内存盘文件。切记切记切记:启动顺序必须先是内核再到内存盘
- boot命令:这个不用我多说了。
Windows
好,既然Linux已经搞定,那么就到Windows了。讲到Windows,我不得不提grub强大的的链式启动机制它竟然可以直接将启动权限转交到分区,在2.0版本之后,grub甚至支持将启动权限转交到EFI文件(因此,我们甚至可以用这个功能启动别的Linux系统!),这实在是太强了(可是正因为这个强大功能,我不得不将Legacy bios和uefi bios分开写,哎)。
好话说完了,那我们开始吧(测试机器:VMware+Windows8.1(Windows系统的启动分区是保留分区))。
Legacy
还是一样,我们用ls查看各个分区的内容
grub> ls
(hd0) (hd0,msdos1) (hd0,msdos2)
grub> ls (hd0,msdos1)/
$AttrDef $BadClus $Bitmap $Boot $Extend/ $LogFile $MFT $MFTMirr $Secure $UpCase $Volume Boot/ bootmgr BOOTNXT BOOTSECT.BAK 'System Volume Information/'
好,这个分区一堆有美元符号的文件,肯定是保留分区了,那么它肯定是可以启动的了
## 首先导入模块,不过有的grub在开始的时候已经自动导入了,因为这个工具太重要了
grub> insmod chain
## 接下来,将根目录导向这个分区,这个Linux玩家可参考
grub> set root=(hd0,msdos1)
## 然后,将grub的启动权限交给这个保留分区,让他启动
## 因为NTFS的机制,启动代码是在第一个扇区开始,所以是+1
grub> chainloader +1
## 最后,所有系统全部启动启动启动启动!还有这个!(DNA)
grub> boot
UEFI
这个玩系统的玩家应该都有所了解,uefi的启动文件主要存放在ESP分区,而ESP分区文件系统是锁死了只能FAT32或者vFAT,所以比较好找。
## 省略了找分区和导入模块的步骤
## 首先,还是先将根目录导向ESP分区
grub> set root=(hd0,gpt1)
## 另外,uefi bios的特点:所有启动文件都必须放在\EFI\下,而Windows的启动文件是在\EFI\Microsoft\Boot\目录下(有两个
##:bootmgr.efi和bootmgfw.efi,其中bootmgr是带驱动启动),所以
## 接下来戏剧性的一幕发生了!
grub> chainloader /EFI/Microsoft/Boot/bootmgr.efi
## 怎么回事,为什么这grub就像EFI Shell一样的啊?
grub> boot
—
好了,我们已经启动系统了,接下来开始用你喜欢的编辑器写配置文件吧
基本语法
命令
menuentry
:在grub启动器中显示一个条目,是结构语言,用法如下:(函数头也是有特别作用的哟)
menuentry ‘系统名称’ –class 标签1 –class 标签2(以此类推) –id ‘简介’ { 命令 }(系统名称有且只有一个,而标签可以有多个,简介和标签可以不要)
## 示例
menuentry 'Arch Linux' --class arch --class linux --class gnu {
set root=(hd0,msdos1)
linux /vmlinuz-linux root=UUID=UUID=44ddf494-6462-4795-96be-e4c0321a05b5 quiet systemd.unit=graphical.target
initrd /initrd-linux.img
boot
}
没错,我们将这些东西写进配置文件后,即可在每次启动前省去大量步骤!
submenu
:在grub启动器中显示一个父目录,也是结构语言,用法如下:(这回函数头少了,但是可以在父目录中塞menuentry当作子目录)
submenu ‘父目录’ –class 标签 { 命令 }
## 示例
submenu 'Arch Linux的高级选项' --class arch {
menuentry 'Arch Linux修复模式' --class arch {
set root=(hd0,msdos1)
linux /vmlinuz-linux root=UUID=UUID=44ddf494-6462-4795-96be-e4c0321a05b5 systemd.unit=emergency.target
initrd /initrd-linux.img
boot
}
menuentry 'Arch Linux开机无图形' --class arch {
set root=(hd0,msdos1)
linux /vmlinuz-linux root=UUID=UUID=44ddf494-6462-4795-96be-e4c0321a05b5 systemd.unit=multi-user.target
initrd /initrd-linux.img
boot
}
## 以此类推
}
function
:定义一个函数,跟Linux Shell一样,那就不用说了。也是结构语言
—
模块类命令
insmod
:导入模块,模块可以用ls $prefix/TARGET(TARGET为安装时选的–target=)查找,注意,导入时无需.mod后缀 - insmod MODULE
lsmod
:查看目前已导入的模块及它们依赖的模块 - lsmod
rmmod
:卸载模块 - rmmod MODULE
—
固件类命令
reboot
:重启计算机 - reboot
halt
:本来是睡眠的,但是GNU开发者觉得不行,改为关机 - halt
fwsetup
:uefi专用,进入固件设置 - fwsetup
boot
:在完成一系列初始化之后启动 - boot
—
其他
ls
:列出文件、分区和磁盘 - ls DIR/DSK/PART
echo
:打印信息和变量 - echo STR
set
:设置一个变量,有些变量是grub的配置,如果只写set则打印目前的变量 - set VAR=ARG
loadfont
:加载一个字体文件,但不是普通的字体文件(后面有讲) - loadfont pf2FILE
terminal_input
和terminal_output
:设置输入输出的回环设备,这点在图形界面详细讲 - terminal_[input|ouput] –[append|remove] DEVICE
***
变量
变量,在grub的作用非常重要,是完美配置grub的利器。以下列出几个比较重要的变量
变量名 | 作用 | 备注 |
background | 背景图片 | 依赖于图形界面及相应的图片模块 |
cmdpath | 启动器所在磁盘 | - |
default | 默认条目 | 前提是得有可显示的条目 |
gfxmode | 图形界面的分辨率,格式为[width]x[height]x[color_bit](例 1920×1080×32)或auto | 必须提前导入相应的模块及通过grub的图形界面性能评估 |
gfxpayload | 支持图形界面的模块是否常驻(通常为keep) | 必须提前导入相应的模块及通过grub的图形界面性能评估 |
grub_cpu | 安装的grub指令集(i386或x86_64) | 无需手动设置 |
grub_platform | 安装的grub平台类型(pc为legacy,efi为uefi) | 无需手动设置 |
lang | 语言 | 格式为zh_CN或en_US |
prefix | 安装grub的绝对路径 | 无需手动设置 |
root | grub根目录 | 将以root的路径为/,跟chroot相似 |
theme | 主题 | 值必须是主题文件夹内的theme.txt文件 |
我们也可以自己设置其他命令,比如Linux内核路径,这样我们在写配置文件的时候可以更方便快捷
******
图形界面
激动人心的图形界面来啦!
- 根据上面的变量及命令学习,在grub开启图形界面其实并不难,那么grub的图形界面性能评估是什么呢?
feature_all_video_module
变量:这个变量就是grub评估性能的结果,当我们得到它的值为y时,证明你的电脑/虚拟机支持它开图形界面,如果不是,那就考虑换一台吧。
- 好,假设我们通过了它的性能评估,请按照我的一步一步来(有顺序,命令通用,放心复制)
- 首先,导入相关模块
## 这个all_video就是驱动大串烧
grub> insmod all_video
## 导入图形输出终端模块
grub> insmod gfxmenu
## 导入图形显示条目模块
grub> insmod gfxmenu
## 导入图形输出背景图片模块
grub> insmod gfxterm_background
很简单,不是吗?
- 接着,利用变量设置grub的图形界面模式
## 图形界面分辨率及颜色位深度,第一个是自动,第二个是强制1024x768,32位色
grub> set gfxmode=auto
grub> set gfxmode=1024x768x32
## 设置图形界面模块模式,其中text是字符界面
grub> set gfxpayload=keep
- 最后,有了图形界面却没有输出,算什么呢?所以我们还要将输出重定向到图形显示器中!
grub> terminal_output --append gfxterm
接着按一下ESC键,我们就会发现grub的界面发生了变化!恭喜,你开启了图形界面!
当然,我们也可以将这一串命令写进配置文件(自取通用)
function load_video{
insmod all_video
insmod gfxmenu
insmod gfxterm
insmod gfxterm_background
set gfxmode=auto
set gfxpayload=keep
terminal_output --append gfxterm
}
******
美化
全局主题
- 是的,grub不仅功能强大,它还很爱美!
- 友情链接:Gnome-Look/grub主题 官网、GNU Grub官方示例主题starfield星空。
好了,我们已经下载好主题包了,它的结构是一个文件夹,里面有很多图标及一个theme.txt。我们把它移进grub安装目录里面的themes目录下,就完成了主题的安装。
- 那我们怎么使用呢?很简单,我们在配置文件里面加一行
set theme=$prefix/themes/主题/theme.txt
重启,看到漂亮的主题,是不是特别简单呢?
背景图片
set background=/图片路径
如果提示不支持的位图格式,则insmod相应的模块即可,比如jpg后缀的图片我们则insmod jpg
,就这么简单。
字体
- ⚠ Windows用户!这不是你该看的东西,请快点转移到Linux!
这里,我们将会了解grub的字体压缩及其配置
- 我们都知道,一般字体文件的后缀是ttf、ttc等的格式,但是grub却不是如此,它用的是经过压缩的.pf2文件!
那么该如何转化呢?
grub-mkfont
命令::该命令用于字体的转换,支持ttf、ttc等源文件转化(此程序只有Linux才有,Windows是没有的。所以Windows用户也可以套用人家弄出来的.pf2文件)
基本用法:
## 摘自Linux命令
$ grub-mkfont --help
用法: grub-mkfont [OPTION...] [选项] 字体文件
将通用字体文件格式转换为 PF2 格式
-a, --force-autohint 强制 autohint
-b, --bold 转换为粗体
-c, --asce=NUM set font ascent
-d, --desc=NUM set font descent
-i, --index=NUM select face index
-n, --name=NAME 设置字体族名称
--no-bitmap ignore bitmap strikes when loading
--no-hinting 金庸 hinting
-o, --output=文件 将输出保存到指定文件 [必需]
-r, --range=FROM-TO[,FROM-TO] 设置字体范围
-s, --size=大小 设置字体大小
-v, --verbose 显示冗长信息。
-?, --help give this help list
--usage give a short usage message
-V, --version print program version
Mandatory or optional arguments to long options are also mandatory or optional
for any corresponding short options.
Report bugs to <bug-grub@gnu.org>.
所以,我们只需要拿出一些重要的参数
$ grub-mkfont [字体源文件].ttf -o [字体输出文件].pf2
接着,将字体文件移入grub安装目录下,然后在配置文件里面加上一行
loadfont $prefix/[字体文件].pf2
—
—
—
好了,现在你已经完成了grub的初步学习······等等,你的配置文件是不是还叫“无标题”?
对,我差点忘了,只需要将配置文件命名为grub.cfg,然后移到grub的安装目录下即可(其他位置grub直接罢工,然后你又要回收开头的grub>)
好了,现在你已经完成了grub的初步学习(真)
—
参考文献:GNU Grub Manual 2.06、UEFI shim安全启动机制、<a href=‘https://wiki.archlinux.org/title/GRUB_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)’ >Arch Wiki GRUB中文</a>`