暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

05 - HelloOS启动

s09g的技术博客 2023-05-09
1785

一般这步需要将操作系统镜像写入到一个引导设备中,比如一个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"

  1. 如果有GRUB_HIDDEN_XXXX
    ,注释掉:这个操作是为了显示 GRUB 菜单。
  2. 将GRUB_TIMEOUT设置为30:将 GRUB 菜单的等待时间改为30秒。
  3. 将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

  1. 打开 grub.cfg
    文件:
sudo nano /boot/grub/grub.cfg

  1. 在文件中找到 menuentry
    部分,这些是现有的启动项。
  2. 在这些 menuentry
    中添加一个新的 menuentry
    来启动你的操作系统。可能如下:
menuentry 'HelloOS' {
    set root='(hd0,msdos1)'
    multiboot /boot/HelloOS.bin
    boot
}

  1. 保存文件并退出编辑器。重启电脑后,就能在 Grub 菜单中看到新的 HelloOS
    启动项。

下一次运行 update-grub
时,更改将会被覆盖。

2.在 etc/grub.d/ 目录下创建一个新的文件 添加HelloOS启动项

想永久添加这个启动项,应该在 /etc/grub.d/
中添加一个新的配置文件。

  1. 首先,操作系统的二进制文件 HelloOS.bin
    存在适当的位置。我将其放在 /boot
    目录下。
  2. /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

  1. 最后,更新 Grub 配置:
sudo update-grub

这将会生成新的 grub.cfg
文件,其中会包含新添加的启动项。

重启电脑后,应该能在 Grub 菜单中看到新的 HelloOS
启动项。


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



文章转载自s09g的技术博客,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论