summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRom Lemarchand <romlem@android.com>2015-02-28 06:39:11 -0800
committerElliott Hughes <enh@google.com>2015-03-19 16:32:02 -0700
commit6a52443d31d4de56ead022a55f63683316d96634 (patch)
tree481b792e495ded8d609c47b119206b3a3e203500
parentbbc01d825448a738160716f95d9cc38f2be5f4f1 (diff)
downloadsystem_core-6a52443d31d4de56ead022a55f63683316d96634.zip
system_core-6a52443d31d4de56ead022a55f63683316d96634.tar.gz
system_core-6a52443d31d4de56ead022a55f63683316d96634.tar.bz2
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
-rw-r--r--init/init.cpp53
1 files 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 <ctype.h>
+#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
@@ -40,6 +41,8 @@
#include <selinux/label.h>
#include <selinux/android.h>
+#include <base/file.h>
+#include <base/stringprintf.h>
#include <cutils/android_reboot.h>
#include <cutils/fs.h>
#include <cutils/iosched_policy.h>
@@ -47,6 +50,8 @@
#include <cutils/sockets.h>
#include <private/android_filesystem_config.h>
+#include <memory>
+
#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_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::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);