SurfaceFlinger启动流程(全网最直白、最详细的讲解,没有之一,覆盖每一个步骤)

SurfaceFlinger进程是由init进程启动的,当内核启动init进程之后,会执行init.cpp中的main方法,在main方法中会加载所有的.rc文件

int main(int argc, char** argv) {
    .......省略
    .......省略
    parser.AddSectionParser("service", std::make_unique<ServiceParser>(&sm));
    parser.AddSectionParser("on", std::make_unique<ActionParser>(&am));
    parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));
    std::string bootscript = GetProperty("ro.boot.init_rc", "");
    if (bootscript.empty()) {
        //加载和解析init.rc文件
        parser.ParseConfig("/init.rc");
 
        //加载和解析/system/etc/init目录下的.rc文件
        parser.set_is_system_etc_init_loaded(
                parser.ParseConfig("/system/etc/init"));
 
        //加载和解析/vendor/etc/init目录下的.rc文件
        parser.set_is_vendor_etc_init_loaded(
                parser.ParseConfig("/vendor/etc/init"));
 
        //加载和解析/odm/etc/init目录下的.rc文件
        parser.set_is_odm_etc_init_loaded(parser.ParseConfig("/odm/etc/init"));
    } else {
        parser.ParseConfig(bootscript);
        parser.set_is_system_etc_init_loaded(true);
        parser.set_is_vendor_etc_init_loaded(true);
        parser.set_is_odm_etc_init_loaded(true);
    }
}

在init.rc中,会有on boot这么一块代码块

on boot
    # basic network init
    ifup lo
    hostname localhost
    domainname localdomain
 
    ......省略
    ......省略
 
    # Start standard binderized HAL daemons
    class_start hal
 
    class_start core

init.rc中on boot块的最后一行class_start core,表示启动所有core类的服务,而SurfaceFlinger就是属于core类的服务,这个可以从SurfaceFlinger.rc中可以看出。接下来,请看SurfaceFlinger.rc文件,可以看到Surfaceflinger.rc中 class core animation这一行,表示SurfaceFlinger属于core 和 animation这两类的,所以执行了class_start core 也就启动了surfaceflinger进程

注意:service surfaceflinger /system/bin/surfaceflinger 这行代码只是 表示声明了一个surfaceflinger服务,对应的可执行程序的路径是/system/bin/surfaceflinger,并不是说这行代码是启动一个surfaceflinger进程,声明和启动是有区别的

service surfaceflinger /system/bin/surfaceflinger
    class core animation
    user system
    group graphics drmrpc readproc
    onrestart restart zygote
    writepid /dev/stune/foreground/tasks
    socket pdx/system/vr/display/client     stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
    socket pdx/system/vr/display/manager    stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
    socket pdx/system/vr/display/vsync      stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0

问题1:init.rc的on boot块是什么时候执行呢?在哪里会触发on boot块的执行?难道上面init.cpp中加载和解释init.rc的时候,扫描到on boot块就会执行on boot块里面的语句?

回答:非也。还是在init.cpp的mian方法中,而启动的on boot块的指令是在init.rc的on late-init块中, trigger boot 就是去执行on boot块,,所以执行了am.QueueEventTrigger("late-init") 就会执行了on late-init块,然后就执行了on boot

