2. VIVO-Y927 lk1st 的移植 | 字数总计: 1.8k | 阅读时长: 8分钟 | 阅读量: |
背景
Y927 原厂 Android 4.4 的 tz/hyp 是 32 位,无法启动 ARM64 内核。lk2nd 也受限于此。必须同时替换 tz、hyp、aboot 三个分区。
最终启动链
1 PBL → SBL1 → DB410c tz → qhypstub (EL2) → lk1st (EL1, aarch32) → Linux (EL1, aarch64) ✅
核心组件
组件
作用
DB410c tz
DragonBoard 410c 的 TrustZone(与 qhypstub 兼容)
qhypstub
开源 hyp stub,替代原厂 hyp,支持 ARM64 EL2 启动
lk1st
从 lk2nd 仓库构建的主引导程序(aboot 替换),提供 Fastboot
备份关键分区
本章操作只替换 tz/hyp/aboot,这三个分区的原厂镜像在线刷包中都有,即使变砖也能 EDL 刷回。
但 modem 和 fsg 存着每台手机唯一的 IMEI,线刷包的 modem 镜像是通用的,覆盖前务必先备份。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 fastboot oem reboot-edl cp Y927\(PD1410V)升级软件_an/prog_emmc_firehose_8916.mbn ~/y927/alias edl='uvx --from git+https://github.com/bkerler/edl.git edl --loader=~/y927/prog_emmc_firehose_8916.mbn' edl r modem ~/y927/backup/modem.img edl r fsg ~/y927/backup/fsg.img edl r sbl1 ~/y927/backup/sbl1.img edl r tz ~/y927/backup/tz.img edl r hyp ~/y927/backup/hyp.img edl r aboot ~/y927/backup/aboot.img edl r rpm ~/y927/backup/rpm.img
获取 DB410c 固件
从 Linaro 下载 DragonBoard 410c 固件:
1 2 3 https://releases.linaro.org/96boards/dragonboard410c/linaro/rescue/17.09/ → dragonboard410c_bootloader_emmc_android-88.zip → 提取 tz.mbn
只需 tz.mbn,sbl1 保留原厂即可。
1 2 3 4 5 cd ~/y927mkdir wget https://releases.linaro.org/96boards/dragonboard410c/linaro/rescue/17.09/dragonboard410c_bootloader_emmc_android-88.zip unzip dragonboard410c_bootloader_emmc_android-88.zip tz.mbn rm dragonboard410c_bootloader_emmc_android-88.zip
编译 qhypstub
1 2 3 4 5 cd ~/y927git clone https://github.com/msm8916-mainline/qhypstub.git cd qhypstubgit clone https://github.com/msm8916-mainline/qtestsign.git make CROSS_COMPILE=aarch64-linux-gnu-
产物
qhypstub.bin: 二进制版本
qhypstub-test-signed.mbn: 测试签名版本(刷入 hyp 分区)
首次编译刷入 lk1st
编译 lk1st
1 2 3 4 cd ~/y927/lk2ndmake -j$(nproc ) TOOLCHAIN_PREFIX=arm-none-eabi- lk1st-msm8916 \ LK2ND_BUNDLE_DTB=msm8916-vivo-y927.dtb \ LK2ND_COMPATIBLE=vivo,y927
签名 lk1st
1 ~/y927/qhypstub/qtestsign/qtestsign.py aboot ~/y927/lk2nd/build-lk1st-msm8916/emmc_appsboot.mbn
刷入固件(EDL)
⚠️ 关键 :必须同时替换 tz!只换 hyp+aboot 不换 tz 会导致深度变砖。
1 2 3 4 5 6 7 8 9 10 11 12 fastboot oem reboot-edl alias edl="uvx --from git+https://github.com/bkerler/edl.git edl --loader=$HOME /y927/prog_emmc_firehose_8916.mbn" edl w tz $HOME /y927/tz.mbn edl w hyp $HOME /y927/qhypstub/qhypstub-test-signed.mbn edl w aboot $HOME /y927/lk2nd/build-lk1st-msm8916/emmc_appsboot-test-signed.mbn edl reset
lk1st 启动
此时lk1st启动,但是手机屏幕并不会亮,因为屏幕驱动暂时还未调通,但是可以使用以下命令看到进入 lk1st 并输出一些日志。
1 2 3 4 5 6 7 8 9 fastboot reboot fastboot fastboot oem log fastboot get_staged /tmp/lk1st.log cat /tmp/lk1st.log fastboot oem screenshot fastboot get_staged /tmp/lk1st-screenshot.pgm
通过oem截图,可以看到进入了lk1st,不过实机屏幕仍未点亮
修复lk1st的屏幕显示并二次编译刷入 lk1st
反编译和移植原厂 boot.img 的面板 DTB
linux-mdss-dsi-panel-driver-generator(简称 lmdpdg)是 msm8916-mainline 社区维护的一个 Python 工具,用于把高通下游 DTB 里的面板节点自动转换成以下文件:
panel-xyz.c: Linux 主线完整的 DRM panel 驱动,包含了所有必要的函数和结构体。
panel-simple-xyz.c: panel-simple.c 的片段,只包含了必要的函数和结构体,没有其他代码。
panel-xyz.dtsi: 面板的设备树节点示例,包含了面板的所有信息。
lk_panel_xyz.h: lk2nd/LK 的面板头文件(正是这里用到的)。
它的仓库在:https://github.com/msm8916-mainline/linux-mdss-dsi-panel-driver-generator
输入是编译好的 .dtb 文件(不是 .dts),用法:
./lmdpdg.py *.dtb
实际就是从原厂 boot.img 提取 DTB → 用 lmdpdg.py 解析 → 自动生成 lk2nd 格式的面板 .h 文件。lk_panel_hx8394d_720p_video.h 头部的注释说的就是这个工具跑出来的结果。
1 2 3 4 5 6 7 8 9 10 cd ~/y927git clone https://github.com/msm8916-mainline/linux-mdss-dsi-panel-driver-generator cd linux-mdss-dsi-panel-driver-generator/mkdir workdircp ~/y927/Y927\(PD1410V)升级软件_an/boot.img workdircd workdir && ../tools/unpackbootimg.py boot.img && cd -mkdir workdir/dtbcd workdir/dtb && ../../tools/unpackqcdt.py ../dtb.img && cd -
寻找定位目标的 dtb 文件,
1 2 cd workdir/dtbgrep -nr hx8394a
我这里输出
1 2 3 4 5 6 7 8 grep: plat_f8-var_1-sub_1.dtb: 匹配到二进制文件 grep: plat_f9-var_1-sub_1.dtb: 匹配到二进制文件 grep: plat_f9-var_1-sub_0.dtb: 匹配到二进制文件 grep: plat_ce-var_1-sub_0.dtb: 匹配到二进制文件 grep: plat_ce-var_1-sub_1.dtb: 匹配到二进制文件 grep: plat_fa-var_1-sub_1.dtb: 匹配到二进制文件 grep: plat_fa-var_1-sub_0.dtb: 匹配到二进制文件 grep: plat_f8-var_1-sub_0.dtb: 匹配到二进制文件
上一章 lk2nd 移植中,引用了一个常量 QCOM_ID_MSM8916 表示芯片型号,MSM8916 = 206 (0xCE),就是这里的plat_id
所以范围进一步缩小到了两个文件:
plat_ce-var_1-sub_0.dtb
plat_ce-var_1-sub_1.dtb
移除其他的无关文件:
1 2 3 4 5 mv plat_ce-var_1-sub_0.dtb plat_ce-var_1-sub_0.dtb.bakmv plat_ce-var_1-sub_1.dtb plat_ce-var_1-sub_1.dtb.bakrm *.dtbmv plat_ce-var_1-sub_0.dtb.bak plat_ce-var_1-sub_0.dtbmv plat_ce-var_1-sub_1.dtb.bak plat_ce-var_1-sub_1.dtb
开始反编译dtb并运行代码生成工具
1 2 3 4 5 cd ~/y927/linux-mdss-dsi-panel-driver-generator/workdir/dtbsudo apt install -y device-tree-compiler python3-libfdtmkdir plat_ce-var_1-sub_0 plat_ce-var_1-sub_1cd plat_ce-var_1-sub_0 && ~/y927/linux-mdss-dsi-panel-driver-generator/lmdpdg.py ../plat_ce-var_1-sub_0.dtb && cd -cd plat_ce-var_1-sub_1 && ~/y927/linux-mdss-dsi-panel-driver-generator/lmdpdg.py ../plat_ce-var_1-sub_1.dtb && cd -
存在两份反编译出来的面板驱动,分别是 plat_ce-var_1-sub_0/hx8394a_720p_video 和 plat_ce-var_1-sub_1/hx8394a_720p_video
,分别对应 plat_ce-var_1-sub_0.dtb 和 plat_ce-var_1-sub_1.dtb。
可以diff看下有啥区别
1 diff plat_ce-var_1-sub_0/hx8394a_720p_video/lk_panel_hx8394a_720p_video.h plat_ce-var_1-sub_1/hx8394a_720p_video/lk_panel_hx8394a_720p_video.h
结果是没区别,用哪份都可以。
修改lk2nd上游代码
1 2 3 4 cp ~/y927/linux-mdss-dsi-panel-driver-generator/workdir/dtb/plat_ce-var_1-sub_0/hx8394a_720p_video/lk_panel_hx8394a_720p_video.h ~/y927/lk2nd/lk2nd/display/panel/generated/cd ~/y927/lk2nd/git add lk2nd/display/panel/generated/lk_panel_hx8394a_720p_video.h git commit -m "Add lk_panel_hx8394a_720p_video.h"
编辑 lk2nd/lk2nd/display/panel/generated/panels.h 文件,在 include 处添加以下内容:
1 #include "lk_panel_hx8394a_720p_video.h"
1 2 git add lk2nd/display/panel/generated/panels.h git commit -m "Add lk_panel_hx8394a_720p_video.h to panels.h"
修改 dts 文件
~/y927/lk2nd/lk2nd/device/dts/msm8916/msm8916-vivo-y927.dts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <skeleton64.dtsi> #include <lk2nd.dtsi> / { qcom,msm-id = <QCOM_ID_MSM8916 0 > ; qcom,board-id = <0x01 0x01 > ; }; &lk2nd { model = "Vivo Y927 (PD1410V)" ; compatible = "vivo,y927" , "vivo,pd1304" ; lk2nd,match-panel ; lk2nd,dtb-files = "msm8916-vivo-y927" ; panel { compatible = "vivo,pd1304-panel" , "lk2nd,panel" ; qcom,mdss_dsi_hx8394a_720p_video { compatible = "vivo,hx8394a-720p" ; touchscreen-compatible = "goodix,gt9xx" ; }; }; regulator-lcd-enp { compatible = "regulator-fixed" ; gpios = <&tlmm 97 GPIO_ACTIVE_HIGH> ; }; regulator-lcd-enn { compatible = "regulator-fixed" ; gpios = <&tlmm 98 GPIO_ACTIVE_HIGH> ; }; regulator-backlight { compatible = "regulator-fixed" ; gpios = <&tlmm 8 GPIO_ACTIVE_HIGH> ; }; };
补充了三个控制屏幕的引脚,分别是 regulator-lcd-enp、regulator-lcd-enn、regulator-backlight,分别对应了屏幕的引脚号。
编译和签名lk1st
1 2 3 4 5 6 cd ~/y927/lk2nd/make -j$(nproc ) TOOLCHAIN_PREFIX=arm-none-eabi- lk1st-msm8916 \ LK2ND_BUNDLE_DTB=msm8916-vivo-y927.dtb \ LK2ND_COMPATIBLE=vivo,y927 \ LK2ND_DISPLAY=hx8394a_720p_video ~/y927/qhypstub/qtestsign/qtestsign.py aboot ~/y927/lk2nd/build-lk1st-msm8916/emmc_appsboot.mbn
刷入固件(EDL)
⚠️ 关键 :必须同时完成之前的替换 tz!只换 hyp+aboot 不换 tz 会导致深度变砖。
1 2 3 4 5 fastboot oem reboot-edl alias edl="uvx --from git+https://github.com/bkerler/edl.git edl --loader=$HOME /y927/prog_emmc_firehose_8916.mbn" edl w aboot $HOME /y927/lk2nd/build-lk1st-msm8916/emmc_appsboot-test-signed.mbn edl reset
移植成功
lk1st 启动成功!
向上游贡献
相关改动已提交给上游lk2nd仓库,PR链接:https://github.com/msm8916-mainline/lk2nd/pull/708
之后的编译构建命令如下:
1 2 3 4 make TOOLCHAIN_PREFIX=arm-none-eabi- lk1st-msm8916 \ LK2ND_BUNDLE_DTB=msm8916-vivo.dtb \ LK2ND_COMPATIBLE=vivo,y927 \ LK2ND_DISPLAY=hx8394a_720p_video