summaryrefslogtreecommitdiffstats
path: root/init/init.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'init/init.cpp')
-rw-r--r--init/init.cpp69
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);