MTK平台Android init.rc服务详解
1. MTK平台典型服务示例:perfservice
rc
# ======================================================================
# perfservice.rc - MTK性能服务
# 位置:vendor/etc/init/perfservice.rc
# MTK特有:此服务用于MTK平台的性能调优
# ======================================================================
# 服务定义段 - 定义如何运行守护进程
service perfservice /vendor/bin/perfservice
# class定义服务类别,main表示主系统服务
class main
# 用户/组:使用system用户运行,降低权限
user system
group system shell graphics input
# 进程能力:授予必要的Linux能力
# CAP_SYS_NICE: 允许设置进程优先级
# CAP_SYS_ADMIN: 允许系统管理操作
# CAP_NET_ADMIN: 允许网络管理
capabilities SYS_NICE SYS_ADMIN NET_ADMIN
# 安全上下文:SELinux标签(MTK Android 8.0+需要)
seclabel u:r:perfservice:s0
# I/O调度优先级:使用best-effort调度,优先级4
ioprio be 4
# OOM调整值:负值表示不容易被杀死
oom_score_adjust -100
# 关键服务标志:如果是关键服务,崩溃会导致重启
# critical
# 重启延迟:如果崩溃,等待5秒后重启
# restart_period 5
# oneshot表示服务退出后不重启,由init控制生命周期
oneshot
# 禁用自动启动,等待trigger触发
disabled
# 创建一个socket,用于进程间通信
socket perfservice stream 660 system system
# 写入pid到cpuset,控制CPU亲和性
writepid /dev/cpuset/system-background/tasks
# 环境变量
env MTK_PLATFORM $(ro.mediatek.platform)
env MTK_LOG_LEVEL 2
# ======================================================================
# Trigger段 - 定义何时启动/停止服务
# ======================================================================
# 在boot阶段启动,但等待zygote启动完成
on boot && property:ro.mtk_perfservice_support=1
# 设置一个属性标记
setprop vendor.perfservice.init 1
# 创建必要的目录
mkdir /data/vendor/perfservice 0775 system system
mkdir /data/vendor/perfservice/trace 0775 system system
# 挂载debugfs用于性能追踪
mount debugfs none /sys/kernel/debug
# 修改系统参数
write /proc/sys/kernel/sched_tunable_scaling 0
# 触发服务启动
start perfservice
# 当zygote启动时,进一步配置
on zygote-start && property:vendor.perfservice.init=1
# 设置CPU频率策略
write /sys/devices/system/cpu/cpufreq/policy0/scaling_governor performance
# 启动性能监控
exec -- /vendor/bin/perfservice --start-monitor
# 当充电器模式激活时,停止性能服务
on charger
stop perfservice
setprop vendor.perfservice.active 0
# 当系统准备关机时
on shutdown
# 保存性能数据
exec -- /vendor/bin/perfservice --dump-stats
# 停止服务
stop perfservice
# 通过属性控制服务
on property:ctl.start=perfservice
# 记录启动时间
write /data/vendor/perfservice/last_start $(date)
# 启动服务
start perfservice
on property:ctl.stop=perfservice
# 记录停止时间
write /data/vendor/perfservice/last_stop $(date)
# 停止服务
stop perfservice
# 自定义属性控制
on property:persist.vendor.perf.enable=1
# 启用性能模式
write /sys/module/mtkperf/parameters/enable 1
start perfservice
on property:persist.vendor.perf.enable=0
# 禁用性能模式
write /sys/module/mtkperf/parameters/enable 0
stop perfservice
# MTK特有:当特定场景触发时
on property:vendor.mtk.gamemode=1
# 游戏模式:提高性能
write /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq 1800000
start perfservice
on property:vendor.mtk.gamemode=0
# 退出游戏模式
write /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq 300000
2. MTK相机服务示例:cameraserver
rc
# ======================================================================
# cameraserver.rc - MTK相机服务
# 位置:vendor/etc/init/cameraserver.rc
# MTK特有:包含MTK相机硬件适配层
# ======================================================================
service cameraserver /system/bin/cameraserver
class main
user cameraserver
group cameraserver audio system graphics input
# MTK特有:相机需要更多能力
capabilities SYS_NICE SYS_ADMIN DAC_OVERRIDE SYS_RESOURCE
# MTK相机服务的特殊安全上下文
seclabel u:r:cameraserver:s0:c256,c512
# 创建必要的socket
socket cameraserver stream 660 system camera
socket cameraserver-debug stream 660 system camera
# 禁用oneshot,让服务持续运行
# oneshot
# 启用自动重启
onrestart restart media
onrestart restart audioserver
# MTK相机特有的环境变量
env MTK_CAMERA_VERSION 2
env MTK_LOG_LEVEL 3
# 设置进程优先级
priority -10
# 创建必要的目录
mkdir /data/vendor/mtk/camera 0775 camera camera
# 禁用自动启动,等待trigger
disabled
# Trigger段
on boot && property:ro.mtk_camera_support=1
# 初始化MTK相机参数
chmod 0666 /dev/mtk_camera*
# 设置相机内存池
write /proc/camerapool/set_size 268435456
# 启动相机服务
start cameraserver
# 当相机被请求时
on property:sys.camera.request=1
# 预热相机硬件
exec -- /vendor/bin/mtk_camera_preload
# 启动服务
start cameraserver
# 低内存时停止相机
on property:sys.lowmem=1
# 如果相机在运行,停止它以释放内存
stop cameraserver
setprop sys.camera.available 0
3. 实际操作与调试
3.1 编译和安装
makefile
# Android.bp 文件
prebuilt_etc {
name: "mtk_perfservice.rc",
src: "mtk_perfservice.rc",
sub_dir: "init",
vendor: true,
filename: "mtk_perfservice.rc",
}
# Android.mk 文件(旧版本)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mtk_perfservice.rc
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_ETC)/init
LOCAL_SRC_FILES := mtk_perfservice.rc
include $(BUILD_PREBUILT)
3.2 手动控制和调试
bash
# 1. 启动服务
adb shell start perfservice
# 或者
adb shell setprop ctl.start perfservice
# 2. 停止服务
adb shell stop perfservice
# 或者
adb shell setprop ctl.stop perfservice
# 3. 检查服务状态
adb shell ps -A | grep perfservice
adb shell getprop | grep perfservice
# 4. 查看服务日志
adb logcat -s perfservice
adb logcat -b events | grep perfservice
# 5. 检查属性变化
adb shell watchprops
adb shell dumpsys activity service perfservice
# 6. MTK特有调试命令
adb shell "cat /proc/perfmgr/perfservice/status"
adb shell "echo 1 > /proc/perfmgr/perfservice/debug"
# 7. 检查socket连接
adb shell netstat -anp | grep perfservice
adb shell ls -l /dev/socket/
# 8. SELinux相关调试
adb shell "ls -Z /vendor/bin/perfservice"
adb shell dmesg | grep avc # 查看SELinux拒绝日志
# 9. 性能分析
adb shell top -p $(pidof perfservice)
adb shell cat /proc/$(pidof perfservice)/status
3.3 预期输出和调试结果
# 服务启动成功
$ adb shell start perfservice
[ 45.123456] init: starting service 'perfservice'...
[ 45.123789] perfservice: Service started with PID 1234
# 查看进程状态
$ adb shell ps -A | grep perf
system 1234 1 123456 12345 perfservice
# 用户:system, PID:1234, PPID:1(init), VSIZE:123456, RSS:12345
# 查看属性
$ adb shell getprop | grep perf
[vendor.perfservice.init]: [1]
[persist.vendor.perf.enable]: [1]
# 查看日志
$ adb logcat -s perfservice
01-01 12:00:00.123 1234 1234 I perfservice: MTK PerfService started
01-01 12:00:00.124 1234 1234 I perfservice: Platform: mt6877
01-01 12:00:00.125 1234 1234 I perfservice: Initializing performance modules
# 检查socket
$ adb shell ls -l /dev/socket/
srw-rw---- system system 2024-01-01 12:00 perfservice
# 性能监控
$ adb shell top -p 1234
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1234 system 20 0 120M 12M 8M S 2.3 0.4 0:10.23 perfservice
4. 创新示例:MTK AI加速服务
rc
# ======================================================================
# mtk_ai_accelerator.rc - MTK AI加速服务
# 创新点:结合MTK APU的AI加速能力
# ======================================================================
service mtk_ai_accelerator /vendor/bin/mtk_ai_accelerator
class main
user system
group system graphics media drmrpc
# MTK APU需要的能力
capabilities SYS_NICE SYS_ADMIN IPC_LOCK
# 内存锁定:AI模型需要锁定内存
rlimit memlock unlimited unlimited
# 设置APU频率
write /proc/apusys/power_ctrl 1
# 创建APU通信socket
socket mtk_apu stream 660 system system
socket mtk_ai_results stream 666 system system
# 共享内存段
shmem ai_shared 0666 system system
disabled
oneshot
# AI场景触发器
on property:sys.ai.scene=photo_enhance
# 加载照片增强模型
exec -- /vendor/bin/load_ai_model /vendor/etc/ai/photo_enhance.bin
# 设置APU为高性能模式
write /proc/apusys/dvfs 1
# 启动AI服务
start mtk_ai_accelerator
on property:sys.ai.scene=voice_assistant
# 加载语音识别模型
exec -- /vendor/bin/load_ai_model /vendor/etc/ai/voice_recognition.bin
# 设置低延迟模式
write /proc/apusys/latency_mode 1
start mtk_ai_accelerator
# 温度控制:防止过热
on property:sys.thermal.temp>80
# 降低APU频率
write /proc/apusys/dvfs 0
write /proc/apusys/power_ctrl 0
# 暂停AI服务
stop mtk_ai_accelerator
# 电量管理
on property:sys.power.saver=1
# 节电模式:使用轻量级模型
exec -- /vendor/bin/load_ai_model /vendor/etc/ai/lightweight.bin
# 限制APU功耗
write /proc/apusys/power_limit 5000
5. 高级调试技巧
5.1 init调试
bash
# 查看init日志
adb logcat -b system
# 查看init进程状态
adb shell "cat /proc/1/status"
# 跟踪服务启动顺序
adb shell "cat /dev/.booting 2>/dev/null || echo 'Not in booting'"
# init的debug模式
adb shell setprop debug.init 1
adb shell stop && adb shell start
5.2 MTK特有调试
bash
# MTK性能调试
adb shell "cat /proc/perfmgr/**"
# MTK APU调试
adb shell "cat /proc/apusys/**"
# MTK GPU调试
adb shell "cat /proc/mali/**"
# MTK thermal调试
adb shell "cat /proc/thermal/**"
5.3 自动化测试脚本
bash
#!/system/bin/sh
# test_perfservice.sh - 自动化测试脚本
# 测试1: 正常启动
echo "Test 1: Normal start"
start perfservice
sleep 2
ps | grep perfservice || echo "FAIL: Service not running"
# 测试2: 属性控制
echo "Test 2: Property control"
setprop persist.vendor.perf.enable 1
sleep 1
getprop persist.vendor.perf.enable | grep 1 || echo "FAIL: Property not set"
# 测试3: 压力测试
echo "Test 3: Stress test"
for i in $(seq 1 10); do
start perfservice
sleep 0.5
stop perfservice
done
# 测试4: 资源检查
echo "Test 4: Resource check"
ls -l /dev/socket/perfservice || echo "FAIL: Socket not created"
cat /proc/$(pidof perfservice)/limits 2>/dev/null || echo "Service not running"
# 测试5: 权限检查
echo "Test 5: Permission check"
ls -Z /vendor/bin/perfservice
6. 创新思路
- 动态配置:根据设备状态(温度、电量、负载)动态调整服务参数
- 预测启动:基于使用模式预测何时需要启动服务
- 跨服务协作:多个服务协同工作,如相机+AI+性能服务
- 自适应QoS:根据应用需求动态调整服务质量
- 热修复:通过init脚本实现服务的在线更新和修复
- 能耗优化:基于使用场景智能管理服务能耗
7. 常见问题和解决方案
rc
# 问题1: 服务启动太早,依赖的资源未就绪
# 解决方案:添加依赖检查
on boot && property:sys.boot_completed=1 && property:vendor.mtk.ready=1
start my_service
# 问题2: 服务崩溃频繁
# 解决方案:添加崩溃保护
service my_service /vendor/bin/my_service
# 限制重启次数
onrestart restart other_service
restart_period 10
# 或者完全禁用重启
# oneshot
# 问题3: 权限不足
# 解决方案:添加必要的capabilities和seclabel
capabilities SYS_NICE NET_ADMIN
seclabel u:r:my_service:s0
# 问题4: 资源竞争
# 解决方案:添加资源锁
exec -- /vendor/bin/acquire_lock /var/lock/my_service.lock
start my_service
# 问题5: 启动顺序依赖
# 解决方案:使用class和trigger控制顺序
class late_start
on property:sys.my_dependency.ready=1
start my_service
通过以上完整的示例和详细的注释,你应该能够:
- 理解MTK平台上.rc文件的完整结构
- 掌握服务定义、trigger、属性的使用方法
- 学会如何调试和监控init服务
- 了解MTK特有的配置和调试方法
- 能够根据自己的需求创新设计新的服务
记住,好的init服务设计应该:
- 最小权限原则
- 适当的错误处理
- 完善的日志记录
- 资源使用可控
- 易于调试和维护