ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

小米Mix2S刷入EDK2 UEFI固件:骁龙845设备引导Linux与Windows on ARM实战

小米Mix2S刷入EDK2 UEFI固件:骁龙845设备引导Linux与Windows on ARM实战 1. 为什么要在小米Mix2S上折腾UEFI手里这台小米Mix2S已经服役好几年了骁龙845放在今天跑个日常应用依然流畅但官方系统早就停更了。我一直在想能不能让它跑点不一样的东西。后来在社区里看到有人用EDK2给骁龙设备移植UEFI固件心里就痒了——如果这台手机能启动UEFI那理论上就能引导Windows on ARM或者Linux发行版可玩性直接拉满。这个项目的核心思路其实不复杂骁龙845本身是ARM64架构而EDK2EFI Development Kit 2是一套开源的UEFI固件开发框架社区里已经有MS8998这个针对骁龙845的平台适配项目。我们要做的事情就是把EDK2-MS8998编译出来的UEFI固件刷入小米Mix2S替换掉原来的Android引导链让设备在开机时直接进入UEFI环境。听起来很美好但实际操作中坑非常多。从编译环境搭建、设备树适配、固件分区布局到刷入后的启动调试每一步都可能卡住。这篇文章我会把整个流程拆开讲清楚包括我踩过的坑和最终跑通的方案。适合有一定Linux基础、了解Android分区结构、愿意折腾的玩家参考。如果你只是想给手机刷个第三方ROM那这篇内容可能过于硬核了。2. 核心概念与方案选型解析2.1 骁龙845的启动链路到底长什么样要理解为什么能移植UEFI得先搞清楚骁龙845的启动流程。高通平台的启动链路大致是这样的上电后先跑PBLPrimary Boot Loader这是固化在芯片里的PBL会加载XBLeXtensible Boot LoaderXBL再加载ABLApplication Boot LoaderABL负责初始化显示、存储等硬件最后加载boot分区里的Linux内核或者Android的recovery。关键点在于ABL这一层。ABL本身就是一个UEFI应用高通在ABL里实现了UEFI启动环境只是它默认只引导Android系统。EDK2-MS8998做的事情本质上是用开源的EDK2框架重新实现一套UEFI固件替换掉高通原厂的ABL同时保留XBL和更底层的引导链不变。这样做的好处是风险可控——XBL和PBL不动即使UEFI固件有问题理论上还能通过9008模式恢复。坏处是EDK2-MS8998需要自己处理硬件初始化包括显示输出、USB控制器、存储控制器等这些在高通原厂ABL里是现成的但在开源项目里需要自己适配。2.2 为什么选EDK2-MS8998而不是其他方案社区里针对骁龙845的UEFI项目不止一个我最终选EDK2-MS8998有几个原因。第一这个项目的代码结构比较清晰平台相关的部分和EDK2核心分离得比较好方便针对小米Mix2S做适配。第二项目已经支持了部分骁龙845设备包括一加6和小米8的部分变种说明基础框架是能跑通的。第三维护者比较活跃issue区里能看到不少设备适配的讨论。另一个考虑是工具链的成熟度。EDK2-MS8998用的是标准的EDK2构建系统交叉编译工具链可以用aarch64-linux-gnu或者项目自带的GCC编译过程相对标准化。相比之下有些项目用的是自定义的构建脚本出了问题很难排查。当然这个项目也不是没有缺点。它对设备树的支持还不够完善小米Mix2S的屏幕、触摸、USB等外设需要自己补充设备树节点。另外项目默认的UEFI固件体积比较大需要调整分区布局才能塞进去。2.3 UEFI固件在手机上的分区布局小米Mix2S的存储分区布局是典型的Android方案和UEFI固件相关的分区主要有这几个分区名原始用途移植UEFI后的用途xbl高通XBL保持不变abl高通ABL替换为EDK2 UEFI固件bootAndroid内核可保留或替换为UEFI引导项dtbo设备树覆盖可能需要调整vbmeta验证启动需要禁用验证abl分区的大小通常在1MB左右而EDK2编译出来的UEFI固件FD文件可能会超过这个大小。我实测编译出来的固件大约1.2MB所以需要先确认abl分区的实际大小如果不够就得考虑裁剪固件或者调整分区表。注意修改分区表有风险操作前务必备份原厂分区镜像尤其是xbl、abl、vbmeta这几个关键分区。3. 编译环境搭建与固件构建3.1 搭建EDK2编译环境编译EDK2-MS8998需要一台Linux机器Ubuntu 20.04或者22.04都可以。我用的是一台旧笔记本装的Ubuntu 22.04内存8GB编译过程大概需要10分钟左右。首先安装基础依赖sudo apt update sudo apt install build-essential uuid-dev iasl git nasm python3-distutils gcc-aarch64-linux-gnu这里有几个包是必须的iasl是ACPI编译器EDK2构建过程中会用到nasm是汇编器gcc-aarch64-linux-gnu是ARM64交叉编译器。如果你用的是Ubuntu 22.04python3-distutils可能已经包含在python3里了装不上也没关系。接下来克隆EDK2-MS8998的代码git clone https://github.com/edk2-ms8998/edk2-ms8998.git cd edk2-ms8998 git submodule update --init --recursive子模块更新这一步很关键EDK2的核心代码和部分依赖库都在子模块里不更新的话编译会报错。3.2 配置目标设备与编译参数EDK2-MS8998的构建系统支持多个目标设备小米Mix2S对应的配置文件名通常是xiaomi_mix2s或者类似的标识。在项目的Platform目录下可以找到各个设备的配置。编译前需要设置环境变量export WORKSPACE$(pwd) export PACKAGES_PATH$WORKSPACE/edk2:$WORKSPACE/edk2-platforms:$WORKSPACE/edk2-non-osi export GCC5_AARCH64_PREFIXaarch64-linux-gnu- source edk2/edksetup.sh然后执行构建build -a AARCH64 -t GCC5 -p Platform/Xiaomi/Mix2S/Mix2S.dsc -b RELEASE这里-b RELEASE表示编译发布版本体积会比DEBUG版本小一些。如果编译过程中报错找不到某个包检查PACKAGES_PATH是否设置正确。编译成功后生成的UEFI固件文件通常在Build/Mix2S/RELEASE_GCC5/FV/目录下文件名可能是MS8998_UEFI.fd或者类似的名字。3.3 固件裁剪与分区适配编译出来的固件如果超过abl分区大小就需要裁剪。EDK2提供了几种裁剪方式去掉不必要的驱动模块、压缩固件、调整FD文件的布局。我首先检查了abl分区的实际大小adb shell su -c ls -l /dev/block/by-name/abl输出显示abl分区大小是1048576字节也就是1MB。而我编译出来的固件是1.2MB超了200KB。裁剪的思路是去掉一些用不到的UEFI驱动比如网络相关的驱动、部分文件系统驱动。在DSC文件里找到对应的驱动条目用!if条件编译或者直接注释掉。另外把FD_SIZE调小一些让构建系统自动压缩。经过几轮调整最终固件大小控制在了980KB左右可以塞进abl分区。实操心得裁剪固件时不要一次性去掉太多驱动否则可能导致UEFI环境无法正常初始化。建议每次去掉一两个模块编译后刷入测试确认没问题再继续。4. 刷入UEFI固件与启动调试4.1 备份原厂分区刷入之前必须备份原厂分区这是保命操作。需要备份的分区包括abl、xbl、vbmeta、boot、dtbo。adb shell su -c dd if/dev/block/by-name/abl of/sdcard/abl_backup.img adb shell su -c dd if/dev/block/by-name/xbl of/sdcard/xbl_backup.img adb shell su -c dd if/dev/block/by-name/vbmeta of/sdcard/vbmeta_backup.img adb pull /sdcard/abl_backup.img adb pull /sdcard/xbl_backup.img adb pull /sdcard/vbmeta_backup.img备份完成后把这些镜像文件存到电脑上最好再复制一份到U盘或者云盘。我见过有人备份完直接放在手机存储里结果刷机后手机无法启动存储也读不出来备份等于没做。4.2 刷入UEFI固件刷入abl分区有几种方式fastboot、dd命令、9008模式。我推荐用fastboot因为操作简单且不容易出错。首先进入fastboot模式adb reboot bootloader然后刷入UEFI固件fastboot flash abl MS8998_UEFI.fd如果abl分区有A/B两份需要确认当前活动的是哪个slot。小米Mix2S是单slot设备直接刷abl即可。刷完后还需要禁用vbmeta验证fastboot --disable-verity --disable-verification flash vbmeta vbmeta_empty.imgvbmeta_empty.img是一个空的vbmeta镜像可以从网上下载或者用工具生成。禁用验证后设备启动时不会校验abl分区的签名。4.3 首次启动与串口调试刷入后重启设备如果一切顺利屏幕上应该会显示UEFI的启动界面。但实际情况往往没那么顺利——我第一次刷入后屏幕黑屏没有任何输出。这时候需要串口调试。小米Mix2S的串口在耳机孔附近需要拆机焊接TX、RX、GND三根线然后通过USB转TTL模块连接到电脑。串口参数是115200波特率8N1。连接串口后用minicom或者picocom打开串口终端picocom -b 115200 /dev/ttyUSB0重启设备观察串口输出。如果看到XBL的日志但ABL没有输出说明UEFI固件没有正确加载。可能的原因包括固件格式不对、分区刷入位置错误、固件大小超过分区限制。我遇到的问题是固件格式不对——EDK2编译出来的FD文件需要转换成高通ABL能识别的格式。项目里提供了一个转换脚本在Tools目录下python3 Tools/elf2abl.py MS8998_UEFI.fd MS8998_UEFI.abl转换后再刷入串口终于有输出了。5. 常见问题与排查技巧实录5.1 编译阶段常见错误编译EDK2-MS8998时最容易遇到的错误是找不到包或者工具链配置错误。下面这个表格整理了我遇到过的几个典型问题错误信息原因解决方法No package foundPACKAGES_PATH未设置或子模块未更新检查环境变量执行git submodule update --init --recursiveiasl: command not found缺少ACPI编译器sudo apt install iaslGCC5_AARCH64_PREFIX not set交叉编译前缀未配置export GCC5_AARCH64_PREFIXaarch64-linux-gnu-FD file too large固件超过分区大小裁剪驱动模块或调整FD_SIZE还有一个比较隐蔽的问题是Python版本冲突。EDK2的构建脚本对Python版本有要求如果系统里同时装了Python 2和Python 3可能会调用错误的版本。建议用python3 --version确认默认版本必要时用update-alternatives切换。5.2 刷入后无法启动的排查思路刷入UEFI固件后设备无法启动排查顺序应该是这样的第一步确认设备是否能进入9008模式。如果9008能进说明PBL和XBL没问题问题出在ABL或更上层。如果9008也进不去那可能是硬件问题或者XBL被破坏了。第二步连接串口看输出。如果串口完全没有输出检查焊接是否牢固、TX和RX是否接反。如果有XBL日志但没有ABL日志说明ABL固件没有被正确加载。第三步检查abl分区的刷入内容。用fastboot getvar all查看分区信息确认abl分区的大小和刷入的固件大小是否匹配。第四步尝试回刷原厂abl镜像。如果回刷后能正常启动说明UEFI固件本身有问题需要重新编译或调整。避坑技巧刷入UEFI固件前先用fastboot boot命令临时启动固件而不是直接刷入。这样即使固件有问题重启后设备还能回到原厂状态。不过fastboot boot对abl分区可能不适用具体要看设备支持情况。5.3 UEFI环境下的外设适配问题进入UEFI环境后屏幕显示和USB功能是需要重点适配的。小米Mix2S的屏幕是1080p的LCDUEFI固件需要正确的显示驱动才能输出画面。如果屏幕不亮但串口有输出说明显示驱动没有适配好。USB控制器也是类似的情况。UEFI环境下如果需要用USB键盘或者U盘必须确保USB驱动正常工作。EDK2-MS8998默认可能只启用了部分USB控制器需要根据设备树补充配置。我在适配屏幕时花了最多时间。小米Mix2S的屏幕初始化序列和高通参考设计不太一样需要从原厂内核里提取屏幕参数然后转换成UEFI显示驱动的配置。这个过程比较繁琐但一旦跑通后续就稳定了。6. 实际体验与后续可玩方向UEFI固件跑通后我在这台小米Mix2S上尝试了几件事。首先是引导Linux发行版用UEFI启动一个ARM64的Ubuntu镜像虽然性能有限但基本能跑起来。其次是尝试Windows on ARM这个难度更大因为Windows对UEFI环境的要求更严格而且驱动适配是个大问题。从实际体验来看骁龙845的性能跑UEFI环境是绰绰有余的瓶颈主要在驱动适配和存储速度上。小米Mix2S的UFS 2.1存储随机读写性能一般启动Linux系统大概需要30秒左右比预期的慢一些。后续可以扩展的方向有几个一是完善设备树把触摸屏、WiFi、蓝牙等外设都适配好二是尝试引导更多的操作系统比如postmarketOS或者Fedora ARM三是优化UEFI固件减少启动时间。这个项目的门槛确实不低需要同时具备Linux内核、UEFI固件、Android分区等多方面的知识。但如果你对底层系统感兴趣这绝对是一个值得投入时间的项目。我从开始折腾到最终跑通前后花了大约两周的业余时间中间刷坏过两次分区都是靠备份救回来的。所以再强调一遍备份、备份、备份。
返回列表