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] [PATCH2] multiboot module support

Hello,

Samuel Thibault, le Wed 09 Dec 2009 15:59:15 +0100, a écrit :
> It'd make the builder more tricky, as multiboot uses absolute
> physical addresses.

Here is a patch.


This defines how multiple modules can be passed to a domain by packing them
together into a "multiboot module" the same way as the multiboot standard.  An
SIF_ flag is added to announce such package. xc_dom_multiboot_mem is added to
libxc to load such list of modules, used by PV-GRUB.

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

diff -r 8f304c003af4 stubdom/grub.patches/99minios
--- a/stubdom/grub.patches/99minios     Wed Dec 09 10:59:31 2009 +0000
+++ b/stubdom/grub.patches/99minios     Fri Dec 11 03:40:30 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 8f304c003af4 stubdom/grub/config.h
--- a/stubdom/grub/config.h     Wed Dec 09 10:59:31 2009 +0000
+++ b/stubdom/grub/config.h     Fri Dec 11 03:40:30 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, char *cmdline, void *module, long 
module_size, int multiboot_number, void **multiboot_blobs, size_t 
*multiboot_sizes, char **multiboot_cmdlines);
 struct fbfront_dev *fb_open(void *fb, int width, int height, int depth);
 void fb_close(void);
 void pv_boot (void);
diff -r 8f304c003af4 stubdom/grub/kexec.c
--- a/stubdom/grub/kexec.c      Wed Dec 09 10:59:31 2009 +0000
+++ b/stubdom/grub/kexec.c      Fri Dec 11 03:40:30 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, char *cmdline, void *module, long 
module_size, int multiboot_number, void **multiboot_blobs, size_t 
*multiboot_sizes, char **multiboot_cmdlines)
 {
     struct xc_dom_image *dom;
     int rc;
@@ -123,11 +123,11 @@
     dom = xc_dom_allocate(cmdline, features);
     dom->allocate = kexec_allocate;
 
-    dom->kernel_blob = kernel;
-    dom->kernel_size = kernel_size;
-
-    dom->ramdisk_blob = module;
-    dom->ramdisk_size = module_size;
+    xc_dom_kernel_mem(dom, kernel, kernel_size);
+    if (module)
+      xc_dom_ramdisk_mem(dom, module, module_size);
+    else if (multiboot_blobs)
+      xc_dom_multiboot_mem(dom, multiboot_number, multiboot_blobs, 
multiboot_sizes, multiboot_cmdlines);
 
     dom->flags = 0;
     dom->console_evtchn = start_info.console.domU.evtchn;
diff -r 8f304c003af4 stubdom/grub/mini-os.c
--- a/stubdom/grub/mini-os.c    Wed Dec 09 10:59:31 2009 +0000
+++ b/stubdom/grub/mini-os.c    Fri Dec 11 03:40:30 2009 +0100
@@ -172,7 +172,11 @@
 
 void *kernel_image, *module_image;
 long  kernel_size, module_size;
-char *kernel_arg, *module_arg;
+char *kernel_arg;
+void **multiboot_blobs;
+size_t *multiboot_sizes;
+char **multiboot_cmdlines;
+int multiboot_number;
 
 kernel_t
 load_image (char *kernel, char *arg, kernel_t suggested_type,
@@ -196,6 +200,13 @@
     if (module_image)
         free(module_image);
     module_image = NULL;
+    multiboot_number = 0;
+    free(multiboot_blobs);
+    multiboot_blobs = NULL;
+    free(multiboot_sizes);
+    multiboot_sizes = NULL;
+    free(multiboot_cmdlines);
+    multiboot_cmdlines = NULL;
     load_file (initrd, &module_image, &module_size);
     return ! errnum;
 }
@@ -203,20 +214,28 @@
 int
 load_module (char *module, char *arg)
 {
-    if (module_image)
-        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;
+    void *module_blob;
+    long module_size;
+
+    if (load_file (module, &module_blob, &module_size))
+        return 0;
+
+    multiboot_number++;
+    multiboot_blobs = realloc(multiboot_blobs, multiboot_number * 
sizeof(*multiboot_blobs));
+    multiboot_sizes = realloc(multiboot_sizes, multiboot_number * 
sizeof(*multiboot_sizes));
+    multiboot_cmdlines = realloc(multiboot_cmdlines, multiboot_number * 
sizeof(*multiboot_cmdlines));
+
+    multiboot_blobs[multiboot_number-1] = module_blob;
+    multiboot_sizes[multiboot_number-1] = module_size;
+    multiboot_cmdlines[multiboot_number-1] = arg;
+
+    return 1;
 }
 
 void
 pv_boot (void)
 {
-    kexec(kernel_image, kernel_size, module_image, module_size, kernel_arg);
+    kexec(kernel_image, kernel_size, kernel_arg, module_image, module_size, 
multiboot_number, multiboot_blobs, multiboot_sizes, multiboot_cmdlines);
 }
 
 /*
diff -r 8f304c003af4 tools/include/xen-foreign/reference.size
--- a/tools/include/xen-foreign/reference.size  Wed Dec 09 10:59:31 2009 +0000
+++ b/tools/include/xen-foreign/reference.size  Fri Dec 11 03:40:30 2009 +0100
@@ -1,7 +1,7 @@
 
 structs                   |  x86_32  x86_64    ia64
 
-start_info                |    1112    1168    1168
+start_info                |    1116    1176    1176
 trap_info                 |       8      16       -
 pt_fpreg                  |       -       -      16
 cpu_user_regs             |      68     200       -
diff -r 8f304c003af4 tools/libxc/xc_dom.h
--- a/tools/libxc/xc_dom.h      Wed Dec 09 10:59:31 2009 +0000
+++ b/tools/libxc/xc_dom.h      Fri Dec 11 03:40:30 2009 +0100
@@ -35,6 +35,10 @@
     size_t kernel_size;
     void *ramdisk_blob;
     size_t ramdisk_size;
+    int multiboot_number;
+    void **multiboot_blobs;
+    char **multiboot_cmdlines;
+    size_t *multiboot_sizes;
 
     /* arguments and parameters */
     char *cmdline;
@@ -47,6 +51,7 @@
     /* memory layout */
     struct xc_dom_seg kernel_seg;
     struct xc_dom_seg ramdisk_seg;
+    struct xc_dom_seg multiboot_seg;
     struct xc_dom_seg p2m_seg;
     struct xc_dom_seg pgtables_seg;
     struct xc_dom_seg devicetree_seg;
@@ -168,6 +173,10 @@
                       size_t memsize);
 int xc_dom_ramdisk_mem(struct xc_dom_image *dom, const void *mem,
                        size_t memsize);
