Index: bootcd/isolinux/syslinux-6.03/com32/hdt/Makefile
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/Makefile	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,149 @@
+## -----------------------------------------------------------------------
+##
+##   Copyright 2001-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.
+##
+## -----------------------------------------------------------------------
+
+##
+## Hardware Detection Tool
+##
+
+VPATH = $(SRC)
+include $(MAKEDIR)/elf.mk
+
+LIBS      = $(objdir)/com32/libupload/libcom32upload.a
+C_LIBS    += $(objdir)/com32/cmenu/libmenu/libmenu.c32
+CFLAGS    += -I$(com32)/cmenu/libmenu -I$(com32)
+
+MODULES	  = hdt.c32
+TESTFILES =
+
+OBJS	  = $(subst $(SRC)/,,$(patsubst %.c,%.o,$(wildcard $(SRC)/*.c)))
+VERSION   = $(shell $(SED) -n 's/\#define VERSION \"\(.*\)\"/\1/p' hdt.h)
+CODENAME  = $(shell $(SED) -n 's/\#define CODENAME \"\(.*\)\"/\1/p' hdt.h)
+NODASH_VERSION = $(shell echo $(VERSION) | $(SED) -e 's/-/_/g' | $(SED) -e 's/\./_/g')
+SUM_FILE  = hdt-$(VERSION).checksums
+
+MEMTEST_URL = http://memtest.org/download/4.20/memtest86+-4.20.bin
+MEMTEST     = memtest.bin
+
+KERNEL_VERSION          ?= $(shell uname -r)
+MODULES_ALIAS_FILE      ?= /lib/modules/$(KERNEL_VERSION)/modules.alias
+GZ_MODULES_ALIAS_FILE   ?= modules.alias.gz
+MODULES_PCIMAP_FILE     ?= /lib/modules/$(KERNEL_VERSION)/modules.pcimap
+GZ_MODULES_PCIMAP_FILE  ?= modules.pcimap.gz
+ISO_DIR                 ?= iso
+ISOLINUX_DIR            ?= isolinux
+FLOPPY_DIR		?= floppy
+PCI_IDS_FILE            ?= $(PWD)/$(FLOPPY_DIR)/pci.ids
+GZ_PCI_IDS_FILE         ?= $(PCI_IDS_FILE).gz
+MENU_COM32              ?= $(com32)/menu/menu.c32
+CHAIN_COM32             ?= $(com32)/chain/chain.c32
+ART_DIR                 ?= art/
+QEMU			?= qemu-kvm
+
+all: $(MODULES) $(TESTFILES)
+
+hdt.elf : $(OBJS) $(LIBS) $(C_LIBS)
+	$(LD) $(LDFLAGS) -o $@ $^
+
+memtest:
+	-[ ! -f $(FLOPPY_DIR)/$(MEMTEST) ] && $(WGET) $(MEMTEST_URL) -O $(FLOPPY_DIR)/$(MEMTEST)
+
+hdt.img: hdt.c32 $(FLOPPY_DIR)/hdt.cfg $(FLOPPY_DIR)/mtools.conf $(topdir)/mtools/syslinux $(MENU_COM32) memtest $(CHAIN_COM32)
+	rm -f hdt*.img
+	$(SED) -e 's/%VERSION%/$(VERSION)/g' $(FLOPPY_DIR)/hdt.cfg |\
+	$(SED) -e 's/%CODENAME%/$(CODENAME)/g' > $(FLOPPY_DIR)/syslinux.cfg
+	MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MFORMAT) -v HDT_$(NODASH_VERSION) -f 1440 -C a:
+	$(topdir)/mtools/syslinux hdt.img
+	-[ ! -f $(GZ_PCI_IDS_FILE) ] && cp /usr/share/hwdata/pci.ids $(PCI_IDS_FILE) && $(GZIPPROG) $(PCI_IDS_FILE)
+	-[ ! -f $(GZ_PCI_IDS_FILE) ] && cp /usr/share/pci.ids $(PCI_IDS_FILE) && $(GZIPPROG) $(PCI_IDS_FILE)
+	-[ -f $(MODULES_ALIAS_FILE) ] &&  cat $(MODULES_ALIAS_FILE) | $(GZIPPROG) - -f | MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) - a:modules.alias
+	-[ -f $(MODULES_PCIMAP_FILE) ] && cat $(MODULES_PCIMAP_FILE) | $(GZIPPROG) - -f | MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) - a:modules.pcimap
+	MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) hdt.c32 a:
+	MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(MENU_COM32) a:
+	MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(CHAIN_COM32) a:
+	@ [ -f $(GZ_PCI_IDS_FILE) ] && MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(GZ_PCI_IDS_FILE) a:pci.ids || printf "\nThe $(GZ_PCI_IDS_FILE) file is missing and can be downloaded from http://pciids.sourceforge.net and gzipped in\nthe ./com32/hdt/$(FLOPPY_DIR) directory of the extracted Syslinux source.\n\n"
+	MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(FLOPPY_DIR)/syslinux.cfg a:
+	MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(FLOPPY_DIR)/$(MEMTEST) a:
+	MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(ART_DIR)/backgnd.png a:
+	MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(ART_DIR)/display.png a:
+	MTOOLSRC=$(PWD)/$(FLOPPY_DIR)/mtools.conf $(MCOPY) $(ART_DIR)/red.png a:
+	mv hdt.img hdt-$(VERSION).img
+	ln -sf hdt-$(VERSION).img hdt.img
+
+hdt.img.gz: hdt.img
+	rm -rf hdt*.img.gz
+	$(GZIPPROG) -c hdt-$(VERSION).img >hdt-$(VERSION).img.gz
+	ln -sf hdt-$(VERSION).img.gz hdt.img.gz
+
+hdt.iso: hdt.c32 $(topdir)/core/isolinux.bin $(FLOPPY_DIR)/hdt.cfg memtest
+	rm -rf $(ISO_DIR)
+	rm -f hdt.iso
+	mkdir -p $(ISO_DIR)/$(ISOLINUX_DIR)
+	cp $(topdir)/core/isolinux.bin $(ISO_DIR)/$(ISOLINUX_DIR)
+	$(SED) -e 's/%VERSION%/$(VERSION)/g' $(FLOPPY_DIR)/hdt.cfg |\
+		$(SED) -e 's/%CODENAME%/$(CODENAME)/g' > $(ISO_DIR)/$(ISOLINUX_DIR)/isolinux.cfg
+	cp hdt.c32 $(ISO_DIR)/$(ISOLINUX_DIR)
+	cp $(FLOPPY_DIR)/$(MEMTEST) $(ISO_DIR)/$(ISOLINUX_DIR)
+	cp $(MENU_COM32) $(ISO_DIR)/$(ISOLINUX_DIR)
+	cp $(CHAIN_COM32) $(ISO_DIR)/$(ISOLINUX_DIR)
+	cp -av $(ART_DIR)/backgnd.png $(ISO_DIR)/$(ISOLINUX_DIR)
+	cp -av $(ART_DIR)/display.png $(ISO_DIR)/$(ISOLINUX_DIR)
+	cp -av $(ART_DIR)/red.png $(ISO_DIR)/$(ISOLINUX_DIR)
+	-[ ! -f $(GZ_PCI_IDS_FILE) ] && cp /usr/share/hwdata/pci.ids $(PCI_IDS_FILE) && $(GZIPPROG) $(PCI_IDS_FILE)
+	-[ ! -f $(GZ_PCI_IDS_FILE) ] && cp /usr/share/pci.ids $(PCI_IDS_FILE) && $(GZIPPROG) $(PCI_IDS_FILE)
+	-[ -f $(MODULES_ALIAS_FILE) ] && cp $(MODULES_ALIAS_FILE) $(ISO_DIR)/$(ISOLINUX_DIR)\
+	       	&& $(GZIPPROG) $(ISO_DIR)/$(ISOLINUX_DIR)/modules.alias\
+		&& mv $(ISO_DIR)/$(ISOLINUX_DIR)/modules.alias.gz $(ISO_DIR)/$(ISOLINUX_DIR)/modules.alias
+	-[ -f $(MODULES_PCIMAP_FILE) ] && cp $(MODULES_PCIMAP_FILE) $(ISO_DIR)/$(ISOLINUX_DIR)\
+		&& $(GZIPPROG) $(ISO_DIR)/$(ISOLINUX_DIR)/modules.pcimap\
+		&& mv $(ISO_DIR)/$(ISOLINUX_DIR)/modules.pcimap.gz $(ISO_DIR)/$(ISOLINUX_DIR)/modules.pcimap
+	-[ ! -f $(ISO_DIR)/$(ISOLINUX_DIR)/pci.ids.gz ] && cp $(GZ_PCI_IDS_FILE) $(ISO_DIR)/$(ISOLINUX_DIR)/pci.ids
+	-[ ! -f $(ISO_DIR)/$(ISOLINUX_DIR)/pci.ids ] && printf "\nThe $(FLOPPY_DIR)/pci.ids file is missing and can be downloaded from http://pciids.sourceforge.net and put in\nthe ./com32/hdt/$(FLOPPY_DIR) directory of the extracted Syslinux source.\n\n"
+	$(MKISOFS) -o hdt.iso -b $(ISOLINUX_DIR)/isolinux.bin -c $(ISOLINUX_DIR)/boot.cat \
+		-no-emul-boot -boot-load-size 4 -boot-info-table \
+		$(ISO_DIR)
+	mv hdt.iso hdt-$(VERSION).iso
+	ln -sf hdt-$(VERSION).iso hdt.iso
+
+hdt-hybrid.iso: hdt.iso ../../utils/isohybrid
+	cp hdt-$(VERSION).iso hdt-hybrid-$(VERSION).iso
+	../../utils/isohybrid --partok hdt-hybrid-$(VERSION).iso
+	ln -sf hdt-hybrid-$(VERSION).iso hdt-hybrid.iso
+
+release: spotless hdt.c32 hdt.img hdt.img.gz hdt.iso hdt-hybrid.iso
+	mv hdt.c32 hdt_$(NODASH_VERSION).c32
+	md5sum hdt_$(NODASH_VERSION).c32 >$(SUM_FILE)
+	md5sum hdt-$(VERSION).iso >>$(SUM_FILE)
+	md5sum hdt-hybrid-$(VERSION).iso >>$(SUM_FILE)
+	md5sum hdt-$(VERSION).img >>$(SUM_FILE)
+	md5sum hdt-$(VERSION).img.gz >>$(SUM_FILE)
+
+test: hdt.img
+	$(QEMU) -fda hdt.img
+
+tidy dist:
+	rm -f *.o *.lo *.a *.lst *.elf .*.d *.tmp
+
+clean: tidy
+	rm -f *.lnx
+
+spotless: clean
+	rm -f *.lss *.c32 *.com hdt*.img hdt*.iso hdt*.img.gz
+	rm -rf $(ISO_DIR)
+	rm -rf $(FLOPPY_DIR)/$(MEMTEST)
+	rm -rf $(FLOPPY_DIR)/pci.ids*
+	rm -rf hdt-*checksums
+	rm -f *~ \#*
+
+install:
+
+-include .*.d
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/README
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/README	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/README	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,19 @@
+--------------
+Compiling HDT
+--------------
+To build HDT, you just have to do a "make" call in this directory.
+
+---------------------------
+Creating a bootable floppy
+--------------------------
+To build a bootable HDT floppy image, you can do a "make hdt.img" call.
+This will requires the mtools (http://mtools.linux.lu) to be installed.
+The script will try to pick several files from your system :
+- /lib/modules/`uname -r`/modules.alias
+- /lib/modules/`uname -r`/modules.pcimap
+- /usr/share/pci.ids or /usr/share/hwdata/pci.ids
+
+This paths can be overrided with the following command line:
+make MODULES_ALIAS_FILE=$(PWD)/floppy/modules.alias MODULES_PCIMAP_FILE=$(PWD)/floppy/modules.pcimap PCI_IDS_FILE=$(PWD)/floppy/pci.ids hdt.img
+
+If your system doesn't have pci.ids, please download it from http://pciids.sourceforge.net/ and put it into the floppy/ directory.
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/art/HDT.svg
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/art/HDT.svg	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/art/HDT.svg	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,535 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 14.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 43363)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+	 width="1280px" height="720px" viewBox="0 0 1280 720" enable-background="new 0 0 1280 720" xml:space="preserve">
+<rect fill="#2C3238" width="1280" height="720"/>
+<g>
+	<g>
+		<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="545.0864" y1="489.623" x2="606.1919" y2="489.623">
+			<stop  offset="0" style="stop-color:#FFFFFF"/>
+			<stop  offset="1" style="stop-color:#D0D2D3"/>
+		</linearGradient>
+		<path fill="url(#SVGID_1_)" d="M560.927,515.72c0.128,1.287,0.386,2.285,0.771,2.992c0.386,0.707,0.82,1.238,1.303,1.592
+			c0.482,0.354,0.972,0.611,1.471,0.771c0.499,0.16,0.957,0.346,1.375,0.555c0.417,0.209,0.747,0.506,0.989,0.893
+			c0.241,0.385,0.344,0.98,0.312,1.785h-22.044c-0.065-0.869,0.041-1.496,0.313-1.881c0.272-0.387,0.644-0.686,1.11-0.893
+			c0.466-0.209,0.972-0.402,1.519-0.58c0.547-0.176,1.069-0.506,1.568-0.988c0.498-0.482,0.916-1.191,1.254-2.123
+			c0.337-0.932,0.522-2.25,0.555-3.955h0.048v-49.64h-0.048c-0.097-1.445-0.322-2.571-0.675-3.375
+			c-0.355-0.805-0.765-1.407-1.231-1.81c-0.466-0.401-0.965-0.69-1.495-0.867c-0.531-0.177-1.013-0.362-1.448-0.555
+			c-0.434-0.193-0.788-0.467-1.061-0.82c-0.272-0.354-0.393-0.917-0.361-1.688c0-0.064,0-0.12,0-0.17
+			c0-0.047,0.112-0.071,0.337-0.071h21.418c0.16,0,0.248,0.031,0.265,0.097c0.016,0.064,0.023,0.128,0.023,0.192
+			c0,0.74-0.128,1.287-0.386,1.641c-0.258,0.354-0.603,0.627-1.037,0.82c-0.435,0.192-0.901,0.369-1.399,0.53
+			c-0.5,0.161-0.982,0.435-1.447,0.82c-0.466,0.385-0.885,0.956-1.254,1.712c-0.37,0.756-0.603,1.81-0.699,3.16h-0.048V515.72z
+			 M599.807,514.948c0.097,1.447,0.32,2.572,0.675,3.377s0.765,1.408,1.23,1.809c0.466,0.404,0.965,0.691,1.495,0.869
+			c0.53,0.176,1.014,0.361,1.447,0.555c0.435,0.193,0.788,0.475,1.061,0.844c0.273,0.371,0.41,0.941,0.41,1.713
+			c0,0.031-0.007,0.08-0.023,0.145s-0.138,0.096-0.361,0.096c-3.409,0-6.834,0-10.275,0s-7.156-0.016-11.143-0.047
+			c-0.161,0-0.25-0.033-0.265-0.096c-0.017-0.066-0.041-0.131-0.073-0.195c0-0.738,0.137-1.285,0.41-1.639
+			c0.273-0.354,0.619-0.627,1.037-0.82c0.417-0.193,0.885-0.369,1.399-0.531c0.514-0.16,1.004-0.434,1.471-0.82
+			s0.885-0.957,1.254-1.711c0.369-0.758,0.619-1.809,0.748-3.16v-23.493H564.4c-0.708,0-1.085-0.201-1.133-0.602
+			c-0.048-0.404,0.152-0.91,0.603-1.521c0.45-0.611,1.102-1.27,1.954-1.977c0.852-0.707,1.849-1.377,2.991-2.002
+			c1.141-0.627,2.395-1.143,3.762-1.545c1.367-0.402,2.757-0.604,4.172-0.604c1.544,0,2.79,0,3.739,0s1.729,0,2.34,0
+			c0.61,0,1.101-0.008,1.47-0.023c0.37-0.018,0.74-0.031,1.11-0.047c0.369-0.018,0.796-0.033,1.278-0.049
+			c0.482-0.018,1.141-0.041,1.979-0.072c0.643-0.033,1.077-0.217,1.302-0.557c0.224-0.336,0.354-0.617,0.387-0.844l-0.049-18.425
+			c-0.162-1.287-0.427-2.284-0.796-2.991c-0.37-0.707-0.796-1.247-1.278-1.617c-0.482-0.37-0.982-0.627-1.496-0.771
+			c-0.514-0.146-0.973-0.322-1.375-0.53c-0.402-0.211-0.732-0.499-0.989-0.868c-0.258-0.37-0.354-0.974-0.29-1.81l22.093,0.049
+			c0.064,0.867-0.049,1.494-0.338,1.881c-0.289,0.386-0.668,0.674-1.133,0.868c-0.467,0.193-0.974,0.377-1.521,0.554
+			s-1.068,0.5-1.567,0.965c-0.499,0.467-0.916,1.167-1.254,2.099c-0.338,0.934-0.523,2.252-0.555,3.956V514.948z"/>
+	</g>
+	<g>
+		<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="677.4297" y1="509.0273" x2="732.7426" y2="453.7145">
+			<stop  offset="0" style="stop-color:#FFFFFF"/>
+			<stop  offset="1" style="stop-color:#D0D2D3"/>
+		</linearGradient>
+		<path fill="url(#SVGID_2_)" d="M734.411,455.47c0.434,0.226,0.587,0.548,0.459,0.965c-0.129,0.419-0.499,0.924-1.109,1.521
+			c-0.611,0.595-1.32,1.245-2.123,1.953c-1.447,1.222-2.99,2.171-4.631,2.846s-3.217,0.981-4.729,0.918h0.05h-14.279v50.698
+			c0.065,1.607,0.266,2.846,0.603,3.715c0.338,0.867,0.74,1.527,1.208,1.979c0.464,0.449,0.964,0.762,1.494,0.939
+			c0.531,0.176,1.013,0.369,1.446,0.578c0.436,0.211,0.788,0.5,1.062,0.867c0.272,0.371,0.379,0.99,0.315,1.859h-9.456h-5.596
+			c-0.74,0-1.464,0-2.171,0s-1.359-0.01-1.953-0.025c-0.596-0.016-1.104-0.023-1.521-0.023c-0.418,0-0.691,0-0.819,0
+			c-0.066-0.869,0.041-1.486,0.314-1.857c0.271-0.369,0.626-0.65,1.061-0.844c0.434-0.193,0.908-0.379,1.422-0.555
+			c0.514-0.178,1.014-0.482,1.496-0.916s0.899-1.07,1.254-1.906c0.354-0.836,0.563-2.041,0.627-3.617v-50.892h-7.525h-15.772
+			c-1.319,0-2.202-0.113-2.654-0.339c-0.449-0.225-0.603-0.546-0.458-0.964c0.145-0.419,0.523-0.916,1.134-1.496
+			c0.611-0.578,1.335-1.238,2.171-1.979c1.446-1.222,2.998-2.17,4.654-2.846s3.225-0.98,4.704-0.916c0.578,0,1.688,0,3.329,0
+			c1.639,0,3.601,0,5.885,0c2.282,0,4.799,0,7.549,0s5.522,0,8.32,0h21.708C733.133,455.133,733.978,455.245,734.411,455.47z"/>
+	</g>
+	<g>
+		<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="614.4233" y1="489.5566" x2="671.4414" y2="489.5566">
+			<stop  offset="0" style="stop-color:#FFFFFF"/>
+			<stop  offset="1" style="stop-color:#D0D2D3"/>
+		</linearGradient>
+		<path fill="url(#SVGID_3_)" d="M667.872,472.496c1.447,2.51,2.404,5.26,2.869,8.252c0.467,2.99,0.7,6.061,0.7,9.213
+			c0,6.237-1.512,11.931-4.535,17.075c-2.99,5.115-7.268,9.312-12.83,12.592c-2.605,1.512-5.709,2.654-9.311,3.426
+			c-0.933,0.193-1.978,0.369-3.136,0.529c-1.158,0.16-2.276,0.297-3.353,0.41s-2.025,0.201-2.847,0.266
+			c-0.818,0.064-1.357,0.096-1.615,0.096c-0.45,0-0.9-0.006-1.352-0.023c-0.449-0.016-0.674-0.25-0.674-0.699
+			c0-0.289,0.145-0.773,0.434-1.447c0.289-0.676,0.748-1.398,1.375-2.172c0.628-0.77,1.431-1.512,2.413-2.219
+			c0.979-0.707,2.176-1.238,3.593-1.592c1.801-0.643,3.321-1.156,4.559-1.543c1.238-0.385,2.371-0.805,3.4-1.254
+			s2.033-1.014,3.015-1.688c0.98-0.676,2.114-1.609,3.401-2.799c2.604-2.412,4.613-5.209,6.029-8.393
+			c1.415-3.186,2.122-6.739,2.122-10.661c0-1.996-0.104-3.947-0.313-5.863c-0.209-1.912-0.563-3.73-1.061-5.449
+			c-0.5-1.721-1.182-3.33-2.051-4.824s-1.96-2.838-3.279-4.027c-1.094-1.094-2.524-2.1-4.293-3.016s-3.65-1.689-5.645-2.316
+			c-1.995-0.627-4.004-1.116-6.031-1.471c-2.025-0.354-3.851-0.538-5.475-0.555c-1.624-0.016-2.951,0.16-3.979,0.531
+			c-1.03,0.37-1.545,0.957-1.545,1.76l0.049,48.722h0.048v10.951h-14.133c0-0.645,0.12-1.125,0.361-1.449
+			c0.241-0.32,0.538-0.57,0.892-0.746c0.355-0.178,0.741-0.305,1.159-0.387c0.417-0.08,0.812-0.201,1.181-0.361
+			c0.37-0.16,0.692-0.395,0.966-0.699c0.272-0.305,0.458-0.764,0.555-1.375c0-1.865,0-4.115,0-6.752
+			c0-2.639-0.009-5.492-0.024-8.564c-0.018-3.07-0.024-6.254-0.024-9.552c0-3.295,0-6.535,0-9.719s-0.008-6.217-0.023-9.094
+			c-0.017-2.879-0.024-5.443-0.024-7.693c0-2.252,0.008-4.077,0.024-5.476c0.016-1.397,0.023-2.211,0.023-2.436
+			c0.032-1.157,0.596-2.099,1.688-2.823c1.093-0.723,2.468-1.277,4.124-1.663s3.497-0.619,5.523-0.699
+			c2.027-0.08,4.004-0.08,5.935,0c1.929,0.08,3.714,0.218,5.354,0.41c1.641,0.192,2.895,0.401,3.763,0.628
+			c1.479,0.449,3.2,1.091,5.161,1.929c1.961,0.835,3.963,1.929,6.006,3.279c2.043,1.352,4.02,2.967,5.934,4.849
+			C664.888,467.795,666.521,469.99,667.872,472.496z"/>
+	</g>
+</g>
+<g>
+	<linearGradient id="SVGID_4_" gradientUnits="userSpaceOnUse" x1="505.0664" y1="544.8008" x2="510.741" y2="544.8008">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_4_)" d="M509.132,551.499c0.033,0.33,0.099,0.584,0.198,0.766s0.21,0.318,0.334,0.41
+		c0.124,0.09,0.25,0.156,0.378,0.197c0.127,0.041,0.246,0.088,0.353,0.143c0.107,0.055,0.192,0.129,0.253,0.229
+		c0.062,0.1,0.089,0.252,0.081,0.457h-5.658c-0.017-0.221,0.011-0.383,0.08-0.48c0.07-0.1,0.165-0.178,0.286-0.23
+		c0.119-0.053,0.249-0.102,0.39-0.148c0.14-0.045,0.274-0.131,0.402-0.254c0.127-0.123,0.235-0.305,0.322-0.543
+		c0.086-0.242,0.134-0.578,0.143-1.018h0.012v-12.738h-0.012c-0.025-0.371-0.083-0.66-0.174-0.867
+		c-0.091-0.205-0.196-0.359-0.315-0.463c-0.12-0.104-0.248-0.178-0.384-0.223c-0.135-0.045-0.259-0.092-0.371-0.143
+		c-0.111-0.049-0.202-0.121-0.272-0.211c-0.07-0.09-0.101-0.234-0.092-0.432c0-0.018,0-0.033,0-0.045
+		c0-0.014,0.028-0.018,0.086-0.018h5.497c0.041,0,0.063,0.008,0.068,0.023c0.004,0.018,0.006,0.033,0.006,0.051
+		c0,0.189-0.033,0.33-0.099,0.42c-0.066,0.09-0.155,0.162-0.267,0.211c-0.111,0.051-0.231,0.096-0.358,0.135
+		c-0.128,0.043-0.252,0.113-0.372,0.211c-0.12,0.1-0.228,0.246-0.322,0.439c-0.096,0.195-0.155,0.465-0.18,0.812h-0.013V551.499z
+		 M519.11,551.3c0.024,0.371,0.082,0.66,0.173,0.865c0.091,0.209,0.196,0.363,0.316,0.465c0.119,0.104,0.248,0.178,0.384,0.223
+		c0.137,0.047,0.26,0.094,0.371,0.143c0.112,0.051,0.202,0.123,0.272,0.217c0.07,0.096,0.105,0.24,0.105,0.439
+		c0,0.01-0.002,0.021-0.007,0.037c-0.003,0.018-0.035,0.025-0.092,0.025c-0.875,0-1.754,0-2.637,0c-0.883,0-1.836-0.004-2.859-0.014
+		c-0.042,0-0.064-0.006-0.068-0.023c-0.005-0.016-0.011-0.033-0.019-0.049c0-0.191,0.035-0.33,0.104-0.422
+		c0.07-0.09,0.159-0.16,0.267-0.211c0.107-0.049,0.227-0.094,0.359-0.137c0.132-0.039,0.258-0.109,0.378-0.209
+		c0.119-0.1,0.227-0.246,0.322-0.439c0.094-0.193,0.159-0.465,0.192-0.811v-6.029h-6.648c-0.182,0-0.278-0.053-0.292-0.154
+		c-0.012-0.104,0.04-0.234,0.155-0.391c0.115-0.158,0.282-0.326,0.501-0.508c0.218-0.182,0.474-0.354,0.768-0.514
+		c0.292-0.162,0.614-0.291,0.966-0.396c0.35-0.104,0.708-0.154,1.07-0.154c0.396,0,0.716,0,0.96,0c0.243,0,0.443,0,0.6,0
+		s0.283-0.002,0.377-0.008c0.095-0.002,0.19-0.006,0.286-0.01c0.094-0.004,0.204-0.01,0.328-0.014s0.293-0.01,0.508-0.02
+		c0.165-0.006,0.276-0.055,0.334-0.141c0.057-0.088,0.091-0.16,0.099-0.217l-0.012-4.73c-0.042-0.33-0.11-0.586-0.205-0.768
+		s-0.204-0.318-0.328-0.414c-0.124-0.094-0.251-0.16-0.383-0.197c-0.132-0.037-0.25-0.084-0.354-0.137
+		c-0.103-0.053-0.188-0.129-0.253-0.223s-0.091-0.25-0.074-0.465l5.67,0.012c0.017,0.225-0.012,0.385-0.086,0.484
+		c-0.075,0.1-0.171,0.174-0.291,0.223c-0.121,0.049-0.25,0.098-0.391,0.143c-0.14,0.045-0.274,0.127-0.402,0.248
+		c-0.128,0.119-0.236,0.299-0.322,0.537c-0.087,0.24-0.135,0.578-0.143,1.016V551.3z"/>
+	<linearGradient id="SVGID_5_" gradientUnits="userSpaceOnUse" x1="521.4248" y1="547.6602" x2="534.7334" y2="547.6602">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_5_)" d="M533.669,552.858c0.066,0.066,0.142,0.117,0.229,0.148c0.086,0.033,0.177,0.062,0.272,0.082
+		c0.094,0.02,0.183,0.049,0.266,0.086c0.083,0.037,0.15,0.092,0.204,0.162c0.053,0.068,0.085,0.176,0.093,0.314
+		c0,0.033-0.017,0.049-0.049,0.049h-3.318h-0.013v-6.016c0-1.246-0.354-2.27-1.064-3.068c-0.718-0.787-1.646-1.178-2.785-1.178
+		c-1.123,0-2.051,0.389-2.786,1.164c-0.727,0.791-1.089,1.791-1.089,2.996c0,1.246,0.375,2.27,1.126,3.07
+		c0.743,0.791,1.692,1.188,2.847,1.188c0.537,0,1.048-0.09,1.535-0.271c0.248-0.092,0.495-0.205,0.743-0.342
+		c0.247-0.135,0.499-0.299,0.755-0.488v2.328c-0.512,0.279-1.032,0.486-1.56,0.617c-0.272,0.066-0.553,0.115-0.842,0.148
+		c-0.289,0.033-0.582,0.051-0.879,0.051c-0.569,0-1.139-0.086-1.708-0.26c-0.562-0.182-1.073-0.43-1.535-0.742
+		c-0.867-0.604-1.531-1.35-1.994-2.242c-0.462-0.906-0.693-1.91-0.693-3.008c0-1.799,0.57-3.289,1.709-4.469
+		c1.139-1.172,2.587-1.758,4.345-1.758c1.164,0,2.224,0.289,3.182,0.867c0.479,0.287,0.905,0.643,1.282,1.062
+		c0.375,0.422,0.683,0.869,0.922,1.338c0.115,0.23,0.219,0.475,0.31,0.725c0.091,0.252,0.161,0.51,0.21,0.773
+		c0.099,0.562,0.148,1.379,0.148,2.451v3.924C533.557,552.694,533.603,552.794,533.669,552.858z"/>
+	<linearGradient id="SVGID_6_" gradientUnits="userSpaceOnUse" x1="535.335" y1="547.5957" x2="545.2256" y2="547.5957">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_6_)" d="M540.28,541.892c0.627-0.248,1.199-0.379,1.714-0.396c0.516-0.016,0.974,0.035,1.375,0.154
+		c0.399,0.119,0.738,0.281,1.015,0.49c0.276,0.205,0.485,0.41,0.625,0.611c0.14,0.203,0.212,0.379,0.217,0.527
+		c0.004,0.148-0.068,0.221-0.217,0.221c-0.207,0.01-0.398,0.014-0.575,0.014c-0.178,0-0.333,0-0.464,0h-0.434
+		c-0.372,0-0.735,0.016-1.089,0.049c-0.355,0.033-0.692,0.09-1.009,0.168c-0.318,0.08-0.607,0.186-0.866,0.322
+		c-0.261,0.135-0.478,0.307-0.65,0.514c-0.314,0.371-0.557,0.838-0.73,1.398s-0.26,1.242-0.26,2.043v3.641
+		c0.033,0.312,0.09,0.553,0.173,0.725c0.083,0.168,0.18,0.295,0.291,0.383c0.112,0.086,0.225,0.148,0.341,0.186
+		s0.221,0.08,0.316,0.129c0.094,0.051,0.168,0.119,0.223,0.211c0.053,0.09,0.076,0.232,0.067,0.42h-5.001
+		c-0.017-0.197,0.006-0.342,0.068-0.432c0.062-0.092,0.143-0.162,0.241-0.211c0.099-0.051,0.208-0.092,0.328-0.131
+		c0.12-0.035,0.236-0.104,0.347-0.203c0.112-0.1,0.206-0.244,0.285-0.434c0.078-0.189,0.13-0.461,0.154-0.818v-9.828h1.993v1.783
+		C539.137,542.708,539.644,542.196,540.28,541.892z"/>
+	<linearGradient id="SVGID_7_" gradientUnits="userSpaceOnUse" x1="545.4424" y1="545.1094" x2="557.5869" y2="545.1094">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_7_)" d="M546.136,544.8c0.462-0.883,1.135-1.633,2.018-2.252c0.454-0.307,0.965-0.553,1.535-0.744
+		c0.569-0.172,1.143-0.258,1.721-0.258c0.611,0,1.18,0.064,1.708,0.197c0.544,0.139,1.065,0.35,1.56,0.631
+		c-0.173,0.297-0.4,0.549-0.681,0.756c-0.239,0.172-0.553,0.316-0.941,0.432c-0.388,0.117-0.867,0.125-1.436,0.025
+		c-0.272-0.033-0.541-0.025-0.805,0.02s-0.516,0.119-0.755,0.223c-0.239,0.102-0.47,0.232-0.693,0.391
+		c-0.223,0.154-0.425,0.33-0.606,0.518c-0.734,0.77-1.102,1.768-1.102,2.998c0,1.27,0.359,2.301,1.077,3.094
+		c0.718,0.775,1.659,1.164,2.822,1.164c1.131,0,2.055-0.389,2.773-1.164c0.709-0.783,1.064-1.807,1.064-3.07v-10.461
+		c-0.041-0.182-0.124-0.301-0.248-0.359c-0.124-0.059-0.254-0.104-0.39-0.137c-0.137-0.031-0.261-0.084-0.372-0.154
+		c-0.112-0.068-0.171-0.209-0.18-0.414c0-0.033,0.017-0.051,0.05-0.051h3.33v1.623v9c0,0.545-0.015,1.02-0.044,1.424
+		s-0.068,0.744-0.117,1.016c-0.099,0.537-0.268,1.031-0.508,1.484c-0.52,1.033-1.258,1.838-2.216,2.414
+		c-0.966,0.596-2.034,0.893-3.207,0.893c-1.75,0-3.194-0.596-4.333-1.783c-1.147-1.189-1.721-2.686-1.721-4.494
+		C545.442,546.687,545.673,545.7,546.136,544.8z"/>
+	<linearGradient id="SVGID_8_" gradientUnits="userSpaceOnUse" x1="558.8647" y1="547.7764" x2="578.2983" y2="547.7764">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_8_)" d="M578.211,541.567c0.025,0,0.045,0.01,0.062,0.027c0.033,0.033,0.033,0.086,0,0.16
+		c-0.05,0.115-0.124,0.295-0.223,0.539c-0.1,0.244-0.231,0.6-0.396,1.07l-2.984,8.318c-0.264,0.834-0.553,1.412-0.866,1.734
+		c-0.314,0.338-0.71,0.508-1.189,0.508c-0.487,0-0.887-0.17-1.201-0.508c-0.148-0.166-0.272-0.389-0.371-0.668
+		c-0.1-0.281-0.215-0.629-0.347-1.041h-0.013l-2.08-5.521l-1.981,5.57c-0.264,0.826-0.553,1.4-0.867,1.723
+		c-0.313,0.336-0.714,0.506-1.201,0.506c-0.479,0-0.875-0.164-1.188-0.494c-0.157-0.166-0.283-0.391-0.377-0.676
+		c-0.096-0.285-0.209-0.633-0.341-1.045l-0.013,0.012l-3.095-8.256c-0.182-0.463-0.322-0.816-0.421-1.059
+		c-0.099-0.244-0.173-0.424-0.223-0.539c-0.041-0.074-0.045-0.129-0.012-0.162c0.017-0.018,0.041-0.023,0.074-0.023
+		c0.396-0.016,0.784,0.053,1.164,0.209c0.157,0.066,0.322,0.154,0.495,0.268c0.174,0.111,0.341,0.252,0.501,0.426
+		c0.162,0.174,0.316,0.381,0.465,0.619c0.148,0.24,0.281,0.521,0.396,0.842l2.612,6.809l2.513-6.857
+		c0.066-0.189,0.136-0.361,0.21-0.514s0.153-0.299,0.235-0.439c0.272-0.33,0.549-0.537,0.829-0.619
+		c0.124-0.033,0.252-0.039,0.384-0.018c0.132,0.02,0.269,0.086,0.409,0.197s0.283,0.275,0.427,0.496
+		c0.144,0.219,0.287,0.508,0.427,0.871l2.625,6.822l2.501-6.859c0.107-0.32,0.235-0.604,0.383-0.848
+		c0.149-0.242,0.304-0.451,0.464-0.625c0.161-0.174,0.328-0.316,0.502-0.434c0.173-0.115,0.342-0.211,0.507-0.285
+		C577.399,541.64,577.799,541.562,578.211,541.567z"/>
+	<linearGradient id="SVGID_9_" gradientUnits="userSpaceOnUse" x1="579.251" y1="547.6602" x2="592.5596" y2="547.6602">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_9_)" d="M591.495,552.858c0.065,0.066,0.143,0.117,0.229,0.148c0.086,0.033,0.177,0.062,0.272,0.082
+		c0.094,0.02,0.183,0.049,0.266,0.086s0.15,0.092,0.205,0.162c0.052,0.068,0.084,0.176,0.092,0.314c0,0.033-0.017,0.049-0.05,0.049
+		h-3.317h-0.013v-6.016c0-1.246-0.354-2.27-1.064-3.068c-0.718-0.787-1.646-1.178-2.786-1.178c-1.123,0-2.051,0.389-2.786,1.164
+		c-0.727,0.791-1.089,1.791-1.089,2.996c0,1.246,0.375,2.27,1.126,3.07c0.743,0.791,1.692,1.188,2.847,1.188
+		c0.537,0,1.048-0.09,1.536-0.271c0.248-0.092,0.495-0.205,0.743-0.342c0.247-0.135,0.499-0.299,0.755-0.488v2.328
+		c-0.512,0.279-1.031,0.486-1.56,0.617c-0.272,0.066-0.553,0.115-0.842,0.148s-0.582,0.051-0.879,0.051
+		c-0.569,0-1.138-0.086-1.708-0.26c-0.562-0.182-1.074-0.43-1.536-0.742c-0.867-0.604-1.531-1.35-1.994-2.242
+		c-0.462-0.906-0.693-1.91-0.693-3.008c0-1.799,0.57-3.289,1.709-4.469c1.139-1.172,2.587-1.758,4.346-1.758
+		c1.164,0,2.224,0.289,3.182,0.867c0.478,0.287,0.905,0.643,1.281,1.062c0.375,0.422,0.683,0.869,0.922,1.338
+		c0.115,0.23,0.219,0.475,0.31,0.725c0.091,0.252,0.161,0.51,0.21,0.773c0.1,0.562,0.149,1.379,0.149,2.451v3.924
+		C591.384,552.694,591.429,552.794,591.495,552.858z"/>
+	<linearGradient id="SVGID_10_" gradientUnits="userSpaceOnUse" x1="593.1611" y1="547.5957" x2="603.0527" y2="547.5957">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_10_)" d="M598.105,541.892c0.628-0.248,1.199-0.379,1.715-0.396c0.516-0.016,0.974,0.035,1.375,0.154
+		c0.399,0.119,0.738,0.281,1.015,0.49c0.276,0.205,0.485,0.41,0.625,0.611c0.141,0.203,0.213,0.379,0.218,0.527
+		c0.003,0.148-0.069,0.221-0.218,0.221c-0.206,0.01-0.398,0.014-0.575,0.014c-0.178,0-0.333,0-0.465,0h-0.433
+		c-0.372,0-0.735,0.016-1.09,0.049s-0.691,0.09-1.009,0.168c-0.317,0.08-0.606,0.186-0.866,0.322
+		c-0.261,0.135-0.478,0.307-0.65,0.514c-0.313,0.371-0.557,0.838-0.73,1.398s-0.26,1.242-0.26,2.043v3.641
+		c0.033,0.312,0.091,0.553,0.173,0.725c0.082,0.168,0.18,0.295,0.291,0.383c0.111,0.086,0.225,0.148,0.341,0.186
+		c0.115,0.037,0.221,0.08,0.315,0.129c0.095,0.051,0.169,0.119,0.224,0.211c0.053,0.09,0.075,0.232,0.067,0.42h-5.002
+		c-0.017-0.197,0.007-0.342,0.068-0.432c0.062-0.092,0.143-0.162,0.241-0.211c0.1-0.051,0.208-0.092,0.328-0.131
+		c0.12-0.035,0.235-0.104,0.347-0.203c0.112-0.1,0.207-0.244,0.285-0.434s0.13-0.461,0.155-0.818v-9.828h1.992v1.783
+		C596.963,542.708,597.471,542.196,598.105,541.892z"/>
+	<linearGradient id="SVGID_11_" gradientUnits="userSpaceOnUse" x1="603.1699" y1="547.7412" x2="615.2402" y2="547.7412">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_11_)" d="M612.888,549.776c0.38-0.346,0.715-0.596,1.009-0.748c0.293-0.152,0.539-0.254,0.736-0.303
+		c0.231-0.059,0.434-0.07,0.607-0.039c-0.074,0.43-0.17,0.824-0.285,1.184s-0.254,0.693-0.415,1.002
+		c-0.161,0.311-0.346,0.6-0.558,0.873c-0.209,0.271-0.451,0.533-0.724,0.781c-1.098,0.998-2.426,1.498-3.986,1.498
+		c-0.536,0-1.064-0.076-1.584-0.225c-0.529-0.139-1.02-0.35-1.474-0.631c-0.949-0.578-1.695-1.35-2.24-2.314
+		c-0.537-0.957-0.805-2.002-0.805-3.133c0-0.42,0.038-0.828,0.116-1.225c0.079-0.396,0.192-0.785,0.341-1.166
+		c0.306-0.748,0.751-1.43,1.338-2.041c0.586-0.594,1.246-1.049,1.98-1.361c0.768-0.314,1.551-0.471,2.352-0.471
+		c1.222,0,2.315,0.32,3.281,0.965c0.966,0.652,1.746,1.588,2.34,2.811l-7.91,4.383c-0.083-0.363-0.079-0.727,0.012-1.09
+		c0.074-0.312,0.236-0.646,0.489-1.002c0.251-0.355,0.662-0.686,1.231-0.99c0.041-0.025,0.117-0.07,0.229-0.137
+		c0.111-0.066,0.248-0.145,0.408-0.236c0.161-0.09,0.337-0.189,0.526-0.297s0.38-0.215,0.569-0.322
+		c0.454-0.256,0.949-0.535,1.485-0.84c-0.355-0.396-0.76-0.697-1.213-0.904c-0.438-0.207-0.929-0.311-1.474-0.311
+		c-1.081,0-1.993,0.404-2.735,1.215c-0.743,0.809-1.114,1.807-1.114,2.996c0,1.188,0.371,2.182,1.114,2.982
+		c0.742,0.818,1.654,1.227,2.735,1.227c1.031,0,1.891-0.34,2.575-1.016c0.231-0.197,0.415-0.391,0.551-0.576
+		C612.535,550.13,612.697,549.95,612.888,549.776z"/>
+	<linearGradient id="SVGID_12_" gradientUnits="userSpaceOnUse" x1="623.3115" y1="544.7832" x2="637.9443" y2="544.7832">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_12_)" d="M637.028,540.405c0.372,0.645,0.617,1.35,0.737,2.117c0.119,0.768,0.179,1.555,0.179,2.363
+		c0,1.602-0.388,3.062-1.163,4.385c-0.769,1.311-1.865,2.389-3.294,3.23c-0.668,0.387-1.464,0.682-2.389,0.879
+		c-0.24,0.051-0.508,0.096-0.805,0.135c-0.297,0.043-0.584,0.078-0.859,0.105c-0.278,0.029-0.521,0.053-0.731,0.068
+		c-0.21,0.018-0.35,0.025-0.415,0.025c-0.116,0-0.23-0.002-0.347-0.006c-0.115-0.004-0.173-0.064-0.173-0.18
+		c0-0.076,0.036-0.197,0.111-0.371c0.073-0.174,0.191-0.359,0.352-0.557c0.163-0.199,0.368-0.389,0.62-0.57
+		c0.251-0.182,0.559-0.318,0.922-0.41c0.462-0.164,0.852-0.297,1.17-0.395c0.318-0.1,0.608-0.207,0.873-0.32
+		c0.264-0.117,0.522-0.262,0.773-0.436c0.252-0.172,0.543-0.412,0.873-0.717c0.668-0.619,1.186-1.338,1.548-2.154
+		c0.363-0.818,0.545-1.729,0.545-2.736c0-0.512-0.028-1.014-0.08-1.504c-0.055-0.49-0.146-0.957-0.273-1.4
+		c-0.127-0.439-0.303-0.854-0.526-1.238c-0.223-0.383-0.503-0.727-0.841-1.033c-0.281-0.281-0.648-0.537-1.102-0.773
+		c-0.455-0.234-0.938-0.434-1.449-0.594s-1.027-0.287-1.548-0.377c-0.52-0.092-0.988-0.139-1.405-0.143s-0.758,0.041-1.021,0.137
+		s-0.396,0.244-0.396,0.451l0.014,12.504h0.013v2.809h-3.628c0-0.164,0.031-0.287,0.093-0.369s0.139-0.146,0.229-0.193
+		c0.092-0.045,0.19-0.078,0.298-0.098c0.107-0.021,0.207-0.053,0.304-0.094c0.095-0.041,0.177-0.102,0.248-0.18
+		c0.068-0.076,0.116-0.195,0.142-0.354c0-0.479,0-1.057,0-1.732c0-0.678-0.003-1.408-0.007-2.197s-0.005-1.604-0.005-2.451
+		c0-0.846,0-1.678,0-2.494c0-0.818-0.003-1.596-0.007-2.334c-0.006-0.74-0.007-1.396-0.007-1.975s0.001-1.045,0.007-1.406
+		c0.004-0.357,0.007-0.566,0.007-0.625c0.007-0.297,0.151-0.537,0.433-0.723c0.28-0.188,0.633-0.328,1.057-0.428
+		c0.426-0.098,0.899-0.158,1.419-0.18c0.521-0.02,1.027-0.02,1.522,0c0.495,0.021,0.954,0.055,1.374,0.104
+		c0.422,0.051,0.743,0.105,0.966,0.162c0.38,0.117,0.822,0.281,1.324,0.496c0.505,0.215,1.018,0.494,1.542,0.842
+		c0.523,0.346,1.03,0.762,1.523,1.244C636.264,539.198,636.682,539.763,637.028,540.405z"/>
+	<linearGradient id="SVGID_13_" gradientUnits="userSpaceOnUse" x1="639.6777" y1="547.7412" x2="651.748" y2="547.7412">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_13_)" d="M649.396,549.776c0.379-0.346,0.717-0.596,1.009-0.748c0.293-0.152,0.539-0.254,0.737-0.303
+		c0.231-0.059,0.433-0.07,0.606-0.039c-0.074,0.43-0.169,0.824-0.285,1.184c-0.115,0.359-0.254,0.693-0.415,1.002
+		c-0.159,0.311-0.347,0.6-0.556,0.873c-0.211,0.271-0.453,0.533-0.725,0.781c-1.099,0.998-2.427,1.498-3.987,1.498
+		c-0.535,0-1.063-0.076-1.584-0.225c-0.529-0.139-1.02-0.35-1.474-0.631c-0.948-0.578-1.696-1.35-2.24-2.314
+		c-0.536-0.957-0.805-2.002-0.805-3.133c0-0.42,0.039-0.828,0.118-1.225c0.077-0.396,0.19-0.785,0.339-1.166
+		c0.307-0.748,0.753-1.43,1.337-2.041c0.588-0.594,1.248-1.049,1.981-1.361c0.769-0.314,1.551-0.471,2.354-0.471
+		c1.221,0,2.314,0.32,3.279,0.965c0.966,0.652,1.745,1.588,2.34,2.811l-7.91,4.383c-0.082-0.363-0.079-0.727,0.013-1.09
+		c0.073-0.312,0.235-0.646,0.488-1.002c0.252-0.355,0.662-0.686,1.231-0.99c0.042-0.025,0.117-0.07,0.23-0.137
+		c0.11-0.066,0.247-0.145,0.408-0.236c0.16-0.09,0.336-0.189,0.525-0.297c0.19-0.107,0.38-0.215,0.569-0.322
+		c0.454-0.256,0.949-0.535,1.485-0.84c-0.354-0.396-0.759-0.697-1.213-0.904c-0.438-0.207-0.929-0.311-1.474-0.311
+		c-1.08,0-1.992,0.404-2.735,1.215c-0.743,0.809-1.114,1.807-1.114,2.996c0,1.188,0.371,2.182,1.114,2.982
+		c0.743,0.818,1.655,1.227,2.735,1.227c1.033,0,1.892-0.34,2.575-1.016c0.23-0.197,0.415-0.391,0.552-0.576
+		S649.207,549.95,649.396,549.776z"/>
+	<linearGradient id="SVGID_14_" gradientUnits="userSpaceOnUse" x1="653.9395" y1="545.9385" x2="660.0059" y2="545.9385">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_14_)" d="M659.721,550.778c0.024,0.01,0.037,0.021,0.037,0.039v2.871v0.012h-0.719c-0.09,0-0.176,0-0.259,0
+		c-0.082,0-0.17-0.004-0.261-0.012h-0.024c-1.437-0.074-2.53-0.439-3.28-1.102c-0.852-0.742-1.275-1.863-1.275-3.367v-8.406v-0.049
+		v-0.484c0.008-0.461,0.123-0.83,0.347-1.105c0.223-0.277,0.47-0.49,0.742-0.639c0.314-0.174,0.673-0.293,1.077-0.359v2.945v0.533
+		v7.182c0,0.973,0.235,1.682,0.706,2.129c0.445,0.42,1.144,0.643,2.091,0.668c0.133-0.033,0.222-0.096,0.267-0.186
+		c0.045-0.092,0.081-0.184,0.106-0.279c0.023-0.094,0.063-0.18,0.118-0.26C659.445,550.831,659.557,550.788,659.721,550.778z
+		 M656.7,541.581h0.26c0.157,0.01,0.31,0.014,0.457,0.014H658c0.438,0.008,0.787,0.119,1.052,0.334
+		c0.264,0.213,0.467,0.449,0.606,0.705c0.166,0.297,0.281,0.635,0.348,1.016h-2.811h-0.508L656.7,541.581z"/>
+	<linearGradient id="SVGID_15_" gradientUnits="userSpaceOnUse" x1="661.4053" y1="547.7412" x2="673.4746" y2="547.7412">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_15_)" d="M671.123,549.776c0.379-0.346,0.715-0.596,1.009-0.748c0.292-0.152,0.538-0.254,0.735-0.303
+		c0.231-0.059,0.434-0.07,0.607-0.039c-0.074,0.43-0.169,0.824-0.284,1.184c-0.116,0.359-0.255,0.693-0.415,1.002
+		c-0.161,0.311-0.347,0.6-0.558,0.873c-0.21,0.271-0.451,0.533-0.724,0.781c-1.098,0.998-2.427,1.498-3.986,1.498
+		c-0.536,0-1.065-0.076-1.585-0.225c-0.528-0.139-1.019-0.35-1.474-0.631c-0.947-0.578-1.695-1.35-2.24-2.314
+		c-0.537-0.957-0.804-2.002-0.804-3.133c0-0.42,0.038-0.828,0.116-1.225c0.079-0.396,0.192-0.785,0.341-1.166
+		c0.306-0.748,0.751-1.43,1.337-2.041c0.586-0.594,1.247-1.049,1.98-1.361c0.768-0.314,1.552-0.471,2.353-0.471
+		c1.222,0,2.314,0.32,3.281,0.965c0.965,0.652,1.745,1.588,2.339,2.811l-7.91,4.383c-0.083-0.363-0.078-0.727,0.012-1.09
+		c0.074-0.312,0.237-0.646,0.49-1.002c0.251-0.355,0.662-0.686,1.23-0.99c0.042-0.025,0.118-0.07,0.23-0.137
+		c0.11-0.066,0.247-0.145,0.407-0.236c0.162-0.09,0.337-0.189,0.527-0.297c0.188-0.107,0.38-0.215,0.568-0.322
+		c0.455-0.256,0.95-0.535,1.485-0.84c-0.354-0.396-0.759-0.697-1.212-0.904c-0.438-0.207-0.929-0.311-1.474-0.311
+		c-1.081,0-1.992,0.404-2.736,1.215c-0.742,0.809-1.114,1.807-1.114,2.996c0,1.188,0.372,2.182,1.114,2.982
+		c0.744,0.818,1.655,1.227,2.736,1.227c1.031,0,1.89-0.34,2.574-1.016c0.231-0.197,0.415-0.391,0.552-0.576
+		S670.933,549.95,671.123,549.776z"/>
+	<linearGradient id="SVGID_16_" gradientUnits="userSpaceOnUse" x1="675.1084" y1="547.6904" x2="683.2793" y2="547.6904">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_16_)" d="M678.711,544.813c-0.908,0.732-1.36,1.699-1.36,2.895c0,1.189,0.452,2.152,1.36,2.887
+		c0.009,0,0.021,0.008,0.037,0.023l-0.049-0.049c0.206,0.164,0.412,0.309,0.619,0.434c0.692,0.379,1.502,0.598,2.426,0.656h0.396
+		c0.132-0.025,0.229-0.072,0.291-0.143c0.062-0.07,0.109-0.152,0.142-0.248c0.033-0.094,0.06-0.195,0.082-0.303
+		c0.02-0.107,0.049-0.205,0.085-0.291c0.038-0.086,0.092-0.16,0.162-0.223c0.069-0.062,0.176-0.098,0.314-0.105
+		c0.043,0,0.062,0.016,0.062,0.049l-0.013,3.33h-1.076h-0.149l-0.396-0.012c-1.906-0.092-3.446-0.641-4.618-1.646
+		c-1.278-1.107-1.919-2.57-1.919-4.395c0-0.99,0.229-1.912,0.681-2.76c0.472-0.852,1.122-1.564,1.957-2.143
+		c0.595-0.396,1.222-0.682,1.882-0.855c0.396-0.105,0.802-0.172,1.22-0.197c0.416-0.023,0.863-0.045,1.343-0.062h1.076v2.068v1.262
+		c0,0.033-0.012,0.049-0.037,0.049c-0.14-0.006-0.247-0.039-0.321-0.098c-0.074-0.057-0.127-0.133-0.161-0.223
+		c-0.032-0.092-0.061-0.188-0.081-0.291c-0.02-0.104-0.047-0.201-0.08-0.297s-0.082-0.18-0.148-0.254s-0.161-0.125-0.284-0.148
+		c-0.742-0.033-1.396,0.053-1.957,0.26S679.141,544.466,678.711,544.813z"/>
+	<linearGradient id="SVGID_17_" gradientUnits="userSpaceOnUse" x1="685.3955" y1="545.9385" x2="691.4629" y2="545.9385">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_17_)" d="M691.178,550.778c0.024,0.01,0.038,0.021,0.038,0.039v2.871v0.012h-0.72c-0.09,0-0.177,0-0.259,0
+		c-0.083,0-0.17-0.004-0.26-0.012h-0.026c-1.436-0.074-2.528-0.439-3.279-1.102c-0.851-0.742-1.276-1.863-1.276-3.367v-8.406v-0.049
+		v-0.484c0.01-0.461,0.126-0.83,0.347-1.105c0.225-0.277,0.472-0.49,0.743-0.639c0.313-0.174,0.673-0.293,1.077-0.359v2.945v0.533
+		v7.182c0,0.973,0.236,1.682,0.705,2.129c0.446,0.42,1.145,0.643,2.094,0.668c0.132-0.033,0.22-0.096,0.266-0.186
+		c0.045-0.092,0.08-0.184,0.104-0.279c0.025-0.094,0.064-0.18,0.119-0.26C690.903,550.831,691.013,550.788,691.178,550.778z
+		 M688.157,541.581h0.26c0.157,0.01,0.31,0.014,0.458,0.014h0.582c0.438,0.008,0.788,0.119,1.053,0.334
+		c0.264,0.213,0.466,0.449,0.607,0.705c0.164,0.297,0.28,0.635,0.346,1.016h-2.811h-0.507L688.157,541.581z"/>
+	<linearGradient id="SVGID_18_" gradientUnits="userSpaceOnUse" x1="692.9678" y1="545.2891" x2="698.0781" y2="545.2891">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_18_)" d="M696.601,551.263c0.008,0.404,0.052,0.717,0.131,0.936c0.078,0.217,0.174,0.385,0.287,0.5
+		c0.112,0.115,0.232,0.193,0.36,0.236c0.13,0.041,0.248,0.086,0.356,0.135c0.108,0.051,0.195,0.119,0.263,0.211
+		c0.067,0.09,0.092,0.238,0.074,0.445h-5.1c-0.017-0.207,0.009-0.355,0.075-0.445c0.065-0.092,0.153-0.158,0.262-0.205
+		c0.108-0.045,0.227-0.09,0.355-0.135c0.13-0.047,0.251-0.125,0.363-0.236c0.111-0.111,0.208-0.275,0.287-0.494
+		s0.123-0.529,0.131-0.936v-9.619c0.427,0.01,0.804,0.154,1.132,0.434c0.139,0.123,0.275,0.281,0.406,0.471
+		c0.132,0.189,0.247,0.428,0.346,0.719c0.098,0.287,0.172,0.629,0.222,1.021c0.049,0.391,0.064,0.85,0.049,1.379V551.263z
+		 M696.563,540.491c-0.346-0.057-0.656-0.156-0.936-0.297c-0.245-0.115-0.481-0.277-0.708-0.488
+		c-0.226-0.211-0.375-0.488-0.449-0.836v-2.018c0.336-0.008,0.646,0.037,0.924,0.137c0.123,0.039,0.244,0.102,0.363,0.18
+		c0.117,0.078,0.23,0.174,0.338,0.289c0.106,0.115,0.202,0.258,0.283,0.422c0.081,0.166,0.143,0.359,0.185,0.582v0.123V540.491z"/>
+	<linearGradient id="SVGID_19_" gradientUnits="userSpaceOnUse" x1="699.4717" y1="547.6787" x2="711.6787" y2="547.6787">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_19_)" d="M699.472,547.659c0-0.824,0.157-1.621,0.471-2.389c0.306-0.75,0.76-1.432,1.362-2.043
+		c0.578-0.594,1.23-1.043,1.956-1.35c0.718-0.305,1.49-0.457,2.315-0.457c0.842,0,1.621,0.152,2.34,0.457
+		c0.751,0.314,1.407,0.764,1.969,1.35c0.585,0.602,1.03,1.279,1.337,2.031c0.305,0.742,0.457,1.543,0.457,2.4
+		c0,0.859-0.152,1.668-0.457,2.428c-0.314,0.775-0.76,1.451-1.337,2.029c-0.562,0.588-1.218,1.035-1.969,1.35
+		c-0.743,0.314-1.523,0.471-2.34,0.471c-0.802,0-1.572-0.156-2.315-0.471c-0.726-0.305-1.378-0.756-1.956-1.35
+		c-0.603-0.602-1.057-1.283-1.362-2.041C699.629,549.306,699.472,548.501,699.472,547.659z M701.726,547.636
+		c0,1.162,0.375,2.152,1.127,2.971c0.76,0.826,1.667,1.238,2.724,1.238c1.063,0,1.972-0.412,2.724-1.238
+		c0.76-0.809,1.139-1.799,1.139-2.971c0-1.156-0.376-2.145-1.127-2.971c-0.759-0.809-1.672-1.215-2.735-1.215
+		c-1.057,0-1.964,0.406-2.724,1.215C702.101,545.491,701.726,546.479,701.726,547.636z"/>
+	<linearGradient id="SVGID_20_" gradientUnits="userSpaceOnUse" x1="712.3057" y1="547.5791" x2="725.4473" y2="547.5791">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_20_)" d="M712.312,553.726c-0.018-0.207,0.007-0.352,0.072-0.439c0.066-0.086,0.149-0.154,0.248-0.203
+		s0.212-0.096,0.342-0.137c0.127-0.041,0.245-0.113,0.352-0.217c0.108-0.104,0.2-0.258,0.278-0.465
+		c0.078-0.205,0.127-0.498,0.144-0.879v-4.244c0-1.75,0.469-3.143,1.41-4.174c0.934-1.023,2.179-1.535,3.739-1.535
+		c1.552,0,2.794,0.512,3.727,1.535c0.925,1.023,1.387,2.414,1.387,4.174v4.295c0.016,0.363,0.065,0.643,0.148,0.842
+		c0.082,0.197,0.177,0.348,0.285,0.451c0.106,0.104,0.222,0.176,0.347,0.217c0.122,0.041,0.235,0.088,0.339,0.137
+		c0.104,0.049,0.185,0.119,0.242,0.211c0.058,0.09,0.083,0.234,0.074,0.432h-2.203h-2.799c-0.016-0.197,0.008-0.342,0.069-0.432
+		c0.061-0.092,0.142-0.162,0.24-0.211s0.209-0.094,0.328-0.131c0.12-0.037,0.235-0.105,0.347-0.203
+		c0.112-0.1,0.207-0.244,0.285-0.436c0.077-0.188,0.129-0.461,0.155-0.814v-4.754c0-0.951-0.276-1.727-0.83-2.328
+		c-0.561-0.594-1.276-0.891-2.142-0.891c-0.867,0-1.584,0.297-2.155,0.891c-0.561,0.611-0.842,1.387-0.842,2.328v4.914
+		c0.034,0.312,0.093,0.557,0.175,0.73c0.083,0.172,0.18,0.303,0.29,0.389c0.111,0.088,0.226,0.148,0.341,0.188
+		c0.115,0.035,0.221,0.08,0.314,0.129c0.096,0.049,0.17,0.121,0.225,0.209c0.053,0.094,0.075,0.232,0.068,0.422H712.312z"/>
+	<linearGradient id="SVGID_21_" gradientUnits="userSpaceOnUse" x1="730.5518" y1="544.8242" x2="746.6016" y2="544.8242">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_21_)" d="M746.473,536.036c0.11,0.057,0.15,0.141,0.117,0.246c-0.033,0.107-0.127,0.238-0.285,0.391
+		c-0.155,0.154-0.337,0.32-0.545,0.502c-0.37,0.312-0.767,0.557-1.188,0.729c-0.419,0.176-0.825,0.254-1.211,0.236h0.011h-3.664
+		v13.012c0.016,0.412,0.068,0.73,0.155,0.953c0.085,0.223,0.188,0.391,0.309,0.508c0.119,0.115,0.248,0.195,0.385,0.24
+		c0.135,0.047,0.26,0.096,0.37,0.148c0.111,0.055,0.203,0.129,0.273,0.223c0.068,0.096,0.098,0.256,0.08,0.477h-2.426h-1.437
+		c-0.19,0-0.376,0-0.558,0s-0.349,0-0.501-0.006c-0.153-0.004-0.283-0.006-0.391-0.006s-0.177,0-0.211,0
+		c-0.016-0.223,0.012-0.381,0.081-0.477c0.07-0.094,0.162-0.166,0.273-0.217c0.11-0.049,0.233-0.096,0.365-0.143
+		c0.132-0.045,0.259-0.123,0.383-0.234s0.231-0.273,0.322-0.488s0.144-0.525,0.16-0.93V538.14h-1.932h-4.047
+		c-0.339,0-0.564-0.027-0.681-0.086c-0.115-0.059-0.155-0.141-0.117-0.248c0.037-0.107,0.134-0.234,0.289-0.385
+		c0.158-0.148,0.344-0.316,0.559-0.508c0.37-0.312,0.77-0.557,1.193-0.73c0.425-0.172,0.828-0.25,1.208-0.232
+		c0.148,0,0.434,0,0.854,0c0.422,0,0.924,0,1.511,0c0.586,0,1.231,0,1.937,0c0.708,0,1.419,0,2.137,0h5.57
+		C746.145,535.95,746.361,535.978,746.473,536.036z"/>
+	<linearGradient id="SVGID_22_" gradientUnits="userSpaceOnUse" x1="743.793" y1="547.6787" x2="755.999" y2="547.6787">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_22_)" d="M743.793,547.659c0-0.824,0.156-1.621,0.47-2.389c0.306-0.75,0.76-1.432,1.362-2.043
+		c0.577-0.594,1.229-1.043,1.956-1.35c0.718-0.305,1.489-0.457,2.315-0.457c0.842,0,1.621,0.152,2.339,0.457
+		c0.751,0.314,1.408,0.764,1.969,1.35c0.585,0.602,1.031,1.279,1.337,2.031c0.305,0.742,0.458,1.543,0.458,2.4
+		c0,0.859-0.153,1.668-0.458,2.428c-0.313,0.775-0.759,1.451-1.337,2.029c-0.561,0.588-1.218,1.035-1.969,1.35
+		c-0.743,0.314-1.523,0.471-2.339,0.471c-0.802,0-1.573-0.156-2.315-0.471c-0.727-0.305-1.379-0.756-1.956-1.35
+		c-0.603-0.602-1.057-1.283-1.362-2.041C743.949,549.306,743.793,548.501,743.793,547.659z M746.045,547.636
+		c0,1.162,0.375,2.152,1.128,2.971c0.759,0.826,1.667,1.238,2.724,1.238c1.062,0,1.971-0.412,2.724-1.238
+		c0.759-0.809,1.139-1.799,1.139-2.971c0-1.156-0.376-2.145-1.127-2.971c-0.76-0.809-1.673-1.215-2.735-1.215
+		c-1.057,0-1.965,0.406-2.724,1.215C746.42,545.491,746.045,546.479,746.045,547.636z"/>
+	<linearGradient id="SVGID_23_" gradientUnits="userSpaceOnUse" x1="757.584" y1="547.6787" x2="769.79" y2="547.6787">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_23_)" d="M757.584,547.659c0-0.824,0.156-1.621,0.47-2.389c0.306-0.75,0.76-1.432,1.362-2.043
+		c0.577-0.594,1.229-1.043,1.956-1.35c0.718-0.305,1.489-0.457,2.314-0.457c0.841,0,1.622,0.152,2.34,0.457
+		c0.751,0.314,1.407,0.764,1.968,1.35c0.588,0.602,1.033,1.279,1.337,2.031c0.308,0.742,0.459,1.543,0.459,2.4
+		c0,0.859-0.151,1.668-0.459,2.428c-0.313,0.775-0.759,1.451-1.337,2.029c-0.561,0.588-1.217,1.035-1.968,1.35
+		c-0.743,0.314-1.521,0.471-2.34,0.471c-0.8,0-1.572-0.156-2.314-0.471c-0.727-0.305-1.379-0.756-1.956-1.35
+		c-0.603-0.602-1.057-1.283-1.362-2.041C757.74,549.306,757.584,548.501,757.584,547.659z M759.836,547.636
+		c0,1.162,0.377,2.152,1.127,2.971c0.759,0.826,1.667,1.238,2.724,1.238c1.065,0,1.974-0.412,2.723-1.238
+		c0.76-0.809,1.14-1.799,1.14-2.971c0-1.156-0.375-2.145-1.126-2.971c-0.76-0.809-1.671-1.215-2.736-1.215
+		c-1.057,0-1.965,0.406-2.724,1.215C760.213,545.491,759.836,546.479,759.836,547.636z"/>
+	<linearGradient id="SVGID_24_" gradientUnits="userSpaceOnUse" x1="771.0596" y1="544.9199" x2="776.0684" y2="544.9199">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="1" style="stop-color:#D0D2D3"/>
+	</linearGradient>
+	<path fill="url(#SVGID_24_)" d="M774.805,552.327c0.082,0.189,0.177,0.332,0.284,0.428c0.107,0.094,0.22,0.164,0.341,0.203
+		c0.119,0.043,0.229,0.084,0.327,0.131c0.1,0.045,0.178,0.113,0.236,0.205c0.056,0.09,0.082,0.234,0.073,0.432h-2.451
+		c-0.312,0-0.619,0-0.917,0c-0.297,0-0.563-0.002-0.797-0.006c-0.235-0.004-0.43-0.006-0.582-0.006c-0.153,0-0.238,0-0.255,0
+		c-0.017-0.189,0.005-0.33,0.062-0.42c0.058-0.092,0.134-0.16,0.229-0.205c0.095-0.047,0.2-0.088,0.315-0.123
+		c0.115-0.039,0.229-0.1,0.34-0.188c0.112-0.086,0.208-0.211,0.291-0.377c0.082-0.164,0.142-0.404,0.174-0.719v-15.561
+		c0.403-0.033,0.767,0.059,1.09,0.273c0.132,0.088,0.265,0.215,0.396,0.369c0.132,0.158,0.247,0.359,0.346,0.602
+		c0.1,0.244,0.18,0.537,0.241,0.879s0.093,0.744,0.093,1.207v12.07C774.667,551.868,774.722,552.138,774.805,552.327z"/>
+</g>
+<g>
+	
+		<linearGradient id="SVGID_25_" gradientUnits="userSpaceOnUse" x1="765.6445" y1="277.7368" x2="808.3828" y2="277.7368" gradientTransform="matrix(0 1.7627 -0.5313 0 746.2548 -985.7871)">
+		<stop  offset="0" style="stop-color:#006838"/>
+		<stop  offset="1" style="stop-color:#8BC53F"/>
+	</linearGradient>
+	<rect x="596.305" y="363.814" fill="url(#SVGID_25_)" width="4.777" height="75.334"/>
+	
+		<linearGradient id="SVGID_26_" gradientUnits="userSpaceOnUse" x1="756.1133" y1="247.3013" x2="811.0918" y2="247.3013" gradientTransform="matrix(0 1.8836 -0.5313 0 746.2548 -1090.623)">
+		<stop  offset="0" style="stop-color:#006838"/>
+		<stop  offset="1" style="stop-color:#8BC53F"/>
+	</linearGradient>
+	<rect x="611.807" y="333.592" fill="url(#SVGID_26_)" width="6.113" height="103.557"/>
+	
+		<linearGradient id="SVGID_27_" gradientUnits="userSpaceOnUse" x1="762.0664" y1="215.625" x2="817.0459" y2="215.625" gradientTransform="matrix(0 2.3897 -0.5313 0 746.2548 -1517.3457)">
+		<stop  offset="0" style="stop-color:#006838"/>
+		<stop  offset="1" style="stop-color:#8BC53F"/>
+	</linearGradient>
+	<rect x="628.637" y="303.764" fill="url(#SVGID_27_)" width="6.113" height="131.385"/>
+	
+		<linearGradient id="SVGID_28_" gradientUnits="userSpaceOnUse" x1="553.5811" y1="411.0479" x2="599.8867" y2="411.0479" gradientTransform="matrix(0.7605 0 0 0.5313 144.8682 147.8136)">
+		<stop  offset="0" style="stop-color:#8BC53F"/>
+		<stop  offset="1" style="stop-color:#006838"/>
+	</linearGradient>
+	<rect x="565.866" y="363.814" fill="url(#SVGID_28_)" width="35.216" height="4.777"/>
+	
+		<linearGradient id="SVGID_29_" gradientUnits="userSpaceOnUse" x1="557.6221" y1="354.8657" x2="612.6035" y2="354.8657" gradientTransform="matrix(0.9408 0 0 0.5313 41.583 147.8136)">
+		<stop  offset="0" style="stop-color:#8BC53F"/>
+		<stop  offset="1" style="stop-color:#006838"/>
+	</linearGradient>
+	<rect x="566.193" y="333.297" fill="url(#SVGID_29_)" width="51.727" height="6.113"/>
+	
+		<linearGradient id="SVGID_30_" gradientUnits="userSpaceOnUse" x1="555.4624" y1="299.3047" x2="614.6807" y2="299.3047" gradientTransform="matrix(1.1577 0 0 0.5313 -76.8652 147.8136)">
+		<stop  offset="0" style="stop-color:#8BC53F"/>
+		<stop  offset="1" style="stop-color:#006838"/>
+	</linearGradient>
+	<rect x="566.193" y="303.777" fill="url(#SVGID_30_)" width="68.557" height="6.113"/>
+	<linearGradient id="SVGID_31_" gradientUnits="userSpaceOnUse" x1="616.7539" y1="416.6992" x2="663.481" y2="463.4263">
+		<stop  offset="0" style="stop-color:#8BC53F"/>
+		<stop  offset="1" style="stop-color:#8BC53F"/>
+	</linearGradient>
+	<path fill="url(#SVGID_31_)" d="M593.305,440.148c0,0,36.604-12.721,47.389-12.721s43.484,11.75,46.117,12.5s-40.199-5-45.533-5"/>
+	
+		<radialGradient id="SVGID_32_" cx="576.5234" cy="382.7012" r="10.5059" gradientTransform="matrix(0 1 1 0 173.9805 -210.3203)" gradientUnits="userSpaceOnUse">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="0.9632" style="stop-color:#67CA32"/>
+	</radialGradient>
+	<path fill="url(#SVGID_32_)" d="M546.176,366.203c0-5.803,4.704-10.506,10.506-10.506s10.506,4.703,10.506,10.506
+		s-4.704,10.506-10.506,10.506S546.176,372.006,546.176,366.203z M556.682,372.906c1.851,0,3.526-0.751,4.739-1.964
+		s1.963-2.889,1.963-4.739c0-3.702-3.001-6.703-6.702-6.703c-3.702,0-6.703,3.001-6.703,6.703
+		C549.979,369.904,552.979,372.906,556.682,372.906z"/>
+	
+		<radialGradient id="SVGID_33_" cx="546.9448" cy="382.7012" r="10.5056" gradientTransform="matrix(0 1 1 0 173.9805 -210.3203)" gradientUnits="userSpaceOnUse">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="0.9632" style="stop-color:#67CA32"/>
+	</radialGradient>
+	<path fill="url(#SVGID_33_)" d="M546.176,336.624c0-5.802,4.704-10.505,10.506-10.505s10.506,4.703,10.506,10.505
+		c0,5.803-4.704,10.506-10.506,10.506S546.176,342.427,546.176,336.624z M556.682,343.327c1.851,0,3.526-0.75,4.739-1.963
+		s1.963-2.889,1.963-4.74c0-3.702-3.001-6.703-6.702-6.703c-3.702,0-6.703,3.001-6.703,6.703S552.979,343.327,556.682,343.327z"/>
+	
+		<radialGradient id="SVGID_34_" cx="517.1543" cy="382.7012" r="10.5059" gradientTransform="matrix(0 1 1 0 173.9805 -210.3203)" gradientUnits="userSpaceOnUse">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="0.9632" style="stop-color:#67CA32"/>
+	</radialGradient>
+	<path fill="url(#SVGID_34_)" d="M546.176,306.834c0-5.802,4.704-10.506,10.506-10.506s10.506,4.704,10.506,10.506
+		c0,5.803-4.704,10.506-10.506,10.506S546.176,312.637,546.176,306.834z M556.682,313.537c1.851,0,3.526-0.751,4.739-1.963
+		c1.213-1.214,1.963-2.89,1.963-4.74c0-3.702-3.001-6.703-6.702-6.703c-3.702,0-6.703,3.001-6.703,6.703
+		C549.979,310.535,552.979,313.537,556.682,313.537z"/>
+	
+		<linearGradient id="SVGID_35_" gradientUnits="userSpaceOnUse" x1="765.6445" y1="357.6123" x2="808.3828" y2="357.6123" gradientTransform="matrix(0 1.7627 0.5313 0 491.3075 -985.7871)">
+		<stop  offset="0" style="stop-color:#006838"/>
+		<stop  offset="1" style="stop-color:#8BC53F"/>
+	</linearGradient>
+	<rect x="678.918" y="363.814" fill="url(#SVGID_35_)" width="4.777" height="75.334"/>
+	
+		<linearGradient id="SVGID_36_" gradientUnits="userSpaceOnUse" x1="756.1133" y1="327.1772" x2="811.0918" y2="327.1772" gradientTransform="matrix(0 1.8836 0.5313 0 491.3075 -1090.623)">
+		<stop  offset="0" style="stop-color:#006838"/>
+		<stop  offset="1" style="stop-color:#8BC53F"/>
+	</linearGradient>
+	<rect x="662.08" y="333.592" fill="url(#SVGID_36_)" width="6.113" height="103.557"/>
+	
+		<linearGradient id="SVGID_37_" gradientUnits="userSpaceOnUse" x1="762.0664" y1="295.5005" x2="817.0459" y2="295.5005" gradientTransform="matrix(0 2.3897 0.5313 0 491.3075 -1517.3457)">
+		<stop  offset="0" style="stop-color:#006838"/>
+		<stop  offset="1" style="stop-color:#8BC53F"/>
+	</linearGradient>
+	<rect x="645.25" y="303.764" fill="url(#SVGID_37_)" width="6.113" height="131.385"/>
+	
+		<linearGradient id="SVGID_38_" gradientUnits="userSpaceOnUse" x1="497.7793" y1="411.0479" x2="544.084" y2="411.0479" gradientTransform="matrix(-0.7605 0 0 0.5313 1092.6943 147.8136)">
+		<stop  offset="0" style="stop-color:#8BC53F"/>
+		<stop  offset="1" style="stop-color:#006838"/>
+	</linearGradient>
+	<rect x="678.918" y="363.814" fill="url(#SVGID_38_)" width="35.215" height="4.777"/>
+	
+		<linearGradient id="SVGID_39_" gradientUnits="userSpaceOnUse" x1="512.5137" y1="354.8657" x2="567.4951" y2="354.8657" gradientTransform="matrix(-0.9408 0 0 0.5313 1195.9795 147.8136)">
+		<stop  offset="0" style="stop-color:#8BC53F"/>
+		<stop  offset="1" style="stop-color:#006838"/>
+	</linearGradient>
+	<rect x="662.08" y="333.297" fill="url(#SVGID_39_)" width="51.727" height="6.113"/>
+	
+		<linearGradient id="SVGID_40_" gradientUnits="userSpaceOnUse" x1="518.8047" y1="299.3047" x2="578.0229" y2="299.3047" gradientTransform="matrix(-1.1577 0 0 0.5313 1314.4268 147.8136)">
+		<stop  offset="0" style="stop-color:#8BC53F"/>
+		<stop  offset="1" style="stop-color:#006838"/>
+	</linearGradient>
+	<rect x="645.25" y="303.777" fill="url(#SVGID_40_)" width="68.557" height="6.113"/>
+	
+		<radialGradient id="SVGID_41_" cx="576.5234" cy="340.2637" r="10.5059" gradientTransform="matrix(0 1 -1 0 1063.582 -210.3203)" gradientUnits="userSpaceOnUse">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="0.9632" style="stop-color:#67CA32"/>
+	</radialGradient>
+	<path fill="url(#SVGID_41_)" d="M723.318,376.709c-5.803,0-10.506-4.703-10.506-10.506s4.703-10.506,10.506-10.506
+		c5.801,0,10.506,4.703,10.506,10.506S729.119,376.709,723.318,376.709z M730.021,366.203c0-3.702-3.002-6.703-6.703-6.703
+		s-6.703,3.001-6.703,6.703c0,1.851,0.75,3.526,1.963,4.739s2.889,1.964,4.74,1.964C727.02,372.906,730.021,369.904,730.021,366.203
+		z"/>
+	
+		<radialGradient id="SVGID_42_" cx="546.9448" cy="340.2637" r="10.5056" gradientTransform="matrix(0 1 -1 0 1063.582 -210.3203)" gradientUnits="userSpaceOnUse">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="0.9632" style="stop-color:#67CA32"/>
+	</radialGradient>
+	<path fill="url(#SVGID_42_)" d="M723.318,347.13c-5.803,0-10.506-4.703-10.506-10.506c0-5.802,4.703-10.505,10.506-10.505
+		c5.801,0,10.506,4.703,10.506,10.505C733.824,342.427,729.119,347.13,723.318,347.13z M730.021,336.624
+		c0-3.702-3.002-6.703-6.703-6.703s-6.703,3.001-6.703,6.703c0,1.852,0.75,3.527,1.963,4.74s2.889,1.963,4.74,1.963
+		C727.02,343.327,730.021,340.326,730.021,336.624z"/>
+	
+		<radialGradient id="SVGID_43_" cx="517.1543" cy="340.2637" r="10.5059" gradientTransform="matrix(0 1 -1 0 1063.582 -210.3203)" gradientUnits="userSpaceOnUse">
+		<stop  offset="0" style="stop-color:#FFFFFF"/>
+		<stop  offset="0.9632" style="stop-color:#67CA32"/>
+	</radialGradient>
+	<path fill="url(#SVGID_43_)" d="M723.318,317.34c-5.803,0-10.506-4.703-10.506-10.506c0-5.802,4.703-10.506,10.506-10.506
+		c5.801,0,10.506,4.704,10.506,10.506C733.824,312.637,729.119,317.34,723.318,317.34z M730.021,306.834
+		c0-3.702-3.002-6.703-6.703-6.703s-6.703,3.001-6.703,6.703c0,1.851,0.75,3.526,1.963,4.74c1.213,1.212,2.889,1.963,4.74,1.963
+		C727.02,313.537,730.021,310.535,730.021,306.834z"/>
+</g>
+</svg>
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/floppy/hdt.cfg
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/floppy/hdt.cfg	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/floppy/hdt.cfg	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,115 @@
+UI menu.c32
+DEFAULT hdt
+PROMPT 0
+TIMEOUT 50
+MENU TITLE Hardware Detection Tool (HDT) version %VERSION% (%CODENAME%)
+MENU MARGIN 0
+MENU ROWS 15
+MENU TABMSG
+MENU TABMSGROW -3
+MENU CMDLINEROW -3
+MENU HELPMSGROW -4
+MENU HELPMSGENDROW -1
+
+MENU COLOR SCREEN 37;40
+MENU COLOR BORDER 34;40
+MENU COLOR TITLE 1;33;40
+MENU COLOR SCROLLBAR 34;46
+MENU COLOR SEL 30;47
+MENU COLOR UNSEL 36;40
+MENU COLOR CMDMARK 37;40
+MENU COLOR CMDLINE 37;40
+MENU COLOR TABMSG 37;40
+MENU COLOR DISABLED 37;40
+MENU COLOR HELP 32;40
+
+LABEL hdt
+MENU LABEL Menu mode
+MENU DEFAULT
+TEXT HELP
+ Starts HDT using the MENU mode
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids quiet
+
+LABEL cli
+MENU LABEL CLI (VESA mode)
+TEXT HELP
+ Starts HDT using the Command Line Interface (CLI)
+ VESA mode is enabled
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids quiet nomenu vesa
+
+LABEL vesa
+MENU LABEL CLI (Text mode)
+TEXT HELP
+ Starts HDT using the Command Line Interface (CLI)
+ VESA mode is disabled
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids quiet nomenu
+
+LABEL summary
+MENU LABEL CLI (Auto summary)
+TEXT HELP
+ Starts HDT using the Command Line Interface (CLI) and run 'show summary'
+ VESA mode is enabled
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids quiet vesa nomenu auto='show summary'
+
+LABEL verbose
+MENU LABEL CLI (VESA mode & Verbose)
+TEXT HELP
+ Starts HDT using the Command Line Interface (CLI) using the verbose mode
+ VESA mode is enabled
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids vesa nomenu verbose
+
+LABEL verbose-text
+MENU LABEL CLI (Text mode & Verbose)
+TEXT HELP
+ Starts HDT using the Command Line Interface (CLI)
+ VESA mode is disabled
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids verbose nomenu
+
+LABEL dump
+MENU LABEL Dump hardware config to TFTP server 
+TEXT HELP
+ Starts HDT using the Command Line Interface (CLI) and run 'dump'
+ VESA mode is enabled
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids quiet vesa nomenu auto='dump'
+
+LABEL postexec
+MENU LABEL Dump memory info, sleep 5 and start memtest entry 
+TEXT HELP
+ Starts HDT using the Command Line Interface (CLI), show an item, say a message reboot and start memtest
+ VESA mode is enabled
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids quiet vesa nomenu auto='show memory;say `########`;say `Starting memtest in 5 sec`;sleep 5;exit' postexec='memtest'
+
+LABEL display
+MENU LABEL Display feature (VESA mode)
+TEXT HELP
+ Starts HDT using the Command Line Interface (CLI)
+ VESA mode is enabled
+ A Picture is shown by using the display command
+ENDTEXT
+COM32 hdt.c32
+APPEND modules_pcimap=modules.pcimap modules_alias=modules.alias pciids=pci.ids silent nomenu vesa auto='display display.png; sleep 5000; display red.png'
+
+MENU SEPARATOR
+
+LABEL memtest
+MENU LABEL Memtest86+ 4.20
+TEXT HELP
+ Starts Memtest86+ 4.20
+ENDTEXT
+LINUX memtest.bin
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/floppy/mtools.conf
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/floppy/mtools.conf	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/floppy/mtools.conf	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,2 @@
+# Floppy image for HDT
+drive a: file="hdt.img"
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-ata.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-ata.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-ata.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,38 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <console.h>
+#include <disk/geom.h>
+#include <disk/util.h>
+
+#include "com32io.h"
+#include "hdt-common.h"
+#include "hdt-ata.h"
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-ata.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-ata.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-ata.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,76 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#ifndef DEFINE_HDT_ATA_H
+#define DEFINE_HDT_ATA_H
+#include <com32io.h>
+
+#include <disk/geom.h>
+#include "hdt.h"
+
+struct ata_identify_device {
+    unsigned short words000_009[10];
+    unsigned char serial_no[20];
+    unsigned short words020_022[3];
+    unsigned char fw_rev[8];
+    unsigned char model[40];
+    unsigned short words047_079[33];
+    unsigned short major_rev_num;
+    unsigned short minor_rev_num;
+    unsigned short command_set_1;
+    unsigned short command_set_2;
+    unsigned short command_set_extension;
+    unsigned short cfs_enable_1;
+    unsigned short word086;
+    unsigned short csf_default;
+    unsigned short words088_255[168];
+} ATTR_PACKED;
+
+struct ata_driveinfo {
+    struct ata_identify_device aid;	/* IDENTIFY xxx DEVICE data */
+    char host_bus_type[5];
+    char interface_type[9];
+    char interface_port;
+} ATTR_PACKED;
+
+/* Useless stuff until I manage how to send ata packets */
+#ifdef ATA
+enum {
+    ATA_ID_FW_REV = 23,
+    ATA_ID_PROD = 27,
+    ATA_ID_FW_REV_LEN = 8,
+    ATA_ID_PROD_LEN = 40,
+};
+void ata_id_c_string(const uint16_t * id, unsigned char *s, unsigned int ofs,
+		     unsigned int len);
+void ata_id_string(const uint16_t * id, unsigned char *s, unsigned int ofs,
+		   unsigned int len);
+void printregs(const com32sys_t * r);
+#endif
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-acpi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-acpi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-acpi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,290 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <acpi/acpi.h>
+
+/* Print ACPI's table header in a defined formating */
+static void show_header(void *address, s_acpi_description_header * h)
+{
+    more_printf("%-4s v%03x %-6s %-8s 0x%08x %-7s 0x%08x @ 0x%p\n",
+		h->signature, h->revision, h->oem_id, h->oem_table_id,
+		h->oem_revision, h->creator_id, h->creator_revision, address)
+}
+
+/* That's an helper to visualize columns*/
+static void show_table_separator(void)
+{
+    more_printf
+	("----|----|------|--------|----------|-------|-----------|--------------------\n");
+}
+
+/* Display the main header before displaying the ACPI tables */
+static void show_table_name(void)
+{
+    more_printf
+	("ACPI rev  oem    table_id oem_rev    creator creat_rev  @ address \n");
+    show_table_separator();
+}
+
+/* called by "show acpi" */
+void main_show_acpi(int argc __unused, char **argv __unused,
+		    struct s_hardware *hardware)
+{
+    reset_more_printf();
+
+    if (hardware->is_acpi_valid == false) {
+	more_printf("No ACPI Tables detected\n");
+	return;
+    }
+
+    show_table_name();
+
+    /* RSDP tables aren't using the same headers as the other
+     * So let's use a dedicated rendering */
+    if (hardware->acpi.rsdp.valid) {
+	s_rsdp *r = &hardware->acpi.rsdp;
+	more_printf
+	    ("RSDP v%03x %-6s                                        @ %p\n",
+	     r->revision, r->oem_id, r->address);
+    }
+
+    if (hardware->acpi.rsdt.valid)
+	show_header(hardware->acpi.rsdt.address,
+		       &hardware->acpi.rsdt.header);
+
+    if (hardware->acpi.xsdt.valid)
+	show_header(hardware->acpi.xsdt.address,
+		       &hardware->acpi.xsdt.header);
+
+    if (hardware->acpi.fadt.valid)
+	show_header(hardware->acpi.fadt.address, &hardware->acpi.fadt.header);
+
+    if (hardware->acpi.dsdt.valid)
+	show_header(hardware->acpi.dsdt.address, &hardware->acpi.dsdt.header);
+
+    /* SSDT includes many optional tables, let's display them */
+    for (int i = 0; i < hardware->acpi.ssdt_count; i++) {
+	if ((hardware->acpi.ssdt[i] != NULL) && (hardware->acpi.ssdt[i]->valid))
+	    show_header(hardware->acpi.ssdt[i]->address,
+			&hardware->acpi.ssdt[i]->header);
+    }
+
+    if (hardware->acpi.sbst.valid)
+	show_header(hardware->acpi.sbst.address, &hardware->acpi.sbst.header);
+
+    if (hardware->acpi.ecdt.valid)
+	show_header(hardware->acpi.ecdt.address, &hardware->acpi.ecdt.header);
+
+    if (hardware->acpi.hpet.valid)
+	show_header(hardware->acpi.hpet.address, &hardware->acpi.hpet.header);
+
+    if (hardware->acpi.tcpa.valid)
+	show_header(hardware->acpi.tcpa.address, &hardware->acpi.tcpa.header);
+
+    if (hardware->acpi.mcfg.valid)
+	show_header(hardware->acpi.mcfg.address, &hardware->acpi.mcfg.header);
+
+    if (hardware->acpi.slic.valid)
+	show_header(hardware->acpi.slic.address, &hardware->acpi.slic.header);
+
+    if (hardware->acpi.boot.valid)
+	show_header(hardware->acpi.boot.address, &hardware->acpi.boot.header);
+
+    /* FACS isn't having the same headers, let's use a dedicated rendering */
+    if (hardware->acpi.facs.valid) {
+	s_facs *fa = &hardware->acpi.facs;
+	more_printf
+	    ("FACS                                                    @ 0x%p\n",
+	     fa->address);
+    }
+
+    if (hardware->acpi.madt.valid)
+	show_header(hardware->acpi.madt.address, &hardware->acpi.madt.header);
+
+    more_printf("\nLocal APIC at 0x%08x\n", hardware->acpi.madt.local_apic_address);
+}
+
+/* Let's display the Processor Local APIC configuration */
+static void show_local_apic(s_madt * madt)
+{
+    if (madt->processor_local_apic_count == 0) {
+	more_printf("No Processor Local APIC found\n");
+	return;
+    }
+
+    /* For all detected logical CPU */
+    for (int i = 0; i < madt->processor_local_apic_count; i++) {
+	s_processor_local_apic *sla = &madt->processor_local_apic[i];
+	char buffer[8];
+	memset(buffer, 0, sizeof(buffer));
+	strcpy(buffer, "disable");
+	/* Let's check if the flags reports the cpu as enabled */
+	if ((sla->flags & PROCESSOR_LOCAL_APIC_ENABLE) ==
+	    PROCESSOR_LOCAL_APIC_ENABLE)
+	    strcpy(buffer, "enable");
+	more_printf("CPU #%u, LAPIC (acpi_id[0x%02x] apic_id[0x%02x]) %s\n",
+		    sla->apic_id, sla->acpi_id, sla->apic_id, buffer);
+    }
+}
+
+/* Display the local apic NMI configuration */
+static void show_local_apic_nmi(s_madt * madt)
+{
+    if (madt->local_apic_nmi_count == 0) {
+	more_printf("No Local APIC NMI found\n");
+	return;
+    }
+
+    for (int i = 0; i < madt->local_apic_nmi_count; i++) {
+	s_local_apic_nmi *slan = &madt->local_apic_nmi[i];
+	char buffer[20];
+	more_printf("LAPIC_NMI (acpi_id[0x%02x] %s lint(0x%02x))\n",
+		    slan->acpi_processor_id, flags_to_string(buffer,
+							     slan->flags),
+		    slan->local_apic_lint);
+    }
+}
+
+/* Display the IO APIC configuration */
+static void show_io_apic(s_madt * madt)
+{
+    if (madt->io_apic_count == 0) {
+	more_printf("No IO APIC found\n");
+	return;
+    }
+
+    /* For all IO APICS */
+    for (int i = 0; i < madt->io_apic_count; i++) {
+	s_io_apic *sio = &madt->io_apic[i];
+	char buffer[15];
+	memset(buffer, 0, sizeof(buffer));
+	/* GSI base reports the GSI configuration
+	 * Let's interpret it as string */
+	switch (sio->global_system_interrupt_base) {
+	case 0:
+	    strcpy(buffer, "GSI 0-23");
+	    break;
+	case 24:
+	    strcpy(buffer, "GSI 24-39");
+	    break;
+	case 40:
+	    strcpy(buffer, "GSI 40-55");
+	    break;
+	default:
+	    strcpy(buffer, "GSI Unknown");
+	    break;
+	}
+
+	more_printf("IO_APIC[%d] : apic_id[0x%02x] address[0x%08x] %s\n",
+		    i, sio->io_apic_id, sio->io_apic_address, buffer);
+    }
+}
+
+/* Display the interrupt source override configuration */
+static void show_interrupt_source_override(s_madt * madt)
+{
+    if (madt->interrupt_source_override_count == 0) {
+	more_printf("No interrupt source override found\n");
+	return;
+    }
+
+    /* Let's process each interrupt source override */
+    for (int i = 0; i < madt->interrupt_source_override_count; i++) {
+	s_interrupt_source_override *siso = &madt->interrupt_source_override[i];
+	char buffer[20];
+	char bus_type[10];
+	memset(bus_type, 0, sizeof(bus_type));
+	/* Spec report bus type 0 as ISA */
+	if (siso->bus == 0)
+	    strcpy(bus_type, "ISA");
+	else
+	    strcpy(bus_type, "unknown");
+
+	more_printf("INT_SRC_OVR (bus %s (%d) bus_irq %d global_irq %d %s)\n",
+		    bus_type, siso->bus, siso->source,
+		    siso->global_system_interrupt, flags_to_string(buffer,
+								   siso->
+								   flags));
+    }
+}
+
+/* Display the apic configuration
+ * This is called by acpi> show apic */
+static void show_acpi_apic(int argc __unused, char **argv __unused,
+			   struct s_hardware *hardware)
+{
+    if (hardware->is_acpi_valid == false) {
+	more_printf("No ACPI Tables detected\n");
+	return;
+    }
+
+    s_madt *madt = &hardware->acpi.madt;
+
+    if (madt->valid == false) {
+	more_printf("No APIC (MADT) table found\n");
+	return;
+    }
+
+    more_printf("Local APIC at 0x%08x\n", madt->local_apic_address);
+    show_local_apic(madt);
+    show_local_apic_nmi(madt);
+    show_io_apic(madt);
+    show_interrupt_source_override(madt);
+}
+
+struct cli_callback_descr list_acpi_show_modules[] = {
+    {
+     .name = "apic",
+     .exec = show_acpi_apic,
+     .nomodule = false,
+     },
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule = false,
+     },
+};
+
+struct cli_module_descr acpi_show_modules = {
+    .modules = list_acpi_show_modules,
+    .default_callback = main_show_acpi,
+};
+
+struct cli_mode_descr acpi_mode = {
+    .mode = ACPI_MODE,
+    .name = CLI_ACPI,
+    .default_modules = NULL,
+    .show_modules = &acpi_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-cpu.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-cpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-cpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,263 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+void main_show_cpu(int argc __unused, char **argv __unused,
+		   struct s_hardware *hardware)
+{
+    char features[81];
+    /* We know the total number of logical cores and we
+     * know the number of cores of the first CPU. Let's consider
+     * the system as symetrical, and so compute the number of
+     * physical CPUs. This is only possible if ACPI is present */
+    if (hardware->acpi.madt.processor_local_apic_count > 0) {
+	more_printf("CPU (%d logical / %d phys)\n",
+		    hardware->acpi.madt.processor_local_apic_count,
+		    hardware->physical_cpu_count);
+    } else
+	more_printf("CPU\n");
+    more_printf(" Manufacturer : %s \n", hardware->cpu.vendor);
+    more_printf(" Product      : %s \n", hardware->cpu.model);
+    more_printf(" CPU Cores    : %d \n", hardware->cpu.num_cores);
+    if (hardware->dmi.processor.thread_count != 0)
+        more_printf(" CPU Threads  : %d \n", hardware->dmi.processor.thread_count);
+    more_printf(" L2 Cache     : %dK\n", hardware->cpu.l2_cache_size);
+
+    memset(features, 0, sizeof(features));
+    snprintf(features, sizeof(features), " Features     : %d Mhz : ",
+	     hardware->dmi.processor.current_speed);
+    if (hardware->cpu.flags.lm)
+	strcat(features, "x86_64 64bit ");
+    else
+	strcat(features, "x86 32bit ");
+    if (hardware->cpu.flags.smp)
+	strcat(features, "SMP ");
+
+    /* This CPU is featuring Intel or AMD Virtualisation Technology */
+    if (hardware->cpu.flags.vmx || hardware->cpu.flags.svm)
+	strcat(features, "HwVIRT ");
+
+    more_printf("%s\n", features);
+}
+
+/* Let's compute the cpu flags display
+ * We have to maximize the number of flags per line */
+static void show_flag(char *buffer, bool flag, char *flag_name, bool flush)
+{
+    char output_buffer[81];
+    /* Flush is only set when no more flags are present
+     * When it's set, or if the line is complete,
+     * we have to end the string computation and display the line.
+     * Before adding the flag into the buffer, let's check that adding it
+     * will not overflow the rendering.*/
+    if ((((strlen(buffer) + strlen(flag_name)) > 66) && flag) || flush) {
+	snprintf(output_buffer, sizeof output_buffer, "Flags     : %s\n",
+		 buffer);
+	more_printf("%s", output_buffer);
+	memset(buffer, 0, sizeof(buffer));
+	if (flush)
+	    return;
+    }
+    /* Let's add the flag name only if the flag is present */
+    if (flag)
+	strcat(buffer, flag_name);
+}
+
+static void show_cpu(int argc __unused, char **argv __unused,
+		     struct s_hardware *hardware)
+{
+    char buffer[81];
+    reset_more_printf();
+    /* We know the total number of logical cores and we
+     * know the number of cores of the first CPU. Let's consider
+     * the system as symetrical, and so compute the number of
+     * physical CPUs. This is only possible if ACPI is present*/
+    if (hardware->acpi.madt.processor_local_apic_count > 0) {
+	more_printf("CPU (%d logical / %d phys)\n",
+		    hardware->acpi.madt.processor_local_apic_count,
+		    hardware->acpi.madt.processor_local_apic_count /
+		    hardware->cpu.num_cores);
+    } else
+	more_printf("CPU\n");
+    more_printf("Vendor    : %s\n", hardware->cpu.vendor);
+    more_printf("Model     : %s\n", hardware->cpu.model);
+    more_printf("CPU Cores : %d\n", hardware->cpu.num_cores);
+    if (hardware->dmi.processor.core_enabled != 0)
+        more_printf("CPU Enable: %d\n", hardware->dmi.processor.core_enabled);
+    if (hardware->dmi.processor.thread_count != 0)
+        more_printf("CPU Thread: %d \n", hardware->dmi.processor.thread_count);
+    more_printf("L1 Cache  : %dK + %dK (I + D) \n",
+		hardware->cpu.l1_instruction_cache_size,
+		hardware->cpu.l1_data_cache_size);
+    more_printf("L2 Cache  : %dK\n", hardware->cpu.l2_cache_size);
+    more_printf("Family ID : %d\n", hardware->cpu.family);
+    more_printf("Model  ID : %d\n", hardware->cpu.model_id);
+    more_printf("Stepping  : %d\n", hardware->cpu.stepping);
+    if (hardware->is_dmi_valid) {
+	more_printf("FSB       : %d MHz\n",
+		    hardware->dmi.processor.external_clock);
+	more_printf("Cur. Speed: %d MHz\n",
+		    hardware->dmi.processor.current_speed);
+	more_printf("Max Speed : %d MHz\n", hardware->dmi.processor.max_speed);
+	more_printf("Upgrade   : %s\n", hardware->dmi.processor.upgrade);
+	more_printf("Voltage   : %d.%02d\n",
+		    hardware->dmi.processor.voltage_mv / 1000,
+		    hardware->dmi.processor.voltage_mv -
+		    ((hardware->dmi.processor.voltage_mv / 1000) * 1000));
+    }
+
+    if (hardware->cpu.flags.smp) {
+	more_printf("SMP       : yes\n");
+    } else {
+	more_printf("SMP       : no\n");
+    }
+
+    if (hardware->cpu.flags.lm) {
+	more_printf("x86_64    : yes\n");
+    } else {
+	more_printf("x86_64    : no\n");
+    }
+
+    if (hardware->cpu.flags.vmx || hardware->cpu.flags.svm) {
+	more_printf("HwVirt    : yes\n");
+    } else {
+	more_printf("HwVirt    : no\n");
+    }
+
+    /* Let's display the supported cpu flags */
+    memset(buffer, 0, sizeof(buffer));
+    show_flag(buffer, hardware->cpu.flags.fpu, "fpu ", false);
+    show_flag(buffer, hardware->cpu.flags.vme, "vme ", false);
+    show_flag(buffer, hardware->cpu.flags.de, "de ", false);
+    show_flag(buffer, hardware->cpu.flags.pse, "pse ", false);
+    show_flag(buffer, hardware->cpu.flags.tsc, "tsc ", false);
+    show_flag(buffer, hardware->cpu.flags.msr, "msr ", false);
+    show_flag(buffer, hardware->cpu.flags.pae, "pae ", false);
+    show_flag(buffer, hardware->cpu.flags.mce, "mce ", false);
+    show_flag(buffer, hardware->cpu.flags.cx8, "cx8 ", false);
+    show_flag(buffer, hardware->cpu.flags.apic, "apic ", false);
+    show_flag(buffer, hardware->cpu.flags.sep, "sep ", false);
+    show_flag(buffer, hardware->cpu.flags.mtrr, "mtrr ", false);
+    show_flag(buffer, hardware->cpu.flags.pge, "pge ", false);
+    show_flag(buffer, hardware->cpu.flags.mca, "mca ", false);
+    show_flag(buffer, hardware->cpu.flags.cmov, "cmov ", false);
+    show_flag(buffer, hardware->cpu.flags.pat, "pat ", false);
+    show_flag(buffer, hardware->cpu.flags.pse_36, "pse_36 ", false);
+    show_flag(buffer, hardware->cpu.flags.psn, "psn ", false);
+    show_flag(buffer, hardware->cpu.flags.clflsh, "clflsh ", false);
+    show_flag(buffer, hardware->cpu.flags.dts, "dts ", false);
+    show_flag(buffer, hardware->cpu.flags.acpi, "acpi ", false);
+    show_flag(buffer, hardware->cpu.flags.mmx, "mmx ", false);
+    show_flag(buffer, hardware->cpu.flags.sse, "sse ", false);
+    show_flag(buffer, hardware->cpu.flags.sse2, "sse2 ", false);
+    show_flag(buffer, hardware->cpu.flags.ss, "ss ", false);
+    show_flag(buffer, hardware->cpu.flags.htt, "ht ", false);
+    show_flag(buffer, hardware->cpu.flags.acc, "acc ", false);
+    show_flag(buffer, hardware->cpu.flags.syscall, "syscall ", false);
+    show_flag(buffer, hardware->cpu.flags.mp, "mp ", false);
+    show_flag(buffer, hardware->cpu.flags.nx, "nx ", false);
+    show_flag(buffer, hardware->cpu.flags.mmxext, "mmxext ", false);
+    show_flag(buffer, hardware->cpu.flags.lm, "lm ", false);
+    show_flag(buffer, hardware->cpu.flags.nowext, "3dnowext ", false);
+    show_flag(buffer, hardware->cpu.flags.now, "3dnow! ", false);
+    show_flag(buffer, hardware->cpu.flags.svm, "svm ", false);
+    show_flag(buffer, hardware->cpu.flags.vmx, "vmx ", false);
+    show_flag(buffer, hardware->cpu.flags.pbe, "pbe ", false);
+    show_flag(buffer, hardware->cpu.flags.fxsr_opt, "fxsr_opt ", false);
+    show_flag(buffer, hardware->cpu.flags.gbpages, "gbpages ", false);
+    show_flag(buffer, hardware->cpu.flags.rdtscp, "rdtscp ", false);
+    show_flag(buffer, hardware->cpu.flags.pni, "pni ", false);
+    show_flag(buffer, hardware->cpu.flags.pclmulqd, "pclmulqd ", false);
+    show_flag(buffer, hardware->cpu.flags.dtes64, "dtes64 ", false);
+    show_flag(buffer, hardware->cpu.flags.smx, "smx ", false);
+    show_flag(buffer, hardware->cpu.flags.est, "est ", false);
+    show_flag(buffer, hardware->cpu.flags.tm2, "tm2 ", false);
+    show_flag(buffer, hardware->cpu.flags.sse3, "sse3 ", false);
+    show_flag(buffer, hardware->cpu.flags.fma, "fma ", false);
+    show_flag(buffer, hardware->cpu.flags.cx16, "cx16 ", false);
+    show_flag(buffer, hardware->cpu.flags.xtpr, "xtpr ", false);
+    show_flag(buffer, hardware->cpu.flags.pdcm, "pdcm ", false);
+    show_flag(buffer, hardware->cpu.flags.dca, "dca ", false);
+    show_flag(buffer, hardware->cpu.flags.xmm4_1, "xmm4_1 ", false);
+    show_flag(buffer, hardware->cpu.flags.xmm4_2, "xmm4_2 ", false);
+    show_flag(buffer, hardware->cpu.flags.x2apic, "x2apic ", false);
+    show_flag(buffer, hardware->cpu.flags.movbe, "movbe ", false);
+    show_flag(buffer, hardware->cpu.flags.popcnt, "popcnt ", false);
+    show_flag(buffer, hardware->cpu.flags.aes, "aes ", false);
+    show_flag(buffer, hardware->cpu.flags.xsave, "xsave ", false);
+    show_flag(buffer, hardware->cpu.flags.osxsave, "osxsave ", false);
+    show_flag(buffer, hardware->cpu.flags.avx, "avx ", false);
+    show_flag(buffer, hardware->cpu.flags.hypervisor, "hypervisor ", false);
+    show_flag(buffer, hardware->cpu.flags.ace2, "ace2 ", false);
+    show_flag(buffer, hardware->cpu.flags.ace2_en, "ace2_en ", false);
+    show_flag(buffer, hardware->cpu.flags.phe, "phe ", false);
+    show_flag(buffer, hardware->cpu.flags.phe_en, "phe_en ", false);
+    show_flag(buffer, hardware->cpu.flags.pmm, "pmm ", false);
+    show_flag(buffer, hardware->cpu.flags.pmm_en, "pmm_en ", false);
+    show_flag(buffer, hardware->cpu.flags.extapic, "extapic ", false);
+    show_flag(buffer, hardware->cpu.flags.cr8_legacy, "cr8_legacy ", false);
+    show_flag(buffer, hardware->cpu.flags.abm, "abm ", false);
+    show_flag(buffer, hardware->cpu.flags.sse4a, "sse4a ", false);
+    show_flag(buffer, hardware->cpu.flags.misalignsse, "misalignsse ", false);
+    show_flag(buffer, hardware->cpu.flags.nowprefetch, "3dnowprefetch ", false);
+    show_flag(buffer, hardware->cpu.flags.osvw, "osvw ", false);
+    show_flag(buffer, hardware->cpu.flags.ibs, "ibs ", false);
+    show_flag(buffer, hardware->cpu.flags.sse5, "sse5 ", false);
+    show_flag(buffer, hardware->cpu.flags.skinit, "skinit ", false);
+    show_flag(buffer, hardware->cpu.flags.wdt, "wdt ", false);
+    show_flag(buffer, hardware->cpu.flags.ida, "ida ", false);
+    show_flag(buffer, hardware->cpu.flags.arat, "arat ", false);
+    show_flag(buffer, hardware->cpu.flags.tpr_shadow, "tpr_shadow ", false);
+    show_flag(buffer, hardware->cpu.flags.vnmi, "vnmi ", false);
+    show_flag(buffer, hardware->cpu.flags.flexpriority, "flexpriority ", false);
+    show_flag(buffer, hardware->cpu.flags.ept, "ept ", false);
+    show_flag(buffer, hardware->cpu.flags.vpid, "vpid ", false);
+
+    /* No more flags, let's display the remaining flags */
+    show_flag(buffer, false, "", true);
+}
+
+struct cli_module_descr cpu_show_modules = {
+    .modules = NULL,
+    .default_callback = show_cpu,
+};
+
+struct cli_mode_descr cpu_mode = {
+    .mode = CPU_MODE,
+    .name = CLI_CPU,
+    .default_modules = NULL,
+    .show_modules = &cpu_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-disk.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-disk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-disk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,253 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer - 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 <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+#include "hdt-util.h"
+
+/**
+ * show_partition_information - print information about a partition
+ * @ptab:	part_entry describing the partition
+ * @i:		Partition number (UI purposes only)
+ * @ptab_root:	part_entry describing the root partition (extended only)
+ * @drive_info:	driveinfo struct describing the drive on which the partition
+ *		is
+ *
+ * Note on offsets (from hpa, see chain.c32):
+ *
+ *  To make things extra confusing: data partition offsets are relative to where
+ *  the data partition record is stored, whereas extended partition offsets
+ *  are relative to the beginning of the extended partition all the way back
+ *  at the MBR... but still not absolute!
+ **/
+static void show_partition_information(struct driveinfo *drive_info,
+				       struct part_entry *ptab,
+				       int partition_offset,
+				       int nb_partitions_seen)
+{
+    char size[11];
+    char bootloader_name[9];
+    char *parttype;
+    unsigned int start, end;
+
+    int i = nb_partitions_seen;
+
+    reset_more_printf();
+
+    start = partition_offset;
+    end = start + ptab->length - 1;
+
+    if (ptab->length > 0)
+	sectors_to_size(ptab->length, size);
+    else
+	memset(size, 0, sizeof size);
+
+    if (i == 1)
+	more_printf(" #  B       Start         End    Size Id Type\n");
+
+    get_label(ptab->ostype, &parttype);
+    more_printf("%2d  %s %11d %11d %s %02X %s",
+		i, (ptab->active_flag == 0x80) ? "x" : " ",
+		start, end, size, ptab->ostype, parttype);
+
+    /* Extra info */
+    if (ptab->ostype == 0x82 && swsusp_check(drive_info, ptab))
+	more_printf("%s", " (Swsusp sig. detected)");
+
+    if (get_bootloader_string(drive_info, ptab, bootloader_name, 9) == 0)
+	more_printf("%-46s %s %s", " ", "Bootloader:", bootloader_name);
+
+    more_printf("\n");
+
+    free(parttype);
+}
+
+void main_show_disk(int argc, char **argv, struct s_hardware *hardware)
+{
+    if (!argc) {
+	more_printf("Which disk?\n");
+	return;
+    }
+
+    int drive = strtol(argv[0], (char **)NULL, 16);
+
+    if (drive < 0x80 || drive >= 0xff) {
+	more_printf("Invalid disk: %d.\n", drive);
+	return;
+    }
+
+    int i = drive - 0x80;
+    struct driveinfo *d = &hardware->disk_info[i];
+    char disk_size[11];
+    char mbr_name[50];
+
+    reset_more_printf();
+
+    if (!hardware->disk_info[i].cbios) {
+	more_printf("No disk found\n");
+	return;			/* Invalid geometry */
+    }
+
+    get_mbr_string(hardware->mbr_ids[i], &mbr_name, 50);
+
+    if ((int)d->edd_params.sectors > 0)
+	sectors_to_size((int)d->edd_params.sectors, disk_size);
+    else
+	memset(disk_size, 0, sizeof disk_size);
+
+    more_printf("DISK 0x%X:\n"
+		"  C/H/S: %d cylinders, %d heads, %d sectors/track\n"
+		"    EDD: Version: %X\n"
+		"         Size: %s, %d bytes/sector, %d sectors/track\n"
+		"         Host bus: %s, Interface type: %s\n"
+		"    MBR: %s (id 0x%X)\n\n",
+		d->disk,
+		d->legacy_max_cylinder + 1, d->legacy_max_head + 1,
+		d->legacy_sectors_per_track, d->edd_version, disk_size,
+		(int)d->edd_params.bytes_per_sector,
+		(int)d->edd_params.sectors_per_track,
+		remove_spaces((char *)d->edd_params.host_bus_type),
+		remove_spaces((char *)d->edd_params.interface_type), mbr_name,
+		hardware->mbr_ids[i]);
+    display_line_nb += 6;
+
+    if (parse_partition_table(d, &show_partition_information)) {
+	if (errno_disk) {
+	    fprintf(stderr, "I/O error parsing disk 0x%X\n", d->disk);
+	    get_error("parse_partition_table");
+	} else {
+	    fprintf(stderr, "Disk 0x%X: unrecognized partition layout\n",
+		    d->disk);
+	}
+	fprintf(stderr, "\n");
+    }
+
+    more_printf("\n");
+}
+
+void main_show_disks(int argc __unused, char **argv __unused,
+		     struct s_hardware *hardware)
+{
+    bool found = false;
+    reset_more_printf();
+
+    int first_one = 0;
+    for (int drive = 0x80; drive < 0xff; drive++) {
+	if (hardware->disk_info[drive - 0x80].cbios) {
+	    found = true;
+	    if (!first_one) {
+		first_one = 1;
+	    } else {
+		pause_printf();
+	    }
+	    char buf[5] = "";
+	    sprintf(buf, "0x%x", drive);
+	    char *argv[1] = { buf };
+	    main_show_disk(1, argv, hardware);
+	}
+    }
+
+    if (found == false)
+	more_printf("No disk found\n");
+}
+
+void disks_summary(int argc __unused, char **argv __unused,
+		   struct s_hardware *hardware)
+{
+    int i = -1;
+    bool found = false;
+
+    reset_more_printf();
+
+    for (int drive = 0x80; drive < 0xff; drive++) {
+	i++;
+	if (!hardware->disk_info[i].cbios)
+	    continue;		/* Invalid geometry */
+
+	found = true;
+	struct driveinfo *d = &hardware->disk_info[i];
+	char disk_size[11];
+
+	if ((int)d->edd_params.sectors > 0)
+	    sectors_to_size((int)d->edd_params.sectors, disk_size);
+	else
+	    memset(disk_size, 0, sizeof disk_size);
+
+	more_printf("DISK 0x%X:\n", d->disk);
+	more_printf("  C/H/S: %d cylinders, %d heads, %d sectors/track\n",
+		    d->legacy_max_cylinder + 1, d->legacy_max_head + 1,
+		    d->legacy_sectors_per_track);
+	more_printf("  EDD:   Version: %X, size: %s\n", d->edd_version,
+		    disk_size);
+
+	/* Do not print Host Bus & Interface if EDD isn't 3.0 or more */
+	if (d->edd_version >= 0x30)
+	    more_printf("         Host bus: %s, Interface type: %s\n\n",
+			remove_spaces((char *)d->edd_params.host_bus_type),
+			remove_spaces((char *)d->edd_params.interface_type));
+    }
+
+    if (found == false)
+	more_printf("No disk found\n");
+}
+
+struct cli_callback_descr list_disk_show_modules[] = {
+    {
+     .name = "disks",
+     .exec = main_show_disks,
+     .nomodule = false,
+     },
+    {
+     .name = "disk",
+     .exec = main_show_disk,
+     .nomodule = false,
+     },
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule = false,
+     },
+};
+
+struct cli_module_descr disk_show_modules = {
+    .modules = list_disk_show_modules,
+    .default_callback = disks_summary,
+};
+
+struct cli_mode_descr disk_mode = {
+    .mode = DISK_MODE,
+    .name = CLI_DISK,
+    .default_modules = NULL,
+    .show_modules = &disk_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-dmi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-dmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-dmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,705 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+static void show_dmi_modules(int argc __unused, char **argv __unused,
+			     struct s_hardware *hardware)
+{
+    char available_dmi_commands[1024];
+    reset_more_printf();
+    memset(available_dmi_commands, 0, sizeof(available_dmi_commands));
+
+    more_printf("Available DMI modules on your system:\n");
+    if (hardware->dmi.base_board.filled == true)
+	more_printf("\t%s\n", CLI_DMI_BASE_BOARD);
+    if (hardware->dmi.battery.filled == true)
+	more_printf("\t%s\n", CLI_DMI_BATTERY);
+    if (hardware->dmi.bios.filled == true)
+	more_printf("\t%s\n", CLI_DMI_BIOS);
+    if (hardware->dmi.chassis.filled == true)
+	more_printf("\t%s\n", CLI_DMI_CHASSIS);
+    for (int i = 0; i < hardware->dmi.memory_count; i++) {
+	if (hardware->dmi.memory[i].filled == true) {
+	    more_printf("\tbank <number>\n");
+	    break;
+	}
+    }
+    for (int i = 0; i < hardware->dmi.memory_module_count; i++) {
+	if (hardware->dmi.memory_module[i].filled == true) {
+	    more_printf("\tmodule <number>\n");
+	    break;
+	}
+    }
+    if (hardware->dmi.processor.filled == true)
+	more_printf("\t%s\n", CLI_DMI_PROCESSOR);
+    if (hardware->dmi.system.filled == true)
+	more_printf("\t%s\n", CLI_DMI_SYSTEM);
+    if (hardware->dmi.ipmi.filled == true)
+	more_printf("\t%s\n", CLI_DMI_IPMI);
+    if (hardware->dmi.cache_count)
+	more_printf("\t%s\n", CLI_DMI_CACHE);
+    if (strlen(hardware->dmi.oem_strings))
+	more_printf("\t%s\n", CLI_DMI_OEM);
+    if (hardware->dmi.hardware_security.filled)
+	more_printf("\t%s\n", CLI_DMI_SECURITY);
+}
+
+static void show_dmi_base_board(int argc __unused, char **argv __unused,
+				struct s_hardware *hardware)
+{
+    if (hardware->dmi.base_board.filled == false) {
+	more_printf("base_board information not found on your system, see "
+		    "`show list' to see which module is available.\n");
+	return;
+    }
+    reset_more_printf();
+    more_printf("Base board\n");
+    more_printf(" Manufacturer : %s\n", hardware->dmi.base_board.manufacturer);
+    more_printf(" Product Name : %s\n", hardware->dmi.base_board.product_name);
+    more_printf(" Version      : %s\n", hardware->dmi.base_board.version);
+    more_printf(" Serial       : %s\n", hardware->dmi.base_board.serial);
+    more_printf(" Asset Tag    : %s\n", hardware->dmi.base_board.asset_tag);
+    more_printf(" Location     : %s\n", hardware->dmi.base_board.location);
+    more_printf(" Type         : %s\n", hardware->dmi.base_board.type);
+    for (int i = 0; i < BASE_BOARD_NB_ELEMENTS; i++) {
+	if (((bool *) (&hardware->dmi.base_board.features))[i] == true) {
+	    more_printf(" %s\n", base_board_features_strings[i]);
+	}
+    }
+
+    for (unsigned int i = 0;
+	 i <
+	 sizeof hardware->dmi.base_board.devices_information /
+	 sizeof *hardware->dmi.base_board.devices_information; i++) {
+	if (strlen(hardware->dmi.base_board.devices_information[i].type)) {
+	    more_printf("On Board Device #%u Information\n", i)
+		more_printf("  Type        : %s\n",
+			    hardware->dmi.base_board.devices_information[i].
+			    type);
+	    more_printf("  Status      : %s\n",
+			hardware->dmi.base_board.devices_information[i].
+			status ? "Enabled" : "Disabled");
+	    more_printf("  Description : %s\n",
+			hardware->dmi.base_board.devices_information[i].
+			description);
+	}
+    }
+}
+
+static void show_dmi_system(int argc __unused, char **argv __unused,
+			    struct s_hardware *hardware)
+{
+    if (hardware->dmi.system.filled == false) {
+	more_printf("system information not found on your system, see "
+		    "`show list' to see which module is available.\n");
+	return;
+    }
+    reset_more_printf();
+    more_printf("System\n");
+    more_printf(" Manufacturer : %s\n", hardware->dmi.system.manufacturer);
+    more_printf(" Product Name : %s\n", hardware->dmi.system.product_name);
+    more_printf(" Version      : %s\n", hardware->dmi.system.version);
+    more_printf(" Serial       : %s\n", hardware->dmi.system.serial);
+    more_printf(" UUID         : %s\n", hardware->dmi.system.uuid);
+    more_printf(" Wakeup Type  : %s\n", hardware->dmi.system.wakeup_type);
+    more_printf(" SKU Number   : %s\n", hardware->dmi.system.sku_number);
+    more_printf(" Family       : %s\n", hardware->dmi.system.family);
+
+    if (strlen(hardware->dmi.system.configuration_options)) {
+	more_printf("System Configuration Options\n");
+	more_printf("%s\n", hardware->dmi.system.configuration_options);
+    }
+
+    if (hardware->dmi.system.system_reset.filled) {
+	more_printf("System Reset\n");
+	more_printf("  Status               : %s\n",
+		    (hardware->dmi.system.system_reset.
+		     status ? "Enabled" : "Disabled"));
+	more_printf("  Watchdog Timer       : %s\n",
+		    (hardware->dmi.system.system_reset.
+		     watchdog ? "Present" : "Not Present"));
+	if (strlen(hardware->dmi.system.system_reset.boot_option))
+	    more_printf("  Boot Option          : %s\n",
+			hardware->dmi.system.system_reset.boot_option);
+	if (strlen(hardware->dmi.system.system_reset.boot_option_on_limit))
+	    more_printf("  Boot Option On Limit : %s\n",
+			hardware->dmi.system.system_reset.boot_option_on_limit);
+	if (strlen(hardware->dmi.system.system_reset.reset_count))
+	    more_printf("  Reset Count          : %s\n",
+			hardware->dmi.system.system_reset.reset_count);
+	if (strlen(hardware->dmi.system.system_reset.reset_limit))
+	    more_printf("  Reset Limit          : %s\n",
+			hardware->dmi.system.system_reset.reset_limit);
+	if (strlen(hardware->dmi.system.system_reset.timer_interval))
+	    more_printf("  Timer Interval       : %s\n",
+			hardware->dmi.system.system_reset.timer_interval);
+	if (strlen(hardware->dmi.system.system_reset.timeout))
+	    more_printf("  Timeout              : %s\n",
+			hardware->dmi.system.system_reset.timeout);
+    }
+
+    more_printf("System Boot Information\n");
+    more_printf(" Status       : %s\n",
+		hardware->dmi.system.system_boot_status);
+}
+
+static void show_dmi_bios(int argc __unused, char **argv __unused,
+			  struct s_hardware *hardware)
+{
+    if (hardware->dmi.bios.filled == false) {
+	more_printf("bios information not found on your system, see "
+		    "`show list' to see which module is available.\n");
+	return;
+    }
+    reset_more_printf();
+    more_printf("BIOS\n");
+    more_printf(" Vendor            : %s\n", hardware->dmi.bios.vendor);
+    more_printf(" Version           : %s\n", hardware->dmi.bios.version);
+    more_printf(" Release Date      : %s\n", hardware->dmi.bios.release_date);
+    more_printf(" Bios Revision     : %s\n", hardware->dmi.bios.bios_revision);
+    if (strlen(hardware->dmi.bios.firmware_revision))
+	more_printf(" Firmware Revision : %s\n",
+		    hardware->dmi.bios.firmware_revision);
+    more_printf(" Address           : 0x%04X0\n", hardware->dmi.bios.address);
+    more_printf(" Runtime address   : %u %s\n",
+		hardware->dmi.bios.runtime_size,
+		hardware->dmi.bios.runtime_size_unit);
+    more_printf(" Rom size          : %u %s\n", hardware->dmi.bios.rom_size,
+		hardware->dmi.bios.rom_size_unit);
+
+    for (int i = 0; i < BIOS_CHAR_NB_ELEMENTS; i++) {
+	if (((bool *) (&hardware->dmi.bios.characteristics))[i] == true) {
+	    more_printf(" %s\n", bios_charac_strings[i]);
+	}
+    }
+    for (int i = 0; i < BIOS_CHAR_X1_NB_ELEMENTS; i++) {
+	if (((bool *) (&hardware->dmi.bios.characteristics_x1))[i] == true) {
+	    more_printf(" %s\n", bios_charac_x1_strings[i]);
+	}
+    }
+
+    for (int i = 0; i < BIOS_CHAR_X2_NB_ELEMENTS; i++) {
+	if (((bool *) (&hardware->dmi.bios.characteristics_x2))[i] == true) {
+	    more_printf(" %s\n", bios_charac_x2_strings[i]);
+	}
+    }
+
+}
+
+static void show_dmi_chassis(int argc __unused, char **argv __unused,
+			     struct s_hardware *hardware)
+{
+    if (hardware->dmi.chassis.filled == false) {
+	more_printf("chassis information not found on your system, see "
+		    "`show list' to see which module is available.\n");
+	return;
+    }
+    reset_more_printf();
+    more_printf("Chassis\n");
+    more_printf(" Manufacturer       : %s\n",
+		hardware->dmi.chassis.manufacturer);
+    more_printf(" Type               : %s\n", hardware->dmi.chassis.type);
+    more_printf(" Lock               : %s\n", hardware->dmi.chassis.lock);
+    more_printf(" Version            : %s\n", hardware->dmi.chassis.version);
+    more_printf(" Serial             : %s\n", hardware->dmi.chassis.serial);
+    more_printf(" Asset Tag          : %s\n",
+		del_multi_spaces(hardware->dmi.chassis.asset_tag));
+    more_printf(" Boot up state      : %s\n",
+		hardware->dmi.chassis.boot_up_state);
+    more_printf(" Power supply state : %s\n",
+		hardware->dmi.chassis.power_supply_state);
+    more_printf(" Thermal state      : %s\n",
+		hardware->dmi.chassis.thermal_state);
+    more_printf(" Security Status    : %s\n",
+		hardware->dmi.chassis.security_status);
+    more_printf(" OEM Information    : %s\n",
+		hardware->dmi.chassis.oem_information);
+    more_printf(" Height             : %u\n", hardware->dmi.chassis.height);
+    more_printf(" NB Power Cords     : %u\n",
+		hardware->dmi.chassis.nb_power_cords);
+}
+
+static void show_dmi_ipmi(int argc __unused, char **argv __unused,
+			  struct s_hardware *hardware)
+{
+    if (hardware->dmi.ipmi.filled == false) {
+	more_printf("IPMI module not available\n");
+	return;
+    }
+    reset_more_printf();
+    more_printf("IPMI\n");
+    more_printf(" Interface Type     : %s\n",
+		hardware->dmi.ipmi.interface_type);
+    more_printf(" Specification Ver. : %u.%u\n",
+		hardware->dmi.ipmi.major_specification_version,
+		hardware->dmi.ipmi.minor_specification_version);
+    more_printf(" I2C Slave Address  : 0x%02x\n",
+		hardware->dmi.ipmi.I2C_slave_address);
+    more_printf(" Nv Storage Address : %u\n", hardware->dmi.ipmi.nv_address);
+    uint32_t high = hardware->dmi.ipmi.base_address >> 32;
+    uint32_t low = hardware->dmi.ipmi.base_address & 0xFFFF;
+    more_printf(" Base Address       : %08X%08X\n", high, (low & ~1));
+    more_printf(" IRQ                : %d\n", hardware->dmi.ipmi.irq);
+}
+
+static void show_dmi_battery(int argc __unused, char **argv __unused,
+			     struct s_hardware *hardware)
+{
+    if (hardware->dmi.battery.filled == false) {
+	more_printf("battery information not found on your system, see "
+		    "`show list' to see which module is available.\n");
+	return;
+    }
+    reset_more_printf();
+    more_printf("Battery \n");
+    more_printf(" Vendor             : %s\n",
+		hardware->dmi.battery.manufacturer);
+    more_printf(" Manufacture Date   : %s\n",
+		hardware->dmi.battery.manufacture_date);
+    more_printf(" Serial             : %s\n", hardware->dmi.battery.serial);
+    more_printf(" Name               : %s\n", hardware->dmi.battery.name);
+    more_printf(" Chemistry          : %s\n", hardware->dmi.battery.chemistry);
+    more_printf(" Design Capacity    : %s\n",
+		hardware->dmi.battery.design_capacity);
+    more_printf(" Design Voltage     : %s\n",
+		hardware->dmi.battery.design_voltage);
+    more_printf(" SBDS               : %s\n", hardware->dmi.battery.sbds);
+    more_printf(" SBDS Manuf. Date   : %s\n",
+		hardware->dmi.battery.sbds_manufacture_date);
+    more_printf(" SBDS Chemistry     : %s\n",
+		hardware->dmi.battery.sbds_chemistry);
+    more_printf(" Maximum Error      : %s\n",
+		hardware->dmi.battery.maximum_error);
+    more_printf(" OEM Info           : %s\n", hardware->dmi.battery.oem_info);
+}
+
+static void show_dmi_cpu(int argc __unused, char **argv __unused,
+			 struct s_hardware *hardware)
+{
+    if (hardware->dmi.processor.filled == false) {
+	more_printf("processor information not found on your system, see "
+		    "`show list' to see which module is available.\n");
+	return;
+    }
+    reset_more_printf();
+    more_printf("CPU\n");
+    more_printf(" Socket Designation : %s\n",
+		hardware->dmi.processor.socket_designation);
+    more_printf(" Type               : %s\n", hardware->dmi.processor.type);
+    more_printf(" Family             : %s\n", hardware->dmi.processor.family);
+    more_printf(" Manufacturer       : %s\n",
+		hardware->dmi.processor.manufacturer);
+    more_printf(" Version            : %s\n", hardware->dmi.processor.version);
+    more_printf(" External Clock     : %u\n",
+		hardware->dmi.processor.external_clock);
+    more_printf(" Max Speed          : %u\n",
+		hardware->dmi.processor.max_speed);
+    more_printf(" Current Speed      : %u\n",
+		hardware->dmi.processor.current_speed);
+    more_printf(" Cpu Type           : %u\n",
+		hardware->dmi.processor.signature.type);
+    more_printf(" Cpu Family         : %u\n",
+		hardware->dmi.processor.signature.family);
+    more_printf(" Cpu Model          : %u\n",
+		hardware->dmi.processor.signature.model);
+    more_printf(" Cpu Stepping       : %u\n",
+		hardware->dmi.processor.signature.stepping);
+    more_printf(" Cpu Minor Stepping : %u\n",
+		hardware->dmi.processor.signature.minor_stepping);
+    more_printf("Voltage             : %d.%02d\n",
+                hardware->dmi.processor.voltage_mv / 1000,
+                hardware->dmi.processor.voltage_mv -
+                ((hardware->dmi.processor.voltage_mv / 1000) * 1000));
+    more_printf(" Status             : %s\n", hardware->dmi.processor.status);
+    more_printf(" Upgrade            : %s\n", hardware->dmi.processor.upgrade);
+    more_printf(" Cache L1 Handle    : %s\n", hardware->dmi.processor.cache1);
+    more_printf(" Cache L2 Handle    : %s\n", hardware->dmi.processor.cache2);
+    more_printf(" Cache L3 Handle    : %s\n", hardware->dmi.processor.cache3);
+    more_printf(" Serial             : %s\n", hardware->dmi.processor.serial);
+    more_printf(" Part Number        : %s\n",
+		hardware->dmi.processor.part_number);
+    if (hardware->dmi.processor.core_count != 0)
+        more_printf(" Cores Count        : %d\n", hardware->dmi.processor.core_count);
+    if (hardware->dmi.processor.core_enabled != 0)
+        more_printf(" Cores Enabled      : %d\n", hardware->dmi.processor.core_enabled);
+    if (hardware->dmi.processor.thread_count != 0)
+        more_printf(" Threads Count      : %d\n", hardware->dmi.processor.thread_count);
+
+    more_printf(" ID                 : %s\n", hardware->dmi.processor.id);
+    for (int i = 0; i < PROCESSOR_FLAGS_ELEMENTS; i++) {
+	if (((bool *) (&hardware->dmi.processor.cpu_flags))[i] == true) {
+	    more_printf(" %s\n", cpu_flags_strings[i]);
+	}
+    }
+}
+
+void show_dmi_memory_bank(int argc, char **argv, struct s_hardware *hardware)
+{
+    int bank = -1;
+
+    /* Sanitize arguments */
+    if (argc > 0)
+	bank = strtol(argv[0], (char **)NULL, 10);
+
+    if (errno == ERANGE || bank < 0) {
+	more_printf("This bank number is incorrect\n");
+	return;
+    }
+
+    if ((bank >= hardware->dmi.memory_count) || (bank < 0)) {
+	more_printf("Bank %d number doesn't exist\n", bank);
+	return;
+    }
+    if (hardware->dmi.memory[bank].filled == false) {
+	more_printf("Bank %d doesn't contain any information\n", bank);
+	return;
+    }
+
+    reset_more_printf();
+    more_printf("Memory Bank %d\n", bank);
+    more_printf(" Form Factor  : %s\n", hardware->dmi.memory[bank].form_factor);
+    more_printf(" Type         : %s\n", hardware->dmi.memory[bank].type);
+    more_printf(" Type Detail  : %s\n", hardware->dmi.memory[bank].type_detail);
+    more_printf(" Speed        : %s\n", hardware->dmi.memory[bank].speed);
+    more_printf(" Size         : %s\n", hardware->dmi.memory[bank].size);
+    more_printf(" Device Set   : %s\n", hardware->dmi.memory[bank].device_set);
+    more_printf(" Device Loc.  : %s\n",
+		hardware->dmi.memory[bank].device_locator);
+    more_printf(" Bank Locator : %s\n",
+		hardware->dmi.memory[bank].bank_locator);
+    more_printf(" Total Width  : %s\n", hardware->dmi.memory[bank].total_width);
+    more_printf(" Data Width   : %s\n", hardware->dmi.memory[bank].data_width);
+    more_printf(" Error        : %s\n", hardware->dmi.memory[bank].error);
+    more_printf(" Vendor       : %s\n",
+		hardware->dmi.memory[bank].manufacturer);
+    more_printf(" Serial       : %s\n", hardware->dmi.memory[bank].serial);
+    more_printf(" Asset Tag    : %s\n", hardware->dmi.memory[bank].asset_tag);
+    more_printf(" Part Number  : %s\n", hardware->dmi.memory[bank].part_number);
+}
+
+static void show_dmi_cache(int argc, char **argv, struct s_hardware *hardware)
+{
+    if (!hardware->dmi.cache_count) {
+	more_printf("cache information not found on your system, see "
+		    "`show list' to see which module is available.\n");
+	return;
+    }
+
+    int cache = strtol(argv[0], NULL, 10);
+
+    if (argc != 1 || cache > hardware->dmi.cache_count) {
+	more_printf("show cache [0-%d]\n", hardware->dmi.cache_count - 1);
+	return;
+    }
+
+    reset_more_printf();
+
+    more_printf("Cache Information #%d\n", cache);
+    more_printf("  Socket Designation    : %s\n",
+		hardware->dmi.cache[cache].socket_designation);
+    more_printf("  Configuration         : %s\n",
+		hardware->dmi.cache[cache].configuration);
+    more_printf("  Operational Mode      : %s\n",
+		hardware->dmi.cache[cache].mode);
+    more_printf("  Location              : %s\n",
+		hardware->dmi.cache[cache].location);
+    more_printf("  Installed Size        : %u KB",
+		hardware->dmi.cache[cache].installed_size);
+    more_printf("\n");
+    more_printf("  Maximum Size          : %u KB",
+		hardware->dmi.cache[cache].max_size);
+    more_printf("\n");
+    more_printf("  Supported SRAM Types  : %s",
+		hardware->dmi.cache[cache].supported_sram_types);
+    more_printf("\n");
+    more_printf("  Installed SRAM Type   : %s",
+		hardware->dmi.cache[cache].installed_sram_types);
+    more_printf("\n");
+    more_printf("  Speed                 : %u ns",
+		hardware->dmi.cache[cache].speed);
+    more_printf("\n");
+    more_printf("  Error Correction Type : %s\n",
+		hardware->dmi.cache[cache].error_correction_type);
+    more_printf("  System Type           : %s\n",
+		hardware->dmi.cache[cache].system_type);
+    more_printf("  Associativity         : %s\n",
+		hardware->dmi.cache[cache].associativity);
+}
+
+void show_dmi_memory_module(int argc, char **argv, struct s_hardware *hardware)
+{
+    int module = -1;
+
+    /* Sanitize arguments */
+    if (argc > 0)
+	module = strtol(argv[0], (char **)NULL, 10);
+
+    if (errno == ERANGE || module < 0) {
+	more_printf("This module number is incorrect\n");
+	return;
+    }
+
+    if ((module >= hardware->dmi.memory_module_count) || (module < 0)) {
+	more_printf("Module number %d doesn't exist\n", module);
+	return;
+    }
+
+    if (hardware->dmi.memory_module[module].filled == false) {
+	more_printf("Module %d doesn't contain any information\n", module);
+	return;
+    }
+
+    reset_more_printf();
+    more_printf("Memory Module %d\n", module);
+    more_printf(" Socket Designation : %s\n",
+		hardware->dmi.memory_module[module].socket_designation);
+    more_printf(" Bank Connections   : %s\n",
+		hardware->dmi.memory_module[module].bank_connections);
+    more_printf(" Current Speed      : %s\n",
+		hardware->dmi.memory_module[module].speed);
+    more_printf(" Type               : %s\n",
+		hardware->dmi.memory_module[module].type);
+    more_printf(" Installed Size     : %s\n",
+		hardware->dmi.memory_module[module].installed_size);
+    more_printf(" Enabled Size       : %s\n",
+		hardware->dmi.memory_module[module].enabled_size);
+    more_printf(" Error Status       : %s\n",
+		hardware->dmi.memory_module[module].error_status);
+}
+
+void main_show_dmi(int argc __unused, char **argv __unused,
+		   struct s_hardware *hardware)
+{
+
+    if (hardware->is_dmi_valid == false) {
+	more_printf("No valid DMI table found, exiting.\n");
+	return;
+    }
+    reset_more_printf();
+    more_printf("DMI Table version %u.%u found\n",
+		hardware->dmi.dmitable.major_version,
+		hardware->dmi.dmitable.minor_version);
+
+    show_dmi_modules(0, NULL, hardware);
+}
+
+void show_dmi_memory_modules(int argc __unused, char **argv __unused,
+			     struct s_hardware *hardware)
+{
+    /* Do we have so display unpopulated banks ? */
+    int show_free_banks = 1;
+
+    more_printf("Memory Size   : %lu MB (%lu KB)\n",
+		(hardware->detected_memory_size + (1 << 9)) >> 10,
+		hardware->detected_memory_size);
+
+    if ((hardware->dmi.memory_count <= 0)
+	&& (hardware->dmi.memory_module_count <= 0)) {
+	more_printf("No memory bank found\n");
+	return;
+    }
+
+    /* Sanitize arguments */
+    if (argc > 0) {
+	/* When we display a summary, there is no need to show the unpopulated banks
+	 * The first argv is set to define this behavior
+	 */
+	show_free_banks = strtol(argv[0], NULL, 10);
+	if (errno == ERANGE || show_free_banks < 0 || show_free_banks > 1)
+	    goto usage;
+    }
+
+    reset_more_printf();
+    /* If type 17 is available */
+    if (hardware->dmi.memory_count > 0) {
+	char bank_number[255];
+	more_printf("Memory Banks\n");
+	for (int i = 0; i < hardware->dmi.memory_count; i++) {
+	    if (hardware->dmi.memory[i].filled == true) {
+		memset(bank_number, 0, sizeof(bank_number));
+		snprintf(bank_number, sizeof(bank_number), "%d ", i);
+		if (show_free_banks == false) {
+		    if (strncmp(hardware->dmi.memory[i].size, "Free", 4))
+			more_printf(" bank %02d      : %s %s@%s\n",
+				    i, hardware->dmi.memory[i].size,
+				    hardware->dmi.memory[i].type,
+				    hardware->dmi.memory[i].speed);
+		} else {
+		    more_printf(" bank %02d      : %s %s@%s\n", i,
+				hardware->dmi.memory[i].size,
+				hardware->dmi.memory[i].type,
+				hardware->dmi.memory[i].speed);
+		}
+	    }
+	}
+    } else if (hardware->dmi.memory_module_count > 0) {
+	/* Let's use type 6 as a fallback of type 17 */
+	more_printf("Memory Modules\n");
+	for (int i = 0; i < hardware->dmi.memory_module_count; i++) {
+	    if (hardware->dmi.memory_module[i].filled == true) {
+		more_printf(" module %02d    : %s %s@%s\n", i,
+			    hardware->dmi.memory_module[i].enabled_size,
+			    hardware->dmi.memory_module[i].type,
+			    hardware->dmi.memory_module[i].speed);
+	    }
+	}
+    }
+
+    return;
+    //printf("Type 'show bank<bank_number>' for more details.\n");
+
+usage:
+    more_printf("show memory <clear screen? <show free banks?>>\n");
+    return;
+}
+
+void show_dmi_oem_strings(int argc __unused, char **argv __unused,
+			  struct s_hardware *hardware)
+{
+    reset_more_printf();
+
+    if (strlen(hardware->dmi.oem_strings))
+	more_printf("OEM Strings\n%s", hardware->dmi.oem_strings);
+}
+
+void show_dmi_hardware_security(int argc __unused, char **argv __unused,
+				struct s_hardware *hardware)
+{
+    reset_more_printf();
+
+    if (!hardware->dmi.hardware_security.filled)
+	return;
+
+    more_printf("Hardware Security\n");
+    more_printf("  Power-On Password Status      : %s\n",
+		hardware->dmi.hardware_security.power_on_passwd_status);
+    more_printf("  Keyboard Password Status      : %s\n",
+		hardware->dmi.hardware_security.keyboard_passwd_status);
+    more_printf("  Administrator Password Status : %s\n",
+		hardware->dmi.hardware_security.administrator_passwd_status);
+    more_printf("  Front Panel Reset Status      : %s\n",
+		hardware->dmi.hardware_security.front_panel_reset_status);
+}
+
+struct cli_callback_descr list_dmi_show_modules[] = {
+    {
+     .name = CLI_DMI_BASE_BOARD,
+     .exec = show_dmi_base_board,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_BIOS,
+     .exec = show_dmi_bios,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_BATTERY,
+     .exec = show_dmi_battery,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_CHASSIS,
+     .exec = show_dmi_chassis,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_MEMORY,
+     .exec = show_dmi_memory_modules,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_MEMORY_BANK,
+     .exec = show_dmi_memory_bank,
+     .nomodule = false,
+     },
+    {
+     .name = "module",
+     .exec = show_dmi_memory_module,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_PROCESSOR,
+     .exec = show_dmi_cpu,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_SYSTEM,
+     .exec = show_dmi_system,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_OEM,
+     .exec = show_dmi_oem_strings,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_SECURITY,
+     .exec = show_dmi_hardware_security,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_IPMI,
+     .exec = show_dmi_ipmi,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_CACHE,
+     .exec = show_dmi_cache,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI_LIST,
+     .exec = show_dmi_modules,
+     .nomodule = false,
+     },
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule = false,
+     },
+};
+
+struct cli_module_descr dmi_show_modules = {
+    .modules = list_dmi_show_modules,
+    .default_callback = main_show_dmi,
+};
+
+struct cli_mode_descr dmi_mode = {
+    .mode = DMI_MODE,
+    .name = CLI_DMI,
+    .default_modules = NULL,
+    .show_modules = &dmi_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-hdt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-hdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-hdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,491 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer - 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 <string.h>
+#include <stdlib.h>
+#include <syslinux/config.h>
+#include <syslinux/reboot.h>
+
+#include "hdt-menu.h"
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+/**
+ * cli_clear_screen - clear (erase) the entire screen
+ **/
+static void cli_clear_screen(int argc __unused, char **argv __unused,
+			     struct s_hardware *hardware __unused)
+{
+    clear_screen();
+}
+
+/**
+ * main_show_modes - show availables modes
+ **/
+static void main_show_modes(int argc __unused, char **argv __unused,
+			    struct s_hardware *hardware __unused)
+{
+    int i = 0;
+
+    reset_more_printf();
+    more_printf("Available modes:\n");
+    while (list_modes[i]) {
+	printf("%s ", list_modes[i]->name);
+	i++;
+    }
+    more_printf("\n");
+}
+
+/**
+ * cli_set_mode - set the mode of the cli, in the cli
+ *
+ * The mode number must be supplied in argv, position 0.
+ **/
+static void cli_set_mode(int argc, char **argv, struct s_hardware *hardware)
+{
+    cli_mode_t new_mode;
+
+    reset_more_printf();
+    if (argc <= 0) {
+	more_printf("Which mode?\n");
+	return;
+    }
+
+    /*
+     * Note! argv[0] is a string representing the mode, we need the
+     * equivalent cli_mode_t to pass it to set_mode.
+     */
+    new_mode = mode_s_to_mode_t(argv[0]);
+    set_mode(new_mode, hardware);
+}
+
+/**
+ * do_exit - shared helper to exit a mode
+ **/
+static void do_exit(int argc __unused, char **argv __unused,
+		    struct s_hardware *hardware)
+{
+    int new_mode = HDT_MODE;
+
+    switch (hdt_cli.mode) {
+    case HDT_MODE:
+	new_mode = EXIT_MODE;
+	break;
+    default:
+	new_mode = HDT_MODE;
+	break;
+    }
+
+    dprintf("CLI DEBUG: Switching from mode %d to mode %d\n", hdt_cli.mode,
+	    new_mode);
+    set_mode(new_mode, hardware);
+}
+
+/**
+ * show_cli_help - shared helper to show available commands
+ **/
+static void show_cli_help(int argc __unused, char **argv __unused,
+			  struct s_hardware *hardware __unused)
+{
+    int j = 0;
+    struct cli_mode_descr *current_mode;
+    struct cli_callback_descr *associated_module = NULL;
+
+    find_cli_mode_descr(hdt_cli.mode, &current_mode);
+
+    more_printf("Available commands are:\n");
+
+    /* List first default modules of the mode */
+    if (current_mode->default_modules && current_mode->default_modules->modules) {
+	while (current_mode->default_modules->modules[j].name) {
+	    printf("%s ", current_mode->default_modules->modules[j].name);
+	    j++;
+	}
+	printf("\n");
+    }
+
+    /* List finally the default modules of the hdt mode */
+    if (current_mode->mode != hdt_mode.mode &&
+	hdt_mode.default_modules && hdt_mode.default_modules->modules) {
+	j = 0;
+	while (hdt_mode.default_modules->modules[j].name) {
+	    /*
+	     * Any default command that is present in hdt mode but
+	     * not in the current mode is available. A default
+	     * command can be redefined in the current mode though.
+	     * This next call test this use case: if it is
+	     * overwritten, do not print it again.
+	     */
+	    find_cli_callback_descr(hdt_mode.default_modules->modules[j].name,
+				    current_mode->default_modules,
+				    &associated_module);
+	    if (associated_module == NULL)
+		printf("%s ", hdt_mode.default_modules->modules[j].name);
+	    j++;
+	}
+	printf("\n");
+    }
+
+    /* List secondly the show modules of the mode */
+    if (current_mode->show_modules && current_mode->show_modules->modules) {
+	more_printf("\nshow commands:\n");
+	j = 0;
+	while (current_mode->show_modules->modules[j].name) {
+	    printf("%s ", current_mode->show_modules->modules[j].name);
+	    j++;
+	}
+	printf("\n");
+    }
+
+    /* List thirdly the set modules of the mode */
+    if (current_mode->set_modules && current_mode->set_modules->modules) {
+	more_printf("\nset commands:\n");
+	j = 0;
+	while (current_mode->set_modules->modules[j].name) {
+	    printf("%s ", current_mode->set_modules->modules[j].name);
+	    j++;
+	}
+	printf("\n");
+    }
+
+
+    printf("\n");
+    main_show_modes(argc, argv, hardware);
+}
+
+/**
+ * show_cli_help - shared helper to show available commands
+ **/
+static void goto_menu(int argc __unused, char **argv __unused,
+		      struct s_hardware *hardware)
+{
+    char version_string[256];
+    snprintf(version_string, sizeof version_string, "%s %s (%s)",
+	     PRODUCT_NAME, VERSION, CODENAME);
+    start_menu_mode(hardware, version_string);
+    return;
+}
+
+/**
+ * main_show_summary - give an overview of the system
+ **/
+void main_show_summary(int argc __unused, char **argv __unused,
+		       struct s_hardware *hardware)
+{
+    reset_more_printf();
+    clear_screen();
+    main_show_cpu(argc, argv, hardware);
+    if (hardware->is_dmi_valid) {
+	more_printf("System\n");
+	more_printf(" Manufacturer : %s\n", hardware->dmi.system.manufacturer);
+	more_printf(" Product Name : %s\n", hardware->dmi.system.product_name);
+	more_printf(" Serial       : %s\n", hardware->dmi.system.serial);
+	more_printf("Bios\n");
+	more_printf(" Version      : %s\n", hardware->dmi.bios.version);
+	more_printf(" Release      : %s\n", hardware->dmi.bios.release_date);
+	more_printf("Memory Size   : %lu MB (%lu KB)\n",
+		    (hardware->detected_memory_size + (1 << 9)) >> 10,
+		    hardware->detected_memory_size);
+    }
+    main_show_pci(argc, argv, hardware);
+
+    if (hardware->is_pxe_valid)
+	main_show_pxe(argc, argv, hardware);
+
+    main_show_kernel(argc, argv, hardware);
+}
+
+void main_show_hdt(int argc __unused, char **argv __unused,
+		   struct s_hardware *hardware __unused)
+{
+    reset_more_printf();
+    more_printf("HDT\n");
+    more_printf(" Product        : %s\n", PRODUCT_NAME);
+    more_printf(" Version        : %s (%s)\n", VERSION, CODENAME);
+    more_printf(" Website        : %s\n", WEBSITE_URL);
+    more_printf(" IRC Channel    : %s\n", IRC_CHANNEL);
+    more_printf(" Mailing List   : %s\n", CONTACT);
+    more_printf(" Project Leader : %s\n", AUTHOR);
+    more_printf(" Core Developer : %s\n", CORE_DEVELOPER);
+    char *contributors[NB_CONTRIBUTORS] = CONTRIBUTORS;
+    for (int c = 0; c < NB_CONTRIBUTORS; c++) {
+	more_printf(" Contributor    : %s\n", contributors[c]);
+    }
+}
+
+/**
+ * do_reboot - reboot the system
+ **/
+static void do_reboot(int argc __unused, char **argv __unused,
+		      struct s_hardware *hardware)
+{
+    (void) hardware;
+    /* Let's call the internal rebooting call */
+    syslinux_reboot(1);
+}
+
+/**
+ * do_dump - dump info
+ **/
+static void do_dump(int argc __unused, char **argv __unused,
+		      struct s_hardware *hardware)
+{
+    dump(hardware);
+}
+
+/**
+ * do_sleep - sleep a number of milliseconds
+ **/ 
+static void do_sleep(int argc , char **argv ,
+		      struct s_hardware *hardware)
+{
+   (void) hardware;
+   if (argc != 1) return;
+   more_printf("Sleep %d milliseconds\n",atoi(argv[0]));
+   msleep(atoi(argv[0]));
+}
+
+/**
+ * do_display - display an image to user
+ **/
+static void do_display(int argc , char **argv ,
+		      struct s_hardware *hardware)
+{
+   (void) hardware;
+   if ((argc != 1) || (vesamode == false)) return;
+   more_printf("Display %s file\n",argv[0]);
+   vesacon_load_background(argv[0]);
+}
+
+/**
+ * do_say - say message to user
+ **/
+static void do_say(int argc , char **argv ,
+		      struct s_hardware *hardware)
+{
+   (void) hardware;
+   if (argc == 0) return;
+
+   char text_to_say[255]={0};
+   int arg=0;
+#if DEBUG
+   for (int i=0; i<argc;i++) dprintf("SAY: arg[%d]={%s}\n",i,argv[i]);
+#endif
+   char *argument = strchr(argv[arg],'`');
+   if ( argument != NULL) {
+	argument++;
+   	strcat(text_to_say, argument);
+
+   	while ((strchr(argument, '`') == NULL) && (arg+1<argc)) {
+		arg++;
+		argument = (char *)argv[arg];
+		strcat(text_to_say, " ");
+		strcat(text_to_say, argument);
+   	}
+    
+	/* Removing last ` if any */
+    	char *last_quote = strrchr(text_to_say,'`');
+    	if ( last_quote != NULL ) {
+	*last_quote='\0';
+	dprintf("SAY CMD = [%s]\n",text_to_say);	   
+    	}
+
+  	more_printf("%s\n",text_to_say);
+  }
+}
+
+/* Default hdt mode */
+struct cli_callback_descr list_hdt_default_modules[] = {
+    {
+     .name = CLI_CLEAR,
+     .exec = cli_clear_screen,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_EXIT,
+     .exec = do_exit,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_HELP,
+     .exec = show_cli_help,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_MENU,
+     .exec = goto_menu,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_REBOOT,
+     .exec = do_reboot,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_HISTORY,
+     .exec = print_history,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DUMP,
+     .exec = do_dump,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_SAY,
+     .exec = do_say,
+     .nomodule = true,
+     },
+    {
+     .name = CLI_DISPLAY,
+     .exec = do_display,
+     .nomodule = true,
+     },
+    {
+     .name = CLI_SLEEP,
+     .exec = do_sleep,
+     .nomodule = true,
+     },
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule = false},
+};
+
+struct cli_callback_descr list_hdt_show_modules[] = {
+    {
+     .name = CLI_SUMMARY,
+     .exec = main_show_summary,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_PCI,
+     .exec = main_show_pci,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DMI,
+     .exec = main_show_dmi,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_CPU,
+     .exec = main_show_cpu,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_DISK,
+     .exec = disks_summary,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_PXE,
+     .exec = main_show_pxe,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_SYSLINUX,
+     .exec = main_show_syslinux,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_KERNEL,
+     .exec = main_show_kernel,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_VESA,
+     .exec = main_show_vesa,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_HDT,
+     .exec = main_show_hdt,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_VPD,
+     .exec = main_show_vpd,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_MEMORY,
+     .exec = show_dmi_memory_modules,
+     .nomodule = false,
+     },
+    {
+     .name = CLI_ACPI,
+     .exec = main_show_acpi,
+     .nomodule = false,
+     },
+    {
+     .name = "modes",
+     .exec = main_show_modes,
+     .nomodule = false,
+     },
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule = false,
+     },
+};
+
+struct cli_callback_descr list_hdt_set_modules[] = {
+    {
+     .name = CLI_MODE,
+     .exec = cli_set_mode,
+     .nomodule = false,
+     },
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule = false,
+     },
+};
+
+struct cli_module_descr hdt_default_modules = {
+    .modules = list_hdt_default_modules,
+};
+
+struct cli_module_descr hdt_show_modules = {
+    .modules = list_hdt_show_modules,
+    .default_callback = main_show_summary,
+};
+
+struct cli_module_descr hdt_set_modules = {
+    .modules = list_hdt_set_modules,
+};
+
+struct cli_mode_descr hdt_mode = {
+    .mode = HDT_MODE,
+    .name = CLI_HDT,
+    .default_modules = &hdt_default_modules,
+    .show_modules = &hdt_show_modules,
+    .set_modules = &hdt_set_modules,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-kernel.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-kernel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-kernel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,148 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+void main_show_kernel(int argc __unused, char **argv __unused,
+		      struct s_hardware *hardware)
+{
+    char buffer[1024] = {0};
+    struct pci_device *pci_device;
+    bool found = false;
+    char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+
+    reset_more_printf();
+    more_printf("Kernel modules\n");
+
+// more_printf(" PCI device no: %d \n", p->pci_device_pos);
+
+    if ((hardware->modules_pcimap_return_code == -ENOMODULESPCIMAP)
+	&& (hardware->modules_alias_return_code == -ENOMODULESALIAS)) {
+	more_printf(" modules.pcimap and modules.alias files are missing\n");
+	return;
+    }
+
+    /* For every detected pci device, compute its submenu */
+    for_each_pci_func(pci_device, hardware->pci_domain) {
+	memset(kernel_modules, 0, sizeof kernel_modules);
+
+	for (int kmod = 0;
+	     kmod < pci_device->dev_info->linux_kernel_module_count; kmod++) {
+	    if (kmod > 0) {
+		strncat(kernel_modules, " | ", 3);
+	    }
+	    strncat(kernel_modules,
+		    pci_device->dev_info->linux_kernel_module[kmod],
+		    LINUX_KERNEL_MODULE_SIZE - 1);
+	}
+
+	if ((pci_device->dev_info->linux_kernel_module_count > 0)
+	    && (!strstr(buffer, kernel_modules))) {
+	    found = true;
+	    if (pci_device->dev_info->linux_kernel_module_count > 1)
+		strncat(buffer, "(", 1);
+	    strncat(buffer, kernel_modules, sizeof(kernel_modules));
+	    if (pci_device->dev_info->linux_kernel_module_count > 1)
+		strncat(buffer, ")", 1);
+	    strncat(buffer, " # ", 3);
+	}
+
+    }
+    if (found == true) {
+	strncat(buffer, "\n", 1);
+	more_printf("%s", buffer);
+    }
+}
+
+static void show_kernel_modules(int argc __unused, char **argv __unused,
+				struct s_hardware *hardware)
+{
+    struct pci_device *pci_device;
+    char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+    char modules[MAX_PCI_CLASSES][256] = {{0}};
+    char category_name[MAX_PCI_CLASSES][256] = {{0}};
+
+    if (hardware->pci_ids_return_code == -ENOPCIIDS) {
+	more_printf(" Missing pci.ids, we can't compute the list\n");
+	return;
+    }
+
+    if (hardware->modules_pcimap_return_code == -ENOMODULESPCIMAP) {
+	more_printf(" Missing modules.pcimap, we can't compute the list\n");
+	return;
+    }
+
+    reset_more_printf();
+    for_each_pci_func(pci_device, hardware->pci_domain) {
+	memset(kernel_modules, 0, sizeof kernel_modules);
+
+	for (int kmod = 0;
+	     kmod < pci_device->dev_info->linux_kernel_module_count; kmod++) {
+	    strncat(kernel_modules,
+		    pci_device->dev_info->linux_kernel_module[kmod],
+		    LINUX_KERNEL_MODULE_SIZE - 1);
+	    strncat(kernel_modules, " ", 1);
+	}
+
+	if ((pci_device->dev_info->linux_kernel_module_count > 0)
+	    && (!strstr(modules[pci_device->class[2]], kernel_modules))) {
+	    strncat(modules[pci_device->class[2]], kernel_modules,
+		    sizeof(kernel_modules));
+	    snprintf(category_name[pci_device->class[2]],
+		     sizeof(category_name[pci_device->class[2]]),
+		     "%s", pci_device->dev_info->category_name);
+	}
+    }
+    /* Print the found items */
+    for (int i = 0; i < MAX_PCI_CLASSES; i++) {
+	if (strlen(category_name[i]) > 1) {
+	    more_printf("%s : %s\n", category_name[i], modules[i]);
+	}
+    }
+}
+
+struct cli_module_descr kernel_show_modules = {
+    .modules = NULL,
+    .default_callback = show_kernel_modules,
+};
+
+struct cli_mode_descr kernel_mode = {
+    .mode = KERNEL_MODE,
+    .name = CLI_KERNEL,
+    .default_modules = NULL,
+    .show_modules = &kernel_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-memory.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-memory.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-memory.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,139 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer - 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 <memory.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+static void show_memory_e820(int argc __unused, char **argv __unused,
+			     struct s_hardware *hardware __unused)
+{
+    struct e820entry map[E820MAX];
+    unsigned long memsize = 0;
+    int count = 0;
+    char type[14];
+
+    detect_memory_e820(map, E820MAX, &count);
+    memsize = memsize_e820(map, count);
+    reset_more_printf();
+    more_printf("Detected RAM                       : %lu MiB (%lu KiB)\n",
+		(memsize + (1 << 9)) >> 10, memsize);
+    more_printf("BIOS-provided physical RAM e820 map:\n");
+    for (int i = 0; i < count; i++) {
+	get_type(map[i].type, type, 14);
+	more_printf("%016llx - %016llx %016llx (%s)\n",
+		    map[i].addr, map[i].size, map[i].addr + map[i].size,
+		    remove_spaces(type));
+    }
+    struct e820entry nm[E820MAX];
+
+    /* Clean up, adjust and copy the BIOS-supplied E820-map. */
+    int nr = sanitize_e820_map(map, nm, count);
+
+    more_printf("\n");
+    more_printf("Sanitized e820 map:\n");
+    for (int i = 0; i < nr; i++) {
+	get_type(nm[i].type, type, 14);
+	more_printf("%016llx - %016llx %016llx (%s)\n",
+		    nm[i].addr, nm[i].size, nm[i].addr + nm[i].size,
+		    remove_spaces(type));
+    }
+}
+
+static void show_memory_e801(int argc __unused, char **argv __unused,
+			     struct s_hardware *hardware __unused)
+{
+    int mem_low, mem_high = 0;
+
+    reset_more_printf();
+    if (detect_memory_e801(&mem_low, &mem_high)) {
+	more_printf("e801 bogus!\n");
+    } else {
+	more_printf("Detected RAM : %d MiB(%d KiB)\n",
+		    (mem_low >> 10) + (mem_high >> 4),
+		    mem_low + (mem_high << 6));
+	more_printf("e801 details : %d Kb (%d MiB) - %d Kb (%d MiB)\n", mem_low,
+		    mem_low >> 10, mem_high << 6, mem_high >> 4);
+    }
+}
+
+static void show_memory_88(int argc __unused, char **argv __unused,
+			   struct s_hardware *hardware __unused)
+{
+    int mem_size = 0;
+
+    reset_more_printf();
+    if (detect_memory_88(&mem_size)) {
+	more_printf("8800h bogus!\n");
+    } else {
+	more_printf("8800h memory size: %d Kb (%d MiB)\n", mem_size,
+		    mem_size >> 10);
+    }
+}
+
+struct cli_callback_descr list_memory_show_modules[] = {
+    {
+     .name = "e820",
+     .exec = show_memory_e820,
+     .nomodule=false,
+     },
+    {
+     .name = "e801",
+     .exec = show_memory_e801,
+     .nomodule=false,
+     },
+    {
+     .name = "88",
+     .exec = show_memory_88,
+     .nomodule=false,
+     },
+    {
+     .name = CLI_DMI_MEMORY_BANK,
+     .exec = show_dmi_memory_bank,
+     .nomodule=false,
+     },
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule=false,
+     },
+};
+
+struct cli_module_descr memory_show_modules = {
+    .modules = list_memory_show_modules,
+    .default_callback = show_dmi_memory_modules,
+};
+
+struct cli_mode_descr memory_mode = {
+    .mode = MEMORY_MODE,
+    .name = CLI_MEMORY,
+    .default_modules = NULL,
+    .show_modules = &memory_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-pci.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-pci.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-pci.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,294 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+void main_show_pci(int argc __unused, char **argv __unused,
+		   struct s_hardware *hardware)
+{
+    reset_more_printf();
+    more_printf("PCI\n");
+    more_printf(" NB Devices   : %d\n", hardware->nb_pci_devices);
+}
+
+static void show_pci_device(int argc, char **argv, struct s_hardware *hardware)
+{
+    int i = 0;
+    struct pci_device *pci_device = NULL, *temp_pci_device;
+    int pcidev = -1;
+    bool nopciids = false;
+    bool nomodulespcimap = false;
+    bool nomodulesalias = false;
+    bool nomodulesfiles = false;
+    char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+    int bus = 0, slot = 0, func = 0;
+
+    reset_more_printf();
+    /* Sanitize arguments */
+    if (argc <= 0) {
+	more_printf("show device <number>\n");
+	return;
+    } else
+	pcidev = strtol(argv[0], (char **)NULL, 10);
+
+    if (errno == ERANGE) {
+	more_printf("This PCI device number is incorrect\n");
+	return;
+    }
+    if ((pcidev > hardware->nb_pci_devices) || (pcidev <= 0)) {
+	more_printf("PCI device %d doesn't exist\n", pcidev);
+	return;
+    }
+    if (hardware->pci_ids_return_code == -ENOPCIIDS) {
+	nopciids = true;
+    }
+    if (hardware->modules_pcimap_return_code == -ENOMODULESPCIMAP) {
+	nomodulespcimap = true;
+    }
+    if (hardware->modules_alias_return_code == -ENOMODULESALIAS) {
+	nomodulesalias = true;
+    }
+    nomodulesfiles = nomodulespcimap && nomodulesalias;
+    for_each_pci_func(temp_pci_device, hardware->pci_domain) {
+	i++;
+	if (i == pcidev) {
+	    bus = __pci_bus;
+	    slot = __pci_slot;
+	    func = __pci_func;
+	    pci_device = temp_pci_device;
+	}
+    }
+
+    if (pci_device == NULL) {
+	more_printf("We were enabled to find PCI device %d\n", pcidev);
+	return;
+    }
+
+    memset(kernel_modules, 0, sizeof kernel_modules);
+    for (int kmod = 0;
+	 kmod < pci_device->dev_info->linux_kernel_module_count; kmod++) {
+	if (kmod > 0) {
+	    strncat(kernel_modules, " | ", 3);
+	}
+	strncat(kernel_modules,
+		pci_device->dev_info->linux_kernel_module[kmod],
+		LINUX_KERNEL_MODULE_SIZE - 1);
+    }
+    if (pci_device->dev_info->linux_kernel_module_count == 0)
+	strlcpy(kernel_modules, "unknown", 7);
+
+    more_printf("PCI Device %d\n", pcidev);
+
+    if (nopciids == false) {
+	more_printf("Vendor Name   : %s\n", pci_device->dev_info->vendor_name);
+	more_printf("Product Name  : %s\n", pci_device->dev_info->product_name);
+	more_printf("Class Name    : %s\n", pci_device->dev_info->class_name);
+    }
+
+    if (nomodulesfiles == false) {
+	more_printf("Kernel module : %s\n", kernel_modules);
+    }
+
+    more_printf("Vendor ID     : %04x\n", pci_device->vendor);
+    more_printf("Product ID    : %04x\n", pci_device->product);
+    more_printf("SubVendor ID  : %04x\n", pci_device->sub_vendor);
+    more_printf("SubProduct ID : %04x\n", pci_device->sub_product);
+    more_printf("Class ID      : %02x.%02x.%02x\n", pci_device->class[2],
+		pci_device->class[1], pci_device->class[0]);
+    more_printf("Revision      : %02x\n", pci_device->revision);
+    if ((pci_device->dev_info->irq > 0)
+	&& (pci_device->dev_info->irq < 255))
+	more_printf("IRQ           : %0d\n", pci_device->dev_info->irq);
+    more_printf("Latency       : %0d\n", pci_device->dev_info->latency);
+    more_printf("PCI Bus       : %02d\n", bus);
+    more_printf("PCI Slot      : %02d\n", slot);
+    more_printf("PCI Func      : %02d\n", func);
+
+    if (hardware->is_pxe_valid == true) {
+	if ((hardware->pxe.pci_device != NULL)
+	    && (hardware->pxe.pci_device == pci_device)) {
+	    more_printf("Mac Address   : %s\n", hardware->pxe.mac_addr);
+	    more_printf("PXE           : Current boot device\n");
+	}
+    }
+}
+
+static void show_pci_devices(int argc __unused, char **argv __unused,
+			     struct s_hardware *hardware)
+{
+    int i = 1;
+    struct pci_device *pci_device;
+    char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+    bool nopciids = false;
+    bool nomodulespcimap = false;
+    bool nomodulesalias = false;
+    bool nomodulesfile = false;
+    char first_line[81];
+    char second_line[81];
+
+    reset_more_printf();
+    more_printf("%d PCI devices detected\n", hardware->nb_pci_devices);
+
+    if (hardware->pci_ids_return_code == -ENOPCIIDS) {
+	nopciids = true;
+    }
+    if (hardware->modules_pcimap_return_code == -ENOMODULESPCIMAP) {
+	nomodulespcimap = true;
+    }
+    if (hardware->modules_pcimap_return_code == -ENOMODULESALIAS) {
+	nomodulesalias = true;
+    }
+
+    nomodulesfile = nomodulespcimap && nomodulesalias;
+
+    /* For every detected pci device, compute its submenu */
+    for_each_pci_func(pci_device, hardware->pci_domain) {
+	memset(kernel_modules, 0, sizeof kernel_modules);
+	for (int kmod = 0;
+	     kmod < pci_device->dev_info->linux_kernel_module_count; kmod++) {
+	    if (kmod > 0) {
+		strncat(kernel_modules, " | ", 3);
+	    }
+	    strncat(kernel_modules,
+		    pci_device->dev_info->linux_kernel_module[kmod],
+		    LINUX_KERNEL_MODULE_SIZE - 1);
+	}
+	if (pci_device->dev_info->linux_kernel_module_count == 0)
+	    strlcpy(kernel_modules, "unknown", 7);
+
+	if (nopciids == false) {
+	    snprintf(first_line, sizeof(first_line),
+		     "%02d: %s %s \n", i,
+		     pci_device->dev_info->vendor_name,
+		     pci_device->dev_info->product_name);
+	    if (nomodulesfile == false)
+		snprintf(second_line, sizeof(second_line),
+			 "    # %-25s # Kmod: %s\n",
+			 pci_device->dev_info->class_name, kernel_modules);
+	    else
+		snprintf(second_line, sizeof(second_line),
+			 "    # %-25s # ID:%04x:%04x[%04x:%04x]\n",
+			 pci_device->dev_info->class_name,
+			 pci_device->vendor,
+			 pci_device->product,
+			 pci_device->sub_vendor, pci_device->sub_product);
+
+	    more_printf("%s", first_line);
+	    more_printf("%s", second_line);
+	    more_printf("\n");
+	} else if (nopciids == true) {
+	    if (nomodulesfile == true) {
+		more_printf("%02d: %04x:%04x [%04x:%04x] \n",
+			    i, pci_device->vendor,
+			    pci_device->product,
+			    pci_device->sub_vendor, pci_device->sub_product);
+	    } else {
+		more_printf
+		    ("%02d: %04x:%04x [%04x:%04x] Kmod:%s\n", i,
+		     pci_device->vendor, pci_device->product,
+		     pci_device->sub_vendor,
+		     pci_device->sub_product, kernel_modules);
+	    }
+	}
+	i++;
+    }
+}
+
+static void show_pci_irq(int argc __unused, char **argv __unused,
+			 struct s_hardware *hardware)
+{
+    struct pci_device *pci_device;
+    bool nopciids = false;
+
+    reset_more_printf();
+    more_printf("%d PCI devices detected\n", hardware->nb_pci_devices);
+    more_printf("IRQ : product\n");
+    more_printf("-------------\n");
+
+    if (hardware->pci_ids_return_code == -ENOPCIIDS) {
+	nopciids = true;
+    }
+
+    /* For every detected pci device, compute its submenu */
+    for_each_pci_func(pci_device, hardware->pci_domain) {
+	/* Only display valid IRQs */
+	if ((pci_device->dev_info->irq > 0)
+	    && (pci_device->dev_info->irq < 255)) {
+	    if (nopciids == false) {
+		more_printf("%02d  : %s %s \n",
+			    pci_device->dev_info->irq,
+			    pci_device->dev_info->vendor_name,
+			    pci_device->dev_info->product_name);
+	    } else {
+		more_printf("%02d  : %04x:%04x [%04x:%04x] \n",
+			    pci_device->dev_info->irq,
+			    pci_device->vendor,
+			    pci_device->product,
+			    pci_device->sub_vendor, pci_device->sub_product);
+	    }
+	}
+    }
+}
+
+struct cli_callback_descr list_pci_show_modules[] = {
+    {
+     .name = CLI_IRQ,
+     .exec = show_pci_irq,
+     .nomodule=false,
+     },
+    {
+     .name = CLI_PCI_DEVICE,
+     .exec = show_pci_device,
+     .nomodule=false,
+     },
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule=false,
+     },
+};
+
+struct cli_module_descr pci_show_modules = {
+    .modules = list_pci_show_modules,
+    .default_callback = show_pci_devices,
+};
+
+struct cli_mode_descr pci_mode = {
+    .mode = PCI_MODE,
+    .name = CLI_PCI,
+    .default_modules = NULL,
+    .show_modules = &pci_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-pxe.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-pxe.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-pxe.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,97 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <syslinux/pxe.h>
+#include <syslinux/config.h>
+#include <sys/gpxe.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+void main_show_pxe(int argc __unused, char **argv __unused,
+		   struct s_hardware *hardware)
+{
+    char buffer[81];
+    memset(buffer, 0, sizeof(81));
+    reset_more_printf();
+    if (hardware->sv->filesystem != SYSLINUX_FS_PXELINUX) {
+	more_printf("You are not currently using PXELINUX\n");
+	return;
+    }
+
+    more_printf("PXE\n");
+    if (hardware->is_pxe_valid == false) {
+	more_printf(" No valid PXE ROM found\n");
+	return;
+    }
+
+    struct s_pxe *p = &hardware->pxe;
+    more_printf(" PCI device no: %d \n", p->pci_device_pos);
+
+    if (hardware->pci_ids_return_code == -ENOPCIIDS || (p->pci_device == NULL)) {
+	snprintf(buffer, sizeof(buffer),
+		 " PCI ID       : %04x:%04x[%04x:%04X] rev(%02x)\n",
+		 p->vendor_id, p->product_id, p->subvendor_id,
+		 p->subproduct_id, p->rev);
+	snprintf(buffer, sizeof(buffer),
+		 " PCI Bus pos. : %02x:%02x.%02x\n", p->pci_bus,
+		 p->pci_dev, p->pci_func);
+	more_printf("%s", buffer);
+    } else {
+	snprintf(buffer, sizeof(buffer), " Manufacturer : %s \n",
+		 p->pci_device->dev_info->vendor_name);
+	more_printf("%s", buffer);
+	snprintf(buffer, sizeof(buffer), " Product      : %s \n",
+		 p->pci_device->dev_info->product_name);
+	more_printf("%s", buffer);
+    }
+    more_printf(" Addresses    : %d.%d.%d.%d @ %s\n", p->ip_addr[0],
+		p->ip_addr[1], p->ip_addr[2], p->ip_addr[3], p->mac_addr);
+
+    if (is_gpxe())
+	more_printf(" gPXE Detected: Yes\n")
+    else
+	more_printf(" gPXE Detected: No\n");
+}
+
+struct cli_module_descr pxe_show_modules = {
+    .modules = NULL,
+    .default_callback = main_show_pxe,
+};
+
+struct cli_mode_descr pxe_mode = {
+    .mode = PXE_MODE,
+    .name = CLI_PXE,
+    .default_modules = NULL,
+    .show_modules = &pxe_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-syslinux.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-syslinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-syslinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,62 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <syslinux/pxe.h>
+#include <syslinux/config.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+void main_show_syslinux(int argc __unused, char **argv __unused,
+			struct s_hardware *hardware)
+{
+    reset_more_printf();
+    more_printf("SYSLINUX\n");
+    more_printf(" Bootloader : %s\n", hardware->syslinux_fs);
+    more_printf(" Version    : %s\n", hardware->sv->version_string);
+    more_printf(" Version    : %u\n", hardware->sv->version);
+    more_printf(" Max API    : %u\n", hardware->sv->max_api);
+    more_printf(" Copyright  : %s\n", hardware->sv->copyright_string);
+}
+
+struct cli_module_descr syslinux_show_modules = {
+    .modules = NULL,
+    .default_callback = main_show_syslinux,
+};
+
+struct cli_mode_descr syslinux_mode = {
+    .mode = SYSLINUX_MODE,
+    .name = CLI_SYSLINUX,
+    .default_modules = NULL,
+    .show_modules = &syslinux_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-vesa.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-vesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-vesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,145 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+void main_show_vesa(int argc __unused, char **argv __unused,
+		    struct s_hardware *hardware)
+{
+    reset_more_printf();
+    if (hardware->is_vesa_valid == false) {
+	more_printf("No VESA BIOS detected\n");
+	return;
+    }
+    more_printf("VESA\n");
+    more_printf(" Vesa version : %d.%d\n", hardware->vesa.major_version,
+		hardware->vesa.minor_version);
+    more_printf(" Vendor       : %s\n", hardware->vesa.vendor);
+    more_printf(" Product      : %s\n", hardware->vesa.product);
+    more_printf(" Product rev. : %s\n", hardware->vesa.product_revision);
+    more_printf(" Software rev.: %d\n", hardware->vesa.software_rev);
+    more_printf(" Memory (KB)  : %d\n", hardware->vesa.total_memory * 64);
+    more_printf(" Modes        : %d\n", hardware->vesa.vmi_count);
+}
+
+static void show_vesa_modes(int argc __unused, char **argv __unused,
+			    struct s_hardware *hardware)
+{
+    reset_more_printf();
+    if (hardware->is_vesa_valid == false) {
+	more_printf("No VESA BIOS detected\n");
+	return;
+    }
+    more_printf(" ResH. x ResV x Bits : vga= : Vesa Mode\n");
+    more_printf("----------------------------------------\n");
+
+    for (int i = 0; i < hardware->vesa.vmi_count; i++) {
+	struct vesa_mode_info *mi = &hardware->vesa.vmi[i].mi;
+	/*
+	 * Sometimes, vesa bios reports 0x0 modes.
+	 * We don't need to display that ones.
+	 */
+	if ((mi->h_res == 0) || (mi->v_res == 0))
+	    continue;
+	more_printf("%5u %5u    %3u     %3d     0x%04x\n",
+		    mi->h_res, mi->v_res, mi->bpp,
+		    hardware->vesa.vmi[i].mode + 0x200,
+		    hardware->vesa.vmi[i].mode);
+    }
+}
+
+static void enable_vesa(int argc __unused, char **argv __unused,
+			struct s_hardware *hardware)
+{
+    vesamode = true;
+    max_console_lines = MAX_VESA_CLI_LINES;
+    init_console(hardware);
+}
+
+static void disable_vesa(int argc __unused, char **argv __unused,
+			 struct s_hardware *hardware)
+{
+    vesamode = false;
+    max_console_lines = MAX_CLI_LINES;
+    init_console(hardware);
+}
+
+struct cli_callback_descr list_vesa_show_modules[] = {
+    {
+     .name = CLI_MODES,
+     .exec = show_vesa_modes,
+     .nomodule=false,
+     },
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule=false,
+     },
+};
+
+struct cli_callback_descr list_vesa_commands[] = {
+    {
+     .name = CLI_ENABLE,
+     .exec = enable_vesa,
+     .nomodule=false,
+     },
+    {
+     .name = CLI_DISABLE,
+     .exec = disable_vesa,
+     .nomodule=false,
+     },
+
+    {
+     .name = NULL,
+     .exec = NULL,
+     .nomodule=false,
+     },
+};
+
+struct cli_module_descr vesa_show_modules = {
+    .modules = list_vesa_show_modules,
+    .default_callback = main_show_vesa,
+};
+
+struct cli_module_descr vesa_commands = {
+    .modules = list_vesa_commands,
+    .default_callback = enable_vesa,
+};
+
+struct cli_mode_descr vesa_mode = {
+    .mode = VESA_MODE,
+    .name = CLI_VESA,
+    .default_modules = &vesa_commands,
+    .show_modules = &vesa_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-vpd.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-vpd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli-vpd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,80 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer - 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 <string.h>
+#include <vpd/vpd.h>
+
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+void main_show_vpd(int argc __unused, char **argv __unused,
+		   struct s_hardware *hardware)
+{
+    reset_more_printf();
+
+    if (!hardware->is_vpd_valid) {
+	more_printf("No VPD structure detected.\n");
+	return;
+    }
+
+    more_printf("VPD present at address : %s\n", hardware->vpd.base_address);
+    if (strlen(hardware->vpd.bios_build_id) > 0)
+	more_printf("Bios Build ID                 : %s\n",
+		    hardware->vpd.bios_build_id);
+    if (strlen(hardware->vpd.bios_release_date) > 0)
+	more_printf("Bios Release Date             : %s\n",
+		    hardware->vpd.bios_release_date);
+    if (strlen(hardware->vpd.bios_version) > 0)
+	more_printf("Bios Version                  : %s\n",
+		    hardware->vpd.bios_version);
+    if (strlen(hardware->vpd.default_flash_filename) > 0)
+	more_printf("Default Flash Filename        : %s\n",
+		    hardware->vpd.default_flash_filename);
+    if (strlen(hardware->vpd.box_serial_number) > 0)
+	more_printf("Box Serial Number             : %s\n",
+		    hardware->vpd.box_serial_number);
+    if (strlen(hardware->vpd.motherboard_serial_number) > 0)
+	more_printf("Motherboard Serial Number     : %s\n",
+		    hardware->vpd.motherboard_serial_number);
+    if (strlen(hardware->vpd.machine_type_model) > 0)
+	more_printf("Machine Type/Model            : %s\n",
+		    hardware->vpd.machine_type_model);
+}
+
+struct cli_module_descr vpd_show_modules = {
+    .modules = NULL,
+    .default_callback = main_show_vpd,
+};
+
+struct cli_mode_descr vpd_mode = {
+    .mode = VPD_MODE,
+    .name = CLI_VPD,
+    .default_modules = NULL,
+    .show_modules = &vpd_show_modules,
+    .set_modules = NULL,
+};
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,1141 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <syslinux/config.h>
+#include <getkey.h>
+#include <acpi/acpi.h>
+#include "hdt-cli.h"
+#include "hdt-common.h"
+
+struct cli_mode_descr *list_modes[] = {
+    &hdt_mode,
+    &dmi_mode,
+    &syslinux_mode,
+    &pxe_mode,
+    &kernel_mode,
+    &cpu_mode,
+    &pci_mode,
+    &vesa_mode,
+    &disk_mode,
+    &vpd_mode,
+    &memory_mode,
+    &acpi_mode,
+    NULL,
+};
+
+/*
+ * .aliases = {"q", "quit"} won't work since it is an array of pointers, not an
+ * array of variables. There is no easy way around it besides declaring the arrays of
+ * strings first.
+ */
+const char *exit_aliases[] = { "q", "quit" };
+const char *help_aliases[] = { "h", "?" };
+
+/* List of aliases */
+struct cli_alias hdt_aliases[] = {
+    {
+     .command = CLI_EXIT,
+     .nb_aliases = 2,
+     .aliases = exit_aliases,
+     },
+    {
+     .command = CLI_HELP,
+     .nb_aliases = 2,
+     .aliases = help_aliases,
+     },
+};
+
+struct cli_mode_descr *current_mode;
+int autocomplete_backlog;
+
+struct autocomplete_list {
+    char autocomplete_token[MAX_LINE_SIZE];
+    struct autocomplete_list *next;
+};
+struct autocomplete_list *autocomplete_head = NULL;
+struct autocomplete_list *autocomplete_tail = NULL;
+struct autocomplete_list *autocomplete_last_seen = NULL;
+
+static void autocomplete_add_token_to_list(const char *token)
+{
+    struct autocomplete_list *new = malloc(sizeof(struct autocomplete_list));
+
+    strlcpy(new->autocomplete_token, token, sizeof(new->autocomplete_token));
+    new->next = NULL;
+    autocomplete_backlog++;
+
+    if (autocomplete_tail != NULL)
+	autocomplete_tail->next = new;
+    if (autocomplete_head == NULL)
+	autocomplete_head = new;
+    autocomplete_tail = new;
+}
+
+static void autocomplete_destroy_list(void)
+{
+    struct autocomplete_list *tmp = NULL;
+
+    while (autocomplete_head != NULL) {
+	tmp = autocomplete_head->next;
+	free(autocomplete_head);
+	autocomplete_head = tmp;
+    }
+    autocomplete_backlog = 0;
+    autocomplete_tail = NULL;
+    autocomplete_last_seen = NULL;
+}
+
+/**
+ * set_mode - set the current mode of the cli
+ * @mode:	mode to set
+ *
+ * Unlike cli_set_mode, this function is not used by the cli directly.
+ **/
+void set_mode(cli_mode_t mode, struct s_hardware *hardware)
+{
+    int i = 0;
+
+    switch (mode) {
+    case EXIT_MODE:
+	hdt_cli.mode = mode;
+	break;
+    case HDT_MODE:
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_HDT);
+	break;
+    case PXE_MODE:
+	if (hardware->sv->filesystem != SYSLINUX_FS_PXELINUX) {
+	    more_printf("You are not currently using PXELINUX\n");
+	    break;
+	}
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_PXE);
+	break;
+    case KERNEL_MODE:
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_KERNEL);
+	break;
+    case SYSLINUX_MODE:
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_SYSLINUX);
+	break;
+    case VESA_MODE:
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_VESA);
+	break;
+    case PCI_MODE:
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_PCI);
+	break;
+    case CPU_MODE:
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_CPU);
+	break;
+    case DMI_MODE:
+	if (!hardware->is_dmi_valid) {
+	    more_printf("No valid DMI table found, exiting.\n");
+	    break;
+	}
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_DMI);
+	break;
+    case DISK_MODE:
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_DISK);
+	break;
+    case VPD_MODE:
+	if (!hardware->is_vpd_valid) {
+	    more_printf("No valid VPD table found, exiting.\n");
+	    break;
+	}
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_VPD);
+	break;
+    case MEMORY_MODE:
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_MEMORY);
+	break;
+    case ACPI_MODE:
+	hdt_cli.mode = mode;
+	snprintf(hdt_cli.prompt, sizeof(hdt_cli.prompt), "%s> ", CLI_ACPI);
+	break;
+    default:
+	/* Invalid mode */
+	more_printf("Unknown mode, please choose among:\n");
+	while (list_modes[i]) {
+	    more_printf("\t%s\n", list_modes[i]->name);
+	    i++;
+	}
+    }
+
+    find_cli_mode_descr(hdt_cli.mode, &current_mode);
+    /* There is not cli_mode_descr struct for the exit mode */
+    if (current_mode == NULL && hdt_cli.mode != EXIT_MODE) {
+	/* Shouldn't get here... */
+	more_printf("!!! BUG: Mode '%d' unknown.\n", hdt_cli.mode);
+    }
+}
+
+/**
+ * mode_s_to_mode_t - given a mode string, return the cli_mode_t representation
+ **/
+cli_mode_t mode_s_to_mode_t(char *name)
+{
+    int i = 0;
+
+    while (list_modes[i]) {
+	if (!strncmp(name, list_modes[i]->name, sizeof(list_modes[i]->name)))
+	    break;
+	i++;
+    }
+
+    if (!list_modes[i])
+	return INVALID_MODE;
+    else
+	return list_modes[i]->mode;
+}
+
+/**
+ * find_cli_mode_descr - find the cli_mode_descr struct associated to a mode
+ * @mode:	mode to look for
+ * @mode_found:	store the mode if found, NULL otherwise
+ *
+ * Given a mode name, return a pointer to the associated cli_mode_descr
+ * structure.
+ * Note: the current mode name is stored in hdt_cli.mode.
+ **/
+void find_cli_mode_descr(cli_mode_t mode, struct cli_mode_descr **mode_found)
+{
+    int i = 0;
+
+    while (list_modes[i] && list_modes[i]->mode != mode)
+	i++;
+
+    /* Shouldn't get here... */
+    if (!list_modes[i])
+	*mode_found = NULL;
+    else
+	*mode_found = list_modes[i];
+}
+
+/**
+ * expand_aliases - resolve aliases mapping
+ * @line:	command line to parse
+ * @command:	first token in the line
+ * @module:	second token in the line
+ * @argc:	number of arguments
+ * @argv:	array of arguments
+ *
+ * We maintain a small list of static alises to enhance user experience.
+ * Only commands can be aliased (first token). Otherwise it can become really hairy...
+ **/
+static void expand_aliases(char *line __unused, char **command, char **module,
+			   int *argc, char **argv)
+{
+    struct cli_mode_descr *mode;
+    int i, j;
+
+    find_cli_mode_descr(mode_s_to_mode_t(*command), &mode);
+    if (mode != NULL && *module == NULL) {
+	/*
+	 * The user specified a mode instead of `set mode...', e.g.
+	 * `dmi' instead of `set mode dmi'
+	 */
+
+	/* *argv is NULL since *module is NULL */
+	*argc = 1;
+	*argv = malloc(*argc * sizeof(char *));
+	argv[0] = malloc((sizeof(*command) + 1) * sizeof(char));
+	strlcpy(argv[0], *command, sizeof(*command) + 1);
+	dprintf("CLI DEBUG: ALIAS %s ", *command);
+
+	strlcpy(*command, CLI_SET, sizeof(CLI_SET));	/* set */
+
+	*module = malloc(sizeof(CLI_MODE) * sizeof(char));
+	strlcpy(*module, CLI_MODE, sizeof(CLI_MODE));	/* mode */
+
+	dprintf("--> %s %s %s\n", *command, *module, argv[0]);
+	goto out;
+    }
+
+    /* Simple aliases mapping a single command to another one */
+    for (i = 0; i < MAX_ALIASES; i++) {
+	for (j = 0; j < hdt_aliases[i].nb_aliases; j++) {
+	    if (!strncmp(*command, hdt_aliases[i].aliases[j],
+			 sizeof(hdt_aliases[i].aliases[j]))) {
+		dprintf("CLI DEBUG: ALIAS %s ", *command);
+		strlcpy(*command, hdt_aliases[i].command,
+			sizeof(hdt_aliases[i].command) + 1);
+		dprintf("--> %s\n", *command);
+		goto out;	/* Don't allow chaining aliases */
+	    }
+	}
+    }
+    return;
+
+out:
+    dprintf("CLI DEBUG: New parameters:\n");
+    dprintf("CLI DEBUG: command = %s\n", *command);
+    dprintf("CLI DEBUG: module  = %s\n", *module);
+    dprintf("CLI DEBUG: argc    = %d\n", *argc);
+    for (i = 0; i < *argc; i++)
+	dprintf("CLI DEBUG: argv[%d] = %s\n", i, argv[0]);
+    return;
+}
+
+/**
+ * parse_command_line - low level parser for the command line
+ * @line:	command line to parse
+ * @command:	first token in the line
+ * @module:	second token in the line
+ * @argc:	number of arguments
+ * @argv:	array of arguments
+ *
+ * The format of the command line is:
+ *	<main command> [<module on which to operate> [<args>]]
+ *	command is always malloc'ed (even for an empty line)
+ **/
+static void parse_command_line(char *line, char **command, char **module,
+			       int *argc, char **argv)
+{
+    int argc_iter = 0, args_pos = 0, token_found = 0, token_len = 0;
+    int args_len = 0;
+    char *pch = NULL, *pch_next = NULL, *tmp_pch_next = NULL;
+
+    *command = NULL;
+    *module = NULL;
+    *argc = 0;
+
+    pch = line;
+    while (pch != NULL) {
+	pch_next = strchr(pch + 1, ' ');
+	tmp_pch_next = pch_next;
+
+	/*
+	 * Skip whitespaces if the user entered
+	 * 'set   mode        foo' for 'set mode foo'
+	 *  ^   ^
+	 *  |___|___ pch
+	 *      |___ pch_next <- wrong!
+	 *
+	 *  We still keep the position into tmp_pch_next to compute
+	 *  the lenght of the current token.
+	 */
+	while (pch_next != NULL && !strncmp(pch_next, CLI_SPACE, 1))
+	    pch_next++;
+
+	/* End of line guaranteed to be zeroed */
+	if (pch_next == NULL) {
+	    token_len = (int)(strchr(pch + 1, '\0') - pch);
+	    args_len = token_len;
+	} else {
+	    token_len = (int)(tmp_pch_next - pch);
+	    args_len = (int)(pch_next - pch);
+	}
+
+	if (token_found == 0) {
+	    /* Main command to execute */
+	    *command = malloc((token_len + 1) * sizeof(char));
+	    strlcpy(*command, pch, token_len);
+	    (*command)[token_len] = '\0';
+	    dprintf("CLI DEBUG parse: command = %s\n", *command);
+	    args_pos += args_len;
+	} else if (token_found == 1) {
+	    /* Module */
+	    *module = malloc((token_len + 1) * sizeof(char));
+	    strlcpy(*module, pch, token_len);
+	    (*module)[token_len] = '\0';
+	    dprintf("CLI DEBUG parse: module  = %s\n", *module);
+	    args_pos += args_len;
+	} else
+	    (*argc)++;
+
+	token_found++;
+	pch = pch_next;
+    }
+    dprintf("CLI DEBUG parse: argc    = %d\n", *argc);
+
+    /* Skip arguments handling if none is supplied */
+    if (!*argc)
+	return;
+
+    /* Transform the arguments string into an array */
+    *argv = malloc(*argc * sizeof(char *));
+    pch = strtok(line + args_pos, CLI_SPACE);
+    while (pch != NULL) {
+	dprintf("CLI DEBUG parse: argv[%d] = %s\n", argc_iter, pch);
+	argv[argc_iter] = malloc(strlen(pch) * sizeof(char));
+	strlcpy(argv[argc_iter], pch, strlen(pch));
+	argc_iter++;
+	pch = strtok(NULL, CLI_SPACE);
+	/*
+	 * strtok(NULL, CLI_SPACE) over a stream of spaces
+	 * will return an empty string
+	 */
+	while (pch != NULL && !strncmp(pch, "", 1))
+	    pch = strtok(NULL, CLI_SPACE);
+    }
+}
+
+/**
+ * find_cli_callback_descr - find a callback in a list of modules
+ * @module_name:	Name of the module to find
+ * @modules_list:	Lits of modules among which to find @module_name
+ * @module_found:	Pointer to the matched module, NULL if not found
+ *
+ * Given a module name and a list of possible modules, find the corresponding
+ * module structure that matches the module name and store it in @module_found.
+ **/
+void find_cli_callback_descr(const char *module_name,
+			     struct cli_module_descr *modules_list,
+			     struct cli_callback_descr **module_found)
+{
+    int modules_iter = 0;
+
+    if (modules_list == NULL)
+	goto not_found;
+
+    /* Find the callback to execute */
+    while (modules_list->modules[modules_iter].name &&
+	   strcmp(module_name, modules_list->modules[modules_iter].name) != 0)
+	modules_iter++;
+
+    if (modules_list->modules[modules_iter].name) {
+	*module_found = &(modules_list->modules[modules_iter]);
+	dprintf("CLI DEBUG: module %s found\n", (*module_found)->name);
+	return;
+    }
+
+not_found:
+    *module_found = NULL;
+    return;
+}
+
+/**
+ * autocomplete_command - print matching commands
+ * @command:	Beginning of the command
+ *
+ * Given a string @command, print all availables commands starting with
+ * @command. Commands are found within the list of commands for the current
+ * mode and the hdt mode (if the current mode is not hdt).
+ **/
+static void autocomplete_command(char *command)
+{
+    int j = 0;
+    struct cli_callback_descr *associated_module = NULL;
+
+    /* First take care of the two special commands: 'show' and 'set' */
+    if (strncmp(CLI_SHOW, command, strlen(command)) == 0) {
+	printf("%s\n", CLI_SHOW);
+	autocomplete_add_token_to_list(CLI_SHOW);
+    }
+    if (strncmp(CLI_SET, command, strlen(command)) == 0) {
+	printf("%s\n", CLI_SET);
+	autocomplete_add_token_to_list(CLI_SET);
+    }
+
+    /*
+     * Then, go through the modes for the special case
+     *      '<mode>' -> 'set mode <mode>'
+     */
+    while (list_modes[j]) {
+	if (strncmp(list_modes[j]->name, command, strlen(command)) == 0) {
+	    printf("%s\n", list_modes[j]->name);
+	    autocomplete_add_token_to_list(list_modes[j]->name);
+	}
+	j++;
+    }
+
+    /*
+     * Let's go now through the list of default_modules for the current mode
+     * (single token commands for the current_mode)
+     */
+    j = 0;
+    if (current_mode->default_modules && current_mode->default_modules->modules) {
+	while (current_mode->default_modules->modules[j].name) {
+	    if (strncmp(current_mode->default_modules->modules[j].name,
+			command, strlen(command)) == 0) {
+		printf("%s\n", current_mode->default_modules->modules[j].name);
+		autocomplete_add_token_to_list(current_mode->default_modules->
+					       modules[j].name);
+	    }
+	    j++;
+	}
+    }
+
+    /*
+     * Finally, if the current_mode is not hdt, list the available
+     * default_modules of hdt (these are always available from any mode).
+     */
+    if (current_mode->mode == HDT_MODE)
+	return;
+
+    if (!hdt_mode.default_modules || !hdt_mode.default_modules->modules)
+	return;
+
+    j = 0;
+    while (hdt_mode.default_modules &&
+	   hdt_mode.default_modules->modules[j].name) {
+	/*
+	 * Any default command that is present in hdt mode but
+	 * not in the current mode is available. A default
+	 * command can be redefined in the current mode though.
+	 * This next call tests this use case: if it is
+	 * overwritten, do not print it again.
+	 */
+	find_cli_callback_descr(hdt_mode.default_modules->modules[j].name,
+				current_mode->default_modules,
+				&associated_module);
+	if (associated_module == NULL &&
+	    strncmp(command,
+		    hdt_mode.default_modules->modules[j].name,
+		    strlen(command)) == 0) {
+	    printf("%s\n", hdt_mode.default_modules->modules[j].name);
+	    autocomplete_add_token_to_list(hdt_mode.default_modules->modules[j].
+					   name);
+	}
+	j++;
+    }
+}
+
+/**
+ * autocomplete_module - print matching modules
+ * @command:	Command on the command line (not NULL)
+ * @module:	Beginning of the module
+ *
+ * Given a command @command and a string @module, print all availables modules
+ * starting with @module for command @command. Commands are found within the
+ * list of commands for the current mode and the hdt mode (if the current mode
+ * is not hdt).
+ **/
+static void autocomplete_module(char *command, char *module)
+{
+    int j = 0;
+    char autocomplete_full_line[MAX_LINE_SIZE];
+
+    if (strncmp(CLI_SHOW, command, strlen(command)) == 0) {
+	if (!current_mode->show_modules || !current_mode->show_modules->modules)
+	    return;
+
+	while (current_mode->show_modules->modules[j].name) {
+	    if (strncmp(current_mode->show_modules->modules[j].name,
+			module, strlen(module)) == 0) {
+		printf("%s\n", current_mode->show_modules->modules[j].name);
+		sprintf(autocomplete_full_line, "%s %s",
+			CLI_SHOW, current_mode->show_modules->modules[j].name);
+		autocomplete_add_token_to_list(autocomplete_full_line);
+	    }
+	    j++;
+	}
+    } else if (strncmp(CLI_SET, command, strlen(command)) == 0) {
+	j = 0;
+	if (!current_mode->set_modules || !current_mode->set_modules->modules)
+	    return;
+
+	while (current_mode->set_modules->modules[j].name) {
+	    if (strncmp(current_mode->set_modules->modules[j].name,
+			module, strlen(module)) == 0) {
+		printf("%s\n", current_mode->set_modules->modules[j].name);
+		sprintf(autocomplete_full_line, "%s %s",
+			CLI_SET, current_mode->set_modules->modules[j].name);
+		autocomplete_add_token_to_list(autocomplete_full_line);
+	    }
+	    j++;
+	}
+    }
+}
+
+/**
+ * autocomplete - find possible matches for a command line
+ * @line:	command line to parse
+ **/
+static void autocomplete(char *line)
+{
+    int i;
+    int argc = 0;
+    char *command = NULL, *module = NULL;
+    char **argv = NULL;
+
+    parse_command_line(line, &command, &module, &argc, argv);
+
+    dprintf("CLI DEBUG autocomplete: before checking args\n");
+    /* If the user specified arguments, there is nothing we can complete */
+    if (argc != 0)
+	goto out;
+
+    /* No argument, (the start of) a module has been specified */
+    if (module != NULL) {
+	autocomplete_module(command, module);
+	free(module);
+	goto out;
+    }
+
+    /* No argument, no module, (the start of) a command has been specified */
+    if (command != NULL) {
+	autocomplete_command(command);
+	free(command);
+	goto out;
+    }
+
+out:
+    /* Let's not forget to clean ourselves */
+    for (i = 0; i < argc; i++)
+	free(argv[i]);
+    if (argc > 0)
+	free(argv);
+    return;
+}
+
+/**
+ * exec_command - main logic to map the command line to callbacks
+ **/
+static void exec_command(char *line, struct s_hardware *hardware)
+{
+    int argc, i = 0;
+    char *command = NULL, *module = NULL;
+    char **argv = NULL;
+    struct cli_callback_descr *current_module = NULL;
+
+    /* This will allocate memory for command and module */
+    parse_command_line(line, &command, &module, &argc, argv);
+
+    dprintf("CLI DEBUG exec: Checking for aliases\n");
+    /*
+     * Expand shortcuts, if needed
+     * This will allocate memory for argc/argv
+     */
+    expand_aliases(line, &command, &module, &argc, argv);
+    
+    find_cli_callback_descr(command, current_mode->default_modules,
+				&current_module);
+
+    if ((module == NULL) || (current_module->nomodule == true)) {
+	dprintf("CLI DEBUG exec : single command detected\n");
+	/*
+	 * A single word was specified: look at the list of default
+	 * commands in the current mode to see if there is a match.
+	 * If not, it may be a generic function (exit, help, ...). These
+	 * are stored in the list of default commands of the hdt mode.
+	 */
+
+	/* First of all it the command doesn't need module, let's rework the arguments */
+	if ((current_module->nomodule == true) && ( module != NULL)) {
+		dprintf("CLI_DEBUG exec: Reworking arguments with argc=%d\n",argc);
+		char **new_argv=NULL;
+    		new_argv=malloc((argc + 2)*sizeof(char *));
+		for (int argc_iter=0; argc_iter<argc; argc_iter++) {
+			dprintf("CLI_DEBUG exec rework : copy %d to %d (%s)\n",argc_iter,argc_iter+1,argv[argc_iter]);
+			new_argv[argc_iter+1] = malloc(strlen(argv[argc_iter]));
+			strlcpy(new_argv[argc_iter+1], argv[argc_iter], strlen(argv[argc_iter]));
+			free(argv[argc_iter]);
+		}
+		new_argv[0] = malloc(strlen(module)*sizeof(char));
+		strlcpy(new_argv[0], module, strlen(module));
+		argc++;
+		free(argv);
+		argv=new_argv;
+	}
+
+	if (current_module != NULL)
+	    current_module->exec(argc, argv, hardware);
+	else if (!strncmp(command, CLI_SHOW, sizeof(CLI_SHOW) - 1) &&
+		 current_mode->show_modules != NULL &&
+		 current_mode->show_modules->default_callback != NULL)
+	    current_mode->show_modules->default_callback(argc, argv, hardware);
+	else if (!strncmp(command, CLI_SET, sizeof(CLI_SET) - 1) &&
+		 current_mode->set_modules != NULL &&
+		 current_mode->set_modules->default_callback != NULL)
+	    current_mode->set_modules->default_callback(argc, argv, hardware);
+	else {
+	    find_cli_callback_descr(command, hdt_mode.default_modules,
+				    &current_module);
+	    if (current_module != NULL)
+		current_module->exec(argc, argv, hardware);
+	    else
+		more_printf("unknown command: '%s'\n", command);
+	}
+    } else {
+	/*
+	 * A module has been specified! We now need to find the type of command.
+	 *
+	 * The syntax of the cli is the following:
+	 *    <type of command> <module on which to operate> <args>
+	 * e.g.
+	 *    dmi> show system
+	 *    dmi> show bank 1
+	 *    dmi> show memory 0 1
+	 *    pci> show device 12
+	 *    hdt> set mode dmi
+	 */
+	if (!strncmp(command, CLI_SHOW, sizeof(CLI_SHOW) - 1)) {
+	    dprintf("CLI DEBUG exec: %s command detected\n", CLI_SHOW);
+	    /* Look first for a 'show' callback in the current mode */
+	    find_cli_callback_descr(module, current_mode->show_modules,
+				    &current_module);
+	    /* Execute the callback, if found */
+	    if (current_module != NULL)
+		current_module->exec(argc, argv, hardware);
+	    else {
+		dprintf("CLI DEBUG exec: Looking for callback\n");
+		/* Look now for a 'show' callback in the hdt mode */
+		find_cli_callback_descr(module, hdt_mode.show_modules,
+					&current_module);
+		/* Execute the callback, if found */
+		if (current_module != NULL)
+		    current_module->exec(argc, argv, hardware);
+		else
+		    printf("unknown module: '%s'\n", module);
+	    }
+	} else if (!strncmp(command, CLI_SET, sizeof(CLI_SET) - 1)) {
+	    dprintf("CLI DEBUG exec : %s command detected\n", CLI_SET);
+	    /* Look now for a 'set' callback in the hdt mode */
+	    find_cli_callback_descr(module, current_mode->set_modules,
+				    &current_module);
+	    /* Execute the callback, if found */
+	    if (current_module != NULL)
+		current_module->exec(argc, argv, hardware);
+	    else {
+		/* Look now for a 'set' callback in the hdt mode */
+		find_cli_callback_descr(module, hdt_mode.set_modules,
+					&current_module);
+		/* Execute the callback, if found */
+		if (current_module != NULL)
+		    current_module->exec(argc, argv, hardware);
+		else
+		    printf("unknown module: '%s'\n", module);
+	    }
+	}
+    }
+
+    /* Let's not forget to clean ourselves */
+    if (command != NULL)
+	free(command);
+    if (module != NULL)
+	free(module);
+    for (i = 0; i < argc; i++)
+	free(argv[i]);
+    if (argc > 0)
+	free(argv);
+}
+
+static void reset_prompt(void)
+{
+    /* No need to display the prompt if we exit */
+    if (hdt_cli.mode != EXIT_MODE) {
+	printf("%s", hdt_cli.prompt);
+	/* Reset the line */
+	hdt_cli.cursor_pos = 0;
+    }
+}
+
+void start_auto_mode(struct s_hardware *hardware)
+{
+    char *mypch;
+    int nb_commands = 0;
+    char *commands[MAX_NB_AUTO_COMMANDS];
+
+    more_printf("\nEntering Auto mode\n");
+
+    /* Protecting the auto_label from the strtok modifications */
+    char *temp = strdup(hardware->auto_label);
+
+    /* Searching & saving all commands */
+    mypch = strtok(temp, AUTO_SEPARATOR);
+    while (mypch != NULL) {
+	if ((strlen(remove_spaces(mypch)) > 0) &&
+	    (remove_spaces(mypch)[0] != AUTO_SEPARATOR[0])) {
+	    nb_commands++;
+	    if ((commands[nb_commands] = malloc(AUTO_COMMAND_SIZE)) != NULL) {
+		sprintf(commands[nb_commands], "%s", remove_spaces(mypch));
+	    } else
+		nb_commands--;
+	}
+	mypch = strtok(NULL, AUTO_SEPARATOR);
+    }
+
+    free(temp);
+
+    /* Executing found commands */
+    for (int i = 1; i <= nb_commands; i++) {
+	if (commands[i]) {
+	    if (!quiet)
+		more_printf("%s%s\n", hdt_cli.prompt, commands[i]);
+	    exec_command(commands[i], hardware);
+	    free(commands[i]);
+	}
+    }
+
+    if (!quiet)
+	more_printf("\nExiting Auto mode\n");
+
+    more_printf("\n");
+}
+
+void print_history(int argc, char **argv, struct s_hardware * hardware)
+{
+    (void)argc;
+    (void)argv;
+    (void)hardware;
+
+    reset_more_printf();
+    for (int i = 1; i <= MAX_HISTORY_SIZE; i++) {
+	if (i == hdt_cli.history_pos) {
+	    more_printf("*%d:'%s'\n", i, hdt_cli.history[i]);
+	    continue;
+	}
+	if (strlen(hdt_cli.history[i]) == 0)
+	    continue;
+	more_printf(" %d:'%s'\n", i, hdt_cli.history[i]);
+    }
+}
+
+/* Code that manages the cli mode */
+void start_cli_mode(struct s_hardware *hardware)
+{
+    int current_key = 0;
+    int future_history_pos = 1;	/* position of the next position in the history */
+    int current_future_history_pos = 1;	/* Temp variable */
+    bool display_history = true;	/* Temp Variable */
+    char temp_command[MAX_LINE_SIZE];
+
+    hdt_cli.cursor_pos = 0;
+    memset(hdt_cli.history, 0, sizeof(hdt_cli.history));
+    hdt_cli.history_pos = 1;
+    hdt_cli.max_history_pos = 1;
+
+    /* Find the mode selected */
+    set_mode(HDT_MODE, hardware);
+    find_cli_mode_descr(hdt_cli.mode, &current_mode);
+    if (current_mode == NULL) {
+	/* Shouldn't get here... */
+	more_printf("!!! BUG: Mode '%d' unknown.\n", hdt_cli.mode);
+	return;
+    }
+
+    /* Start the auto mode if the command line is set */
+    if (strlen(hardware->auto_label) > 0) {
+	start_auto_mode(hardware);
+    }
+
+    more_printf("Entering CLI mode\n");
+
+    reset_prompt();
+
+    while (hdt_cli.mode != EXIT_MODE) {
+
+	/* Display the cursor */
+	display_cursor(true);
+
+	/* Let's put the cursor blinking until we get an input */
+	set_cursor_blink(true);
+
+	/* We wait endlessly for a keyboard input */
+	current_key = get_key(stdin, 0);
+
+	/* We have to cancel the blinking mode to prevent
+	 * input text to blink */
+	set_cursor_blink(false);
+
+	/* Reset autocomplete buffer unless TAB is pressed */
+	if (current_key != KEY_TAB)
+	    autocomplete_destroy_list();
+
+	switch (current_key) {
+	    /* clear until then end of line */
+	case KEY_CTRL('k'):
+	    /* Clear the end of the line */
+	    clear_end_of_line();
+	    memset(&INPUT[hdt_cli.cursor_pos], 0,
+		   strlen(INPUT) - hdt_cli.cursor_pos);
+	    break;
+
+	case KEY_CTRL('c'):
+	    printf("\n");
+	    reset_prompt();
+	    break;
+
+	case KEY_LEFT:
+	    if (hdt_cli.cursor_pos > 0) {
+		move_cursor_left(1);
+		hdt_cli.cursor_pos--;
+	    }
+	    break;
+
+	case KEY_RIGHT:
+	    if (hdt_cli.cursor_pos < (int)strlen(INPUT)) {
+		move_cursor_right(1);
+		hdt_cli.cursor_pos++;
+	    }
+	    break;
+
+	case KEY_CTRL('e'):
+	case KEY_END:
+	    /* Calling with a 0 value will make the cursor move */
+	    /* So, let's move the cursor only if needed */
+	    if ((strlen(INPUT) - hdt_cli.cursor_pos) > 0) {
+		/* Return to the begining of line */
+		move_cursor_right(strlen(INPUT) - hdt_cli.cursor_pos);
+		hdt_cli.cursor_pos = strlen(INPUT);
+	    }
+	    break;
+
+	case KEY_CTRL('a'):
+	case KEY_HOME:
+	    /* Calling with a 0 value will make the cursor move */
+	    /* So, let's move the cursor only if needed */
+	    if (hdt_cli.cursor_pos > 0) {
+		/* Return to the begining of line */
+		move_cursor_left(hdt_cli.cursor_pos);
+		hdt_cli.cursor_pos = 0;
+	    }
+	    break;
+
+	case KEY_UP:
+
+	    /* Saving future position */
+	    current_future_history_pos = future_history_pos;
+
+	    /* We have to compute the next position */
+	    if (future_history_pos == 1) {
+		future_history_pos = MAX_HISTORY_SIZE;
+	    } else {
+		future_history_pos--;
+	    }
+
+	    /* Does the next position is valid */
+	    if (strlen(hdt_cli.history[future_history_pos]) == 0) {
+		/* Position is invalid, restoring position */
+		future_history_pos = current_future_history_pos;
+		break;
+	    }
+
+	    /* Let's make that future position the one we use */
+	    memset(INPUT, 0, sizeof(INPUT));
+	    strlcpy(INPUT, hdt_cli.history[future_history_pos], sizeof(INPUT));
+
+	    /* Clear the line */
+	    clear_line();
+
+	    /* Move to the begining of line */
+	    move_cursor_to_column(0);
+
+	    reset_prompt();
+	    printf("%s", INPUT);
+	    hdt_cli.cursor_pos = strlen(INPUT);
+	    break;
+
+	case KEY_DOWN:
+	    display_history = true;
+
+	    /* Saving future position */
+	    current_future_history_pos = future_history_pos;
+
+	    if (future_history_pos == MAX_HISTORY_SIZE) {
+		future_history_pos = 1;
+	    } else {
+		future_history_pos++;
+	    }
+
+	    /* Does the next position is valid */
+	    if (strlen(hdt_cli.history[future_history_pos]) == 0)
+		display_history = false;
+
+	    /* An exception is made to reach the last empty line */
+	    if (future_history_pos == hdt_cli.max_history_pos)
+		display_history = true;
+
+	    if (display_history == false) {
+		/* Position is invalid, restoring position */
+		future_history_pos = current_future_history_pos;
+		break;
+	    }
+
+	    /* Let's make that future position the one we use */
+	    memset(INPUT, 0, sizeof(INPUT));
+	    strlcpy(INPUT, hdt_cli.history[future_history_pos], sizeof(INPUT));
+
+	    /* Clear the line */
+	    clear_line();
+
+	    /* Move to the begining of line */
+	    move_cursor_to_column(0);
+
+	    reset_prompt();
+	    printf("%s", INPUT);
+	    hdt_cli.cursor_pos = strlen(INPUT);
+	    break;
+
+	case KEY_TAB:
+	    if (autocomplete_backlog) {
+		clear_line();
+		/* Move to the begining of line */
+		move_cursor_to_column(0);
+		reset_prompt();
+		printf("%s", autocomplete_last_seen->autocomplete_token);
+		strlcpy(INPUT,
+			autocomplete_last_seen->autocomplete_token,
+			sizeof(INPUT));
+		hdt_cli.cursor_pos = strlen(INPUT);
+
+		/* Cycle through the list */
+		autocomplete_last_seen = autocomplete_last_seen->next;
+		if (autocomplete_last_seen == NULL)
+		    autocomplete_last_seen = autocomplete_head;
+	    } else {
+		printf("\n");
+		autocomplete(skip_spaces(INPUT));
+		autocomplete_last_seen = autocomplete_head;
+
+		printf("%s%s", hdt_cli.prompt, INPUT);
+	    }
+	    break;
+
+	case KEY_ENTER:
+	    printf("\n");
+	    if (strlen(remove_spaces(INPUT)) < 1) {
+		reset_prompt();
+		break;
+	    }
+	    exec_command(remove_spaces(INPUT), hardware);
+	    hdt_cli.history_pos++;
+
+	    /* Did we reach the end of the history ?*/
+	    if (hdt_cli.history_pos > MAX_HISTORY_SIZE) {
+		/* Let's return at the beginning */    
+		hdt_cli.history_pos = 1;
+	    }
+
+	    /* Does the next position is already used ?
+	     * If yes, we are cycling in history */
+	    if (strlen(INPUT) > 0) {
+		/* Let's clean that entry */
+		memset(&INPUT,0,sizeof(INPUT));
+	    }
+
+	    future_history_pos = hdt_cli.history_pos;
+	    if (hdt_cli.history_pos > hdt_cli.max_history_pos)
+		hdt_cli.max_history_pos = hdt_cli.history_pos;
+	    reset_prompt();
+	    break;
+
+	case KEY_CTRL('d'):
+	case KEY_DELETE:
+	    /* No need to delete when input is empty */
+	    if (strlen(INPUT) == 0)
+		break;
+	    /* Don't delete when cursor is at the end of the line */
+	    if (hdt_cli.cursor_pos >= strlen(INPUT))
+		break;
+
+	    for (int c = hdt_cli.cursor_pos; c < (int)strlen(INPUT) - 1; c++)
+		INPUT[c] = INPUT[c + 1];
+	    INPUT[strlen(INPUT) - 1] = '\0';
+
+	    /* Clear the end of the line */
+	    clear_end_of_line();
+
+	    /* Print the resulting buffer */
+	    printf("%s", INPUT + hdt_cli.cursor_pos);
+
+	    /* Replace the cursor at the proper place */
+	    if (strlen(INPUT + hdt_cli.cursor_pos) > 0)
+		move_cursor_left(strlen(INPUT + hdt_cli.cursor_pos));
+	    break;
+
+	case KEY_DEL:
+	case KEY_BACKSPACE:
+	    /* Don't delete prompt */
+	    if (hdt_cli.cursor_pos == 0)
+		break;
+
+	    for (int c = hdt_cli.cursor_pos - 1;
+		 c < (int)strlen(INPUT) - 1; c++)
+		INPUT[c] = INPUT[c + 1];
+	    INPUT[strlen(INPUT) - 1] = '\0';
+
+	    /* Get one char back */
+	    move_cursor_left(1);
+
+	    /* Clear the end of the line */
+	    clear_end_of_line();
+
+	    /* Print the resulting buffer */
+	    printf("%s", INPUT + hdt_cli.cursor_pos - 1);
+
+	    /* Realing to a char before the place we were */
+	    hdt_cli.cursor_pos--;
+	    move_cursor_to_column(strlen(hdt_cli.prompt) + hdt_cli.cursor_pos +
+				  1);
+
+	    break;
+
+	case KEY_F1:
+	    printf("\n");
+	    exec_command(CLI_HELP, hardware);
+	    reset_prompt();
+	    break;
+
+	default:
+	    if ((current_key < 0x20) || (current_key > 0x7e))
+		break;
+	    /* Prevent overflow */
+	    if (hdt_cli.cursor_pos > MAX_LINE_SIZE - 2)
+		break;
+	    /* If we aren't at the end of the input line, let's insert */
+	    if (hdt_cli.cursor_pos < (int)strlen(INPUT)) {
+		char key[2];
+		int trailing_chars = strlen(INPUT) - hdt_cli.cursor_pos;
+		memset(temp_command, 0, sizeof(temp_command));
+		strlcpy(temp_command, INPUT, hdt_cli.cursor_pos);
+		sprintf(key, "%c", current_key);
+		strncat(temp_command, key, 1);
+		strncat(temp_command,
+			INPUT + hdt_cli.cursor_pos, trailing_chars);
+		memset(INPUT, 0, sizeof(INPUT));
+		snprintf(INPUT, sizeof(INPUT), "%s", temp_command);
+
+		/* Clear the end of the line */
+		clear_end_of_line();
+
+		/* Print the resulting buffer */
+		printf("%s", INPUT + hdt_cli.cursor_pos);
+
+		/* Return where we must put the new char */
+		move_cursor_left(trailing_chars);
+
+	    } else {
+		putchar(current_key);
+		INPUT[hdt_cli.cursor_pos] = current_key;
+	    }
+	    hdt_cli.cursor_pos++;
+	    break;
+	}
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-cli.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,216 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#ifndef DEFINE_HDT_CLI_H
+#define DEFINE_HDT_CLI_H
+#include <stdio.h>
+#include <getkey.h>
+#include <dprintf.h>
+
+#include "hdt-common.h"
+
+#define MAX_LINE_SIZE 256
+
+#define CLI_SPACE " "
+#define CLI_LF "\n"
+#define CLI_MENU "menu"
+#define CLI_CLEAR "clear"
+#define CLI_EXIT "exit"
+#define CLI_HELP "help"
+#define CLI_REBOOT "reboot"
+#define CLI_SHOW "show"
+#define CLI_SET "set"
+#define CLI_MODE "mode"
+#define CLI_HDT  "hdt"
+#define CLI_PCI  "pci"
+#define CLI_PXE  "pxe"
+#define CLI_KERNEL "kernel"
+#define CLI_SYSLINUX "syslinux"
+#define CLI_VESA "vesa"
+#define CLI_SUMMARY "summary"
+#define CLI_COMMANDS "commands"
+#define CLI_DMI  "dmi"
+#define CLI_CPU  "cpu"
+#define CLI_DISK  "disk"
+#define CLI_SHOW_LIST "list"
+#define CLI_IRQ "irq"
+#define CLI_MODES "modes"
+#define CLI_VPD  "vpd"
+#define CLI_MEMORY  "memory"
+#define CLI_ACPI "acpi"
+#define CLI_ENABLE "enable"
+#define CLI_DISABLE "disable"
+#define CLI_DUMP "dump"
+#define CLI_SAY "say"
+#define CLI_DISPLAY "display"
+#define CLI_SLEEP "sleep"
+
+typedef enum {
+    INVALID_MODE,
+    EXIT_MODE,
+    HDT_MODE,
+    PCI_MODE,
+    DMI_MODE,
+    CPU_MODE,
+    PXE_MODE,
+    KERNEL_MODE,
+    SYSLINUX_MODE,
+    VESA_MODE,
+    DISK_MODE,
+    VPD_MODE,
+    MEMORY_MODE,
+    ACPI_MODE
+} cli_mode_t;
+
+#define PROMPT_SIZE 32
+#define MAX_HISTORY_SIZE 32
+#define INPUT hdt_cli.history[hdt_cli.history_pos]
+struct s_cli {
+    cli_mode_t mode;
+    char prompt[PROMPT_SIZE];
+    uint8_t cursor_pos;
+    char history[MAX_HISTORY_SIZE+1][MAX_LINE_SIZE];
+    int history_pos;
+    int max_history_pos;
+};
+struct s_cli hdt_cli;
+
+/* Describe a cli mode */
+struct cli_mode_descr {
+    const unsigned int mode;
+    const char *name;
+    /* Handle 1-token commands */
+    struct cli_module_descr *default_modules;
+    /* Handle show <module> <args> */
+    struct cli_module_descr *show_modules;
+    /* Handle set <module> <args> */
+    struct cli_module_descr *set_modules;
+};
+
+/* Describe a subset of commands in a module (default, show, set, ...) */
+struct cli_module_descr {
+    struct cli_callback_descr *modules;
+    void (*default_callback) (int argc, char **argv,
+			      struct s_hardware * hardware);
+};
+
+/* Describe a callback (belongs to a mode and a module) */
+struct cli_callback_descr {
+    const char *name;
+    void (*exec) (int argc, char **argv, struct s_hardware * hardware);
+    bool nomodule;
+};
+
+/* Manage aliases */
+#define MAX_ALIASES 2
+struct cli_alias {
+    const char *command;	/* Original command */
+    const int nb_aliases;	/* Size of aliases array */
+    const char **aliases;	/* List of aliases */
+};
+
+/* List of implemented modes */
+extern struct cli_mode_descr *list_modes[];
+struct cli_mode_descr hdt_mode;
+struct cli_mode_descr dmi_mode;
+struct cli_mode_descr syslinux_mode;
+struct cli_mode_descr pxe_mode;
+struct cli_mode_descr kernel_mode;
+struct cli_mode_descr cpu_mode;
+struct cli_mode_descr pci_mode;
+struct cli_mode_descr vesa_mode;
+struct cli_mode_descr disk_mode;
+struct cli_mode_descr vpd_mode;
+struct cli_mode_descr memory_mode;
+struct cli_mode_descr acpi_mode;
+
+/* cli helpers */
+void find_cli_mode_descr(cli_mode_t mode, struct cli_mode_descr **mode_found);
+void find_cli_callback_descr(const char *module_name,
+			     struct cli_module_descr *modules_list,
+			     struct cli_callback_descr **module_found);
+cli_mode_t mode_s_to_mode_t(char *name);
+
+void set_mode(cli_mode_t mode, struct s_hardware *hardware);
+void start_cli_mode(struct s_hardware *hardware);
+void start_auto_mode(struct s_hardware *hardware);
+void main_show(char *item, struct s_hardware *hardware);
+
+#define CLI_HISTORY "history"
+void print_history(int argc, char **argv, struct s_hardware * hardware);
+
+// DMI STUFF
+#define CLI_DMI_BASE_BOARD "base_board"
+#define CLI_DMI_BATTERY "battery"
+#define CLI_DMI_BIOS "bios"
+#define CLI_DMI_CHASSIS "chassis"
+#define CLI_DMI_MEMORY "memory"
+#define CLI_DMI_MEMORY_BANK "bank"
+#define CLI_DMI_PROCESSOR "cpu"
+#define CLI_DMI_SYSTEM "system"
+#define CLI_DMI_IPMI "ipmi"
+#define CLI_DMI_CACHE "cache"
+#define CLI_DMI_OEM "oem"
+#define CLI_DMI_SECURITY "security"
+#define CLI_DMI_LIST CLI_SHOW_LIST
+void main_show_dmi(int argc, char **argv, struct s_hardware *hardware);
+void show_dmi_memory_modules(int argc, char **argv,
+			     struct s_hardware *hardware);
+void show_dmi_memory_bank(int argc, char **argv, struct s_hardware *hardware);
+
+// PCI STUFF
+#define CLI_PCI_DEVICE "device"
+void main_show_pci(int argc, char **argv, struct s_hardware *hardware);
+
+// CPU STUFF
+void main_show_cpu(int argc, char **argv, struct s_hardware *hardware);
+
+// DISK STUFF
+void disks_summary(int argc, char **argv, struct s_hardware *hardware);
+
+// PXE STUFF
+void main_show_pxe(int argc, char **argv, struct s_hardware *hardware);
+
+// KERNEL STUFF
+void main_show_kernel(int argc, char **argv, struct s_hardware *hardware);
+
+// SYSLINUX STUFF
+void main_show_syslinux(int argc, char **argv, struct s_hardware *hardware);
+
+// VESA STUFF
+void main_show_vesa(int argc, char **argv, struct s_hardware *hardware);
+
+// VPD STUFF
+void main_show_vpd(int argc __unused, char **argv __unused,
+		   struct s_hardware *hardware);
+
+// ACPI STUFF
+void main_show_acpi(int argc __unused, char **argv __unused,
+		                    struct s_hardware *hardware);
+
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-common.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-common.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-common.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,792 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <getkey.h>
+#include "syslinux/config.h"
+#include "../lib/sys/vesa/vesa.h"
+#include "hdt-common.h"
+#include <disk/util.h>
+#include <disk/mbrs.h>
+#include <memory.h>
+
+/* ISOlinux requires a 8.3 format */
+void convert_isolinux_filename(char *filename, struct s_hardware *hardware)
+{
+    /* Exit if we are not running ISOLINUX */
+    if (hardware->sv->filesystem != SYSLINUX_FS_ISOLINUX)
+	return;
+    /* Searching the dot */
+    char *dot = strchr(filename, '.');
+    /* Exiting if no dot exists in that string */
+    if (dot == NULL)
+	return;
+    /* Exiting if the extension is 3 char or less */
+    if (strlen(dot) <= 4)
+	return;
+
+    /* We have an extension bigger than .blah
+     * so we have to shorten it to 3*/
+    dot[4] = '\0';
+}
+
+void detect_parameters(const int argc, const char *argv[],
+		       struct s_hardware *hardware)
+{
+    /* Quiet mode - make the output more quiet */
+    quiet = true;
+
+    /* Silent mode - make not output at all */
+    silent = false;
+
+    /* Vesa mode isn't set until we explictly call it */
+    vesamode = false;
+
+    /* Automode isn't the default*/
+    automode = false;
+
+    /* Menu mode is the default*/
+    menumode = true;
+
+    for (int i = 1; i < argc; i++) {
+	if (!strncmp(argv[i], "quiet", 5)) {
+	    quiet = true;
+	} else if (!strncmp(argv[i], "silent", 6)) {
+	    silent = true;
+	} else	if (!strncmp(argv[i], "verbose", 7)) {
+	    quiet = false;
+	} else if (!strncmp(argv[i], "modules_pcimap=", 15)) {
+	    strlcpy(hardware->modules_pcimap_path, argv[i] + 15,
+		    sizeof(hardware->modules_pcimap_path));
+	    convert_isolinux_filename(hardware->modules_pcimap_path, hardware);
+	} else if (!strncmp(argv[i], "pciids=", 7)) {
+	    strlcpy(hardware->pciids_path, argv[i] + 7,
+		    sizeof(hardware->pciids_path));
+	    convert_isolinux_filename(hardware->pciids_path, hardware);
+	} else if (!strncmp(argv[i], "modules_alias=", 14)) {
+	    strlcpy(hardware->modules_alias_path, argv[i] + 14,
+		    sizeof(hardware->modules_alias_path));
+	    convert_isolinux_filename(hardware->modules_alias_path, hardware);
+	} else if (!strncmp(argv[i], "memtest=", 8)) {
+	    strlcpy(hardware->memtest_label, argv[i] + 8,
+		    sizeof(hardware->memtest_label));
+	    convert_isolinux_filename(hardware->memtest_label, hardware);
+	} else if (!strncmp(argv[i], "vesa", 4)) {
+	    vesamode = true;
+	    max_console_lines = MAX_VESA_CLI_LINES;
+	    /* If the user defines a background image */
+	    if (!strncmp(argv[i], "vesa=", 5)) {
+		strlcpy(hardware->vesa_background, argv[i] + 5,
+			sizeof(hardware->vesa_background));
+	    }
+	} else if (!strncmp(argv[i], "novesa", 6)) {
+	    vesamode = false;
+	    max_console_lines = MAX_CLI_LINES;
+	} else if (!strncmp(argv[i], "nomenu", 6)) {
+	    menumode = false;
+	} else if (!strncmp(argv[i], "dump_filename=", 14)) {
+	    strlcpy(hardware->dump_filename, argv[i] + 14,
+		    sizeof(hardware->dump_filename));
+	} else if (!strncmp(argv[i], "dump_path=", 10)) {
+	    strlcpy(hardware->dump_path, argv[i] + 10,
+		    sizeof(hardware->dump_path));
+	} else if (!strncmp(argv[i], "tftp_ip=", 8)) {
+	    strlcpy(hardware->tftp_ip, argv[i] + 8,
+		    sizeof(hardware->tftp_ip));
+	} else if (!strncmp(argv[i], "postexec=", 9)) {
+	    /* The postexec= parameter is separated in several argv[]
+	     * as it can contains spaces.
+	     * We use the AUTO_DELIMITER char to define the limits
+	     * of this parameter.
+	     * i.e postexec='linux memtest.bin'
+	     */
+
+	    char *argument = (char*)argv[i]+10;
+	    /* Extracting the first parameter */
+	    strcpy(hardware->postexec, argument);
+
+	    /* While we can't find the other AUTO_DELIMITER, let's process the argv[] */
+	    while ((strchr(argument, AUTO_DELIMITER) == NULL) && (i+1<argc)) {
+		i++;
+	    	argument = (char *)argv[i];
+		strcat(hardware->postexec, " ");
+		strcat(hardware->postexec, argument);
+	    } 
+	
+	     hardware->postexec[strlen(hardware->postexec) - 1] = 0;
+	} else if (!strncmp(argv[i], "auto=", 5)) {
+	    /* The auto= parameter is separated in several argv[]
+	     * as it can contains spaces.
+	     * We use the AUTO_DELIMITER char to define the limits
+	     * of this parameter.
+	     * i.e auto='show dmi; show pci'
+	     */
+
+	    automode=true;
+	    char *argument = (char*)argv[i]+6;
+	    /* Extracting the first parameter */
+	    strcpy(hardware->auto_label, argument);
+
+	    /* While we can't find the other AUTO_DELIMITER, let's process the argv[] */
+	    while ((strchr(argument, AUTO_DELIMITER) == NULL) && (i+1<argc)) {
+		i++;
+	    	argument = (char *)argv[i];
+		strcat(hardware->auto_label, " ");
+		strcat(hardware->auto_label, argument);
+	    } 
+
+	     hardware->auto_label[strlen(hardware->auto_label) - 1] = 0;
+	}
+    }
+}
+
+void detect_syslinux(struct s_hardware *hardware)
+{
+    hardware->sv = syslinux_version();
+    switch (hardware->sv->filesystem) {
+    case SYSLINUX_FS_SYSLINUX:
+	strlcpy(hardware->syslinux_fs, "SYSlinux", 9);
+	break;
+    case SYSLINUX_FS_PXELINUX:
+	strlcpy(hardware->syslinux_fs, "PXElinux", 9);
+	break;
+    case SYSLINUX_FS_ISOLINUX:
+	strlcpy(hardware->syslinux_fs, "ISOlinux", 9);
+	break;
+    case SYSLINUX_FS_EXTLINUX:
+	strlcpy(hardware->syslinux_fs, "EXTlinux", 9);
+	break;
+    case SYSLINUX_FS_UNKNOWN:
+    default:
+	strlcpy(hardware->syslinux_fs, "Unknown Bootloader",
+		sizeof hardware->syslinux_fs);
+	break;
+    }
+}
+
+void init_hardware(struct s_hardware *hardware)
+{
+    hardware->pci_ids_return_code = 0;
+    hardware->modules_pcimap_return_code = 0;
+    hardware->modules_alias_return_code = 0;
+    hardware->cpu_detection = false;
+    hardware->pci_detection = false;
+    hardware->disk_detection = false;
+    hardware->disks_count = 0;
+    hardware->dmi_detection = false;
+    hardware->pxe_detection = false;
+    hardware->vesa_detection = false;
+    hardware->vpd_detection = false;
+    hardware->memory_detection = false;
+    hardware->acpi_detection = false;
+    hardware->nb_pci_devices = 0;
+    hardware->is_dmi_valid = false;
+    hardware->is_pxe_valid = false;
+    hardware->is_vpd_valid = false;
+    hardware->is_acpi_valid = false;
+    hardware->pci_domain = NULL;
+    hardware->detected_memory_size = 0;
+    hardware->physical_cpu_count =1; /* we have at least one cpu */
+
+    /* Cleaning structures */
+    memset(hardware->disk_info, 0, sizeof(hardware->disk_info));
+    memset(hardware->mbr_ids, 0, sizeof(hardware->mbr_ids));
+    memset(&hardware->dmi, 0, sizeof(s_dmi));
+    memset(&hardware->cpu, 0, sizeof(s_cpu));
+    memset(&hardware->pxe, 0, sizeof(struct s_pxe));
+    memset(&hardware->vesa, 0, sizeof(struct s_vesa));
+    memset(&hardware->vpd, 0, sizeof(s_vpd));
+    memset(&hardware->acpi, 0, sizeof(s_acpi));
+    memset(hardware->syslinux_fs, 0, sizeof hardware->syslinux_fs);
+    memset(hardware->pciids_path, 0, sizeof hardware->pciids_path);
+    memset(hardware->modules_pcimap_path, 0,
+	   sizeof hardware->modules_pcimap_path);
+    memset(hardware->modules_alias_path, 0,
+	   sizeof hardware->modules_alias_path);
+    memset(hardware->memtest_label, 0, sizeof hardware->memtest_label);
+    memset(hardware->auto_label, 0, sizeof hardware->auto_label);
+    memset(hardware->dump_path, 0, sizeof hardware->dump_path);
+    memset(hardware->dump_filename, 0, sizeof hardware->dump_filename);
+    memset(hardware->vesa_background, 0, sizeof hardware->vesa_background);
+    memset(hardware->tftp_ip, 0, sizeof hardware->tftp_ip);
+    memset(hardware->postexec, 0, sizeof hardware->postexec);
+    strcat(hardware->dump_path, "hdt");
+    strcat(hardware->dump_filename, "%{m}+%{p}+%{v}");
+    strcat(hardware->pciids_path, "pci.ids");
+    strcat(hardware->modules_pcimap_path, "modules.pcimap");
+    strcat(hardware->modules_alias_path, "modules.alias");
+    strcat(hardware->memtest_label, "memtest");
+    strlcpy(hardware->vesa_background, CLI_DEFAULT_BACKGROUND,
+	    sizeof(hardware->vesa_background));
+}
+
+/*
+ * Detecting if a DMI table exist
+ * if yes, let's parse it
+ */
+int detect_dmi(struct s_hardware *hardware)
+{
+    if (hardware->dmi_detection == true)
+	return -1;
+    hardware->dmi_detection = true;
+    if (dmi_iterate(&hardware->dmi) == -ENODMITABLE) {
+	hardware->is_dmi_valid = false;
+	return -ENODMITABLE;
+    }
+
+    parse_dmitable(&hardware->dmi);
+    hardware->is_dmi_valid = true;
+    return 0;
+}
+
+/*
+ * Detecting ACPI
+ * if yes, let's parse it
+ */
+int detect_acpi(struct s_hardware *hardware)
+{
+    int retval;
+    if (hardware->acpi_detection == true)
+	return -1;
+    hardware->acpi_detection = true;
+    if ((retval=parse_acpi(&hardware->acpi)) != ACPI_FOUND) {
+	hardware->is_acpi_valid = false;
+	return retval;
+    }
+
+    hardware->is_acpi_valid = true;
+    return retval;
+}
+
+/**
+ * vpd_detection - populate the VPD structure
+ *
+ * VPD is a structure available on IBM machines.
+ * It is documented at:
+ *    http://www.pc.ibm.com/qtechinfo/MIGR-45120.html
+ * (XXX the page seems to be gone)
+ **/
+int detect_vpd(struct s_hardware *hardware)
+{
+    if (hardware->vpd_detection)
+	return -1;
+    else
+	hardware->vpd_detection = true;
+
+    if (vpd_decode(&hardware->vpd) == -ENOVPDTABLE) {
+	hardware->is_vpd_valid = false;
+	return -ENOVPDTABLE;
+    } else {
+	hardware->is_vpd_valid = true;
+	return 0;
+    }
+}
+
+/* Detection vesa stuff*/
+int detect_vesa(struct s_hardware *hardware)
+{
+    static com32sys_t rm;
+    struct vesa_general_info *gi;
+    struct vesa_mode_info *mi;
+    uint16_t mode, *mode_ptr;
+    char *oem_ptr;
+    int rv = -1;
+
+    if (hardware->vesa_detection == true)
+	return -1;
+
+    hardware->vesa_detection = true;
+    hardware->is_vesa_valid = false;
+
+    gi = lmalloc(sizeof(*gi));
+    if (!gi)
+	return -1;
+
+    mi = lmalloc(sizeof(*mi));
+    if (!mi)
+	goto out;
+
+    gi->signature = VBE2_MAGIC;	/* Get VBE2 extended data */
+    memset(&rm, 0, sizeof rm);
+    rm.eax.w[0] = 0x4F00;	/* Get SVGA general information */
+    rm.edi.w[0] = OFFS(gi);
+    rm.es = SEG(gi);
+    __intcall(0x10, &rm, &rm);
+
+    if (rm.eax.w[0] != 0x004F) {
+	goto out;
+    };
+
+    mode_ptr = GET_PTR(gi->video_mode_ptr);
+    oem_ptr = GET_PTR(gi->oem_vendor_name_ptr);
+    strlcpy(hardware->vesa.vendor, oem_ptr, sizeof(hardware->vesa.vendor));
+    oem_ptr = GET_PTR(gi->oem_product_name_ptr);
+    strlcpy(hardware->vesa.product, oem_ptr, sizeof(hardware->vesa.product));
+    oem_ptr = GET_PTR(gi->oem_product_rev_ptr);
+    strlcpy(hardware->vesa.product_revision, oem_ptr,
+	    sizeof(hardware->vesa.product_revision));
+
+    hardware->vesa.major_version = (gi->version >> 8) & 0xff;
+    hardware->vesa.minor_version = gi->version & 0xff;
+    hardware->vesa.total_memory = gi->total_memory;
+    hardware->vesa.software_rev = gi->oem_software_rev;
+
+    hardware->vesa.vmi_count = 0;
+
+    while ((mode = *mode_ptr++) != 0xFFFF) {
+
+        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;
+
+	/* Saving detected values */
+	memcpy(&hardware->vesa.vmi[hardware->vesa.vmi_count].mi, mi,
+	       sizeof(struct vesa_mode_info));
+	hardware->vesa.vmi[hardware->vesa.vmi_count].mode = mode;
+
+	hardware->vesa.vmi_count++;
+    }
+    hardware->is_vesa_valid = true;
+
+    rv = 0;
+out:
+    lfree(mi);
+    lfree(gi);
+    return rv;
+}
+
+/* Try to detect disks from port 0x80 to 0xff */
+void detect_disks(struct s_hardware *hardware)
+{
+    int i = -1;
+    int err;
+
+    if (hardware->disk_detection)
+	return;
+
+    hardware->disk_detection = true;
+    for (int drive = 0x80; drive < 0xff; drive++) {
+	i++;
+	hardware->disk_info[i].disk = drive;
+	err = get_drive_parameters(&hardware->disk_info[i]);
+
+	/*
+	 * Do not print output when drive does not exist or
+	 * doesn't support int13 (cdrom, ...)
+	 */
+	if (err == -1 || !hardware->disk_info[i].cbios)
+	    continue;
+
+	/* Detect MBR */
+	hardware->mbr_ids[i] = get_mbr_id(&hardware->disk_info[i]);
+
+	hardware->disks_count++;
+    }
+}
+
+int detect_pxe(struct s_hardware *hardware)
+{
+    void *dhcpdata;
+
+    size_t dhcplen;
+    t_PXENV_UNDI_GET_NIC_TYPE gnt;
+
+    if (hardware->pxe_detection == true)
+	return -1;
+    hardware->pxe_detection = true;
+    hardware->is_pxe_valid = false;
+    memset(&gnt, 0, sizeof(t_PXENV_UNDI_GET_NIC_TYPE));
+    memset(&hardware->pxe, 0, sizeof(struct s_pxe));
+
+    /* This code can only work if pxelinux is loaded */
+    if (hardware->sv->filesystem != SYSLINUX_FS_PXELINUX) {
+	return -1;
+    }
+// printf("PXE: PXElinux detected\n");
+    if (!pxe_get_cached_info(PXENV_PACKET_TYPE_DHCP_ACK, &dhcpdata, &dhcplen)) {
+	pxe_bootp_t *dhcp = &hardware->pxe.dhcpdata;
+	memcpy(&hardware->pxe.dhcpdata, dhcpdata,
+	       sizeof(hardware->pxe.dhcpdata));
+	snprintf(hardware->pxe.mac_addr, sizeof(hardware->pxe.mac_addr),
+		 "%02x:%02x:%02x:%02x:%02x:%02x", dhcp->CAddr[0],
+		 dhcp->CAddr[1], dhcp->CAddr[2], dhcp->CAddr[3],
+		 dhcp->CAddr[4], dhcp->CAddr[5]);
+
+	/* Saving our IP address in a easy format */
+	hardware->pxe.ip_addr[0] = hardware->pxe.dhcpdata.yip & 0xff;
+	hardware->pxe.ip_addr[1] = hardware->pxe.dhcpdata.yip >> 8 & 0xff;
+	hardware->pxe.ip_addr[2] = hardware->pxe.dhcpdata.yip >> 16 & 0xff;
+	hardware->pxe.ip_addr[3] = hardware->pxe.dhcpdata.yip >> 24 & 0xff;
+
+	if (!pxe_get_nic_type(&gnt)) {
+	    switch (gnt.NicType) {
+	    case PCI_NIC:
+		hardware->is_pxe_valid = true;
+		hardware->pxe.vendor_id = gnt.info.pci.Vendor_ID;
+		hardware->pxe.product_id = gnt.info.pci.Dev_ID;
+		hardware->pxe.subvendor_id = gnt.info.pci.SubVendor_ID;
+		hardware->pxe.subproduct_id =
+		    gnt.info.pci.SubDevice_ID,
+		    hardware->pxe.rev = gnt.info.pci.Rev;
+		hardware->pxe.pci_bus = (gnt.info.pci.BusDevFunc >> 8) & 0xff;
+		hardware->pxe.pci_dev = (gnt.info.pci.BusDevFunc >> 3) & 0x7;
+		hardware->pxe.pci_func = gnt.info.pci.BusDevFunc & 0x03;
+		hardware->pxe.base_class = gnt.info.pci.Base_Class;
+		hardware->pxe.sub_class = gnt.info.pci.Sub_Class;
+		hardware->pxe.prog_intf = gnt.info.pci.Prog_Intf;
+		hardware->pxe.nictype = gnt.NicType;
+		break;
+	    case CardBus_NIC:
+		hardware->is_pxe_valid = true;
+		hardware->pxe.vendor_id = gnt.info.cardbus.Vendor_ID;
+		hardware->pxe.product_id = gnt.info.cardbus.Dev_ID;
+		hardware->pxe.subvendor_id = gnt.info.cardbus.SubVendor_ID;
+		hardware->pxe.subproduct_id =
+		    gnt.info.cardbus.SubDevice_ID,
+		    hardware->pxe.rev = gnt.info.cardbus.Rev;
+		hardware->pxe.pci_bus =
+		    (gnt.info.cardbus.BusDevFunc >> 8) & 0xff;
+		hardware->pxe.pci_dev =
+		    (gnt.info.cardbus.BusDevFunc >> 3) & 0x7;
+		hardware->pxe.pci_func = gnt.info.cardbus.BusDevFunc & 0x03;
+		hardware->pxe.base_class = gnt.info.cardbus.Base_Class;
+		hardware->pxe.sub_class = gnt.info.cardbus.Sub_Class;
+		hardware->pxe.prog_intf = gnt.info.cardbus.Prog_Intf;
+		hardware->pxe.nictype = gnt.NicType;
+		break;
+	    case PnP_NIC:
+	    default:
+		return -1;
+		break;
+	    }
+
+	    /* The firt pass try to find the exact pci device */
+	    hardware->pxe.pci_device = NULL;
+	    hardware->pxe.pci_device_pos = 0;
+	    struct pci_device *pci_device;
+	    int pci_number = 0;
+	    for_each_pci_func(pci_device, hardware->pci_domain) {
+		pci_number++;
+		if ((__pci_bus == hardware->pxe.pci_bus) &&
+		    (__pci_slot == hardware->pxe.pci_dev) &&
+		    (__pci_func == hardware->pxe.pci_func) &&
+		    (pci_device->vendor == hardware->pxe.vendor_id)
+		    && (pci_device->product == hardware->pxe.product_id)) {
+		    hardware->pxe.pci_device = pci_device;
+		    hardware->pxe.pci_device_pos = pci_number;
+		    return 0;
+		}
+	    }
+
+	    /* If we reach that part, it means the pci device pointed by
+	     * the pxe rom wasn't found in our list.
+	     * Let's try to find the device only by its pci ids.
+	     * The pci device we'll match is maybe not exactly the good one
+	     * as we can have the same pci id several times.
+	     * At least, the pci id, the vendor/product will be right.
+	     * That's clearly a workaround for some weird cases.
+	     * This should happend very unlikely */
+	    hardware->pxe.pci_device = NULL;
+	    hardware->pxe.pci_device_pos = 0;
+	    pci_number = 0;
+	    for_each_pci_func(pci_device, hardware->pci_domain) {
+		pci_number++;
+		if ((pci_device->vendor == hardware->pxe.vendor_id)
+		    && (pci_device->product == hardware->pxe.product_id)) {
+		    hardware->pxe.pci_device = pci_device;
+		    hardware->pxe.pci_device_pos = pci_number;
+		    return 0;
+		}
+	    }
+
+	}
+    }
+    return 0;
+}
+
+void detect_memory(struct s_hardware *hardware) {
+     if (hardware->memory_detection == false) {
+	     hardware->memory_detection = true;
+     hardware->detected_memory_size = detect_memsize();
+     }
+}
+
+void detect_pci(struct s_hardware *hardware)
+{
+    if (hardware->pci_detection == true)
+	return;
+    hardware->pci_detection = true;
+
+    hardware->nb_pci_devices = 0;
+
+    /* Scanning to detect pci buses and devices */
+    hardware->pci_domain = pci_scan();
+
+    if (!hardware->pci_domain)
+	return;
+
+    /* Gathering addtional information */
+    gather_additional_pci_config(hardware->pci_domain);
+
+    struct pci_device *pci_device;
+    for_each_pci_func(pci_device, hardware->pci_domain) {
+	hardware->nb_pci_devices++;
+    }
+
+    if (!quiet) {
+	more_printf("PCI: %d devices detected\n", hardware->nb_pci_devices);
+	more_printf("PCI: Resolving names\n");
+    }
+    /* Assigning product & vendor name for each device */
+    hardware->pci_ids_return_code =
+	get_name_from_pci_ids(hardware->pci_domain, hardware->pciids_path);
+
+    if (!quiet)
+	more_printf("PCI: Resolving class names\n");
+    /* Assigning class name for each device */
+    hardware->pci_ids_return_code =
+	get_class_name_from_pci_ids(hardware->pci_domain,
+				    hardware->pciids_path);
+
+    if (!quiet)
+	more_printf("PCI: Resolving module names\n");
+    /* Detecting which kernel module should match each device using modules.pcimap */
+    hardware->modules_pcimap_return_code =
+	get_module_name_from_pcimap(hardware->pci_domain,
+				    hardware->modules_pcimap_path);
+
+    /* Detecting which kernel module should match each device using modules.alias */
+    hardware->modules_alias_return_code =
+	get_module_name_from_alias(hardware->pci_domain,
+				   hardware->modules_alias_path);
+
+}
+
+void cpu_detect(struct s_hardware *hardware)
+{
+    if (hardware->cpu_detection == true)
+	return;
+    detect_cpu(&hardware->cpu);
+    /* Old processors doesn't manage the identify commands 
+     * Let's use the dmi value in that case */
+    if (strlen(remove_spaces(hardware->cpu.model)) == 0)
+	strlcpy(hardware->cpu.model, hardware->dmi.processor.version,
+		sizeof(hardware->cpu.model));
+
+    /* Some CPUs like to put many spaces in the model name
+     * That makes some weird display in console/menu
+     * Let's remove that mulitple spaces */
+    strlcpy(hardware->cpu.model,del_multi_spaces(hardware->cpu.model),sizeof(hardware->cpu.model));
+
+    if ((hardware->is_acpi_valid) && (hardware->acpi.madt.valid)) {
+    	hardware->physical_cpu_count=hardware->acpi.madt.processor_local_apic_count / hardware->cpu.num_cores;
+    }
+    hardware->cpu_detection = true;
+}
+
+/*
+ * Find the last instance of a particular command line argument
+ * (which should include the final =; do not use for boolean arguments)
+ */
+const char *find_argument(const char **argv, const char *argument)
+{
+    int la = strlen(argument);
+    const char **arg;
+    const char *ptr = NULL;
+
+    for (arg = argv; *arg; arg++) {
+	if (!memcmp(*arg, argument, la))
+	    ptr = *arg + la;
+    }
+
+    return ptr;
+}
+
+void clear_screen(void)
+{
+    move_cursor_to_next_line();
+    disable_utf8();
+    set_g1_special_char();
+    set_us_g0_charset();
+    display_cursor(false);
+    clear_entire_screen();
+    gotoxy(0,0);
+    reset_more_printf();
+}
+
+/* remove begining spaces */
+char *skip_spaces(char *p)
+{
+    while (*p && *p <= ' ') {
+	p++;
+    }
+
+    return p;
+}
+
+/* remove trailing & begining spaces */
+char *remove_spaces(char *p)
+{
+    char *save = p;
+    p += strlen(p) - 1;
+    while (*p && *p <= ' ') {
+	*p = '\0';
+	p--;
+    }
+    p = save;
+    while (*p && *p <= ' ') {
+	p++;
+    }
+
+    return p;
+}
+
+/* remove trailing LF */
+char *remove_trailing_lf(char *p)
+{
+    char *save = p;
+    p += strlen(p) - 1;
+    while (*p && *p == 10) {
+	*p = '\0';
+	p--;
+    }
+    p = save;
+
+    return p;
+}
+
+/* delete multiple spaces, one is enough */
+char *del_multi_spaces(char *p)
+{
+    /* Saving the original pointer */
+    char *save = p;
+
+    /* Let's parse the complete string
+     * As we search for a double spacing
+     * we have to be sure then string is
+     * long enough to be processed */
+    while (*p && *(p + 1)) {
+
+	/* If we have two consecutive spaces */
+	if ((*p == ' ') && (*(p + 1) == ' ')) {
+
+	    /* Let's copy to the current position
+	     * the content from the second space*/
+	    strlcpy(p, p + 1, strlen(p + 1));
+
+	    /* Don't increment the pointer as we
+	     * changed the content of the current position*/
+	    continue;
+	}
+
+	/* Nothing as been found, let's see on the next char */
+	p++;
+    }
+    /* Returning the original pointer */
+    return save;
+}
+
+/* Reset the more_printf counter */
+void reset_more_printf(void)
+{
+    display_line_nb = 0;
+}
+
+int draw_background(const char *what)
+{
+    if (!what)
+	return vesacon_default_background();
+    else
+	return vesacon_load_background(what);
+}
+
+void init_console(struct s_hardware *hardware)
+{
+    if (vesamode) {
+	openconsole(&dev_rawcon_r, &dev_vesaserial_w);
+	draw_background(hardware->vesa_background);
+    } else
+	console_ansi_raw();
+}
+
+void detect_hardware(struct s_hardware *hardware)
+{
+    if (!quiet)
+        more_printf("ACPI: Detecting\n");
+    detect_acpi(hardware);
+
+    if (!quiet)
+        more_printf("MEMORY: Detecting\n");
+    detect_memory(hardware);
+
+    if (!quiet)
+        more_printf("DMI: Detecting Table\n");
+    if (detect_dmi(hardware) == -ENODMITABLE) {
+        more_printf("DMI: ERROR ! Table not found ! \n");
+        more_printf("DMI: Many hardware components will not be detected ! \n");
+    } else {
+        if (!quiet)
+            more_printf("DMI: Table found ! (version %u.%u)\n",
+                        hardware->dmi.dmitable.major_version,
+                        hardware->dmi.dmitable.minor_version);
+    }
+
+    if (!quiet)
+        more_printf("CPU: Detecting\n");
+    cpu_detect(hardware);
+
+    if (!quiet)
+        more_printf("DISKS: Detecting\n");
+    detect_disks(hardware);
+
+    if (!quiet)
+        more_printf("VPD: Detecting\n");
+    detect_vpd(hardware);
+
+    detect_pci(hardware);
+    if (!quiet)
+        more_printf("PCI: %d Devices Found\n", hardware->nb_pci_devices);
+ 
+   if (!quiet)
+        more_printf("PXE: Detecting\n");
+    detect_pxe(hardware);
+
+    if (!quiet)
+        more_printf("VESA: Detecting\n");
+    detect_vesa(hardware);
+}
+
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-common.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-common.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-common.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,250 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#ifndef DEFINE_HDT_COMMON_H
+#define DEFINE_HDT_COMMON_H
+#include <stdio.h>
+#include <syslinux/pxe.h>
+#include <console.h>
+#include <consoles.h>
+#include <syslinux/vesacon.h>
+#include "sys/pci.h"
+
+#include <disk/bootloaders.h>
+#include <disk/errno_disk.h>
+#include <disk/error.h>
+#include <disk/geom.h>
+#include <disk/mbrs.h>
+#include <disk/msdos.h>
+#include <disk/partition.h>
+#include <disk/swsusp.h>
+#include <disk/read.h>
+
+#include "cpuid.h"
+#include "dmi/dmi.h"
+#include "hdt-ata.h"
+#include <lib/sys/vesa/vesa.h>
+#include <vpd/vpd.h>
+#include <libansi.h>
+#include <acpi/acpi.h>
+#include <libupload/upload_backend.h>
+
+/* This two values are used for switching for the menu to the CLI mode */
+#define HDT_SWITCH_TO_CLI "hdt_switch_to_cli"
+#define HDT_DUMP "hdt_dump"
+#define HDT_RETURN_TO_CLI 100
+#define MAX_VESA_MODES 255
+
+/* This value is used for rebooting from the menu mode */
+#define HDT_REBOOT "hdt_reboot"
+
+/* The maximum number of commands we can process */
+#define MAX_NB_AUTO_COMMANDS 255
+/* The maximum size of a command */
+#define AUTO_COMMAND_SIZE 255
+/* The char that separate two commands */
+#define AUTO_SEPARATOR ";"
+/* The char that surround the list of commands */
+#define AUTO_DELIMITER '\'' 
+
+/* Graphic to load in background when using the vesa mode */
+#define CLI_DEFAULT_BACKGROUND "backgnd.png"
+
+/* The maximum number of lines */
+#define MAX_CLI_LINES 20
+#define MAX_VESA_CLI_LINES 24
+
+struct upload_backend *upload;
+
+/* Defines if the cli is quiet*/
+bool quiet;
+
+/* Defines if the cli is totally silent*/
+bool silent;
+
+/* Defines if we must use the vesa mode */
+bool vesamode;
+
+/* Defines if we must use the menu mode */
+bool menumode;
+
+/* Defines if we are running the auto mode */
+bool automode;
+
+/* Defines the number of lines in the console
+ * Default is 20 for a std console */
+extern int max_console_lines;
+
+extern int display_line_nb;
+extern bool disable_more_printf;
+
+#define pause_printf() do {\
+       printf("--More--");\
+       get_key(stdin, 0);\
+       printf("\033[2K\033[1G\033[1F\n");\
+} while (0);
+
+/* The brokeness of that macro is that
+ * it assumes that __VA_ARGS__ contains
+ * one \n (and only one)
+ */
+#define more_printf(...) do {\
+ if (__likely(!silent)) {\
+  if (__likely(!disable_more_printf)) {\
+   if (display_line_nb == max_console_lines) {\
+    display_line_nb=0;\
+    printf("\n--More--");\
+    get_key(stdin, 0);\
+    printf("\033[2K\033[1G\033[1F");\
+   }\
+   display_line_nb++;\
+  }\
+  printf(__VA_ARGS__);\
+ }\
+} while (0);
+
+/* Display CPU registers for debugging purposes */
+static inline void printregs(const com32sys_t * r)
+{
+    printf("eflags = %08x  ds = %04x  es = %04x  fs = %04x  gs = %04x\n"
+	   "eax = %08x  ebx = %08x  ecx = %08x  edx = %08x\n"
+	   "ebp = %08x  esi = %08x  edi = %08x  esp = %08x\n",
+	   r->eflags.l, r->ds, r->es, r->fs, r->gs,
+	   r->eax.l, r->ebx.l, r->ecx.l, r->edx.l,
+	   r->ebp.l, r->esi.l, r->edi.l, r->_unused_esp.l);
+}
+
+struct s_pxe {
+    uint16_t vendor_id;
+    uint16_t product_id;
+    uint16_t subvendor_id;
+    uint16_t subproduct_id;
+    uint8_t rev;
+    uint8_t pci_bus;
+    uint8_t pci_dev;
+    uint8_t pci_func;
+    uint8_t base_class;
+    uint8_t sub_class;
+    uint8_t prog_intf;
+    uint8_t nictype;
+    char mac_addr[18];		/* The current mac address */
+    uint8_t ip_addr[4];
+    pxe_bootp_t dhcpdata;	/* The dhcp answer */
+    struct pci_device *pci_device;	/* The matching pci device */
+    uint8_t pci_device_pos;	/* It position in our pci sorted list */
+};
+
+struct s_vesa_mode_info {
+    struct vesa_mode_info mi;
+    uint16_t mode;
+};
+
+struct s_vesa {
+    uint8_t major_version;
+    uint8_t minor_version;
+    struct s_vesa_mode_info vmi[MAX_VESA_MODES];
+    uint8_t vmi_count;
+    uint16_t total_memory;
+    char vendor[256];
+    char product[256];
+    char product_revision[256];
+    uint16_t software_rev;
+};
+
+struct s_hardware {
+    s_dmi dmi;			/* DMI table */
+    s_cpu cpu;			/* CPU information */
+    uint8_t physical_cpu_count; /* Number of physical cpu */
+    s_vpd vpd;			/* VPD information */
+    s_acpi acpi;
+    struct pci_domain *pci_domain;	/* PCI Devices */
+    struct driveinfo disk_info[256];	/* Disk Information */
+    uint32_t mbr_ids[256];	/* MBR ids */
+    int disks_count;		/* Number of detected disks */
+    struct s_pxe pxe;
+    struct s_vesa vesa;
+    unsigned long detected_memory_size;	/* The detected memory size (in KB) */
+
+    int pci_ids_return_code;
+    int modules_pcimap_return_code;
+    int modules_alias_return_code;
+    int nb_pci_devices;
+    bool is_dmi_valid;
+    bool is_pxe_valid;
+    bool is_vesa_valid;
+    bool is_vpd_valid;
+    bool is_acpi_valid;
+
+    bool dmi_detection;		/* Does the dmi stuff has already been detected? */
+    bool pci_detection;		/* Does the pci stuff has already been detected? */
+    bool cpu_detection;		/* Does the cpu stuff has already been detected? */
+    bool disk_detection;	/* Does the disk stuff has already been detected? */
+    bool pxe_detection;		/* Does the pxe stuff has already been detected? */
+    bool vesa_detection;	/* Does the vesa sutff have been already detected? */
+    bool vpd_detection;		/* Does the vpd stuff has already been detected? */
+    bool memory_detection;	/* Does the memory size got detected ?*/
+    bool acpi_detection;	/* Does the acpi got detected ?*/
+
+    char syslinux_fs[22];
+    const struct syslinux_version *sv;
+    char modules_pcimap_path[255];
+    char modules_alias_path[255];
+    char pciids_path[255];
+    char dump_path[255]; /* Dump path on the tftp server */
+    char dump_filename[255]; /* Dump filename on the tftp server */
+    char tftp_ip[255];   /* IP address of tftp server (dump mode) */
+    char memtest_label[255];
+    char auto_label[AUTO_COMMAND_SIZE];
+    char vesa_background[255];
+    char postexec[255];
+};
+
+void reset_more_printf(void);
+const char *find_argument(const char **argv, const char *argument);
+char *remove_spaces(char *p);
+char *remove_trailing_lf(char *p);
+char *skip_spaces(char *p);
+char *del_multi_spaces(char *p);
+int detect_dmi(struct s_hardware *hardware);
+int detect_vpd(struct s_hardware *hardware);
+void detect_disks(struct s_hardware *hardware);
+void detect_pci(struct s_hardware *hardware);
+void cpu_detect(struct s_hardware *hardware);
+int detect_pxe(struct s_hardware *hardware);
+void init_hardware(struct s_hardware *hardware);
+void clear_screen(void);
+void detect_syslinux(struct s_hardware *hardware);
+int detect_acpi(struct s_hardware *hardware);
+void detect_parameters(const int argc, const char *argv[],
+		       struct s_hardware *hardware);
+int detect_vesa(struct s_hardware *hardware);
+void detect_memory(struct s_hardware *hardware);
+void init_console(struct s_hardware *hardware);
+void detect_hardware(struct s_hardware *hardware);
+void dump(struct s_hardware *hardware);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-acpi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-acpi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-acpi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,600 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 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 "hdt-common.h"
+#include "hdt-dump.h"
+
+void show_header(char *name, void *address, s_acpi_description_header *h, ZZJSON_CONFIG *config, ZZJSON **item)
+{
+	char signature[10]={0};
+	char revision[10]={0};
+	char s_address[16]={0};
+	char oem_id[16]={0};
+	char oem_table_id[16]={0};
+	char oem_revision[16]={0};
+	char creator_revision[16]={0};
+	char creator_id[16]={0};
+	snprintf(signature,sizeof(signature),"%s",h->signature);
+	snprintf(revision,sizeof(revision),"0x%03x",h->revision);
+	snprintf(oem_id,sizeof(oem_id),"%s",h->oem_id);
+	snprintf(oem_table_id,sizeof(oem_table_id),"%s",h->oem_table_id);
+	snprintf(creator_id,sizeof(creator_id),"%s",h->creator_id);
+	snprintf(oem_revision,sizeof(oem_revision),"0x%08x",h->oem_revision);
+	snprintf(creator_revision,sizeof(creator_revision),"0x%08x",h->creator_revision);
+	snprintf(s_address,sizeof(s_address),"%p",address);
+
+	char address_name[32]={0};
+	char signature_name[32]={0};
+	char revision_name[32]={0};
+	char oem_id_name[32]={0};
+	char oem_table_id_name[32]={0};
+	char oem_revision_name[32]={0};
+	char creator_revision_name[32]={0};
+	char creator_id_name[32]={0};
+	snprintf(signature_name,sizeof(signature_name),"acpi.%s.signature",name);
+	snprintf(revision_name,sizeof(revision_name),"acpi.%s.revision",name);
+	snprintf(address_name,sizeof(address_name),"acpi.%s.address",name);
+	snprintf(oem_id_name,sizeof(oem_id_name),"acpi.%s.oem_id",name);
+	snprintf(oem_table_id_name,sizeof(oem_table_id_name),"acpi.%s.oem_table_id",name);
+	snprintf(oem_revision_name,sizeof(oem_revision_name),"acpi.%s.oem_revision",name);
+	snprintf(creator_revision_name,sizeof(creator_revision_name),"acpi.%s.creator_revision",name);
+	snprintf(creator_id_name,sizeof(creator_id_name),"acpi.%s.creator_id",name);
+
+	APPEND_ARRAY
+		add_as(signature_name,signature)
+		add_as(revision_name,revision)
+		add_as(oem_id_name,oem_id)
+		add_as(oem_table_id_name,oem_table_id)
+		add_as(oem_revision_name,oem_revision)
+		add_as(creator_id_name,creator_id)
+		add_as(creator_revision_name,creator_revision)
+		add_as(address_name,s_address)
+	END_OF_APPEND;
+
+	FLUSH_OBJECT;
+
+}
+
+void dump_rsdt(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->rsdt.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","rsdt")
+		add_as("acpi.rsdt.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->rsdt.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("rsdt",acpi->rsdt.address, &acpi->rsdt.header, config, item);	
+}
+
+void dump_xsdt(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->xsdt.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","xsdt")
+		add_as("acpi.xsdt.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->xsdt.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("xsdt",acpi->xsdt.address, &acpi->xsdt.header, config, item);	
+}
+
+void dump_fadt(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->rsdt.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","fadt")
+		add_as("acpi.fadt.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->fadt.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("fadt",acpi->fadt.address, &acpi->fadt.header, config, item);	
+}
+
+void dump_dsdt(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->dsdt.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","dsdt")
+		add_as("acpi.dsdt.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->dsdt.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("dsdt",acpi->dsdt.address, &acpi->dsdt.header, config, item);	
+}
+
+void dump_sbst(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->sbst.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","sbst")
+		add_as("acpi.sbst.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->sbst.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("sbst",acpi->sbst.address, &acpi->sbst.header, config, item);	
+}
+
+void dump_ecdt(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->ecdt.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","ecdt")
+		add_as("acpi.ecdt.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->ecdt.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("ecdt",acpi->ecdt.address, &acpi->ecdt.header, config, item);	
+}
+
+void dump_hpet(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->hpet.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","hpet")
+		add_as("acpi.hpet.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->hpet.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("hpet",acpi->hpet.address, &acpi->hpet.header, config, item);	
+}
+
+void dump_tcpa(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->tcpa.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","tcpa")
+		add_as("acpi.tcpa.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->tcpa.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("tcpa",acpi->tcpa.address, &acpi->tcpa.header, config, item);	
+}
+
+void dump_mcfg(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->mcfg.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","mcfg")
+		add_as("acpi.mcfg.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->mcfg.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("mcfg",acpi->mcfg.address, &acpi->mcfg.header, config, item);	
+}
+
+void dump_slic(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->slic.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","slic")
+		add_as("acpi.slic.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->slic.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("slic",acpi->slic.address, &acpi->slic.header, config, item);	
+}
+
+
+void dump_boot(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->boot.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","boot")
+		add_as("acpi.boot.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->boot.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("boot",acpi->boot.address, &acpi->boot.header, config, item);	
+}
+
+void dump_madt(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->madt.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","madt")
+		add_as("acpi.madt.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->madt.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("madt",acpi->madt.address, &acpi->madt.header, config, item);	
+}
+
+void dump_ssdt(s_ssdt *ssdt, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (ssdt->valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","ssdt")
+		add_as("acpi.ssdt.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (ssdt->valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	show_header("ssdt",ssdt->address, &ssdt->header, config, item);	
+}
+
+void dump_rsdp(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->rsdp.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","rsdp")
+		add_as("acpi.rsdp.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->rsdp.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	s_rsdp *r = &acpi->rsdp;
+	char revision[10]={0};
+	char address[16]={0};
+	char oem_id[16]={0};
+	snprintf(revision,sizeof(revision),"0x%03x",r->revision);
+	snprintf(address,sizeof(address),"%p",r->address);
+	snprintf(oem_id,sizeof(oem_id),"%s",r->oem_id);
+	APPEND_ARRAY
+		add_as("acpi.rsdp.revision",revision)
+		add_as("acpi.rsdp.oem_id",oem_id)
+		add_as("acpi.rsdp.address",address)
+	END_OF_APPEND;
+
+	FLUSH_OBJECT;
+
+}
+
+void dump_facs(s_acpi * acpi, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+	char valid[8]={0};
+	snprintf(valid,sizeof(valid),"%s","false");
+	if (acpi->facs.valid) {
+		snprintf(valid,sizeof(valid),"%s","true");
+	}
+	CREATE_ARRAY
+		add_as("acpi.item","facs")
+		add_as("acpi.facs.is_valid",valid)
+	END_OF_ARRAY;
+	
+	if (acpi->facs.valid==false) {
+		FLUSH_OBJECT;
+		return;
+	}
+
+	s_facs *fa = &acpi->facs;
+	char address[16]={0};
+	snprintf(address,sizeof(address),"%p",fa->address);
+	APPEND_ARRAY
+		add_as("acpi.facs.address",address)
+	END_OF_APPEND;
+
+	FLUSH_OBJECT;
+
+}
+
+void dump_interrupt_source_override(s_madt * madt, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+    CREATE_ARRAY
+	add_as("acpi.item","interrupt_source_override")
+    	add_ai("acpi.interrupt_source_override.count", madt->interrupt_source_override_count)
+    END_OF_ARRAY;
+
+    if (madt->interrupt_source_override_count == 0) {
+    	    FLUSH_OBJECT;
+	    return;
+    }
+
+    /* Let's process each interrupt source override */
+    for (int i = 0; i < madt->interrupt_source_override_count; i++) {
+	s_interrupt_source_override *siso = &madt->interrupt_source_override[i];
+	char buffer[20] = {0};
+	char bus_type[10]= {0};
+	
+	/* Spec report bus type 0 as ISA */
+	if (siso->bus == 0)
+	    strcpy(bus_type, "ISA");
+	else
+	    strcpy(bus_type, "unknown");
+
+	APPEND_ARRAY
+		add_as("acpi.interrupt_source_override.bus_type",bus_type)
+		add_ai("acpi.interrupt_source_override.bus",siso->bus)
+		add_ai("acpi.interrupt_source_override.bus_irq",siso->source)
+		add_ai("acpi.interrupt_source_override.global_irq",siso->global_system_interrupt)
+		add_as("acpi.interrupt_source_override.flags",flags_to_string(buffer,siso->flags))
+	END_OF_APPEND;
+    }
+    FLUSH_OBJECT;
+}
+
+void dump_io_apic(s_madt * madt, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+    CREATE_ARRAY
+	add_as("acpi.item","io_apic")
+    	add_ai("acpi.io_apic.count", madt->io_apic_count)
+    END_OF_ARRAY;
+
+    if (madt->io_apic_count == 0) {
+    	    FLUSH_OBJECT;
+	    return;
+    }
+
+    /* For all IO APICS */
+    for (int i = 0; i < madt->io_apic_count; i++) {
+	s_io_apic *sio = &madt->io_apic[i];
+	char buffer[15]={0};
+	memset(buffer, 0, sizeof(buffer));
+	/* GSI base reports the GSI configuration
+	 * Let's interpret it as string */
+	switch (sio->global_system_interrupt_base) {
+	case 0:
+	    strcpy(buffer, "0-23");
+	    break;
+	case 24:
+	    strcpy(buffer,"24-39");
+	    break;
+	case 40:
+	    strcpy(buffer, "40-55");
+	    break;
+	default:
+	    strcpy(buffer,"Unknown");
+	    break;
+	}
+
+	char apic_id[16] = { 0 };
+	char address[16] = { 0 };
+	snprintf(apic_id,sizeof(apic_id),"0x%02x",sio->io_apic_id);
+	snprintf(address,sizeof(address),"0x%08x",sio->io_apic_address);
+	APPEND_ARRAY
+		add_ai("acpi.io_apic.number",i)
+		add_as("acpi.io_apic.apic_id",apic_id)
+		add_as("acpi.io_apic.adress",address)
+		add_as("acpi.io_apic.gsi",buffer)
+	END_OF_APPEND;
+    }
+    FLUSH_OBJECT;
+}
+
+void dump_local_apic_nmi(s_madt * madt, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+    CREATE_ARRAY
+	add_as("acpi.item","local_apic_nmi")
+    	add_ai("acpi.local_apic_nmi.count", madt->local_apic_nmi_count)
+    END_OF_ARRAY;
+
+    if (madt->local_apic_nmi_count == 0) {
+    	    FLUSH_OBJECT;
+	    return;
+    }
+
+    for (int i = 0; i < madt->local_apic_nmi_count; i++) {
+	s_local_apic_nmi *slan = &madt->local_apic_nmi[i];
+	char buffer[20]={0};
+	char acpi_id[16] = { 0 };
+	char local_apic_lint[16] = { 0 };
+	snprintf(acpi_id, sizeof(acpi_id), "0x%02x", slan->acpi_processor_id);
+	snprintf(local_apic_lint, sizeof(local_apic_lint), "0x%02x", slan->local_apic_lint);
+	APPEND_ARRAY
+		add_as("acpi.processor_id", acpi_id)
+		add_as("acpi.local_apic_nmi.flags", flags_to_string(buffer,slan->flags))
+		add_as("acpi.local_apic_nmi.lint",local_apic_lint)
+	END_OF_APPEND;
+    }
+
+    FLUSH_OBJECT;
+}
+
+void dump_local_apic(s_madt * madt, ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+    char buffer[16] = { 0 };
+    snprintf(buffer, sizeof(buffer), "0x%08x", madt->local_apic_address);
+
+    CREATE_ARRAY
+	add_as("acpi.item","local_apic")
+    	add_as("acpi.local_apic.address", buffer)
+    	add_ai("acpi.processor_local_apic.count", madt->processor_local_apic_count)
+    END_OF_ARRAY;
+
+    if (madt->processor_local_apic_count ==0) {
+        FLUSH_OBJECT;
+	return;
+    }
+
+    /* For all detected logical CPU */
+    for (int i = 0; i < madt->processor_local_apic_count; i++) {
+	s_processor_local_apic *sla = &madt->processor_local_apic[i];
+	char lapic_status[16] = { 0 };
+	char acpi_id[16] = { 0 };
+	char apic_id[16] = { 0 };
+
+	snprintf(lapic_status,sizeof(lapic_status),"%s","disabled");
+	/* Let's check if the flags reports the cpu as enabled */
+	if ((sla->flags & PROCESSOR_LOCAL_APIC_ENABLE) ==
+	    PROCESSOR_LOCAL_APIC_ENABLE)
+	    snprintf(lapic_status,sizeof(lapic_status),"%s","enabled");
+	snprintf(acpi_id, sizeof(acpi_id), "0x%02x", sla->acpi_id);
+	snprintf(apic_id, sizeof(apic_id), "0x%02x", sla->apic_id);
+	APPEND_ARRAY
+		add_ai("acpi.cpu.apic_id", sla->apic_id)
+		add_as("acpi.cpu.apic_id (hex)", apic_id)
+		add_as("acpi.cpu.acpi_id (hex)", acpi_id)
+		add_as("acpi.lapic.enabled", lapic_status)
+	END_OF_APPEND;
+    }
+    FLUSH_OBJECT;
+}
+
+void dump_acpi(struct s_hardware *hardware, ZZJSON_CONFIG * config,
+	       ZZJSON ** item)
+{
+    CREATE_NEW_OBJECT;
+    add_hb(is_acpi_valid);
+    if (hardware->is_acpi_valid == false)
+	goto exit;
+
+    s_madt *madt = &hardware->acpi.madt;
+    add_b("acpi.apic.detected", madt->valid);
+    if (madt->valid == false) {
+	goto exit;
+    }
+
+    FLUSH_OBJECT;
+
+    dump_local_apic(madt, config, item);
+    dump_local_apic_nmi(madt, config, item);
+    dump_io_apic(madt, config, item);
+    dump_interrupt_source_override(madt, config, item);
+
+    dump_rsdp(&hardware->acpi,config,item);
+    dump_rsdt(&hardware->acpi,config,item);
+    dump_xsdt(&hardware->acpi,config,item);
+    dump_fadt(&hardware->acpi,config,item);
+    dump_dsdt(&hardware->acpi,config,item);
+    dump_sbst(&hardware->acpi,config,item);
+    dump_ecdt(&hardware->acpi,config,item);
+    dump_hpet(&hardware->acpi,config,item);
+    dump_tcpa(&hardware->acpi,config,item);
+    dump_mcfg(&hardware->acpi,config,item);
+    dump_slic(&hardware->acpi,config,item);
+    dump_boot(&hardware->acpi,config,item);
+    dump_madt(&hardware->acpi,config,item);
+    for (int i = 0; i < hardware->acpi.ssdt_count; i++) {
+            if ((hardware->acpi.ssdt[i] != NULL) && (hardware->acpi.ssdt[i]->valid))
+		    dump_ssdt(hardware->acpi.ssdt[i], config, item);
+    }
+    dump_facs(&hardware->acpi,config,item);
+
+exit:
+    to_cpio("acpi");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-cpu.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-cpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-cpu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,53 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 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 "hdt-common.h"
+#include "hdt-dump.h"
+
+void dump_cpu(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+        CREATE_NEW_OBJECT;
+	add_hs(cpu.vendor);
+	add_hs(cpu.model);
+	add_hi(cpu.vendor_id);
+	add_hi(cpu.family);
+	add_hi(cpu.model_id);
+	add_hi(cpu.stepping);
+	add_hi(cpu.num_cores);
+	add_hi(cpu.l1_data_cache_size);
+	add_hi(cpu.l1_instruction_cache_size);
+	add_hi(cpu.l2_cache_size);
+	size_t i;
+	for (i = 0; i < cpu_flags_count; i++) {
+		char temp[128]={0};
+		snprintf(temp,sizeof(temp),"cpu.flags.%s",cpu_flags_names[i]);
+		add_b(temp,get_cpu_flag_value_from_name(&hardware->cpu,cpu_flags_names[i]));
+	}
+	FLUSH_OBJECT;
+	to_cpio("cpu");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-disks.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-disks.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-disks.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,145 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 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 "hdt-common.h"
+#include "hdt-dump.h"
+#include "hdt-util.h"
+
+ZZJSON_CONFIG *config;
+ZZJSON **item;
+
+static void show_partition_information(struct driveinfo *drive_info,
+                                       struct part_entry *ptab,
+                                       int partition_offset,
+                                       int nb_partitions_seen) {
+    char size[11] = {0};
+    char bootloader_name[9] = {0};
+    char ostype[64]={0};
+    char *parttype;
+    unsigned int start, end;
+    char bootable[6] = {0};
+
+    int i = nb_partitions_seen;
+    start = partition_offset;
+    end = start + ptab->length - 1;
+
+    if (ptab->length > 0)
+        sectors_to_size(ptab->length, size);
+
+    get_label(ptab->ostype, &parttype);
+    get_bootloader_string(drive_info, ptab, bootloader_name, 9);
+    if (ptab->active_flag == 0x80)
+    	snprintf(bootable,sizeof(bootable),"%s","true");
+    else
+	snprintf(bootable,sizeof(bootable),"%s","false");
+
+    snprintf(ostype,sizeof(ostype),"%02X",ptab->ostype);
+
+    APPEND_ARRAY
+	    add_ai("partition->number",i)
+	    add_ai("partition->sector_start",start)
+	    add_ai("partition->sector_end",end)
+	    add_as("partition->size",size)
+	    add_as("partition->type",parttype)
+	    add_as("partition->os_type",ostype)
+	    add_as("partition->boot_flag",bootable)
+    END_OF_APPEND;
+    free(parttype);
+}
+
+
+
+void show_disk(struct s_hardware *hardware, ZZJSON_CONFIG *conf, ZZJSON **it, int drive) {
+	config=conf;
+	item=it;
+	int i = drive - 0x80;
+	struct driveinfo *d = &hardware->disk_info[i];
+	char mbr_name[50]={0};
+	char disk_size[11]={0};
+
+	get_mbr_string(hardware->mbr_ids[i], &mbr_name,sizeof(mbr_name));
+	if ((int)d->edd_params.sectors > 0)
+		sectors_to_size((int)d->edd_params.sectors, disk_size);
+
+	char disk[5]={0};
+	char edd_version[5]={0};
+	snprintf(disk,sizeof(disk),"0x%X",d->disk);
+	snprintf(edd_version,sizeof(edd_version),"%X",d->edd_version);
+	zzjson_print(config, *item);
+	zzjson_free(config, *item);
+
+	CREATE_ARRAY
+		add_as("disk->number",disk) 
+		add_ai("disk->cylinders",d->legacy_max_cylinder +1) 
+		add_ai("disk->heads",d->legacy_max_head +1)
+		add_ai("disk->sectors_per_track",d->legacy_sectors_per_track)
+		add_as("disk->edd_version",edd_version)
+		add_as("disk->size",disk_size)
+		add_ai("disk->bytes_per_sector",(int)d->edd_params.bytes_per_sector)
+		add_ai("disk->sectors_per_track",(int)d->edd_params.sectors_per_track)
+		add_as("disk->host_bus",remove_spaces((char *)d->edd_params.host_bus_type))
+		add_as("disk->interface_type",remove_spaces((char *)d->edd_params.interface_type))
+		add_as("disk->mbr_name",mbr_name)
+		add_ai("disk->mbr_id",hardware->mbr_ids[i])
+	END_OF_ARRAY;
+
+	if (parse_partition_table(d, &show_partition_information)) {
+	        if (errno_disk) { 
+			APPEND_ARRAY
+				add_as("disk->error", "IO Error")
+			END_OF_APPEND;
+		} else  {
+			APPEND_ARRAY
+				add_as("disk->error", "Unrecognized Partition Layout")
+			END_OF_APPEND;
+		}
+	}
+}
+
+void dump_disks(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	bool found=false;
+
+ 	if (hardware->disks_count > 0)  
+	    for (int drive = 0x80; drive < 0xff; drive++) {
+	        if (hardware->disk_info[drive - 0x80].cbios) {
+			if (found==false) {
+				CREATE_NEW_OBJECT;
+				add_b("disks->is_valid",true);
+       				found=true;
+			}
+			show_disk(hardware, config, item, drive);
+		}
+	}
+
+	if (found==false) {
+		CREATE_NEW_OBJECT;
+		add_b("disks->is_valid",false);
+	}
+	FLUSH_OBJECT;
+	to_cpio("disks");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-dmi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-dmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-dmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,447 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 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 "hdt-common.h"
+#include "hdt-dump.h"
+
+void dump_hardware_security(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	if (!hardware->dmi.hardware_security.filled) {
+			CREATE_NEW_OBJECT;
+				add_s("dmi.warning","No hardware security structure found");
+			FLUSH_OBJECT;
+			return;
+	}
+	
+	CREATE_NEW_OBJECT;
+		add_s("dmi.item","hardware_security");
+		add_hs(dmi.hardware_security.power_on_passwd_status);
+		add_hs(dmi.hardware_security.keyboard_passwd_status);
+		add_hs(dmi.hardware_security.administrator_passwd_status);
+		add_hs(dmi.hardware_security.front_panel_reset_status);
+	FLUSH_OBJECT;
+}
+
+void dump_oem_strings(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	if (strlen(hardware->dmi.oem_strings) == 0) {
+			CREATE_NEW_OBJECT;
+				add_s("dmi.warning","No OEM structure found");
+			FLUSH_OBJECT;
+			return;
+	}
+	CREATE_NEW_OBJECT;
+		add_s("dmi.item","OEM");
+		add_hs(dmi.oem_strings);
+	FLUSH_OBJECT;
+}
+
+void dump_memory_size(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	CREATE_NEW_OBJECT;
+		add_s("dmi.item","memory size");
+		add_i("dmi.memory_size (KB)",hardware->detected_memory_size);
+		add_i("dmi.memory_size (MB)",(hardware->detected_memory_size + (1 << 9)) >> 10);
+	FLUSH_OBJECT;
+}
+
+void dump_memory_modules(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	if (hardware->dmi.memory_module_count == 0) {
+			CREATE_NEW_OBJECT;
+				add_s("dmi.warning","No memory module structure found");
+			FLUSH_OBJECT;
+			return;
+	}
+
+	for (int module=0; module<hardware->dmi.memory_module_count;module++) {
+		if (hardware->dmi.memory_module[module].filled == false) {
+			char msg[64]={0};
+			snprintf(msg,sizeof(msg),"Module %d doesn't contain any information", module);
+
+			CREATE_NEW_OBJECT;
+				add_s("dmi.warning",msg);
+			FLUSH_OBJECT;
+			continue;
+		}
+
+		CREATE_NEW_OBJECT;
+		add_i("Memory module", module);
+		add_s("dmi.memory_module.socket_designation", hardware->dmi.memory_module[module].socket_designation);
+		add_s("dmi.memory_module.bank_connections", hardware->dmi.memory_module[module].bank_connections);
+		add_s("dmi.memory_module.speed", hardware->dmi.memory_module[module].speed);
+		add_s("dmi.memory_module.type", hardware->dmi.memory_module[module].type);
+		add_s("dmi.memory_module.installed_size", hardware->dmi.memory_module[module].installed_size);
+		add_s("dmi.memory_module.enabled_size", hardware->dmi.memory_module[module].enabled_size);
+		add_s("dmi.memory_module.error_status", hardware->dmi.memory_module[module].error_status);
+		FLUSH_OBJECT;
+	}
+}
+	
+void dump_cache(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	if (hardware->dmi.cache_count == 0) {
+			CREATE_NEW_OBJECT;
+				add_s("dmi.warning","No cache structure found");
+			FLUSH_OBJECT;
+			return;
+	}
+
+	for (int cache=0; cache<hardware->dmi.cache_count;cache++) {
+		CREATE_NEW_OBJECT;
+		add_i("Cache", cache);
+		add_s("dmi.cache.socket_designation", hardware->dmi.cache[cache].socket_designation);
+		add_s("dmi.cache.configuration", hardware->dmi.cache[cache].configuration);
+		add_s("dmi.cache.mode", hardware->dmi.cache[cache].mode);
+		add_s("dmi.cache.location", hardware->dmi.cache[cache].location);
+		add_i("dmi.cache.installed_size (KB)", hardware->dmi.cache[cache].installed_size);
+		add_i("dmi.cache.max_size (KB)", hardware->dmi.cache[cache].max_size);
+		add_s("dmi.cache.supported_sram_types", hardware->dmi.cache[cache].supported_sram_types);
+		add_s("dmi.cache.installed_sram_types", hardware->dmi.cache[cache].installed_sram_types);
+		add_i("dmi.cache.speed (ns)", hardware->dmi.cache[cache].speed);
+		add_s("dmi.cache.error_correction_type", hardware->dmi.cache[cache].error_correction_type);
+		add_s("dmi.cache.system_type", hardware->dmi.cache[cache].system_type);
+		add_s("dmi.cache.associativity", hardware->dmi.cache[cache].associativity);
+		FLUSH_OBJECT;
+	}
+}
+void dump_memory_banks(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	if (hardware->dmi.memory_count == 0) {
+			CREATE_NEW_OBJECT;
+				add_s("dmi.warning","No memory bank structure found");
+			FLUSH_OBJECT;
+			return;
+	}
+
+	for (int bank=0; bank<hardware->dmi.memory_count;bank++) {
+
+		if (hardware->dmi.memory[bank].filled == false) {
+			char msg[64]={0};
+			snprintf(msg,sizeof(msg),"Bank %d doesn't contain any information", bank);
+
+			CREATE_NEW_OBJECT;
+				add_s("dmi.warning",msg);
+			FLUSH_OBJECT;
+			continue;
+		}
+
+		CREATE_NEW_OBJECT;
+		add_i("Memory Bank", bank);
+		add_s("dmi.memory.form_factor", hardware->dmi.memory[bank].form_factor);
+		add_s("dmi.memory.type", hardware->dmi.memory[bank].type);
+		add_s("dmi.memory.type_detail", hardware->dmi.memory[bank].type_detail);
+		add_s("dmi.memory.speed", hardware->dmi.memory[bank].speed);
+		add_s("dmi.memory.size", hardware->dmi.memory[bank].size);
+		add_s("dmi.memory.device_set", hardware->dmi.memory[bank].device_set);
+		add_s("dmi.memory.device_locator", hardware->dmi.memory[bank].device_locator);
+		add_s("dmi.memory.bank_locator", hardware->dmi.memory[bank].bank_locator);
+		add_s("dmi.memory.total_width", hardware->dmi.memory[bank].total_width);
+		add_s("dmi.memory.data_width", hardware->dmi.memory[bank].data_width);
+		add_s("dmi.memory.error", hardware->dmi.memory[bank].error);
+		add_s("dmi.memory.vendor", hardware->dmi.memory[bank].manufacturer);
+		add_s("dmi.memory.serial", hardware->dmi.memory[bank].serial);
+		add_s("dmi.memory.asset_tag", hardware->dmi.memory[bank].asset_tag);
+		add_s("dmi.memory.part_number", hardware->dmi.memory[bank].part_number);
+		FLUSH_OBJECT;
+	}
+}
+
+void dump_processor(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	if (hardware->dmi.processor.filled == false) {
+		CREATE_NEW_OBJECT;
+			add_s("dmi.warning","no processor structure found");
+		FLUSH_OBJECT;
+		return;
+	}
+
+	char voltage[16]={0};
+	snprintf(voltage,sizeof(voltage),"%d.%02d",
+		hardware->dmi.processor.voltage_mv / 1000,
+		hardware->dmi.processor.voltage_mv - ((hardware->dmi.processor.voltage_mv / 1000) * 1000));
+
+	CREATE_NEW_OBJECT;
+	add_s("dmi.item","processor");
+	add_hs(dmi.processor.socket_designation);
+	add_hs(dmi.processor.type);
+	add_hs(dmi.processor.family);
+	add_hs(dmi.processor.manufacturer);
+	add_hs(dmi.processor.version);
+	add_hi(dmi.processor.external_clock);
+	add_hi(dmi.processor.max_speed);
+	add_hi(dmi.processor.current_speed);
+	add_hi(dmi.processor.signature.type);
+	add_hi(dmi.processor.signature.family);
+	add_hi(dmi.processor.signature.model);
+	add_hi(dmi.processor.signature.stepping);
+	add_hi(dmi.processor.signature.minor_stepping);
+	add_s("dmi.processor.voltage",voltage);
+	add_hs(dmi.processor.status);
+	add_hs(dmi.processor.upgrade);
+	add_hs(dmi.processor.cache1);
+	add_hs(dmi.processor.cache2);
+	add_hs(dmi.processor.cache3);
+	add_hs(dmi.processor.serial);
+	add_hs(dmi.processor.part_number);
+	add_hi(dmi.processor.core_count);
+	add_hi(dmi.processor.core_enabled);
+	add_hi(dmi.processor.thread_count);
+	add_hs(dmi.processor.id);
+	for (int i = 0; i < PROCESSOR_FLAGS_ELEMENTS; i++) {
+	        if (((bool *) (&hardware->dmi.processor.cpu_flags))[i] == true) {
+	            add_s("dmi.processor.flag",(char *)cpu_flags_strings[i]);
+		}
+	}
+	FLUSH_OBJECT;
+}
+
+void dump_battery(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	if (hardware->dmi.battery.filled == false) {
+		CREATE_NEW_OBJECT;
+			add_s("dmi.warning","no battery structure found");
+		FLUSH_OBJECT;
+		return;
+	}
+
+	CREATE_NEW_OBJECT;
+	add_s("dmi.item","battery");
+	add_hs(dmi.battery.manufacturer);
+	add_hs(dmi.battery.manufacture_date);
+	add_hs(dmi.battery.serial);
+	add_hs(dmi.battery.name);
+	add_hs(dmi.battery.chemistry);
+	add_hs(dmi.battery.design_capacity);
+	add_hs(dmi.battery.design_voltage);
+	add_hs(dmi.battery.sbds);
+	add_hs(dmi.battery.sbds_manufacture_date);
+	add_hs(dmi.battery.sbds_chemistry);
+	add_hs(dmi.battery.maximum_error);
+	add_hs(dmi.battery.oem_info);
+	FLUSH_OBJECT;
+}
+
+void dump_ipmi(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	if (hardware->dmi.ipmi.filled == false) {
+		CREATE_NEW_OBJECT;
+			add_s("dmi.warning","no IPMI structure found");
+		FLUSH_OBJECT;
+		return;
+	}
+
+	char spec_ver[16]={0};
+	char i2c[16]={0};
+	char base[16]={0};
+	snprintf(spec_ver,sizeof(spec_ver),"%u.%u",
+			hardware->dmi.ipmi.major_specification_version,
+			hardware->dmi.ipmi.minor_specification_version);
+
+	snprintf(i2c,sizeof(i2c),"0x%02x", hardware->dmi.ipmi.I2C_slave_address);
+	snprintf(base,sizeof(base),"%08X%08X",
+			(uint32_t)(hardware->dmi.ipmi.base_address >> 32),
+			(uint32_t)((hardware->dmi.ipmi.base_address & 0xFFFF) & ~1));
+
+	CREATE_NEW_OBJECT;
+	add_s("dmi.item","ipmi");
+	add_hs(dmi.ipmi.interface_type);
+	add_s("dmi.ipmi.spec_version",spec_ver);
+	add_hi(dmi.ipmi.I2C_slave_address);
+	add_hi(dmi.ipmi.nv_address);
+	add_s("dmi.ipmi.base_address",base);
+	add_hi(dmi.ipmi.irq);
+	FLUSH_OBJECT;
+}
+
+void dump_chassis(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	if (hardware->dmi.chassis.filled == false) {
+		CREATE_NEW_OBJECT;
+			add_s("dmi.warning","no chassis structure found");
+		FLUSH_OBJECT;
+		return;
+	}
+
+	CREATE_NEW_OBJECT;
+	add_s("dmi.item","bios");
+	add_hs(dmi.chassis.manufacturer);
+	add_hs(dmi.chassis.type);
+	add_hs(dmi.chassis.lock);
+	add_hs(dmi.chassis.version);
+	add_hs(dmi.chassis.serial);
+	add_s("dmi.chassis.asset_tag",del_multi_spaces(hardware->dmi.chassis.asset_tag));
+	add_hs(dmi.chassis.boot_up_state);
+	add_hs(dmi.chassis.power_supply_state);
+	add_hs(dmi.chassis.thermal_state);
+	add_hs(dmi.chassis.security_status);
+	add_hs(dmi.chassis.oem_information);
+	add_hi(dmi.chassis.height);
+	add_hi(dmi.chassis.nb_power_cords);
+	FLUSH_OBJECT;
+}
+
+void dump_bios(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	if (hardware->dmi.bios.filled == false) {
+		CREATE_NEW_OBJECT;
+			add_s("dmi.warning","no bios structure found");
+		FLUSH_OBJECT;
+		return;
+	}
+	char address[16]={0};
+	char runtime[16]={0};
+	char rom[16]={0};
+	snprintf(address,sizeof(address),"0x%04X0",hardware->dmi.bios.address);
+	snprintf(runtime,sizeof(runtime),"%u %s",hardware->dmi.bios.runtime_size, hardware->dmi.bios.runtime_size_unit);
+	snprintf(rom,sizeof(rom),"%u %s",hardware->dmi.bios.rom_size, hardware->dmi.bios.rom_size_unit);
+
+	CREATE_NEW_OBJECT;
+	add_s("dmi.item","bios");
+	add_hs(dmi.bios.vendor);
+	add_hs(dmi.bios.version);
+	add_hs(dmi.bios.release_date);
+	add_hs(dmi.bios.bios_revision);
+	add_hs(dmi.bios.firmware_revision);
+	add_s("dmi.bios.address",address);
+	add_s("dmi.bios.runtime_size",runtime);
+	add_s("dmi.bios.rom_size",rom);
+	for (int i = 0; i < BIOS_CHAR_NB_ELEMENTS; i++) {
+	        if (((bool *) (&hardware->dmi.bios.characteristics))[i] == true) {
+			add_s("dmi.bios.characteristics",(char *)bios_charac_strings[i]);
+		}
+	}
+	
+	for (int i = 0; i < BIOS_CHAR_X1_NB_ELEMENTS; i++) {
+	        if (((bool *) (&hardware->dmi.bios.characteristics_x1))[i] == true) {
+			add_s("dmi.bios.characteristics",(char *)bios_charac_x1_strings[i]);
+		}
+	}
+
+	for (int i = 0; i < BIOS_CHAR_X2_NB_ELEMENTS; i++) {
+	        if (((bool *) (&hardware->dmi.bios.characteristics_x2))[i] == true) {
+			add_s("dmi.bios.characteristics",(char *)bios_charac_x2_strings[i]);
+		}
+	}
+	FLUSH_OBJECT;
+}
+
+void dump_system(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	if (hardware->dmi.system.filled == false) {
+		CREATE_NEW_OBJECT;
+			add_s("dmi.warning","no system structure found");
+		FLUSH_OBJECT;
+		return;
+	}
+	char system_reset_status[10]={0};
+	char watchdog_timer[15]={0};
+	snprintf(system_reset_status,sizeof(system_reset_status),"%s", (hardware->dmi.system.system_reset.status ? "Enabled" :"Disabled"));
+	snprintf(watchdog_timer,sizeof(watchdog_timer),"%s", (hardware->dmi.system.system_reset.watchdog ? "Present" :"Not Present"));
+
+	CREATE_NEW_OBJECT;
+	add_s("dmi.item","system");
+	add_hs(dmi.system.manufacturer);
+	add_hs(dmi.system.product_name);
+	add_hs(dmi.system.version);
+	add_hs(dmi.system.serial);
+	add_hs(dmi.system.uuid);
+	add_hs(dmi.system.wakeup_type);
+	add_hs(dmi.system.sku_number);
+	add_hs(dmi.system.family);
+	add_hs(dmi.system.configuration_options);
+	add_s("dmi.system.system_reset.status",system_reset_status);
+	add_s("dmi.system.system_reset.watchdog",watchdog_timer);
+	add_hs(dmi.system.system_reset.boot_option);
+	add_hs(dmi.system.system_reset.boot_option_on_limit);
+	add_hs(dmi.system.system_reset.reset_count);
+	add_hs(dmi.system.system_reset.reset_limit);
+	add_hs(dmi.system.system_reset.timer_interval);
+	add_hs(dmi.system.system_reset.timeout);
+	add_hs(dmi.system.system_boot_status);
+	FLUSH_OBJECT;
+}
+
+void dump_base_board(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	if (hardware->dmi.base_board.filled == false) {
+		CREATE_NEW_OBJECT;
+			add_s("dmi.warning","no base_board structure found");
+		FLUSH_OBJECT;
+		return;
+	}
+
+	CREATE_NEW_OBJECT;
+	add_s("dmi.item","base_board");
+	add_hs(dmi.base_board.manufacturer);
+	add_hs(dmi.base_board.product_name);
+	add_hs(dmi.base_board.version);
+	add_hs(dmi.base_board.serial);
+	add_hs(dmi.base_board.asset_tag);
+	add_hs(dmi.base_board.location);
+	add_hs(dmi.base_board.type);
+	for (int i = 0; i < BASE_BOARD_NB_ELEMENTS; i++) {
+		if (((bool *) (&hardware->dmi.base_board.features))[i] == true) {
+			add_s("dmi.base_board.features",(char *)base_board_features_strings[i]);
+		}
+	}
+
+	for (unsigned int i = 0; i < sizeof hardware->dmi.base_board.devices_information /
+		         sizeof *hardware->dmi.base_board.devices_information; i++) {
+	        if (strlen(hardware->dmi.base_board.devices_information[i].type)) {
+			add_s("dmi.base_board.devices_information.type", hardware->dmi.base_board.devices_information[i].type);
+			add_i("dmi.base_board.devices_information.status", hardware->dmi.base_board.devices_information[i].status);
+			add_s("dmi.base_board.devices_information.description", hardware->dmi.base_board.devices_information[i].description);
+		}
+	}
+	FLUSH_OBJECT;
+}
+
+void dump_dmi(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	CREATE_NEW_OBJECT;
+	add_hb(is_dmi_valid);
+
+	if (hardware->is_dmi_valid == false) {
+		FLUSH_OBJECT;
+		goto exit;
+	} else {
+		char buffer[8]={0};
+		snprintf(buffer,sizeof(buffer),"%d.%d",hardware->dmi.dmitable.major_version, hardware->dmi.dmitable.minor_version);
+		add_s("dmi.version",buffer);
+		FLUSH_OBJECT;
+	}
+
+	dump_base_board(hardware,config,item);
+	dump_system(hardware,config,item);
+	dump_bios(hardware,config,item);
+	dump_chassis(hardware,config,item);
+	dump_ipmi(hardware,config,item);
+	dump_battery(hardware,config,item);
+	dump_processor(hardware,config,item);
+	dump_cache(hardware,config,item);
+	dump_memory_banks(hardware,config,item);
+	dump_memory_modules(hardware,config,item);
+	dump_memory_size(hardware,config,item);
+	dump_oem_strings(hardware,config,item);
+	dump_hardware_security(hardware,config,item);
+exit:
+	to_cpio("dmi");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-hdt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-hdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-hdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,50 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 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 "hdt-common.h"
+#include "hdt-dump.h"
+#include <syslinux/config.h>
+
+void dump_hdt(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	(void) hardware;
+	CREATE_NEW_OBJECT;
+	add_s("hdt.product_name",PRODUCT_NAME);
+	add_s("hdt.version",VERSION);
+	add_s("hdt.code_name",CODENAME);
+	add_s("hdt.author", AUTHOR);
+	add_s("hdt.core_developer", CORE_DEVELOPER);
+	char *contributors[NB_CONTRIBUTORS] = CONTRIBUTORS;
+	for (int c = 0; c < NB_CONTRIBUTORS; c++) {
+		add_s("hdt.contributor", contributors[c]);
+	}
+	add_s("hdt.website",WEBSITE_URL);
+	add_s("hdt.irc_channel",IRC_CHANNEL);
+	FLUSH_OBJECT
+	to_cpio("hdt");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-kernel.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-kernel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-kernel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,69 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 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 "hdt-common.h"
+#include "hdt-dump.h"
+
+void dump_kernel(struct s_hardware *hardware, ZZJSON_CONFIG * config,
+		 ZZJSON ** item)
+{
+    struct pci_device *pci_device = NULL;
+    CREATE_ARRAY
+	    add_as("Linux Kernel modules", "")
+    END_OF_ARRAY;
+
+    if (hardware->pci_ids_return_code == -ENOPCIIDS) {
+	APPEND_ARRAY 
+		add_as("Error", "No pci.ids file")
+	END_OF_APPEND FLUSH_OBJECT;
+	return;
+    }
+
+    if ((hardware->modules_pcimap_return_code == -ENOMODULESPCIMAP)
+	&&(hardware->modules_pcimap_return_code == -ENOMODULESALIAS)) {
+	APPEND_ARRAY
+		add_as("Error", "No modules.pcimap or modules.alias file")
+	END_OF_APPEND FLUSH_OBJECT;
+	return;
+
+	}
+
+    /* For every detected pci device, compute its submenu */
+    for_each_pci_func(pci_device, hardware->pci_domain) {
+	if (pci_device == NULL)
+	    continue;
+	for (int kmod = 0;
+	     kmod < pci_device->dev_info->linux_kernel_module_count; kmod++) {
+	    APPEND_ARRAY
+		    add_as(pci_device->dev_info->category_name, pci_device->dev_info->linux_kernel_module[kmod])
+	    END_OF_APPEND;
+	}
+    }
+    FLUSH_OBJECT;
+    to_cpio("kernel");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-memory.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-memory.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-memory.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,133 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 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 <memory.h>
+#include "hdt-common.h"
+#include "hdt-dump.h"
+
+void dump_88(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	(void) hardware;
+	int mem_size = 0;
+	CREATE_NEW_OBJECT;
+	if (detect_memory_88(&mem_size)) {
+		add_s("memory.error","8800h memory configuration is invalid");
+		FLUSH_OBJECT
+		return;
+	}
+
+	add_s("dmi.item","memory via 88");
+	add_i("memory.size (KiB)", mem_size);
+	add_i("memory.size (MiB)", mem_size >> 10);
+	FLUSH_OBJECT;
+}
+
+void dump_e801(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	(void) hardware;
+	int mem_low, mem_high = 0;
+	CREATE_NEW_OBJECT;
+	if (detect_memory_e801(&mem_low,&mem_high)) {
+		add_s("memory.error","e801 memory configuration is invalid");
+		FLUSH_OBJECT;
+		return;
+	}
+
+	add_s("dmi.item","memory via e801");
+	add_i("memory.total.size (KiB)", mem_low + (mem_high << 6));
+	add_i("memory.total.size (MiB)", (mem_low >> 10) + (mem_high >> 4));
+	add_i("memory.low.size (KiB)", mem_low );
+	add_i("memory.low.size (MiB)", mem_low >> 10);
+	add_i("memory.high.size (KiB)", mem_high << 6);
+	add_i("memory.high.size (MiB)", mem_high >> 4);
+	FLUSH_OBJECT;
+
+}
+void dump_e820(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+    
+	(void) hardware;
+	struct e820entry map[E820MAX];
+	struct e820entry nm[E820MAX];
+	unsigned long memsize = 0;
+	int count = 0;
+	char type[14] = {0};
+	
+	detect_memory_e820(map, E820MAX, &count);
+ 	memsize = memsize_e820(map, count);
+	
+	CREATE_NEW_OBJECT;
+		add_s("dmi.item","memory via e820");
+		add_i("memory.total.size (KiB)", memsize);
+		add_i("memory.total.size (MiB)", (memsize + (1 << 9)) >> 10);
+	FLUSH_OBJECT;
+
+	for (int i = 0; i < count; i++) {
+		get_type(map[i].type, type, sizeof(type));
+		char begin[24]={0};
+		char size[24]={0};
+		char end[24]={0};
+		snprintf(begin,sizeof(begin),"0x%016llx",map[i].addr);
+		snprintf(size,sizeof(size),"0x%016llx",map[i].size);
+		snprintf(end,sizeof(end),"0x%016llx",map[i].addr+map[i].size);
+		CREATE_NEW_OBJECT;
+			add_s("memory.segment.start",begin);
+			add_s("memory.segment.size ",size);
+			add_s("memory.segment.end  ",end);
+			add_s("memory.segment.type ",remove_spaces(type));
+		FLUSH_OBJECT;
+	}
+
+	int nr = sanitize_e820_map(map, nm, count);
+	for (int i = 0; i < nr; i++) {
+		get_type(nm[i].type, type, sizeof(type));
+		char begin[24]={0};
+		char size[24]={0};
+		char end[24]={0};
+		snprintf(begin,sizeof(begin),"0x%016llx",nm[i].addr);
+		snprintf(size,sizeof(size),"0x%016llx",nm[i].size);
+		snprintf(end,sizeof(end),"0x%016llx",nm[i].addr+nm[i].size);
+		CREATE_NEW_OBJECT;
+			add_s("sanitized_memory.segment.start",begin);
+			add_s("sanitized_memory.segment.size ",size);
+			add_s("sanitized_memory.segment.end  ",end);
+			add_s("sanitized_memory.segment.type ",remove_spaces(type));
+		FLUSH_OBJECT;
+	}
+}
+
+void dump_memory(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	CREATE_NEW_OBJECT;
+		add_s("Memory configuration","true");
+	FLUSH_OBJECT;
+
+	dump_88(hardware,config,item);
+	dump_e801(hardware,config,item);
+	dump_e820(hardware,config,item);
+	to_cpio("memory");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-pci.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-pci.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-pci.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,136 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 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 "hdt-common.h"
+#include "hdt-dump.h"
+
+void dump_pci(struct s_hardware *hardware, ZZJSON_CONFIG * config,
+	      ZZJSON ** item)
+{
+    int i = 1;
+    struct pci_device *pci_device=NULL;
+    char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+    bool nopciids = false;
+    bool nomodulespcimap = false;
+    bool nomodulesalias = false;
+    bool nomodulesfile = false;
+    int bus = 0, slot = 0, func = 0;
+    
+    if (hardware->pci_ids_return_code == -ENOPCIIDS) {
+	nopciids = true;
+    }
+    if (hardware->modules_pcimap_return_code == -ENOMODULESPCIMAP) {
+	nomodulespcimap = true;
+    }
+    if (hardware->modules_pcimap_return_code == -ENOMODULESALIAS) {
+	nomodulesalias = true;
+    }
+
+    nomodulesfile = nomodulespcimap && nomodulesalias;
+
+    CREATE_NEW_OBJECT;
+
+    add_i("pci_device.count", hardware->nb_pci_devices);
+
+    FLUSH_OBJECT;
+    /* For every detected pci device, compute its submenu */
+    for_each_pci_func(pci_device, hardware->pci_domain) {
+	if (pci_device == NULL)
+	    continue;
+	char v[10] = { 0 };
+	char sv[10] = { 0 };
+	char p[10] = { 0 };
+	char sp[10] = { 0 };
+	char c[10] = { 0 };
+	char r[10] = { 0 };
+
+	CREATE_NEW_OBJECT;
+	bus = __pci_bus;
+	slot = __pci_slot;
+	func = __pci_func;
+
+	memset(kernel_modules, 0, sizeof kernel_modules);
+	for (int kmod = 0;
+	     kmod < pci_device->dev_info->linux_kernel_module_count; kmod++) {
+	    if (kmod > 0) {
+		strncat(kernel_modules, " | ", 3);
+	    }
+	    strncat(kernel_modules,
+		    pci_device->dev_info->linux_kernel_module[kmod],
+		    LINUX_KERNEL_MODULE_SIZE - 1);
+	}
+	if (pci_device->dev_info->linux_kernel_module_count == 0)
+	    strlcpy(kernel_modules, "unknown", 7);
+
+	add_i("pci_device.number", i);
+	if (nopciids == false) {
+	    add_s("pci_device.vendor_name", pci_device->dev_info->vendor_name);
+	    add_s("pci_device.product_name",
+		   pci_device->dev_info->product_name);
+	}
+	if (nomodulesfile == false) {
+	    add_s("pci_device.class_name", pci_device->dev_info->class_name);
+	    add_s("pci_device.kernel_module", kernel_modules);
+	}
+
+	snprintf(v, sizeof(v), "%04x", pci_device->vendor);
+	snprintf(p, sizeof(p), "%04x", pci_device->product);
+	snprintf(sv, sizeof(sv), "%04x", pci_device->sub_vendor);
+	snprintf(sp, sizeof(sp), "%04x", pci_device->sub_product);
+	snprintf(c, sizeof(c), "%02x.%02x.%02x",
+		 pci_device->class[2],
+		 pci_device->class[1], pci_device->class[0]);
+	snprintf(r, sizeof(r), "%02x", pci_device->revision);
+	add_s("pci_device.vendor_id", v);
+	add_s("pci_device.product_id", p);
+	add_s("pci_device.sub_vendor_id", sv);
+	add_s("pci_device.sub_product_id", sp);
+	add_s("pci_device.class_id", c);
+	add_s("pci_device.revision", r);
+	if ((pci_device->dev_info->irq > 0)
+	    && (pci_device->dev_info->irq < 255))
+	    add_i("pci_device.irq", pci_device->dev_info->irq);
+
+	add_i("pci_device.latency", pci_device->dev_info->latency);
+	add_i("pci_device.bus", bus);
+	add_i("pci_device.slot", slot);
+	add_i("pci_device.func", func);
+
+	if (hardware->is_pxe_valid == true) {
+	    if ((hardware->pxe.pci_device != NULL)
+		&& (hardware->pxe.pci_device == pci_device)) {
+		add_hs(pxe.mac_addr);
+		add_s("pxe", "Current boot device");
+	    }
+	}
+	i++;
+	FLUSH_OBJECT;
+    }
+    to_cpio("pci");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-pxe.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-pxe.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-pxe.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,80 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 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 "hdt-common.h"
+#include "hdt-dump.h"
+#include <sys/gpxe.h>
+#include <netinet/in.h>
+
+void dump_pxe(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+	struct in_addr in;
+
+	CREATE_NEW_OBJECT;
+	add_hb(is_pxe_valid);
+	if (hardware->is_pxe_valid) {
+		char buffer[32] = {0};
+		snprintf(buffer,sizeof(buffer),"0x%x",hardware->pxe.vendor_id);
+		add_s("pxe.vendor_id",buffer);
+		snprintf(buffer,sizeof(buffer),"0x%x",hardware->pxe.product_id);
+		add_s("pxe.product_id",buffer);
+		snprintf(buffer,sizeof(buffer),"0x%x",hardware->pxe.subvendor_id);
+		add_s("pxe.subvendor_id",buffer);
+		snprintf(buffer,sizeof(buffer),"0x%x",hardware->pxe.subproduct_id);
+		add_s("pxe.subproduct_id",buffer);
+
+		if (hardware->pci_ids_return_code == -ENOPCIIDS || (hardware->pxe.pci_device == NULL)) { 
+			add_s("Manufacturer_name","no_pci_ids_file or no device found");
+			add_s("Product_name","no_pci_ids_file or no device found");
+		} else {
+			add_s("Manufacturer_name", hardware->pxe.pci_device->dev_info->vendor_name);
+			add_s("Product_name", hardware->pxe.pci_device->dev_info->product_name);
+		}
+
+		add_hi(pxe.rev);
+		add_hi(pxe.pci_bus);
+		add_hi(pxe.pci_dev);
+		add_hi(pxe.pci_func);
+		add_hi(pxe.base_class);
+		add_hi(pxe.sub_class);
+		add_hi(pxe.prog_intf);
+		add_hi(pxe.nictype);
+		add_hs(pxe.mac_addr);
+	
+		in.s_addr = hardware->pxe.dhcpdata.cip;
+		add_s("pxe.client_ip", inet_ntoa(in));
+		in.s_addr = hardware->pxe.dhcpdata.sip;
+		add_s("pxe.next_server_ip",inet_ntoa(in));
+		in.s_addr = hardware->pxe.dhcpdata.gip;
+		add_s("pxe.relay_agent_ip",inet_ntoa(in));
+		memcpy(&in, hardware->pxe.ip_addr, sizeof in);
+		add_s("pxe.ipaddr",inet_ntoa(in));
+		add_b("gpxe_detected",is_gpxe());
+	}
+	FLUSH_OBJECT;
+	to_cpio("pxe");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-syslinux.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-syslinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-syslinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,43 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 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 "hdt-common.h"
+#include "hdt-dump.h"
+#include <syslinux/config.h>
+
+void dump_syslinux(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	CREATE_NEW_OBJECT;
+	add_hs(syslinux_fs);
+	add_hs(sv->version_string);
+	add_hi(sv->version);
+	add_hi(sv->max_api);
+	add_hs(sv->copyright_string);
+	FLUSH_OBJECT
+	to_cpio("syslinux");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-vesa.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-vesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-vesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,67 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 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 "hdt-common.h"
+#include "hdt-dump.h"
+#include <syslinux/config.h>
+
+void dump_vesa(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	CREATE_NEW_OBJECT;
+	add_hb(is_vesa_valid);
+	if (hardware->is_vesa_valid) {
+		char buffer[64]={0};
+		snprintf(buffer,sizeof(buffer),"%d.%d", hardware->vesa.major_version, hardware->vesa.minor_version);
+		add_s("vesa.version",buffer);
+		add_hs(vesa.vendor);
+		add_hs(vesa.product);
+		add_hs(vesa.product_revision);
+		add_hi(vesa.software_rev);
+		memset(buffer,0,sizeof(buffer));
+		snprintf(buffer,sizeof(buffer),"%d KB",hardware->vesa.total_memory*64);
+		add_s("vesa.memory",buffer);
+		add_i("vesa.modes",hardware->vesa.vmi_count);
+		FLUSH_OBJECT;
+		for (int i = 0; i < hardware->vesa.vmi_count; i++) {
+		        struct vesa_mode_info *mi = &hardware->vesa.vmi[i].mi;
+		        if ((mi->h_res == 0) || (mi->v_res == 0))
+				continue;
+			CREATE_NEW_OBJECT;
+			memset(buffer,0,sizeof(buffer));
+			snprintf(buffer,sizeof(buffer),"0x%04x",hardware->vesa.vmi[i].mode + 0x200);
+			add_s("vesa.kernel_mode",buffer);
+			add_i("vesa.hres",mi->h_res);
+			add_i("vesa.vres",mi->v_res);
+			add_i("vesa.bpp",mi->bpp);
+			FLUSH_OBJECT;
+		}
+	} else {
+		FLUSH_OBJECT;
+	}
+	to_cpio("vesa");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-vpd.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-vpd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump-vpd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,47 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 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 "hdt-common.h"
+#include "hdt-dump.h"
+
+void dump_vpd(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item) {
+
+	CREATE_NEW_OBJECT;
+	add_hb(is_vpd_valid);
+    	if (hardware->is_vpd_valid) {
+		add_hs(vpd.bios_build_id);
+		add_hs(vpd.bios_release_date);
+		add_hs(vpd.bios_version);
+		add_hs(vpd.default_flash_filename);
+		add_hs(vpd.box_serial_number);
+		add_hs(vpd.motherboard_serial_number);
+		add_hs(vpd.machine_type_model);
+	}
+	FLUSH_OBJECT;
+	to_cpio("vpd");
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,229 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2011 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 <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <getkey.h>
+#include <syslinux/config.h>
+#include "hdt-common.h"
+#include "hdt-dump.h"
+
+struct print_buf p_buf;
+
+struct dump_option {
+    char *flag;
+    char *item;
+};
+
+char *get_value_from_option(struct s_hardware *hardware, char *option)
+{
+    struct dump_option dump_options[10];
+    dump_options[0].flag = "%{m}";
+    dump_options[0].item = hardware->pxe.mac_addr;
+
+    dump_options[1].flag = "%{v}";
+    dump_options[1].item = hardware->dmi.system.manufacturer;
+
+    dump_options[2].flag = "%{p}";
+    dump_options[2].item = hardware->dmi.system.product_name;
+
+    dump_options[3].flag = "%{ba}";
+    dump_options[3].item = hardware->dmi.base_board.asset_tag;
+
+    dump_options[4].flag = "%{bs}";
+    dump_options[4].item = hardware->dmi.base_board.serial;
+
+    dump_options[5].flag = "%{ca}";
+    dump_options[5].item = hardware->dmi.chassis.asset_tag;
+
+    dump_options[6].flag = "%{cs}";
+    dump_options[6].item = hardware->dmi.chassis.serial;
+
+    dump_options[7].flag = "%{sk}";
+    dump_options[7].item = hardware->dmi.system.sku_number;
+
+    dump_options[8].flag = "%{ss}";
+    dump_options[8].item = hardware->dmi.system.serial;
+
+    dump_options[9].flag = NULL;
+    dump_options[9].item = NULL;
+
+    for (int i = 0; i < 9; i++) {
+	if (strcmp(option, dump_options[i].flag) == 0) {
+	    return remove_spaces(dump_options[i].item);
+	}
+    }
+
+    return NULL;
+}
+
+char *compute_filename(struct s_hardware *hardware)
+{
+
+    char *filename = malloc(512);
+    snprintf(filename, 512, "%s/%s", hardware->dump_path,
+	     hardware->dump_filename);
+
+    /* Until we found some dump parameters */
+    char *buffer;
+    while ((buffer = strstr(filename, "%{"))) {
+	// Find the end of the parameter
+	char *buffer_end = strstr(buffer, "}");
+
+	// Extracting the parameter between %{ and }
+	char option[8] = { 0 };
+	strncpy(option, buffer, buffer_end - buffer + 1);
+
+	/* Replace this option by its value in the filename 
+	 * Filename is longer than the previous filename we had
+	 * so let's restart from the beginning */
+	filename =
+	    strreplace(filename, option,
+		       get_value_from_option(hardware, option));
+    }
+
+    /* We replace the ":" in the filename by some "-"
+     * This will avoid Microsoft FS turning crazy */
+    chrreplace(filename, ':', '-');
+
+    /* Avoid space to make filename easier to manipulate */
+    chrreplace(filename, ' ', '_');
+
+    return filename;
+}
+
+int dumpprintf(FILE * p, const char *format, ...)
+{
+    va_list ap;
+    int rv;
+
+    (void)p;
+    va_start(ap, format);
+    rv = vbufprintf(&p_buf, format, ap);
+    va_end(ap);
+    return rv;
+}
+
+void to_cpio(char *filename)
+{
+    cpio_writefile(upload, filename, p_buf.buf, p_buf.len);
+    if ((p_buf.buf) && (p_buf.len > 0)) {
+	memset(p_buf.buf, 0, p_buf.len);
+	free(p_buf.buf);
+	p_buf.buf = NULL;
+	p_buf.size = 0;
+	p_buf.len = 0;
+    }
+}
+
+void flush(ZZJSON_CONFIG * config, ZZJSON ** item)
+{
+    zzjson_print(config, *item);
+    zzjson_free(config, *item);
+    *item = NULL;
+}
+
+/**
+ * dump - dump info
+ **/
+void dump(struct s_hardware *hardware)
+{
+    if (hardware->is_pxe_valid == false) {
+	more_printf("PXE stack was not detected, Dump feature is not available\n");
+	return;
+    }
+
+    const union syslinux_derivative_info *sdi = syslinux_derivative_info();
+    int err = 0;
+    ZZJSON *json = NULL;
+    ZZJSON_CONFIG config = { ZZJSON_VERY_STRICT, NULL,
+	(int (*)(void *))fgetc,
+	NULL,
+	malloc, calloc, free, realloc,
+	stderr, NULL, stdout,
+	(int (*)(void *, const char *,...))dumpprintf,
+	(int (*)(int, void *))fputc
+    };
+
+    memset(&p_buf, 0, sizeof(p_buf));
+
+    /* By now, we only support TFTP reporting */
+    upload = &upload_tftp;
+    upload->name = "tftp";
+
+    /* The following defines the behavior of the reporting */
+    char *arg[64];
+    char *filename = compute_filename(hardware);
+
+    /* The filename */
+    arg[0] = filename;
+    /* The server to upload the file */
+    if (strlen(hardware->tftp_ip) != 0) {
+	arg[1] = hardware->tftp_ip;
+	arg[2] = NULL;
+    } else {
+	arg[1] = NULL;
+	snprintf(hardware->tftp_ip, sizeof(hardware->tftp_ip),
+		 "%u.%u.%u.%u",
+		 ((uint8_t *) & sdi->pxe.ipinfo->serverip)[0],
+		 ((uint8_t *) & sdi->pxe.ipinfo->serverip)[1],
+		 ((uint8_t *) & sdi->pxe.ipinfo->serverip)[2],
+		 ((uint8_t *) & sdi->pxe.ipinfo->serverip)[3]);
+
+    }
+
+    /* We initiate the cpio to send */
+    cpio_init(upload, (const char **)arg);
+
+    dump_cpu(hardware, &config, &json);
+    dump_pxe(hardware, &config, &json);
+    dump_syslinux(hardware, &config, &json);
+    dump_vpd(hardware, &config, &json);
+    dump_vesa(hardware, &config, &json);
+    dump_disks(hardware, &config, &json);
+    dump_dmi(hardware, &config, &json);
+    dump_memory(hardware, &config, &json);
+    dump_pci(hardware, &config, &json);
+    dump_acpi(hardware, &config, &json);
+    dump_kernel(hardware, &config, &json);
+    dump_hdt(hardware, &config, &json);
+
+    /* We close & flush the file to send */
+    cpio_close(upload);
+
+    if ((err = flush_data(upload)) != TFTP_OK) {
+	/* As we manage a tftp connection, let's display the associated error message */
+	more_printf("Dump failed !\n");
+	more_printf("TFTP ERROR on  : %s:/%s \n", hardware->tftp_ip, filename);
+	more_printf("TFTP ERROR msg : %s \n", tftp_string_error_message[-err]);
+    } else {
+	more_printf("Dump file sent at %s:/%s\n", hardware->tftp_ip, filename);
+    }
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-dump.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,85 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 20011 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 <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <bufprintf.h>
+#include <zzjson/zzjson.h>
+#include "hdt-common.h"
+
+// Macros to manipulate Arrays
+#define APPEND_ARRAY ZZJSON *temp_array; temp_array = zzjson_array_append(config, *item, zzjson_create_object(config,
+#define APPEND_OBJECT_ARRAY(value) ZZJSON *temp_ar; temp_ar = zzjson_array_append(config, *item, value); *item=temp_ar; 
+#define CREATE_ARRAY *item = zzjson_create_array(config, zzjson_create_object(config, 
+#define add_ai(name,value) name,zzjson_create_number_i(config,value),
+#define add_ahi(value) add_ai(#value,hardware->value)
+#define add_as(name,value) name,zzjson_create_string(config,value),
+#define add_ahs(value) add_as(#value,hardware->value)
+#define END_OF_ARRAY NULL),NULL)
+#define END_OF_APPEND NULL)); *item=temp_array;
+
+// Macros to manipulate objects
+#define CREATE_NEW_OBJECT   *item = zzjson_create_object(config, NULL);
+#define FLUSH_OBJECT flush(config, item); 
+
+// Macros to manipulate integers as objects
+#define add_i(name,value) *item = zzjson_object_append(config, *item, name, zzjson_create_number_i(config, value))
+#define add_hi(value) add_i(#value,hardware->value)
+
+// Macros to manipulate strings as objects
+#define add_s(name,value) *item = zzjson_object_append(config, *item, name, zzjson_create_string(config, value))
+#define add_hs(value) add_s(#value,(char *)hardware->value)
+
+// Macros to manipulate bool as objects
+#define add_bool_true(name) *item = zzjson_object_append(config, *item, (char *)name, zzjson_create_true(config))
+#define add_bool_false(name) *item = zzjson_object_append(config, *item, (char*)name, zzjson_create_false(config))
+#define add_b(name,value) if (value==true) {add_bool_true(name);} else {add_bool_false(name);}
+#define add_hb(value) add_b(#value,hardware->value)
+
+extern struct print_buf p_buf;
+
+void print_and_flush(ZZJSON_CONFIG *config, ZZJSON **item);
+int dumpprintf(FILE *p, const char *format, ...);
+void flush (ZZJSON_CONFIG *config, ZZJSON ** item);
+void to_cpio(char *filename);
+
+void dump_cpu(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_pxe(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_syslinux(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_vpd(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_vesa(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_disks(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_dmi(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_memory(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_pci(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_acpi(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_kernel(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump_hdt(struct s_hardware *hardware, ZZJSON_CONFIG *config, ZZJSON **item);
+void dump(struct s_hardware *hardware);
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-about.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-about.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-about.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,92 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-menu.h"
+
+/* Computing About menu*/
+void compute_aboutmenu(struct s_my_menu *menu)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    menu->menu = add_menu(" About ", -1);
+    menu->items_count = 0;
+
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "Product        : %s", PRODUCT_NAME);
+    snprintf(statbuffer, sizeof statbuffer, "Product : %s", PRODUCT_NAME);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Version        : %s (%s)", VERSION,
+	     CODENAME);
+    snprintf(statbuffer, sizeof statbuffer, "Version : %s (%s)", VERSION,
+	     CODENAME);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Website        : %s", WEBSITE_URL);
+    snprintf(statbuffer, sizeof statbuffer, "Website : %s",WEBSITE_URL);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "IRC Channel    : %s", IRC_CHANNEL);
+    snprintf(statbuffer, sizeof statbuffer, "IRC Channel : %s",IRC_CHANNEL);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Mailing List   : %s", CONTACT);
+    snprintf(statbuffer, sizeof statbuffer, "Mailing List: %s", CONTACT);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    add_item("", "", OPT_SEP, "", 0);
+
+    snprintf(buffer, sizeof buffer, "Project Leader : %s", AUTHOR);
+    snprintf(statbuffer, sizeof statbuffer, "Project Leader  : %s", AUTHOR);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Core Developer : %s", CORE_DEVELOPER);
+    snprintf(statbuffer, sizeof statbuffer, "Core Developer  : %s",
+	     CORE_DEVELOPER);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    char *contributors[NB_CONTRIBUTORS] = CONTRIBUTORS;
+    for (int c = 0; c < NB_CONTRIBUTORS; c++) {
+	snprintf(buffer, sizeof buffer, "Contributor    : %s", contributors[c]);
+	snprintf(statbuffer, sizeof statbuffer, "Contributor : %s",
+		 contributors[c]);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    printf("MENU: About menu done (%d items)\n", menu->items_count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-acpi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-acpi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-acpi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,134 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include "hdt-menu.h"
+
+void compute_table(struct s_my_menu *menu, void *address, s_acpi_description_header * h) {
+    char buffer[SUBMENULEN + 1] = { 0 };
+    char statbuffer[STATLEN + 1] = { 0 };
+
+    snprintf(buffer, sizeof buffer, "%-4s v%03x %-6s %-8s %-7s %08x", 
+		    h->signature, h->revision, h->oem_id, h->oem_table_id, h->creator_id, h->creator_revision);
+    snprintf(statbuffer, sizeof statbuffer, "%-4s v%03x %-6s %-7s 0x%08x %-4s    0x%08x @ 0x%p", 
+		    h->signature, h->revision, h->oem_id, h->oem_table_id,
+		    h->oem_revision, h->creator_id, h->creator_revision, address);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+}
+
+/* Submenu for the vesa card */
+static void compute_acpi_tables(struct s_my_menu *menu,
+			      struct s_hardware *hardware)
+{
+    menu->menu = add_menu(" ACPI Tables ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    char buffer[SUBMENULEN + 1] = { 0 };
+
+    snprintf(buffer, sizeof buffer, "%-4s %-4s %-6s %-8s %-7s %-8s", 
+		    "ACPI", "rev", "oem", "table_id", "creator", "creator_rev");
+    add_item(buffer, "Description", OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    add_item("", "", OPT_SEP, "", 0);
+
+    if (hardware->acpi.rsdt.valid)
+        compute_table(menu,hardware->acpi.rsdt.address,
+                       &hardware->acpi.rsdt.header);
+
+    if (hardware->acpi.xsdt.valid)
+        compute_table(menu,hardware->acpi.xsdt.address,
+                       &hardware->acpi.xsdt.header);
+
+    if (hardware->acpi.fadt.valid)
+        compute_table(menu,hardware->acpi.fadt.address, &hardware->acpi.fadt.header);
+
+    if (hardware->acpi.dsdt.valid)
+        compute_table(menu,hardware->acpi.dsdt.address, &hardware->acpi.dsdt.header);
+
+    /* SSDT includes many optional tables, let's display them */
+    for (int i = 0; i < hardware->acpi.ssdt_count; i++) {
+        if ((hardware->acpi.ssdt[i] != NULL) && (hardware->acpi.ssdt[i]->valid))
+            compute_table(menu,hardware->acpi.ssdt[i]->address,
+                        &hardware->acpi.ssdt[i]->header);
+    }
+
+    if (hardware->acpi.sbst.valid)
+        compute_table(menu,hardware->acpi.sbst.address, &hardware->acpi.sbst.header);
+
+    if (hardware->acpi.ecdt.valid)
+        compute_table(menu,hardware->acpi.ecdt.address, &hardware->acpi.ecdt.header);
+
+    if (hardware->acpi.hpet.valid)
+        compute_table(menu,hardware->acpi.hpet.address, &hardware->acpi.hpet.header);
+
+    if (hardware->acpi.tcpa.valid)
+        compute_table(menu,hardware->acpi.tcpa.address, &hardware->acpi.tcpa.header);
+
+    if (hardware->acpi.mcfg.valid)
+        compute_table(menu,hardware->acpi.mcfg.address, &hardware->acpi.mcfg.header);
+    
+    if (hardware->acpi.slic.valid)
+        compute_table(menu,hardware->acpi.slic.address, &hardware->acpi.slic.header);
+
+    if (hardware->acpi.boot.valid)
+        compute_table(menu,hardware->acpi.boot.address, &hardware->acpi.boot.header);
+
+    /* FACS isn't having the same headers, let's use a dedicated rendering */
+    if (hardware->acpi.facs.valid) {
+	s_facs *fa = &hardware->acpi.facs;
+        char buffer[SUBMENULEN + 1] = { 0 };
+        char statbuffer[STATLEN + 1] = { 0 };
+
+	snprintf(buffer, sizeof buffer, "%-4s", fa->signature); 
+	snprintf(statbuffer, sizeof statbuffer, "%-4s @ 0x%p", fa->signature, fa->address);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    	menu->items_count++;
+    }
+
+    if (hardware->acpi.madt.valid)
+        compute_table(menu,hardware->acpi.madt.address, &hardware->acpi.madt.header);
+
+}
+
+/* Main ACPI Menu*/
+int compute_ACPI(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware)
+{
+    compute_acpi_tables(&hdt_menu->acpi_tables_menu, hardware);
+    hdt_menu->acpi_menu.menu = add_menu(" ACPI ", -1);
+    hdt_menu->acpi_menu.items_count = 0;
+
+    add_item("Tables", "Tables", OPT_SUBMENU, NULL,
+	     hdt_menu->acpi_tables_menu.menu);
+    hdt_menu->acpi_menu.items_count++;
+    printf("MENU: ACPI menu done (%d items)\n",
+	   hdt_menu->acpi_menu.items_count);
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-disk.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-disk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-disk.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,264 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <stdlib.h>
+
+#include "hdt-menu.h"
+#include "hdt-util.h"
+
+static int dn;
+
+static void show_partition_information(struct driveinfo *drive_info,
+				       struct part_entry *ptab __unused,
+				       int partition_offset __unused,
+				       int nb_partitions_seen)
+{
+    char menu_title[MENULEN + 1];
+    char menu_title_ref[MENULEN + 1];
+
+    if (nb_partitions_seen == 1)
+	add_sep();
+
+    memset(menu_title, 0, sizeof menu_title);
+    memset(menu_title_ref, 0, sizeof menu_title_ref);
+    snprintf(menu_title_ref, sizeof menu_title_ref, "disk_%x_part_%d",
+	     drive_info[dn].disk, nb_partitions_seen);
+    snprintf(menu_title, sizeof menu_title, "Partition %d", nb_partitions_seen);
+
+    add_item(menu_title,
+	     "Partition information (start, end, length, type, ...)",
+	     OPT_SUBMENU, menu_title_ref, 0);
+}
+
+/**
+ * compute_partition_information - print information about a partition
+ * @ptab:       part_entry describing the partition
+ * @i:          Partition number (UI purposes only)
+ * @ptab_root:  part_entry describing the root partition (extended only)
+ * @drive_info: driveinfo struct describing the drive on which the partition
+ *              is
+ *
+ * Note on offsets (from hpa, see chain.c32):
+ *
+ *  To make things extra confusing: data partition offsets are relative to where
+ *  the data partition record is stored, whereas extended partition offsets
+ *  are relative to the beginning of the extended partition all the way back
+ *  at the MBR... but still not absolute!
+ **/
+static void compute_partition_information(struct driveinfo *drive_info,
+					  struct part_entry *ptab,
+					  int partition_offset,
+					  int nb_partitions_seen)
+{
+    char size[11];
+    char bootloader_name[9];
+    char *parttype;
+    unsigned int start, end;
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+    char menu_title[MENULEN + 1];
+    char menu_title_ref[MENULEN + 1];
+
+    memset(buffer, 0, sizeof buffer);
+    memset(statbuffer, 0, sizeof statbuffer);
+    memset(menu_title, 0, sizeof menu_title);
+    memset(menu_title_ref, 0, sizeof menu_title_ref);
+    snprintf(menu_title_ref, sizeof menu_title_ref, "disk_%x_part_%d",
+	     drive_info[dn].disk, nb_partitions_seen);
+    snprintf(menu_title, sizeof menu_title, "Partition %d", nb_partitions_seen);
+
+    add_named_menu(menu_title_ref, menu_title, -1);
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    start = partition_offset;
+    end = start + ptab->length - 1;
+
+    if (ptab->length > 0)
+	sectors_to_size(ptab->length, size);
+    else
+	memset(size, 0, sizeof size);
+
+    get_label(ptab->ostype, &parttype);
+
+    snprintf(buffer, sizeof buffer, "Size        : %s", remove_spaces(size));
+    snprintf(statbuffer, sizeof statbuffer, "Size : %s", remove_spaces(size));
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+    snprintf(buffer, sizeof buffer, "Type        : %s", parttype);
+    snprintf(statbuffer, sizeof statbuffer, "Type: %s", parttype);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+    if (get_bootloader_string(drive_info, ptab, bootloader_name, 9) == 0) {
+	snprintf(buffer, sizeof buffer, "Bootloader  : %s", bootloader_name);
+	snprintf(statbuffer, sizeof statbuffer, "Bootloader: %s",
+		 bootloader_name);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    }
+
+    snprintf(buffer, sizeof buffer, "Boot Flag   : %s",
+	     (ptab->active_flag == 0x80) ? "Yes" : "No");
+    snprintf(statbuffer, sizeof statbuffer, "Boot Flag: %s",
+	     (ptab->active_flag == 0x80) ? "Yes" : "No");
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+    snprintf(buffer, sizeof buffer, "Start       : %d", start);
+    snprintf(statbuffer, sizeof statbuffer, "Start: %d", start);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+    snprintf(buffer, sizeof buffer, "End         : %d", end);
+    snprintf(statbuffer, sizeof statbuffer, "End: %d", end);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+    snprintf(buffer, sizeof buffer, "Id          : %X", ptab->ostype);
+    snprintf(statbuffer, sizeof statbuffer, "Id: %X", ptab->ostype);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+    free(parttype);
+
+    /* Extra info */
+    if (ptab->ostype == 0x82 && swsusp_check(drive_info, ptab) != -1) {
+	snprintf(buffer, sizeof buffer, "%s", "Swsusp sig  : detected");
+	snprintf(statbuffer, sizeof statbuffer, "%s", "Swsusp sig  : detected");
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    }
+}
+
+/* Compute the disk submenu */
+static int compute_disk_module(struct s_my_menu *menu, int nb_sub_disk_menu,
+			       const struct s_hardware *hardware,
+			       int disk_number)
+{
+    char buffer[MENULEN + 1];
+    char statbuffer[STATLEN + 1];
+    char mbr_name[50];
+    struct driveinfo *d = (struct driveinfo *)hardware->disk_info;
+
+    snprintf(buffer, sizeof buffer, " Disk <0x%X> (EDD %X)",
+	     d[disk_number].disk, d[disk_number].edd_version);
+    menu[nb_sub_disk_menu].menu = add_menu(buffer, -1);
+    menu[nb_sub_disk_menu].items_count = 0;
+
+    int previous_size, size;
+    char previous_unit[3], unit[3];	// GB
+    char size_iec[11];		// GiB
+    char size_dec[11];		// GB
+    sectors_to_size_dec(previous_unit, &previous_size, unit, &size,
+			d[disk_number].edd_params.sectors);
+    sectors_to_size(d[disk_number].edd_params.sectors, size_iec);
+    sectors_to_size_dec2(d[disk_number].edd_params.sectors, size_dec);
+
+    snprintf(buffer, sizeof buffer, "Size              : %s/%s (%d %s)",
+	     remove_spaces(size_iec), remove_spaces(size_dec), previous_size,
+	     previous_unit);
+    snprintf(statbuffer, sizeof statbuffer, "Size: %s/%s (%d %s)",
+	     remove_spaces(size_iec), remove_spaces(size_dec), previous_size,
+	     previous_unit);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu[nb_sub_disk_menu].items_count++;
+
+    /* Do not print Host Bus & Interface if EDD isn't 3.0 or more */
+    if (d[disk_number].edd_version >= 0x30) {
+	snprintf(buffer, sizeof buffer, "Host Bus/Interface: %s / %s",
+		 remove_spaces((char *)d[disk_number].edd_params.host_bus_type),
+		 d[disk_number].edd_params.interface_type);
+	snprintf(statbuffer, sizeof statbuffer, "Host Bus / Interface: %s / %s",
+		 remove_spaces((char *)d[disk_number].edd_params.host_bus_type),
+		 d[disk_number].edd_params.interface_type);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu[nb_sub_disk_menu].items_count++;
+    }
+
+    snprintf(buffer, sizeof buffer, "C / H / S         : %d / %d / %d",
+	     d[disk_number].legacy_max_cylinder + 1,
+	     d[disk_number].legacy_max_head + 1,
+	     (int)d[disk_number].edd_params.sectors);
+    snprintf(statbuffer, sizeof statbuffer,
+	     "Cylinders / Heads / Sectors: %d / %d / %d",
+	     d[disk_number].legacy_max_cylinder + 1,
+	     d[disk_number].legacy_max_head + 1,
+	     (int)d[disk_number].edd_params.sectors);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu[nb_sub_disk_menu].items_count++;
+
+    snprintf(buffer, sizeof buffer, "Sectors/Track     : %d",
+	     d[disk_number].legacy_sectors_per_track);
+    snprintf(statbuffer, sizeof statbuffer, "Sectors per Track: %d",
+	     d[disk_number].legacy_sectors_per_track);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu[nb_sub_disk_menu].items_count++;
+
+    get_mbr_string(hardware->mbr_ids[disk_number], &mbr_name, 50);
+
+    snprintf(buffer, sizeof buffer, "MBR               : %s (0x%X)",
+	     remove_spaces(mbr_name), hardware->mbr_ids[disk_number]);
+    snprintf(statbuffer, sizeof statbuffer, "MBR: %s (id 0x%X)",
+	     remove_spaces(mbr_name), hardware->mbr_ids[disk_number]);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu[nb_sub_disk_menu].items_count++;
+
+    dn = disk_number;
+
+    parse_partition_table(&d[disk_number], &show_partition_information);
+    if (!parse_partition_table(&d[disk_number], &compute_partition_information)) {
+	get_error("parse_partition_table");
+	menu[nb_sub_disk_menu].items_count++;
+    }
+
+    return 0;
+}
+
+/* Compute the Disks menu */
+void compute_disks(struct s_hdt_menu *menu, struct s_hardware *hardware)
+{
+    char buffer[MENULEN + 1];
+    int nb_sub_disk_menu = 0;
+
+    /* No need to compute that menu if no disks were detected */
+    menu->disk_menu.items_count = 0;
+    if (hardware->disks_count == 0)
+	return;
+
+    for (int drive = 0x80; drive < 0xff; drive++) {
+	if (!hardware->disk_info[drive - 0x80].cbios)
+	    continue;		/* Invalid geometry */
+	compute_disk_module
+	    ((struct s_my_menu *)&(menu->disk_sub_menu), nb_sub_disk_menu,
+	     hardware, drive - 0x80);
+	nb_sub_disk_menu++;
+    }
+
+    menu->disk_menu.menu = add_menu(" Disks ", -1);
+
+    for (int i = 0; i < nb_sub_disk_menu; i++) {
+	snprintf(buffer, sizeof buffer, " Disk <%d> ", i + 1);
+	add_item(buffer, "Disk", OPT_SUBMENU, NULL,
+		 menu->disk_sub_menu[i].menu);
+	menu->disk_menu.items_count++;
+    }
+    printf("MENU: Disks menu done (%d items)\n", menu->disk_menu.items_count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-dmi.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-dmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-dmi.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,381 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-menu.h"
+
+/* Compute System main menu */
+void compute_system(struct s_my_menu *menu, s_dmi * dmi)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    menu->menu = add_menu(" System ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "Vendor    : %s", dmi->system.manufacturer);
+    snprintf(statbuffer, sizeof statbuffer, "Vendor: %s",
+	     dmi->system.manufacturer);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Product   : %s", dmi->system.product_name);
+    snprintf(statbuffer, sizeof statbuffer, "Product Name: %s",
+	     dmi->system.product_name);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Version   : %s", dmi->system.version);
+    snprintf(statbuffer, sizeof statbuffer, "Version: %s", dmi->system.version);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Serial    : %s", dmi->system.serial);
+    snprintf(statbuffer, sizeof statbuffer, "Serial Number: %s",
+	     dmi->system.serial);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "UUID      : %s", dmi->system.uuid);
+    snprintf(statbuffer, sizeof statbuffer, "UUID: %s", dmi->system.uuid);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Wakeup    : %s", dmi->system.wakeup_type);
+    snprintf(statbuffer, sizeof statbuffer, "Wakeup Type: %s",
+	     dmi->system.wakeup_type);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "SKU Number: %s", dmi->system.sku_number);
+    snprintf(statbuffer, sizeof statbuffer, "SKU Number: %s",
+	     dmi->system.sku_number);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Family    : %s", dmi->system.family);
+    snprintf(statbuffer, sizeof statbuffer, "Family: %s", dmi->system.family);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    printf("MENU: System menu done (%d items)\n", menu->items_count);
+}
+
+/* Compute Chassis menu */
+void compute_chassis(struct s_my_menu *menu, s_dmi * dmi)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+    menu->menu = add_menu(" Chassis ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "Vendor    : %s",
+	     dmi->chassis.manufacturer);
+    snprintf(statbuffer, sizeof statbuffer, "Vendor: %s",
+	     dmi->chassis.manufacturer);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Type      : %s", dmi->chassis.type);
+    snprintf(statbuffer, sizeof statbuffer, "Type: %s", dmi->chassis.type);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Version   : %s", dmi->chassis.version);
+    snprintf(statbuffer, sizeof statbuffer, "Version: %s",
+	     dmi->chassis.version);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Serial    : %s", dmi->chassis.serial);
+    snprintf(statbuffer, sizeof statbuffer, "Serial Number: %s",
+	     dmi->chassis.serial);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Asset Tag : %s",
+	     del_multi_spaces(dmi->chassis.asset_tag));
+    snprintf(statbuffer, sizeof statbuffer, "Asset Tag: %s",
+	     del_multi_spaces(dmi->chassis.asset_tag));
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Lock      : %s", dmi->chassis.lock);
+    snprintf(statbuffer, sizeof statbuffer, "Lock: %s", dmi->chassis.lock);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    printf("MENU: Chassis menu done (%d items)\n", menu->items_count);
+}
+
+/* Compute BIOS menu */
+void compute_bios(struct s_my_menu *menu, s_dmi * dmi)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    menu->menu = add_menu(" BIOS ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "Vendor    : %s", dmi->bios.vendor);
+    snprintf(statbuffer, sizeof statbuffer, "Vendor: %s", dmi->bios.vendor);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Version   : %s", dmi->bios.version);
+    snprintf(statbuffer, sizeof statbuffer, "Version: %s", dmi->bios.version);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Release   : %s", dmi->bios.release_date);
+    snprintf(statbuffer, sizeof statbuffer, "Release Date: %s",
+	     dmi->bios.release_date);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Bios Rev. : %s", dmi->bios.bios_revision);
+    snprintf(statbuffer, sizeof statbuffer, "Bios Revision: %s",
+	     dmi->bios.bios_revision);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Fw.  Rev. : %s",
+	     dmi->bios.firmware_revision);
+    snprintf(statbuffer, sizeof statbuffer, "Firmware Revision : %s",
+	     dmi->bios.firmware_revision);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+    printf("MENU: BIOS menu done (%d items)\n", menu->items_count);
+}
+
+/* Compute Motherboard main menu */
+void compute_motherboard(struct s_my_menu *menu, s_dmi * dmi)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    menu->menu = add_menu(" Motherboard ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "Vendor    : %s",
+	     dmi->base_board.manufacturer);
+    snprintf(statbuffer, sizeof statbuffer, "Vendor: %s",
+	     dmi->base_board.manufacturer);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Product   : %s",
+	     dmi->base_board.product_name);
+    snprintf(statbuffer, sizeof statbuffer, "Product Name: %s",
+	     dmi->base_board.product_name);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Version   : %s", dmi->base_board.version);
+    snprintf(statbuffer, sizeof statbuffer, "Version: %s",
+	     dmi->base_board.version);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Serial    : %s", dmi->base_board.serial);
+    snprintf(statbuffer, sizeof statbuffer, "Serial Number: %s",
+	     dmi->base_board.serial);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Asset Tag : %s",
+	     dmi->base_board.asset_tag);
+    snprintf(statbuffer, sizeof statbuffer, "Asset Tag: %s",
+	     dmi->base_board.asset_tag);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Location  : %s", dmi->base_board.location);
+    snprintf(statbuffer, sizeof statbuffer, "Location: %s",
+	     dmi->base_board.location);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Type      : %s", dmi->base_board.type);
+    snprintf(statbuffer, sizeof statbuffer, "Type: %s", dmi->base_board.type);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    printf("MENU: Motherboard menu done (%d items)\n", menu->items_count);
+}
+
+/* Compute Main IPMI menu */
+void compute_ipmi(struct s_my_menu *menu, s_dmi * dmi)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+    menu->menu = add_menu(" IPMI ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "Interface Type  : %s",
+	     dmi->ipmi.interface_type);
+    snprintf(statbuffer, sizeof statbuffer, "Interface Type: %s",
+	     dmi->ipmi.interface_type);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Spec. Version   : %u.%u",
+	     dmi->ipmi.major_specification_version,
+	     dmi->ipmi.minor_specification_version);
+    snprintf(statbuffer, sizeof statbuffer, "Specification Version: %u.%u",
+	     dmi->ipmi.major_specification_version,
+	     dmi->ipmi.minor_specification_version);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "I2C Slave @     : 0x%02x",
+	     dmi->ipmi.I2C_slave_address);
+    snprintf(statbuffer, sizeof statbuffer, "I2C Slave Address: 0x%02x",
+	     dmi->ipmi.I2C_slave_address);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "NV Storage @    : %u",
+	     dmi->ipmi.nv_address);
+    snprintf(statbuffer, sizeof statbuffer, "NV Storage Address: %u",
+	     dmi->ipmi.nv_address);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    uint32_t high = dmi->ipmi.base_address >> 32;
+    uint32_t low = dmi->ipmi.base_address & 0xFFFF;
+
+    snprintf(buffer, sizeof buffer, "Base Address    : %08X%08X",
+	     high, (low & ~1));
+    snprintf(statbuffer, sizeof statbuffer, "Base Address : %08X%08X",
+	     high, (low & ~1));
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "IRQ             : %d", dmi->ipmi.irq);
+    snprintf(statbuffer, sizeof statbuffer, "IRQ : %d", dmi->ipmi.irq);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    printf("MENU: IPMI menu done (%d items)\n", menu->items_count);
+}
+
+/* Compute Main Battery menu */
+void compute_battery(struct s_my_menu *menu, s_dmi * dmi)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+    menu->menu = add_menu(" Battery ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "Vendor          : %s",
+	     dmi->battery.manufacturer);
+    snprintf(statbuffer, sizeof statbuffer, "Vendor: %s",
+	     dmi->battery.manufacturer);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Manufacture Date: %s",
+	     dmi->battery.manufacture_date);
+    snprintf(statbuffer, sizeof statbuffer, "Manufacture Date: %s",
+	     dmi->battery.manufacture_date);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Serial          : %s",
+	     dmi->battery.serial);
+    snprintf(statbuffer, sizeof statbuffer, "Serial: %s", dmi->battery.serial);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Name            : %s", dmi->battery.name);
+    snprintf(statbuffer, sizeof statbuffer, "Name: %s", dmi->battery.name);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Chemistry       : %s",
+	     dmi->battery.chemistry);
+    snprintf(statbuffer, sizeof statbuffer, "Chemistry: %s",
+	     dmi->battery.chemistry);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Design Capacity : %s",
+	     dmi->battery.design_capacity);
+    snprintf(statbuffer, sizeof statbuffer, "Design Capacity: %s",
+	     dmi->battery.design_capacity);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Design Voltage  : %s",
+	     dmi->battery.design_voltage);
+    snprintf(statbuffer, sizeof statbuffer, "Design Voltage : %s",
+	     dmi->battery.design_voltage);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "SBDS            : %s", dmi->battery.sbds);
+    snprintf(statbuffer, sizeof statbuffer, "SBDS: %s", dmi->battery.sbds);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "SBDS Manuf. Date: %s",
+	     dmi->battery.sbds_manufacture_date);
+    snprintf(statbuffer, sizeof statbuffer, "SBDS Manufacture Date: %s",
+	     dmi->battery.sbds_manufacture_date);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "SBDS Chemistry  : %s",
+	     dmi->battery.sbds_chemistry);
+    snprintf(statbuffer, sizeof statbuffer, "SBDS Chemistry : %s",
+	     dmi->battery.sbds_chemistry);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Maximum Error   : %s",
+	     dmi->battery.maximum_error);
+    snprintf(statbuffer, sizeof statbuffer, "Maximum Error (percent) : %s",
+	     dmi->battery.maximum_error);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "OEM Info        : %s",
+	     dmi->battery.oem_info);
+    snprintf(statbuffer, sizeof statbuffer, "OEM Info: %s",
+	     dmi->battery.oem_info);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    printf("MENU: Battery menu done (%d items)\n", menu->items_count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-kernel.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-kernel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-kernel.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,87 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-menu.h"
+
+/* Main Kernel menu */
+void compute_kernel(struct s_my_menu *menu, struct s_hardware *hardware)
+{
+    char buffer[SUBMENULEN + 1];
+    char infobar[STATLEN + 1];
+    char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+    struct pci_device *pci_device;
+
+    menu->menu = add_menu(" Kernel Modules ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    if ((hardware->modules_pcimap_return_code == -ENOMODULESPCIMAP) &&
+	(hardware->modules_alias_return_code == -ENOMODULESALIAS)) {
+	add_item("The modules.{pcimap|alias} file is missing",
+		 "Missing modules.{pcimap|alias} file", OPT_INACTIVE, NULL, 0);
+	add_item("Kernel modules can't be computed.",
+		 "Missing modules.{pcimap|alias} file", OPT_INACTIVE, NULL, 0);
+	add_item("Please put one of them in same dir as hdt",
+		 "Missing modules.{pcimap|alias} file", OPT_INACTIVE, NULL, 0);
+	add_item("", "", OPT_SEP, "", 0);
+    } else {
+	/*
+	 * For every detected pci device, grab its kernel module to
+	 * compute this submenu
+	 */
+	for_each_pci_func(pci_device, hardware->pci_domain) {
+	    memset(kernel_modules, 0, sizeof kernel_modules);
+	    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);
+	    }
+	    /* No need to add unknown kernel modules */
+	    if (strlen(kernel_modules) > 0) {
+		snprintf(buffer, sizeof buffer, "%s (%s)",
+			 kernel_modules, pci_device->dev_info->class_name);
+		snprintf(infobar, sizeof infobar,
+			 "%04x:%04x %s : %s",
+			 pci_device->vendor,
+			 pci_device->product,
+			 pci_device->dev_info->vendor_name,
+			 pci_device->dev_info->product_name);
+
+		add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+		menu->items_count++;
+	    }
+	}
+    }
+
+    printf("MENU: Kernel menu done (%d items)\n", menu->items_count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-memory.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-memory.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-memory.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,382 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <memory.h>
+#include "hdt-menu.h"
+#define E820MAX 128
+
+/* Compute the e820 submenu */
+static void compute_e820(struct s_my_menu *menu)
+{
+    char buffer[MENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    sprintf(buffer, " e820 information ");
+    menu->items_count = 0;
+    menu->menu = add_menu(buffer, -1);
+
+    struct e820entry map[E820MAX];
+    int count = 0;
+    char type[14];
+
+    detect_memory_e820(map, E820MAX, &count);
+    unsigned long memory_size = memsize_e820(map, count);
+    snprintf(buffer, sizeof buffer, "Detected Memory  - %lu MiB (%lu KiB)",
+	     memory_size >> 10, memory_size);
+    snprintf(statbuffer, sizeof statbuffer,
+	     "Detected Memory : %lu MiB (%lu KiB)", memory_size >> 10,
+	     memory_size);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    add_item("", "", OPT_SEP, "", 0);
+
+    for (int j = 0; j < count; j++) {
+	get_type(map[j].type, type, 14);
+	snprintf(buffer, sizeof buffer,
+		 "%016llx - %016llx (%s)",
+		 map[j].addr, map[j].size, remove_spaces(type));
+	snprintf(statbuffer, sizeof statbuffer,
+		 "%016llx - %016llx (%s)",
+		 map[j].addr, map[j].size, remove_spaces(type));
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+}
+
+/* Compute the e801 submenu */
+static void compute_e801(struct s_my_menu *menu)
+{
+    char buffer[MENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    sprintf(buffer, " e801 information ");
+    menu->items_count = 0;
+    menu->menu = add_menu(buffer, -1);
+
+    int mem_low, mem_high = 0;
+    if (detect_memory_e801(&mem_low, &mem_high)) {
+	snprintf(buffer, sizeof buffer, "%s", "e801 output is bogus");
+	snprintf(statbuffer, sizeof statbuffer, "%s", "e801 output is bogus");
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    } else {
+	snprintf(buffer, sizeof buffer, "Detected Memory  : %d MiB (%d KiB)",
+		 (mem_high >> 4) + (mem_low >> 10), mem_low + (mem_high << 6));
+	snprintf(statbuffer, sizeof statbuffer,
+		 "Detected Memory : %d MiB (%d KiB)",
+		 (mem_high >> 4) + (mem_low >> 10), mem_low + (mem_high << 6));
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+	add_item("", "", OPT_SEP, "", 0);
+	snprintf(buffer, sizeof buffer, "Low Memory       : %d KiB (%d MiB)",
+		 mem_low, mem_low >> 10);
+	snprintf(statbuffer, sizeof statbuffer, "Low Memory : %d KiB (%d MiB)",
+		 mem_low, mem_low >> 10);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+	snprintf(buffer, sizeof buffer, "High Memory      : %d KiB (%d MiB)",
+		 mem_high << 6, mem_high >> 4);
+	snprintf(statbuffer, sizeof statbuffer, "High Memory : %d KiB (%d MiB)",
+		 mem_high << 6, mem_high >> 4);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+
+    }
+    menu->items_count++;
+}
+
+/* Compute the 88 submenu */
+static void compute_88(struct s_my_menu *menu)
+{
+    char buffer[MENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    sprintf(buffer, " 88 information ");
+    menu->items_count = 0;
+    menu->menu = add_menu(buffer, -1);
+
+    int mem_size = 0;
+    if (detect_memory_88(&mem_size)) {
+	snprintf(buffer, sizeof buffer, "%s", "88 output is bogus");
+	snprintf(statbuffer, sizeof statbuffer, "%s", "88 output is bogus");
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    } else {
+	snprintf(buffer, sizeof buffer, "Detected Memory : %d MiB (%d KiB)",
+		 mem_size >> 10, mem_size);
+	snprintf(statbuffer, sizeof statbuffer,
+		 "Detected Memory : %d MiB (%d KiB)", mem_size >> 10, mem_size);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    }
+    menu->items_count++;
+}
+
+/* Compute the Memory submenu */
+static void compute_memory_module(struct s_my_menu *menu, s_dmi * dmi,
+				  int slot_number)
+{
+    int i = slot_number;
+    char buffer[MENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    sprintf(buffer, " Bank <%d> ", i);
+    menu->items_count = 0;
+    menu->menu = add_menu(buffer, -1);
+
+    snprintf(buffer, sizeof buffer, "Form Factor  : %s",
+	     dmi->memory[i].form_factor);
+    snprintf(statbuffer, sizeof statbuffer, "Form Factor: %s",
+	     dmi->memory[i].form_factor);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Type         : %s", dmi->memory[i].type);
+    snprintf(statbuffer, sizeof statbuffer, "Type: %s", dmi->memory[i].type);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Type Details : %s",
+	     dmi->memory[i].type_detail);
+    snprintf(statbuffer, sizeof statbuffer, "Type Details: %s",
+	     dmi->memory[i].type_detail);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Speed        : %s", dmi->memory[i].speed);
+    snprintf(statbuffer, sizeof statbuffer, "Speed (Mhz): %s",
+	     dmi->memory[i].speed);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Size         : %s", dmi->memory[i].size);
+    snprintf(statbuffer, sizeof statbuffer, "Size: %s", dmi->memory[i].size);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Device Set   : %s",
+	     dmi->memory[i].device_set);
+    snprintf(statbuffer, sizeof statbuffer, "Device Set: %s",
+	     dmi->memory[i].device_set);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Device Loc.  : %s",
+	     dmi->memory[i].device_locator);
+    snprintf(statbuffer, sizeof statbuffer, "Device Location: %s",
+	     dmi->memory[i].device_locator);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Bank Locator : %s",
+	     dmi->memory[i].bank_locator);
+    snprintf(statbuffer, sizeof statbuffer, "Bank Locator: %s",
+	     dmi->memory[i].bank_locator);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Total Width  : %s",
+	     dmi->memory[i].total_width);
+    snprintf(statbuffer, sizeof statbuffer, "Total bit Width: %s",
+	     dmi->memory[i].total_width);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Data Width   : %s",
+	     dmi->memory[i].data_width);
+    snprintf(statbuffer, sizeof statbuffer, "Data bit Width: %s",
+	     dmi->memory[i].data_width);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Error        : %s", dmi->memory[i].error);
+    snprintf(statbuffer, sizeof statbuffer, "Error: %s", dmi->memory[i].error);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Vendor       : %s",
+	     dmi->memory[i].manufacturer);
+    snprintf(statbuffer, sizeof statbuffer, "Vendor: %s",
+	     dmi->memory[i].manufacturer);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Serial       : %s", dmi->memory[i].serial);
+    snprintf(statbuffer, sizeof statbuffer, "Serial: %s",
+	     dmi->memory[i].serial);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Asset Tag    : %s",
+	     dmi->memory[i].asset_tag);
+    snprintf(statbuffer, sizeof statbuffer, "Asset Tag: %s",
+	     dmi->memory[i].asset_tag);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Part Number  : %s",
+	     dmi->memory[i].part_number);
+    snprintf(statbuffer, sizeof statbuffer, "Part Number: %s",
+	     dmi->memory[i].part_number);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+}
+
+/* Compute the Memory submenu when type 6 is used*/
+static void compute_memory_module_type6(struct s_my_menu *menu, s_dmi * dmi,
+					int slot_number)
+{
+    int i = slot_number;
+    char buffer[MENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    sprintf(buffer, " Bank <%d> ", i);
+    menu->items_count = 0;
+    menu->menu = add_menu(buffer, -1);
+
+    snprintf(buffer, sizeof buffer, "Socket Designation : %s",
+	     dmi->memory_module[i].socket_designation);
+    snprintf(statbuffer, sizeof statbuffer, "Socket Designation : %s",
+	     dmi->memory_module[i].socket_designation);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Bank Connections   : %s",
+	     dmi->memory_module[i].bank_connections);
+    snprintf(statbuffer, sizeof statbuffer, "Bank Connections: %s",
+	     dmi->memory_module[i].bank_connections);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Type               : %s",
+	     dmi->memory_module[i].type);
+    snprintf(statbuffer, sizeof statbuffer, "Type : %s",
+	     dmi->memory_module[i].type);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Current Speed      : %s",
+	     dmi->memory_module[i].speed);
+    snprintf(statbuffer, sizeof statbuffer, "Current Speed : %s",
+	     dmi->memory_module[i].speed);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Installed Size     : %s",
+	     dmi->memory_module[i].installed_size);
+    snprintf(statbuffer, sizeof statbuffer, "Installed Size : %s",
+	     dmi->memory_module[i].installed_size);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Enabled Size       : %s",
+	     dmi->memory_module[i].enabled_size);
+    snprintf(statbuffer, sizeof statbuffer, "Enabled Size : %s",
+	     dmi->memory_module[i].enabled_size);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Error Status       : %s",
+	     dmi->memory_module[i].error_status);
+    snprintf(statbuffer, sizeof statbuffer, "Error Status : %s",
+	     dmi->memory_module[i].error_status);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+}
+
+/* Compute the Memory menu */
+void compute_memory(struct s_hdt_menu *menu, s_dmi * dmi,
+		    struct s_hardware *hardware)
+{
+    char buffer[MENULEN + 1];
+    int i = 0;
+    int memory_count = 0;
+
+    /* If memory type 17 is available */
+    if (dmi->memory_count > 0) {
+	memory_count = dmi->memory_count;
+	for (i = 0; i < dmi->memory_count; i++) {
+	    compute_memory_module(&(menu->memory_sub_menu[i]), dmi, i);
+	}
+    } else if (dmi->memory_module_count > 0) {
+	memory_count = dmi->memory_module_count;
+	/* Memory Type 17 isn't available, let's fallback on type 6 */
+	for (i = 0; i < dmi->memory_module_count; i++) {
+	    compute_memory_module_type6(&(menu->memory_sub_menu[i]), dmi, i);
+	}
+    }
+
+    compute_e820(&(menu->memory_sub_menu[++i]));
+    compute_e801(&(menu->memory_sub_menu[++i]));
+    compute_88(&(menu->memory_sub_menu[++i]));
+
+    menu->memory_menu.menu = add_menu(" Memory ", -1);
+    menu->memory_menu.items_count = 0;
+
+    snprintf(buffer, sizeof(buffer), " %lu MB detected ",
+	     (hardware->detected_memory_size + (1 << 9)) >> 10);
+    add_item(buffer, "Detected Memory", OPT_INACTIVE, NULL,
+	     menu->memory_sub_menu[0].menu);
+    menu->memory_menu.items_count++;
+
+    add_item("", "", OPT_SEP, "", 0);
+
+    if (memory_count == 0) {
+	snprintf(buffer, sizeof buffer, " No memory bank detected ");
+	add_item(buffer, "Memory Bank", OPT_INACTIVE, NULL,
+		 menu->memory_sub_menu[1].menu);
+	menu->memory_menu.items_count++;
+    } else
+	for (i = 0; i < memory_count; i++) {
+	    snprintf(buffer, sizeof buffer, " Bank <%d> ", i);
+	    add_item(buffer, "Memory Bank", OPT_SUBMENU, NULL,
+		     menu->memory_sub_menu[i].menu);
+	    menu->memory_menu.items_count++;
+	}
+
+    add_item("", "", OPT_SEP, "", 0);
+
+    snprintf(buffer, sizeof buffer, " e820 ");
+    add_item(buffer, "e820 mapping", OPT_SUBMENU, NULL,
+	     menu->memory_sub_menu[++i].menu);
+    menu->memory_menu.items_count++;
+
+    snprintf(buffer, sizeof buffer, " e801 ");
+    add_item(buffer, "e801 information", OPT_SUBMENU, NULL,
+	     menu->memory_sub_menu[++i].menu);
+    menu->memory_menu.items_count++;
+
+    snprintf(buffer, sizeof buffer, " 88 ");
+    add_item(buffer, "88 information", OPT_SUBMENU, NULL,
+	     menu->memory_sub_menu[++i].menu);
+    menu->memory_menu.items_count++;
+
+    add_item("", "", OPT_SEP, "", 0);
+    printf("MENU: Memory menu done (%d items)\n",
+	   menu->memory_menu.items_count);
+    add_item("Run Test", "Run Test", OPT_RUN, hardware->memtest_label, 0);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-pci.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-pci.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-pci.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,203 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-menu.h"
+
+/* Dynamic submenu for pci devices */
+static void compute_pci_device(struct s_my_menu *menu,
+			       struct pci_device *pci_device,
+			       int pci_bus, int pci_slot, int pci_func,
+			       struct s_hardware *hardware)
+{
+    char buffer[56];
+    char statbuffer[STATLEN];
+    char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+
+    menu->menu = add_menu(" Details ", -1);
+    menu->items_count = 0;
+    set_menu_pos(5, 17);
+
+    snprintf(buffer, sizeof buffer, "Vendor  : %s",
+	     pci_device->dev_info->vendor_name);
+    snprintf(statbuffer, sizeof statbuffer, "Vendor Name: %s",
+	     pci_device->dev_info->vendor_name);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Product : %s",
+	     pci_device->dev_info->product_name);
+    snprintf(statbuffer, sizeof statbuffer, "Product Name  %s",
+	     pci_device->dev_info->product_name);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Class   : %s",
+	     pci_device->dev_info->class_name);
+    snprintf(statbuffer, sizeof statbuffer, "Class Name: %s",
+	     pci_device->dev_info->class_name);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Location: %02x:%02x.%01x", pci_bus,
+	     pci_slot, pci_func);
+    snprintf(statbuffer, sizeof statbuffer,
+	     "Location on the PCI Bus: %02x:%02x.%01x", pci_bus, pci_slot,
+	     pci_func);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "PCI ID  : %04x:%04x[%04x:%04x]",
+	     pci_device->vendor, pci_device->product,
+	     pci_device->sub_vendor, pci_device->sub_product);
+    snprintf(statbuffer, sizeof statbuffer,
+	     "vendor:product[sub_vendor:sub_product] : %04x:%04x[%04x:%04x]",
+	     pci_device->vendor, pci_device->product,
+	     pci_device->sub_vendor, pci_device->sub_product);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    if ((pci_device->dev_info->irq > 0) && (pci_device->dev_info->irq < 255)) {
+	snprintf(buffer, sizeof buffer, "IRQ     : %d",
+		 pci_device->dev_info->irq);
+	snprintf(statbuffer, sizeof statbuffer, "IRQ : %d",
+		 pci_device->dev_info->irq);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    snprintf(buffer, sizeof buffer, "Latency : %d",
+	     pci_device->dev_info->latency);
+    snprintf(statbuffer, sizeof statbuffer, "Latency : %d",
+	     pci_device->dev_info->latency);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    memset(kernel_modules, 0, sizeof(kernel_modules));
+
+    if (pci_device->dev_info->linux_kernel_module_count > 1) {
+	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);
+	}
+	snprintf(buffer, sizeof buffer, "Modules : %s", kernel_modules);
+	snprintf(statbuffer, sizeof statbuffer, "Kernel Modules: %s",
+		 kernel_modules);
+    } else {
+	snprintf(buffer, sizeof buffer, "Module  : %s",
+		 pci_device->dev_info->linux_kernel_module[0]);
+	snprintf(statbuffer, sizeof statbuffer, "Kernel Module: %s",
+		 pci_device->dev_info->linux_kernel_module[0]);
+    }
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    if (hardware->is_pxe_valid == true) {
+	if ((hardware->pxe.pci_device != NULL)
+	    && (hardware->pxe.pci_device == pci_device)) {
+
+	    snprintf(buffer, sizeof buffer, "MAC Addr: %s",
+		     hardware->pxe.mac_addr);
+	    snprintf(statbuffer, sizeof statbuffer, "MAC Address : %s",
+		     hardware->pxe.mac_addr);
+	    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	    menu->items_count++;
+
+	    snprintf(buffer, sizeof buffer, "PXE     : %s",
+		     "Current Boot device");
+	    snprintf(statbuffer, sizeof statbuffer, "PXE : %s",
+		     "Current Boot device");
+	    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	    menu->items_count++;
+	}
+    }
+}
+
+/* Main PCI menu */
+int compute_PCI(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware)
+{
+    int i = 0;
+    char menuname[255][MENULEN + 1];
+    char infobar[255][STATLEN + 1];
+    struct pci_device *pci_device;
+    char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+
+    /* For every detected pci device, compute its submenu */
+    for_each_pci_func(pci_device, hardware->pci_domain) {
+	memset(kernel_modules, 0, sizeof kernel_modules);
+	for (int kmod = 0;
+	     kmod < pci_device->dev_info->linux_kernel_module_count; kmod++) {
+	    if (kmod > 0) {
+		strncat(kernel_modules, " | ", 3);
+	    }
+	    strncat(kernel_modules,
+		    pci_device->dev_info->linux_kernel_module[kmod],
+		    LINUX_KERNEL_MODULE_SIZE - 1);
+	}
+	if (pci_device->dev_info->linux_kernel_module_count == 0)
+	    strlcpy(kernel_modules, "unknown", 7);
+
+	compute_pci_device(&(hdt_menu->pci_sub_menu[i]), pci_device,
+			   __pci_bus, __pci_slot, __pci_func, hardware);
+	snprintf(menuname[i], 59, "%s|%s",
+		 pci_device->dev_info->vendor_name,
+		 pci_device->dev_info->product_name);
+	snprintf(infobar[i], STATLEN,
+		 "%02x:%02x.%01x # %s # ID:%04x:%04x[%04x:%04x] # Kmod:%s",
+		 __pci_bus, __pci_slot, __pci_func,
+		 pci_device->dev_info->class_name, pci_device->vendor,
+		 pci_device->product, pci_device->sub_vendor,
+		 pci_device->sub_product, kernel_modules);
+	i++;
+    }
+
+    hdt_menu->pci_menu.menu = add_menu(" PCI Devices ", -1);
+    hdt_menu->pci_menu.items_count = 0;
+    if (hardware->pci_ids_return_code == -ENOPCIIDS) {
+	add_item("The pci.ids file is missing", "Missing pci.ids file",
+		 OPT_INACTIVE, NULL, 0);
+	add_item("PCI Device names  can't be computed.",
+		 "Missing pci.ids file", OPT_INACTIVE, NULL, 0);
+	add_item("Please put one in same dir as hdt",
+		 "Missing pci.ids file", OPT_INACTIVE, NULL, 0);
+	add_item("", "", OPT_SEP, "", 0);
+    }
+    for (int j = 0; j < i; j++) {
+	add_item(menuname[j], infobar[j], OPT_SUBMENU, NULL,
+		 hdt_menu->pci_sub_menu[j].menu);
+	hdt_menu->pci_menu.items_count++;
+    }
+    printf("MENU: PCI menu done (%d items)\n", hdt_menu->pci_menu.items_count);
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-processor.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-processor.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-processor.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,313 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-menu.h"
+
+static void show_flag(struct s_my_menu *menu, char *buffer, bool flag,
+		      char *flag_name, bool flush)
+{
+    char output_buffer[SUBMENULEN + 1];
+    char statbuffer[SUBMENULEN + 1];
+    if ((((strlen(buffer) + strlen(flag_name)) > 35) && flag) || flush) {
+	snprintf(output_buffer, sizeof output_buffer, "Flags     : %s", buffer);
+	snprintf(statbuffer, sizeof statbuffer, "Flags: %s", buffer);
+	add_item(output_buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	memset(buffer, 0, sizeof(buffer));
+	if (flush)
+	    return;
+    }
+    if (flag)
+	strcat(buffer, flag_name);
+}
+
+/* Compute Processor menu */
+void compute_processor(struct s_my_menu *menu, struct s_hardware *hardware)
+{
+    char buffer[SUBMENULEN + 1];
+    char buffer1[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    if (hardware->acpi.madt.processor_local_apic_count > 0) {
+	snprintf(buffer, sizeof buffer,
+		 " Main Processors (%d logical / %d phys. ) ",
+		 hardware->acpi.madt.processor_local_apic_count,
+		 hardware->physical_cpu_count);
+	menu->menu = add_menu(buffer, -1);
+	menu->items_count = 0;
+	set_menu_pos(SUBMENU_Y, SUBMENU_X);
+    } else {
+	menu->menu = add_menu(" Main Processor ", -1);
+	menu->items_count = 0;
+	set_menu_pos(SUBMENU_Y, SUBMENU_X);
+    }
+
+    snprintf(buffer, sizeof buffer, "Vendor    : %s", hardware->cpu.vendor);
+    snprintf(statbuffer, sizeof statbuffer, "Vendor: %s", hardware->cpu.vendor);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Model     : %s", hardware->cpu.model);
+    snprintf(statbuffer, sizeof statbuffer, "Model: %s", hardware->cpu.model);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "CPU Cores : %d", hardware->cpu.num_cores);
+    snprintf(statbuffer, sizeof statbuffer, "Number of CPU cores: %d",
+	     hardware->cpu.num_cores);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    if (hardware->dmi.processor.core_enabled != 0) {
+        snprintf(buffer, sizeof buffer, "CPU Enable: %d", hardware->dmi.processor.core_enabled);
+        snprintf(statbuffer, sizeof statbuffer, "Number of CPU Enabled : %d",
+	     hardware->dmi.processor.core_enabled);
+        add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+        menu->items_count++;
+    }
+
+    if (hardware->dmi.processor.thread_count != 0) {
+        snprintf(buffer, sizeof buffer, "CPU Thread: %d", hardware->dmi.processor.thread_count);
+        snprintf(statbuffer, sizeof statbuffer, "Number of CPU Threads : %d",
+	     hardware->dmi.processor.thread_count);
+        add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+        menu->items_count++;
+    }
+
+    snprintf(buffer, sizeof buffer, "L1 Cache  : %dK + %dK (I+D)",
+	     hardware->cpu.l1_instruction_cache_size,
+	     hardware->cpu.l1_data_cache_size);
+    snprintf(statbuffer, sizeof statbuffer,
+	     "L1 Cache Size: %dK + %dK (Instruction + Data)",
+	     hardware->cpu.l1_instruction_cache_size,
+	     hardware->cpu.l1_data_cache_size);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "L2 Cache  : %dK",
+	     hardware->cpu.l2_cache_size);
+    snprintf(statbuffer, sizeof statbuffer, "L2 Cache Size: %dK",
+	     hardware->cpu.l2_cache_size);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Family ID : %d", hardware->cpu.family);
+    snprintf(statbuffer, sizeof statbuffer, "Family ID: %d",
+	     hardware->cpu.family);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Model  ID : %d", hardware->cpu.model_id);
+    snprintf(statbuffer, sizeof statbuffer, "Model  ID: %d",
+	     hardware->cpu.model_id);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Stepping  : %d", hardware->cpu.stepping);
+    snprintf(statbuffer, sizeof statbuffer, "Stepping: %d",
+	     hardware->cpu.stepping);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    if (hardware->is_dmi_valid) {
+	snprintf(buffer, sizeof buffer, "FSB       : %d",
+		 hardware->dmi.processor.external_clock);
+	snprintf(statbuffer, sizeof statbuffer,
+		 "Front Side Bus (MHz): %d",
+		 hardware->dmi.processor.external_clock);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "Cur. Speed: %d",
+		 hardware->dmi.processor.current_speed);
+	snprintf(statbuffer, sizeof statbuffer,
+		 "Current Speed (MHz): %d",
+		 hardware->dmi.processor.current_speed);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "Max Speed : %d",
+		 hardware->dmi.processor.max_speed);
+	snprintf(statbuffer, sizeof statbuffer, "Max Speed (MHz): %d",
+		 hardware->dmi.processor.max_speed);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "Upgrade   : %s",
+		 hardware->dmi.processor.upgrade);
+	snprintf(statbuffer, sizeof statbuffer, "Upgrade: %s",
+		 hardware->dmi.processor.upgrade);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "Voltage   : %d.%02d",
+		 hardware->dmi.processor.voltage_mv / 1000,
+		 hardware->dmi.processor.voltage_mv -
+		 ((hardware->dmi.processor.voltage_mv / 1000) * 1000));
+	snprintf(statbuffer, sizeof statbuffer, "Voltage (V) : %d.%02d",
+		 hardware->dmi.processor.voltage_mv / 1000,
+		 hardware->dmi.processor.voltage_mv -
+		 ((hardware->dmi.processor.voltage_mv / 1000) * 1000));
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    if (hardware->cpu.flags.smp) {
+	snprintf(buffer, sizeof buffer, "SMP       : Yes");
+	snprintf(statbuffer, sizeof statbuffer, "SMP: Yes");
+    } else {
+	snprintf(buffer, sizeof buffer, "SMP       : No");
+	snprintf(statbuffer, sizeof statbuffer, "SMP: No");
+    }
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    if (hardware->cpu.flags.lm) {
+	snprintf(buffer, sizeof buffer, "x86_64    : Yes");
+	snprintf(statbuffer, sizeof statbuffer,
+		 "x86_64 compatible processor: Yes");
+    } else {
+	snprintf(buffer, sizeof buffer, "X86_64    : No");
+	snprintf(statbuffer, sizeof statbuffer,
+		 "X86_64 compatible processor: No");
+    }
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    if ((hardware->cpu.flags.vmx) || (hardware->cpu.flags.svm)) {
+	snprintf(buffer, sizeof buffer, "Hw Virt.  : Yes");
+	snprintf(statbuffer, sizeof statbuffer,
+		 "Hardware Virtualisation Capable: Yes");
+    } else {
+	snprintf(buffer, sizeof buffer, "Hw Virt.  : No");
+	snprintf(statbuffer, sizeof statbuffer,
+		 "Hardware Virtualisation Capabable : No");
+    }
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    memset(buffer1, 0, sizeof(buffer1));
+    show_flag(menu, buffer1, hardware->cpu.flags.fpu, "fpu ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.vme, "vme ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.de, "de ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pse, "pse ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.tsc, "tsc ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.msr, "msr ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pae, "pae ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.mce, "mce ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.cx8, "cx8 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.apic, "apic ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.sep, "sep ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.mtrr, "mtrr ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pge, "pge ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.mca, "mca ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.cmov, "cmov ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pat, "pat ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pse_36, "pse_36 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.psn, "psn ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.clflsh, "clflsh ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.dts, "dts ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.acpi, "acpi ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.mmx, "mmx ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.sse, "sse ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.sse2, "sse2 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.ss, "ss ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.htt, "ht ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.acc, "acc ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.syscall, "syscall ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.mp, "mp ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.nx, "nx ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.mmxext, "mmxext ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.lm, "lm ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.nowext, "3dnowext ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.now, "3dnow! ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.svm, "svm ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.vmx, "vmx ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pbe, "pbe ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.fxsr_opt, "fxsr_opt ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.gbpages, "gbpages ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.rdtscp, "rdtscp ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pni, "pni ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pclmulqd, "pclmulqd ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.dtes64, "dtes64 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.smx, "smx ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.est, "est ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.tm2, "tm2 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.sse3, "sse3 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.fma, "fma ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.cx16, "cx16 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.xtpr, "xtpr ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pdcm, "pdcm ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.dca, "dca ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.xmm4_1, "xmm4_1 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.xmm4_2, "xmm4_2 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.x2apic, "x2apic ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.movbe, "movbe ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.popcnt, "popcnt ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.aes, "aes ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.xsave, "xsave ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.osxsave, "osxsave ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.avx, "avx ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.hypervisor, "hypervisor ",
+	      false);
+    show_flag(menu, buffer1, hardware->cpu.flags.ace2, "ace2 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.ace2_en, "ace2_en ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.phe, "phe ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.phe_en, "phe_en ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pmm, "pmm ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.pmm_en, "pmm_en ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.extapic, "extapic ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.cr8_legacy, "cr8_legacy ",
+	      false);
+    show_flag(menu, buffer1, hardware->cpu.flags.abm, "abm ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.sse4a, "sse4a ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.misalignsse, "misalignsse ",
+	      false);
+    show_flag(menu, buffer1, hardware->cpu.flags.nowprefetch, "3dnowprefetch ",
+	      false);
+    show_flag(menu, buffer1, hardware->cpu.flags.osvw, "osvw ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.ibs, "ibs ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.sse5, "sse5 ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.skinit, "skinit ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.wdt, "wdt ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.ida, "ida ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.arat, "arat ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.tpr_shadow, "tpr_shadow ",
+	      false);
+    show_flag(menu, buffer1, hardware->cpu.flags.vnmi, "vnmi ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.flexpriority, "flexpriority ",
+	      false);
+    show_flag(menu, buffer1, hardware->cpu.flags.ept, "ept ", false);
+    show_flag(menu, buffer1, hardware->cpu.flags.vpid, "vpid ", false);
+
+    /* Let's flush the remaining flags */
+    show_flag(menu, buffer1, false, "", true);
+
+    printf("MENU: Processor menu done (%d items)\n", menu->items_count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-pxe.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-pxe.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-pxe.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,125 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "hdt-menu.h"
+#include <sys/gpxe.h>
+
+/* Main Kernel menu */
+void compute_PXE(struct s_my_menu *menu, struct s_hardware *hardware)
+{
+    char buffer[SUBMENULEN + 1];
+    char infobar[STATLEN + 1];
+    char gpxe[4]={0};
+
+    if (hardware->is_pxe_valid == false)
+	return;
+
+    menu->menu = add_menu(" PXE ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    struct s_pxe *p = &hardware->pxe;
+
+    if ((hardware->pci_ids_return_code == -ENOPCIIDS)
+	|| (p->pci_device == NULL)) {
+	snprintf(buffer, sizeof buffer, "PCI Vendor    : %d", p->vendor_id);
+	snprintf(infobar, sizeof infobar, "PCI Vendor    : %d", p->vendor_id);
+	add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "PCI Product   : %d", p->vendor_id);
+	snprintf(infobar, sizeof infobar, "PCI Product   : %d", p->vendor_id);
+	add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "PCI SubVendor  : %d", p->subvendor_id);
+	snprintf(infobar, sizeof infobar, "PCI SubVendor  : %d",
+		 p->subvendor_id);
+	add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "PCI SubProduct : %d",
+		 p->subproduct_id);
+	snprintf(infobar, sizeof infobar, "PCI SubProduct : %d",
+		 p->subproduct_id);
+	add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "PCI Revision   : %d", p->rev);
+	snprintf(infobar, sizeof infobar, "PCI Revision   : %d", p->rev);
+	add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer,
+		 "PCI Bus Pos.   : %02x:%02x.%02x", p->pci_bus,
+		 p->pci_dev, p->pci_func);
+	snprintf(infobar, sizeof infobar,
+		 "PCI Bus Pos.   : %02x:%02x.%02x", p->pci_bus,
+		 p->pci_dev, p->pci_func);
+	add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+    } else {
+
+	snprintf(buffer, sizeof buffer, "Manufacturer : %s",
+		 p->pci_device->dev_info->vendor_name);
+	snprintf(infobar, sizeof infobar, "Manufacturer : %s",
+		 p->pci_device->dev_info->vendor_name);
+	add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "Product      : %s",
+		 p->pci_device->dev_info->product_name);
+	snprintf(infobar, sizeof infobar, "Product      : %s",
+		 p->pci_device->dev_info->product_name);
+	add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    snprintf(buffer, sizeof buffer, "MAC Address  : %s", p->mac_addr);
+    snprintf(infobar, sizeof infobar, "MAC Address  : %s", p->mac_addr);
+    add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "IP Address   : %d.%d.%d.%d",
+	     p->ip_addr[0], p->ip_addr[1], p->ip_addr[2], p->ip_addr[3]);
+    snprintf(infobar, sizeof infobar, "IP Address   : %d.%d.%d.%d",
+	     p->ip_addr[0], p->ip_addr[1], p->ip_addr[2], p->ip_addr[3]);
+    add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    if (is_gpxe()) snprintf(gpxe,sizeof(gpxe),"%s","Yes");
+    else snprintf (gpxe, sizeof(gpxe), "%s", "No");
+
+    snprintf(buffer, sizeof buffer, "gPXE Detected: %s", gpxe);
+    snprintf(infobar, sizeof infobar, "gPXE Detected: %s", gpxe);
+    add_item(buffer, infobar, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    printf("MENU: PXE menu done (%d items)\n", menu->items_count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-summary.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-summary.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-summary.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,197 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include "hdt-menu.h"
+
+/* Computing Summary menu */
+void compute_summarymenu(struct s_my_menu *menu, struct s_hardware *hardware)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    snprintf(buffer, sizeof(buffer), " Summary (%d CPU) ", hardware->physical_cpu_count);
+    menu->menu = add_menu(buffer, -1);
+    menu->items_count = 0;
+
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "CPU Vendor    : %s", hardware->cpu.vendor);
+    snprintf(statbuffer, sizeof statbuffer, "CPU Vendor: %s",
+	     hardware->cpu.vendor);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "CPU Model     : %s", hardware->cpu.model);
+    snprintf(statbuffer, sizeof statbuffer, "CPU Model: %s",
+	     hardware->cpu.model);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    char features[255]={0};
+    if (hardware->dmi.processor.thread_count != 0)
+        sprintf(buffer, ", %d thread", hardware->dmi.processor.thread_count);
+    else
+        buffer[0] = 0x00;
+    sprintf(features, "%d core%s, %dK L2 Cache", hardware->cpu.num_cores,
+        buffer, hardware->cpu.l2_cache_size);
+    if (hardware->cpu.flags.lm)
+	strcat(features, ", 64bit");
+    else
+	strcat(features, ", 32bit");
+    if (hardware->cpu.flags.smp)
+	strcat(features, ", SMP");
+    if (hardware->cpu.flags.vmx || hardware->cpu.flags.svm)
+	strcat(features, ", HwVIRT");
+    snprintf(buffer, sizeof buffer, "%s", features);
+    snprintf(statbuffer, sizeof statbuffer, "Features : %s", features);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    add_item("", "", OPT_SEP, "", 0);
+    if (hardware->is_dmi_valid == true) {
+
+	snprintf(buffer, sizeof buffer, "System Vendor : %s",
+		 hardware->dmi.system.manufacturer);
+	snprintf(statbuffer, sizeof statbuffer, "System Vendor: %s",
+		 hardware->dmi.system.manufacturer);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "System Product: %s",
+		 hardware->dmi.system.product_name);
+	snprintf(statbuffer, sizeof statbuffer,
+		 "System Product Name: %s", hardware->dmi.system.product_name);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "System Serial : %s",
+		 hardware->dmi.system.serial);
+	snprintf(statbuffer, sizeof statbuffer,
+		 "System Serial Number: %s", hardware->dmi.system.serial);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	add_item("", "", OPT_SEP, "", 0);
+
+	snprintf(buffer, sizeof buffer, "Bios Version  : %s",
+		 hardware->dmi.bios.version);
+	snprintf(statbuffer, sizeof statbuffer, "Bios Version: %s",
+		 hardware->dmi.bios.version);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "Bios Release  : %s",
+		 hardware->dmi.bios.release_date);
+	snprintf(statbuffer, sizeof statbuffer, "Bios Release Date: %s",
+		 hardware->dmi.bios.release_date);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    add_item("", "", OPT_SEP, "", 0);
+
+    snprintf(buffer, sizeof buffer, "Memory Size   : %lu MiB (%lu KiB)",
+	     (hardware->detected_memory_size + (1 << 9)) >> 10,
+	     hardware->detected_memory_size);
+    snprintf(statbuffer, sizeof statbuffer,
+	     "Detected Memory Size: %lu MiB (%lu KiB)",
+	     (hardware->detected_memory_size + (1 << 9)) >> 10,
+	     hardware->detected_memory_size);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    add_item("", "", OPT_SEP, "", 0);
+
+    snprintf(buffer, sizeof buffer, "Nb PCI Devices: %d",
+	     hardware->nb_pci_devices);
+    snprintf(statbuffer, sizeof statbuffer, "Number of PCI Devices: %d",
+	     hardware->nb_pci_devices);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    if (hardware->is_pxe_valid == true) {
+	add_item("", "", OPT_SEP, "", 0);
+
+	struct s_pxe *p = &hardware->pxe;
+
+	snprintf(buffer, sizeof buffer, "PXE MAC Address: %s", p->mac_addr);
+	snprintf(statbuffer, sizeof statbuffer, "PXE MAC Address: %s",
+		 p->mac_addr);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+
+	snprintf(buffer, sizeof buffer, "PXE IP Address : %d.%d.%d.%d",
+		 p->ip_addr[0], p->ip_addr[1], p->ip_addr[2], p->ip_addr[3]);
+	snprintf(statbuffer, sizeof statbuffer,
+		 "PXE IP Address: %d.%d.%d.%d", p->ip_addr[0],
+		 p->ip_addr[1], p->ip_addr[2], p->ip_addr[3]);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    if (hardware->modules_pcimap_return_code != -ENOMODULESPCIMAP) {
+	add_item("", "", OPT_SEP, "", 0);
+
+	struct pci_device *pci_device;
+	char kernel_modules[LINUX_KERNEL_MODULE_SIZE *
+			    MAX_KERNEL_MODULES_PER_PCI_DEVICE];
+
+	/*
+	 * For every detected pci device, grab its kernel module to compute
+	 * this submenu
+	 */
+	for_each_pci_func(pci_device, hardware->pci_domain) {
+	    memset(kernel_modules, 0, sizeof kernel_modules);
+	    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);
+	    }
+	    /* No need to add unknown kernel modules */
+	    if (strlen(kernel_modules) > 0) {
+		snprintf(buffer, sizeof buffer, "%s (%s)",
+			 kernel_modules, pci_device->dev_info->class_name);
+		snprintf(statbuffer, sizeof statbuffer,
+			 "%04x:%04x %s : %s",
+			 pci_device->vendor,
+			 pci_device->product,
+			 pci_device->dev_info->vendor_name,
+			 pci_device->dev_info->product_name);
+
+		add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+		menu->items_count++;
+	    }
+	}
+    }
+
+    printf("MENU: Summary menu done (%d items)\n", menu->items_count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-syslinux.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-syslinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-syslinux.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,82 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include "syslinux/config.h"
+#include "hdt-menu.h"
+
+/* Computing Syslinux menu */
+void compute_syslinuxmenu(struct s_my_menu *menu, struct s_hardware *hardware)
+{
+    char syslinux_fs_menu[24];
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    memset(syslinux_fs_menu, 0, sizeof syslinux_fs_menu);
+
+    snprintf(syslinux_fs_menu, sizeof syslinux_fs_menu, " %s ",
+	     hardware->syslinux_fs);
+    menu->menu = add_menu(syslinux_fs_menu, -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "Bootloader : %s", hardware->syslinux_fs);
+    snprintf(statbuffer, sizeof statbuffer, "Bootloader: %s",
+	     hardware->syslinux_fs);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Version    : %s",
+	     hardware->sv->version_string);
+    snprintf(statbuffer, sizeof statbuffer, "Version: %s",
+	     hardware->sv->version_string);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Version    : %u", hardware->sv->version);
+    snprintf(statbuffer, sizeof statbuffer, "Version: %u",
+	     hardware->sv->version);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Max API    : %u", hardware->sv->max_api);
+    snprintf(statbuffer, sizeof statbuffer, "Max API: %u",
+	     hardware->sv->max_api);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    add_item("", "", OPT_SEP, "", 0);
+
+    snprintf(buffer, sizeof buffer, "%s", hardware->sv->copyright_string);
+    /* Remove the trailing LF in the copyright string to avoid scrolling */
+    snprintf(statbuffer, sizeof statbuffer, "%s",
+	     remove_trailing_lf((char *)hardware->sv->copyright_string));
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    printf("MENU: Syslinux menu done (%d items)\n", menu->items_count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-vesa.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-vesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-vesa.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,129 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+*/
+
+#include "hdt-menu.h"
+
+/* Submenu for the vesa card */
+static void compute_vesa_card(struct s_my_menu *menu,
+			      struct s_hardware *hardware)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];
+
+    menu->menu = add_menu(" VESA Bios ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "VESA Version: %d.%d",
+	     hardware->vesa.major_version, hardware->vesa.minor_version);
+    snprintf(statbuffer, sizeof statbuffer, "Version: %d.%d",
+	     hardware->vesa.major_version, hardware->vesa.minor_version);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Vendor      : %s", hardware->vesa.vendor);
+    snprintf(statbuffer, sizeof statbuffer, "Vendor Name: %s",
+	     hardware->vesa.vendor);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Product     : %s", hardware->vesa.product);
+    snprintf(statbuffer, sizeof statbuffer, "Product Name: %s",
+	     hardware->vesa.product);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Product Rev.: %s",
+	     hardware->vesa.product_revision);
+    snprintf(statbuffer, sizeof statbuffer, "Produt Revision: %s",
+	     hardware->vesa.product_revision);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Software Rev: %d",
+	     hardware->vesa.software_rev);
+    snprintf(statbuffer, sizeof statbuffer, "Software Revision: %d",
+	     hardware->vesa.software_rev);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    snprintf(buffer, sizeof buffer, "Memory (KB) : %d",
+	     hardware->vesa.total_memory * 64);
+    snprintf(statbuffer, sizeof statbuffer, "Memory (KB): %d",
+	     hardware->vesa.total_memory * 64);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+}
+
+/* Submenu for the vesa card */
+void compute_vesa_modes(struct s_my_menu *menu, struct s_hardware *hardware)
+{
+    char buffer[56];
+    char statbuffer[STATLEN];
+
+    menu->menu = add_menu(" VESA Modes ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+    for (int i = 0; i < hardware->vesa.vmi_count; i++) {
+	struct vesa_mode_info *mi = &hardware->vesa.vmi[i].mi;
+	/* Sometimes, vesa bios reports 0x0 modes
+	 * We don't need to display that ones */
+	if ((mi->h_res == 0) || (mi->v_res == 0))
+	    continue;
+	snprintf(buffer, sizeof buffer, "%4u x %4u x %2ubits vga=%3d",
+		 mi->h_res, mi->v_res, mi->bpp,
+		 hardware->vesa.vmi[i].mode + 0x200);
+	snprintf(statbuffer, sizeof statbuffer, "%4ux%4ux%2ubits vga=%3d",
+		 mi->h_res, mi->v_res, mi->bpp,
+		 hardware->vesa.vmi[i].mode + 0x200);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+}
+
+/* Main VESA Menu*/
+int compute_VESA(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware)
+{
+    char buffer[15];
+    compute_vesa_card(&hdt_menu->vesa_card_menu, hardware);
+    compute_vesa_modes(&hdt_menu->vesa_modes_menu, hardware);
+    hdt_menu->vesa_menu.menu = add_menu(" VESA ", -1);
+    hdt_menu->vesa_menu.items_count = 0;
+
+    add_item("VESA Bios", "VESA Bios", OPT_SUBMENU, NULL,
+	     hdt_menu->vesa_card_menu.menu);
+    hdt_menu->vesa_menu.items_count++;
+    snprintf(buffer, sizeof buffer, "%s (%d)", "Modes",
+	     hardware->vesa.vmi_count);
+    add_item(buffer, "VESA Modes", OPT_SUBMENU, NULL,
+	     hdt_menu->vesa_modes_menu.menu);
+    hdt_menu->vesa_menu.items_count++;
+    printf("MENU: VESA menu done (%d items)\n",
+	   hdt_menu->vesa_menu.items_count);
+    return 0;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-vpd.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-vpd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu-vpd.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,114 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer - 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 "hdt-menu.h"
+
+/**
+ * compute_vpd - generate vpd menu
+ **/
+void compute_vpd(struct s_my_menu *menu, struct s_hardware *hardware)
+{
+    char buffer[SUBMENULEN + 1];
+    char statbuffer[STATLEN + 1];	/* Status bar */
+
+    menu->menu = add_menu(" VPD ", -1);
+    menu->items_count = 0;
+    set_menu_pos(SUBMENU_Y, SUBMENU_X);
+
+    snprintf(buffer, sizeof buffer, "Address                  : %s",
+	     hardware->vpd.base_address);
+    snprintf(statbuffer, sizeof statbuffer, "Address: %s",
+	     hardware->cpu.vendor);
+    add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+    menu->items_count++;
+
+    if (strlen(hardware->vpd.bios_build_id) > 0) {
+	snprintf(buffer, sizeof buffer, "Bios Build ID            : %s",
+		 hardware->vpd.bios_build_id);
+	snprintf(statbuffer, sizeof statbuffer, "Bios Build ID: %s",
+		 hardware->vpd.bios_build_id);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    if (strlen(hardware->vpd.bios_release_date) > 0) {
+	snprintf(buffer, sizeof buffer, "Bios Release Date        : %s",
+		 hardware->vpd.bios_release_date);
+	snprintf(statbuffer, sizeof statbuffer, "Bios Release Date: %s",
+		 hardware->vpd.bios_release_date);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    if (strlen(hardware->vpd.bios_version) > 0) {
+	snprintf(buffer, sizeof buffer, "Bios Version             : %s",
+		 hardware->vpd.bios_version);
+	snprintf(statbuffer, sizeof statbuffer, "Bios Version: %s",
+		 hardware->vpd.bios_version);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    if (strlen(hardware->vpd.default_flash_filename) > 0) {
+	snprintf(buffer, sizeof buffer, "Default Flash Filename   : %s",
+		 hardware->vpd.default_flash_filename);
+	snprintf(statbuffer, sizeof statbuffer, "Default Flash Filename: %s",
+		 hardware->vpd.default_flash_filename);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    if (strlen(hardware->vpd.box_serial_number) > 0) {
+	snprintf(buffer, sizeof buffer, "Box Serial Number        : %s",
+		 hardware->vpd.box_serial_number);
+	snprintf(statbuffer, sizeof statbuffer, "Box Serial Number: %s",
+		 hardware->vpd.box_serial_number);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    if (strlen(hardware->vpd.motherboard_serial_number) > 0) {
+	snprintf(buffer, sizeof buffer, "Motherboard Serial Number: %s",
+		 hardware->vpd.motherboard_serial_number);
+	snprintf(statbuffer, sizeof statbuffer, "Motherboard Serial Number: %s",
+		 hardware->vpd.motherboard_serial_number);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    if (strlen(hardware->vpd.machine_type_model) > 0) {
+	snprintf(buffer, sizeof buffer, "Machine Type/Model       : %s",
+		 hardware->vpd.machine_type_model);
+	snprintf(statbuffer, sizeof statbuffer, "Machine Type/Model: %s",
+		 hardware->vpd.machine_type_model);
+	add_item(buffer, statbuffer, OPT_INACTIVE, NULL, 0);
+	menu->items_count++;
+    }
+
+    printf("MENU: VPD menu done (%d items)\n", menu->items_count);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,311 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#include <unistd.h>
+#include <memory.h>
+#include <syslinux/reboot.h>
+#include "hdt-menu.h"
+
+int start_menu_mode(struct s_hardware *hardware, char *version_string)
+{
+    struct s_hdt_menu hdt_menu;
+
+    memset(&hdt_menu, 0, sizeof(hdt_menu));
+
+    /* Setup the menu system */
+    setup_menu(version_string);
+
+    /* Compute all submenus */
+    compute_submenus(&hdt_menu, hardware);
+
+    /* Compute the main menu */
+    compute_main_menu(&hdt_menu, hardware);
+
+#ifdef WITH_MENU_DISPLAY
+    t_menuitem *curr;
+    char cmd[160];
+
+    if (!quiet)
+	more_printf("Starting Menu (%d menus)\n", hdt_menu.total_menu_count);
+    curr = showmenus(hdt_menu.main_menu.menu);
+    /* When we exit the menu, do we have something to do? */
+    if (curr) {
+	/* When want to execute something */
+	if (curr->action == OPT_RUN) {
+	    /* Tweak, we want to switch to the cli */
+	    if (!strncmp
+		(curr->data, HDT_SWITCH_TO_CLI, sizeof(HDT_SWITCH_TO_CLI))) {
+		return HDT_RETURN_TO_CLI;
+	    }
+	    /* Tweak, we want to start the dump mode */
+	    if (!strncmp
+		(curr->data, HDT_DUMP, sizeof(HDT_DUMP))) {
+		    dump(hardware);
+	        return 0;
+	    }
+	    if (!strncmp
+		(curr->data, HDT_REBOOT, sizeof(HDT_REBOOT))) {
+		syslinux_reboot(1);
+	    }
+	    strcpy(cmd, curr->data);
+
+	    /* Use specific syslinux call if needed */
+	    if (issyslinux())
+		runsyslinuxcmd(cmd);
+	    else
+		csprint(cmd, 0x07);
+	    return 1;		// Should not happen when run from SYSLINUX
+	}
+    }
+#endif
+    return 0;
+}
+
+/* In the menu system, what to do on keyboard timeout */
+TIMEOUTCODE ontimeout(void)
+{
+    // beep();
+    return CODE_WAIT;
+}
+
+/* Keyboard handler for the menu system */
+void keys_handler(t_menusystem * ms
+		  __attribute__ ((unused)), t_menuitem * mi, int scancode)
+{
+    int nr, nc;
+
+    /* 0xFFFF is an invalid helpid */
+    if (scancode == KEY_F1 && mi->helpid != 0xFFFF) {
+	runhelpsystem(mi->helpid);
+    }
+
+    /*
+     * If user hit TAB, and item is an "executable" item
+     * and user has privileges to edit it, edit it in place.
+     */
+    if ((scancode == KEY_TAB) && (mi->action == OPT_RUN)) {
+//(isallowed(username,"editcmd") || isallowed(username,"root"))) {
+	if (getscreensize(1, &nr, &nc)) {
+	    /* Unknown screen size? */
+	    nc = 80;
+	    nr = 24;
+	}
+	/* User typed TAB and has permissions to edit command line */
+	gotoxy(EDITPROMPT, 1);
+	csprint("Command line:", 0x07);
+	editstring(mi->data, ACTIONLEN);
+	gotoxy(EDITPROMPT, 1);
+	cprint(' ', 0x07, nc - 1);
+    }
+}
+
+/* Setup the Menu system */
+void setup_menu(char *version)
+{
+    /* Creating the menu */
+    init_menusystem(version);
+    set_window_size(0, 0, 25, 80);
+
+    /* Do not use inactive attributes - they make little sense for HDT */
+    set_normal_attr(-1, -1, 0x17, 0x1F);
+
+    /* Register the menusystem handler */
+    // reg_handler(HDLR_SCREEN,&msys_handler);
+    reg_handler(HDLR_KEYS, &keys_handler);
+
+    /* Register the ontimeout handler, with a time out of 10 seconds */
+    reg_ontimeout(ontimeout, 1000, 0);
+}
+
+/* Compute Main' submenus */
+void compute_submenus(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware)
+{
+
+    /* Compute this menu if a DMI table exists */
+    if (hardware->is_dmi_valid) {
+	if (hardware->dmi.ipmi.filled == true)
+	    compute_ipmi(&hdt_menu->ipmi_menu, &hardware->dmi);
+	if (hardware->dmi.base_board.filled == true)
+	    compute_motherboard(&(hdt_menu->mobo_menu), &(hardware->dmi));
+	if (hardware->dmi.chassis.filled == true)
+	    compute_chassis(&(hdt_menu->chassis_menu), &(hardware->dmi));
+	if (hardware->dmi.system.filled == true)
+	    compute_system(&(hdt_menu->system_menu), &(hardware->dmi));
+	compute_memory(hdt_menu, &(hardware->dmi), hardware);
+	if (hardware->dmi.bios.filled == true)
+	    compute_bios(&(hdt_menu->bios_menu), &(hardware->dmi));
+	if (hardware->dmi.battery.filled == true)
+	    compute_battery(&(hdt_menu->battery_menu), &(hardware->dmi));
+    }
+
+    compute_processor(&(hdt_menu->cpu_menu), hardware);
+    compute_vpd(&(hdt_menu->vpd_menu), hardware);
+    compute_disks(hdt_menu, hardware);
+
+    compute_PCI(hdt_menu, hardware);
+    compute_PXE(&(hdt_menu->pxe_menu), hardware);
+    compute_kernel(&(hdt_menu->kernel_menu), hardware);
+    
+    compute_summarymenu(&(hdt_menu->summary_menu), hardware);
+    compute_syslinuxmenu(&(hdt_menu->syslinux_menu), hardware);
+    compute_VESA(hdt_menu, hardware);
+    compute_ACPI(hdt_menu, hardware);
+    compute_aboutmenu(&(hdt_menu->about_menu));
+}
+
+void compute_main_menu(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware)
+{
+    char menu_item[64];
+    /* Let's count the number of menus we have */
+    hdt_menu->total_menu_count = 0;
+    hdt_menu->main_menu.items_count = 0;
+
+    hdt_menu->main_menu.menu = add_menu(" Main Menu ", -1);
+    set_item_options(-1, 24);
+
+    snprintf(menu_item, sizeof(menu_item), "PC<I> Devices(%2d)\n",
+	     hardware->nb_pci_devices);
+    add_item(menu_item, "PCI Devices Menu", OPT_SUBMENU, NULL,
+	     hdt_menu->pci_menu.menu);
+    hdt_menu->main_menu.items_count++;
+    hdt_menu->total_menu_count += hdt_menu->pci_menu.items_count;
+    
+    if (hdt_menu->disk_menu.items_count > 0) {
+	snprintf(menu_item, sizeof(menu_item), "<D>isks      (%2d)\n",
+		 hdt_menu->disk_menu.items_count);
+	add_item(menu_item, "Disks Menu", OPT_SUBMENU, NULL,
+		 hdt_menu->disk_menu.menu);
+	hdt_menu->main_menu.items_count++;
+	hdt_menu->total_menu_count += hdt_menu->disk_menu.items_count;
+    }
+
+    snprintf(menu_item, sizeof(menu_item), "<M>emory\n");
+    add_item(menu_item, "Memory Menu", OPT_SUBMENU, NULL,
+	     hdt_menu->memory_menu.menu);
+    hdt_menu->main_menu.items_count++;
+    hdt_menu->total_menu_count += hdt_menu->memory_menu.items_count;
+
+    add_item("<P>rocessor", "Main Processor Menu", OPT_SUBMENU, NULL,
+	     hdt_menu->cpu_menu.menu);
+    hdt_menu->main_menu.items_count++;
+
+    if (hardware->is_dmi_valid) {
+	if (hardware->dmi.base_board.filled == true) {
+	    add_item("M<o>therboard", "Motherboard Menu",
+		     OPT_SUBMENU, NULL, hdt_menu->mobo_menu.menu);
+	    hdt_menu->main_menu.items_count++;
+	}
+
+	if (hardware->dmi.bios.filled == true) {
+	    add_item("<B>ios", "Bios Menu", OPT_SUBMENU, NULL,
+		     hdt_menu->bios_menu.menu);
+	    hdt_menu->main_menu.items_count++;
+	}
+
+	if (hardware->dmi.chassis.filled == true) {
+	    add_item("<C>hassis", "Chassis Menu", OPT_SUBMENU, NULL,
+		     hdt_menu->chassis_menu.menu);
+	    hdt_menu->main_menu.items_count++;
+	}
+
+	if (hardware->dmi.system.filled == true) {
+	    add_item("<S>ystem", "System Menu", OPT_SUBMENU, NULL,
+		     hdt_menu->system_menu.menu);
+	    hdt_menu->main_menu.items_count++;
+	}
+
+	if (hardware->dmi.battery.filled == true) {
+	    add_item("Ba<t>tery", "Battery Menu", OPT_SUBMENU, NULL,
+		     hdt_menu->battery_menu.menu);
+	    hdt_menu->main_menu.items_count++;
+	}
+	if (hardware->dmi.ipmi.filled == true) {
+	    add_item("I<P>MI", "IPMI Menu", OPT_SUBMENU, NULL,
+		     hdt_menu->ipmi_menu.menu);
+	    hdt_menu->main_menu.items_count++;
+	}
+    }
+
+    if (hardware->is_vpd_valid == true) {
+	add_item("<V>PD", "VPD Information Menu", OPT_SUBMENU, NULL,
+		 hdt_menu->vpd_menu.menu);
+	hdt_menu->main_menu.items_count++;
+    }
+
+    if (hardware->is_pxe_valid == true) {
+	add_item("P<X>E", "PXE Information Menu", OPT_SUBMENU, NULL,
+		 hdt_menu->pxe_menu.menu);
+	hdt_menu->main_menu.items_count++;
+    }
+
+    if (hardware->is_vesa_valid == true) {
+	add_item("<V>ESA", "VESA Information Menu", OPT_SUBMENU, NULL,
+		 hdt_menu->vesa_menu.menu);
+	hdt_menu->main_menu.items_count++;
+    }
+
+    if (hardware->is_acpi_valid == true) {
+	add_item("<A>CPI", "ACPI Menu", OPT_SUBMENU, NULL,
+		 hdt_menu->acpi_menu.menu);
+	hdt_menu->main_menu.items_count++;
+    }
+
+    add_item("", "", OPT_SEP, "", 0);
+    
+    if ((hardware->modules_pcimap_return_code != -ENOMODULESPCIMAP) ||
+	(hardware->modules_alias_return_code != -ENOMODULESALIAS)) {
+	add_item("<K>ernel Modules", "Kernel Modules Menu", OPT_SUBMENU,
+		 NULL, hdt_menu->kernel_menu.menu);
+	hdt_menu->main_menu.items_count++;
+    }
+    
+    add_item("S<y>slinux", "Syslinux Information Menu", OPT_SUBMENU, NULL,
+	     hdt_menu->syslinux_menu.menu);
+    hdt_menu->main_menu.items_count++;
+    add_item("S<u>mmary", "Summary Information Menu", OPT_SUBMENU, NULL,
+	     hdt_menu->summary_menu.menu);
+    hdt_menu->main_menu.items_count++;
+
+    add_item("", "", OPT_SEP, "", 0);
+
+    add_item("S<w>itch to CLI", "Switch to Command Line", OPT_RUN,
+	     HDT_SWITCH_TO_CLI, 0);
+
+    if (hardware->is_pxe_valid == true) {
+    add_item("<D>ump to tftp", "Dump to tftp", OPT_RUN,
+	     HDT_DUMP, 0);
+    }
+
+    add_item("<A>bout", "About Menu", OPT_SUBMENU, NULL,
+	     hdt_menu->about_menu.menu);
+    add_item("<R>eboot", "Reboot", OPT_RUN, HDT_REBOOT, 0);
+    add_item("E<x>it", "Exit", OPT_EXITMENU, NULL, 0);
+    hdt_menu->main_menu.items_count++;
+
+    hdt_menu->total_menu_count += hdt_menu->main_menu.items_count;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-menu.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,140 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#ifndef DEFINE_HDT_MENU_H
+#define DEFINE_HDT_MENU_H
+#include <stdio.h>
+#include <getkey.h>
+
+#include "menu.h"
+#include "help.h"
+//#include "cpuid.h"
+#include "sys/pci.h"
+#include "hdt-common.h"
+#include "dmi/dmi.h"
+#include "hdt-ata.h"
+
+#define EDITPROMPT 21
+
+#define SUBMENULEN 46
+
+#define SUBMENU_Y 3
+#define SUBMENU_X 29
+
+#define MAX_PCI_SUB_MENU 128
+#define MAX_MEMORY_SUB_MENU 32
+#define MAX_DISK_SUB_MENU 32
+
+struct s_my_menu {
+    unsigned char menu;
+    int items_count;
+};
+
+struct s_hdt_menu {
+    struct s_my_menu main_menu;
+    struct s_my_menu cpu_menu;
+    struct s_my_menu mobo_menu;
+    struct s_my_menu chassis_menu;
+    struct s_my_menu bios_menu;
+    struct s_my_menu ipmi_menu;
+    struct s_my_menu system_menu;
+    struct s_my_menu pci_menu;
+    struct s_my_menu pci_sub_menu[MAX_PCI_SUB_MENU];
+    struct s_my_menu kernel_menu;
+    struct s_my_menu memory_menu;
+    struct s_my_menu memory_sub_menu[MAX_MEMORY_SUB_MENU];
+    struct s_my_menu disk_menu;
+    struct s_my_menu disk_sub_menu[MAX_DISK_SUB_MENU];
+    struct s_my_menu battery_menu;
+    struct s_my_menu syslinux_menu;
+    struct s_my_menu about_menu;
+    struct s_my_menu summary_menu;
+    struct s_my_menu pxe_menu;
+    struct s_my_menu vesa_menu;
+    struct s_my_menu vesa_card_menu;
+    struct s_my_menu vesa_modes_menu;
+    struct s_my_menu vpd_menu;
+    struct s_my_menu acpi_menu;
+    struct s_my_menu acpi_apic_menu;
+    struct s_my_menu acpi_tables_menu;
+    int total_menu_count;	// Sum of all menus we have
+};
+
+TIMEOUTCODE ontimeout(void);
+void keys_handler(t_menusystem * ms
+		  __attribute__ ((unused)), t_menuitem * mi, int scancode);
+
+// PCI Stuff
+int compute_PCI(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware);
+
+// KERNEL Stuff
+void compute_kernel(struct s_my_menu *menu, struct s_hardware *hardware);
+
+// Disk Stuff
+void compute_disks(struct s_hdt_menu *menu, struct s_hardware *hardware);
+
+// DMI Stuff
+void compute_motherboard(struct s_my_menu *menu, s_dmi * dmi);
+void compute_battery(struct s_my_menu *menu, s_dmi * dmi);
+void compute_system(struct s_my_menu *menu, s_dmi * dmi);
+void compute_chassis(struct s_my_menu *menu, s_dmi * dmi);
+void compute_bios(struct s_my_menu *menu, s_dmi * dmi);
+void compute_memory(struct s_hdt_menu *menu, s_dmi * dmi,
+		    struct s_hardware *hardware);
+void compute_ipmi(struct s_my_menu *menu, s_dmi * dmi);
+
+// VPD Stuff
+void compute_vpd(struct s_my_menu *menu, struct s_hardware *hardware);
+
+// Processor Stuff
+void compute_processor(struct s_my_menu *menu, struct s_hardware *hardware);
+
+// Syslinux stuff
+void compute_syslinuxmenu(struct s_my_menu *menu, struct s_hardware *hardware);
+
+// About menu
+void compute_aboutmenu(struct s_my_menu *menu);
+
+// Summary menu
+void compute_summarymenu(struct s_my_menu *menu, struct s_hardware *hardware);
+
+// PXE menu
+void compute_PXE(struct s_my_menu *menu, struct s_hardware *hardware);
+
+//VESA menu
+int compute_VESA(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware);
+
+// ACPI menu
+int compute_ACPI(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware);
+
+int start_menu_mode(struct s_hardware *hardware, char *version_string);
+void setup_menu(char *version);
+void compute_main_menu(struct s_hdt_menu *hdt_menu,
+		       struct s_hardware *hardware);
+void compute_submenus(struct s_hdt_menu *hdt_menu, struct s_hardware *hardware);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-util.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-util.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-util.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,96 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer - 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 <string.h>
+
+/* Computing div(x,y) */
+#define sub(val) (((val%1024)*100)>>10)
+#define sub_dec(val) (((val%1000)*100)/1000)
+
+void sectors_to_size(int sectors, char *buffer)
+{
+    int b = (sectors / 2);
+    int mib = b >> 10;
+    int gib = mib >> 10;
+    int tib = gib >> 10;
+
+    if (tib > 0)
+	sprintf(buffer, "%3d.%02d TiB", tib,sub(gib));
+    else if (gib > 0)
+	sprintf(buffer, "%3d.%02d GiB", gib,sub(mib));
+    else if (mib > 0)
+	sprintf(buffer, "%3d.%02d MiB", mib,sub(b));
+    else
+	sprintf(buffer, "%d B", b);
+}
+
+void sectors_to_size_dec(char *previous_unit, int *previous_size, char *unit,
+			 int *size, int sectors)
+{
+    *size = sectors / 2;	// Converting to bytes
+    strlcpy(unit, "KB", 2);
+    strlcpy(previous_unit, unit, 2);
+    *previous_size = *size;
+    if (*size > 1000) {
+	*size = *size / 1000;
+	strlcpy(unit, "MB", 2);
+	if (*size > 1000) {
+	    *previous_size = *size;
+	    *size = *size / 1000;
+	    strlcpy(previous_unit, unit, 2);
+	    strlcpy(unit, "GB", 2);
+	    if (*size > 1000) {
+		*previous_size = *size;
+		*size = *size / 1000;
+		strlcpy(previous_unit, unit, 2);
+		strlcpy(unit, "TB", 2);
+	    }
+	}
+    }
+}
+
+/* Return the human readable size of device
+ * This function avoid disk's size rounding while
+ * not using float as they aren't currently supported */
+void sectors_to_size_dec2(int sectors, char *buffer)
+{
+    int b = (sectors / 2);
+    int mib = b / 1000;
+    int gib = mib / 1000;
+    int tib = gib / 1000;
+
+    if (tib > 0)
+	sprintf(buffer, "%3d.%02d TB", tib,sub_dec(gib));
+    else if (gib > 0)
+	sprintf(buffer, "%3d.%02d GB", gib,sub_dec(mib));
+    else if (mib > 0)
+	sprintf(buffer, "%3d.%02d MB", mib,sub_dec(b));
+    else
+	sprintf(buffer, "%d B", b);
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-util.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-util.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt-util.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,34 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   Copyright 2009 Pierre-Alexandre Meyer - All Rights Reserved
+ *
+ *   Permission is hereby granted, free of charge, to any person
+ *   obtaining a copy of this software and associated documentation
+ *   files (the "Software"), to deal in the Software without
+ *   restriction, including without limitation the rights to use,
+ *   copy, modify, merge, publish, distribute, sublicense, and/or
+ *   sell copies of the Software, and to permit persons to whom
+ *   the Software is furnished to do so, subject to the following
+ *   conditions:
+ *
+ *   The above copyright notice and this permission notice shall
+ *   be included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *   OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#ifndef DEFINE_HDT_UTIL_H
+#define DEFINE_HDT_UTIL_H
+void sectors_to_size(int, char *);
+void sectors_to_size_dec(char *, int *, char *, int *, int);
+void sectors_to_size_dec2(int sectors, char *buffer);
+#endif
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt.c
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt.c	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,94 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+/*
+ * hdt.c
+ *
+ * An Hardware Detection Tool
+ */
+
+#include <stdio.h>
+#include "hdt.h"
+#include "hdt-cli.h"
+#include "hdt-menu.h"
+#include "hdt-common.h"
+
+int display_line_nb = 0;
+bool disable_more_printf = false;
+
+/* Defines the number of lines in the console
+ * Default is 20 for a std console */
+int max_console_lines = MAX_CLI_LINES;
+
+int main(const int argc, const char *argv[])
+{
+    char version_string[256];
+    static struct s_hardware hardware;
+
+    snprintf(version_string, sizeof version_string, "%s %s (%s)",
+	     PRODUCT_NAME, VERSION, CODENAME);
+
+    /* Cleaning structures */
+    init_hardware(&hardware);
+
+    /* Detecting Syslinux version */
+    detect_syslinux(&hardware);
+
+    /* Detecting parameters */
+    detect_parameters(argc, argv, &hardware);
+
+    /* Opening the Syslinux console */
+    init_console(&hardware);
+
+    /* Detect hardware */
+    detect_hardware(&hardware);
+
+    /* Clear the screen and reset position of the cursor */
+    clear_screen();
+    printf("\033[1;1H");
+
+    more_printf("%s\n", version_string);
+
+    int return_code = 0;
+
+    if (!menumode || automode)
+	start_cli_mode(&hardware);
+    else {
+	return_code = start_menu_mode(&hardware, version_string);
+	if (return_code == HDT_RETURN_TO_CLI)
+	    start_cli_mode(&hardware);
+    }
+
+    /* Do we got request to do something at exit time ? */
+    if (strlen(hardware.postexec)>0) {
+	    more_printf("Executing postexec instructions : %s\n",hardware.postexec);
+	    runsyslinuxcmd(hardware.postexec);
+    }
+
+    return return_code;
+}
Index: bootcd/isolinux/syslinux-6.03/com32/hdt/hdt.h
===================================================================
--- bootcd/isolinux/syslinux-6.03/com32/hdt/hdt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
+++ bootcd/isolinux/syslinux-6.03/com32/hdt/hdt.h	(revision e16e8f2a41938d263af54a9fd6b4020d6c0d69fa)
@@ -0,0 +1,47 @@
+/* ----------------------------------------------------------------------- *
+ *
+ *   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.
+ *
+ * -----------------------------------------------------------------------
+ */
+
+#ifndef DEFINE_HDT_H
+#define DEFINE_HDT_H
+
+#define PRODUCT_NAME "Hardware Detection Tool"
+#define AUTHOR "Erwan Velu"
+#define CORE_DEVELOPER "Pierre-Alexandre Meyer"
+#define CONTACT "hdt@zytor.com"
+#define VERSION "0.5.2"
+#define CODENAME "Manon"
+#define NB_CONTRIBUTORS 3
+#define CONTRIBUTORS {"Sebastien Gonzalve (Patches)", "Gert Hulselmans (Tests)", "Alexander Andino (Design)"}
+#define WEBSITE_URL "http://hdt-project.org"
+#define IRC_CHANNEL "#hdt on freenode"
+
+#define ATTR_PACKED __attribute__((packed))
+
+#define WITH_MENU_DISPLAY 1
+
+#endif
