其实从标题就能看出来我有多蛋疼了。我不期望还有别的人和我有同样的奇怪需求,但是希望本文的一部分或几部分能对部分折腾者有一定有作用。

一、为什么会有这样的需求

要 BIOS 不要 UEFI

虽说现在的主板都采用 UEFI 了;虽说 BIOS 是很古老的东西了……但是,我实在不喜欢 UEFI 的复杂设计。说是 Unified 但是我感觉它一点也不统一。最重要的是:UEFI 对 Linux 不够友好。

要 GPT 不要 MBR

虽说严格来说 GPT 也是 UEFI 的一部分,但是我对它的印象好多了——MBR 只支持 4 个主分区而 GPT 默认情况就能支持 128 个分区,再也不用小心翼翼地折腾扩展分区和逻辑分区——这也是我所讨厌的。

要 Steam.exe 不要 Steam.deb

虽然我已经用惯了 Arch Linux;虽然 Valve 也有出 Steam for Linux 甚至 SteamOS,但是至少到目前为止,毕竟 Windows 才是正经的玩游戏的操作系统。

二、BIOS + GPT

2009 年之后的主板基本是 BIOS + UEFI 双配置,为了不让 UEFI 来瞎捣乱,我在主板设置里会选择 BIOS Only 以堵死 UEFI 的路。至于 2009 年以前的那些不支持 UEFI 的主板,倒有些需要小心:虽然理论上,只要不是古董电脑,都能支持 GPT,但是有一小部分有问题的 BIOS 会无法从 GPT 启动。 GPT 的分区工具首选 gdisk,不要用太旧的版本,默认就能 4k 对齐。

三、GRUB + Linux

虽然受到软件无政府主义的困扰,但是 GRUB 依旧是一款功能强大且十分流行的引导器。本文所指的 GRUB 一律指 GRUB 版本 2,而不是曾经的 GRUB Legacy。 要想让 BIOS + GPT + GRUB 工作,你需要一个 EF02 分区。由于没有了 post-MBR gap,这个分区是给 GRUB 放置它的 core.img 的,不需要文件系统。事实上,把 core.img 放在一个单独的分区里比放在 post-MBR gap 里稳定、整洁多了。在 gdisk 里新建分区时将分区标识符改为 EF02 即可,大小的话,2 MiB 足够了。 创建完 EF02 分区之后,其他的分区正常创建即可,比如我这样:

Number  Start (sector)    End (sector)  Size       Code  Name1            2048            6143   2.0 MiB     EF02  BIOS boot partition2            6144        20977663   10.0 GiB    8300  Linux filesystem3        20977664       230692863   100.0 GiB   8300  Linux filesystem4       230692864       500117503   128.5 GiB   0700  Microsoft basic data

然后使用 grub-install 即可自动将 core.img 嵌入那个迷你小分区。 至于 Linux 的安装,无需多言。

四、+ Windows

如无特别说明,以下提到的 Windows 指 NT 内核 6.0 以上版本。本文以 Windows 8.1 为例。

傲娇的 Windows

MSDN 明确指出,Windows 只能安装于 BIOS + MBR 或是 UEFI + GPT 的组合上,而 BIOS + GPT 和 UEFI + MBR 是不允许的。这实在是太傲娇了——因为 BIOS + GPT + GRUB + Linux 是完全没有问题的。事实上,我的笔记本电脑刚安装的时候并没有考虑到往硬盘里灌 Windows,因此之前一直是 BIOS + GPT + GRUB 的配置,在这样的情况想让 Windows 入驻,简直是逼我上梁山…… 为什么 MSDN 声称 Windows 不能在 BIOS + GPT 工作?经过我的试验,发现其实只是 bootmgr 读不了 GPT 而已。直到 bootmgr 被唤醒之前,一切都是没有问题的,而 bootmgr 应该去读取 \Boot\BCD 然后再根据 BCD 去加载 \Windows\System32\winload.exentoskrnl.exe。可是 bootmgr 读不了 GPT,直接导致它找不到 \Boot\BCD…… 那么怎么办呢?

  • 换一个能读 GPT 的引导器,读取 BCD 之后正常加载 Windows 内核。——不好意思,这样的引导器不存在。在得出这个结论之前,我吃了很多苦。
  • 将 BCD 放在 bootmgr 能读的地方。——比如一(小)块 MBR 存储设备,它不一定要是物理的,也能是虚拟的。在得出这个结论之前,我流了很多泪。

而 Windows 默认的安装程序要求又高、功能又弱,根本不会给你选择启动文件安装到哪里的,所以必须要手工安装。

