给你自动启动如何设置程序ramdiskrc(进程命令程序文件目录)「让程序自动启动」

一、如何设置开机启动某个程序?1.需求描述最近有个项目需要在Android开机启动之后,自动执行一个C语言编写的程序:pengd该程序运行时需要修改网络ip地址及其他网络操作,所以需要root权限根据需求描述,我们需要做一下操作:将pengd 预置到Android中的某个路径下,比如放在 /sbin/pengd ;然后修改init.rc文件,实现开机后自动运行我们的程序pengd本次项目用到的安卓设备的init.rc和sbin下的文件重启后会恢复默认,主要是安卓部分目录是基于ramdisk,因此我们需要重新制作ramdisk.img,将前面2个步骤的操作同步到到ramdisk.img,然后再重新烧录设备对应分区2.移植步骤1)解压缩ramdisk.img假定厂家提供文件名为:ramdisk_newpeng@ubuntu:~/work/ramdisk$ mv ramdisk_new.img ramdisk_new.img.gzpeng@ubuntu:~/work/ramdisk$ gunzip ramdisk_new.img.gz peng@ubuntu:~/work/ramdisk$ cpio -i -F ramdisk_new.img 5385 blocks2)修改init.rc、修改init.rc文件,如下:service pengd /sbin/pengd seclabel u:r:pengd:s0 user root group root disable oneshoton property:sys.boot_completed=1 start pengd 注意rc文件最后一定要有空行,否则编译报错
“init.rc语法见第二章 该配置文件并不是唯一写法,具体要参考实际厂家提供的sdk中的ramdisk”3) 拷贝程序pengd直接拷贝pengd到 /home/peng/work/ramdisk/sbin也可以是其他bin目录4)重新压缩ramdiskpeng@ubuntu:~/work/ramdisk$ rm ramdisk_new.img 第一次peng@ubuntu:~/work/ramdisk$ find . | cpio -o -H newc > ../ramdisk.img.unzippeng@ubuntu:~/work/ramdisk$ cd ..peng@ubuntu:~/work$ gzip -c ./ramdisk.img.unzip > ./ramdisk.img.gzpeng@ubuntu:~/work$ mv ramdisk.img.gz ramdisk_new.imgpeng@ubuntu:~/work$ chmod 766 ramdisk_new.img3. 运行测试采用厂家提供的烧录工具烧录ramdisk即可,不在截图
可以adb shell登录安卓设备,用以下命令查看进程是否生效:ps -ef | grep pengd二、init.rc详解0、 什么是init.rc?1)init.rc基础概念Adnroid系统就像是是运行在linux系统上的一个“服务进程”,并不算是一个完整的操作系统
这些服务进程是维持设备正常运转的关键,而这些进程的鼻祖就是init进程
进程ID为1,源代码位于system/core/init 目录
作为Android系统的第一个进程,Init进程承担这很多重要的初始化任务,一般Init进程的初始化可以分为两部分,前半部分挂载文件系统,初始化属性系统和Klog, selinux的初始化等,后半部分重要通过解析init.rc来初始化系统daemon服务进程,然后以epoll的监控属性文件,系统信号等
init.rc则是init进程启动的配置脚本,这个脚本是用一种叫Android Init Language(Android初始化语言)的语言写的
2) init.rc语法init.rc语法官方文档路径:system/core/init/Readme.txt下图是瑞芯微sdk的改文件路径:一个完整的init.rc脚本由4种类型的声明组成:Action(动作)Commands(命令)Services(服务)Options(选项)on <trigger> [&& <trigger>] <command> <command> <command>service <name> <pathname> [ <argument> ] <option> <option> ...3)语法规则:注释以 # 开头关键字和参数以空格分隔,每个语句以行为单位C语言风格的 \ 转义字符可以用来为参数添加风格字符串使用 “ ”行尾的 \ 用来表示和下面一行是同一行Actions(动作)和Services(服务)就是一个新语句的开始,这个两个后面跟着Commands(命令)或Options(选项)都属于这个新语句Actions(动作)和Services(服务)有唯一的名字,如果出现重名就会被当成错误忽略掉1、Actions(动作)一个动作其实就是响应某个事件的过程
如下图所示:当early-init这个触发条件产生时,依次执行下面的命令1、命令2、命令3、命令4【改文件位于system/core/rootdir/init.rc 】源码实现思想:当相应的事件发生后,系统就会对init.rc中的各个触发条件进行匹配,只要匹配成功就会把这个动作加到“命令执行队列的尾部”,等待执行
如果已经存在是不会再次添加的
2、Commands(命令)命令会在条件触发后一条一条的执行
1.)init.rc中常见的触发条件:触发条件解释示例boot这是init程序启动后触发的第一个事件on boot<name> = <Value>当属性name满足特定的value时触发on property:vold.decrypt=trigger_load_persist_propsdevice-added-<path> device-removed-<path>当设备节点添加/删除时会触发service-exited-<name>当指定的服务<name>存在时触发2)init.rc中常见的命令init.rc中常见的Commands有以下一些:exec <path> [ <argument> ]创建和执行程序(<path>). 这将会阻塞init,直到程序执行完成
由于它不是内置命令,应尽量避免使用exec,它可能会引起init卡死
export <name> <value>在全局环境变量中设在环境变量 <name>为<value>
(这将会被所有在这命令之后运行的进程所继承)ifup <interface>启动网络接口<interface>import <filename>解析一个init配置文件,扩展当前配置
hostname <name>设置主机名
chdir<directory>改变工作目录
chmod <octal-mode> <path>更改文件访问权限
chown <owner> <group> <path>更改文件的所有者和组
chroot <directory>改变进程的根目录
class_start <serviceclass>启动该类service所有尚未运行的服务
class_stop <serviceclass>停止所有该类正在运行的service
domainname <name>设置域名
enable <servicename>改变一个disable的service为enabled
一般用于service在init.rc中被标记为disabled,这样的service是不会被启动的,当满足一定的触发条件时,可以同enable命令来将他变为enabled
示例: on property:boot_completed=1 enable my_service_nameinsmod <path>安装位于<path>的模块(PS:驱动)
mkdir <path> [mode] [owner] [group]在<path>创建一个目录,(可选)使用给定的模式,所有者个组
如果没有提供,该目录将用755权限,所有者为root用户,组为root
mount <type> <device> <dir>[ <mountoption> ]尝试挂载<device>到<dir>,<device>可能有mtd@name形式,以指定名为name的mtd块设备
<mountoption>包括 "ro", "rw", "remount", "noatime", ...restorecon <path> [ <path> ]恢复名为<path>的文件在file_contexts中配置的的安全级别
自动被init标记正确,不需要用init.rc创建的目录
restorecon_recursive <path> [ <path> ]递归的恢复<path>指出的目录树中file_contexts配置指定的安全级别
path不要用shell可写或app可写的目录,如/data/locla/temp,/data/data,或者有类似前缀的(目录)
setcon <securitycontext>设置当前进程的security context为特定的字符串
这是典型的仅用于所有进程启动之前的early-init设置init contextsetenforce 0|1设置SELinux系统范围的enfoucing状态
0 is permissive (i.e. log but do not deny), 1 is enforcing.setprop <name> <value>设置系统属性<name>为<value>.setrlimit <resource> <cur> <max>为特定资源设置rlimitsetsebool <name> <value>设置SELinux的bool类型<name>为<value>
<value> may be 1|true|on or 0|false|offstart <service>启动一个服务(如果服务尚未启动)
stop <service>停止服务(如果正在运行)
symlink <target> <path>创建一个符号连接,at <path> with the value <target>
sysclktz <mins_west_of_gmt>Set the system clock base (0 if system clock ticks in GMT)trigger <event>触发一个事件
一个动作将另一动作排队
wait <path> [ <timeout> ]poll特定的<path>,出现后返回,或timeout到达
如果timeout没有指定,默认为5秒
write <path> <string>打开一个位于<path>的文件,写入(不是追加)字符串<string>
3、Services(服务)Services其实是可执行程序,他们在特定选项的约束下会被init程序运行或者重启
一般格式:Service <name> <pathname> <argument> <option> <option>......其中标识符含义如下: <name>表示service的名称 <pathname>表示service所在的路径 <argument>表示启动service所带的参数 <option>表示对这个service的约束选项4、Option选项Option用来定义Service的行为,决定了Service将在何时启动,如何运行等
常用的Option有包括以下一些
critical这是十分关键的服务
如果在四分钟内退出超过四次,手机将会重启并进入recovery模式
disabled这种类型的服务不会自动启动
它必须明确的使用名字启动
setenv <name> <value>设置环境变量=在加载的进程中
socket <name> <type> <perm> [ <user> [ <group> [ <context> ] ] ]创建一个名为/dev/socket/<name>的UNIX域socket并将fd传递到加载的进程中
<type>必须是"dgram", "stream", "seqpacket"中的一种
<user>和<group>默认为0.<context>是 SELinux socket 安全上下文,默认为service安全级别,可以指定为seclabel或根据service的可执行文件的安全级别计算
user <username>在执行该service前改变用户名,默认为root
如果你的进程请求Linux的特殊能力,就不要用这个命令
需以进入进程仍是root->请求特权->切换到你期望的uid来替换此法
group <groupname> [ <groupname> ]在执行该service前改变组名
第一个以后的附加组名用于设定进程的附加组(通过setgroups())
当前默认是root
seclabel <securitycontext>在执行服务之前改变安全级别
主要用于从rootfs执行服务,比如ueventd, adbd. 在system分区上可以用基于文件安全级别的策略定义的transition,如果没有指定且没有定义策略的transition,默认是init上下文
oneshot退出不重启服务(名副其实,一次性)
class <name>为一service指定一个类名,所有有相同类名的service可以一同启动或停止
如果没有用class选项指定类名,该service属于"default"
onrestart在service重启的时候执行
给你自动启动如何设置程序ramdiskrc(进程命令程序文件目录)
(图片来源网络,侵删)

联系我们

在线咨询:点击这里给我发消息