如何将Grub装入U盘

Last Updated: 2023-09-04 13:41:25 Monday

-- TOC --

本文总结个人在尝试将grub装入U盘过程中学习到的知识和经验。将grub装入U盘,是为了让U盘可以启动电脑系统,至少可以启动到grub的界面!

grub

Grub官方文档:https://www.gnu.org/software/grub/manual/grub/grub.html

什么是Grub

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盘

准备一块U盘,做MBR分区,最少分1个区,格式化为FAT32文件系统。

使用FAT32文件系统,一方面是UEFI的要求,另外也可以兼容Windows系统和Linux系统。

安装UEFI版本的Grub,U盘可以完全不用分区,UEFI的启动不依赖MBR,它是读取文件系统固定位置的文件,即/EFI/BOOT/BOOTX64.efi。

使用MBR分区的U盘,是为了兼容传统BIOS启动。

在Windows系统下安装Grub到U盘

在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,这两个参数会出现在下面的命令行中。

传统BIOS模式

--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.

32位UEFI模式

--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.

64位UEFI模式

--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经验。

传统BIOS和UEFI,两种模式共存

我的电脑是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全部安装上,基本上就都能启动了!:)

配置文件grub.cfg

在U盘的grub文件夹内,创建一个文件,名为grub.cfg,编辑内容如下,设置两个选项(reboot和halt都是grub提供的命令):

menuentry "Restart" {
    reboot
}

menuentry "Power Off" {
    halt
}

用U盘启动电脑,就能看到grub的选择菜单!

用上述方式安装的grub,默认的配置文件是 grub/grub.cfg 文件。(虽然是不同的grub程序文件,但都是读取这个位置的配置信息)

在Ubuntu下安装grub到U盘

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

编完之后,插入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参数!

安装64位UEFI模式

$ 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目录。

安装32位UEFI模式

$ cd ../../EFI32/grub-core
$ sudo grub-install -d $PWD --removable --target=i386-efi --boot-directory=/mnt/u --efi-directory=/mnt/u

安装传统BIOS模式

$ 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格式的。

使用grub-install

过了好一段时间,在我的移动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

后来没有复现,有可能是之前命令行参数敲错了...

error: embedding is not possible

在安装BIOS模式时,出现此错误。

BIOS模式的安装,必须要有MBR支持。因此U盘要有MBR分区,至少1个分区,并在第1块分区之前预留(默认)1MB空间出来。(参考:GRUB启动的3个阶段

因为您正在将grub安装到分区而不是MBR上。这意味着无法将grub嵌入到MBR和第一个分区之间的未使用空间中。相反,它必须将/boot/grub/core.img驻留的块列表放入MBR。

multiple partition labels error

分区表内的数据混乱了,用dd命令将U盘前面一段数据全部清除,然后重新安装。先备份数据,dd命令的杀伤力很强。

直接进rescue模式,error: no such device,unknow filesystem...

grub-mkimage

grub-mkstandalone

本文链接:https://cs.pynote.net/sf/grub/202110165/

-- EOF --

-- MORE --