折腾了两天,总算成功实现了安卓手机的多系统,在此记录一下,权且做一个教程,给其他热爱折腾的人做一点参考。

首先要说明的是安装双系统乃至多系统,尤其是在手机上,对于很多人来说绝对是非常鸡肋的,而且安装的过程肯定会造成原先数据的丢失等等,安装之后也不能保证所有功能的正常(比如视频),但是对于爱玩机的人来说,能够经常体验不同的ROM还是很重要的。我之所以想安装多系统,就是因为发现了两个都让我非常喜欢的ROM——Pixel ExperienceSimplicity。这两个ROM可谓是两个极端,一个是纯原生安卓的体验,手感非常的好,吊打国内的各大ROM(这才是安卓啊),另一个则是浓厚的极客气息(自带Magisk、Busybox,以及各种底层破解……),在分别体验了两个ROM之后,我发现对它们都是爱不释手。小孩子才做选择,成年人全都要,多启动的想法自然而然地萌生了出来。

我的设备是Xiaomi Mix 2s (polaris) 国行6+64GB,其他设备的用户本教程可能并不适用,仅供参考

免责声明:本人不对任何教程中的操作造成的数据丢失以及设备损坏负责,请在操作前做好数据备份

一、常见方案

折腾前当然要看看有啥现成的轮子了,大致研究了一下界内的方案,基本都在XDA的这篇文章里讲到了,这里简单概括一下。

MultiROM

官方Wiki

作用于bootloader之后,可以用于引导不同的系统(含Linux),XDA称这是“已知的最好的多系统解决方案”。

https://forum.xda-developers.com/xiaomi-mi-mix-2s/how-to/multirom-multirom-polaris-t3957428

DualBoot Patcher

官网

非常有名的安卓引导工具,XDA高级成员,陈小龙大牛开发&&维护,但是在安卓10到来之后,开发者停止维护了。主要是由于新版安卓在架构上的一些调整造成了开发的困难。但是我想要安装Pixel Experience正是基于安卓10的,所以这个方案不行。

GRUB for Android

GRUB是x86架构上知名的引导程序,那么GRUB4Android顾名思义也是一个原生bootloader的替代品。现在这个项目已经衍生为了EFIDroid,但是看了一下官网最后一次更新是2016年,现在貌似也没有对Mix 2s进行适配,所以就放弃了。

综合以上,我最后选择MultiROM作为多系统的解决方案。

二、安装MultiROM版TWRP

在安装ROM之前,我们首先需要对引导程序进行一些处理。

1. 解锁BootLoader

BootLoader是嵌入式设备在操作系统内核运行之前运行的一段程序,它相当于控制了整个启动的大方向,厂商往往会在BootLoader里加入一些检查代码,限制非官方的系统的启动。因此如果想要进行刷机、root等操作,必须将厂商的限制解除。

由于BootLoader与硬件强绑定,因此必须通过厂商的官方途径(或者万能的淘宝)进行解锁。小米官方提供了解锁方式,傻瓜操作,在此略过。

2. 刷入Recovery

安卓刷机一般使用TWRP,这是一个开源的第三方Recovery,可以用于替换官方的Recovery,从而更方便地进行刷机等操作。

刷入的过程非常简单,重启手机进入fastboot模式之后,连接手机与电脑,使用ADB进行以下操作:

fastboot devices
# 检查设备连接状态
fastboot flash recovery your-TWRP.img
# 将TWRP烧入Recovery

现在,TWRP已经在你的手机的Recovery分区下了。

3. 安装MultiROM补丁

但是原版的TWRP并不支持多系统,因此我们需要安装TWRP之后打补丁,并替换MultiROM专用的TWRP版本。

而且因为嵌入式的强硬件相关性,我们需要根据自己的设备选择专用的MultiROM补丁,很幸运的是Mix 2s已经有人进行了适配,所以我们直接用轮子就好了。

我们打开相关页面,下载multirom_14-08-19.ziprecovery_3.3.1_17-08-19.img两个文件,储存在手机根目录或者U盘里,然后重启手机进入Recovery模式。

使用TWRP先刷入MultiROM补丁到原始ROM(操作与刷入Magisk类似,使用Install ZIP),再将recovery分区替换为MultiROM专用TWRP(使用Install Image)。

完成后再次重启手机,即可看到MultiROM已经安装完毕,此时理论上就可以使用MultiROM安装第二个ROM了。

三、安装第二个ROM

此时进入Recovery分区,也能通过点击右上角的菜单进入MultiROM的配置菜单

点击Add ROM,ROM类型选择Android,安装地点选择内置储存Internal Storage

选择你想要安装的ROM即可。

教程结束。显然不会这么简单,如果你安装的两个ROM都是安卓9及以下,而且是比较轻量化的ROM或者官方系统,那么以上应该就够了。但是如果你是安装安卓10或者含有root或者大量魔改的ROM,那么你的工作,才刚刚开始……

四、安装Pixel Experience

