[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.