]> rtime.felk.cvut.cz Git - jailhouse.git/commitdiff
inmates: Add support for command line parameters
authorJan Kiszka <jan.kiszka@siemens.com>
Mon, 4 Jan 2016 10:17:11 +0000 (11:17 +0100)
committerJan Kiszka <jan.kiszka@siemens.com>
Fri, 8 Jan 2016 18:34:38 +0000 (19:34 +0100)
This provides support for parsing string, integer (long long type) and
boolean command line parameters. The former two need to be in the form
of "name=value" so that cmdline_parse_str/int will return the extracted
value. Boolean parameters are just of the form "name", and
cmdline_parse_bool will return true if this pattern is found. Parameters
need to be separated by blanks.

The parameters can be passed to the inmate by loading the string at an
architecture-specific location. That is 0xf0000 on x86 and 0x100 on ARM
so far. Note that the inmate has to reserve an appropriately sized
buffer via the CMDLINE_BUFFER macro.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
inmates/lib/arm/Makefile
inmates/lib/arm/inmate.lds
inmates/lib/cmdline.c [new file with mode: 0644]
inmates/lib/inmate_common.h
inmates/lib/x86/Makefile
inmates/lib/x86/inmate.lds

index ba0f5d29be166173c80b1187b7d8dd7749924e1f..42c34cf59028ec365b740aabe7fbe9b226159949 100644 (file)
@@ -17,7 +17,7 @@ always := lib.a
 ccflags-y := -ffunction-sections
 
 lib-y                          := header.o gic.o printk.o timer.o
-lib-y                          += ../string.o
+lib-y                          += ../string.o ../cmdline.o
 lib-$(CONFIG_ARM_GIC)          += gic-v2.o
 lib-$(CONFIG_ARM_GIC_V3)       += gic-v3.o
 lib-$(CONFIG_SERIAL_AMBA_PL011)        += uart-pl011.o
