init: export all androidboot cmd line values as ro.boot.xx props
Also, clean up how we initialize the ro.xx properties and process
the kernel command line.
Change-Id: Iedda6c90e31340a189171a44b2767480403354f7
Signed-off-by: Dima Zavin <dima@android.com>
diff --git a/init/init.c b/init/init.c
index 41de63a..c3be93d 100755
--- a/init/init.c
+++ b/init/init.c
@@ -59,11 +59,7 @@
#endif
static char console[32];
-static char serialno[32];
static char bootmode[32];
-static char baseband[32];
-static char carrier[32];
-static char bootloader[32];
static char hardware[32];
static unsigned revision = 0;
static char qemu[32];
@@ -420,45 +416,6 @@
}
}
-static void import_kernel_nv(char *name, int in_qemu)
-{
- char *value = strchr(name, '=');
-
- if (value == 0) return;
- *value++ = 0;
- if (*name == 0) return;
-
- if (!in_qemu)
- {
- /* on a real device, white-list the kernel options */
- if (!strcmp(name,"qemu")) {
- strlcpy(qemu, value, sizeof(qemu));
- } else if (!strcmp(name,"androidboot.console")) {
- strlcpy(console, value, sizeof(console));
- } else if (!strcmp(name,"androidboot.mode")) {
- strlcpy(bootmode, value, sizeof(bootmode));
- } else if (!strcmp(name,"androidboot.serialno")) {
- strlcpy(serialno, value, sizeof(serialno));
- } else if (!strcmp(name,"androidboot.baseband")) {
- strlcpy(baseband, value, sizeof(baseband));
- } else if (!strcmp(name,"androidboot.carrier")) {
- strlcpy(carrier, value, sizeof(carrier));
- } else if (!strcmp(name,"androidboot.bootloader")) {
- strlcpy(bootloader, value, sizeof(bootloader));
- } else if (!strcmp(name,"androidboot.hardware")) {
- strlcpy(hardware, value, sizeof(hardware));
- }
- } else {
- /* in the emulator, export any kernel option with the
- * ro.kernel. prefix */
- char buff[32];
- int len = snprintf( buff, sizeof(buff), "ro.kernel.%s", name );
- if (len < (int)sizeof(buff)) {
- property_set( buff, value );
- }
- }
-}
-
static struct command *get_first_command(struct action *act)
{
struct listnode *node;
@@ -565,30 +522,104 @@
return 0;
}
-static int set_init_properties(void)
+static void import_kernel_nv(char *name, int for_emulator)
+{
+ char *value = strchr(name, '=');
+ int name_len = strlen(name);
+
+ if (value == 0) return;
+ *value++ = 0;
+ if (name_len == 0) return;
+
+ if (for_emulator) {
+ /* in the emulator, export any kernel option with the
+ * ro.kernel. prefix */
+ char buff[PROP_NAME_MAX];
+ int len = snprintf( buff, sizeof(buff), "ro.kernel.%s", name );
+
+ if (len < (int)sizeof(buff))
+ property_set( buff, value );
+ return;
+ }
+
+ if (!strcmp(name,"qemu")) {
+ strlcpy(qemu, value, sizeof(qemu));
+ } else if (!strncmp(name, "androidboot.", 12) && name_len > 12) {
+ const char *boot_prop_name = name + 12;
+ char prop[PROP_NAME_MAX];
+ int cnt;
+
+ cnt = snprintf(prop, sizeof(prop), "ro.boot.%s", boot_prop_name);
+ if (cnt < PROP_NAME_MAX)
+ property_set(prop, value);
+ }
+}
+
+static void export_kernel_boot_props(void)
{
char tmp[PROP_VALUE_MAX];
+ const char *pval;
+ unsigned i;
+ struct {
+ const char *src_prop;
+ const char *dest_prop;
+ const char *def_val;
+ } prop_map[] = {
+ { "ro.boot.serialno", "ro.serialno", "", },
+ { "ro.boot.mode", "ro.bootmode", "unknown", },
+ { "ro.boot.baseband", "ro.baseband", "unknown", },
+ { "ro.boot.carrier", "ro.carrier", "unknown", },
+ { "ro.boot.bootloader", "ro.bootloader", "unknown", },
+ };
- if (qemu[0])
- import_kernel_cmdline(1, import_kernel_nv);
+ for (i = 0; i < ARRAY_SIZE(prop_map); i++) {
+ pval = property_get(prop_map[i].src_prop);
+ property_set(prop_map[i].dest_prop, pval ?: prop_map[i].def_val);
+ }
+ pval = property_get("ro.boot.console");
+ if (pval)
+ strlcpy(console, pval, sizeof(console));
+
+ /* save a copy for init's usage during boot */
+ strlcpy(bootmode, property_get("ro.bootmode"), sizeof(bootmode));
+
+ /* if this was given on kernel command line, override what we read
+ * before (e.g. from /proc/cpuinfo), if anything */
+ pval = property_get("ro.boot.hardware");
+ if (pval)
+ strlcpy(hardware, pval, 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");
else if (!strcmp(bootmode,"factory2"))
property_set("ro.factorytest", "2");
else
property_set("ro.factorytest", "0");
+}
- property_set("ro.serialno", serialno[0] ? serialno : "");
- property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown");
- property_set("ro.baseband", baseband[0] ? baseband : "unknown");
- property_set("ro.carrier", carrier[0] ? carrier : "unknown");
- property_set("ro.bootloader", bootloader[0] ? bootloader : "unknown");
+static void process_kernel_cmdline(void)
+{
+ /* don't expose the raw commandline to nonpriv processes */
+ chmod("/proc/cmdline", 0440);
- property_set("ro.hardware", hardware);
- snprintf(tmp, PROP_VALUE_MAX, "%d", revision);
- property_set("ro.revision", tmp);
- return 0;
+ /* first pass does the common stuff, and finds if we are in qemu.
+ * second pass is only necessary for qemu to export all kernel params
+ * as props.
+ */
+ 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)
@@ -691,18 +722,17 @@
*/
open_devnull_stdio();
klog_init();
+ property_init();
- /* don't expose the raw commandline to nonpriv processes */
- chmod("/proc/cmdline", 0440);
- /* pull the kernel commandline and ramdisk properties file in */
- import_kernel_cmdline(0, import_kernel_nv);
get_hardware_name(hardware, &revision);
+ process_kernel_cmdline();
+
is_charger = !strcmp(bootmode, "charger");
INFO("property init\n");
- property_init(!is_charger);
- set_init_properties();
+ if (!is_charger)
+ property_load_boot_defaults();
INFO("reading config file\n");
init_parse_config_file("/init.rc");
diff --git a/init/property_service.c b/init/property_service.c
index 687de6d..d06df31 100644
--- a/init/property_service.c
+++ b/init/property_service.c
@@ -490,11 +490,14 @@
persistent_properties_loaded = 1;
}
-void property_init(bool load_defaults)
+void property_init(void)
{
init_property_area();
- if (load_defaults)
- load_properties_from_file(PROP_PATH_RAMDISK_DEFAULT);
+}
+
+void property_load_boot_defaults(void)
+{
+ load_properties_from_file(PROP_PATH_RAMDISK_DEFAULT);
}
int properties_inited(void)
diff --git a/init/property_service.h b/init/property_service.h
index 37c2788..b9d1bf6 100644
--- a/init/property_service.h
+++ b/init/property_service.h
@@ -20,7 +20,8 @@
#include <stdbool.h>
extern void handle_property_set_fd(void);
-extern void property_init(bool load_defaults);
+extern void property_init(void);
+extern void property_load_boot_defaults(void);
extern void load_persist_props(void);
extern void start_property_service(void);
void get_property_workspace(int *fd, int *sz);