WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH] multiboot-like module support

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH] multiboot-like module support
From: Samuel Thibault <samuel.thibault@xxxxxxxxxxxx>
Date: Wed, 9 Dec 2009 15:01:49 +0100
Delivery-date: Wed, 09 Dec 2009 06:02:11 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Mail-followup-to: Samuel Thibault <samuel.thibault@xxxxxxxxxxxx>, xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.12-2006-07-14
This defines how multiple modules can be passed to a domain by packing
them together into a "multiboot module" in a way very similar to the
multiboot standard.  An SIF_ flag is added to announce such package.
This also adds a packing implementation to PV-GRUB.

Signed-Off-By: Samuel Thibault <samuel.thibault@xxxxxxxxxxxx>

diff -r d0b030008814 xen/include/public/xen.h
--- a/xen/include/public/xen.h  Fri Nov 27 08:09:26 2009 +0000
+++ b/xen/include/public/xen.h  Sun Nov 29 13:17:38 2009 +0100
@@ -584,8 +584,35 @@ typedef struct start_info start_info_t;
 /* These flags are passed in the 'flags' field of start_info_t. */
 #define SIF_PRIVILEGED    (1<<0)  /* Is the domain privileged? */
 #define SIF_INITDOMAIN    (1<<1)  /* Is this the initial control domain? */
+#define SIF_MULTIBOOT_MOD (1<<2)  /* Is mod_start a multiboot module? */
 #define SIF_PM_MASK       (0xFF<<8) /* reserve 1 byte for xen-pm options */
 