index 16c48710df99b57d6eb25872bb8d39411f9fc1bc..fe1325320f659f34481294f85173731436b95613 100644 (file)
@@ -16,6 +16,12 @@ SECTIONS {
        . = 0;
        .boot           : { *(.boot) }
 
+       . = 0x100;
+       .cmdline        : {
+               *(.cmdline)
+               BYTE(0); /* empty string in case no buffer is provided */
+       }
+
        . = ALIGN(4);
        .text           : {
                *(.text)
diff --git a/inmates/lib/cmdline.c b/inmates/lib/cmdline.c
new file mode 100644 (file)
index 0000000..c0eceaa
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Jailhouse, a Linux-based partitioning hypervisor
+ *
+ * Copyright (c) Siemens AG, 2016
+ *
+ * Authors:
+ *  Jan Kiszka <jan.kiszka@siemens.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ */
+
+#include <inmate.h>
+
+extern const char cmdline[];
+
+static bool get_param(const char *param, char *value_buffer,
+                     unsigned long buffer_size)
+{
+       unsigned long param_len = strlen(param);
+       const char *p = cmdline;
+
+       while (1) {
+               /* read over leading blanks */
+               while (*p == ' ') {
+                       if (*p == 0)
+                               return false;
+                       p++;
+               }
+
+               if (strncmp(p, param, param_len) == 0) {
+                       p += param_len;
+
+                       /* check for boolean parameter */
+                       if ((buffer_size == 0 && (*p == ' ' || *p == 0)))
+                               return true;
+
+                       /* extract parameter value */
+                       if (*p == '=') {
+                               p++;
+                               while (buffer_size > 1) {
+                                       if (*p == ' ' || *p == 0)
+                                               break;
+                                       *value_buffer++ = *p++;
+                                       buffer_size--;
+                               }
+                               if (buffer_size > 0)
+                                       *value_buffer = 0;
+                               return true;
+                       }
+               }
+
+               /* search for end of this parameter */
+               while (*p != ' ') {
+                       if (*p == 0)
+                               return false;
+                       p++;
+               }
+       }
+}
+
+const char *cmdline_parse_str(const char *param, char *value_buffer,
+                             unsigned long buffer_size,
+                             const char *default_value)
+{
+       if (get_param(param, value_buffer, buffer_size))
+               return value_buffer;
+       else
+               return default_value;
+}
+
+long long cmdline_parse_int(const char *param, long long default_value)
+{
+       char value_buffer[32];
+       char *p = value_buffer;
+       bool negative = false;
+       long long value = 0;
+
+       if (!get_param(param, value_buffer, sizeof(value_buffer)))
+               return default_value;
+
+       if (strncmp(p, "0x", 2) == 0) {
+               p += 2;
+               do {
+                       if (*p >= '0' && *p <= '9')
+                               value = (value << 4) + *p - '0';
+                       else if (*p >= 'A' && *p <= 'F')
+                               value = (value << 4) + *p - 'A';
+                       else if (*p >= 'a' && *p <= 'f')
+                               value = (value << 4) + *p - 'a';
+                       else
+                               return default_value;
+                       p++;
+               } while (*p != 0);
+       } else {
+               if (*p == '-' || *p == '+')
+                       negative = (*p++ == '-');
+
+               do {
+                       if (*p >= '0' && *p <= '9')
+                               value = (value * 10) + *p - '0';
+                       else
+                               return default_value;
+                       p++;
+               } while (*p != 0);
+       }
+
+       return negative ? -value : value;
+}
+
+bool cmdline_parse_bool(const char *param)
+{
+       return get_param(param, NULL, 0);
+}
index 382b81b6754c931a8db27a9483c6c064f25cffd2..475c2312f0456d59acf5449d21156d989b6cba75 100644 (file)
@@ -43,6 +43,15 @@ void *memcpy(void *d, const void *s, unsigned long n);
 unsigned long strlen(const char *s);
 int strncmp(const char *s1, const char *s2, unsigned long n);
 
+const char *cmdline_parse_str(const char *param, char *value_buffer,
+                             unsigned long buffer_size,
+                             const char *default_value);
+long long cmdline_parse_int(const char *param, long long default_value);
+bool cmdline_parse_bool(const char *param);
+
+#define CMDLINE_BUFFER(size) \
+       const char cmdline[size] __attribute__((section(".cmdline")));
+
 void inmate_main(void);
 
 #endif /* !__ASSEMBLY__ */
index 3413d6ae656f8aefbe87d022e831faa2d7673a44..30c5122d7df3c7442156ce89f93f9c642e09df0b 100644 (file)
@@ -13,7 +13,7 @@
 always := lib.a lib32.a
 
 TARGETS := header.o hypercall.o ioapic.o printk.o smp.o
-TARGETS += ../pci.o ../string.o
+TARGETS += ../pci.o ../string.o ../cmdline.o
 TARGETS_64_ONLY := int.o mem.o pci.o timing.o
 
 ccflags-y := -ffunction-sections
index 4e4a506c08148b5dd6f2e77e7b9b3ae0537aedf9..de6e5928cbe058d415bf7206b8ed7fbb40a802ab 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Jailhouse, a Linux-based partitioning hypervisor
  *
- * Copyright (c) Siemens AG, 2013
+ * Copyright (c) Siemens AG, 2013-2016
  *
  * Authors:
  *  Jan Kiszka <jan.kiszka@siemens.com>
  *  0x000000..        : heap (not configured here)
  *          ..0x0e0000: stack
  *  0x0e0000..0x0effff: bss
- *  0x0f0000..0x0fffef: startup code, text, rodata, data
+ *  0x0f0000..0x0fffef: command line, startup code, text, rodata, data
  *  0x0ffff0..0x0fffff: startup code (boot address)
  *  0x100000..0x100fff: communication region (not configured here)
  */
 SECTIONS
 {
-       /* 16-bit sections */
        . = 0;
+       .cmdline        : {
+               cmdline = 0xf0000; /* adjust relocation address of variable */
+               *(.cmdline)
+               BYTE(0); /* empty string in case no buffer is provided */
+       }
+
+       /* 16-bit sections */
        .startup        : { *(.startup) }
 
        . = 0xfff0;
@@ -42,7 +48,7 @@ SECTIONS
        bss_dwords = SIZEOF(.bss) / 4;
        bss_qwords = SIZEOF(.bss) / 8;
 
-       . = 0xf0000 + SIZEOF(.startup);
+       . = 0xf0000 + ADDR(.startup) + SIZEOF(.startup);
        .text           : AT (ADDR(.text) & 0xffff) {
                *(.text)
        }