ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Android设备树指南:以三星N5120为例的移植与编译实践

Android设备树指南:以三星N5120为例的移植与编译实践 简介这是一份面向Android系统移植与ROM定制开发者的设备适配源码包对应三星Galaxy Note 8国际版GT-N5120包含定制系统所需的设备配置与底层组件覆盖设备树、HAL硬件抽象层、内核启动初始化及项目构建规则等关键环节。压缩包共22个文件约50KB核心类型包括mk构建脚本、xml配置、rc启动脚本与prop系统属性另有少量C/H源码及readme说明虽然体量不大但完整呈现了从BoardConfig、init脚本到audio HAL的框架结构。目前已有108人学习下载对希望了解骁龙smdk4x12平台设备适配逻辑的开发者颇具参考价值。通过分析项目中的Android.mk、n5120.mk、init.smdk4x12.rc等文件可快速掌握设备树参数配置、驱动注册接口、RIL与音频HAL的组织方式理解目标设备从底层硬件到系统服务的裁剪与编译流程为自主移植或调试类似三星设备提供一份紧凑的目录级参考。 很多人第一次见到android_device_samsung_n5120这个仓库名时多半会以为它是三星官方的某个固件包。其实这是在 Android 开源社区里非常常见的一种设备树仓库。我早几年折腾三星 Galaxy Note 8.0N5120的时候就亲手整理过这样一个项目也靠着它把一台出厂 Android 4.1 的老平板带到了能正常编译 LineageOS 的状态。N5120 是 2013 年上市的 8.0 英寸平板型号全称 Galaxy Note 8.0 LTE使用三星自家的 Exynos 4412 处理器、2GB RAM还带 S Pen 手写笔。放到今天看硬件确实老旧但它的架构非常干净社区资料也比很多冷门手机多得多。这篇文章会从设备树的作用讲起逐步拆解移植过程中真正会踩到的问题最后落到如何把编译出的 ROM 刷进机器。不管你是想学 Android 系统构建还是手里恰好有一台 n5120 想续命都可以按着这条线索走一遍。1. 先看清 N5120 这台硬件的底细1.1 一台 2013 年的平板为什么还值得折腾先说需求判断。如果你只想把它当一台能刷微信、刷视频的平板那 N5120 确实不太够用了。但从 Android 系统移植的学习角度讲这台机器的价值一点没过期。它用的是 Exynos 4412四核 Cortex-A9同代芯片在开源社区里的移植资料极其丰富。2GB 内存放到现在算不上大但跑 Android 9/10 的轻量 ROM 依然可行。屏幕虽然是 1280x800 分辨率Super Clear LCD 的色彩通透度在同尺寸里算不错的。最难得的是 S Pen 和背后的 Wacom 手写层这批硬件在现在的新设备上很少见了。从移植成本看Samsung 老款设备的 bootloader 没有那么多加密限制进 download 模式刷 TWRP、拿 root 权限都比较顺畅实验成本低。相比那些绑定运营商锁、分区表混乱的机器N5120 几乎是为想动手的人准备的理想练习板。它的架构学习和功能验证意义远大于“让它跑最新系统”这个表面目标。1.2 硬件配置对设备树的每个约束设备树之所以叫“树”就是因为每个配置项都要对应到硬件实际能力。N5120 的关键部件大概可以整理成下面这张表部件型号/规格在设备树和内核中的体现SoC三星 Exynos 4412TARGET_BOARD_PLATFORM : exynos4412内核设备树对应exynos4412-n5120.dtsGPUARM Mali-400 MP4闭源二进制库libGLES_mali.sogralloc/hwcomposer 都依赖它内存2GB LPDDR2BoardConfig 中的内核 cmdline预留 CMA 内存给摄像头和显示屏幕8.0 英寸 1280x800 LCD内核 DRM/FB 驱动overlay 中配置分辨率、dpi、默认旋转方向WiFiBroadcom bcmdhd内核驱动bcmdhd固件放在/vendor/firmware或/system/etc/wifi3G/LTEModem / RILSamsung RIL 库libsecril-client等来自官方 system 镜像提取S PenWacom 电磁手写输入子系统节点通常通过 evdev 直接识别不需要额外 HAL这一张表基本上就是设备树的“索引”。打开社区里 exynos4412 相关的设备仓库你会看到大量变量都能和表里的行对应上比如BOARD_WLAN_DEVICE : bcmdhd、PRODUCT_PACKAGES libGLES_mali、TARGET_RIL_VARIANT : msm8226之类的写法。弄懂了硬件再看脚本就不会晕。2. 设备树在 Android 构建系统里到底扮演什么角色2.1 lunch 是怎么找到你的设备的很多新手第一次跑source build/envsetup.sh lunch都会被满屏的菜单吓到。实际上lunch做的事情就是去device/厂商/机型/下面找AndroidProducts.mk里面定义了一个或多个 product 名比如lineage_n5120再通过这个 product 名去匹配BoardConfig.mk、device.mk这些文件。设备树不是 Linux 内核里那个 device tree它更像是一份“穿衣搭配清单”。Android 编译系统从里面读三件事我要把哪些文件打进 ROMPRODUCT_COPY_FILES、PRODUCT_PACKAGES这块主板怎么启动、分区怎么挂载BOARD_*系列变量、fstab、init.rc系统属性、权限、开机动画等资源文件从哪个 overlay 目录覆盖PRODUCT_PACKAGE_OVERLAYS。所以一个设备树仓库的核心任务就是把这些信息全部以 build 系统能读懂的格式组织起来。android_device_samsung_n5120这个仓库名正表示它的服务对象是 Samsung 的 N5120 设备。2.2 一个最简设备树需要哪些文件如果从零开始一个最小可编译的设备树会包含下面这些文件AndroidProducts.mk BoardConfig.mk device.mk lineage.mk proprietary-files.txt extract-files.sh setup-makefiles.sh overlay/frameworks/base/core/res/res/values/config.xml rootdir/init.rc rootdir/fstab.smdk4x12 rootdir/ueventd.smdk4x12.rc recovery/root/init.recovery.smdk4x12.rc逐个解释一下AndroidProducts.mk负责向构建系统注册 product 名BoardConfig.mk是主控文件内核 cmdline、架构、ABI、分区大小都在里面device.mk是产品级配置负责继承公共 HAL 包、复制文件lineage.mk通常定义PRODUCT_NAME、PRODUCT_MODEL这类属性proprietary-files.txt列出所有需要从官方固件里提取的闭源文件extract-files.sh是提取脚本。对 N5120 这种老设备来说recovery/root和rootdir的 init 脚本特别重要。因为 kernel 3.4 时代还没有太多 init 分区解耦很多服务要通过 rc 文件手动拉起比如 RIL 守护进程、WiFi 固件加载、sensor 服务。少一行start wifi开机就会出现 Wi-Fi 打不开之类的问题。2.3 借鉴同平台机型而不是从零手写我见过不少新手一上来就想写“自己的设备树”结果写了三个星期还在 BoardConfig 里挣扎。实际上做系统移植最理智的路线是找同平台兄弟机型做底子然后针对性修改。N5120 的几个兄弟机型非常明确N5110 是 WiFi-only 版N5100 是 3G 版N5120 是 LTE 版。三者的 SoC、屏幕、摄像头基本一样差异主要在调制解调器和天线调谐部分。你完全可以把 N5110 或 N5100 的设备树复制过来然后做以下改动改名所有n5110、n5100字符串替换为n5120调整 modem 相关配置LTE 版需要加入对应 RIL 库和 APN 段检查 DTS 里的 model 字符串改成Samsung Galaxy Note 8.0 (LTE)在device.mk里调整PRODUCT_MODEL和PRODUCT_BRAND。这样做的好处是主板初始化、显示、输入、电源管理等大量工作已经有人验证过了你能把精力集中在真正有差异的 modem 和板上外设上。移植不是发明而是适配这个心态很重要。3. 移植 N5120 真正的几个难点3.1 闭源 blobs 的提取vendor 目录不能凭空捏造Android 闭源驱动是每个移植项目的“命门”。N5120 的 Mali GPU、相机、RIL、传感器等核心库都没有公开源码你只能在编译时把它们放进 ROM否则开机就会崩在 HAL 初始化阶段。我的做法是走标准路线先下载一台 N5120 的官方 4.4.x 固件解包拿到system.img.ext4然后用simg2img把稀疏镜像还原成完整镜像sudo apt install android-tools-fsutils simg2img system.img.ext4 system.img mkdir system_root sudo mount -o loop system.img system_root挂载之后对照设备树里的proprietary-files.txt逐项拷贝。注意extract-files.sh脚本不一定非要从 adb 设备上跑你也可以自己改成从挂载目录读取。拷贝完成之后还需要检查库文件的依赖关系file vendor/samsung/n5120/proprietary/lib/libsecril-client.so readelf -d vendor/samsung/n5120/proprietary/lib/libsecril-client.so | grep NEEDED如果出现链接缺失需要在proprietary-files.txt里补充对应的库或者设置LOCAL_SHARED_LIBRARIES。对于老设备我强烈建议给提取完的 vendor 目录做一次 git 提交这样后面改坏了能随时回滚也能直观看到哪些文件是从哪个版本固件里来的。3.2 内核准备defconfig、DTS 与 WiFi 固件N5120 使用基于 Linux 3.4 的内核移植到新系统时通常不需要大改但有几个点必须处理第一是 defconfig。社区里常见的lineageos_n5120_defconfig需要保证CONFIG_ANDROID、CONFIG_BINDER、CONFIG_ASHMEM、CONFIG_FHANDLE是全开的。Android 9 之后的 init 对CONFIG_FHANDLE有硬性要求少了它开机后 looper 直接跑不起来。第二是 DTS 设备树文件。N5120 的.dts里model、compatible、bootargs这些字段必须和 Bootloader 实际传给内核的保持一致。特别是consolettySAC2,115200这类参数如果留了串口输出又没接串口线看起来就像死机了一样实际系统在正常跑只是输出被卡住了。第三是 WiFi 固件路径。bcmdhd 驱动通常会有BCMDHD_FW_PATH和BCMDHD_NVRAM_PATH两个编译宏设备的 NVRAM 文件参数每台机器都不一样。如果你刷完后 WiFi 列表刷不出来优先查固件文件是不是被放到了内核驱动真正会去读的位置。3.3 HAL 适配RIL、音频摄像头的配置逻辑老设备适配新系统最花时间的往往不是 build而是 HAL。N5120 的音频可以用 exynos 平台传统的 tinyhal 方案只要在BoardConfig.mk里声明BOARD_USES_ALSA_AUDIO : true再配上对应的audio.primary.smdk4x12.so一般就能出声。真正麻烦的是 RIL。因为 LTE 版本的 modem 和 3G 版本不同RIL socket 的服务名、AT channel 路径都会变。你不能直接把 N5100 的 RIL 配置搬过来至少要确认rild服务连接的是/dev/socket/rild还是/dev/socket/rild3g。我平时会看官方固件的init.rc或libsecril的源码注释找到正确的 socket 名再写进我们自己的init.rc。摄像头部分N5120 的相机库是典型的老式 Samsung Camera HAL依赖 V4L2 和 Samsung 私有的libcamera。如果新系统想用 Camera HAL1需要在device.mk里用PRODUCT_PACKAGES把camera.smdk4x12.so一起压进/vendor/lib/hw。不要轻易上 HAL3这类老平台的camera provider支持不好只会白增加调试工作量。4. 编译到刷机包的完整过程4.1 环境准备与源码同步编译 Android 系统不是apt install android-build就能解决的还是得老老实实同步源码。我建议用 Ubuntu 20.04 或 22.04 的 LTS 环境内存至少 16GB磁盘预留 200GB 以上否则一次mka bacon很容易在链接阶段内存溢出。源码同步用 repo 命令mkdir -p ~/lineage cd ~/lineage repo init -u https://github.com/LineageOS/android.git -b lineage-17.1 repo sync -j8 -c同步完以后把你的设备树、内核、vendor 目录克隆到对应路径mkdir -p device/samsung/n5120 git clone 你的设备树仓库 device/samsung/n5120 git clone 你的内核仓库 kernel/samsung/n5120 git clone 你的vendor仓库 vendor/samsung/n5120注意vendor 仓库不需要完整的 Android 源码库结构只要按vendor/samsung/n5120这个目录层次放文件device.mk里的路径引用就能对上。4.2 注册设备并执行编译执行编译前建议先配置 ccache 加速重复构建export USE_CCACHE1 export CCACHE_EXEC$(which ccache) ccache -M 50G然后开始source build/envsetup.sh lunch lineage_n5120-userdebug mka bacon -j$(nproc)lunch成功后会输出一堆环境变量看到PLATFORM_VERSION和TARGET_PRODUCTlineage_n5120就说明设备树注册成功了。如果报错找不到 lunch 项八成是AndroidProducts.mk里 product 名或路径写错。整个编译过程以我的经验双路 E5 机器全速跑大约需要 40 到 80 分钟普通笔记本可能要 2 到 3 小时。产物在out/target/product/n5120/lineage-*.zip同时这里还会生成boot.img、recovery.img、dtbo.img老设备没有 dtbo。4.3 TWRP 刷入与分区知识N5120 没有独立的 vendor 分区系统镜像会直接写入 system 分区。刷机前通过 TWRP 执行四清data、cache、dalvik、system然后刷入lineage-*.zip。如果想保留恢复模式还可以单独刷recovery.img。这里必须强调分区表N5120 的 efs 分区保存着基带和 IMEI 等校准数据任何情况下都不要去 wipe 它。我见过有人手滑把 efs 抹了结果直接变砖只能靠 3G 版同型号备份才能救回来。刷机前用 TWRP 备份 EFS 是最简单也最值得养成的习惯。4.4 编译期常见错误速查我把这段时间遇到的高频错误整理成了一张表错误现象常见原因解决方法No rule to make target vendor/samsung/n5120/proprietary/...vendor 文件没提取完整对照proprietary-files.txt补全重新跑extract-files.sh老内核编译报错error: unknown type name bool新编译器太严格指定 GCC 4.9 工具链或在内核 Makefile 里临时加-stdgnu89编译中途因内存不足挂掉链接时内存不够加大 swap或降低-j并发数刷机后卡开机 logo内核 cmdline 或 init.rc 有问题先看dmesg再查 init 服务的拉起日志Signature verification failed签名不匹配userdebug 包要关闭签名校验或用对应的sign_target_files_apks签名WiFi 打不开固件放错路径对比 dmesg这张表里的问题我几乎每一条都踩过。尤其是内核编译在现代 clang 环境下的报错最直接的解决办法是别用主线 clang给老 kernel 单独配一套 GCC 工具链。5. 刷完之后的验证与老设备特有的坑5.1 开机以后应该先看哪些日志刷完进系统后先别急着点各种 App先抓日志确认底层硬件是否健康。adb root adb shell dmesg | grep -E fs_mgr|init|bcmdhd|secril|mali adb shell logcat -d -b all | grep -E E |F adb shell getprop | grep -E gsm|wifi|cameradmesg里的 fs_mgr 信息会告诉你 system/vendor 分区是否挂载成功bcmdhd能看出 WiFi 固件加载路径secril能看到 RIL 服务是否正常。如果日志里出现avc: denied多半是 SELinux 策略问题可以先临时切到 permissive 模式验证再针对性地补 sepolicy 文件。5.2 老平板的通病处理和优化这类老设备最常见的问题有三个一是电量显示不准。Exynos 4412 的 fuel gauge 驱动在 Android 9 以上偶尔会出现“一直显示 1%”的情况这是因为新系统对电池健康状态的读取逻辑变了。解决办法是在内核里找到对应电池驱动把电量上报的POWER_SUPPLY_PROP_CAPACITY回归到旧逻辑或者在 overlay 里关掉 “自适应电池” 功能。二是低内存场景下频繁杀后台。2GB 内存跑新系统确实紧张我自己的做法是调低 lowmemorykiller 阈值在init.rc里把ro.lmk.min_free_kbytes和ro.lmk.medium这些参数调宽松一点再配合 zram 设置 1GB 交换空间日常使用会顺滑不少。三是休眠唤醒偶发黑屏。老平台的 GPU 电源管理在深度休眠后偶尔会拒绝恢复输出常见解决办法是在init.rc里加一个echo on /sys/class/backlight/.../bl_power之类的重置脚本或者在显示 HAL 层屏蔽某些面板进入 D3 状态。5.3 把经验整理进项目方便日后维护每次移植调试完我都会回头把设备树仓库里的README.md和提交信息写清楚标注“这个配置来自哪个固件版本”“这个 fix 解决的是哪个 issue”。对老设备而言仓库的维护价值不亚于编译结果。我会在仓库里放一个docs/build.md记录同步分支、编译命令、常见报错和对应的 log 前缀。这样三个月之后再有人提起 N5120我不用重新回忆直接拉仓库看文档就能恢复整套环境。做 Android 移植最重要的不是一次成功而是把每次试错沉淀成可复现的步骤让自己和后来者都能少走弯路。以后真要给其他设备做移植这套方法换成device/厂商/型号再走一遍就行原理完全一样。本文还有配套的精品资源点击获取
返回列表