Tag Archive for bootmgr

BIOS + GPT + GRUB + Linux + Windows 折腾笔记

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

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

要 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  Name
   1            2048            6143   2.0 MiB     EF02  BIOS boot partition
   2            6144        20977663   10.0 GiB    8300  Linux filesystem
   3        20977664       230692863   100.0 GiB   8300  Linux filesystem
   4       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 也能释放文件)

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 harddisk
  initrd16 /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

关于多系统启动及如何在已有 Win 7 情况下装 Win XP

在很多网上的教程里都告诉我们,如果要在你的电脑里装多个系统,那么一定要按照这个顺序装:低等级 Windows 系统→高等级 Windows 系统→ Ubuntu 等 Linux 发行版。这是因为如果倒过来装,那么低等级的 Windows 系统的引导程序会把高级的 Windows 系统及 Linux 发行版的引导程序破坏。事实也的确是这样的,但是难道真的没有变通的方法吗?如果我硬盘里已经有 Windows 7 了,我要再装个 XP ,一定就要重装 Windows 7 吗?本文将会为你提供一种解决此问题的方法。

一、关于多系统启动

(由于 Mac OS X 系列系统难以在普通 PC 上安装,所以本文只讨论 Windows 和 Linux 。前者以 Windows 7 和 Windows XP 为例,后者以最流行的发行版 Ubuntu 的 10.04 版本为例)

在 NT 架构出现之后, NT6.0 出现之前,也就是从 Windows NT 到 Windows Server 2003 (内核为 NT 5.3 )这段时间里, Windows 系统的引导程序都是 ntldr ,这是一个存在于硬盘的第一个主分区的一个小文件,就是它引导系统启动的。如果你的电脑的操作系统是 Windows XP 的话,那么看看 C 分区的根目录里,就有这样的一个文件。

在 NT6.0 (第一个使用 NT6.0 内核的操作系统是 Windows Vista )出现之后, ntldr 就退休了,新的引导程序叫 bootmgr ,也就是 Boot Manager ,这也是一个存在于硬盘第一个主分区的小文件,比 ntldr 稍大一些,但是也只有 300KB 多一点,新的 Windows 系统用它来引导启动。如果你的电脑的操作系统是 Windows Vista 或是 Windows 7 的话,那么在 C 分区的根目录里就有这样的一个文件。

无论是 ntldr 还是 bootmgr ,都是可以管理多系统启动的,就是说它可以形成一个多系统选单,在开机的时候显示一下,让你选择进入哪个系统,问题也就这样来了。 ntldr 时代要管理多系统选单是很容易的,因为在与 ntldr 这个文件同目录里,还有一个叫 boot.ini 的文本文件,用记事本打开它可以看到类似这样的文字:

