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