你好,我是LMOS。
经过前面那么多课程的准备,现在我们距离把我们自己操作系统跑起来,已经是一步之遥了。现在,你是不是很兴奋,很激动?有这些情绪说明你是喜欢这门课程的。
接下来的三节课,我们会一起完成一个壮举,从GRUB老大哥手中接过权柄,让计算机回归到我们的革命路线上来,为我们之后的开发自己的操作系统做好准备。
具体我是这样来安排的,今天这节课,我们先来搭好操作系统的测试环境。第二节课,我们一起实现一个初始化环境的组件——二级引导器,让它真正继承GRUB权力。第三节课,我们正式攻下初始化的第一个山头,对硬件抽象层进行初始化。
好,让我们正式开始今天的学习。首先我们来解决内核文件封装的问题,然后动手一步步建好虚拟机和生产虚拟硬盘。课程配套代码你可以在这里下载。
从内核映像格式说起
我们都知道,一个内核工程肯定有多个文件组成,为了不让GRUB老哥加载多个文件,因疲劳过度而产生问题,我们决定让GRUB只加载一个文件。
但是要把多个文件变成一个文件就需要封装,即把多个文件组装在一起形成一个文件。这个文件我们称为内核映像文件,其中包含二级引导器的模块,内核模块,图片和字库文件。为了这映像文件能被GRUB加载,并让它自身能够解析其中的内容,我们就要定义好具体的格式。如下图所示。

上图中的GRUB头有4KB大小,GRUB正是通过这一小段代码,来识别映像文件的。另外,根据映像文件头描述符和文件头描述符里的信息,这一小段代码还可以解析映像文件中的其它文件。
映像文件头描述符和文件描述符是两个C语言结构体,如下所示。
1 | //映像文件头描述符 |
有了映像文件格式,我们还要有个打包映像的工具,我给你提供了一个Linux命令行下的工具(在Gitee代码仓库中,通过这个链接获取),你只要明白使用方法就可以,如下所示。
1 | lmoskrlimg -m k -lhf GRUB头文件 -o 映像文件 -f 输入的文件列表 |
准备虚拟机
打包好了映像文件,我们还有很重要的一步配置——准备虚拟机。这里你不妨先想一想,开发应用跟开发操作系统有什么不同呢?
在你开发应用程序时,可以在IDE中随时编译运行应用程序,然后观察结果状态是否正确,中间可能还要百度一下查找相关资料,不要笑,这是大多数人的开发日常。但是你开发操作系统时,不可能写5行代码之后就安装在计算机上,重启计算机去观察运行结果,这非常繁琐,也很浪费时间。
好在我们有虚拟机这个好帮手。虚拟机用软件的方式实现了真实计算机的全部功能特性,它在我们所使用的Linux下,其实就是个应用程序。
使用虚拟机软件我们就可以在现有的Linux系统之上开发、编译、运行我们的操作系统了,省时且方便。节约的时间我们可以喝茶、听听音乐、享受美好生活。
安装虚拟机
这里我们一致约定使用甲骨文公司的VirtualBox虚拟机。经过测试,我发现VirtualBox虚拟机有很多优点,它的功能相对完善、性能强、BUG少,而且比较稳定。
在现代Linux系统上安装VirtualBox虚拟机是非常简单的,你只要在Linux发行版中找到其应用商店,在其中搜索VirtualBox就行了。我们作为专业人士一条命令可以解决的事情,为什么要用鼠标点来点去呢,多浪费时间。
所以,你只要在终端中输入如下命令就行了,我假定你安装了Ubuntu系的Linux发行版,这里Ubuntu的版本不做规定。
1 | sudo apt-get install virtualbox-6.1 |
运行Virtualbox后,如果出现如下界面,就说明安装VirtualBox成功了。
建立虚拟电脑
前面我们只是安好了虚拟机管理软件,我们还要新建虚拟机才可以。点击上图中的新建,然后选择专家模式,就可以进入专家模式配置我们的电脑了。
尽管它是虚拟的,我们还是可以选择CPU类型、内存大小、硬盘大小、网络等配置,为了一致性,请你按照如下截图来配置。


