Init进程笔记

来源:互联网 发布:深圳乐易网络双休吗 编辑:程序博客网 时间:2024/06/08 14:26
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);
}

原创粉丝点击