当前位置: 代码网 > it编程>App开发>Android > 【Android 源码学习】 init启动

【Android 源码学习】 init启动

2024年08月02日 Android 我要评论
Android 源码学习 init启动流程、属性服务

android 源码学习 init启动

android 11 init 启动流程学习。主要是学习刘望舒腾讯课堂教的androidframework部分的笔记。
参考文章:
android系统启动-zygote进程
5张图搞懂android系统启动的核心流程

从main.cpp开始

system/core/init/main.cpp

using namespace android::init;

int main(int argc, char** argv) {
#if __has_feature(address_sanitizer)
    __asan_set_error_report_callback(asanreportcallback);
#endif

    if (!strcmp(basename(argv[0]), "ueventd")) {
        return ueventd_main(argc, argv);
    }

    if (argc > 1) {
        if (!strcmp(argv[1], "subcontext")) {
            android::base::initlogging(argv, &android::base::kernellogger);
            const builtinfunctionmap& function_map = getbuiltinfunctionmap();

            return subcontextmain(argc, argv, &function_map);
        }
		// 第二次调用
        if (!strcmp(argv[1], "selinux_setup")) {
            return setupselinux(argv);
        }
		// 第三次调用
        if (!strcmp(argv[1], "second_stage")) {
            return secondstagemain(argc, argv);
        }
    }
	// 第一次调用
    return firststagemain(argc, argv);
}

init.cpp 部分逻辑

system/core/init/init.cpp

int secondstagemain(int argc, char** argv) {
	...
	// 系统属性初始化
	propertyinit();
	...
	// 创建epoll,epoll是linux内核的可扩展i/o事件通知机制
	epoll epoll;
	if(auto result = epol.open();!result.ok()){
		plog(fatal) << result.error();
	}
	// 注册信号处理
	installsignalfdhandler(&epoll);
	//加载默认的系统属性
	installinitnotifier(&epoll);
	//启动属性服务
	startpropertyservice(&property_fd);
	...
	actionmanager& am = actionmanager::getinstance();
	servicelist& sm = servicelist::getinstance();
	//解析init.rc
	loadbootscripts(am,sm);
	...
	return 0;
}

 static void loadbootscripts(actionmanager& action_manager, servicelist& service_list) {
    parser parser = createparser(action_manager, service_list);

    std::string bootscript = getproperty("ro.boot.init_rc", "");
    if (bootscript.empty()) {
        parser.parseconfig("/system/etc/init/hw/init.rc");
        if (!parser.parseconfig("/system/etc/init")) {
            late_import_paths.emplace_back("/system/etc/init");
        }
			parser.parseconfig("/system_ext/etc/init")
        if (!parser.parseconfig("/product/etc/init")) {
            late_import_paths.emplace_back("/product/etc/init");
        }
        if (!parser.parseconfig("/odm/etc/init")) {
            late_import_paths.emplace_back("/odm/etc/init");
        }
        if (!parser.parseconfig("/vendor/etc/init")) {
            late_import_paths.emplace_back("/vendor/etc/init");
        }
    } else {
        parser.parseconfig(bootscript);
    }
}

init启动zygote

/system/core/rootdir/init.zygote64.rc

service zygote /system/bin/app_process64 -xzygote /system/bin --zygote --start-system-server
    class main
    priority -20
    user root
    group root readproc reserved_disk
    socket zygote stream 660 root system
    socket usap_pool_primary stream 660 root system
    onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    onrestart restart wificond
    writepid /dev/cpuset/foreground/tasks

init.rc中还import了其他的rc文件,解析完init.rc后,依次解析其他的rc文件

import /system/etc/init/hw/init.${ro.zygote}.rc

nonencrypted 会触发启动main类别的服务。
main 指zygote
/system/core/rootdir/init.rc 部分代码

on nonencrypted
      class_start main
      class_start late_start

class_start 在/system/core/init/builtins.cpp 文件中定义
builtins.cpp

static result<void> do_class_start(const builtinarguments& args) {
    // do not start a class if it has a property persist.dont_start_class.class set to 1.
    if (android::base::getboolproperty("persist.init.dont_start_class." + args[1], false))
        return {};
    // starting a class does not start services which are explicitly disabled.
    // they must  be started individually.
    for (const auto& service : servicelist::getinstance()) {
        if (service->classnames().count(args[1])) {
            if (auto result = service->startifnotdisabled(); !result.ok()) {
                log(error) << "could not start service '" << service->name()
                           << "' as part of class '" << args[1] << "': " << result.error();
            }
        }
    }
    return {};
}

