[Android9.0][GSI][Qualcomm_SDM845]刷完Google GSI包后无法开机

本文分析了高通SDM845设备在刷写Google GSI包后无法正常开机的问题,通过logcat日志定位到qseecomd服务启动失败,进一步排查发现是由于libtzcom库的缺失导致。文中详细记录了解决步骤,包括修改设备代码和在vendor分区中备份libtzcom.so。

【现象】

高通SDM845 Android 9.0项目,刷完Google GSI包(vbmeta.img和system.img)之后无法开机,定在第一帧logo处

【分析】

  • logcat log:每次logcat都block在如下log附近
[    4.710406] c6      1 init: starting service 'vendor.qseecomd'...[    4.710406] c6      1 init: starting service 'vendor.qseecomd'...
[    4.711698] c6      1 init: starting service 'exec 2 (/vendor/bin/init.qti.qseecomd.sh)'...
[    4.712547] c6      1 init: SVC_EXEC pid 622 (uid 1000 gid 1000+0 context default) started; waiting...
[    4.721147] c4      1 init: Service 'vendor.qseecomd' (pid 620) exited with status 1
[    4.721161] c4      1 init: Sending signal 9 to service 'vendor.qseecomd' (pid 620) process group...
  • 通过如上log可知应该是qseecomd服务无法启动,查看device/qcom/sdm845/init.qti.qseecomd.sh
while [ "$registered" != "true" ]
do
    sleep 0.1
    registered="`getprop vendor.sys.listeners.registered`"
done
  • 通过如上代码,vendor.sys.listeners.registerd属性需要被置为true才能退出这个死循环,而此属性会在vendor/qcom/proprietary/securemsm/daemon/qseecomd.c中main函数被设置为true。
  • 为了验证是不是vendor.sys.listeners.registerd属性没有被设置为true导致开不了机,直接通过adb将init.qti.qseecomd.sh删除,再去刷GSI包。(反向思维,先证明跟此有关)
  • 此时开机不在定在第一帧logo处,但是依然还是不能开机,定在Android logo处,而此时logcat依然可以看到qseecomd服务无法启动。
  • 为验证是不是qseecomd服务中某段代码导致的,直接将qseecomd.c中main函数全部注释,复测结果依然定在Android logo处,而此时logcat依然可以看到qseecomd服务无法启动。(反向思维,先证明跟此有关)
  • 通过上轮测试后,感觉qseecomd服务一启动就挂了。说明跟qseecomd内部实现code无关。
  • 分析相关Android.mk和Android.bp文件,看看qseecomd有没有依赖什么静态库之类的,且此库是在system.img中(system/lib64/)
  • 根据如果代码,最终发现会依赖libtzcom库
#vendor/qcom/proprietary/securemsm/daemon/Android.mk
LOCAL_SHARED_LIBRARIES += \
	libtbaseLoader

#vendor/qcom/proprietary/securemsm/tbase/loader/Android.mk
LOCAL_SHARED_LIBRARIES += \
        libcutils \
        libutils \
        libQSEEComAPI \
        liblog \
        libtzcom

#vendor/qcom/proprietary/prebuilt_grease/target/product/sdm845/Android.mk
include $(CLEAR_VARS)
LOCAL_MODULE        := libtzcom
LOCAL_MODULE_CLASS  := SHARED_LIBRARIES
LOCAL_MODULE_SUFFIX := .so
LOCAL_STRIP_MODULE  := false
LOCAL_MULTILIB      := 64
LOCAL_MODULE_OWNER  := qcom
LOCAL_MODULE_TAGS   := optional
LOCAL_SRC_FILES     := ../../.././target/product/sdm845/system/lib64/libtzcom.so
LOCAL_MODULE_PATH   := $(PRODUCT_OUT)/system/lib64
include $(BUILD_PREBUILT)

【解决】

将libtzcom.so备份到vendor分区中,在项目的device.mk中添加如下代码

PRODUCT_COPY_FILES += \
  out/target/product/$(TARGET_PRODUCT)/system/lib/libtzcom.so:vendor/lib/libtzcom.so \
  out/target/product/$(TARGET_PRODUCT)/system/lib64/libtzcom.so:vendor/lib64/libtzcom.so

 

