参考
https://time.geekbang.org/column/article/379291
整体思路
1、操作系统需要放在硬盘中,所以需要生产一块硬盘
2、本机系统(host)识别和访问硬盘,需要硬盘上有文件系统
3、使用文件模拟硬盘,先要搞个二进制文件,然后把文件设置成回环设备,然后使用命令给设备建立文件系统
4、安装GRUB,主要把grub安装到新建的文件里,所以把文件设置为设备,再把设备挂载到本机(host)已存在的目录上,安装grub
5、现在硬盘里安装好了grub,需要使用虚拟机启动这个硬盘了,但是虚拟机不识别这个硬盘文件格式,所以要转成虚拟机能识别格式的硬盘文件格式
6、设置虚拟机使用这个硬盘
脚本
将课程中老师的步骤写成了两个脚本,方便执行:
genimg.sh:
#!/usr/bin/env bash
# 生成镜像文件 xxx.img
function genimg() {
imgname="$1"
if [[ "$1" = "" ]]; then
echo "please input image file name"
exit 1
fi
umount /mnt/hdisk
dd if=/dev/zero of="$imgname.img" bs=512 count=204800
lodev=$(losetup -f)
losetup $lodev "$1.img"
mkfs.ext4 -q $lodev
if [[ -f /mnt/hdisk ]]; then
mount -o loop "$imgname.img" /mnt/hdisk
else
mkdir -p /mnt/hdisk
mount -o loop "$imgname.img" /mnt/hdisk
fi
mkdir -p /mnt/hdisk/boot
# 安装grub
grub-install --boot-directory=/mnt/hdisk/boot --force --allow-floppy $lodev
# 使用 heredoc, 新建 grub.cfg
cat << EOF > /mnt/hdisk/boot/grub/grub.cfg
menuentry 'HelloOS' {
insmod part_msdos
insmod ext2
set root='hd0,msdos1' #我们的硬盘只有一个分区所以是'hd0,msdos1'
multiboot2 /boot/HelloOS.eki #加载boot目录下的HelloOS.eki文件
boot #引导启动
}
set timeout_style=menu
if [ "\${timeout}" = 0 ]; then
set timeout=10 #等待10秒钟自动启动
fi
EOF
umount /mnt/hdisk
losetup -d $lodev
}
genimg $1
opvm.sh:
#!/usr/bin/env bash
# 该脚本用于将 img 文件转换为 vdi 文件并挂载到 指定的虚拟机的sata 接口上
# function handle_vm {
function handle_vm() {
vmname="$1"
imgname="$2"
# 删除虚拟机的 sata 接口
VBoxManage storagectl "$vmname" --name "SATA" --remove
# 删除 uuid
VBoxManage closemedium disk "${imgname}.vdi"
# 删除 hd.vdi
rm -rf "${imgname}.vdi"
# 转换 hd.img 为 hd.vdi
VBoxManage convertfromraw "${imgname}.img" --format VDI "${imgname}.vdi"
# 为虚拟机添加 sata 接口
VBoxManage storagectl "$vmname" --name "SATA" --add sata --controller IntelAhci --portcount 1
# 将虚拟硬盘挂载到虚拟机的硬盘控制器上
VBoxManage storageattach "$vmname" --storagectl "SATA" --port 1 --device 0 --type hdd --medium "${imgname}.vdi"
}
handle_vm $1 $2
问题总结
1、报hd0,mddos1找不到
需要修改grub.cfg文件,将hd0,msdos1更改为hd0,然后重新制作镜像。其中删除虚拟硬盘操作可以参考上面脚本。
登陆发表评论