参考

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,然后重新制作镜像。其中删除虚拟硬盘操作可以参考上面脚本。



登陆发表评论