Hi, I''m currently porting Mach to Xen, and I need to preload several Mach modules and give them command lines. The limited "ramdisk" feature of Xen doesn''t permits this. Maybe xen''s domain building process could include a notion of module with associated command line? For instance, a bit like grub''s multiboot module syntax: modules = [ "/foo/bar arg1 arg2", "/baz arg3" ] Samuel _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
On 2/1/07 23:12, "Samuel Thibault" <samuel.thibault@ens-lyon.org> wrote:> I''m currently porting Mach to Xen, and I need to preload several Mach > modules and give them command lines. The limited "ramdisk" feature of > Xen doesn''t permits this. Maybe xen''s domain building process could > include a notion of module with associated command line? For instance, > a bit like grub''s multiboot module syntax: > > modules = [ "/foo/bar arg1 arg2", "/baz arg3" ]Fine. You could load them into contiguous memory with a header on the front, and call the whole thing a ''ramdisk''. Then your changes to Mach start of day can simply unpack the ''ramdisk'' and set up module metadata inside Mach as necessary. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Hi, Keir Fraser, le Wed 03 Jan 2007 14:55:30 +0000, a écrit :> On 2/1/07 23:12, "Samuel Thibault" <samuel.thibault@ens-lyon.org> wrote: > > > I''m currently porting Mach to Xen, and I need to preload several Mach > > modules and give them command lines. The limited "ramdisk" feature of > > Xen doesn''t permits this. Maybe xen''s domain building process could > > include a notion of module with associated command line? For instance, > > a bit like grub''s multiboot module syntax: > > > > modules = [ "/foo/bar arg1 arg2", "/baz arg3" ] > > Fine. You could load them into contiguous memory with a header on the front, > and call the whole thing a ''ramdisk''. Then your changes to Mach start of day > can simply unpack the ''ramdisk'' and set up module metadata inside Mach as > necessary.I would be fine with that. Samuel _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Samuel Thibault
2009-Nov-23 00:25 UTC
[Xen-devel] [RFC] Re: multiboot-like domain building?
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@lists.xensource.com
http://lists.xensource.com/xen-devel
This defines how multiple modules can be passed to a domain by packing
them together in 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.
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@lists.xensource.com
http://lists.xensource.com/xen-devel