根据XDA论坛上提供MultiROM的大神的介绍,安卓10需要作为主ROM进行安装,具体可能与安卓10的加密机制有关。(具体原因尚不清楚,但是在安装完基于安卓10的系统后,文件系统是被加密的,需要安装MultiROM的补丁才能禁用掉加密)。

后来测试发现安卓10测试版也是可以直接刷入的……,可能只是Pixel Experience必须作为主ROM安装,或者安卓10正式版不能作为次ROM安装。

总之安卓10(在我这儿我选择的是Pixel Experience)必须在一开始就安装,然后在重启手机完成初始化之后再打补丁(不然可能会再初始化时卡住)。

在检查安卓10可以正常启动,MultiROM工作正常后,我们就可以继续安装其他的ROM了。

五、魔改并安装其他ROM

1. MIUI10

MIUI是基于安卓9的(虽然小米修改安卓版本号为10.0.0,但是实际上还是9的底层)。

使用MIUI10开发版(版本号9.8.22),可以正常作为Secondary ROM安装,没有遇到大问题。

2. Simplicity

首先尝试安装最新版的基于安卓10的Simpilicty,直接安装会触发E1001: Failed to update system image.的报错。

然后尝试安装基于安卓9的旧版Simplicity,发现仍然会触发这个报错。考虑到Simplicity本质上就是对MIUI的破解,开始对旧版Simplicity的ROM进行魔改。

因为安卓的ROM安装过程是由updater-script脚本控制的,它位于your-ROM.zip\META-INF\com\google\android目录下。打开后发现官方能够直接作为第二系统刷入的ROM是按照bootsystemvendorfirmware的顺序进行patch的,而Simplicity是按照bootfirmwaresystemvendor的顺序进行patch的,于是修改updater-script,将patch顺序进行调换。

## BEFORE
ui_print("Patching boot image unconditionally...");
package_extract_file("boot.img", "/dev/block/bootdevice/by-name/boot");
ui_print("Patching firmware images...");
package_extract_file("firmware-update/dsp.img", "/dev/block/bootdevice/by-name/dsp");
... # details omitted
package_extract_file("firmware-update/hyp.img", "/dev/block/bootdevice/by-name/hyp_b");
show_progress(0.600000, 250);
ui_print("Patching system image unconditionally...");
block_image_update("/dev/block/bootdevice/by-name/system", package_extract_file("system.transfer.list"), "system.new.dat", "system.patch.dat") ||
  abort("E1001: Failed to update system image.");
ui_print("Patching vendor image unconditionally...");
block_image_update("/dev/block/bootdevice/by-name/vendor", package_extract_file("vendor.transfer.list"), "vendor.new.dat", "vendor.patch.dat") ||
  abort("E2001: Failed to update vendor image.");
ui_print(" ");

## AFTER
# Patch boot first
ui_print("Patching boot image unconditionally...");
package_extract_file("boot.img", "/dev/block/bootdevice/by-name/boot");

# Patch system and vendor before firmware
ui_print("Patching system image unconditionally...");
block_image_update("/dev/block/bootdevice/by-name/system", package_extract_file("system.transfer.list"), "system.new.dat", "system.patch.dat") ||
  abort("E1001: Failed to update system image.");
ui_print("Patching vendor image unconditionally...");
block_image_update("/dev/block/bootdevice/by-name/vendor", package_extract_file("vendor.transfer.list"), "vendor.new.dat", "vendor.patch.dat") ||
  abort("E2001: Failed to update vendor image.");
ui_print(" ");

# Patch firmware at last
ui_print("Patching firmware images...");
package_extract_file("firmware-update/dsp.img", "/dev/block/bootdevice/by-name/dsp");
... # details omitted
package_extract_file("firmware-update/hyp.img", "/dev/block/bootdevice/by-name/hyp_b");
show_progress(0.600000, 250);

修改之后,即可正常安装,重启后能够进入系统,root等功能正常,安装成功。

六、体验与缺陷

整体来讲,双系统的切换还算流畅,切换的成本不是很高。

作为主系统的Pixel Experience手感非常好,功能基本正常,但是每次启动的时候都要重新设置时间,双摄不能正常使用(未适配)。

作为次系统的Simplicity有各种极客功能,主题也被破解了,可以免费换自己喜欢的使用,内置的迅雷下载加速也被破解为付费模式,可以把家里带宽跑满。但是估计是由于MulitROM启动次系统的时候只切换部分挂载的原因,GPU或者DSP驱动似乎有些问题,导致视频解码有问题,视频无法正常播放(作为次系统的MIUI也有这个问题)。

整体来说,还是实现了一开始的目的,反正小米也不是日用主力机,Pixel主要是用手感和Google的全家桶(手动狗头),Simplicity主要就是为了下载奇怪的资源和一些ROOT功能(比如虚拟定位,再次狗头)。

当然折腾的过程也大致了解了一些安卓底层的东西,但是所知还是甚少,看来还是要多读书,多学习(狗头.jpg


踩坑完毕