All of lore.kernel.org
 help / color / mirror / Atom feed
* RFC/Patch: Support for other bootloaders
@ 2005-03-21 12:15 Michal Ostrowski
  0 siblings, 0 replies; 27+ messages in thread
From: Michal Ostrowski @ 2005-03-21 12:15 UTC (permalink / raw)
  To: xen-devel


[-- Attachment #1.1: Type: text/plain, Size: 1300 bytes --]


I need to net-boot xen on an HS20 blade.  HS20's have a Broadcom NIC,
which is not supported by grub.  The attached patch allows me to build a
Xen image which I can boot using PXELinux  (and the entire SysLinux
family of boot-loaders).

PXELinux should work with any PXE-enabled NIC and thus does not face the
same driver-support issues as grub.

This functionality is enabled by using the Linux code that is wrapped
around a vmlinux to form a zImage.  I've come up with two ways of doing
this; as part of the xen build, or a seperate shell-script ("mkzen").

Both methods reach into a specified Linux-kernel build tree to grab the
bits for the wrapper.  The result, from the boot-loader's point of view
looks identical to a zImage.

However, running in this environment, Xen must now accept arguments in
the format used between a zImage and a vmlinux and distinguish between
this format and the multi-boot format.

Also, since grub is not being used, loading of multiple modules is not
supported.  Thus I've created a tool to package multiple images, with
parameter lists into a "meta-ramdisk".  My patch also includes code for
Xen to extract multiple images from such a meta-ramdisk.

Comments/suggestions appreciated.

-- 
Michal Ostrowski <mostrows@watson.ibm.com>

[-- Attachment #1.2: bootloader.patch --]
[-- Type: text/x-patch, Size: 26857 bytes --]

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/03/20 16:10:07-05:00 mostrows@heater.watson.ibm.com 
#   Support being booted by arbitrary boot-loaders with bzImage code from Linux.
#   Wrap xen with Linux's bzImage code, either through support in Makefiles or via 
#   the mkzen script.  Both methods require that one specify the location
#   of a linux i386 build tree, from which we extract the necessary bits.
#   
#   Booting with the bzImage code requires that xen recognize parameters in the format 
#   that vmlinux expects. Have __setup_xen be able to recognize both kinds of parameter
#   formats.
#   
#   Using non-grub boot-loaders means that we'll only see one module loaded in addition
#   to the "kernel" image.
#   
#   Add a "mkmetard" tool to create "meta-ramdisks" which can include multiple modules with
#   parameters, all packaged into one ramdisk image.
#   
#   Support decomposition of meta-ramdisks in xen.
# 
# xen/arch/x86/mkzen
#   2005/03/20 16:10:06-05:00 mostrows@heater.watson.ibm.com +76 -0
# 
# xen/tools/Makefile
#   2005/03/20 16:10:06-05:00 mostrows@heater.watson.ibm.com +3 -1
#   Built the mkmetard tool.
# 
# xen/include/xen/multiboot.h
#   2005/03/20 16:10:06-05:00 mostrows@heater.watson.ibm.com +4 -0
#   Reasonable max number of MBI modules.
# 
# xen/arch/x86/setup.c
#   2005/03/20 16:10:06-05:00 mostrows@heater.watson.ibm.com +190 -44
#   Support being booted by arbitrary boot-loaders with bzImage code from Linux.
#   Thus, parameters may be passed via pointer in %esi.  Add appropriate checks to
#   detect parameters of this form vs. multi-boot.
#   
#   Add code to extract parameter and system data (e820 memory maps) from either multi-boot
#   or Linux parameter formats.
#   
#   If using Linux parameter format, it is possible that the single ramdisk is a "meta-ramdisk",
#   with a multi-boot-like record that describes multiple module images and parameter
#   strings.
# 
# xen/arch/x86/mkzen
#   2005/03/20 16:10:06-05:00 mostrows@heater.watson.ibm.com +0 -0
#   BitKeeper file /home/mostrows/xen/xeno-unstable.bk/xen/arch/x86/mkzen
# 
# xen/arch/x86/boot/x86_32.S
#   2005/03/20 16:10:06-05:00 mostrows@heater.watson.ibm.com +9 -7
#   Support being booted by arbitrary boot-loaders with bzImage code from Linux.
#   Thus, parameters may be passed via pointer in %esi.  Add appropriate checks to
#   detect parameters of this form vs. multi-boot.
# 
# xen/arch/x86/Makefile
#   2005/03/20 16:10:06-05:00 mostrows@heater.watson.ibm.com +42 -0
#   Add target to build zenImg -- xen wrapped with Linux's bzImage machinery.
# 
# xen/Makefile
#   2005/03/20 16:10:06-05:00 mostrows@heater.watson.ibm.com +3 -1
#   Build mkmetard.
# 
# xen/tools/mkmetard/mkmetard.c
#   2005/03/20 15:01:15-05:00 mostrows@heater.watson.ibm.com +225 -0
# 
# xen/tools/mkmetard/Makefile
#   2005/03/20 15:01:15-05:00 mostrows@heater.watson.ibm.com +10 -0
# 
# xen/tools/mkmetard/mkmetard.c
#   2005/03/20 15:01:15-05:00 mostrows@heater.watson.ibm.com +0 -0
#   BitKeeper file /home/mostrows/xen/xeno-unstable.bk/xen/tools/mkmetard/mkmetard.c
# 
# xen/tools/mkmetard/Makefile
#   2005/03/20 15:01:15-05:00 mostrows@heater.watson.ibm.com +0 -0
#   BitKeeper file /home/mostrows/xen/xeno-unstable.bk/xen/tools/mkmetard/Makefile
# 
diff -Nru a/xen/Makefile b/xen/Makefile
--- a/xen/Makefile	2005-03-20 16:15:16 -05:00
+++ b/xen/Makefile	2005-03-20 16:15:16 -05:00
@@ -27,7 +27,7 @@
 dist: install
 
 build: $(TARGET).gz
-	
+
 install: $(TARGET).gz
 	[ -d $(DESTDIR)/boot ] || $(INSTALL_DIR) $(DESTDIR)/boot
 	$(INSTALL_DATA) $(TARGET).gz $(DESTDIR)/boot
@@ -52,9 +52,11 @@
 	[ -e include/asm ] || ln -sf asm-$(TARGET_ARCH) include/asm
 	$(MAKE) -C arch/$(TARGET_ARCH) asm-offsets.s
 	$(MAKE) include/asm-$(TARGET_ARCH)/asm-offsets.h
+	$(MAKE) -C tools/mkmetard
 	$(MAKE) -C common
 	$(MAKE) -C drivers
 	$(MAKE) -C arch/$(TARGET_ARCH)
+
 
 # drivers/char/console.o may contain static banner/compile info. Blow it away.
 delete-unfresh-files:
diff -Nru a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile	2005-03-20 16:15:16 -05:00
+++ b/xen/arch/x86/Makefile	2005-03-20 16:15:16 -05:00
@@ -15,7 +15,11 @@
 OBJS := $(patsubst cdb%.o,,$(OBJS))
 endif
 
+ifdef LINUX_BUILD
+default: $(TARGET) zenImg
+else
 default: $(TARGET)
+endif
 
 $(TARGET): $(TARGET)-syms boot/mkelf32
 	./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000
@@ -32,6 +36,44 @@
 
 boot/mkelf32: boot/mkelf32.c
 	$(HOSTCC) $(HOSTCFLAGS) -o $@ $<
+
+
+ifdef LINUX_BUILD
+
+#
+# Check Makefile in Linux build dir.  If it contains KERNELSRC, then use
+# that as source dir, otherwise build==source dir
+LINUX_SRC:= $(shell if grep -q KERNELSRC $(LINUX_BUILD)/Makefile ; then \
+			sed -e '/^KERNELSRC/!d' $(LINUX_BUILD)/Makefile | \
+			bash -c '( read A B C ; echo -n $$C)' ; \
+		    else \
+			echo -n $(LINUX_BUILD); \
+		    fi )
+
+$(TARGET).bin: $(TARGET)
+	$(OBJCOPY) -O binary -R .note -R .comment -S  $^ $@
+
+$(TARGET).bin.gz: $(TARGET).bin
+	gzip -f -9 < $< > $@
+
+piggy.o: $(TARGET).bin.gz
+	$(LD) -m elf_i386  -r --format binary --oformat elf32-i386 \
+	-T $(LINUX_SRC)/arch/i386/boot/compressed/vmlinux.scr $< -o $@
+
+zen:	$(LINUX_BUILD)/arch/i386/boot/compressed/head.o \
+	$(LINUX_BUILD)/arch/i386/boot/compressed/misc.o \
+	piggy.o
+	$(LD) -m elf_i386  -Ttext 0x100000 -e startup_32 $^ -o $@
+
+zenImg: zen
+	$(OBJCOPY) -O binary -R .note -R .comment -S  $^ $@.tmp
+	$(LINUX_BUILD)/arch/i386/boot/tools/build \
+		-b $(LINUX_BUILD)/arch/i386/boot/bootsect \
+		$(LINUX_BUILD)/arch/i386/boot/setup $@.tmp > $@
+
+
+endif
+
 
 clean:
 	rm -f *.o *.s *~ core boot/*.o boot/*~ boot/core boot/mkelf32
diff -Nru a/xen/arch/x86/boot/x86_32.S b/xen/arch/x86/boot/x86_32.S
--- a/xen/arch/x86/boot/x86_32.S	2005-03-20 16:15:16 -05:00
+++ b/xen/arch/x86/boot/x86_32.S	2005-03-20 16:15:16 -05:00
@@ -55,7 +55,7 @@
         mov     %ecx,%gs
         ljmp    $(__HYPERVISOR_CS),$(1f)-__PAGE_OFFSET
 1:      lss     stack_start-__PAGE_OFFSET,%esp
-
+	
         /* Reset EFLAGS (subsumes CLI and CLD). */
 	pushl	$0
 	popf
@@ -82,15 +82,17 @@
         and     $0x7f,%cl   # CR4.PGE (global enable)
         mov     %ecx,%cr4
                 
+        /* Check for Multiboot bootloader */
+        cmp     $0x2BADB002,%eax
+        je     1f
+	/* No multi-boot?  Hope that we've got a Linux boot-params */
+	/* stashed in esi. Save in %ebx until stack is ready. */
+	movl	%esi, %ebx
+1:
         cmp     $(SECONDARY_CPU_FLAG),%ebx
         je      start_paging
                 
-        /* Check for Multiboot bootloader */
-        cmp     $0x2BADB002,%eax
-        jne     not_multiboot
-
-        /* Save the Multiboot info structure for later use. */
-	add     $__PAGE_OFFSET,%ebx
+	/* Stack is now ready, so store boot parameter pointer */
         push    %ebx
 
         /* Initialize BSS (no nasty surprises!) */
diff -Nru a/xen/arch/x86/mkzen b/xen/arch/x86/mkzen
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/xen/arch/x86/mkzen	2005-03-20 16:15:16 -05:00
@@ -0,0 +1,76 @@
+#!/bin/bash
+#
+# Copyright (C) 2005 Michal Ostrowski <mostrows@watson.ibm.com>, 
+#					  IBM Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+
+
+# Reaches into a Linux build tree and uses objects and scripts from
+# linux to wrap a Xen ELF image in the Linuz bzImage machinery,
+# allowing the resulting "zen" image to be booted using any
+# boot-loader thant can load a Linux bzImage.
+
+#
+# Usage: mkzen <LINUX_BUILD> <XEN IMAGE> <ZEN>
+
+set -e
+LINUX_BUILD=$1
+XEN=$2
+ZEN=$3
+
+: ${CROSS_COMPILE:=}
+: ${OBJCOPY:=${CROSS_COMPILE}objcopy}
+: ${LD:=${CROSS_COMPILE}ld}
+
+function cleanup(){
+    rm -f ${XEN}.bin.$$ ${XEN}.bin.gz.$$ ${XEN}.piggy.o.$$
+    rm -f ${ZEN}.1.$$ ${ZEN}.2.$$
+}
+
+trap cleanup ERR
+
+#
+# Check Makefile in Linux build dir.  If it contains KERNELSRC, then use
+# that as source dir, otherwise build==source dir
+#
+LINUX_SRC=`sed -e '/^KERNELSRC/!d;s/^.*:=[ ]*//'  <${LINUX_BUILD}/Makefile`
+if [ -z "${LINUX_SRC}" ]; then
+    LINUX_SRC=${LINUX_BUILD};
+fi
+
+${OBJCOPY} -O binary -R .note -R .comment -S ${XEN} ${XEN}.bin.$$
+
+gzip -f -9 < ${XEN}.bin.$$ > ${XEN}.bin.gz.$$
+
+${LD} -m elf_i386  -r --format binary --oformat elf32-i386 \
+    -T ${LINUX_SRC}/arch/i386/boot/compressed/vmlinux.scr \
+    ${XEN}.bin.gz -o ${XEN}.piggy.o.$$
+
+
+${LD} -m elf_i386  -Ttext 0x100000 -e startup_32 \
+    ${LINUX_BUILD}/arch/i386/boot/compressed/head.o \
+    ${LINUX_BUILD}/arch/i386/boot/compressed/misc.o ${XEN}.piggy.o.$$ \
+    -o ${ZEN}.1.$$
+
+${OBJCOPY} -O binary -R .note -R .comment -S  ${ZEN}.1.$$ ${ZEN}.2.$$
+
+${LINUX_BUILD}/arch/i386/boot/tools/build \
+    -b ${LINUX_BUILD}/arch/i386/boot/bootsect \
+    ${LINUX_BUILD}/arch/i386/boot/setup ${ZEN}.2.$$ > ${ZEN}
+
+
+cleanup
\ No newline at end of file
diff -Nru a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c	2005-03-20 16:15:16 -05:00
+++ b/xen/arch/x86/setup.c	2005-03-20 16:15:16 -05:00
@@ -86,6 +86,24 @@
 int phys_proc_id[NR_CPUS];
 int logical_proc_id[NR_CPUS];
 
+
+/* Details about what is found where in the Linux boot parameters area. */
+/* Put into a seperate header if it grows much more. */
+#define PARAM_SIZE              2048
+#define COMMAND_LINE_SIZE       256
+#define NEW_CL_POINTER          0x228
+#define E820NR                  0x1e8
+#define E820MAP                 0x2d0
+#define INITRD_START            0x218
+#define INITRD_SIZE             0x21c
+
+static unsigned char boot_params[PARAM_SIZE];
+static unsigned char cmd_line_buf[COMMAND_LINE_SIZE];
+static unsigned char dom0_cmd_line_buf[COMMAND_LINE_SIZE];
+static module_t boot_modules[MAX_MBI_MODULES];
+
+
+
 /* Standard macro to see if a specific flag is changeable. */
 static inline int flag_is_changeable_p(unsigned long flag)
 {
@@ -453,36 +471,19 @@
 #endif
 }
 
-void __init __start_xen(multiboot_info_t *mbi)
+static int __init boot_param_e820_setup(unsigned char *boot_params, 
+                                        struct e820entry *e820raw)
 {
-    char *cmdline;
-    module_t *mod = (module_t *)__va(mbi->mods_addr);
-    void *heap_start;
-    unsigned long firsthole_start, nr_pages;
-    unsigned long initial_images_start, initial_images_end;
-    struct e820entry e820_raw[E820MAX];
-    int i, e820_raw_nr = 0, bytes = 0;
-
-    /* Parse the command-line options. */
-    if ( (mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0) )
-        cmdline_parse(__va(mbi->cmdline));
-
-    /* Must do this early -- e.g., spinlocks rely on get_current(). */
-    set_current(&idle0_exec_domain);
-
-    /* We initialise the serial devices very early so we can get debugging. */
-    serial_init_stage1();
-
-    init_console();
-
-    /* Check that we have at least one Multiboot module. */
-    if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
-    {
-        printk("FATAL ERROR: Require at least one Multiboot module.\n");
-        for ( ; ; ) ;
-    }
+    int e820_raw_nr = *(int*)&boot_params[E820NR];
+    memcpy(e820raw, boot_params + E820MAP, e820_raw_nr * sizeof(*e820raw));
+    return e820_raw_nr;
+}
 
-    xenheap_phys_end = opt_xenheap_megabytes << 20;
+static int __init mbi_e820_setup(multiboot_info_t *mbi, 
+                                 struct e820entry *e820_raw)
+{
+    int bytes = 0;
+    int e820_raw_nr = 0;
 
     if ( mbi->flags & MBI_MEMMAP )
     {
@@ -509,14 +510,154 @@
         e820_raw[1].type = E820_RAM;
         e820_raw_nr = 2;
     }
+    return e820_raw_nr;
+}
+
+int __init mbi_boot_modules(multiboot_info_t *mbi)
+{
+    /* Check that we have at least one Multiboot module. */
+    if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
+    {
+        printk("FATAL ERROR: Require at least one Multiboot module.\n");
+        for ( ; ; ) ;
+    }
+
+    memcpy(&boot_modules, __va(mbi->mods_addr), 
+           sizeof(module_t) * mbi->mods_count);
+    return mbi->mods_count;
+}
+
+int __init boot_param_modules(unsigned char *params)
+{
+    u32 rd = *(u32*)&boot_params[INITRD_START];
+    int size = *(int*)&boot_params[INITRD_SIZE];
+
+    boot_modules[0].mod_start = rd;
+    boot_modules[0].mod_end = rd + size;
+    boot_modules[0].string = 0;
+    boot_modules[0].reserved = 0;
+
+    u32 *magic = (u32*)boot_modules[0].mod_start;
+    u32 num_modules = magic[1];
+    u32 base = boot_modules[0].mod_start;
+    
+    printf("Multi-module: %x %d %x\n", *magic, num_modules, base);
+    printf("Module: %x %x %x\n",
+           boot_modules[0].mod_start, boot_modules[0].mod_end,
+           boot_modules[0].string);
+    
+
+    if ( *magic != MULTIBOOT_BOOTLOADER_MAGIC )
+    {
+        return 1;
+    }
+    
+    memcpy(&boot_modules[0], (void*)(base + sizeof(u32) * 2), 
+                                     num_modules * sizeof(module_t));
+    printf("Module: %x %x %x\n",
+           boot_modules[0].mod_start, boot_modules[0].mod_end,
+           boot_modules[0].string);
+    
+    int i = 0;
+    for ( ; i < num_modules; ++i) 
+    {
+        boot_modules[i].mod_start += base;
+        boot_modules[i].mod_end += base;
+        boot_modules[i].string += base;
+    }
+    printf("Module: %x %x %x\n",
+           boot_modules[0].mod_start, boot_modules[0].mod_end,
+           boot_modules[0].string);
+    return num_modules;
+}
+
+void __init __start_xen(void *params)
+{
+    char *cmdline = NULL;
+    void *heap_start;
+    unsigned long firsthole_start, nr_pages;
+    unsigned long initial_images_start, initial_images_end;
+    struct e820entry e820_raw[E820MAX];
+    int i, e820_raw_nr = 0;
+    int num_mods = 0;
+    multiboot_info_t *mbi = NULL;
+    
+    if (MULTIBOOT_BOOTLOADER_MAGIC == *(u32*)params ) 
+    {
+        mbi = (struct multiboot_info_t*)__va(mbi);
+        if ( (mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0) ) 
+        {
+            cmdline = __va(mbi->cmdline);
+        }
+    } 
+    else 
+    {
+        /* Hope it is a Linux boot parameters area. */
+        unsigned char* orig_cmd_line;
+        memcpy(boot_params, __va(((char*)params)), PARAM_SIZE);
+        
+        orig_cmd_line = __va(*(unsigned char**)&boot_params[NEW_CL_POINTER]);
+
+        memcpy(cmd_line_buf, orig_cmd_line, COMMAND_LINE_SIZE);
+        cmdline = cmd_line_buf;
+    }
+
+    /* Parse the command-line options. */
+    cmdline_parse(cmdline);
+
+    /* Must do this early -- e.g., spinlocks rely on get_current(). */
+    set_current(&idle0_exec_domain);
+
+    /* We initialise the serial devices very early so we can get debugging. */
+    serial_init_stage1();
+
+    init_console();
+
+    xenheap_phys_end = opt_xenheap_megabytes << 20;
+
+    if ( mbi != NULL ) 
+    {
+        e820_raw_nr = mbi_e820_setup(mbi, e820_raw);
+    }
     else
     {
+        e820_raw_nr = boot_param_e820_setup(boot_params, e820_raw);
+    }
+
+    if (e820_raw_nr == 0) 
+    {
         printk("FATAL ERROR: Bootloader provided no memory information.\n");
         for ( ; ; ) ;
     }
 
     max_page = init_e820(e820_raw, e820_raw_nr);
 
+    if (mbi != NULL)
+    {
+        num_mods = mbi_boot_modules(mbi);        
+    }
+    else
+    {
+        num_mods = boot_param_modules(boot_params);
+    }
+
+    /* Save dom0 cmd line to a known place. */
+    if ( boot_modules[0].string )
+    {
+        
+#if defined(__i386__)
+        memcpy(dom0_cmd_line_buf, (void*)boot_modules[0].string, 
+               COMMAND_LINE_SIZE);
+#elif defined(__x86_64__)
+        memcpy(dom0_cmd_line_buf, __va(boot_modules[0].string), 
+               COMMAND_LINE_SIZE);
+#endif
+    } 
+    else
+    {
+        dom0_cmd_line_buf[0] = 0;
+    }
+    
     /* Find the first high-memory RAM hole. */
     for ( i = 0; i < e820.nr_map; i++ )
         if ( (e820.map[i].type == E820_RAM) &&
@@ -527,7 +668,7 @@
     /* Relocate the Multiboot modules. */
     initial_images_start = xenheap_phys_end;
     initial_images_end   = initial_images_start + 
-        (mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+        (boot_modules[num_mods - 1].mod_end - boot_modules[0].mod_start);
     if ( initial_images_end > firsthole_start )
     {
         printk("Not enough memory to stash the DOM0 kernel image.\n");
@@ -535,14 +676,14 @@
     }
 #if defined(__i386__)
     memmove((void *)initial_images_start,  /* use low mapping */
-            (void *)mod[0].mod_start,      /* use low mapping */
-            mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+            (void *)boot_modules[0].mod_start,      /* use low mapping */
+            boot_modules[num_mods - 1].mod_end - boot_modules[0].mod_start);
 #elif defined(__x86_64__)
     memmove(__va(initial_images_start),
-            __va(mod[0].mod_start),
-            mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+            __va(boot_modules[0].mod_start),
+            boot_modules[num_mods-1].mod_end - boot_modules[0].mod_start);
 #endif
-
+    
     /* Initialise boot-time allocator with all RAM situated after modules. */
     heap_start = memguard_init(&_end);
     heap_start = __va(init_boot_allocator(__pa(heap_start)));
@@ -587,7 +728,8 @@
     set_bit(DF_PRIVILEGED, &dom0->d_flags);
 
     /* Grab the DOM0 command line. Skip past the image name. */
-    cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
+    cmdline = (dom0_cmd_line_buf[0] ? dom0_cmd_line_buf : NULL);
+
     if ( cmdline != NULL )
     {
         while ( *cmdline == ' ' ) cmdline++;
@@ -599,15 +741,19 @@
      * We're going to setup domain0 using the module(s) that we stashed safely
      * above our heap. The second module, if present, is an initrd ramdisk.
      */
-    if ( construct_dom0(dom0,
-                        initial_images_start, 
-                        mod[0].mod_end-mod[0].mod_start,
-                        (mbi->mods_count == 1) ? 0 :
-                        initial_images_start + 
-                        (mod[1].mod_start-mod[0].mod_start),
-                        (mbi->mods_count == 1) ? 0 :
-                        mod[mbi->mods_count-1].mod_end - mod[1].mod_start,
-                        cmdline) != 0)
+    u32 img_size = boot_modules[0].mod_end - boot_modules[0].mod_start;
+    u32 rd_start = 0;
+    u32 rd_size = 0;
+    if ( num_mods > 1 ) 
+    {
+        rd_start = initial_images_start
+                   + boot_modules[1].mod_start - boot_modules[0].mod_start;
+
+        rd_size = boot_modules[num_mods-1].mod_end - boot_modules[1].mod_start;
+    }
+
+    if ( construct_dom0(dom0, initial_images_start, img_size,
+                        rd_start, rd_size, cmdline) != 0)
         panic("Could not set up DOM0 guest OS\n");
 
     /* Scrub RAM that is still free and so may go to an unprivileged domain. */
diff -Nru a/xen/include/xen/multiboot.h b/xen/include/xen/multiboot.h
--- a/xen/include/xen/multiboot.h	2005-03-20 16:15:16 -05:00
+++ b/xen/include/xen/multiboot.h	2005-03-20 16:15:16 -05:00
@@ -28,6 +28,10 @@
 #define MBI_MEMMAP     (1<<6)
 #define MBI_LOADERNAME (1<<9)
 
+/* Make up some reasonable maximum that we support. */
+#define MAX_MBI_MODULES 4
+
+
 /* The symbol table for a.out.  */
 typedef struct {
     u32 tabsize;
diff -Nru a/xen/tools/Makefile b/xen/tools/Makefile
--- a/xen/tools/Makefile	2005-03-20 16:15:16 -05:00
+++ b/xen/tools/Makefile	2005-03-20 16:15:16 -05:00
@@ -1,6 +1,8 @@
 
 default:
 	$(MAKE) -C figlet
+	$(MAKE) -C mkmetard
 
 clean:
-	$(MAKE) -C figlet clean
\ No newline at end of file
+	$(MAKE) -C figlet clean
+	$(MAKE) -C mkmetard clean
\ No newline at end of file
diff -Nru a/xen/tools/mkmetard/Makefile b/xen/tools/mkmetard/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/xen/tools/mkmetard/Makefile	2005-03-20 16:15:16 -05:00
@@ -0,0 +1,10 @@
+
+include ../../../Config.mk
+
+CFLAGS += -DBUILD_ARCH=$(XEN_COMPILE_ARCH) -DTARGET_ARCH=$(XEN_TARGET_ARCH)
+CFLAGS += -I$(BASEDIR)/include
+mkmetard: mkmetard.c
+	$(HOSTCC) $(CFLAGS) -o $@ $<
+
+clean:
+	rm -f *.o mkmetard
diff -Nru a/xen/tools/mkmetard/mkmetard.c b/xen/tools/mkmetard/mkmetard.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/xen/tools/mkmetard/mkmetard.c	2005-03-20 16:15:16 -05:00
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2005 Michal Ostrowski <mostrows@watson.ibm.com>, 
+ *					  IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+/* Combines several images and cmdlines into one meta-ramdisk image.
+ * For use with non-grub boot-loader that don't do "multi-boot" as
+ * grub does.
+ *
+ * Usage: mkmetard <output_file> <module1_file> <mod1_arg1> ... \
+ *								 --- <module2_file> <mod2_arg1> ...
+ * 
+ * Allows up to 4 module images.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <endian.h>
+#include <byteswap.h>
+
+
+
+/* We need to know whether build platform endianness matches that of target */
+#define LITTLE_ENDIAN_ppc		0
+#define LITTLE_ENDIAN_x86_32	1
+#define LITTLE_ENDIAN_x86_64	1
+#define LITTLE_ENDIAN_ia64		1
+
+#define __CAT(a,b)		a##b
+#define IS_LITTLE_ENDIAN(arch) __CAT(LITTLE_ENDIAN_,arch)
+
+#if IS_LITTLE_ENDIAN(BUILD_ARCH) == IS_LITTLE_ENDIAN(TARGET_ARCH)
+#define ENDIAN_MATCH	1
+#else
+#define ENDIAN_MATCH	0
+#endif
+
+
+#if ENDIAN_MATCH == 0
+#define byteswap(x)								\
+	({											\
+		typeof(x) tmp = x;						\
+		switch(sizeof(tmp))						\
+		{										\
+		case 1:									\
+			break;								\
+		case 2:									\
+			tmp = bswap_16(tmp);				\
+			break;								\
+		case 4:									\
+			tmp = bswap_32(tmp);				\
+			break;								\
+		case 8:									\
+			tmp = bswap_64(tmp);				\
+			break;								\
+		default:								\
+			printf("no valid byteswap for " #x);	\
+			tmp = 0;								\
+			break;									\
+		}											\
+		tmp;										\
+	})
+#else /* ENDIAN_MATCH == 0 */		
+#define byteswap(x) (x)
+#endif /* ENDIAN_MATCH == 0 */		
+
+
+
+/* We cannot use types.h, since we may be cross-compiling and thus
+ * don't want to pick up an asm header that doesn't match the
+ * architecture we're building for */
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+/* See if we are 32 or 64-bit */
+#if 2147483647L == __LONG_MAX__
+typedef signed long long s64;
+typedef unsigned long long u64;
+#define BITS_PER_LONG 32
+#else
+typedef signed long s64;
+typedef unsigned long u64;
+#define BITS_PER_LONG 64
+#endif
+
+#include <xen/multiboot.h>
+
+int curr_offset = 0;
+int rd_fd;
+
+static inline void 
+write_to_file(void* buf, int len)
+{
+	int ret = write(rd_fd, buf, len);
+	if (ret == len) 
+	{
+		curr_offset += ret;
+	}
+	else
+	{
+		perror("Incomplete write to ramdisk file.");
+		exit(-1);
+	}
+}
+
+
+module_t mods[MAX_MBI_MODULES];
+
+int main(int argc, char** argv)
+{
+	char* rdname = argv[1];
+	argv += 2;
+	argc -= 2;
+	
+	int mod = 0;
+	int x = 0;
+	
+	int parts[MAX_MBI_MODULES + 1] = { -1, };
+
+	parts[mod] = 0;
+
+	/* Identify cmdlines for each module */
+	while ( x < argc && mod < MAX_MBI_MODULES)
+	{
+		if ( strcmp(argv[x],"---") == 0 )
+		{
+			++x;
+			if (x < argc && mod < MAX_MBI_MODULES)
+			{
+				++mod;
+				parts[mod] = x;
+			}
+			
+		}
+		else 
+		{
+			++x;
+		}
+	}
+	++mod;
+
+	rd_fd = open(rdname, O_RDWR | O_CREAT | O_TRUNC, 0644);
+	if ( rd_fd < 0 ) perror("Can't open meta-ramdisk image file\n");
+	
+	/* Use the multi-boot magic number, can't see why not to. */
+	u32 magic = byteswap(MULTIBOOT_BOOTLOADER_MAGIC);
+	write_to_file(&magic, sizeof(magic));
+
+	magic = byteswap(mod);
+	write_to_file(&magic, sizeof(magic));
+
+	/* We'll come back and re-write this later, but we just need
+	 * filler for now */
+	write_to_file(&mods, sizeof(module_t) * mod);
+
+	for ( x = 0; x < mod; ++x ) 
+	{
+		int fd = open(argv[parts[x]], O_RDONLY);
+		if ( fd < 0 ) 
+		{
+			perror("Can't open image file");
+			exit(-1);
+		}
+		
+		char string[1024];
+		char buf[1024];
+		int size = 0;
+		int ret;
+		
+		/* Copy cmdline component */
+		string[0] = 0;
+		
+		int y = parts[x];
+		while(y < argc  && strcmp(argv[y], "---")!=0 )
+		{
+			strcpy(string + size, argv[y]);
+			size += strlen(argv[y]);
+			string[size++] = ' ';
+			++y;
+		}
+		string[size++] = 0;
+		
+		mods[x].string = byteswap(curr_offset);
+		write_to_file(string, size);
+		
+		/* Now copy module image */
+		mods[x].mod_start = byteswap(curr_offset);
+		while ( (ret = read(fd, buf, 1024)) > 0)
+		{
+			write_to_file(buf, ret);
+		}
+		mods[x].mod_end = byteswap(curr_offset);
+	}
+
+	/* Re-write the modules structs at the start of the file */
+	lseek(rd_fd, sizeof(magic) * 2, SEEK_SET);
+	write(rd_fd, &mods, sizeof(module_t) * mod);
+	
+	return 0;
+	
+}

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* RFC/Patch: Support for other bootloaders
@ 2005-03-21 15:46 Michal Ostrowski
  2005-03-21 16:26 ` Tim Deegan
  2005-03-23 20:40 ` Christian Limpach
  0 siblings, 2 replies; 27+ messages in thread
From: Michal Ostrowski @ 2005-03-21 15:46 UTC (permalink / raw)
  To: xen-devel


[-- Attachment #1.1: Type: text/plain, Size: 1300 bytes --]


I need to net-boot xen on an HS20 blade.  HS20's have a Broadcom NIC,
which is not supported by grub.  The attached patch allows me to build a
Xen image which I can boot using PXELinux  (and the entire SysLinux
family of boot-loaders).

PXELinux should work with any PXE-enabled NIC and thus does not face the
same driver-support issues as grub.

This functionality is enabled by using the Linux code that is wrapped
around a vmlinux to form a zImage.  I've come up with two ways of doing
this; as part of the xen build, or a seperate shell-script ("mkzen").

Both methods reach into a specified Linux-kernel build tree to grab the
bits for the wrapper.  The result, from the boot-loader's point of view
looks identical to a zImage.

However, running in this environment, Xen must now accept arguments in
the format used between a zImage and a vmlinux and distinguish between
this format and the multi-boot format.

Also, since grub is not being used, loading of multiple modules is not
supported.  Thus I've created a tool to package multiple images, with
parameter lists into a "meta-ramdisk".  My patch also includes code for
Xen to extract multiple images from such a meta-ramdisk.

Comments/suggestions appreciated.

-- 
Michal Ostrowski <mostrows@watson.ibm.com>

[-- Attachment #1.2: bootloader.patch --]
[-- Type: text/x-patch, Size: 26857 bytes --]

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/03/20 16:10:07-05:00 mostrows@heater.watson.ibm.com 
#   Support being booted by arbitrary boot-loaders with bzImage code from Linux.
#   Wrap xen with Linux's bzImage code, either through support in Makefiles or via 
#   the mkzen script.  Both methods require that one specify the location
#   of a linux i386 build tree, from which we extract the necessary bits.
#   
#   Booting with the bzImage code requires that xen recognize parameters in the format 
#   that vmlinux expects. Have __setup_xen be able to recognize both kinds of parameter
#   formats.
#   
#   Using non-grub boot-loaders means that we'll only see one module loaded in addition
#   to the "kernel" image.
#   
#   Add a "mkmetard" tool to create "meta-ramdisks" which can include multiple modules with
#   parameters, all packaged into one ramdisk image.
#   
#   Support decomposition of meta-ramdisks in xen.
# 
# xen/arch/x86/mkzen
#   2005/03/20 16:10:06-05:00 mostrows@heater.watson.ibm.com +76 -0
# 
# xen/tools/Makefile
#   2005/03/20 16:10:06-05:00 mostrows@heater.watson.ibm.com +3 -1
#   Built the mkmetard tool.
# 
# xen/include/xen/multiboot.h
#   2005/03/20 16:10:06-05:00 mostrows@heater.watson.ibm.com +4 -0
#   Reasonable max number of MBI modules.
# 
# xen/arch/x86/setup.c
#   2005/03/20 16:10:06-05:00 mostrows@heater.watson.ibm.com +190 -44
#   Support being booted by arbitrary boot-loaders with bzImage code from Linux.
#   Thus, parameters may be passed via pointer in %esi.  Add appropriate checks to
#   detect parameters of this form vs. multi-boot.
#   
#   Add code to extract parameter and system data (e820 memory maps) from either multi-boot
#   or Linux parameter formats.
#   
#   If using Linux parameter format, it is possible that the single ramdisk is a "meta-ramdisk",
#   with a multi-boot-like record that describes multiple module images and parameter
#   strings.
# 
# xen/arch/x86/mkzen
#   2005/03/20 16:10:06-05:00 mostrows@heater.watson.ibm.com +0 -0
#   BitKeeper file /home/mostrows/xen/xeno-unstable.bk/xen/arch/x86/mkzen
# 
# xen/arch/x86/boot/x86_32.S
#   2005/03/20 16:10:06-05:00 mostrows@heater.watson.ibm.com +9 -7
#   Support being booted by arbitrary boot-loaders with bzImage code from Linux.
#   Thus, parameters may be passed via pointer in %esi.  Add appropriate checks to
#   detect parameters of this form vs. multi-boot.
# 
# xen/arch/x86/Makefile
#   2005/03/20 16:10:06-05:00 mostrows@heater.watson.ibm.com +42 -0
#   Add target to build zenImg -- xen wrapped with Linux's bzImage machinery.
# 
# xen/Makefile
#   2005/03/20 16:10:06-05:00 mostrows@heater.watson.ibm.com +3 -1
#   Build mkmetard.
# 
# xen/tools/mkmetard/mkmetard.c
#   2005/03/20 15:01:15-05:00 mostrows@heater.watson.ibm.com +225 -0
# 
# xen/tools/mkmetard/Makefile
#   2005/03/20 15:01:15-05:00 mostrows@heater.watson.ibm.com +10 -0
# 
# xen/tools/mkmetard/mkmetard.c
#   2005/03/20 15:01:15-05:00 mostrows@heater.watson.ibm.com +0 -0
#   BitKeeper file /home/mostrows/xen/xeno-unstable.bk/xen/tools/mkmetard/mkmetard.c
# 
# xen/tools/mkmetard/Makefile
#   2005/03/20 15:01:15-05:00 mostrows@heater.watson.ibm.com +0 -0
#   BitKeeper file /home/mostrows/xen/xeno-unstable.bk/xen/tools/mkmetard/Makefile
# 
diff -Nru a/xen/Makefile b/xen/Makefile
--- a/xen/Makefile	2005-03-20 16:15:16 -05:00
+++ b/xen/Makefile	2005-03-20 16:15:16 -05:00
@@ -27,7 +27,7 @@
 dist: install
 
 build: $(TARGET).gz
-	
+
 install: $(TARGET).gz
 	[ -d $(DESTDIR)/boot ] || $(INSTALL_DIR) $(DESTDIR)/boot
 	$(INSTALL_DATA) $(TARGET).gz $(DESTDIR)/boot
@@ -52,9 +52,11 @@
 	[ -e include/asm ] || ln -sf asm-$(TARGET_ARCH) include/asm
 	$(MAKE) -C arch/$(TARGET_ARCH) asm-offsets.s
 	$(MAKE) include/asm-$(TARGET_ARCH)/asm-offsets.h
+	$(MAKE) -C tools/mkmetard
 	$(MAKE) -C common
 	$(MAKE) -C drivers
 	$(MAKE) -C arch/$(TARGET_ARCH)
+
 
 # drivers/char/console.o may contain static banner/compile info. Blow it away.
 delete-unfresh-files:
diff -Nru a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile	2005-03-20 16:15:16 -05:00
+++ b/xen/arch/x86/Makefile	2005-03-20 16:15:16 -05:00
@@ -15,7 +15,11 @@
 OBJS := $(patsubst cdb%.o,,$(OBJS))
 endif
 
+ifdef LINUX_BUILD
+default: $(TARGET) zenImg
+else
 default: $(TARGET)
+endif
 
 $(TARGET): $(TARGET)-syms boot/mkelf32
 	./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000
@@ -32,6 +36,44 @@
 
 boot/mkelf32: boot/mkelf32.c
 	$(HOSTCC) $(HOSTCFLAGS) -o $@ $<
+
+
+ifdef LINUX_BUILD
+
+#
+# Check Makefile in Linux build dir.  If it contains KERNELSRC, then use
+# that as source dir, otherwise build==source dir
+LINUX_SRC:= $(shell if grep -q KERNELSRC $(LINUX_BUILD)/Makefile ; then \
+			sed -e '/^KERNELSRC/!d' $(LINUX_BUILD)/Makefile | \
+			bash -c '( read A B C ; echo -n $$C)' ; \
+		    else \
+			echo -n $(LINUX_BUILD); \
+		    fi )
+
+$(TARGET).bin: $(TARGET)
+	$(OBJCOPY) -O binary -R .note -R .comment -S  $^ $@
+
+$(TARGET).bin.gz: $(TARGET).bin
+	gzip -f -9 < $< > $@
+
+piggy.o: $(TARGET).bin.gz
+	$(LD) -m elf_i386  -r --format binary --oformat elf32-i386 \
+	-T $(LINUX_SRC)/arch/i386/boot/compressed/vmlinux.scr $< -o $@
+
+zen:	$(LINUX_BUILD)/arch/i386/boot/compressed/head.o \
+	$(LINUX_BUILD)/arch/i386/boot/compressed/misc.o \
+	piggy.o
+	$(LD) -m elf_i386  -Ttext 0x100000 -e startup_32 $^ -o $@
+
+zenImg: zen
+	$(OBJCOPY) -O binary -R .note -R .comment -S  $^ $@.tmp
+	$(LINUX_BUILD)/arch/i386/boot/tools/build \
+		-b $(LINUX_BUILD)/arch/i386/boot/bootsect \
+		$(LINUX_BUILD)/arch/i386/boot/setup $@.tmp > $@
+
+
+endif
+
 
 clean:
 	rm -f *.o *.s *~ core boot/*.o boot/*~ boot/core boot/mkelf32
diff -Nru a/xen/arch/x86/boot/x86_32.S b/xen/arch/x86/boot/x86_32.S
--- a/xen/arch/x86/boot/x86_32.S	2005-03-20 16:15:16 -05:00
+++ b/xen/arch/x86/boot/x86_32.S	2005-03-20 16:15:16 -05:00
@@ -55,7 +55,7 @@
         mov     %ecx,%gs
         ljmp    $(__HYPERVISOR_CS),$(1f)-__PAGE_OFFSET
 1:      lss     stack_start-__PAGE_OFFSET,%esp
-
+	
         /* Reset EFLAGS (subsumes CLI and CLD). */
 	pushl	$0
 	popf
@@ -82,15 +82,17 @@
         and     $0x7f,%cl   # CR4.PGE (global enable)
         mov     %ecx,%cr4
                 
+        /* Check for Multiboot bootloader */
+        cmp     $0x2BADB002,%eax
+        je     1f
+	/* No multi-boot?  Hope that we've got a Linux boot-params */
+	/* stashed in esi. Save in %ebx until stack is ready. */
+	movl	%esi, %ebx
+1:
         cmp     $(SECONDARY_CPU_FLAG),%ebx
         je      start_paging
                 
-        /* Check for Multiboot bootloader */
-        cmp     $0x2BADB002,%eax
-        jne     not_multiboot
-
-        /* Save the Multiboot info structure for later use. */
-	add     $__PAGE_OFFSET,%ebx
+	/* Stack is now ready, so store boot parameter pointer */
         push    %ebx
 
         /* Initialize BSS (no nasty surprises!) */
diff -Nru a/xen/arch/x86/mkzen b/xen/arch/x86/mkzen
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/xen/arch/x86/mkzen	2005-03-20 16:15:16 -05:00
@@ -0,0 +1,76 @@
+#!/bin/bash
+#
+# Copyright (C) 2005 Michal Ostrowski <mostrows@watson.ibm.com>, 
+#					  IBM Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+
+
+# Reaches into a Linux build tree and uses objects and scripts from
+# linux to wrap a Xen ELF image in the Linuz bzImage machinery,
+# allowing the resulting "zen" image to be booted using any
+# boot-loader thant can load a Linux bzImage.
+
+#
+# Usage: mkzen <LINUX_BUILD> <XEN IMAGE> <ZEN>
+
+set -e
+LINUX_BUILD=$1
+XEN=$2
+ZEN=$3
+
+: ${CROSS_COMPILE:=}
+: ${OBJCOPY:=${CROSS_COMPILE}objcopy}
+: ${LD:=${CROSS_COMPILE}ld}
+
+function cleanup(){
+    rm -f ${XEN}.bin.$$ ${XEN}.bin.gz.$$ ${XEN}.piggy.o.$$
+    rm -f ${ZEN}.1.$$ ${ZEN}.2.$$
+}
+
+trap cleanup ERR
+
+#
+# Check Makefile in Linux build dir.  If it contains KERNELSRC, then use
+# that as source dir, otherwise build==source dir
+#
+LINUX_SRC=`sed -e '/^KERNELSRC/!d;s/^.*:=[ ]*//'  <${LINUX_BUILD}/Makefile`
+if [ -z "${LINUX_SRC}" ]; then
+    LINUX_SRC=${LINUX_BUILD};
+fi
+
+${OBJCOPY} -O binary -R .note -R .comment -S ${XEN} ${XEN}.bin.$$
+
+gzip -f -9 < ${XEN}.bin.$$ > ${XEN}.bin.gz.$$
+
+${LD} -m elf_i386  -r --format binary --oformat elf32-i386 \
+    -T ${LINUX_SRC}/arch/i386/boot/compressed/vmlinux.scr \
+    ${XEN}.bin.gz -o ${XEN}.piggy.o.$$
+
+
+${LD} -m elf_i386  -Ttext 0x100000 -e startup_32 \
+    ${LINUX_BUILD}/arch/i386/boot/compressed/head.o \
+    ${LINUX_BUILD}/arch/i386/boot/compressed/misc.o ${XEN}.piggy.o.$$ \
+    -o ${ZEN}.1.$$
+
+${OBJCOPY} -O binary -R .note -R .comment -S  ${ZEN}.1.$$ ${ZEN}.2.$$
+
+${LINUX_BUILD}/arch/i386/boot/tools/build \
+    -b ${LINUX_BUILD}/arch/i386/boot/bootsect \
+    ${LINUX_BUILD}/arch/i386/boot/setup ${ZEN}.2.$$ > ${ZEN}
+
+
+cleanup
\ No newline at end of file
diff -Nru a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c	2005-03-20 16:15:16 -05:00
+++ b/xen/arch/x86/setup.c	2005-03-20 16:15:16 -05:00
@@ -86,6 +86,24 @@
 int phys_proc_id[NR_CPUS];
 int logical_proc_id[NR_CPUS];
 
+
+/* Details about what is found where in the Linux boot parameters area. */
+/* Put into a seperate header if it grows much more. */
+#define PARAM_SIZE              2048
+#define COMMAND_LINE_SIZE       256
+#define NEW_CL_POINTER          0x228
+#define E820NR                  0x1e8
+#define E820MAP                 0x2d0
+#define INITRD_START            0x218
+#define INITRD_SIZE             0x21c
+
+static unsigned char boot_params[PARAM_SIZE];
+static unsigned char cmd_line_buf[COMMAND_LINE_SIZE];
+static unsigned char dom0_cmd_line_buf[COMMAND_LINE_SIZE];
+static module_t boot_modules[MAX_MBI_MODULES];
+
+
+
 /* Standard macro to see if a specific flag is changeable. */
 static inline int flag_is_changeable_p(unsigned long flag)
 {
@@ -453,36 +471,19 @@
 #endif
 }
 
-void __init __start_xen(multiboot_info_t *mbi)
+static int __init boot_param_e820_setup(unsigned char *boot_params, 
+                                        struct e820entry *e820raw)
 {
-    char *cmdline;
-    module_t *mod = (module_t *)__va(mbi->mods_addr);
-    void *heap_start;
-    unsigned long firsthole_start, nr_pages;
-    unsigned long initial_images_start, initial_images_end;
-    struct e820entry e820_raw[E820MAX];
-    int i, e820_raw_nr = 0, bytes = 0;
-
-    /* Parse the command-line options. */
-    if ( (mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0) )
-        cmdline_parse(__va(mbi->cmdline));
-
-    /* Must do this early -- e.g., spinlocks rely on get_current(). */
-    set_current(&idle0_exec_domain);
-
-    /* We initialise the serial devices very early so we can get debugging. */
-    serial_init_stage1();
-
-    init_console();
-
-    /* Check that we have at least one Multiboot module. */
-    if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
-    {
-        printk("FATAL ERROR: Require at least one Multiboot module.\n");
-        for ( ; ; ) ;
-    }
+    int e820_raw_nr = *(int*)&boot_params[E820NR];
+    memcpy(e820raw, boot_params + E820MAP, e820_raw_nr * sizeof(*e820raw));
+    return e820_raw_nr;
+}
 
-    xenheap_phys_end = opt_xenheap_megabytes << 20;
+static int __init mbi_e820_setup(multiboot_info_t *mbi, 
+                                 struct e820entry *e820_raw)
+{
+    int bytes = 0;
+    int e820_raw_nr = 0;
 
     if ( mbi->flags & MBI_MEMMAP )
     {
@@ -509,14 +510,154 @@
         e820_raw[1].type = E820_RAM;
         e820_raw_nr = 2;
     }
+    return e820_raw_nr;
+}
+
+int __init mbi_boot_modules(multiboot_info_t *mbi)
+{
+    /* Check that we have at least one Multiboot module. */
+    if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
+    {
+        printk("FATAL ERROR: Require at least one Multiboot module.\n");
+        for ( ; ; ) ;
+    }
+
+    memcpy(&boot_modules, __va(mbi->mods_addr), 
+           sizeof(module_t) * mbi->mods_count);
+    return mbi->mods_count;
+}
+
+int __init boot_param_modules(unsigned char *params)
+{
+    u32 rd = *(u32*)&boot_params[INITRD_START];
+    int size = *(int*)&boot_params[INITRD_SIZE];
+
+    boot_modules[0].mod_start = rd;
+    boot_modules[0].mod_end = rd + size;
+    boot_modules[0].string = 0;
+    boot_modules[0].reserved = 0;
+
+    u32 *magic = (u32*)boot_modules[0].mod_start;
+    u32 num_modules = magic[1];
+    u32 base = boot_modules[0].mod_start;
+    
+    printf("Multi-module: %x %d %x\n", *magic, num_modules, base);
+    printf("Module: %x %x %x\n",
+           boot_modules[0].mod_start, boot_modules[0].mod_end,
+           boot_modules[0].string);
+    
+
+    if ( *magic != MULTIBOOT_BOOTLOADER_MAGIC )
+    {
+        return 1;
+    }
+    
+    memcpy(&boot_modules[0], (void*)(base + sizeof(u32) * 2), 
+                                     num_modules * sizeof(module_t));
+    printf("Module: %x %x %x\n",
+           boot_modules[0].mod_start, boot_modules[0].mod_end,
+           boot_modules[0].string);
+    
+    int i = 0;
+    for ( ; i < num_modules; ++i) 
+    {
+        boot_modules[i].mod_start += base;
+        boot_modules[i].mod_end += base;
+        boot_modules[i].string += base;
+    }
+    printf("Module: %x %x %x\n",
+           boot_modules[0].mod_start, boot_modules[0].mod_end,
+           boot_modules[0].string);
+    return num_modules;
+}
+
+void __init __start_xen(void *params)
+{
+    char *cmdline = NULL;
+    void *heap_start;
+    unsigned long firsthole_start, nr_pages;
+    unsigned long initial_images_start, initial_images_end;
+    struct e820entry e820_raw[E820MAX];
+    int i, e820_raw_nr = 0;
+    int num_mods = 0;
+    multiboot_info_t *mbi = NULL;
+    
+    if (MULTIBOOT_BOOTLOADER_MAGIC == *(u32*)params ) 
+    {
+        mbi = (struct multiboot_info_t*)__va(mbi);
+        if ( (mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0) ) 
+        {
+            cmdline = __va(mbi->cmdline);
+        }
+    } 
+    else 
+    {
+        /* Hope it is a Linux boot parameters area. */
+        unsigned char* orig_cmd_line;
+        memcpy(boot_params, __va(((char*)params)), PARAM_SIZE);
+        
+        orig_cmd_line = __va(*(unsigned char**)&boot_params[NEW_CL_POINTER]);
+
+        memcpy(cmd_line_buf, orig_cmd_line, COMMAND_LINE_SIZE);
+        cmdline = cmd_line_buf;
+    }
+
+    /* Parse the command-line options. */
+    cmdline_parse(cmdline);
+
+    /* Must do this early -- e.g., spinlocks rely on get_current(). */
+    set_current(&idle0_exec_domain);
+
+    /* We initialise the serial devices very early so we can get debugging. */
+    serial_init_stage1();
+
+    init_console();
+
+    xenheap_phys_end = opt_xenheap_megabytes << 20;
+
+    if ( mbi != NULL ) 
+    {
+        e820_raw_nr = mbi_e820_setup(mbi, e820_raw);
+    }
     else
     {
+        e820_raw_nr = boot_param_e820_setup(boot_params, e820_raw);
+    }
+
+    if (e820_raw_nr == 0) 
+    {
         printk("FATAL ERROR: Bootloader provided no memory information.\n");
         for ( ; ; ) ;
     }
 
     max_page = init_e820(e820_raw, e820_raw_nr);
 
+    if (mbi != NULL)
+    {
+        num_mods = mbi_boot_modules(mbi);        
+    }
+    else
+    {
+        num_mods = boot_param_modules(boot_params);
+    }
+
+    /* Save dom0 cmd line to a known place. */
+    if ( boot_modules[0].string )
+    {
+        
+#if defined(__i386__)
+        memcpy(dom0_cmd_line_buf, (void*)boot_modules[0].string, 
+               COMMAND_LINE_SIZE);
+#elif defined(__x86_64__)
+        memcpy(dom0_cmd_line_buf, __va(boot_modules[0].string), 
+               COMMAND_LINE_SIZE);
+#endif
+    } 
+    else
+    {
+        dom0_cmd_line_buf[0] = 0;
+    }
+    
     /* Find the first high-memory RAM hole. */
     for ( i = 0; i < e820.nr_map; i++ )
         if ( (e820.map[i].type == E820_RAM) &&
@@ -527,7 +668,7 @@
     /* Relocate the Multiboot modules. */
     initial_images_start = xenheap_phys_end;
     initial_images_end   = initial_images_start + 
-        (mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+        (boot_modules[num_mods - 1].mod_end - boot_modules[0].mod_start);
     if ( initial_images_end > firsthole_start )
     {
         printk("Not enough memory to stash the DOM0 kernel image.\n");
@@ -535,14 +676,14 @@
     }
 #if defined(__i386__)
     memmove((void *)initial_images_start,  /* use low mapping */
-            (void *)mod[0].mod_start,      /* use low mapping */
-            mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+            (void *)boot_modules[0].mod_start,      /* use low mapping */
+            boot_modules[num_mods - 1].mod_end - boot_modules[0].mod_start);
 #elif defined(__x86_64__)
     memmove(__va(initial_images_start),
-            __va(mod[0].mod_start),
-            mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+            __va(boot_modules[0].mod_start),
+            boot_modules[num_mods-1].mod_end - boot_modules[0].mod_start);
 #endif
-
+    
     /* Initialise boot-time allocator with all RAM situated after modules. */
     heap_start = memguard_init(&_end);
     heap_start = __va(init_boot_allocator(__pa(heap_start)));
@@ -587,7 +728,8 @@
     set_bit(DF_PRIVILEGED, &dom0->d_flags);
 
     /* Grab the DOM0 command line. Skip past the image name. */
-    cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
+    cmdline = (dom0_cmd_line_buf[0] ? dom0_cmd_line_buf : NULL);
+
     if ( cmdline != NULL )
     {
         while ( *cmdline == ' ' ) cmdline++;
@@ -599,15 +741,19 @@
      * We're going to setup domain0 using the module(s) that we stashed safely
      * above our heap. The second module, if present, is an initrd ramdisk.
      */
-    if ( construct_dom0(dom0,
-                        initial_images_start, 
-                        mod[0].mod_end-mod[0].mod_start,
-                        (mbi->mods_count == 1) ? 0 :
-                        initial_images_start + 
-                        (mod[1].mod_start-mod[0].mod_start),
-                        (mbi->mods_count == 1) ? 0 :
-                        mod[mbi->mods_count-1].mod_end - mod[1].mod_start,
-                        cmdline) != 0)
+    u32 img_size = boot_modules[0].mod_end - boot_modules[0].mod_start;
+    u32 rd_start = 0;
+    u32 rd_size = 0;
+    if ( num_mods > 1 ) 
+    {
+        rd_start = initial_images_start
+                   + boot_modules[1].mod_start - boot_modules[0].mod_start;
+
+        rd_size = boot_modules[num_mods-1].mod_end - boot_modules[1].mod_start;
+    }
+
+    if ( construct_dom0(dom0, initial_images_start, img_size,
+                        rd_start, rd_size, cmdline) != 0)
         panic("Could not set up DOM0 guest OS\n");
 
     /* Scrub RAM that is still free and so may go to an unprivileged domain. */
diff -Nru a/xen/include/xen/multiboot.h b/xen/include/xen/multiboot.h
--- a/xen/include/xen/multiboot.h	2005-03-20 16:15:16 -05:00
+++ b/xen/include/xen/multiboot.h	2005-03-20 16:15:16 -05:00
@@ -28,6 +28,10 @@
 #define MBI_MEMMAP     (1<<6)
 #define MBI_LOADERNAME (1<<9)
 
+/* Make up some reasonable maximum that we support. */
+#define MAX_MBI_MODULES 4
+
+
 /* The symbol table for a.out.  */
 typedef struct {
     u32 tabsize;
diff -Nru a/xen/tools/Makefile b/xen/tools/Makefile
--- a/xen/tools/Makefile	2005-03-20 16:15:16 -05:00
+++ b/xen/tools/Makefile	2005-03-20 16:15:16 -05:00
@@ -1,6 +1,8 @@
 
 default:
 	$(MAKE) -C figlet
+	$(MAKE) -C mkmetard
 
 clean:
-	$(MAKE) -C figlet clean
\ No newline at end of file
+	$(MAKE) -C figlet clean
+	$(MAKE) -C mkmetard clean
\ No newline at end of file
diff -Nru a/xen/tools/mkmetard/Makefile b/xen/tools/mkmetard/Makefile
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/xen/tools/mkmetard/Makefile	2005-03-20 16:15:16 -05:00
@@ -0,0 +1,10 @@
+
+include ../../../Config.mk
+
+CFLAGS += -DBUILD_ARCH=$(XEN_COMPILE_ARCH) -DTARGET_ARCH=$(XEN_TARGET_ARCH)
+CFLAGS += -I$(BASEDIR)/include
+mkmetard: mkmetard.c
+	$(HOSTCC) $(CFLAGS) -o $@ $<
+
+clean:
+	rm -f *.o mkmetard
diff -Nru a/xen/tools/mkmetard/mkmetard.c b/xen/tools/mkmetard/mkmetard.c
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/xen/tools/mkmetard/mkmetard.c	2005-03-20 16:15:16 -05:00
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2005 Michal Ostrowski <mostrows@watson.ibm.com>, 
+ *					  IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ */
+
+/* Combines several images and cmdlines into one meta-ramdisk image.
+ * For use with non-grub boot-loader that don't do "multi-boot" as
+ * grub does.
+ *
+ * Usage: mkmetard <output_file> <module1_file> <mod1_arg1> ... \
+ *								 --- <module2_file> <mod2_arg1> ...
+ * 
+ * Allows up to 4 module images.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <endian.h>
+#include <byteswap.h>
+
+
+
+/* We need to know whether build platform endianness matches that of target */
+#define LITTLE_ENDIAN_ppc		0
+#define LITTLE_ENDIAN_x86_32	1
+#define LITTLE_ENDIAN_x86_64	1
+#define LITTLE_ENDIAN_ia64		1
+
+#define __CAT(a,b)		a##b
+#define IS_LITTLE_ENDIAN(arch) __CAT(LITTLE_ENDIAN_,arch)
+
+#if IS_LITTLE_ENDIAN(BUILD_ARCH) == IS_LITTLE_ENDIAN(TARGET_ARCH)
+#define ENDIAN_MATCH	1
+#else
+#define ENDIAN_MATCH	0
+#endif
+
+
+#if ENDIAN_MATCH == 0
+#define byteswap(x)								\
+	({											\
+		typeof(x) tmp = x;						\
+		switch(sizeof(tmp))						\
+		{										\
+		case 1:									\
+			break;								\
+		case 2:									\
+			tmp = bswap_16(tmp);				\
+			break;								\
+		case 4:									\
+			tmp = bswap_32(tmp);				\
+			break;								\
+		case 8:									\
+			tmp = bswap_64(tmp);				\
+			break;								\
+		default:								\
+			printf("no valid byteswap for " #x);	\
+			tmp = 0;								\
+			break;									\
+		}											\
+		tmp;										\
+	})
+#else /* ENDIAN_MATCH == 0 */		
+#define byteswap(x) (x)
+#endif /* ENDIAN_MATCH == 0 */		
+
+
+
+/* We cannot use types.h, since we may be cross-compiling and thus
+ * don't want to pick up an asm header that doesn't match the
+ * architecture we're building for */
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed int s32;
+typedef unsigned int u32;
+
+/* See if we are 32 or 64-bit */
+#if 2147483647L == __LONG_MAX__
+typedef signed long long s64;
+typedef unsigned long long u64;
+#define BITS_PER_LONG 32
+#else
+typedef signed long s64;
+typedef unsigned long u64;
+#define BITS_PER_LONG 64
+#endif
+
+#include <xen/multiboot.h>
+
+int curr_offset = 0;
+int rd_fd;
+
+static inline void 
+write_to_file(void* buf, int len)
+{
+	int ret = write(rd_fd, buf, len);
+	if (ret == len) 
+	{
+		curr_offset += ret;
+	}
+	else
+	{
+		perror("Incomplete write to ramdisk file.");
+		exit(-1);
+	}
+}
+
+
+module_t mods[MAX_MBI_MODULES];
+
+int main(int argc, char** argv)
+{
+	char* rdname = argv[1];
+	argv += 2;
+	argc -= 2;
+	
+	int mod = 0;
+	int x = 0;
+	
+	int parts[MAX_MBI_MODULES + 1] = { -1, };
+
+	parts[mod] = 0;
+
+	/* Identify cmdlines for each module */
+	while ( x < argc && mod < MAX_MBI_MODULES)
+	{
+		if ( strcmp(argv[x],"---") == 0 )
+		{
+			++x;
+			if (x < argc && mod < MAX_MBI_MODULES)
+			{
+				++mod;
+				parts[mod] = x;
+			}
+			
+		}
+		else 
+		{
+			++x;
+		}
+	}
+	++mod;
+
+	rd_fd = open(rdname, O_RDWR | O_CREAT | O_TRUNC, 0644);
+	if ( rd_fd < 0 ) perror("Can't open meta-ramdisk image file\n");
+	
+	/* Use the multi-boot magic number, can't see why not to. */
+	u32 magic = byteswap(MULTIBOOT_BOOTLOADER_MAGIC);
+	write_to_file(&magic, sizeof(magic));
+
+	magic = byteswap(mod);
+	write_to_file(&magic, sizeof(magic));
+
+	/* We'll come back and re-write this later, but we just need
+	 * filler for now */
+	write_to_file(&mods, sizeof(module_t) * mod);
+
+	for ( x = 0; x < mod; ++x ) 
+	{
+		int fd = open(argv[parts[x]], O_RDONLY);
+		if ( fd < 0 ) 
+		{
+			perror("Can't open image file");
+			exit(-1);
+		}
+		
+		char string[1024];
+		char buf[1024];
+		int size = 0;
+		int ret;
+		
+		/* Copy cmdline component */
+		string[0] = 0;
+		
+		int y = parts[x];
+		while(y < argc  && strcmp(argv[y], "---")!=0 )
+		{
+			strcpy(string + size, argv[y]);
+			size += strlen(argv[y]);
+			string[size++] = ' ';
+			++y;
+		}
+		string[size++] = 0;
+		
+		mods[x].string = byteswap(curr_offset);
+		write_to_file(string, size);
+		
+		/* Now copy module image */
+		mods[x].mod_start = byteswap(curr_offset);
+		while ( (ret = read(fd, buf, 1024)) > 0)
+		{
+			write_to_file(buf, ret);
+		}
+		mods[x].mod_end = byteswap(curr_offset);
+	}
+
+	/* Re-write the modules structs at the start of the file */
+	lseek(rd_fd, sizeof(magic) * 2, SEEK_SET);
+	write(rd_fd, &mods, sizeof(module_t) * mod);
+	
+	return 0;
+	
+}

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC/Patch: Support for other bootloaders
  2005-03-21 15:46 Michal Ostrowski
@ 2005-03-21 16:26 ` Tim Deegan
  2005-03-21 21:04   ` Michal Ostrowski
  2005-03-23 20:40 ` Christian Limpach
  1 sibling, 1 reply; 27+ messages in thread
From: Tim Deegan @ 2005-03-21 16:26 UTC (permalink / raw)
  To: Michal Ostrowski; +Cc: xen-devel

On Mon, Mar 21, 2005 at 10:46:02AM -0500, Michal Ostrowski wrote:
> I need to net-boot xen on an HS20 blade.  HS20's have a Broadcom NIC,
> which is not supported by grub.  The attached patch allows me to build a
> Xen image which I can boot using PXELinux  (and the entire SysLinux
> family of boot-loaders).

Did you try using mbootpack for this?  (I haven't tested its output with
PXELinux, so I don't know if it would work.)

Tim.

-- 
Tim Deegan                           (My opinions, not the University's)
Systems Research Group
University of Cambridge Computer Laboratory


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC/Patch: Support for other bootloaders
  2005-03-21 16:26 ` Tim Deegan
@ 2005-03-21 21:04   ` Michal Ostrowski
  0 siblings, 0 replies; 27+ messages in thread
From: Michal Ostrowski @ 2005-03-21 21:04 UTC (permalink / raw)
  To: Tim Deegan; +Cc: xen-devel

[-- Attachment #1: Type: text/plain, Size: 1539 bytes --]



On Mon, 2005-03-21 at 16:26 +0000, Tim Deegan wrote:
> On Mon, Mar 21, 2005 at 10:46:02AM -0500, Michal Ostrowski wrote:
> > I need to net-boot xen on an HS20 blade.  HS20's have a Broadcom NIC,
> > which is not supported by grub.  The attached patch allows me to build a
> > Xen image which I can boot using PXELinux  (and the entire SysLinux
> > family of boot-loaders).
> 
> Did you try using mbootpack for this?  (I haven't tested its output with
> PXELinux, so I don't know if it would work.)

No.  This is the first I've heard of it.

Given the two implementations, let's compare and discuss...

My objective was to try to use the Linux bits as-is and to have Xen
recognize that it is not loaded via GRUB (are there any other
non-GRUB-related multi-boot implementations?).  As you can see, the
changes required for Xen to recognize the parameters as passed out of
Linux's setup.S are not very complicated.  Figuring out where everything
is is the tough part.

I'm not attached at all to necessarily reach into a Linux build tree to
extract a built setup and bootsect.  I just think this is the easiest
way to do it.   x86 BIOS code is just icky and so I'd like to be able to
avoid having to maintain or even change it.   I think it's easier to
have Xen get data out of boot_params.

So, what I think it boils down to is whether Xen should accept
parameters passed into it in Linux-style boot_params array, or only
accept parameters in GRUB format.

-- 
Michal Ostrowski <mostrows@watson.ibm.com>

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: RFC/Patch: Support for other bootloaders
@ 2005-03-21 21:57 Ian Pratt
  2005-03-21 23:01 ` Tim Deegan
  0 siblings, 1 reply; 27+ messages in thread
From: Ian Pratt @ 2005-03-21 21:57 UTC (permalink / raw)
  To: Michal Ostrowski, Tim Deegan; +Cc: xen-devel, ian.pratt

 
> > Did you try using mbootpack for this?  (I haven't tested 
> its output with
> > PXELinux, so I don't know if it would work.)
> 
> No.  This is the first I've heard of it.
> 
> Given the two implementations, let's compare and discuss...
> 
> My objective was to try to use the Linux bits as-is and to have Xen
> recognize that it is not loaded via GRUB (are there any other
> non-GRUB-related multi-boot implementations?).  

kexec supports multiboot (admittedly thanks to a patch from us). 

> As you can see, the
> changes required for Xen to recognize the parameters as passed out of
> Linux's setup.S are not very complicated.  Figuring out where 
> everything
> is is the tough part.
>
> I'm not attached at all to necessarily reach into a Linux 
> build tree to
> extract a built setup and bootsect.  I just think this is the easiest
> way to do it.   x86 BIOS code is just icky and so I'd like to 
> be able to
> avoid having to maintain or even change it.   I think it's easier to
> have Xen get data out of boot_params.

As I recall, mbootpack uses Linux's x86 BIOS code too, so this shouldn't
be an issue. 
 
> So, what I think it boils down to is whether Xen should accept
> parameters passed into it in Linux-style boot_params array, or only
> accept parameters in GRUB format.

I can't see any obvious advantage over the mbootpack approach, and that
has the advantage of being simpler and doesn't require making Xen
understand another boot parameter format.

Is there a downside I haven't spotted?

Ian


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC/Patch: Support for other bootloaders
  2005-03-21 21:57 Ian Pratt
@ 2005-03-21 23:01 ` Tim Deegan
  2005-03-21 23:35   ` Michal Ostrowski
  2005-03-22  0:08   ` Michal Ostrowski
  0 siblings, 2 replies; 27+ messages in thread
From: Tim Deegan @ 2005-03-21 23:01 UTC (permalink / raw)
  To: Ian Pratt; +Cc: Michal Ostrowski, Tim Deegan, xen-devel, ian.pratt

On Mon, Mar 21, 2005 at 09:57:39PM -0000, Ian Pratt wrote:
> As I recall, mbootpack uses Linux's x86 BIOS code too, so this shouldn't
> be an issue. 

mbootpack does have a number of changes to the linux boot code, in order
to prepare a Multiboot environment; this might be a bit heavyweight as I
don't imagine is has much use apart from for Xen.

> Is there a downside I haven't spotted?

The xenlinux image, command-lines and initrd can't be altered at boot
time; it looks like Michal's approach has this problem too.

Tim.

-- 
Tim Deegan                           (My opinions, not the University's)
Systems Research Group
University of Cambridge Computer Laboratory


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC/Patch: Support for other bootloaders
  2005-03-21 23:01 ` Tim Deegan
@ 2005-03-21 23:35   ` Michal Ostrowski
  2005-03-22  9:17     ` Keir Fraser
  2005-03-22  0:08   ` Michal Ostrowski
  1 sibling, 1 reply; 27+ messages in thread
From: Michal Ostrowski @ 2005-03-21 23:35 UTC (permalink / raw)
  To: Tim Deegan; +Cc: Ian Pratt, xen-devel, ian.pratt

[-- Attachment #1: Type: text/plain, Size: 1482 bytes --]

On Mon, 2005-03-21 at 23:01 +0000, Tim Deegan wrote:
> On Mon, Mar 21, 2005 at 09:57:39PM -0000, Ian Pratt wrote:
> > As I recall, mbootpack uses Linux's x86 BIOS code too, so this shouldn't
> > be an issue. 
> 
> mbootpack does have a number of changes to the linux boot code, in order
> to prepare a Multiboot environment; this might be a bit heavyweight as I
> don't imagine is has much use apart from for Xen.
> 
> > Is there a downside I haven't spotted?
> 

I think it boils down to an argument of whether or not the boot_params
approach used between setup.S and vmlinux can be supported with minimal
code.  As I said before, and as you can see from the code I posted, I
don't think it is very difficult to do.  I would argue that the
complexity of Xen handling boot_params is lower than that of assembly
code in mbootpack's setup.S to setup a multiboot environment.

Additionally, if you are willing to take the boot_param's as provided by
Linux's setup.S, then you also inherit all of the BIOS probe data that
setup.S performed.  Currently, only the E820 data is used, but
conceivably one could export some of this data to dom0, as it doesn't
get to run the BIOS probes as a bare-metal Linux would.  (I don't how
important such data is though.)

> The xenlinux image, command-lines and initrd can't be altered at boot
> time; it looks like Michal's approach has this problem too.
> 
Agreed.  

-- 
Michal Ostrowski <mostrows@watson.ibm.com>

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC/Patch: Support for other bootloaders
  2005-03-21 23:01 ` Tim Deegan
  2005-03-21 23:35   ` Michal Ostrowski
@ 2005-03-22  0:08   ` Michal Ostrowski
  1 sibling, 0 replies; 27+ messages in thread
From: Michal Ostrowski @ 2005-03-22  0:08 UTC (permalink / raw)
  To: Tim Deegan; +Cc: Ian Pratt, xen-devel, ian.pratt

[-- Attachment #1: Type: text/plain, Size: 570 bytes --]


> The xenlinux image, command-lines and initrd can't be altered at boot
> time; it looks like Michal's approach has this problem too.

One could also use an approach where anything after "---" on the Xen
cmdline gets passed on as a dom0 cmdline.  Then you can select kernel
image and dom0 arguments at boot time.  If you don't have a ramdisk, or
have packaged it in the kernel image (as can be done on ppc64 at the
very least), then you don't need any special packaging for the xen or
linux/ramdisk image.


-- 
Michal Ostrowski <mostrows@watson.ibm.com>

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC/Patch: Support for other bootloaders
  2005-03-21 23:35   ` Michal Ostrowski
@ 2005-03-22  9:17     ` Keir Fraser
  0 siblings, 0 replies; 27+ messages in thread
From: Keir Fraser @ 2005-03-22  9:17 UTC (permalink / raw)
  To: Michal Ostrowski; +Cc: xen-devel, Ian Pratt, Tim Deegan, ian.pratt


On 21 Mar 2005, at 23:35, Michal Ostrowski wrote:

> I think it boils down to an argument of whether or not the boot_params
> approach used between setup.S and vmlinux can be supported with minimal
> code.  As I said before, and as you can see from the code I posted, I
> don't think it is very difficult to do.  I would argue that the
> complexity of Xen handling boot_params is lower than that of assembly
> code in mbootpack's setup.S to setup a multiboot environment.

The assembly code only needed writing once. If we need a wrapper 
program at all, I'd rather push skanky argument parsing into that than 
add another format to Xen. The info you can get from BIOS calls is 
increasingly redundant -- apart from e820 it's all passed in MP and 
ACPI tables these days.

  -- Keir



-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click

^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: RFC/Patch: Support for other bootloaders
@ 2005-03-22  9:29 Ian Pratt
  2005-03-22 14:18 ` Michal Ostrowski
  0 siblings, 1 reply; 27+ messages in thread
From: Ian Pratt @ 2005-03-22  9:29 UTC (permalink / raw)
  To: Keir Fraser, Michal Ostrowski; +Cc: xen-devel, Tim Deegan, ian.pratt

 

> The assembly code only needed writing once. If we need a wrapper 
> program at all, I'd rather push skanky argument parsing into 
> that than 
> add another format to Xen. The info you can get from BIOS calls is 
> increasingly redundant -- apart from e820 it's all passed in MP and 
> ACPI tables these days.

We need to get one of these approaches checked into the main tree, lest
someon writes a third.

The wrapper program is pretty unavoidable as the 'legacy' loaders only
support two modules and we potentially need three. Having both the xen
and kernel command line's configurable via a '--' hack seems sane. 

Michael, Tim: Please can you try and agree on a way forward.

Thanks,
Ian


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_ide95&alloc_id\x14396&op=click

^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: RFC/Patch: Support for other bootloaders
  2005-03-22  9:29 RFC/Patch: Support for other bootloaders Ian Pratt
@ 2005-03-22 14:18 ` Michal Ostrowski
  2005-03-22 14:42   ` Tim Deegan
  0 siblings, 1 reply; 27+ messages in thread
From: Michal Ostrowski @ 2005-03-22 14:18 UTC (permalink / raw)
  To: Ian Pratt; +Cc: Keir Fraser, xen-devel, Tim Deegan, ian.pratt

[-- Attachment #1: Type: text/plain, Size: 1473 bytes --]


As far as I can tell, Tim's solution was developed under the constraint
that Xen support only multi-boot format arguments.   If either solution
is adopted, then Xen will effectively support both the multi-boot
parameter format and the Linux boot_params format.  The major
distinction then is whether or not Xen will support boot_params by
converting it into multi-boot format in assembly, or whether boot_params
arguments will be processed in C code.

It is my opinion that it is preferable to have C code in place of
assembly code for such tasks.


That issue aside, here are my thoughts on some of the other issues in
this space:

1.  Xen command-line arguments should come from the boot-loader at boot
time, not hard-coded into a boot image.

2.  dom0 command-line arguments are appended to Xen command-line
arguments, separated by  "---"  (Linux command-line parsing allows for
"--").

3.  Using a ramdisk with dom0 requires that Linux be able to package a
ramdisk within itself or that Xen at some level supports some form of a
ram-disk format that allows multiple images to be packed into one
module.   I think it might be feasible to get Linux to support the
former.



PS:  mbootpack did not work on my system.  It printed:

mbootpack v0.1 (alpha)

and then nothing else happened.

Of course, I'm now curious as to whether or not my solution works in
Tim's environment.


-- 
Michal Ostrowski <mostrows@watson.ibm.com>


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC/Patch: Support for other bootloaders
  2005-03-22 14:18 ` Michal Ostrowski
@ 2005-03-22 14:42   ` Tim Deegan
  2005-03-22 15:05     ` Michal Ostrowski
  2005-03-23 11:20     ` Tim Deegan
  0 siblings, 2 replies; 27+ messages in thread
From: Tim Deegan @ 2005-03-22 14:42 UTC (permalink / raw)
  To: Michal Ostrowski; +Cc: Ian Pratt, Keir Fraser, xen-devel, Tim Deegan, ian.pratt

On Tue, Mar 22, 2005 at 09:18:52AM -0500, Michal Ostrowski wrote:
> It is my opinion that it is preferable to have C code in place of
> assembly code for such tasks.

Using the linux boot format will always be an unpleasant hack, and is
only useful when multiboot loaders don't work (Xen + xenlinux + initrd
is three files, and linux only deals with two files).  I'd rather keep
this grimness separate from Xen.

As far as I can tell, the "right" answer to this problem is to port the
relevant network driver to GrUB.

> That issue aside, here are my thoughts on some of the other issues in
> this space:
> 
> 1.  Xen command-line arguments should come from the boot-loader at boot
> time, not hard-coded into a boot image.

Fixed this morning in mbootpack.  I'll be uploading a version that
passes the boot-time command line later today.
 
> 2.  dom0 command-line arguments are appended to Xen command-line
> arguments, separated by  "---"  (Linux command-line parsing allows for
> "--").

Also implemented this morning in mbootpack.

> 3.  Using a ramdisk with dom0 requires that Linux be able to package a
> ramdisk within itself or that Xen at some level supports some form of a
> ram-disk format that allows multiple images to be packed into one
> module.   I think it might be feasible to get Linux to support the
> former. 

If we provide Xen with a struct mb_info that tells it where xenlinux and
the initrd are, it will boot them, without needing to change either Xen
or Linux.  That works already.

> PS:  mbootpack did not work on my system.  It printed:
> 
> mbootpack v0.1 (alpha)
> 
> and then nothing else happened.

Urgh.  Can you send me the command line you used to mbootpack?  It works
fine for me from EXTLINUX, though I don't have a PXELINUX test rig at
the moment, or a HS20 blade.

Tim.

-- 
Tim Deegan                           (My opinions, not the University's)
Systems Research Group
University of Cambridge Computer Laboratory


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC/Patch: Support for other bootloaders
  2005-03-22 14:42   ` Tim Deegan
@ 2005-03-22 15:05     ` Michal Ostrowski
  2005-03-23 11:20     ` Tim Deegan
  1 sibling, 0 replies; 27+ messages in thread
From: Michal Ostrowski @ 2005-03-22 15:05 UTC (permalink / raw)
  To: Tim Deegan; +Cc: Ian Pratt, Keir Fraser, xen-devel, ian.pratt

[-- Attachment #1: Type: text/plain, Size: 1610 bytes --]

On Tue, 2005-03-22 at 14:42 +0000, Tim Deegan wrote:
> On Tue, Mar 22, 2005 at 09:18:52AM -0500, Michal Ostrowski wrote:
> > It is my opinion that it is preferable to have C code in place of
> > assembly code for such tasks.
> 
> Using the linux boot format will always be an unpleasant hack, and is
> only useful when multiboot loaders don't work (Xen + xenlinux + initrd
> is three files, and linux only deals with two files).  I'd rather keep
> this grimness separate from Xen.
> 
> As far as I can tell, the "right" answer to this problem is to port the
> relevant network driver to GrUB.
> 

I strongly disagree on this.  It's not a permanent solution because
there will always be devices out there you need to add support for.
Using the PXE firmware, which is increasingly common let's you break
away from requiring specific hardware support in the boot-loader.


> > PS:  mbootpack did not work on my system.  It printed:
> > 
> > mbootpack v0.1 (alpha)
> > 
> > and then nothing else happened.
> 
> Urgh.  Can you send me the command line you used to mbootpack?  It works
> fine for me from EXTLINUX, though I don't have a PXELINUX test rig at
> the moment, or a HS20 blade.

EXTLINUX should be sufficient for these tests.  I actually did most of
my development work on Bochs with SYSLINUX.

./mbootpack -c "xen console=com2 com2=19200,8n1 nosmp=1 noht=1"  \
-m "/u/kitchawa/tftpboot/mostrows/vmlinuz root=/dev/hda" \
-o /u/kitchawa/tftpboot/mostrows/ximg \
/homes/heater/mostrows/xen/xeno-unstable.bk/xen/xen



-- 
Michal Ostrowski <mostrows@watson.ibm.com>

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC/Patch: Support for other bootloaders
  2005-03-22 14:42   ` Tim Deegan
  2005-03-22 15:05     ` Michal Ostrowski
@ 2005-03-23 11:20     ` Tim Deegan
  2005-03-23 13:00       ` Michal Ostrowski
  2005-03-23 16:09       ` Anthony Liguori
  1 sibling, 2 replies; 27+ messages in thread
From: Tim Deegan @ 2005-03-23 11:20 UTC (permalink / raw)
  To: Tim Deegan; +Cc: Michal Ostrowski, Ian Pratt, Keir Fraser, xen-devel, ian.pratt

On Tue, Mar 22, 2005 at 02:42:27PM +0000, Tim Deegan wrote:
> Fixed this morning in mbootpack.  I'll be uploading a version that
> passes the boot-time command line later today.

A bit later than advertised:

http://www.tjd.phlegethon.org/software/mbootpack-0.2a.tar.gz

This version gets the command lines at boot time; i.e. the image is
packed up with 

  mbootpack -o bzImage -m ./xenlinux -m ./initrd.img ./xen-image

and booted with 

  boot: bzImage com1=9600,8n1 console=com1 dom0_mem=49152 -- root=/dev/sda3 ro console=ttyS0,9600n8 

So far as the difference between the two proposed solutions goes, I
think it can be summarised as:

mbootpack: Shim between bzImage bootloader interface and Multiboot.
	   Has some assembler in it, but keeps the unpleasant
             hack separate from the Xen codebase.

mkzen: Add sort-of-bzImage interface support to Xen.
       No assembler, but not self-contained; puts hack into Xen code.

Not much between them, but I'm still with mbootpack, since it doesn't
need Xen to change to accomodate the bodge, and because it doesn't
invent yet another x86 boot protocol.

Tim.

-- 
Tim Deegan                           (My opinions, not the University's)
Systems Research Group
University of Cambridge Computer Laboratory


-------------------------------------------------------
This SF.net email is sponsored by: 2005 Windows Mobile Application Contest
Submit applications for Windows Mobile(tm)-based Pocket PCs or Smartphones
for the chance to win $25,000 and application distribution. Enter today at
http://ads.osdn.com/?ad_id=6882&alloc_id=15148&op=click

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC/Patch: Support for other bootloaders
  2005-03-23 11:20     ` Tim Deegan
@ 2005-03-23 13:00       ` Michal Ostrowski
  2005-03-23 16:09       ` Anthony Liguori
  1 sibling, 0 replies; 27+ messages in thread
From: Michal Ostrowski @ 2005-03-23 13:00 UTC (permalink / raw)
  To: Tim Deegan; +Cc: Ian Pratt, Keir Fraser, xen-devel, ian.pratt

[-- Attachment #1: Type: text/plain, Size: 1168 bytes --]


> So far as the difference between the two proposed solutions goes, I
> think it can be summarised as:
> 
> mbootpack: Shim between bzImage bootloader interface and Multiboot.
> 	   Has some assembler in it, but keeps the unpleasant
>              hack separate from the Xen codebase.
> 
> mkzen: Add sort-of-bzImage interface support to Xen.
>        No assembler, but not self-contained; puts hack into Xen code.
> 
> Not much between them, but I'm still with mbootpack, since it doesn't
> need Xen to change to accomodate the bodge, and because it doesn't
> invent yet another x86 boot protocol.
> 

It just seems to me that extreme measures are being taken so that one
can say that Xen changes are not required.  If this is going to be a
blessed utility for booting Xen it is in effect a part of Xen, whether
or not it is in the Xen bk repository, whether or not it is in the Xen
code proper.  My opinion is that it's better to support it in a
first-class way that to try to sweep it under the rug and pretend it
doesn't exist.  

Regardless, mbootpack works just as well so go with it.

-- 
Michal Ostrowski <mostrows@watson.ibm.com>

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: RFC/Patch: Support for other bootloaders
@ 2005-03-23 15:52 Ian Pratt
  2005-03-23 16:10 ` Michal Ostrowski
                   ` (2 more replies)
  0 siblings, 3 replies; 27+ messages in thread
From: Ian Pratt @ 2005-03-23 15:52 UTC (permalink / raw)
  To: Michal Ostrowski, Tim Deegan; +Cc: Keir Fraser, xen-devel, ian.pratt

 > It just seems to me that extreme measures are being taken so that one
> can say that Xen changes are not required.  If this is going to be a
> blessed utility for booting Xen it is in effect a part of Xen, whether
> or not it is in the Xen bk repository, whether or not it is in the Xen
> code proper.  My opinion is that it's better to support it in a
> first-class way that to try to sweep it under the rug and pretend it
> doesn't exist.  
> 
> Regardless, mbootpack works just as well so go with it.

My current feeling is that since a wrapper program has to be required to
package the three items into two, we might as well put the complexity in
the wrapper rather than in Xen.   

If the wrapping wasn't required, your approach would clearly be better
[*]. As it stands, I don't think there's much in it, and mbootpack does
have the advantage that a bunch of people have used it successfully. 

Let's get mbootpack documented and checked into the main repository.

Ian

[*] would it possible to do something whereby the vmlinuz and initrd
image were simply cat'ed together? This might swing the balance the
other way from a userbility POV, not sure.



-------------------------------------------------------
This SF.net email is sponsored by: 2005 Windows Mobile Application Contest
Submit applications for Windows Mobile(tm)-based Pocket PCs or Smartphones
for the chance to win $25,000 and application distribution. Enter today at
http://ads.osdn.com/?ad_idh82&alloc_id\x15148&op=click

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC/Patch: Support for other bootloaders
  2005-03-23 11:20     ` Tim Deegan
  2005-03-23 13:00       ` Michal Ostrowski
@ 2005-03-23 16:09       ` Anthony Liguori
  1 sibling, 0 replies; 27+ messages in thread
From: Anthony Liguori @ 2005-03-23 16:09 UTC (permalink / raw)
  To: Tim Deegan; +Cc: Michal Ostrowski, Ian Pratt, Keir Fraser, xen-devel, ian.pratt

Hi Tim,

Tim Deegan wrote:

>mbootpack: Shim between bzImage bootloader interface and Multiboot.
>	   Has some assembler in it, but keeps the unpleasant
>             hack separate from the Xen codebase.
>  
>
This is the great solution.  We had been discussing this internally as 
the preferred mechanism to add this kind of support.  My only concern 
had been the file-size limit on TFTP reducing the potential size of an 
initrd image for dom0.  That's not a huge concern though.

Great job!

Regards,
Anthony Liguori



-------------------------------------------------------
This SF.net email is sponsored by Microsoft Mobile & Embedded DevCon 2005
Attend MEDC 2005 May 9-12 in Vegas. Learn more about the latest Windows
Embedded(r) & Windows Mobile(tm) platforms, applications & content.  Register
by 3/29 & save $300 http://ads.osdn.com/?ad_id=6883&alloc_id=15149&op=click

^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: RFC/Patch: Support for other bootloaders
  2005-03-23 15:52 Ian Pratt
@ 2005-03-23 16:10 ` Michal Ostrowski
  2005-03-23 16:23 ` Tim Deegan
  2005-03-23 16:56 ` Jeremy Katz
  2 siblings, 0 replies; 27+ messages in thread
From: Michal Ostrowski @ 2005-03-23 16:10 UTC (permalink / raw)
  To: Ian Pratt; +Cc: Tim Deegan, Keir Fraser, xen-devel, ian.pratt

[-- Attachment #1: Type: text/plain, Size: 700 bytes --]


> 
> [*] would it possible to do something whereby the vmlinuz and initrd
> image were simply cat'ed together? This might swing the balance the
> other way from a userbility POV, not sure.

At least for ppc, it is currently possible to build a zImage.initrd.

It would also not be very hard to do an "objcopy" step to inject an
initrd into a vmlinux (not a zImage or bzImage).

Inserting initrd into bzImage or zImage can be done as well.

It seems easy to do if you want to integrate this step into the linux
build process.  The more you push it out to doing the glue work after
the fact the more restrictions and work we'll face.

-- 
Michal Ostrowski <mostrows@watson.ibm.com>

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC/Patch: Support for other bootloaders
  2005-03-23 15:52 Ian Pratt
  2005-03-23 16:10 ` Michal Ostrowski
@ 2005-03-23 16:23 ` Tim Deegan
  2005-03-23 16:44   ` Michal Ostrowski
  2005-03-23 16:57   ` Anthony Liguori
  2005-03-23 16:56 ` Jeremy Katz
  2 siblings, 2 replies; 27+ messages in thread
From: Tim Deegan @ 2005-03-23 16:23 UTC (permalink / raw)
  To: Ian Pratt; +Cc: Michal Ostrowski, Tim Deegan, Keir Fraser, xen-devel, ian.pratt

On Wed, Mar 23, 2005 at 03:52:32PM -0000, Ian Pratt wrote:
> [*] would it possible to do something whereby the vmlinuz and initrd
> image were simply cat'ed together? This might swing the balance the
> other way from a userbility POV, not sure.

It should be.  xen-vmlinux is an ELF, so if we can be *sure* that the
largest file offset in an ELF header is the same as the size of the
file, then it would be possible to just do

 $ cat vmlinux-xen0 initrd-xen0 >pseudo-initrd

 boot: xen pseudo-initrd.

and then have Xen root around in the ELF headers to see where the break
is.

Suporting gzipped vmlinux should be possible too; Xen needs to unzip the
kernel and then knows that the next byte after the gzipped input will be
ramdisk.  (As long as the bootloader doesn't helfully unzip the
'ramdisk' for us.)

Michal, what do you think?  It sounds like this could be added to your
code without too much horror.

Tim.

-- 
Tim Deegan                           (My opinions, not the University's)
Systems Research Group
University of Cambridge Computer Laboratory


-------------------------------------------------------
This SF.net email is sponsored by Microsoft Mobile & Embedded DevCon 2005
Attend MEDC 2005 May 9-12 in Vegas. Learn more about the latest Windows
Embedded(r) & Windows Mobile(tm) platforms, applications & content.  Register
by 3/29 & save $300 http://ads.osdn.com/?ad_id=6883&alloc_id=15149&op=click

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC/Patch: Support for other bootloaders
  2005-03-23 16:23 ` Tim Deegan
@ 2005-03-23 16:44   ` Michal Ostrowski
  2005-03-23 16:57   ` Anthony Liguori
  1 sibling, 0 replies; 27+ messages in thread
From: Michal Ostrowski @ 2005-03-23 16:44 UTC (permalink / raw)
  To: Tim Deegan; +Cc: Ian Pratt, Keir Fraser, xen-devel, ian.pratt

[-- Attachment #1: Type: text/plain, Size: 2254 bytes --]

On Wed, 2005-03-23 at 16:23 +0000, Tim Deegan wrote:
> On Wed, Mar 23, 2005 at 03:52:32PM -0000, Ian Pratt wrote:
> > [*] would it possible to do something whereby the vmlinuz and initrd
> > image were simply cat'ed together? This might swing the balance the
> > other way from a userbility POV, not sure.
> 
> It should be.  xen-vmlinux is an ELF, so if we can be *sure* that the
> largest file offset in an ELF header is the same as the size of the
> file, then it would be possible to just do
> 
>  $ cat vmlinux-xen0 initrd-xen0 >pseudo-initrd
> 
>  boot: xen pseudo-initrd.
> 
> and then have Xen root around in the ELF headers to see where the break
> is.
> 

Sure, you could do that.  You could also define, in Linux, two symbols
"initrd_start", "initrd_end".

Then, use objcopy to insert a ramdisk in between the two.  It's not
"cat", but you can just create a wrapper shell script around the
objcopy.

Linux then checks to see if the two symbols point to the same spot; if
they don't it's got a ramdisk embedded in it.

What you can actually do is this:

1.  Take a vmlinux and "load" it into a file (use objcopy to output
binary format).  Remember the entry point address!! (Entry point
instructions should be at the start of the file.)

2.  With a magic linker script, take the vmlinux.bin and initrd and
create a single ELF file, which contains two "LOAD" segments.

3.  A proper ELF loader will then load those two segments into memory.

Essentially, what I'm saying is that you can use ELF as the format for
the "meta-ramdisk".


> Suporting gzipped vmlinux should be possible too; Xen needs to unzip the
> kernel and then knows that the next byte after the gzipped input will be
> ramdisk.  (As long as the bootloader doesn't helfully unzip the
> 'ramdisk' for us.)
> 

Linux should be able to unzip the ramdisk itself.  I thought it could
already do that.

> Michal, what do you think?  It sounds like this could be added to your
> code without too much horror.

Sure,  but I thought the direction we're going in is to use you wrapper
around the Xen binary.  If that's the case then I don't see much further
use for my code.  


-- 
Michal Ostrowski <mostrows@watson.ibm.com>

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: RFC/Patch: Support for other bootloaders
  2005-03-23 15:52 Ian Pratt
  2005-03-23 16:10 ` Michal Ostrowski
  2005-03-23 16:23 ` Tim Deegan
@ 2005-03-23 16:56 ` Jeremy Katz
  2005-03-23 23:39   ` Michal Ostrowski
  2 siblings, 1 reply; 27+ messages in thread
From: Jeremy Katz @ 2005-03-23 16:56 UTC (permalink / raw)
  To: Ian Pratt; +Cc: Michal Ostrowski, Tim Deegan, Keir Fraser, xen-devel

On Wed, 2005-03-23 at 15:52 +0000, Ian Pratt wrote:
> [*] would it possible to do something whereby the vmlinuz and initrd
> image were simply cat'ed together? This might swing the balance the
> other way from a userbility POV, not sure.

If you're using an initramfs instead of an initrd, you can just cat the
initramfs to the end of the kernel image.

It's still ugly from a user's perspective, but since this isn't the
default (the default case is you're booting with grub and you can take
advantage of multiboot), it's probably not too bad.

Jeremy



-------------------------------------------------------
This SF.net email is sponsored by Microsoft Mobile & Embedded DevCon 2005
Attend MEDC 2005 May 9-12 in Vegas. Learn more about the latest Windows
Embedded(r) & Windows Mobile(tm) platforms, applications & content.  Register
by 3/29 & save $300 http://ads.osdn.com/?ad_id=6883&alloc_id=15149&op=click

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC/Patch: Support for other bootloaders
  2005-03-23 16:23 ` Tim Deegan
  2005-03-23 16:44   ` Michal Ostrowski
@ 2005-03-23 16:57   ` Anthony Liguori
  1 sibling, 0 replies; 27+ messages in thread
From: Anthony Liguori @ 2005-03-23 16:57 UTC (permalink / raw)
  To: Tim Deegan; +Cc: Ian Pratt, Michal Ostrowski, Keir Fraser, xen-devel, ian.pratt

Tim Deegan wrote:

>On Wed, Mar 23, 2005 at 03:52:32PM -0000, Ian Pratt wrote:
>  
>
>>[*] would it possible to do something whereby the vmlinuz and initrd
>>image were simply cat'ed together? This might swing the balance the
>>other way from a userbility POV, not sure.
>>    
>>
>
>It should be.  xen-vmlinux is an ELF, so if we can be *sure* that the
>largest file offset in an ELF header is the same as the size of the
>file, then it would be possible to just do
>  
>
The problem with something like this is that it's very Linux specific.  
If we every support a dom0 other than Linux, it's entirely conceivable 
that that OS may require two boot-time modules instead of just one.

The multiboot shim allows for that.  Also, it's likely that there will 
be a scenario where using something other than the Linux boot protocol 
is desirable.  The multiboot shim could handle take care of that also.

It keeps an awful lot of ugliness out of Xen.

Regards,
Anthony Liguori


-------------------------------------------------------
This SF.net email is sponsored by Microsoft Mobile & Embedded DevCon 2005
Attend MEDC 2005 May 9-12 in Vegas. Learn more about the latest Windows
Embedded(r) & Windows Mobile(tm) platforms, applications & content.  Register
by 3/29 & save $300 http://ads.osdn.com/?ad_id=6883&alloc_id=15149&op=click

^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: RFC/Patch: Support for other bootloaders
@ 2005-03-23 17:30 Ian Pratt
  2005-03-24 14:27 ` Michal Ostrowski
  0 siblings, 1 reply; 27+ messages in thread
From: Ian Pratt @ 2005-03-23 17:30 UTC (permalink / raw)
  To: Michal Ostrowski, Tim Deegan; +Cc: Keir Fraser, xen-devel, ian.pratt


> > It should be.  xen-vmlinux is an ELF, so if we can be 
> *sure* that the
> > largest file offset in an ELF header is the same as the size of the
> > file, then it would be possible to just do
> > 
> >  $ cat vmlinux-xen0 initrd-xen0 >pseudo-initrd
> > 
> >  boot: xen pseudo-initrd.
> > 
> > and then have Xen root around in the ELF headers to see 
> where the break
> > is.
> > 
> 
> Sure, you could do that.  You could also define, in Linux, two symbols
> "initrd_start", "initrd_end".
> 
> Then, use objcopy to insert a ramdisk in between the two.  It's not
> "cat", but you can just create a wrapper shell script around the
> objcopy.
> 
> Linux then checks to see if the two symbols point to the same spot; if
> they don't it's got a ramdisk embedded in it.

You mentioned that ppc Linux already has a build target for making an
initrd and wrapping it with a kernel. Do other architectures have this?
How does it work? What are the prospects of getting such funcitonality
added to native i386? Can we ease make the procedure for producing a
wrapped file easy when your building on a different machine from the
target (i.e. where mkinitrd needs different args)?
 
> > Suporting gzipped vmlinux should be possible too; Xen needs 
> to unzip the
> > kernel and then knows that the next byte after the gzipped 
> input will be
> > ramdisk.  (As long as the bootloader doesn't helfully unzip the
> > 'ramdisk' for us.)

As I recall, we currently rely on having GRUB uncompressing the kernel
and initrd. It's a bit grim to do this in Xen, but doable.

> Sure,  but I thought the direction we're going in is to use 
> your wrapper
> around the Xen binary.  If that's the case then I don't see 
> much further use for my code.  

I don't think we have all the inputs to have a firm direction yet. 


Ian


-------------------------------------------------------
This SF.net email is sponsored by Microsoft Mobile & Embedded DevCon 2005
Attend MEDC 2005 May 9-12 in Vegas. Learn more about the latest Windows
Embedded(r) & Windows Mobile(tm) platforms, applications & content.  Register
by 3/29 & save $300 http://ads.osdn.com/?ad_idh83&alloc_id\x15149&op=click

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC/Patch: Support for other bootloaders
  2005-03-21 15:46 Michal Ostrowski
  2005-03-21 16:26 ` Tim Deegan
@ 2005-03-23 20:40 ` Christian Limpach
  2005-03-23 23:15   ` Michal Ostrowski
  1 sibling, 1 reply; 27+ messages in thread
From: Christian Limpach @ 2005-03-23 20:40 UTC (permalink / raw)
  To: Michal Ostrowski; +Cc: xen-devel, kaf24, iap10

On Mon, 21 Mar 2005 10:46:02 -0500, Michal Ostrowski
<mostrows@watson.ibm.com> wrote:
> 
> I need to net-boot xen on an HS20 blade.  HS20's have a Broadcom NIC,
> which is not supported by grub.  The attached patch allows me to build a
> Xen image which I can boot using PXELinux  (and the entire SysLinux
> family of boot-loaders).

I think this breaks multiboot support because of:
+void __init __start_xen(void *params)
+{
...
+    multiboot_info_t *mbi = NULL;
+    
+    if (MULTIBOOT_BOOTLOADER_MAGIC == *(u32*)params ) 
+    {
+        mbi = (struct multiboot_info_t*)__va(mbi);

I think this should be:
+    if (MULTIBOOT_BOOTLOADER_MAGIC == *(u32*)__va(params) ) 
+    {
+        mbi = (struct multiboot_info_t*)__va(params);

Also, have you tested your changes on a SMP or HT machine?  I think
you're lucky if it works at all because you rearranged some of the
tests, and now the test for multiboot is no longer protected by the
test if we're running on a secondary cpu (%ebx == 0).

Finally, I think the updated mbootpack is a sufficient solution --
we're trying to fix a limitation in most bootloaders and interposing
something which works around this limitation seems like a sane
approach...

    christian


-------------------------------------------------------
This SF.net email is sponsored by Microsoft Mobile & Embedded DevCon 2005
Attend MEDC 2005 May 9-12 in Vegas. Learn more about the latest Windows
Embedded(r) & Windows Mobile(tm) platforms, applications & content.  Register
by 3/29 & save $300 http://ads.osdn.com/?ad_id=6883&alloc_id=15149&op=click

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: RFC/Patch: Support for other bootloaders
  2005-03-23 20:40 ` Christian Limpach
@ 2005-03-23 23:15   ` Michal Ostrowski
  0 siblings, 0 replies; 27+ messages in thread
From: Michal Ostrowski @ 2005-03-23 23:15 UTC (permalink / raw)
  To: Christian.Limpach; +Cc: xen-devel, kaf24, iap10

[-- Attachment #1: Type: text/plain, Size: 756 bytes --]


> Also, have you tested your changes on a SMP or HT machine?  I think
> you're lucky if it works at all because you rearranged some of the
> tests, and now the test for multiboot is no longer protected by the
> test if we're running on a secondary cpu (%ebx == 0).
> 

You're correct; my primary intention of the patch was for discussion,
problems are to be expected.


> Finally, I think the updated mbootpack is a sufficient solution --
> we're trying to fix a limitation in most bootloaders and interposing
> something which works around this limitation seems like a sane
> approach...
> 

My primary concern is of style, though aside from that mbootpack is
clearly sufficient.



-- 
Michal Ostrowski <mostrows@watson.ibm.com>

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: RFC/Patch: Support for other bootloaders
  2005-03-23 16:56 ` Jeremy Katz
@ 2005-03-23 23:39   ` Michal Ostrowski
  0 siblings, 0 replies; 27+ messages in thread
From: Michal Ostrowski @ 2005-03-23 23:39 UTC (permalink / raw)
  To: Jeremy Katz; +Cc: Ian Pratt, Tim Deegan, Keir Fraser, xen-devel

[-- Attachment #1: Type: text/plain, Size: 1201 bytes --]

On Wed, 2005-03-23 at 11:56 -0500, Jeremy Katz wrote:
> On Wed, 2005-03-23 at 15:52 +0000, Ian Pratt wrote:
> > [*] would it possible to do something whereby the vmlinuz and initrd
> > image were simply cat'ed together? This might swing the balance the
> > other way from a userbility POV, not sure.
> 
> If you're using an initramfs instead of an initrd, you can just cat the
> initramfs to the end of the kernel image.
> 

How is this supported?  I've been looking through linux to find code
that would look for this, but haven't found it.  Can you provide a
pointer?

> It's still ugly from a user's perspective, but since this isn't the
> default (the default case is you're booting with grub and you can take
> advantage of multiboot), it's probably not too bad.
> 

If the above is true,  I'd argue add that we should not bother with
trying to package a Linux kernel and a ramdisk.   This is something that
would appear to be a Linux and Linux tools issue.   Hence, there is only
a requirement to load Xen and one image which is dom0 (with any ramdisk
embedded in that image).  This could simplify a fair bit of code.


-- 
Michal Ostrowski <mostrows@watson.ibm.com>

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

* RE: RFC/Patch: Support for other bootloaders
  2005-03-23 17:30 Ian Pratt
@ 2005-03-24 14:27 ` Michal Ostrowski
  0 siblings, 0 replies; 27+ messages in thread
From: Michal Ostrowski @ 2005-03-24 14:27 UTC (permalink / raw)
  To: Ian Pratt; +Cc: Tim Deegan, Keir Fraser, xen-devel, ian.pratt

[-- Attachment #1: Type: text/plain, Size: 19646 bytes --]

Here's a revised patch.

I've eliminated support for trying to combine two modules into one
loadable image.  As per previous  discussions, I think in these
circumstances if a ramdisk is required it is adequate for it to be
built-in to the dom0 image (e.g. embedded initramfs).

Also included the agreed-upon cmdline hack, and SMP booting has been
verified and fixed.

(Not "signed-off" because I don't think it is ready just yet.)

-- 
Michal Ostrowski <mostrows@watson.ibm.com>


# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/03/24 09:19:31-05:00 mostrows@heater.watson.ibm.com 
#   Support for non-grub boot-loaders.
# 
# BitKeeper/etc/logging_ok
#   2005/03/24 09:19:31-05:00 mostrows@heater.watson.ibm.com +1 -0
#   Logging to logging@openlogging.org accepted
# 
# xen/arch/x86/mkzen
#   2005/03/24 09:19:28-05:00 mostrows@heater.watson.ibm.com +76 -0
# 
# xen/include/xen/multiboot.h
#   2005/03/24 09:19:28-05:00 mostrows@heater.watson.ibm.com +4 -0
#   Define reasonable max number of modules.
# 
# xen/arch/x86/mkzen
#   2005/03/24 09:19:28-05:00 mostrows@heater.watson.ibm.com +0 -0
#   BitKeeper file /home/mostrows/xen/xen.base/xen/arch/x86/mkzen
# 
# xen/include/xen/lib.h
#   2005/03/24 09:19:27-05:00 mostrows@heater.watson.ibm.com +2 -1
#   Return pointer to unparse portion of command line.
#   Stop parsing command line at "--".
# 
# xen/common/kernel.c
#   2005/03/24 09:19:27-05:00 mostrows@heater.watson.ibm.com +9 -2
#   Return pointer to unparse portion of command line.
#   Stop parsing command line at "--".
# 
# xen/arch/x86/setup.c
#   2005/03/24 09:19:27-05:00 mostrows@heater.watson.ibm.com +166 -52
#   Handle Linux-style boot-params structure if multi-boot headers not
present.
# 
# xen/arch/x86/boot/x86_32.S
#   2005/03/24 09:19:27-05:00 mostrows@heater.watson.ibm.com +13 -7
#   Detect Linux-style boot-params in %ebx if no multi-boot magic number
present.
# 
# xen/arch/x86/Makefile
#   2005/03/24 09:19:27-05:00 mostrows@heater.watson.ibm.com +42 -0
#   Add rules to build a zenImg (which incorporates Linux bzImage
binaries). 
#    Depends on LINUX_BUILD being defined to point to a linux build
tree.
# 
diff -Nru a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile	2005-03-24 09:20:15 -05:00
+++ b/xen/arch/x86/Makefile	2005-03-24 09:20:15 -05:00
@@ -15,7 +15,11 @@
 OBJS := $(patsubst cdb%.o,,$(OBJS))
 endif
 
+ifdef LINUX_BUILD
+default: $(TARGET) zenImg
+else
 default: $(TARGET)
+endif
 
 $(TARGET): $(TARGET)-syms boot/mkelf32
 	./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000
@@ -32,6 +36,44 @@
 
 boot/mkelf32: boot/mkelf32.c
 	$(HOSTCC) $(HOSTCFLAGS) -o $@ $<
+
+
+ifdef LINUX_BUILD
+
+#
+# Check Makefile in Linux build dir.  If it contains KERNELSRC, then
use
+# that as source dir, otherwise build==source dir
+LINUX_SRC:= $(shell if grep -q KERNELSRC $(LINUX_BUILD)/Makefile ; then
\
+			sed -e '/^KERNELSRC/!d' $(LINUX_BUILD)/Makefile | \
+			bash -c '( read A B C ; echo -n $$C)' ; \
+		    else \
+			echo -n $(LINUX_BUILD); \
+		    fi )
+
+$(TARGET).bin: $(TARGET)
+	$(OBJCOPY) -O binary -R .note -R .comment -S  $^ $@
+
+$(TARGET).bin.gz: $(TARGET).bin
+	gzip -f -9 < $< > $@
+
+piggy.o: $(TARGET).bin.gz
+	$(LD) -m elf_i386  -r --format binary --oformat elf32-i386 \
+	-T $(LINUX_SRC)/arch/i386/boot/compressed/vmlinux.scr $< -o $@
+
+zen:	$(LINUX_BUILD)/arch/i386/boot/compressed/head.o \
+	$(LINUX_BUILD)/arch/i386/boot/compressed/misc.o \
+	piggy.o
+	$(LD) -m elf_i386  -Ttext 0x100000 -e startup_32 $^ -o $@
+
+zenImg: zen
+	$(OBJCOPY) -O binary -R .note -R .comment -S  $^ $@.tmp
+	$(LINUX_BUILD)/arch/i386/boot/tools/build \
+		-b $(LINUX_BUILD)/arch/i386/boot/bootsect \
+		$(LINUX_BUILD)/arch/i386/boot/setup $@.tmp > $@
+
+
+endif
+
 
 clean:
 	rm -f *.o *.s *~ core boot/*.o boot/*~ boot/core boot/mkelf32
diff -Nru a/xen/arch/x86/boot/x86_32.S b/xen/arch/x86/boot/x86_32.S
--- a/xen/arch/x86/boot/x86_32.S	2005-03-24 09:20:15 -05:00
+++ b/xen/arch/x86/boot/x86_32.S	2005-03-24 09:20:15 -05:00
@@ -55,7 +55,7 @@
         mov     %ecx,%gs
         ljmp    $(__HYPERVISOR_CS),$(1f)-__PAGE_OFFSET
 1:      lss     stack_start-__PAGE_OFFSET,%esp
-
+	
         /* Reset EFLAGS (subsumes CLI and CLD). */
 	pushl	$0
 	popf
@@ -82,15 +82,21 @@
         and     $0x7f,%cl   # CR4.PGE (global enable)
         mov     %ecx,%cr4
                 
-        cmp     $(SECONDARY_CPU_FLAG),%ebx
-        je      start_paging
-                
         /* Check for Multiboot bootloader */
         cmp     $0x2BADB002,%eax
-        jne     not_multiboot
+        je     1f
 
-        /* Save the Multiboot info structure for later use. */
-	add     $__PAGE_OFFSET,%ebx
+	/* No multi-boot?  Hope that we've got a Linux boot-params */
+	/* stashed in esi. Save in %ebx until stack is ready. */
+	/* But do this only if this isn't a secondary cpu. */
+        cmp     $(SECONDARY_CPU_FLAG),%ebx
+	je	1f
+	movl	%esi, %ebx
+1:
+        cmp     $(SECONDARY_CPU_FLAG),%ebx
+        je      start_paging
+                
+	/* Stack is now ready, so store boot parameter pointer */
         push    %ebx
 
         /* Initialize BSS (no nasty surprises!) */
diff -Nru a/xen/arch/x86/mkzen b/xen/arch/x86/mkzen
--- /dev/null	Wed Dec 31 16:00:00 196900
+++ b/xen/arch/x86/mkzen	2005-03-24 09:20:15 -05:00
@@ -0,0 +1,76 @@
+#!/bin/bash
+#
+# Copyright (C) 2005 Michal Ostrowski <mostrows@watson.ibm.com>, 
+#					  IBM Corporation
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
USA
+#
+
+
+# Reaches into a Linux build tree and uses objects and scripts from
+# linux to wrap a Xen ELF image in the Linuz bzImage machinery,
+# allowing the resulting "zen" image to be booted using any
+# boot-loader thant can load a Linux bzImage.
+
+#
+# Usage: mkzen <LINUX_BUILD> <XEN IMAGE> <ZEN>
+
+set -e
+LINUX_BUILD=$1
+XEN=$2
+ZEN=$3
+
+: ${CROSS_COMPILE:=}
+: ${OBJCOPY:=${CROSS_COMPILE}objcopy}
+: ${LD:=${CROSS_COMPILE}ld}
+
+function cleanup(){
+    rm -f ${XEN}.bin.$$ ${XEN}.bin.gz.$$ ${XEN}.piggy.o.$$
+    rm -f ${ZEN}.1.$$ ${ZEN}.2.$$
+}
+
+trap cleanup ERR
+
+#
+# Check Makefile in Linux build dir.  If it contains KERNELSRC, then
use
+# that as source dir, otherwise build==source dir
+#
+LINUX_SRC=`sed -e '/^KERNELSRC/!d;s/^.*:=[ ]*//'  <
${LINUX_BUILD}/Makefile`
+if [ -z "${LINUX_SRC}" ]; then
+    LINUX_SRC=${LINUX_BUILD};
+fi
+
+${OBJCOPY} -O binary -R .note -R .comment -S ${XEN} ${XEN}.bin.$$
+
+gzip -f -9 < ${XEN}.bin.$$ > ${XEN}.bin.gz.$$
+
+${LD} -m elf_i386  -r --format binary --oformat elf32-i386 \
+    -T ${LINUX_SRC}/arch/i386/boot/compressed/vmlinux.scr \
+    ${XEN}.bin.gz -o ${XEN}.piggy.o.$$
+
+
+${LD} -m elf_i386  -Ttext 0x100000 -e startup_32 \
+    ${LINUX_BUILD}/arch/i386/boot/compressed/head.o \
+    ${LINUX_BUILD}/arch/i386/boot/compressed/misc.o ${XEN}.piggy.o.$$ \
+    -o ${ZEN}.1.$$
+
+${OBJCOPY} -O binary -R .note -R .comment -S  ${ZEN}.1.$$ ${ZEN}.2.$$
+
+${LINUX_BUILD}/arch/i386/boot/tools/build \
+    -b ${LINUX_BUILD}/arch/i386/boot/bootsect \
+    ${LINUX_BUILD}/arch/i386/boot/setup ${ZEN}.2.$$ > ${ZEN}
+
+
+cleanup
\ No newline at end of file
diff -Nru a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c	2005-03-24 09:20:15 -05:00
+++ b/xen/arch/x86/setup.c	2005-03-24 09:20:15 -05:00
@@ -86,6 +86,22 @@
 int phys_proc_id[NR_CPUS];
 int logical_proc_id[NR_CPUS];
 
+
+/* Details about what is found where in the Linux boot parameters area.
*/
+/* Put into a seperate header if it grows much more. */
+#define PARAM_SIZE              2048
+#define COMMAND_LINE_SIZE       256
+#define NEW_CL_POINTER          0x228
+#define E820NR                  0x1e8
+#define E820MAP                 0x2d0
+#define INITRD_START            0x218
+#define INITRD_SIZE             0x21c
+
+static unsigned char boot_params[PARAM_SIZE];
+static module_t boot_modules[MAX_MBI_MODULES];
+
+
+
 /* Standard macro to see if a specific flag is changeable. */
 static inline int flag_is_changeable_p(unsigned long flag)
 {
@@ -453,36 +469,19 @@
 #endif
 }
 
-void __init __start_xen(multiboot_info_t *mbi)
+static int __init boot_param_e820_setup(unsigned char *boot_params, 
+                                        struct e820entry *e820raw)
 {
-    char *cmdline;
-    module_t *mod = (module_t *)__va(mbi->mods_addr);
-    void *heap_start;
-    unsigned long firsthole_start, nr_pages;
-    unsigned long initial_images_start, initial_images_end;
-    struct e820entry e820_raw[E820MAX];
-    int i, e820_raw_nr = 0, bytes = 0;
-
-    /* Parse the command-line options. */
-    if ( (mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0) )
-        cmdline_parse(__va(mbi->cmdline));
-
-    /* Must do this early -- e.g., spinlocks rely on get_current(). */
-    set_current(&idle0_exec_domain);
-
-    /* We initialise the serial devices very early so we can get
debugging. */
-    serial_init_stage1();
-
-    init_console();
-
-    /* Check that we have at least one Multiboot module. */
-    if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
-    {
-        printk("FATAL ERROR: Require at least one Multiboot
module.\n");
-        for ( ; ; ) ;
-    }
+    int e820_raw_nr = *(int*)&boot_params[E820NR];
+    memcpy(e820raw, boot_params + E820MAP, e820_raw_nr *
sizeof(*e820raw));
+    return e820_raw_nr;
+}
 
-    xenheap_phys_end = opt_xenheap_megabytes << 20;
+static int __init mbi_e820_setup(multiboot_info_t *mbi, 
+                                 struct e820entry *e820_raw)
+{
+    int bytes = 0;
+    int e820_raw_nr = 0;
 
     if ( mbi->flags & MBI_MEMMAP )
     {
@@ -509,14 +508,134 @@
         e820_raw[1].type = E820_RAM;
         e820_raw_nr = 2;
     }
+    return e820_raw_nr;
+}
+
+int __init mbi_boot_modules(multiboot_info_t *mbi)
+{
+    /* Check that we have at least one Multiboot module. */
+    if ( !(mbi->flags & MBI_MODULES) || (mbi->mods_count == 0) )
+    {
+        printk("FATAL ERROR: Require at least one Multiboot
module.\n");
+        for ( ; ; ) ;
+    }
+
+    memcpy(&boot_modules, __va(mbi->mods_addr), 
+           sizeof(module_t) * mbi->mods_count);
+    return mbi->mods_count;
+}
+
+int __init boot_param_modules(unsigned char *params)
+{
+    u32 rd = *(u32*)&boot_params[INITRD_START];
+    int size = *(int*)&boot_params[INITRD_SIZE];
+
+    boot_modules[0].mod_start = rd;
+    boot_modules[0].mod_end = rd + size;
+    boot_modules[0].string = 0;
+    boot_modules[0].reserved = 0;
+
+    return 1;
+}
+
+void __init __start_xen(void *params)
+{
+    void *heap_start;
+    unsigned long firsthole_start, nr_pages;
+    unsigned long initial_images_start, initial_images_end;
+    struct e820entry e820_raw[E820MAX];
+    int i, e820_raw_nr = 0;
+    int num_mods = 0;
+    multiboot_info_t *mbi = NULL;
+    char *leftover;
+    unsigned char cmdline[COMMAND_LINE_SIZE + 1];
+    unsigned char dom0_cmdline[COMMAND_LINE_SIZE + 1];
+    
+    /* Forces correct empty-string and null-termination behavior */
+    memset(cmdline, 0, sizeof(cmdline));
+    memset(dom0_cmdline, 0, sizeof(dom0_cmdline));
+    
+    if (MULTIBOOT_BOOTLOADER_MAGIC == *(u32*)__va(params) ) 
+    {
+        mbi = (struct multiboot_info_t*)__va(mbi);
+        if ( (mbi->flags & MBI_CMDLINE) && (mbi->cmdline != 0) ) 
+        {
+            memcpy(cmdline, __va(mbi->cmdline), COMMAND_LINE_SIZE);
+        }
+    } 
+    else 
+    {
+        /* Hope it is a Linux boot parameters area. */
+        unsigned char* orig_cmd_line;
+        memcpy(boot_params, __va(((char*)params)), PARAM_SIZE);
+        
+        orig_cmd_line = __va(*(unsigned
char**)&boot_params[NEW_CL_POINTER]);
+
+        memcpy(cmdline, orig_cmd_line, COMMAND_LINE_SIZE);
+    }
+
+    /* Parse the command-line options. */
+    leftover = cmdline_parse(cmdline);
+    
+    /* Must do this early -- e.g., spinlocks rely on get_current(). */
+    set_current(&idle0_exec_domain);
+
+    /* We initialise the serial devices very early so we can get
debugging. */
+    serial_init_stage1();
+
+    init_console();
+    
+    xenheap_phys_end = opt_xenheap_megabytes << 20;
+
+    if ( mbi != NULL ) 
+    {
+        e820_raw_nr = mbi_e820_setup(mbi, e820_raw);
+    }
     else
     {
+        e820_raw_nr = boot_param_e820_setup(boot_params, e820_raw);
+    }
+
+    if (e820_raw_nr == 0) 
+    {
         printk("FATAL ERROR: Bootloader provided no memory
information.\n");
         for ( ; ; ) ;
     }
 
     max_page = init_e820(e820_raw, e820_raw_nr);
 
+    if (mbi != NULL)
+    {
+        num_mods = mbi_boot_modules(mbi);        
+    }
+    else
+    {
+        num_mods = boot_param_modules(boot_params);
+    }
+
+    /* Save dom0 cmd line to a known place. */
+    if ( boot_modules[0].string )
+    {
+#if defined(__i386__)
+        char *cmdline = (char *)boot_modules[0].string;
+#elif defined(__x86_64__)
+        char *cmdline = (char *)__va(boot_modules[0].string);
+#endif        
+        /* Skip past the image name. */
+        int  i = 0;
+        while ( cmdline[i] && cmdline[i] == ' ' ) ++i;
+        while ( cmdline[i] && cmdline[i] != ' ') ++i;
+        while ( cmdline[i] && cmdline[i] == ' ' ) ++i;
+  
+        memcpy(dom0_cmdline, cmdline, COMMAND_LINE_SIZE - i);
+    } 
+    else if ( leftover )
+    {
+        /* NULL termination is guaranteed on the cmdline buffer, */
+        /* and leftover is a pointer into that. */
+        strcpy(dom0_cmdline, leftover);
+    }
+
     /* Find the first high-memory RAM hole. */
     for ( i = 0; i < e820.nr_map; i++ )
         if ( (e820.map[i].type == E820_RAM) &&
@@ -527,7 +646,7 @@
     /* Relocate the Multiboot modules. */
     initial_images_start = xenheap_phys_end;
     initial_images_end   = initial_images_start + 
-        (mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+        (boot_modules[num_mods - 1].mod_end -
boot_modules[0].mod_start);
     if ( initial_images_end > firsthole_start )
     {
         printk("Not enough memory to stash the DOM0 kernel image.\n");
@@ -535,14 +654,14 @@
     }
 #if defined(__i386__)
     memmove((void *)initial_images_start,  /* use low mapping */
-            (void *)mod[0].mod_start,      /* use low mapping */
-            mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+            (void *)boot_modules[0].mod_start,      /* use low mapping
*/
+            boot_modules[num_mods - 1].mod_end -
boot_modules[0].mod_start);
 #elif defined(__x86_64__)
     memmove(__va(initial_images_start),
-            __va(mod[0].mod_start),
-            mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
+            __va(boot_modules[0].mod_start),
+            boot_modules[num_mods-1].mod_end -
boot_modules[0].mod_start);
 #endif
-
+    
     /* Initialise boot-time allocator with all RAM situated after
modules. */
     heap_start = memguard_init(&_end);
     heap_start = __va(init_boot_allocator(__pa(heap_start)));
@@ -586,28 +705,23 @@
 
     set_bit(DF_PRIVILEGED, &dom0->d_flags);
 
-    /* Grab the DOM0 command line. Skip past the image name. */
-    cmdline = (char *)(mod[0].string ? __va(mod[0].string) : NULL);
-    if ( cmdline != NULL )
-    {
-        while ( *cmdline == ' ' ) cmdline++;
-        if ( (cmdline = strchr(cmdline, ' ')) != NULL )
-            while ( *cmdline == ' ' ) cmdline++;
-    }
-
     /*
      * We're going to setup domain0 using the module(s) that we stashed
safely
      * above our heap. The second module, if present, is an initrd
ramdisk.
      */
-    if ( construct_dom0(dom0,
-                        initial_images_start, 
-                        mod[0].mod_end-mod[0].mod_start,
-                        (mbi->mods_count == 1) ? 0 :
-                        initial_images_start + 
-                        (mod[1].mod_start-mod[0].mod_start),
-                        (mbi->mods_count == 1) ? 0 :
-                        mod[mbi->mods_count-1].mod_end -
mod[1].mod_start,
-                        cmdline) != 0)
+    u32 img_size = boot_modules[0].mod_end - boot_modules[0].mod_start;
+    u32 rd_start = 0;
+    u32 rd_size = 0;
+    if ( num_mods > 1 ) 
+    {
+        rd_start = initial_images_start
+                   + boot_modules[1].mod_start -
boot_modules[0].mod_start;
+
+        rd_size = boot_modules[num_mods-1].mod_end -
boot_modules[1].mod_start;
+    }
+
+    if ( construct_dom0(dom0, initial_images_start, img_size,
+                        rd_start, rd_size, dom0_cmdline) != 0)
         panic("Could not set up DOM0 guest OS\n");
 
     /* Scrub RAM that is still free and so may go to an unprivileged
domain. */
diff -Nru a/xen/common/kernel.c b/xen/common/kernel.c
--- a/xen/common/kernel.c	2005-03-24 09:20:15 -05:00
+++ b/xen/common/kernel.c	2005-03-24 09:20:15 -05:00
@@ -14,13 +14,14 @@
 #include <xen/compile.h>
 #include <xen/sched.h>
 
-void cmdline_parse(char *cmdline)
+/* Returns pointer to unparsed portion of command line. */
+char* cmdline_parse(char *cmdline)
 {
     char *opt_end, *opt;
     struct kernel_param *param;
     
     if ( cmdline == NULL )
-        return;
+        return NULL;
 
     while ( *cmdline == ' ' )
         cmdline++;
@@ -31,6 +32,11 @@
             cmdline++;
         if ( *cmdline == '\0' )
             break;
+        
+        /* Pass all options after -- to dom0 */
+        if ( *cmdline == '-' && ( cmdline[1] == '-' || cmdline[1] ==
'\0' ) )
+            return cmdline + 2;
+            
         opt_end = strchr(cmdline, ' ');
         if ( opt_end != NULL )
             *opt_end++ = '\0';
@@ -62,6 +68,7 @@
         }
         cmdline = opt_end;
     }
+    return NULL;
 }
 
 /*
diff -Nru a/xen/include/xen/lib.h b/xen/include/xen/lib.h
--- a/xen/include/xen/lib.h	2005-03-24 09:20:15 -05:00
+++ b/xen/include/xen/lib.h	2005-03-24 09:20:15 -05:00
@@ -29,7 +29,8 @@
 
 struct domain;
 
-void cmdline_parse(char *cmdline);
+/* Returns pointer to unparsed portion of command line. */
+char* cmdline_parse(char *cmdline);
 
 #ifndef NDEBUG
 extern int debugtrace_send_to_console;
diff -Nru a/xen/include/xen/multiboot.h b/xen/include/xen/multiboot.h
--- a/xen/include/xen/multiboot.h	2005-03-24 09:20:15 -05:00
+++ b/xen/include/xen/multiboot.h	2005-03-24 09:20:15 -05:00
@@ -28,6 +28,10 @@
 #define MBI_MEMMAP     (1<<6)
 #define MBI_LOADERNAME (1<<9)
 
+/* Make up some reasonable maximum that we support. */
+#define MAX_MBI_MODULES 4
+
+
 /* The symbol table for a.out.  */
 typedef struct {
     u32 tabsize;


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2005-03-24 14:27 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-22  9:29 RFC/Patch: Support for other bootloaders Ian Pratt
2005-03-22 14:18 ` Michal Ostrowski
2005-03-22 14:42   ` Tim Deegan
2005-03-22 15:05     ` Michal Ostrowski
2005-03-23 11:20     ` Tim Deegan
2005-03-23 13:00       ` Michal Ostrowski
2005-03-23 16:09       ` Anthony Liguori
  -- strict thread matches above, loose matches on Subject: below --
2005-03-23 17:30 Ian Pratt
2005-03-24 14:27 ` Michal Ostrowski
2005-03-23 15:52 Ian Pratt
2005-03-23 16:10 ` Michal Ostrowski
2005-03-23 16:23 ` Tim Deegan
2005-03-23 16:44   ` Michal Ostrowski
2005-03-23 16:57   ` Anthony Liguori
2005-03-23 16:56 ` Jeremy Katz
2005-03-23 23:39   ` Michal Ostrowski
2005-03-21 21:57 Ian Pratt
2005-03-21 23:01 ` Tim Deegan
2005-03-21 23:35   ` Michal Ostrowski
2005-03-22  9:17     ` Keir Fraser
2005-03-22  0:08   ` Michal Ostrowski
2005-03-21 15:46 Michal Ostrowski
2005-03-21 16:26 ` Tim Deegan
2005-03-21 21:04   ` Michal Ostrowski
2005-03-23 20:40 ` Christian Limpach
2005-03-23 23:15   ` Michal Ostrowski
2005-03-21 12:15 Michal Ostrowski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.