android7.0启动zygote进程

    zygote孵化器在android系统中有着及其中要的位置. android系统中的进程都是有zygote孵化出来的, 所有应用进程都是zygote的子进程. 在init进程中的服务都是由命令启动起来的, zygote服务也不例外, 所以在分析zygote之前要分析一下init.rc中命令是如何执行的.

 在分析init进程时知道在init.cpp中的main函数循环执行命令

    while (true) {
        if (!waiting_for_exec) {
            am.ExecuteOneCommand();   //循环执行命令
            restart_processes();    //重启死掉的进程
        }

        int timeout = -1;
        if (process_needs_restart) {
            timeout = (process_needs_restart - gettime()) * 1000;
            if (timeout < 0)
                timeout = 0;
        }

        if (am.HasMoreCommands()) {
            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;
void ActionManager::ExecuteOneCommand() {
    // Loop through the trigger queue until we have an action to execute
    while (current_executing_actions_.empty() && !trigger_queue_.empty()) { //当前的可执行action队列为空, trigger_queue_队列不为空
        for (const auto& action : actions_) {           //循环遍历action_队列,包含了所有需要执行的命令,解析init.rc获得
            if (trigger_queue_.front()->CheckTriggers(*action)) {   //获取队头的trigger, 检查actions_列表中的action的trigger,对比是否相同
                current_executing_actions_.emplace(action.get());  //将所有具有同一trigger的action加入当前可执行action队列
            }
        }
        trigger_queue_.pop();   //将队头trigger出栈
    }

    if (current_executing_actions_.empty()) {//当前可执行的actions队列为空就返回
        return;
    }

    auto action = current_executing_actions_.front(); //获取当前可执行actions队列的首个action

    if (current_command_ == 0) {
        std::string trigger_name = action->BuildTriggersString();
        INFO("processing action (%s)\n", trigger_name.c_str());
    }

    action->ExecuteOneCommand(current_command_);      //执行当前的命令

    // If this was the last command in the current action, then remove
    // the action from the executing list.
    // If this action was oneshot, then also remove it from actions_.
    ++current_command_;    //不断叠加,将action_中的所有命令取出
    if (current_command_ == action->NumCommands()) {
        current_executing_actions_.pop();
        current_command_ = 0;
        if (action->oneshot()) {
            auto eraser = [&action] (std::unique_ptr& a) {
                return a.get() == action;
            };
            actions_.erase(std::remove_if(actions_.begin(), actions_.end(), eraser));
        }
    }
}
由于所有的命令执行顺序都是根据trigger的顺序执行的, 所以在获取现在需要执行的action就需要检查一下这个action的trigger.

不同的trigger对应这不同的CheckTriggers. 之前讲android7.0 init进程时知道

early-init等的trigger为EventTrigger

wait_for_coldboot_done_action等的trigger就为BuiltinTrigger

在init.rc可以看到类似与on property:sys.powerctl=*这样的trigger为PropertyTrigger

下面具体看一下这几个trigger的CheckTriggers函数

class EventTrigger : public Trigger {
public:
    EventTrigger(const std::string& trigger) : trigger_(trigger) {
    }
    bool CheckTriggers(const Action& action) const override {
        return action.CheckEventTrigger(trigger_);
    }
private:
    const std::string trigger_;
};

class PropertyTrigger : public Trigger {
public:
    PropertyTrigger(const std::string& name, const std::string& value)
        : name_(name), value_(value) {
    }
    bool CheckTriggers(const Action& action) const override {
        return action.CheckPropertyTrigger(name_, value_);
    }
private:
    const std::string name_;
    const std::string value_;
};

class BuiltinTrigger : public Trigger {
public:
    BuiltinTrigger(Action* action) : action_(action) {
    }
    bool CheckTriggers(const Action& action) const override {
        return action_ == &action;    //如果action相等就返回true执行
    }
private:
    const Action* action_;
};
EventTrigger
bool Action::CheckEventTrigger(const std::string& trigger) const {
    return !event_trigger_.empty() &&   //event_trigger_不为空, 在addCommand时InitTriggers添加数据
        trigger == event_trigger_ &&       //event_trigger_与当前的trigger相同
        CheckPropertyTriggers();            //不是property trigger
} 
PropertyTrigger
bool Action::CheckPropertyTrigger(const std::string& name,
                                  const std::string& value) const {
    return event_trigger_.empty() && CheckPropertyTriggers(name, value);  
}
bool Action::CheckPropertyTriggers(const std::string& name,
                                   const std::string& value) const {
    if (property_triggers_.empty()) {   //property triggers为空返回true
        return true;
    }

    bool found = name.empty();
    for (const auto& t : property_triggers_) {
        const auto& trigger_name = t.first;
        const auto& trigger_value = t.second;
        if (trigger_name == name) {
            if (trigger_value != "*" && trigger_value != value) {
                return false;      //是property trigger 返回false
            } else {
                found = true;
            }
        } else {
            std::string prop_val = property_get(trigger_name.c_str());
            if (prop_val.empty() || (trigger_value != "*" &&
                                     trigger_value != prop_val)) {
                return false;
            }
        }
    }
    return found;
}
根据trigger找到对应的action就开始执行了

void Action::ExecuteOneCommand(std::size_t command) const {
    ExecuteCommand(commands_[command]);   //从commands_队列取出命令对应的函数
}
void Action::ExecuteCommand(const Command& command) const {
    Timer t;      //使用timer计时
    int result = command.InvokeFunc();

    if (klog_get_level() >= KLOG_INFO_LEVEL) {
        std::string trigger_name = BuildTriggersString();
        std::string cmd_str = command.BuildCommandString();
        std::string source = command.BuildSourceString();

        INFO("Command '%s' action=%s%s returned %d took %.2fs\n",
             cmd_str.c_str(), trigger_name.c_str(), source.c_str(),
             result, t.duration());  //可以将该log级别改为NOTICE,可以输出当前执行命令的信息以及执行时间输出, 定位开机问题
    }
}
int Command::InvokeFunc() const {
    std::vector expanded_args;
    expanded_args.resize(args_.size());
    expanded_args[0] = args_[0];    
    for (std::size_t i = 1; i < args_.size(); ++i) {
        if (!expand_props(args_[i], &expanded_args[i])) {
            ERROR("%s: cannot expand '%s'\n", args_[0].c_str(), args_[i].c_str());
            return -EINVAL;
        }
    }

    return func_(expanded_args);  //执行获得的函数
}

由于根据android7.0 init进程可以知道第一个触发的动作为early-init

在init.rc中early-init的命令如下:

on early-init       //触发器为early-init, 首先执行
    # Set init and its forked children's oom_adj.
    write /proc/1/oom_score_adj -1000  //调用do_write函数

    # Disable sysrq from keyboard
    write /proc/sys/kernel/sysrq 0  

    # Set the security context of /adb_keys if present.
    restorecon /adb_keys      //调用do_restorecon函数

    # Shouldn't be necessary, but sdcard won't start without it. http://b/22568628.
    mkdir /mnt 0775 root system  //调用do_mkdir函数

    # Set the security context of /postinstall if present.
    restorecon /postinstall 

    start ueventd   //调用do_start函数启动ueventd服务
service ueventd /sbin/ueventd
    class core      //class name为core
    critical          //重要服务
    seclabel u:r:ueventd:s0

之后会相继触发init, late-init等.

on late-init     
    trigger early-fs    //触发early-fs
    trigger fs             //触发fs
    trigger post-fs    //触发post-fs

    # Load properties from /system/ + /factory after fs mount. Place
    # this in another action so that the load will be scheduled after the prior
    # issued fs triggers have completed.
    trigger load_system_props_action

    # Now we can mount /data. File encryption requires keymaster to decrypt
    # /data, which in turn can only be loaded when system properties are present
    trigger post-fs-data
    trigger load_persist_props_action

    # Remove a file to wake up anything waiting for firmware.
    trigger firmware_mounts_complete

    trigger early-boot
    trigger boot
on fs         //触发fs就会执行如下命令
    ubiattach 0 ubipac
    exec /sbin/resize2fs -ef /fstab.${ro.hardware}
    mount_all /fstab.${ro.hardware}     //执行do_mount_all函数
    mount pstore pstore /sys/fs/pstore
    setprop ro.crypto.fuse_sdcard true
        symlink /system/res /res
        symlink /system/bin /bin
在system/core/init/builtins.cpp中实现了do_mount_all函数

static int do_mount_all(const std::vector& args) {
    pid_t pid;
    int ret = -1;
    int child_ret = -1;
    int status;
    struct fstab *fstab;

    const char* fstabfile = args[1].c_str();
    /*
     * Call fs_mgr_mount_all() to mount all filesystems.  We fork(2) and
     * do the call in the child to provide protection to the main init
     * process if anything goes wrong (crash or memory leak), and wait for
     * the child to finish in the parent.
     */
    pid = fork();
    ..............
    if (ret == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) {
        ActionManager::GetInstance().QueueEventTrigger("encrypt");
    } else if (ret == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) {
        property_set("ro.crypto.state", "encrypted");
        property_set("ro.crypto.type", "block");
        ActionManager::GetInstance().QueueEventTrigger("defaultcrypto");
    } else if (ret == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
        property_set("ro.crypto.state", "unencrypted");
        ActionManager::GetInstance().QueueEventTrigger("nonencrypted");  //将nonencrypted加入trigger_queue_
    } else if (ret == FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
        property_set("ro.crypto.state", "unsupported");
        ActionManager::GetInstance().QueueEventTrigger("nonencrypted");  //将nonencrypted加入trigger_queue_
    } else if (ret == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) {
        /* Setup a wipe via recovery, and reboot into recovery */
        ERROR("fs_mgr_mount_all suggested recovery, so wiping data via recovery.\n");
        ret = wipe_data_via_recovery("wipe_data_via_recovery");
        /* If reboot worked, there is no return. */
    } else if (ret == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
        if (e4crypt_install_keyring()) {
            return -1;
        }
        property_set("ro.crypto.state", "encrypted");
        property_set("ro.crypto.type", "file");

        // Although encrypted, we have device key, so we do not need to
        // do anything different from the nonencrypted case.
        ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
    } else if (ret > 0) {
        ERROR("fs_mgr_mount_all returned unexpected error %d\n", ret);
    }
    /* else ... < 0: error */

    return ret;
}
on nonencrypted    //触发action 
    # A/B update verifier that marks a successful boot.
    exec - root -- /system/bin/update_verifier nonencrypted
    class_start main         //调用do_class_start函数将class name为main的services启动起来
    class_start late_start
在system/core/rootdir/init.zygote64.rc文件中可以看出zygote的class name就为main

service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
    class main                 //class name为main
    socket zygote stream 660 root system
    onrestart write /sys/android_power/request_state wake
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
还是在system/core/init/builtins.cpp中实现了do_class_start函数
static int do_class_start(const std::vector& args) {
        /* Starting a class does not start services
         * which are explicitly disabled.  They must
         * be started individually.
         */
    ServiceManager::GetInstance().
        ForEachServiceInClass(args[1], [] (Service* s) { s->StartIfNotDisabled(); });
    return 0;
}
bool Service::StartIfNotDisabled() {
    if (!(flags_ & SVC_DISABLED)) {
        return Start();          //如果services不是disable,就将start()函数返回
    } else {
        flags_ |= SVC_DISABLED_START;  //否则,标记services为disable
    }
    return true;
}
void ServiceManager::ForEachServiceInClass(const std::string& classname,
                                           void (*func)(Service* svc)) const {
    for (const auto& s : services_) {   //遍历services_寻找所有name为main的servies
        if (classname == s->classname()) {   
            func(s.get());    //如果找到就调用Start()函数
        }
    }
}
bool Service::Start() {
    // Starting a service removes it from the disabled or reset state and
    // immediately takes it out of the restarting state if it was in there.
    flags_ &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));
    time_started_ = 0;

    // Running processes require no additional work --- if they're in the
    // process of exiting, we've ensured that they will immediately restart
    // on exit, unless they are ONESHOT.
    if (flags_ & SVC_RUNNING) {
        return false;
    }

    bool needs_console = (flags_ & SVC_CONSOLE);
    if (needs_console && !have_console) {
        ERROR("service '%s' requires console\n", name_.c_str());
        flags_ |= SVC_DISABLED;
        return false;
    }

    struct stat sb;
    if (stat(args_[0].c_str(), &sb) == -1) {
        ERROR("cannot find '%s' (%s), disabling '%s'\n",
              args_[0].c_str(), strerror(errno), name_.c_str());
        flags_ |= SVC_DISABLED;
        return false;
    }

    std::string bootmode = property_get("ro.bootmode");
    if(((!strncmp(name_.c_str(),"healthd",7))||(!strncmp(name_.c_str(),"bootanim",8))||(!strncmp(name_.c_str(),"zygote",6))||(!strncmp(name_.c_str(),"surfaceflinger",14)))&&(bootmode == "charger")){

         ERROR("stopping '%s'\n",name_.c_str());

        flags_ |= SVC_DISABLED;

         return false;

     }
    std::string scon;
    if (!seclabel_.empty()) {
        scon = seclabel_;
    } else {
        char* mycon = nullptr;
        char* fcon = nullptr;

        INFO("computing context for service '%s'\n", args_[0].c_str());
        int rc = getcon(&mycon);
        if (rc < 0) {
            ERROR("could not get context while starting '%s'\n", name_.c_str());
            return false;
        }

        rc = getfilecon(args_[0].c_str(), &fcon);
        if (rc < 0) {
            ERROR("could not get context while starting '%s'\n", name_.c_str());
            free(mycon);
            return false;
        }

        char* ret_scon = nullptr;
        rc = security_compute_create(mycon, fcon, string_to_security_class("process"),
                                     &ret_scon);
        if (rc == 0) {
            scon = ret_scon;
            free(ret_scon);
        }
        if (rc == 0 && scon == mycon) {
            ERROR("Service %s does not have a SELinux domain defined.\n", name_.c_str());
            free(mycon);
            free(fcon);
            return false;
        }
        free(mycon);
        free(fcon);
        if (rc < 0) {
            ERROR("could not get context while starting '%s'\n", name_.c_str());
            return false;
        }
    }
    //上面都是对services进行判断,设置flags, 下面才是重点
    NOTICE("Starting service '%s'...\n", name_.c_str());  //在kernel log中可以看打印信息
    pid_t pid = fork();     //孵化进程
    if (pid == 0) {
        umask(077);

        for (const auto& ei : envvars_) {
            add_environment(ei.name.c_str(), ei.value.c_str());
        }

        for (const auto& si : sockets_) {
            int socket_type = ((si.type == "stream" ? SOCK_STREAM :
                                (si.type == "dgram" ? SOCK_DGRAM :
                                 SOCK_SEQPACKET)));
            const char* socketcon =
                !si.socketcon.empty() ? si.socketcon.c_str() : scon.c_str();

            int s = create_socket(si.name.c_str(), socket_type, si.perm,
                                  si.uid, si.gid, socketcon);
            if (s >= 0) {
                PublishSocket(si.name, s);
            }
        }

        std::string pid_str = StringPrintf("%d", getpid());
        for (const auto& file : writepid_files_) {
            if (!WriteStringToFile(pid_str, file)) {
                ERROR("couldn't write %s to %s: %s\n",
                      pid_str.c_str(), file.c_str(), strerror(errno));
            }
        }

        if (ioprio_class_ != IoSchedClass_NONE) {
            if (android_set_ioprio(getpid(), ioprio_class_, ioprio_pri_)) {
                ERROR("Failed to set pid %d ioprio = %d,%d: %s\n",
                      getpid(), ioprio_class_, ioprio_pri_, strerror(errno));
            }
        }

        if (needs_console) {
            setsid();
            OpenConsole();
        } else {
            ZapStdio();
        }

        setpgid(0, getpid());
        // As requested, set our gid, supplemental gids, and uid.
        if (gid_) {
            if (setgid(gid_) != 0) {
                ERROR("setgid failed: %s\n", strerror(errno));
                _exit(127);
            }
        }
        if (!supp_gids_.empty()) {
            if (setgroups(supp_gids_.size(), &supp_gids_[0]) != 0) {
                ERROR("setgroups failed: %s\n", strerror(errno));
                _exit(127);
            }
        }
        if (uid_) {
            if (setuid(uid_) != 0) {
                ERROR("setuid failed: %s\n", strerror(errno));
                _exit(127);
            }
        }
        if (!seclabel_.empty()) {
            if (setexeccon(seclabel_.c_str()) < 0) {
                ERROR("cannot setexeccon('%s'): %s\n",
                      seclabel_.c_str(), strerror(errno));
                _exit(127);
            }
        }

        std::vector strs;
        for (const auto& s : args_) {
            strs.push_back(const_cast(s.c_str()));
        }
        strs.push_back(nullptr);
        if (execve(args_[0].c_str(), (char**) &strs[0], (char**) ENV) < 0) {     //执行system/bin/process程序,进入framework层
            ERROR("cannot execve('%s'): %s\n", args_[0].c_str(), strerror(errno));
        }

        _exit(127);
    }

    if (pid < 0) {
        ERROR("failed to start '%s'\n", name_.c_str());
        pid_ = 0;
        return false;
    }

    time_started_ = gettime();
    pid_ = pid;
    flags_ |= SVC_RUNNING;   //将services标记为running
    if ((flags_ & SVC_EXEC) != 0) {
        INFO("SVC_EXEC pid %d (uid %d gid %d+%zu context %s) started; waiting...\n",
             pid_, uid_, gid_, supp_gids_.size(),
             !seclabel_.empty() ? seclabel_.c_str() : "default");
    }

    NotifyStateChange("running");
    return true;
}

调用execve执行system/bin/app_process程序, 就会进入framework/cmds/app_process/app_main.cpp的main函数.

正式进入framework层. 后文将详细分析.

你可能感兴趣的:(Android启动流程)