可以看到,我们选择了64位的架构,1024MB内存,但是不要添加硬盘,后面自有妙用。显卡是VBoxVGA,还有硬件加速,这会让虚拟机调用我们机器上真实的CPU来运行我们的操作系统。
手工生产硬盘
上面的虚拟机中还没有硬盘,没有硬盘虚拟机就没地方加载数据,我们当然不是要买一块硬盘挂上去,而是要去手工生产一块硬盘。你马上就会发现,从零开始生产一块虚拟硬盘,这比从零开始写一个操作系统简单得多。
至于为什么手工生产硬盘,我先卖个关子,你看完这部分内容就能找到答案。
其实大多数虚拟机都是用文件来模拟硬盘的,即主机系统(HOST OS 即你使用的物理机系统 )下特定格式的文件,虚拟机中操作系统的数据只是写入了这个文件中。
生产虚拟硬盘
其实虚拟机只是用特定格式的文件来模拟硬盘,所以生产虚拟硬盘就变成了生成对应格式的文件,这就容易多了。我们要建立100MB的硬盘,这意味着要生成100MB的大文件。
下面我们用Linux下的dd命令(用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换)生成100MB的纯二进制的文件(就是1~100M字节的文件里面填充为0 ),如下所示。
1 | dd bs=512 if=/dev/zero of=hd.img count=204800 |
执行以上命令就可以生成100MB的文件。文件数据为全0。由于我们不用转换数据,就是需要全0的文件,所以dd命令只需要这几个参数就行。
格式化虚拟硬盘
虚拟硬盘也需要格式化才能使用,所谓格式化就是在硬盘上建立文件系统。只有建立了文件系统,现有的成熟操作系统才能在其中存放数据。
可是,问题来了。虚拟硬盘毕竟是个文件,如何让Linux在一个文件上建立文件系统呢?这个问题我们要分成三步来解决。
第一步,把虚拟硬盘文件变成Linux下的回环设备,让Linux以为这是个设备。其实在Linux下文件可以是设备,设备可以是文件。下面我们用losetup命令,将hd.img变成Linux的回环设备,代码如下。
1 | sudo losetup /dev/loop0 hd.img |
第二步,将losetup命令用于设置回环设备。回环设备可以把文件虚拟成Linux块设备,用来模拟整个文件系统,让用户可以将其看作硬盘、光驱或软驱等设备,并且可用mount命令挂载当作目录来使用。
我们可以用Linux下的mkfs.ext4命令格式化这个/dev/loop0回环块设备,在里面建立EXT4文件系统。
1 | sudo mkfs.ext4 -q /dev/loop0 |
第三步,我们用Linux下的mount命令,将hd.img文件当作块设备,把它挂载到事先建立的hdisk目录下,并在其中建立一个boot,这也是后面安装GRUB需要的。如果能建立成功,就说明前面的工作都正确完成了。
说到这里,也许你已经想到了我们要手工生成硬盘的原因。这是因为mount命令只能识别在纯二进制文件上建立的文件系统,如果使用虚拟机自己生成的硬盘文件,mount就无法识别我们的文件系统了。
1 | sudo mount -o loop ./hd.img ./hdisk/ ;挂载硬盘文件 |
进行到这里,我们会发现hdisk目录下多了一个boot目录,这说明我们挂载成功了。
安装GRUB
正常安装系统的情况下,Linux会把GRUB安装在我们的物理硬盘上,可是我们现在要把GRUB安装在我们的虚拟硬盘上,而且我们的操作系统还没有安装程序。所以,我们得利用一下手上Linux(HOST OS),通过GRUB的安装程序,把GRUB安装到指定的设备上(虚拟硬盘)。
想要安装GRUB也不难,具体分为两步,如下所示。
1 | 第一步挂载虚拟硬盘文件为loop0回环设备 |
可以看到,现在/hdisk/boot/目录下多了一个grub目录,表示我们的GRUB安装成功。请注意,这里还要在/hdisk/boot/grub/目录下建立一个grub.cfg文本文件,GRUB正是通过这个文件内容,查找到我们的操作系统映像文件的。
我们需要在这个文件里写入如下内容。
1 | menuentry 'HelloOS' { |
转换虚拟硬盘格式
你可能会好奇,我们前面好不容易生产了mount命令能识别的虚拟硬盘,这里为什么又要转换虚拟硬盘的格式呢?
这是因为这个纯二进制格式只能被我们使用的Linux系统识别,但不能被虚拟机本身识别,但是我们最终目的却是让这个虚拟机加载这个虚拟硬盘,从而启动其中的由我们开发的操作系统。
好在虚拟机提供了专用的转换格式的工具,我们只要输入一行命令即可。
1 | VBoxManage convertfromraw ./hd.img --format VDI ./hd.vdi |
安装虚拟硬盘
好了,到这里我们已经生成了VDI格式的虚拟硬盘,这正是我们虚拟机所需要的。然而虚拟硬盘必须要安装虚拟机才可以运行,也就是这个hd.vdi文件要和虚拟机软件联系起来。
因为我们之前在建立虚拟机时并没有配置硬盘相关的信息,所以这里需要我们进行手工配置。
配置虚拟硬盘分两步:第一步,配置硬盘控制器,我们使用SATA的硬盘,其控制器是intelAHCI;第二步,挂载虚拟硬盘文件。
具体操作如下所示。
1 | #第一步 SATA的硬盘其控制器是intelAHCI |
因为VirtualBox虚拟机用UUID管理硬盘,所以每次挂载硬盘时,都需要删除虚拟硬盘的UUID并重新分配。
最成功的失败
现在硬盘也安装好了,下面终于可以启动我们的虚拟电脑了,我们依然通过命令启动,在Linux终端中输入如下命令就可以了。
1 | VBoxManage startvm HelloOS #启动虚拟机 |
输入以上命令就会出现以下界面,出现GRUB引导菜单。

直接按下回车键,就能选择我们的HelloOS,GRUB就会加载我们的HelloOS,但是会出现如下错误。

上面的错误显示,GRUB没有找到HelloOS.eki文件,这是因为我们从来没有向虚拟硬盘中放入HelloOS.eki文件,所以才会失败。
但这是我们最成功的失败,因为我们配置好了虚拟机,手动建造了硬盘,并在其上安装了GRUB,到这里我们运行测试环境已经准备好了。
其实你不必太过担心,等我们完成了二级引导器的时候,这个问题会迎刃而解。
重点回顾
希望今天这节课给你带来成就感,虽然我们才走出了万里长征的第一步。为了这一步我们准备了很多。但是我们始终没忘记这一课程的目的,即我们要从GRUB老大哥手里接过权柄,控制计算机王国,为此,我们完成了后面这三个工作。
- 我们了解了内核映像格式,以便我们对编译产生的内核程序文件进行封装打包。
- 为了方便测试我们的操作系统,我们了解并安装了虚拟机。
- 手动建立了虚拟硬盘,对其格式化,在其中手动安装了GRUB引导器,并且启动了虚拟电脑。
虽然我们启动虚拟电脑失败了,但是对我们而言却是巨大的成功,因为它标志着我们测试运行内核的环境已经成功建立,下一课我们将继续实现二级引导器。
思考题
请问,我们为什么要把虚拟硬盘格式化成ext4文件系统格式呢?
欢迎你在留言区跟我交流探讨,如果你身边有对写操作系统感兴趣的朋友,也欢迎把这节课分享给他,一起学习。
好,我是LMOS,我们下节课见!
- Chaos 👍(18) 💬(4)
没想到这一个步骤花费了好几天,现在成功在mac m1的CPU环境下通过QEMU跑起来了hello world。相关细节可以查看我的仓库https://github.com/Rlyown/ToyOS。 这里简要说明一下:成功的关键是借助了Docker和QEMU。Docker可以通过创建x86的Linux容器来完成ext4磁盘的分区、格式化以及安装grub。而QEMU则是用来启动内核的虚拟机。
以下步骤均在x86的容器中完成:
- 通过命令创建磁盘镜像,本人选择之创建32M的镜像
dd if=/dev/zero of=$DISK bs=512 count=$((32 * 1024 * 1024 / 512)) - 对磁盘进行分区,这里只做了一个分区。分区的目的是避免后续执行grub-install安装时报错。
parted -s $DISK mklabel msdos
parted -s $DISK mkpart primary 2048s 100%
parted -s $DISK set 1 boot on - 查找一个空闲的回环设备映射到镜像文件,假设是/dev/loop0
losetup –find –show –partscan ${DISK} - 如果像我一样是arm架构借助了x86容器,那么这个步骤很关键。因为容器出于某种原因,映射了带分区的镜像文件后,找不到类似/dev/loop0p1的分区设备。这一步就是手动创建这个分区设备。
PARTITIONS=$(lsblk –raw –output "MAJ:MIN" –noheadings ${LOOPDEV} | tail -n +2)
COUNTER=1
for i in $PARTITIONS; do
MAJ=$(echo $i | cut -d: -f1)
MIN=$(echo $i | cut -d: -f2)
if [ ! -e "${LOOPDEV}p${COUNTER}" ]; then mknod ${LOOPDEV}p${COUNTER} b $MAJ $MIN; fi
COUNTER=$((COUNTER + 1))
done - 格式化分区。
mkfs.ext4 -q /dev/loop0p1 - 后面就可以挂载这个分区,然后安装grub。这里注意挂载时使用的设备是分区/dev/loop0p1,而进行grub-install时使用的设备是镜像/dev/loop0。
mkdir ISO
mount /dev/loop0p1 ISO
mkdir -p ISO/boot/grub
grub-install –boot-directory=ISO/boot –force –allow-floppy –target=i386-pc /dev/loop0
cp grub.cfg ISO/boot/grub - 取消挂载和映射,并删除手动创建的分区设备。
umount ISO
lostup -d /dev/loop0
rm -f /dev/loop0p1 - 通过qemu模拟x86虚拟机
qemu-system-i386 -m 1024 -drive format=raw,file=disk.img2022-04-15 - hdhwjjs 👍(2) 💬(4)
看到这一课的内容有需要上机实操的就非常喜欢,终于啃了那么多天的理论课,迎来了实操课。
我的实操环境是:WIN10 + VBox+ Ubuntu 20.04
一开始我搞错了,跟着课程内容,去ubuntu里安装vBox,这等于是把自己引入了套娃的险境。
如果你也是和我同样的运行环境,那可以参考下文绕过这个坑。
正确的操作应该是在我们的VBox里建立这个与我们的Ubuntu并列的HelloOS虚拟系统,具体如何建立,跟着课程里的内容来完成即可。
这里我要分享一下我踩这些坑的捷径,
听完课先扒拉课后大神们的留言,老师已把精华踩坑攻略帮我们置顶了,基本上前三篇留言里能找到大部分你即将遇到的坑。
然后,我遇到第二个坑,是loop0
这个我也是去课后留言区扒拉,带着问题,明确目标去找,很快就查到,可以用
sudo losetup这条指令找出你系统里哪些loop已被占用,然后你使用没有被占用的loop即可
范围是0到11 。第三个坑,是我生成了hd.vdi文件后,继续跟着课程操作,系统老不让我过,我去查大神留言,发现我这是陷在跟套娃死磕的骚操作,
像我这里的运行环境下,正确的操作应该是:
生成完hd.vdi文件,就把它保存到windows里,然后打开vbox,在我们一开始建立的HelloOS虚拟系统里,加载这个hd.vdi虚拟硬盘,然后就在VBox里启动这个HelloOS操作系统。启动之后,又遇到了一个坑,提示 hd0,msdos1错误,
发现错误后,再次扒拉课后大神的留言,找到解决方法:
修改grub.cfg文件,把里面的hd0,msdos1 改为hd0 即可,按照攻略,改完后,生成的hd.vfi放进HelloOS系统,启动果然就完成了今天这课的操作要求。(记得报错后,最好能重启一下虚拟机里的操作系统,否则可能遇到你已经更新了正确的hd.vdi,但系统提示你挂载的hd.vdi硬盘有问题不让你通过!)课后老师留的思考题,为什么我们要把虚拟盘格式化成ext4格式,
2021-11-08
我的印象中,文件格式系统在dos时代是FAT文件格式,后来有了FAT32,再后来硬盘越来越大,包括不同的操作系统,从windows、linux到MacOS,各个系统有各自的文件格式系统。
我的理解是,磁盘格式是为了即将安装的操作系统准备的,也就是我们即将做的这个操作系统是采用ext4文件格式,不能用其他的比如FAT32或exFAT等。 - 通过命令创建磁盘镜像,本人选择之创建32M的镜像
- 安之若素 👍(1) 💬(3)
使用服务器的小伙伴,可以参考如下链接,使用vnc方式,访问图形化ubuntu界面
2021-11-04
https://www.voidking.com/dev-linux-virtualbox/
https://support.huaweicloud.com/bestpractice-ecs/zh-cn_topic_0168615364.html
https://askubuntu.com/questions/800302/vncserver-grey-screen-ubuntu-16-04-lts - 山不厌高,海不厌深 👍(0) 💬(1)
# arch linux安装virtualbox
我使用的是manjaro系统,本来linux玩的就不是很熟,直接上arch我人都麻了,不过最后还是跑成功了,这里贴一下我遇到的坑。
1、arch需要先更新一下系统(很重要)
1
yay -Syy
2、然后直接安装virtualbox
1
yay -S virtualbox
3、然后很关键(我这里只装完这些,是用不了的,需要先安装一下与内核有关的东西):
查看一下你的内核版本
uname -r,比如我是5.10.70-1-MANJARO,还需要装一下内核与virtualbox有关的一些包(注意安装的版本要和你的内核相同)这里我就装了
linux510-virtualbox-host-modules与linux510-virtualbox-host-modules(在manjaro自带的软件商店内)安装完成根据提示
reboot4、然后根据archwiki,我们还需要加载virtualBox内核模块
如果你上一步没有安装相关内核包的话,这里会报错说xxx module找不到之类的错误,我也是在这里卡了好久
1
sudo modprobe vboxdrv
5、完成
2021-10-26
然后就是跟着老师的步骤走了,arch成功跑起来HelloOS! - Fx 👍(8) 💬(1)
## Ubuntu18.04最全排坑指南
- virtualbox安装问题无法定位资源包,直接'sudo apt-get install virtualbox', 不要指定版本,安装后版本为5.2.42,目前不影响实验
- loop资源占用问题,参考前面的评论
- grub安装时efi方式启动出现问题,指定 '–target i386-pc'出现找不到该文件,若能在系统文件中找到该文件则指定路径查找即可
1
2
3
4cd /tmp # 进入efi所在的文件夹,名字可能会不一样,按照报错查找不到的路径为准
sudo apt-get download grub-pc-bin
dpkg-deb -R grub-pc-bin_2.02~beta2-36ubuntu3.16_amd64.deb grub/
sudo mv grub/usr/lib/grub/i386-pc/ /usr/lib/grub/- 在执行步骤时我一开始是直接忽略了3,继续往下也不会出现报错,但最后启动虚拟机时出现'FATAL:No bootable medium ….',查看评论需要重新创建虚拟硬盘,于是直接在文件系统删除新建立的能看到的文件,并重启计算机,就能从头开始,否则会出现某些文件已存在的报错但不知道如何删除。最终解决了坑三成功完成实验。2021-08-26
- Jayying 👍(20) 💬(5)
终于显示出来了。
记录一下我遇到的几个问题: - grub-install时遇到EFI的问题, 添加 参数 –target i386-pc
- 挂载/dev/loop0时可能遇到device busy, 换一个就行了,比如loop8
- 进入了grub,但是没有看到HelloOS;这个是我自己头铁,把老师第二行命令删掉了,因为每次执行这条命令都会报错, 按老师的命令写就可以了:
VBoxManage closemedium disk ./hd.vdi #删除虚拟硬盘UUID并重新分配 - 看到HelloOS,但是进入显示找不到hd0,msdos1什么的。在我第三步坑那里,我ls看到的是hd0,所以把hd0,msdos1改成hd0就可以了2021-07-31
- 黎标松 👍(4) 💬(1)
第一次留言: 我的宿主机是windows 10系统,用系统自带的Hyper-V虚拟机跑ubuntu,为了和老师一致,我又下了vitural Box,按照老师的步骤键虚拟机,这样避免套娃(我试过在虚拟机中跑虚拟机,真的很慢);生成虚拟硬盘的过程和老师一样;第一个坑是第一步,设置回环设备:sudo losetup /dev/loop0 hd.img 这里可以用命令 ls /dev/loop* 查看,看看哪个没有被占用(loop0-11一个一个试也行),以实际为准;第二个将hd.img文件生成DVI文件后,(不用在虚拟机中配置虚拟硬盘)把ubuntu虚拟机中的DVI文件共享到windows系统里面(可以参考这篇文章:https://blog.csdn.net/qq_27607539/article/details/75007717),在windows系统下拿到我们生成的hd.dvi文件后,使用vitualBox 虚拟机加载我们的虚拟硬盘(参考这篇文章:https://blog.csdn.net/love__coder/article/details/8270856),这样就可以启动我们的helloOS系统了;第三个坑就是提示'hd0,msdos1'错误,需要重新制作镜像,并且修改grub.cfg里的这行为'hd0,msdos1'为'hd0'(参考评论第一条第九天魔王大佬);这些坑都排完后应该就可以达到老师的效果了
2021-07-22 - Pure 👍(0) 💬(4)
我在设置回关设备这儿稍微卡了一下,跟大家说一下,就是我输完sudo losetup /dev/loop0 hd.img以后系统提示我说:使用设备失败,没有那个设备。把我搞蒙了,我去网上搜了一下,其实我们要先用命令找一个没有被用过的回环设备名也就是这里的loop0,我们可以用命令sudo losetup /dev/loopn来试哪个回环设备是没有被用过(这里的n其实就是你需要试的数字,0不行就1,1不行就2,一直试,我的是12)直到你试到人家说:使用设备失败,没有那个设备,这时候你的loopn就是你需要的回环设备名,然后再sudo losetup /dev/loopn hd.img就可以啦
2021-07-21 - 青玉白露 👍(9) 💬(1)
参考neohope的方法,其实在Mac和Windows环境下利用VirtualBox可以很方便的进行测试, 只需要建立两个虚拟机,一个ubuntu一个是我们的COSMOS,自己在Mac上进行了测试,具体的细节可以参考博客: https://blog.csdn.net/ll15982534415/article/details/118771286
2021-07-15 - Shinymimiq 👍(8) 💬(4)
我来优化一下Mac小伙伴的开发流程,直接能用Mac编译,并修改我们Cosmos的硬盘镜像文件了,基本可以不需要启动Ubuntu虚拟机了。
首先得按评论区里Veek或者Neohoped大佬的教程得到一个hd.vdi之类的镜像文件
然后使用 Virtual Box 提供的 VBoxManage clonehd 命令,把它转成 raw image
VBoxManage clonehd ~/VirtualBox\ VMs/MyUbuntu/hd.vdi image.img --format raw这时候在 Virtual Box 的 Virtual Media Manager 里是会多一个image.img的硬盘
然后我们只要把Cosmos虚拟机的启动硬盘改成这个image.img就行了我们修改完OS代码之后,可以把 image.img 加载到 MacOS 系统中
最简单的方式是这样open image.img这时候系统的 /Volumes 目录下会多出一个 Untitled 1 文件夹(如果你没有其他 Untitled 镜像加载的话)
之后就可以把相关文件比如 Cosmos.eki 拷贝到 /Volumes/Untitled\ 1/boot 下完成修改之后,接着使用
umount /Volumes/Untitled\ 1来取消镜像文件的加载
这时候再启动我们的Cosmos虚拟机就是直接跑更新后的文件了。
至于编译源代码的话,我们可以使用Docker来帮助我们生成一个基于Linux x64的工具链,这样就能直接编译,并且能直接使用课程中提供的 lmoskrlimg,(原来因为文件格式的问题在Mac下无法直接使用这个工具)
首先安装好Docker Desktop
随便新建一个目录
mkdir cosmos_build_env
在里面创建一个Dockerfile, 我在这里直接把内容echo到新文件里面echo "FROM dockcross/linux-x64
ENV DEFAULT_DOCKCROSS_IMAGE cosmos_build
RUN apt-get install -y nasm" > cosmos_build_env/Dockerfile接下来创建 Docker image
docker build cosmos_build_env -t cosmos_build创建完之后使用
docker run cosmos_build > cosmos_build chmod +x cosmos_build然后得到的这个cosmos_build就可以用来编译我们的cosmos
例如./cosmos_build make release</p>2021-06-11</li><br/><li><span>Vic</span> 👍(13) 💬(5)<p>超过2000字,补发后记:
卡了很久,可以看到GRUB,但看不到*HelloOS
2个疑点:
(1)在虚拟机2里/dev/loop0被占用,改用/dev/loop6,是不是还有哪里要改,没改对
(2)在grub-install时遇到 ext2 不support embedding的警告
grub-install: warning: File system `ext2' doesn't support embedding.
grub-install: warning: Embedding is not possible. GRUB can only be installed in this setup by using blocklists. However, blocklists are UNRELIABLE and their use is discouraged..
Installation finished. No error reported.但在物理机18.04也遇到,但不影响,只是个警告(warning),不碍事。
才发现自己grub.cfg放错位置,放在hdisk/boot/,而不是放在hdisk/boot/grub里
谢谢老师的精彩教程
2021-06-05 - Vic 👍(58) 💬(20)
终于试成功了,真开心,断断续续搞了快一个星期。
因为我的主机是mac, 谢谢第九天魔王大、neohoped大和老王大的分享,免去套娃,少走很多弯路。0.在主机Mac上安装 Virtual Box 6.1,开了2个虚拟机:
虚拟机1: HelloOS
虚拟机2: Linux Ubuntu 20.04 (server)依照老师课程介绍安装虚拟机1: HelloOS
新增虚拟机2: Linux Ubuntu 20.04
但建议网络可用bridge 桥接模式不用缺省的NAT,方便从虛擬機2傳檔案到mac 主機。例如我的虚拟机2的网络设定:
连接方式:桥接网卡
界面名称: en0: Wi-Fi (AirPort)
启动虛擬機2
在家目錄执行以下命令建立虚拟磁碟
dd bs=512 if=/dev/zero of=hd.img count=204800sudo losetup /dev/loop0 hd.img
会遇到losetup: hd.img: failing to set up loop device: Device or resource busy
可執行以下命令查看:
sudo losetup列出 /dev/loop0 到 /dev/loop5都被使用了, 挑一个没人用的例如: /dev/loop6
sudo losetup /dev/loop6 hd.img
- 进行格式化:请依照实际使用的loop设备号码更改,我这里用的是/dev/loop6
sudo mkfs.ext4 -q /dev/loop6
建立hdisk目录 mkdir hdisk
挂载硬盘文件
sudo mount -o loop ./hd.img ./hdisk/
建立boot目录 sudo mkdir ./hdisk/boot/
安装grub 请依照实际使用的loop设备号码更改,我这里用的是/dev/loop6
sudo grub-install –boot-directory=./hdisk/boot/ –force –allow-floppy /dev/loop6
创建grub.cfg
安装好grub,应该可看到 ./hdisk/boot/ 下多了一个grub目录,
cd 进去 ./hdisk/boot/grub/
里面没有grub.cfg,要自行创建,文件内容请参考老师课程
回到mac上
将虚拟机2上刚做好的hd.img 透过scp 传回我的mac,例如:
scp vic@192.168.50.27:hd.img . (hd.img是放在虚拟机2的家目录,最后有个小点,表示将档案拷到现在这个目录)
- 转换虚拟机1要用的硬盘格式为VDI
在mac上执行
VBoxManage convertfromraw ./hd.img –format VDI ./hd.vdi
此时应可看到除了原来的hd.img,多了一个hd.vdi的档案 (约13MB)
- 在mac的/Users/vic/VirtualBox VMs目录执行以下命令:
VBoxManage storagectl HelloOS –name "SATA" –add sata –controller IntelAhci –portcount 1
VBoxManage closemedium disk ./hd.vdi
VBoxManage storageattach HelloOS –storagectl "SATA" –port 1 –device 0 –type hdd –medium ./hd.vdi- 在mac 上执行
VBoxManage startvm HelloOS
- 如果看到虚拟机1 的GRUB 菜单画面出现
*HelloOS
按下回车键看到
error: file '/boot/HelloOS.eki' not found.
error: you need to load the kernel first.
就大功告成
谢谢老师的精彩课程
2021-06-05 - neohope 👍(75) 💬(19)
【更新】对于使用Windows、MacOS的同学,或不熟悉命令行的同学可以这样操作【不需要套娃,也不用做硬盘格式转换】: 1、先安装一个Linux虚拟机A,比如Ubuntu18或Ubuntu20 2、关闭虚拟机,在这个虚拟机上,用向导添加一个新硬盘hd.vdi 3、启动虚拟机A 4、创建新硬盘挂载目录 cd ~ mkdir hdisk 5、挂载新硬盘,创建ext4文件系统【当前应该只有两块硬盘,所以操作sdb,根据你实际情况调整】 sudo mkfs.ext4 /dev/sdb sudo mount /dev/sdb hdisk 6、创建boot目录 sudo mkdir hdisk/boot 7、安装grub到新硬盘 sudo grub-install --boot-directory=./hdisk/boot/ --force --allow-floppy /dev/sdb 8、拷贝HelloOS.eki到hdisk/boot目录 9、创建grub.cfg,用你喜欢的编辑器就好【其中root可以只写'hd0'】 sudo vi hdisk/boot/grub/grub.cfg 10、关闭虚拟机A 11、创建虚拟机B,选择类型“其他Linux”,硬盘不要新建,直接选择hd.vdi 12、开启虚拟机B,就可以看到Grub界面了
以后要发布内容,就关闭虚拟机B,开启虚拟机A进行操作;
2021-06-01
要看效果,就关闭虚拟机A,开启虚拟机B;
硬盘以后也不需要重复创建,只要保证A、B不同时开启就好了; - 老王 👍(4) 💬(7)
在整个操作中
2021-06-01
安装GRUB这一步:
sudo grub-install –boot-directory=./hdisk/boot/ –force –allow-floppy /dev/loop0
在ubutnu16.04下会报告一下问题
Installing for i386-pc platform.
grub-install: warning: File system `ext2' doesn't support embedding.
grub-install:错误: 无法嵌入,但在跨盘安装时是必须的.
我尝试修复也不成功,后面换ubutnu18.04,一次成功
但是如果创建回环设备这一步
sudo losetup /dev/loop0 hd.img
出现"losetup: hd.img:设置回环设备失败: 设备或资源忙"
那么就使用 ls /dev/loop* 查看下
brw-rw—- 1 root disk 7, 0 6月 1 12:13 /dev/loop0
brw-rw—- 1 root disk 7, 1 6月 1 12:13 /dev/loop1
brw-rw—- 1 root disk 7, 2 6月 1 12:13 /dev/loop2
brw-rw—- 1 root disk 7, 3 6月 1 12:13 /dev/loop3
brw-rw—- 1 root disk 7, 4 6月 1 12:13 /dev/loop4
brw-rw—- 1 root disk 7, 5 6月 1 12:13 /dev/loop5
brw-rw—- 1 root disk 7, 6 6月 1 12:13 /dev/loop6
brw-rw—- 1 root disk 7, 7 6月 1 12:13 /dev/loop7
brw-rw—- 1 root disk 7, 8 6月 1 12:13 /dev/loop8
crw-rw—- 1 root disk 10, 237 6月 1 12:13 /dev/loop-control
那么说明/dev/loop9是空的,可以使用
sudo losetup /dev/loop9 hd.img可以创建成功
其他操作为了防止不套娃可以参"第几天魔王"的操作 - 第九天魔王 👍(142) 💬(15)
已完成实验,有几个心得分享一下。
2021-05-31
1,如果主机就是Linux比如Ubuntu,则完全按照东哥的教程做即可,即Linux主机安装虚拟机启动HelloOS。
2,如果主机是Windows,启动虚拟机运行Ubuntu,很多童鞋担心虚拟机Ubuntu里再运行虚拟机启动HelloOS,这样就会套娃。其实可以避免套娃的。在你的虚拟机,也就是Ubuntu环境下,完成hd.img的创建,文件系统的格式化,grub的安装后,生成最终的hd.img文件。然后把hd.img文件通过命令变成vdi文件即可。然后在你的WIN主机环境下,新建一个虚拟机,加载vdi即可。也就是说此时HelloOS和Ubuntu都是你WIN环境下并列的两个虚拟机,这样就可以避免套娃了。
3,如果虚拟机使用的不是VirtualBox, 面是vmware,在生成hd.img后,可以使用starwindconverter工具(网上下载,WIN下运行),这个工具可以把img转换为各种格式,比如vmware的vmdk文件。然后vmware创建一个新的虚拟机,硬盘选择这个vmdk文件,就可以加载HelloOS了。
4,如果HelloOS加载成功,但是提示'hd0,msdos1'错误,则重新制作镜像,并且修改grub.cfg里的这行为'hd0,msdos1'为'hd0'即可。