/system/core/init/service.cpp

result<void> service::startifnotdisabled() {
    if (!(flags_ & svc_disabled)) {
        return start();
    } else {
        flags_ |= svc_disabled_start;
    }
    return {};
}

result<void> service::start() {
	...
	pid_t pid = -1;
    if (namespace_flags_) {
        pid = clone(nullptr, nullptr, namespace_flags_ | sigchld, nullptr);
    } else {
        pid = fork();
    }

    if (pid == 0) {
    	...
    	if(!expandargsandexecv(args_, sigstop_)){
    		 plog(error) << "cannot execve('" << args_[0]
    		  << "').see the 'debugging init' section of init's readme.md for tips";
    	}
    	_exit(127);
    }
    if (pid < 0) {
        pid_ = 0;
        return errnoerror() << "failed to fork";
    }
	...
	return {};
}

service 就是 zygote
expandargsandexecv 传递的参数就是“/system/bin/app_process64”

static bool expandargsandexecv(const std::vector<std::string>& args, bool sigstop) {
    std::vector<std::string> expanded_args;
    std::vector<char*> c_strings;

    expanded_args.resize(args.size());
    c_strings.push_back(const_cast<char*>(args[0].data()));
    for (std::size_t i = 1; i < args.size(); ++i) {
        auto expanded_arg = expandprops(args[i]);
        if (!expanded_arg.ok()) {
            log(fatal) << args[0] << ": cannot expand arguments': " << expanded_arg.error();
        }
        expanded_args[i] = *expanded_arg;
        c_strings.push_back(expanded_args[i].data());
    }
    c_strings.push_back(nullptr);

    if (sigstop) {
        kill(getpid(), sigstop);
    }

    return execv(c_strings[0], c_strings.data()) == 0;
}

其中/system/bin/app_process64的映射的执行文件为:/frameworks/base/cmds/app_process/app_main.cpp,定义在
/frameworks/base/cmds/app_process/android.bp
低版本是
/frameworks/base/cmds/app_process/android.mk

cc_binary {
    name: "app_process",

    srcs: ["app_main.cpp"],

    multilib: {
        lib32: {
            version_script: ":art_sigchain_version_script32.txt",
            suffix: "32",
        },
        lib64: {
            version_script: ":art_sigchain_version_script64.txt",
            suffix: "64",
        },
    },

    ldflags: ["-wl,--export-dynamic"],

    shared_libs: [
        "libandroid_runtime",
        "libbinder",
        "libcutils",
        "libdl",
        "libhidlbase",
        "liblog",
        "libnativeloader",
        "libutils",

        // this is a list of libraries that need to be included in order to avoid
        // bad apps. this prevents a library from having a mismatch when resolving
        // new/delete from an app shared library.
        // see b/21032018 for more details.
        "libwilhelm",
    ],

    whole_static_libs: ["libsigchain"],

    compile_multilib: "both",

    cflags: [
        "-wall",
        "-werror",
        "-wunused",
        "-wunreachable-code",
    ],

    // if sanitize_lite is revived this will need:
    //product_variables: {
    //    sanitize_lite: {
    //        // in sanitize_lite mode, we create the sanitized binary in a separate location (but reuse
    //        // the same module). using the same module also works around an issue with make: binaries
    //        // that depend on sanitized libraries will be relinked, even if they set local_sanitize := never.
    //        //
    //        // also pull in the asanwrapper helper.
    //        relative_install_path: "asan",
    //        required: ["asanwrapper"],
    //    },
    //},

    // create a symlink from app_process to app_process32 or 64
    // depending on the target configuration.
    symlink_preferred_arch: true,
}

/frameworks/base/cmds/app_process/app_main.cpp

int main(int argc, char* const argv[]){
	......
    if (zygote) {
   		// 启动zygote
        runtime.start("com.android.internal.os.zygoteinit", args, zygote);
    } else if (classname) {
        runtime.start("com.android.internal.os.runtimeinit", args, zygote);
    } else {
        fprintf(stderr, "error: no class name or --zygote supplied.\n");
        app_usage();
        log_always_fatal("app_process: no class name or --zygote supplied.");
    }
}

