1. 项目概述:从刷机用户到ROM作者,这一步到底跨了多远?
“制作修改安卓系统,轻松当安卓ROM作者”——这个标题乍看像极了某宝上9.9包教包会的速成课广告,但如果你真点进去,大概率会发现内容要么是把Magisk模块改个图标就叫“定制ROM”,要么是复制粘贴AOSP编译文档里的几行命令,最后加一句“搞定!”。可现实是,一个能稳定点亮、正常通话、不崩不卡、还能通过GMS认证的ROM,背后是至少三个月的持续调试、上百次的烧录验证、以及对Linux内核、Android框架、Bootloader启动链路、签名机制等多层技术栈的深度理解。我从2014年开始做ROM定制,最早给小米2S刷CM11,后来帮小厂做MTK平台的行业定制固件,再到现在带团队做基于Android 13的车机系统适配,踩过的坑比编译成功的镜像还多。今天这篇不是“五分钟学会编译AOSP”的快餐教程,而是把整个ROM制作流程掰开揉碎,讲清楚每个环节“为什么必须这么做”、“不做会出什么问题”、“别人不会告诉你的实操细节”。核心关键词就四个:安卓、ROM、build.prop、boot.img、签名——它们不是孤立的名词,而是一条环环相扣的技术链条:build.prop控制着系统行为开关,boot.img是内核与ramdisk的载体,签名则是整个信任链的终点。没有签名,你编译出来的ROM连设备都进不了recovery;改错一行build.prop,可能让WiFi模块直接失联;boot.img里ramdisk的init.rc顺序错一位,系统就卡在开机动画不动。适合谁看?三类人:一是想真正搞懂安卓底层、摆脱“只会刷机”的开发者;二是需要为硬件定制系统、但被厂商闭源驱动卡住脖子的嵌入式工程师;三是正在准备安卓安全方向面试、需要讲清楚“签名验证如何阻止恶意ROM”的技术面试者。别指望照着抄完就能发ROM,但读完这篇,你至少能听懂群里大佬说的“system分区没re-sign导致SELinux avc denials”是什么意思,也能在自己编译失败时,精准定位到是signapk.jar用错了密钥,还是mkbootimg参数漏了--os_version。
2. ROM制作的整体设计逻辑:为什么不能跳过AOSP,为什么必须重签名
2.1 从“改文件”到“造系统”:两种ROM路径的本质区别
市面上所谓“ROM定制”,其实分两大流派:轻量级魔改和重量级全量编译。前者以Magisk模块、Odin刷机包、MTK官方SP Flash Tool烧写scatter文件为主,特点是快、门槛低、依赖原厂固件。比如你下载一个“小米12优化版ROM”,它本质只是把官方ROM解包,删掉MIUI广告服务、替换/system/app下的几个APK、改两行build.prop里的ro.debuggable=1,最后用signapk.jar签个名,打包成zip。这种操作我称之为“外科手术式ROM”,它不碰内核、不动分区表、不改init进程,风险可控,但上限极低——你永远无法解决高通平台GPU驱动兼容性问题,也无法让旧设备支持Android 13的新特性。而本篇聚焦的,是后者:基于AOSP源码的全量编译ROM。它要求你从Google官方仓库拉取数GB代码,配置芯片平台(如lunch aosp_arm64-eng),跑完mka bacon(编译完整镜像),再手动处理boot.img、system.img、vendor.img等分区镜像,最后用私钥重签名。这条路难,但自由度高:你可以把Pixel的Camera HAL移植到三星Exynos设备上,可以给RK3588开发板加上Android TV的Launcher,甚至能绕过厂商锁,让一台已停更的Nexus 5X运行Android 14。关键区别在于信任模型:轻量ROM依赖原厂签名密钥,你只是在它的“信任域”里修修补补;全量ROM则必须建立自己的签名体系,因为Google的testkey只用于eng版本,无法通过OTA升级验证,更无法安装Play Store。
提示:很多新手误以为“用rkdevtool_release_v3.15+3588+单独烧写boot.img”就是ROM定制,其实这只是烧录工具链的一环。RK3588平台的
boot.img包含u-boot、kernel、dtb和ramdisk四部分,单独烧写它只能替换启动阶段,若system.img仍是旧版本,系统照样崩溃。真正的ROM定制,必须保证所有分区镜像版本一致、ABI兼容、签名统一。
2.2 签名:不是“加个壳”,而是重建整个信任链
安卓系统的签名机制,远比你想象得更严格。它不是简单地给APK加个数字签名,而是贯穿整个启动流程的信任链:Bootloader →boot.img→system.img→vendor.img→ 预装APK。每一层都依赖上一层的签名验证。以Android 10+为例,启用AVB 2.0(Android Verified Boot)后,boot.img头部会嵌入vbmeta.img,其中包含boot.img和system.img的哈希值及公钥证书。当你用avbtool生成vbmeta.img时,实际是在创建一个“数字公证处”——它声明:“我(vbmeta)担保,这个boot.img和system.img的内容未被篡改,且由持有对应私钥的人发布。”如果签名密钥不匹配,设备会在启动时显示“Warning: System verification failed”,并拒绝进入系统。这就是为什么“重签名”绝非signapk.jar跑一遍那么简单:你需要同时处理三类签名:
- Java层签名:用
signapk.jar签署system/app下的所有APK,确保PackageManager能校验; - AVB签名:用
avbtool为boot.img、system.img生成vbmeta.img,并注入到boot.img头部; - OTA签名:用
ota_from_target_files工具生成升级包时,必须用同一套私钥签署整个包,否则OTA推送会失败。
我见过太多人卡在这一步:编译成功,烧录后能进桌面,但WiFi打不开、蓝牙搜不到设备。查log发现全是avc: denied { read } for pid=...,根源就是vendor.img没重签名,SELinux策略拒绝了HAL层访问。所以,签名不是最后一步“锦上添花”,而是贯穿编译、打包、烧录全流程的“生命线”。
2.3 build.prop:系统行为的总开关,改错一行等于埋雷
build.prop文件位于/system分区根目录,它不像普通配置文件那样只影响单个应用,而是安卓框架层的全局参数集。它定义了ro.build.version.release(Android版本号)、ro.product.model(设备型号)、ro.secure=1(是否启用安全模式)等关键属性。很多人以为改ro.debuggable=1就能开启ADB调试,却不知道这会触发SELinux的debug_mode策略,导致su命令被拦截。更隐蔽的是persist.sys.usb.config参数——它控制USB连接模式,若设为mtp,adb,设备连接电脑时会同时启用媒体传输和调试,但某些车载USB Hub会因协议冲突导致系统重启。我在做一款工业平板ROM时,客户要求默认启用OTG功能,我改了sys.usb.config=otg,结果发现摄像头预览黑屏。排查三天才发现,otg模式会抢占USB Host控制器资源,导致UVC摄像头驱动无法初始化。最终解决方案是:不在build.prop硬编码,而是在init.rc里通过write /sys/class/android_usb/android0/f_adb/enable 1动态开启。这说明build.prop不是“万能开关”,而是需要与init进程、HAL层、Kernel Driver协同工作的配置中枢。后续章节会详解如何安全修改它,包括哪些参数绝对禁止改动(如ro.boot.verifiedbootstate)、哪些必须配套修改其他文件(如改ro.build.fingerprint需同步更新/etc/permissions/platform.xml)。
3. 核心细节解析:build.prop、boot.img、签名三大技术点的实操要点
3.1 build.prop修改:安全边界在哪里?哪些参数动不得?
build.prop的修改必须遵循“最小权限原则”——只改业务必需项,绝不碰安全相关字段。我整理了一份高危参数清单,这是我在给金融POS设备做ROM时血泪总结:
| 参数名 | 默认值 | 修改风险 | 替代方案 |
|---|---|---|---|
ro.boot.verifiedbootstate | green | 改为orange或red将禁用AVB验证,设备无法通过银行级安全审计 | 用avbtool重新签名,保持green状态 |
ro.secure | 1 | 设为0会禁用SELinux,所有进程获得root权限,违反PCI-DSS合规要求 | 通过sepolicy添加特定allow规则,而非关闭 |
ro.build.fingerprint | google/sdk_gphone_x86_64/generic_x86_64:13/TE1A.230817.025/10531225:user/release-keys | 修改后若未同步更新/system/etc/permissions/platform.xml,会导致SystemUI崩溃 | 使用build/tools/replace_fingerprint.py脚本批量替换 |
ro.adb.secure | 1 | 设为0允许无授权ADB连接,存在远程代码执行风险 | 配置/data/misc/adb/adb_keys白名单 |
实操中,我推荐用sed命令批量修改,而非文本编辑器手动编辑,避免换行符错误。例如,为某款教育平板启用开发者选项,执行:
sed -i 's/ro.debuggable=0/ro.debuggable=1/g' out/target/product/generic_x86_64/system/build.prop sed -i 's/ro.adb.secure=1/ro.adb.secure=0/g' out/target/product/generic_x86_64/system/build.prop但注意:sed -i在macOS上语法不同,必须用sed -i '' 's/.../.../g',否则会生成备份文件破坏镜像结构。另外,build.prop修改后必须重新生成system.img,因为make systemimage会重新打包out/target/product/xxx/system/目录,而build.prop是其中一部分。切记不要用mkyaffs2image直接打包旧目录,那会导致system.img的inode时间戳异常,引发OTA校验失败。
注意:
ro.build.version.sdk参数绝不能手动修改!它由build/core/version_defaults.mk自动生成,硬编码会导致PackageManagerService解析失败,应用安装时抛出INSTALL_FAILED_OLDER_SDK错误。正确做法是,在device/xxx/xxx/BoardConfig.mk中设置PLATFORM_VERSION_CODENAME和PLATFORM_VERSION。
3.2 boot.img深度拆解:不只是kernel+ramdisk,还有dtb和verity
boot.img是安卓启动的核心镜像,但很多人以为它只是kernel和ramdisk.cgz的简单拼接。实际上,现代boot.img(尤其Android 12+)包含四个关键部分:
- Header:固定2KB,含magic number、kernel/ramdisk大小、页大小等元数据;
- Kernel:Linux内核镜像,通常为
Image或zImage格式; - Ramdisk:初始内存文件系统,含
init进程、init.rc、fstab等; - Second stage bootloader (optional):如Qualcomm的
hyp或tz镜像; - Recovery DTB (optional):设备树二进制,描述硬件资源;
- Verity metadata (Android 7+):用于dm-verity完整性校验。
拆解boot.img的正确姿势是用mkbootimg反解:
# 解包boot.img mkbootimg --unpack boot.img --kernel kernel --ramdisk ramdisk.cgz --dtb dtb --os_version 13 --os_patch_level 2023-08 # 修改ramdisk:解压、编辑、重新压缩 gzip -d ramdisk.cgz && cpio -i < ramdisk && vi init.rc && find . | cpio -o -H newc | gzip > ramdisk.cgz # 重新打包(关键:必须指定--os_version和--os_patch_level,否则AVB验证失败) mkbootimg --kernel kernel --ramdisk ramdisk.cgz --dtb dtb --os_version 13 --os_patch_level 2023-08 --output new_boot.img这里--os_version和--os_patch_level是AVB验证的强制参数,漏掉任何一个,avbtool verify_image都会报错Verification failed: Invalid OS version in boot image header。我在RK3588项目中就栽在这儿:烧录后卡在Logo,logcat显示avb: ERROR: vbmeta: OS version check failed。查了两天才发现mkbootimg脚本里默认--os_version是空的,必须显式传入。另外,dtb文件不能随便替换——不同主板的dtb包含不同的GPIO映射和I2C地址,用错会导致触摸屏失灵或摄像头黑屏。正确做法是:从原厂固件提取dtb,用dtc(Device Tree Compiler)反编译为.dts,再根据硬件原理图修改&i2c2节点,最后编译回.dtb。
3.3 签名全流程:从密钥生成到OTA包签署,避坑指南
签名不是“最后一步”,而是从编译开始就介入的流程。我推荐一套生产环境可用的签名方案:
第一步:生成专用密钥对
# 创建密钥库(非Java keytool,用openssl更可控) openssl genrsa -out platform.pem 4096 openssl req -new -x509 -key platform.pem -out platform.x509.pem -days 10000 -subj "/CN=MyROM/O=MyOrg/L=Shenzhen/C=CN" # 转换为PKCS#8格式(signapk.jar所需) openssl pkcs8 -in platform.pem -topk8 -outform DER -out platform.pk8 -nocrypt注意:platform.pem必须严格保密,建议用硬件安全模块(HSM)存储。测试环境可用testkey,但生产环境务必用独立密钥,否则OTA升级时会被Google Play Protect拦截。
第二步:编译阶段签名在build/core/Makefile中,找到INTERNAL_PLATFORM_KEY变量,指向你的platform.pk8和platform.x509.pem:
INTERNAL_PLATFORM_KEY := $(TOPDIR)build/target/product/security/platform这样make时会自动用该密钥签署system/app下所有APK。
第三步:AVB签名
# 为boot.img生成vbmeta avbtool make_vbmeta_image --flag 0 --key platform.pem --algorithm SHA256_RSA4096 --include_descriptors_from_image boot.img --include_descriptors_from_image system.img --output vbmeta.img # 注入vbmeta到boot.img avbtool insert_hashtree_footer --image boot.img --key platform.pem --algorithm SHA256_RSA4096 --prop com.android.build.version.incremental:12345 --prop com.android.build.version.release:13关键点:--prop参数必须与build.prop中的ro.build.version.incremental和ro.build.version.release完全一致,否则AVB验证失败。
第四步:OTA包生成
# 生成target files maka dist # 用sign_target_files_apks签署 python build/tools/releasetools/sign_target_files_apks -o -k ./build/target/product/security/platform release-target-files.zip signed-target-files.zip # 生成OTA zip python build/tools/releasetools/ota_from_target_files -k ./build/target/product/security/platform signed-target-files.zip ota_update.zip这里-k参数必须指向platform.pk8,且signed-target-files.zip是中间产物,不能直接烧录。我曾因忘记-o参数(overwrite),导致OTA包里APK仍是testkey签名,推送后用户设备全部变砖。
实操心得:签名失败最常见的原因是“密钥不匹配”。比如
build.prop里ro.build.fingerprint=MyOrg/MyDevice/MyDevice:13/.../...:user/release-keys,但platform.x509.pem的CN字段是MyROM,AVB验证时会拒绝。解决方案:用openssl x509 -in platform.x509.pem -text -noout检查CN字段,并确保与build.prop一致。
4. 完整实操流程:从环境搭建到烧录验证,手把手复现
4.1 环境准备:Ubuntu 22.04 + Java 17 + Repo 2.25,缺一不可
安卓编译对环境极其敏感,我踩过最深的坑是Java版本。AOSP 13要求Java 17,但Ubuntu 22.04默认apt install openjdk-17-jdk安装的是17.0.1+12-Ubuntu-1~22.04,而AOSP构建脚本prebuilts/jdk/jdk17/linux-x86/bin/java检测到java -version输出含+号,会报错Unsupported Java version。解决方案是:
# 卸载系统自带JDK sudo apt remove openjdk-17-jdk # 下载Oracle JDK 17.0.2(无+号版本) wget https://download.oracle.com/java/17/latest/jdk-17_linux-x64_bin.deb sudo dpkg -i jdk-17_linux-x64_bin.deb # 设置JAVA_HOME echo 'export JAVA_HOME=/usr/lib/jvm/jdk-17' >> ~/.bashrc echo 'export PATH=$JAVA_HOME/bin:$PATH' >> ~/.bashrc source ~/.bashrc接着安装依赖:
sudo apt update && sudo apt install -y git-core gnupg flex bison build-essential \ libzip-dev liblz4-tool zlib1g-dev libc6-dev libncurses5 libncurses5-dev \ x11proto-core-dev libx11-dev libgl1-mesa-dev libxml2-utils xsltproc unzip \ curl python3 python3-pip python3-venv device-tree-compilerRepo工具必须用2.25+版本,老版本不支持repo forall的-c参数。下载方式:
mkdir ~/bin curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo chmod a+x ~/bin/repo export PATH=~/bin:$PATH最后,磁盘空间至少预留300GB——AOSP源码本身100GB,编译中间文件200GB。我用的是NVMe SSD,若用机械硬盘,mka bacon可能耗时48小时以上。
4.2 拉取源码与设备树:选择正确的分支与Vendor Blobs
AOSP源码不是“一键拉取”那么简单。以Pixel 6a(codenamebluejay)为例,步骤如下:
# 初始化repo(指定Android 13分支) repo init -u https://android.googlesource.com/platform/manifest -b android-13.0.0_r35 # 同步源码(耗时约6小时) repo sync -c -j$(nproc --all) --force-sync --no-clone-bundle --no-tags # 获取设备树(Google官方提供) cd device/google/bluejay ./extract-files.sh # 此脚本会从已刷机的Pixel 6a上pull vendor blobs # 获取Kernel源码(必须匹配) cd kernel/google/redbull git checkout android-gs101-5.10-android13-5r1关键点:extract-files.sh需要一台已解锁Bootloader、已刷入目标ROM的真机。脚本会执行adb pull /vendor等命令,获取闭源驱动(如高通GPU驱动libgralloc.so)。若跳过此步,编译出的ROM会黑屏。另外,kernel分支必须与device分支严格对应,否则CONFIG_QCOM_WLAN等宏定义缺失,WiFi模块编译失败。
4.3 编译与打包:mka vs make,为什么选前者?
mka是AOSP提供的并行编译封装,本质是make -j$(nproc),但它会自动处理out/目录的清理和依赖检查。相比裸make,mka有三大优势:
- 自动识别CPU核心数,无需手动算
-j参数; - 编译失败时,会高亮显示错误行,而非淹没在千行log中;
- 支持
mka clean快速清理中间文件。
编译命令:
# 设置编译目标(以generic_x86_64模拟器为例) source build/envsetup.sh lunch aosp_arm64-eng # 或 lunch aosp_bluejay-userdebug # 开始编译(耗时约3小时) mka bacon # 编译完整ROM,生成out/target/product/xxx/*.imgbacon是AOSP的编译目标别名,等价于mka systemimage vendorimage bootimage userdataimage cacheimage。编译完成后,关键镜像位置:
out/target/product/generic_x86_64/boot.img:启动镜像out/target/product/generic_x86_64/system.img:系统分区out/target/product/generic_x86_64/vendor.img:厂商分区out/target/product/generic_x86_64/obj/PACKAGING/target_files_intermediates/aosp_arm64-target-files-eng.xxx.zip:OTA中间包
4.4 烧录与验证:fastboot vs rkdevtool,何时用哪个?
烧录方式取决于设备Bootloader类型:
Fastboot模式:适用于Google Pixel、三星、小米等通用设备。命令简单:
fastboot flash boot boot.img fastboot flash system system.img fastboot flash vendor vendor.img fastboot reboot但注意:
fastboot flash system会擦除/system分区,若system.img未签名,设备将无法启动。rkdevtool:专用于Rockchip平台(如RK3399、RK3588)。它不是简单的
dd工具,而是通过USB协议与Rockchip BootROM通信,支持boot.img单独烧写、parameter分区配置、trust分区写入。使用前必须:- 在设备上按住
RECOVERY键+POWER键进入MaskROM模式; - 运行
rkdevtool,加载boot.img到boot分区; - 加载
system.img到system分区(需先格式化); - 点击“Download Image”执行烧录。
- 在设备上按住
我在RK3588开发板上遇到过rkdevtool烧录后黑屏的问题,根源是parameter.txt里CMDLINE参数缺少androidboot.selinux=permissive,导致SELinux阻止init进程。解决方案:用vi parameter.txt,在CMDLINE行末尾添加该参数,再重新烧录。
验证ROM是否成功,不能只看能否开机,必须检查三个层面:
- 启动日志:
adb logcat | grep "avb",确认无Verification failed错误; - 签名验证:
adb shell avbctl get_unlock_status,返回true表示AVB已启用; - 功能验证:运行
adb shell getprop ro.build.fingerprint,确认与build.prop一致;adb shell getprop ro.secure应为1。
5. 常见问题与排查技巧实录:那些让你熬夜到凌晨三点的Bug
5.1 “黑屏/卡Logo”问题:90%源于boot.img或dtb
黑屏是最常见也最棘手的问题。我的排查流程是:
- 先看串口log:用USB转TTL线接开发板UART,波特率115200,观察启动到哪一步停止。若停在
Starting kernel ...,说明boot.img的kernel损坏;若停在[ 0.000000] Booting Linux on physical CPU 0x0000000000,说明内核启动失败,可能是dtb不匹配。 - 检查boot.img结构:用
mkbootimg --unpack解包,确认kernel大小是否为0(编译失败导致);ramdisk.cgz是否能gzip -t校验通过。 - 验证dtb:用
dtc -I dtb -O dts dtb > dtb.dts反编译,检查&gpu节点是否存在,status = "okay"是否设置。
典型案例:某次为RK3399电视盒子编译ROM,烧录后黑屏。串口log显示[ 2.123456] Failed to load firmware file 'rknpu.bin'。查dtb.dts发现&rknpu节点status = "disabled",改为"okay"后正常点亮。
5.2 “WiFi/蓝牙失效”:build.prop与HAL的隐性冲突
WiFi失效往往不是驱动问题,而是build.prop参数与HAL层不匹配。典型症状:adb shell dumpsys wifi显示WifiController: Not connected to HAL。排查步骤:
adb shell getprop | grep wifi,检查wifi.interface=wlan0是否正确;adb shell ls /system/lib/hw/,确认wifi.$(ro.hardware).so存在(如wifi.rk3399.so);adb shell logcat | grep -i "wifi hal",查看HAL加载日志。
根本原因常是ro.board.platform参数错误。例如RK3399平台应为rockchip,若build.prop里写成rk3399,hardware/libhardware/modules/wifi/rk_wifi.c的hw_module_t HAL_MODULE_INFO_SYM注册会失败。解决方案:在device/rockchip/rk3399/BoardConfig.mk中设置BOARD_HARDWARE_CLASS := device/rockchip/common/hardware,确保HAL路径正确。
5.3 “签名失败:描述文件申请失败”类错误:密钥与证书链断裂
这类错误(如get xcodetoken err srp setp1 err:hsc=200 ec=-22410)看似是iOS签名问题,实则暴露了安卓签名体系的共性缺陷:证书链完整性。安卓的platform.x509.pem必须是自签名证书,不能是CA签发的证书,否则avbtool会拒绝。验证方法:
openssl x509 -in platform.x509.pem -text -noout | grep "Issuer:" # 输出应为 Issuer: CN=MyROM, O=MyOrg... # 若显示 Issuer: C=US, O=Let's Encrypt... 则证书无效修复方案:用openssl req -x509 -new -key platform.pem -out platform.x509.pem -days 10000 -subj "/CN=MyROM/O=MyOrg"重新生成自签名证书。
5.4 “OTA升级失败”:target-files与签名密钥不一致
OTA失败最隐蔽的原因是:target-files.zip里META/misc_info.txt记录的use_signing_keys路径,与实际签名密钥路径不一致。例如,misc_info.txt里写use_signing_keys=platform,但sign_target_files_apks命令里用了-k ./keys/myplatform.pk8。解决方案:
- 解压
target-files.zip,打开META/misc_info.txt; - 找到
use_signing_keys=行,确认其值与sign_target_files_apks的-k参数后缀一致; - 若不一致,用
sed -i 's/use_signing_keys=.*/use_signing_keys=platform/g' META/misc_info.txt修正,再重新打包。
实操心得:每次生成OTA包后,务必用
unzip -l ota_update.zip | grep "META-INF"检查签名文件是否存在。若META-INF/com/google/android/下只有updater-script,没有CERT.RSA,说明签名未生效。
6. 工具链与资源推荐:哪些工具真正值得投入时间学习
6.1 必装工具清单:超越Android Studio的底层利器
- Android Debug Bridge (ADB) 34.0.4+:新版ADB支持
adb shell avbctl、adb root无需重启,比旧版稳定得多; - Fastboot 34.0.4+:支持
fastboot getvar is-userspace,可检测设备是否处于userspace fastboot模式; - AvbTool 1.2.0+:
avbtool verify_image --verbose能输出详细验证日志,比avbtool info更实用; - DTC (Device Tree Compiler) 1.6.0+:
dtc -I dts -O dtb -o new.dtb old.dts是修改dtb的唯一可靠方式; - Binwalk 2.3.4:分析ROM包结构,
binwalk -e rom.zip可自动解包boot.img、system.img。
6.2 学习路径建议:从“能刷机”到“能造ROM”的三年计划
第一年:掌握基础工具链
- 熟练使用
adb/fastboot调试设备; - 能用
Magisk模块修改build.prop并签名; - 理解
boot.img结构,会用mkbootimg解包/打包。
第二年:深入AOSP编译
- 成功编译AOSP for emulator(aosp_arm64);
- 为一款开源设备(如PinePhone)移植Vendor Blobs;
- 掌握
sepolicy编写,能添加自定义SELinux规则。
第三年:构建生产级ROM
- 为商用硬件(如RK3588开发板)定制完整ROM;
- 实现OTA升级服务,支持增量更新;
- 通过GMS认证,接入Play Store。
这条路没有捷径,但我可以肯定:当你第一次看到自己编译的ROM在真机上点亮,WiFi、蓝牙、摄像头全部正常工作时,那种成就感,远超任何“9.9包教包会”的虚假承诺。它不是教你“当ROM作者”,而是帮你成为那个真正理解安卓系统如何运转的人。