Android:msm8909:添加自定义脚本

目录

写在前面

本次目的

详细步骤

添加自定义脚本

device/qcom/msm8909/lingump.sh

device/qcom/msm8909/msm8909.mk

system/core/libcutils/fs_config.c

 添加自定义服务

system/core/rootdir/init.rc

device/qcom/sepolicy/common/file_contexts

device/qcom/sepolicy/common/lingump.te 

device/qcom/sepolicy/common/init.te

device/qcom/sepolicy/common/lingump.te

重新编译

 本次小结

 

写在前面

SOC:Qualcomm msm8909

Core-Board:SC20-CE QA/PJ

Base-Board:xxx

Linux Kernel:xxx

Android:7.1

 

本次目的

给系统添加自定义脚本服务,希望在系统开机的过程中执行。

 

详细步骤

 

添加自定义脚本

也许有比这里更简单的方法,不一样的方法都是有不同的优缺点,比如系统跑起来后,通过重新挂载文件系统为可读可写,然后再在系统中编辑脚本等操作,这类操作调试的时候或许方便,但是一来没有集成到系统源码树中,不方便批量生产(试想每次烧录后还要开机去手动修改系统),二来把操作系统挂载成可读可写也不是很符合规范,所以,我这里的做法还是尽量参照安卓系统内部的一些规则进行实现。

首先是创建你自己的脚本文件:

 

device/qcom/msm8909/lingump.sh

#!/system/bin/sh

echo "[GumpIoT] : starting ... powered by lingump.sh"
echo "[GumpIoT] : endding ... powered by lingump.sh"

 注意,如果这个脚本文件编码不对(比如在非类Unix系统下编写的),或者脚本的格式不对(比如没有上述第一行标语或者此标语不能够被目标系统正确识别的),会导致一系列错误,有可能提示你找不到这个脚本文件等等,如下,列出我的情况:

[   11.881639] init: Starting service 'lingump'...
[   11.897026] init: cannot execve('/system/etc/lingump.sh'): No such file or directory
[   12.629945] init: Service 'lingump' (pid 489) exited with status 127
[   11.539183] init: Starting service 'lingump'...
[   11.575105] init: cannot execve('/system/etc/lingump.sh'): Exec format error
[   12.328268] init: Service 'lingump' (pid 488) exited with status 127

device/qcom/msm8909/msm8909.mk

接下来就是修改这个文件,在编译系统镜像时可以把该脚本打包到镜像中:

PRODUCT_COPY_FILES += device/qcom/msm8909/lingump.sh:system/etc/lingump.sh

system/core/libcutils/fs_config.c

安卓用这个文件管理系统初始化时的一些文件属性,包括一些文件权限设置 ,按照我的情况,我需要这个脚本是可读可运行的,其中“{ 00550, AID_ROOT,      AID_SHELL,     0, "system/etc/lingump.sh" },”就是我参考其他文件的设置加上去的:

