一般这步需要将操作系统镜像写入到一个引导设备中,比如一个USB驱动器或者一个CD/DVD。然后在电脑重启的时候,进入到BIOS/UEFI设置。找到Boot顺序,将USB驱动器或者CD/DVD驱动器设置为第一启动设备。
之前第2章GRUB引导程序的时候,说过可以用GRUB引导程序来启动操作系统。可以将HelloOS添加到GRUB的启动菜单中,这样就可以在计算机启动时选择HelloOS。
我使用的环境是VMware + Ubuntu 20.
1. 修改/etc/default/grub
sudo apt install neovim
sudo vim /etc/default/grub
在 Ubuntu 中,Grub 的默认配置文件位于 etc/default/grub,主要用于设置 Grub 的全局参数。
以下是我原有的/etc/default/grub文件内容:
# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
# info -f grub -n 'Simple configuration'
GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=30
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""
# Uncomment to enable BadRAM filtering, modify to suit your needs
# This works with Linux (no patch required) and with any kernel that obtains
# the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)
#GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef"
# Uncomment to disable graphical terminal (grub-pc only)
#GRUB_TERMINAL=console
# The resolution used on graphical terminal
# note that you can use only modes which your graphic card supports via VBE
# you can see them in real GRUB with the command `vbeinfo'
#GRUB_GFXMODE=640x480
# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux
#GRUB_DISABLE_LINUX_UUID=true
# Uncomment to disable generation of recovery mode menu entries
#GRUB_DISABLE_RECOVERY="true"
# Uncomment to get a beep at grub start
#GRUB_INIT_TUNE="480 440 1"
如果有 GRUB_HIDDEN_XXXX
,注释掉:这个操作是为了显示 GRUB 菜单。将GRUB_TIMEOUT设置为30:将 GRUB 菜单的等待时间改为30秒。 将GRUB_CMDLINE_LINUX_DEFAUL设置为text:这个操作是为了让系统以文本模式启动。
#GRUB_HIDDEN_TIMEOUT=0
#GRUB_HIDDEN_TIMEOUT_QUIET=true
GRUB_TIMEOUT=30
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
#GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX_DEFAULT="text"
GRUB_CMDLINE_LINUX=""
不会退出的vim的:按一下ESC
,再输入:wq
修改完 etc/default/grub 文件后,需要执行 sudo update-grub
命令来更新 /boot/grub/grub.cfg
文件,重启后生效
sudo update-grub
sudo reboot
2. 修改/boot/grub/grub.cfg,临时添加HelloOS启动项
直接修改 /boot/grub/grub.cfg
文件可以添加一个新的启动项。然而,这并不是推荐的方法,因为这个文件是由 update-grub
命令自动生成的。如果在 /etc/default/grub
或 /etc/grub.d/
中的文件做了更改并运行了 update-grub
,在 grub.cfg
中的更改将会被覆盖。
然而,想临时添加一个启动项,可以按照以下步骤修改 grub.cfg
:
打开 grub.cfg
文件:
sudo nano /boot/grub/grub.cfg
在文件中找到 menuentry
部分,这些是现有的启动项。在这些 menuentry
中添加一个新的menuentry
来启动你的操作系统。可能如下:
menuentry 'HelloOS' {
set root='(hd0,msdos1)'
multiboot /boot/HelloOS.bin
boot
}
保存文件并退出编辑器。重启电脑后,就能在 Grub 菜单中看到新的 HelloOS
启动项。
下一次运行 update-grub
时,更改将会被覆盖。
2.在 etc/grub.d/ 目录下创建一个新的文件 添加HelloOS启动项
想永久添加这个启动项,应该在 /etc/grub.d/
中添加一个新的配置文件。
首先,操作系统的二进制文件 HelloOS.bin
存在适当的位置。我将其放在/boot
目录下。在 /etc/grub.d/
目录下创建一个新的文件,例如40_custom_helloos
。注意,文件的名字中的数字决定了在 Grub 菜单中的顺序,数字越大,顺序越后。在这个文件中,添加一个新的菜单项来启动操作系统。文件的内容如下:
#!/bin/sh
exec tail -n +3 $0
# This file provides an easy way to add custom menu entries. Simply type the
# menu entries you want to add after this comment. Be careful not to change
# the 'exec tail' line above.
menuentry 'HelloOS' { #新的菜单项的定义,菜单项的名字是 "HelloOS"。
insmod part_msdos #加载一个名为 part_msdos 的模块,这个模块用于识别 MS-DOS 风格的分区表。
insmod ext2 #加载一个名为 ext2 的模块,这个模块用于识别 ext2(以及 ext3 和 ext4)文件系统。
set root='hd0,msdos5' #设置 Grub 的根设备。hd0,msdos5 指的是第一个硬盘的第五个 MS-DOS 风格的分区。
multiboot2 /boot/HelloOS.bin #使用 Multiboot 2 协议来加载 /boot/HelloOS.bin 这个文件。Multiboot 是一个由 GNU 提出的标准,用于让不同的操作系统可以被同一种引导加载器加载。
boot #命令 Grub 启动已经加载的操作系统。
}
这个文件中的 set root='(hd0,msdos1)'
指定了根文件系统所在的磁盘分区,(hd0,msdos1)
表示第一个硬盘的第一个分区,这通常是 /boot
分区在的地方。如果你的 /boot
分区在其他地方,你需要相应地调整这一行。
我的环境中:
$ df /boot
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda5 25107716 10702648 13104332 45% /
意味着/boot
目录是挂载在/dev/sda5
这个分区上的。这个分区是硬盘上的一个区域,用于存储/boot
目录下的所有文件,包括操作系统的内核、initrd镜像以及Grub的配置文件等。/dev/sda5
对应于Grub的hd0,msdos5
(Grub从0开始计数,所以sda
是hd0
,5
是msdos5
)。
但是查看挂载的话
$ mount | grep sda5
/dev/sda5 on / type ext4 (rw,relatime,errors=remount-ro)
这个命令的输出表示/dev/sda5
分区已经被挂载在文件系统的根目录(/
)上,并且使用的文件系统类型是ext4
。rw
表示这个分区是可读可写的,relatime
是一个选项,表示只在文件被读取时更新文件的访问时间,errors=remount-ro
是一个错误处理选项,表示如果有错误发生,系统会尝试把这个分区重新挂载为只读。
这对grub.cfg
中的设置产生了影响,应该将set root='hd0,msdos5'
更改为正确的值,即set root='hd0,msdos1'
,因为根文件系统(/
)通常在GRUB中被认为是第一个分区(msdos1
)。
不过,因为GRUB和Linux的设备命名不完全一样,需要确认一下这个设置是否正确。可以在GRUB命令行(可以在GRUB菜单中按c
进入)中使用ls
命令来查看硬盘和分区情况。
不过你可能需要在GRUB命令行中确认一下这个设置是否正确。
在 GRUB 启动菜单界面,可以按 'c' 键进入 GRUB 命令行模式。
在 GRUB 命令行中,可以使用 ls
命令来查看设备和分区。会看到像 (hd0,msdos1)
这样的设备和分区名称。其中,hd0
表示第一块硬盘,msdos1
表示该硬盘的第一个分区。
可以使用 ls (hd0,msdos1)/
来查看该分区的根目录内容。这样,可以通过确认 /boot/HelloOS.bin
文件是否存在来判断是否是正确的分区。
当确定了正确的设置后,可以按 'Esc' 键退出 GRUB 命令行模式,返回到 GRUB 菜单。然后可以按 'e' 键编辑启动项,将启动项的 set root
命令修改为正确的设置,然后按 'Ctrl+x' 或 'F10' 来启动操作系统。查看一下我还是选择(hd0,msdos5)

2.5. 保存文件后,需要使其可执行:
sudo chmod +x /etc/grub.d/40_custom_helloos
以上两步可以合并为一步:直接修改/etc/grub.d/40_custom
最后,更新 Grub 配置:
sudo update-grub
这将会生成新的 grub.cfg
文件,其中会包含新添加的启动项。
重启电脑后,应该能在 Grub 菜单中看到新的 HelloOS
启动项。

启动之后,会看到 Hello OS
的输出。





