init.cpp
//init进程启动的起点
int main(int argc, char** argv) {
...
umask(0);//设置文件属性0777
add_environment("PATH", _PATH_DEFPATH);
bool is_first_stage = (argc == 1) || (strcmp(argv[1], "--second-stage") != 0);
//创建文件并挂载
if (is_first_stage) {
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "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();
klog_init();//初始化kernel log,位于设备节点/dev/kmsg
klog_set_level(KLOG_NOTICE_LEVEL);//设置输出Log级别,当log级别小于5时则会输出到kernel log, 默认值为3.
//输出init启动阶段log
NOTICE("init%s started!\n", is_first_stage ? "" : " second stage");
if (!is_first_stage) {
close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
property_init();//创建一块共享内存空间,用于属性服务
//将参数设置到DT和cmdLine中,DT优先级高于cmdline
process_kernel_dt();//dt(device tree)
process_kernel_cmdline();
export_kernel_boot_props();//将核心参数设置为属性
}
//建立
//SELinux带给Linux的主要价值是:提供了一个灵活的,可配置的MAC机制。
//SELinux是一个安全体系结构,它通过LSM(Linux Security Modules)框架被集成到Linux Kernel 2.6.x中。它是NSA (United States National Security Agency)和SELinux社区的联合项目。
selinux_initialize(is_first_stage);
....
INFO("Running restorecon...\n");
restorecon("/dev");
restorecon("/dev/socket");
restorecon("/dev/__properties__");
restorecon_recursive("/sys");
epoll_fd = epoll_create1(EPOLL_CLOEXEC);
if (epoll_fd == -1) {
ERROR("epoll_create1 failed: %s\n", strerror(errno));
exit(1);
}
signal_handler_init();//初始化子进程退出的信号处理过程
property_load_boot_defaults();//加载default.prop文件
start_property_service();//启动属性服务器
init_parse_config_file("/init.rc");//解析init.rc文件
action_for_each_trigger("early-init", action_add_queue_tail);//执行rc文件中触发器为on early-init的语句
queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");
queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
queue_builtin_action(keychord_init_action, "keychord_init");//设置组合键的初始化操作
queue_builtin_action(console_init_action, "console_init");//在屏幕上显示android的静态LOGO,执行console_init_action函数
action_for_each_trigger("init", action_add_queue_tail);//执行rc文件中触发器为on init的语句
queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
char bootmode[PROP_VALUE_MAX];
//当处于充电模式,将charger加入执行队列,
if (property_get("ro.bootmode", bootmode) > 0 && strcmp(bootmode, "charger") == 0) {
action_for_each_trigger("charger", action_add_queue_tail);
} else if (strncmp(bootmode, "ffbm", 4) == 0) {
KLOG_ERROR("Booting into ffbm mode\n");
action_for_each_trigger("ffbm", action_add_queue_tail);
} else {
//执行rc文件中触发器为on late-init的语句
action_for_each_trigger("late-init", action_add_queue_tail);
}
queue_builtin_action(queue_property_triggers_action, "queue_property_triggers");
while (true) {
if (!waiting_for_exec) {
execute_one_command();
//
restart_processes();//检查service_list中的所有服务,对于带有SVC_RESTARTING标志的服务,则都会调用其相应的restart_service_if_needed。
}
int timeout = -1;
if (process_needs_restart) {
timeout = (process_needs_restart - gettime()) * 1000;
if (timeout < 0)
timeout = 0;
}
if (!action_queue_empty() || cur_action) {
timeout = 0;
}
bootchart_sample(&timeout);
epoll_event ev;
//循环等待事件的发生
int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, timeout));
if (nr == -1) {
ERROR("epoll_wait failed: %s\n", strerror(errno));
} else if (nr == 1) {
((void (*)()) ev.data.ptr)();
}
}
return 0;
}
//信号处理,signal_handler.cpp
void signal_handler_init() {
// 创建信号SINGAL的机制
int s[2];
//调用一对已连接好的socket
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0, s) == -1) {
ERROR("socketpair failed: %s\n", strerror(errno));
exit(1);
}
signal_write_fd = s[0];
signal_read_fd = s[1];
// 当捕获SINGLE时,则写入single_write_fd
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = SIGCHLD_handler;//调用SINGLE_handler函数,不断向signal_write_fd写入1,直到成功为止
//SA_NOCLDSTOP是init进程在其子进程终止时才会收到SINGLE信号
act.sa_flags = SA_NOCLDSTOP;
//init进程调用信号安装函数,传递参数给sigaction结构体
sigaction(SIGCHLD, &act, 0);
reap_any_outstanding_children();
//handle_single,调用handle_single函数,从single_read_fd中读取数据,放入buf
//调用register_epoll_handler注册epoll句柄
register_epoll_handler(signal_read_fd, handle_signal);
}
//init进程启动的起点
int main(int argc, char** argv) {
...
umask(0);//设置文件属性0777
add_environment("PATH", _PATH_DEFPATH);
bool is_first_stage = (argc == 1) || (strcmp(argv[1], "--second-stage") != 0);
//创建文件并挂载
if (is_first_stage) {
mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "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();
klog_init();//初始化kernel log,位于设备节点/dev/kmsg
klog_set_level(KLOG_NOTICE_LEVEL);//设置输出Log级别,当log级别小于5时则会输出到kernel log, 默认值为3.
//输出init启动阶段log
NOTICE("init%s started!\n", is_first_stage ? "" : " second stage");
if (!is_first_stage) {
close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
property_init();//创建一块共享内存空间,用于属性服务
//将参数设置到DT和cmdLine中,DT优先级高于cmdline
process_kernel_dt();//dt(device tree)
process_kernel_cmdline();
export_kernel_boot_props();//将核心参数设置为属性
}
//建立
//SELinux带给Linux的主要价值是:提供了一个灵活的,可配置的MAC机制。
//SELinux是一个安全体系结构,它通过LSM(Linux Security Modules)框架被集成到Linux Kernel 2.6.x中。它是NSA (United States National Security Agency)和SELinux社区的联合项目。
selinux_initialize(is_first_stage);
....
INFO("Running restorecon...\n");
restorecon("/dev");
restorecon("/dev/socket");
restorecon("/dev/__properties__");
restorecon_recursive("/sys");
epoll_fd = epoll_create1(EPOLL_CLOEXEC);
if (epoll_fd == -1) {
ERROR("epoll_create1 failed: %s\n", strerror(errno));
exit(1);
}
signal_handler_init();//初始化子进程退出的信号处理过程
property_load_boot_defaults();//加载default.prop文件
start_property_service();//启动属性服务器
init_parse_config_file("/init.rc");//解析init.rc文件
action_for_each_trigger("early-init", action_add_queue_tail);//执行rc文件中触发器为on early-init的语句
queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");
queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
queue_builtin_action(keychord_init_action, "keychord_init");//设置组合键的初始化操作
queue_builtin_action(console_init_action, "console_init");//在屏幕上显示android的静态LOGO,执行console_init_action函数
action_for_each_trigger("init", action_add_queue_tail);//执行rc文件中触发器为on init的语句
queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
char bootmode[PROP_VALUE_MAX];
//当处于充电模式,将charger加入执行队列,
if (property_get("ro.bootmode", bootmode) > 0 && strcmp(bootmode, "charger") == 0) {
action_for_each_trigger("charger", action_add_queue_tail);
} else if (strncmp(bootmode, "ffbm", 4) == 0) {
KLOG_ERROR("Booting into ffbm mode\n");
action_for_each_trigger("ffbm", action_add_queue_tail);
} else {
//执行rc文件中触发器为on late-init的语句
action_for_each_trigger("late-init", action_add_queue_tail);
}
queue_builtin_action(queue_property_triggers_action, "queue_property_triggers");
while (true) {
if (!waiting_for_exec) {
execute_one_command();
//
restart_processes();//检查service_list中的所有服务,对于带有SVC_RESTARTING标志的服务,则都会调用其相应的restart_service_if_needed。
}
int timeout = -1;
if (process_needs_restart) {
timeout = (process_needs_restart - gettime()) * 1000;
if (timeout < 0)
timeout = 0;
}
if (!action_queue_empty() || cur_action) {
timeout = 0;
}
bootchart_sample(&timeout);
epoll_event ev;
//循环等待事件的发生
int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, timeout));
if (nr == -1) {
ERROR("epoll_wait failed: %s\n", strerror(errno));
} else if (nr == 1) {
((void (*)()) ev.data.ptr)();
}
}
return 0;
}
//信号处理,signal_handler.cpp
void signal_handler_init() {
// 创建信号SINGAL的机制
int s[2];
//调用一对已连接好的socket
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0, s) == -1) {
ERROR("socketpair failed: %s\n", strerror(errno));
exit(1);
}
signal_write_fd = s[0];
signal_read_fd = s[1];
// 当捕获SINGLE时,则写入single_write_fd
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = SIGCHLD_handler;//调用SINGLE_handler函数,不断向signal_write_fd写入1,直到成功为止
//SA_NOCLDSTOP是init进程在其子进程终止时才会收到SINGLE信号
act.sa_flags = SA_NOCLDSTOP;
//init进程调用信号安装函数,传递参数给sigaction结构体
sigaction(SIGCHLD, &act, 0);
reap_any_outstanding_children();
//handle_single,调用handle_single函数,从single_read_fd中读取数据,放入buf
//调用register_epoll_handler注册epoll句柄
register_epoll_handler(signal_read_fd, handle_signal);
}