The init process is the first executable program that the system performs after Android startup, called Init.
Function:
- Device Management
- Parsing the startup script init.rc
- Perform basic functions in a startup script
- Perform various services in the startup script
Code path: System/core/init
Compile the result to generate an executable file: Init
1.main{}
int main (int argc, char **argv)
{
int device_fd =-1;
int property_set_fd =-1;
int signal_recv_fd =-1;
int keychord_fd =-1;
int fd_count;
int s[2];
int FD;
struct Sigaction Act;
Char Tmp[prop_value_max];
struct POLLFD ufds[4];
Char *tmpdev;
char* debuggable;
Act.sa_handler = Sigchld_handler;
Act.sa_flags = Sa_nocldstop;
Act.sa_mask = 0;
Act.sa_restorer = NULL;
Sigaction (SIGCHLD, &act, 0);
Umask (0);
mkdir ("/dev", 0755); //Create a basic directory of file systems
mkdir ("/proc", 0755);
mkdir ("/sys", 0755);
mount ("Tmpfs", "/dev", "Tmpfs", 0, "mode=0755");
mkdir ("/dev/pts", 0755);
mkdir ("/dev/socket", 0755);
mount ("devpts", "/dev/pts", "Devpts", 0, NULL);
mount ("proc", "/proc", "Proc", 0, NULL);
mount ("Sysfs", "/sys", "Sysfs", 0, NULL);
Open_devnull_stdio (); //Open 3 files: input, input, error
Log_init (); //Initialize Log
INFO ("reading config file\n");
Parse_config_file ("/init.rc"); //Process initialization script, get kernel command line parameters
Qemu_init ();
Import_kernel_cmdline (0); //Initialize drive device, create file system node
Get_hardware_name ();
snprintf (TMP, sizeof (TMP), "/init.%s.rc", hardware);
Parse_config_file (TMP);
Action_for_each_trigger ("Early-init", Action_add_queue_tail);
Drain_action_queue ();
INFO ("Device init\n");
DEVICE_FD = Device_init (); //attribute related processing and start logo
if (emmc_boot) {
Action_for_each_trigger ("eMMC", Action_add_queue_tail);
Drain_action_queue ();
}else{
Action_for_each_trigger ("NAND", action_add_queue_tail);
Drain_action_queue ();
}
Property_init ();
Only listen to Keychords if Ro.debuggable is true
KEYCHORD_FD = Open_keychord ();
if (Console[0]) {
snprintf (TMP, sizeof (TMP), "/dev/%s", console);
Console_name = StrDup (TMP);
}
FD = open (Console_name, O_RDWR);
if (FD >= 0)
Have_console = 1;
Close (FD);
if (Load_565rle_image (init_image_file)) {//
FD = open ("/dev/tty0", o_wronly);
if (FD >= 0) {
const char *msg;
msg = "\ n"
"\ n"
"\ n"
"\ n"
"\ n"
"\ n"
"\ n"//console is cols x lines
"\ n"
"\ n"
"\ n"
"\ n"
"\ n"
"\ n"
"\ n"
"A N D R O I D";
Write (FD, MSG, strlen (msg));
Close (FD);
}
}
if (Qemu[0])
Import_kernel_cmdline (1);
if (!strcmp (Bootmode, "Factory"))
Property_set ("Ro.factorytest", "1");
else if (!strcmp (Bootmode, "Factory2"))
Property_set ("Ro.factorytest", "2");
Else
Property_set ("Ro.factorytest", "0");
Property_set ("Ro.serialno", Serialno[0]? Serialno: ");
Property_set ("Ro.bootmode", Bootmode[0]? Bootmode: "Unknown");
Property_set ("Ro.baseband", baseband[0]? Baseband: "Unknown");
Property_set ("Ro.carrier", Carrier[0]? Carrier: "Unknown");
Property_set ("Ro.bootloader", Bootloader[0]? Bootloader: "Unknown");
Property_set ("Ro.hardware", hardware);
SNPRINTF (TMP, Prop_value_max, "%d", revision);
Property_set ("Ro.revision", TMP);
Property_set ("Ro.emmc", Emmc_boot?) "1": "0");
action_for_each_trigger ("Init", action _add_queue_tail);
drain_action_queue ();
{
error ("PMD processing!\n") ;
system ("/SYSTEM/BIN/PMD");
error ("PMD exit!\n");
//}
    PROPERTY_SET_FD = Start_property_service ();
if (Socketpair (Af_unix, Sock_stream, 0, s) = = 0) {
      SIGNAL_FD = S[0];
        SIGNAL_RECV_FD = s[1];
fcntl (S[0], F_SETFD, fd_cloexec);
fcntl (S[0], F_SETFL, O_nonblock);
fcntl (s[1], F_SETFD, fd_cloexec);
fcntl (s[1], F_SETFL, O_nonblock);
}
if ((device_fd < 0) | |
(PROPERTY_SET_FD < 0) | |
(SIGNAL_RECV_FD < 0)) {
ERROR ("Init startup failure\n");
return 1;
}
if (battchg_pause) {
Action_for_each_trigger ("Boot-pause", Action_add_queue_tail);
Drain_action_queue ();
}
Action_for_each_trigger ("Early-boot", Action_add_queue_tail);
Action_for_each_trigger ("Boot", action_add_queue_tail);
Drain_action_queue ();
Queue_all_property_triggers ();
Drain_action_queue ();
property_triggers_enabled = 1;
UFDS[0].FD = DEVICE_FD; //Initialize struct POLLFD ufds[4]
Ufds[0].events = Pollin;
UFDS[1].FD = PROPERTY_SET_FD;
Ufds[1].events = Pollin;
UFDS[2].FD = SIGNAL_RECV_FD;
Ufds[2].events = Pollin;
Fd_count = 3;
if (keychord_fd > 0) {
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;UFDS[3].FD = KEYCHORD_FD;
ufds[3].events = Pollin;
fd_count++;
} else {
ufds[3].events = 0;
ufds[3].revents = 0;
}
#if bootchart
bootchart_count = Bootchart_init ();
if (Bootchart_count < 0) {
error (" Bootcharting init failure\n ");
} else if (Bootchart_count > 0) {
NOTICE ("Bootcharting started (period=%d ms) \ n", Bootchart_count*bootchart_polling_ms);
} else {
notice ("bootcharting Ignored\n ");
}
#endif
for (;;) { //Enter loop, handle ufds[4] Event
int nr, I, timeout =-1;
for (i = 0; i < Fd_count; i++)
ufds[i].revents = 0;
Drain_action_queue ();
Restart_processes ();
if (Process_needs_restart) {
Timeout = (Process_needs_restart-gettime ()) * 1000;
if (Timeout < 0)
Timeout = 0;
}
#if Bootchart
if (Bootchart_count > 0) {
if (Timeout < 0 | | timeout > Bootchart_polling_ms)
Timeout = Bootchart_polling_ms;
if (Bootchart_step () < 0 | |--bootchart_count = = 0) {
Bootchart_finish ();
Bootchart_count = 0;
}
}
#endif
NR = Poll (UFDs, Fd_count, timeout);
if (NR <= 0)
Continue
if (ufds[2].revents = = Pollin) {
Read (SIGNAL_RECV_FD, TMP, sizeof (TMP));
while (!wait_for_one_process (0))
;
Continue
}
if (ufds[0].revents = = Pollin)
HANDLE_DEVICE_FD (DEVICE_FD);
if (ufds[1].revents = = Pollin)
HANDLE_PROPERTY_SET_FD (PROPERTY_SET_FD);
if (ufds[3].revents = = Pollin)
Handle_keychord (KEYCHORD_FD);
}
return 0;
}
Android--init executable Program