要 imagex 不要 Setup.exe

Windows 默认安装框架是在 Windows PE 里使用 Setup.exe。该程序会运行一系列烦人的检查并增加一堆不合理的限定,比如要求 .NET Framework,比如强制添加 300 MiB 的系统分区等。而实际上它所做的事情也不过是:解压 install.wim 到指定分区、写入引导扇区、写入 BCD 这三样。可是这三件事,能自定义的部分还很少或很麻烦,那为啥不自己来呢?所以我更喜欢的方法是启动到 Windows PE 之后手工安装。

Windows PE 哪里来?TechNet 提供的方法是从 WAIK 里生成。但前面说了,Windows 的安装框架是 Windows PE,而 Windows 安装镜像文件也不过就是 Windows PE 和 install.wim 的组合而已,所以直接从安装镜像里就可以释放一个 Windows PE 出来。用 wimlib 提供的 mkwinpeimg 可以很方便地做到这一点,能直接从 Windows 安装镜像中获取 Windows PE 所需的 boot.wim 并制成可启动的镜像文件。如果你懒得自己提取 Windows PE,那么这里有我做好的两份。两份 Windows PE 除了添加了一个 imagex.exe 之外没有任何改动,十分纯洁干净:(其实不添加也行,用更加高大上的 dism 也能释放文件)

  • Windows PE 3.1 (32 bit)。提取自 Windows 7 SP1;
  • Windows PE 5.0 (64 bit)。提取自 Windows 8.1。

install.wim 哪里来?Windows 安装镜像里就有,使用 7z e Windows.iso sources/install.wim 即可把它解压出来。在移动存储设备里保存 install.wim 而不是完整的 iso,甚至能省下 500 MiB 以上的空间。

接下来就是安装了。通过可启动媒体启动进 Windows PE,用 diskpart 进行合理的分区。以下为带注释的操作过程:

# 确认当前硬盘情况
DISKPART> list disk
# 假设系统硬盘为 Disk 0 (Windows 将安装于此)
# Windows PE 所在的盘为 Disk 1 (请忽略)
# 过会儿要创建的 VHD 为 Disk 2 (Windows 启动文件将安装于此)
DISKPART> select disk 0
DISKPART> list partition
DISKPART> select partition 4
DISKPART> format label="Windows 8.1" quick
DISKPART> assign letter=c
# 以上命令格式化要安装 Windows 的分区并分配卷标 C:
# 接下来创建并挂载 VHD
DISKPART> create vdisk file=c:\bootmgr.vhd maximum=32 type=fixed
DISKPART> attach vdisk
# 然后在 VHD 里创建并激活分区。offset 不是必须的,但是我喜欢
DISKPART> select disk 2
DISKPART> create partition primary offset=1024
DISKPART> active
DISKPART> format label=bootmgr quick
# 分配一个卷标 B:
DISKPART> assign letter=b
# 退出 diskpart
DISKPART> exit

然后就是安装 Windows 和 Windows 启动文件了:

# 解压文件,注意根据实际情况选择 index,此处为 1
X:\> imagex /apply install.wim 1 c:
# dism 的等效命令是:(长多了)
X:\> dism /Apply-Image /ImageFile:install.wim /Index:1 /ApplyDir:C:\
# 写入启动代码和启动文件
X:\> bootsect /nt60 b: /mbr
X:\> bcdboot c:\Windows /s b:

至此 Windows 部分就算完成了,可以在 diskpart 里 detach vdisk 然后重启进 Linux 继续操作。

用 MEMDISK 引导硬盘镜像

在上一节中,我们得到了一个装好了 Windows 的分区,以及一块 32 MiB 的虚拟硬盘镜像,这块虚拟硬盘采用 MBR,有且只有一个主分区,主分区里装着大约 19 MiB 的 Windows 启动文件。其实这些启动文件真正核心的只有不到 1 MiB,其他的都是语言包和字体等,如果你闲得无聊可以挂载来删除它们,当然硬盘镜像文件大小不会自动缩小就是了。

那么,MEMDISK 能直接引导 vhd 么?我一开始也觉得不能,因此查到了用 VirtualBox 或 QEMU 来把 vhd 转成 raw image 的方法:VBoxManage clonehd --type raw bootmgr.vhd bootmgr.img。但是后来经 @tjmao 的提醒,我才发现原来当 type=fixed 的时候,vhd 其实就是 raw image 加上 512 字节的 footer。切掉这个尾巴之后,得到的东西和 dd 式的 raw image 是一模一样的。而就算不切掉尾巴,这一部分也会被认为是未分区空间从而被忽略掉。所以,其实 type=fixed 的 vhd 是不用转换,直接可以当 raw image 用喂给 MEMDISK 的。

