IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 【Android 源码学习】 init启动 -> 正文阅读

[移动开发]【Android 源码学习】 init启动

Android 源码学习 init启动

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

从main.cpp开始

main.cpp first_stage_init.cpp seliunx.cpp init.cpp FirstStageMain "selinux_setup" "selinux_setup" "second_stage" "second_stage" 1.系统属性初始化 2.加载默认的系统属性 3.启动属性服务 4.解析 init.rc main.cpp first_stage_init.cpp seliunx.cpp init.cpp

system/core/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.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进程
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 12:09:06  更:2022-10-31 12:12:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 0:30:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码