From: Jan Kiszka Date: Mon, 4 Jan 2016 10:17:11 +0000 (+0100) Subject: inmates: Add support for command line parameters X-Git-Url: https://rtime.felk.cvut.cz/gitweb/jailhouse.git/commitdiff_plain/b97a9cacd4a1a3c1f2cde645a1aea5c395f5f976 inmates: Add support for command line parameters 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 --- diff --git a/inmates/lib/arm/Makefile b/inmates/lib/arm/Makefile index ba0f5d2..42c34cf 100644 --- a/inmates/lib/arm/Makefile +++ b/inmates/lib/arm/Makefile @@ -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 diff --git a/inmates/lib/arm/inmate.lds b/inmates/lib/arm/inmate.lds index 16c4871..fe13253 100644 --- a/inmates/lib/arm/inmate.lds +++ b/inmates/lib/arm/inmate.lds @@ -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 index 0000000..c0eceaa --- /dev/null +++ b/inmates/lib/cmdline.c @@ -0,0 +1,114 @@ +/* + * Jailhouse, a Linux-based partitioning hypervisor + * + * Copyright (c) Siemens AG, 2016 + * + * Authors: + * Jan Kiszka + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + */ + +#include + +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); +} diff --git a/inmates/lib/inmate_common.h b/inmates/lib/inmate_common.h index 382b81b..475c231 100644 --- a/inmates/lib/inmate_common.h +++ b/inmates/lib/inmate_common.h @@ -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__ */ diff --git a/inmates/lib/x86/Makefile b/inmates/lib/x86/Makefile index 3413d6a..30c5122 100644 --- a/inmates/lib/x86/Makefile +++ b/inmates/lib/x86/Makefile @@ -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 diff --git a/inmates/lib/x86/inmate.lds b/inmates/lib/x86/inmate.lds index 4e4a506..de6e592 100644 --- a/inmates/lib/x86/inmate.lds +++ b/inmates/lib/x86/inmate.lds @@ -1,7 +1,7 @@ /* * Jailhouse, a Linux-based partitioning hypervisor * - * Copyright (c) Siemens AG, 2013 + * Copyright (c) Siemens AG, 2013-2016 * * Authors: * Jan Kiszka @@ -15,14 +15,20 @@ * 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) }