打造兼容BIOS和UEFI的启动盘
我并不喜欢打游戏,随着我对Linux的深入了解,Windows对我的吸引力越来越少,但是总免不了需要用到Office的时候,就是为了用一下Office或者Photoshop而占用了一个分区,实在是有点浪费空间,我的硬盘一般只分出来EFI和ext4两个分区,根本不必担心会有需要重装系统的问题,而Windows一般情况下都是打开Qemu虚拟机来临时用一下。天有不测之风云啊,系统没有发生故障,笔记本的固态硬盘坏了,幸好笔记本还在保修期内,可以免费更换一块新的硬盘,但是系统还是需要重做的,部分资料因为没有备份也丢失了,在笔记本送修的这段时间里,我用旧的笔记本先把系统安装好,回来再恢复一下就可以了,于是就狠狠地折腾了一把Linux各种安装方法。对于启动盘,我需要满足一下的要求:
- 可以同时支持BIOS和UEFI启动。
- 引导各种版本的Linux Live CD。
- 引导可读写的Debian Linux的img镜像。
- 直接加载Win PE镜像,免去每次制作Windows启动盘都需要重新烧录U盘。
- 引导Windows 10 LTSB的vhd镜像。
- Linux和Windows镜像既可以在真机上启动也可以在Qemu虚拟机启动。
这么复杂和奇葩的需求,当然就没有现成的可以下载,只能自己动手做啦。 写这篇文章花费了不少的时间,如果只是做一个可用的启动盘,是用不了多少时间的,但是为了把每一步都搞明白,使用虚拟机做了很多实验,Debian和Windows都重复安装了几遍,写这篇文章的过程中,送修的笔记本拿回来了,却看到远景的帖子上有人在我这个笔记本型号上成功安装了macOS,立刻就心动了,跑去折腾黑苹果的安装方法,所以之后我也会写一篇关于HP ENVY AS110TU安装macOS的文章。本文写作前期是使用Linux,测试启动盘主要是使用Qemu,也因此对Qemu有了深入的了解,后期是在macOS下完成的,但Qemu for macOS不能使用USB Passthrough,改用Parallels Desktop。安装macOS之后,笔记本的续航时间居然变长了,后来发现是Firefox惹的祸,相对于Chrome,用Firefox时CPU使用率长期偏高,改用chrome浏览器之后CPU发热变小了,续航也就变长了,续航时间短应该不是因为使用Linux的缘故。使用macOS一段时间之后,我决定不再换回Linux系统了,Linux下太缺乏应用了,而且用docker就可以满足基本的开发需求。 我是用SSD的移动硬盘制作启动盘的,感觉还是不够方便,就想把拿个大容量的u盘来试试,Linux的启动当然就没有什么问题了,但是windows的vhd镜像,就不好做了,Windows To Go的功能是对U盘是有要求的,Removable media类型是Fixed的才能够安装,虽然可以通过cfadisk驱动来改变Removable Media的类型,但需要对驱动进行签名,否则每次开机都提示你驱动没有签名,需要修改BCD启动文件关闭驱动签名才能启动,以下就是制作过程。
1 用Qemu测试启动盘
根据自己的测试需要打开和关闭相应的命令行参数就可以了,Qemu可以很方便地将主机上的某个插口直通到虚拟机中,有了这个它,就不需要通过重启来测试启动盘了。
# 保存CD镜像路径的变量 |
2 分区和安装grub2
不是所有的qemu-img所支持的镜像格式qemu都能直接支持,但可以通过使用qemu-nbd命令挂载,提供间接的支持,vhd格式qemu能够直接支持所以就不选最新的vhdx格式,如果需要使用vhdx格式,可以先用qemu-nbd -t -k soket-file-path vhdx-file挂载,然后以qemu-system-x86_64 -hda -hda nbd:unix:/soket-file-path启动虚拟机。
# 创建vhd镜像文件 |
bios_grub分区是用于存放core.img,特别强调bios_grub标记的分区必须存在,否则BIOS模式下无法使用,分区为1M容量,因为1M是保证扇区能够对齐的最低容量。
3 配置启动菜单grub.cfg
把grub.cfg保存到/mnt/boot/grub/grub.cfg,就可以使用Qemu来测试移动硬盘了,看是否能看到菜单。 grub.cfg配置文件是主要是参考《How to create an Hybrid UEFI GPT + BIOS GPT/MBR boot USB disk》和《U盘引导多个linux镜像安装,同时支持BIOS和UEFI模式》两篇文章。
# path to the partition holding ISO images (using UUID) |
4 准备系统镜像
为了让镜像文件可以直接在Qemu中启动,我对镜像文件进行分区并添加了兼容UEFI和BIOS启动的Boot Loader,因为Qemu支持-kernel和-initrd参数加载内核,所以Linux镜像也可以不分区直接使用LVM管理整个镜像文件,关于Linux镜像的两种制作方法我都记录下来了。为了兼容Windows系统,系统镜像所在的分区采用的是NTFS文件系统格式,Debian需要安装ntfs-3g以支持ntfs文件系统格式,可以在安装过程中,切换到shell,chroot到安装好系统的目录,安装ntfs-3g以及修改Ramdisk的挂载脚本,使得内核可以在不同的执行环境中正确挂载分区和根目录。Debian镜像需要在虚拟机和真机上两种环境上运行的,不同的环境需要不同的挂载规则,需要修改Ramdisk中的挂载脚本以提供相应的支持。用虚拟机测试启动盘非常方便,可以把镜像文件作为虚拟机的虚拟机硬盘,先把系统安装和调试好,再放到移动硬盘中测试,Qemu也很容易配置USB Passthrough来测试启动盘,不需要在真机上不断重启来进行测试,请参考前文脚本。
刚开始并没有打算安装Gnome 3作为桌面环境的,而是使用轻量的i3窗口管理器。 Gnome 3的好处是开箱即用,不需要花费太多的时间去配置系统,一条命令下去就有一个舒适的桌面环境,5G的镜像,装完Gnome 3就所剩无几,你需要增加镜像的容量,用LVM管理分区的好处就是扩展容量会方便一点,不用LVM管理分区,用图形化的gparted分区扩容也是件很容易的事情。
4.1 添加loop和nbd内核模块
raw格式的镜像可以用loop内核模块加载,也可以nbd模块加载,nbd模块支持很多种镜像格式,如常见的vhd(x)、vmdk、vdi、qcow2等等,所支持格式的详情参考qemu-nbd文档。
# 内核中添加nbd和loop内核模块 |
4.2 制作LVM管理分区的Debian系统镜像(高级做法)
考虑到不是所有人都使用Linux作为主系统,使用macOS时,可以把创建逻辑卷过程放到Qemu虚拟机在Boot CD引导完成之后来进行。
4.2.1 先准备好内核Ramdisk中的挂载的脚本
安装ntfs-3g之后,内核当中就会添加ntfs-3g的内容,不需要手动添加ntfs-3g模块,内核挂载脚本执行顺序依次为/etc/initramfs-tools/scripts/{local-top,local-premount,local-bottom},这里需要在local-top和local-bottom分别添加一个脚本,前者用于挂载Debian系统镜像所在的数据分区和挂载系统镜像,后者用于在内核switch_root前,把数据分区以可读写的方式挂载到根文件系统中,否则switch_root后,是整个文件系统都是只读的。如果加载内核的过程中出现(initramfs),说明没有正确挂载系统镜像,在命令行中加载必要的内核模块、挂载数据分区和losetup系统镜像后,输入exit,就会内核就会继续执行启动步骤。需要调试脚本的话,可以参考lvm-loops-finalize,添加相应的log信息。这两个脚本的写法是参考buddy-linux项目的。 现在当前shell目录中准备好脚本lvm-loops-setup和lvm-loops-finalize,系统安装好之后,分别复制到/etc/initramfs-tools/scripts/{local-top,local-bottom}/目录中。
#!/bin/sh |
#!/bin/sh |
4.2.2 创建镜像、挂载分区和安装系统
sudo -s |
4.2.3 调整镜像容量
以下命令需要在Linux环境下执行
sudo losetup -f debian.img |
4.3 制作普通分区的Debian系统镜像(一般做法)
4.3.1 先准备好内核Ramdisk中的挂载的脚本
安装ntfs-3g之后,内核当中就会添加ntfs-3g的内容,不需要手动添加ntfs-3g模块,内核挂载脚本执行顺序依次为/etc/initramfs-tools/scripts/{local-top,local-premount,local-bottom},这里需要在local-top和local-bottom分别添加一个脚本,前者用于挂载Debian系统镜像所在的数据分区和挂载系统镜像,后者用于在内核switch_root前,把数据分区以可读写的方式挂载到根文件系统中,否则switch_root后,是整个文件系统都是只读的。如果加载内核的过程中出现(initramfs),说明没有正确挂载系统镜像,在命令行中加载必要的内核模块、挂载数据分区和losetup系统镜像后,输入exit,就会内核就会继续执行启动步骤。需要调试脚本的话,可以参考lvm-loops-finalize,添加相应的log信息。这两个脚本的写法是参考buddy-linux项目的。 现在当前shell目录中准备好脚本lvm-loops-setup和lvm-loops-finalize,系统安装好之后,分别复制到/etc/initramfs-tools/scripts/{local-top,local-bottom}/目录中。
#!/bin/sh |
#!/bin/sh |
4.3.2 创建镜像、分区、挂载分区和安装系统
qemu-img create -f raw debian.img 5g |
4.3.3 调整镜像容量
qemu-img resize -f raw debian.img +1G |
4.4 制作兼容UEFI和BIOS启动的Windows 10系统镜像
Windows 10的制作过程相对简单,却是花了最多的时间的才总结出来的,Windows所有的工具都是闭源的,只能效仿别人博客当中的用法。
diskpart |
5 参考文章
- 配置USB控制器的官方说明文档
- QEMU KVM Libvirt手册(6) – Network Block Device
- BIOS boot partition
- Hybrid_UEFI_MBR_USB_Drive
- How to create an Hybrid UEFI GPT + BIOS GPT/MBR boot USB disk
- U盘引导多个linux镜像安装,同时支持BIOS和UEFI模式
- Like "Wubi Ubuntu Installer" Project
- BIOS + GPT + GRUB + Linux + Windows 折腾笔记
- 继续折腾 - Dual Boot! 可移动的 Windows 和 Linux
- 使用BOOTICE修复BCD启动配置文件
- Grub2引导VHDX中的Windows
- Installing Windows 10 on a GPT disk with legacy BIOS and GRUB2
- WTG系统实现UEFI和传统BIOS双启动
- Installing Linux in a file in an NTFS partition
- Cannot delete device /dev/loop0