|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1 of 4] minios/cmdline: Port Xen command line argument handling to minios
This is a direct port of the core command line functional, and some
tweaking with the linker setup. It required adding some extra consts to
some of the library functions to compile.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
diff -r 0049de3827bc -r 505992114832 extras/mini-os/Makefile
--- a/extras/mini-os/Makefile
+++ b/extras/mini-os/Makefile
@@ -76,6 +76,7 @@ src-$(CONFIG_BLKFRONT) += blkfront.c
src-$(CONFIG_TPMFRONT) += tpmfront.c
src-$(CONFIG_TPM_TIS) += tpm_tis.c
src-$(CONFIG_TPMBACK) += tpmback.c
+src-y += cmdline.c
src-y += daytime.c
src-y += events.c
src-$(CONFIG_FBFRONT) += fbfront.c
diff -r 0049de3827bc -r 505992114832 extras/mini-os/arch/x86/minios-x86_32.lds
--- a/extras/mini-os/arch/x86/minios-x86_32.lds
+++ b/extras/mini-os/arch/x86/minios-x86_32.lds
@@ -45,6 +45,9 @@ SECTIONS
.data : { /* Data */
*(.data)
+ __setup_start = .;
+ *(.initsetup)
+ __setup_end = .;
}
_edata = .; /* End of data section */
diff -r 0049de3827bc -r 505992114832 extras/mini-os/arch/x86/minios-x86_64.lds
--- a/extras/mini-os/arch/x86/minios-x86_64.lds
+++ b/extras/mini-os/arch/x86/minios-x86_64.lds
@@ -45,6 +45,9 @@ SECTIONS
.data : { /* Data */
*(.data)
+ __setup_start = .;
+ *(.initsetup)
+ __setup_end = .;
}
_edata = .; /* End of data section */
diff -r 0049de3827bc -r 505992114832 extras/mini-os/cmdline.c
--- /dev/null
+++ b/extras/mini-os/cmdline.c
@@ -0,0 +1,165 @@
+#include <mini-os/cmdline.h>
+#include <mini-os/lib.h>
+#include <mini-os/ctype.h>
+
+size_t strlcpy(char *dest, const char *src, size_t size)
+{
+ size_t ret = strlen(src);
+
+ if (size) {
+ size_t len = (ret >= size) ? size-1 : ret;
+ memcpy(dest, src, len);
+ dest[len] = '\0';
+ }
+ return ret;
+}
+
+unsigned long long parse_size_and_unit(const char *s, const char **ps)
+{
+ unsigned long long ret;
+ const char *s1;
+
+ ret = simple_strtoull(s, &s1, 0);
+
+ switch ( *s1 )
+ {
+ case 'G': case 'g':
+ ret <<= 10;
+ case 'M': case 'm':
+ ret <<= 10;
+ case 'K': case 'k':
+ ret <<= 10;
+ case 'B': case 'b':
+ s1++;
+ break;
+ default:
+ ret <<= 10; /* default to kB */
+ break;
+ }
+
+ if ( ps != NULL )
+ *ps = s1;
+
+ return ret;
+}
+
+static void __init assign_integer_param(
+ struct kernel_param *param, uint64_t val)
+{
+ switch ( param->len )
+ {
+ case sizeof(uint8_t):
+ *(uint8_t *)param->var = val;
+ break;
+ case sizeof(uint16_t):
+ *(uint16_t *)param->var = val;
+ break;
+ case sizeof(uint32_t):
+ *(uint32_t *)param->var = val;
+ break;
+ case sizeof(uint64_t):
+ *(uint64_t *)param->var = val;
+ break;
+ default:
+ BUG();
+ }
+}
+
+static int __init parse_bool(const char *s)
+{
+ if ( !strcmp("no", s) ||
+ !strcmp("off", s) ||
+ !strcmp("false", s) ||
+ !strcmp("disable", s) ||
+ !strcmp("0", s) )
+ return 0;
+
+ if ( !strcmp("yes", s) ||
+ !strcmp("on", s) ||
+ !strcmp("true", s) ||
+ !strcmp("enable", s) ||
+ !strcmp("1", s) )
+ return 1;
+
+ return -1;
+}
+
+void __init cmdline_parse(char *cmdline)
+{
+ char opt[100], *optval, *optkey, *q;
+ const char *p = cmdline;
+ struct kernel_param *param;
+ int bool_assert;
+
+ if ( p == NULL )
+ return;
+
+ for ( ; ; )
+ {
+ /* Skip whitespace. */
+ while ( *p == ' ' )
+ p++;
+ if ( *p == '\0' )
+ break;
+
+ /* Grab the next whitespace-delimited option. */
+ q = optkey = opt;
+ while ( (*p != ' ') && (*p != '\0') )
+ {
+ if ( (q-opt) < (sizeof(opt)-1) ) /* avoid overflow */
+ *q++ = *p;
+ p++;
+ }
+ *q = '\0';
+
+ /* Search for value part of a key=value option. */
+ optval = strchr(opt, '=');
+ if ( optval != NULL )
+ *optval++ = '\0'; /* nul-terminate the option value */
+ else
+ optval = q; /* default option value is empty string */
+
+ /* Boolean parameters can be inverted with 'no-' prefix. */
+ bool_assert = !!strncmp("no-", optkey, 3);
+ if ( !bool_assert )
+ optkey += 3;
+
+ for ( param = &__setup_start; param < &__setup_end; param++ )
+ {
+ if ( strcmp(param->name, optkey) )
+ continue;
+
+ switch ( param->type )
+ {
+ case OPT_STR:
+ strlcpy(param->var, optval, param->len);
+ break;
+ case OPT_UINT:
+ assign_integer_param(
+ param,
+ simple_strtoll(optval, NULL, 0));
+ break;
+ case OPT_BOOL:
+ case OPT_INVBOOL:
+ if ( !parse_bool(optval) )
+ bool_assert = !bool_assert;
+ assign_integer_param(
+ param,
+ (param->type == OPT_BOOL) == bool_assert);
+ break;
+ case OPT_SIZE:
+ assign_integer_param(
+ param,
+ parse_size_and_unit(optval, NULL));
+ break;
+ case OPT_CUSTOM:
+ printk("Would call 0x%08lx\n", param->var);
+ ((void (*)(const char *))param->var)(optval);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ }
+ }
+}
diff -r 0049de3827bc -r 505992114832 extras/mini-os/include/cmdline.h
--- /dev/null
+++ b/extras/mini-os/include/cmdline.h
@@ -0,0 +1,63 @@
+#ifndef _MINIOS_CMDLINE_H
+#define _MINIOS_CMDLINE_H
+
+#include <mini-os/types.h>
+#include <sys/cdefs.h>
+
+#define __init __attribute__ ((__section__ (".text")))
+#define __initdata __attribute_used__ __attribute__ ((__section__ (".data")))
+#define __initsetup __attribute_used__ __attribute__ ((__section__
(".initsetup")))
+
+/*
+ * Used for kernel command line parameter setup
+ */
+struct kernel_param {
+ const char *name;
+ enum {
+ OPT_STR,
+ OPT_UINT,
+ OPT_BOOL,
+ OPT_INVBOOL,
+ OPT_SIZE,
+ OPT_CUSTOM
+ } type;
+ void *var;
+ unsigned int len;
+};
+
+extern struct kernel_param __setup_start, __setup_end;
+
+#define __setup_str static __initdata __attribute__((__aligned__(1))) char
+#define __kparam static __attribute_used__ __initsetup struct kernel_param
+
+#define custom_param(_name, _var) \
+ __setup_str __setup_str_##_var[] = _name; \
+ __kparam __setup_##_var = { __setup_str_##_var, OPT_CUSTOM, _var, 0 }
+#define boolean_param(_name, _var) \
+ __setup_str __setup_str_##_var[] = _name; \
+ __kparam __setup_##_var = \
+ { __setup_str_##_var, OPT_BOOL, &_var, sizeof(_var) }
+#define invbool_param(_name, _var) \
+ __setup_str __setup_str_##_var[] = _name; \
+ __kparam __setup_##_var = \
+ { __setup_str_##_var, OPT_INVBOOL, &_var, sizeof(_var) }
+#define integer_param(_name, _var) \
+ __setup_str __setup_str_##_var[] = _name; \
+ __kparam __setup_##_var = \
+ { __setup_str_##_var, OPT_UINT, &_var, sizeof(_var) }
+#define size_param(_name, _var) \
+ __setup_str __setup_str_##_var[] = _name; \
+ __kparam __setup_##_var = \
+ { __setup_str_##_var, OPT_SIZE, &_var, sizeof(_var) }
+#define string_param(_name, _var) \
+ __setup_str __setup_str_##_var[] = _name; \
+ __kparam __setup_##_var = \
+ { __setup_str_##_var, OPT_STR, &_var, sizeof(_var) }
+
+/* Make sure obsolete cmdline params don't break the build. */
+#define __setup(_name, _fn) static void * __attribute_used__ _dummy_##_fn = _fn
+
+
+void __init cmdline_parse(char *cmdline);
+
+#endif
diff -r 0049de3827bc -r 505992114832 extras/mini-os/include/lib-gpl.h
--- a/extras/mini-os/include/lib-gpl.h
+++ b/extras/mini-os/include/lib-gpl.h
@@ -33,10 +33,10 @@
#ifndef HAVE_LIBC
/* printing */
-extern unsigned long simple_strtoul(const char *,char **,unsigned int);
-extern long simple_strtol(const char *,char **,unsigned int);
-extern unsigned long long simple_strtoull(const char *,char **,unsigned int);
-extern long long simple_strtoll(const char *,char **,unsigned int);
+extern unsigned long simple_strtoul(const char *,const char **,unsigned int);
+extern long simple_strtol(const char *,const char **,unsigned int);
+extern unsigned long long simple_strtoull(const char *,const char **,unsigned
int);
+extern long long simple_strtoll(const char *,const char **,unsigned int);
extern int sprintf(char * buf, const char * fmt, ...)
__attribute__ ((format (printf, 2, 3)));
diff -r 0049de3827bc -r 505992114832 extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c
+++ b/extras/mini-os/kernel.c
@@ -42,6 +42,7 @@
#include <mini-os/fbfront.h>
#include <mini-os/pcifront.h>
#include <mini-os/xmalloc.h>
+#include <mini-os/cmdline.h>
#include <fcntl.h>
#include <xen/features.h>
#include <xen/version.h>
@@ -117,6 +118,10 @@ void start_kernel(start_info_t *si)
/* Init the console driver. */
init_console();
+ /* Parse the command line options. */
+ if ( si->cmd_line )
+ cmdline_parse((char*)si->cmd_line);
+
/* Init grant tables */
init_gnttab();
diff -r 0049de3827bc -r 505992114832 extras/mini-os/lib/printf.c
--- a/extras/mini-os/lib/printf.c
+++ b/extras/mini-os/lib/printf.c
@@ -63,7 +63,7 @@
* @endp: A pointer to the end of the parsed string will be placed here
* @base: The number base to use
*/
-unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
+unsigned long simple_strtoul(const char *cp,const char **endp,unsigned int
base)
{
unsigned long result = 0,value;
@@ -94,7 +94,7 @@ unsigned long simple_strtoul(const char
* @endp: A pointer to the end of the parsed string will be placed here
* @base: The number base to use
*/
-long simple_strtol(const char *cp,char **endp,unsigned int base)
+long simple_strtol(const char *cp,const char **endp,unsigned int base)
{
if(*cp=='-')
return -simple_strtoul(cp+1,endp,base);
@@ -107,7 +107,7 @@ long simple_strtol(const char *cp,char *
* @endp: A pointer to the end of the parsed string will be placed here
* @base: The number base to use
*/
-unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int
base)
+unsigned long long simple_strtoull(const char *cp,const char **endp,unsigned
int base)
{
unsigned long long result = 0,value;
@@ -138,7 +138,7 @@ unsigned long long simple_strtoull(const
* @endp: A pointer to the end of the parsed string will be placed here
* @base: The number base to use
*/
-long long simple_strtoll(const char *cp,char **endp,unsigned int base)
+long long simple_strtoll(const char *cp,const char **endp,unsigned int base)
{
if(*cp=='-')
return -simple_strtoull(cp+1,endp,base);
@@ -559,7 +559,7 @@ int sprintf(char * buf, const char *fmt,
int vsscanf(const char * buf, const char * fmt, va_list args)
{
const char *str = buf;
- char *next;
+ const char *next;
char digit;
int num = 0;
int qualifier;
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |