准备虚拟机

打包好了映像文件,我们还有很重要的一步配置——准备虚拟机。这里你不妨先想一想,开发应用跟开发操作系统有什么不同呢?在你开发应用程序时,可以在 IDE 中随时编译运行应用程序,然后观察结果状态是否正确,中间可能还要百度一下查找相关资料,不要笑,这是大多数人的开发日常。但是你开发操作系统时,不可能写 5 行代码之后就安装在计算机上,重启计算机去观察运行结果,这非常繁琐,也很浪费时间。
好在我们有虚拟机这个好帮手。虚拟机用软件的方式实现了真实计算机的全部功能特性,它在我们所使用的 Linux 下,其实就是个应用程序。使用虚拟机软件我们就可以在现有的 Linux 系统之上开发、编译、运行我们的操作系统了,省时且方便。节约的时间我们可以喝茶、听听音乐、享受美好生活。

安装虚拟机

这里我们一致约定使用甲骨文公司的VirtualBox虚拟机。经过测试,我发现 VirtualBox 虚拟机有很多优点,它的功能相对完善、性能强、BUG 少,而且比较稳定。
在现代 Linux 系统上安装 VirtualBox 虚拟机是非常简单的,你只要在 Linux 发行版中找到其应用商店,在其中搜索 VirtualBox 就行了。
我们作为专业人士一条命令可以解决的事情,为什么要用鼠标点来点去呢,多浪费时间。所以,你只要在终端中输入如下命令就行了,我假定你安装了 Ubuntu 系的 Linux 发行版,这里 Ubuntu 的版本不做规定。
在这个命令时我发现出现了报错于是我去官网找了一个安装包链接

sudo apt-get install virtualbox-6.1

2023-02-28T06:36:40.png
发现失败了,原因是定位不到

sudo apt-get install virtualbox   //尝试不带版本

定位成功安装成功,接下来是实现vm下ubuntu的共享文件夹,因为我是vm,所以我需要挂载一个共享文件夹,这篇文章解决了我的问题,现在我已经创建了一个共享文件夹目录为/Hellohttps://blog.csdn.net/qq_38196234/article/details/89568826
创建一个HelloOS(不带虚拟硬盘的那种)
2023-02-28T06:36:51.png
那我们接下来就是生产虚拟硬盘
其实虚拟机只是用特定格式的文件来模拟硬盘,所以生产虚拟硬盘就变成了生成对应格式的文件,这就容易多了。我们要建立 100MB 的硬盘,这意味着要生成 100MB 的大文件。
下面我们用 Linux 下的 dd 命令(用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换)生成 100MB 的纯二进制的文件(就是 1~100M 字节的文件里面填充为 0 ),如下所示。

dd bs=512 if=/dev/zero of=hd.img count=204800

;bs:表示块大小,这里是512字节
;if:表示输入文件,/dev/zero就是Linux下专门返回0数据的设备文件,读取它就返回0
;of:表示输出文件,即我们的硬盘文件。
;count:表示输出多少块

执行以上命令就可以生成 100MB 的文件。文件数据为全 0。由于我们不用转换数据,就是需要全 0 的文件,所以 dd 命令只需要这几个参数就行。
2023-02-28T06:37:06.png

格式化虚拟硬盘

虚拟硬盘也需要格式化才能使用,所谓格式化就是在硬盘上建立文件系统。只有建立了文件系统,现有的成熟操作系统才能在其中存放数据。可是,问题来了。虚拟硬盘毕竟是个文件,如何让 Linux 在一个文件上建立文件系统呢?这个问题我们要分成三步来解决。第一步,把虚拟硬盘文件变成 Linux 下的回环设备,让 Linux 以为这是个设备。其实在 Linux 下文件可以是设备,设备可以是文件。下面我们用 losetup 命令,将 hd.img 变成 Linux 的回环设备,代码如下。

sudo losetup /dev/loop0 hd.img //该部会报错fail ....busy,所以使用
sudo losetup  //使用这里面没有的如loop9
sudo losetup /dev/loop9 hd.img 

第二步,将 losetup 命令用于设置回环设备。回环设备可以把文件虚拟成 Linux 块设备,用来模拟整个文件系统,让用户可以将其看作硬盘、光驱或软驱等设备,并且可用 mount 命令挂载当作目录来使用。我们可以用 Linux 下的 mkfs.ext4 命令格式化这个 /dev/loop0 回环块设备,在里面建立 EXT4 文件系统。