属性服务

void startpropertyservice(int* epoll_socket) {
    initpropertyset("ro.property_service.version", "2");

    int sockets[2];
    if (socketpair(af_unix, sock_seqpacket | sock_cloexec, 0, sockets) != 0) {
        plog(fatal) << "failed to socketpair() between property_service and init";
    }
    *epoll_socket = from_init_socket = sockets[0];
    init_socket = sockets[1];
    startsendingmessages();

    if (auto result = createsocket(prop_service_name, sock_stream | sock_cloexec | sock_nonblock,
                                   false, 0666, 0, 0, {});
        result.ok()) {
        property_set_fd = *result;
    } else {
        log(fatal) << "start_property_service socket creation failed: " << result.error();
    }
	// 监听socket 属性服务,最多同时被8个视图使用
    listen(property_set_fd, 8);
	// 创建属性服务线程
    auto new_thread = std::thread{propertyservicethread};
    property_service_thread.swap(new_thread);
}

static void propertyservicethread() {
    epoll epoll;
    if (auto result = epoll.open(); !result.ok()) {
        log(fatal) << result.error();
    }
	// 监听property_set_fd,当socket有请求的时候调用handle_property_set_fd 来处理
    if (auto result = epoll.registerhandler(property_set_fd, handle_property_set_fd);
        !result.ok()) {
        log(fatal) << result.error();
    }

    if (auto result = epoll.registerhandler(init_socket, handleinitsocket); !result.ok()) {
        log(fatal) << result.error();
    }

    while (true) {
        auto pending_functions = epoll.wait(std::nullopt);
        if (!pending_functions.ok()) {
            log(error) << pending_functions.error();
        } else {
            for (const auto& function : *pending_functions) {
                (*function)();
            }
        }
    }
}

static void handle_property_set_fd() {
	.....
	switch (cmd) {
		case prop_msg_setprop:{
			......
			break;
		}
		case prop_msg_setprop2:{
			......
			// 关键代码
			uint32_t result = handlepropertyset(name, value, source_context, cr, &socket, &error);
	        if (result != prop_success) {
	            log(error) << "unable to set property '" << name << "' from uid:" << cr.uid
	                       << " gid:" << cr.gid << " pid:" << cr.pid << ": " << error;
	        }
	        socket.senduint32(result);
        	break;
		}
	}
}


uint32_t handlepropertyset(const std::string& name, const std::string& value,
                           const std::string& source_context, const ucred& cr,
                           socketconnection* socket, std::string* error) {
	.......
	// 设置属性
	return propertyset(name, value, error);                          
}

static uint32_t propertyset(const std::string& name, const std::string& value, std::string* error) {
    size_t valuelen = value.size();

    if (!islegalpropertyname(name)) {
        *error = "illegal property name";
        return prop_error_invalid_name;
    }

    if (auto result = islegalpropertyvalue(name, value); !result.ok()) {
        *error = result.error().message();
        return prop_error_invalid_value;
    }

	// 从属性存储空间查找属性
    prop_info* pi = (prop_info*) __system_property_find(name.c_str());
    if (pi != nullptr) {
        // ro.* properties are actually "write-once".
        // ro开头的是只读,只能设置一次
        if (startswith(name, "ro.")) {
            *error = "read-only property was already set";
            return prop_error_read_only_property;
        }

        __system_property_update(pi, value.c_str(), valuelen);
    } else {
        int rc = __system_property_add(name.c_str(), name.size(), value.c_str(), valuelen);
        if (rc < 0) {
            *error = "__system_property_add failed";
            return prop_error_set_failed;
        }
    }

    // don't write properties to disk until after we have read all default
    // properties to prevent them from being overwritten by default values.
    if (persistent_properties_loaded && startswith(name, "persist.")) {
        writepersistentproperty(name, value);
    }
    // if init hasn't started its main loop, then it won't be handling property changed messages
    // anyway, so there's no need to try to send them.
    auto lock = std::lock_guard{accept_messages_lock};
    if (accept_messages) {
        propertychanged(name, value);
    }
    return prop_success;
}

总结

init进程在启动过程中主要做了三件事:

  1. 创建一些文件并挂载设备
  2. 启动属性服务
  3. 解析init.rc配置文件并启动zygote进程
(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com