zygote 之前的 android init關鍵點

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
 
發佈了25 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章