1、编写自己的shell脚本
以RK3399 安卓Q为例,device/rockchip/rk3399/myscript.sh
:
#!/vendor/bin/sh
while true;do
echo "++++++This is a test script !++++++" > /dev/console
sleep 5
done
2、修改安卓源文件
2.1 修改device.mk编译时将脚本拷贝到镜像中
device/rockchip/rk3399/device.mk
:
@@ -59,6 +59,7 @@ PRODUCT_COPY_FILES += \
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/init.rk3399.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/hw/init.rk3399.rc \
$(LOCAL_PATH)/init.rk3399.usb.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/hw/init.rk3399.usb.rc \
+ $(LOCAL_PATH)/myscript.sh:$(TARGET_COPY_OUT_VENDOR)/bin/myscript.sh \
$(LOCAL_PATH)/wake_lock_filter.xml:system/etc/wake_lock_filter.xml \
device/rockchip/rk3399/package_performance.xml:$(TARGET_COPY_OUT_ODM)/etc/package_performance.xml \
2.2 修改init.xxx.rc添加服务并启动
device/rockchip/rk3399/init.rk3399.rc
:
@@ -7,6 +7,7 @@ on property:sys.boot_completed=1
chmod 0664 /sys/class/devfreq/ff9a0000.gpu/max_freq
chown root system /sys/class/devfreq/dmc/governor
chmod 0664 /sys/class/devfreq/dmc/governor
+ start myscript
@@ -51,3 +52,9 @@ on post-fs-data
chown root system /sys/class/graphics/fb0/cabc
chmod 0664 /sys/class/graphics/fb0/cabc
+service myscript /vendor/bin/myscript.sh
+ class main
+ user root
+ group root
+ disabled
+ oneshot
另外需要注意service的名称不要超过16个字符。
2.3 新建xxx.te文件声明运行域
device/rockchip/common/sepolicy/vendor/myscript.te
:
type myscript, domain;
type myscript_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(myscript)
allow myscript vendor_shell_exec:file rx_file_perms;
allow myscript vendor_toolbox_exec:file rx_file_perms;
2.4 修改file_contexts文件绑定te文件
device/rockchip/common/sepolicy/vendor/file_contexts
:
@@ -107,6 +107,7 @@
/vendor/bin/hw/rk_wifi_hal u:object_r:rk_wifi_hal_exec:s0
/vendor/bin/hw/rockchip\.hardware\.outputmanager@1\.0-service u:object_r:rk_output_hal_exec:s0
/vendor/bin/abc u:object_r:abc_exec:s0
+/vendor/bin/myscript\.sh u:object_r:myscript_exec:s0
/vendor/lib(64)?/libdrm.so u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libdrm_rockchip.so u:object_r:same_process_hal_file:s0
/vendor/lib(64)?/libIMGegl.so u:object_r:same_process_hal_file:s0
至此,在系统没有开启SELinux权限情况下,以上步骤一般已经能正常执行了。但如果开启了SELinux,则需要继续下面第3步进行权限的配置。(SELinux权限可以adb或串口执行getenforce
查询,Enforcing
为开启、Permissive
为关闭)
3、SELinux权限问题解决
3.1 解决方法1:添加相应的权限
① 查看所缺乏的权限
推荐使用命令“setenforce 0”先将SELinux权限暂时关闭后再执行命令“start 服务名”手动启动服务来抓取log,因为在SELinux权限开启时,缺乏的权限并不是一次性提示所有,而是添加完成一项后才会提示下一项权限,工作量会比较大。
adb shell "dmesg | grep avc" > avc_log.txt
permissive=0说明缺乏某项权限;permissive=1则代表只是提示,但不会造成影响。
例如提示以下log:
type=1400 audit(1611044417.518:29): avc: denied {
write } for comm="myscript.sh" name="console" dev="tmpfs" ino=20774 scontext=u:r:myscript:s0 tcontext=u:object_r:console_device:s0 tclass=chr_file permissive=1
type=1400 audit(1611044417.518:29): avc: denied {
write } for comm="myscript.sh" name="console" dev="tmpfs" ino=20774 scontext=u:r:myscript:s0 tcontext=u:object_r:console_device:s0 tclass=chr_file permissive=1
type=1400 audit(1611044417.518:30): avc: denied {
open } for comm="myscript.sh" path="/dev/console" dev="tmpfs" ino=20774 scontext=u:r:myscript:s0 tcontext=u:object_r:console_device:s0 tclass=chr_file permissive=1
② 修改te文件添加权限
按照公式allow + scontext + tcontext + “:” + tclass + { permission };
手动编写或使用audit2allow -i avc_log.txt
命令自动生成相应规则,然后添加到对应文件中。
根据上一步抓取的log来编写相应的权限:
allow myscript console_device:chr_file {
open write };
所以添加相关权限后的device/rockchip/common/sepolicy/vendor/myscript.te
内容为:
type myscript, domain;
type myscript_exec, exec_type, vendor_file_type, file_type;
init_daemon_domain(myscript)
allow myscript vendor_shell_exec:file rx_file_perms;
allow myscript vendor_toolbox_exec:file rx_file_perms;
allow myscript console_device:chr_file {
open write };
3.2 解决方法2:源码里关闭SELinux权限
system/core/init/selinux.cpp
:
@@ -97,6 +97,7 @@ EnforcingStatus StatusFromCmdline() {
}
bool IsEnforcing() {
+ return false;
if (ALLOW_PERMISSIVE_SELINUX) {
return StatusFromCmdline() == SELINUX_ENFORCING;
}
参考资料
- Android开机执行指定shell脚本 – CSDN
- SELinux权限问题解决方法 – CSDN
- Android SeLinux权限问题和解决方法 – CSDN
- [LINUX DEVICE DRIVER] ANDROID10 关闭SELINUX权限方法 – 灰信网
如有错误,希望大家不吝赐教。