那么怎么喂呢?根据调用 MEMDISK 的方法不同,具体的语法也有一定差别,完整的叙述可在这里找到。以下是 GRUB 的方法:

menuentry "bootmgr.vhd" {linux16 /boot/syslinux/memdisk harddiskinitrd16 /boot/bootmgr.vhd
}

把这一段复制到 /boot/grub/grub.cfg 中即可使用。如果要使它可在 grub-mkconfig 后自动生成的话,复制到 /etc/grub.d/40_custom 中即可。

至此 Windows 的引导就算是做好了。重启计算机在 GRUB 菜单中选择对应的 menuentry 即可进入。第一次进入的时候会自动安装驱动等,安装完自动重启,然后就功德圆满了。

五、一些可以改动的部分

如导言中所说,有和我完全一样的需求的人应该不存在,但是本文的思路可用于一些别的折腾过程中。以下列举了部分可以改动的部分,适用于不同的具体情况。

Linux 不是必须的

如果你只是想安装 BIOS + GPT 的 Windows,自然不用装 Linux。但是你可能需要备一个 Notepad.exe 在 Windows PE 环境中,用来编辑引导器的配置文件。

GRUB 可以换成别的

如果不装 Linux 了,那单独装个 GRUB 也没啥意思,还不如换点别的引导器。诸如 Syslinux, Grub4Dos 等,都可以用来加载 MEMDISK。具体的语法依然戳这里。不过如果换成别的启动器的话,那个启动器得要像 GRUB 一样对 GPT 有支持……

VHD 的大小问题

在想到 VHD 的方法之前,我曾试过的是把装的引导分区的 U 盘整个 dd_rescue 复制下来。这是一个较老的 U 盘,容量只有 4 GB,但是就这样产生的镜像文件也太大了,无法被 MEMDISK 正确加载。虽然最后我成功地把这个镜像挂载之后缩小文件系统和分区使它「瘦身」,但步骤较复杂。想到 VHD 的方法之后就简单了,直接创建一个小一点的 VHD 然后在里面操作即可。现在已知镜像文件不能太大,否则 MEMDISK 加载不了,那么它最小能多小呢?

核心的 Windows 启动文件只有 bootmgrBoot\BCD 这两个,加起来不到 1 MiB。我也试过,引导分区里只放这两个文件,依然能正常引导,但是实际上 VHD 不能只有 1 MiB。这是因为:

  • bcdboot 复制启动文件的时候,默认会复制那些语言包和字体,总共 19 MiB 左右
  • NTFS 分区最小需要 8 MiB

我实验成功的最小大小是 10 MiB 的 VHD,里面装着一个 8 MiB 的 NTFS。

当代的计算机大部分都是 4 GB 和 8 GB 的内存了,所以不用克扣这么一点点空间(毕竟它引导完就被释放掉了),所以创建 VHD 时选择 32 MiB 是个比较好的选择。记得 type=fixed 就行。

六、吐槽和尾巴

好久没写有关 Windows 的博文了。本来以为自己的对 Windows 的需求在 VirtualBox 里就能完全满足了,因此笔记本电脑安装系统的时候并没有为 Windows 考虑过,直接就是 BIOS + GPT + Linux 的组合了。可是自从 2014 年初在迷上了 Call of Duty 之后就入了 Steam 的大坑了,因此对独立的 Windows OS 的需求再次浮现。之前尝试 BIOS + GPT + Linux 既有配置下再塞个 Windows 怎么都没成功,因此选择了 Windows To Go 的解决方案——将整个 Windows 及其引导文件装到外置 USB 硬盘里。可是 USB 机械硬盘的速度又怎么能和 Samsung 840 Pro SSD 相比……于是发愤图强,努力研究,终于实现了 Windows 本体安装在 GPT SSD 里而把引导文件装到 MBR U 盘里的方法。慢慢地这样的方法又不能满足我的要求了,于是继续发愤图强,在各种来源都说这是不可能的情况下,我最终还是曲线救国成功了。

于是便有了本文。

转载请注明出处: https://wzyboy.im/post/1049.html

