The init process is the first process that Android starts with a process PID of 1. It mainly does the following several things:
* Parse configuration file
* Operation according to the configuration file early_init init early_boot boot
* Set Property Service
This section explains how to parse init.rc files and run zygote.
1. Parsing the init.rc configuration file
/**init.c*/
In the main function, perform the following function:
Init_parse_config_file ("/init.rc");
/**init_parse.c*/
int init_parse_config_file (const char *FN) { char *data; data = Read_file (FN, 0); if (!data) return-1; Parse_config (FN, data); DUMP (); return 0;} static void Parse_config (const char *FN, char *s);
The Parse_config function mainly finds a section node to begin parsing if (kw_is (kw, section)) { state.parse_line (&state, 0, 0);
The kw_is function executes the keywords file and places the specified k_# #symbol
/**keywords.h*/
1> Definition enumeration. Enumeration value is K_class K_mkdir, etc.
2> defines a struct array keyword_info, changes the KEYOWRD macro to a struct, and finds the symbol and func parsing init.rc file by macro definition
If symbol for the keyword section is chdir, find the declaration of the Int do_chdir (int nargs, char **args) to see the corresponding definition
>>> keywords are: option,command,section
/**init.rc*/
On init #表示on的SECTION名称为init basic steps for Early-init init early-boot boot
#从一个section开始 end before the next section start tag
Export Android_root/system #表示export为一个COMMAND
* IF
2. Analysis Zygote
/**init.rc Config file */
In this file zygote is defined as requiring 4 operations and a service with a socket of 660, which is a child process of init.
Service Zygote/system/bin/app_process-xzygote/system/bin--zygote--start-system-server class main socket Zygote Stream 660 root system Onrestart write/sys/android_power/request_state Wake Onrestart write/sys/power/ State on onrestart Restart media onrestart Restart netd
---------------Service Definition Information------------------
-Maintain a doubly linked list of all generated service ListNode
The name of the-service name Zygote is Init.svc.zygote
-classname Default "Defaults"
-attribute flag PID UID GID io priority parameter (number)
-time_started time_crashed nr_crashed Total number of deaths at the time of last boot death
-socketinfo (Socket environment variable information) svcenvinfo (process required environment variable information)
-struct Action Onrestart; Save the command message after option
------------------------------------------------
---------------Onrestart Definition Information------------------
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;//Save restart inside the Commond action};
------------------------------------------------
/**init_parse.c*/
#主要执行parse_service and Parse_line_service
// Create service structure body main frame and add to service_list doubly linked list
//socketinfo is a one-way list zygote only a 660 TCP Scoket
//onrestart through the Commond point to a commonds linked list zygote above in init.rc can see that there are 4 Commond
static void *parse_service (struct parse_state *state, int nargs, char **args) {struct Service *svc;svc = calloc (1, sizeof (* SVC) + sizeof (char*) * Nargs); if (!svc) { parse_error (state, "out of memory\n"); return 0; } Svc->name = args[1]; Svc->classname = "Default"; memcpy (Svc->args, args + 2, sizeof (char*) * Nargs); Svc->args[nargs] = 0; Svc->nargs = Nargs; Svc->onrestart.name = "Onrestart"; List_init (&svc->onrestart.commands); List_add_tail (&service_list, &svc->slist); Return SVC;}
static void Parse_line_service (struct parse_state *state, int nargs, char **args) {struct Service *svc = state->context; nargs--; args++; KW = Lookup_keyword (Args[0]);//create commond struct cmd = malloc (sizeof (*cmd) + sizeof (char*) * Nargs); Cmd->func = kw_func (kw); Cmd->nargs = Nargs; memcpy (Cmd->args, args, sizeof (char*) * Nargs);//Added to the bidirectional list list_add_tail (&svc->onrestart.commands, &cmd->clist);}
**********init start zygote**********
1) init.c::main>
//Add the boot Commond to the execution queue
because zygote is included in the boot action
Action_for_each_trigger ("boot", action_add_queue_tail);
//Execute the Commond in the queue and perform the commond of all sections uniformly
queue_builtin_action (queue_property_triggers_action, "queue_property_triggers");
2) BULTINS.C::d o_class_start>
Because Class_start is a commond, so he's going to be executed here zygote is a "default" classname
/ /So execute service_start_if_not_disabled function
//If the service's flag is explicitly specified as disable then execution of the service must be performed separately
Service_for_each_class (args[1],
service_start_if_not_disabled);
3) BULTINS.C::
service_start_if_not_disabled>
if (! ( Svc->flags & svc_disabled)) {
Service_start (SVC, NULL);//previous setting did not create flags indicates that the service has not been enabled for execution Service_start
}
4) init.c::service_start>
>> Determine if file process
/system/bin/process file exists General Service has its own process
rc = Security_compute_create (Mycon, Fcon, String_to_security_class ("process"), &scon);
>> Start the init sub-process
pid = fork ();
>> Adding process environment variable information
>> Add the socket environment variable information and create a socket
>> set UID GID and start the main function of the/system/bin/app_process file
>> set the start time of the service PID, etc.
**********init Restart zygote**********
>> bind operation Response Events
1) init.c::main>>
queue_builtin_action (signal_init_action, "Signal_init");
2) init.c::signal_init_action>>
signal_init ();
3) signal_handler::signal_init>>
struct Sigaction act;//binds 2 methods Sigchld_handler handle_signal Its structure also includes a sa_flags flag
>>zygote Dead Parent process init call Sigchld_handler
1) signal_handler::sigchld_handler>>
Write (SIGNAL_FD, &s, 1);//writing data to SIGNAL_FD
SIGNAL_FD is one of the two sockets in Socketpair
2) init.c::main>>
nr = Poll (UFDs, Fd_count, timeout);
if (nr <= 0)
continue;
For (i = 0; i < Fd_count; i++) {
if (ufds[i].revents = = Pollin) {
else if (ufds[i].fd = = GET_SIGNAL_FD ())
handle_signal ();
}
}
3) signal_handler::handle_signal>>
Read (SIGNAL_RECV_FD, TMP, sizeof (TMP));
while (!wait_for_one_process (0));
4) Signal_handler::wait_for_one_process>>
//Kill all child processes of zygote
//Clear the scoket we are going to rebuild
//Add all Onrestart Commond (4 in zygote) to the list of action struct bodies in the SVC
//Change SVC status to restarting
5) init.c::main>>
//poll after entering the next round of loops and executing main
Execute_one_command ();//Perform all Commond
Restart_processes ();//change Flag ID
Android-init process (1)