Android 重启时执行 shell 脚本 init.rc 执行 shell 脚本
最近有个需求,需要生成系统的默认配置,使得在系统开机后,直接读取已经配置好的文件。当时想的解决方案是,在编译时,先将系统默认配置拷贝到 /system 目录,然后在 init.rc 文件添加语句,将文件直接拷贝到 /data 目录。
但在实际操作过程中发现,只要系统重启后,配置会被覆盖。想通过判断文件是否存在来决定是否拷贝,但是 init.rc 无条件判断语句,所以想到通过执行 shell 脚本来进行判断。说了这么多,总结一句话是
init.rc 无条件判断语句,借助 shell 进行判断。
init.rc 重启时 执行 shell 脚本
该案例基于 rockchip 芯片开发,在 PX30 Android 10上进行的测试,在其他设备上大同小异,请自行查找或替换为对应的路径。
1. 编写脚本 test.sh
#!/system/bin/sh
# 该脚本只是演示,请根据自己需求编写脚本
if [ -f /data/system/test.xml ]; then
echo "test already set"
else
cp /system/test.xml /data/system/test.xml
chmod 0600 /data/system/test.xml
chown system:system /data/system/test.xml
fi
具体到我的工程,我在 AOSP_DIR/device/rockchip/rk3326/PX30_indpx30a/test
目录下新建了该test.sh
2.修改 .mk 配置文件,将创建的 test.sh 编译到系统分区
# copy test.sh to dir vendor/bin/test.sh
PRODUCT_COPY_FILES +=device/rockchip/rk3288/test.sh:vendor/bin/test.sh
将 工程中device/rockchip/rk3288/test.sh
拷贝到 /vendor/bin/test.sh
目录下。
具体到我的工程,target 对应的 mk 文件为 AOSP_DIR/device/rockchip/rk3326/PX30_indpx30a/device-common.mk
3. 配置 SELinux 权限
3.1 创建 test.te
在 service.te
文件所在的目录下创建 test.te
type testshell, domain;
type testshell_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(testshell)
allow testshell vendor_shell_exec:file { execute_no_trans };
allow testshell device:chr_file { ioctl };
#allow testshell system_file:file { execute };
#allow testshell toolbox_exec:file { map };
allow testshell storage_file:dir { search };
allow testshell storage_file:lnk_file { read };
allow testshell mnt_user_file:lnk_file { read };
allow testshell mnt_user_file:dir { search };
allow testshell sdcardfs:dir { search write add_name create };
#allow testshell media_rw_data_file:dir { read open search write };
allow testshell system_data_file:file { getattr };
3.2 配置 service.te
在 service.te
中增加一行
...
type test_service, app_api_service, ephemeral_app_api_service, system_server_service, service_manager_type;
...
3.3 配置 file_context
在 file_contexts
中增加一行
#test
/vendor/bin/test.sh u:object_r:testshell_exec:s0
具体到我的工程,SELinux 配置所在的路径为 AOSP_DIR/device/rockchip/common/sepolicy/vendor
, test.te
、service.te
、file_context
都在该目录下。
4. 配置 init.rc
在 init.rc
文件中找到 on boot
,在其中增加一行 exec -- /vendor/bin/test.sh
,如下
on boot
...
...
# execute test.sh
exec -- /vendor/bin/test.sh
具体到我的工程,target 对应的 init.rc
文件为 AOSP_DIR/device/rockchip/rk3326/PX30_indpx30a/init.rk30board.rc
5. 重新生成固件并刷入
重新生成固件并刷入,查看文件是否成功被复制,从而验证 test.sh
脚本是否被执行,可以通过 adb shell dmesg >julian.log
命令查看开机日志
6. 注意事项
案例中的路径可能和你工程路径不一致,请自行查找或替换为对应的路径。