+int xc_dom_multiboot_mem(struct xc_dom_image *dom, int multiboot_number,
+                         void **multiboot_blobs,
+                         size_t *multiboot_sizes,
+                         char **multiboot_cmdlines);
 
 int xc_dom_parse_image(struct xc_dom_image *dom);
 struct xc_dom_arch *xc_dom_find_arch_hooks(char *guest_type);
diff -r 8f304c003af4 tools/libxc/xc_dom_core.c
--- a/tools/libxc/xc_dom_core.c Wed Dec 09 10:59:31 2009 +0000
+++ b/tools/libxc/xc_dom_core.c Fri Dec 11 03:40:30 2009 +0100
@@ -607,6 +607,17 @@
     return 0;
 }
 
+int xc_dom_multiboot_mem(struct xc_dom_image *dom, int number,
+                         void **mems, size_t *memsizes, char **cmdlines)
+{
+    xc_dom_printf("%s: called\n", __FUNCTION__);
+    dom->multiboot_number = number;
+    dom->multiboot_blobs = mems;
+    dom->multiboot_sizes = memsizes;
+    dom->multiboot_cmdlines = cmdlines;
+    return 0;
+}
+
 int xc_dom_parse_image(struct xc_dom_image *dom)
 {
     int i;
@@ -757,6 +768,54 @@
             memcpy(ramdiskmap, dom->ramdisk_blob, dom->ramdisk_size);
     }
 
+    /* load multiboot modules */
+    if ( dom->multiboot_blobs )
+    {
+        void *multibootmap;
+        int i;
+        struct xen_multiboot_mod_list *module;
+        char *module_cmdline;
+        void *module_blob;
+        size_t totsize = 0;
+        size_t headers_size = 0;
+        size_t cmdlines_size = 0;
+
+        for (i = 0; i < dom->multiboot_number; i++) {
+            totsize += ROUNDUP(dom->multiboot_sizes[i], page_size);
+            headers_size += sizeof(*module);
+            cmdlines_size += strlen(dom->multiboot_cmdlines[i]) + 1;
+        }
+
+        totsize += ROUNDUP(headers_size + cmdlines_size, page_size);
+
+        if (xc_dom_alloc_segment(dom, &dom->multiboot_seg, "multiboot", 0, 
totsize))
+            goto err;
+        multibootmap = xc_dom_seg_to_ptr(dom, &dom->multiboot_seg);
+
+        module = multibootmap;
+        module_cmdline = multibootmap + headers_size;
+        module_blob = multibootmap + headers_size + cmdlines_size;
+
+        for (i = 0; i < dom->multiboot_number; i++) {
+            int len = strlen(dom->multiboot_cmdlines[i]) + 1;
+            memcpy(module_cmdline, dom->multiboot_cmdlines[i], len);
+            module->cmdline = (void*) module_cmdline - multibootmap
+                            + dom->multiboot_seg.vstart - dom->parms.virt_base;
+            module_cmdline += len;
+
+            memcpy(module_blob, dom->multiboot_blobs[i],
+                   dom->multiboot_sizes[i]);
+            module->mod_start = (void*) module_blob - multibootmap
+                            + dom->multiboot_seg.vstart - dom->parms.virt_base;
+            module->mod_end = module->mod_start + dom->multiboot_sizes[i] - 1;
+            module_blob += ROUNDUP(dom->multiboot_sizes[i], page_size);
+
+            module->pad = 0;
+
+            module++;
+        }
+    }
+
     /* allocate other pages */
     if ( dom->arch_hooks->alloc_magic_pages(dom) != 0 )
         goto err;