+/*
+ * A multiboot module is a package containing modules very similar to a
+ * multiboot module array. The only differences are:
+ * - the array of module descriptors is by convention simply at the beginning
+ *   of the multiboot module,
+ * - addresses in the module descriptors are based on the beginning of the
+ *   multiboot module,
+ * - the number of modules is determined by a termination descriptor that has
+ *   mod_start == 0.
+ *
+ * This permits to both build it statically and reference it in a configuration
+ * file, and let the PV guest easily rebase the addresses to virtual addresses
+ * and at the same time count the number of modules.
+ */
+struct xen_multiboot_mod_list
+{
+    /* Address of first byte of the module */
+    uint32_t mod_start;
+    /* Address of last byte of the module (inclusive) */
+    uint32_t mod_end;
+    /* Address of zero-terminated command line */
+    uint32_t cmdline;
+    /* Unused, must be zero */
+    uint32_t pad;
+};
+
 typedef struct dom0_vga_console_info {
     uint8_t video_type; /* DOM0_VGA_CONSOLE_??? */
 #define XEN_VGATYPE_TEXT_MODE_3 0x03
diff -r d0b030008814 stubdom/grub.patches/99minios
--- a/stubdom/grub.patches/99minios     Fri Nov 27 08:09:26 2009 +0000
+++ b/stubdom/grub.patches/99minios     Sun Nov 29 13:17:38 2009 +0100
@@ -151,6 +151,14 @@ Index: grub/stage2/builtins.c
  
  /* print */
  static int
+@@ -2910,6 +2910,7 @@
+   switch (kernel_type)
+     {
+     case KERNEL_TYPE_MULTIBOOT:
++    case KERNEL_TYPE_PV:
+       if (mb_cmdline + len + 1 > (char *) MB_CMDLINE_BUF + MB_CMDLINE_BUFLEN)
+       {
+         errnum = ERR_WONT_FIT;
 @@ -3776,6 +3802,7 @@
  };
  
diff -r d0b030008814 stubdom/grub/config.h
--- a/stubdom/grub/config.h     Fri Nov 27 08:09:26 2009 +0000
+++ b/stubdom/grub/config.h     Sun Nov 29 13:17:38 2009 +0100
@@ -5,7 +5,7 @@
 #define debug _debug
 #define grub_halt(a) do_exit()
 #define printf grub_printf
-void kexec(void *kernel, long kernel_size, void *module, long module_size, 
char *cmdline);
+void kexec(void *kernel, long kernel_size, void *module, long module_size, 
char *cmdline, unsigned long flags);
 struct fbfront_dev *fb_open(void *fb, int width, int height, int depth);
 void fb_close(void);
 void pv_boot (void);
diff -r d0b030008814 stubdom/grub/kexec.c
--- a/stubdom/grub/kexec.c      Fri Nov 27 08:09:26 2009 +0000
+++ b/stubdom/grub/kexec.c      Sun Nov 29 13:17:38 2009 +0100
@@ -103,7 +103,7 @@ int kexec_allocate(struct xc_dom_image *
     return 0;
 }
 
-void kexec(void *kernel, long kernel_size, void *module, long module_size, 
char *cmdline)
+void kexec(void *kernel, long kernel_size, void *module, long module_size, 
char *cmdline, unsigned long flags)
 {
     struct xc_dom_image *dom;
     int rc;
@@ -129,7 +129,7 @@ void kexec(void *kernel, long kernel_siz
     dom->ramdisk_blob = module;
     dom->ramdisk_size = module_size;
 
-    dom->flags = 0;
+    dom->flags = flags;
     dom->console_evtchn = start_info.console.domU.evtchn;
     dom->xenstore_evtchn = start_info.store_evtchn;
 
diff -r d0b030008814 stubdom/grub/mini-os.c
--- a/stubdom/grub/mini-os.c    Fri Nov 27 08:09:26 2009 +0000
+++ b/stubdom/grub/mini-os.c    Sun Nov 29 13:17:38 2009 +0100
@@ -173,6 +173,8 @@ load_file(char *name, void **ptr, long *
 void *kernel_image, *module_image;
 long  kernel_size, module_size;
 char *kernel_arg, *module_arg;
+void *multiboot_next_module;
+struct xen_multiboot_mod_list *multiboot_next_module_header;
 
 kernel_t
 load_image (char *kernel, char *arg, kernel_t suggested_type,
@@ -196,6 +198,8 @@ load_initrd (char *initrd)
     if (module_image)
         free(module_image);
     module_image = NULL;
+    multiboot_next_module = NULL;
+    multiboot_next_module_header = NULL;
     load_file (initrd, &module_image, &module_size);
     return ! errnum;
 }
@@ -203,20 +207,76 @@ load_initrd (char *initrd)
 int
 load_module (char *module, char *arg)
 {
-    if (module_image)
+    void *new_module, *new_module_image;
+    long new_module_size, rounded_new_module_size;
+
+    if (load_file (module, &new_module, &new_module_size))
+        return 0;
+    if (strlen(arg) >= PAGE_SIZE) {
+        /* Too big module command line */
+        errnum = ERR_WONT_FIT;
+        return 0;
+    }
+    rounded_new_module_size = (new_module_size + PAGE_SIZE - 1) & PAGE_MASK;
+
+    if (module_image && !multiboot_next_module_header) {
+        /* Initrd already loaded, drop it */
         free(module_image);
-    module_image = NULL;
-    load_file (module, &module_image, &module_size);
-    if (module_arg)
-        free(module_arg);
-    module_arg = strdup(arg);
-    return ! errnum;
+        if (module_arg)
+            free(module_arg);
+        module_image = NULL;
+    }
+    if (!module_image)
+        /* Reserve one page for the header */
+        multiboot_next_module = (void*) PAGE_SIZE;
+
+    /* Allocate more room for the new module plus its arg */
+    new_module_image = realloc(module_image,
+            (multiboot_next_module - module_image) + rounded_new_module_size + 
PAGE_SIZE);
+
+    /* Update pointers */
+    multiboot_next_module += new_module_image - module_image;
+    multiboot_next_module_header = (void*) multiboot_next_module_header + 
(new_module_image - module_image);
+    module_image = new_module_image;
+
+    if ((void*) (multiboot_next_module_header+1) - module_image > PAGE_SIZE) {
+        /* Too many modules */
+        ERR_WONT_FIT;
+        return 0;
+    }
+
+    /* Copy module */
+    memcpy(multiboot_next_module, new_module, new_module_size);
+    multiboot_next_module_header->mod_start = multiboot_next_module - 
module_image;
+    multiboot_next_module_header->mod_end = 
multiboot_next_module_header->mod_start + new_module_size - 1;
+    multiboot_next_module += rounded_new_module_size;
+
+    /* Copy cmdline */
+    strcpy(multiboot_next_module, arg);
+    multiboot_next_module_header->cmdline = multiboot_next_module - 
module_image;
+    multiboot_next_module += PAGE_SIZE;
+
+    /* Pad */
+    multiboot_next_module_header->pad = 0;
+
+    multiboot_next_module_header++;
+
+    return 1;
 }
 
 void
 pv_boot (void)
 {
-    kexec(kernel_image, kernel_size, module_image, module_size, kernel_arg);
+    unsigned long flags = 0;
+    if (multiboot_next_module_header) {
+        /* Termination entry */
+        multiboot_next_module_header->mod_start = 0;
+        /* Total size */
+        module_size = multiboot_next_module - module_image;
+        /* It's a multiboot module */
+        flags |= SIF_MULTIBOOT_MOD;
+    }
+    kexec(kernel_image, kernel_size, module_image, module_size, kernel_arg, 
flags);
 }
 
 /*

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel