Index: bootcd/isolinux/syslinux-6.03/com32/modules/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,52 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-2009 H. Peter Anvin - All Rights Reserved
+##   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+##
+##   This program is free software; you can redistribute it and/or modify
+##   it under the terms of the GNU General Public License as published by
+##   the Free Software Foundation, Inc., 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.
+##
+## -----------------------------------------------------------------------
+
+##
+## COM32 standard modules
+##
+
+VPATH = $(SRC)
+include $(MAKEDIR)/elf.mk
+
+MODULES	  = config.c32 ethersel.c32 dmitest.c32 cpuidtest.c32 \
+	    disk.c32 pcitest.c32 elf.c32 linux.c32 reboot.c32 pmload.c32 \
+	    meminfo.c32 sdi.c32 sanboot.c32 ifcpu64.c32 vesainfo.c32 \
+	    kbdmap.c32 cmd.c32 vpdtest.c32 host.c32 ls.c32 gpxecmd.c32 \
+	    ifcpu.c32 cpuid.c32 cat.c32 pwd.c32 ifplop.c32 zzjson.c32 \
+	    whichsys.c32 prdhcp.c32 pxechn.c32 kontron_wdt.c32 ifmemdsk.c32 \
+	    hexdump.c32 poweroff.c32 cptime.c32 debug.c32
+
+TESTFILES =
+
+all: $(MODULES) $(TESTFILES)
+
+.PRECIOUS: %.o
+dmitest.o: dmitest.c
+	$(CC) $(CFLAGS) $(GPLINCLUDE) -c -o $@ $<
+
+dmitest.elf : dmi_utils.o dmitest.o $(C_LIBS)
+	$(LD) $(LDFLAGS) -o $@ $^
+
+tidy dist:
+	rm -f *.o *.lo *.a *.lst *.elf .*.d *.tmp
+
+clean: tidy
+	rm -f *.lnx
+
+spotless: clean
+	rm -f *.lss *.c32 *.com
+	rm -f *~ \#*
+
+install:
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/modules/cat.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/cat.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/cat.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,31 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <console.h>
+
+int main(int argc, char *argv[])
+{
+    FILE *f;
+    int i;
+    int len;
+    char buf[4096];
+
+    if (argc < 2) {
+	fprintf(stderr, "Usage: %s filename...\n", argv[0]);
+	return 1;
+    }
+
+    for (i = 1; i < argc; i++) {
+	f = fopen(argv[i], "r");
+	if (!f) {
+	    fprintf(stderr, "%s: %s: file not found\n", argv[0], argv[i]);
+	    return 1;
+	}
+
+	while ((len = fread(buf, 1, sizeof buf, f)) > 0)
+	    fwrite(buf, 1, len, stdout);
+	
+	fclose(f);
+    }
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/cmd.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/cmd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/cmd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,26 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008 Michael Brown - 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * cmd.c
+ *
+ * Execute arbitrary commands
+ */
+
+#include <com32.h>
+#include <syslinux/boot.h>
+
+int main(void)
+{
+    syslinux_run_command(com32_cmdline());
+    return -1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/config.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/config.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/config.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,37 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * config.c
+ *
+ * Loads a new configuration file
+ *
+ * Usage: config filename
+ */
+
+#include <stdio.h>
+#include <console.h>
+#include <syslinux/boot.h>
+
+int main(int argc, char *argv[])
+{
+    if (argc < 2 || argc > 3) {
+	fprintf(stderr, "Usage: config <filename> [<directory>]\n");
+	return 1;
+    }
+
+    syslinux_run_kernel_image(argv[1], argv[2] ? argv[2] : "",
+			      0, IMAGE_TYPE_CONFIG);
+
+    fprintf(stderr, "config: %s: failed to load (missing file?)\n", argv[1]);
+    return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/cptime.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/cptime.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/cptime.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,284 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010-2011 Gene Cumm
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * cptime.c	Version 1.4
+ *
+ * Timed copy; read entire file then output total time, bytes transferred,
+ * and compute transfer rate.
+ *
+ * cptime [-s|-l] [-v|-q] [-b _SIZE_] [-n _LEN_] _FILE_...
+ *	-s	Change to simple output mode without computing transfer rate
+ *	-l	Change to long output mode (to allow for overriding previous -s)
+ *	-v	Verbose output
+ *	-q	Quiet output
+ *	-b _SIZE_	use _SIZE_ for transfer size
+ *	-n _LEN_	maximum length to fetch
+ *	_FILE_...	Space delimited list of files to dump
+ * Note: The last instance of -s or -l wins, along with the last use of -b and -n and the winning option will be applied to all operations
+ *
+ * Hisory:
+ * 1.4	Use fread() rather than read(); use CLK_TCK when available.
+ * 1.3	Added -v/-q; rework some argument processing.
+ * 1.2	Added -n
+ * 1.1	Added -l and -b switches; more flexible command line processing
+ * 1.0	First release
+ */
+
+/*
+ * ToDos:
+ * - Refine timing to be more precise.  Low priority.
+ * - Add -o for offset.  Wishlist.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/times.h>
+#include <consoles.h>
+#include <minmax.h>
+#include <limits.h>
+#include <string.h>
+#include <stdint.h>
+#include <console.h>
+
+#ifdef __COM32__
+#  define BUFSZ_DEF	(size_t)2048
+/* What's optimal?  Under 4k?
+ *	layout.inc: xfer_buf_seg	equ 1000h
+ *	com32.inc: push dword (1 << 16)		; 64K bounce buffer
+ */
+/* typedef size_t off_t */
+
+#  define TPS_T	float
+#  ifdef CLK_TCK
+static inline TPS_T get_tps(void) {	return CLK_TCK;	}
+#  else
+static inline TPS_T get_tps(void) {	return 18.2;	}
+#  endif
+
+#else /* __COM32__ */
+
+#  define BUFSZ_DEF	(size_t)16384
+/* Need to check what might be a "best" buffer/fetch block size here */
+
+#  define TPS_T	long
+static inline TPS_T get_tps(void) {	return sysconf(_SC_CLK_TCK);	}
+
+#endif /* __COM32__ */
+
+#ifndef SSIZE_MAX
+#  define SSIZE_MAX	PTRDIFF_MAX
+#endif
+/* typedef ptrdiff_t ssize_t; */
+#define BUFSZ_MAX	(size_t)SSIZE_MAX
+/* ssize_t max */
+#define BUFSZ_MIN	(size_t)1
+
+
+/* Please note: I don't know the origin of these two macros nor their license */
+#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+#define TYPE_MAX(t) \
+  ((t) (! TYPE_SIGNED (t) \
+        ? (t) -1 \
+	: ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))))
+
+#ifndef OFF_T_MAX
+#  define OFF_T_MAX	TYPE_MAX(off_t)
+#endif
+/* Can't be SIZE_MAX or SSIZE_MAX as Syslinux/COM32 is unsigned while Linux 
+ * is signed.
+ */
+
+#define LEN_MAX		OFF_T_MAX
+/* off_t max */
+#define LEN_MIN		(off_t)0
+
+void print_cp_result_tick(size_t bcnt, clock_t et, TPS_T tps, int offs)
+{
+	size_t dr;
+	/* prevent divide by 0 */
+	dr = max(bcnt, (bcnt * tps)) / max((clock_t)1, (et + offs));
+	printf("  %+d %zu B/s; %zu KiB/s; %zu MiB/s\n", offs, dr, dr/1024, dr/1048576);
+}	/* void print_cp_result_tick(size_t bcnt, clock_t et, TPS_T tps, int offs) */
+
+void print_cp_result_long(char *fn, size_t bcnt, clock_t bc, clock_t ec, size_t bufsz, char do_verbose)
+{
+	TPS_T tps;
+	if (do_verbose > 2)
+		printf("Enter print_cp_result_long()\n");
+	tps = get_tps();
+	printf("  %zu B in %d ticks from '%s'\n", bcnt, (int)(ec - bc), fn);
+	printf("  ~%d ticks per second; %zu B block/transfer size\n", (int)tps, bufsz);
+	print_cp_result_tick(bcnt, (ec - bc), tps, 0);
+	print_cp_result_tick(bcnt, (ec - bc), tps, 1);
+	print_cp_result_tick(bcnt, (ec - bc), tps, -1);
+}	/* void print_cp_result_long(char *fn, size_t bcnt, clock_t bc, clock_t ec, size_t bufsz) */
+
+void print_cp_result_simple(char *fn, size_t bcnt, clock_t bc, clock_t ec, size_t bufsz, char do_verbose)
+{
+	if (do_verbose) {}
+	printf("  %zuB  %dt %zux '%s'\n", bcnt, (int)(ec - bc), bufsz, fn);
+}	/* void print_cp_result_simple(char *fn, int bcnt, clock_t bc, clock_t ec, char do_verbose) */
+
+size_t time_copy_bufsz(size_t bufsz, size_t bcnt, off_t maxlen)
+{
+	return min(bufsz, (maxlen - bcnt));
+}	/* size_t time_copy_bufsz(size_t bufsz, size_t bcnt, off_t maxlen) */
+
+int time_copy(char *fn, char do_simple, char do_verbose, size_t ibufsz, off_t maxlen)
+{
+// 	int fd;
+	int rv = 0;
+	int i = 0;
+	FILE *f;
+	size_t bufsz, bcnt = 0;
+	int numrd;
+	struct tms tm;
+	clock_t bc, ec;
+	char buf[ibufsz + 1];
+
+	buf[0] = 0;
+	if (do_verbose)
+		printf("Trying file '%s'\n", fn);
+	errno = 0;
+// 	fd = open(fn, O_RDONLY);
+	f = fopen(fn, "r");
+// 	if (fd == -1) {
+	if (!f) {
+		switch (errno) {
+		case ENOENT :
+			printf("File '%s' does not exist\n", fn);
+			break;
+		case EBADF:
+			printf("File '%s': Bad File Descriptor\n", fn);
+			break;
+		default :
+			printf("Error '%d' opening file '%s'\n", errno, fn);
+		}
+		rv = 1;
+	} else {
+		if (do_verbose)
+			printf("File '%s' opened\n", fn);
+		bufsz = time_copy_bufsz(ibufsz, bcnt, maxlen);
+		bc = times(&tm);
+// 		numrd = read(fd, buf, bufsz);
+// 		numrd = fread(buf, bufsz, 1, f);
+		numrd = fread(buf, 1, bufsz, f);
+		i++;
+		if (numrd > 0)
+			bcnt = numrd;
+		while ((numrd > 0) && (bufsz > 0)) {
+			bufsz = time_copy_bufsz(bufsz, bcnt, maxlen);
+// 			numrd = read(fd, buf, bufsz);
+// 			numrd = fread(buf, bufsz, 1, f);
+			numrd = fread(buf, 1, bufsz, f);
+			i++;
+			if (numrd >= 0)
+// 				bcnt = bcnt + numrd;
+				bcnt += numrd;
+		}
+		ec = times(&tm);
+// 		close(fd);
+		fclose(f);
+		if (do_verbose)
+			printf("File '%s' closed\n", fn);
+		if (numrd < 0) {
+			switch (errno) {
+			case EIO :
+				printf("IO Error at %zu B reading file '%s'\n", bcnt, fn);
+				break;
+			case EINVAL :
+				printf("Invalid Mode at %zu B reading file '%s'\n", bcnt, fn);
+				break;
+			default :
+				printf("Error '%d' at %zu B reading file '%s'\n", errno, bcnt, fn);
+			}
+			rv = 2;
+		}
+		if (bcnt > 0) {
+			if (bufsz == 0)
+				printf("maxed out on maxln\n");
+			if (do_simple)
+				print_cp_result_simple(fn, bcnt, bc, ec, ibufsz, do_verbose);
+			else
+				print_cp_result_long(fn, bcnt, bc, ec, ibufsz, do_verbose);
+		}
+		if (do_verbose)
+			printf("  numrd %d bcnt %d bufsz %d i %d\n", numrd, bcnt, bufsz, i);
+	}
+	return rv;
+}	/* int time_copy(char *fn, char do_simple, int bufsz, off_t maxlen) */
+
+int main(int argc, char *argv[])
+{
+	int i;
+	char do_simple = 0, do_pbuf = 0, do_plen = 0, do_verbose = 0;
+	char *arg;
+	size_t tbufsz, bufsz = min((BUFSZ_DEF), (BUFSZ_MAX));
+	off_t tmaxlen, maxlen = LEN_MAX;
+	int numfl = 0;
+	console_ansi_std();
+// 	openconsole(&dev_stdcon_r, &dev_stdcon_w);
+	for (i = 1; i < argc; i++) {
+		if (argv[i][0] == '-') {
+			arg = argv[i] + 1;
+			if (strcmp(arg, "b") == 0) {
+				i++;
+				if (i < argc) {
+					tbufsz = atoi(argv[i]);
+					if (tbufsz > 0)
+						bufsz = min(max((BUFSZ_MIN), tbufsz), (BUFSZ_MAX));
+					do_pbuf = 1;
+				}
+			} else if (strcmp(arg, "n") == 0) {
+				i++;
+				if (i < argc) {
+					tmaxlen = atoi(argv[i]);
+					if (tmaxlen > 0)
+						maxlen = min(max((LEN_MIN), tmaxlen), (LEN_MAX));
+					do_plen = 1;
+				}
+			} else if (strcmp(arg, "s") == 0)
+				do_simple = 1;
+			else if (strcmp(arg, "l") == 0)
+				do_simple = 0;
+			else if (strcmp(arg, "v") == 0)
+				do_verbose = 1;
+			else if (strcmp(arg, "q") == 0)
+				do_verbose = 0;
+		}
+	}
+	if (do_pbuf || do_verbose)
+		printf("Using bufsz %zu\n", bufsz);
+	if (do_plen || do_verbose)
+		printf("Using maxlen %zu\n", maxlen);
+	for (i = 1; i < argc; i++) {
+		if (argv[i][0] == '-') {
+			arg = argv[i] + 1;
+			if ((strcmp(arg, "b") == 0) || (strcmp(arg, "n") == 0))
+				i++; 	/* Skip next arg */
+			else if (!((strcmp(arg, "s") == 0) || (strcmp(arg, "l") == 0) || (strcmp(arg, "v") == 0) || (strcmp(arg, "q") == 0))) {
+				time_copy(argv[i], do_simple, do_verbose, bufsz, maxlen);
+				numfl++;
+			}
+		} else {
+			time_copy(argv[i], do_simple, do_verbose, bufsz, maxlen);
+			numfl++;
+		}
+	}
+	if (numfl == 0)
+		fprintf(stderr, "%s: Please specify a file\n", argv[0]);
+	return 0;
+}	/* int main(int argc, char *argv[]) */
Index: bootcd/isolinux/syslinux-6.03/com32/modules/cpuid.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/cpuid.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/cpuid.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,58 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 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., 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 <stdio.h>
+#include <stdlib.h>
+#include <sys/cpu.h>
+#include <console.h>
+#include <com32.h>
+
+static void dump_reg(const char *name, uint32_t val)
+{
+    int i;
+
+    printf("%-3s : %10u 0x%08x ", name, val, val);
+
+    for (i = 3; i >= 0; i--) {
+	uint8_t c = val >> (i*8);
+	putchar((c >= ' ' && c <= '~') ? c : '.');
+    }
+    putchar('\n');
+}
+
+int main(int argc, char *argv[])
+{
+    uint32_t leaf, counter;
+    uint32_t eax, ebx, ecx, edx;
+
+    if (argc < 2 || argc > 4) {
+	printf("Usage: %s leaf [counter]\n", argv[0]);
+	exit(1);
+    }
+
+    leaf = strtoul(argv[1], NULL, 0);
+    counter = (argc > 2) ? strtoul(argv[2], NULL, 0) : 0;
+
+    if (!cpu_has_eflag(EFLAGS_ID)) {
+	printf("The CPUID instruction is not supported\n");
+	exit(1);
+    }
+
+    cpuid_count(leaf, counter, &eax, &ebx, &ecx, &edx);
+
+    dump_reg("eax", eax);
+    dump_reg("ebx", ebx);
+    dump_reg("ecx", ecx);
+    dump_reg("edx", edx);
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/cpuidtest.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/cpuidtest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/cpuidtest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,137 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 Erwan Velu - 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.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+/*
+ * cpuidtest.c
+ *
+ * A CPUID demo program using libcom32
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <console.h>
+#include "cpuid.h"
+
+char display_line;
+
+int main(void)
+{
+    s_cpu cpu;
+
+    for (;;) {
+	detect_cpu(&cpu);
+	printf("Vendor      = %s\n", cpu.vendor);
+	printf("Model       = %s\n", cpu.model);
+	printf("Vendor ID   = %d\n", cpu.vendor_id);
+	printf("Family      = %d\n", cpu.family);
+	printf("Model ID    = %d\n", cpu.model_id);
+	printf("Stepping    = %d\n", cpu.stepping);
+	printf("Flags       = ");
+	if (cpu.flags.fpu)
+	    printf("fpu ");
+	if (cpu.flags.vme)
+	    printf("vme ");
+	if (cpu.flags.de)
+	    printf("de ");
+	if (cpu.flags.pse)
+	    printf("pse ");
+	if (cpu.flags.tsc)
+	    printf("tsc ");
+	if (cpu.flags.msr)
+	    printf("msr ");
+	if (cpu.flags.pae)
+	    printf("pae ");
+	if (cpu.flags.mce)
+	    printf("mce ");
+	if (cpu.flags.cx8)
+	    printf("cx8 ");
+	if (cpu.flags.apic)
+	    printf("apic ");
+	if (cpu.flags.sep)
+	    printf("sep ");
+	if (cpu.flags.mtrr)
+	    printf("mtrr ");
+	if (cpu.flags.pge)
+	    printf("pge ");
+	if (cpu.flags.mca)
+	    printf("mca ");
+	if (cpu.flags.cmov)
+	    printf("cmov ");
+	if (cpu.flags.pat)
+	    printf("pat ");
+	if (cpu.flags.pse_36)
+	    printf("pse_36 ");
+	if (cpu.flags.psn)
+	    printf("psn ");
+	if (cpu.flags.clflsh)
+	    printf("clflsh ");
+	if (cpu.flags.dts)
+	    printf("dts ");
+	if (cpu.flags.acpi)
+	    printf("acpi ");
+	if (cpu.flags.mmx)
+	    printf("mmx ");
+	if (cpu.flags.sse)
+	    printf("sse ");
+	if (cpu.flags.sse2)
+	    printf("sse2 ");
+	if (cpu.flags.ss)
+	    printf("ss ");
+	if (cpu.flags.htt)
+	    printf("ht ");
+	if (cpu.flags.acc)
+	    printf("acc ");
+	if (cpu.flags.syscall)
+	    printf("syscall ");
+	if (cpu.flags.mp)
+	    printf("mp ");
+	if (cpu.flags.nx)
+	    printf("nx ");
+	if (cpu.flags.mmxext)
+	    printf("mmxext ");
+	if (cpu.flags.lm)
+	    printf("lm ");
+	if (cpu.flags.nowext)
+	    printf("3dnowext ");
+	if (cpu.flags.now)
+	    printf("3dnow! ");
+	if (cpu.flags.vmx)
+	    printf("vmx ");
+	if (cpu.flags.svm)
+	    printf("svm ");
+	printf("\n");
+	printf("SMP         = ");
+	if (cpu.flags.smp)
+	    printf("yes\n");
+	else
+	    printf("no\n");
+	break;
+    }
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/debug.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/debug.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/debug.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,54 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2013 Intel Corporation; author: Matt Fleming
+ *
+ *   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 <syslinux/debug.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static char *progname;
+
+static void usage(void)
+{
+    fprintf(stderr, "Usage: %s [-e|-d] <func1> [<func2>, ...]\n", progname);
+}
+
+int main(int argc, char *argv[])
+{
+    bool enable;
+    int i;
+
+    progname = argv[0];
+
+    if (argc < 3) {
+	usage();
+	return -1;
+    }
+
+    if (!strncmp(argv[1], "-e", 2))
+	enable = true;
+    else if (!strncmp(argv[1], "-d", 2))
+	enable = false;
+    else {
+	usage();
+	return -1;
+    }
+
+    for (i = 2; i < argc; i++) {
+	char *str = argv[i];
+
+	if (syslinux_debug(str, enable) < 0)
+	    fprintf(stderr, "Failed to debug symbol \"%s\"\n", str);
+    }
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/dir.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/dir.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/dir.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,175 @@
+/*
+ * Display directory contents
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <console.h>
+#include <string.h>
+#include <com32.h>
+#include <dirent.h>
+#include <minmax.h>
+#include <unistd.h>
+#include <getkey.h>
+
+static int rows, cols;		/* Screen parameters */
+
+#define DIR_CHUNK	1024
+
+static const char *type_str(int type)
+{
+    switch (type) {
+    case DT_FIFO:
+	return "[fif]";
+    case DT_CHR:
+	return "[chr]";
+    case DT_DIR:
+	return "[dir]";
+    case DT_BLK:
+	return "[blk]";
+    case DT_UNKNOWN:
+    case DT_REG:
+	return "";
+    case DT_LNK:
+	return "[lnk]";
+    case DT_SOCK:
+	return "[sck]";
+    case DT_WHT:
+	return "[wht]";
+    default:
+	return "[???]";
+    }
+}
+
+static void free_dirents(struct dirent **dex, size_t n_de)
+{
+    size_t i;
+
+    for (i = 0; i < n_de; i++)
+	free(dex[i]);
+
+    free(dex);
+}
+
+static int compare_dirent(const void *p_de1, const void *p_de2)
+{
+    const struct dirent *de1 = *(const struct dirent **)p_de1;
+    const struct dirent *de2 = *(const struct dirent **)p_de2;
+    int ndir1, ndir2;
+
+    ndir1 = de1->d_type != DT_DIR;
+    ndir2 = de2->d_type != DT_DIR;
+
+    if (ndir1 != ndir2)
+	return ndir1 - ndir2;
+
+    return strcmp(de1->d_name, de2->d_name);
+}
+
+static int display_directory(const char *dirname)
+{
+    DIR *dir;
+    struct dirent *de;
+    struct dirent **dex = NULL;
+    size_t n_dex = 0, n_de = 0;
+    size_t i, j, k;
+    size_t nrows, ncols, perpage;
+    size_t endpage;
+    int maxlen = 0;
+    int pos, tpos, colwidth;
+
+    dir = opendir(dirname);
+    if (!dir) {
+	printf("Unable to read directory: %s\n", dirname);
+	return -1;
+    }
+
+    while ((de = readdir(dir)) != NULL) {
+	struct dirent *nde;
+
+	if (n_de >= n_dex) {
+	    struct dirent **ndex;
+
+	    ndex = realloc(dex, (n_dex + DIR_CHUNK) * sizeof *dex);
+	    if (!ndex)
+		goto nomem;
+
+	    dex = ndex;
+	    n_dex += DIR_CHUNK;
+	}
+
+	nde = malloc(de->d_reclen);
+	if (!nde)
+	    goto nomem;
+
+	memcpy(nde, de, de->d_reclen);
+	dex[n_de++] = nde;
+
+	maxlen = max(maxlen, de->d_reclen);
+    }
+
+    closedir(dir);
+
+    qsort(dex, n_de, sizeof *dex, compare_dirent);
+
+    maxlen -= offsetof(struct dirent, d_name) + 1;
+    ncols = (cols + 2)/(maxlen + 8);
+    ncols = min(ncols, n_de);
+    ncols = max(ncols, 1U);
+    colwidth = (cols + 2)/ncols;
+    perpage = ncols * (rows - 1);
+
+    for (i = 0; i < n_de; i += perpage) {
+	/* Rows on this page */
+	endpage = min(i+perpage, n_de);
+	nrows = ((endpage-i) + ncols - 1)/ncols;
+
+	for (j = 0; j < nrows; j++) {
+	    pos = tpos = 0;
+	    for (k = i+j; k < endpage; k += nrows) {
+		pos += printf("%*s%-5s %s",
+			      (tpos - pos), "",
+			      type_str(dex[k]->d_type),
+			      dex[k]->d_name);
+		tpos += colwidth;
+	    }
+	    printf("\n");
+	}
+
+	if (endpage >= n_de)
+	    break;
+
+	get_key(stdin, 0);
+    }
+
+    free_dirents(dex, n_de);
+    return 0;
+
+nomem:
+    closedir(dir);
+    printf("Out of memory error!\n");
+    free_dirents(dex, n_de);
+    return -1;
+}
+
+int main(int argc, char *argv[])
+{
+    int rv;
+
+    if (getscreensize(1, &rows, &cols)) {
+	/* Unknown screen size? */
+	rows = 24;
+	cols = 80;
+    }
+
+    if (argc < 2)
+	rv = display_directory(".");
+    else if (argc == 2)
+	rv = display_directory(argv[1]);
+    else {
+	printf("Usage: dir directory\n");
+	rv = 1;
+    }
+
+    return rv ? 1 : 0;
+}
+  
Index: bootcd/isolinux/syslinux-6.03/com32/modules/disk.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/disk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/disk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,60 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer - 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 <stdio.h>
+#include <console.h>
+#include <stdlib.h>
+#include <string.h>
+#include <disk/geom.h>
+#include <disk/util.h>
+#include <disk/errno_disk.h>
+#include <disk/error.h>
+
+int main(int argc, char *argv[])
+{
+	struct driveinfo drive;
+	struct driveinfo *d = &drive;
+
+	(void)argc;
+	(void)argv;
+
+	for (int disk = 0x80; disk < 0xff; disk++) {
+		memset(d, 0, sizeof(struct driveinfo));
+		d->disk = disk;
+		get_drive_parameters(d);
+
+		/* Do not print output when drive does not exists */
+		if (errno_disk == -1 || !d->cbios)
+			continue;
+
+		if (errno_disk) {
+			get_error("reading disk");
+			continue;
+		}
+
+		printf("DISK 0x%X:\n", d->disk);
+		printf("  C/H/S: %d heads, %d cylinders\n",
+			d->legacy_max_head + 1, d->legacy_max_cylinder + 1);
+		printf("         %d sectors/track, %d drives\n",
+			d->legacy_sectors_per_track, d->legacy_max_drive);
+		printf("  EDD:   ebios=%d, EDD version: %X\n",
+			d->ebios, d->edd_version);
+		printf("         %d heads, %d cylinders\n",
+			(int) d->edd_params.heads, (int) d->edd_params.cylinders);
+		printf("         %d sectors, %d bytes/sector, %d sectors/track\n",
+			(int) d->edd_params.sectors, (int) d->edd_params.bytes_per_sector,
+			(int) d->edd_params.sectors_per_track);
+		printf("         Host bus: %s, Interface type: %s\n\n",
+			d->edd_params.host_bus_type, d->edd_params.interface_type);
+	}
+	return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/dmi_utils.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/dmi_utils.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/dmi_utils.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,71 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 Erwan Velu - 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.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include "stdio.h"
+#include "dmi/dmi.h"
+
+void display_bios_characteristics(s_dmi * dmi)
+{
+    int i;
+    for (i = 0; i < BIOS_CHAR_NB_ELEMENTS; i++) {
+	if (((bool *) (&dmi->bios.characteristics))[i] == true) {
+	    moreprintf("\t\t%s\n", bios_charac_strings[i]);
+	}
+    }
+    for (i = 0; i < BIOS_CHAR_X1_NB_ELEMENTS; i++) {
+	if (((bool *) (&dmi->bios.characteristics_x1))[i] == true) {
+	    moreprintf("\t\t%s\n", bios_charac_x1_strings[i]);
+	}
+    }
+
+    for (i = 0; i < BIOS_CHAR_X2_NB_ELEMENTS; i++) {
+	if (((bool *) (&dmi->bios.characteristics_x2))[i] == true) {
+	    moreprintf("\t\t%s\n", bios_charac_x2_strings[i]);
+	}
+    }
+}
+
+void display_base_board_features(s_dmi * dmi)
+{
+    int i;
+    for (i = 0; i < BASE_BOARD_NB_ELEMENTS; i++) {
+	if (((bool *) (&dmi->base_board.features))[i] == true) {
+	    moreprintf("\t\t%s\n", base_board_features_strings[i]);
+	}
+    }
+}
+
+void display_processor_flags(s_dmi * dmi)
+{
+    int i;
+    for (i = 0; i < PROCESSOR_FLAGS_ELEMENTS; i++) {
+	if (((bool *) (&dmi->processor.cpu_flags))[i] == true) {
+	    moreprintf("\t\t%s\n", cpu_flags_strings[i]);
+	}
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/dmitest.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/dmitest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/dmitest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,229 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 Erwan Velu - 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.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+/*
+ * dmitest.c
+ *
+ * DMI demo program using libcom32
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <console.h>
+#include "dmi/dmi.h"
+
+char display_line;
+
+void display_memory(s_dmi * dmi)
+{
+    int i;
+    for (i = 0; i < dmi->memory_count; i++) {
+	moreprintf("Memory Bank %d\n", i);
+	moreprintf("\tForm Factor  : %s\n", dmi->memory[i].form_factor);
+	moreprintf("\tType         : %s\n", dmi->memory[i].type);
+	moreprintf("\tType Detail  : %s\n", dmi->memory[i].type_detail);
+	moreprintf("\tSpeed        : %s\n", dmi->memory[i].speed);
+	moreprintf("\tSize         : %s\n", dmi->memory[i].size);
+	moreprintf("\tDevice Set   : %s\n", dmi->memory[i].device_set);
+	moreprintf("\tDevice Loc.  : %s\n", dmi->memory[i].device_locator);
+	moreprintf("\tBank Locator : %s\n", dmi->memory[i].bank_locator);
+	moreprintf("\tTotal Width  : %s\n", dmi->memory[i].total_width);
+	moreprintf("\tData Width   : %s\n", dmi->memory[i].data_width);
+	moreprintf("\tError        : %s\n", dmi->memory[i].error);
+	moreprintf("\tVendor       : %s\n", dmi->memory[i].manufacturer);
+	moreprintf("\tSerial       : %s\n", dmi->memory[i].serial);
+	moreprintf("\tAsset Tag    : %s\n", dmi->memory[i].asset_tag);
+	moreprintf("\tPart Number  : %s\n", dmi->memory[i].part_number);
+    }
+}
+
+void display_battery(s_dmi * dmi)
+{
+    moreprintf("Battery\n");
+    moreprintf("\tVendor              : %s\n", dmi->battery.manufacturer);
+    moreprintf("\tManufacture Date    : %s\n", dmi->battery.manufacture_date);
+    moreprintf("\tSerial              : %s\n", dmi->battery.serial);
+    moreprintf("\tName                : %s\n", dmi->battery.name);
+    moreprintf("\tChemistry           : %s\n", dmi->battery.chemistry);
+    moreprintf("\tDesign Capacity     : %s\n", dmi->battery.design_capacity);
+    moreprintf("\tDesign Voltage      : %s\n", dmi->battery.design_voltage);
+    moreprintf("\tSBDS                : %s\n", dmi->battery.sbds);
+    moreprintf("\tSBDS Manufact. Date : %s\n",
+	       dmi->battery.sbds_manufacture_date);
+    moreprintf("\tSBDS Chemistry      : %s\n", dmi->battery.sbds_chemistry);
+    moreprintf("\tMaximum Error       : %s\n", dmi->battery.maximum_error);
+    moreprintf("\tOEM Info            : %s\n", dmi->battery.oem_info);
+}
+
+void display_bios(s_dmi * dmi)
+{
+    moreprintf("BIOS\n");
+    moreprintf("\tVendor:   %s\n", dmi->bios.vendor);
+    moreprintf("\tVersion:  %s\n", dmi->bios.version);
+    moreprintf("\tRelease:  %s\n", dmi->bios.release_date);
+    moreprintf("\tBios Revision     %s\n", dmi->bios.bios_revision);
+    moreprintf("\tFirmware Revision %s\n", dmi->bios.firmware_revision);
+    moreprintf("\tAddress:  0x%04X0\n", dmi->bios.address);
+    moreprintf("\tRuntime address: %u %s\n", dmi->bios.runtime_size,
+	       dmi->bios.runtime_size_unit);
+    moreprintf("\tRom size: %u %s\n", dmi->bios.rom_size,
+	       dmi->bios.rom_size_unit);
+    display_bios_characteristics(dmi);
+}
+
+void display_system(s_dmi * dmi)
+{
+    moreprintf("\nSystem\n");
+    moreprintf("\tManufacturer %s\n", dmi->system.manufacturer);
+    moreprintf("\tProduct Name %s\n", dmi->system.product_name);
+    moreprintf("\tVersion      %s\n", dmi->system.version);
+    moreprintf("\tSerial       %s\n", dmi->system.serial);
+    moreprintf("\tUUID         %s\n", dmi->system.uuid);
+    moreprintf("\tWakeup Type  %s\n", dmi->system.wakeup_type);
+    moreprintf("\tSKU Number   %s\n", dmi->system.sku_number);
+    moreprintf("\tFamily       %s\n", dmi->system.family);
+}
+
+void display_base_board(s_dmi * dmi)
+{
+    moreprintf("Base board\n");
+    moreprintf("\tManufacturer %s\n", dmi->base_board.manufacturer);
+    moreprintf("\tProduct Name %s\n", dmi->base_board.product_name);
+    moreprintf("\tVersion      %s\n", dmi->base_board.version);
+    moreprintf("\tSerial       %s\n", dmi->base_board.serial);
+    moreprintf("\tAsset Tag    %s\n", dmi->base_board.asset_tag);
+    moreprintf("\tLocation     %s\n", dmi->base_board.location);
+    moreprintf("\tType         %s\n", dmi->base_board.type);
+    display_base_board_features(dmi);
+}
+
+void display_chassis(s_dmi * dmi)
+{
+    moreprintf("\nChassis\n");
+    moreprintf("\tManufacturer %s\n", dmi->chassis.manufacturer);
+    moreprintf("\tType	   %s\n", dmi->chassis.type);
+    moreprintf("\tLock	   %s\n", dmi->chassis.lock);
+    moreprintf("\tVersion      %s\n", dmi->chassis.version);
+    moreprintf("\tSerial       %s\n", dmi->chassis.serial);
+    moreprintf("\tAsset Tag    %s\n", dmi->chassis.asset_tag);
+    moreprintf("\tBoot up state %s\n", dmi->chassis.boot_up_state);
+    moreprintf("\tPower supply state %s\n", dmi->chassis.power_supply_state);
+    moreprintf("\tThermal state %s\n", dmi->chassis.thermal_state);
+    moreprintf("\tSecurity Status    %s\n", dmi->chassis.security_status);
+    moreprintf("\tOEM Information    %s\n", dmi->chassis.oem_information);
+    moreprintf("\tHeight       %u\n", dmi->chassis.height);
+    moreprintf("\tNB Power Cords     %u\n", dmi->chassis.nb_power_cords);
+}
+
+void display_cpu(s_dmi * dmi)
+{
+    moreprintf("\nCPU\n");
+    moreprintf("\tSocket Designation %s\n", dmi->processor.socket_designation);
+    moreprintf("\tType         %s\n", dmi->processor.type);
+    moreprintf("\tFamily       %s\n", dmi->processor.family);
+    moreprintf("\tManufacturer %s\n", dmi->processor.manufacturer);
+    moreprintf("\tVersion      %s\n", dmi->processor.version);
+    moreprintf("\tExternal Clock    %u\n", dmi->processor.external_clock);
+    moreprintf("\tMax Speed         %u\n", dmi->processor.max_speed);
+    moreprintf("\tCurrent Speed     %u\n", dmi->processor.current_speed);
+    moreprintf("\tCpu Type     %u\n", dmi->processor.signature.type);
+    moreprintf("\tCpu Family   %u\n", dmi->processor.signature.family);
+    moreprintf("\tCpu Model    %u\n", dmi->processor.signature.model);
+    moreprintf("\tCpu Stepping %u\n", dmi->processor.signature.stepping);
+    moreprintf("\tCpu Minor Stepping %u\n",
+	       dmi->processor.signature.minor_stepping);
+    moreprintf("\tVoltage      %d mV\n", dmi->processor.voltage_mv);
+    moreprintf("\tStatus       %s\n", dmi->processor.status);
+    moreprintf("\tUpgrade      %s\n", dmi->processor.upgrade);
+    moreprintf("\tCache L1 Handle %s\n", dmi->processor.cache1);
+    moreprintf("\tCache L2 Handle %s\n", dmi->processor.cache2);
+    moreprintf("\tCache L3 Handle %s\n", dmi->processor.cache3);
+    moreprintf("\tSerial       %s\n", dmi->processor.serial);
+    moreprintf("\tPart Number  %s\n", dmi->processor.part_number);
+    if (dmi->processor.core_count != 0)
+        moreprintf("\tCores Count   %d\n", dmi->processor.core_count);
+    if (dmi->processor.core_enabled != 0)
+        moreprintf("\tCores Enabled %d\n", dmi->processor.core_enabled);
+    if (dmi->processor.thread_count != 0)
+        moreprintf("\tThreads Count %d\n", dmi->processor.thread_count);
+    moreprintf("\tID           %s\n", dmi->processor.id);
+    display_processor_flags(dmi);
+}
+
+int main(void)
+{
+    char buffer[1024];
+    s_dmi dmi;
+
+    if (dmi_iterate(&dmi) == -ENODMITABLE) {
+	printf("No DMI Structure found\n");
+	return -1;
+    } else {
+	printf("DMI %u.%u present.\n", dmi.dmitable.major_version,
+	       dmi.dmitable.minor_version);
+	printf("%d structures occupying %d bytes.\n", dmi.dmitable.num,
+	       dmi.dmitable.len);
+	printf("DMI table at 0x%08X.\n", dmi.dmitable.base);
+    }
+
+    parse_dmitable(&dmi);
+
+    for (;;) {
+	printf
+	    ("Available commands are system, chassis, base_board, cpu, bios, memory, battery, all, exit\n");
+	printf("dmi: ");
+	fgets(buffer, sizeof buffer, stdin);
+	if (!strncmp(buffer, "exit", 4))
+	    break;
+	if (!strncmp(buffer, "system", 6))
+	    display_system(&dmi);
+	if (!strncmp(buffer, "chassis", 6))
+	    display_chassis(&dmi);
+	if (!strncmp(buffer, "base_board", 10))
+	    display_base_board(&dmi);
+	if (!strncmp(buffer, "cpu", 3))
+	    display_cpu(&dmi);
+	if (!strncmp(buffer, "bios", 4))
+	    display_bios(&dmi);
+	if (!strncmp(buffer, "memory", 6))
+	    display_memory(&dmi);
+	if (!strncmp(buffer, "battery", 7))
+	    display_battery(&dmi);
+	if (!strncmp(buffer, "all", 3)) {
+	    display_bios(&dmi);
+	    display_system(&dmi);
+	    display_chassis(&dmi);
+	    display_base_board(&dmi);
+	    display_cpu(&dmi);
+	    display_memory(&dmi);
+	    display_battery(&dmi);
+	}
+    }
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/elf.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/elf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/elf.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,279 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * elf.c
+ *
+ * Module to load a protected-mode ELF kernel
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <minmax.h>
+#include <sys/stat.h>
+#include <elf.h>
+#include <console.h>
+#include <dprintf.h>
+
+#include <syslinux/loadfile.h>
+#include <syslinux/movebits.h>
+#include <syslinux/bootpm.h>
+
+/* If we don't have this much memory for the stack, signal failure */
+#define MIN_STACK	512
+
+static inline void error(const char *msg)
+{
+    fputs(msg, stderr);
+}
+
+int boot_elf(void *ptr, size_t len, char **argv)
+{
+    char *cptr = ptr;
+    Elf32_Ehdr *eh = ptr;
+    Elf32_Phdr *ph;
+    unsigned int i;
+    struct syslinux_movelist *ml = NULL;
+    struct syslinux_memmap *mmap = NULL, *amap = NULL;
+    struct syslinux_pm_regs regs;
+    int argc;
+    addr_t argsize;
+    char **argp;
+    addr_t lstart, llen;
+    char *stack_frame = NULL;
+    addr_t stack_frame_size;
+    addr_t stack_pointer;
+    uint32_t *spp;
+    char *sfp;
+    addr_t sfa;
+
+    memset(&regs, 0, sizeof regs);
+
+    /*
+     * Note: mmap is the memory map (containing free and zeroed regions)
+     * needed by syslinux_shuffle_boot_pm(); amap is a map where we keep
+     * track ourselves which target memory ranges have already been
+     * allocated.
+     */
+
+    if (len < sizeof(Elf32_Ehdr))
+	goto bail;
+
+    /* Must be ELF, 32-bit, littleendian, version 1 */
+    if (memcmp(eh->e_ident, "\x7f" "ELF\1\1\1", 6))
+	goto bail;
+
+    /* Is this a worthwhile test?  In particular x86-64 normally
+       would imply ELF64 support, which we could do as long as
+       the addresses are 32-bit addresses, and entry is 32 bits.
+       64-bit addresses would take a lot more work. */
+    if (eh->e_machine != EM_386 && eh->e_machine != EM_486 &&
+	eh->e_machine != EM_X86_64)
+	goto bail;
+
+    if (eh->e_version != EV_CURRENT)
+	goto bail;
+
+    if (eh->e_ehsize < sizeof(Elf32_Ehdr) || eh->e_ehsize >= len)
+	goto bail;
+
+    if (eh->e_phentsize < sizeof(Elf32_Phdr))
+	goto bail;
+
+    if (!eh->e_phnum)
+	goto bail;
+
+    if (eh->e_phoff + eh->e_phentsize * eh->e_phnum > len)
+	goto bail;
+
+    mmap = syslinux_memory_map();
+    amap = syslinux_dup_memmap(mmap);
+    if (!mmap || !amap)
+	goto bail;
+
+    dprintf("Initial memory map:\n");
+    syslinux_dump_memmap(mmap);
+
+    ph = (Elf32_Phdr *) (cptr + eh->e_phoff);
+
+    for (i = 0; i < eh->e_phnum; i++) {
+	if (ph->p_type == PT_LOAD || ph->p_type == PT_PHDR) {
+	    /* This loads at p_paddr, which is arguably the correct semantics.
+	       The SysV spec says that SysV loads at p_vaddr (and thus Linux does,
+	       too); that is, however, a major brainfuckage in the spec. */
+	    addr_t addr = ph->p_paddr;
+	    addr_t msize = ph->p_memsz;
+	    addr_t dsize = min(msize, ph->p_filesz);
+
+	    dprintf("Segment at 0x%08x data 0x%08x len 0x%08x\n",
+		    addr, dsize, msize);
+
+	    if (syslinux_memmap_type(amap, addr, msize) != SMT_FREE) {
+		printf("Memory segment at 0x%08x (len 0x%08x) is unavailable\n",
+		       addr, msize);
+		goto bail;	/* Memory region unavailable */
+	    }
+
+	    /* Mark this region as allocated in the available map */
+	    if (syslinux_add_memmap(&amap, addr, dsize, SMT_ALLOC))
+		goto bail;
+
+	    if (ph->p_filesz) {
+		/* Data present region.  Create a move entry for it. */
+		if (syslinux_add_movelist
+		    (&ml, addr, (addr_t) cptr + ph->p_offset, dsize))
+		    goto bail;
+	    }
+	    if (msize > dsize) {
+		/* Zero-filled region.  Mark as a zero region in the memory map. */
+		if (syslinux_add_memmap
+		    (&mmap, addr + dsize, msize - dsize, SMT_ZERO))
+		    goto bail;
+	    }
+	} else {
+	    /* Ignore this program header */
+	}
+
+	ph = (Elf32_Phdr *) ((char *)ph + eh->e_phentsize);
+    }
+
+    /* Create the invocation record (initial stack frame) */
+
+    argsize = argc = 0;
+    for (argp = argv; *argp; argp++) {
+	dprintf("argv[%2d] = \"%s\"\n", argc, *argp);
+	argc++;
+	argsize += strlen(*argp) + 1;
+    }
+
+    /* We need the argument strings, argument pointers,
+       argc, plus four zero-word terminators. */
+    stack_frame_size = argsize + argc * sizeof(char *) + 5 * sizeof(long);
+    stack_frame_size = (stack_frame_size + 15) & ~15;
+    stack_frame = calloc(stack_frame_size, 1);
+    if (!stack_frame)
+	goto bail;
+
+    dprintf("Right before syslinux_memmap_largest()...\n");
+    syslinux_dump_memmap(amap);
+
+    if (syslinux_memmap_largest(amap, SMT_FREE, &lstart, &llen))
+	goto bail;		/* NO free memory?! */
+
+    if (llen < stack_frame_size + MIN_STACK + 16)
+	goto bail;		/* Insufficient memory  */
+
+    /* Initial stack pointer address */
+    stack_pointer = (lstart + llen - stack_frame_size) & ~15;
+
+    dprintf("Stack frame at 0x%08x len 0x%08x\n",
+	    stack_pointer, stack_frame_size);
+
+    /* Create the stack frame.  sfp is the pointer in current memory for
+       the next argument string, sfa is the address in its final resting place.
+       spp is the pointer into the argument array in current memory. */
+    spp = (uint32_t *) stack_frame;
+    sfp = stack_frame + argc * sizeof(char *) + 5 * sizeof(long);
+    sfa = stack_pointer + argc * sizeof(char *) + 5 * sizeof(long);
+
+    *spp++ = argc;
+    for (argp = argv; *argp; argp++) {
+	int bytes = strlen(*argp) + 1;	/* Including final null */
+	*spp++ = sfa;
+	memcpy(sfp, *argp, bytes);
+	sfp += bytes;
+	sfa += bytes;
+    }
+    /* Zero fields are aready taken care of by calloc() */
+
+    /* ... and we'll want to move it into the right place... */
+#if DEBUG
+    if (syslinux_memmap_type(amap, stack_pointer, stack_frame_size)
+	!= SMT_FREE) {
+	dprintf("Stack frame area not free (how did that happen?)!\n");
+	goto bail;		/* Memory region unavailable */
+    }
+#endif
+
+    if (syslinux_add_memmap(&amap, stack_pointer, stack_frame_size, SMT_ALLOC))
+	goto bail;
+
+    if (syslinux_add_movelist(&ml, stack_pointer, (addr_t) stack_frame,
+			      stack_frame_size))
+	goto bail;
+
+    memset(&regs, 0, sizeof regs);
+    regs.eip = eh->e_entry;
+    regs.esp = stack_pointer;
+
+    dprintf("Final memory map:\n");
+    syslinux_dump_memmap(mmap);
+
+    dprintf("Final available map:\n");
+    syslinux_dump_memmap(amap);
+
+    dprintf("Movelist:\n");
+    syslinux_dump_movelist(ml);
+
+    /* This should not return... */
+    fputs("Booting...\n", stdout);
+    syslinux_shuffle_boot_pm(ml, mmap, 0, &regs);
+
+bail:
+    if (stack_frame)
+	free(stack_frame);
+    syslinux_free_memmap(amap);
+    syslinux_free_memmap(mmap);
+    syslinux_free_movelist(ml);
+
+    return -1;
+}
+
+int main(int argc, char *argv[])
+{
+    void *data;
+    size_t data_len;
+
+    if (argc < 2) {
+	error("Usage: elf.c32 elf_file arguments...\n");
+	return 1;
+    }
+
+    if (zloadfile(argv[1], &data, &data_len)) {
+	error("Unable to load file\n");
+	return 1;
+    }
+
+    boot_elf(data, data_len, &argv[1]);
+    error("Invalid ELF file or insufficient memory\n");
+    return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/ethersel.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/ethersel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/ethersel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,197 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2005-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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * ethersel.c
+ *
+ * Search for an Ethernet card with a known PCI signature, and run
+ * the corresponding Ethernet module.
+ *
+ * To use this, set up a syslinux config file like this:
+ *
+ * PROMPT 0
+ * DEFAULT ethersel.c32
+ * # DEV [DID xxxx:yyyy[/mask]] [RID zz-zz] [SID uuuu:vvvv[/mask]] commandline
+ * # ...
+ *
+ * DID = PCI device ID
+ * RID = Revision ID (range)
+ * SID = Subsystem ID
+ */
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <console.h>
+#include <sys/pci.h>
+#include <com32.h>
+#include <syslinux/boot.h>
+#include <syslinux/config.h>
+#include <dprintf.h>
+
+#define MAX_LINE 512
+
+/* Check to see if we are at a certain keyword (case insensitive) */
+static int looking_at(const char *line, const char *kwd)
+{
+    const char *p = line;
+    const char *q = kwd;
+
+    while (*p && *q && ((*p ^ *q) & ~0x20) == 0) {
+	p++;
+	q++;
+    }
+
+    if (*q)
+	return 0;		/* Didn't see the keyword */
+
+    return *p <= ' ';		/* Must be EOL or whitespace */
+}
+
+static char *get_did(char *p, uint32_t * idptr, uint32_t * maskptr)
+{
+    unsigned long vid, did, m1, m2;
+
+    *idptr = -1;
+    *maskptr = 0xffffffff;
+
+    vid = strtoul(p, &p, 16);
+    if (*p != ':')
+	return p;		/* Bogus ID */
+    did = strtoul(p + 1, &p, 16);
+
+    *idptr = (did << 16) + vid;
+
+    if (*p == '/') {
+	m1 = strtoul(p + 1, &p, 16);
+	if (*p != ':') {
+	    *maskptr = (m1 << 16) | 0xffff;
+	} else {
+	    m2 = strtoul(p + 1, &p, 16);
+	    *maskptr = (m1 << 16) | m2;
+	}
+    }
+
+    return p;
+}
+
+static char *get_rid_range(char *p, uint8_t * rid_min, uint8_t * rid_max)
+{
+    unsigned long r0, r1;
+
+    p = skipspace(p + 3);
+
+    r0 = strtoul(p, &p, 16);
+    if (*p == '-') {
+	r1 = strtoul(p + 1, &p, 16);
+    } else {
+	r1 = r0;
+    }
+
+    *rid_min = r0;
+    *rid_max = r1;
+
+    return p;
+}
+
+static struct match *parse_config(const char *filename)
+{
+    char line[MAX_LINE], *p;
+    FILE *f;
+    struct match *list = NULL;
+    struct match **ep = &list;
+    struct match *m;
+
+    if (!filename)
+	filename = syslinux_config_file();
+
+    f = fopen(filename, "r");
+    if (!f)
+	return list;
+
+    while (fgets(line, sizeof line, f)) {
+	p = skipspace(line);
+
+	if (!looking_at(p, "#"))
+	    continue;
+	p = skipspace(p + 1);
+
+	if (!looking_at(p, "dev"))
+	    continue;
+	p = skipspace(p + 3);
+
+	m = malloc(sizeof(struct match));
+	if (!m)
+	    continue;
+
+	memset(m, 0, sizeof *m);
+	m->rid_max = 0xff;
+
+	for (;;) {
+	    p = skipspace(p);
+
+	    if (looking_at(p, "did")) {
+		p = get_did(p + 3, &m->did, &m->did_mask);
+	    } else if (looking_at(p, "sid")) {
+		p = get_did(p + 3, &m->sid, &m->sid_mask);
+	    } else if (looking_at(p, "rid")) {
+		p = get_rid_range(p + 3, &m->rid_min, &m->rid_max);
+	    } else {
+		char *e;
+
+		e = strchr(p, '\n');
+		if (*e)
+		    *e = '\0';
+		e = strchr(p, '\r');
+		if (*e)
+		    *e = '\0';
+
+		m->filename = strdup(p);
+		if (!m->filename)
+		    m->did = -1;
+		break;		/* Done with this line */
+	    }
+	}
+
+	dprintf("DEV DID %08x/%08x SID %08x/%08x RID %02x-%02x CMD %s\n",
+		m->did, m->did_mask, m->sid, m->sid_mask,
+		m->rid_min, m->rid_max, m->filename);
+
+	*ep = m;
+	ep = &m->next;
+    }
+
+    return list;
+}
+
+int main(int argc, char *argv[])
+{
+    struct match *list, *match;
+    struct pci_domain *pci_domain;
+
+    pci_domain = pci_scan();
+
+    if (pci_domain) {
+	list = parse_config(argc < 2 ? NULL : argv[1]);
+
+	match = find_pci_device(pci_domain, list);
+
+	if (match)
+	    syslinux_run_command(match->filename);
+    }
+
+    /* On error, return to the command line */
+    fputs("Error: no recognized network card found!\n", stderr);
+    return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/gpxecmd.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/gpxecmd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/gpxecmd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,80 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * gpxecmd.c
+ *
+ * Invoke an arbitrary gPXE command, if available.
+ */
+
+#include <alloca.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <console.h>
+#include <com32.h>
+#include <string.h>
+
+#include <sys/gpxe.h>
+#include <syslinux/pxe_api.h>
+
+struct segoff16 {
+    uint16_t offs, seg;
+};
+
+struct s_PXENV_FILE_EXEC {
+    uint16_t Status;
+    struct segoff16 Command;
+};
+
+static void gpxecmd(const char **args)
+{
+    char *q;
+    struct s_PXENV_FILE_EXEC *fx;
+
+    fx = lmalloc(sizeof *fx);
+    if (!fx)
+	return;
+
+    q = (char *)(fx + 1);
+
+    fx->Status = 1;
+    fx->Command.offs = OFFS(q);
+    fx->Command.seg = SEG(q);
+
+    while (*args) {
+	q = stpcpy(q, *args);
+	*q++ = ' ';
+	args++;
+    }
+    *--q = '\0';
+
+    pxe_call(PXENV_FILE_EXEC, fx);
+
+    /* This should not return... */
+}
+
+int main(int argc, const char *argv[])
+{
+    if (argc < 2) {
+	printf("Usage: gpxecmd command...\n");
+	return 1;
+    }
+
+    if (!is_gpxe()) {
+	printf("gpxecmd: gPXE API not detected\n");
+	return 1;
+    }
+
+    gpxecmd(argv + 1);
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/hexdump.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/hexdump.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/hexdump.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,245 @@
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <console.h>
+#include <errno.h>
+#include <syslinux/loadfile.h>
+
+/* Macros */
+#define ROWS_PER_PAGE 24
+#define COLS_PER_ROW 16
+#define BYTES_PER_PAGE (ROWS_PER_PAGE * COLS_PER_ROW)
+
+/* Functions declarations */
+static int usage(void);
+static void eat_stdin(void);
+static int do_page(void);
+static void hexdump(const void *memory, size_t bytes);
+
+/* Objects */
+static const char *prog_name;
+static int opt_page;
+static int opt_no_buffer;
+static int opt_extended_ascii;
+
+int main(int argc, char **argv)
+{
+    int rc;
+    const char *filename;
+    int i;
+    void *file_data;
+    size_t file_sz;
+    FILE *f;
+    size_t len;
+    const char *cur_pos;
+
+    /* Assume failure */
+    rc = EXIT_FAILURE;
+
+    /* Determine the program name, as invoked */
+    if (argc < 1 || !argv || !argv[0]) {
+	fprintf(stderr, "argc or argv failure!\n");
+	goto err_prog_name;
+    }
+    prog_name = argv[0];
+
+    /* Process arguments */
+    filename = NULL;
+    for (i = 1; i < argc; ++i) {
+	if (!argv[i]) {
+	    fprintf(stderr, "argc and argv mismatch!\n");
+	    goto err_argv;
+	}
+
+	if (!strncmp(argv[i], "--page", sizeof "--page") ||
+	    !strncmp(argv[i], "-p", sizeof "-p")) {
+	    opt_page = 1;
+	    continue;
+	}
+
+	if (!strncmp(argv[i], "--no-buffer", sizeof "--no-buffer")) {
+	    opt_no_buffer = 1;
+	    continue;
+	}
+
+	if (!strncmp(argv[i], "--extended-ascii", sizeof "--extended-ascii")) {
+	    opt_extended_ascii = 1;
+	    continue;
+	}
+
+	if (!strncmp(argv[i], "--help", sizeof "--help") ||
+	    !strncmp(argv[i], "-h", sizeof "-h") ||
+	    !strncmp(argv[i], "-?", sizeof "-?"))
+	    return usage();
+
+	/* Otherwise, interpret as a filename, but only accept one */
+	if (filename)
+	    return usage();
+	filename = argv[i];
+    }
+    if (!filename)
+	return usage();
+    fprintf(stdout, "Dumping file: %s\n", filename);
+
+    /* Either fetch the whole file, or just allocate a buffer */
+    f = NULL;
+    if (opt_no_buffer) {
+	errno = 0;
+	if (loadfile(filename, &file_data, &file_sz)) {
+	    fprintf(stderr, "Couldn't load file.  Error: %d\n", errno);
+	    goto err_file_data;
+	}
+    } else {
+	file_sz = BYTES_PER_PAGE;
+	file_data = malloc(file_sz);
+	if (!file_data) {
+	    fprintf(stderr, "Couldn't allocate file data buffer\n");
+	    goto err_file_data;
+	}
+	errno = 0;
+	f = fopen(filename, "r");
+	if (!f) {
+	    fprintf(stderr, "Couldn't open file.  Error: %d\n", errno);
+	    goto err_f;
+	}
+    }
+
+    /* Dump the data */
+    len = BYTES_PER_PAGE;
+    cur_pos = file_data;
+    do {
+	if (f) {
+	    /* Buffered */
+	    len = fread(file_data, 1, file_sz, f);
+	    cur_pos = file_data;
+	} else {
+	    /* Non-buffered */
+	    if (file_sz < len)
+		len = file_sz;
+	}
+	if (!len)
+	    break;
+
+	hexdump(cur_pos, len);
+
+	/* Pause, if requested */
+	if (opt_page) {
+	    /* The user might choose to quit */
+	    if (do_page())
+		break;
+	}
+
+	/* Reduce file_sz for non-buffered mode */
+	if (!f)
+	    file_sz -= len;
+    } while (cur_pos += len);
+
+    rc = EXIT_SUCCESS;
+
+    if (f)
+	fclose(f);
+    err_f:
+
+    free(file_data);
+    err_file_data:
+
+    err_argv:
+
+    err_prog_name:
+
+    return rc;
+}
+
+static int usage(void)
+{
+    static const char usage[] =
+	"Usage: %s [<option> [...]] <filename> [<option> [...]]\n"
+	"\n"
+	"Options: -p\n"
+	"         --page . . . . . . . Pause output every 24 lines\n"
+	"         --no-buffer . . . .  Load the entire file before dumping\n"
+	"         --extended-ascii . . Use extended ASCII chars in dump\n"
+	"         -?\n"
+	"         -h\n"
+	"         --help  . . . . . .  Display this help\n";
+
+    fprintf(stderr, usage, prog_name);
+    return EXIT_FAILURE;
+}
+
+static void eat_stdin(void)
+{
+    int i;
+
+    while (1) {
+	i = fgetc(stdin);
+	if (i == EOF || i == '\n')
+	    return;
+    }
+}
+static int do_page(void)
+{
+    int i;
+
+    while (1) {
+	fprintf(stdout, "Continue? [Y|n]: ");
+	i = fgetc(stdin);
+	switch (i) {
+	    case 'n':
+	    case 'N':
+	    eat_stdin();
+	    return 1;
+
+	    case EOF:
+	    fprintf(stderr, "No response.  Continuing...\n");
+	    /* Fall through to "yes" */
+
+	    case 'y':
+	    case 'Y':
+	    eat_stdin();
+	    case '\n':
+	    return 0;
+
+	    default:
+	    fprintf(stderr, "Invalid choice\n");
+	    eat_stdin();
+	}
+    }
+}
+
+static void hexdump(const void *memory, size_t bytes)
+{
+    const unsigned char *p, *q;
+    int i;
+ 
+    p = memory;
+    while (bytes) {
+        q = p;
+        printf("%p: ", (void *) p);
+        for (i = 0; i < 16 && bytes; ++i) {
+            printf("%02X ", *p);
+            ++p;
+            --bytes;
+          }
+        bytes += i;
+        while (i < 16) {
+            printf("XX ");
+            ++i;
+          }
+        printf("| ");
+        p = q;
+        for (i = 0; i < 16 && bytes; ++i) {
+            printf("%c", isprint(*p) && !isspace(*p) ? *p : ' ');
+            ++p;
+            --bytes;
+          }
+        while (i < 16) {
+            printf(" ");
+            ++i;
+          }
+        printf("\n");
+      }
+    return;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/host.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/host.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/host.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <console.h>
+#include <netinet/in.h>
+#include <com32.h>
+#include <syslinux/pxe.h>
+
+static inline uint32_t dns_resolve(const char *hostname)
+{
+    return pxe_dns(hostname);
+}
+
+static inline void usage(const char *s)
+{
+    fprintf(stderr, "Usage: %s hostname [, hostname_1, hostname_2, ...]\n", s);
+}
+
+int main(int argc, char *argv[])
+{
+    int i;
+    uint32_t ip;
+
+    openconsole(&dev_null_r, &dev_stdcon_w);
+
+    if (argc < 2) {
+        usage(argv[0]);
+        return 1;
+    }
+
+    for (i = 1; i < argc; i++) {
+        ip = dns_resolve(argv[i]);
+        if (!ip) {
+            printf("%s not found.\n", argv[i]);
+        } else {
+            printf("%-39s %08X %u.%u.%u.%u\n", argv[i], ntohl(ip), ip & 0xFF,
+                   (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, (ip >> 24) & 0xFF);
+        }
+    }
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/ifcpu.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/ifcpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/ifcpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,174 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * ifcpu.c
+ *
+ */
+
+#include <alloca.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <cpuid.h>
+#include <unistd.h>
+#include <syslinux/boot.h>
+#include <com32.h>
+#include <consoles.h>
+
+static inline void error(const char *msg)
+{
+    fputs(msg, stderr);
+}
+
+static void usage(void) 
+{
+ error("Run one command if system match some CPU features, another if it doesn't. \n"
+ "Usage: \n"
+ "   label ifcpu \n"
+ "       com32 ifcpu.c32 \n"
+ "       append <option> <cpu_features> -- boot_entry_1 -- boot_entry_2 \n"
+ "   label boot_entry_1 \n"
+ "   	  kernel vmlinuz_entry1 \n"
+ "	  append ... \n"
+ "   label boot_entry_2 \n"
+ "       kernel vmlinuz_entry2 \n"
+ "       append ... \n"
+ "\n"
+ "options could be :\n"
+ "   debug     : display some debugging messages \n"
+ "   dry-run   : just do the detection, don't boot \n"
+ "\n"
+ "cpu_features could be:\n"
+ "   64         : Processor is x86_64 compatible (lm cpu flag)\n"
+ "   hvm        : Processor features hardware virtualization (hvm or svm cpu flag)\n"
+ "   multicore  : Processor must be multi-core \n"
+ "   smp        : System must be multi-processor \n"
+ "   pae        : Processor features Physical Address Extension (PAE)\n"
+ "   hypervisor : Processor is running under an hypervisor\n"
+ "\n"
+ "if you want to match many cpu features, just separate them with a single space.\n");
+}
+
+/* XXX: this really should be librarized */
+static void boot_args(char **args)
+{
+    int len = 0, a = 0;
+    char **pp;
+    const char *p;
+    char c, *q, *str;
+
+    for (pp = args; *pp; pp++)
+	len += strlen(*pp) + 1;
+
+    q = str = alloca(len);
+    for (pp = args; *pp; pp++) {
+	p = *pp;
+	while ((c = *p++))
+	    *q++ = c;
+	*q++ = ' ';
+	a = 1;
+    }
+    q -= a;
+    *q = '\0';
+
+    if (!str[0])
+	syslinux_run_default();
+    else
+	syslinux_run_command(str);
+}
+
+#define show_bool(mybool) mybool ? "found":"not found"
+
+int main(int argc, char *argv[])
+{
+    char **args[3];
+    int i=0;
+    int n=0;
+    bool hardware_matches = true;
+    bool multicore = false;
+    bool dryrun = false;
+    bool debug = false;
+
+    s_cpu cpu;
+    console_ansi_raw();
+    detect_cpu(&cpu);
+
+    /* If no argument got passed, let's show the usage */
+    if (argc == 1) {
+	    usage();
+	    return -1;
+    }
+
+    for (i = 1; i < argc; i++) {
+	if (!strcmp(argv[i], "--")) {
+	    argv[i] = NULL;
+	    args[n++] = &argv[i + 1];
+	} else if (!strcmp(argv[i], "64")) {
+	    if (debug)
+		printf(" 64bit      : %s on this system\n",
+		       show_bool(cpu.flags.lm));
+	    hardware_matches = cpu.flags.lm && hardware_matches;
+	} else if (!strcmp(argv[i], "pae")) {
+	    if (debug)
+		printf(" pae        : %s on this system\n",
+		       show_bool(cpu.flags.pae));
+	    hardware_matches = cpu.flags.pae && hardware_matches;
+	} else if (!strcmp(argv[i], "hvm")) {
+	    if (debug)
+		printf(" hvm        : %s on this system\n",
+		       show_bool((cpu.flags.vmx || cpu.flags.svm)));
+	    hardware_matches = (cpu.flags.vmx || cpu.flags.svm)
+		&& hardware_matches;
+	} else if (!strcmp(argv[i], "multicore")) {
+	    if (debug)
+		printf(" multicore  : %d cores on this system\n", cpu.num_cores);
+	    if (cpu.num_cores > 1)
+		multicore = true;
+	    hardware_matches = multicore && hardware_matches;
+	} else if (!strcmp(argv[i], "smp")) {
+	    if (debug)
+		printf(" smp        : %s on this system\n", show_bool(cpu.flags.smp));
+	    hardware_matches = cpu.flags.smp && hardware_matches;
+	} else if (!strcmp(argv[i], "hypervisor")) {
+	    if (debug)
+		printf(" hypervisor : %s on this system\n", show_bool(cpu.flags.hypervisor));
+	    hardware_matches = cpu.flags.hypervisor && hardware_matches;
+	} else if (!strcmp(argv[i], "dry-run")) {
+	    dryrun = true;
+	} else if (!strcmp(argv[i], "debug")) {
+	    debug = true;
+	}
+	if (n >= 2)
+	    break;
+    }
+    while (n < 2) {
+	args[n] = args[n - 1];
+	n++;
+    }
+    if (debug) {
+	printf("\nBooting labels are : '%s' or '%s'\n", *args[0], *args[1]);
+	printf("Hardware requirements%smatch this system, let's booting '%s'\n",
+	       hardware_matches ? " " : " doesn't ",
+	       hardware_matches ? *args[0] : *args[1]);
+	printf("Sleeping 5sec before booting\n");
+	if (!dryrun)
+	    sleep(5);
+    }
+
+    if (!dryrun)
+	boot_args(hardware_matches ? args[0] : args[1]);
+    else
+	printf("Dry-run mode, let's exiting\n");
+
+    return -1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/ifcpu64.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/ifcpu64.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/ifcpu64.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,125 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * ifcpu64.c
+ *
+ * Run one command if the CPU has 64-bit support, and another if it doesn't.
+ * Eventually this and other features should get folded into some kind
+ * of scripting engine.
+ *
+ * Usage:
+ *
+ *    label boot_kernel
+ *        com32 ifcpu64.c32
+ *        append boot_kernel_64 [-- boot_kernel_32pae] -- boot_kernel_32
+ *    label boot_kernel_32
+ *        kernel vmlinuz_32
+ *        append ...
+ *    label boot_kernel_64
+ *        kernel vmlinuz_64
+ *        append ...
+ */
+
+#include <alloca.h>
+#include <stdlib.h>
+#include <string.h>
+#include <cpuid.h>
+#include <syslinux/boot.h>
+
+static bool __constfunc cpu_has_cpuid(void)
+{
+    return cpu_has_eflag(X86_EFLAGS_ID);
+}
+
+static bool __constfunc cpu_has_level(uint32_t level)
+{
+    uint32_t group;
+    uint32_t limit;
+
+    if (!cpu_has_cpuid())
+	return false;
+
+    group = level & 0xffff0000;
+    limit = cpuid_eax(group);
+
+    if ((limit & 0xffff0000) != group)
+	return false;
+
+    if (level > limit)
+	return false;
+
+    return true;
+}
+
+/* This only supports feature groups 0 and 1, corresponding to the
+   Intel and AMD EDX bit vectors.  We can add more later if need be. */
+static bool __constfunc cpu_has_feature(int x)
+{
+    uint32_t level = ((x & 1) << 31) | 1;
+
+    return cpu_has_level(level) && ((cpuid_edx(level) >> (x & 31) & 1));
+}
+
+/* XXX: this really should be librarized */
+static void boot_args(char **args)
+{
+    int len = 0, a = 0;
+    char **pp;
+    const char *p;
+    char c, *q, *str;
+
+    for (pp = args; *pp; pp++)
+	len += strlen(*pp) + 1;
+
+    q = str = alloca(len);
+    for (pp = args; *pp; pp++) {
+	p = *pp;
+	while ((c = *p++))
+	    *q++ = c;
+	*q++ = ' ';
+	a = 1;
+    }
+    q -= a;
+    *q = '\0';
+
+    if (!str[0])
+	syslinux_run_default();
+    else
+	syslinux_run_command(str);
+}
+
+int main(int argc, char *argv[])
+{
+    char **args[3];
+    int i;
+    int n;
+
+    args[0] = &argv[1];
+    n = 1;
+    for (i = 1; i < argc; i++) {
+	if (!strcmp(argv[i], "--")) {
+	    argv[i] = NULL;
+	    args[n++] = &argv[i + 1];
+	}
+	if (n >= 3)
+	    break;
+    }
+    while (n < 3) {
+	args[n] = args[n - 1];
+	n++;
+    }
+
+    boot_args(cpu_has_feature(X86_FEATURE_LM) ? args[0] :
+	      cpu_has_feature(X86_FEATURE_PAE) ? args[1] : args[2]);
+    return -1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/ifmemdsk.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/ifmemdsk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/ifmemdsk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,392 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 Shao Miller - 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/****
+ * @file ifmemdsk.c
+ *
+ * This COM32 module detects if there are MEMDISKs established.
+ */
+
+static const char usage_text[] = "\
+Usage:\n\
+  ifmemdsk.c32 [<option> [...]] --info [<option> [...]]\n\
+  ifmemdsk.c32 [<option> [...]] [<detected_cmd>] -- [<not_detected_cmd>]\n\
+\n\
+Options:\n\
+  --info  . . . . . Displays info about MEMDISK(s)\n\
+  --safe-hooks . .  Will scan INT 13h \"safe hook\" chain\n\
+  --mbfts . . . . . Will scan memory for MEMDISK mBFTs\n\
+  --no-sequential   Suppresses probing all drive numbers\n\
+\n\
+If a MEMDISK is found, or if a particular MEMDISK is sought by the options\n\
+and is found, then the 'detected_cmd' action will be taken, else the\n\
+'not_detected_cmd' action will be taken.\n\
+\n";
+
+#include <stdio.h>
+#include <string.h>
+#include <alloca.h>
+#include <com32.h>
+#include <console.h>
+#include <syslinux/boot.h>
+
+/* Pull in MEMDISK common structures */
+#include "../../memdisk/mstructs.h"
+
+/*** Macros */
+#define M_GET_DRIVE_PARAMS (0x08)
+#define M_SEGOFFTOPTR(seg, off) (((seg) << 4) + (off))
+#define M_INT13H M_SEGOFFTOPTR(0x0000, 0x0013 * 4)
+#define M_FREEBASEMEM M_SEGOFFTOPTR(0x0040, 0x0013)
+#define M_TOP M_SEGOFFTOPTR(0x9FFF, 0x0000)
+
+/*** Object types */
+typedef struct mdi s_mdi;
+typedef real_addr_t u_segoff;
+typedef struct safe_hook s_safe_hook;
+typedef struct mBFT s_mbft;
+
+/*** Function types */
+typedef int f_find(void);
+
+/*** Function declarations */
+static const s_mdi * installation_check(int);
+static f_find scan_drives;
+static f_find walk_safe_hooks;
+static const s_safe_hook * is_safe_hook(const void *);
+static const s_mdi * is_memdisk_hook(const s_safe_hook *);
+static f_find scan_mbfts;
+static const s_mbft * is_mbft(const void *);
+static f_find do_nothing;
+static void memdisk_info(const s_mdi *);
+static void boot_args(char **);
+static const char * bootloadername(uint8_t);
+
+/*** Structure/union definitions */
+
+/*** Objects */
+static int show_info = 0;
+
+/*** Function definitions */
+
+int main(int argc, char ** argv) {
+    static f_find * do_scan_drives = scan_drives;
+    static f_find * do_walk_safe_hooks = do_nothing;
+    static f_find * do_scan_mbfts = do_nothing;
+    char ** detected_cmd;
+    char ** not_detected_cmd;
+    char ** cmd;
+    char ** cur_arg;
+    int show_usage;
+    int found;
+
+    (void) argc;
+
+    openconsole(&dev_null_r, &dev_stdcon_w);
+
+    detected_cmd = NULL;
+    not_detected_cmd = NULL;
+    show_usage = 1;
+    for (cur_arg = argv + 1; *cur_arg; ++cur_arg) {
+        /* Check for command divider */
+        if (!strcmp(*cur_arg, "--")) {
+            show_usage = 0;
+            *cur_arg = NULL;
+            not_detected_cmd = cur_arg + 1;
+            break;
+          }
+
+        /* Check for '--info' */
+        if (!strcmp(*cur_arg, "--info")) {
+            show_usage = 0;
+            show_info = 1;
+            continue;
+          }
+
+        /* Other options */
+        if (!strcmp(*cur_arg, "--no-sequential")) {
+            do_scan_drives = do_nothing;
+            continue;
+          }
+
+        if (!strcmp(*cur_arg, "--safe-hooks")) {
+            do_walk_safe_hooks = walk_safe_hooks;
+            continue;
+          }
+
+        if (!strcmp(*cur_arg, "--mbfts")) {
+            do_scan_mbfts = scan_mbfts;
+            continue;
+          }
+
+        /* Check for invalid option */
+        if (!memcmp(*cur_arg, "--", sizeof "--" - 1)) {
+            puts("Invalid option!");
+            show_usage = 1;
+            break;
+          }
+
+        /* Set 'detected_cmd' if it's null */
+        if (!detected_cmd)
+          detected_cmd = cur_arg;
+
+        continue;
+      }
+
+    if (show_usage) {
+        fprintf(stderr, usage_text);
+        return 1;
+      }
+
+    found = 0;
+    found += do_walk_safe_hooks();
+    found += do_scan_mbfts();
+    found += do_scan_drives();
+
+    cmd = found ? detected_cmd : not_detected_cmd;
+    if (cmd && *cmd)
+      boot_args(cmd);
+
+    return 0;
+  }
+
+static const s_mdi * installation_check(int drive) {
+    com32sys_t params, results;
+    int found;
+
+    /* Set parameters for INT 0x13 call */
+    memset(&params, 0, sizeof params);
+    params.eax.w[0] = M_GET_DRIVE_PARAMS << 8;
+    params.edx.w[0] = drive;
+    /* 'ME' 'MD' 'IS' 'K?' */
+    params.eax.w[1] = 0x454D;
+    params.ecx.w[1] = 0x444D;
+    params.edx.w[1] = 0x5349;
+    params.ebx.w[1] = 0x3F4B;
+
+    /* Perform the call */
+    __intcall(0x13, &params, &results);
+
+    /* Check result */
+    found = (
+        /* '!M' 'EM' 'DI' 'SK' */
+        results.eax.w[1] == 0x4D21 &&
+        results.ecx.w[1] == 0x4D45 &&
+        results.edx.w[1] == 0x4944 &&
+        results.ebx.w[1] == 0x4B53
+      );
+
+    if (found)
+      return MK_PTR(results.es, results.edi.w[0]);
+
+    return NULL;
+  }
+
+static int scan_drives(void) {
+    int found, drive;
+    const s_mdi * mdi;
+
+    for (found = drive = 0; drive <= 0xFF; ++drive) {
+        mdi = installation_check(drive);
+        if (!mdi)
+          continue;
+
+        memdisk_info(mdi);
+        ++found;
+        continue;
+      }
+
+    return found;
+  }
+
+static int walk_safe_hooks(void) {
+    static const u_segoff * const int13 = (void *) M_INT13H;
+    const void * addr;
+    int found;
+    const s_safe_hook * hook;
+    const s_mdi * mdi;
+
+    /* INT 0x13 vector */
+    addr = MK_PTR(int13->seg_off.segment, int13->seg_off.offset);
+    found = 0;
+    while (addr) {
+        hook = is_safe_hook(addr);
+        if (!hook)
+          break;
+
+        mdi = is_memdisk_hook(hook);
+        if (mdi) {
+            memdisk_info(mdi);
+            ++found;
+          }
+
+        addr = MK_PTR(
+            hook->old_hook.seg_off.segment,
+            hook->old_hook.seg_off.offset
+          );
+        continue;
+      }
+    return found;
+  }
+
+static const s_safe_hook * is_safe_hook(const void * addr) {
+    static const char magic[] = "$INT13SF";
+    const s_safe_hook * const test = addr;
+
+    if (memcmp(test->signature, magic, sizeof magic - 1))
+      return NULL;
+
+    return test;
+  }
+
+static const s_mdi * is_memdisk_hook(const s_safe_hook * hook) {
+    static const char magic[] = "MEMDISK";
+    const s_mbft * mbft;
+
+    if (memcmp(hook->vendor, magic, sizeof magic - 1))
+      return NULL;
+
+    /* An mBFT is always aligned */
+    mbft = MK_PTR(hook->mbft >> 4, 0);
+    return &mbft->mdi;
+  }
+
+static int scan_mbfts(void) {
+    static const uint16_t * const free_base_mem = (void *) M_FREEBASEMEM;
+    static const void * const top = (void *) M_TOP;
+    const void * addr;
+    const s_mbft * mbft;
+    int found;
+
+    found = 0;
+    for (addr = MK_PTR(*free_base_mem << 4, 0); addr < top; addr += 1 << 4) {
+        if (!(mbft = is_mbft(addr)))
+          continue;
+
+        memdisk_info(&mbft->mdi);
+        ++found;
+        continue;
+      }
+
+    return found;
+  }
+
+static const s_mbft * is_mbft(const void * addr) {
+    static const char magic[] = "mBFT";
+    const s_mbft * const test = addr;
+    const uint8_t * ptr, * end;
+    uint8_t chksum;
+
+    if (memcmp(test->acpi.signature, magic, sizeof magic - 1))
+      return NULL;
+
+    if (test->acpi.length != sizeof *test)
+      return NULL;
+
+    end = (void *) (test + 1);
+    chksum = 0;
+    for (ptr = addr; ptr < end; ++ptr)
+      chksum += *ptr;
+    if (chksum)
+      return NULL;
+
+    /* Looks like it's an mBFT! */
+    return test;
+  }
+
+static int do_nothing(void) {
+    return 0;
+  }
+
+static void memdisk_info(const s_mdi * mdi) {
+    const char * cmdline;
+
+    if (!show_info)
+      return;
+
+    cmdline = MK_PTR(
+        mdi->cmdline.seg_off.segment,
+        mdi->cmdline.seg_off.offset
+      );
+    printf(
+        "Found MEMDISK version %u.%02u:\n"
+        "  diskbuf == 0x%08X, disksize == %u sectors\n"
+        "  bootloaderid == 0x%02X (%s),\n"
+        "  cmdline: %s\n",
+        mdi->version_major,
+        mdi->version_minor,
+        mdi->diskbuf,
+        mdi->disksize,
+        mdi->bootloaderid,
+        bootloadername(mdi->bootloaderid),
+        cmdline
+      );
+    return;
+  }
+
+/* This function copyright H. Peter Anvin */
+static void boot_args(char **args)
+{
+    int len = 0, a = 0;
+    char **pp;
+    const char *p;
+    char c, *q, *str;
+
+    for (pp = args; *pp; pp++)
+	len += strlen(*pp) + 1;
+
+    q = str = alloca(len);
+    for (pp = args; *pp; pp++) {
+	p = *pp;
+	while ((c = *p++))
+	    *q++ = c;
+	*q++ = ' ';
+	a = 1;
+    }
+    q -= a;
+    *q = '\0';
+
+    if (!str[0])
+	syslinux_run_default();
+    else
+	syslinux_run_command(str);
+}
+
+/* This function copyright H. Peter Anvin */
+static const char *bootloadername(uint8_t id)
+{
+    static const struct {
+	uint8_t id, mask;
+	const char *name;
+    } *lp, list[] = {
+	{0x00, 0xf0, "LILO"}, 
+	{0x10, 0xf0, "LOADLIN"},
+	{0x31, 0xff, "SYSLINUX"},
+	{0x32, 0xff, "PXELINUX"},
+	{0x33, 0xff, "ISOLINUX"},
+	{0x34, 0xff, "EXTLINUX"},
+	{0x30, 0xf0, "Syslinux family"},
+	{0x40, 0xf0, "Etherboot"},
+	{0x50, 0xf0, "ELILO"},
+	{0x70, 0xf0, "GrUB"},
+	{0x80, 0xf0, "U-Boot"},
+	{0xA0, 0xf0, "Gujin"},
+	{0xB0, 0xf0, "Qemu"},
+	{0x00, 0x00, "unknown"}
+    };
+
+    for (lp = list;; lp++) {
+	if (((id ^ lp->id) & lp->mask) == 0)
+	    return lp->name;
+    }
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/modules/ifplop.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/ifplop.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/ifplop.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,168 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010 Gert Hulselmans - 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * ifplop.c
+ *
+ * This COM32 module detects if the PLoP Boot Manager was used to boot a CDROM
+ * drive or USB drive, by checking for the presence of the PLoP INT13h hook.
+ *
+ * Usage:    ifplop.c32 [<plop_detected>] -- [<plop_not_detected>]
+ * Examples: ifplop.c32 menu.c32 another.cfg -- plpbt hiddenusb usb1=2
+ *              You need to remove the ".bin" extension of the plpbt.bin file
+ *              if you use it this way.
+ *           ifplop.c32 plop_detected -- plop_not_detected
+ *
+ * A possible config file could be:
+ *
+ * ===========================================================================
+ *  DEFAULT plopcheck
+ *
+ *  # Check for the presence of PLoP (run by default)
+ *  #   When PLoP INT13h hook is found, run the first command (plop_detected)
+ *  #   When PLoP INT13h hook isn't found, run the second command (plop_not_detected)
+ *  LABEL plopcheck
+ *      COM32 ifplop.c32
+ *      APPEND plop_detected -- plop_not_detected
+ *
+ *  # When PLoP INT13h hook was found, boot the menu system.
+ *  # PLoP can have added USB 2.0 speed, so the entries we want to boot
+ *  # will be read from disk much faster (supposing that we have a BIOS
+ *  # that only supports USB 1.1 speed, but a mobo with USB 2.0 controllers).
+ *  LABEL plop_detected
+ *      COM32 menu.c32
+ *      APPEND another.cfg
+ *
+ *  # PLoP INT13h hook wasn't found, so we boot PLoP, so it can add USB 2.0 support
+ *  # When using "LINUX plpbt.bin", you don't need to remove the .bin extension.
+ *  LABEL plop_not_detected
+ *      LINUX plpbt.bin
+ *      APPEND hiddenusb usb1=2
+ *
+ * ===========================================================================
+ *
+ * Why is/can this module be useful?
+ *
+ * You may want to boot PLoP by default from Syslinux when you boot from your
+ * USB stick/drive:
+ *   1. PLoP can upgrade USB 1.1 speed offered by the BIOS to USB 2.0 speed
+ *      if you have USB 2.0 controllers on your mobo.
+ *   2. Some BIOSes only can access the first 128GiB (137GB) on USB drives, while
+ *      internal hard drives don't necessarily suffer from this 128GiB problem.
+ *      Using PLoPs USB capabilities, you can access the whole drive.
+ *
+ * When you select the "USB" entry in PLoP, it will boot your USB stick/drive
+ * again and it will boot PLoP again when you have set booting PLoP as DEFAULT
+ * boot option in your Syslinux configuration file.
+ *
+ * By using ifplop.c32 you can specify which action you want to do the second
+ * time your USB stick/drive is booted. So you can load another config file or
+ * boot a large hard disk image or whatever you want.
+ *
+ * PLoP Boot Manager website: http://www.plop.at/en/bootmanager.html
+ */
+
+#include <com32.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <alloca.h>
+#include <console.h>
+#include <syslinux/boot.h>
+
+static bool plop_INT13h_check(void)
+{
+    com32sys_t inregs, outregs;
+
+    /* Prepare the register set */
+    memset(&inregs, 0, sizeof inregs);
+
+    /*
+     * Check if PLoP already has booted a CDROM or USB drive by checking
+     * for the presence of the PLoP INT13h hook.
+     *
+     * The following assembly code (NASM) can detect the PLoP INT13h hook:
+     *
+     *   mov eax,'PoLP'  ; Reverse of 'PLoP'
+     *   mov ebp,'DKHC'  ; Reverse of 'CHKD'
+     *   int 13h
+     *   cmp eax,' sey'  ; Reverse of 'yes '
+     *   jz plop_INT13h_active
+     */
+
+    inregs.eax.l = 0x504c6f50;	/* "PLoP" */
+    inregs.ebp.l = 0x43484b44;	/* "CHKD" */
+
+    __intcall(0x13, &inregs, &outregs);
+
+    /* eax will contain "yes " if PLoP INT13h hook is available */
+    if (outregs.eax.l == 0x79657320)
+	return true;
+
+    return false;
+}
+
+/* XXX: this really should be librarized */
+static void boot_args(char **args)
+{
+    int len = 0, a = 0;
+    char **pp;
+    const char *p;
+    char c, *q, *str;
+
+    for (pp = args; *pp; pp++)
+	len += strlen(*pp) + 1;
+
+    q = str = alloca(len);
+    for (pp = args; *pp; pp++) {
+	p = *pp;
+	while ((c = *p++))
+	    *q++ = c;
+	*q++ = ' ';
+	a = 1;
+    }
+    q -= a;
+    *q = '\0';
+
+    if (!str[0])
+	syslinux_run_default();
+    else
+	syslinux_run_command(str);
+}
+
+int main(int argc, char *argv[])
+{
+    char **args[2];
+    int arg = 0;
+
+    if (argc)
+	arg++;
+    args[0] = &argv[arg];
+    args[1] = NULL;
+    while (arg < argc) {
+	if (!strcmp(argv[arg], "--")) {
+	    argv[arg] = NULL;
+	    args[1] = &argv[arg + 1];
+	    break;
+	}
+	arg++;
+    }
+    if (args[1] != NULL) {
+	boot_args(plop_INT13h_check()? args[0] : args[1]);
+    } else {
+	fprintf(stderr,
+		"Usage:   ifplop.c32 [<plop_detected>] -- [<plop_not_detected>]\n"
+		"Example: ifplop.c32 menu.c32 another.cfg -- plpbt hiddenusb usb1=2\n");
+    }
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/kbdmap.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/kbdmap.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/kbdmap.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,52 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#include <stdio.h>
+#include <string.h>
+#include <console.h>
+#include <syslinux/loadfile.h>
+#include <syslinux/keyboard.h>
+
+static inline void error(const char *msg)
+{
+    fputs(msg, stderr);
+}
+
+int main(int argc, char *argv[])
+{
+    const struct syslinux_keyboard_map *const kmap = syslinux_keyboard_map();
+    size_t map_size;
+    void *kbdmap;
+
+    if (argc != 2) {
+	error("Usage: kbdmap mapfile\n");
+	return 1;
+    }
+
+    if (kmap->version != 1) {
+	error("Syslinux core version mismatch\n");
+	return 1;
+    }
+
+    if (loadfile(argv[1], &kbdmap, &map_size)) {
+	error("Keyboard map file load error\n");
+	return 1;
+    }
+
+    if (map_size != kmap->length) {
+	error("Keyboard map file format error\n");
+	return 1;
+    }
+
+    memcpy(kmap->map, kbdmap, map_size);
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/kontron_wdt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/kontron_wdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/kontron_wdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,414 @@
+/*
+ *  kempld_wdt.c - Kontron PLD watchdog driver
+ *
+ *  Copyright (c) 2010 Kontron Embedded Modules GmbH
+ *  Author: Michael Brunner <michael.brunner@kontron.com>
+ *  Author: Erwan Velu <erwan.velu@zodiacaerospace.com>
+ *
+ *  Note: From the PLD watchdog point of view timeout and pretimeout are
+ *        defined differently than in the kernel.
+ *        First the pretimeout stage runs out before the timeout stage gets
+ *        active. This has to be kept in mind.
+ *
+ *  Kernel/API:                     P-----| pretimeout
+ *                |-----------------------T timeout
+ *  Watchdog:     |-----------------P       pretimeout_stage
+ *                                  |-----T timeout_stage
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <string.h>
+#include <sys/io.h>
+#include <unistd.h>
+#include <syslinux/boot.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <console.h>
+#include "kontron_wdt.h"
+
+struct kempld_device_data  pld;
+struct kempld_watchdog_data wdt;
+uint8_t status;
+char default_label[255];
+
+/* Default Timeout is 60sec */
+#define TIMEOUT 60
+#define PRETIMEOUT 0
+
+#define do_div(n,base) ({ \
+		int __res; \
+		__res = ((unsigned long) n) % (unsigned) base; \
+		n = ((unsigned long) n) / (unsigned) base; \
+		__res; })
+
+
+/* Basic Wrappers to get code as less changed as possible */
+void iowrite8(uint8_t val, uint16_t addr) { outb(val,addr); }
+void iowrite16(uint16_t val, uint16_t addr) { outw(val,addr); }
+void iowrite32(uint32_t val, uint16_t addr) { outl(val,addr);}
+uint8_t ioread8(uint16_t addr)   { return inb(addr);}
+uint16_t ioread16(uint16_t addr) { return inw(addr);}
+uint32_t ioread32(uint32_t addr) { return inl(addr);}
+
+
+/**
+ * kempld_set_index -  change the current register index of the PLD
+ * @pld:   kempld_device_data structure describing the PLD
+ * @index: register index on the chip
+ *
+ * This function changes the register index of the PLD.
+ */
+void kempld_set_index(struct kempld_device_data *pld, uint8_t index)
+{
+        if (pld->last_index != index) {
+                iowrite8(index, pld->io_index);
+                pld->last_index = index;
+        }
+}
+
+
+uint8_t kempld_read8(struct kempld_device_data *pld, uint8_t index) {
+        kempld_set_index(pld, index);
+        return ioread8(pld->io_data);
+}
+
+
+void kempld_write8(struct kempld_device_data *pld, uint8_t index, uint8_t data) {
+        kempld_set_index(pld, index);
+        iowrite8(data, pld->io_data);
+}
+
+
+uint16_t kempld_read16(struct kempld_device_data *pld, uint8_t index)
+{
+        return kempld_read8(pld, index) | kempld_read8(pld, index+1) << 8;
+}
+
+
+void kempld_write16(struct kempld_device_data *pld, uint8_t index, uint16_t data)
+{
+        kempld_write8(pld, index, (uint8_t)data);
+        kempld_write8(pld, index+1, (uint8_t)(data>>8));
+}
+
+uint32_t kempld_read32(struct kempld_device_data *pld, uint8_t index)
+{
+        return kempld_read16(pld, index) | kempld_read16(pld, index+2) << 16;
+}
+
+void kempld_write32(struct kempld_device_data *pld, uint8_t index, uint32_t data)
+{
+        kempld_write16(pld, index, (uint16_t)data);
+        kempld_write16(pld, index+2, (uint16_t)(data>>16));
+}
+
+static void kempld_release_mutex(struct kempld_device_data *pld)
+{
+        iowrite8(pld->last_index | KEMPLD_MUTEX_KEY, pld->io_index);
+}
+
+void init_structure(void) {
+	/* set default values for the case we start the watchdog or change
+	 * the configuration */
+	memset(&wdt,0,sizeof(wdt));
+	memset(&pld,0,sizeof(pld));
+	memset(&default_label,0,sizeof(default_label));
+        wdt.timeout = TIMEOUT;
+        wdt.pretimeout = PRETIMEOUT;
+        wdt.pld = &pld;
+
+	pld.io_base=KEMPLD_IOPORT;
+	pld.io_index=KEMPLD_IOPORT;
+	pld.io_data=KEMPLD_IODATA;
+	pld.pld_clock=33333333;
+}
+
+static int kempld_probe(void) {
+   /* Check for empty IO space */
+	int ret=0;
+	uint8_t  index_reg = ioread8(pld.io_index);
+        if ((index_reg == 0xff) && (ioread8(pld.io_data) == 0xff)) {
+                ret = 1;
+                goto err_empty_io;
+        }
+	printf("Kempld structure found at 0x%X (data @ 0x%X)\n",pld.io_base,pld.io_data);
+	return 0;
+
+err_empty_io:
+	printf("No IO Found !\n");
+	return ret;
+}
+
+static int kempld_wdt_probe_stages(struct kempld_watchdog_data *wdt)
+{
+        struct kempld_device_data *pld = wdt->pld;
+        int i, ret;
+        uint32_t timeout;
+        uint32_t timeout_mask;
+        struct kempld_watchdog_stage *stage;
+
+        wdt->stages = 0;
+        wdt->timeout_stage = NULL;
+        wdt->pretimeout_stage = NULL;
+
+        for (i = 0; i < KEMPLD_WDT_MAX_STAGES; i++) {
+
+		timeout = kempld_read32(pld, KEMPLD_WDT_STAGE_TIMEOUT(i));
+                kempld_write32(pld, KEMPLD_WDT_STAGE_TIMEOUT(i), 0x00000000);
+                timeout_mask = kempld_read32(pld, KEMPLD_WDT_STAGE_TIMEOUT(i));
+                kempld_write32(pld, KEMPLD_WDT_STAGE_TIMEOUT(i), timeout);
+
+                if (timeout_mask != 0xffffffff) {
+                        stage = malloc(sizeof(struct kempld_watchdog_stage));
+                        if (stage == NULL) {
+                                ret = -1;
+                                goto err_alloc_stages;
+                        }
+                        stage->num = i;
+                        stage->timeout_mask = ~timeout_mask;
+                        wdt->stage[i] = stage;
+                        wdt->stages++;
+
+                        /* assign available stages to timeout and pretimeout */
+                        if (wdt->stages == 1)
+                                wdt->timeout_stage = stage;
+                        else if (wdt->stages == 2) {
+                                wdt->pretimeout_stage = wdt->timeout_stage;
+                                wdt->timeout_stage = stage;
+                        }
+                } else {
+                        wdt->stage[i] = NULL;
+                }
+        }
+
+        return 0;
+err_alloc_stages:
+	kempld_release_mutex(pld);
+	printf("Cannot allocate stages\n");
+	return ret;
+}
+
+static int kempld_wdt_keepalive(struct kempld_watchdog_data *wdt)
+{
+        struct kempld_device_data *pld = wdt->pld;
+
+	kempld_write8(pld, KEMPLD_WDT_KICK, 'K');
+
+        return 0;
+}
+
+static int kempld_wdt_setstageaction(struct kempld_watchdog_data *wdt,
+                                 struct kempld_watchdog_stage *stage,
+                                 int action)
+{
+        struct kempld_device_data *pld = wdt->pld;
+        uint8_t stage_cfg;
+
+        if (stage == NULL)
+                return -1;
+
+        stage_cfg = kempld_read8(pld, KEMPLD_WDT_STAGE_CFG(stage->num));
+        stage_cfg &= ~KEMPLD_WDT_STAGE_CFG_ACTION_MASK;
+        stage_cfg |= (action & KEMPLD_WDT_STAGE_CFG_ACTION_MASK);
+        if (action == KEMPLD_WDT_ACTION_RESET)
+                stage_cfg |= KEMPLD_WDT_STAGE_CFG_ASSERT;
+        else
+                stage_cfg &= ~KEMPLD_WDT_STAGE_CFG_ASSERT;
+
+        kempld_write8(pld, KEMPLD_WDT_STAGE_CFG(stage->num), stage_cfg);
+        stage_cfg = kempld_read8(pld, KEMPLD_WDT_STAGE_CFG(stage->num));
+
+        return 0;
+}
+
+static int kempld_wdt_setstagetimeout(struct kempld_watchdog_data *wdt,
+                                 struct kempld_watchdog_stage *stage,
+                                 int timeout)
+{
+        struct kempld_device_data *pld = wdt->pld;
+        uint8_t stage_cfg;
+        uint8_t prescaler;
+        uint64_t stage_timeout64;
+        uint32_t stage_timeout;
+
+        if (stage == NULL)
+                return -1;
+
+        prescaler = KEMPLD_WDT_PRESCALER_21BIT;
+
+        stage_timeout64 = ((uint64_t)timeout*pld->pld_clock);
+        do_div(stage_timeout64, KEMPLD_PRESCALER(prescaler));
+        stage_timeout = stage_timeout64 & stage->timeout_mask;
+
+        if (stage_timeout64 != (uint64_t)stage_timeout)
+                return -1;
+
+        stage_cfg = kempld_read8(pld, KEMPLD_WDT_STAGE_CFG(stage->num));
+        stage_cfg &= ~KEMPLD_WDT_STAGE_CFG_PRESCALER_MASK;
+        stage_cfg |= KEMPLD_WDT_STAGE_CFG_SET_PRESCALER(prescaler);
+        kempld_write8(pld, KEMPLD_WDT_STAGE_CFG(stage->num), stage_cfg);
+        kempld_write32(pld, KEMPLD_WDT_STAGE_TIMEOUT(stage->num),
+                       stage_timeout);
+
+        return 0;
+}
+
+
+static int kempld_wdt_settimeout(struct kempld_watchdog_data *wdt)
+{
+        int stage_timeout;
+        int stage_pretimeout;
+        int ret;
+        if ((wdt->timeout <= 0) ||
+            (wdt->pretimeout < 0) ||
+            (wdt->pretimeout > wdt->timeout)) {
+                ret = -1;
+                goto err_check_values;
+        }
+
+        if ((wdt->pretimeout == 0) || (wdt->pretimeout_stage == NULL)) {
+                if (wdt->pretimeout != 0)
+                        printf("No pretimeout stage available, only enabling reset!\n");
+                stage_pretimeout = 0;
+                stage_timeout =  wdt->timeout;
+        } else {
+                stage_pretimeout = wdt->timeout - wdt->pretimeout;
+                stage_timeout =  wdt->pretimeout;
+        }
+
+        if (stage_pretimeout != 0) {
+                ret = kempld_wdt_setstageaction(wdt, wdt->pretimeout_stage,
+                                                KEMPLD_WDT_ACTION_NMI);
+        } else if ((stage_pretimeout == 0)
+                   && (wdt->pretimeout_stage != NULL)) {
+                ret = kempld_wdt_setstageaction(wdt, wdt->pretimeout_stage,
+                                                KEMPLD_WDT_ACTION_NONE);
+        } else
+                ret = 0;
+        if (ret)
+                goto err_setstage;
+
+        if (stage_pretimeout != 0) {
+                ret = kempld_wdt_setstagetimeout(wdt, wdt->pretimeout_stage,
+                                                 stage_pretimeout);
+                if (ret)
+                        goto err_setstage;
+        }
+
+        ret = kempld_wdt_setstageaction(wdt, wdt->timeout_stage,
+                                        KEMPLD_WDT_ACTION_RESET);
+        if (ret)
+                goto err_setstage;
+
+        ret = kempld_wdt_setstagetimeout(wdt, wdt->timeout_stage,
+                                         stage_timeout);
+        if (ret)
+                goto err_setstage;
+
+        return 0;
+err_setstage:
+err_check_values:
+        return ret;
+}
+
+static int kempld_wdt_start(struct kempld_watchdog_data *wdt)
+{
+        struct kempld_device_data *pld = wdt->pld;
+        uint8_t status;
+
+        status = kempld_read8(pld, KEMPLD_WDT_CFG);
+        status |= KEMPLD_WDT_CFG_ENABLE;
+        kempld_write8(pld, KEMPLD_WDT_CFG, status);
+        status = kempld_read8(pld, KEMPLD_WDT_CFG);
+
+        /* check if the watchdog was enabled */
+        if (!(status & KEMPLD_WDT_CFG_ENABLE))
+                return -1;
+
+        return 0;
+}
+
+/* A regular configuration file looks like
+
+   LABEL WDT
+       COM32 wdt.c32
+       APPEND timeout=120 default_label=local
+*/
+void detect_parameters(const int argc, const char *argv[]) {
+	for (int i = 1; i < argc; i++) {
+		/* Override the timeout if specified on the cmdline */
+		if (!strncmp(argv[i], "timeout=", 8)) {
+			wdt.timeout=atoi(argv[i]+8);
+		} else
+		/* Define which boot entry shall be used */
+		if (!strncmp(argv[i], "default_label=", 14)) {
+			strlcpy(default_label, argv[i] + 14, sizeof(default_label));
+		}
+	}
+}
+
+int main(int argc, const char *argv[]) {
+	int ret=0;
+	openconsole(&dev_rawcon_r, &dev_stdcon_w);
+	init_structure();
+	detect_parameters(argc,argv);
+	kempld_probe();
+
+        /* probe how many usable stages we have */
+        if (kempld_wdt_probe_stages(&wdt)) {
+		printf("Cannot Probe Stages\n");
+		return -1;
+	}
+
+	/* Useless but who knows */
+	wdt.ident.firmware_version = KEMPLD_WDT_REV_GET(kempld_read8(&pld, KEMPLD_WDT_REV));
+
+        status = kempld_read8(&pld, KEMPLD_WDT_CFG);
+	/* kick the watchdog if it is already enabled, otherwise start it */
+        if (status & KEMPLD_WDT_CFG_ENABLE) {
+		/* Maybye the BIOS did setup a first timer
+		 * in this case, let's enforce the timeout
+		 * to be sure we do have the proper value */
+		kempld_wdt_settimeout(&wdt);
+                kempld_wdt_keepalive(&wdt);
+        } else {
+		ret = kempld_wdt_settimeout(&wdt);
+                if (ret) {
+			printf("Unable to setup timeout !\n");
+			goto booting;
+		}
+
+		ret = kempld_wdt_start(&wdt);
+                if (ret) {
+			printf("Unable to start watchdog !\n");
+			goto booting;
+		}
+
+        }
+
+	printf("Watchog armed ! Rebooting in %d seconds if no feed occurs !\n",wdt.timeout);
+
+booting:
+	/* Release Mutex to let Linux's Driver taking control */
+        kempld_release_mutex(&pld);
+
+	/* Let's boot the default entry if specified */
+	if (strlen(default_label)>0) {
+		printf("Executing default label = '%s'\n",default_label);
+		syslinux_run_command(default_label);
+	} else {
+		return ret;
+	}
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/kontron_wdt.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/kontron_wdt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/kontron_wdt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,117 @@
+/*
+ *  kempld_wdt.h - Kontron PLD watchdog driver definitions
+ *
+ *  Copyright (c) 2010 Kontron Embedded Modules GmbH
+ *  Author: Michael Brunner <michael.brunner@kontron.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _KEMPLD_WDT_H_
+#define _KEMPLD_WDT_H_
+#include <stdint.h>
+
+#define KEMPLD_IOPORT 0x0a80
+#define KEMPLD_IODATA (KEMPLD_IOPORT+1)
+
+#define KEMPLD_MUTEX_KEY	0x80
+
+/* watchdog register definitions */
+#define KEMPLD_WDT_KICK                 0x16
+#define KEMPLD_WDT_REV                  0x16
+#define         KEMPLD_WDT_REV_GET(x)                   (x & 0xf)
+#define KEMPLD_WDT_CFG                  0x17
+#define         KEMPLD_WDT_CFG_STAGE_TIMEOUT_OCCURED(x) (1<<x)
+#define         KEMPLD_WDT_CFG_ENABLE_LOCK              0x8
+#define         KEMPLD_WDT_CFG_ENABLE                   0x10
+#define         KEMPLD_WDT_CFG_AUTO_RELOAD              0x40
+#define         KEMPLD_WDT_CFG_GLOBAL_LOCK              0x80
+#define KEMPLD_WDT_STAGE_CFG(x)         (0x18+x)
+#define         KEMPLD_WDT_STAGE_CFG_ACTION_MASK        0x7
+#define         KEMPLD_WDT_STAGE_CFG_GET_ACTION(x)      (x & 0x7)
+#define         KEMPLD_WDT_STAGE_CFG_ASSERT             0x8
+#define         KEMPLD_WDT_STAGE_CFG_PRESCALER_MASK     0x30
+#define         KEMPLD_WDT_STAGE_CFG_GET_PRESCALER(x)   ((x & 0x30)>>4)
+#define         KEMPLD_WDT_STAGE_CFG_SET_PRESCALER(x)   ((x & 0x30)<<4)
+#define KEMPLD_WDT_STAGE_TIMEOUT(x)     (0x1b+x*4)
+#define KEMPLD_WDT_MAX_STAGES           3
+
+#define KEMPLD_WDT_ACTION_NONE          0x0
+#define KEMPLD_WDT_ACTION_RESET         0x1
+#define KEMPLD_WDT_ACTION_NMI           0x2
+#define KEMPLD_WDT_ACTION_SMI           0x3
+#define KEMPLD_WDT_ACTION_SCI           0x4
+#define KEMPLD_WDT_ACTION_DELAY         0x5
+
+#define KEMPLD_WDT_PRESCALER_21BIT      0x0
+#define KEMPLD_WDT_PRESCALER_17BIT      0x1
+#define KEMPLD_WDT_PRESCALER_12BIT      0x2
+
+const int kempld_prescaler_bits[] = { 21, 17, 12 };
+
+struct kempld_watchdog_stage {
+        int     num;
+        uint32_t     timeout_mask;
+};
+
+/**
+ * struct kempld_device_data - Internal representation of the PLD device
+ * @io_base:            Pointer to the IO memory
+ * @io_index:           Pointer to the IO index register
+ * @io_data:            Pointer to the IO data register
+ * @pld_clock:          PLD clock frequency
+ * @lock:               PLD spin-lock
+ * @lock_flags:         PLD spin-lock flags
+ * @have_mutex:         Bool value that indicates if mutex is aquired
+ * @last_index:         Last written index value
+ * @rscr:               Kernel resource structure
+ * @dev:                Pointer to kernel device structure
+ * @info:               KEMPLD info structure
+ */
+struct kempld_device_data {
+        uint16_t 	        io_base;
+        uint16_t		io_index;
+        uint16_t		io_data;
+        uint32_t		 pld_clock;
+/*        spinlock_t              lock;
+        unsigned long           lock_flags; */
+        int                     have_mutex;
+        uint8_t			last_index;
+/*        struct resource         rscr;
+        struct device           *dev;
+        struct kempld_info      info;*/
+};
+
+struct watchdog_info {
+	uint32_t options;          /* Options the card/driver supports */
+	uint32_t firmware_version; /* Firmware version of the card */
+	uint8_t  identity[32];     /* Identity of the board */
+};
+
+struct kempld_watchdog_data {
+        unsigned int                    revision;
+        int                             timeout;
+        int                             pretimeout;
+        unsigned long                   is_open;
+        unsigned long                   expect_close;
+        int                             stages;
+        struct kempld_watchdog_stage    *timeout_stage;
+        struct kempld_watchdog_stage    *pretimeout_stage;
+        struct kempld_device_data       *pld;
+        struct kempld_watchdog_stage    *stage[KEMPLD_WDT_MAX_STAGES];
+	struct watchdog_info		ident;
+};
+
+#endif /* _KEMPLD_WDT_H_ */
+#define KEMPLD_PRESCALER(x)     (0xffffffff>>(32-kempld_prescaler_bits[x]))
Index: bootcd/isolinux/syslinux-6.03/com32/modules/linux.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/linux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/linux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,415 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2007-2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2012 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * linux.c
+ *
+ * Sample module to load Linux kernels.  This module can also create
+ * a file out of the DHCP return data if running under PXELINUX.
+ *
+ * If -dhcpinfo is specified, the DHCP info is written into the file
+ * /dhcpinfo.dat in the initramfs.
+ *
+ * Usage: linux.c32 [-dhcpinfo] kernel arguments...
+ */
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <console.h>
+#include <syslinux/loadfile.h>
+#include <syslinux/linux.h>
+#include <syslinux/pxe.h>
+
+enum ldmode {
+    ldmode_raw,
+    ldmode_cpio,
+    ldmodes
+};
+
+typedef int f_ldinitramfs(struct initramfs *, char *);
+
+const char *progname = "linux.c32";
+
+/* Find the last instance of a particular command line argument
+   (which should include the final =; do not use for boolean arguments) */
+static char *find_argument(char **argv, const char *argument)
+{
+    int la = strlen(argument);
+    char **arg;
+    char *ptr = NULL;
+
+    for (arg = argv; *arg; arg++) {
+	if (!strncmp(*arg, argument, la))
+	    ptr = *arg + la;
+    }
+
+    return ptr;
+}
+
+/* Find the next instance of a particular command line argument */
+static char **find_arguments(char **argv, char **ptr,
+			     const char *argument)
+{
+    int la = strlen(argument);
+    char **arg;
+
+    for (arg = argv; *arg; arg++) {
+	if (!strncmp(*arg, argument, la)) {
+	    *ptr = *arg + la;
+	    break;
+	}
+    }
+
+    /* Exhausted all arguments */
+    if (!*arg)
+	return NULL;
+
+    return arg;
+}
+
+/* Search for a boolean argument; return its position, or 0 if not present */
+static int find_boolean(char **argv, const char *argument)
+{
+    char **arg;
+
+    for (arg = argv; *arg; arg++) {
+	if (!strcmp(*arg, argument))
+	    return (arg - argv) + 1;
+    }
+
+    return 0;
+}
+
+/* Stitch together the command line from a set of argv's */
+static char *make_cmdline(char **argv)
+{
+    char **arg;
+    size_t bytes;
+    char *cmdline, *p;
+
+    bytes = 1;			/* Just in case we have a zero-entry cmdline */
+    for (arg = argv; *arg; arg++) {
+	bytes += strlen(*arg) + 1;
+    }
+
+    p = cmdline = malloc(bytes);
+    if (!cmdline)
+	return NULL;
+
+    for (arg = argv; *arg; arg++) {
+	int len = strlen(*arg);
+	memcpy(p, *arg, len);
+	p[len] = ' ';
+	p += len + 1;
+    }
+
+    if (p > cmdline)
+	p--;			/* Remove the last space */
+    *p = '\0';
+
+    return cmdline;
+}
+
+static f_ldinitramfs ldinitramfs_raw;
+static int ldinitramfs_raw(struct initramfs *initramfs, char *fname)
+{
+    return initramfs_load_archive(initramfs, fname);
+}
+
+static f_ldinitramfs ldinitramfs_cpio;
+static int ldinitramfs_cpio(struct initramfs *initramfs, char *fname)
+{
+    char *target_fname, *p;
+    int do_mkdir, unmangle, rc;
+
+    /* Choose target_fname based on presence of "@" syntax */
+    target_fname = strchr(fname, '@');
+    if (target_fname) {
+	/* Temporarily mangle */
+	unmangle = 1;
+	*target_fname++ = '\0';
+
+	/* Make parent directories? */
+	do_mkdir = !!strchr(target_fname, '/');
+    } else {
+	unmangle = 0;
+
+	/* Forget the source path */
+	target_fname = fname;
+	while ((p = strchr(target_fname, '/')))
+	    target_fname = p + 1;
+
+	/* The user didn't specify a desired path */
+	do_mkdir = 0;
+    }
+
+    /*
+     * Load the file, encapsulate it with the desired path, make the
+     * parent directories if the desired path contains them, add to initramfs
+     */
+    rc = initramfs_load_file(initramfs, fname, target_fname, do_mkdir, 0755);
+
+    /* Unmangle, if needed*/
+    if (unmangle)
+	*--target_fname = '@';
+
+    return rc;
+}
+
+/* It only makes sense to call this function from main */
+static int process_initramfs_args(char *arg, struct initramfs *initramfs,
+				  const char *kernel_name, enum ldmode mode,
+				  bool opt_quiet)
+{
+    const char *mode_msg;
+    f_ldinitramfs *ldinitramfs;
+    char *p;
+
+    switch (mode) {
+    case ldmode_raw:
+	mode_msg = "Loading";
+	ldinitramfs = ldinitramfs_raw;
+	break;
+    case ldmode_cpio:
+	mode_msg = "Encapsulating";
+	ldinitramfs = ldinitramfs_cpio;
+	break;
+    case ldmodes:
+    default:
+	return 1;
+    }
+
+    do {
+	p = strchr(arg, ',');
+	if (p)
+	    *p = '\0';
+
+	if (!opt_quiet)
+	    printf("%s %s... ", mode_msg, arg);
+	errno = 0;
+	if (ldinitramfs(initramfs, arg)) {
+	    if (opt_quiet)
+		printf("Loading %s ", kernel_name);
+	    printf("failed: ");
+	    return 1;
+	}
+	if (!opt_quiet)
+	    printf("ok\n");
+
+	if (p)
+	    *p++ = ',';
+    } while ((arg = p));
+
+    return 0;
+}
+
+static int setup_data_file(struct setup_data *setup_data,
+			   uint32_t type, const char *filename,
+			   bool opt_quiet)
+{
+    if (!opt_quiet)
+	printf("Loading %s... ", filename);
+
+    if (setup_data_load(setup_data, type, filename)) {
+	if (opt_quiet)
+	    printf("Loading %s ", filename);
+	printf("failed\n");
+	return -1;
+    }
+	    
+    if (!opt_quiet)
+	printf("ok\n");
+    
+    return 0;
+}
+
+int main(int argc, char *argv[])
+{
+    const char *kernel_name;
+    struct initramfs *initramfs;
+    struct setup_data *setup_data;
+    char *cmdline;
+    char *boot_image;
+    void *kernel_data;
+    size_t kernel_len;
+    bool opt_dhcpinfo = false;
+    bool opt_quiet = false;
+    void *dhcpdata;
+    size_t dhcplen;
+    char **argp, **argl, *arg;
+
+    (void)argc;
+    argp = argv + 1;
+
+    while ((arg = *argp) && arg[0] == '-') {
+	if (!strcmp("-dhcpinfo", arg)) {
+	    opt_dhcpinfo = true;
+	} else {
+	    fprintf(stderr, "%s: unknown option: %s\n", progname, arg);
+	    return 1;
+	}
+	argp++;
+    }
+
+    if (!arg) {
+	fprintf(stderr, "%s: missing kernel name\n", progname);
+	return 1;
+    }
+
+    kernel_name = arg;
+
+    errno = 0;
+    boot_image = malloc(strlen(kernel_name) + 12);
+    if (!boot_image) {
+	fprintf(stderr, "Error allocating BOOT_IMAGE string: ");
+	goto bail;
+    }
+    strcpy(boot_image, "BOOT_IMAGE=");
+    strcpy(boot_image + 11, kernel_name);
+    /* argp now points to the kernel name, and the command line follows.
+       Overwrite the kernel name with the BOOT_IMAGE= argument, and thus
+       we have the final argument. */
+    *argp = boot_image;
+
+    if (find_boolean(argp, "quiet"))
+	opt_quiet = true;
+
+    if (!opt_quiet)
+	printf("Loading %s... ", kernel_name);
+    errno = 0;
+    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");
+
+    errno = 0;
+    cmdline = make_cmdline(argp);
+    if (!cmdline) {
+	fprintf(stderr, "make_cmdline() failed: ");
+	goto bail;
+    }
+
+    /* Initialize the initramfs chain */
+    errno = 0;
+    initramfs = initramfs_init();
+    if (!initramfs) {
+	fprintf(stderr, "initramfs_init() failed: ");
+	goto bail;
+    }
+
+    /* Process initramfs arguments */
+    if ((arg = find_argument(argp, "initrd="))) {
+	if (process_initramfs_args(arg, initramfs, kernel_name, ldmode_raw,
+				   opt_quiet))
+	    goto bail;
+    }
+
+    argl = argv;
+    while ((argl = find_arguments(argl, &arg, "initrd+="))) {
+	argl++;
+	if (process_initramfs_args(arg, initramfs, kernel_name, ldmode_raw,
+				   opt_quiet))
+	    goto bail;
+    }
+
+    argl = argv;
+    while ((argl = find_arguments(argl, &arg, "initrdfile="))) {
+	argl++;
+	if (process_initramfs_args(arg, initramfs, kernel_name, ldmode_cpio,
+				   opt_quiet))
+	    goto bail;
+    }
+
+    /* Append the DHCP info */
+    if (opt_dhcpinfo &&
+	!pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK, &dhcpdata, &dhcplen)) {
+	errno = 0;
+	if (initramfs_add_file(initramfs, dhcpdata, dhcplen, dhcplen,
+			       "/dhcpinfo.dat", 0, 0755)) {
+	    fprintf(stderr, "Unable to add DHCP info: ");
+	    goto bail;
+	}
+    }
+
+    /* Handle dtb and eventually other setup data */
+    setup_data = setup_data_init();
+    if (!setup_data)
+	goto bail;
+
+    argl = argv;
+    while ((argl = find_arguments(argl, &arg, "dtb="))) {
+	argl++;
+	if (setup_data_file(setup_data, SETUP_DTB, arg, opt_quiet))
+	    goto bail;
+    }
+
+    argl = argv;
+    while ((argl = find_arguments(argl, &arg, "blob."))) {
+	uint32_t type;
+	char *ep;
+
+	argl++;
+	type = strtoul(arg, &ep, 10);
+	if (ep[0] != '=' || !ep[1])
+	    continue;
+
+	if (!type)
+	    continue;
+
+	if (setup_data_file(setup_data, type, ep+1, opt_quiet))
+	    goto bail;
+    }
+
+    /* This should not return... */
+    errno = 0;
+    syslinux_boot_linux(kernel_data, kernel_len, initramfs,
+			setup_data, cmdline);
+    fprintf(stderr, "syslinux_boot_linux() failed: ");
+
+bail:
+    switch(errno) {
+    case ENOENT:
+	fprintf(stderr, "File not found\n");
+	break;
+    case ENOMEM:
+	fprintf(stderr, "Out of memory\n");
+	break;
+    default:
+	fprintf(stderr, "Error %d\n", errno);
+	break;
+    }
+    fprintf(stderr, "%s: Boot aborted!\n", progname);
+    return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/ls.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/ls.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/ls.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,175 @@
+/*
+ * Display directory contents
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <console.h>
+#include <string.h>
+#include <com32.h>
+#include <dirent.h>
+#include <minmax.h>
+#include <unistd.h>
+#include <getkey.h>
+
+static int rows, cols;		/* Screen parameters */
+
+#define DIR_CHUNK	1024
+
+static const char *type_str(int type)
+{
+    switch (type) {
+    case DT_FIFO:
+	return "[fif]";
+    case DT_CHR:
+	return "[chr]";
+    case DT_DIR:
+	return "[dir]";
+    case DT_BLK:
+	return "[blk]";
+    case DT_UNKNOWN:
+    case DT_REG:
+	return "";
+    case DT_LNK:
+	return "[lnk]";
+    case DT_SOCK:
+	return "[sck]";
+    case DT_WHT:
+	return "[wht]";
+    default:
+	return "[???]";
+    }
+}
+
+static void free_dirents(struct dirent **dex, size_t n_de)
+{
+    size_t i;
+
+    for (i = 0; i < n_de; i++)
+	free(dex[i]);
+
+    free(dex);
+}
+
+static int compare_dirent(const void *p_de1, const void *p_de2)
+{
+    const struct dirent *de1 = *(const struct dirent **)p_de1;
+    const struct dirent *de2 = *(const struct dirent **)p_de2;
+    int ndir1, ndir2;
+
+    ndir1 = de1->d_type != DT_DIR;
+    ndir2 = de2->d_type != DT_DIR;
+
+    if (ndir1 != ndir2)
+	return ndir1 - ndir2;
+
+    return strcmp(de1->d_name, de2->d_name);
+}
+
+static int display_directory(const char *dirname)
+{
+    DIR *dir;
+    struct dirent *de;
+    struct dirent **dex = NULL;
+    size_t n_dex = 0, n_de = 0;
+    size_t i, j, k;
+    size_t nrows, ncols, perpage;
+    size_t endpage;
+    int maxlen = 0;
+    int pos, tpos, colwidth;
+
+    dir = opendir(dirname);
+    if (!dir) {
+	printf("Unable to read directory: %s\n", dirname);
+	return -1;
+    }
+
+    while ((de = readdir(dir)) != NULL) {
+	struct dirent *nde;
+
+	if (n_de >= n_dex) {
+	    struct dirent **ndex;
+
+	    ndex = realloc(dex, (n_dex + DIR_CHUNK) * sizeof *dex);
+	    if (!ndex)
+		goto nomem;
+
+	    dex = ndex;
+	    n_dex += DIR_CHUNK;
+	}
+
+	nde = malloc(de->d_reclen);
+	if (!nde)
+	    goto nomem;
+
+	memcpy(nde, de, de->d_reclen);
+	dex[n_de++] = nde;
+
+	maxlen = max(maxlen, de->d_reclen);
+    }
+
+    closedir(dir);
+
+    qsort(dex, n_de, sizeof *dex, compare_dirent);
+
+    maxlen -= offsetof(struct dirent, d_name) + 1;
+    ncols = (cols + 2)/(maxlen + 8);
+    ncols = min(ncols, n_de);
+    ncols = max(ncols, 1U);
+    colwidth = (cols + 2)/ncols;
+    perpage = ncols * (rows - 1);
+
+    for (i = 0; i < n_de; i += perpage) {
+	/* Rows on this page */
+	endpage = min(i+perpage, n_de);
+	nrows = ((endpage-i) + ncols - 1)/ncols;
+
+	for (j = 0; j < nrows; j++) {
+	    pos = tpos = 0;
+	    for (k = i+j; k < endpage; k += nrows) {
+		pos += printf("%*s%-5s %s",
+			      (tpos - pos), "",
+			      type_str(dex[k]->d_type),
+			      dex[k]->d_name);
+		tpos += colwidth;
+	    }
+	    printf("\n");
+	}
+
+	if (endpage >= n_de)
+	    break;
+
+	get_key(stdin, 0);
+    }
+
+    free_dirents(dex, n_de);
+    return 0;
+
+nomem:
+    closedir(dir);
+    printf("Out of memory error!\n");
+    free_dirents(dex, n_de);
+    return -1;
+}
+
+int main(int argc, char *argv[])
+{
+    int rv;
+
+    if (getscreensize(1, &rows, &cols)) {
+	/* Unknown screen size? */
+	rows = 24;
+	cols = 80;
+    }
+
+    if (argc < 2)
+	rv = display_directory(".");
+    else if (argc == 2)
+	rv = display_directory(argv[1]);
+    else {
+	printf("Usage: %s directory\n", argv[0]);
+	rv = 1;
+    }
+
+    return rv ? 1 : 0;
+}
+ 
Index: bootcd/isolinux/syslinux-6.03/com32/modules/meminfo.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/meminfo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/meminfo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,132 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * meminfo.c
+ *
+ * Dump the memory map of the system
+ */
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <console.h>
+#include <com32.h>
+
+struct e820_data {
+    uint64_t base;
+    uint64_t len;
+    uint32_t type;
+    uint32_t extattr;
+} __attribute__ ((packed));
+
+static const char *const e820_types[] = {
+    "usable",
+    "reserved",
+    "ACPI reclaim",
+    "ACPI NVS",
+    "unusable",
+};
+
+static void dump_e820(void)
+{
+    com32sys_t ireg, oreg;
+    struct e820_data ed;
+    uint32_t type;
+    void *low_ed;
+
+    low_ed = lmalloc(sizeof ed);
+    if (!low_ed)
+	return;
+
+    memset(&ireg, 0, sizeof ireg);
+
+    ireg.eax.w[0] = 0xe820;
+    ireg.edx.l = 0x534d4150;
+    ireg.ecx.l = sizeof(struct e820_data);
+    ireg.edi.w[0] = OFFS(low_ed);
+    ireg.es = SEG(low_ed);
+
+    memset(&ed, 0, sizeof ed);
+    ed.extattr = 1;
+
+    do {
+	memcpy(low_ed, &ed, sizeof ed);
+
+	__intcall(0x15, &ireg, &oreg);
+	if (oreg.eflags.l & EFLAGS_CF ||
+	    oreg.eax.l != 0x534d4150 || oreg.ecx.l < 20)
+	    break;
+
+	memcpy(&ed, low_ed, sizeof ed);
+
+	if (oreg.ecx.l >= 24) {
+	    /* ebx base length end type */
+	    printf("%8x %016llx %016llx %016llx %d [%x]",
+		   ireg.ebx.l, ed.base, ed.len, ed.base + ed.len, ed.type,
+		   ed.extattr);
+	} else {
+	    /* ebx base length end */
+	    printf("%8x %016llx %016llx %016llx %d [-]",
+		   ireg.ebx.l, ed.base, ed.len, ed.base + ed.len, ed.type);
+	    ed.extattr = 1;
+	}
+
+	type = ed.type - 1;
+	if (type < sizeof(e820_types) / sizeof(e820_types[0]))
+	    printf(" %s", e820_types[type]);
+
+	putchar('\n');
+
+	ireg.ebx.l = oreg.ebx.l;
+    } while (ireg.ebx.l);
+
+    lfree(low_ed);
+}
+
+static void dump_legacy(void)
+{
+    com32sys_t ireg, oreg;
+    uint16_t dosram = *(uint16_t *) 0x413;
+    struct {
+	uint16_t offs, seg;
+    } *const ivt = (void *)0;
+
+    memset(&ireg, 0, sizeof ireg);
+
+    __intcall(0x12, &ireg, &oreg);
+
+    printf
+	("INT 15h = %04x:%04x  DOS RAM: %dK (0x%05x)  INT 12h: %dK (0x%05x)\n",
+	 ivt[0x15].seg, ivt[0x15].offs, dosram, dosram << 10, oreg.eax.w[0],
+	 oreg.eax.w[0] << 10);
+
+    memset(&ireg, 0, sizeof ireg);
+    ireg.eax.b[1] = 0x88;
+    __intcall(0x15, &ireg, &oreg);
+
+    printf("INT 15 88: 0x%04x (%uK)  ", oreg.eax.w[0], oreg.eax.w[0]);
+
+    memset(&ireg, 0, sizeof ireg);
+    ireg.eax.w[0] = 0xe801;
+    __intcall(0x15, &ireg, &oreg);
+
+    printf("INT 15 E801: 0x%04x (%uK) 0x%04x (%uK)\n",
+	   oreg.ecx.w[0], oreg.ecx.w[0], oreg.edx.w[0], oreg.edx.w[0] << 6);
+}
+
+int main(int argc __unused, char **argv __unused)
+{
+    dump_legacy();
+    dump_e820();
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/pcitest.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/pcitest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/pcitest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,151 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2006 Erwan Velu - 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.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+/*
+ * pcitest.c
+ *
+ */
+
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <console.h>
+#include <com32.h>
+#include <sys/pci.h>
+#include <stdbool.h>
+#include <dprintf.h>
+
+char display_line = 0;
+#define moreprintf(...)				\
+  do {						\
+    display_line++;				\
+    if (display_line == 24) {			\
+      char tempbuf[10];				\
+      display_line=0;				\
+      printf("Press Enter to continue\n");	\
+      fgets(tempbuf, sizeof tempbuf, stdin);	\
+    }						\
+    printf ( __VA_ARGS__);			\
+  } while (0);
+
+void display_pci_devices(struct pci_domain *pci_domain)
+{
+    struct pci_device *pci_device;
+    char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+
+    for_each_pci_func(pci_device, pci_domain) {
+
+	memset(kernel_modules, 0, sizeof kernel_modules);
+
+/*	printf("PCI: found %d kernel modules for  %04x:%04x[%04x:%04x]\n",
+		  pci_device->dev_info->linux_kernel_module_count,
+		  pci_device->vendor, pci_device->product,
+		  pci_device->sub_vendor, pci_device->sub_product);
+*/
+	for (int i = 0; i < pci_device->dev_info->linux_kernel_module_count;
+	     i++) {
+	    if (i > 0) {
+		strncat(kernel_modules, " | ", 3);
+	    }
+	    strncat(kernel_modules,
+		    pci_device->dev_info->linux_kernel_module[i],
+		    LINUX_KERNEL_MODULE_SIZE - 1);
+	}
+
+	moreprintf("%04x:%04x[%04x:%04x]: %s\n",
+		   pci_device->vendor, pci_device->product,
+		   pci_device->sub_vendor, pci_device->sub_product,
+		   pci_device->dev_info->class_name);
+
+	moreprintf(" Vendor Name      : %s\n",
+		   pci_device->dev_info->vendor_name);
+	moreprintf(" Product Name     : %s\n",
+		   pci_device->dev_info->product_name);
+	moreprintf(" PCI bus position : %02x:%02x.%01x\n", __pci_bus,
+		   __pci_slot, __pci_func);
+	moreprintf(" Kernel modules   : %s\n\n", kernel_modules);
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    struct pci_domain *pci_domain;
+    int return_code = 0;
+    int nb_pci_devices = 0;
+
+    (void)argc;
+    (void)argv;
+
+    /* Scanning to detect pci buses and devices */
+    printf("PCI: Scanning PCI BUS\n");
+    pci_domain = pci_scan();
+    if (!pci_domain) {
+	printf("PCI: no devices found!\n");
+	return 1;
+    }
+
+    struct pci_device *pci_device;
+    for_each_pci_func(pci_device, pci_domain) {
+	nb_pci_devices++;
+    }
+
+    printf("PCI: %d PCI devices found\n", nb_pci_devices);
+
+    printf("PCI: Looking for device name\n");
+    /* Assigning product & vendor name for each device */
+    return_code = get_name_from_pci_ids(pci_domain, "pci.ids");
+    if (return_code == -ENOPCIIDS) {
+	printf("PCI: ERROR !\n");
+	printf("PCI: Unable to open pci.ids file in current directory.\n");
+	printf("PCI: PCI Device names can't be computed.\n");
+    }
+
+    printf("PCI: Resolving class names\n");
+    /* Assigning class name for each device */
+    return_code = get_class_name_from_pci_ids(pci_domain, "pci.ids");
+    if (return_code == -ENOPCIIDS) {
+	printf("PCI: ERROR !\n");
+	printf("PCI: Unable to open pci.ids file in current directory.\n");
+	printf("PCI: PCI class names can't be computed.\n");
+    }
+
+    printf("PCI: Looking for Kernel modules\n");
+    /* Detecting which kernel module should match each device */
+    return_code = get_module_name_from_pcimap(pci_domain, "modules.pcimap");
+    if (return_code == -ENOMODULESPCIMAP) {
+	printf("PCI: ERROR !\n");
+	printf("PCI: Unable to open modules.pcimap file in current directory.\n");
+	printf("PCI: Kernel Module names can't be computed.\n");
+    }
+
+    /* display the pci devices we found */
+    display_pci_devices(pci_domain);
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/pmload.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/pmload.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/pmload.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,216 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * pmload.c
+ *
+ * Load a binary file and run it in protected mode.  We give it
+ * an ELF-style invocation record, becase, why not?
+ *
+ * Usage: pmload.c32 filename address [arguments...]
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <elf.h>
+#include <console.h>
+#include <dprintf.h>
+
+#include <syslinux/loadfile.h>
+#include <syslinux/movebits.h>
+#include <syslinux/bootpm.h>
+
+/* If we don't have this much memory for the stack, signal failure */
+#define MIN_STACK	512
+
+static inline void error(const char *msg)
+{
+    fputs(msg, stderr);
+}
+
+int boot_raw(void *ptr, size_t len, addr_t where, char **argv)
+{
+    struct syslinux_movelist *ml = NULL;
+    struct syslinux_memmap *mmap = NULL, *amap = NULL;
+    struct syslinux_pm_regs regs;
+    int argc;
+    addr_t argsize;
+    char **argp;
+    addr_t lstart, llen;
+    char *stack_frame = NULL;
+    addr_t stack_frame_size;
+    addr_t stack_pointer;
+    uint32_t *spp;
+    char *sfp;
+    addr_t sfa;
+
+    memset(&regs, 0, sizeof regs);
+
+    mmap = syslinux_memory_map();
+    amap = syslinux_dup_memmap(mmap);
+    if (!mmap || !amap)
+	goto bail;
+
+    dprintf("Initial memory map:\n");
+    syslinux_dump_memmap(mmap);
+
+    dprintf("Segment at 0x%08x len 0x%08x\n", where, len);
+
+    if (syslinux_memmap_type(amap, where, len) != SMT_FREE) {
+	printf("Memory segment at 0x%08x (len 0x%08x) is unavailable\n",
+	       where, len);
+	goto bail;		/* Memory region unavailable */
+    }
+
+    /* Mark this region as allocated in the available map */
+    if (syslinux_add_memmap(&amap, where, len, SMT_ALLOC))
+	goto bail;
+
+    /* Data present region.  Create a move entry for it. */
+    if (syslinux_add_movelist(&ml, where, (addr_t) ptr, len))
+	goto bail;
+
+    /* Create the invocation record (initial stack frame) */
+
+    argsize = argc = 0;
+    for (argp = argv; *argp; argp++) {
+	dprintf("argv[%2d] = \"%s\"\n", argc, *argp);
+	argc++;
+	argsize += strlen(*argp) + 1;
+    }
+
+    /* We need the argument strings, argument pointers,
+       argc, plus four zero-word terminators. */
+    stack_frame_size = argsize + argc * sizeof(char *) + 5 * sizeof(long);
+    stack_frame_size = (stack_frame_size + 15) & ~15;
+    stack_frame = calloc(stack_frame_size, 1);
+    if (!stack_frame)
+	goto bail;
+
+    dprintf("Right before syslinux_memmap_largest()...\n");
+    syslinux_dump_memmap(amap);
+
+    if (syslinux_memmap_largest(amap, SMT_FREE, &lstart, &llen))
+	goto bail;		/* NO free memory?! */
+
+    if (llen < stack_frame_size + MIN_STACK + 16)
+	goto bail;		/* Insufficient memory  */
+
+    /* Initial stack pointer address */
+    stack_pointer = (lstart + llen - stack_frame_size) & ~15;
+
+    dprintf("Stack frame at 0x%08x len 0x%08x\n",
+	    stack_pointer, stack_frame_size);
+
+    /* Create the stack frame.  sfp is the pointer in current memory for
+       the next argument string, sfa is the address in its final resting place.
+       spp is the pointer into the argument array in current memory. */
+    spp = (uint32_t *) stack_frame;
+    sfp = stack_frame + argc * sizeof(char *) + 5 * sizeof(long);
+    sfa = stack_pointer + argc * sizeof(char *) + 5 * sizeof(long);
+
+    *spp++ = argc;
+    for (argp = argv; *argp; argp++) {
+	int bytes = strlen(*argp) + 1;	/* Including final null */
+	*spp++ = sfa;
+	memcpy(sfp, *argp, bytes);
+	sfp += bytes;
+	sfa += bytes;
+    }
+    /* Zero fields are aready taken care of by calloc() */
+
+    /* ... and we'll want to move it into the right place... */
+#if DEBUG
+    if (syslinux_memmap_type(amap, stack_pointer, stack_frame_size)
+	!= SMT_FREE) {
+	dprintf("Stack frame area not free (how did that happen?)!\n");
+	goto bail;		/* Memory region unavailable */
+    }
+#endif
+
+    if (syslinux_add_memmap(&amap, stack_pointer, stack_frame_size, SMT_ALLOC))
+	goto bail;
+
+    if (syslinux_add_movelist(&ml, stack_pointer, (addr_t) stack_frame,
+			      stack_frame_size))
+	goto bail;
+
+    memset(&regs, 0, sizeof regs);
+    regs.eip = where;
+    regs.esp = stack_pointer;
+
+    dprintf("Final memory map:\n");
+    syslinux_dump_memmap(mmap);
+
+    dprintf("Final available map:\n");
+    syslinux_dump_memmap(amap);
+
+    dprintf("Movelist:\n");
+    syslinux_dump_movelist(ml);
+
+    /* This should not return... */
+    fputs("Booting...\n", stdout);
+    syslinux_shuffle_boot_pm(ml, mmap, 0, &regs);
+
+bail:
+    if (stack_frame)
+	free(stack_frame);
+    syslinux_free_memmap(amap);
+    syslinux_free_memmap(mmap);
+    syslinux_free_movelist(ml);
+
+    return -1;
+}
+
+int main(int argc, char *argv[])
+{
+    void *data;
+    size_t data_len;
+    addr_t where;
+
+    if (argc < 3) {
+	error("Usage: pmload.c32 bin_file address arguments...\n");
+	return 1;
+    }
+
+    where = strtoul(argv[2], NULL, 0);
+
+    if (loadfile(argv[1], &data, &data_len)) {
+	error("Unable to load file\n");
+	return 1;
+    }
+
+    boot_raw(data, data_len, where, &argv[1]);
+    error("Failed to boot, probably insufficient memory\n");
+    return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/poweroff.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/poweroff.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/poweroff.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,91 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2013 Sebastian Herbszt - 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * poweroff.c
+ *
+ * APM poweroff module
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <com32.h>
+
+int main(int argc __unused, char *argv[] __unused)
+{
+	com32sys_t inregs, outregs;
+
+	memset(&inregs, 0, sizeof inregs);
+
+	inregs.eax.l = 0x5300; /* APM Installation Check (00h) */
+	inregs.ebx.l = 0; /* APM BIOS (0000h) */
+	__intcall(0x15, &inregs, &outregs);
+
+	if (outregs.eflags.l & EFLAGS_CF) {
+		printf("APM not present.\n");
+		return 1;
+	}
+
+	if ((outregs.ebx.l & 0xffff) != 0x504d) { /* signature 'PM' */
+		printf("APM not present.\n");
+		return 1;
+	}
+
+	if ((outregs.eax.l & 0xffff) < 0x101) { /* Need version 1.1+ */
+		printf("APM 1.1+ not supported.\n");
+		return 1;
+	}
+
+	if ((outregs.ecx.l & 0x8) == 0x8) { /* bit 3 APM BIOS Power Management disabled */
+		printf("Power management disabled.\n");
+		return 1;
+	}
+
+	memset(&inregs, 0, sizeof inregs);
+	inregs.eax.l = 0x5301; /* APM Real Mode Interface Connect (01h) */
+	inregs.ebx.l = 0; /* APM BIOS (0000h) */
+	__intcall(0x15, &inregs, &outregs);
+
+	if (outregs.eflags.l & EFLAGS_CF) {
+		printf("APM RM interface connect failed.\n");
+		return 1;
+	}
+
+	memset(&inregs, 0, sizeof inregs);
+	inregs.eax.l = 0x530e; /* APM Driver Version (0Eh) */
+	inregs.ebx.l = 0; /* APM BIOS (0000h) */
+	inregs.ecx.l = 0x101; /* APM Driver version 1.1 */
+	__intcall(0x15, &inregs, &outregs);
+
+	if (outregs.eflags.l & EFLAGS_CF) {
+		printf("APM 1.1+ not supported.\n");
+		return 1;
+	}
+
+	if ((outregs.ecx.l & 0xffff) < 0x101) { /* APM Connection version */
+		printf("APM 1.1+ not supported.\n");
+		return 1;
+	}
+
+	memset(&inregs, 0, sizeof inregs);
+	inregs.eax.l = 0x5307; /* Set Power State (07h) */
+	inregs.ebx.l = 1; /* All devices power managed by the APM BIOS */
+	inregs.ecx.l = 3; /* Power state off */
+	__intcall(0x15, &inregs, &outregs);
+
+	if (outregs.eflags.l & EFLAGS_CF) {
+		printf("Power off failed.\n");
+		return 1;
+	}
+
+	return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/prdhcp.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/prdhcp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/prdhcp.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,164 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010-2011 Gene Cumm - All Rights Reserved
+ *
+ *   Portions from chain.c:
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *   Significant portions copyright (C) 2010 Shao Miller
+ *					[partition iteration, GPT, "fs"]
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * prdhcp.c
+ *
+ * Print the contents of the 3 DHCP packets
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <consoles.h>
+#include <console.h>
+#include <errno.h>
+#include <string.h>
+#include <syslinux/config.h>
+#include <syslinux/loadfile.h>
+#include <syslinux/bootrm.h>
+#include <syslinux/video.h>
+#include <com32.h>
+#include <stdint.h>
+#include <syslinux/pxe.h>
+#include <sys/gpxe.h>
+#include <unistd.h>
+#include <getkey.h>
+
+#define PRDHCP_DEBUG 0
+
+#define dprintf0(f, ...)		((void)0)
+
+#ifdef PRDHCP_DEBUG
+#  define dpressanykey			pressanykey
+#  define dprintf			printf
+#  define dprint_pxe_bootp_t		print_pxe_bootp_t
+#  define dprint_pxe_vendor_blk		print_pxe_vendor_blk
+#  define dprint_pxe_vendor_raw		print_pxe_vendor_raw
+#else
+#  define dpressanykey(void)		((void)0)
+#  define dprintf(f, ...)		((void)0)
+#  define dprint_pxe_bootp_t(p, l)	((void)0)
+#  define dprint_pxe_vendor_blk(p, l)	((void)0)
+#  define dprint_pxe_vendor_raw(p, l)	((void)0)
+#endif
+
+#define dprintf_opt_cp	dprintf0
+#define dprintf_opt_inj	dprintf
+
+
+const char app_name_str[] = "prdhcp.c32";
+
+
+int pressanykey(void) {
+    int inc;
+
+    printf("Press any key to continue. ");
+    inc = KEY_NONE;
+    while (inc == KEY_NONE)
+	inc = get_key(stdin, 6000);
+    puts("");
+    return inc;
+}
+
+void print_pxe_vendor_blk(pxe_bootp_t *p, size_t len)
+{
+    int i, vlen, oplen, j;
+    uint8_t *d;
+    uint32_t magic;
+    if (!p) {
+	printf("  packet pointer is null\n");
+	return;
+    }
+    vlen = len - ((void *)&(p->vendor) - (void *)p);
+    printf("  Vendor Data:    Len=%d", vlen);
+    d = p->vendor.d;
+    /* Print only 256 characters of the vendor/option data */
+    /*
+    print_pxe_vendor_raw(p, (len - vlen) + 256);
+    vlen = 0;
+    */
+    magic = ntohl(*((uint32_t *)d));
+    printf("    Magic: %08X", ntohl(*((uint32_t *)d)));
+    if (magic != VM_RFC1048)	/* Invalid DHCP packet */
+	vlen = 0;
+    for (i = 4; i < vlen; i++) {
+	if (d[i])	/* Skip the padding */
+	    printf("\n    @%03X-%3d", i, d[i]);
+	if (d[i] == 255)	/* End of list */
+	    break;
+	if (d[i]) {
+	    oplen = d[++i];
+	    printf(" l=%3d:", oplen);
+	    for (j = (++i + oplen); i < vlen && i < j; i++) {
+		printf(" %02X", d[i]);
+	    }
+	    i--;
+	}
+    }
+    printf("\n");
+}
+
+void print_pxe_bootp_t(pxe_bootp_t *p, size_t len)
+{
+    if (!p) {
+	printf("  packet pointer is null\n");
+	return;
+    }
+    printf("  op:%02X  hw:%02X  hl:%02X  gh:%02X  id:%08X se:%04X f:%04X"
+	"  cip:%08X\n", p->opcode, p->Hardware, p->Hardlen, p->Gatehops,
+	ntohl(p->ident), ntohs(p->seconds), ntohs(p->Flags), ntohl(p->cip));
+    printf("  yip:%08X  sip:%08X  gip:%08X",
+	ntohl(p->yip), ntohl(p->sip), ntohl(p->gip));
+    printf("  caddr-%02X:%02X:%02X:%02X:%02X:%02X\n", p->CAddr[0],
+	p->CAddr[1], p->CAddr[2], p->CAddr[3], p->CAddr[4], p->CAddr[5]);
+    printf("  sName: '%s'\n", p->Sname);
+    printf("  bootfile: '%s'\n", p->bootfile);
+    print_pxe_vendor_blk(p, len);
+}
+
+void print_dhcp_pkt_all(void)
+{
+    pxe_bootp_t *p;
+    size_t len;
+    int i;
+    int ptype[3] = {PXENV_PACKET_TYPE_DHCP_DISCOVER, PXENV_PACKET_TYPE_DHCP_ACK, PXENV_PACKET_TYPE_CACHED_REPLY};
+
+    for (i = 0; i < 3; i++) {
+	if (!pxe_get_cached_info(ptype[i],
+		(void **)&(p), &(len))) {
+	    dprintf("Got packet #%d/%d\n", (i + 1), ptype[i]);
+	    print_pxe_bootp_t(p, len);
+	    pressanykey();
+	}
+    }
+}
+
+int main(void)
+{
+    int rv= -1;
+    const struct syslinux_version *sv;
+
+    console_ansi_raw();
+    sv = syslinux_version();
+    if (sv->filesystem != SYSLINUX_FS_PXELINUX) {
+	printf("%s: May only run in PXELINUX\n", app_name_str);
+	return -2;
+    }
+    print_dhcp_pkt_all();
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/pwd.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/pwd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/pwd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,50 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010 Gene Cumm - 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * Display present (current) working directory
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <console.h>
+#include <unistd.h>
+#include <dirent.h>
+
+/* Size of path buffer string */
+#ifndef PATH_MAX
+#  ifdef NAME_MAX
+#    define PATH_MAX   NAME_MAX
+#  elif FILENAME_MAX
+#    define PATH_MAX   FILENAME_MAX
+#  else
+#    define PATH_MAX   256
+#  endif       /* NAME_MAX */
+#endif /* PATH_MAX */
+
+int main(void)
+{
+    int rv = 0;
+    char pwd[PATH_MAX], *pwdptr;
+
+    pwdptr = getcwd(pwd, PATH_MAX);
+    if (pwdptr) {
+       if (pwd[0] != 0)
+           puts(pwd);
+       else
+           puts(".");
+    } else {
+       rv = errno;
+       puts("ERROR: getcwd() returned NULL");
+    }
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/pxechn.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/pxechn.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/pxechn.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1148 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010-2012 Gene Cumm - All Rights Reserved
+ *
+ *   Portions from chain.c:
+ *   Copyright 2003-2009 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin
+ *   Significant portions copyright (C) 2010 Shao Miller
+ *					[partition iteration, GPT, "fs"]
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * pxechn.c
+ *
+ * PXE Chain Loader; Chain load to another PXE network boot program
+ * that may be on another host.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <consoles.h>
+#include <console.h>
+#include <errno.h>
+#include <string.h>
+#include <syslinux/config.h>
+#include <syslinux/loadfile.h>
+#include <syslinux/bootrm.h>
+#include <syslinux/video.h>
+#include <com32.h>
+#include <stdint.h>
+#include <syslinux/pxe.h>
+#include <sys/gpxe.h>
+#include <unistd.h>
+#include <getkey.h>
+#include <dhcp.h>
+#include <limits.h>
+
+
+#ifdef DEBUG
+#  define PXECHN_DEBUG 1
+#else
+#  define PXECHN_DEBUG 0
+#endif
+
+typedef union {
+    uint64_t q;
+    uint32_t l[2];
+    uint16_t w[4];
+    uint8_t b[8];
+} reg64_t;
+
+#define dprintf0(f, ...)		((void)0)
+
+#ifndef dprintf
+#  if (PXECHN_DEBUG > 0)
+#    define dprintf			printf
+#  else
+#    define dprintf(f, ...)		((void)0)
+#  endif
+#endif
+
+#if (PXECHN_DEBUG > 0)
+#  define dpressanykey			pressanykey
+#  define dprint_pxe_bootp_t		print_pxe_bootp_t
+#  define dprint_pxe_vendor_blk		print_pxe_vendor_blk
+#  define dprint_pxe_vendor_raw		print_pxe_vendor_raw
+#else
+#  define dpressanykey(tm)		((void)0)
+#  define dprint_pxe_bootp_t(p, l)	((void)0)
+#  define dprint_pxe_vendor_blk(p, l)	((void)0)
+#  define dprint_pxe_vendor_raw(p, l)	((void)0)
+#endif
+
+#define dprintf_opt_cp		dprintf0
+#define dprintf_opt_inj		dprintf0
+#define dprintf_pc_pa		dprintf
+#define dprintf_pc_so_s		dprintf0
+
+#define t_PXENV_RESTART_TFTP	t_PXENV_TFTP_READ_FILE
+
+#define STACK_SPLIT	11
+
+/* same as pxelinux.asm REBOOT_TIME */
+#define REBOOT_TIME	300
+
+#define NUM_DHCP_OPTS		256
+#define DHCP_OPT_LEN_MAX	256
+#define PXE_VENDOR_RAW_PRN_MAX	0x7F
+#define PXECHN_HOST_LEN		256	/* 63 bytes per label; 255 max total */
+
+#define PXECHN_NUM_PKT_TYPE	3
+#define PXECHN_NUM_PKT_AVAIL	2*PXECHN_NUM_PKT_TYPE
+#define PXECHN_PKT_TYPE_START	PXENV_PACKET_TYPE_DHCP_DISCOVER
+
+#define PXECHN_FORCE_PKT1	0x80000000
+#define PXECHN_FORCE_PKT2	0x40000000
+#define PXECHN_FORCE_ALL	(PXECHN_FORCE_PKT1 | PXECHN_FORCE_PKT2)
+#define PXECHN_FORCE_ALL_1	0
+#define STRASINT_str		('s' + (('t' + ('r' << 8)) << 8))
+
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+
+const char app_name_str[] = "pxechn.c32";
+
+struct pxelinux_opt {
+    char *fn;	/* Filename as passed to us */
+    in_addr_t fip;	/* fn's IP component */
+    char *fp;	/* fn's path component */
+    in_addr_t gip;	/* giaddr; Gateway/DHCP relay */
+    uint32_t force;
+    uint32_t wait;	/* Additional decision to wait before boot */
+    int32_t wds;	/* WDS option/level */
+    in_addr_t sip;	/* siaddr: Next Server IP Address */
+    struct dhcp_option p[PXECHN_NUM_PKT_AVAIL];
+	/* original _DHCP_DISCOVER, _DHCP_ACK, _CACHED_REPLY then modified packets */
+    char host[PXECHN_HOST_LEN];
+    struct dhcp_option opts[PXECHN_NUM_PKT_TYPE][NUM_DHCP_OPTS];
+    char p_unpacked[PXECHN_NUM_PKT_TYPE];
+};
+
+
+/* from chain.c */
+struct data_area {
+    void *data;
+    addr_t base;
+    addr_t size;
+};
+
+/* From chain.c */
+static inline void error(const char *msg)
+{
+    fputs(msg, stderr);
+}
+
+/* From chain.c */
+static void do_boot(struct data_area *data, int ndata,
+		    struct syslinux_rm_regs *regs)
+{
+    uint16_t *const bios_fbm = (uint16_t *) 0x413;
+    addr_t dosmem = *bios_fbm << 10;	/* Technically a low bound */
+    struct syslinux_memmap *mmap;
+    struct syslinux_movelist *mlist = NULL;
+    addr_t endimage;
+    int i;
+
+    mmap = syslinux_memory_map();
+
+    if (!mmap) {
+	error("Cannot read system memory map\n");
+	return;
+    }
+
+    endimage = 0;
+    for (i = 0; i < ndata; i++) {
+	if (data[i].base + data[i].size > endimage)
+	    endimage = data[i].base + data[i].size;
+    }
+    if (endimage > dosmem)
+	goto too_big;
+
+    for (i = 0; i < ndata; i++) {
+	if (syslinux_add_movelist(&mlist, data[i].base,
+				  (addr_t) data[i].data, data[i].size))
+	    goto enomem;
+    }
+
+
+    /* Tell the shuffler not to muck with this area... */
+    syslinux_add_memmap(&mmap, endimage, 0xa0000 - endimage, SMT_RESERVED);
+
+    /* Force text mode */
+    syslinux_force_text_mode();
+
+    fputs("Booting...\n", stdout);
+    syslinux_shuffle_boot_rm(mlist, mmap, 3, regs);
+    error("Chainboot failed!\n");
+    return;
+
+too_big:
+    error("Loader file too large\n");
+    return;
+
+enomem:
+    error("Out of memory\n");
+    return;
+}
+
+void usage(void)
+{
+    printf("USAGE:\n"
+        "    %s [OPTIONS]... _new-nbp_\n"
+	"    %s -r _new-nbp_    (calls PXE stack PXENV_RESTART_TFTP)\n"
+	"OPTIONS:\n"
+	"    [-c config] [-g gateway] [-p prefix] [-t reboot] [-u] [-w] [-W]"
+	" [-o opt.ty=val]\n\n",
+	app_name_str, app_name_str);
+}
+
+void pxe_error(int ierr, const char *evt, const char *msg)
+{
+    if (msg)
+	printf("%s", msg);
+    else if (evt)
+	printf("Error while %s: ", evt);
+    printf("%d:%s\n", ierr, strerror(ierr));
+}
+
+int pressanykey(clock_t tm) {
+    int inc;
+
+    printf("Press any key to continue. ");
+    inc = get_key(stdin, tm);
+    puts("");
+    return inc;
+}
+
+int dhcp_find_opt(pxe_bootp_t *p, size_t len, uint8_t opt)
+{
+    int rv = -1;
+    int i, vlen, oplen;
+    uint8_t *d;
+    uint32_t magic;
+
+    if (!p) {
+	dprintf("  packet pointer is null\n");
+	return rv;
+    }
+    vlen = len - ((void *)&(p->vendor) - (void *)p);
+    d = p->vendor.d;
+    magic = ntohl(*((uint32_t *)d));
+    if (magic != VM_RFC1048)	/* Invalid DHCP packet */
+	vlen = 0;
+    for (i = 4; i < vlen; i++) {
+	if (d[i] == opt) {
+	    dprintf("\n    @%03X-%2d\n", i, d[i]);
+	    rv = i;
+	    break;
+	}
+	if (d[i] == ((NUM_DHCP_OPTS) - 1))	/* End of list */
+	    break;
+	if (d[i]) {		/* Skip padding */
+	    oplen = d[++i];
+	    i += oplen;
+	}
+    }
+    return rv;
+}
+
+void print_pxe_vendor_raw(pxe_bootp_t *p, size_t len)
+{
+    int i, vlen;
+
+    if (!p) {
+	printf("  packet pointer is null\n");
+	return;
+    }
+    vlen = len - ((void *)&(p->vendor) - (void *)p);
+    if (vlen > PXE_VENDOR_RAW_PRN_MAX)
+	vlen = PXE_VENDOR_RAW_PRN_MAX;
+    dprintf("  rawLen = %d", vlen);
+    for (i = 0; i < vlen; i++) {
+	if ((i & 0xf) == 0)
+	    printf("\n  %04X:", i);
+	printf(" %02X", p->vendor.d[i]);
+    }
+    printf("\n");
+}
+
+void print_pxe_vendor_blk(pxe_bootp_t *p, size_t len)
+{
+    int i, vlen, oplen, j;
+    uint8_t *d;
+    uint32_t magic;
+    if (!p) {
+	printf("  packet pointer is null\n");
+	return;
+    }
+    vlen = len - ((void *)&(p->vendor) - (void *)p);
+    printf("  Vendor Data:    Len=%d", vlen);
+    d = p->vendor.d;
+    magic = ntohl(*((uint32_t *)d));
+    printf("    Magic: %08X", ntohl(*((uint32_t *)d)));
+    if (magic != VM_RFC1048)	/* Invalid DHCP packet */
+	vlen = 0;
+    for (i = 4; i < vlen; i++) {
+	if (d[i])	/* Skip the padding */
+	    printf("\n    @%03X-%3d", i, d[i]);
+	if (d[i] == ((NUM_DHCP_OPTS) - 1))	/* End of list */
+	    break;
+	if (d[i]) {
+	    oplen = d[++i];
+	    printf(" l=%3d:", oplen);
+	    for (j = (++i + oplen); i < vlen && i < j; i++) {
+		printf(" %02X", d[i]);
+	    }
+	    i--;
+	}
+    }
+    printf("\n");
+}
+
+void print_pxe_bootp_t(pxe_bootp_t *p, size_t len)
+{
+    if (!p || len <= 0) {
+	printf("  packet pointer is null\n");
+	return;
+    }
+    printf("  op:%02X  hw:%02X  hl:%02X  gh:%02X  id:%08X se:%04X f:%04X"
+	"  cip:%08X\n", p->opcode, p->Hardware, p->Hardlen, p->Gatehops,
+	ntohl(p->ident), ntohs(p->seconds), ntohs(p->Flags), ntohl(p->cip));
+    printf("  yip:%08X  sip:%08X  gip:%08X",
+	ntohl(p->yip), ntohl(p->sip), ntohl(p->gip));
+    printf("  caddr-%02X:%02X:%02X:%02X:%02X:%02X\n", p->CAddr[0],
+	p->CAddr[1], p->CAddr[2], p->CAddr[3], p->CAddr[4], p->CAddr[5]);
+    printf("  sName: '%s'\n", p->Sname);
+    printf("  bootfile: '%s'\n", p->bootfile);
+    dprint_pxe_vendor_blk(p, len);
+}
+
+void pxe_set_regs(struct syslinux_rm_regs *regs)
+{
+    const union syslinux_derivative_info *sdi;
+    const com32sys_t *pxe_regs;
+
+    sdi = syslinux_derivative_info();
+    pxe_regs = sdi->pxe.stack;	/* Original register values */
+
+    /* Just to be sure... */
+    memset(regs, 0, sizeof *regs);
+
+    regs->ip = 0x7C00;
+
+    /* Point to the original stack */
+    regs->ss    = sdi->pxe.stack_seg;
+    regs->esp.l = sdi->pxe.stack_offs + sizeof(com32sys_t);
+
+    /* Point to the PXENV+ address */
+    regs->es    = pxe_regs->es;
+    regs->ebx.l = pxe_regs->ebx.l;
+
+    dprintf("\nsp:%04x    ss:%04x    es:%04x    bx:%04x\n", regs->esp.w[0],
+	regs->ss, regs->es, regs->ebx.w[0]);
+}
+
+int hostlen_limit(int len)
+{
+    return min(len, ((PXECHN_HOST_LEN) - 1));
+}
+
+//FIXME: To a library
+/* Parse a filename into an IPv4 address and filename pointer
+ *	returns	Based on the interpretation of fn
+ *		0 regular file name
+ *		1 in format IP::FN
+ *		2 TFTP URL
+ *		3 HTTP URL
+ *		4 FTP URL
+ *		3 + 2^30 HTTPS URL
+ *		-1 if fn is another URL type
+ */
+int pxechn_parse_fn(char fn[], in_addr_t *fip, char *host, char *fp[])
+{
+    in_addr_t tip = 0;
+    char *csep, *ssep, *hsep;	/* Colon, Slash separator positions */
+    int hlen, plen;	/* Hostname, protocol length */
+    int rv = 0;
+
+    csep = strchr(fn, ':');
+    if (csep) {
+	if (csep[1] == ':') {	/* assume IP::FN */
+	    *fp = &csep[2];
+	    rv = 1;
+	    if (fn[0] != ':') {
+		hlen = hostlen_limit(csep - fn);
+		memcpy(host, fn, hlen);
+		host[hlen] = 0;
+	    }
+	} else if ((csep[1] == '/') && (csep[2] == '/')) {
+		/* URL: proto://host:port/path/file */
+		/* proto://[user[:passwd]@]host[:port]/path/file */
+	    ssep = strchr(csep + 3, '/');
+	    if (ssep) {
+		hlen = hostlen_limit(ssep - (csep + 3));
+		*fp = ssep + 1;
+	    } else {
+		hlen = hostlen_limit(strlen(csep + 3));
+	    }
+	    memcpy(host, (csep + 3), hlen);
+	    host[hlen] = 0;
+	    plen = csep - fn;
+	    if (strncmp(fn, "tftp", plen) == 0)
+		rv = 2;
+	    else if (strncmp(fn, "http", plen) == 0)
+		rv = 3;
+	    else if (strncmp(fn, "ftp", plen) == 0)
+		rv = 4;
+	    else if (strncmp(fn, "https", plen) == 0)
+		rv = 3 + ( 1 << 30 );
+	    else
+		rv = -1;
+	} else {
+	    csep = NULL;
+	}
+    }
+    if (!csep) {
+	*fp = fn;
+    }
+    if (host[0]) {
+	hsep = strchr(host, '@');
+	if (!hsep)
+	    hsep = host;
+	tip = pxe_dns(hsep);
+    }
+    if (tip != 0)
+	*fip = tip;
+    dprintf0("  host '%s'\n  fp   '%s'\n  fip  %08x\n", host, *fp, ntohl(*fip));
+    return rv;
+}
+
+void pxechn_opt_free(struct dhcp_option *opt)
+{
+    free(opt->data);
+    opt->len = -1;
+}
+
+void pxechn_fill_pkt(struct pxelinux_opt *pxe, int ptype)
+{
+    int rv = -1;
+    int p1, p2;
+    if ((ptype < 0) || (ptype > PXECHN_NUM_PKT_TYPE))
+	rv = -2;
+    p1 = ptype - PXECHN_PKT_TYPE_START;
+    p2 = p1 + PXECHN_NUM_PKT_TYPE;
+    if ((rv >= -1) && (!pxe_get_cached_info(ptype,
+	    (void **)&(pxe->p[p1].data), (size_t *)&(pxe->p[p1].len)))) {
+	pxe->p[p2].data = malloc(2048);
+	if (pxe->p[p2].data) {
+	    memcpy(pxe->p[p2].data, pxe->p[p1].data, pxe->p[p1].len);
+	    pxe->p[p2].len = pxe->p[p1].len;
+	    rv = 0;
+	    dprint_pxe_bootp_t((pxe_bootp_t *)(pxe->p[p1].data), pxe->p[p1].len);
+	    dpressanykey(INT_MAX);
+	} else {
+	    printf("%s: ERROR: Unable to malloc() for second packet\n", app_name_str);
+	}
+    } else {
+	printf("%s: ERROR: Unable to retrieve first packet\n", app_name_str);
+    }
+    if (rv <= -1) {
+	pxechn_opt_free(&pxe->p[p1]);
+    }
+}
+
+void pxechn_init(struct pxelinux_opt *pxe)
+{
+    /* Init for paranoia */
+    pxe->fn = NULL;
+    pxe->fp = NULL;
+    pxe->force = 0;
+    pxe->wait = 0;
+    pxe->gip = 0;
+    pxe->wds = 0;
+    pxe->sip = 0;
+    pxe->host[0] = 0;
+    pxe->host[((NUM_DHCP_OPTS) - 1)] = 0;
+    for (int j = 0; j < PXECHN_NUM_PKT_TYPE; j++){
+	for (int i = 0; i < NUM_DHCP_OPTS; i++) {
+	    pxe->opts[j][i].data = NULL;
+	    pxe->opts[j][i].len = -1;
+	}
+	pxe->p_unpacked[j] = 0;
+	pxe->p[j].data = NULL;
+	pxe->p[j+PXECHN_NUM_PKT_TYPE].data = NULL;
+	pxe->p[j].len = 0;
+	pxe->p[j+PXECHN_NUM_PKT_TYPE].len = 0;
+    }
+    pxechn_fill_pkt(pxe, PXENV_PACKET_TYPE_CACHED_REPLY);
+}
+
+int pxechn_to_hex(char i)
+{
+    if (i >= '0' && i <= '9')
+	return (i - '0');
+    if (i >= 'A' && i <= 'F')
+	return (i - 'A' + 10);
+    if (i >= 'a' && i <= 'f')
+	return (i - 'a' + 10);
+    if (i == 0)
+	return -1;
+    return -2;
+}
+
+int pxechn_parse_2bhex(char ins[])
+{
+    int ret = -2;
+    int n0 = -3, n1 = -3;
+    /* NULL pointer */
+    if (!ins) {
+	ret = -1;
+    /* pxechn_to_hex can handle the NULL character by returning -1 and
+       breaking the execution of the statement chain */
+    } else if (((n0 = pxechn_to_hex(ins[0])) >= 0)
+	    && ((n1 = pxechn_to_hex(ins[1])) >= 0)) {
+	ret = (n0 * 16) + n1;
+    } else if (n0 == -1) {	/* Leading NULL char */
+	ret = -1;
+    }
+    return ret;
+}
+
+int pxechn_optnum_ok(int optnum)
+{
+    if ((optnum > 0) && (optnum < ((NUM_DHCP_OPTS) - 1)))
+	return 1;
+    return 0;
+}
+
+int pxechn_optnum_ok_notres(int optnum)
+{
+    if ((optnum <= 0) && (optnum >= ((NUM_DHCP_OPTS) - 1)))
+	return 0;
+    switch(optnum){
+    case 66: case 67:
+	return 0;
+	break;
+    default:	return 1;
+    }
+}
+
+int pxechn_optlen_ok(int optlen)
+{
+    if ((optlen >= 0) && (optlen < ((DHCP_OPT_LEN_MAX) - 1)))
+	return 1;
+    return 0;
+}
+
+int pxechn_setopt(struct dhcp_option *opt, void *data, int len)
+{
+    void *p;
+    if (!opt || !data)
+	return -1;
+    if (len < 0) {
+	return -3;
+    }
+    p = realloc(opt->data, len);
+    if (!p && len) {	/* Allow for len=0 */
+	pxechn_opt_free(opt);
+	return -2;
+    }
+    opt->data = p;
+    memcpy(opt->data, data, len);
+    opt->len = len;
+    return len;
+}
+
+int pxechn_setopt_str(struct dhcp_option *opt, void *data)
+{
+    return pxechn_setopt(opt, data, strnlen(data, DHCP_OPT_LEN_MAX));
+}
+
+int pxechn_parse_int(char *data, char istr[], int tlen)
+{
+    int terr = errno;
+
+    if ((tlen == 1) || (tlen == 2) || (tlen == 4)) {
+	errno = 0;
+	uint32_t optval = strtoul(istr, NULL, 0);
+	if (errno)
+	    return -3;
+	errno = terr;
+	switch(tlen){
+	case  1:
+	    if (optval & 0xFFFFFF00)
+		return -4;
+	    break;
+	case  2:
+	    if (optval & 0xFFFF0000)
+		return -4;
+	    optval = htons(optval);
+	    break;
+	case  4:
+	    optval = htonl(optval);
+	    break;
+	}
+	memcpy(data, &optval, tlen);
+    } else if (tlen == 8) {
+	errno = 0;
+	uint64_t optval = strtoull(istr, NULL, 0);
+	if (errno)
+	    return -3;
+	errno = terr;
+	optval = htonq(optval);
+	memcpy(data, &optval, tlen);
+    } else {
+	return -2;
+    }
+    return tlen;
+}
+
+int pxechn_parse_hex_sep(char *data, char istr[], char sep)
+{
+    int len = 0;
+    int ipos = 0, ichar;
+    
+    if (!data || !istr)
+	return -1;
+    while ((istr[ipos]) && (len < DHCP_OPT_LEN_MAX)) {
+	dprintf(" %02X%02X", *((int *)(istr + ipos)) & 0xFF, *((int *)(istr + ipos +1)) & 0xFF);
+	ichar = pxechn_parse_2bhex(istr + ipos);
+	if (ichar >=0) {
+	    data[len++] = ichar;
+	} else {
+	    return -EINVAL;
+	}
+	if (!istr[ipos+2]){
+	    ipos += 2;
+	} else if (istr[ipos+2] != sep) {
+	    return -(EINVAL + 1);
+	} else {
+	    ipos += 3;
+	}
+    }
+    return len;
+}
+
+int pxechn_parse_opttype(char istr[], int optnum)
+{
+    char *pos;
+    int tlen, type, tmask;
+
+    if (!istr)
+	return -1;
+    pos = strchr(istr, '=');
+    if (!pos)
+	return -2;
+    if (istr[0] != '.') {
+	if (!pxechn_optnum_ok(optnum))
+	    return -3;
+	return -3;	/* do lookup here */
+    } else {
+	tlen = pos - istr - 1;
+	if ((tlen < 1) || (tlen > 4))
+	    return -4;
+	tmask = 0xFFFFFFFF >> (8 * (4 - tlen));
+	type = (*(int*)(istr + 1)) & tmask;
+    }
+    return type;
+}
+
+int pxechn_parse_setopt(struct dhcp_option opts[], struct dhcp_option *iopt,
+			char istr[])
+{
+    int rv = 0, optnum, opttype;
+    char *cpos = NULL, *pos;
+
+    if (!opts || !iopt || !(iopt->data))
+	return -1;
+    if (!istr || !istr[0])
+	return -2;
+    // -EINVAL;
+    optnum = strtoul(istr, &cpos, 0);
+    if (!pxechn_optnum_ok(optnum))
+	return -3;
+    pos = strchr(cpos, '=');
+    if (!pos)
+	return -4;
+    opttype = pxechn_parse_opttype(cpos, optnum);
+    pos++;
+    switch(opttype) {
+    case 'b':
+	iopt->len = pxechn_parse_int(iopt->data, pos, 1);
+	break;
+    case 'l':
+	iopt->len = pxechn_parse_int(iopt->data, pos, 4);
+	break;
+    case 'q':
+	iopt->len = pxechn_parse_int(iopt->data, pos, 8);
+	break;
+    case 's':
+    case STRASINT_str:
+	iopt->len = strlen(pos);
+	if (iopt->len > DHCP_OPT_LEN_MAX)
+	    iopt->len = DHCP_OPT_LEN_MAX;
+	memcpy(iopt->data, pos, iopt->len);
+	dprintf_pc_so_s("s.len=%d\trv=%d\n", iopt->len, rv);
+	break;
+    case 'w':
+	iopt->len = pxechn_parse_int(iopt->data, pos, 2);
+	break;
+    case 'x':
+	iopt->len = pxechn_parse_hex_sep(iopt->data, pos, ':');
+	break;
+    default:
+	return -6;
+	break;
+    }
+    if (pxechn_optlen_ok(iopt->len)) {
+	rv = pxechn_setopt(&(opts[optnum]), (void *)(iopt->data), iopt->len);
+    }
+    if((opttype == 's') || (opttype == STRASINT_str))
+	dprintf_pc_so_s("rv=%d\n", rv);
+    return rv;
+}
+
+int pxechn_parse_force(const char istr[])
+{
+    uint32_t rv = 0;
+    char *pos;
+    int terr = errno;
+
+    errno = 0;
+    rv = strtoul(istr, &pos, 0);
+    if ((istr == pos ) || ((rv == ULONG_MAX) && (errno)))
+	rv = 0;
+    errno = terr;
+    return rv;
+}
+
+int pxechn_uuid_set(struct pxelinux_opt *pxe)
+{
+    int ret = 0;
+
+    if (!pxe->p_unpacked[0])
+	ret = dhcp_unpack_packet((pxe_bootp_t *)(pxe->p[0].data),
+				 pxe->p[0].len, pxe->opts[0]);
+    if (ret) {
+	error("Could not unpack packet\n");
+	return -ret;	/* dhcp_unpack_packet always returns positive errors */
+    }
+
+    if (pxe->opts[0][97].len >= 0 )
+	pxechn_setopt(&(pxe->opts[2][97]), pxe->opts[0][97].data, pxe->opts[0][97].len);
+	return 1;
+    return 0;
+}
+
+int pxechn_parse_args(int argc, char *argv[], struct pxelinux_opt *pxe,
+			 struct dhcp_option opts[])
+{
+    int arg, optnum, rv = 0;
+    char *p = NULL;
+    const char optstr[] = "c:f:g:o:p:St:uwW";
+    struct dhcp_option iopt;
+
+    if (pxe->p[5].data)
+	pxe->fip = ( (pxe_bootp_t *)(pxe->p[5].data) )->sip;
+    else
+	pxe->fip = 0;
+    /* Fill */
+    pxe->fn = argv[0];
+    pxechn_parse_fn(pxe->fn, &(pxe->fip), pxe->host, &(pxe->fp));
+    pxechn_setopt_str(&(opts[67]), pxe->fp);
+    pxechn_setopt_str(&(opts[66]), pxe->host);
+    iopt.data = malloc(DHCP_OPT_LEN_MAX);
+    iopt.len = 0;
+    while ((rv >= 0) && (arg = getopt(argc, argv, optstr)) >= 0) {
+	dprintf_pc_pa("  Got arg '%c'/'%c' addr %08X val %s\n", arg == '?' ? optopt : arg, arg, (unsigned int)optarg, optarg ? optarg : "");
+	switch(arg) {
+	case 'c':	/* config */
+	    pxechn_setopt_str(&(opts[209]), optarg);
+	    break;
+	case 'f':	/* force */
+	    pxe->force = pxechn_parse_force(optarg);
+	    break;
+	case 'g':	/* gateway/DHCP relay */
+	    pxe->gip = pxe_dns(optarg);
+	    break;
+	case 'n':	/* native */
+	    break;
+	case 'o':	/* option */
+	    rv = pxechn_parse_setopt(opts, &iopt, optarg);
+	    break;
+	case 'p':	/* prefix */
+	    pxechn_setopt_str(&(opts[210]), optarg);
+	    break;
+	case 'S':	/* sip from sName */
+	    pxe->sip = 1;
+	    break;
+	case 't':	/* timeout */
+	    optnum = strtoul(optarg, &p, 0);
+	    if (p != optarg) {
+		optnum = htonl(optnum);
+		pxechn_setopt(&(opts[211]), (void *)(&optnum), 4);
+	    } else {
+		rv = -3;
+	    }
+	    break;
+	case 'u':	/* UUID: copy option 97 from packet 1 if present */
+	    pxechn_uuid_set(pxe);
+	    break;
+	case 'w':	/* wait */
+	    pxe->wait = 1;
+	    break;
+	case 'W':	/* WDS */
+	    pxe->wds = 1;
+	    break;
+	case '?':
+	    rv = -'?';
+	default:
+	    break;
+	}
+	if (rv >= 0)	/* Clear it since getopt() doesn't guarentee it */
+	    optarg = NULL;
+    }
+    if (iopt.data)
+	pxechn_opt_free(&iopt);
+/* FIXME: consider reordering the application of parsed command line options
+       such that the new nbp may be at the end */
+    if (rv >= 0) {
+	rv = 0;
+    } else if (arg != '?') {
+	printf("Invalid argument for -%c: %s\n", arg, optarg);
+    }
+    dprintf("pxechn_parse_args rv=%d\n", rv);
+    return rv;
+}
+
+int pxechn_args(int argc, char *argv[], struct pxelinux_opt *pxe)
+{
+    pxe_bootp_t *bootp0, *bootp1;
+    int ret = 0;
+    struct dhcp_option *opts;
+    char *str;
+
+    opts = pxe->opts[2];
+    /* Start filling packet #1 */
+    bootp0 = (pxe_bootp_t *)(pxe->p[2].data);
+    bootp1 = (pxe_bootp_t *)(pxe->p[5].data);
+
+    ret = dhcp_unpack_packet(bootp0, pxe->p[2].len, opts);
+    if (ret) {
+	error("Could not unpack packet\n");
+	return -ret;
+    }
+    pxe->p_unpacked[2] = 1;
+    pxe->gip = bootp1->gip;
+
+    ret = pxechn_parse_args(argc, argv, pxe, opts);
+    if (ret)
+	return ret;
+    if (pxe->sip > 0xFFFFFF) {	/* a real IPv4 address */
+	bootp1->sip = pxe->sip;
+    } else if ((pxe->sip == 1)
+		&& (opts[66].len > 0)){
+	/* unterminated? */
+	if (strnlen(opts[66].data, opts[66].len) == (size_t)opts[66].len) {
+	    str = malloc(opts[66].len + 1);
+	    if (str) {
+		memcpy(str, opts[66].data, opts[66].len);
+		str[opts[66].len] = 0;
+	    }	
+	} else {
+	    str = opts[66].data;
+	}
+	if (str) {
+	    bootp1->sip = pxe_dns(str);
+	    if (str != opts[66].data)
+		free(str);
+	} else {
+	    bootp1->sip = pxe->fip;
+	}
+    } else {
+	bootp1->sip = pxe->fip;
+    }
+    bootp1->gip = pxe->gip;
+
+    ret = dhcp_pack_packet(bootp1, (size_t *)&(pxe->p[5].len), opts);
+    if (ret) {
+	error("Could not pack packet\n");
+	return -ret;	/* dhcp_pack_packet always returns positive errors */
+    }
+    return ret;
+}
+
+/* dhcp_pkt2pxe: Copy packet to PXE's BC data for a ptype packet
+ *	Input:
+ *	p	Packet data to copy
+ *	len	length of data to copy
+ *	ptype	Packet type to overwrite
+ */
+int dhcp_pkt2pxe(pxe_bootp_t *p, size_t len, int ptype)
+{
+    t_PXENV_GET_CACHED_INFO *ci;
+    void *cp;
+    int rv = -1;
+
+    if (!(ci = lzalloc(sizeof(t_PXENV_GET_CACHED_INFO)))){
+	dprintf("Unable to lzalloc() for PXE call structure\n");
+	rv = 1;
+	goto ret;
+    }
+    ci->Status = PXENV_STATUS_FAILURE;
+    ci->PacketType = ptype;
+    pxe_call(PXENV_GET_CACHED_INFO, ci);
+
+    if (ci->Status != PXENV_STATUS_SUCCESS) {
+	dprintf("PXE Get Cached Info failed: %d\n", ci->Status);
+	rv = 2;
+	goto ret;
+    }
+
+    cp = MK_PTR(ci->Buffer.seg, ci->Buffer.offs);
+    if (!(memcpy(cp, p, len))) {
+	dprintf("Failed to copy packet\n");
+	rv = 3;
+	goto ret;
+    }
+ret:
+    lfree(ci);
+   return rv;
+}
+
+int pxechn_mergeopt(struct pxelinux_opt *pxe, int d, int s)
+{
+    int ret = 0, i;
+
+    if ((d >= PXECHN_NUM_PKT_TYPE) || (s >= PXECHN_NUM_PKT_TYPE) 
+	    || (d < 0) || (s < 0)) {
+	return -2;
+    }
+    if (!pxe->p_unpacked[s])
+	ret = dhcp_unpack_packet(pxe->p[s].data, pxe->p[s].len, pxe->opts[s]);
+    if (ret) {
+	error("Could not unpack packet for merge\n");
+	printf("Error %d (%d)\n", ret, EINVAL);
+	if (ret == EINVAL) {
+	    if (pxe->p[s].len < 240)
+		printf("Packet %d is too short: %d (240)\n", s, pxe->p[s].len);
+	    else if (((const struct dhcp_packet *)(pxe->p[s].data))->magic != htonl(DHCP_VENDOR_MAGIC))
+		printf("Packet %d has no magic\n", s);
+	    else
+		error("Unknown EINVAL error\n");
+	} else {
+	    error("Unknown error\n");
+	}
+	return -ret;
+    }
+    for (i = 0; i < NUM_DHCP_OPTS; i++) {
+	if (pxe->opts[d][i].len <= -1) {
+	    if (pxe->opts[s][i].len >= 0)
+		pxechn_setopt(&(pxe->opts[d][i]), pxe->opts[s][i].data, pxe->opts[s][i].len);
+	}
+    }
+    return 0;
+}
+
+/* pxechn: Chainload to new PXE file ourselves
+ *	Input:
+ *	argc	Count of arguments passed
+ *	argv	Values of arguments passed
+ *	Returns	0 on success (which should never happen)
+ *		1 on loadfile() error
+ *		2 if DHCP Option 52 (Option Overload) used file field
+ *		-1 on usage error
+ */
+int pxechn(int argc, char *argv[])
+{
+    struct pxelinux_opt pxe;
+    pxe_bootp_t* p[(2 * PXECHN_NUM_PKT_TYPE)];
+    int rv = 0;
+    int i;
+    struct data_area file;
+    struct syslinux_rm_regs regs;
+
+    pxechn_init(&pxe);
+    for (i = 0; i < (2 * PXECHN_NUM_PKT_TYPE); i++) {
+	p[i] = (pxe_bootp_t *)(pxe.p[i].data);
+    }
+
+    /* Parse arguments and patch packet 1 */
+    rv = pxechn_args(argc, argv, &pxe);
+    dpressanykey(INT_MAX);
+    if (rv)
+	goto ret;
+    pxe_set_regs(&regs);
+    /* Load the file late; it's the most time-expensive operation */
+    printf("%s: Attempting to load '%s': ", app_name_str, pxe.fn);
+    if (loadfile(pxe.fn, &file.data, &file.size)) {
+	pxe_error(errno, NULL, NULL);
+	rv = -2;
+	goto ret;
+    }
+    puts("loaded.");
+    /* we'll be shuffling to the standard location of 7C00h */
+    file.base = 0x7C00;
+    if ((pxe.wds) || 
+	    ((pxe.force) && ((pxe.force & (~PXECHN_FORCE_ALL)) == 0))) {
+	printf("Forcing behavior %08X\n", pxe.force);
+	// P2 is the same as P3 if no PXE server present.
+	if ((pxe.wds) ||
+		(pxe.force & PXECHN_FORCE_PKT2)) {
+	    pxechn_fill_pkt(&pxe, PXENV_PACKET_TYPE_DHCP_ACK);
+	    rv = pxechn_mergeopt(&pxe, 2, 1);
+	    if (rv) {
+		dprintf("Merge Option returned %d\n", rv);
+	    }
+	    rv = dhcp_pack_packet(p[5], (size_t *)&(pxe.p[5].len), pxe.opts[2]);
+	    rv = dhcp_pkt2pxe(p[5], pxe.p[5].len, PXENV_PACKET_TYPE_DHCP_ACK);
+	}
+	if (pxe.force & PXECHN_FORCE_PKT1) {
+	    puts("Unimplemented force option utilized");
+	}
+    }
+    rv = dhcp_pkt2pxe(p[5], pxe.p[5].len, PXENV_PACKET_TYPE_CACHED_REPLY);
+    dprint_pxe_bootp_t(p[5], pxe.p[5].len);
+    if ((pxe.wds) ||
+	    ((pxe.force) && ((pxe.force & (~PXECHN_FORCE_ALL)) == 0))) {
+	// printf("Forcing behavior %08X\n", pxe.force);
+	// P2 is the same as P3 if no PXE server present.
+	if ((pxe.wds) ||
+		(pxe.force & PXECHN_FORCE_PKT2)) {
+	    rv = dhcp_pkt2pxe(p[5], pxe.p[5].len, PXENV_PACKET_TYPE_DHCP_ACK);
+	}
+    } else if (pxe.force) {
+	printf("FORCE: bad argument %08X\n", pxe.force);
+    }
+    printf("\n...Ready to boot:\n");
+    if (pxe.wait) {
+	pressanykey(INT_MAX);
+    } else {
+	dpressanykey(INT_MAX);
+    }
+    if (true) {
+	puts("  Attempting to boot...");
+	do_boot(&file, 1, &regs);
+    }
+    /* If failed, copy backup back in and abort */
+    dhcp_pkt2pxe(p[2], pxe.p[2].len, PXENV_PACKET_TYPE_CACHED_REPLY);
+    if (pxe.force && ((pxe.force & (~PXECHN_FORCE_ALL)) == 0)) {
+	if (pxe.force & PXECHN_FORCE_PKT2) {
+	    rv = dhcp_pkt2pxe(p[1], pxe.p[1].len, PXENV_PACKET_TYPE_DHCP_ACK);
+	}
+    }
+ret:
+    return rv;
+}
+
+/* pxe_restart: Restart the PXE environment with a new PXE file
+ *	Input:
+ *	ifn	Name of file to chainload to in a format PXELINUX understands
+ *		This must strictly be TFTP or relative file
+ */
+int pxe_restart(char *ifn)
+{
+    int rv = 0;
+    struct pxelinux_opt pxe;
+    t_PXENV_RESTART_TFTP *pxep;	/* PXENV callback Parameter */
+
+    pxe.fn = ifn;
+    pxechn_fill_pkt(&pxe, PXENV_PACKET_TYPE_CACHED_REPLY);
+    if (pxe.p[5].data)
+	pxe.fip = ( (pxe_bootp_t *)(pxe.p[5].data) )->sip;
+    else
+	pxe.fip = 0;
+    rv = pxechn_parse_fn(pxe.fn, &(pxe.fip), pxe.host, &(pxe.fp));
+    if ((rv > 2) || (rv < 0)) {
+	printf("%s: ERROR: Unparsable filename argument: '%s'\n\n", app_name_str, pxe.fn);
+	goto ret;
+    }
+    printf("  Attempting to boot '%s'...\n\n", pxe.fn);
+    if (!(pxep = lzalloc(sizeof(t_PXENV_RESTART_TFTP)))){
+	dprintf("Unable to lzalloc() for PXE call structure\n");
+	goto ret;
+    }
+    pxep->Status = PXENV_STATUS_SUCCESS;	/* PXENV_STATUS_FAILURE */
+    strcpy((char *)pxep->FileName, ifn);
+    pxep->BufferSize = 0x8000;
+    pxep->Buffer = (void *)0x7c00;
+    pxep->ServerIPAddress = pxe.fip;
+    dprintf("FN='%s'  %08X %08X %08X %08X\n\n", (char *)pxep->FileName,
+	pxep->ServerIPAddress, (unsigned int)pxep,
+	pxep->BufferSize, (unsigned int)pxep->Buffer);
+    dprintf("PXENV_RESTART_TFTP status %d\n", pxep->Status);
+
+    pxe_call(PXENV_RESTART_TFTP, pxep);
+
+    printf("PXENV_RESTART_TFTP returned %d\n", pxep->Status);
+    lfree(pxep);
+
+ret:
+    return rv;
+}
+
+/* pxechn_gpxe: Use gPXE to chainload a new NBP
+ *	Input:
+ *	argc	Count of arguments passed
+ *	argv	Values of arguments passed
+ *	Returns	0 on success (which should never happen)
+ *		1 on loadfile() error
+ *		-1 on usage error
+ */
+//FIXME:Implement
+int pxechn_gpxe(int argc, char *argv[])
+{
+    int rv = 0;
+    struct pxelinux_opt pxe;
+
+    if (argc) {
+	printf("%s\n", argv[0]);
+	pxechn_args(argc, argv, &pxe);
+    }
+    return rv;
+}
+
+int main(int argc, char *argv[])
+{
+    int rv= -1;
+    int err;
+    const struct syslinux_version *sv;
+
+    /* Initialization */
+    err = errno;
+    console_ansi_raw();	/* sets errno = 9 (EBADF) */
+    /* printf("%d %d\n", err, errno); */
+    errno = err;
+    sv = syslinux_version();
+    if (sv->filesystem != SYSLINUX_FS_PXELINUX) {
+	printf("%s: May only run in PXELINUX\n", app_name_str);
+	argc = 1;	/* prevents further processing to boot */
+    }
+    if (argc == 2) {
+	if ((strcasecmp(argv[1], "-h") == 0) || ((strcmp(argv[1], "-?") == 0))
+		|| (strcasecmp(argv[1], "--help") == 0)) {
+	    argc = 1;
+	} else {
+	    rv = pxechn(argc - 1, &argv[1]);
+	}
+    } else if (argc >= 3) {
+	if ((strcmp(argv[1], "-r") == 0)) {
+	    if (argc == 3)
+		rv = pxe_restart(argv[2]);
+	} else {
+	    rv = pxechn(argc - 1, &argv[1]);
+	}
+    }
+    if (rv <= -1 ) {
+	usage();
+	rv = 1;
+    }
+    return rv;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/reboot.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/reboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/reboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,15 @@
+#include <syslinux/reboot.h>
+#include <string.h>
+
+int main(int argc, char *argv[])
+{
+    int warm = 0;
+    int i;
+
+    for (i = 1; i < argc; i++) {
+	if (!strcmp(argv[i], "-w") || !strcmp(argv[i], "--warm"))
+	    warm = 1;
+    }
+
+    syslinux_reboot(warm);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/sanboot.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/sanboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/sanboot.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,83 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * sanboot.c
+ *
+ * Invoke the gPXE "sanboot" command, if available.
+ */
+
+#include <alloca.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <console.h>
+#include <com32.h>
+#include <string.h>
+
+#include <sys/gpxe.h>
+#include <syslinux/pxe_api.h>
+
+struct segoff16 {
+    uint16_t offs, seg;
+};
+
+struct s_PXENV_FILE_EXEC {
+    uint16_t Status;
+    struct segoff16 Command;
+};
+
+static void sanboot(const char **args)
+{
+    char *q;
+    struct s_PXENV_FILE_EXEC *fx;
+
+    fx = lmalloc(sizeof *fx);
+    if (!fx)
+	return;
+
+    q = (char *)(fx + 1);
+
+    fx->Status = 1;
+    fx->Command.offs = OFFS(q);
+    fx->Command.seg = SEG(q);
+
+    q = stpcpy(q, "sanboot");
+
+    while (*args) {
+	*q++ = ' ';
+	q = stpcpy(q, *args);
+	args++;
+    }
+
+    pxe_call(PXENV_FILE_EXEC, fx);
+
+    /* This should not return... */
+}
+
+int main(int argc, const char *argv[])
+{
+    if (argc < 2) {
+	printf("Usage: sanboot rootpath\n");
+	return 1;
+    }
+
+    if (!is_gpxe()) {
+	printf("sanboot: gPXE API not detected\n");
+	return 1;
+    }
+
+    sanboot(argv + 1);
+
+    /* sanboot() should not return... */
+    printf("SAN boot failed.\n");
+    return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/sdi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/sdi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/sdi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,185 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2008 H. Peter Anvin - All Rights Reserved
+ *   Copyright 2009 Intel Corporation; author: H. Peter Anvin
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ *   Boston MA 02110-1301, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * sdi.c
+ *
+ * Loader for the Microsoft System Deployment Image (SDI) format.
+ * Based on a historical patch by Remi Lefevre.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <minmax.h>
+#include <sys/stat.h>
+#include <console.h>
+#include <dprintf.h>
+
+#include <syslinux/loadfile.h>
+#include <syslinux/movebits.h>
+#include <syslinux/bootrm.h>
+
+typedef uint8_t guid_t[16];
+
+struct SDIHeader {
+    uint32_t Signature;
+    char Version[4];
+    uint64_t MDBtype;
+    uint64_t BootCodeOffset;
+    uint64_t BootCodeSize;
+    uint64_t VendorID;
+    uint64_t DeviceID;
+    guid_t DeviceModel;
+    uint64_t DeviceRole;
+    uint64_t Reserved1;
+    guid_t RuntimeGUID;
+    uint64_t RuntimeOEMrev;
+    uint64_t Reserved2;
+    uint64_t PageAlignment;	/* BLOB alignment value in pages */
+    uint64_t Reserved3[48];
+    uint64_t Checksum;
+};
+
+#define SDI_LOAD_ADDR	(16 << 20)	/* 16 MB */
+#define SDI_SIGNATURE	('$' + ('S' << 8) + ('D' << 16) + ('I' << 24))
+
+static inline void error(const char *msg)
+{
+    fputs(msg, stderr);
+}
+
+static int boot_sdi(void *ptr, size_t len)
+{
+    const struct SDIHeader *hdr = ptr;
+    struct syslinux_memmap *mmap = NULL, *amap = NULL;
+    struct syslinux_rm_regs regs;
+    struct syslinux_movelist *ml = NULL;
+
+    /* **** Basic sanity checking **** */
+    if (hdr->Signature != SDI_SIGNATURE) {
+	fputs("No $SDI signature in file\n", stdout);
+	goto bail;
+    }
+    if (memcmp(hdr->Version, "0001", 4)) {
+	int i;
+	fputs("Warning: unknown SDI version: ", stdout);
+	for (i = 0; i < 4; i++)
+	    putchar(hdr->Version[i]);
+	putchar('\n');
+	/* Then try anyway... */
+    }
+
+    /* **** Setup **** */
+    mmap = syslinux_memory_map();
+    amap = syslinux_dup_memmap(mmap);
+    if (!mmap || !amap)
+	goto bail;
+
+    /* **** Map the BOOT BLOB to 0x7c00 **** */
+    if (!hdr->BootCodeOffset) {
+	fputs("No BOOT BLOB in image\n", stdout);
+	goto bail;
+    }
+    if (!hdr->BootCodeSize) {
+	fputs("BOOT BLOB is empty\n", stdout);
+	goto bail;
+    }
+    if (len < hdr->BootCodeOffset + hdr->BootCodeSize) {
+	fputs("BOOT BLOB extends beyond file\n", stdout);
+	goto bail;
+    }
+
+    if (syslinux_memmap_type(amap, 0x7c00, hdr->BootCodeSize) != SMT_FREE) {
+	fputs("BOOT BLOB too large for memory\n", stdout);
+	goto bail;
+    }
+    if (syslinux_add_memmap(&amap, 0x7c00, hdr->BootCodeSize, SMT_ALLOC))
+	goto bail;
+    if (syslinux_add_movelist(&ml, 0x7c00, (addr_t) ptr + hdr->BootCodeOffset,
+			      hdr->BootCodeSize))
+	goto bail;
+
+    /* **** Map the entire image to SDI_LOAD_ADDR **** */
+    if (syslinux_memmap_type(amap, SDI_LOAD_ADDR, len) != SMT_FREE) {
+	fputs("Image too large for memory\n", stdout);
+	goto bail;
+    }
+    if (syslinux_add_memmap(&amap, SDI_LOAD_ADDR, len, SMT_ALLOC))
+	goto bail;
+    if (syslinux_add_movelist(&ml, SDI_LOAD_ADDR, (addr_t) ptr, len))
+	goto bail;
+
+    /* **** Set up registers **** */
+    memset(&regs, 0, sizeof regs);
+    regs.ip = 0x7c00;
+    regs.esp.l = 0x7c00;
+    regs.edx.l = SDI_LOAD_ADDR | 0x41;
+
+    fputs("Booting...\n", stdout);
+    syslinux_shuffle_boot_rm(ml, mmap, 0, &regs);
+
+bail:
+    syslinux_free_memmap(amap);
+    syslinux_free_memmap(mmap);
+    syslinux_free_movelist(ml);
+    return -1;
+}
+
+/*
+ * Check that the sum of all bytes from first 512 bytes (SDI header)
+ * is 0 modulo 256.
+ */
+int has_valid_header(unsigned char *header)
+{
+    unsigned char checksum;
+    unsigned int i;
+
+    checksum = 0;
+    for (i = 0; i < sizeof(struct SDIHeader); i++)
+	checksum += header[i];
+    return (!checksum);
+}
+
+int main(int argc, char *argv[])
+{
+    void *data;
+    size_t data_len;
+
+    if (argc != 2) {
+	error("Usage: sdi.c32 sdi_file\n");
+	return 1;
+    }
+
+    fputs("Loading ", stdout);
+    fputs(argv[1], stdout);
+    fputs("... ", stdout);
+    if (zloadfile(argv[1], &data, &data_len)) {
+	error("failed!\n");
+	return 1;
+    }
+    fputs("ok\n", stdout);
+
+    if (!has_valid_header(data)) {
+	error("SDI header is corrupted\n");
+	return 1;
+    }
+
+    boot_sdi(data, data_len);
+    error("Invalid SDI file or insufficient memory\n");
+    return 1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/stubs/copydown.asm
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/stubs/copydown.asm	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/stubs/copydown.asm	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,11 @@
+		bits 16
+		rep movsd
+		mov si,0
+		mov di,0
+		mov ds,si
+		mov es,di
+		mov ecx,0
+		mov esi,0
+		mov edi,0
+		jmp 0:0
+		align 16
Index: bootcd/isolinux/syslinux-6.03/com32/modules/stubs/swapstub.asm
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/stubs/swapstub.asm	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/stubs/swapstub.asm	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,33 @@
+	bits 16
+swap:
+	push bx
+	movzx bx,dl
+	mov dl,[cs:bx+(table-$$)]
+	pop bx
+.jmp:	jmp 0:0
+	nop
+	nop
+install:
+	;; DS = CS, ES = 0
+	mov edi,[es:si+4*0x13]
+	mov [swap.jmp+1],edi
+	mov di,[es:0x413]
+	dec di
+	mov [es:0x413],di
+	shl edi,16+6
+	mov [es:si+4*0x13],edi
+	shr edi,16
+	mov es,di
+	xor di,di
+	rep movsd
+	mov si,0
+	mov di,0
+	mov ds,si
+	mov es,di
+	mov ecx,0
+	mov esi,0
+	mov edi,0
+	jmp 0:0
+
+	align 16
+table:
Index: bootcd/isolinux/syslinux-6.03/com32/modules/vesainfo.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/vesainfo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/vesainfo.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,92 @@
+/*
+ * vesainfo.c
+ *
+ * Dump information about what VESA graphics modes are supported.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <console.h>
+#include <com32.h>
+#include <inttypes.h>
+#include "../lib/sys/vesa/vesa.h"
+
+/* Wait for a keypress */
+static void wait_key(void)
+{
+    char ch;
+    while (fread(&ch, 1, 1, stdin) == 0) ;
+}
+
+static void print_modes(void)
+{
+	static com32sys_t rm;
+	struct vesa_general_info *gi;
+	struct vesa_mode_info *mi;
+	uint16_t mode, *mode_ptr;
+	int lines;
+
+	struct vesa_info *vesa;
+
+	vesa = lmalloc(sizeof(*vesa));
+	if (!vesa) {
+		printf("vesainfo.c32: fail in lmalloc\n");
+		return;
+	}
+	gi = &vesa->gi;
+	mi = &vesa->mi;
+
+        memset(&rm, 0, sizeof rm);
+	gi->signature = VBE2_MAGIC;	/* Get VBE2 extended data */
+	rm.eax.w[0] = 0x4F00;	/* Get SVGA general information */
+	rm.edi.w[0] = OFFS(gi);
+	rm.es = SEG(gi);
+	__intcall(0x10, &rm, &rm);
+
+    if (rm.eax.w[0] != 0x004F) {
+	printf("No VESA BIOS detected\n");
+	goto exit;
+    } else if (gi->signature != VESA_MAGIC) {
+	printf("VESA information structure has bad magic, trying anyway...\n");
+    }
+
+    printf("VBE version %d.%d\n"
+	   "Mode   attrib h_res v_res bpp layout rpos gpos bpos\n",
+	   (gi->version >> 8) & 0xff, gi->version & 0xff);
+
+    lines = 1;
+
+    mode_ptr = GET_PTR(gi->video_mode_ptr);
+
+    while ((mode = *mode_ptr++) != 0xFFFF) {
+	if (++lines >= 23) {
+	    wait_key();
+	    lines = 0;
+	}
+
+        memset(&rm, 0, sizeof rm);
+	rm.eax.w[0] = 0x4F01;	/* Get SVGA mode information */
+	rm.ecx.w[0] = mode;
+	rm.edi.w[0] = OFFS(mi);
+	rm.es = SEG(mi);
+	__intcall(0x10, &rm, &rm);
+
+	/* Must be a supported mode */
+	if (rm.eax.w[0] != 0x004f)
+	    continue;
+
+	printf("0x%04x 0x%04x %5u %5u %3u %6u %4u %4u %4u\n",
+	       mode, mi->mode_attr, mi->h_res, mi->v_res, mi->bpp,
+	       mi->memory_layout, mi->rpos, mi->gpos, mi->bpos);
+    }
+
+exit:
+	lfree(vesa);
+	return;
+}
+
+int main(int argc __unused, char **argv __unused)
+{
+    print_modes();
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/vpdtest.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/vpdtest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/vpdtest.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,68 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Erwan Velu - 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.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+/*
+ * vpdtest.c
+ *
+ * VPD demo program using libcom32
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <console.h>
+#include "vpd/vpd.h"
+
+int main(void)
+{
+    s_vpd vpd;
+
+    if (vpd_decode(&vpd) == -ENOVPDTABLE) {
+	printf("No VPD Structure found\n");
+	return -1;
+    } else {
+	printf("VPD present at address : 0x%s\n", vpd.base_address);
+    }
+    if (strlen(vpd.bios_build_id) > 0)
+	printf("Bios Build ID                 : %s\n", vpd.bios_build_id);
+    if (strlen(vpd.bios_release_date) > 0)
+	printf("Bios Release Date             : %s\n", vpd.bios_release_date);
+    if (strlen(vpd.bios_version) > 0)
+	printf("Bios Version                  : %s\n", vpd.bios_version);
+    if (strlen(vpd.default_flash_filename) > 0)
+	printf("Default Flash Filename        : %s\n",
+	       vpd.default_flash_filename);
+    if (strlen(vpd.box_serial_number) > 0)
+	printf("Box Serial Number             : %s\n", vpd.box_serial_number);
+    if (strlen(vpd.motherboard_serial_number) > 0)
+	printf("Motherboard Serial Number     : %s\n",
+	       vpd.motherboard_serial_number);
+    if (strlen(vpd.machine_type_model) > 0)
+	printf("Machine Type/Model            : %s\n", vpd.machine_type_model);
+
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/whichsys.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/whichsys.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/whichsys.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,126 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2010 Gert Hulselmans - 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.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * whichsys.c
+ *
+ * Detemine which command to execute, based on the Syslinux bootloader variant
+ * from which you run it.
+ *
+ * Usage:    whichsys.c32 [-iso- command] [-pxe- command] [-sys- command]
+ * Examples: whichsys.c32 -iso- chain.c32 hd0 -sys- chain.c32 hd1 swap
+ *           whichsys.c32 -iso- config iso.cfg -pxe- config pxe.cfg
+ *
+ */
+
+#include <stdio.h>
+#include <alloca.h>
+#include <console.h>
+#include <string.h>
+#include <syslinux/boot.h>
+#include "syslinux/config.h"
+
+
+static struct syslinux_parameter {
+    char **arg[1];
+    bool option;
+} isolinux, pxelinux, syslinux;
+
+/* XXX: this really should be librarized */
+static void boot_args(char **args)
+{
+    int len = 0, a = 0;
+    char **pp;
+    const char *p;
+    char c, *q, *str;
+
+    for (pp = args; *pp; pp++)
+	len += strlen(*pp) + 1;
+
+    q = str = alloca(len);
+    for (pp = args; *pp; pp++) {
+	p = *pp;
+	while ((c = *p++))
+	    *q++ = c;
+	*q++ = ' ';
+	a = 1;
+    }
+    q -= a;
+    *q = '\0';
+
+    if (!str[0])
+	syslinux_run_default();
+    else
+	syslinux_run_command(str);
+}
+
+static void usage(void)
+{
+    static const char usage[] = "\
+Usage:    whichsys.c32 [-iso- command] [-pxe- command] [-sys- command]\n\
+Examples: whichsys.c32 -iso- chain.c32 hd0 -sys- chain.c32 hd1 swap\n\
+          whichsys.c32 -iso- config iso.cfg -pxe- config pxe.cfg\n";
+    fprintf(stderr, usage);
+}
+
+int main(int argc, char *argv[])
+{
+    const union syslinux_derivative_info *sdi;
+
+    int arg = 0;
+
+    /* If no argument got passed, let's show the usage */
+    if (argc == 1) {
+	    usage();
+	    return 0;
+    }
+
+    arg++;
+
+    while (arg < argc) {
+	if (!strcmp(argv[arg], "-iso-")) {
+	    argv[arg] = NULL;
+	    isolinux.arg[0] = &argv[arg + 1];
+	    isolinux.option = true;
+	}
+	if (!strcmp(argv[arg], "-pxe-")) {
+	    argv[arg] = NULL;
+	    pxelinux.arg[0] = &argv[arg + 1];
+	    pxelinux.option = true;
+	}
+	if (!strcmp(argv[arg], "-sys-")) {
+	    argv[arg] = NULL;
+	    syslinux.arg[0] = &argv[arg + 1];
+	    syslinux.option = true;
+	}
+	arg++;
+    }
+
+    sdi = syslinux_derivative_info();
+
+    switch (sdi->c.filesystem) {
+	case SYSLINUX_FS_ISOLINUX:
+	    isolinux.option ? boot_args(isolinux.arg[0]) : fprintf(stderr, "No command specified for ISOLINUX.\n\n"); usage();
+	    break;
+	case SYSLINUX_FS_PXELINUX:
+	    pxelinux.option ? boot_args(pxelinux.arg[0]) : fprintf(stderr, "No command specified for PXELINUX.\n\n"); usage();
+	    break;
+	case SYSLINUX_FS_SYSLINUX:
+	    syslinux.option ? boot_args(syslinux.arg[0]) : fprintf(stderr, "No command specified for SYSLINUX.\n\n"); usage();
+	    break;
+	case SYSLINUX_FS_UNKNOWN:
+	default:
+	    fprintf(stderr, "Unknown Syslinux filesystem\n\n");
+    }
+
+    return -1;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/modules/zzjson.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/modules/zzjson.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/modules/zzjson.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,107 @@
+/*
+ * Display directory contents
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <console.h>
+#include <string.h>
+#include <com32.h>
+#include <zzjson/zzjson.h>
+#include <stdarg.h>
+
+static void myerror(void *ehandle, const char *format, ...) {
+    va_list ap;
+    fprintf(ehandle, "error: ");
+    va_start(ap, format);
+    vfprintf(ehandle, format, ap);
+    va_end(ap);
+    fputc('\n', ehandle);
+}
+
+
+int main(int argc, char *argv[])
+{
+#if 0
+	/* this hangs! */
+    openconsole(&dev_rawcon_r, &dev_stdcon_w);
+#else
+	/* this works */
+    openconsole(&dev_rawcon_r, &dev_ansiserial_w);
+#endif
+    (void) argc;
+    (void) argv;
+    ZZJSON  *tmp;
+    ZZJSON_CONFIG config = { ZZJSON_VERY_STRICT, NULL,
+                             (int(*)(void*)) fgetc,
+                             NULL,
+                             malloc, calloc, free, realloc,
+                             stderr, myerror, stdout,
+                             (int(*)(void*,const char*,...)) fprintf,
+                             (int(*)(int,void*)) fputc };
+    
+    do {
+        ZZJSON *tmp2;
+
+        tmp = zzjson_create_array(&config,
+                zzjson_create_number_d(&config, 3.14),
+                zzjson_create_number_i(&config, 1234LL),
+                zzjson_create_number_i(&config, -4321LL),
+                zzjson_create_true(&config),
+                zzjson_create_false(&config),
+                zzjson_create_null(&config),
+                zzjson_create_string(&config, "hello, world"),
+                zzjson_create_object(&config,
+                    "picard", zzjson_create_string(&config, "jean-luc"),
+                    "riker",  zzjson_create_string(&config, "william t."),
+                    NULL),
+                zzjson_create_object(&config, NULL),
+                zzjson_create_array(&config, NULL),
+                NULL );
+
+        if (!tmp) {
+            fprintf(stderr, "error during creation of json tree\n");
+            break;
+        }
+
+        tmp2 = zzjson_array_prepend(&config, tmp,
+                    zzjson_create_string(&config, "prepended string"));
+
+        if (!tmp2) {
+            fprintf(stderr, "error during prepend\n");
+            break;
+        }
+        tmp = tmp2;
+
+        tmp2 = zzjson_array_append(&config, tmp,
+                    zzjson_create_string(&config, "appended string (slow)"));
+
+        if (!tmp2) {
+            fprintf(stderr, "error during append\n");
+            break;
+        }
+        tmp = tmp2;
+
+        zzjson_print(&config, tmp);
+    } while(0);
+    if (tmp) zzjson_free(&config, tmp);
+
+    {
+        tmp = zzjson_create_array(&config, NULL); /* empty array */
+        tmp = zzjson_array_prepend(&config, tmp, zzjson_create_true(&config));
+        zzjson_print(&config, tmp);
+        zzjson_free(&config, tmp);
+    }
+
+    {
+        tmp = zzjson_create_object(&config, NULL); /* empty object */
+        tmp = zzjson_object_prepend(&config, tmp, "hello",
+                                zzjson_create_string(&config, "world"));
+        tmp = zzjson_object_append(&config, tmp, "goodbye",
+                                zzjson_create_string(&config, "cruel world"));
+        zzjson_print(&config, tmp);
+        zzjson_free(&config, tmp);
+    }
+
+    return 0;
+}
+  
