Last Updated: 2023-09-04 13:41:25 Monday
-- TOC --
本文总结个人在尝试将grub装入U盘过程中学习到的知识和经验。将grub装入U盘,是为了让U盘可以启动电脑系统,至少可以启动到grub的界面!
Grub官方文档:https://www.gnu.org/software/grub/manual/grub/grub.html
Grub,GRand Unified Bootloader
我们现在说grub,都是指grub2,截止到写这段文字的时候,最新版本是2.06。grub是GNU搞出来的bootloader,可以用来启动各种主流的操作系统。Linux系统基本都使用grub来启动自己,比如启动Linux时,我们可以选择kernel版本,那个选择kernel的界面,就是grub的。
看了一堆资料,我是这样理解的:bootloader是硬件启动后执行的第一个软件程序,它在OS运行之前,在firmware之后(BIOS或UEFI就是固件)。firmware会按照BIOS(或者UEFI)设定的规则,读取磁盘,开始运行磁盘上的程序,bootloader就是第一个(对于UEFI系统,也可以说是UEFI的一个App)被调用的程序。bootloader的主要任务,就是加载OS。grub就是那个最著名的bootloader程序!
64位系统的UEFI启动,读取U盘中
/EFI/BOOT/BOOTX64.efi
这个文件!Briefly, a boot loader is the first software program that runs when a computer starts. It is responsible for loading and transferring control to an operating system kernel software (such as Linux or GNU Mach). The kernel, in turn, initializes the rest of the operating system (e.g. a GNU system).
准备一块U盘,做MBR分区,最少分1个区,格式化为FAT32文件系统。
使用FAT32文件系统,一方面是UEFI的要求,另外也可以兼容Windows系统和Linux系统。
安装UEFI版本的Grub,U盘可以完全不用分区,UEFI的启动不依赖MBR,它是读取文件系统固定位置的文件,即/EFI/BOOT/BOOTX64.efi。
使用MBR分区的U盘,是为了兼容传统BIOS启动。
在Windows下也可以安装grub,首先下载grub-for-windows:
Grub官方下载地址:https://ftp.gnu.org/gnu/grub/
我下载的是2.06版本!
先在Windows系统中确认U盘的DeviceID,使用 wmic diskdrive list brief
命令:
D:\>grub-2.06-for-windows>wmic diskdrive list brief
Caption DeviceID Model Partitions Size
TOSHIBA TransMemory USB Device \\.\PHYSICALDRIVE1 TOSHIBA TransMemory USB Device 1 15512878080
Colorful SL500 360GB \\.\PHYSICALDRIVE0 Colorful SL500 360GB 3 360078082560
我U盘的盘符是E:
,DevideID是\\.\PHYSICALDRIVE1
,这两个参数会出现在下面的命令行中。
--target=i386-pc
D:\grub-2.06-for-windows>grub-install.exe --boot-directory=E:\ --target=i386-pc \\.\PHYSICALDRIVE1
Installing for i386-pc platform.
Installation finished. No error reported.
--target=i386-efi
D:\grub-2.06-for-windows>grub-install.exe --boot-directory=E:\ --efi-directory=e: --removable --target=i386-efi
Installing for x86_64-efi platform.
Installation finished. No error reported.
--target=x86_64-efi
D:\grub-2.06-for-windows>grub-install.exe --boot-directory=E:\ --efi-directory=e: --removable --target=x86_64-efi
Installing for x86_64-efi platform.
Installation finished. No error reported.
没遇到过错误,没有debug经验。
我的电脑是64位的,我先尝试了安装BIOS模式,然后再尝试安装64位UEFI模式,中间没有清理U盘,发现两种模式可以并存。
BIOS模式下,U盘中只有一个grub文件夹。64位UEFI模式下,U盘多了一个/EFI/BOOT/BOOTX64.efi
文件,grub文件夹中也多了一些文件。
测试电脑用U盘启动,不管是BIOS模式启动,还是UEFI模式启动,都可以进入grub提示符界面!
如果用VMware虚拟机测试,它用的是32位的UEFI启动!所以,准备一个U盘,将上面3中x86架构的grub全部安装上,基本上就都能启动了!:)
在U盘的grub文件夹内,创建一个文件,名为grub.cfg,编辑内容如下,设置两个选项(reboot和halt都是grub提供的命令):
menuentry "Restart" {
reboot
}
menuentry "Power Off" {
halt
}
用U盘启动电脑,就能看到grub的选择菜单!
用上述方式安装的grub,默认的配置文件是 grub/grub.cfg 文件。(虽然是不同的grub程序文件,但都是读取这个位置的配置信息)
Ubuntu系统自带grub-insall等一些列工具(WSL除外),但是我个人实践出来的安装方法,还是需要编译grub源码。如果使用Ubuntu自带的grub-install,安装的grub,总是进入rescue模式,不得要领...
以下说明略过了编译安装grub的依赖,我记得有bison和flex,还有必须的build-ensential。
下载grub源码包,tar解压,进入解压目录,创建3个文件夹,分别进入这3个文件夹,分别编译grub在各个不同CPU架构下的版本:
$ mkdir EFI64 EFI32 BIOS
$ cd EFI64
$ ../configure --target=x86_64 --with-platform=efi --disable-werror --disable-nls && make
$ cd ../EFI32
$ ../configure --target=i386 --with-platform=efi --disable-werror --disable-nls && make
$ cd ../BIOS
$ ../configure --target=i386 --with-platform=pc --disable-werror --disable-nls && make
--disable-werror
,如果不关闭这个选项,warning会被当成error,有可能导致编译不通过。--disable-nls
, disable native language support。编完之后,插入U盘,用fdisk -l
命名查询U盘的设备号,假设我这里是 /dev/sdc1
,然后mount:
$ sudo fdisk -l
$ sudo mkdir /mnt/u
$ sudo mount /dev/sdc1 /mnt/u
然后开始安装grub。
下面命令中的grub-install,其实是Ubuntu自带的那个,前面编译grub,并没有执行make install。下面的命令,只是用到了编译出来的grub-core。如果使用自己编译出来的grub-install,也是可以的,见后面的记录。
下面几个命令,如果失败,可以尝试添加
--force
参数!
$ cd ../EFI64/grub-core
$ sudo grub-install -d $PWD --removable --target=x86_64-efi --boot-directory=/mnt/u --efi-directory=/mnt/u
$PWD
就是cd进入的编译出来的grub-core目录。
$ cd ../../EFI32/grub-core
$ sudo grub-install -d $PWD --removable --target=i386-efi --boot-directory=/mnt/u --efi-directory=/mnt/u
$ cd ../../BIOS/grub-core
$ sudo grub-install -d $PWD --target=i386-pc --boot-directory=/mnt/u /dev/sdc
到这里,U盘启动时,就可以正常进入grub那个bash-like的界面了!
grub不是必须,直接引导OS也是可以的,但在多OS情况下,grub就基本就必须要有了。
UEFI启动U盘的复制,可以直接通过copy文件的方式,但记得要format为FAT32格式的。
过了好一段时间,在我的移动Fedora上继续折腾,编译如上。make之后,当前目录下会生成一大堆工具程序,其中就有grub-install。使用此grub-install,如上描述,安装grub到U盘。
手动修改文件
UEFI启动,一定需要这个文件:/efi/boot/bootx64.efi
用编译出来的grub-install,在U盘中安装64位UEFI,成功了,但是生成的文件是/efi/grub/grubx64.efi
,要手动修改为/efi/boot/bootx64.efi
!
后来没有复现,有可能是之前命令行参数敲错了...
在安装BIOS模式时,出现此错误。
BIOS模式的安装,必须要有MBR支持。因此U盘要有MBR分区,至少1个分区,并在第1块分区之前预留(默认)1MB空间出来。(参考:GRUB启动的3个阶段)
因为您正在将grub安装到分区而不是MBR上。这意味着无法将grub嵌入到MBR和第一个分区之间的未使用空间中。相反,它必须将/boot/grub/core.img驻留的块列表放入MBR。
分区表内的数据混乱了,用dd命令将U盘前面一段数据全部清除,然后重新安装。先备份数据,dd命令的杀伤力很强。
-hda /dev/sdb
,而不是-hda /dev/sdb1
,如果错误的使用了后者,也会进入rescue模式。本文链接:https://cs.pynote.net/sf/grub/202110165/
-- EOF --
-- MORE --