Android启动后,系统执行的第一个进程是一个名称为init 的可执行程序。提供了以下的功能:设备管理、解析启动脚本、执行基本的功能、启动各种服务。代码的路径:
system/core/init,编译的结果是一个可执行文件:init。这个init 的可执行文件是系统运行的第一个用户空间的程序,它以守护进程的方式运行。启动脚本则就是下面要讲的Init.rc。
===========================================================================================
在Android中使用启动脚本init.rc,可以在系统的初始化过程中进行一些简单的初始化操作。这个脚本被直接安装到目标系统的根文件系统中,被 init可执行程序解析。使用方法参考system/core/init/readme.txt,关键字参考system/core/init/keyword.h。
init.rc是在init启动后被执行的启动脚本,其语法主要包含了以下内容:
Commands:命令
Actions: 动作
Triggers:触发条件
Services:服务
Options:选项
Propertise:属性
(1) Commands是一些基本的操作,例如:
mkdir /sdcard 0000 system system
mkdir /system
mkdir /data 0771 system system
mkdir /cache 0770 system cache
mkdir /config 0500 root root
mkdir /sqlite_stmt_journals 01777 root root
mount tmpfs tmpfs /sqlite_stmt_journals size=4m
这些命令在init可执行程序中被解析,然后调用相关的函数来实现。
(2)Actions(动作)表示一系列的命令,通常在Triggers(触发条件)中调用,动作和触发条件的形式为:
on <trigger>
<command>
<command>
<command>
动作的使用示例如下:
on init
export PATH /sbin:/system/sbin:/system/bin:/system/xbin
mkdir /system
init表示一个触发条件,这个触发事件发生后,进行设置环境变量和建立目录的操作称为一个“动作”。
(3)Services(服务)通常表示启动一个可执行程序,Options(选项)是服务的附加内容,用于配合服务使用。
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分别是他们所对应的可执行程序。socket、user、group、oneshot就是配合服务使用的选项。其中oneshot选项表示该服务只启动一次,而如果没有oneshot选项,这个可执行程序会一直存在--如果可执行程序被杀死,则会重新启动。
(4) Properties(属性)是系统中使用的一些值,可以进行设置和读取。
setprop ro.FOREGROUND_APP_MEM 1536
setprop ro.sf.hwrotation 90
on property:ro.kernel.qemu=1
start adbd
setprop 用于设置属性,on property可以用于判断属性,这里的属性在整个Android系统运行中都是一致的。init脚本的关键字可以参考init进程的system/core/init/keyword.h文件。init.rc的使用方法,可以参考说明文件system/core/init/readme.txt。如果想要修改启动过程只需要修改init.c(system/core/init)或者init.rc里的内容即可.
以上说明了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-boot -> boot
==================================================================================================================
既然android是运行在linux之上的,我们可否只启动linux而不启动android,这样的话在不需要图形界面的设备中可以大大降低硬件运行要求而提供内核服务。我们可以通过修改init.rc来实现。
android的系统应用中的一个重要的进程就是zygote,所有的java应用程序进程都是由zygote派生出来的,zygote这个进程的作用就是“生儿子”。zygote进程正是在linux kernel startup后通过这个文件启动的,具体看init.rc中这一段:service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server。一段一段的分析这个代码:启动服务名字zygote. /system/bin/app_process:进程的bin文件具体路径,后面跟的就是启动参数-Xzygote /system/bin --zygote --start-system-server。
=================================================================================================
假设要内置的文件名称为iperf。(1)将iperf放到Codebase的任意一个目录下(该目录必须能够在搜索Android.mk时被搜索到),比如system/iperf/iperf。(2)在system/iperf目录下添加一个Android.mk文件,内容如下:
LOCAL_PATH:= $(call my-dir)
PRODUCT_COPY_FILES += $(LOCAL_PATH)/iperf:system/iperf/iperf
重新编译Codebase即可,该文件将被内置到手机的system/iperf目录下。注意这种方法禁止复制APK文件。
=================================================================================================
假设,我们通过adb调试命令调好了一个外设的硬件模块,下一步的动作,需要让系统开机自动跑这些命令并正常启动模块的工作。这个时候,就需要用到sh将这些命令组合起来,放到init.rc中就可以实现这个目的(不要放到init.project.rc中,会影响到WIFIBT)。
出于执行权限原因,ko文件可以放到vendor的/system/lib/modules下(不能放到vendor对应的/data目录,RELEASE版本/data无权限insmod),可执行文件包括shell则放到vendor的/system/bin下,这样确保任何时候都可以执行。
#!/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
./qlulpsh_loader_app -i ./ulpsh_s2_main.shexe -b -s -t -d
sleep
./qlulpsh_loader_app -c -a echo "Starting SensorHub..."
echo > /sys/devices/virtual/QL_Sensors/qlulpsh/intr_enable
echo > /sys/devices/virtual/QL_Sensors/qlulpsh/FFE_RunCnt
sleep 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
---