zygote 之前的 android init关键点

来源:互联网 发布:铅弹在淘宝怎么淘 编辑:程序博客网 时间:2024/04/29 19:46

system/core/init/init.c    main()开始:


property service , 

对应的property 储存到nand flash上, 启动时需要先mount, 对应的设备节点:/dev/__properties__ 


init时property_init()会把此设备节点打开, 并以可读可写和共享的方式mmap到memory中后使用:__system_property_area__。


init rc里主要有三类:
service:  以service开头的section, parse后会分别放到service_list (双向链表)中
        /* list of all services */
    struct listnode slist;




action: 以on开头的section  ,parse后会分别放到action_list(双向链表)中。
        /* node in list of all actions */
    struct listnode alist;
        /* node in the queue of pending actions */
    struct listnode qlist;
        /* node in list of actions for a trigger */
    struct listnode tlist;
 
import: 以import开头的section, 主要用于把另外 文件中的内容导入进来,方便模块化管理
         把对应文件内容读出来后继续service/action/import的流程parse。
 
 
action_for_each_trigger  :执行对应 的action。
action_add_queue_tail: 把对应的act放到 action_queue等待执行。


init.rc里的执行顺序 :
early-init -->[init.rc之外的...console_init]-->init-->early-fs-->fs-->post-fs-->post-fs-data-->[.property_service_init..signal_init...]-->early-boot-->boot-->[所有on property:***]
console_init_action:
load_565rle_image  显示/initlogo.rle 如果没有就显示文字ANDROID。
signal_init:
监听到子进程退出消息:handle_signal--》wait_for_one_process
INFO("waitpid returned pid %d, status = %08x\n", pid, status);
ERROR("untracked pid %d exited\n", pid);
NOTICE("process '%s', pid %d exited\n", svc->name, pid);
property_service_init:
load_properties_from_file |
property 位置:           <--| 
#define PROP_PATH_RAMDISK_DEFAULT  "/default.prop"
#define PROP_PATH_SYSTEM_BUILD     "/system/build.prop"
#define PROP_PATH_SYSTEM_DEFAULT   "/system/default.prop"
#define PROP_PATH_LOCAL_OVERRIDE   "/data/local.prop"
#define PROP_PATH_FACTORY          "/factory/factory.prop"

#define PERSISTENT_PROPERTY_DIR  "/data/property"

创建一个socket名字为property_service,并listen client端的请求,-->property_set_fd
property_set时,则会建一个socket作为client跟property_service进行发消息,接着在下面的for循环中accept socket进行处理: handle_property_set_fd()进行处理。

 
FOR: 循环执行action 和service:
        execute_one_command();  -->action :action_list
        restart_processes(); --> service:service_list 
service_start()-->execve()-->更新service状态(init.svc....[RUNNING/STOP/...])


获取文件id,(property/signal,keychord),poll这几个fd是否需要处理:
handle_property_set_fd()
handle_signal()
handle_keychord()



Zygote启动: 当所有的service按照init.rc里的顺序启动就会起来(带disable 选项的则不会启动。)
所以接下来就会进入android的第一个进程Zygote。

system/core/init/Keywords.h 里定义了对应的关键字跟具体函数的关系。
    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(class_reset, COMMAND, 1, do_class_reset)
    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,      SECTION, 1, 0)
    KEYWORD(keycodes,    OPTION,  0, 0)
    KEYWORD(mkdir,       COMMAND, 1, do_mkdir)
    KEYWORD(mount_all,   COMMAND, 1, do_mount_all)
    KEYWORD(mount,       COMMAND, 3, do_mount)
    KEYWORD(on,          SECTION, 0, 0)
    KEYWORD(oneshot,     OPTION,  0, 0)
    KEYWORD(onrestart,   OPTION,  0, 0)
    KEYWORD(powerctl,    COMMAND, 1, do_powerctl)
    KEYWORD(restart,     COMMAND, 1, do_restart)
    KEYWORD(restorecon,  COMMAND, 1, do_restorecon)
    KEYWORD(rm,          COMMAND, 1, do_rm)
    KEYWORD(rmdir,       COMMAND, 1, do_rmdir)
    KEYWORD(seclabel,    OPTION,  0, 0)
    KEYWORD(service,     SECTION, 0, 0)
    KEYWORD(setcon,      COMMAND, 1, do_setcon)
    KEYWORD(setenforce,  COMMAND, 1, do_setenforce)
    KEYWORD(setenv,      OPTION,  2, 0)
    KEYWORD(setkey,      COMMAND, 0, do_setkey)
    KEYWORD(setprop,     COMMAND, 2, do_setprop)
    KEYWORD(setrlimit,   COMMAND, 3, do_setrlimit)
    KEYWORD(setsebool,   COMMAND, 2, do_setsebool)
    KEYWORD(socket,      OPTION,  0, 0)
    KEYWORD(start,       COMMAND, 1, do_start)
    KEYWORD(stop,        COMMAND, 1, do_stop)
    KEYWORD(swapon_all,  COMMAND, 1, do_swapon_all)
    KEYWORD(trigger,     COMMAND, 1, do_trigger)
    KEYWORD(symlink,     COMMAND, 1, do_symlink)
    KEYWORD(sysclktz,    COMMAND, 1, do_sysclktz)
    KEYWORD(user,        OPTION,  0, 0)
    KEYWORD(wait,        COMMAND, 1, do_wait)
    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(load_persist_props,    COMMAND, 0, do_load_persist_props)
    KEYWORD(ioprio,      OPTION,  0, 0)
 
property在存储的方式如下;
typedef struct prop_info prop_info;
/*
 * Properties are stored in a hybrid trie/binary tree structure.
 * Each property's name is delimited at '.' characters, and the tokens are put
 * into a trie structure.  Siblings at each level of the trie are stored in a
 * binary tree.  For instance, "ro.secure"="1" could be stored as follows:
 *
 * +-----+   children    +----+   children    +--------+
 * |     |-------------->| ro |-------------->| secure |
 * +-----+               +----+               +--------+
 *                       /    \                /   |
 *                 left /      \ right   left /    |  prop   +===========+
 *                     v        v            v     +-------->| ro.secure |
 *                  +-----+   +-----+     +-----+            +-----------+
 *                  | net |   | sys |     | com |            |     1     |
 *                  +-----+   +-----+     +-----+            +===========+
 */


 最后对memory __system_property_area__里的的查找更新细节暂时还没搞懂。
 可以先参考 http://www.tuicool.com/articles/3eiqim
 
0 0