init进程 && 解析init.rc && init.rc中启动sh文件 && JAVA中跑shell && 文件和文件夹拷贝

        Android启动后,系统执行的第一个进程是一个称为init 的可执行程序。它提供了以下的功能:设备管理、解析启动脚本、执行基本的功能、启动各种服务。代码的路径:system/core/init,结果是一个可执行文件:init,在根文件系统root下。这个init 的可执行文件是系统运行的第一个用户空间的程序,它以守护进程的方式运行。启动脚本则就是下面要讲的Init.rc。

=============解析Android启动脚本init.rc===================

        init.rc,可以在系统的初始化过程中进行一些简单的初始化操作。这个脚本被直接安装到目标系统的根文件系统中,被 init可执行程序解析。它主要包含了四种类型的语句:Action,Commands,Services,Options.其中 Action 和 services 显式声明了一个语句块,以Service 开头的 Section 叫做服务,而以 On 开头的叫做动作(Action)。而 commands 和 options 属于最近声明的语句块。

(1) Commands是一些基本的操作,例如:
    mkdir /sdcard 0000 system system
    mkdir /system
    mount tmpfs tmpfs /sqlite_stmt_journals size=4m

这些命令在init可执行程序中被解析,然后调用相关的函数来实现,可在Keywords.h (system\core\init)中查到命令和函数的对应关系。

        常见命令如下:

export:设置全局环境参数,此参数被设置后对所有进程都有效.

class_start:启动指定类属的所有服务,如果服务已经启动,则不再重复启动

class_stop:停止指定类属的所有服务

insmod:安装模块到指定路径

mkdir [mode] [owner] [group]:用指定参数创建一个目录,在默认情况下,创建的目录读取权限为 755。用户名为 root,组名为 root

setprop:设置属性及对应的值。类似setprop selinux.reload_policy 1。那么开机后在JAVA层和CPP层都可以访问这个值。

start :如果指定的服务未启动,则启动它

stop :如果指定的服务当前正在运行,则停止

symlink:创建一个符号链接

sysclktz:设置系统基准时间

write:往指定的文件写字符串

mount:类似于 linux 的 mount 指令

chdir :改变工作目录
(2)Actions(动作)表示一系列的命令,通常在Triggers(触发条件,关键字on)中调用,动作和触发条件的形式为:
   on
     
     
动作的使用示例如下:
    on init
    export PATH /sbin:/system/sbin:/system/bin:/system/xbin
    mkdir /system
on init表示一个触发条件。

        还有on property可以用于判断是否满足属性,满足xx条件的时候,执行一系列操作,比如:

on property:gpsId=GPS_ID_3332
    insmod /system/drivers/gps.ko

(3)Services(服务)是指那些需要在系统初始化时就启动或退出时自动重启的程序,这些service的源码都会在 frameworks\base\cmds\目录下。
service vold /system/bin/vold
    socket vold stream 0660 root mount
service bootsound /system/bin/playmp3
    user media
    group audio
    oneshot
vold和bootsound分别是两个服务的名称,/system/bin/vold和/system/bin/playmp3分别是他们所对应的可执行程序。

        跟Services搭配使用的常用Options(选项)解释如下:

socket:在/dev/socket/下创建一个 unix domain 的 socket

user:在执行此服务之前先切换用户名。当前默认为 root

group:类似于 user,切换组名

oneshot:表示该服务只启动一次;而如果没有oneshot选项,这个可执行程序会一直存在,如果可执行程序被杀死,则会重新启动。

class:类属,即可以为多个 service 指定一个相同的类属,方便操作同时启动或停止。可为main或者core等

onrestart:当服务重启时执行一条指令

disabled:服务不会自动运行,必须显式地启动。启动方法:(0)sh中,以start 服务名(1)adb命令行:#setprop ctl.start bootanim #setprop ctl.stop bootanim(2)C代码:property_set(“ctl.start”, “bootanim”); property_set(“ctl.stop”, “bootanim”);(3)JAVA代码,就是SystemProperties.set

(4)以上说明了init.rc中各个组成部分,这些内容是有固定的执行顺序,这个顺序由early-init, init, early-boot, boot这四个关键字决定。一个典型的rc文件的写法如下:

on early-init
--------------

on init
--------------

on early-boot
--------------

on boot
--------------

rc文件中这4个部分是可以打乱顺序随便写的,但是解析完了以后的执行顺序确实固定的,执行顺序如下: early-init、init、early-fs,fs,post-fs,post-fs-data,early-boot,boot。

(4)chmod无法改变权限的问题

        添加了chmod语句后,开机发现权限仍然没变。最后发现要先修改/system ro权限为rw,即mount ext4 /dev/block/system  /system rw wait noatime nodiratime,而且chmod要放在该句同属的on fs段才可以(on fs挂载文件系统)

(5)如何知道一个service是否还在运行

用getprop init.svc.$service_name即可,service_name即定义的服务名。比如

getprop init.svc.mcucomm
running

================init.rc中启动sh文件================

         假设,我们通过adb调试命令调好了一个外设的硬件模块,下一步的动作,需要让系统开机自动跑这些命令并正常启动模块的工作。这个时候,就需要用到sh将这些命令组合起来,放到init.rc中就可以实现这个目的。shell内容如下:

#!/system/bin/sh
PKG_DIR=/system/lib/modules
APP_DIR=/system/bin

cd $PKG_DIR
CUR_PKG_DIR=`pwd`
echo "CUR_PKG_DIR = $CUR_PKG_DIR"