<think>嗯,用户这次的问题是关于Android GSI中生成lp_metadata的方法。看来用户正在开发或定制Android系统,特别是处理Generic System Image相关的工作。这类问题通常涉及AOSP底层机制,需要查阅官方文档和源码实现。 从用户提问方式看,ta应该具备一定的Android系统开发经验,因为lp_metadata是逻辑分区相关的元数据,普通应用开发者很少接触这个层面。用户可能正在尝试修改或创建动态分区布局,需要生成对应的元数据文件。 回忆之前对话历史,虽然用户提供了关于知识图谱课程的引用,但显然与本问题无关。重点应该聚焦在Android系统分区机制上。用户真正需要的是具体的操作步骤和工具使用说明。 关于lp_metadata,核心要点有几个: 第一要明确它是通过lpmake工具生成的二进制数据 第二需要准备分区布局描述文件作为输入 第三涉及动态分区特有的super分区结构 比较关键的是分区描述文件的格式要求,必须含分区名、大小、属性等关键字段。实际操作中开发者最容易出错的就是这个描述文件的编写,比如忘记设置readonly属性或弄错区块大小。 考虑到用户可能遇到的困难点,应该在回答中特别强调: - 如何验证生成的lp_metadata是否有效 - 常见错误排查方法 - 与AVB密钥的集成方式 另外要注意术语的准确性,比如要区分"logical partitions"和"dynamic partitions"的关系,避免用户概念混淆。GSI场景下还需要说明super.img与lp_metadata的联系。 最后生成的示例命令要测试可用性,避免直接复制文档但实际环境报错的情况。比如将企业提供的Android11命令调整为通用的Android 10+格式更稳妥。 </think>在Android GSI (Generic System Image) 中生成 `lp_metadata`(逻辑分区元数据)需通过 **`lpmake` 工具**成,该工具位于 AOSP 源码的 `build/make/tools/releasetools` 目录下。以下是详细步骤: --- ### 生成步骤 1. **准备分区描述文件** 创建一个文本文件(如 `partitions.txt`),定义分区布局。格式示例(以 `system` 和 `vendor` 为例): ``` system read-only 1000 vendor read-only 800 ``` *说明*:每行格式为 `分区名 属性 分区大小(MB)`,属性常用 `read-only` 或 `readwrite`。 2. **使用 `lpmake` 生成元数据** 执行命令(需在 AOSP 编译环境中): ```bash lpmake \ --device-size=auto \ # 自动计算设备总大小 --metadata-size=65536 \ # 元数据分区大小(默认64KB) --metadata-slots=2 \ # A/B 槽位数量 --output=super.img \ # 输出的 super 分区镜像 --partition=partitions.txt # 分区描述文件 ``` 生成的 `super.img` 中即含 `lp_metadata`。 3. **提取 `lp_metadata`** 通过 `lpdump` 工具从 `super.img` 中提取元数据: ```bash lpdump super.img > lp_metadata.bin ``` --- ### 关键说明 - **依赖环境**:需整 AOSP 源码及编译环境(如 `lunch` 目标设为 `aosp_arm64-eng`)。 - **分区对齐**:默认按 4KB 对齐,可通过 `--alignment` 参数调整。 - **动态分区**:`lp_metadata` 是 Android 动态分区(Dynamic Partitions)的核心元数据,用于描述 `super` 分区内各逻辑分区(`system`, `vendor` 等)的布局[^1]。 - **GSI 适配**:在构建 GSI 时,`lp_metadata` 会随 `super.img` 一同生成,确保分区结构与目标设备兼容。 --- ### 相关问题 1. 如何验证生成的 `lp_metadata` 是否正确? 2. 动态分区与传统分区方案相比有哪些优势? 3. 在非 AOSP 环境中(如设备厂商 SDK)能否生成 `lp_metadata`? 4. `lpmake` 工具支持哪些高级参数优化分区布局? [^1]: 动态分区机制允许 OTA 更新时动态调整分区大小,无需固定分区表,提升系统灵活性。详见 [AOSP 官方文档](https://source.android.com/docs/core/ota/dynamic_partitions)。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值