diff options
Diffstat (limited to 'init/init.cpp')
-rw-r--r-- | init/init.cpp | 69 |
1 files changed, 50 insertions, 19 deletions
diff --git a/init/init.cpp b/init/init.cpp index 41ceb0a..ddd6223 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -31,6 +31,9 @@ #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> +#include <dirent.h> + +#include <memory> #include <selinux/selinux.h> #include <selinux/label.h> @@ -45,6 +48,8 @@ #include <cutils/fs.h> #include <private/android_filesystem_config.h> #include <termios.h> +#include <utils/file.h> +#include <utils/stringprintf.h> #include "devices.h" #include "init.h" @@ -65,8 +70,6 @@ static int property_triggers_enabled = 0; static char console[32]; static char bootmode[32]; -static char hardware[32]; -static unsigned revision = 0; static char qemu[32]; static struct action *cur_action = NULL; @@ -764,6 +767,8 @@ static void export_kernel_boot_props(void) { "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", }, }; for (i = 0; i < ARRAY_SIZE(prop_map); i++) { @@ -782,16 +787,6 @@ static void export_kernel_boot_props(void) property_get("ro.bootmode", tmp); strlcpy(bootmode, tmp, sizeof(bootmode)); - /* if this was given on kernel command line, override what we read - * before (e.g. from /proc/cpuinfo), if anything */ - ret = property_get("ro.boot.hardware", tmp); - if (ret) - strlcpy(hardware, tmp, sizeof(hardware)); - property_set("ro.hardware", hardware); - - snprintf(tmp, PROP_VALUE_MAX, "%d", revision); - property_set("ro.revision", tmp); - /* TODO: these are obsolete. We should delete them */ if (!strcmp(bootmode,"factory")) property_set("ro.factorytest", "1"); @@ -801,6 +796,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::StringPrintf("%s/compatible", android_dir); + + std::string dt_file; + android::ReadFileToString(file_name, &dt_file); + if (!dt_file.compare("android,firmware")) { + ERROR("firmware/android is not compatible with 'android,firmware'\n"); + return; + } + + std::unique_ptr<DIR, int(*)(DIR*)>dir(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::StringPrintf("%s/%s", android_dir, dp->d_name); + + android::ReadFileToString(file_name, &dt_file); + std::replace(dt_file.begin(), dt_file.end(), ',', '.'); + + std::string property_name = android::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 */ @@ -813,11 +842,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) @@ -1015,10 +1039,17 @@ int main(int argc, char **argv) klog_init(); property_init(); - get_hardware_name(hardware, &revision); - + 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(); + union selinux_callback cb; cb.func_log = log_callback; selinux_set_callback(SELINUX_CB_LOG, cb); |