Mindows Android ↔ Windows 切换原理分析¶
分析时间: 2026-07-22
设备型号: LG G8 ThinQ (LM-G850, 代号 mh2lm)
存储类型: UFS (1d84000.ufshc)
当前状态: Android, 激活槽位 _a
一、整体架构¶
什么是 Mindows¶
Mindows 是一套让 LG 手机在 Android 和 Windows 之间双系统启动的方案。它的核心思路是:把手机原厂固件中的启动器(ABL)替换成电脑上使用的 UEFI 固件,然后利用 UEFI 的启动管理器在两个系统之间切换。
启动流程¶
| Text Only | |
|---|---|
关键:ABL 被替换成 UEFI¶
这是整个方案最关键的一步。LG G8 原厂的 ABL (Application Boot Loader) 分区中存储的固件,被替换成了 TianoCore/EDK2 编译的 UEFI 固件。UEFI 固件认识 FAT32/NTFS 文件系统,所以它能读取 Windows 的 EFI 分区并启动 Windows。
二、关键分区¶
| 分区名 | 块设备路径 | 大小 | 文件系统 | 用途 |
|---|---|---|---|---|
boot_a |
/dev/block/sde11 | 96 MB | 原始镜像 | 槽位 A 的启动镜像 |
boot_b |
/dev/block/sde34 | 96 MB | 原始镜像 | 槽位 B 的启动镜像 |
xbl_a |
/dev/block/sdb1 | 3.5 MB | 原始固件 | 槽位 A 的底层初始化 |
xbl_b |
/dev/block/sdc1 | 3.5 MB | 原始固件 | 槽位 B 的底层初始化 |
abl_a |
/dev/block/sde7 | 32 KB | ELF 程序 | UEFI 固件 (已替换) |
abl_b |
/dev/block/sde30 | 32 KB | ELF 程序 | UEFI 固件 (已替换) |
mindowsesp |
/dev/block/sda32 | 307 MB | FAT32 | Windows EFI 系统分区 |
mindowswin |
/dev/block/sda33 | 73 GB | NTFS | Windows C 盘 |
uefivarstore |
/dev/block/sde62 | 512 B | 二进制 | UEFI 变量存储 |
misc |
/dev/block/sda7 | 1 MB | 二进制 | 启动控制分区 |
三、切换方法¶
Android → Windows 切换¶
目标文件位于 /sdcard/Mindows助手/Mindows备份/:
| 文件 | 大小 | 写入目标 |
|---|---|---|
mh2lm_boot_b.img |
100 MB | boot_b 分区 |
mh2lm_xbl_b.img |
3.7 MB | xbl_b 分区 |
dtb |
1 MB | dtb 分区 |
mh2lm_fdt |
1 MB | fdt 分区 |
- 将上述文件用
dd命令写入对应分区 - 设置启动槽位为 B
- 重启手机
重启后,UEFI 会读取 simpleinit.uefi.cfg 配置:
| INI | |
|---|---|
UEFI 从 mindowsesp 分区加载 Windows Boot Manager,启动 Windows。
Windows → Android 切换¶
由 MindowsToolbox/Mindows一键切换/Mindows一键切换.bat 脚本实现:
- 将
boot.img(96MB Android 启动镜像) 用 dd 写入所有 boot 分区 - 可选擦除
misc分区(清空启动标记) - 执行
shutdown /r /t 0重启
重启后,UEFI 加载 Android kernel,正常启动 Android。
四、技术细节¶
本章节说明分析过程中用到的命令,以及每个命令揭示了什么信息。
4.1 确认当前用户身份和权限¶
| Bash | |
|---|---|
说明: 当前是 root 用户,拥有完整权限,可以读取所有分区。Magisk 上下文表示设备已 Root 并安装了 Magisk。
4.2 列出所有分区(核心命令)¶
| Bash | |
|---|---|
这是 最重要的命令。Android 设备在 /dev/block/by-name/ 目录下为每个分区创建了带名称的符号链接,直接指明了每个分区的用途。
输出中包含的关键分区:
说明: 通过分区名称直接推断用途。"mindows" 前缀的分区说明这确实是 Mindows 方案。A/B 双槽位是 Android 的标准做法,用于无缝系统更新。
4.3 查看分区大小¶
| Bash | |
|---|---|
输出中提取关键分区的大小信息(单位是块,通常是 1KB 一块):
| Text Only | |
|---|---|
说明: boot_a/boot_b 各 96MB 是标准的 Android 启动分区大小。Windows EFI 分区 300MB 足以存放启动管理器。Windows 系统分区 70GB 占了设备存储的大部分。
4.4 确认 ABL 分区已被替换为 UEFI¶
| Text Only | |
|---|---|
(abl_b 输出完全相同)
说明:
7f45 4c46即\x7fELF,这是 ELF 可执行文件的标准头标识。在电脑上,.exe是 PE 格式,.so是 ELF 格式。原厂的 ABL (Android Boot Loader) 通常是小端格式的 ARM 固件,但这里显示的是完整的 ELF 可执行文件,证实 ABL 已被替换为编译好的 UEFI 固件程序。
结论:abl_a 和 abl_b 都已经是 UEFI 固件,不再是最初的 Android Boot Loader。
4.5 确认启动分区内容为 Android 启动镜像¶
| Text Only | |
|---|---|
(boot_b 输出完全相同)
说明:
414e 4452 4f49 4421就是ANDROID!。所有 Android 启动镜像都以这 8 个字节开头作为标准标识 (magic number)。boot_a 和 boot_b 都包含 Android 启动镜像。
4.6 确认 Windows 分区的文件系统¶
| Bash | |
|---|---|
| Text Only | |
|---|---|
说明:
-mindowsesp(sda32) 格式为 vfat (FAT32),这是 UEFI 标准要求的 EFI 系统分区格式
-mindowswin(sda33) 格式为 NTFS,这是 Windows 的系统盘格式这两个文件系统都是 UEFI 固件原生支持的,UEFI 可以直接读取它们来启动 Windows。
4.7 确认当前启动的槽位 (Slot)¶
说明: 内核启动参数
androidboot.slot_suffix=_a表明当前是从槽位 A 启动的。这意味着 boot_a 分区中存放的是当前正在使用的 Android 内核和 ramdisk。
4.8 查看 misc 分区内容¶
| Bash | |
|---|---|
| Text Only | |
|---|---|
说明: misc 分区在整个 1MB 范围内都是 0。在标准 Android A/B 系统中,misc 分区用于在 recovery 和系统之间传递启动命令。这里全零说明 Windows → Android 切换脚本中的 "erase misc" 步骤已生效,或者从未使用过 misc 来标记启动目标。
4.9 查看 UEFI 变量存储分区¶
| Bash | |
|---|---|
| Text Only | |
|---|---|
说明: 头部
PTBL表示这是一个 Partition Table (分区表) 结构。UEFI 变量通常存储在文件或特殊分区中,这里使用分区表格式来组织变量数据。
4.10 查看设备信息¶
说明: 设备代号
mh2lm是 LG G8 ThinQ 的工程代号。Mindows 备份文件名中的mh2lm_前缀正是来源于此。
4.11 查看 Mindows 备份文件¶
| Bash | |
|---|---|
| Text Only | |
|---|---|
说明: 这些备份文件就是 Android → Windows 切换时需要的材料。
-mh2lm_boot_b.img (100MB)→ 写入 boot_b 分区
-mh2lm_xbl_b.img (3.7MB)→ 写入 xbl_b 分区,这是重新编译的初始化固件
-dtb/mh2lm_fdt→ 设备树文件,描述硬件拓扑给内核
-recovery_dtbo→ 设备树叠加层
4.12 查看 Windows 侧的切换脚本¶
执行命令查看脚本核心逻辑:
| Bash | |
|---|---|
脚本核心操作(第 159-176 行):
1. 使用 blktool_arm64.exe 通过分区名反向查找磁盘和分区编号
2. 将磁盘号映射为 /dev/sdX{num} 格式的块设备路径
3. 用 dd_cygwin/dd.exe 将 boot.img 写入所有 boot 分区
4. 执行 shutdown /r /t 0 重启
4.13 查看 UEFI 启动配置¶
| Bash | |
|---|---|
| INI | |
|---|---|
说明: 这是 UEFI 的启动配置文件。
-boot.default = "continue": 默认继续启动(启动 Windows 的 Boot Manager)
-boot.second = "simple-init": 第二选项进入 simple-init(这是一个简单的 UEFI 应用程序,可能提供在 Android 和 Windows 之间选择的菜单)
-boot.timeout = 3: 等待 3 秒超时后自动选择默认项
4.14 使用 blktool 一站式查询分区(比手动 ls/proc 更强大)¶
前面 4.2、4.3、4.6 使用了三个不同命令(ls /dev/block/by-name/、cat /proc/partitions、blkid)来查分区信息。实际上 Mindows 工具箱 APK 内置的 libblktool.so 可以在 Termux 下直接执行,一条命令完成所有查询:
libblktool.so 实质上是静态链接的 ARM64 可执行文件,虽然后缀是 .so,但不需要任何依赖即可运行:
| Text Only | |
|---|---|
在 Termux 中直接使用:
| Bash | |
|---|---|
对比: 原来需要三个命令 + 手动计算块大小 → 现在一行命令直接出结果,还自动标注了文件系统类型。
JSON 格式输出(方便脚本解析):
| Bash | |
|---|---|
| JSON | |
|---|---|
说明:
blktool是blktool_arm64.exe(Windows 版)的 ARM64 Linux 版本。同一个工具,在 Windows 侧和 Android 侧都能跑,API 完全一致。
4.15 使用 magiskboot 深入分析启动镜像¶
前面 4.5 只读了 boot 镜像的前 8 个字节确认 ANDROID! 头。用 libmagiskboot.so 可以**完整解包启动镜像**,查看内核、ramdisk、设备树等所有组件:
| Bash | |
|---|---|
| Text Only | |
|---|---|
查看 header(启动镜像元数据):
| Bash | |
|---|---|
| Text Only | |
|---|---|
说明: header 中包含了内核命令行参数,可以看到
slot_suffix信息。这说明启动槽位不仅记录在 misc 分区中,也烧录在启动镜像本身的 cmdline 里。
应用价值: 可以用 magiskboot 的 hexpatch 功能修补 kernel cmdline、用 cpio 修改 ramdisk 中的 init 脚本,实现更高级的启动行为定制——比如修改超时时间、预设默认系统等。
4.16 使用 ntfs-3g 在 Android 下直接访问 Windows 分区¶
前面 4.6 用了 blkid 确认 Windows 分区的文件系统类型是 NTFS。但确认类型和**真正挂载读写**是两回事。APK 中的 libntfs-3g.so 同样是静态可执行文件,可以在 Android 下直接挂载 Windows 分区:
| Bash | |
|---|---|
| Text Only | |
|---|---|
| Bash | |
|---|---|
说明: 这意味着在 Android 系统中就可以直接操作 Windows C 盘——备份文件、修复驱动、编辑注册表等都可以做到,不需要切换到 Windows。
ntfs-3g也支持-o rw读写挂载,但需谨慎操作避免损坏 NTFS 文件系统。
4.17 验证三个 .so 文件是独立的可执行程序¶
很多人会认为 .so 是动态链接库,必须在 APP 内通过 System.loadLibrary() 加载。但 Mindows 这三个 .so 文件实际上是**静态链接的独立可执行文件**:
| Text Only | |
|---|---|
libblktool.so 和 libmagiskboot.so 是纯静态链接,完全没有外部依赖:
| Bash | |
|---|---|
| Text Only | |
|---|---|
说明: Android APK 规范要求 native 代码以
.so扩展名存放在lib/<架构>/目录下。开发者把独立可执行程序编译后直接改名为.so放入 APK,APP 通过Runtime.exec()调用它们(而非System.loadLibrary())。这也是为什么这些文件能从 Termux 中直接运行。
五、总结¶
Mindows 双系统切换的本质¶
- 固件层面: 用 UEFI 替换 ABL,让手机像电脑一样支持 UEFI 启动
- 分区层面: 在手机闪存中划分出 Windows 专用的 EFI 分区和系统分区
- 切换层面: 通过向 boot 分区写入不同的启动镜像来控制启动哪个系统
- 工具层面: 提供 Windows 下的批处理脚本和 Android 下的备份文件来完成切换
整个方案的精妙之处在于利用 Android 的 A/B 分区机制,让两个系统和平共处:槽位 A 负责 Android,槽位 B 负责 Windows,切换只需几个 dd 命令和一次重启。
工具链全景图¶
Mindows 在三层都提供了对应的工具:
你可以直接用这些工具做什么¶
有了 blktool + magiskboot + ntfs-3g 三个命令行工具,在 Termux root 环境下,无需打开 APP 即可完成以下操作:
| 操作 | 命令 |
|---|---|
| 查任意分区路径/大小 | blktool -N 分区名 --print-device --print-size -n |
| 备份 boot 分区 | dd if=$(blktool -N boot_a --print-device -n) of=boot_a.img |
| 解包启动镜像 | magiskboot unpack boot_a.img |
| 修改 kernel cmdline | magiskboot hexpatch kernel "旧参数" "新参数" |
| 重新打包 | magiskboot repack boot_a.img new_boot.img |
| 挂载 Windows C 盘 | ntfs-3g -o rw $(blktool -N mindowswin --print-device -n) /mnt/win |
| 修复 Windows 文件 | 挂载后直接 cp / rm / 编辑文件 |
| 手动切换到 Windows | dd if=mh2lm_boot_b.img of=$(blktool -N boot_b --print-device -n) && reboot |
| 手动切回 Android | dd if=boot.img of=$(blktool -N boot_a --print-device -n) && reboot |