[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(6)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(6)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetec

这样编辑起来真是太容易了,只要把这个文件的只读属性去掉,然后就可以随意地添加选项并保存了。

而 bootmgr 出现后,编辑多系统选单就没有这么简明了。在 Windows Vista和Windows 7 里内置了一个叫 bcdedit 的命令行工具,可以用来导出、编辑、保存 bootmgr 的设置,具体用法可以在 cmd 里敲入 bcdedit 来查看,这里不再详细叙述。此外还有一些带 GUI 的编辑器,下文会提到。

至于 Ubuntu 10.04 这个发行版,则是用一个叫 grub2 的工具来引导的,这是一个安装在 MBR 里的微型操作系统,功能强大,但是却不是那么容易使用,这里也不再详细介绍。

清楚了这三个系统的引导机制,问题也就来了:安装顺序。关于安装顺序的几点事实:

  1. 先装 Windows XP 再装 Windows Vista/7 ,那么后者会自动检测前者的存在,把它加入到 bootmgr 的多系统选单中,双系统或三系统都可以正常启动。
  2. 先装 Windows XP/Vista/7 ,再装 Ubuntu ,那么后者也会自动检测前者的存在,把它们都加入到 grub2 的多系统选单中,双系统或三系统或四系统都能正常启动。
  3. 先装 Windows Vista/7 ,再装 Windows XP ,那么后者会用自己的 ntldr 把前面的设置全部覆盖掉,只有 Windows XP 能启动,其它的系统都存在于硬盘里,但是无法启动。这也很好理解,因为 XP 是 2001 年出生的,当时还没有 bootmgr 这种东西。
  4. 硬盘里已经存在有 Ubuntu 再装 Windows XP/Vista/7 ,结果我不记得了,貌似比较惨烈,因为 grub2 似乎还存在,但是已经无法正常工作,似乎一个也启动不了,或者还有一种结果是只有 Vista/7 能启动,其它的都看不见了。

需要说明的是,以上列出的情况下,都是把不同的系统装在不同的分区里的。

本来我的电脑里是 Windows 7 和 Ubuntu 双系统,用 grub2 引导的这一个系统,使用 bootmgr 引导,前段时间因为一些特殊原因,我需要在电脑里装一个 Windows XP ,于是有了这篇文章。

二、尝试用 grub2 引导

我本来是想用 grub2 引导三个系统的,但是后来发现我实在是搞不定 grub2 ,安装了 XP 之后 grub2 就陷入不正常的状态,可能是相关的设置信息丢失了,结果开机后一个系统也看不见,只有 grub rescue 的命令行界面在一闪一闪。没办法,我用 Ubuntu Live CD 启动,然后尝试用 root 权限修改 /boot/grub/grub2.cfg 文件,改了半天,重启动, grub rescue 还是在那里一闪一闪,实在是没辙,算了,放弃 grub2 吧,改用 bootmgr 了。

于是要请走 grub2 ,我用量产过的 U 盘启动到 PE 下,用磁盘分区表工具把 MB R重写了一遍,这样之后,存在于 MBR 里的 grub2 就算被清除了。

二、在已存在 Windows 7 情况下安装 Windows XP 的步骤

正如上文所说,如果先装了高等级的 Windows 系统,再安装低等级的 Windows 系统,则后者会把前的引导设置破坏。比如我的电脑里已经有了 Windows 7 ,这时候我要装 Windows XP 了,那么装完后就只有 Windows XP 能启动了。如何修复双系统启动菜单呢?按着下面的步骤走:

安装 Windows XP

  1. 分区安装XP。我的Windows 7是安装在硬盘的第一个主分区的,打算把XP安装在后面的一个逻辑分区里。分好区之后,格式化,就可以安装了。我用的是普通的安装版XP而非GhostXP。
  2. 安装完XP之后,的确只有XP能启动,没有多系统选单出现。这时候接管引导任务的是ntldr而不是bootmgr了。

修复bootmgr引导

  1. 进入Windows XP,从Windows 7的安装光盘里提取X:\boot\bootsect.exe(其中X代表光盘盘符)个文件,把它放到一个便于操作的目录里,比如D分区根目录。
  2. 打开cmd,切换到D分区,然后键入以下命令:bootsect /nt60 c:输入完毕后重启系统。这时候系统是用bootmgr引导的,不过只有Windows 7能够启动,没有多系统选单。

修复Windows 7和Windows XP双系统选单

  1. 现在已经在Windows 7里了,如果你之前用的是mbr导入证书式的破解版Windows 7,此时应该会提示你你使用的版本不是正版,重新导入一次就可以消去提示。
  2. 下载一个叫EasyBCD的软件,这就是上文提到的bcdedit工具的GUI版本,是第三方制造的。它的功能非常强大,可以轻易地修改BCD设置,添加各种各样的启动项,包括各类Windows版本,WinPE,Linux/BSD,甚至包括Virtual Disk(vhd文件)和Mac OS X。
  3. 打开它,按照下面的图示操作:easybcd-1
  4. 点击 Save 之后,列表就应该多出一个你刚才添加的选项了,也就是Windows XP。这时点击左侧的第一个按钮 View Settings ,看到的内容应该与下面类似:
    There are a total of 2 entries listed in the bootloader.
    
    Default: Windows 7
    Timeout: 3 seconds.
    Boot Drive: C:\
    
    Entry #1
    Name: Windows 7
    BCD ID: {current}
    Drive: C:\
    Bootloader Path: \Windows\system32\winload.exe
    
    Entry #2
    Name: Windows XP
    BCD ID: {a2744f94-d151-11de-9a84-a4dce0d08af0}
    Device: boot
    Bootloader Path: \NTLDR
  5. 这时点击左侧的 Change Settings 按钮,可以看到如下画面:easybcd-2
  6. 在②处可以修改默认的启动系统,在③处可以修改系统选单停留的时间。修改完后按 Save Settings 按钮保存。
  7. 此时重启动系统已经是双系统选单了。

转载请注明本文出处。谢谢合作。

~~~~
wzyboy
Twitter: @wzyboy
Link: http://wzyboy.im/