技术 222 阅读 10 评论

    手动将一加13 升级到 16.0.8.301 版本同时保留 EDL (9008)权限

    之前通过刷写旧版本的abl_a、xbl_a、xbl_config_a、xbl_ramdump_a保9008失效了,因为新版本内核代码中加入了防回滚,现在除了刷这几个分区,你还得在刷入新包前解包,自己删除这部分代码,重新编译内核,打包线刷包。
    如图,近期更新的源码:
    在源码中搜索update_arb可以看到:

    001.jpg

    002.jpg

    003.jpg

    004.jpg

    005.jpg

    看看内容:qcom_scm.c中的:int qcom_scm_update_rollback_version(void)
    qcom-dload-mode.c中的 static ssize_t update_arb_store(struct kobject *kobj

    所以我有一个想法:fork 内核源代码,移除 update_arb 代码,然后使用自动化编译工具构建一个修改过的 AnyKernel3 内核,去除回滚保护。理论上,在解锁的设备上,更新到新版本后重启前立即刷入这个 AnyKernel3 内核应该是安全的。但是,如果系统在更新后重启,那么应该没用。

    内核源代码:https://github.com/OnePlusOSS/android_kernel_oneplus_sm8750

    由于重新编译内核对于大多数人可能比较困难,所以我想到了另一种方法。众所周知,Android 在启动时会加载一系列硬件驱动程序。我在vendor.img 中发现包含一个名为 android.hardware.boot-service.qti 的文件。

    使用 WinHex 打开该文件并搜索“arb”,我发现它会在启动时加载 /sys/kernel/dload/update_arb。因此,我们可以将其替换为一个不包含此代码的旧版本 android.hardware.boot-service.qti,然后重新打包 vendor.img,并在系统更新后、重启前刷入修改后的 vendor.img。
    也许使用winhex将android.hardware.boot-service.qti中的/sys/kernel/dload/update_arb的16进制代码填充成00也可行,不过我没测试。

    22.jpg

    已知版本 16.0.7.201 和 16.0.8.301 都包含 /sys/kernel/dload/update_arb,所以必须使用版本 16.0.5.703 或更早版本的 android.hardware.boot-service.qti 作为替换。

    如图,版本 16.0.5.703 不包含 /sys/kernel/dload/update_arb

    33.jpg

    接下来我会提供重新打包vender.img的教程,而不是直接提供vender.img,方便不同版本使用

    你可以使用ubuntu或者wsl,因为op13的系统镜像是erofs格式,所以我们需要先安装erofs-utils

    使用命令sudo apt-get install erofs-utils即可安装

    这里我使用wsl做演示。

    在宿主机上使用payload_dumper-master将刷机包中的payload.bin解包后会得到一堆分区,将16.0.5.703的vender.img和16.0.8.301的vender.img提取备用。

    30.jpg

    我的16.0.8.301的vender.img位于/Desktop/payload_dumper-master/output/vendor.img,16.0.5.703的vender.img位于Desktop/payload_dumper-master1/output/vendor.img

    在wsl中使用sudo mount /mnt/c/Users/dezhao/Desktop/payload_dumper-master1/output/vendor.img /home/dezhao/op13/vendor_org1命令

    sudo mount /mnt/c/Users/dezhao/Desktop/payload_dumper-master/output/vendor.img /home/dezhao/op13/vendor_org命令将其分别挂载。

    然后使用cd到/home/dezhao/op13文件夹,使用sudo cp -rf --preserve=all vendor_org vendor命令将16.0.8.301的vendor_org复制到vendor文件夹,然后使用sudo rm /home/dezhao/op13/vendor/bin/hw/android.hardware.boot-service.qti删除 vendor文件夹中的android.hardware.boot-service.qti,然后使用sudo cp /home/dezhao/op13/vendor_org1/bin/hw/android.hardware.boot-service.qti /home/dezhao/op13/vendor/bin/hw/android.hardware.boot-service.qti将旧版本的android.hardware.boot-service.qti复制到hw目录下。

    然后umount所有目录:sudo umount /home/dezhao/op13/vendor_org
    sudo umount /home/dezhao/op13/vendor_org1

    最后在/home/dezhao/op13目录下使用sudo mkfs.erofs -zlz4hc vendor.img vendor/打包即可

    45.jpg

    44.jpg

    注意在升级后重启设备之前将vendor.img、abl.img、xbl.img、xbl_config.img、xbl_ramdump.img通通刷入。
    16.0.8.301及后续版本想要保9008和arb必须对分区进行修改,注意!!由于我们重新打包修改了分区内容,所以必须解锁bl和去除vbmeta校验,如果设备没有解锁bl和去校验,那么刷入后将导致无法开机!!

    abl.img, xbl.img, xbl_config.img, and xbl_ramdump.img这几个分区可以从安全的旧版本中提取arb0的版本,比如我是从403版本中提取的。
    16.0.8.301可用,我不确定后续版本是否有效,测试前请备份好数据

    刷入分区:
    首先将所有分区复制到手机根目录,
    adb shell 连接到手机
    su
    使用getprop ro.boot.slot_suffix获取当前slot
    比如我运行后输出_b
    那么我的更新是安装到_a
    所以我的刷入命令是:
    blockdev --setrw /dev/block/bootdevice/by-name/abl_a
    blockdev --setrw /dev/block/bootdevice/by-name/xbl_a
    blockdev --setrw /dev/block/bootdevice/by-name/xbl_config_a
    blockdev --setrw /dev/block/bootdevice/by-name/xbl_ramdump_a
    blockdev --setrw /dev/block/bootdevice/by-name/vendor_a
    这5条命令是将上面各分区置于可写状态。

    dd if=/sdcard/abl.img of=/dev/block/bootdevice/by-name/abl_a
    dd if=/sdcard/xbl.img of=/dev/block/bootdevice/by-name/xbl_a
    dd if=/sdcard/xbl_config.img of=/dev/block/bootdevice/by-name/xbl_config_a
    dd if=/sdcard/xbl_ramdump.img of=/dev/block/bootdevice/by-name/xbl_ramdump_a
    dd if=/sdcard/vendor.img of=/dev/block/bootdevice/by-name/vendor_a
    这5条是刷入命令。

    如果getprop ro.boot.slot_suffix输出_a,那么就都刷入slot b,上面的各分区后缀改成_b即可。

    同步发表在xda:https://xdaforums.com/t/manual-upgrade-of-oneplus-13-to-16-0-8-301-while-preserving-edl-9008-access.4793082/

    如果需要16.0.8.301的vendor和其余几个文件打包可以留言,文件太大上传比较慢。

    46.jpg

    最后测试9008

    47.jpg

    我已经把系统更新冻结,防止在不知不觉间被更新。

    我总想起那天光影的聚合,好像一起一落之间,还看得到光阴的来去。

    10

      1. kelvin.ma
        kelvin.ma
        2026-07-07 22:41

        请问修改vendor后直接输入就行了嘛?这个和之前的那四个xbl abl文件一样,刷完能直接启动嘛?我看有人说需要关闭Vbmeta验证啥的?这玩意没有一点校验么,譬如最简单的hash?被人修改了还能直接启动?

      2. 昭君
        2026-07-07 23:25

        不能,16.0.8.301及后续版本想要保9008和arb必须对分区进行修改,修改后分区过不了校验,所以前提是解锁bl和去vbmeta校验。如果没解锁刷入修改后的分区那肯定无法开机,已对文章中包含这部分的内容进行加粗避免误操作。

      3. kelvin.ma
        kelvin.ma
        2026-07-07 23:37

        之前都是刷写arb保熔断和9008升级到了氧16.0.702,刷完可以直接启动,没出现过校验问题。16.0.8化因为动了vendor.img就会触发vbmeta嘛?想启动得关闭这个。我现在是一加12,保的9008 8gen3。现在卡在702天天提示我更新,自动更新adb命令还关不掉,烦的一批

      4. 昭君
        2026-07-07 23:44

        现在没有其他办法,内核中和vendor中都包含了update_arb的代码,要想保熔断和9008就只能动他们了,原本的abl_a、xbl_a、xbl_config_a、xbl_ramdump_a是官方提供的,我们自己改了分区就会触发vbmeta,提示更新可以把系统更新给停用或者冻结嘛。使用fastboot oem set-gpu-preemption 0 androidboot.selinux=permissive和fastboot continue设置selinux为宽容模式,然后安装kernelsu越狱看看,然后把不必要的应用冻结掉。

      5. kelvin.ma
        kelvin.ma
        2026-07-07 23:57

        谢谢,我试试临时root能不能把更新关掉,这个更新一开始用adb可以禁用,不小心重新打开后再adb就再也禁用不了了。我不太了解avb机制,abl和xbl因为是启动链第二步,只校验文件签名?所以替换成老版本的官方文件验证就通过了?但动了vendor话因为hash或者签名变动就必须关闭AVB验证?直接把新版的vendor整个替换成老版的,而不是修改其中的android.hardware.boot-service.qti有机会通过avb验证同时保9008么,还是因为和其他配套文件版本不匹配可能就直接卡机了

      6. 昭君
        2026-07-08 00:08

        不客气,理论上直接把新版的vendor整个替换成老版的话,如果版本比较接近,解锁后的机器大概率是能够启动的,因为我之前给我的一加9pro移植color16时,进行过分区杂交,就是其中的分区来自不同版本,我现在一加9pro用的是新版的coloros16,最好把boot、vendor_boot、vendor_dlkm(如有)一并给替换掉,我没有一加12,不清楚分区情况,你可以尝试把固件解包,然后把boot等分区拆开,使用winhex搜索arb,看看哪些里面有,然后把相应分区替换掉,但是一些新功能可能在这些分区,或者某些内容差距大可能引发bug,如果设备没解锁,大概率还是无法启动,因为abl、xbl、xbl_config、xbl_ramdump属于loader阶段,我在xda的一个帖子提取过abl分区,中发现有loader什么的,这个阶段只验证签名,后续vbmeta验证签名还有hash,不过只是理论,我并没有尝试过

      7. 昭君
        2026-07-08 02:04

        就是说xbl和 abl(android bootloader)等是系统启动链的发起者,abl就是bootloader所在分区,它们属于引导加载程序loader,不在 vbmeta 的校验列表内,所以替换能行,而其他分区就不行,因为其他分区除了校验签名还要检验hash,顺便使用imjtool可以将abl分区解包,可以得到linuxloader,我之前就干过:https://xdaforums.com/t/remove-oos13-orange-state-message-text.4520727/

      8. Kelvin ma
        Kelvin ma
        2026-07-08 06:13

        我有一个问题,16.0.7和 8.xxx内核代码都含有update arb,区别是8调用了?这个调用是发生在刷写阶段还是重启切换卡槽后的阶段,也不知道OTA增量它是刷一个卡槽还是都刷。我现在在CPH2581 16.0.7.200.arb==0.不会一刷8xx没重启arb就被改了吧?毕竟7.xxx代码里面就已经埋好钩子了。最保险还得降级再刷8xx?

      9. 昭君
        2026-07-08 18:27

        刷入后重启到新的slot才生效,我每次都是刷全量包后立即使用dd命令刷写分区,然后再重启,,重启后才会加载新的abl等

      10. kelvin.ma
        kelvin.ma
        2026-07-14 21:32

        好的,万分感谢,所以目前没有不关闭vbmeta更新且保留9008的办法,哎,要是能像之前一样刷完四个abl xbl再多刷一个vendor不用关闭认证话该有多好