Android初始化的文件在system/core/init/init.c中
具体执行过程为
1、定义相关变量
2、判断是init进程启动,还是uevented进程启动,或是watchdogd进程启动
3、umask(0); // clear the umask
4、创建相关设备节点
5、open_devnull_stdio(); 观察函数内部,实际上是把标准输出、标准错误输出都定向到/dev/__null__节点上
6、klog_init(); 初始化内核日志
7、property_init(); 初始化系统属性。相当于在内存中初始化一块共享内存区域,用来存储系统属性,方便其他进程在执行过程中读取。调用函数__system_property_area_init()实现
8、get_hardware_name(hardware, &revision);
9、process_kernel_cmdline(); 还没有具体研究
10、init_parse_config_file("/init.rc"); 解析init.rc脚本,把脚本分为三个部分,action,service,import
action结构体为
struct action {
/* 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;
unsigned hash;
const char *name;
struct listnode commands;
struct command *current;
};
commands用来链接很多command结构体,也就是说,一个action中,含有很多个command。
alist,用来链接action_list,action_list包含了所有从init.rc中解析出来的结构体。
qlist用来链接action_queue,后面会讲到
struct command
{
/* list of commands in an action */
struct listnode clist;
int (*func)(int nargs, char **args);
int nargs;
char *args[1];
};
command结构体中func指定的函数决定了这个command具体做什么动作,nargs,args是两个参数,传给func
struct service {
/* list of all services */
struct listnode slist;
const char *name;
const char *classname;
unsigned flags;
pid_t pid;
time_t time_started; /* time of last start */
time_t time_crashed; /* first crash within inspection window */
int nr_crashed; /* number of times crashed within window */
uid_t uid;
gid_t gid;
gid_t supp_gids[NR_SVC_SUPP_GIDS];
size_t nr_supp_gids;
char *seclabel;
struct socketinfo *sockets;
struct svcenvinfo *envvars;
struct action onrestart; /* Actions to execute on restart. */
/* keycodes for triggering this service via /dev/keychord */
int *keycodes;
int nkeycodes;
int keychord_id;
int ioprio_class;
int ioprio_pri;
int nargs;
/* "MUST BE AT THE END OF THE STRUCT" */
char *args[1];
}; /* ^-------'args' MUST be at the end of this struct! */
所有从init.rc中解析出来的service都用slist链接到service_list中。service结构体中其他变量代表了service的option选项
综上所述,一个action_list包含了所有的从init.rc中解析出来的action,每一个action包含了多个command,每个command有自己的func函数和参数。一个service_list包含了所有从init.rc解析出来的service,每个service包含了自己的很多选项。
11、action_for_each_trigger("early-init", action_add_queue_tail); 在action_list 中寻找trigger为“early-init”的action,找到后,放入action_queue中去
queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done"); 把自定义的action,放入action_queue中去
12、for(;;) 最后的for循环式死循环,说明init一直在执行
execute_one_command(); action_queue是所有需要执行的action的集合,每次循环到函数execute_one_command时,就从action_queue中取出一个需要执行的command去执行。直到所有的action中的command都被执行完。
当执行到class_start这个command时,会从service_list中取出service来执行。注意:如果service的option选项为disable,则不执行
init进程会循环在这里,等待有任何触发条件的发生,从而采取相关动作,由poll函数承担监控角色。