最近在学习操作系统,需要从零开始搭建系统,由于教程中给的虚拟机搭建的方式感觉还是过于重量级,因此研究了一下通过 qemu 模拟器,配合 grub 完成启动系统的搭建。
qemu 是一款十分优秀的系统模拟器,可以用于模拟各种CPU架构硬件。你可以在 x86平台上模拟出 arm 架构的 CPU并在其上运行程序,也可以反过来。总而言之,通过 qemu 可以忽略平台间的架构差异,完成硬件模拟。
grub 是一个开源的系统启动器,用于对计算机进行初始化并引导至操作系统。
整个操作是在 wsl2 中执行的,需要提前安装一些软件:
sudo apt install -y qemu-system-x86 qemu-utils grub2
以下命令需要在 root 权限下执行,如果由于权限问题无法执行可以通过在前面加 sudo执行
dd
命令在 linux 系统中主要用于创建文件如:
# 创建一个 file.bin 的空文件,写入块大小为 512字节,共2M
dd bs=512 count=20000 if=/dev/zero of=file.bin
# 创建一个随机文件
dd bs=512 count=20000 if=/dev/random of=file.bin
这里使用该命令创建了一个 raw 类型的虚拟磁盘,qemu 可以直接使用这种类型的虚拟磁盘。
# 创建了一个虚拟磁盘文件,其实就是一个全是0 的空文件
dd bs=512 count=102400 if=/dev/zero of=hd.img
# bs=512 单次写入 512字节
# count=102400 共写入 102400次,合计 50MB
# if=/dev/zero 写入源为 zero
# of=hd.img 指定输出文件名称
然后通过 losetup -f
将这个虚拟硬盘文件关联为回环设备:
losetup -f hd.img
# -f 随机找一个空闲的回环设备,并将 hd.img 附加到上面
losetup -a
/dev/loop0: [2080]:409 (/root/hd.img)
# 这里可以看到我们刚刚创建的虚拟硬盘文件被附加到了 /dev/loop0 这个回环设备上了
# 可以通过 losetup -D 移除关联
通过 mkfs.ext4
将我们刚刚创建的的虚拟硬盘文件格式化为 ext4 磁盘文件系统类型
mkfs.ext4 hd.img
挂载我们刚刚初始化好的文件系统到当前系统上:
mkdir hdisk && mount hd.img hdisk
# 创建 hdisk 文件夹,并将 hd.img 虚拟硬盘挂载到这个文件夹上
到这里准备工作就完成了,现在我们为虚拟硬盘安装 grub:
grub-install --boot-directory=./hdisk/boot --no-floppy --force /dev/loop0
# --boot-directory 指定启动目录
# --no-floppy 设置没有软盘
# --force 只要没有发生错误,就继续写入,如果不指定 --force 可能会安装报错
# /dev/loop0 指定写入的磁盘文件,这里填刚刚通过 losetup -a 查询到的关联的回环设备文件
现在我们已经可以通过 qemu 启动这块硬盘了,虽然启动后直接是进入到 grub 界面:
qemu-system-x86_64 -hda hd.img
# --nographic 没有窗口条件的话可以添加这个选项
# qemu-system-x86_64 -drive file=hd.img,index=0,media=disk,format=raw 与上面命令效果一样
当然这只是一个空界面,你可以用 grub 的一些命令做一些初步的操作
insmod part_msdos #GRUB加载分区模块识别分区
insmod ext2 #GRUB加载ext文件系统模块识别ext文件系统
set root='hd0' #注意boot目录挂载的分区,这是我机器上的情况
multiboot2 /boot/HelloOS.bin #GRUB以multiboot2协议加载HelloOS.bin
boot #GRUB启动HelloOS.bin
如果想要重复练习上面的过程,可以在关闭 qemu 窗口后,接触对虚拟硬盘的关联:
umount hdisk
# 接触 hdisk 目录与 hd.img 的关联
然后接触 hd.img 与本地回环设备的关联:
losetup -D
# 移除所有关联的本地回环设备
losetup -a
# 查看是否已经解除关联
最后删除掉当前目录中的 hd.img 和 hdisk 目录.重新操作即可.
先按下 Ctrl + A 然后按下 X.
内核加载部分不做介绍.