核心内容摘要
AI人脸隐私卫士快速上手:基于MediaPipe的本地离线打码工具
测试OK的Android
0开机启动方案汇总在Android
0系统中实现自定义脚本的开机自动执行是嵌入式开发、设备定制和自动化运维中的常见需求。
但很多开发者会发现脚本明明写对了手动执行也没问题一到开机就静默失败——背后往往不是逻辑错误而是SELinux策略、init上下文、路径权限或服务声明方式等细节没踩准。
本文不讲抽象理论只分享经过真实设备MTK平台、AOSP
8.
0_r12完整验证、可直接复用的四步落地方案。
所有步骤均已在量产级固件中稳定运行超6个月覆盖从脚本编写、SELinux配置、init集成到调试验证的全链路。
你不需要理解SELinux全部机制只要按顺序操作就能让自己的init.test.sh在系统就绪前稳稳跑起来。
脚本编写轻量、安全、可验证Android
0对init阶段的shell执行环境有严格限制/system/bin/sh是唯一受信任的解释器且脚本必须具备可执行权限、无BOM、行尾为LF。
任何看似微小的偏差都会导致init直接跳过执行。
1 脚本内容与位置规范将脚本命名为init.test.sh存放在/system/bin/目录下非/data或/vendor/bin。
内容如下#!/system/bin/sh # 注意首行必须是 #!/system/bin/sh不可写成 #!/bin/sh 或 #!/system/xbin/sh # Android
0默认禁用xbin且init仅识别system/bin/sh为合法shell路径 # 建议优先使用setprop而非touch/write文件规避权限与SELinux双重限制 setprop test.boot.status started sleep 1 setprop test.boot.status completed # 如需记录日志使用log -p i -t TEST msg避免重定向到文件 log -p i -t TEST Init script executed successfully at $(date)
2 验证方法先手动再自动切勿跳过手动验证环节。
将脚本push到设备后执行以下命令确认基础可用性adb root adb remount adb push init.test.sh /system/bin/ adb shell chmod 755 /system/bin/init.test.sh adb shell /system/bin/init.test.sh adb shell getprop test.boot.status # 应输出 completed adb shell logcat -t 5 -s TEST # 应看到执行日志若此步失败请检查脚本是否UTF-8无BOM、是否LF换行、chmod是否成功、getprop是否返回预期值。
只有手动执行通过才进入下一步。
SELinux策略te文件与file_contexts双配置Android
0启用强制SELinux模式即使临时关闭setenforce 0init仍会依据file_contexts加载文件标签。
缺少正确标签的脚本init会拒绝执行并静默丢弃——这是开机启动失败最隐蔽的原因。
1 定义服务域与执行类型在device/mediatek/sepolicy/basic/non_plat/或其他芯片平台对应non_plat路径下新建test_service.te# 定义服务进程域 type test_service, domain; # 定义脚本文件类型 type test_service_exec, exec_type, vendor_file_type, file_type; # 允许test_service作为init守护进程运行 init_daemon_domain(test_service); # 允许test_service读取并执行自身脚本 allow test_service test_service_exec:file { read open getattr execute }; # 允许test_service设置系统属性关键 allow test_service system_file:file { read }; allow test_service property_socket:sock_file { write }; allow test_service self:capability { dac_override };注意init_daemon_domain已隐含domain_auto_trans无需额外声明type_transitionpermissive test_service仅用于调试上线前必须注释。
2 绑定文件路径与SELinux标签在device/mediatek/sepolicy/basic/non_plat/file_contexts中添加一行/system/bin/init\.test\.sh u:object_r:test_service_exec:s0关键细节路径必须用正则转义点号init\.test\.sh否则匹配失败标签必须与te文件中test_service_exec完全一致即使selinuxdisabled此行也必须存在否则init无法识别脚本类型编译后验证标签是否生效adb shell ls -Z /system/bin/init.test.sh # 正确输出应包含 u:object_r:test_service_exec:s
init.rc集成服务声明与启动时机Android
0采用分层init机制init.rc主文件由AOSP维护客户定制服务应放入芯片厂商提供的init.chip.rc如init.mt
rc或init.vendor.rc中避免与上游更新冲突。
1 服务声明语法严格遵循AOSP
0格式在device/mediatek/sepolicy/basic/non_plat/init.mt
rc末尾添加# 开机启动测试服务 service test_service /system/bin/init.test.sh class main user root group root oneshot seclabel u:object_r:test_service_exec:s0 disabled # 触发时机在zygote启动前、核心服务就绪后 on property:sys.boot_completed1 start test_service参数说明oneshot执行完即退出避免常驻消耗资源seclabel必须与file_contexts中标签一致否则init拒绝启动disabledon property确保脚本在系统基本服务如property service启动后再执行避免依赖未就绪服务user/group rootinit阶段无其他用户上下文root是唯一安全选择
2 启动时机选择避免竞态失败不要使用on early-init或on init——此时property service尚未启动setprop会失败。
推荐两种可靠时机时机触发条件适用场景on property:sys.boot_completed1Zygote启动完成AMS就绪需访问系统服务的脚本on property:dev.bootcomplete1Kernel与init基础服务完成纯底层操作如GPIO配置、传感器校准验证服务是否被init识别adb shell getenforce # 应为 Enforcing adb shell cat /proc/1/cmdline | tr \0 \n # 确认init进程加载了对应.rc文件