sudo mkfs.ext4 -q /dev/loop9

2023-02-28T06:37:18.png
第三步,我们用 Linux 下的 mount 命令,将 hd.img 文件当作块设备,把它挂载到事先建立的 hdisk 目录下,并在其中建立一个 boot,这也是后面安装 GRUB 需要的。如果能建立成功,就说明前面的工作都正确完成了。说到这里,也许你已经想到了我们要手工生成硬盘的原因。这是因为 mount 命令只能识别在纯二进制文件上建立的文件系统,如果使用虚拟机自己生成的硬盘文件,mount 就无法识别我们的文件系统了。

sudo mount -o loop ./hd.img ./hdisk/ ;挂载硬盘文件
sudo mkdir ./hdisk/boot/ ;建立boot目录

2023-02-28T06:37:26.png

安装 GRUB

正常安装系统的情况下,Linux 会把 GRUB 安装在我们的物理硬盘上,可是我们现在要把 GRUB 安装在我们的虚拟硬盘上,而且我们的操作系统还没有安装程序。所以,我们得利用一下手上 Linux(HOST OS),通过 GRUB 的安装程序,把 GRUB 安装到指定的设备上(虚拟硬盘)。想要安装 GRUB 也不难,具体分为两步,如下所示。

第一步挂载虚拟硬盘文件为loop0回环设备
sudo losetup /dev/loop0 hd.img
sudo mount -o loop ./hd.img ./hdisk/ ;挂载硬盘文件
第二步安装GRUB
sudo grub-install --boot-directory=./hdisk/boot/ --force --allow-floppy /dev/loop9
;--boot-directory 指向先前我们在虚拟硬盘中建立的boot目录。
;--force --allow-floppy :指向我们的虚拟硬盘设备文件/dev/loop0

以看到,现在 /hdisk/boot/ 目录下多了一个 grub 目录,表示我们的 GRUB 安装成功。请注意,这里还要在 /hdisk/boot/grub/ 目录下建立一个 grub.cfg 文本文件,GRUB 正是通过这个文件内容,查找到我们的操作系统映像文件的。我们需要在这个文件里写入如下内容。

menuentry 'HelloOS' {
insmod part_msdos
insmod ext2
set root='hd0' #这里注意是hd0没有别的不然会报错
multiboot2 /boot/HelloOS.eki #加载boot目录下的HelloOS.eki文件
boot #引导启动
}
set timeout_style=menu
if [ "${timeout}" = 0 ]; then
  set timeout=10 #等待10秒钟自动启动
fi

2023-02-28T06:37:41.png
2023-02-28T06:37:54.png
在这里我们需要赋予他内容,需要先创建后赋予权限然后写入保存

转换虚拟硬盘格式

VBoxManage convertfromraw ./hd.img --format VDI ./hd.vdi
;convertfromraw 指向原始格式文件
;--format VDI  表示转换成虚拟需要的VDI格式

安装虚拟硬盘

到这里我们已经生成了 VDI 格式的虚拟硬盘,这正是我们虚拟机所需要的。然而虚拟硬盘必须要安装虚拟机才可以运行,也就是这个 hd.vdi 文件要和虚拟机软件联系起来。
因为我们之前在建立虚拟机时并没有配置硬盘相关的信息,所以这里需要我们进行手工配置。配置虚拟硬盘分两步:第一步,配置硬盘控制器,我们使用 SATA 的硬盘,其控制器是 intelAHCI;第二步,挂载虚拟硬盘文件。

#第一步 SATA的硬盘其控制器是intelAHCI
VBoxManage storagectl HelloOS --name "SATA" --add sata --controller IntelAhci --portcount 1
#第二步
VBoxManage closemedium disk ./hd.vdi #删除虚拟硬盘UUID并重新分配
#将虚拟硬盘挂到虚拟机的硬盘控制器
VBoxManage storageattach HelloOS --storagectl "SATA" --port 1 --device 0 --type hdd --medium ./hd.vdi

因为 VirtualBox 虚拟机用 UUID 管理硬盘,所以每次挂载硬盘时,都需要删除虚拟硬盘的 UUID 并重新分配。

最成功的失败

现在硬盘也安装好了,下面终于可以启动我们的虚拟电脑了,我们使用最早在win上新建的HelloOS系统启动
2023-02-28T06:38:11.png
成功了就是这样啦