diff -r 8f304c003af4 tools/libxc/xc_dom_ia64.c
--- a/tools/libxc/xc_dom_ia64.c Wed Dec 09 10:59:31 2009 +0000
+++ b/tools/libxc/xc_dom_ia64.c Fri Dec 11 03:40:30 2009 +0100
@@ -69,6 +69,17 @@
         bp->initrd_start = start_info->mod_start;
         bp->initrd_size = start_info->mod_len;
     }
+
+    if ( dom->multiboot_blobs )
+    {
+        start_info->mod_start = dom->multiboot_seg.vstart;
+        start_info->mod_len = dom->multiboot_seg.vend - 
dom->multiboot_seg.vstart;
+        start_info->mods_count = dom->multiboot_number;
+        bp->initrd_start = start_info->mod_start;
+        bp->initrd_size = start_info->mod_len;
+        dom->flags |= SIF_MULTIBOOT_MOD;
+    }
+
     bp->command_line = (dom->start_info_pfn << PAGE_SHIFT_IA64)
         + offsetof(start_info_t, cmd_line);
     if ( dom->cmdline )
diff -r 8f304c003af4 tools/libxc/xc_dom_x86.c
--- a/tools/libxc/xc_dom_x86.c  Wed Dec 09 10:59:31 2009 +0000
+++ b/tools/libxc/xc_dom_x86.c  Fri Dec 11 03:40:30 2009 +0100
@@ -441,6 +441,14 @@
         start_info->mod_len = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart;
     }
 
+    if ( dom->multiboot_blobs )
+    {
+        start_info->mod_start = dom->multiboot_seg.vstart;
+        start_info->mod_len = dom->multiboot_seg.vend - 
dom->multiboot_seg.vstart;
+        start_info->mods_count = dom->multiboot_number;
+        dom->flags |= SIF_MULTIBOOT_MOD;
+    }
+
     if ( dom->cmdline )
     {
         strncpy((char *)start_info->cmd_line, dom->cmdline, MAX_GUEST_CMDLINE);
@@ -481,6 +489,14 @@
         start_info->mod_len = dom->ramdisk_seg.vend - dom->ramdisk_seg.vstart;
     }
 
+    if ( dom->multiboot_blobs )
+    {
+        start_info->mod_start = dom->multiboot_seg.vstart;
+        start_info->mod_len = dom->multiboot_seg.vend - 
dom->multiboot_seg.vstart;
+        start_info->mods_count = dom->multiboot_number;
+        dom->flags |= SIF_MULTIBOOT_MOD;
+    }
+
     if ( dom->cmdline )
     {
         strncpy((char *)start_info->cmd_line, dom->cmdline, MAX_GUEST_CMDLINE);
diff -r 8f304c003af4 xen/include/public/xen.h
--- a/xen/include/public/xen.h  Wed Dec 09 10:59:31 2009 +0000
+++ b/xen/include/public/xen.h  Fri Dec 11 03:40:30 2009 +0100
@@ -572,6 +572,7 @@
     /* The pfn range here covers both page table and p->m table frames.   */
     unsigned long first_p2m_pfn;/* 1st pfn forming initial P->M table.    */
     unsigned long nr_p2m_frames;/* # of pfns forming initial P->M table.  */
+    unsigned long mods_count;   /* Number of multiboot modules.           */
 };
 typedef struct start_info start_info_t;
 
@@ -584,8 +585,25 @@
 /* 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 like a multiboot module
+ * array.
+ */
+struct xen_multiboot_mod_list
+{
+    /* PHYSICAL address of first byte of the module */
+    unsigned long mod_start;
+    /* PHYSICAL address of last byte of the module (inclusive) */
+    unsigned long mod_end;
+    /* PHYSICAL address of zero-terminated command line */
+    unsigned long cmdline;
+    /* Unused, must be zero */
+    unsigned long pad;
+};
+
 typedef struct dom0_vga_console_info {
     uint8_t video_type; /* DOM0_VGA_CONSOLE_??? */
 #define XEN_VGATYPE_TEXT_MODE_3 0x03

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