Index: bootcd/isolinux/syslinux-6.03/com32/elflink/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,36 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-2008 H. Peter Anvin - All Rights Reserved
+##
+##   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., 53 Temple Place Ste 330,
+##   Boston MA 02111-1307, USA; either version 2 of the License, or
+##   (at your option) any later version; incorporated herein by reference.
+##
+## -----------------------------------------------------------------------
+
+MODULES = 
+TESTFILES =
+
+all: $(MODULES) $(TESTFILES)
+
+test_memalign.elf : test_memalign.o  $(LIBS) $(C_LIBS)
+	$(LD) $(LDFLAGS) -o $@ $^
+
+test_com32.elf: CFLAGS += -DELF_DEBUG
+test_com32.elf: test_com32.o ../lib/libcom32min.a $(LIBGCC)
+	$(LD) -n $(LDFLAGS) -o $@ test_com32.o $(LIBGCC) --whole-archive ../lib/libcom32min.a -Map test_com32.map
+
+tidy dist:
+	rm -f *.o *.lo *.a *.lst *.elf .*.d *.map
+
+clean: tidy
+	rm -f *.lss *.c32 *.lnx *.com
+
+spotless: clean
+	rm -f *~ \#*
+
+install:
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,59 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2011-2013 Intel Corporation - All Rights Reserved
+##
+##   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., 53 Temple Place Ste 330,
+##   Boston MA 02111-1307, USA; either version 2 of the License, or
+##   (at your option) any later version; incorporated herein by reference.
+##
+## -----------------------------------------------------------------------
+
+VPATH = $(SRC)
+include $(MAKEDIR)/elf.mk
+
+CFLAGS += -I$(topdir)/core/elflink -I$(topdir)/core/include -I$(topdir)/com32/lib -fvisibility=hidden
+LIBS = --whole-archive $(objdir)/com32/lib/libcom32min.a
+
+OBJS = ldlinux.o cli.o readconfig.o refstr.o colors.o getadv.o adv.o \
+	execute.o chainboot.o kernel.o get_key.o advwrite.o setadv.o \
+	loadhigh.o msg.o
+
+BTARGET = $(LDLINUX)
+
+ifdef EFI_BUILD
+%.e$(BITS): %.elf
+	$(OBJCOPY) --strip-debug --strip-unneeded $< $@
+SONAME = $(patsubst %.elf,%.e$(BITS),$(@F))
+else
+SONAME = $(patsubst %.elf,%.c32,$(@F))
+endif
+
+all: $(BTARGET) ldlinux_lnx.a
+
+ldlinux.elf : $(OBJS)
+	$(LD) $(LDFLAGS) -soname $(SONAME) -o $@ $^ $(LIBS)
+
+LNXCFLAGS += -D__export='__attribute__((visibility("default")))'
+LNXLIBOBJS = get_key.lo
+ldlinux_lnx.a: $(LNXLIBOBJS)
+	rm -f $@
+	$(AR) cq $@ $(LNXLIBOBJS)
+	$(RANLIB) $@
+
+tidy dist:
+	rm -f *.o *.lo *.a *.lst .*.d 
+
+clean: tidy
+	rm -f *.lss *.lnx *.com
+
+spotless: clean
+	rm -f *~ \#* $(BTARGET)
+
+install: all
+	mkdir -m 755 -p $(INSTALLROOT)$(AUXDIR)
+	install -m 644 $(BTARGET) $(INSTALLROOT)$(AUXDIR)
+
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/adv.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/adv.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/adv.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,42 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/adv.c
+ *
+ * Access the syslinux auxilliary data vector
+ */
+
+#include <syslinux/adv.h>
+#include <syslinux/firmware.h>
+#include <klibc/compiler.h>
+#include <syslinux/adv.h>
+
+void __constructor __syslinux_init(void)
+{
+	firmware->adv_ops->init();
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/advwrite.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/advwrite.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/advwrite.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,41 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/advwrite.c
+ *
+ * Write back the ADV
+ */
+
+#include <klibc/compiler.h>
+#include <syslinux/adv.h>
+#include <syslinux/firmware.h>
+
+__export int syslinux_adv_write(void)
+{
+    return firmware->adv_ops->write();
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/chainboot.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/chainboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/chainboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,156 @@
+/* ----------------------------------------------------------------------- *
+ *   
+ *   Copyright 2012 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * chainbooting - replace the current bootloader completely.  This
+ * is BIOS-specific.
+ */
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <dprintf.h>
+
+#include <com32.h>
+#include <sys/exec.h>
+#include <sys/io.h>
+#include "core.h"
+#include "menu.h"
+#include "fs.h"
+#include "config.h"
+#include "localboot.h"
+#include "bios.h"
+
+#include <syslinux/boot.h>
+#include <syslinux/bootrm.h>
+#include <syslinux/movebits.h>
+#include <syslinux/config.h>
+
+void chainboot_file(const char *file, uint32_t type)
+{
+    uint8_t keeppxe = 0;
+    const union syslinux_derivative_info *sdi;
+    struct syslinux_rm_regs regs;
+    struct syslinux_movelist *fraglist = NULL;
+    struct syslinux_memmap *mmap = NULL;
+    struct com32_filedata fd;
+    com32sys_t reg;
+    char *stack;
+    void *buf;
+    int rv, max, size;
+    
+    max = 0xA0000;		/* Maximum load */
+    buf = malloc(max);
+    if (!buf)
+	goto bail;
+    
+    rv = open_file(file, O_RDONLY, &fd);
+    if (rv == -1)
+	goto bail;
+    
+    reg.eax.l = max;
+    reg.ebx.l = 0;
+    reg.edx.w[0] = 0;
+    reg.edi.l = (uint32_t)buf;
+    reg.ebp.l = -1;	/* XXX: limit? */
+    reg.esi.w[0] = rv;
+
+    pm_load_high(&reg);
+
+    size = reg.edi.l - (unsigned long)buf;
+    if (size > 0xA0000 - 0x7C00) {
+	printf("Too large for a boostrap (need LINUX instead of KERNEL?)\n");
+	goto bail;
+    }
+
+    mmap = syslinux_memory_map();
+    if (!mmap)
+	goto bail;
+
+    sdi = syslinux_derivative_info();
+
+    memset(&regs, 0, sizeof(regs));
+    regs.ip = 0x7c00;
+
+    if (sdi->c.filesystem == SYSLINUX_FS_SYSLINUX ||
+	sdi->c.filesystem == SYSLINUX_FS_EXTLINUX) {
+	if (syslinux_add_movelist(&fraglist, 0x800 - 18,
+				  (addr_t)sdi->r.esbx, 16))
+	    goto bail;
+
+	/* DS:SI points to partition info */
+	regs.esi.l = 0x800 - 18;
+    }
+
+    /*
+     * For a BSS boot sector we have to transfer the
+     * superblock.
+     */
+    if (sdi->c.filesystem == SYSLINUX_FS_SYSLINUX &&
+	type == IMAGE_TYPE_BSS && this_fs->fs_ops->copy_super(buf))
+	goto bail;
+
+    if (sdi->c.filesystem == SYSLINUX_FS_PXELINUX) {
+	keeppxe = 0x03;		/* Chainloading + keep PXE */
+	stack = (char *)sdi->r.fssi;
+
+	/*
+	 * Set up the registers with their initial values
+	 */
+
+	regs.eax.l = *(uint32_t *)&stack[36];
+	regs.ecx.l = *(uint32_t *)&stack[32];
+	regs.edx.l = *(uint32_t *)&stack[28];
+	regs.ebx.l = *(uint32_t *)&stack[24];
+	regs.esp.l = sdi->rr.r.esi.w[0] + 44;
+	regs.ebp.l = *(uint32_t *)&stack[16];
+	regs.esi.l = *(uint32_t *)&stack[12];
+	regs.edi.l = *(uint32_t *)&stack[8];
+	regs.es = *(uint16_t *)&stack[4];
+	regs.ss = sdi->rr.r.fs;
+	regs.ds = *(uint16_t *)&stack[6];
+	regs.fs = *(uint16_t *)&stack[2];
+	regs.gs = *(uint16_t *)&stack[0];
+    } else {
+	const uint16_t *esdi = (const uint16_t *)sdi->disk.esdi_ptr;
+
+	regs.esp.l = (uint16_t)(unsigned long)StackBuf + 44;
+
+	/*
+	 * DON'T DO THIS FOR PXELINUX...
+	 * For PXE, ES:BX -> PXENV+, and this would
+	 * corrupt that use.
+	 *
+	 * Restore ES:DI -> $PnP (if we were ourselves
+	 * called that way...)
+	 */
+	regs.edi.w[0] = esdi[0]; /* New DI */
+	regs.es       = esdi[2]; /* New ES */
+
+	regs.edx.l    = sdi->rr.r.edx.b[0]; /* Drive number -> DL */
+    }
+
+    if (syslinux_add_movelist(&fraglist, 0x7c00, (addr_t)buf, size))
+	goto bail;
+
+    syslinux_shuffle_boot_rm(fraglist, mmap, keeppxe, &regs);
+
+bail:
+    if (fraglist)
+	syslinux_free_movelist(fraglist);
+    if (mmap)
+	syslinux_free_memmap(mmap);
+    if (buf)
+	free(buf);
+    return;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/cli.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/cli.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/cli.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,486 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <console.h>
+#include <com32.h>
+#include <syslinux/adv.h>
+#include <syslinux/config.h>
+#include <setjmp.h>
+#include <netinet/in.h>
+#include <limits.h>
+#include <minmax.h>
+#include <linux/list.h>
+#include <sys/exec.h>
+#include <sys/module.h>
+#include <dprintf.h>
+#include <core.h>
+
+#include "getkey.h"
+#include "menu.h"
+#include "cli.h"
+#include "config.h"
+
+static struct list_head cli_history_head;
+
+void clear_screen(void)
+{
+    //dprintf("enter");
+    fputs("\033e\033%@\033)0\033(B\1#0\033[?25l\033[2J", stdout);
+}
+
+static int mygetkey_timeout(clock_t *kbd_to, clock_t *tto)
+{
+    clock_t t0, t1;
+    int key;
+
+    t0 = times(NULL);
+    key = get_key(stdin, *kbd_to ? *kbd_to : *tto);
+
+    /* kbdtimeout only applies to the first character */
+    if (*kbd_to)
+	*kbd_to = 0;
+
+    t1 = times(NULL) - t0;
+    if (*tto) {
+	/* Timed out. */
+	if (*tto <= (long long)t1)
+	    key = KEY_NONE;
+	else {
+	    /* Did it wrap? */
+	    if (*tto > totaltimeout)
+		key = KEY_NONE;
+
+	    *tto -= t1;
+	}
+    }
+
+    return key;
+}
+
+static const char * cmd_reverse_search(int *cursor, clock_t *kbd_to,
+				       clock_t *tto)
+{
+    int key;
+    int i = 0;
+    char buf[MAX_CMDLINE_LEN];
+    const char *p = NULL;
+    struct cli_command *last_found;
+    struct cli_command *last_good = NULL;
+
+    last_found = list_entry(cli_history_head.next, typeof(*last_found), list);
+
+    memset(buf, 0, MAX_CMDLINE_LEN);
+
+    printf("\033[1G\033[1;36m(reverse-i-search)`': \033[0m");
+    while (1) {
+	key = mygetkey_timeout(kbd_to, tto);
+
+	if (key == KEY_CTRL('C')) {
+	    return NULL;
+	} else if (key == KEY_CTRL('R')) {
+	    if (i == 0)
+		continue; /* User typed nothing yet */
+	    /* User typed 'CTRL-R' again, so try the next */
+	    last_found = list_entry(last_found->list.next, typeof(*last_found), list);
+	} else if (key >= ' ' && key <= 'z') {
+	        buf[i++] = key;
+	} else {
+	    /* Treat other input chars as terminal */
+	    break;
+	}
+
+	while (last_found) {
+	    p = strstr(last_found->command, buf);
+	    if (p)
+	        break;
+
+	    if (list_is_last(&last_found->list, &cli_history_head))
+		break;
+
+	    last_found = list_entry(last_found->list.next, typeof(*last_found), list);
+	}
+
+	if (!p && !last_good) {
+	    return NULL;
+	} else if (!p) {
+	    continue;
+	} else {
+	    last_good = last_found;
+            *cursor = p - last_good->command;
+	}
+
+	printf("\033[?7l\033[?25l");
+	/* Didn't handle the line wrap case here */
+	printf("\033[1G\033[1;36m(reverse-i-search)\033[0m`%s': %s",
+		buf, last_good->command ? : "");
+	printf("\033[K\r");
+    }
+
+    return last_good ? last_good->command : NULL;
+}
+
+
+
+const char *edit_cmdline(const char *input, int top /*, int width */ ,
+			 int (*pDraw_Menu) (int, int, int),
+			 void (*show_fkey) (int), bool *timedout)
+{
+    char cmdline[MAX_CMDLINE_LEN] = { };
+    int key, len, prev_len, cursor;
+    int redraw = 0;
+    int x, y;
+    bool done = false;
+    const char *ret;
+    int width = 0;
+    struct cli_command *comm_counter = NULL;
+    clock_t kbd_to = kbdtimeout;
+    clock_t tto = totaltimeout;
+
+    if (!width) {
+	int height;
+	if (getscreensize(1, &height, &width))
+	    width = 80;
+    }
+
+    len = cursor = 0;
+    prev_len = 0;
+    x = y = 0;
+
+    /*
+     * Before we start messing with the x,y coordinates print 'input'
+     * so that it follows whatever text has been written to the screen
+     * previously.
+     */
+    printf("%s ", input);
+
+    while (!done) {
+	if (redraw > 1) {
+	    /* Clear and redraw whole screen */
+	    /* Enable ASCII on G0 and DEC VT on G1; do it in this order
+	       to avoid confusing the Linux console */
+	    clear_screen();
+	    if (pDraw_Menu)
+		    (*pDraw_Menu) (-1, top, 1);
+	    prev_len = 0;
+	    printf("\033[2J\033[H");
+	    // printf("\033[0m\033[2J\033[H");
+	}
+
+	if (redraw > 0) {
+	    int dy, at;
+
+	    prev_len = max(len, prev_len);
+
+	    /* Redraw the command line */
+	    printf("\033[?25l");
+	    printf("\033[1G%s ", input);
+
+	    x = strlen(input);
+	    y = 0;
+	    at = 0;
+	    while (at < prev_len) {
+		putchar(at >= len ? ' ' : cmdline[at]);
+		at++;
+		x++;
+		if (x >= width) {
+		    printf("\r\n");
+		    x = 0;
+		    y++;
+		}
+	    }
+	    printf("\033[K\r");
+
+	    dy = y - (cursor + strlen(input) + 1) / width;
+	    x = (cursor + strlen(input) + 1) % width;
+
+	    if (dy) {
+		printf("\033[%dA", dy);
+		y -= dy;
+	    }
+	    if (x)
+		printf("\033[%dC", x);
+	    printf("\033[?25h");
+	    prev_len = len;
+	    redraw = 0;
+	}
+
+	key = mygetkey_timeout(&kbd_to, &tto);
+
+	switch (key) {
+	case KEY_NONE:
+	    /* We timed out. */
+	    *timedout = true;
+	    return NULL;
+
+	case KEY_CTRL('L'):
+	    redraw = 2;
+	    break;
+
+	case KEY_ENTER:
+	case KEY_CTRL('J'):
+	    ret = cmdline;
+	    done = true;
+	    break;
+
+	case KEY_BACKSPACE:
+	case KEY_DEL:
+	    if (cursor) {
+		memmove(cmdline + cursor - 1, cmdline + cursor,
+			len - cursor + 1);
+		len--;
+		cursor--;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_CTRL('D'):
+	case KEY_DELETE:
+	    if (cursor < len) {
+		memmove(cmdline + cursor, cmdline + cursor + 1, len - cursor);
+		len--;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_CTRL('U'):
+	    if (len) {
+		len = cursor = 0;
+		cmdline[len] = '\0';
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_CTRL('W'):
+	    if (cursor) {
+		int prevcursor = cursor;
+
+		while (cursor && my_isspace(cmdline[cursor - 1]))
+		    cursor--;
+
+		while (cursor && !my_isspace(cmdline[cursor - 1]))
+		    cursor--;
+
+#if 0
+		memmove(cmdline + cursor, cmdline + prevcursor,
+			len - prevcursor + 1);
+#else
+		{
+		    int i;
+		    char *q = cmdline + cursor;
+		    char *p = cmdline + prevcursor;
+		    for (i = 0; i < len - prevcursor + 1; i++)
+			*q++ = *p++;
+		}
+#endif
+		len -= (prevcursor - cursor);
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_LEFT:
+	case KEY_CTRL('B'):
+	    if (cursor) {
+		cursor--;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_RIGHT:
+	case KEY_CTRL('F'):
+	    if (cursor < len) {
+		putchar(cmdline[cursor]);
+		cursor++;
+		x++;
+		if (x >= width) {
+		    printf("\r\n");
+		    y++;
+		    x = 0;
+		}
+	    }
+	    break;
+
+	case KEY_CTRL('K'):
+	    if (cursor < len) {
+		cmdline[len = cursor] = '\0';
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_HOME:
+	case KEY_CTRL('A'):
+	    if (cursor) {
+		cursor = 0;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_END:
+	case KEY_CTRL('E'):
+	    if (cursor != len) {
+		cursor = len;
+		redraw = 1;
+	    }
+	    break;
+
+	case KEY_F1:
+	case KEY_F2:
+	case KEY_F3:
+	case KEY_F4:
+	case KEY_F5:
+	case KEY_F6:
+	case KEY_F7:
+	case KEY_F8:
+	case KEY_F9:
+	case KEY_F10:
+	case KEY_F11:
+	case KEY_F12:
+	    if (show_fkey != NULL) {
+		(*show_fkey) (key);
+		redraw = 1;
+	    }
+	    break;
+	case KEY_CTRL('P'):
+	case KEY_UP:
+	    {
+		if (!list_empty(&cli_history_head)) {
+		    struct list_head *next;
+
+		    if (!comm_counter)
+			next = cli_history_head.next;
+		    else
+			next = comm_counter->list.next;
+
+		    comm_counter =
+			list_entry(next, typeof(*comm_counter), list);
+
+		    if (&comm_counter->list != &cli_history_head)
+			strcpy(cmdline, comm_counter->command);
+
+		    cursor = len = strlen(cmdline);
+		    redraw = 1;
+		}
+	    }
+	    break;
+	case KEY_CTRL('N'):
+	case KEY_DOWN:
+	    {
+		if (!list_empty(&cli_history_head)) {
+		    struct list_head *prev;
+
+		    if (!comm_counter)
+			prev = cli_history_head.prev;
+		    else
+			prev = comm_counter->list.prev;
+
+		    comm_counter =
+			list_entry(prev, typeof(*comm_counter), list);
+
+		    if (&comm_counter->list != &cli_history_head)
+			strcpy(cmdline, comm_counter->command);
+
+		    cursor = len = strlen(cmdline);
+		    redraw = 1;
+		}
+	    }
+	    break;
+	case KEY_CTRL('R'):
+	    {
+	         /* 
+	          * Handle this case in another function, since it's 
+	          * a kind of special.
+	          */
+	        const char *p = cmd_reverse_search(&cursor, &kbd_to, &tto);
+	        if (p) {
+	            strcpy(cmdline, p);
+		    len = strlen(cmdline);
+	        } else {
+	            cmdline[0] = '\0';
+		    cursor = len = 0;
+	        }
+	        redraw = 1;
+	    }
+	    break;
+	case KEY_TAB:
+	    {
+		const char *p;
+		size_t len;
+
+		/* Label completion enabled? */
+		if (nocomplete)
+	            break;
+
+		p = cmdline;
+		len = 0;
+		while(*p && !my_isspace(*p)) {
+		    p++;
+		    len++;
+		}
+
+		print_labels(cmdline, len);
+		redraw = 1;
+		break;
+	    }
+	case KEY_CTRL('V'):
+	    if (BIOSName)
+		printf("%s%s%s", syslinux_banner,
+		       (char *)MK_PTR(0, BIOSName), copyright_str);
+	    else
+		printf("%s%s", syslinux_banner, copyright_str);
+
+	    redraw = 1;
+	    break;
+
+	default:
+	    if (key >= ' ' && key <= 0xFF && len < MAX_CMDLINE_LEN - 1) {
+		if (cursor == len) {
+		    cmdline[len++] = key;
+		    cmdline[len] = '\0';
+		    putchar(key);
+		    cursor++;
+		    x++;
+		    if (x >= width) {
+			printf("\r\n\033[K");
+			y++;
+			x = 0;
+		    }
+		    prev_len++;
+		} else {
+		    if (cursor > len)
+			return NULL;
+
+		    memmove(cmdline + cursor + 1, cmdline + cursor,
+			    len - cursor + 1);
+		    cmdline[cursor++] = key;
+		    len++;
+		    redraw = 1;
+		}
+	    }
+	    break;
+	}
+    }
+
+    printf("\033[?7h");
+
+    /* Add the command to the history if its length is larger than 0 */
+    len = strlen(ret);
+    if (len > 0) {
+	comm_counter = malloc(sizeof(struct cli_command));
+	comm_counter->command = malloc(sizeof(char) * (len + 1));
+	strcpy(comm_counter->command, ret);
+	list_add(&(comm_counter->list), &cli_history_head);
+    }
+
+    return len ? ret : NULL;
+}
+
+static int __constructor cli_init(void)
+{
+	INIT_LIST_HEAD(&cli_history_head);
+
+	return 0;
+}
+
+static void __destructor cli_exit(void)
+{
+	/* Nothing to do */
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/colors.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/colors.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/colors.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,184 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <colortbl.h>
+#include "menu.h"
+
+/*
+ * The color/attribute indexes (\1#X, \2#XX, \3#XXX) are as follows
+ *
+ * 00 - screen		Rest of the screen
+ * 01 - border		Border area
+ * 02 - title		Title bar
+ * 03 - unsel		Unselected menu item
+ * 04 - hotkey		Unselected hotkey
+ * 05 - sel		Selection bar
+ * 06 - hotsel		Selected hotkey
+ * 07 - scrollbar	Scroll bar
+ * 08 - tabmsg		Press [Tab] message
+ * 09 - cmdmark		Command line marker
+ * 10 - cmdline		Command line
+ * 11 - pwdborder	Password box border
+ * 12 - pwdheader	Password box header
+ * 13 - pwdentry	Password box contents
+ * 14 - timeout_msg	Timeout message
+ * 15 - timeout		Timeout counter
+ * 16 - help		Current entry help text
+ * 17 - disabled        Disabled menu item
+ */
+
+static const struct color_table default_colors[] = {
+    {"screen", "37;40", 0x80ffffff, 0x00000000, SHADOW_NORMAL},
+    {"border", "30;44", 0x40000000, 0x00000000, SHADOW_NORMAL},
+    {"title", "1;36;44", 0xc00090f0, 0x00000000, SHADOW_NORMAL},
+    {"unsel", "37;44", 0x90ffffff, 0x00000000, SHADOW_NORMAL},
+    {"hotkey", "1;37;44", 0xffffffff, 0x00000000, SHADOW_NORMAL},
+    {"sel", "7;37;40", 0xe0000000, 0x20ff8000, SHADOW_ALL},
+    {"hotsel", "1;7;37;40", 0xe0400000, 0x20ff8000, SHADOW_ALL},
+    {"scrollbar", "30;44", 0x40000000, 0x00000000, SHADOW_NORMAL},
+    {"tabmsg", "31;40", 0x90ffff00, 0x00000000, SHADOW_NORMAL},
+    {"cmdmark", "1;36;40", 0xc000ffff, 0x00000000, SHADOW_NORMAL},
+    {"cmdline", "37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL},
+    {"pwdborder", "30;47", 0x80ffffff, 0x20ffffff, SHADOW_NORMAL},
+    {"pwdheader", "31;47", 0x80ff8080, 0x20ffffff, SHADOW_NORMAL},
+    {"pwdentry", "30;47", 0x80ffffff, 0x20ffffff, SHADOW_NORMAL},
+    {"timeout_msg", "37;40", 0x80ffffff, 0x00000000, SHADOW_NORMAL},
+    {"timeout", "1;37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL},
+    {"help", "37;40", 0xc0ffffff, 0x00000000, SHADOW_NORMAL},
+    {"disabled", "1;30;44", 0x60cccccc, 0x00000000, SHADOW_NORMAL},
+};
+
+#define NCOLORS (sizeof default_colors/sizeof default_colors[0])
+const int message_base_color = NCOLORS;
+const int menu_color_table_size = NCOLORS + 256;
+
+/* Algorithmically generate the msgXX colors */
+void set_msg_colors_global(struct color_table *tbl,
+			   unsigned int fg, unsigned int bg,
+			   enum color_table_shadow shadow)
+{
+    struct color_table *cp = tbl + message_base_color;
+    unsigned int i;
+    unsigned int fga, bga;
+    unsigned int fgh, bgh;
+    unsigned int fg_idx, bg_idx;
+    unsigned int fg_rgb, bg_rgb;
+
+    static const unsigned int pc2rgb[8] =
+	{ 0x000000, 0x0000ff, 0x00ff00, 0x00ffff, 0xff0000, 0xff00ff, 0xffff00,
+	0xffffff
+    };
+
+    /* Converting PC RGBI to sensible RGBA values is an "interesting"
+       proposition.  This algorithm may need plenty of tweaking. */
+
+    fga = fg & 0xff000000;
+    fgh = ((fg >> 1) & 0xff000000) | 0x80000000;
+
+    bga = bg & 0xff000000;
+    bgh = ((bg >> 1) & 0xff000000) | 0x80000000;
+
+    for (i = 0; i < 256; i++) {
+	fg_idx = i & 15;
+	bg_idx = i >> 4;
+
+	fg_rgb = pc2rgb[fg_idx & 7] & fg;
+	bg_rgb = pc2rgb[bg_idx & 7] & bg;
+
+	if (fg_idx & 8) {
+	    /* High intensity foreground */
+	    fg_rgb |= fgh;
+	} else {
+	    fg_rgb |= fga;
+	}
+
+	if (bg_idx == 0) {
+	    /* Default black background, assume transparent */
+	    bg_rgb = 0;
+	} else if (bg_idx & 8) {
+	    bg_rgb |= bgh;
+	} else {
+	    bg_rgb |= bga;
+	}
+
+	cp->argb_fg = fg_rgb;
+	cp->argb_bg = bg_rgb;
+	cp->shadow = shadow;
+	cp++;
+    }
+}
+
+struct color_table *default_color_table(void)
+{
+    unsigned int i;
+    const struct color_table *dp;
+    struct color_table *cp;
+    struct color_table *color_table;
+    static const int pc2ansi[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+    static char msg_names[6 * 256];
+    char *mp;
+
+    color_table = calloc(NCOLORS + 256, sizeof(struct color_table));
+
+    dp = default_colors;
+    cp = color_table;
+
+    for (i = 0; i < NCOLORS; i++) {
+	*cp = *dp;
+	cp->ansi = refstrdup(dp->ansi);
+	cp++;
+	dp++;
+    }
+
+    mp = msg_names;
+    for (i = 0; i < 256; i++) {
+	cp->name = mp;
+	mp += sprintf(mp, "msg%02x", i) + 1;
+
+	rsprintf(&cp->ansi, "%s3%d;4%d", (i & 8) ? "1;" : "",
+		 pc2ansi[i & 7], pc2ansi[(i >> 4) & 7]);
+	cp++;
+    }
+
+  /*** XXX: This needs to move to run_menu() ***/
+    console_color_table = color_table;
+    console_color_table_size = NCOLORS + 256;
+
+    set_msg_colors_global(color_table, MSG_COLORS_DEF_FG,
+			  MSG_COLORS_DEF_BG, MSG_COLORS_DEF_SHADOW);
+
+    return color_table;
+}
+
+struct color_table *copy_color_table(const struct color_table *master)
+{
+    const struct color_table *dp;
+    struct color_table *color_table, *cp;
+    unsigned int i;
+
+    color_table = calloc(NCOLORS + 256, sizeof(struct color_table));
+
+    dp = master;
+    cp = color_table;
+
+    for (i = 0; i < NCOLORS + 256; i++) {
+	*cp = *dp;
+	cp->ansi = refstr_get(dp->ansi);
+	cp++;
+	dp++;
+    }
+
+    return color_table;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/config.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/config.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/config.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,52 @@
+/*
+ *   Copyright 2011 Intel Corporation - All Rights Reserved
+ *
+ *   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.
+ *
+ */
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+/*
+ * These values correspond to the "default" and "ui" commands
+ * respectively. "ui" takes precendence over "default".
+ */
+#define LEVEL_DEFAULT	1
+#define LEVEL_UI	2
+
+extern short uappendlen;	//bytes in append= command
+extern short ontimeoutlen;	//bytes in ontimeout command
+extern short onerrorlen;	//bytes in onerror command
+extern short forceprompt;	//force prompt
+extern short noescape;		//no escape
+extern short nocomplete;	//no label completion on TAB key
+extern short allowimplicit;	//allow implicit kernels
+extern short allowoptions;	//user-specified options allowed
+extern short includelevel;	//nesting level
+extern short defaultlevel;	//the current level of default
+extern short vkernel;		//have we seen any "label" statements?
+extern short displaycon;	//conio.inc
+extern short nohalt;		//idle.inc
+
+extern const char *default_cmd;	//"default" command line
+extern const char *onerror;	//"onerror" command line
+extern const char *ontimeout;	//"ontimeout" command line
+
+extern void cat_help_file(int key);
+extern struct menu_entry *find_label(const char *str);
+extern void print_labels(const char *prefix, size_t len);
+
+extern int new_linux_kernel(char *okernel, char *ocmdline);
+
+extern void pm_load_high(com32sys_t *regs);
+
+extern void ldlinux_enter_command(void);
+extern void ldlinux_console_init(void);
+extern const char *apply_extension(const char *kernel, const char *ext);
+
+#endif /* __CONFIG_H__ */
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/execute.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/execute.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/execute.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,174 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <dprintf.h>
+
+#include <com32.h>
+#include <sys/exec.h>
+#include <sys/io.h>
+#include <sys/module.h>
+#include "core.h"
+#include "menu.h"
+#include "fs.h"
+#include "config.h"
+#include "localboot.h"
+#include "bios.h"
+
+#include <syslinux/bootrm.h>
+#include <syslinux/movebits.h>
+#include <syslinux/config.h>
+#include <syslinux/boot.h>
+
+const struct image_types image_boot_types[] = {
+    { "localboot", IMAGE_TYPE_LOCALBOOT },
+    { "kernel", IMAGE_TYPE_KERNEL },
+    { "linux", IMAGE_TYPE_LINUX },
+    { "boot", IMAGE_TYPE_BOOT },
+    { "bss", IMAGE_TYPE_BSS },
+    { "pxe", IMAGE_TYPE_PXE },
+    { "fdimage", IMAGE_TYPE_FDIMAGE },
+    { "com32", IMAGE_TYPE_COM32 },
+    { "config", IMAGE_TYPE_CONFIG },
+    { NULL, 0 },
+};
+
+extern int create_args_and_load(char *);
+
+__export void execute(const char *cmdline, uint32_t type, bool sysappend)
+{
+	const char *kernel, *args;
+	const char *p;
+	com32sys_t ireg;
+	char *q, ch;
+
+	memset(&ireg, 0, sizeof ireg);
+
+	if (strlen(cmdline) >= MAX_CMDLINE_LEN) {
+		printf("cmdline too long\n");
+		return;
+	}
+
+	q = malloc(MAX_CMDLINE_LEN);
+	if (!q) {
+		printf("%s(): Fail to malloc a buffer to exec %s\n",
+			__func__, cmdline);
+		return;
+	}
+
+	kernel = q;
+	p = cmdline;
+	while (*p && !my_isspace(*p))
+		*q++ = *p++;
+	*q++ = '\0';
+
+	args = q;
+	while (*p && my_isspace(*p))
+		p++;
+
+	do {
+		*q++ = ch = *p++;
+	} while (ch);
+
+	if (sysappend) {
+		/* If we've seen some args, insert a space */
+		if (--q != args)
+			*q++ = ' ';
+
+		do_sysappend(q);
+	}
+
+	dprintf("kernel is %s, args = %s  type = %d \n", kernel, args, type);
+
+	if (kernel[0] == '.') {
+		/* It might be a type specifier */
+		const struct image_types *t;
+		for (t = image_boot_types; t->name; t++) {
+			if (!strcmp(kernel + 1, t->name)) {
+				/*
+				 * Strip the type specifier, apply the
+				 * filename extension if COM32 and
+				 * retry.
+				 */
+				p = args;
+				if (t->type == IMAGE_TYPE_COM32) {
+					p = apply_extension(p, ".c32");
+					if (!p)
+						return;
+				}
+
+				execute(p, t->type, sysappend);
+				return;
+			}
+		}
+	}
+
+	if (type == IMAGE_TYPE_COM32) {
+		/*
+		 * We may be called with the console in an unknown
+		 * state, so initialise it.
+		 */
+		ldlinux_console_init();
+
+		/* new entry for elf format c32 */
+		if (create_args_and_load((char *)cmdline))
+			printf("Failed to load COM32 file %s\n", kernel);
+
+		/*
+		 * The old COM32 module code would run the module then
+		 * drop the user back at the command prompt,
+		 * irrespective of how the COM32 module was loaded,
+		 * e.g. from vesamenu.c32.
+		 */
+		unload_modules_since(LDLINUX);
+
+		/* Restore the console */
+		ldlinux_console_init();
+
+		ldlinux_enter_command();
+	} else if (type == IMAGE_TYPE_CONFIG) {
+		char *argv[] = { LDLINUX, NULL, NULL };
+		char *config;
+		int rv;
+
+		/* kernel contains the config file name */
+		config = malloc(FILENAME_MAX);
+		if (!config)
+			goto out;
+
+		realpath(config, kernel, FILENAME_MAX);
+
+		/* If we got anything on the command line, do a chdir */
+		if (*args)
+			mangle_name(config_cwd, args);
+
+		argv[1] = config;
+		rv = start_ldlinux(2, argv);
+		printf("Failed to exec %s: %s\n", LDLINUX, strerror(rv));
+	} else if (type == IMAGE_TYPE_LOCALBOOT) {
+		local_boot(strtoul(kernel, NULL, 0));
+	} else if (type == IMAGE_TYPE_PXE || type == IMAGE_TYPE_BSS ||
+		   type == IMAGE_TYPE_BOOT) {
+		chainboot_file(kernel, type);
+	} else {
+		/* Need add one item for kernel load, as we don't use
+		* the assembly runkernel.inc any more */
+		new_linux_kernel((char *)kernel, (char *)args);
+	}
+
+out:
+	free((void *)kernel);
+
+	/* If this returns, something went bad; return to menu */
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/get_key.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/get_key.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/get_key.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,243 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * get_key.c
+ *
+ * Get a single key, and try to pick apart function key codes.
+ * This doesn't decode anywhere close to all possiblities, but
+ * hopefully is enough to be useful.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/times.h>
+#include <getkey.h>
+#include <libutil.h>
+#include <sys/file.h>
+
+struct keycode {
+    int code;
+    int seqlen;
+    const unsigned char *seq;
+};
+
+#define CODE(x,y) { x, (sizeof y)-1, (const unsigned char *)(y) }
+
+static const struct keycode keycodes[] = {
+    /* First, the BIOS combined codes */
+    CODE(KEY_F1, "\0\x3B"),
+    CODE(KEY_F2, "\0\x3C"),
+    CODE(KEY_F3, "\0\x3D"),
+    CODE(KEY_F4, "\0\x3E"),
+    CODE(KEY_F5, "\0\x3F"),
+    CODE(KEY_F6, "\0\x40"),
+    CODE(KEY_F7, "\0\x41"),
+    CODE(KEY_F8, "\0\x42"),
+    CODE(KEY_F9, "\0\x43"),
+    CODE(KEY_F10, "\0\x44"),
+    CODE(KEY_F11, "\0\x85"),
+    CODE(KEY_F12, "\0\x86"),
+
+    CODE(KEY_UP, "\0\x48"),
+    CODE(KEY_DOWN, "\0\x50"),
+    CODE(KEY_LEFT, "\0\x4B"),
+    CODE(KEY_RIGHT, "\0\x4D"),
+    CODE(KEY_PGUP, "\0\x49"),
+    CODE(KEY_PGDN, "\0\x51"),
+    CODE(KEY_HOME, "\0\x47"),
+    CODE(KEY_END, "\0\x4F"),
+    CODE(KEY_INSERT, "\0\x52"),
+    CODE(KEY_DELETE, "\0\x53"),
+
+    /* Now, VT/xterm/Linux codes */
+    CODE(KEY_F1, "\033[[A"),
+    CODE(KEY_F1, "\033OP"),
+    CODE(KEY_F2, "\033[[B"),
+    CODE(KEY_F2, "\033OQ"),
+    CODE(KEY_F3, "\033[[C"),
+    CODE(KEY_F3, "\033OR"),
+    CODE(KEY_F4, "\033[[D"),
+    CODE(KEY_F4, "\033OS"),
+    CODE(KEY_F5, "\033[[E"),
+    CODE(KEY_F5, "\033[15~"),
+    CODE(KEY_F6, "\033[17~"),
+    CODE(KEY_F7, "\033[18~"),
+    CODE(KEY_F8, "\033[19~"),
+    CODE(KEY_F9, "\033[20~"),
+    CODE(KEY_F10, "\033[21~"),
+    CODE(KEY_F11, "\033[23~"),
+    CODE(KEY_F12, "\033[24~"),
+
+    CODE(KEY_UP, "\033[A"),
+    CODE(KEY_DOWN, "\033[B"),
+    CODE(KEY_LEFT, "\033[D"),
+    CODE(KEY_RIGHT, "\033[C"),
+    CODE(KEY_PGUP, "\033[5~"),
+    CODE(KEY_PGUP, "\033[V"),
+    CODE(KEY_PGDN, "\033[6~"),
+    CODE(KEY_PGDN, "\033[U"),
+    CODE(KEY_HOME, "\033[1~"),
+    CODE(KEY_HOME, "\033[H"),
+    CODE(KEY_END, "\033[4~"),
+    CODE(KEY_END, "\033[F"),
+    CODE(KEY_END, "\033OF"),
+    CODE(KEY_INSERT, "\033[2~"),
+    CODE(KEY_INSERT, "\033[@"),
+    CODE(KEY_DELETE, "\033[3~"),
+
+    /* EFI scan codes */
+    CODE(KEY_UP, "\0\x01"),
+    CODE(KEY_DOWN, "\0\x02"),
+    CODE(KEY_RIGHT, "\0\x03"),
+    CODE(KEY_LEFT, "\0\x04"),
+    CODE(KEY_HOME, "\0\x05"),
+    CODE(KEY_END, "\0\x06"),
+    CODE(KEY_INSERT, "\0\x07"),
+    CODE(KEY_DELETE, "\0\x08"),
+    CODE(KEY_PGUP, "\0\x09"),
+    CODE(KEY_PGDN, "\0\x0a"),
+    CODE(KEY_F1, "\0\x0b"),
+    CODE(KEY_F2, "\0\x0c"),
+    CODE(KEY_F3, "\0\x0d"),
+    CODE(KEY_F4, "\0\x0e"),
+    CODE(KEY_F5, "\0\x0f"),
+    CODE(KEY_F6, "\0\x10"),
+    CODE(KEY_F7, "\0\x11"),
+    CODE(KEY_F8, "\0\x12"),
+    CODE(KEY_F9, "\0\x13"),
+    CODE(KEY_F10, "\0\x14"),
+    CODE(KEY_F11, "\0\x15"),
+    CODE(KEY_F12, "\0\x16"),
+    CODE(KEY_ESC, "\0\x17"),
+};
+
+#define NCODES ((int)(sizeof keycodes/sizeof(struct keycode)))
+
+#define KEY_TIMEOUT ((CLK_TCK+9)/10)
+
+/*
+ * Attempt to decode the key sequence in 'buffer'.
+ *
+ * On success (the data in 'buffer' matches a key code) put the
+ * corresponding key code in 'code' and return 0. Return 1 if 'buffer'
+ * partially matches a key code, i.e. we need more data before we can
+ * make an unambiguous match. Return -1 if the buffer does not contain
+ * a key code.
+ */
+int get_key_decode(char *buffer, int nc, int *code)
+{
+    const struct keycode *kc;
+    int i, rv;
+
+    rv = -1;
+    for (i = 0, kc = keycodes; i < NCODES; i++, kc++) {
+	if (nc == kc->seqlen && !memcmp(buffer, kc->seq, nc)) {
+	    *code = kc->code;
+	    rv = 0;
+	    break;
+	} else if (nc < kc->seqlen && !memcmp(buffer, kc->seq, nc)) {
+	    rv = 1;
+	    break;
+	}
+    }
+
+    return rv;
+}
+
+#ifdef __COM32__
+extern ssize_t __rawcon_read(struct file_info *fp, void *buf, size_t count);
+
+int raw_read(int fd, void *buf, size_t count)
+{
+	(void)fd;
+
+	/*
+	 * Instead of using the read(2) stdlib function use
+	 * __rawcon_read() directly since we want a single key and
+	 * don't want any processing/batching of the user input to
+	 * occur - we want the raw data.
+	 */
+	return __rawcon_read(NULL, buf, count);
+}
+#else
+extern int raw_read(int fd, void *buf, size_t count);
+#endif
+
+__export int get_key(FILE * f, clock_t timeout)
+{
+    char buffer[KEY_MAXLEN];
+    int nc, rv;
+    int another;
+    char ch;
+    clock_t start;
+    int code;
+
+    /* We typically start in the middle of a clock tick */
+    if (timeout)
+	timeout++;
+
+    nc = 0;
+    start = times(NULL);
+    do {
+	rv = raw_read(fileno(f), &ch, 1);
+	if (rv == 0 || (rv == -1 && errno == EAGAIN)) {
+	    clock_t lateness = times(NULL) - start;
+	    if (nc && lateness > 1 + KEY_TIMEOUT) {
+		if (nc == 1)
+		    return (unsigned char)buffer[0];	/* timeout */
+		else if (timeout && lateness > timeout)
+		    return KEY_NONE;
+	    } else if (!nc && timeout && lateness > timeout)
+		return KEY_NONE;	/* timeout before sequence */
+
+	    do_idle();
+
+	    another = 1;
+	    continue;
+	}
+
+	start = times(NULL);
+
+	buffer[nc++] = ch;
+
+	another = 0;
+	rv = get_key_decode(buffer, nc, &code);
+	if (!rv)
+		return code;
+	else if (rv == 1)
+		another = 1;
+
+    } while (another);
+
+    /* We got an unrecognized sequence; return the first character */
+    /* We really should remember this and return subsequent characters later */
+    return (unsigned char)buffer[0];
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/getadv.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/getadv.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/getadv.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,68 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/getadv.c
+ *
+ * Get a data item from the auxilliary data vector.  Returns a pointer
+ * and sets *size on success; NULL on failure.
+ */
+
+#include <syslinux/adv.h>
+#include <klibc/compiler.h>
+#include <inttypes.h>
+
+__export const void *syslinux_getadv(int tag, size_t * size)
+{
+    const uint8_t *p;
+    size_t left;
+
+    p = syslinux_adv_ptr();
+    left = syslinux_adv_size();
+
+    while (left >= 2) {
+	uint8_t ptag = *p++;
+	size_t plen = *p++;
+	left -= 2;
+
+	if (ptag == ADV_END)
+	    return NULL;	/* Not found */
+
+	if (left < plen)
+	    return NULL;	/* Item overrun */
+
+	if (ptag == tag) {
+	    *size = plen;
+	    return p;
+	}
+
+	p += plen;
+	left -= plen;
+    }
+
+    return NULL;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/kernel.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/kernel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/kernel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,131 @@
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <console.h>
+#include <dprintf.h>
+#include <syslinux/loadfile.h>
+#include <syslinux/linux.h>
+#include <syslinux/pxe.h>
+#include "core.h"
+
+const char *globaldefault = NULL;
+const char *append = NULL;
+
+/* Will be called from readconfig.c */
+int new_linux_kernel(char *okernel, char *ocmdline)
+{
+	const char *kernel_name = NULL, *args = NULL;
+	struct initramfs *initramfs = NULL;
+	char *temp;
+	void *kernel_data;
+	size_t kernel_len, cmdline_len;
+	bool opt_quiet = false;
+	char *initrd_name, *cmdline;
+
+	dprintf("okernel = %s, ocmdline = %s", okernel, ocmdline);
+
+	if (okernel)
+		kernel_name = okernel;
+	else if (globaldefault)
+		kernel_name = globaldefault;
+
+	if (ocmdline)
+		args = ocmdline;
+	else if (append)
+		args = append;
+
+	cmdline_len = strlen("BOOT_IMAGE=") + strlen(kernel_name);
+	cmdline_len += 1;	/* space between BOOT_IMAGE and args */
+	cmdline_len += strlen(args);
+	cmdline_len += 1;	/* NUL-termination */
+
+	cmdline = malloc(cmdline_len);
+	if (!cmdline) {
+	    printf("Failed to alloc memory for cmdline\n");
+	    return 1;
+	}
+
+	sprintf(cmdline, "BOOT_IMAGE=%s %s", kernel_name, args);
+
+	/* "keeppxe" handling */
+#if IS_PXELINUX
+	extern char KeepPXE;
+
+	if (strstr(cmdline, "keeppxe"))
+		KeepPXE |= 1;
+#endif
+
+	if (strstr(cmdline, "quiet"))
+		opt_quiet = true;
+
+	if (!opt_quiet)
+		printf("Loading %s... ", kernel_name);
+
+	if (loadfile(kernel_name, &kernel_data, &kernel_len)) {
+		if (opt_quiet)
+			printf("Loading %s ", kernel_name);
+		printf("failed: ");
+		goto bail;
+	}
+
+	if (!opt_quiet)
+		printf("ok\n");
+
+	/* Find and load initramfs */
+	temp = strstr(cmdline, "initrd=");
+	if (temp) {
+		/* Initialize the initramfs chain */
+		initramfs = initramfs_init();
+		if (!initramfs)
+			goto bail;
+
+		temp += 6; /* strlen("initrd") */
+		do {
+		    size_t n = 0;
+		    char *p;
+
+		    temp++;	/* Skip = or , */
+
+		    p = temp;
+		    while (*p != ' ' && *p != ',' && *p) {
+			p++;
+			n++;
+		    }
+
+		    initrd_name = malloc(n + 1);
+		    if (!initrd_name) {
+			printf("Failed to allocate space for initrd\n");
+			goto bail;
+		    }
+
+		    snprintf(initrd_name, n + 1, "%s", temp);
+		    temp += n;
+
+		    if (!opt_quiet)
+			printf("Loading %s...", initrd_name);
+
+		    if (initramfs_load_archive(initramfs, initrd_name)) {
+			if (opt_quiet)
+			    printf("Loading %s ", initrd_name);
+			free(initrd_name);
+			printf("failed: ");
+			goto bail;
+		    }
+
+		    free(initrd_name);
+
+		    if (!opt_quiet)
+			printf("ok\n");
+		} while (*temp == ',');
+	}
+
+	/* This should not return... */
+	syslinux_boot_linux(kernel_data, kernel_len, initramfs, NULL, cmdline);
+	printf("Booting kernel failed: ");
+
+bail:
+	free(cmdline);
+	printf("%s\n", strerror(errno));
+	return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/ldlinux.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/ldlinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/ldlinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,348 @@
+#include <linux/list.h>
+#include <sys/times.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <string.h>
+#include <core.h>
+#include <fs.h>
+#include "cli.h"
+#include "console.h"
+#include "com32.h"
+#include "menu.h"
+#include "config.h"
+#include "syslinux/adv.h"
+#include "syslinux/boot.h"
+#include "syslinux/config.h"
+
+#include <sys/module.h>
+
+struct file_ext {
+	const char *name;
+	enum kernel_type type;
+};
+
+static const struct file_ext file_extensions[] = {
+	{ ".c32", IMAGE_TYPE_COM32 },
+	{ ".img", IMAGE_TYPE_FDIMAGE },
+	{ ".bss", IMAGE_TYPE_BSS },
+	{ ".bin", IMAGE_TYPE_BOOT },
+	{ ".bs", IMAGE_TYPE_BOOT },
+	{ ".0", IMAGE_TYPE_PXE },
+	{ NULL, 0 },
+};
+
+/*
+ * Return a pointer to one byte after the last character of the
+ * command.
+ */
+static inline const char *find_command(const char *str)
+{
+	const char *p;
+
+	p = str;
+	while (*p && !my_isspace(*p))
+		p++;
+	return p;
+}
+
+__export uint32_t parse_image_type(const char *kernel)
+{
+	const struct file_ext *ext;
+	const char *p;
+	int len;
+
+	/* Find the end of the command */
+	p = find_command(kernel);
+	len = p - kernel;
+
+	for (ext = file_extensions; ext->name; ext++) {
+		int elen = strlen(ext->name);
+
+		if (!strncmp(kernel + len - elen, ext->name, elen))
+			return ext->type;
+	}
+
+	/* use IMAGE_TYPE_KERNEL as default */
+	return IMAGE_TYPE_KERNEL;
+}
+
+/*
+ * Returns the kernel name with file extension if one wasn't present.
+ */
+static const char *get_extension(const char *kernel)
+{
+	const struct file_ext *ext;
+	const char *p;
+	int len;
+
+	/* Find the end of the command */
+	p = find_command(kernel);
+	len = p - kernel;
+
+	for (ext = file_extensions; ext->name; ext++) {
+		char *str;
+		int elen = strlen(ext->name);
+		FILE *f;
+
+		str = malloc(len + elen + 1);
+
+		strncpy(str, kernel, len);
+		strncpy(str + len, ext->name, elen);
+		str[len + elen] = '\0';
+		f = findpath(str);
+		free(str);
+
+		if (f) {
+			fclose(f);
+			return ext->name;
+		}
+	}
+
+	return NULL;
+}
+
+const char *apply_extension(const char *kernel, const char *ext)
+{
+	const char *p;
+	char *k;
+	int len = strlen(kernel);
+	int elen = strlen(ext);
+
+	k = malloc(len + elen + 1);
+	if (!k)
+		return NULL;
+
+	p = find_command(kernel);
+
+	len = p - kernel;
+
+	/* Copy just the kernel name */
+	memcpy(k, kernel, len);
+
+	/* Append the extension */
+	if (strncmp(p - elen, ext, elen)) {
+		memcpy(k + len, ext, elen);
+		len += elen;
+	}
+
+	/* Copy the rest of the command line */
+	strcpy(k + len, p);
+
+	k[len + strlen(p)] = '\0';
+
+	return k;
+}
+
+/*
+ * Attempt to load a kernel after deciding what type of image it is.
+ *
+ * We only return from this function if something went wrong loading
+ * the the kernel. If we return the caller should call enter_cmdline()
+ * so that the user can help us out.
+ */
+__export void load_kernel(const char *command_line)
+{
+	struct menu_entry *me;
+	const char *cmdline;
+	const char *kernel;
+	uint32_t type;
+
+	kernel = strdup(command_line);
+	if (!kernel)
+		goto bad_kernel;
+
+	/* Virtual kernel? */
+	me = find_label(kernel);
+	if (me) {
+		const char *args;
+		char *cmd;
+		size_t len = strlen(me->cmdline) + 1;
+
+		/* Find the end of the command */
+		args = find_command(kernel);
+		while(*args && my_isspace(*args))
+			args++;
+
+		if (strlen(args))
+			len += strlen(args) + 1; /* +1 for space (' ') */
+
+		cmd = malloc(len);
+		if (!cmd)
+			goto bad_kernel;
+
+		if (strlen(args))
+			snprintf(cmd, len, "%s %s", me->cmdline, args);
+		else
+			strncpy(cmd, me->cmdline, len);
+
+		type = parse_image_type(cmd);
+		execute(cmd, type, false);
+		/* We shouldn't return */
+		goto bad_kernel;
+	}
+
+	if (!allowimplicit)
+		goto bad_implicit;
+
+	/* Insert a null character to ignore any user-specified options */
+	if (!allowoptions) {
+		char *p = (char *)find_command(kernel);
+		*p = '\0';
+	}
+
+	type = parse_image_type(kernel);
+	if (type == IMAGE_TYPE_KERNEL) {
+		const char *ext;
+
+		/*
+		 * Automatically lookup the extension if one wasn't
+		 * supplied by the user.
+		 */
+		ext = get_extension(kernel);
+		if (ext) {
+			const char *k;
+
+			k = apply_extension(kernel, ext);
+			if (!k)
+				goto bad_kernel;
+
+			free((void *)kernel);
+			kernel = k;
+
+			type = parse_image_type(kernel);
+		}
+	}
+
+	execute(kernel, type, true);
+	free((void *)kernel);
+
+bad_implicit:
+bad_kernel:
+	/*
+	 * If we fail to boot the kernel execute the "onerror" command
+	 * line.
+	 */
+	if (onerrorlen) {
+		me = find_label(onerror);
+		if (me)
+			rsprintf(&cmdline, "%s %s", me->cmdline, default_cmd);
+		else
+			rsprintf(&cmdline, "%s %s", onerror, default_cmd);
+
+		type = parse_image_type(cmdline);
+		execute(cmdline, type, true);
+	}
+}
+
+/*
+ * If this function returns you must call ldinux_enter_command() to
+ * preserve the 4.0x behaviour.
+ */
+void ldlinux_auto_boot(void)
+{
+	if (!defaultlevel) {
+		if (strlen(ConfigName))
+			printf("No DEFAULT or UI configuration directive found!\n");
+		if (noescape)
+			kaboom();
+	} else
+		load_kernel(default_cmd);
+}
+
+static void enter_cmdline(void)
+{
+	const char *cmdline;
+
+	/* Enter endless command line prompt, should support "exit" */
+	while (1) {
+		bool to = false;
+
+		if (noescape) {
+			ldlinux_auto_boot();
+			continue;
+		}
+
+		cmdline = edit_cmdline("boot:", 1, NULL, cat_help_file, &to);
+		printf("\n");
+
+		/* return if user only press enter or we timed out */
+		if (!cmdline || cmdline[0] == '\0') {
+			if (to && ontimeoutlen)
+				load_kernel(ontimeout);
+			else
+				ldlinux_auto_boot();
+		} else
+			load_kernel(cmdline);
+	}
+}
+
+void ldlinux_enter_command(void)
+{
+	enter_cmdline();
+}
+
+/*
+ * Undo the work we did in openconsole().
+ */
+static void __destructor close_console(void)
+{
+	int i;
+
+	for (i = 0; i <= 2; i++)
+		close(i);
+}
+
+void ldlinux_console_init(void)
+{
+	openconsole(&dev_stdcon_r, &dev_ansiserial_w);
+}
+
+__export int main(int argc __unused, char **argv)
+{
+	const void *adv;
+	const char *cmdline;
+	size_t count = 0;
+
+	ldlinux_console_init();
+
+	parse_configs(&argv[1]);
+
+	__syslinux_set_serial_console_info();
+
+	adv = syslinux_getadv(ADV_BOOTONCE, &count);
+	if (adv && count) {
+		/*
+		 * We apparently have a boot-once set; clear it and
+		 * then execute the boot-once.
+		 */
+		char *src, *dst;
+		size_t i;
+
+		src = (char *)adv;
+		cmdline = dst = malloc(count + 1);
+		if (!dst) {
+			printf("Failed to allocate memory for ADV\n");
+			ldlinux_enter_command();
+		}
+
+		for (i = 0; i < count; i++)
+			*dst++ = *src++;
+		*dst = '\0';	/* Null-terminate */
+
+		/* Clear the boot-once data from the ADV */
+		if (!syslinux_setadv(ADV_BOOTONCE, 0, NULL))
+			syslinux_adv_write();
+
+		load_kernel(cmdline); /* Shouldn't return */
+		ldlinux_enter_command();
+	}
+
+	if (!forceprompt && !shift_is_held())
+		ldlinux_auto_boot();
+
+	if (defaultlevel > 1)
+		ldlinux_auto_boot();
+
+	ldlinux_enter_command();
+	return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/loadhigh.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/loadhigh.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/loadhigh.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,112 @@
+/*
+ * -----------------------------------------------------------------------
+ *
+ *   Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 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., 53 Temple Place Ste 330,
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * loadhigh.c
+ *
+ * An alternate interface to getfssec.
+ *
+ * Inputs:	SI  = file handle/cluster pointer
+ *		EDI = target address in high memory
+ *		EAX = maximum number of bytes to load
+ *		DX  = zero-padding mask (e.g. 0003h for pad to dword)
+ *		BX  = 16-bit subroutine to call at the top of each loop
+ *                    (to print status and check for abort)
+ *		EBP = maximum load address
+ *
+ * Outputs:	SI  = file handle/cluster pointer
+ *		EBX = first untouched address (not including padding)
+ *		EDI = first untouched address (including padding)
+ *		CF  = reached EOF
+ *		OF  = ran out of high memory
+ */
+
+#include <com32.h>
+#include <minmax.h>
+#include "core.h"
+#include "fs.h"
+
+#define MAX_CHUNK	(1UL << 20) /* 1 MB */
+
+void pm_load_high(com32sys_t *regs)
+{
+    struct fs_info *fs;
+    uint32_t bytes;
+    uint32_t zero_mask;
+    bool have_more;
+    uint32_t bytes_read;
+    char *buf, *limit;
+    struct file *file;
+    uint32_t sector_mask;
+    size_t pad;
+    uint32_t retflags = 0;
+
+    bytes     = regs->eax.l;
+    zero_mask = regs->edx.w[0];
+    buf       = (char *)regs->edi.l;
+    limit     = (char *)(regs->ebp.l & ~zero_mask);
+    file      = handle_to_file(regs->esi.w[0]);
+    fs        = file->fs;
+
+    sector_mask = SECTOR_SIZE(fs) - 1;
+
+    while (bytes) {
+	uint32_t sectors;
+	uint32_t chunk;
+
+	if (buf + SECTOR_SIZE(fs) > limit) {
+	    /* Can't fit even one more sector in... */
+	    retflags = EFLAGS_OF;
+	    break;
+	}
+
+	chunk = bytes;
+
+	if (regs->ebx.w[0]) {
+	    call16((void (*)(void))(size_t)regs->ebx.w[0], &zero_regs, NULL);
+	    chunk = min(chunk, MAX_CHUNK);
+	}
+
+	if (chunk > (((char *)limit - buf) & ~sector_mask))
+	    chunk = ((char *)limit - buf) & ~sector_mask;
+
+	sectors = (chunk + sector_mask) >> SECTOR_SHIFT(fs);
+	bytes_read = fs->fs_ops->getfssec(file, buf, sectors, &have_more);
+
+	if (bytes_read > chunk)
+	    bytes_read = chunk;
+
+	buf += bytes_read;
+	bytes -= bytes_read;
+
+	if (!have_more) {
+	    /*
+	     * If we reach EOF, the filesystem driver will have already closed
+	     * the underlying file... this really should be cleaner.
+	     */
+	    _close_file(file);
+	    regs->esi.w[0] = 0;
+	    retflags = EFLAGS_CF;
+	    break;
+	}
+    }
+
+    pad = (size_t)buf & zero_mask;
+    if (pad)
+	memset(buf, 0, pad);
+
+    regs->ebx.l = (size_t)buf;
+    regs->edi.l = (size_t)buf + pad;
+    set_flags(regs, retflags);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/msg.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/msg.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/msg.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,229 @@
+#include <syslinux/video.h>
+#include <com32.h>
+#include <stdio.h>
+#include <bios.h>
+#include <graphics.h>
+
+static uint8_t TextAttribute;	/* Text attribute for message file */
+extern uint8_t DisplayMask;	/* Display modes mask */
+
+/* Routine to interpret next print char */
+static void (*NextCharJump)(uint8_t);
+
+void msg_initvars(void);
+static void msg_setfg(uint8_t data);
+static void msg_putchar(uint8_t ch);
+
+/*
+ *
+ * get_msg_file: Load a text file and write its contents to the screen,
+ *               interpreting color codes.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+int get_msg_file(char *filename)
+{
+	FILE *f;
+	char ch;
+
+	f = fopen(filename, "r");
+	if (!f)
+		return -1;
+
+	TextAttribute = 0x7;	/* Default grey on white */
+	DisplayMask = 0x7;	/* Display text in all modes */
+	msg_initvars();
+
+	/*
+	 * Read the text file a byte at a time and interpret that
+	 * byte.
+	 */
+	while ((ch = getc(f)) != EOF) {
+		/* DOS EOF? */
+		if (ch == 0x1A)
+			break;
+
+		NextCharJump(ch);	/* Do what shall be done */
+	}
+
+	DisplayMask = 0x07;
+
+	fclose(f);
+	return 0;
+}
+
+static inline int display_mask_vga(void)
+{
+	uint8_t mask = UsingVGA & 0x1;
+	return (DisplayMask & ++mask);
+}
+
+static void msg_setbg(uint8_t data)
+{
+	if (unhexchar(&data) == 0) {
+		data <<= 4;
+		if (display_mask_vga())
+			TextAttribute = data;
+
+		NextCharJump = msg_setfg;
+	} else {
+		TextAttribute = 0x7;	/* Default attribute */
+		NextCharJump = msg_putchar;
+	}
+}
+
+static void msg_setfg(uint8_t data)
+{
+	if (unhexchar(&data) == 0) {
+		if (display_mask_vga()) {
+			/* setbg set foreground to 0 */
+			TextAttribute |= data;
+		}
+	} else
+		TextAttribute = 0x7;	/* Default attribute */
+
+	NextCharJump = msg_putchar;
+}
+
+static inline void msg_ctrl_o(void)
+{
+	NextCharJump = msg_setbg;
+}
+
+/* Convert ANSI colors to PC display attributes */
+static int convert_to_pcdisplay[] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+
+static void set_fgbg(void)
+{
+	uint8_t bg, fg;
+
+	fg = convert_to_pcdisplay[(TextAttribute & 0x7)];
+	bg = convert_to_pcdisplay[((TextAttribute >> 4) & 0x7)];
+
+	printf("\033[");
+	if (TextAttribute & 0x8)
+		printf("1;"); /* Foreground bright */
+
+	printf("3%dm\033[", fg);
+
+	if (TextAttribute & 0x80)
+		printf("5;"); /* Foreground blink */
+
+	printf("4%dm", bg);
+}
+
+static void msg_formfeed(void)
+{
+	set_fgbg();
+	printf("\033[2J\033[H\033[0m");
+}
+
+static void msg_novga(void)
+{
+	syslinux_force_text_mode();
+	msg_initvars();
+}
+
+static void msg_viewimage(void)
+{
+	FILE *f;
+
+	*VGAFilePtr = '\0';	/* Zero-terminate filename */
+
+	mangle_name(VGAFileMBuf, VGAFileBuf);
+	f = fopen(VGAFileMBuf, "r");
+	if (!f) {
+		/* Not there */
+		NextCharJump = msg_putchar;
+		return;
+	}
+
+	vgadisplayfile(f);
+	fclose(f);
+	msg_initvars();
+}
+
+/*
+ * Getting VGA filename
+ */
+static void msg_filename(uint8_t data)
+{
+	/* <LF> = end of filename */
+	if (data == 0x0A) {
+		msg_viewimage();
+		return;
+	}
+
+	/* Ignore space/control char */
+	if (data > ' ') {
+		if ((char *)VGAFilePtr < (VGAFileBuf + sizeof(VGAFileBuf)))
+			*VGAFilePtr++ = data;
+	}
+}
+
+static void msg_vga(void)
+{
+	NextCharJump = msg_filename;
+	VGAFilePtr = (uint16_t *)VGAFileBuf;
+}
+
+static void msg_normal(uint8_t data)
+{
+	/* 0x1 = text mode, 0x2 = graphics mode */
+	if (!display_mask_vga() || !(DisplayCon & 0x01)) {
+		/* Write to serial port */
+		if (DisplayMask & 0x4)
+			write_serial(data);
+
+		return;		/* Not screen */
+	}
+
+	set_fgbg();
+	printf("%c\033[0m", data);
+}
+
+static void msg_modectl(uint8_t data)
+{
+	data &= 0x07;
+	DisplayMask = data;
+	NextCharJump = msg_putchar;
+}
+
+static void msg_putchar(uint8_t ch)
+{
+	/* 10h to 17h are mode controls */
+	if (ch >= 0x10 && ch < 0x18) {
+		msg_modectl(ch);
+		return;
+	}
+
+	switch (ch) {
+	case 0x0F:		/* ^O = color code follows */
+		msg_ctrl_o();
+		break;
+	case 0x0D:		/* Ignore <CR> */
+		break;
+	case 0x0C:		/* <FF> = clear screen */
+		msg_formfeed();
+		break;
+	case 0x19:		/* <EM> = return to text mode */
+		msg_novga();
+		break;
+	case 0x18:		/* <CAN> = VGA filename follows */
+		msg_vga();
+		break;
+	default:
+		msg_normal(ch);
+		break;
+	}
+}
+
+/*
+ * Subroutine to initialize variables, also needed after loading
+ * graphics file.
+ */
+void msg_initvars(void)
+{
+	/* Initialize state machine */
+	NextCharJump = msg_putchar;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/readconfig.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/readconfig.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/readconfig.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1571 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2004-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2013 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <sys/io.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <minmax.h>
+#include <alloca.h>
+#include <inttypes.h>
+#include <colortbl.h>
+#include <com32.h>
+#include <syslinux/adv.h>
+#include <syslinux/config.h>
+#include <dprintf.h>
+#include <ctype.h>
+#include <bios.h>
+#include <core.h>
+#include <fs.h>
+#include <syslinux/pxe_api.h>
+
+#include "menu.h"
+#include "config.h"
+#include "getkey.h"
+#include "core.h"
+#include "fs.h"
+
+const struct menu_parameter mparm[NPARAMS] = {
+    [P_WIDTH] = {"width", 0},
+    [P_MARGIN] = {"margin", 10},
+    [P_PASSWD_MARGIN] = {"passwordmargin", 3},
+    [P_MENU_ROWS] = {"rows", 12},
+    [P_TABMSG_ROW] = {"tabmsgrow", 18},
+    [P_CMDLINE_ROW] = {"cmdlinerow", 18},
+    [P_END_ROW] = {"endrow", -1},
+    [P_PASSWD_ROW] = {"passwordrow", 11},
+    [P_TIMEOUT_ROW] = {"timeoutrow", 20},
+    [P_HELPMSG_ROW] = {"helpmsgrow", 22},
+    [P_HELPMSGEND_ROW] = {"helpmsgendrow", -1},
+    [P_HSHIFT] = {"hshift", 0},
+    [P_VSHIFT] = {"vshift", 0},
+    [P_HIDDEN_ROW] = {"hiddenrow", -2},
+};
+
+/* Must match enum kernel_type */
+static const char *const kernel_types[] = {
+    "none",
+    "localboot",
+    "kernel",
+    "linux",
+    "boot",
+    "bss",
+    "pxe",
+    "fdimage",
+    "comboot",
+    "com32",
+    "config",
+    NULL
+};
+
+short uappendlen = 0;		//bytes in append= command
+short ontimeoutlen = 0;		//bytes in ontimeout command
+short onerrorlen = 0;		//bytes in onerror command
+short forceprompt = 0;		//force prompt
+short noescape = 0;		//no escape
+short nocomplete = 0;		//no label completion on TAB key
+short allowimplicit = 1;	//allow implicit kernels
+short allowoptions = 1;		//user-specified options allowed
+short includelevel = 1;		//nesting level
+short defaultlevel = 0;		//the current level of default
+short vkernel = 0;		//have we seen any "label" statements?
+extern short NoHalt;		//idle.c
+
+const char *onerror = NULL;	//"onerror" command line
+const char *ontimeout = NULL;	//"ontimeout" command line
+
+__export const char *default_cmd = NULL;	//"default" command line
+
+/* Empty refstring */
+const char *empty_string;
+
+/* Root menu, starting menu, hidden menu, and list of all menus */
+struct menu *root_menu, *start_menu, *hide_menu, *menu_list, *default_menu;
+
+/* These are global parameters regardless of which menu we're displaying */
+int shiftkey = 0;		/* Only display menu if shift key pressed */
+int hiddenmenu = 0;
+long long totaltimeout = 0;
+unsigned int kbdtimeout = 0;
+
+/* Keep track of global default */
+static int has_ui = 0;		/* DEFAULT only counts if UI is found */
+extern const char *globaldefault;
+static bool menusave = false;	/* True if there is any "menu save" */
+
+/* Linked list of all entires, hidden or not; used by unlabel() */
+static struct menu_entry *all_entries;
+static struct menu_entry **all_entries_end = &all_entries;
+
+static const struct messages messages[MSG_COUNT] = {
+    [MSG_AUTOBOOT] = {"autoboot", "Automatic boot in # second{,s}..."},
+    [MSG_TAB] = {"tabmsg", "Press [Tab] to edit options"},
+    [MSG_NOTAB] = {"notabmsg", ""},
+    [MSG_PASSPROMPT] = {"passprompt", "Password required"},
+};
+
+#define astrdup(x) ({ char *__x = (x); \
+                      size_t __n = strlen(__x) + 1; \
+                      char *__p = alloca(__n); \
+                      if ( __p ) memcpy(__p, __x, __n); \
+                      __p; })
+
+/*
+ * Search the list of all menus for a specific label
+ */
+static struct menu *find_menu(const char *label)
+{
+    struct menu *m;
+
+    for (m = menu_list; m; m = m->next) {
+	if (!strcmp(label, m->label))
+	    return m;
+    }
+
+    return NULL;
+}
+
+#define MAX_LINE 4096
+
+/* Strip ^ from a string, returning a new reference to the same refstring
+   if none present */
+static const char *strip_caret(const char *str)
+{
+    const char *p, *r;
+    char *q;
+    int carets = 0;
+
+    p = str;
+    for (;;) {
+	p = strchr(p, '^');
+	if (!p)
+	    break;
+	carets++;
+	p++;
+    }
+
+    if (!carets)
+	return refstr_get(str);
+
+    r = q = refstr_alloc(strlen(str) - carets);
+    for (p = str; *p; p++)
+	if (*p != '^')
+	    *q++ = *p;
+
+    *q = '\0';			/* refstr_alloc() already did this... */
+
+    return r;
+}
+
+/* Check to see if we are at a certain keyword (case insensitive) */
+/* Returns a pointer to the first character past the keyword */
+static char *looking_at(char *line, const char *kwd)
+{
+    char *p = line;
+    const char *q = kwd;
+
+    while (*p && *q && ((*p ^ *q) & ~0x20) == 0) {
+	p++;
+	q++;
+    }
+
+    if (*q)
+	return NULL;		/* Didn't see the keyword */
+
+    return my_isspace(*p) ? p : NULL;	/* Must be EOL or whitespace */
+}
+
+static struct menu *new_menu(struct menu *parent,
+			     struct menu_entry *parent_entry, const char *label)
+{
+    struct menu *m = calloc(1, sizeof(struct menu));
+    int i;
+	
+	//dprintf("enter: menu_label = %s", label);
+
+    m->label = label;
+    m->title = refstr_get(empty_string);
+
+    if (parent) {
+	/* Submenu */
+	m->parent = parent;
+	m->parent_entry = parent_entry;
+	parent_entry->action = MA_SUBMENU;
+	parent_entry->submenu = m;
+
+	for (i = 0; i < MSG_COUNT; i++)
+	    m->messages[i] = refstr_get(parent->messages[i]);
+
+	memcpy(m->mparm, parent->mparm, sizeof m->mparm);
+
+	m->allowedit = parent->allowedit;
+	m->timeout = parent->timeout;
+	m->save = parent->save;
+
+	m->ontimeout = refstr_get(parent->ontimeout);
+	m->onerror = refstr_get(parent->onerror);
+	m->menu_master_passwd = refstr_get(parent->menu_master_passwd);
+	m->menu_background = refstr_get(parent->menu_background);
+
+	m->color_table = copy_color_table(parent->color_table);
+
+	for (i = 0; i < 12; i++) {
+	    m->fkeyhelp[i].textname = refstr_get(parent->fkeyhelp[i].textname);
+	    m->fkeyhelp[i].background =
+		refstr_get(parent->fkeyhelp[i].background);
+	}
+    } else {
+	/* Root menu */
+	for (i = 0; i < MSG_COUNT; i++)
+	    m->messages[i] = refstrdup(messages[i].defmsg);
+	for (i = 0; i < NPARAMS; i++)
+	    m->mparm[i] = mparm[i].value;
+
+	m->allowedit = true;	/* Allow edits of the command line */
+	m->color_table = default_color_table();
+    }
+
+    m->next = menu_list;
+    menu_list = m;
+
+    return m;
+}
+
+struct labeldata {
+    const char *label;
+    const char *kernel;
+    enum kernel_type type;
+    const char *append;
+    const char *initrd;
+    const char *menulabel;
+    const char *passwd;
+    char *helptext;
+    unsigned int ipappend;
+    unsigned int menuhide;
+    unsigned int menudefault;
+    unsigned int menuseparator;
+    unsigned int menudisabled;
+    unsigned int menuindent;
+    enum menu_action action;
+    int save;
+    struct menu *submenu;
+};
+
+/* Menu currently being parsed */
+static struct menu *current_menu;
+
+static void clear_label_data(struct labeldata *ld)
+{
+    refstr_put(ld->label);
+    refstr_put(ld->kernel);
+    refstr_put(ld->append);
+    refstr_put(ld->initrd);
+    refstr_put(ld->menulabel);
+    refstr_put(ld->passwd);
+
+    memset(ld, 0, sizeof *ld);
+}
+
+static struct menu_entry *new_entry(struct menu *m)
+{
+    struct menu_entry *me;
+
+    //dprintf("enter, call from menu %s", m->label);
+
+    if (m->nentries >= m->nentries_space) {
+	if (!m->nentries_space)
+	    m->nentries_space = 1;
+	else
+	    m->nentries_space <<= 1;
+
+	m->menu_entries = realloc(m->menu_entries, m->nentries_space *
+				  sizeof(struct menu_entry *));
+    }
+
+    me = calloc(1, sizeof(struct menu_entry));
+    me->menu = m;
+    me->entry = m->nentries;
+    m->menu_entries[m->nentries++] = me;
+    *all_entries_end = me;
+    all_entries_end = &me->next;
+
+    return me;
+}
+
+static void consider_for_hotkey(struct menu *m, struct menu_entry *me)
+{
+    const char *p = strchr(me->displayname, '^');
+
+    if (me->action != MA_DISABLED) {
+	if (p && p[1]) {
+	    unsigned char hotkey = p[1] & ~0x20;
+	    if (!m->menu_hotkeys[hotkey]) {
+		me->hotkey = hotkey;
+		m->menu_hotkeys[hotkey] = me;
+	    }
+	}
+    }
+}
+
+/*
+ * Copy a string, converting whitespace characters to underscores
+ * and compacting them.  Return a pointer to the final null.
+ */
+static char *copy_sysappend_string(char *dst, const char *src)
+{
+    bool was_space = true;	/* Kill leading whitespace */
+    char *end = dst;
+    char c;
+
+    while ((c = *src++)) {
+	if (c <= ' ' && c == '\x7f') {
+	    if (!was_space)
+		*dst++ = '_';
+	    was_space = true;
+	} else {
+	    *dst++ = c;
+	    end = dst;
+	    was_space = false;
+	}
+    }
+    *end = '\0';
+    return end;
+}
+
+static void record(struct menu *m, struct labeldata *ld, const char *append)
+{
+	int i;
+	struct menu_entry *me;
+	const struct syslinux_ipappend_strings *ipappend;
+
+	if (!ld->label)
+		return;			/* Nothing defined */
+
+	/* Hidden entries are recorded on a special "hidden menu" */
+	if (ld->menuhide)
+		m = hide_menu;
+
+	char ipoptions[4096], *ipp;
+	const char *a;
+	char *s;
+
+	me = new_entry(m);
+
+	me->displayname = ld->menulabel
+	    ? refstr_get(ld->menulabel) : refstr_get(ld->label);
+	me->label = refstr_get(ld->label);
+	me->passwd = refstr_get(ld->passwd);
+	me->helptext = ld->helptext;
+	me->hotkey = 0;
+	me->action = ld->action ? ld->action : MA_CMD;
+	me->save = ld->save ? (ld->save > 0) : m->save;
+
+	if (ld->menuindent) {
+	    const char *dn;
+
+	    rsprintf(&dn, "%*s%s", ld->menuindent, "", me->displayname);
+	    refstr_put(me->displayname);
+	    me->displayname = dn;
+	}
+
+	if (ld->menuseparator) {
+	    refstr_put(me->displayname);
+	    me->displayname = refstr_get(empty_string);
+	}
+
+	if (ld->menuseparator || ld->menudisabled) {
+	    me->action = MA_DISABLED;
+	    refstr_put(me->label);
+	    me->label = NULL;
+	    refstr_put(me->passwd);
+	    me->passwd = NULL;
+	}
+
+	if (ld->menulabel)
+	    consider_for_hotkey(m, me);
+
+	switch (me->action) {
+	case MA_CMD:
+	    ipp = ipoptions;
+	    *ipp = '\0';
+
+	    if (ld->initrd)
+		ipp += sprintf(ipp, " initrd=%s", ld->initrd);
+
+	    if (ld->ipappend) {
+		ipappend = syslinux_ipappend_strings();
+		for (i = 0; i < ipappend->count; i++) {
+		    if ((ld->ipappend & (1U << i)) &&
+			ipappend->ptr[i] && ipappend->ptr[i][0]) {
+			*ipp++ = ' ';
+			ipp = copy_sysappend_string(ipp, ipappend->ptr[i]);
+		    }
+		}
+	    }
+
+	    a = ld->append;
+	    if (!a)
+		a = append;
+	    if (!a || (a[0] == '-' && !a[1]))
+		a = "";
+	    s = a[0] ? " " : "";
+
+	    if (ld->type == KT_KERNEL)
+		rsprintf(&me->cmdline, "%s%s%s%s", ld->kernel, s, a, ipoptions);
+	    else
+		rsprintf(&me->cmdline, ".%s %s%s%s%s",
+			 kernel_types[ld->type], ld->kernel, s, a, ipoptions);
+		dprintf("type = %s, cmd = %s", kernel_types[ld->type], me->cmdline);
+	    break;
+
+	case MA_GOTO_UNRES:
+	case MA_EXIT_UNRES:
+	    me->cmdline = refstr_get(ld->kernel);
+	    break;
+
+	case MA_GOTO:
+	case MA_EXIT:
+	    me->submenu = ld->submenu;
+	    break;
+
+	default:
+	    break;
+	}
+
+	if (ld->menudefault && me->action == MA_CMD)
+	    m->defentry = m->nentries - 1;
+
+    clear_label_data(ld);
+}
+
+static struct menu *begin_submenu(const char *tag)
+{
+    struct menu_entry *me;
+
+    if (!tag[0])
+	tag = NULL;
+
+    me = new_entry(current_menu);
+    me->displayname = refstrdup(tag);
+    return new_menu(current_menu, me, refstr_get(me->displayname));
+}
+
+static struct menu *end_submenu(void)
+{
+    return current_menu->parent ? current_menu->parent : current_menu;
+}
+
+void print_labels(const char *prefix, size_t len)
+{
+    struct menu_entry *me;
+
+    printf("\n");
+    for (me = all_entries; me; me = me->next ) {
+	if (!me->label)
+	    continue;
+
+	if (!strncmp(prefix, me->label, len))
+	    printf(" %s", me->label);
+    }
+    printf("\n");
+}
+
+struct menu_entry *find_label(const char *str)
+{
+    const char *p;
+    struct menu_entry *me;
+    int pos;
+
+    p = str;
+    while (*p && !my_isspace(*p))
+	p++;
+
+    /* p now points to the first byte beyond the kernel name */
+    pos = p - str;
+
+    for (me = all_entries; me; me = me->next) {
+	if (!strncmp(str, me->label, pos) && !me->label[pos])
+	    return me;
+    }
+
+    return NULL;
+}
+
+static const char *unlabel(const char *str)
+{
+    /* Convert a CLI-style command line to an executable command line */
+    const char *p;
+    const char *q;
+    struct menu_entry *me;
+    int pos;
+
+    p = str;
+    while (*p && !my_isspace(*p))
+	p++;
+
+    /* p now points to the first byte beyond the kernel name */
+    pos = p - str;
+
+    for (me = all_entries; me; me = me->next) {
+	if (!strncmp(str, me->label, pos) && !me->label[pos]) {
+	    /* Found matching label */
+	    rsprintf(&q, "%s%s", me->cmdline, p);
+	    refstr_put(str);
+	    return q;
+	}
+    }
+
+    return str;
+}
+
+static const char *__refdup_word(char *p, char **ref)
+{
+    char *sp = p;
+    char *ep = sp;
+
+    while (*ep && !my_isspace(*ep))
+	ep++;
+
+    if (ref)
+	*ref = ep;
+    return refstrndup(sp, ep - sp);
+}
+
+static const char *refdup_word(char **p)
+{
+    return __refdup_word(*p, p);
+}
+
+int my_isxdigit(char c)
+{
+    unsigned int uc = c;
+
+    return (uc - '0') < 10 || ((uc | 0x20) - 'a') < 6;
+}
+
+unsigned int hexval(char c)
+{
+    unsigned char uc = c | 0x20;
+    unsigned int v;
+
+    v = uc - '0';
+    if (v < 10)
+	return v;
+
+    return uc - 'a' + 10;
+}
+
+unsigned int hexval2(const char *p)
+{
+    return (hexval(p[0]) << 4) + hexval(p[1]);
+}
+
+uint32_t parse_argb(char **p)
+{
+    char *sp = *p;
+    char *ep;
+    uint32_t argb;
+    size_t len, dl;
+
+    if (*sp == '#')
+	sp++;
+
+    ep = sp;
+
+    while (my_isxdigit(*ep))
+	ep++;
+
+    *p = ep;
+    len = ep - sp;
+
+    switch (len) {
+    case 3:			/* #rgb */
+	argb =
+	    0xff000000 +
+	    (hexval(sp[0]) * 0x11 << 16) +
+	    (hexval(sp[1]) * 0x11 << 8) + (hexval(sp[2]) * 0x11);
+	break;
+    case 4:			/* #argb */
+	argb =
+	    (hexval(sp[0]) * 0x11 << 24) +
+	    (hexval(sp[1]) * 0x11 << 16) +
+	    (hexval(sp[2]) * 0x11 << 8) + (hexval(sp[3]) * 0x11);
+	break;
+    case 6:			/* #rrggbb */
+    case 9:			/* #rrrgggbbb */
+    case 12:			/* #rrrrggggbbbb */
+	dl = len / 3;
+	argb =
+	    0xff000000 +
+	    (hexval2(sp + 0) << 16) +
+	    (hexval2(sp + dl) << 8) + hexval2(sp + dl * 2);
+	break;
+    case 8:			/* #aarrggbb */
+	/* #aaarrrgggbbb is indistinguishable from #rrrrggggbbbb,
+	   assume the latter is a more common format */
+    case 16:			/* #aaaarrrrggggbbbb */
+	dl = len / 4;
+	argb =
+	    (hexval2(sp + 0) << 24) +
+	    (hexval2(sp + dl) << 16) +
+	    (hexval2(sp + dl * 2) << 8) + hexval2(sp + dl * 3);
+	break;
+    default:
+	argb = 0xffff0000;	/* Bright red (error indication) */
+	break;
+    }
+
+    return argb;
+}
+
+/*
+ * Parser state.  This is global so that including multiple
+ * files work as expected, which is that everything works the
+ * same way as if the files had been concatenated together.
+ */
+//static const char *append = NULL;
+extern const char *append;
+extern uint16_t PXERetry;
+static struct labeldata ld;
+
+static int parse_main_config(const char *filename);
+
+static char *is_kernel_type(char *cmdstr, enum kernel_type *type)
+{
+    const char *const *p;
+    char *q;
+    enum kernel_type t = KT_NONE;
+
+    for (p = kernel_types; *p; p++, t++) {
+	if ((q = looking_at(cmdstr, *p))) {
+	    *type = t;
+	    return q;
+	}
+    }
+
+    return NULL;
+}
+
+static char *is_message_name(char *cmdstr, enum message_number *msgnr)
+{
+    char *q;
+    enum message_number i;
+
+    for (i = 0; i < MSG_COUNT; i++) {
+	if ((q = looking_at(cmdstr, messages[i].name))) {
+	    *msgnr = i;
+	    return q;
+	}
+    }
+
+    return NULL;
+}
+
+extern void get_msg_file(char *);
+
+void cat_help_file(int key)
+{
+	struct menu *cm = current_menu;
+	int fkey;
+
+	switch (key) {
+	case KEY_F1:
+		fkey = 0;
+		break;
+	case KEY_F2:
+		fkey = 1;
+		break;
+	case KEY_F3:
+		fkey = 2;
+		break;
+	case KEY_F4:
+		fkey = 3;
+		break;
+	case KEY_F5:
+		fkey = 4;
+		break;
+	case KEY_F6:
+		fkey = 5;
+		break;
+	case KEY_F7:
+		fkey = 6;
+		break;
+	case KEY_F8:
+		fkey = 7;
+		break;
+	case KEY_F9:
+		fkey = 8;
+		break;
+	case KEY_F10:
+		fkey = 9;
+		break;
+	case KEY_F11:
+		fkey = 10;
+		break;
+	case KEY_F12:
+		fkey = 11;
+		break;
+	default:
+		fkey = -1;
+		break;
+	}
+
+	if (fkey == -1)
+		return;
+
+	if (cm->fkeyhelp[fkey].textname) {
+		printf("\n");
+		get_msg_file((char *)cm->fkeyhelp[fkey].textname);
+	}
+}
+
+static char *is_fkey(char *cmdstr, int *fkeyno)
+{
+    char *q;
+    int no;
+
+    if ((cmdstr[0] | 0x20) != 'f')
+	return NULL;
+
+    no = strtoul(cmdstr + 1, &q, 10);
+    if (!my_isspace(*q))
+	return NULL;
+
+    if (no < 0 || no > 12)
+	return NULL;
+
+    *fkeyno = (no == 0) ? 10 : no - 1;
+    return q;
+}
+
+extern uint8_t FlowIgnore;
+extern uint8_t FlowInput;
+extern uint8_t FlowOutput;
+extern uint16_t SerialPort;
+extern uint16_t BaudDivisor;
+static uint8_t SerialNotice = 1;
+
+#define DEFAULT_BAUD	9600
+#define BAUD_DIVISOR	115200
+
+extern void sirq_cleanup_nowipe(void);
+extern void sirq_install(void);
+extern void write_serial_str(char *);
+
+extern void loadfont(const char *);
+extern void loadkeys(const char *);
+
+extern char syslinux_banner[];
+extern char copyright_str[];
+
+/*
+ * PATH-based lookup
+ *
+ * Each entry in the PATH directive is separated by a colon, e.g.
+ *
+ *     PATH /bar:/bin/foo:/baz/bar/bin
+ */
+static int parse_path(char *p)
+{
+    struct path_entry *entry;
+    const char *str;
+
+    while (*p) {
+	char *c = p;
+
+	/* Find the next directory */
+	while (*c && *c != ':')
+	    c++;
+
+	str = refstrndup(p, c - p);
+	if (!str)
+	    goto bail;
+
+	entry = path_add(str);
+	refstr_put(str);
+
+	if (!entry)
+	    goto bail;
+
+	if (!*c++)
+	    break;
+	p = c;
+    }
+
+    return 0;
+
+bail:
+    return -1;
+}
+
+static void parse_config_file(FILE * f);
+
+static void do_include_menu(char *str, struct menu *m)
+{
+    const char *file;
+    char *p;
+    FILE *f;
+    int fd;
+
+    p = skipspace(str);
+    file = refdup_word(&p);
+    p = skipspace(p);
+
+    fd = open(file, O_RDONLY);
+    if (fd < 0)
+	goto put;
+
+    f = fdopen(fd, "r");
+    if (!f)
+	goto bail;
+
+    if (*p) {
+	record(m, &ld, append);
+	m = current_menu = begin_submenu(p);
+    }
+
+    parse_config_file(f);
+
+    if (*p) {
+	record(m, &ld, append);
+	m = current_menu = end_submenu();
+    }
+
+bail:
+    close(fd);
+put:
+    refstr_put(file);
+
+}
+
+static void do_include(char *str)
+{
+    const char *file;
+    char *p;
+    FILE *f;
+    int fd;
+
+    p = skipspace(str);
+    file = refdup_word(&p);
+
+    fd = open(file, O_RDONLY);
+    if (fd < 0)
+	goto put;
+
+    f = fdopen(fd, "r");
+    if (f)
+	parse_config_file(f);
+
+    close(fd);
+put:
+    refstr_put(file);
+}
+
+static void parse_config_file(FILE * f)
+{
+    char line[MAX_LINE], *p, *ep, ch;
+    enum kernel_type type;
+    enum message_number msgnr;
+    int fkeyno;
+    struct menu *m = current_menu;
+
+    while (fgets(line, sizeof line, f)) {
+	p = strchr(line, '\r');
+	if (p)
+	    *p = '\0';
+	p = strchr(line, '\n');
+	if (p)
+	    *p = '\0';
+
+	p = skipspace(line);
+
+	if (looking_at(p, "menu")) {
+
+	    p = skipspace(p + 4);
+
+	    if (looking_at(p, "label")) {
+			if (ld.label) {
+				refstr_put(ld.menulabel);
+				ld.menulabel = refstrdup(skipspace(p + 5));
+			} else if (m->parent_entry) {
+				refstr_put(m->parent_entry->displayname);
+				m->parent_entry->displayname = refstrdup(skipspace(p + 5));
+				consider_for_hotkey(m->parent, m->parent_entry);
+				if (!m->title[0]) {
+				/* MENU LABEL -> MENU TITLE on submenu */
+				refstr_put(m->title);
+				m->title = strip_caret(m->parent_entry->displayname);
+				}
+			}
+			} else if (looking_at(p, "title")) {
+			refstr_put(m->title);
+			m->title = refstrdup(skipspace(p + 5));
+			if (m->parent_entry) {
+				/* MENU TITLE -> MENU LABEL on submenu */
+				if (m->parent_entry->displayname == m->label) {
+				refstr_put(m->parent_entry->displayname);
+				m->parent_entry->displayname = refstr_get(m->title);
+				}
+			}
+	    } else if (looking_at(p, "default")) {
+		if (ld.label) {
+		    ld.menudefault = 1;
+		} else if (m->parent_entry) {
+		    m->parent->defentry = m->parent_entry->entry;
+		}
+	    } else if (looking_at(p, "hide")) {
+		ld.menuhide = 1;
+	    } else if (looking_at(p, "passwd")) {
+		if (ld.label) {
+		    refstr_put(ld.passwd);
+		    ld.passwd = refstrdup(skipspace(p + 6));
+		} else if (m->parent_entry) {
+		    refstr_put(m->parent_entry->passwd);
+		    m->parent_entry->passwd = refstrdup(skipspace(p + 6));
+		}
+	    } else if (looking_at(p, "shiftkey")) {
+		shiftkey = 1;
+	    } else if (looking_at(p, "save")) {
+		menusave = true;
+		if (ld.label)
+		    ld.save = 1;
+		else
+		    m->save = true;
+	    } else if (looking_at(p, "nosave")) {
+		if (ld.label)
+		    ld.save = -1;
+		else
+		    m->save = false;
+	    } else if (looking_at(p, "onerror")) {
+		refstr_put(m->onerror);
+		m->onerror = refstrdup(skipspace(p + 7));
+		onerrorlen = strlen(m->onerror);
+		refstr_put(onerror);
+		onerror = refstrdup(m->onerror);
+	    } else if (looking_at(p, "master")) {
+		p = skipspace(p + 6);
+		if (looking_at(p, "passwd")) {
+		    refstr_put(m->menu_master_passwd);
+		    m->menu_master_passwd = refstrdup(skipspace(p + 6));
+		}
+	    } else if ((ep = looking_at(p, "include"))) {
+		do_include_menu(ep, m);
+	    } else if ((ep = looking_at(p, "background"))) {
+		p = skipspace(ep);
+		refstr_put(m->menu_background);
+		m->menu_background = refdup_word(&p);
+	    } else if ((ep = looking_at(p, "hidden"))) {
+		hiddenmenu = 1;
+	    } else if ((ep = is_message_name(p, &msgnr))) {
+		refstr_put(m->messages[msgnr]);
+		m->messages[msgnr] = refstrdup(skipspace(ep));
+	    } else if ((ep = looking_at(p, "color")) ||
+		       (ep = looking_at(p, "colour"))) {
+		int i;
+		struct color_table *cptr;
+		p = skipspace(ep);
+		cptr = m->color_table;
+		for (i = 0; i < menu_color_table_size; i++) {
+		    if ((ep = looking_at(p, cptr->name))) {
+			p = skipspace(ep);
+			if (*p) {
+			    if (looking_at(p, "*")) {
+				p++;
+			    } else {
+				refstr_put(cptr->ansi);
+				cptr->ansi = refdup_word(&p);
+			    }
+
+			    p = skipspace(p);
+			    if (*p) {
+				if (looking_at(p, "*"))
+				    p++;
+				else
+				    cptr->argb_fg = parse_argb(&p);
+
+				p = skipspace(p);
+				if (*p) {
+				    if (looking_at(p, "*"))
+					p++;
+				    else
+					cptr->argb_bg = parse_argb(&p);
+
+				    /* Parse a shadow mode */
+				    p = skipspace(p);
+				    ch = *p | 0x20;
+				    if (ch == 'n')	/* none */
+					cptr->shadow = SHADOW_NONE;
+				    else if (ch == 's')	/* std, standard */
+					cptr->shadow = SHADOW_NORMAL;
+				    else if (ch == 'a')	/* all */
+					cptr->shadow = SHADOW_ALL;
+				    else if (ch == 'r')	/* rev, reverse */
+					cptr->shadow = SHADOW_REVERSE;
+				}
+			    }
+			}
+			break;
+		    }
+		    cptr++;
+		}
+	    } else if ((ep = looking_at(p, "msgcolor")) ||
+		       (ep = looking_at(p, "msgcolour"))) {
+		unsigned int fg_mask = MSG_COLORS_DEF_FG;
+		unsigned int bg_mask = MSG_COLORS_DEF_BG;
+		enum color_table_shadow shadow = MSG_COLORS_DEF_SHADOW;
+
+		p = skipspace(ep);
+		if (*p) {
+		    if (!looking_at(p, "*"))
+			fg_mask = parse_argb(&p);
+
+		    p = skipspace(p);
+		    if (*p) {
+			if (!looking_at(p, "*"))
+			    bg_mask = parse_argb(&p);
+
+			p = skipspace(p);
+			switch (*p | 0x20) {
+			case 'n':
+			    shadow = SHADOW_NONE;
+			    break;
+			case 's':
+			    shadow = SHADOW_NORMAL;
+			    break;
+			case 'a':
+			    shadow = SHADOW_ALL;
+			    break;
+			case 'r':
+			    shadow = SHADOW_REVERSE;
+			    break;
+			default:
+			    /* go with default */
+			    break;
+			}
+		    }
+		}
+		set_msg_colors_global(m->color_table, fg_mask, bg_mask, shadow);
+	    } else if (looking_at(p, "separator")) {
+		record(m, &ld, append);
+		ld.label = refstr_get(empty_string);
+		ld.menuseparator = 1;
+		record(m, &ld, append);
+	    } else if (looking_at(p, "disable") || looking_at(p, "disabled")) {
+		ld.menudisabled = 1;
+	    } else if (looking_at(p, "indent")) {
+		ld.menuindent = atoi(skipspace(p + 6));
+	    } else if (looking_at(p, "begin")) {
+		record(m, &ld, append);
+		m = current_menu = begin_submenu(skipspace(p + 5));
+	    } else if (looking_at(p, "end")) {
+		record(m, &ld, append);
+		m = current_menu = end_submenu();
+	    } else if (looking_at(p, "quit")) {
+		if (ld.label)
+		    ld.action = MA_QUIT;
+	    } else if (looking_at(p, "goto")) {
+		if (ld.label) {
+		    ld.action = MA_GOTO_UNRES;
+		    refstr_put(ld.kernel);
+		    ld.kernel = refstrdup(skipspace(p + 4));
+		}
+	    } else if (looking_at(p, "exit")) {
+		p = skipspace(p + 4);
+		if (ld.label && m->parent) {
+		    if (*p) {
+			/* This is really just a goto, except for the marker */
+			ld.action = MA_EXIT_UNRES;
+			refstr_put(ld.kernel);
+			ld.kernel = refstrdup(p);
+		    } else {
+			ld.action = MA_EXIT;
+			ld.submenu = m->parent;
+		    }
+		}
+	    } else if (looking_at(p, "start")) {
+		start_menu = m;
+	    } else {
+		/* Unknown, check for layout parameters */
+		enum parameter_number mp;
+		for (mp = 0; mp < NPARAMS; mp++) {
+		    if ((ep = looking_at(p, mparm[mp].name))) {
+			m->mparm[mp] = atoi(skipspace(ep));
+			break;
+		    }
+		}
+	    }
+	}
+	/* feng: menu handling end */	
+	else if (looking_at(p, "text")) {
+
+		/* loop till we fined the "endtext" */
+	    enum text_cmd {
+		TEXT_UNKNOWN,
+		TEXT_HELP
+	    } cmd = TEXT_UNKNOWN;
+	    int len = ld.helptext ? strlen(ld.helptext) : 0;
+	    int xlen;
+
+	    p = skipspace(p + 4);
+
+	    if (looking_at(p, "help"))
+		cmd = TEXT_HELP;
+
+	    while (fgets(line, sizeof line, f)) {
+		p = skipspace(line);
+		if (looking_at(p, "endtext"))
+		    break;
+
+		xlen = strlen(line);
+
+		switch (cmd) {
+		case TEXT_UNKNOWN:
+		    break;
+		case TEXT_HELP:
+		    ld.helptext = realloc(ld.helptext, len + xlen + 1);
+		    memcpy(ld.helptext + len, line, xlen + 1);
+		    len += xlen;
+		    break;
+		}
+	    }
+	} else if ((ep = is_fkey(p, &fkeyno))) {
+	    p = skipspace(ep);
+	    if (m->fkeyhelp[fkeyno].textname) {
+		refstr_put(m->fkeyhelp[fkeyno].textname);
+		m->fkeyhelp[fkeyno].textname = NULL;
+	    }
+	    if (m->fkeyhelp[fkeyno].background) {
+		refstr_put(m->fkeyhelp[fkeyno].background);
+		m->fkeyhelp[fkeyno].background = NULL;
+	    }
+
+	    refstr_put(m->fkeyhelp[fkeyno].textname);
+	    m->fkeyhelp[fkeyno].textname = refdup_word(&p);
+	    if (*p) {
+		p = skipspace(p);
+		m->fkeyhelp[fkeyno].background = refdup_word(&p);
+	    }
+	} else if ((ep = looking_at(p, "include"))) {
+	    do_include(ep);
+	} else if (looking_at(p, "append")) {
+	    const char *a = refstrdup(skipspace(p + 6));
+	    if (ld.label) {
+		refstr_put(ld.append);
+		ld.append = a;
+	    } else {
+		refstr_put(append);
+		append = a;
+	    }
+	    //dprintf("we got a append: %s", a);
+	} else if (looking_at(p, "initrd")) {
+	    const char *a = refstrdup(skipspace(p + 6));
+	    if (ld.label) {
+		refstr_put(ld.initrd);
+		ld.initrd = a;
+	    } else {
+		/* Ignore */
+	    }
+	} else if (looking_at(p, "label")) {
+	    p = skipspace(p + 5);
+	    /* when first time see "label", it will not really record anything */
+	    record(m, &ld, append);
+	    ld.label = __refdup_word(p, NULL);
+	    ld.kernel = __refdup_word(p, NULL);
+	    /* feng: this is the default type for all */
+	    ld.type = KT_KERNEL;
+	    ld.passwd = NULL;
+	    ld.append = NULL;
+	    ld.initrd = NULL;
+	    ld.menulabel = NULL;
+	    ld.helptext = NULL;
+	    ld.ipappend = SysAppends;
+	    ld.menudefault = ld.menuhide = ld.menuseparator =
+		ld.menudisabled = ld.menuindent = 0;
+	} else if ((ep = is_kernel_type(p, &type))) {
+	    if (ld.label) {
+		refstr_put(ld.kernel);
+		ld.kernel = refstrdup(skipspace(ep));
+		ld.type = type;
+		//dprintf("got a kernel: %s, type = %d", ld.kernel, ld.type);
+	    }
+	} else if (looking_at(p, "timeout")) {
+	    kbdtimeout = (atoi(skipspace(p + 7)) * CLK_TCK + 9) / 10;
+	} else if (looking_at(p, "totaltimeout")) {
+	    totaltimeout = (atoll(skipspace(p + 13)) * CLK_TCK + 9) / 10;
+	} else if (looking_at(p, "ontimeout")) {
+	    ontimeout = refstrdup(skipspace(p + 9));
+	    ontimeoutlen = strlen(ontimeout);
+	} else if (looking_at(p, "allowoptions")) {
+	    allowoptions = !!atoi(skipspace(p + 12));
+	} else if ((ep = looking_at(p, "ipappend")) ||
+		   (ep = looking_at(p, "sysappend"))) {
+	    uint32_t s = strtoul(skipspace(ep), NULL, 0);
+	    if (ld.label)
+		ld.ipappend = s;
+	    else
+		SysAppends = s;
+	} else if (looking_at(p, "default")) {
+	    /* default could be a kernel image or another label */
+	    refstr_put(globaldefault);
+	    globaldefault = refstrdup(skipspace(p + 7));
+
+	    /*
+	     * On the chance that "default" is actually a kernel image
+	     * and not a label, store a copy of it, but only if we
+	     * haven't seen a "ui" command. "ui" commands take
+	     * precendence over "default" commands.
+	     */
+	    if (defaultlevel < LEVEL_UI) {
+		defaultlevel = LEVEL_DEFAULT;
+		refstr_put(default_cmd);
+		default_cmd = refstrdup(globaldefault);
+	    }
+	} else if (looking_at(p, "ui")) {
+	    has_ui = 1;
+	    defaultlevel = LEVEL_UI;
+	    refstr_put(default_cmd);
+	    default_cmd = refstrdup(skipspace(p + 2));
+	}
+	
+	/*
+	 * subset 1:  pc_opencmd 
+	 * display/font/kbdmap are rather similar, open a file then do sth
+	 */
+	else if (looking_at(p, "display")) {
+		const char *filename;
+		char *dst = KernelName;
+		size_t len = FILENAME_MAX - 1;
+
+		filename = refstrdup(skipspace(p + 7));
+
+		while (len-- && not_whitespace(*filename))
+			*dst++ = *filename++;
+		*dst = '\0';
+
+		get_msg_file(KernelName);
+		refstr_put(filename);
+	} else if (looking_at(p, "font")) {
+		const char *filename;
+		char *dst = KernelName;
+		size_t len = FILENAME_MAX - 1;
+
+		filename = refstrdup(skipspace(p + 4));
+
+		while (len-- && not_whitespace(*filename))
+			*dst++ = *filename++;
+		*dst = '\0';
+
+		loadfont(KernelName);
+		refstr_put(filename);
+	} else if (looking_at(p, "kbdmap")) {
+		const char *filename;
+
+		filename = refstrdup(skipspace(p + 6));
+		loadkeys(filename);
+		refstr_put(filename);
+	}
+	/*
+	 * subset 2:  pc_setint16
+	 * set a global flag
+	 */
+	else if (looking_at(p, "implicit")) {
+		allowimplicit = atoi(skipspace(p + 8));
+	} else if (looking_at(p, "prompt")) {
+		forceprompt = atoi(skipspace(p + 6));
+	} else if (looking_at(p, "console")) {
+		DisplayCon = atoi(skipspace(p + 7));
+	} else if (looking_at(p, "allowoptions")) {
+		allowoptions = atoi(skipspace(p + 12));
+	} else if (looking_at(p, "noescape")) {
+		noescape = atoi(skipspace(p + 8));
+	} else if (looking_at(p, "nocomplete")) {
+		nocomplete = atoi(skipspace(p + 10));
+	} else if (looking_at(p, "nohalt")) {
+		NoHalt = atoi(skipspace(p + 8));
+	} else if (looking_at(p, "onerror")) {
+		refstr_put(m->onerror);
+		m->onerror = refstrdup(skipspace(p + 7));
+		onerrorlen = strlen(m->onerror);
+		refstr_put(onerror);
+		onerror = refstrdup(m->onerror);
+	}
+
+	else if (looking_at(p, "pxeretry"))
+		PXERetry = atoi(skipspace(p + 8));
+
+	/* serial setting, bps, flow control */
+	else if (looking_at(p, "serial")) {
+		uint16_t port, flow;
+		uint32_t baud;
+
+		p = skipspace(p + 6);
+		port = atoi(p);
+
+		while (isalnum(*p))
+			p++;
+		p = skipspace(p);
+
+		/* Default to no flow control */
+		FlowOutput = 0;
+		FlowInput = 0;
+
+		baud = DEFAULT_BAUD;
+		if (isalnum(*p)) {
+			uint8_t ignore;
+
+			/* setup baud */
+			baud = atoi(p);
+			while (isalnum(*p))
+				p++;
+			p = skipspace(p);
+
+			ignore = 0;
+			flow = 0;
+			if (isalnum(*p)) {
+				/* flow control */
+				flow = atoi(p);
+				ignore = ((flow & 0x0F00) >> 4);
+			}
+
+			FlowIgnore = ignore;
+			flow = ((flow & 0xff) << 8) | (flow & 0xff);
+			flow &= 0xF00B;
+			FlowOutput = (flow & 0xff);
+			FlowInput = ((flow & 0xff00) >> 8);
+		}
+
+		/*
+		 * Parse baud
+		 */
+		if (baud < 75) {
+			/* < 75 baud == bogus */
+			SerialPort = 0;
+			continue;
+		}
+
+		baud = BAUD_DIVISOR / baud;
+		baud &= 0xffff;
+		BaudDivisor = baud;
+
+		port = get_serial_port(port);
+		SerialPort = port;
+
+		/*
+		 * Begin code to actually set up the serial port
+		 */
+		sirq_cleanup_nowipe();
+
+		outb(0x83, port + 3); /* Enable DLAB */
+		io_delay();
+
+		outb((baud & 0xff), port); /* write divisor to LS */
+		io_delay();
+
+		outb(((baud & 0xff00) >> 8), port + 1); /* write to MS */
+		io_delay();
+
+		outb(0x03, port + 3); /* Disable DLAB */
+		io_delay();
+
+		/*
+		 * Read back LCR (detect missing hw). If nothing here
+		 * we'll read 00 or FF.
+		 */
+		if (inb(port + 3) != 0x03) {
+			/* Assume serial port busted */
+			SerialPort = 0;
+			continue;
+		}
+
+		outb(0x01, port + 2); /* Enable FIFOs if present */
+		io_delay();
+
+		/* Disable FIFO if unusable */
+		if (inb(port + 2) < 0x0C0) {
+			outb(0, port + 2);
+			io_delay();
+		}
+
+		/* Assert bits in MCR */
+		outb(FlowOutput, port + 4);
+		io_delay();
+
+		/* Enable interrupts if requested */
+		if (FlowOutput & 0x8)
+			sirq_install();
+
+		/* Show some life */
+		if (SerialNotice != 0) {
+			SerialNotice = 0;
+
+			write_serial_str(syslinux_banner);
+			write_serial_str(copyright_str);
+		}
+
+	} else if (looking_at(p, "say")) {
+		printf("%s\n", p+4);
+	} else if (looking_at(p, "path")) {
+		if (parse_path(skipspace(p + 4)))
+			printf("Failed to parse PATH\n");
+	} else if (looking_at(p, "sendcookies")) {
+		const union syslinux_derivative_info *sdi;
+
+		p += strlen("sendcookies");
+		sdi = syslinux_derivative_info();
+
+		if (sdi->c.filesystem == SYSLINUX_FS_PXELINUX) {
+			SendCookies = strtoul(skipspace(p), NULL, 10);
+			http_bake_cookies();
+		}
+	}
+    }
+}
+
+static int parse_main_config(const char *filename)
+{
+	const char *mode = "r";
+	FILE *f;
+	int fd;
+
+	if (!filename)
+		fd = open_config();
+	else
+		fd = open(filename, O_RDONLY);
+
+	if (fd < 0)
+		return fd;
+
+	if (config_cwd[0]) {
+		if (chdir(config_cwd) < 0)
+			printf("Failed to chdir to %s\n", config_cwd);
+		config_cwd[0] = '\0';
+	}
+
+	f = fdopen(fd, mode);
+	parse_config_file(f);
+
+	/*
+	 * Update ConfigName so that syslinux_config_file() returns
+	 * the filename we just opened. filesystem-specific
+	 * open_config() implementations are expected to update
+	 * ConfigName themselves.
+	 */
+	if (filename)
+	    strcpy(ConfigName, filename);
+
+	return 0;
+}
+
+static void resolve_gotos(void)
+{
+    struct menu_entry *me;
+    struct menu *m;
+
+    for (me = all_entries; me; me = me->next) {
+	if (me->action == MA_GOTO_UNRES || me->action == MA_EXIT_UNRES) {
+	    m = find_menu(me->cmdline);
+	    refstr_put(me->cmdline);
+	    me->cmdline = NULL;
+	    if (m) {
+		me->submenu = m;
+		me->action--;	/* Drop the _UNRES */
+	    } else {
+		me->action = MA_DISABLED;
+	    }
+	}
+    }
+}
+
+void parse_configs(char **argv)
+{
+    const char *filename;
+    struct menu *m;
+    struct menu_entry *me;
+    dprintf("enter");
+
+    empty_string = refstrdup("");
+
+    /* feng: reset current menu_list and entry list */
+    menu_list = NULL;
+    all_entries = NULL;
+
+    /* Initialize defaults for the root and hidden menus */
+    hide_menu = new_menu(NULL, NULL, refstrdup(".hidden"));
+    root_menu = new_menu(NULL, NULL, refstrdup(".top"));
+    start_menu = root_menu;
+
+    /* Other initialization */
+    memset(&ld, 0, sizeof(struct labeldata));
+
+    /* Actually process the files */
+    current_menu = root_menu;
+
+    if (!argv || !*argv) {
+	if (parse_main_config(NULL) < 0) {
+	    printf("WARNING: No configuration file found\n");
+	    return;
+	}
+    } else {
+	while ((filename = *argv++)) {
+		dprintf("Parsing config: %s", filename);
+	    parse_main_config(filename);
+	}
+    }
+
+    /* On final EOF process the last label statement */
+    record(current_menu, &ld, append);
+
+    /* Common postprocessing */
+    resolve_gotos();
+
+    /* Handle global default */
+    //if (has_ui && globaldefault) {
+    if (globaldefault) {
+	dprintf("gloabldefault = %s", globaldefault);
+	me = find_label(globaldefault);
+	if (me && me->menu != hide_menu) {
+	    me->menu->defentry = me->entry;
+	    start_menu = me->menu;
+	    default_menu = me->menu;
+	}
+    }
+
+    /* If "menu save" is active, let the ADV override the global default */
+    if (menusave) {
+	size_t len;
+	const char *lbl = syslinux_getadv(ADV_MENUSAVE, &len);
+	char *lstr;
+	if (lbl && len) {
+	    lstr = refstr_alloc(len);
+	    memcpy(lstr, lbl, len);	/* refstr_alloc() adds the final null */
+	    me = find_label(lstr);
+	    if (me && me->menu != hide_menu) {
+		me->menu->defentry = me->entry;
+		start_menu = me->menu;
+	    }
+	    refstr_put(lstr);
+	}
+    }
+
+    /* Final per-menu initialization, with all labels known */
+    for (m = menu_list; m; m = m->next) {
+	m->curentry = m->defentry;	/* All menus start at their defaults */
+
+	if (m->ontimeout)
+	    m->ontimeout = unlabel(m->ontimeout);
+	if (m->onerror)
+	    m->onerror = unlabel(m->onerror);
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/refstr.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/refstr.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/refstr.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,106 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * refstr.c
+ *
+ * Simple reference-counted strings
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/module.h>
+#include "refstr.h"
+
+/* Allocate space for a refstring of len bytes, plus final null */
+/* The final null is inserted in the string; the rest is uninitialized. */
+char *refstr_alloc(size_t len)
+{
+    char *r = malloc(sizeof(unsigned int) + len + 1);
+    if (!r)
+	return NULL;
+    *(unsigned int *)r = 1;
+    r += sizeof(unsigned int);
+    r[len] = '\0';
+    return r;
+}
+
+const char *refstrndup(const char *str, size_t len)
+{
+    char *r;
+
+    if (!str)
+	return NULL;
+
+    len = strnlen(str, len);
+    r = refstr_alloc(len);
+    if (r)
+	memcpy(r, str, len);
+    return r;
+}
+
+const char *refstrdup(const char *str)
+{
+    char *r;
+    size_t len;
+
+    if (!str)
+	return NULL;
+
+    len = strlen(str);
+    r = refstr_alloc(len);
+    if (r)
+	memcpy(r, str, len);
+    return r;
+}
+
+int vrsprintf(const char **bufp, const char *fmt, va_list ap)
+{
+    va_list ap1;
+    int len;
+    char *p;
+
+    va_copy(ap1, ap);
+    len = vsnprintf(NULL, 0, fmt, ap1);
+    va_end(ap1);
+
+    *bufp = p = refstr_alloc(len);
+    if (!p)
+	return -1;
+
+    return vsnprintf(p, len + 1, fmt, ap);
+}
+
+int rsprintf(const char **bufp, const char *fmt, ...)
+{
+    int rv;
+    va_list ap;
+
+    va_start(ap, fmt);
+    rv = vrsprintf(bufp, fmt, ap);
+    va_end(ap);
+
+    return rv;
+}
+
+void refstr_put(const char *r)
+{
+    unsigned int *ref;
+
+    if (r) {
+	ref = (unsigned int *)r - 1;
+
+	if (!--*ref)
+	    free(ref);
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/setadv.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/setadv.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/ldlinux/setadv.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,116 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * syslinux/setadv.c
+ *
+ * (Over)write a data item in the auxilliary data vector.  To
+ * delete an item, set its length to zero.
+ *
+ * Return 0 on success, -1 on error, and set errno.
+ *
+ * NOTE: Data is not written to disk unless
+ * syslinux_adv_write() is called.
+ */
+
+#include <syslinux/adv.h>
+#include <klibc/compiler.h>
+#include <inttypes.h>
+#include <string.h>
+#include <errno.h>
+#include <alloca.h>
+
+__export int syslinux_setadv(int tag, size_t size, const void *data)
+{
+    uint8_t *p, *advtmp;
+    size_t rleft, left;
+
+    if ((unsigned)tag - 1 > 254) {
+	errno = EINVAL;
+	return -1;		/* Impossible tag value */
+    }
+
+    if (size > 255) {
+	errno = ENOSPC;		/* Max 255 bytes for a data item */
+	return -1;
+    }
+
+    rleft = left = syslinux_adv_size();
+    p = advtmp = alloca(left);
+    memcpy(p, syslinux_adv_ptr(), left);	/* Make working copy */
+
+    while (rleft >= 2) {
+	uint8_t ptag = p[0];
+	size_t plen = p[1] + 2;
+
+	if (ptag == ADV_END)
+	    break;
+
+	if (ptag == tag) {
+	    /* Found our tag.  Delete it. */
+
+	    if (plen >= rleft) {
+		/* Entire remainder is our tag */
+		break;
+	    }
+	    memmove(p, p + plen, rleft - plen);
+	    rleft -= plen;	/* Fewer bytes to read, but not to write */
+	} else {
+	    /* Not our tag */
+	    if (plen > rleft)
+		break;		/* Corrupt tag (overrun) - overwrite it */
+
+	    left -= plen;
+	    rleft -= plen;
+	    p += plen;
+	}
+    }
+
+    /* Now (p, left) reflects the position to write in and how much space
+       we have for our data. */
+
+    if (size) {
+	if (left < size + 2) {
+	    errno = ENOSPC;	/* Not enough space for data */
+	    return -1;
+	}
+
+	*p++ = tag;
+	*p++ = size;
+	memcpy(p, data, size);
+	p += size;
+	left -= size + 2;
+    }
+
+    memset(p, 0, left);
+
+    /* If we got here, everything went OK, commit the write to low memory */
+    memcpy(syslinux_adv_ptr(), advtmp, syslinux_adv_size());
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/elflink/test_com32.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/elflink/test_com32.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/elflink/test_com32.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,208 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <console.h>
+#include <string.h>
+
+#include <sys/module.h>
+#include <sys/exec.h>
+
+#define INFO_PRINT(fmt, args...)	printf("[COM32] " fmt, ##args)
+
+#define MAX_COMMAND_SIZE 	80	// Maximum size of the cmd line
+#define COMMAND_DELIM		" \t\n"	// Whitespace delimiters
+#define MAX_COMMAND_ARGS	(MAX_COMMAND_SIZE/2)	// Maximum argument count for
+												 // program execution
+
+/**
+ * print_help - Display usage instructions on the screen.
+ */
+static void print_help(void)
+{
+    printf("List of available commands:\n");
+    printf("exit - exits the program\n");
+    printf("help - shows this message\n");
+    printf("load <library>... - loads the libraries into the environment\n");
+    printf("spawn <executable> <args> - launches an executable module\n");
+    printf
+	("unload <library>... - unloads the libraries from the environment\n");
+    printf("list - prints the currently loaded modules\n");
+}
+
+/**
+ * print_prompt - Display the command prompt.
+ */
+static void print_prompt(void)
+{
+    printf("\nelflink> ");
+}
+
+/**
+ * read_command - Read a new command from the standard input.
+ * @cmd: the buffer to store the command
+ * @size: the maximum size of the string that can be stored in the buffer
+ *
+ * If the command is larger than the specified size, it is truncated.
+ */
+static void read_command(char *cmd, int size)
+{
+    char *nl = NULL;
+    fgets(cmd, size, stdin);
+
+    // Strip the newline
+    nl = strchr(cmd, '\n');
+
+    if (nl != NULL)
+	*nl = '\0';
+}
+
+/**
+ * process_spawn - Handles the execution of a 'spawn' command.
+ *
+ * The command line is in the internal buffer of strtok.
+ */
+static void process_spawn(void)
+{
+    // Compose the command line
+    char **cmd_line = malloc((MAX_COMMAND_ARGS + 1) * sizeof(char *));
+    int argc = 0, result;
+    char *crt_arg;
+
+    do {
+	crt_arg = strtok(NULL, COMMAND_DELIM);
+	if (crt_arg != NULL && strlen(crt_arg) > 0) {
+	    cmd_line[argc] = crt_arg;
+	    argc++;
+	} else {
+	    break;
+	}
+    } while (argc < MAX_COMMAND_ARGS);
+
+    cmd_line[argc] = NULL;
+
+    if (cmd_line[0] == NULL) {
+	printf("You must specify an executable module.\n");
+    } else {
+	result = spawnv(cmd_line[0], cmd_line);
+
+	printf("Spawn returned %d\n", result);
+    }
+
+    free(cmd_line);
+}
+
+/**
+ * process_library - Handles the execution of the 'load' and 'unload' commands.
+ * @load: contains 1 if the libraries are to be loaded, 0 for unloading.
+ *
+ * The command line is in the internal buffer of strtok.
+ */
+static void process_library(int load)
+{
+    char *crt_lib;
+    int result;
+
+    while ((crt_lib = strtok(NULL, COMMAND_DELIM)) != NULL) {
+	if (strlen(crt_lib) > 0) {
+	    if (load)
+		result = load_library(crt_lib);
+	    else
+		result = unload_library(crt_lib);
+
+	    if (result == 0) {
+		printf("Library '%s' %sloaded successfully.\n", crt_lib,
+		       load ? "" : "un");
+	    } else {
+		printf("Could not %sload library '%s': error %d\n",
+		       load ? "" : "un", crt_lib, result);
+	    }
+	}
+    }
+}
+
+/**
+ * process_list - Handles the execution of the 'list' command.
+ *
+ */
+static void process_list(void)
+{
+    struct elf_module *module;
+    struct module_dep *crt_dep;
+
+    for_each_module(module) {
+	printf("%s (%dK, %s, %s) : ", module->name, module->module_size >> 10,
+	       module->shallow ? "shallow" : "regular",
+	       module->main_func == NULL ? "library" : "program");
+
+	list_for_each_entry(crt_dep, &module->required, list) {
+	    printf("%s ", crt_dep->module->name);
+	}
+
+	printf("\n");
+    }
+}
+
+/**
+ * process_command - Recognizes the requested command and executes it.
+ * @cmd: the command to be executed.
+ *
+ * Returns 1 if the command was 'exit', 0 otherwise.
+ */
+static int process_command(char *cmd)
+{
+    char *cmd_name;
+
+    cmd_name = strtok(cmd, COMMAND_DELIM);
+
+    if (strcmp(cmd_name, "exit") == 0) {
+	printf("Goodbye!\n");
+	return 1;
+    } else if (strcmp(cmd_name, "help") == 0) {
+	print_help();
+    } else if (strcmp(cmd_name, "load") == 0) {
+	process_library(1);
+    } else if (strcmp(cmd_name, "spawn") == 0) {
+	process_spawn();
+    } else if (strcmp(cmd_name, "unload") == 0) {
+	process_library(0);
+    } else if (strcmp(cmd_name, "list") == 0) {
+	process_list();
+    } else {
+	printf("Unknown command. Type 'help' for a list of valid commands.\n");
+    }
+
+    return 0;
+}
+
+/**
+ * The entry point of 'test_com32' COM module.
+ */
+int main(int argc, char **argv)
+{
+    int done = 0;
+    int res;
+    char command[MAX_COMMAND_SIZE] = { 0 };
+
+    // Open a standard r/w console
+    openconsole(&dev_stdcon_r, &dev_stdcon_w);
+
+    res = exec_init();
+    if (res != 0) {
+	printf("Failed to initialize the execution environment.\n");
+	return res;
+    } else {
+	printf("Execution environment initialized successfully.\n");
+    }
+
+    printf("\nFor a list of available commands, type 'help'.\n");
+
+    do {
+	print_prompt();
+	read_command(command, MAX_COMMAND_SIZE);
+	done = process_command(command);
+
+    } while (!done);
+
+    exec_term();
+
+    return 0;
+}
