当前位置:操作系统 > 安卓/Android >>

android启动--深入理解init进程

init是一个进程,它是linux系统中用户空间的第一个进程,其进程PID是1,父进程为linux
系统内核的0号进程。所以其被赋予很多极其重要的职责,linux内核初始化完成后就开始执行它。


代码路径:\system\core\init\init.c


下面就分析一下先吧,只分析重点的函数功能:
int main(int argc, char **argv)

{

     // 1、设置子进程退出的信号处理函数:sigchld_handler

    act.sa_handler = sigchld_handler;
    act.sa_flags = SA_NOCLDSTOP;
    act.sa_mask = 0;
    act.sa_restorer = NULL;
    sigaction(SIGCHLD, &act, 0);

    // 2、创建文件夹,并挂载设备
    mkdir("/dev", 0755);
    mkdir("/proc", 0755);
    ....
   
    // 3、重定向标准输入输出错误到 /dev/__null__
    open_devnull_stdio();
   
    // 4、解析 init.rc 脚本
    parse_config_file("/init.rc");


     // 5、解析机器相关的配置文件,一般相关的放在init.rc中利用service action调过去
     snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
    parse_config_file(tmp);


     // 6、建立 uevent,用于与linux kernel交互的socket
     device_fd = device_init();

     // 7、初始化及加载属性相关资源,这里利用ashmem共享,属于整个系统的资源
     property_init();

     // 8、执行 on init 、early-boot 及 boot 片段动作,这些定义于 init.rc 中
     /* execute all the boot actions to get us started */
     action_for_each_trigger("init", action_add_queue_tail);
     drain_action_queue();
   
    /* execute all the boot actions to get us started */
    action_for_each_trigger("early-boot", action_add_queue_tail);
    action_for_each_trigger("boot", action_add_queue_tail);

    // 9、这里定义的init进程需要关注的四个方面事情 
    ufds[0].fd = device_fd;
    ufds[0].events = POLLIN;   // Uevent事件
    ufds[1].fd = property_set_fd;
    ufds[1].events = POLLIN;   // 属性事件
    ufds[2].fd = signal_recv_fd;
    ufds[2].events = POLLIN;   // 子进程事件
    fd_count = 3;


   ufds[3].fd = keychord_fd;
    ufds[3].events = POLLIN;  // keychord热键事件
    fd_count++;

    // ok, 下面就是init进程的处理循环
    for(;;) {
         // I、执行init.rc 脚本中的动作
         drain_action_queue();
       
         // II、执行标志为SVC_RESTARTING的进程,利用fork+execve启动新的进程
         restart_processes();

 

 // III、调用poll轮询上述的四个事件
        nr = poll(ufds, fd_count, timeout);
        if (nr <= 0)
            continue;

 

 // IV、依次处理各个事件
         if (ufds[2].revents == POLLIN) {
            /* we got a SIGCHLD - reap and restart as needed */
            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;
}


这里我们重点关注一下service的解析过程:


这里以启动 zygote 为例讲解一下:
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
    socket zygote stream 666   //创建一个stream流式套接字www.zzzyk.com
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart media


服务名称: zygote
进程路径: /system/bin/app_process
进程启动参数:-Xzygote /system/bin --zygote --start-system-server

解析入口函数:parse_new_section

void parse_new_section(struct parse_state *state, int kw,
                       int nargs, char **args)
{
    switch(kw) {
    case K_service:
        state->context = parse_service(state, nargs, args);
        if (state->context) {
            state->parse_line = parse_line_service;
            return;
        }
        break;
...
}


--> 其中所有的解析的service放在如下双链表结构中
struct service {
    /* list of all services */
    struct listnode slist;


    const char *name;
    const char *classname; //所属class名字,默认为"default"


    unsigned flags;
    pid_t pid;


    struct socketinfo *sockets;
    struct svcenvinfo *envvars;


    struct action onrestart;  /* Actions to execute on restart. */
    ...
};


static void *parse_service(struct parse_state *state, int nargs, char **args)
{
    struct service *svc;

    svc = service_find_by_name(args[1]);

    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);


    // 加入到全

补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,