Android 11属性系统初始化流程
在init进程启动的第二阶段,调用PropertyInit 对属性系统进行初始化
int SecondStageMain(int argc, char** argv) { //省略 PropertyInit(); //省略 }
PropertyInit函数在system\core\init\property_service.cpp 中实现
void PropertyInit() { //省略 mkdir("/dev/__properties__", S_IRWXU | S_IXGRP | S_IXOTH); //1 CreateSerializedPropertyInfo();//2 if (__system_property_area_init()) {//3 LOG(FATAL) LOG(FATAL) auto property_infos = std::vector if (!LoadPropertyInfoFromFile("/system/etc/selinux/plat_property_contexts", &property_infos)) { return; } // Don't check for failure here, so we always have a sane list of properties. // E.g. In case of recovery, the vendor partition will not have mounted and we // still need the system / platform properties to function. if (access("/system_ext/etc/selinux/system_ext_property_contexts", R_OK) != -1) { LoadPropertyInfoFromFile("/system_ext/etc/selinux/system_ext_property_contexts", &property_infos); } if (!LoadPropertyInfoFromFile("/vendor/etc/selinux/vendor_property_contexts", &property_infos)) { // Fallback to nonplat_* if vendor_* doesn't exist. LoadPropertyInfoFromFile("/vendor/etc/selinux/nonplat_property_contexts", &property_infos); } if (access("/product/etc/selinux/product_property_contexts", R_OK) != -1) { LoadPropertyInfoFromFile("/product/etc/selinux/product_property_contexts", &property_infos); } if (access("/odm/etc/selinux/odm_property_contexts", R_OK) != -1) { LoadPropertyInfoFromFile("/odm/etc/selinux/odm_property_contexts", &property_infos); } } //省略 auto serialized_contexts = std::string(); auto error = std::string(); if (!BuildTrie(property_infos, "u:object_r:default_prop:s0", "string", &serialized_contexts, &error)) { LOG(ERROR) PLOG(ERROR) bool fsetxattr_failed = false; return system_properties.AreaInit(PROP_FILENAME, &fsetxattr_failed) && !fsetxattr_failed ? 0 : -1; } if (strlen(filename) = PROP_FILENAME_MAX) { return false; } strcpy(property_filename_, filename); contexts_ = new (contexts_data_) ContextsSerialized(); if (!contexts_-Initialize(true, property_filename_, fsetxattr_failed)) { return false; } initialized_ = true; return true; } filename_ = filename; if (!InitializeProperties()) { return false; } if (writable) { mkdir(filename_, S_IRWXU | S_IXGRP | S_IXOTH); bool open_failed = false; if (fsetxattr_failed) { *fsetxattr_failed = false; } for (size_t i = 0; i d_name; android::base::ReadFileToString(file_name, &dt_file); std::replace(dt_file.begin(), dt_file.end(), ',', '.'); InitPropertySet("ro.boot."s + dp->d_name, dt_file); } }
首先检查compatible属性的值是"android,firmware"如果不是,函数直接返回。如果是的话,再打开目录下的dts文件,并读取其内容。其中 get_android_dt_dir是在cmdline中指定
static std::string init_android_dt_dir() { // Use the standard procfs-based path by default std::string android_dt_dir = kDefaultAndroidDtDir; // The platform may specify a custom Android DT path in kernel cmdline ImportKernelCmdline([&](const std::string& key, const std::string& value) { if (key == "androidboot.android_dt_dir") { android_dt_dir = value; } }); LOG(INFO) // Set once and saves time for subsequent calls to this function static const std::string kAndroidDtDir = init_android_dt_dir(); return kAndroidDtDir; } bool for_emulator = false; ImportKernelCmdline([&](const std::string& key, const std::string& value) { if (key == "qemu") { for_emulator = true; } else if (StartsWith(key, "androidboot.")) { InitPropertySet("ro.boot." + key.substr(12), value); } }); if (for_emulator) { ImportKernelCmdline([&](const std::string& key, const std::string& value) { // In the emulator, export any kernel option with the "ro.kernel." prefix. InitPropertySet("ro.kernel." + key, value); }); } } constexpr const char* UNSET = ""; struct { const char* src_prop; const char* dst_prop; const char* default_value; } prop_map[] = { // clang-format off { "ro.boot.serialno", "ro.serialno", UNSET, }, { "ro.boot.mode", "ro.bootmode", "unknown", }, { "ro.boot.baseband", "ro.baseband", "unknown", }, { "ro.boot.bootloader", "ro.bootloader", "unknown", }, { "ro.boot.hardware", "ro.hardware", "unknown", }, { "ro.boot.revision", "ro.revision", "0", }, // clang-format on }; for (const auto& prop : prop_map) { std::string value = GetProperty(prop.src_prop, prop.default_value); if (value != UNSET) InitPropertySet(prop.dst_prop, value); } }
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。