Index: bootcd/isolinux/syslinux-6.03/com32/mboot/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,45 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
+##   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+##
+##   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, Inc., 51 Franklin St, Fifth Floor,
+##   Boston MA 02110-1301, USA; either version 2 of the License, or
+##   (at your option) any later version; incorporated herein by reference.
+##
+## -----------------------------------------------------------------------
+
+##
+## Multiboot module
+##
+
+VPATH = $(SRC)
+include $(MAKEDIR)/elf.mk
+
+LNXLIBS	   = $(objdir)/com32/libutil/libutil_lnx.a
+
+MODULES	  = mboot.c32
+TESTFILES =
+
+OBJS = mboot.o map.o mem.o initvesa.o apm.o solaris.o syslinux.o
+
+all: $(MODULES) $(TESTFILES)
+
+mboot.elf : $(OBJS) $(C_LIBS)
+	$(LD) $(LDFLAGS) -o $@ $^
+
+tidy dist:
+	rm -f *.o *.lo *.a *.lst *.elf .*.d *.tmp
+
+clean: tidy
+	rm -f *.lnx
+
+spotless: clean
+	rm -f *.lss *.c32 *.com
+	rm -f *~ \#*
+
+install:
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/apm.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/apm.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/apm.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,88 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   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, Inc., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ *   Based on code from the Linux kernel:
+ *
+ *   Copyright (C) 1991, 1992 Linus Torvalds
+ *   Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ *   Original APM BIOS checking by Stephen Rothwell, May 1994
+ *   (sfr@canb.auug.org.au)
+ *
+ *   This file is part of the Linux kernel, and is made available under
+ *   the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * apm.c
+ *
+ * APM information for Multiboot
+ */
+
+#include "mboot.h"
+#include <com32.h>
+
+void mboot_apm(void)
+{
+    static struct apm_info apm;
+    com32sys_t ireg, oreg;
+
+    memset(&ireg, 0, sizeof ireg);
+
+    ireg.eax.w[0] = 0x5300;
+    __intcall(0x15, &ireg, &oreg);
+
+    if (oreg.eflags.l & EFLAGS_CF)
+	return;			/* No APM BIOS */
+
+    if (oreg.ebx.w[0] != 0x504d)
+	return;			/* No "PM" signature */
+
+    if (!(oreg.ecx.w[0] & 0x02))
+	return;			/* 32 bits not supported */
+
+    /* Disconnect first, just in case */
+    memset(&ireg, 0, sizeof ireg);
+    ireg.eax.b[0] = 0x04;
+    __intcall(0x15, &ireg, &oreg);
+
+    /* 32-bit connect */
+    ireg.eax.b[0] = 0x03;
+    __intcall(0x15, &ireg, &oreg);
+
+    apm.cseg = oreg.eax.w[0];
+    apm.offset = oreg.ebx.l;
+    apm.cseg_16 = oreg.ecx.w[0];
+    apm.dseg_16 = oreg.edx.w[0];
+    apm.cseg_len = oreg.esi.w[0];
+    apm.cseg_16_len = oreg.esi.w[1];
+    apm.dseg_16_len = oreg.edi.w[0];
+
+    /* Redo the installation check as the 32-bit connect;
+       some BIOSes return different flags this way... */
+
+    memset(&ireg, 0, sizeof ireg);
+    ireg.eax.b[0] = 0x00;
+    __intcall(0x15, &ireg, &oreg);
+
+    if ((oreg.eflags.l & EFLAGS_CF) || (oreg.ebx.w[0] != 0x504d)) {
+	/* Failure with 32-bit connect, try to disconect and ignore */
+	ireg.eax.b[0] = 0x04;
+	__intcall(0x15, &ireg, NULL);
+	return;
+    }
+
+    apm.version = oreg.eax.w[0];
+
+    mbinfo.apm_table = map_data(&apm, sizeof apm, 4, false);
+    if (mbinfo.apm_table)
+	mbinfo.flags |= MB_INFO_APM_TABLE;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/initvesa.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/initvesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/initvesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,233 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 1999-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * initvesa.c
+ *
+ * Query the VESA BIOS and select a 640x480x32 mode with local mapping
+ * support, if one exists.
+ */
+
+#include <inttypes.h>
+#include <com32.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <graphics.h>
+
+#include "vesa.h"
+#include "mboot.h"
+
+struct vesa_info vesa_info;
+
+void set_graphics_mode(const struct multiboot_header *mbh,
+		       struct multiboot_info *mbi)
+{
+    com32sys_t rm;
+    uint16_t mode, bestmode, *mode_ptr;
+    struct vesa_general_info *gi;
+    struct vesa_mode_info *mi;
+    int pxf, bestpxf;
+    int wantx, wanty;
+    int err, besterr;
+    bool better;
+    addr_t viaddr;
+
+    /* Only do this if requested by the OS image */
+    if (!(mbh->flags & MULTIBOOT_VIDEO_MODE) || mbh->mode_type != 0)
+	return;
+
+    gi = lmalloc(sizeof *gi);
+    if (!gi)
+	return;
+
+    mi = lmalloc(sizeof *mi);
+    if (!mi)
+	goto out;
+
+    memset(&rm, 0, sizeof rm);
+    memset(gi, 0, sizeof *gi);
+
+    gi->signature = VBE2_MAGIC;	/* Get VBE2 extended data */
+    rm.eax.w[0] = 0x4F00;	/* Get SVGA general information */
+    rm.edi.w[0] = OFFS(gi);
+    rm.es = SEG(gi);
+    __intcall(0x10, &rm, &rm);
+
+    if (rm.eax.w[0] != 0x004F)
+	goto out;		/* Function call failed */
+    if (gi->signature != VESA_MAGIC)
+	goto out;		/* No magic */
+    if (gi->version < 0x0102)
+	goto out;		/* VESA 1.2+ required */
+
+    memcpy(&vesa_info.gi, gi, sizeof *gi);
+
+    /* Search for a suitable mode with a suitable color and memory model... */
+
+    mode_ptr = GET_PTR(gi->video_mode_ptr);
+    bestmode = 0;
+    bestpxf = 0;
+    wantx = mbh->width  ? mbh->width  : 0xffff;
+    wanty = mbh->height ? mbh->height : 0xffff;
+    besterr = wantx + wanty;
+
+    while ((mode = *mode_ptr++) != 0xFFFF) {
+	mode &= 0x1FF;		/* The rest are attributes of sorts */
+
+        memset(&rm, 0, sizeof rm);
+	memset(mi, 0, sizeof *mi);
+	rm.eax.w[0] = 0x4F01;	/* Get SVGA mode information */
+	rm.ecx.w[0] = mode;
+	rm.edi.w[0] = OFFS(mi);
+	rm.es = SEG(mi);
+	__intcall(0x10, &rm, &rm);
+
+	/* Must be a supported mode */
+	if (rm.eax.w[0] != 0x004f)
+	    continue;
+
+	/* Must be an LFB color graphics mode supported by the hardware.
+
+	   The bits tested are:
+	   7 - linear frame buffer
+	   4 - graphics mode
+	   3 - color mode
+	   1 - mode information available (mandatory in VBE 1.2+)
+	   0 - mode supported by hardware
+	 */
+	if ((mi->mode_attr & 0x009b) != 0x009b)
+	    continue;
+
+	/* We don't support multibank (interlaced memory) modes */
+	/*
+	 *  Note: The Bochs VESA BIOS (vbe.c 1.58 2006/08/19) violates the
+	 * specification which states that banks == 1 for unbanked modes;
+	 * fortunately it does report bank_size == 0 for those.
+	 */
+	if (mi->banks > 1 && mi->bank_size)
+	    continue;
+
+	/* Must either be a packed-pixel mode or a direct color mode
+	   (depending on VESA version ); must be a supported pixel format */
+
+	if (mi->bpp == 32 &&
+	    (mi->memory_layout == 4 ||
+	     (mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 &&
+	      mi->bpos == 0)))
+	    pxf = 32;
+	else if (mi->bpp == 24 &&
+		 (mi->memory_layout == 4 ||
+		  (mi->memory_layout == 6 && mi->rpos == 16 && mi->gpos == 8 &&
+		   mi->bpos == 0)))
+	    pxf = 24;
+	else if (mi->bpp == 16 &&
+		 (mi->memory_layout == 4 ||
+		  (mi->memory_layout == 6 && mi->rpos == 11 && mi->gpos == 5 &&
+		   mi->bpos == 0)))
+	    pxf = 16;
+	else if (mi->bpp == 15 &&
+		 (mi->memory_layout == 4 ||
+		  (mi->memory_layout == 6 && mi->rpos == 10 && mi->gpos == 5 &&
+		   mi->bpos == 0)))
+	    pxf = 15;
+	else
+	    continue;
+
+	better = false;
+	err = abs(mi->h_res - wantx) + abs(mi->v_res - wanty);
+
+#define IS_GOOD(mi, bestx, besty) \
+	((mi)->h_res >= (bestx) && (mi)->v_res >= (besty))
+
+	if (!bestpxf)
+	    better = true;
+	else if (!IS_GOOD(&vesa_info.mi, wantx, wanty) &&
+		 IS_GOOD(mi, wantx, wanty))
+	    /* This matches criteria, which the previous one didn't */
+	    better = true;
+	else if (IS_GOOD(&vesa_info.mi, wantx, wanty) &&
+		 !IS_GOOD(mi, wantx, wanty))
+	    /* This doesn't match criteria, and the previous one did */
+	    better = false;
+	else if (err < besterr)
+	    better = true;
+	else if (err == besterr && (pxf == (int)mbh->depth || pxf > bestpxf))
+	    better = true;
+
+	if (better) {
+	    bestmode = mode;
+	    bestpxf = pxf;
+	    memcpy(&vesa_info.mi, mi, sizeof *mi);
+	}
+    }
+
+    if (!bestpxf)
+	goto out;		/* No mode found */
+
+    mi = &vesa_info.mi;
+    mode = bestmode;
+
+    /* Now set video mode */
+    memset(&rm, 0, sizeof rm);
+    rm.eax.w[0] = 0x4F02;	/* Set SVGA video mode */
+    mode |= 0x4000;		/* Request linear framebuffer */
+    rm.ebx.w[0] = mode;
+    __intcall(0x10, &rm, &rm);
+    if (rm.eax.w[0] != 0x004F)
+	goto out;		/* Failed to set mode */
+
+    mbi->flags |= MB_INFO_VIDEO_INFO;
+    mbi->vbe_mode = mode;
+    viaddr = map_data(&vesa_info, sizeof vesa_info, 4, 0);
+    mbi->vbe_control_info = viaddr + offsetof(struct vesa_info, gi);
+    mbi->vbe_mode_info = viaddr + offsetof(struct vesa_info, mi);
+
+    /* Get the VBE 2.x PM entry point if supported */
+    rm.eax.w[0] = 0x4F0A;
+    rm.ebx.w[0] = 0;
+    __intcall(0x10, &rm, &rm);
+    if (rm.eax.w[0] == 0x004F) {
+	mbi->vbe_interface_seg = rm.es;
+	mbi->vbe_interface_off = rm.edi.w[0];
+	mbi->vbe_interface_len = rm.ecx.w[0];
+    }
+
+    /* In theory this should be:
+     *
+     * UsingVga = (mi->mode_attr & 4) ? 0x0007 : 0x000f;
+     *
+     * However, that would assume all systems that claim to handle text
+     * output in VESA modes actually do that...
+     */
+    graphics_using_vga(0x0F, vesa_info.mi.h_res, vesa_info.mi.v_res);
+
+out:
+    lfree(mi);
+    lfree(gi);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/map.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/map.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/map.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,352 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * map.c
+ *
+ * Functions that deal with the memory map of various objects
+ */
+
+#include "mboot.h"
+
+static struct syslinux_movelist *ml = NULL;
+static struct syslinux_memmap *mmap = NULL, *amap = NULL;
+static addr_t mboot_high_water_mark = 0x100000;
+
+/*
+ * Note: although there is no such thing in the spec, at least Xen makes
+ * assumptions as to where in the memory space Grub would have loaded
+ * certain things.  To support that, if "high" is set, then allocate this
+ * at an address strictly above any previous allocations.
+ *
+ * As a precaution, this also pads the data with zero up to the next
+ * alignment datum.
+ */
+addr_t map_data(const void *data, size_t len, size_t align, int flags)
+{
+    addr_t start = (flags & MAP_HIGH) ? mboot_high_water_mark : 0x2000;
+    addr_t pad = (flags & MAP_NOPAD) ? 0 : -len & (align - 1);
+    addr_t xlen = len + pad;
+
+    if (syslinux_memmap_find_type(amap, SMT_FREE, &start, &xlen, align) ||
+	syslinux_add_memmap(&amap, start, len + pad, SMT_ALLOC) ||
+	syslinux_add_movelist(&ml, start, (addr_t) data, len) ||
+	(pad && syslinux_add_memmap(&mmap, start + len, pad, SMT_ZERO))) {
+	printf("Cannot map %zu bytes\n", len + pad);
+	return 0;
+    }
+
+    dprintf("Mapping 0x%08x bytes (%#x pad) at 0x%08x\n", len, pad, start);
+
+    if (start + len + pad > mboot_high_water_mark)
+	mboot_high_water_mark = start + len + pad;
+
+    return start;
+}
+
+addr_t map_string(const char *string)
+{
+    if (!string)
+	return 0;
+    else
+	return map_data(string, strlen(string) + 1, 1, 0);
+}
+
+int init_map(void)
+{
+    /*
+     * Note: mmap is the memory map (containing free and zeroed regions)
+     * needed by syslinux_shuffle_boot_pm(); amap is a map where we keep
+     * track ourselves which target memory ranges have already been
+     * allocated.
+     */
+    mmap = syslinux_memory_map();
+    amap = syslinux_dup_memmap(mmap);
+    if (!mmap || !amap) {
+	error("Failed to allocate initial memory map!\n");
+	return -1;
+    }
+
+    dprintf("Initial memory map:\n");
+    syslinux_dump_memmap(mmap);
+
+    return 0;
+}
+
+struct multiboot_header *map_image(void *ptr, size_t len)
+{
+    struct multiboot_header *mbh;
+    int mbh_len;
+    char *cptr = ptr;
+    Elf32_Ehdr *eh = ptr;
+    Elf32_Phdr *ph;
+    Elf32_Shdr *sh;
+    unsigned int i, mbh_offset;
+    uint32_t bad_flags;
+
+    /*
+     * Search for the multiboot header...
+     */
+    mbh_len = 0;
+    for (mbh_offset = 0; mbh_offset < MULTIBOOT_SEARCH; mbh_offset += 4) {
+	mbh = (struct multiboot_header *)((char *)ptr + mbh_offset);
+	if (mbh->magic != MULTIBOOT_MAGIC)
+	    continue;
+	if (mbh->magic + mbh->flags + mbh->checksum)
+	    continue;
+	if (mbh->flags & MULTIBOOT_VIDEO_MODE)
+	    mbh_len = 48;
+	else if (mbh->flags & MULTIBOOT_AOUT_KLUDGE)
+	    mbh_len = 32;
+	else
+	    mbh_len = 12;
+
+	if (mbh_offset + mbh_len > len)
+	    mbh_len = 0;	/* Invalid... */
+	else
+	    break;		/* Found something... */
+    }
+
+    if (mbh_len) {
+	bad_flags = mbh->flags & MULTIBOOT_UNSUPPORTED;
+	if (bad_flags) {
+	    printf("Unsupported Multiboot flags set: %#x\n", bad_flags);
+	    return NULL;
+	}
+    }
+
+    if (len < sizeof(Elf32_Ehdr) ||
+	memcmp(eh->e_ident, "\x7f" "ELF\1\1\1", 6) ||
+	(eh->e_machine != EM_386 && eh->e_machine != EM_486 &&
+	 eh->e_machine != EM_X86_64) ||
+	eh->e_version != EV_CURRENT ||
+	eh->e_ehsize < sizeof(Elf32_Ehdr) || eh->e_ehsize >= len ||
+	eh->e_phentsize < sizeof(Elf32_Phdr) ||
+	!eh->e_phnum || eh->e_phoff + eh->e_phentsize * eh->e_phnum > len)
+	eh = NULL;		/* No valid ELF header found */
+
+    /* Is this a Solaris kernel? */
+    if (!set.solaris && eh && kernel_is_solaris(eh))
+	opt.solaris = true;
+
+    /*
+     * Note: the Multiboot Specification implies that AOUT_KLUDGE should
+     * have precedence over the ELF header.  However, Grub disagrees, and
+     * Grub is "the reference bootloader" for the Multiboot Specification.
+     * This is insane, since it makes the AOUT_KLUDGE bit functionally
+     * useless, but at least Solaris apparently depends on this behavior.
+     */
+    if (eh && !(opt.aout && mbh_len && (mbh->flags & MULTIBOOT_AOUT_KLUDGE))) {
+	regs.eip = eh->e_entry;	/* Can be overridden further down... */
+
+	ph = (Elf32_Phdr *) (cptr + eh->e_phoff);
+
+	for (i = 0; i < eh->e_phnum; i++) {
+	    if (ph->p_type == PT_LOAD || ph->p_type == PT_PHDR) {
+		/*
+		 * This loads at p_paddr, which matches Grub.  However, if
+		 * e_entry falls within the p_vaddr range of this PHDR, then
+		 * adjust it to match the p_paddr range... this is how Grub
+		 * behaves, so it's by definition correct (it doesn't have to
+		 * make sense...)
+		 */
+		addr_t addr = ph->p_paddr;
+		addr_t msize = ph->p_memsz;
+		addr_t dsize = min(msize, ph->p_filesz);
+
+		if (eh->e_entry >= ph->p_vaddr
+		    && eh->e_entry < ph->p_vaddr + msize)
+		    regs.eip = eh->e_entry + (ph->p_paddr - ph->p_vaddr);
+
+		dprintf("Segment at 0x%08x data 0x%08x len 0x%08x\n",
+			addr, dsize, msize);
+
+		if (syslinux_memmap_type(amap, addr, msize) != SMT_FREE) {
+		    printf
+			("Memory segment at 0x%08x (len 0x%08x) is unavailable\n",
+			 addr, msize);
+		    return NULL;	/* Memory region unavailable */
+		}
+
+		/* Mark this region as allocated in the available map */
+		if (syslinux_add_memmap(&amap, addr, msize, SMT_ALLOC)) {
+		    error("Overlapping segments found in ELF header\n");
+		    return NULL;
+		}
+
+		if (ph->p_filesz) {
+		    /* Data present region.  Create a move entry for it. */
+		    if (syslinux_add_movelist
+			(&ml, addr, (addr_t) cptr + ph->p_offset, dsize)) {
+			error("Failed to map PHDR data\n");
+			return NULL;
+		    }
+		}
+		if (msize > dsize) {
+		    /* Zero-filled region.  Mark as a zero region in the memory map. */
+		    if (syslinux_add_memmap
+			(&mmap, addr + dsize, msize - dsize, SMT_ZERO)) {
+			error("Failed to map PHDR zero region\n");
+			return NULL;
+		    }
+		}
+		if (addr + msize > mboot_high_water_mark)
+		    mboot_high_water_mark = addr + msize;
+	    } else {
+		/* Ignore this program header */
+	    }
+
+	    ph = (Elf32_Phdr *) ((char *)ph + eh->e_phentsize);
+	}
+
+	/* Load the ELF symbol table */
+	if (eh->e_shoff) {
+	    addr_t addr, len;
+
+	    sh = (Elf32_Shdr *) ((char *)eh + eh->e_shoff);
+
+	    len = eh->e_shentsize * eh->e_shnum;
+	    /*
+	     * Align this, but don't pad -- in general this means a bunch of
+	     * smaller sections gets packed into a single page.
+	     */
+	    addr = map_data(sh, len, 4096, MAP_HIGH | MAP_NOPAD);
+	    if (!addr) {
+		error("Failed to map symbol table\n");
+		return NULL;
+	    }
+
+	    mbinfo.flags |= MB_INFO_ELF_SHDR;
+	    mbinfo.syms.e.addr = addr;
+	    mbinfo.syms.e.num = eh->e_shnum;
+	    mbinfo.syms.e.size = eh->e_shentsize;
+	    mbinfo.syms.e.shndx = eh->e_shstrndx;
+
+	    for (i = 0; i < eh->e_shnum; i++) {
+		addr_t align;
+
+		if (!sh[i].sh_size)
+		    continue;	/* Empty section */
+		if (sh[i].sh_flags & SHF_ALLOC)
+		    continue;	/* SHF_ALLOC sections should have PHDRs */
+
+		align = sh[i].sh_addralign ? sh[i].sh_addralign : 0;
+		addr = map_data((char *)ptr + sh[i].sh_offset, sh[i].sh_size,
+				align, MAP_HIGH);
+		if (!addr) {
+		    error("Failed to map symbol section\n");
+		    return NULL;
+		}
+		sh[i].sh_addr = addr;
+	    }
+	}
+    } else if (mbh_len && (mbh->flags & MULTIBOOT_AOUT_KLUDGE)) {
+	/*
+	 * a.out kludge thing...
+	 */
+	char *data_ptr;
+	addr_t data_len, bss_len;
+	addr_t bss_addr;
+
+	regs.eip = mbh->entry_addr;
+
+	data_ptr = (char *)mbh - (mbh->header_addr - mbh->load_addr);
+
+	if (mbh->load_end_addr)
+	    data_len = mbh->load_end_addr - mbh->load_addr;
+	else
+	    data_len = len - mbh_offset + (mbh->header_addr - mbh->load_addr);
+
+	bss_addr = mbh->load_addr + data_len;
+
+	if (mbh->bss_end_addr)
+	    bss_len = mbh->bss_end_addr - mbh->load_end_addr;
+	else
+	    bss_len = 0;
+
+	if (syslinux_memmap_type(amap, mbh->load_addr, data_len + bss_len)
+	    != SMT_FREE) {
+	    printf("Memory segment at 0x%08x (len 0x%08x) is unavailable\n",
+		   mbh->load_addr, data_len + bss_len);
+	    return NULL;		/* Memory region unavailable */
+	}
+	if (syslinux_add_memmap(&amap, mbh->load_addr,
+				data_len + bss_len, SMT_ALLOC)) {
+	    error("Failed to claim a.out address space!\n");
+	    return NULL;
+	}
+	if (data_len)
+	    if (syslinux_add_movelist(&ml, mbh->load_addr, (addr_t) data_ptr,
+				      data_len)) {
+		error("Failed to map a.out data\n");
+		return NULL;
+	    }
+	if (bss_len)
+	    if (syslinux_add_memmap
+		(&mmap, bss_addr, bss_len, SMT_ZERO)) {
+		error("Failed to map a.out bss\n");
+		return NULL;
+	    }
+	if (bss_addr + bss_len > mboot_high_water_mark)
+	    mboot_high_water_mark = bss_addr + bss_len;
+    } else {
+	error
+	    ("Invalid Multiboot image: neither ELF header nor a.out kludge found\n");
+	return NULL;
+    }
+
+    return mbh;
+}
+
+/*
+ * Set up a stack.  This isn't actually required by the spec, but it seems
+ * like a prudent thing to do.  Also, put enough zeros at the top of the
+ * stack that something that looks for an ELF invocation record will know
+ * there isn't one.
+ */
+static void mboot_map_stack(void)
+{
+    addr_t start, len;
+
+    if (syslinux_memmap_largest(amap, SMT_FREE, &start, &len) || len < 64)
+	return;			/* Not much we can do, here... */
+
+    regs.esp = (start + len - 32) & ~15;
+    dprintf("Mapping stack at 0x%08x\n", regs.esp);
+    syslinux_add_memmap(&mmap, regs.esp, 32, SMT_ZERO);
+}
+
+void mboot_run(int bootflags)
+{
+    mboot_map_stack();
+
+    dprintf("Running, eip = 0x%08x, ebx = 0x%08x\n", regs.eip, regs.ebx);
+
+    regs.eax = MULTIBOOT_VALID;
+    syslinux_shuffle_boot_pm(ml, mmap, bootflags, &regs);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/mb_header.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/mb_header.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/mb_header.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,88 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000   Free Software Foundation, Inc.
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef MBOOT_MB_HEADER_H
+#define MBOOT_MB_HEADER_H
+
+#include <inttypes.h>
+
+/*
+ *  MultiBoot Header description
+ */
+
+struct multiboot_header {
+    /* Must be MULTIBOOT_MAGIC - see below.  */
+    uint32_t magic;
+
+    /* Feature flags - see below.  */
+    uint32_t flags;
+
+    /*
+     * Checksum
+     *
+     * The above fields plus this one must equal 0 mod 2^32.
+     */
+    uint32_t checksum;
+
+    /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set.  */
+    uint32_t header_addr;
+    uint32_t load_addr;
+    uint32_t load_end_addr;
+    uint32_t bss_end_addr;
+    uint32_t entry_addr;
+
+    /* These are only valid if MULTIBOOT_VIDEO_MODE is set.  */
+    uint32_t mode_type;
+    uint32_t width;
+    uint32_t height;
+    uint32_t depth;
+};
+
+/*
+ * The entire multiboot_header must be contained
+ * within the first MULTIBOOT_SEARCH bytes of the kernel image.
+ */
+#define MULTIBOOT_SEARCH		8192
+
+/* Magic value identifying the multiboot_header.  */
+#define MULTIBOOT_MAGIC			0x1BADB002
+
+/*
+ * Features flags for 'flags'.
+ * If a boot loader sees a flag in MULTIBOOT_MUSTKNOW set
+ * and it doesn't understand it, it must fail.
+ */
+#define MULTIBOOT_MUSTKNOW		0x0000FFFF
+
+/* currently unsupported flags...  this is a kind of version number.  */
+#define MULTIBOOT_UNSUPPORTED		0x0000FFF8
+
+/* Align all boot modules on i386 page (4KB) boundaries.  */
+#define MULTIBOOT_PAGE_ALIGN		0x00000001
+
+/* Must pass memory information to OS.  */
+#define MULTIBOOT_MEMORY_INFO		0x00000002
+
+/* Must pass video information to OS.  */
+#define MULTIBOOT_VIDEO_MODE		0x00000004
+
+/* This flag indicates the use of the address fields in the header.  */
+#define MULTIBOOT_AOUT_KLUDGE		0x00010000
+
+#endif /* MBOOT_MB_HEADER_H */
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/mb_info.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/mb_info.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/mb_info.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,207 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000  Free Software Foundation, Inc.
+ *
+ *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *  The structure type "mod_list" is used by the "multiboot_info" structure.
+ */
+
+#ifndef MBOOT_MB_INFO_H
+#define MBOOT_MB_INFO_H
+
+#include <inttypes.h>
+
+struct mod_list {
+    /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
+    uint32_t mod_start;
+    uint32_t mod_end;
+
+    /* Module command line */
+    uint32_t cmdline;
+
+    /* padding to take it to 16 bytes (must be zero) */
+    uint32_t pad;
+};
+
+/*
+ *  INT-15, AX=E820 style "AddressRangeDescriptor"
+ *  ...with a "size" parameter on the front which is the structure size - 4,
+ *  pointing to the next one, up until the full buffer length of the memory
+ *  map has been reached.
+ */
+
+struct AddrRangeDesc {
+    uint32_t size;
+    uint64_t BaseAddr;
+    uint64_t Length;
+    uint32_t Type;
+    /* unspecified optional padding... */
+} __attribute__ ((packed));
+
+/* usable memory "Type", all others are reserved.  */
+#define MB_ARD_MEMORY		1
+
+/* Drive Info structure.  */
+struct drive_info {
+    /* The size of this structure.  */
+    uint32_t size;
+
+    /* The BIOS drive number.  */
+    uint8_t drive_number;
+
+    /* The access mode (see below).  */
+    uint8_t drive_mode;
+
+    /* The BIOS geometry.  */
+    uint16_t drive_cylinders;
+    uint8_t drive_heads;
+    uint8_t drive_sectors;
+
+    /* The array of I/O ports used for the drive.  */
+    uint16_t drive_ports[0];
+};
+
+/* Drive Mode.  */
+#define MB_DI_CHS_MODE		0
+#define MB_DI_LBA_MODE		1
+
+/* APM BIOS info.  */
+struct apm_info {
+    uint16_t version;
+    uint16_t cseg;
+    uint32_t offset;
+    uint16_t cseg_16;
+    uint16_t dseg_16;
+    uint16_t cseg_len;
+    uint16_t cseg_16_len;
+    uint16_t dseg_16_len;
+};
+
+/*
+ *  MultiBoot Info description
+ *
+ *  This is the struct passed to the boot image.  This is done by placing
+ *  its address in the EAX register.
+ */
+
+struct multiboot_info {
+    /* MultiBoot info version number */
+    uint32_t flags;
+
+    /* Available memory from BIOS */
+    uint32_t mem_lower;
+    uint32_t mem_upper;
+
+    /* "root" partition */
+    uint32_t boot_device;
+
+    /* Kernel command line */
+    uint32_t cmdline;
+
+    /* Boot-Module list */
+    uint32_t mods_count;
+    uint32_t mods_addr;
+
+    union {
+	struct {
+	    /* (a.out) Kernel symbol table info */
+	    uint32_t tabsize;
+	    uint32_t strsize;
+	    uint32_t addr;
+	    uint32_t pad;
+	} a;
+	struct {
+	    /* (ELF) Kernel section header table */
+	    uint32_t num;
+	    uint32_t size;
+	    uint32_t addr;
+	    uint32_t shndx;
+	} e;
+    } syms;
+
+    /* Memory Mapping buffer */
+    uint32_t mmap_length;
+    uint32_t mmap_addr;
+
+    /* Drive Info buffer */
+    uint32_t drives_length;
+    uint32_t drives_addr;
+
+    /* ROM configuration table */
+    uint32_t config_table;
+
+    /* Boot Loader Name */
+    uint32_t boot_loader_name;
+
+    /* APM table */
+    uint32_t apm_table;
+
+    /* Video */
+    uint32_t vbe_control_info;
+    uint32_t vbe_mode_info;
+    uint16_t vbe_mode;
+    uint16_t vbe_interface_seg;
+    uint16_t vbe_interface_off;
+    uint16_t vbe_interface_len;
+};
+
+/*
+ *  Flags to be set in the 'flags' parameter above
+ */
+
+/* is there basic lower/upper memory information? */
+#define MB_INFO_MEMORY			0x00000001
+/* is there a boot device set? */
+#define MB_INFO_BOOTDEV			0x00000002
+/* is the command-line defined? */
+#define MB_INFO_CMDLINE			0x00000004
+/* are there modules to do something with? */
+#define MB_INFO_MODS			0x00000008
+
+/* These next two are mutually exclusive */
+
+/* is there a symbol table loaded? */
+#define MB_INFO_AOUT_SYMS		0x00000010
+/* is there an ELF section header table? */
+#define MB_INFO_ELF_SHDR		0x00000020
+
+/* is there a full memory map? */
+#define MB_INFO_MEM_MAP			0x00000040
+
+/* Is there drive info?  */
+#define MB_INFO_DRIVE_INFO		0x00000080
+
+/* Is there a config table?  */
+#define MB_INFO_CONFIG_TABLE		0x00000100
+
+/* Is there a boot loader name?  */
+#define MB_INFO_BOOT_LOADER_NAME	0x00000200
+
+/* Is there a APM table?  */
+#define MB_INFO_APM_TABLE		0x00000400
+
+/* Is there video information?  */
+#define MB_INFO_VIDEO_INFO		0x00000800
+
+/*
+ *  The following value must be present in the EAX register.
+ */
+
+#define MULTIBOOT_VALID			0x2BADB002
+
+#endif /* MBOOT_MB_INFO_H */
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/mboot.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/mboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/mboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,247 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * mboot.c
+ *
+ * Module to load a multiboot kernel
+ */
+
+#include "mboot.h"
+
+struct multiboot_info mbinfo;
+struct syslinux_pm_regs regs;
+struct my_options opt, set;
+
+struct module_data {
+    void *data;
+    size_t len;
+    const char *cmdline;
+};
+
+static int map_modules(struct module_data *modules, int nmodules)
+{
+    struct mod_list *mod_list;
+    addr_t map_list = 0;
+    size_t list_size = nmodules * sizeof *mod_list;
+    int i;
+
+    mod_list = malloc(list_size);
+    if (!mod_list) {
+	printf("Failed to allocate module list\n");
+	return -1;
+    }
+
+    map_list = map_data(mod_list, list_size, 16, 0);
+    if (!map_list) {
+	printf("Cannot map module list\n");
+	return -1;
+    }
+
+    for (i = 0; i < nmodules; i++) {
+	addr_t mod_map = 0;
+	addr_t cmd_map = 0;
+
+	dprintf("Module %d cmdline: \"%s\"\n", i, modules[i].cmdline);
+
+	cmd_map = map_string(modules[i].cmdline);
+
+	mod_map = map_data(modules[i].data, modules[i].len, 4096, MAP_HIGH);
+	if (!mod_map) {
+	    printf("Failed to map module (memory fragmentation issue?)\n");
+	    return -1;
+	}
+	mod_list[i].mod_start = mod_map;
+	mod_list[i].mod_end = mod_map + modules[i].len;
+	mod_list[i].cmdline = cmd_map;
+	mod_list[i].pad = 0;
+    }
+
+    mbinfo.flags |= MB_INFO_MODS;
+    mbinfo.mods_count = nmodules;
+    mbinfo.mods_addr = map_list;
+    return 0;
+}
+
+static int get_modules(char **argv, struct module_data **mdp)
+{
+    char **argp, **argx;
+    struct module_data *mp;
+    int rv;
+    int module_count = 1;
+    int arglen;
+    const char module_separator[] = "---";
+
+    for (argp = argv; *argp; argp++) {
+	if (!strcmp(*argp, module_separator))
+	    module_count++;
+    }
+
+    *mdp = mp = malloc(module_count * sizeof(struct module_data));
+    if (!mp) {
+	error("Out of memory!\n");
+	return -1;
+    }
+
+    argp = argv;
+    while (*argp) {
+	/* Note: it seems Grub transparently decompresses all compressed files,
+	   not just the primary kernel. */
+	printf("Loading %s... ", *argp);
+	rv = zloadfile(*argp, &mp->data, &mp->len);
+
+	if (rv) {
+	    printf("failed!\n");
+	    return -1;
+	}
+	printf("ok\n");
+
+	/* 
+	 * Note: Grub includes the kernel filename in the command line, so we
+	 * want to match that behavior.
+	 */
+	arglen = 0;
+	for (argx = argp; *argx && strcmp(*argx, module_separator); argx++)
+	    arglen += strlen(*argx) + 1;
+
+	if (arglen == 0) {
+	    mp->cmdline = strdup("");
+	} else {
+	    char *p;
+	    mp->cmdline = p = malloc(arglen);
+	    for (; *argp && strcmp(*argp, module_separator); argp++) {
+		p = stpcpy(p, *argp);
+		*p++ = ' ';
+	    }
+	    *--p = '\0';
+	}
+	mp++;
+	if (*argp)
+	    argp++;		/* Advance past module_separator */
+    }
+
+    return module_count;
+}
+
+int main(int argc, char *argv[])
+{
+    int nmodules;
+    struct module_data *modules;
+    struct multiboot_header *mbh;
+    bool keeppxe = false;
+
+    openconsole(&dev_null_r, &dev_stdcon_w);
+
+    (void)argc;			/* Unused */
+    argv++;
+
+    while (*argv) {
+	bool v = true;
+	const char *p = *argv;
+
+	if (!memcmp(p, "-no", 3)) {
+	    v = false;
+	    p += 3;
+	}
+
+	if (!strcmp(p, "-solaris")) {
+	    opt.solaris = v;
+	    set.solaris = true;
+	} else if (!strcmp(p, "-aout")) {
+	    opt.aout = v;
+	    set.aout = true;
+	} else
+	    break;
+	argv++;
+    }
+
+    if (!*argv) {
+	error
+	    ("Usage: mboot.c32 [opts] mboot_file args... [--- module args...]...\n"
+	     "Options:\n"
+	     "  -solaris  Enable Solaris DHCP information passing\n"
+	     "  -aout     Use the \"a.out kludge\" if enabled, even for ELF\n"
+	     "            This matches the Multiboot spec, but differs from Grub\n");
+	return 1;
+    }
+
+    /* Load the files */
+    nmodules = get_modules(argv, &modules);
+    if (nmodules < 1) {
+	error("No files found!\n");
+	return 1;		/* Failure */
+    }
+
+    if (init_map())
+	return 1;		/* Failed to allocate initial map */
+
+    /*
+     * Map the primary image.  This should be done before mapping anything
+     * else, since it will have fixed address requirements.
+     */
+    mbh = map_image(modules[0].data, modules[0].len);
+    if (!mbh)
+	return 1;
+
+    /* Map the mbinfo structure */
+    regs.ebx = map_data(&mbinfo, sizeof mbinfo, 4, 0);
+    if (!regs.ebx) {
+	error("Failed to map Multiboot info structure!\n");
+	return 1;
+    }
+
+    /* Map the primary command line */
+    if (modules[0].cmdline) {
+	mbinfo.cmdline = map_string(modules[0].cmdline);
+	dprintf("Main cmdline: \"%s\"\n", modules[0].cmdline);
+	if (mbinfo.cmdline)
+	    mbinfo.flags |= MB_INFO_CMDLINE;
+    }
+
+    /* Map auxilliary images */
+    if (nmodules > 1) {
+	if (map_modules(modules + 1, nmodules - 1))
+	    return 1;
+    }
+
+    /* Add auxilliary information */
+    mboot_make_memmap();
+    mboot_apm();
+    mboot_syslinux_info();
+
+    if (opt.solaris)
+	mboot_solaris_dhcp_hack();
+
+    /* Set the graphics mode if requested */
+    set_graphics_mode(mbh, &mbinfo);
+
+    /* Run it */
+    mboot_run(keeppxe ? 3 : 0);
+    error("mboot.c32: boot failed\n");
+    return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/mboot.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/mboot.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/mboot.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,98 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * mboot.h
+ *
+ * Module to load a multiboot kernel
+ */
+
+#ifndef MBOOT_H
+
+#include <dprintf.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <minmax.h>
+#include <sys/stat.h>
+#include <elf.h>
+#include <console.h>
+
+#include <syslinux/loadfile.h>
+#include <syslinux/movebits.h>
+#include <syslinux/bootpm.h>
+#include <syslinux/config.h>
+
+#include "mb_header.h"
+#include "mb_info.h"
+
+static inline void error(const char *msg)
+{
+    fputs(msg, stderr);
+}
+
+/* mboot.c */
+extern struct multiboot_info mbinfo;
+extern struct syslinux_pm_regs regs;
+extern struct my_options {
+    bool solaris;
+    bool aout;
+} opt, set;
+
+/* map.c */
+#define MAP_HIGH	1
+#define MAP_NOPAD	2
+addr_t map_data(const void *data, size_t len, size_t align, int flags);
+addr_t map_string(const char *string);
+struct multiboot_header *map_image(void *ptr, size_t len);
+void mboot_run(int bootflags);
+int init_map(void);
+
+/* mem.c */
+void mboot_make_memmap(void);
+
+/* apm.c */
+void mboot_apm(void);
+
+/* solaris.c */
+bool kernel_is_solaris(const Elf32_Ehdr *);
+void mboot_solaris_dhcp_hack(void);
+
+/* syslinux.c */
+void mboot_syslinux_info(void);
+
+/* initvesa.c */
+void set_graphics_mode(const struct multiboot_header *mbh,
+		       struct multiboot_info *mbi);
+
+#endif /* MBOOT_H */
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/mem.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/mem.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/mem.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,223 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * mem.c
+ *
+ * Obtain a memory map for a Multiboot OS
+ *
+ * This differs from the libcom32 memory map functions in that it doesn't
+ * attempt to filter out memory regions...
+ */
+
+#include "mboot.h"
+#include <com32.h>
+
+struct e820_entry {
+    uint64_t start;
+    uint64_t len;
+    uint32_t type;
+};
+
+#define RANGE_ALLOC_BLOCK	128
+
+static int mboot_scan_memory(struct AddrRangeDesc **ardp, uint32_t * dosmem)
+{
+    com32sys_t ireg, oreg;
+    struct e820_entry *e820buf;
+    struct AddrRangeDesc *ard;
+    size_t ard_count, ard_space;
+    int rv = 0;
+
+    /* Use INT 12h to get DOS memory */
+    __intcall(0x12, &__com32_zero_regs, &oreg);
+    *dosmem = oreg.eax.w[0] << 10;
+    if (*dosmem < 32 * 1024 || *dosmem > 640 * 1024) {
+	/* INT 12h reports nonsense... now what? */
+	uint16_t ebda_seg = *(uint16_t *) 0x40e;
+	if (ebda_seg >= 0x8000 && ebda_seg < 0xa000)
+	    *dosmem = ebda_seg << 4;
+	else
+	    *dosmem = 640 * 1024;	/* Hope for the best... */
+    }
+
+    e820buf = lmalloc(sizeof(*e820buf));
+    if (!e820buf)
+	return 0;
+
+    /* Allocate initial space */
+    *ardp = ard = malloc(RANGE_ALLOC_BLOCK * sizeof *ard);
+    if (!ard)
+	goto out;
+
+    ard_count = 0;
+    ard_space = RANGE_ALLOC_BLOCK;
+
+    /* First try INT 15h AX=E820h */
+    memset(&ireg, 0, sizeof ireg);
+    ireg.eax.l = 0xe820;
+    ireg.edx.l = 0x534d4150;
+    /* ireg.ebx.l    = 0; */
+    ireg.ecx.l = sizeof(*e820buf);
+    ireg.es = SEG(e820buf);
+    ireg.edi.w[0] = OFFS(e820buf);
+    memset(e820buf, 0, sizeof *e820buf);
+
+    do {
+	__intcall(0x15, &ireg, &oreg);
+
+	if ((oreg.eflags.l & EFLAGS_CF) ||
+	    (oreg.eax.l != 0x534d4150) || (oreg.ecx.l < 20))
+	    break;
+
+	if (ard_count >= ard_space) {
+	    ard_space += RANGE_ALLOC_BLOCK;
+	    *ardp = ard = realloc(ard, ard_space * sizeof *ard);
+	    if (!ard) {
+		rv = ard_count;
+		goto out;
+	    }
+	}
+
+	ard[ard_count].size = 20;
+	ard[ard_count].BaseAddr = e820buf->start;
+	ard[ard_count].Length = e820buf->len;
+	ard[ard_count].Type = e820buf->type;
+	ard_count++;
+
+	ireg.ebx.l = oreg.ebx.l;
+    } while (oreg.ebx.l);
+
+    if (ard_count) {
+	rv = ard_count;
+	goto out;
+    };
+
+    ard[0].size = 20;
+    ard[0].BaseAddr = 0;
+    ard[0].Length = *dosmem << 10;
+    ard[0].Type = 1;
+
+    /* Next try INT 15h AX=E801h */
+    memset(&ireg, 0, sizeof ireg);
+    ireg.eax.w[0] = 0xe801;
+    __intcall(0x15, &ireg, &oreg);
+
+    if (!(oreg.eflags.l & EFLAGS_CF) && oreg.ecx.w[0]) {
+	ard[1].size = 20;
+	ard[1].BaseAddr = 1 << 20;
+	ard[1].Length = oreg.ecx.w[0] << 10;
+	ard[1].Type = 1;
+
+	if (oreg.edx.w[0]) {
+	    ard[2].size = 20;
+	    ard[2].BaseAddr = 16 << 20;
+	    ard[2].Length = oreg.edx.w[0] << 16;
+	    ard[2].Type = 1;
+	    rv = 3;
+	} else {
+	    rv = 2;
+	}
+
+	goto out;
+    }
+
+    /* Finally try INT 15h AH=88h */
+    memset(&ireg, 0, sizeof ireg);
+    ireg.eax.w[0] = 0x8800;
+    __intcall(0x15, &ireg, &oreg);
+    if (!(oreg.eflags.l & EFLAGS_CF) && oreg.eax.w[0]) {
+	ard[1].size = 20;
+	ard[1].BaseAddr = 1 << 20;
+	ard[1].Length = oreg.ecx.w[0] << 10;
+	ard[1].Type = 1;
+	rv = 2;
+	goto out;
+    }
+
+    rv = 1;			/* ... problematic ... */
+out:
+    lfree(e820buf);
+    return rv;
+}
+
+void mboot_make_memmap(void)
+{
+    int i, nmap;
+    struct AddrRangeDesc *ard;
+    uint32_t lowmem, highmem;
+    uint32_t highrsvd;
+
+    /* Always report DOS memory as "lowmem", this may be overly conservative
+       (e.g. if we're dropping PXE), but it should be *safe*... */
+
+    nmap = mboot_scan_memory(&ard, &lowmem);
+
+    highmem = 0x100000;
+    highrsvd = 0xfff00000;
+
+again:
+    for (i = 0; i < nmap; i++) {
+	uint64_t start, end;
+
+	start = ard[i].BaseAddr;
+	end = start + ard[i].Length;
+
+	if (end < start)
+	    end = ~0ULL;
+
+	if (start & 0xffffffff00000000ULL)
+	    continue;		/* Not interested in 64-bit memory */
+
+	if (start < highmem)
+	    start = highmem;
+
+	if (end <= start)
+	    continue;
+
+	if (ard[i].Type == 1 && start == highmem) {
+	    highmem = end;
+	    goto again;
+	} else if (ard[i].Type != 1 && start < highrsvd)
+	    highrsvd = start;
+    }
+
+    if (highmem > highrsvd)
+	highmem = highrsvd;
+
+    mbinfo.mem_lower = lowmem >> 10;
+    mbinfo.mem_upper = (highmem - 0x100000) >> 10;
+    mbinfo.flags |= MB_INFO_MEMORY;
+
+    /* The spec says this address should be +4, but Grub disagrees */
+    mbinfo.mmap_addr = map_data(ard, nmap * sizeof *ard, 4, false);
+    if (mbinfo.mmap_addr) {
+	mbinfo.mmap_length = nmap * sizeof *ard;
+	mbinfo.flags |= MB_INFO_MEM_MAP;
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/solaris.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/solaris.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/solaris.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,62 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * solaris.c
+ *
+ * Solaris DHCP hack
+ *
+ * Solaris uses a nonstandard hack to pass DHCP information from a netboot.
+ */
+
+#include "mboot.h"
+#include <syslinux/pxe.h>
+#include <syslinux/config.h>
+
+bool kernel_is_solaris(const Elf32_Ehdr *eh)
+{
+    return eh->e_ident[EI_OSABI] == 6;	/* ABI == Solaris */
+}
+
+void mboot_solaris_dhcp_hack(void)
+{
+    void *dhcpdata;
+    size_t dhcplen;
+
+    if (syslinux_derivative_info()->c.filesystem != SYSLINUX_FS_PXELINUX)
+	return;
+    
+    if (!pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK, &dhcpdata, &dhcplen)) {
+	mbinfo.drives_addr = map_data(dhcpdata, dhcplen, 4, 0);
+	if (mbinfo.drives_addr) {
+	    mbinfo.drives_length = dhcplen;
+	    mbinfo.boot_device = 0x20ffffff;
+	    mbinfo.flags =
+		(mbinfo.flags & ~MB_INFO_DRIVE_INFO) | MB_INFO_BOOTDEV;
+	}
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/syslinux.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/syslinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/syslinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,45 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010 Intel Corporation; author: H. Peter Anvin
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux.c
+ *
+ * Syslinux-specific information for the kernel
+ */
+
+#include <syslinux/config.h>
+#include "mboot.h"
+
+void mboot_syslinux_info(void)
+{
+    const struct syslinux_version *sv;
+
+    sv = syslinux_version();
+    mbinfo.boot_loader_name = map_string(sv->version_string);
+    if (mbinfo.boot_loader_name)
+	mbinfo.flags |= MB_INFO_BOOT_LOADER_NAME;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/mboot/vesa.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/mboot/vesa.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/mboot/vesa.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,100 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 1999-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef LIB_SYS_VESA_H
+#define LIB_SYS_VESA_H
+
+#include <inttypes.h>
+#include <com32.h>
+
+/* VESA General Information table */
+struct vesa_general_info {
+    uint32_t signature;		/* Magic number = "VESA" */
+    uint16_t version;
+    far_ptr_t vendor_string;
+    uint8_t capabilities[4];
+    far_ptr_t video_mode_ptr;
+    uint16_t total_memory;
+
+    uint16_t oem_software_rev;
+    far_ptr_t oem_vendor_name_ptr;
+    far_ptr_t oem_product_name_ptr;
+    far_ptr_t oem_product_rev_ptr;
+
+    uint8_t reserved[222];
+    uint8_t oem_data[256];
+} __attribute__ ((packed));
+
+#define VESA_MAGIC ('V' + ('E' << 8) + ('S' << 16) + ('A' << 24))
+#define VBE2_MAGIC ('V' + ('B' << 8) + ('E' << 16) + ('2' << 24))
+
+struct vesa_mode_info {
+    uint16_t mode_attr;
+    uint8_t win_attr[2];
+    uint16_t win_grain;
+    uint16_t win_size;
+    uint16_t win_seg[2];
+    far_ptr_t win_scheme;
+    uint16_t logical_scan;
+
+    uint16_t h_res;
+    uint16_t v_res;
+    uint8_t char_width;
+    uint8_t char_height;
+    uint8_t memory_planes;
+    uint8_t bpp;
+    uint8_t banks;
+    uint8_t memory_layout;
+    uint8_t bank_size;
+    uint8_t image_pages;
+    uint8_t page_function;
+
+    uint8_t rmask;
+    uint8_t rpos;
+    uint8_t gmask;
+    uint8_t gpos;
+    uint8_t bmask;
+    uint8_t bpos;
+    uint8_t resv_mask;
+    uint8_t resv_pos;
+    uint8_t dcm_info;
+
+    uint8_t *lfb_ptr;		/* Linear frame buffer address */
+    uint8_t *offscreen_ptr;	/* Offscreen memory address */
+    uint16_t offscreen_size;
+
+    uint8_t reserved[206];
+} __attribute__ ((packed));
+
+struct vesa_info {
+    struct vesa_general_info gi;
+    struct vesa_mode_info mi;
+};
+
+extern struct vesa_info vesa_info;
+
+#endif /* LIB_SYS_VESA_H */
