添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

一.架构概述

长按电源启动机器手机CPU第一条指令会指向操作系统所在位置,BootLoader (系统启动加载器),用以初始化硬件设备,建立内存空间的映像图,为最终调用系统内核准备好环境。 在 Android 里没有硬盘,而是 ROM,它类似于硬盘存放操作系统,用户程序等。 ROM 跟硬盘一样也会划分为不同的区域,用于放置不同的程序。当 Linux 内核启动后会初始化各种软硬件环境,加载驱动程序,挂载根文件系统,Linux 内核加载的准备完毕后就开始加载一些特定的程序(进程)了。第一个加载的就是 init 进程。

二.启动源码流程 init.cpp main函数

int main(int argc, char** argv) {
    //umask是确定掩码设置的命令,该掩码控制如何为新创建的文件设置文件权限 umask(0)取反=0777=rwx rwx rwx
    umask(0);
    //设置Path环境变量 _PATH_DEFPATH  "/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin"添加到ENV数组中
    add_environment("PATH", _PATH_DEFPATH);
    //初始化日志和输出日志的级别
    klog_init();
    klog_set_level(KLOG_NOTICE_LEVEL);
      //2.0
     //开启属性服务,通过mmap开启共享内存位置/dev/properties 大小(128 * 1024)2.1
     property_init();
    //创建epoll句柄 I/O多路复用 容量 EPOLL_CLOEXEC=02000000
    epoll_fd = epoll_create1(EPOLL_CLOEXEC);
    //3.1
    //初始化信号监
    signal_handler_init();
    //4.0
    //启动属性服务
    start_property_service();
    //5.0解析init.rc
    init_parse_config_file("/init.rc");
    //添加一些额外的执行任务
    action_for_each_trigger("early-init", action_add_queue_tail);
    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");
    action_for_each_trigger("init", action_add_queue_tail);
    queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
    queue_builtin_action(queue_property_triggers_action, "queue_property_triggers");
    while (true) {
        if (!waiting_for_exec) {
            //执行init.rc封装的命令
            execute_one_command();
            restart_processes();
        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;

2.1 property_init

void property_init() {
    //只初始化一次
    if (property_area_initialized) {
        return;
    property_area_initialized = true;
     //2.1.1   通过mmap开启共享内存位置/dev/properties 大小(128 * 1024) 
    if (__system_property_area_init()) {
        return;
    //属性服务参数存储到静态workspace结构体重
    pa_workspace.size = 0;
    //创建PROP_FILENAME句柄
    pa_workspace.fd = open(PROP_FILENAME, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
    if (pa_workspace.fd == -1) {
        ERROR("Failed to open %s: %s\n", PROP_FILENAME, strerror(errno));
        return;

2.2__system_property_area_init

static int map_prop_area_rw()
     //property_filename=/dev/properties 
    const int fd = open(property_filename,
                        O_RDWR | O_CREAT | O_NOFOLLOW | O_CLOEXEC | O_EXCL, 0444);
    //PA_SIZE (128 * 1024) 
    pa_size = PA_SIZE;
    pa_data_size = pa_size - sizeof(prop_area);
    compat_mode = false;
    //mmap开启虚拟内存地址 
    void *const memory_area = mmap(NULL, pa_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (memory_area == MAP_FAILED) {
        close(fd);
        return -1;
    //内存的首地址保存在__system_property_area__
    prop_area *pa = new(memory_area) prop_area(PROP_AREA_MAGIC, PROP_AREA_VERSION);
    __system_property_area__ = pa;
    close(fd);
    return 0;

3.1 signal_handler_init

 void signal_handler_init() {
    int s[2];
//socketpair()函数用于创建一对无名的、相互连接的套接子。 
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];
// Write to signal_write_fd if we catch SIGCHLD.
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = SIGCHLD_handler;
act.sa_flags = SA_NOCLDSTOP;
//设置SIGCHLD信号处理的方法
sigaction(SIGCHLD, &act, 0);
//3.2 处理子进程退出的时候对服务的资源释放
reap_any_outstanding_children();
3.3注册
register_epoll_handler(signal_read_fd, handle_signal);

3.2reap_any_outstanding_children()

static void reap_any_outstanding_children() {   while (wait_for_one_process()) { static bool wait_for_one_process() {   int status;   //等待任意一个子进程失败如果子进程返回0没有退出 退出的情况返回对应子进程的pid   pid_t pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG));   if (pid == 0) {       return false;   } else if (pid == -1) {       ERROR("waitpid failed: %s\n", strerror(errno));       return false;   //获取进程的服务   service* svc = service_find_by_pid(pid);   std::string name;   if (svc) {       name = android::base::StringPrintf("Service '%s' (pid %d)", svc->name, pid);   } else {       name = android::base::StringPrintf("Untracked pid %d", pid);   //无服务退出   if (!svc) {       return true;   //服务的标识不为SVC_ONESHOT或者为SVC_RESTART 杀死进程   if (!(svc->flags & SVC_ONESHOT) || (svc->flags & SVC_RESTART)) {       NOTICE("Service '%s' (pid %d) killing any children in process group\n", svc->name, pid);       kill(-pid, SIGKILL);   //清空服务创建的socket   for (socketinfo* si = svc->sockets; si; si = si->next) {       char tmp[128];       snprintf(tmp, sizeof(tmp), ANDROID_SOCKET_DIR"/%s", si->name);       unlink(tmp);   //服务标识SVC_EXEC释放内存   if (svc->flags & SVC_EXEC) {       INFO("SVC_EXEC pid %d finished...\n", svc->pid);       waiting_for_exec = false;       list_remove(&svc->slist);       free(svc->name);       free(svc);       return true;   svc->pid = 0;   svc->flags &= (~SVC_RUNNING);     //flags标识SVC_ONESHOT并且不是SVC_RESTART 设置为SVC_DISABLED   if ((svc->flags & SVC_ONESHOT) && !(svc->flags & SVC_RESTART)) {       svc->flags |= SVC_DISABLED;   //禁用和重置的服务,都不再自动重启   if (svc->flags & (SVC_DISABLED | SVC_RESET)) {       svc->NotifyStateChange("stopped");       return true;   time_t now = gettime();   //服务在4分钟内重启次数超过4次,则重启手机进入recovery模式   if ((svc->flags & SVC_CRITICAL) && !(svc->flags & SVC_RESTART)) {       if (svc->time_crashed + CRITICAL_CRASH_WINDOW >= now) {           if (++svc->nr_crashed > CRITICAL_CRASH_THRESHOLD) {               android_reboot(ANDROID_RB_RESTART2, 0, "recovery");               return true;       } else {           svc->time_crashed = now;           svc->nr_crashed = 1;   svc->flags &= (~SVC_RESTART);   svc->flags |= SVC_RESTARTING;   //执行当前service中所有onrestart命令   struct listnode* node;   list_for_each(node, &svc->onrestart.commands) {       command* cmd = node_to_item(node, struct command, clist);       cmd->func(cmd->nargs, cmd->args);   //设置相应的service状态为restarting   svc->NotifyStateChange("restarting");   return true;

3.3register_epoll_handler(signal_read_fd, handle_signal);

void register_epoll_handler(int fd, void (*fn)()) {
    epoll_event ev;
    ev.events = EPOLLIN;
    ev.data.ptr = reinterpret_cast<void*>(fn);
    //将fd的可读事件加入到epoll_fd的监听队列中
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) {
        ERROR("epoll_ctl failed: %s\n", strerror(errno));

3.4 handle_signal和SIGCHLD_handler

//读取数据
static void handle_signal() {
    // Clear outstanding requests.
    char buf[32];
    read(signal_read_fd, buf, sizeof(buf));
    reap_any_outstanding_children();
//写入数据
static void SIGCHLD_handler(int) {
     //向signal_write_fd写入1,直到成功为止
    if (TEMP_FAILURE_RETRY(write(signal_write_fd, "1", 1)) == -1) {
        ERROR("write(signal_write_fd) failed: %s\n", strerror(errno));

4.start_property_service

  start_property_service();
  void start_property_service() {
    //PROP_SERVICE_NAME property_service 
    property_set_fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
                                    0666, 0, 0, NULL);
    if (property_set_fd == -1) {
        ERROR("start_property_service socket creation failed: %s\n", strerror(errno));
        exit(1);
    listen(property_set_fd, 8);
    //4.1监听
    register_epoll_handler(property_set_fd, handle_property_set_fd);

4.1register_epoll_handler

void register_epoll_handler(int fd, void (*fn)()) {
    epoll_event ev;
    ev.events = EPOLLIN;
    //函数转换成void*
    ev.data.ptr = reinterpret_cast<void*>(fn);
    //fd的事件添加到epoll_fd队列中
    if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &ev) == -1) {
        ERROR("epoll_ctl failed: %s\n", strerror(errno));

4.2 handle_property_set_fd

static void handle_property_set_fd()
    prop_msg msg;
    int s;
    int r;
    struct ucred cr;
    struct sockaddr_un addr;
    socklen_t addr_size = sizeof(addr);
    socklen_t cr_size = sizeof(cr);
    char * source_ctx = NULL;
    struct pollfd ufds[1];
    const int timeout_ms = 2 * 1000;  /* Default 2 sec timeout for caller to send property. */
    int nr;
    if ((s = accept(property_set_fd, (struct sockaddr *) &addr, &addr_size)) < 0) {
        return;
    /* Check socket options here */
    if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cr, &cr_size) < 0) {
        close(s);
        ERROR("Unable to receive socket options\n");
        return;
    ufds[0].fd = s;
    ufds[0].events = POLLIN;
    ufds[0].revents = 0;
    nr = TEMP_FAILURE_RETRY(poll(ufds, 1, timeout_ms));
    if (nr == 0) {
        ERROR("sys_prop: timeout waiting for uid=%d to send property message.\n", cr.uid);
        close(s);
        return;
    } else if (nr < 0) {
        ERROR("sys_prop: error waiting for uid=%d to send property message: %s\n", cr.uid, strerror(errno));
        close(s);
        return;
    r = TEMP_FAILURE_RETRY(recv(s, &msg, sizeof(msg), MSG_DONTWAIT));
    if(r != sizeof(prop_msg)) {
        ERROR("sys_prop: mis-match msg size received: %d expected: %zu: %s\n",
              r, sizeof(prop_msg), strerror(errno));
        close(s);
        return;
    //处理消息命令  
    switch(msg.cmd) {
    case PROP_MSG_SETPROP:
        msg.name[PROP_NAME_MAX-1] = 0;
        msg.value[PROP_VALUE_MAX-1] = 0;
        if (!is_legal_property_name(msg.name, strlen(msg.name))) {
            ERROR("sys_prop: illegal property name. Got: "%s"\n", msg.name);
            close(s);
            return;
        getpeercon(s, &source_ctx);
         //msg.name匹配上ctl.开头 
        if(memcmp(msg.name,"ctl.",4) == 0) {
            close(s);
            if (check_control_mac_perms(msg.value, source_ctx)) {
                //4.3
                handle_control_message((char*) msg.name + 4, (char*) msg.value);
            } else {
                ERROR("sys_prop: Unable to %s service ctl [%s] uid:%d gid:%d pid:%d\n",
                        msg.name + 4, msg.value, cr.uid, cr.gid, cr.pid);
        } else {
            if (check_perms(msg.name, source_ctx)) {
                property_set((char*) msg.name, (char*) msg.value);
            } else {
                ERROR("sys_prop: permission denied uid:%d  name:%s\n",
                      cr.uid, msg.name);
            close(s);
        freecon(source_ctx);
        break;
    default:
        close(s);
        break;

4.3handle_control_message

void handle_control_message(const char *msg, const char *arg)
    if (!strcmp(msg,"start")) {
        //启动服务
        msg_start(arg);
    } else if (!strcmp(msg,"stop")) {
        //关闭服务
        msg_stop(arg);
    } else if (!strcmp(msg,"restart")) {
        //重启服务
        msg_restart(arg);
    } else {
        ERROR("unknown control msg '%s'\n", msg);

\

  • 私信