BIOS + GPT + GRUB + Linux + Windows 折腾笔记相关推荐

  1. BIOS, UEFI, MBR, GPT, GRUB介绍

    1. 前言 在学习 Linux 系统启动原理之前,我们先了解下与操作系统启动相关的几个概念. 2. 与操作系统启动相关的几个概念 不管是 Windows 还是 Linux 操作系统,底层设备一般均为物 ...

  2. NUC 折腾笔记 - Linux 系统篇

    NUC 折腾笔记 - Linux 系统篇 写一篇迟到的折腾笔记:NUC8 8i5beh .原本计划折腾 Hackintosh ,最后折腾了一台 Linux Homelab 设备. 本篇记录 NUC 基 ...

  3. linux安装 grub失败,安装linux+windows的系统 如果grub引导失败的解决方法

    对于安装linux+windows双系统的计算机,如果linux系统崩溃或者grub引导失败,可能导致windows也无法进入. (1) 通过linux的安装盘重新安装grub引导程序,成功地概率很小 ...

  4. Kali Linux 折腾笔记

    Kali Linux 折腾笔记(一)--安装及配置 安装的具体过程我就不说了,主要记录下配置中出现的一些问题 1. 更新源 首先判断kali版本 lsb_release -a 我的是kali-roll ...

  5. linux 可道云_unraid折腾笔记 篇八:手把手教你安装官方可道云,媲美FB的文件管理神器,学不会找我...

    unraid折腾笔记 篇八:手把手教你安装官方可道云,媲美FB的文件管理神器,学不会找我 2020-04-15 17:08:53 46点赞 232收藏 53评论 写在前面 unRaid作为Nas领域直 ...

  6. Linux(CentOS)学习笔记

    Linux (CentOS 7)笔记 1. Linux 目录的作用 目录名 目录作用 /bin 存放系统命令的目录, 普通用户和超级用户都可以执行. 不过放在/bin下的命令在单用户模式下也可以执行. ...

  7. 手写操作系统(4)——计算机是如何启动的?BIOS、GRUB、文件系统......

    我一直有一个疑惑--计算机到底是怎么启动的? 而且似乎有点矛盾--要想启动,就必须运行程序,但是计算机没开机怎么加载和运行程序呢? 为了解决这个矛盾,工程师终于想出将一小段程序固化进一块存储设备,电脑 ...

  8. windows相关笔记

    windows相关笔记 前言 一. 彻底关闭windows10自动更新 二.开机启动批处理禁用win10更新服务 三.解决win和(linux或mac)双系统时间不同步问题 四.添加环境变量示例ope ...

  9. 【Linux鸟哥笔记】20-启动流程、模块管理与Loader

    [Linux鸟哥笔记]20-启动流程.模块管理与Loader 目录浏览 章节学习 BIOS加载 内核功能 init进程 内核与内核模块 Boot Loader: Grub initrd 文件 启动过程 ...

最新文章

  1. Python再获年度编程语言,微软或成最大赢家
  2. Android开发之SpannableString具体解释
  3. Silverlight 2 RTW中ToolTipService.ToolTip不继承父节点的DataContext的问题
  4. 【Paper】2018_Nonlinear Consensus-Based Connected Vehicle Platoon Control Incorporating Car-Following
  5. 的日志在哪里_写给大忙人看的,MyBatis日志如何做到兼容所有常用的日志框架?...
  6. 【NLP】jieba分词-Python中文分词领域的佼佼者
  7. springmvc 后台向页面EasyUI的Datagrid传递数据(JSon格式)
  8. Establishing SSL connection without server's identity verification is not recommended.
  9. 在 Oracle Enterprise Linux 和 iSCSI 上构建您自己的 Oracle RAC 11g 集群 (2)
  10. Deep Learning for Joint Channel Estimation and Feedback in Massive MIMO Systems
  11. linux下怎么卸载mysql数据库_linux 怎么完全卸载mysql数据库
  12. JSP+javabean实现购物车功能
  13. Mysql数据库的备份与恢复
  14. 栈--后进先出的线性表
  15. AutoJs学习-传感器图像
  16. Java+控制台 商城销售系统
  17. Python 基础起步 (七) 初识字典 Dictionary(绝命毒师前传)
  18. 华为HCIP之静态路由
  19. 【原创】Windows Docker 设置阿里云镜像加速
  20. AppStore内收费软件和游戏破解方法--证实可行

热门文章

  1. [转载]总结LDO与升压芯片的选型
  2. 视频监控系统搭建为什么要使用流媒体服务器做视频分发?
  3. 第二十六讲:神州路由器PPP PAP认证的配置
  4. SMC 产品带有SIL认证的型号
  5. esp8266--arduinoJson在线解析V6版本的使用
  6. js现在的时间上增加小时分钟秒
  7. onmouseover和onmouseout事件冒泡导致闪烁的问题
  8. ActionForm中reset()的用法[转]
  9. emgucv4学习5---图像基本运算
  10. Java中的Stream流详解