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] [RFC] Re: multiboot-like domain building?

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [RFC] Re: multiboot-like domain building?
From: Samuel Thibault <samuel.thibault@xxxxxxxxxxxx>
Date: Mon, 23 Nov 2009 01:25:32 +0100
Delivery-date: Sun, 22 Nov 2009 16:25:55 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <20070102231230.GI4946@xxxxxxxxxxxxxxxxxxxxxxxxxx>
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
References: <20070102231230.GI4946@xxxxxxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.12-2006-07-14
Hello,

A lot of time and things have happened since my initial post, but at
last I took the time to implement something to support multiboot-like
domain building.

As was discussed at the time, the principle would be to just stuff
modules and command lines into a big module with a multiboot
header, and let the guest unpack it.  The patch below simply adds a
xen_multiboot_mod_list structure that is used almost exactly like the
multiboot standard, and a SIF_ flag to announce that the PV module is
not a simple module but a multiboot module that should be unpacked.

The second part of my patch is a packing implementation in pv-grub,
which does boot GNU/Hurd as expected.

Does it look sane to people?

Samuel

diff -r bec27eb6f72c xen/include/public/xen.h
--- a/xen/include/public/xen.h  Sat Nov 14 10:32:59 2009 +0000
+++ b/xen/include/public/xen.h  Mon Nov 23 01:16:42 2009 +0100
@@ -581,9 +581,30 @@
 #define console_evtchn console.domU.evtchn
 #endif
 
+/*
+ * A multiboot module is a sort of package containing modules very similar to a
+ * multiboot module list. The only differences are:
+ * - the list of module descriptors is at the beginning of the multiboot 
module,
+ * - addresses are based on the beginning of the multiboot module,
+ * - the number of modules is determined by a termination entry that has
+ *   mod_start == 0.
+ */
+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 command line */
+    uint32_t cmdline;
+    /* Unused, must be zero */
+    uint32_t pad;
+};
+
 /* 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 */
 
 typedef struct dom0_vga_console_info {



diff -r bec27eb6f72c stubdom/grub.patches/99minios
--- a/stubdom/grub.patches/99minios     Sat Nov 14 10:32:59 2009 +0000
+++ b/stubdom/grub.patches/99minios     Mon Nov 23 01:16:42 2009 +0100
@@ -151,6 +151,14 @@
  
  /* 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 bec27eb6f72c stubdom/grub/config.h
--- a/stubdom/grub/config.h     Sat Nov 14 10:32:59 2009 +0000
+++ b/stubdom/grub/config.h     Mon Nov 23 01:16:42 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 bec27eb6f72c stubdom/grub/kexec.c
--- a/stubdom/grub/kexec.c      Sat Nov 14 10:32:59 2009 +0000
+++ b/stubdom/grub/kexec.c      Mon Nov 23 01:16:42 2009 +0100
@@ -103,7 +103,7 @@
     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 @@
     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 bec27eb6f72c stubdom/grub/mini-os.c
--- a/stubdom/grub/mini-os.c    Sat Nov 14 10:32:59 2009 +0000
+++ b/stubdom/grub/mini-os.c    Mon Nov 23 01:16:42 2009 +0100
@@ -173,6 +173,8 @@
 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 @@
     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 @@
 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

<Prev in Thread] Current Thread [Next in Thread>