am.QueueEventTrigger("early-init");
 
    // Queue an action that waits for coldboot done so we know ueventd has set up all of /dev...
    am.QueueBuiltinAction(wait_for_coldboot_done_action, "wait_for_coldboot_done");
    // ... so that we can start queuing up actions that require stuff from /dev.
    am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
    am.QueueBuiltinAction(set_mmap_rnd_bits_action, "set_mmap_rnd_bits");
    am.QueueBuiltinAction(set_kptr_restrict_action, "set_kptr_restrict");
    am.QueueBuiltinAction(keychord_init_action, "keychord_init");
    am.QueueBuiltinAction(console_init_action, "console_init");
 
    // Trigger all the boot actions to get us started.
    am.QueueEventTrigger("init");
 
    // Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random
    // wasn't ready immediately after wait_for_coldboot_done
    am.QueueBuiltinAction(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
 
    // Don't mount filesystems or start core system services in charger mode.
    std::string bootmode = GetProperty("ro.bootmode", "");
    if (bootmode == "charger") {
        am.QueueEventTrigger("charger");
    } else {
        am.QueueEventTrigger("late-init");
    }
 
    // Run all property triggers based on current state of the properties.
    am.QueueBuiltinAction(queue_property_triggers_action, "queue_property_triggers");
on late-init
    trigger early-fs
 
    # Mount fstab in init.{$device}.rc by mount_all command. Optional parameter
    # '--early' can be specified to skip entries with 'latemount'.
    # /system and /vendor must be mounted by the end of the fs stage,
    # while /data is optional.
    trigger fs
    trigger post-fs
 
    # Mount fstab in init.{$device}.rc by mount_all with '--late' parameter
    # to only mount entries with 'latemount'. This is needed if '--early' is
    # specified in the previous mount_all command on the fs stage.
    # With /system mounted and properties form /system + /factory available,
    # some services can be started.
    trigger late-fs
 
    # 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
 
    # Now we can start zygote for devices with file based encryption
    trigger zygote-start
 
    # Load persist properties and override properties (if enabled) from /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

问题2:为什么说,执行class_start core 后,就会启动对应的进程呢??对应的启动进程的逻辑在哪里呢?

回答:执行class_start core后,系统会触发system/core/init/buildins.cpp中的 do_class_start方法的调用,args[1] 为core,ForEachServiceInClass 会遍历所有core类的服务,然后去执行

static int do_class_start(const std::vector<std::string>& args) {
        /* Starting a class does not start services
         * which are explicitly disabled.  They must
         * be started individually.
         */
    //这里的args[1]是core
    ServiceManager::GetInstance().
        ForEachServiceInClass(args[1], [] (Service* s) { s->StartIfNotDisabled(); });
    return 0;
}
void ServiceManager::ForEachServiceInClass(const std::string& classname,
                                           void (*func)(Service* svc)) const {
    for (const auto& s : services_) {
        if (s->classnames().find(classname) != s->classnames().end()) {
            func(s.get());
        }
    }
}
bool Service::StartIfNotDisabled() {
    if (!(flags_ & SVC_DISABLED)) {
        return Start();
    } else {
        flags_ |= SVC_DISABLED_START;
    }
    return true;
}
bool Service::Start() {
    .......省略
    .......省略
    pid_t pid = -1;
    if (namespace_flags_) {
        pid = clone(nullptr, nullptr, namespace_flags_ | SIGCHLD, nullptr);
    } else {
        //这里fork出一个进程,也就是surfaceflinger进程
        pid = fork();
    }
 
    if (pid == 0) {
    
        //执行完ExpandArgsAndExecve后,会执行到可执行文件,真正启动了进程
 
        if (!ExpandArgsAndExecve(args_)) {
            PLOG(ERROR) << "cannot execve('" << args_[0] << "')";
        }
        _exit(127);
 
    }
    return true;
}
static bool ExpandArgsAndExecve(const std::vector<std::string>& args) {
    .....省略
    //启动对应的二进制可执行程序,如/system/bin/surfaceflinger
    return execve(c_strings[0], c_strings.data(), (char**)ENV) == 0;
}

当调用execve后,会执行对应的可执行程序/system/bin/surfaceflinger,至此,surfaceflinger进程就启动了,于是触发执行了main_surfaceflinger.cpp中main方法的调用

int main(int, char**) {
    startHidlServices();
 
    // start the thread pool
    sp<ProcessState> ps(ProcessState::self());
    ps->startThreadPool();
 
    // instantiate surfaceflinger
    sp<SurfaceFlinger> flinger = new SurfaceFlinger();
 
    flinger->init();
 
    // run surface flinger in this thread
    flinger->run();
 
    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容