static const struct fs_path_config android_files[] = {
    { 00440, AID_ROOT,      AID_SHELL,     0, "system/etc/init.goldfish.rc" },
    { 00550, AID_ROOT,      AID_SHELL,     0, "system/etc/init.goldfish.sh" },
    { 00550, AID_ROOT,      AID_SHELL,     0, "system/etc/init.ril" },
    { 00550, AID_ROOT,      AID_SHELL,     0, "system/etc/lingump.sh" },
...

这里有一个小插曲,就是之前的一些安卓系统中,应在“system/core/include/private/android_filesystem_config.h” 中修改对应内容,但是我打开这个文件发现并没有相关的设置项,取而代之的是一条注释内容:

/* Rules for directories and files has moved to system/code/libcutils/fs_config.c */

哈哈,非常有意思,也就是告诉我们相关设置内容搬家了,但是告诉我们的新家地址却是错的,因为你无法找到这个地址,我也迷路了一段时间,我想肯定是留下这个字条的人犯困了,把“core”写成了“code”。

 

 添加自定义服务

 

system/core/rootdir/init.rc

在该文件中添加新的服务项,具体内容含义可以自行上网了解:

service lingump /system/etc/lingump.sh
    class main
    user root
    group root
    oneshot

其实在有些时候这样子就算完成了,但是往往有些系统使用了SELinux,导致该服务无法正常运行,各种权限不足之类的,如果你遇到了类似问题,你还需要参照后续步骤,完成SELinux权限规则设置,这里直接给出步骤,如果需要,请自行上网了解SELinux相关的内容。

值得一提的是,我的系统之前做过了“ROOT权限的获取”,其中就设置了SELinux为“permissive”,有需要了解的朋友可以参考下面两个链接:

https://blog.csdn.net/uestc_ganlin/article/details/90673527

https://blog.csdn.net/uestc_ganlin/article/details/83377528

[   12.318339] init: Service lingump does not have a SELinux domain defined.

 如果遇到了上面的问题你首先需要:

 

device/qcom/sepolicy/common/file_contexts

添加以下内容,其中“lingump_exec”就是我们将要设定的规则类型:

/system/etc/lingump.sh                          u:object_r:lingump_exec:s0

 

device/qcom/sepolicy/common/lingump.te 

添加该SELinux规则定义文件,参考以下内容,这里我们就定义了上面用到的规则类型“lingump_exec”:

type lingump, domain;
type lingump_exec, exec_type, file_type;
init_daemon_domain(lingump)

好了,配置完成SELinux的基本规则之后,再去尝试开机启动脚本,你可能还会遇到一些SELinux规则引发的一些拒绝行为,如下:

[   12.344682] type=1400 audit(5832.459:3): avc: denied { getattr } for pid=1 comm="init" path="/system/etc/lingump.sh" dev="mmcblk0p21" ino=8
65 scontext=u:r:init:s0 tcontext=u:object_r:lingump_exec:s0 tclass=file permissive=1

根据SELinux规则设置,我们需要加入相关允许条件,该条规则参考格式为“allow  : ”,所以我们要做:

 

device/qcom/sepolicy/common/init.te

添加以下内容:

allow init lingump_exec:file   getattr

 接下来尝试的时候,我们又发现了新的拒绝行为:

[   11.137184] init: Starting service 'lingump'...
[   11.268677] type=1400 audit(19.379:3): avc: denied { getattr } for pid=478 comm="lingump.sh" path="/system/bin/sh" dev="mmcblk0p21" ino=59
3 scontext=u:r:lingump:s0 tcontext=u:object_r:shell_exec:s0 tclass=file permissive=1
[   11.269595] type=1400 audit(19.379:4): avc: denied { getattr } for pid=478 comm="lingump.sh" path="/vendor" dev="rootfs" ino=6909 scontext
=u:r:lingump:s0 tcontext=u:object_r:rootfs:s0 tclass=lnk_file permissive=1
[   11.432588] type=1400 audit(19.379:5): avc: denied { read } for pid=478 comm="lingump.sh" path="/system/bin/sh" dev="mmcblk0p21" ino=593 s
context=u:r:lingump:s0 tcontext=u:object_r:shell_exec:s0 tclass=file permissive=1
[   12.611101] init: Service 'lingump' (pid 478) exited with status 0

同理,参考SELinux规则设置,我们为这些拒绝条件放行:

 

device/qcom/sepolicy/common/lingump.te

添加如下内容:

allow lingump shell_exec:file { getattr read };
allow lingump rootfs:lnk_file { getattr };

接下来继续尝试,没有了之前的问题,一切看起来那么正常:

[   11.043634] init: Starting service 'lingump'...
[   11.651394] init: Service 'lingump' (pid 496) exited with status 0

 看起来没有异常日志,但是脚本中打印的内容为何没有输出呢,我猜测应该是控制台输出级别等原因导致的,不在本次探讨,目前看起来脚本服务运行是正常的,Over。

 

重新编译

本次操作步骤中涉及的多次重新编译,建议完全重新编译所有内容后,再尝试相关操作。

 
本次小结

这个人很懒,什么也没有留下!

 

你可能感兴趣的:(Android,Linux)