From 6a52443d31d4de56ead022a55f63683316d96634 Mon Sep 17 00:00:00 2001 From: Rom Lemarchand Date: Sat, 28 Feb 2015 06:39:11 -0800 Subject: Parse boot properties from device tree - Make sure compatible DT node is "android,firmware" - Set ro.boot.* properties from firmware/android/ DT node (cherry-pick of cbcbea27c70846a96f4bba2f7cb245f937de4d3f.) Change-Id: If3d0716831516cb3d3fde1f75d57e2691d42d054 --- init/init.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/init/init.cpp b/init/init.cpp index 3418d65..5a40fd3 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -40,6 +41,8 @@ #include #include +#include +#include #include #include #include @@ -47,6 +50,8 @@ #include #include +#include + #include "devices.h" #include "init.h" #include "log.h" @@ -800,6 +805,40 @@ static void export_kernel_boot_props(void) property_set("ro.factorytest", "0"); } +static void process_kernel_dt(void) +{ + static const char android_dir[] = "/proc/device-tree/firmware/android"; + + std::string file_name = android::base::StringPrintf("%s/compatible", android_dir); + + std::string dt_file; + android::base::ReadFileToString(file_name, &dt_file); + if (!dt_file.compare("android,firmware")) { + ERROR("firmware/android is not compatible with 'android,firmware'\n"); + return; + } + + std::unique_ptrdir(opendir(android_dir), closedir); + if (!dir) + return; + + struct dirent *dp; + while ((dp = readdir(dir.get())) != NULL) { + if (dp->d_type != DT_REG || !strcmp(dp->d_name, "compatible")) + continue; + + file_name = android::base::StringPrintf("%s/%s", android_dir, dp->d_name); + + android::base::ReadFileToString(file_name, &dt_file); + std::replace(dt_file.begin(), dt_file.end(), ',', '.'); + + std::string property_name = android::base::StringPrintf("ro.boot.%s", dp->d_name); + if (property_set(property_name.c_str(), dt_file.c_str())) { + ERROR("Could not set property %s to value %s", property_name.c_str(), dt_file.c_str()); + } + } +} + static void process_kernel_cmdline(void) { /* don't expose the raw commandline to nonpriv processes */ @@ -812,11 +851,6 @@ static void process_kernel_cmdline(void) import_kernel_cmdline(0, import_kernel_nv); if (qemu[0]) import_kernel_cmdline(1, import_kernel_nv); - - /* now propogate the info given on command line to internal variables - * used by init as well as the current required properties - */ - export_kernel_boot_props(); } static int property_service_init_action(int nargs, char **args) @@ -1004,8 +1038,17 @@ int main(int argc, char** argv) { klog_init(); property_init(); + process_kernel_dt(); + /* in case one is passing arguments both on the command line and in DT + * Properties set in DT always have priority over the command-line ones + */ process_kernel_cmdline(); + /* now propogate the kernel variables to internal variables + * used by init as well as the current required properties + */ + export_kernel_boot_props(); + selinux_callback cb; cb.func_log = log_callback; selinux_set_callback(SELINUX_CB_LOG, cb); -- cgit v1.1