前言
“上一次制作WinPE,还是6.1。”
几个月前,遇到一个比较小众的需求——简单来说是要在 64位 的 WinPE 系统中运行某个第三方 32位 的应用程序。当时草草解决了这一问题,也在优快云写了部分草稿。你说巧不巧,不久之后GRUB就爆出了漏洞;优快云被挂了马。同时,也发现WinPE相关的论坛和工具多多少少带点毒。所以在此做个小结,记录要点,不做详细教程。
原始需求是为一台基于 64位 CPU 平台的计算机,在优先考虑 EFI / UEFI 启动方式的前提下,制作一个可运行 32位 应用程序的 WinPE 系统安装(恢复)映像。在考虑先进性、便捷性、可靠性后,选择以 WinRE 映像(版本 1.0.19041.1 )为基础进行修改,手动提取和添加 WoW64 子系统,实现对 32位 应用程序的兼容。
关联背景
架构
“从系统中的第一个比特,到……”
一文搞懂 x64 IA-64 AMD64 Inte64 IA-32e 架构之间的关系-优快云博客
x86
特指历史上 Intel 在若干型号以86结尾的处理器中使用的指令集架构,包含部分 16位 指令集架构。后也通指 32位 指令集架构。
IA-32
全称 Intel Architecture 32-bit。因 32位 架构完全由 Intel 提出和实现,故也通指所有 32位 指令集架构。
i386
特指 Intel 在 80386 处理器中使用的第一款 32位 指令集架构,后也通指 32位 指令集架构。
x64
通指所有 64位 指令集架构,与 x86 对应。
x86_64 / amd64
特指由 AMD 首次提出的 兼容 32位 的 64位 指令集架构。由于 Intel 和 AMD 使用的技术方案几乎相同,故也通指所有兼容 32位 的 64位 指令集架构。
IA-32e / EM64T (Intel64)
Intel 对自家 64位 指令集架构的别称,同 x86_64 / amd64 。
IA-64
Intel 在 安腾 (Itanium) 系列处理器中使用的 64位 指令集架构,不兼容 32位 。区别于 x86_64 / amd64 。
系统启动(Legacy BIOS & UEFI)
“起初,主板说要开机,便有了BIOS。”
关于两种引导方式的区别,可以参考这个链接。为防链接失效,在此整合,做一个文字引用。简单来说,启动方式-系统-应用程序 三者是对应绑定的,不同位数的三者基本不互相兼容。
从技术上来讲,是因为x86 32位函数调用calling convention和64位函数calling convention不相容(参数传递、压栈出栈等),UEFI和操作系统BootLoader之间是直接通过Boottime和Runtime协议函数互相调用的,没有转换层,不能直接调用,会死机。
Q:为什么Legacy BIOS可以启动 32位 和 64位 操作系统?
A:实际上,在操作系统启动之前,CPU和BIOS始终工作在16位实模式。之后由操作系统的Boot Loader使CPU进入32位保护模式,或进入保护模式后再进入64位长模式。换而言之,BIOS始终工作在16位模式下,对不同位数的兼容并不是BIOS提供的。
Q:为什么不同位数的UEFI和操作系统不能互相兼容?
A:简单来说,CPU制造商、操作系统制造商都懒得做,从而导致的历史遗留问题。实际上,早期基于Intel CPU的Mac是使用32位EFI固件启动64位Mac OS X的;ArcaOS 5.1 (OS/2的一个第三方版本) 则是只支持64位UEFI启动32位系统。
Windows-32-on-Windows-64(WOW64)
基于 x64 的 Microsoft Windows 版本经过优化,可运行本机 64 位程序。 此外,基于 x64 的 Windows 版本使用 WOW64 子系统来运行 32 位程序。