[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |