参考:
https://www.it610.com/article/1304931662924124160.htm
https://blog.csdn.net/pepsimaxin/article/details/107284563
https://juejin.cn/post/6844903946151002125
上一篇:
http://www.gaohaiyan.com/4021.html#FirstStageMain
system/core/init/selinux.cpp
main –> FirstStageMain –> SetupSelinux –> SecondStageMain
main –> SetupSelinux –> SecondStageMain
部分操作和FirstStageMain是一样的,做一些Linux的设定操作。最后都是前往SecondStageMain。
●挂载boot.img的更新
●注册回调,用来设置需要写入kmsg的selinux日志
●加载SELinux规则配置文件
●通过init进入second_stage
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
#include "selinux.h" #include <android/api-level.h> #include <fcntl.h> #include <linux/audit.h> #include <linux/netlink.h> #include <stdlib.h> #include <sys/wait.h> #include <unistd.h> #include <android-base/chrono_utils.h> #include <android-base/file.h> #include <android-base/logging.h> #include <android-base/parseint.h> #include <android-base/strings.h> #include <android-base/unique_fd.h> #include <fs_avb/fs_avb.h> #include <fs_mgr.h> #include <libgsi/libgsi.h> #include <libsnapshot/snapshot.h> #include <selinux/android.h> #include "block_dev_initializer.h" #include "debug_ramdisk.h" #include "reboot_utils.h" #include "util.h" using namespace std::string_literals; using android::base::ParseInt; using android::base::Timer; using android::base::unique_fd; using android::fs_mgr::AvbHandle; using android::snapshot::SnapshotManager; namespace android { namespace init { namespace { enum EnforcingStatus { SELINUX_PERMISSIVE, SELINUX_ENFORCING }; EnforcingStatus StatusFromCmdline() { // 略 } bool IsEnforcing() { // 略 } bool ForkExecveAndWaitForCompletion(const char* filename, char* const argv[]) { // 略 } bool ReadFirstLine(const char* file, std::string* line) { // 略 } bool FindPrecompiledSplitPolicy(std::string* file) { // 略 } bool GetVendorMappingVersion(std::string* plat_vers) { // 略 } constexpr const char plat_policy_cil_file[] = "/system/etc/selinux/plat_sepolicy.cil"; bool IsSplitPolicyDevice() { // 略 } bool LoadSplitPolicy() { // 略 } bool LoadMonolithicPolicy() { // 略 } bool LoadPolicy() { // 略 } void SelinuxInitialize() { // 略 } constexpr size_t kKlogMessageSize = 1024; void SelinuxAvcLog(char* buf, size_t buf_len) { // 略 } } // namespace void SelinuxRestoreContext() { // 略 } int SelinuxKlogCallback(int type, const char* fmt, ...) { // 略 } void SelinuxSetupKernelLogging() { // 略 } int SelinuxGetVendorAndroidVersion() { // 略 } // This is for R(指Android 11,api 30) system.img/system_ext.img to work on old vendor.img as system_ext.img is introduced in R. // We mount system_ext in second stage init because the first-stage init in boot.img won't be updated in the system-only OTA scenario. // 此函数为了在老版本到*.img中引导R。OTA模式下init的第1阶段不会更新boot.img,所以在此第二阶段挂载system_ext。 void MountMissingSystemPartitions() { // 略 } // 入口 // system/core/init/selinux.cpp约673行 int SetupSelinux(char** argv) { SetStdioToDevNull(argv); // 将标准输入输出标准错误重定向到/dev/null InitKernelLogging(argv); // 初始化内核Log系统,重定向到/dev/kmsg if (REBOOT_BOOTLOADER_ON_PANIC) { InstallRebootSignalHandlers(); // 当init挂掉时重启bootloader } boot_clock::time_point start_time = boot_clock::now(); // 启动计时 // 本文件约606行。 MountMissingSystemPartitions(); // 挂载boot.img的更新 // Set up SELinux, loading the SELinux policy. SelinuxSetupKernelLogging(); // 注册回调,用来设置需要写入kmsg的selinux日志 SelinuxInitialize(); // 加载SELinux规则配置文件 // We're in the kernel domain and want to transition to the init domain. // File systems that store SELabels in their xattrs, such as ext4 do not need an explicit restorecon here, // but other file systems do. In particular, this is needed for ramdisks such as the recovery image for A/B devices. // 从这里,开始从内核域转换到init域。已有SE标签的扩展文件系统(如ext4)不需显式转换;但其它文件系统须要,尤其是虚拟磁盘,如双机A/B恢复镜像。 if (selinux_android_restorecon("/system/bin/init", 0) == -1) { PLOG(FATAL) << "restorecon failed of /system/bin/init failed"; } // 设置环境变量kEnvSelinuxStartedAt当前时间 setenv(kEnvSelinuxStartedAt, std::to_string(start_time.time_since_epoch().count()).c_str(), 1); const char* path = "/system/bin/init"; const char* args[] = {path, "second_stage", nullptr}; execv(path, const_cast<char**>(args)); //【重点】通过execv重新给该进程装载并携带参数 “/system/bin/init second_stage” 进入第2阶段second_stage // execv() only returns if an error happened, in which case we panic and never return from this function. PLOG(FATAL) << "execv(\"" << path << "\") failed"; return 1; } } // namespace init } // namespace android |
- end
本文由崔维友 威格灵 cuiweiyou vigiles cuiweiyou 原创,转载请注明出处:http://www.gaohaiyan.com/4030.html
承接App定制、企业web站点、办公系统软件 设计开发,外包项目,毕设