概述
目标
- 向目标U盘中安装Ubuntu系统
- 该安装能够在BIOS或UEFI引导下进入系统
- 无需制作另外的LiveCD安装介质
方法
- 使用虚拟机(VMWare为例)作为安装环境, 安全无污染, 不必担心宿主机环境被损毁
- 使用GPT分区表, 预留bios_grub分区, 先进行UEFI引导下的安装, 之后添加BIOS引导
- 使用虚拟机(VMWare为例)作为测试环境, 无需开关宿主机就可以验证安装是否成功
需求
- Ubuntu镜像, iso格式, 本教程使用20.04.1, 对于其他linux发行版有待验证
- VMWare Workstation Pro或其替代品, 能够支持:
- 创建并管理虚拟机, 需要提供虚拟光驱, USB
- (安装用)UEFI模式引导虚拟机系统
- (安装用)挂载USB设备, 或将宿主机UAS设备挂载为虚拟机SCSI磁盘
- (测试用)BIOS模式引导虚拟机系统
- (测试用)将宿主机UAS设备挂载为虚拟机SCSI磁盘
- U盘
- 16GB或更高, USB3.1或更高
- (推荐)使用固态硬盘+转换盒组成的固态U盘
警告
- 升级内核时或者大版本时, 请务必谨慎
- 如果出现升级后无法引导的情况, 请查阅下文当中的
维护U盘中的Ubuntu
向U盘安装Ubuntu
准备U盘
- 备份U盘中的任何数据, 如果有必要
- 必须确认U盘中的数据可以全部被删除
- 删除所有已经存在的分区, 并将U盘分区表转换为GPT类型
创建虚拟机
- 虚拟机名称: 随意
- 虚拟机版本: 默认
- 客户机操作系统: Ubuntu 64位
- 硬件: 全部默认
更改虚拟机属性
- 移除-虚拟网络控制器
- 移除-虚拟硬盘
- 修改-USB控制器版本, 匹配宿主机目标U盘的实际协议
- 修改-虚拟光驱, 挂载Ubuntu镜像iso, 勾选
启动时连接
- 修改-
虚拟机设置>选项>高级>固件类型
, 设置为UEFI
启动虚拟机, 准备安装
- 开机-虚拟机应当引导进入Ubuntu LiveCD, 直到出现
Try Ubuntu
和Install Ubuntu
字样 - 选择-
Try Ubuntu
, 直到进入LiveCD桌面 - 挂载-右下角托盘, 将目标U盘作为USB设备挂载到虚拟机
- 选择-检测到USB设备后,
Install Ubuntu xxxx
, 启动安装程序
开始安装
- 选择-按需选择语言, 安装规模等, 直到
Installation Type
页面 - 选择-
Something Else
, 即手动进行分区并安装
对U盘进行分区
- 新建分区表-右键U盘设备, 应当为
/dev/sda
, 选择New partition table
- 添加分区-添加如下的分区, 分区大小仅供参考
- (必须)大小1MB, 类型为
Reserved BIOS boot area
- 添加该分区后, 您可能会注意到, 磁盘头部出现33MB的未分配空间, 而该分区大小变为33MB, 这是完全正常的
- (必须)大小500MB, 类型为
EFI System Partition
- (可选)大小500MB, 类型为
Ext4 journaling file system
, 挂载点/boot
- 该操作不推荐, 99%的情况下不必要
- 某些老旧的BIOS无法识别存在于8GB或64GB之后的可引导分区, 因此该操作曾经有意义
- 使用raid等方式安装系统时, 该操作是必须的, 很明显我们没有这样做
- (必须)大小10GB+, 类型为
Ext4 journaling file system
, 挂载点/
- 若有单独为
/home
分区, 该大小推荐设置为20GB左右 - 若无单独
/home
, 占满磁盘剩余空间即可, 若有需要可以保留一些未分配空间
- (可选)大小10GB+, 类型为
Ext4 journaling file system
, 挂载点/home
- 看个人情况, 占满剩余磁盘空间或保留一些未分配空间
- 确认分区-必须包括如下分区
- (必须)大小1MB, 类型为
Reserved BIOS boot area
- (必须)大小500MB, 类型为
EFI System Partition
- (必须)大小10GB+, 类型为
Ext4 journaling file system
, 挂载点/
完成安装
- 地区, 账户按需要填写, 等待安装完成, 不要退出安装程序
- 选择-
Continue trying
为BIOS添加引导
fdisk -l
# 教程假定挂载点为'/boot'的分区(若存在)为/dev/sda3, 请根据需要修改
# 教程假定挂载点为'/'的分区为/dev/sda3, 请根据需要修改
- 挂载
/
的分区到当前系统 或 挂载/boot
的分区到当前系统
mkdir /mnt/sda3
mount /dev/sda3 /mnt/sda3
- 安装grub, 根据挂载的是否为
/boot
挂载点的分区选择您待执行的命令
# 如果您挂载的是'/'分区, 其为/dev/sda3, 则
grub-install --target=i386-pc --boot-directory=/mnt/sda3/boot /dev/sda
# 如果您挂载的是'/boot'分区, 其为/dev/sda3, 则
grub-install --target=i386-pc --boot-directory=/mnt/sda3 /dev/sda
- 检查分区情况
- 启动gparted
- 如果您发现添加时设置为1MB的分区, 此时拥有文件系统
grub core.img
, 说明grub-pc安装完毕
关闭虚拟机
测试U盘中的Ubuntu
更改虚拟机属性
- 添加-虚拟硬盘, 磁盘类型设置为
使用物理驱动器
, 选择目标U盘, 一般为最后一个 - 修改-虚拟光驱, 取消勾选
启动时连接
启动虚拟机(UEFI)
- 虚拟机应当成功引导进入Ubuntu桌面, 执行下面的命令, 以验证当前的引导类型
ls /sys/firmware/efi
# 若成功执行, 说明为UEFI引导; 若提示找不到文件, 则为BIOS引导
更改虚拟机属性
- 修改-
虚拟机设置>选项>高级>固件类型
, 设置为BIOS
启动虚拟机(BIOS)
- 虚拟机应当成功引导进入Ubuntu桌面, 执行上文的命令, 以验证当前的引导类型
关闭虚拟机
维护U盘中的Ubuntu
- 如果发生无法引导的状况, 可以参考该节进行维护, 仍使用虚拟机方法
创建虚拟机
启动至LiveCD
开始修复
# root
sudo su
# 定位分区
fdisk -l
# 假设 /dev/sda2 为 efi 分区
# 假设 /dev/sda3 为 / 分区
# 假设 /dev/sda3 为 /boot 分区, 如果有
# 挂载分区
mkdir /mnt/sda2
mkdir /mnt/sda3
mount /dev/sda2 /mnt/sda2
mount /dev/sda3 /mnt/sda3
# 安装efi需要的依赖
apt install grub-efi-amd64
# 安装bios需要的依赖,-bin结尾的不会与efi冲突
apt install grub-pc-bin
# 以下命令针对没有单独/boot分区的用户
## 修复UEFI引导
grub-install --target=x86_64-efi --boot-directory=/mnt/sda3/boot --efi-directory=/mnt/sda2 --removable /dev/sda
## 修复BIOS引导
grub-install --target=i386-pc --boot-directory=/mnt/sda3/boot /dev/sda
# 以下命令针对单独/boot分区的用户
## 修复UEFI引导
grub-install --target=x86_64-efi --boot-directory=/mnt/sda3 --efi-directory=/mnt/sda2 --removable /dev/sda
## 修复BIOS引导
grub-install --target=i386-pc --boot-directory=/mnt/sda3 /dev/sda
测试修复结果
发生甚么事了
- 这一部分将解释为什么上文的操作能行, 核心的概念:
- 我不是BIOS或者UEFI或者MBR或者GPT专家, 这里的介绍仅供参考
MBR分区表
- MBR: 主引导记录, 在磁盘扇区0, 包括一段引导代码和分区表之类的
- 神秘的空间: 扇区1~扇区62
GPT分区表
- GPT: 在磁盘扇区1
- protective MBR: 在磁盘扇区0
- 主要为了防止不认识GPT的程序, 将磁盘误认为未分区, 因此添加该部分, 假装自己是MBR
- 尽管具有正常MBR的结构, 但是这里把整个磁盘分为一个区, 意思就是"别瞎搞"
- 正因此结构, BIOS+GPT的组合才能成功
- bios_grub分区
- 代替"神秘的空间", 专门为grub-pc在GPT上运行
BIOS引导
- 流程概述
- 加载主板rom当中的BIOS固件
- 磁盘扇区0为MBR, 加载其中的代码段
- 代码段执行, 直接加载操作系统, 或者加载更多代码直到加载操作系统
- grub-pc
- MBR扇区代码段, 被grub-install替代为
boot.img
的内容, 该代码将加载一个硬编码地址的core.img
- 由于GPT存在
protective MBR
, 在GPT分区下依然可以安放这段代码, 而BIOS固件根本不在乎分区表类型, 因此可以启动
core.img
存放在:- MBR下: 扇区1~扇区62的这个部分里, “神秘的空间”, 和bootkit类病毒肩并肩
- GPT下: 带有
bios_grub
的分区内
core.img
执行时, 将根据配置文件加载操作系统
UEFI引导
- 流程概述
- 加载主板nvram当中的UEFI固件
- 磁盘带
esp
flag的分区, 加载其中的.efi
文件 - 加载操作系统
- grub-efi
UEFI+GPT
- 美滋滋, 最新最好的引导和分区方式, 一种标准范式
- windows使用UEFI引导强制要求GPT, 这是windows的错误
UEFI+MBR
- 可以配合BIOS+MBR实现双启动
- 我也尝试过了, 但是不优雅, 等我心情好在写在这里
- MBR面临主分区最大4个或3个, 外带拓展分区和逻辑分区的问题, 不影响使用, 但不够优雅
BIOS+GPT
- 本文方法, 配合UEFI+GPT实现双启动
- BIOS只查看第一个扇区, 加载里面的代码, 然后跳转走人, 因此只要第一个扇区是一个有效的MBR即可, 而GPT恰好可以
- UEFI只看一个esp分区, 也是同样
BIOS+MBR
总结
- 本文操作能成功的关键
- GPT的protective MBR, 允许一个GPT分区兼容MBR的代码段
- grub-pc针对GPT提供的bios_grub解决方法