insmod $PKG_DIR/accel_qlulpsh.ko 
insmod $PKG_DIR/mag_qlulpsh.ko 
insmod $PKG_DIR/gyro_qlulpsh.ko 
insmod $PKG_DIR/pedometer_qlulpsh.ko 
insmod $PKG_DIR/gestures_qlulpsh.ko 
insmod $PKG_DIR/contexts_qlulpsh.ko 

cd $APP_DIR
CUR_APP_DIR=`pwd`
echo "CUR_APP_DIR = $CUR_APP_DIR"

#Program the Sensor hub 
echo "SensorHub Programming using loader APP"
sleep 1
./qlulpsh_loader_app -i ./ulpsh_s2_main.shexe -b 1 -s 1 -t 10 -d
sleep 1
./qlulpsh_loader_app -c 1 -a 0002

echo "Starting SensorHub..."
echo 1 > /sys/devices/virtual/QL_Sensors/qlulpsh/intr_enable
echo 16 > /sys/devices/virtual/QL_Sensors/qlulpsh/FFE_RunCnt
sleep 1

echo "Starting sensorservice..."
sensorservice &
注意:(1)两个可执行文件前要加./,否则提示可执行文件not found,需指明当前目录下。(2)考虑硬件的实际执行情况,sh中有sleep语句,有些读操作要等待真实硬件初始化OK。(3)sensorservice &启动安卓系统sensor服务。

        在init.rc中,补上如下语句,用service启动一个shell。

# SenHub scripts
		service myshell /system/bin/sensorhub_init.sh
		oneshot

===================JAVA中跑shell=============

如果在java中跑shell命令。systemui中可跑,app中老是失败。

 void cpimage() {
	 	String result;
        try {           
            Process p = Runtime.getRuntime().exec("cp /system/BerylliumVideo.mp4 /storage/sdcard0/Movies");
            int status = p.waitFor();
            if (status == 0) {
                result = "Pass";
            } else {
                result = "Fail: IP addr not reachable";
            }
        } catch (IOException e) {
            result = "Fail: IOException";
        } catch (InterruptedException e) {
            result = "Fail: InterruptedException";
        }
    }
如果在java中跑shell脚本
     void cpimage() {
	 	String result;
        try {           
            Process p = Runtime.getRuntime().exec("system/bin/init.BerylliumVideo.sh");
            int status = p.waitFor();
            if (status == 0) {
                result = "Pass";
            } else {
                result = "Fail";
            }
        } catch (IOException e) {
            result = "Fail: IOException";
        } catch (InterruptedException e) {
            result = "Fail: InterruptedException";
        }
    }

shell内容:

if [ ! -e /storage/sdcard0/Movies/BerylliumVideo.mp4 ];then
 cp /system/BerylliumVideo.mp4 /storage/sdcard0/Movies/
fi
========================文件和文件夹拷贝=====================

上述执行shell拷贝的功能,用java函数也可以完成。

(1)文件拷贝,systemui中试验成功

public void copyVideoFile(String oldPath, String newPath) {   
       try {   
            int bytesum = 0;   
            int byteread = 0;   
            File oldfile = new File(oldPath);   
File newfile = new File(newPath);  
            if (oldfile.exists()) {    
Log.d("Clock","oldfile exists ");  
if(!newfile.exists()){
Log.d("Clock","newfile no exists ");
InputStream inStream = new FileInputStream(oldPath); //?áè??-???t   
                FileOutputStream fs = new FileOutputStream(newPath);   
                byte[] buffer = new byte[1024];   
                while ( (byteread = inStream.read(buffer)) != -1) {   
                    bytesum += byteread;   
                    fs.write(buffer, 0, byteread);   
                }   
                inStream.close();   
fs.close();   
}
           }   
       }   
       catch (Exception e) {   
           Log.d("Clock","copy video error");   
           e.printStackTrace();     
       }   
}   
使用时用copyVideoFile("/system/BerylliumVideo.mp4","/storage/sdcard0/Movies/BerylliumVideo.mp4");

(2)文件夹拷贝

public void copyFolder(String oldPath, String newPath) {     
       try {   
           (new File(newPath)).mkdirs(); 
           File a=new File(oldPath);   
           String[] file=a.list();   
           File temp=null;   
           for (int i = 0; i < file.length; i++) {   
               if(oldPath.endsWith(File.separator)){   
                   temp=new File(oldPath+file[i]);   
               }   
               else{   
                   temp=new File(oldPath+File.separator+file[i]);   
               }   
  
               if(temp.isFile()){   
                   FileInputStream input = new FileInputStream(temp);   
                   FileOutputStream output = new FileOutputStream(newPath + "/" +   
                           (temp.getName()).toString());   
                   byte[] b = new byte[1024 * 5];   
                   int len;   
                   while ( (len = input.read(b)) != -1) {   
                       output.write(b, 0, len);   
                   }   
                   output.flush();   
                   output.close();   
                   input.close();   
               }   
               if(temp.isDirectory()){
                   copyFolder(oldPath+"/"+file[i],newPath+"/"+file[i]);   
               }   
           }   
       }   
       catch (Exception e) {   
           System.out.println("copy folder error");   
           e.printStackTrace();   
  
       }   
  
   }  
使用时copyFolder("/system/filetest","/storage/sdcard0/Movies/filetest");



参考原文:http://hi.baidu.com/albertchen521/blog/item/4ac8d500f894fddf277fb59b.html

参考原文:http://blog.csdn.net/jiajie961/article/details/6047219

参考原文:http://hi.baidu.com/donghaozheng/blog/item/e2f5045577cb73c8b645aec0.html

你可能感兴趣的:(Android)