打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Init.rc分析(刘举奎)

目录

 [隐藏

init.rc

Android init language

Android 初始化语言由四大类声明组成 : 行为类 (Actions), 命令类 (Commands) ,服务类 (Services), 选项类 (Options).

  • 初始化语言以行为单位,由以空格间隔的语言符号组成。 C 风格的反斜杠转义符可以用来插入空白到语言符号。双引号也可以用来防止文本被空格分成多个语言符号。当反斜杠在行末时,作为折行符。
  • 以 # 开始 ( 前面允许有空格 ) 的行为注释行。
  • Actions 和 Services 隐含声明一个新的段落。所有该段落下 Commands 或 Options 的声明属于该段落。第一段落前的 Commands 或 Options 被忽略。
  • Actions 和 Services 拥有独一无二的命名。在它们之后声明相同命名的类将被当作错误并忽略。

下面给出了源文件system/core/init/keywords.h中定义的所有的关键字。

形式:KEYWORD(symbol, flags, nargs, func)    KEYWORD(capability,  OPTION,  0, 0)    KEYWORD(chdir,       COMMAND, 1, do_chdir)    KEYWORD(chroot,      COMMAND, 1, do_chroot)    KEYWORD(class,       OPTION,  0, 0)    KEYWORD(class_start, COMMAND, 1, do_class_start)    KEYWORD(class_stop,  COMMAND, 1, do_class_stop)    KEYWORD(console,     OPTION,  0, 0)    KEYWORD(critical,    OPTION,  0, 0)    KEYWORD(disabled,    OPTION,  0, 0)    KEYWORD(domainname,  COMMAND, 1, do_domainname)    KEYWORD(exec,        COMMAND, 1, do_exec)    KEYWORD(export,      COMMAND, 2, do_export)    KEYWORD(group,       OPTION,  0, 0)    KEYWORD(hostname,    COMMAND, 1, do_hostname)    KEYWORD(ifup,        COMMAND, 1, do_ifup)    KEYWORD(insmod,      COMMAND, 1, do_insmod)    KEYWORD(import,      COMMAND, 1, do_import)    KEYWORD(keycodes,    OPTION,  0, 0)    KEYWORD(mkdir,       COMMAND, 1, do_mkdir)    KEYWORD(mount,       COMMAND, 3, do_mount)    KEYWORD(on,          SECTION, 0, 0)    KEYWORD(oneshot,     OPTION,  0, 0)    KEYWORD(onrestart,   OPTION,  0, 0)    KEYWORD(restart,     COMMAND, 1, do_restart)    KEYWORD(service,     SECTION, 0, 0)    KEYWORD(setenv,      OPTION,  2, 0)    KEYWORD(setkey,      COMMAND, 0, do_setkey)    KEYWORD(setprop,     COMMAND, 2, do_setprop)    KEYWORD(setrlimit,   COMMAND, 3, do_setrlimit)    KEYWORD(socket,      OPTION,  0, 0)    KEYWORD(start,       COMMAND, 1, do_start)    KEYWORD(stop,        COMMAND, 1, do_stop)    KEYWORD(trigger,     COMMAND, 1, do_trigger)    KEYWORD(symlink,     COMMAND, 1, do_symlink)    KEYWORD(sysclktz,    COMMAND, 1, do_sysclktz)    KEYWORD(user,        OPTION,  0, 0)    KEYWORD(write,       COMMAND, 2, do_write)    KEYWORD(copy,        COMMAND, 2, do_copy)    KEYWORD(chown,       COMMAND, 2, do_chown)    KEYWORD(chmod,       COMMAND, 2, do_chmod)    KEYWORD(loglevel,    COMMAND, 1, do_loglevel)    KEYWORD(device,      COMMAND, 4, do_device)    KEYWORD(ioprio,      OPTION,  0, 0)    KEYWORD(devwait,     COMMAND, 1, do_devwait)

Actions

Actions 是一系列命令的命名。 Actions 拥有一个触发器 (trigger) 用来决定 action 何时执行。当一个 action 在符合触发条件被执行时,如果它还没被加入到待执行队列中的话,则加入到队列最后。

队列中的 action 依次执行, action 中的命令也依次执行。 Init 在执行命令的中间处理其它活动 ( 设备创建 / 销毁 ,property 设置,进程重启 ) 。

Actions 表现形式为:

on <trigger>    <command>    <command>    <command>

trigger可以有以下几种,并且在init进程中,所有的Actions执行顺序为下面所列出顺序。

  • early-init
  • init
  • early-boot
  • boot

Triggers

Triggers( 触发器 ) 是一个字符串,可以用来匹配某种类型的事件并执行一个 action 。

boot
这是当 init 开始后执行的第一个触发器 ( 当 /init.conf 被加载 )
<name>=<value>
当 property <name> 被设为指定的值 <value> 时触发。
device-added-<path>
当设备节点被添加时触发。
device-removed-<path>
当设备节点被移除时触发。
service-exited-<name>
当指定的服务存在时触发

Commands

exec
exec <path> [ <argument> ]*
Fork 并执行一个程序 (<path>). 这将被 block 直到程序执行完毕。最好避免执行例如内建命令以外的程序,它可能会导致 init 被阻塞不动。
export
export <name> <value>
设定全局环境变量 <name> 的值 <value> ,当这个命令执行后所有的进程都可以取得。
ifup
ifup <interface>
使网络接口 <interface> 联机。
import
import <filename>
解析一个 init 配置文件,扩展当前配置文件。
hostname
hostname <name>
设置主机名
chmod
chmod <octal-mode> <path>
改变文件访问权限
chown
chown <owner> <group> <path>
改变文件所属和组
class_start
class_start <serviceclass>
当指定类别的服务没有运行,启动该类别除disable标志以外的所有的服务。
class_stop
class_stop <serviceclass>
当指定类别的服务正在运行,停止该类别所有的服务。
domainname
domainname <name>
设置域名。
insmod
insmod <path>
加载该路径 <path> 的模块
mkdir
mkdir <path> [mode] [owner] [group]
在 <path> 创建一个目录 , 可选选项 :mod,owner,group. 如果没有指定,目录以 755 权限, owner 为 root,group 为 root 创建 .
mount
mount <type> <device> <dir> [ <mountoption> ]*
尝试 mount <device> 到目录 <dir>. <device> 可以用 mtd@name 格式以命名指定一个 mtd 块设备。 <mountoption> 包含"ro","rw","remount","noatime".
setkey

setprop
setprop <name> <value>
设置系统 property <name> 的值 <value>.
setrlimit
setrlimit <resource> <cur> <max>
设置 resource 的 rlimit.
start
start <service>
启动一个没有运行的服务。
stop
stop <service>
停止一个正在运行的服务。
symlink
symlink <target> <path>
创建一个 <path> 的符号链接到 <target>
sysclktz
sysclktz <mins_west_of_gmt>
设置系统时区 (GMT 为 0)
trigger
trigger <event>
触发一个事件。用于调用其它 action 。
write
write <path> <string> [ <string> ]*
打开 <path> 的文件并写入一个或多个字符串。

Services

Services 是由 init 启动,在它们退出时重启 ( 可选 ) 。 Service 表现形式为 :

service <name> <pathname> [ <argument> ]*   <option>   <option>   ...

Options

Options 是 Services 的修饰,它们影响 init 何时、如何运行 service.

critical
这是一个设备关键服务 (device-critical service) . 如果它在 4 分钟内退出超过 4 次,设备将重启并进入恢复模式。
#define SVC_CRITICAL    0x20  /* will reboot into recovery if keeps crashing */
disabled
这个服务的级别将不会自动启动,它必须被依照服务名指定启动才可以启动。
使用class_start时不会被启动,使用start才会被启动,无论怎样,只有当服务没有运行时才会去启动。
setenv
setenv <name> <value>
设置已启动的进程的环境变量 <name> 的值 <value>
socket
socket <name> <type> <perm> [ <user> [ <group> ] ]
创建一个名为 /dev/socket/<name> 的 unix domin socket ,并传送它的 fd 到已启动的进程。 <type> 必须为 "dgram" 或 "stream". 用户和组默认为 0.
user
user <username>
在执行服务前改变用户名。当前默认为 root. 如果你的进程需要 linux 能力,你不能使用这个命令。你必须在还是 root 时请求能力,并下降到你需要的 uid.
group
group <groupname> [ <groupname> ]*
在执行服务前改变组。在第一个组后的组将设为进程附加组 ( 通过 setgroups()). 当前默认为 root.
oneshot
在服务退出后不重启。
class
class <name>
为 service 指定一个类别名。同样类名的所有的服务可以一起启动或停止。如果没有指定类别的服务默认为 "default" 类。
onrestart
当服务重启时执行一个命令。
ioprio
ioprio <rt|be|idle> <ioprio 0-7>
设置IO优先权
/* 21  * These are the io priority groups as implemented by CFQ. RT is the realtime 22  * class, it always gets premium service. BE is the best-effort scheduling 23  * class, the default for any process. IDLE is the idle scheduling class, it 24  * is only served when no one else is using the disk. 25  */ 26 enum { 27         IOPRIO_CLASS_NONE, 28         IOPRIO_CLASS_RT, 29         IOPRIO_CLASS_BE, 30         IOPRIO_CLASS_IDLE, 31 };

Properties

init 会更新一些系统 property 以提供查看它正在干嘛。

init.action
当前正在执行的 action, 如果没有则为 ""
init.command
被执行的命令,如果没有则为 ""
init.svc.<name>
命名为 <name> 的服务的状态 ("stopped", "running", "restarting")

init进程

init是一个由内核启动的用户级进程。内核自行启动(已经被载入内存,开始运行,并已初始化所有的设备驱动程序和数据结构等)之后,就通过启动一个用户级程序init的方式,完成引导进程。init始终是第一个进程。基本功能有:

  • 解析系统所有property文件并存储
  • 管理设备
  • 解析并处理启动脚本init.rc
  • 实时维护这个init.rc中的服务
  • 担当系统property的设置服务

下面来看一下主函数:

int main(int argc, char **argv){    int device_fd = -1;    int property_set_fd = -1;    int signal_recv_fd = -1;    int keychord_fd = -1;    int fd_count;    int s[2];    int fd;    struct sigaction act;    char tmp[PROP_VALUE_MAX];    struct pollfd ufds[4];    char *tmpdev;    char* debuggable;   /**    安装SIGCHLD信号。如果父进程不等待子进程结束,子进程将成为僵尸进程,    其占用的系统资源将得不到释,必须注册此信号处理。    */    act.sa_handler = sigchld_handler;    act.sa_flags = SA_NOCLDSTOP;    act.sa_mask = 0;    act.sa_restorer = NULL;    sigaction(SIGCHLD, &act, 0);    /**     创建文件系统需要的基本目录。mount一些必要的分区     */      /* clear the umask */    umask(0);        /* Get the basic filesystem setup we need put         * together in the initramdisk on / and then we'll         * let the rc file figure out the rest.         */    mkdir("/dev", 0755);    mkdir("/proc", 0755);    mkdir("/sys", 0755);    mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755");    mkdir("/dev/pts", 0755);    mkdir("/dev/socket", 0755);    mount("devpts", "/dev/pts", "devpts", 0, NULL);    mount("proc", "/proc", "proc", 0, NULL);    mount("sysfs", "/sys", "sysfs", 0, NULL);        /* We must have some place other than / to create the         * device nodes for kmsg and null, otherwise we won't         * be able to remount / read-only later on.         * Now that tmpfs is mounted on /dev, we can actually         * talk to the outside world.         */    /**     打开了stdin stdout和stderr,创建了/dev/null节点。     初始化log,(创建/dev/kmsg节点)     */      open_devnull_stdio();    log_init();        INFO("reading config file\n");  // kmsg节点创建后,可以打trace了    /*解析初始化脚本,这里只是parse,将脚本解析到一个链表中,没有执行。 */      parse_config_file("/init.rc");    /*获得内核命令行参数*/      /* pull the kernel commandline and ramdisk properties file in */    qemu_init();    import_kernel_cmdline(0);      /* 根据上一部获得的hardware参数信息,解析额外的硬件相关init脚本, 一般qemu为init.goldfish.rc */      get_hardware_name();    snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);    parse_config_file(tmp);    /* 检查是否存在/init.target.rc,存在的话则解析并保存到链表 */      /* Check for a target specific initialisation file and read if present */    if (access("/init.target.rc", R_OK) == 0) {        INFO("Reading target specific config file");        parse_config_file("/init.target.rc");    }      /* 触发标志为early-init的Action,将其添加到action queue中 */      action_for_each_trigger("early-init", action_add_queue_tail);    /* 执行这些queue中Action的Commands */      drain_action_queue();    /*初始化驱动设备,创建文件系统节点*/    INFO("device init\n");    device_fd = device_init();    /* 执行init.rc中关于启动介质Action的Commands */      if (emmc_boot){        action_for_each_trigger("emmc", action_add_queue_tail);        drain_action_queue();    }else{        action_for_each_trigger("nand", action_add_queue_tail);        drain_action_queue();    }    // 初始化属性系统,并导入初始化属性文件(PROP_PATH_RAMDISK_DEFAULT)    property_init();        // only listen for keychords if ro.debuggable is true    keychord_fd = open_keychord();      /*打开console*/      if (console[0]) {        snprintf(tmp, sizeof(tmp), "/dev/%s", console);        console_name = strdup(tmp);    }    fd = open(console_name, O_RDWR);    if (fd >= 0)        have_console = 1;    close(fd);  /* 加载logo图片,格式是rgb565的raw data(/initlogo.rle),如果不存在此文件,则直接在console上打印android文字,    //注意的是: android在首次加载时,会非常慢, 这个图就是提醒下我们是在加载模式下,此图显示后会被自动删除,因此默认只有烧code完毕后看到一次 */      if( load_565rle_image(INIT_IMAGE_FILE) ) {    fd = open("/dev/tty0", O_WRONLY);    if (fd >= 0) {        const char *msg;            msg = "\n"        "\n"        "\n"        "\n"        "\n"        "\n"        "\n"  // console is 40 cols x 30 lines        "\n"        "\n"        "\n"        "\n"        "\n"        "\n"        "\n"        "             A N D R O I D ";        write(fd, msg, strlen(msg));        close(fd);    }    }    if (qemu[0])        import_kernel_cmdline(1);       /* 设置一些属性的默认值,属性干嘛用的还没研究 */      if (!strcmp(bootmode,"factory"))        property_set("ro.factorytest", "1");    else if (!strcmp(bootmode,"factory2"))        property_set("ro.factorytest", "2");    else        property_set("ro.factorytest", "0");    property_set("ro.serialno", serialno[0] ? serialno : "");    property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown");    property_set("ro.baseband", baseband[0] ? baseband : "unknown");    property_set("ro.carrier", carrier[0] ? carrier : "unknown");    property_set("ro.bootloader", bootloader[0] ? bootloader : "unknown");    property_set("ro.hardware", hardware);    snprintf(tmp, PROP_VALUE_MAX, "%d", revision);    property_set("ro.revision", tmp);    property_set("ro.emmc",emmc_boot ? "1" : "0");   //执行触发标志为init的Action中的Command        /* execute all the boot actions to get us started */    action_for_each_trigger("init", action_add_queue_tail);    drain_action_queue();    //读取几个属性文件后,打开一个service socket//    在函数start_property_service()里//    load_properties_from_file(PROP_PATH_SYSTEM_BUILD);//    load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT);//    load_properties_from_file(PROP_PATH_LOCAL_OVERRIDE);//    /* Read persistent properties after all default values have been loaded. *///    load_persistent_properties();        /* read any property files on system or data and         * fire up the property service.  This must happen         * after the ro.foo properties are set above so         * that /data/local.prop cannot interfere with them.         */    property_set_fd = start_property_service();    //创建socket对,为SIGCHLD处理做准备    /* 关于socketpair的这个mechanism,可以参考http://www.lupaworld.com/home-space-uid-384165-do-blog-id-138155.html */      /* create a signalling mechanism for the sigchld handler */    if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0) {        signal_fd = s[0];        signal_recv_fd = s[1];        fcntl(s[0], F_SETFD, FD_CLOEXEC);        fcntl(s[0], F_SETFL, O_NONBLOCK);        fcntl(s[1], F_SETFD, FD_CLOEXEC);        fcntl(s[1], F_SETFL, O_NONBLOCK);    }    /* make sure we actually have all the pieces we need */    if ((device_fd < 0) ||        (property_set_fd < 0) ||        (signal_recv_fd < 0)) {        ERROR("init startup failure\n");        return 1;    }    //不知为何此处需要暂停    /* pause if necessary */    if (battchg_pause) {          alarm_entry();//        action_for_each_trigger("boot-pause", action_add_queue_tail);//        drain_action_queue();    }    //执行触发标志为early-boot和boot的Action中的Commands    /* execute all the boot actions to get us started */    action_for_each_trigger("early-boot", action_add_queue_tail);    action_for_each_trigger("boot", action_add_queue_tail);    drain_action_queue();    //执行已经满足property=value Action中的Commands        /* run all property triggers based on current state of the properties */    queue_all_property_triggers();    drain_action_queue();        /* enable property triggers */       property_triggers_enabled = 1;         //为后面检测这些文件描述符事件做一些数据准备    ufds[0].fd = device_fd;    ufds[0].events = POLLIN;    ufds[1].fd = property_set_fd;    ufds[1].events = POLLIN;    ufds[2].fd = signal_recv_fd;    ufds[2].events = POLLIN;    fd_count = 3;    if (keychord_fd > 0) {        ufds[3].fd = keychord_fd;        ufds[3].events = POLLIN;        fd_count++;    } else {        ufds[3].events = 0;        ufds[3].revents = 0;    }#if BOOTCHART    bootchart_count = bootchart_init();    if (bootchart_count < 0) {        ERROR("bootcharting init failure\n");    } else if (bootchart_count > 0) {        NOTICE("bootcharting started (period=%d ms)\n", bootchart_count*BOOTCHART_POLLING_MS);    } else {        NOTICE("bootcharting ignored\n");    }#endif   /* 进入服务循环。 等待device|property set|child process exit事件并执行相应处理。 */      for(;;) {        int nr, i, timeout = -1;        for (i = 0; i < fd_count; i++)            ufds[i].revents = 0;        drain_action_queue();        /* 检测是否存在需要重新启动的服务,如果有则检测距离上次启动是否大于5秒,如果大于5秒就重新启动,否则置process_needs_restart */          restart_processes();        /* 计算下一步poll等待时间 */        if (process_needs_restart) {            timeout = (process_needs_restart - gettime()) * 1000;            if (timeout < 0)                timeout = 0;        }#if BOOTCHART        if (bootchart_count > 0) {            if (timeout < 0 || timeout > BOOTCHART_POLLING_MS)                timeout = BOOTCHART_POLLING_MS;            if (bootchart_step() < 0 || --bootchart_count == 0) {                bootchart_finish();                bootchart_count = 0;            }        }#endif        nr = poll(ufds, fd_count, timeout);        if (nr <= 0)            continue;        if (ufds[2].revents == POLLIN) {            /* we got a SIGCHLD - reap and restart as needed */            read(signal_recv_fd, tmp, sizeof(tmp));            //处理子进程死掉,如果死了的子进程是个服务,在这里面释放资源并置好service list中相关service的状态以便restart            while (!wait_for_one_process(0))                ;            continue;        }        if (ufds[0].revents == POLLIN)            //处理设备事件            handle_device_fd(device_fd);        if (ufds[1].revents == POLLIN)            //处理property set事件,设置属性,并判断是否有可触发的Action,若有则执行            handle_property_set_fd(property_set_fd);        if (ufds[3].revents == POLLIN)            handle_keychord(keychord_fd);    }    return 0;}

流程图

流程图如下:

上图源文件为xmind格式文件,使用xMind打开

文件:Init main.xmind.zip

实例

init.rc

on initsysclktz 0loglevel 3# setup the global environment    export PATH /sbin:/system/sbin:/system/bin:/system/xbin    export LD_LIBRARY_PATH /system/lib    export ANDROID_BOOTLOGO 1    export ANDROID_ROOT /system    export ANDROID_ASSETS /system/app    export ANDROID_DATA /data    export EXTERNAL_STORAGE /mnt/sdcard    export ASEC_MOUNTPOINT /mnt/asec    export BOOTCLASSPATH /system/framework/core.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar# Backward compatibility    symlink /system/etc /etc    symlink /sys/kernel/debug /d# create mountpoints    mkdir /mnt 0775 root system    mkdir /mnt/sdcard 0000 system system# Create cgroup mount point for cpu accounting    mkdir /acct    mount cgroup none /acct cpuacct    mkdir /acct/uid# Backwards Compat - XXX: Going away in G*    symlink /mnt/sdcard /sdcard    mkdir /system    mkdir /data 0771 system system    mkdir /cache 0770 system cache    mkdir /config 0500 root root    # Directory for putting things only root should see.    mkdir /mnt/secure 0700 root root    # Directory for staging bindmounts    mkdir /mnt/secure/staging 0700 root root    # Directory-target for where the secure container    # imagefile directory will be bind-mounted    mkdir /mnt/secure/asec  0700 root root    # Secure container public mount points.    mkdir /mnt/asec  0700 root system    mount tmpfs tmpfs /mnt/asec mode=0755,gid=1000    mount rootfs rootfs / ro remount    write /proc/sys/kernel/panic_on_oops 1    write /proc/sys/kernel/hung_task_timeout_secs 0    write /proc/cpu/alignment 4    write /proc/sys/kernel/sched_latency_ns 10000000    write /proc/sys/kernel/sched_wakeup_granularity_ns 2000000    write /proc/sys/kernel/sched_compat_yield 1    write /proc/sys/kernel/sched_child_runs_first 0# Create cgroup mount points for process groups    mkdir /dev/cpuctl    mount cgroup none /dev/cpuctl cpu    chown system system /dev/cpuctl    chown system system /dev/cpuctl/tasks    chmod 0777 /dev/cpuctl/tasks    write /dev/cpuctl/cpu.shares 1024    mkdir /dev/cpuctl/fg_boost    chown system system /dev/cpuctl/fg_boost/tasks    chmod 0777 /dev/cpuctl/fg_boost/tasks    write /dev/cpuctl/fg_boost/cpu.shares 1024    mkdir /dev/cpuctl/bg_non_interactive    chown system system /dev/cpuctl/bg_non_interactive/tasks    chmod 0777 /dev/cpuctl/bg_non_interactive/tasks    # 5.0 %    write /dev/cpuctl/bg_non_interactive/cpu.shares 52# mount mtd partitions    # Mount /system rw first to give the filesystem a chance to save a checkpoint    mount yaffs2 mtd@system /system    mount yaffs2 mtd@system /system ro remount    # We chown/chmod /data again so because mount is run as root + defaults    mount yaffs2 mtd@userdata /data nosuid nodev    chown system system /data    chmod 0771 /data    # Create dump dir and collect dumps.    # Do this before we mount cache so eventually we can use cache for    # storing dumps on platforms which do not have a dedicated dump partition.       mkdir /data/dontpanic    chown root log /data/dontpanic    chmod 0750 /data/dontpanic    # Collect apanic data, free resources and re-arm trigger    copy /proc/apanic_console /data/dontpanic/apanic_console    chown root log /data/dontpanic/apanic_console    chmod 0640 /data/dontpanic/apanic_console    copy /proc/apanic_threads /data/dontpanic/apanic_threads    chown root log /data/dontpanic/apanic_threads    chmod 0640 /data/dontpanic/apanic_threads    write /proc/apanic_console 1    # Same reason as /data above    mount yaffs2 mtd@cache /cache nosuid nodev    chown system cache /cache    chmod 0770 /cache    # This may have been created by the recovery system with odd permissions    chown system cache /cache/recovery    chmod 0770 /cache/recovery    #change permissions on vmallocinfo so we can grab it from bugreports    chown root log /proc/vmallocinfo    chmod 0440 /proc/vmallocinfo    #change permissions on kmsg & sysrq-trigger so bugreports can grab kthread stacks    chown root system /proc/kmsg    chmod 0440 /proc/kmsg    chown root system /proc/sysrq-trigger    chmod 0220 /proc/sysrq-trigger# create basic filesystem structure    mkdir /data/misc 01771 system misc    mkdir /data/misc/bluetoothd 0770 bluetooth bluetooth    mkdir /data/misc/bluetooth 0770 system system    mkdir /data/misc/keystore 0700 keystore keystore    mkdir /data/misc/vpn 0770 system system    mkdir /data/misc/systemkeys 0700 system system    mkdir /data/misc/vpn/profiles 0770 system system    # give system access to wpa_supplicant.conf for backup and restore    mkdir /data/misc/wifi 0770 wifi wifi    chmod 0770 /data/misc/wifi    chmod 0660 /data/misc/wifi/wpa_supplicant.conf    mkdir /data/local 0771 shell shell    mkdir /data/local/tmp 0771 shell shell    mkdir /data/data 0771 system system    mkdir /data/app-private 0771 system system    mkdir /data/app 0771 system system    mkdir /data/property 0700 root root    # create dalvik-cache and double-check the perms    mkdir /data/dalvik-cache 0771 system system    chown system system /data/dalvik-cache    chmod 0771 /data/dalvik-cache    # create the lost+found directories, so as to enforce our permissions    mkdir /data/lost+found 0770    mkdir /cache/lost+found 0770    # double check the perms, in case lost+found already exists, and set owner    chown root root /data/lost+found    chmod 0770 /data/lost+found    chown root root /cache/lost+found    chmod 0770 /cache/lost+foundon boot# basic network init    ifup lo    hostname localhost    domainname localdomain# set RLIMIT_NICE to allow priorities from 19 to -20    setrlimit 13 40 40# Define the oom_adj values for the classes of processes that can be# killed by the kernel.  These are used in ActivityManagerService.    setprop ro.FOREGROUND_APP_ADJ 0    setprop ro.VISIBLE_APP_ADJ 1    setprop ro.SECONDARY_SERVER_ADJ 2    setprop ro.BACKUP_APP_ADJ 2    setprop ro.HOME_APP_ADJ 4    setprop ro.HIDDEN_APP_MIN_ADJ 7    setprop ro.CONTENT_PROVIDER_ADJ 14    setprop ro.EMPTY_APP_ADJ 15# Define the memory thresholds at which the above process classes will# be killed.  These numbers are in pages (4k).    setprop ro.FOREGROUND_APP_MEM 1536    setprop ro.VISIBLE_APP_MEM 2048    setprop ro.SECONDARY_SERVER_MEM 4096    setprop ro.BACKUP_APP_MEM 4096    setprop ro.HOME_APP_MEM 4096    setprop ro.HIDDEN_APP_MEM 5120    setprop ro.CONTENT_PROVIDER_MEM 5632    setprop ro.EMPTY_APP_MEM 6144# Write value must be consistent with the above properties.# Note that the driver only supports 6 slots, so we have HOME_APP at the# same memory level as services.    write /sys/module/lowmemorykiller/parameters/adj 0,1,2,7,14,15    write /proc/sys/vm/overcommit_memory 1    write /proc/sys/vm/min_free_order_shift 4    write /sys/module/lowmemorykiller/parameters/minfree 1536,2048,4096,5120,5632,6144    # Set init its forked children's oom_adj.    write /proc/1/oom_adj -16    # Tweak background writeout    write /proc/sys/vm/dirty_expire_centisecs 200    write /proc/sys/vm/dirty_background_ratio  5    # Permissions for System Server and daemons.    chown radio system /sys/android_power/state    chown radio system /sys/android_power/request_state    chown radio system /sys/android_power/acquire_full_wake_lock    chown radio system /sys/android_power/acquire_partial_wake_lock    chown radio system /sys/android_power/release_wake_lock    chown radio system /sys/power/state    chown radio system /sys/power/wake_lock    chown radio system /sys/power/wake_unlock    chmod 0660 /sys/power/state    chmod 0660 /sys/power/wake_lock    chmod 0660 /sys/power/wake_unlock    chown system system /sys/class/timed_output/vibrator/enable    chown system system /sys/class/leds/keyboard-backlight/brightness    chown system system /sys/class/leds/lcd-backlight/brightness    chown system system /sys/class/leds/button-backlight/brightness    chown system system /sys/class/leds/jogball-backlight/brightness    chown system system /sys/class/leds/red/brightness    chown system system /sys/class/leds/green/brightness    chown system system /sys/class/leds/blue/brightness    chown system system /sys/class/leds/red/device/grpfreq    chown system system /sys/class/leds/red/device/grppwm    chown system system /sys/class/leds/red/device/blink    chown system system /sys/class/leds/red/brightness    chown system system /sys/class/leds/green/brightness    chown system system /sys/class/leds/blue/brightness    chown system system /sys/class/leds/red/device/grpfreq    chown system system /sys/class/leds/red/device/grppwm    chown system system /sys/class/leds/red/device/blink    chown system system /sys/class/timed_output/vibrator/enable    chown system system /sys/module/sco/parameters/disable_esco    chown system system /sys/kernel/ipv4/tcp_wmem_min    chown system system /sys/kernel/ipv4/tcp_wmem_def    chown system system /sys/kernel/ipv4/tcp_wmem_max    chown system system /sys/kernel/ipv4/tcp_rmem_min    chown system system /sys/kernel/ipv4/tcp_rmem_def    chown system system /sys/kernel/ipv4/tcp_rmem_max    chown root radio /proc/cmdline# Define TCP buffer sizes for various networks#   ReadMin, ReadInitial, ReadMax, WriteMin, WriteInitial, WriteMax,    setprop net.tcp.buffersize.default 4096,87380,110208,4096,16384,110208    setprop net.tcp.buffersize.wifi    4095,87380,110208,4096,16384,110208    setprop net.tcp.buffersize.umts    4094,87380,110208,4096,16384,110208    setprop net.tcp.buffersize.edge    4093,26280,35040,4096,16384,35040    setprop net.tcp.buffersize.gprs    4092,8760,11680,4096,8760,11680    class_start default## Daemon processes to be run by init.##service console /system/bin/sh    console# adbd is controlled by the persist.service.adb.enable system propertyservice adbd /sbin/adbd    disabled# adbd on at boot in emulatoron property:ro.kernel.qemu=1    start adbdon property:persist.service.adb.enable=1    start adbdon property:persist.service.adb.enable=0    stop adbdservice servicemanager /system/bin/servicemanager    user system    critical    onrestart restart zygote    onrestart restart mediaservice vold /system/bin/vold    socket vold stream 0660 root mount    ioprio be 2service netd /system/bin/netd    socket netd stream 0660 root systemservice debuggerd /system/bin/debuggerdservice ril-daemon /system/bin/rild    socket rild stream 660 root radio    socket rild-debug stream 660 radio system    user root    group radio cache inet misc audioservice zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server    socket zygote stream 666    onrestart write /sys/android_power/request_state wake    onrestart write /sys/power/state on    onrestart restart mediaservice media /system/bin/mediaserver    user media    group system audio camera graphics inet net_bt net_bt_admin net_raw    ioprio rt 4service bootanim /system/bin/bootanimation    user graphics    group graphics    disabled    oneshotservice dbus /system/bin/dbus-daemon --system --nofork    socket dbus stream 660 bluetooth bluetooth    user bluetooth    group bluetooth net_bt_adminservice bluetoothd /system/bin/bluetoothd -n    socket bluetooth stream 660 bluetooth bluetooth    socket dbus_bluetooth stream 660 bluetooth bluetooth    # init.rc does not yet support applying capabilities, so run as root and    # let bluetoothd drop uid to bluetooth with the right linux capabilities    group bluetooth net_bt_admin misc    disabledservice hfag /system/bin/sdptool add --channel=10 HFAG    user bluetooth    group bluetooth net_bt_admin    disabled    oneshotservice hsag /system/bin/sdptool add --channel=11 HSAG    user bluetooth    group bluetooth net_bt_admin    disabled    oneshotservice opush /system/bin/sdptool add --channel=12 OPUSH    user bluetooth    group bluetooth net_bt_admin    disabled    oneshotservice pbap /system/bin/sdptool add --channel=19 PBAP    user bluetooth    group bluetooth net_bt_admin    disabled    oneshotservice installd /system/bin/installd    socket installd stream 600 system systemservice flash_recovery /system/etc/install-recovery.sh    oneshotservice racoon /system/bin/racoon    socket racoon stream 600 system system    # racoon will setuid to vpn after getting necessary resources.    group net_admin    disabled    oneshotservice mtpd /system/bin/mtpd    socket mtpd stream 600 system system    user vpn    group vpn net_admin net_raw    disabled    oneshotservice keystore /system/bin/keystore /data/misc/keystore    user keystore    group keystore    socket keystore stream 666service dumpstate /system/bin/dumpstate -s    socket dumpstate stream 0660 shell log    disabled    oneshot

init.goldfish.rc

on boot    setprop ARGH ARGH    setprop net.eth0.dns1 10.0.2.3    setprop net.gprs.local-ip 10.0.2.15    setprop ro.radio.use-ppp no    setprop ro.build.product generic    setprop ro.product.device generic# fake some battery state    setprop status.battery.state Slow    setprop status.battery.level 5    setprop status.battery.level_raw  50    setprop status.battery.level_scale 9# disable some daemons the emulator doesn't want    stop dund    stop akmd    setprop ro.setupwizard.mode EMULATOR# enable Google-specific location features,# like NetworkLocationProvider and LocationCollector    setprop ro.com.google.locationfeatures 1# For the emulator, which bypasses Setup Wizard, you can specify# account info for the device via these two properties.  Google# Login Service will insert these accounts into the database when# it is created (ie, after a data wipe).##   setprop ro.config.hosted_account username@hosteddomain.org:password#   setprop ro.config.google_account username@gmail.com:password## You MUST have a Google account on the device, and you MAY# additionally have a hosted account.  No other configuration is# supported, and arbitrary breakage may result if you specify# something else.service goldfish-setup /system/etc/init.goldfish.sh    oneshotservice qemud /system/bin/qemud    socket qemud    stream 666    oneshot# -Q is a special logcat option that forces the# program to check wether it runs on the emulator# if it does, it redirects its output to the device# named by the androidboot.console kernel option# if not, is simply exit immediatelyservice goldfish-logcat /system/bin/logcat -Q    oneshot

参考文章

http://blog.csdn.net/AndyTsui/archive/2011/02/27/6211065.aspx
http://blog.csdn.net/u0fly/archive/2010/10/27/5968754.aspx
http://www.cnblogs.com/cnhome/archive/2010/05/14/1735054.html
http://blog.csdn.net/freshui/archive/2010/07/20/5747199.aspx
http://blog.csdn.net/dadahacker/archive/2011/04/18/6331294.aspx

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Android启动脚本init.rc--中国移动开发者社区
android init.rc 语法分析
深入浅出
android的init.rc文件的语法-一天一点一滴-搜狐博客
Android中init.rc文件的解析
Android init.rc文件详细分析
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服