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