有个愿望:让小米平板2用上64位 Android9.0。因为64位 Android9.0 的 houdini 兼容性非常好,我曾经试过把 houdini9 植入 Android_x86-9.0 r2,然后安装到小米平板2中,发现APP运行很稳定,其它小米平板2安卓系统常见的APP闪退问题基本上都没有。只是因为显卡原因,Android_x86-9.0 r2 在小米平板2上只能运行在 nomodeset 模式下,视频靠CPU解码,导致系统卡顿很厉害。
目标很美好,但对于安卓适配新兵来说,实现这个目标还是要循序渐进。
我手头有能成功编译的 lineage13.0 for latte(小米平板2的代号是 latte)源码,lineage13.0 属于安卓6,为了缩小跨度,降低难度,我决定先从 lineage14.1 的小米平板2适配入手,因为 lineage14.1 属于安卓7,相比安卓6的变化比9要小一些。
虽然适配工作还没有完成,但过程中也有不少收获,总结一下。
一、下载源码
lineage14.1 的主源码可以按 LineageOS Wiki 上的说明下载,latte 的 vendor、device、kernel 则来自 Github( LineageOS Resources for Xiaomi Mi Pad 2 ),但配置 local_mainifest.xml 时要注意:不要使用 cm-14.1 分支的 vendor、device、kernel,它的BUG太多,基于它进行适配工作量巨大,并且会出现很多看不懂的问题。建议用 cm-13.0 分支,因为它已经在 lineage13.0 for latte上适配成功,本身不存在问题,所需要做的是对 lineage14.1 调试。
二、获取日志
最初编译出来的 lineage14.1 Rom 安装到小米平板2上多半无法成功运行,需要查看日志来分析原因,但系统如果没有运行到合适的阶段是无法通过 ADB 获取日志的,怎么办?群友 ygjsz 提供了一个方法。
在 init.rc 中加入以下代码:
# Take logs even when adb is not working.
# Thanks: markakash
# Add these lines to your init.rc file:
service boot_lc_main /system/bin/logcat -f /cache/boot_lc_main.txt
class main
user root
group root system
oneshot
service boot_dmesg /system/bin/sh -c "dmesg > /cache/boot_dmesg.txt"
class main
user root
group root system
oneshot
on property:sys.boot_completed=1
start boot_lc_main
start boot_dmesg
这段代码在开机后会自动把日志记录到 cache 文件夹中。当系统启动失败后,长按电源键+音量增键,让平板进入 Recovery 模式,就能把日志拷贝出来分析。
三、处理 dlopen failed 错误
日志中常出现 dlopen failed 报错,形式为 cannot locate symbol "_ZNxxxx" referenced by "xxxxx.so",例如:
dlopen failed: cannot locate symbol "_ZN7android13GraphicBufferC1Ejjij" referenced by "/system/vendor/lib/hw/hwcomposer.gmin.so"
这里需要重点搞清 symbol "_ZN7androidxxxxxx" 是什么?简单说,它是系统在编译 so 时自动生成的某个函数的别名,这个函数在源码中本来有易理解的名称,但在编译时编译器给它生成了一个 symbol,这个 symbol 具有唯一性,生成规则与函数名称、参数个数和参数类型有关,系统运行时根据它就可以定位到具体的动态库中具体的函数。
解决这个报错的第一步是要定位这个函数,但由于不知道生成规则,所以无法直接解码 symbol 去定位函数源码,但我找到了一个方法。
报错中的 xxxxx.so 一般都位于 system/vendor/lib 中,因为用的是 lineage13.