[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] merge with xen-unstable.hg



# HG changeset patch
# User Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
# Date 1213847186 -32400
# Node ID 0034766b45c27400b334fd202eb397d30776e06a
# Parent  1201c765783217371166062621e8926cb7643cfd
# Parent  b55f6d42668d862170df03dc42995a0600f93fc6
merge with xen-unstable.hg
---
 xen/drivers/acpi/utglobal.c                               |  136 -
 .hgignore                                                 |    7 
 buildconfigs/select-repository                            |   57 
 extras/mini-os/Makefile                                   |   41 
 extras/mini-os/arch/ia64/Makefile                         |    7 
 extras/mini-os/arch/ia64/common.c                         |    6 
 extras/mini-os/arch/ia64/time.c                           |    6 
 extras/mini-os/arch/x86/Makefile                          |   10 
 extras/mini-os/arch/x86/mm.c                              |   10 
 extras/mini-os/arch/x86/setup.c                           |   10 
 extras/mini-os/arch/x86/time.c                            |    9 
 extras/mini-os/arch/x86/traps.c                           |    4 
 extras/mini-os/arch/x86/x86_32.S                          |    2 
 extras/mini-os/blkfront.c                                 |   55 
 extras/mini-os/console/console.c                          |   12 
 extras/mini-os/console/xencons_ring.c                     |   44 
 extras/mini-os/events.c                                   |   35 
 extras/mini-os/fbfront.c                                  |   52 
 extras/mini-os/fs-front.c                                 |    2 
 extras/mini-os/gnttab.c                                   |   14 
 extras/mini-os/include/blkfront.h                         |    7 
 extras/mini-os/include/byteswap.h                         |   39 
 extras/mini-os/include/console.h                          |   10 
 extras/mini-os/include/events.h                           |    1 
 extras/mini-os/include/gnttab.h                           |    1 
 extras/mini-os/include/ia64/os.h                          |    3 
 extras/mini-os/include/ia64/traps.h                       |    4 
 extras/mini-os/include/kernel.h                           |    7 
 extras/mini-os/include/mm.h                               |    1 
 extras/mini-os/include/netfront.h                         |    1 
 extras/mini-os/include/time.h                             |    1 
 extras/mini-os/include/wait.h                             |    2 
 extras/mini-os/include/x86/arch_mm.h                      |   24 
 extras/mini-os/include/x86/os.h                           |    4 
 extras/mini-os/include/xenbus.h                           |    3 
 extras/mini-os/kernel.c                                   |   48 
 extras/mini-os/lib/sys.c                                  |   48 
 extras/mini-os/lwip-net.c                                 |    6 
 extras/mini-os/main.c                                     |   39 
 extras/mini-os/minios.mk                                  |    6 
 extras/mini-os/mm.c                                       |    4 
 extras/mini-os/netfront.c                                 |   21 
 extras/mini-os/xenbus/xenbus.c                            |   17 
 stubdom/Makefile                                          |  106 -
 stubdom/README                                            |   70 
 stubdom/c/Makefile                                        |    5 
 stubdom/caml/Makefile                                     |    5 
 stubdom/grub.patches/10graphics.diff                      |  772 +++++++++
 stubdom/grub.patches/20print_func.diff                    |   47 
 stubdom/grub.patches/30savedefault.diff                   |   60 
 stubdom/grub.patches/40ext3_256byte_inode.diff            |   51 
 stubdom/grub.patches/99minios                             | 1085 ++++++++++++++
 stubdom/grub/Makefile                                     |   76 
 stubdom/grub/boot-x86_32.S                                |  112 +
 stubdom/grub/boot-x86_64.S                                |  108 +
 stubdom/grub/config.h                                     |   11 
 stubdom/grub/kexec.c                                      |  324 ++++
 stubdom/grub/mini-os.c                                    |  702 +++++++++
 stubdom/grub/mini-os.h                                    |    5 
 stubdom/grub/osdep.h                                      |   30 
 tools/console/daemon/io.c                                 |    3 
 tools/examples/xmexample.hvm                              |   10 
 tools/firmware/rombios/rombios.c                          |   45 
 tools/fs-back/fs-ops.c                                    |   21 
 tools/fs-back/fs-xenbus.c                                 |   22 
 tools/include/xen-sys/NetBSD/privcmd.h                    |    1 
 tools/ioemu/Makefile.target                               |   11 
 tools/ioemu/cocoa.m                                       |    2 
 tools/ioemu/hw/pc.c                                       |    7 
 tools/ioemu/hw/pci_emulation.c                            |  118 +
 tools/ioemu/hw/pci_emulation.h                            |   24 
 tools/ioemu/hw/pl110.c                                    |    4 
 tools/ioemu/hw/tcx.c                                      |    2 
 tools/ioemu/hw/usb-msd.c                                  |    4 
 tools/ioemu/hw/usb.h                                      |    2 
 tools/ioemu/hw/vga.c                                      |  153 +
 tools/ioemu/hw/vga_int.h                                  |    1 
 tools/ioemu/hw/xenfb.c                                    |  343 ----
 tools/ioemu/hw/xenfb.h                                    |    2 
 tools/ioemu/monitor.c                                     |    2 
 tools/ioemu/sdl.c                                         |   35 
 tools/ioemu/vl.c                                          |   43 
 tools/ioemu/vl.h                                          |   24 
 tools/ioemu/vnc.c                                         |   18 
 tools/ioemu/xenfbfront.c                                  |  315 ++++
 tools/libfsimage/ufs/fsys_ufs.c                           |    6 
 tools/libfsimage/zfs/fsys_zfs.c                           |   12 
 tools/libxc/Makefile                                      |    2 
 tools/libxc/ia64/dom_fw_acpi.c                            |   29 
 tools/libxc/xc_cpuid_x86.c                                |  268 ++-
 tools/libxc/xc_dom.h                                      |    3 
 tools/libxc/xc_dom_core.c                                 |    6 
 tools/libxc/xc_dom_x86.c                                  |    4 
 tools/libxc/xc_domain_restore.c                           |   16 
 tools/libxc/xc_domain_save.c                              |   19 
 tools/libxc/xc_netbsd.c                                   |    6 
 tools/misc/Makefile                                       |    9 
 tools/misc/nsplitd/nsplitd.c                              |    2 
 tools/misc/xenperf.c                                      |    2 
 tools/python/get-path                                     |   22 
 tools/python/install-wrap                                 |   44 
 tools/python/xen/lowlevel/acm/acm.c                       |    3 
 tools/python/xen/lowlevel/xc/xc.c                         |   15 
 tools/python/xen/lowlevel/xs/xs.c                         |    6 
 tools/python/xen/util/acmpolicy.py                        |   11 
 tools/python/xen/util/oshelp.py                           |   20 
 tools/python/xen/util/utils.py                            |    6 
 tools/python/xen/util/xsconstants.py                      |   12 
 tools/python/xen/util/xsm/acm/acm.py                      |   60 
 tools/python/xen/xend/XendAPI.py                          |    6 
 tools/python/xen/xend/XendConfig.py                       |    7 
 tools/python/xen/xend/XendDomain.py                       |    4 
 tools/python/xen/xend/XendDomainInfo.py                   |    4 
 tools/python/xen/xend/XendLogging.py                      |    6 
 tools/python/xen/xend/XendOptions.py                      |    4 
 tools/python/xen/xend/XendXSPolicyAdmin.py                |    2 
 tools/python/xen/xend/balloon.py                          |    2 
 tools/python/xen/xend/image.py                            |  255 ++-
 tools/python/xen/xend/server/blkif.py                     |    2 
 tools/python/xen/xm/create.py                             |    2 
 tools/python/xen/xm/main.py                               |    8 
 tools/python/xen/xm/xenapi_create.py                      |  113 +
 tools/vnet/vnet-module/varp_util.h                        |    6 
 tools/vnet/vnet-module/vnet.c                             |    2 
 tools/vtpm_manager/migration/vtpm_migratord_handler.c     |   22 
 tools/xenmon/xenbaked.c                                   |    8 
 tools/xenstat/libxenstat/src/xenstat_linux.c              |   31 
 tools/xenstat/xentop/xentop.c                             |    7 
 tools/xenstore/hashtable.c                                |   25 
 tools/xenstore/list.h                                     |    4 
 tools/xentrace/formats                                    |   57 
 tools/xentrace/xentrace_format                            |   24 
 unmodified_drivers/linux-2.6/platform-pci/panic-handler.c |   28 
 xen/arch/ia64/xen/acpi.c                                  |   36 
 xen/arch/ia64/xen/dom_fw_common.c                         |   21 
 xen/arch/ia64/xen/dom_fw_dom0.c                           |   84 -
 xen/arch/ia64/xen/machine_kexec.c                         |    9 
 xen/arch/ia64/xen/mm.c                                    |    2 
 xen/arch/ia64/xen/xenmem.c                                |    2 
 xen/arch/x86/acpi/boot.c                                  |  114 -
 xen/arch/x86/acpi/cpu_idle.c                              |   45 
 xen/arch/x86/domain.c                                     |  150 -
 xen/arch/x86/domain_build.c                               |   14 
 xen/arch/x86/hpet.c                                       |   24 
 xen/arch/x86/hvm/hvm.c                                    |   61 
 xen/arch/x86/hvm/svm/intr.c                               |   16 
 xen/arch/x86/hvm/svm/svm.c                                |   28 
 xen/arch/x86/hvm/vlapic.c                                 |    2 
 xen/arch/x86/hvm/vmsi.c                                   |   14 
 xen/arch/x86/hvm/vmx/vmcs.c                               |   29 
 xen/arch/x86/hvm/vmx/vmx.c                                |   39 
 xen/arch/x86/machine_kexec.c                              |   13 
 xen/arch/x86/mm.c                                         |  209 +-
 xen/arch/x86/mm/p2m.c                                     |    4 
 xen/arch/x86/mm/shadow/common.c                           |   11 
 xen/arch/x86/mm/shadow/multi.c                            |   11 
 xen/arch/x86/shutdown.c                                   |  218 +-
 xen/arch/x86/time.c                                       |    4 
 xen/arch/x86/trace.c                                      |   16 
 xen/arch/x86/traps.c                                      |  100 -
 xen/arch/x86/x86_32/traps.c                               |   53 
 xen/arch/x86/x86_64/compat/mm.c                           |    8 
 xen/arch/x86/x86_64/cpu_idle.c                            |    2 
 xen/arch/x86/x86_64/mm.c                                  |   47 
 xen/arch/x86/x86_64/traps.c                               |   70 
 xen/arch/x86/x86_emulate/x86_emulate.c                    |   30 
 xen/common/compat/domain.c                                |    2 
 xen/common/compat/grant_table.c                           |    2 
 xen/common/compat/memory.c                                |   13 
 xen/common/kexec.c                                        |   65 
 xen/common/keyhandler.c                                   |   21 
 xen/common/memory.c                                       |   13 
 xen/common/page_alloc.c                                   |    2 
 xen/common/schedule.c                                     |    3 
 xen/drivers/acpi/Makefile                                 |    5 
 xen/drivers/acpi/numa.c                                   |   54 
 xen/drivers/acpi/osl.c                                    |   54 
 xen/drivers/acpi/reboot.c                                 |   37 
 xen/drivers/acpi/tables.c                                 |  773 ++-------
 xen/drivers/acpi/tables/Makefile                          |    5 
 xen/drivers/acpi/tables/tbfadt.c                          |  458 +++++
 xen/drivers/acpi/tables/tbinstal.c                        |  150 +
 xen/drivers/acpi/tables/tbutils.c                         |  560 +++++++
 xen/drivers/acpi/tables/tbxface.c                         |  261 +++
 xen/drivers/acpi/tables/tbxfroot.c                        |  275 +++
 xen/drivers/acpi/utilities/Makefile                       |    2 
 xen/drivers/acpi/utilities/utglobal.c                     |  740 +++++++++
 xen/drivers/acpi/utilities/utmisc.c                       |  229 ++
 xen/drivers/char/console.c                                |    6 
 xen/drivers/char/serial.c                                 |   70 
 xen/drivers/passthrough/amd/iommu_acpi.c                  |    5 
 xen/drivers/passthrough/amd/pci_amd_iommu.c               |    2 
 xen/drivers/passthrough/io.c                              |    7 
 xen/drivers/passthrough/iommu.c                           |   16 
 xen/drivers/passthrough/vtd/dmar.c                        |   21 
 xen/drivers/passthrough/vtd/intremap.c                    |    8 
 xen/drivers/passthrough/vtd/iommu.c                       |   67 
 xen/include/acpi/acnamesp.h                               |  305 +++
 xen/include/acpi/actables.h                               |  118 +
 xen/include/acpi/platform/aclinux.h                       |   64 
 xen/include/asm-ia64/bug.h                                |    3 
 xen/include/asm-ia64/config.h                             |    3 
 xen/include/asm-ia64/mm.h                                 |    3 
 xen/include/asm-ia64/xenprocessor.h                       |    2 
 xen/include/asm-x86/config.h                              |   10 
 xen/include/asm-x86/domain.h                              |   14 
 xen/include/asm-x86/guest_access.h                        |   55 
 xen/include/asm-x86/hpet.h                                |    1 
 xen/include/asm-x86/hvm/guest_access.h                    |    2 
 xen/include/asm-x86/hvm/svm/amd-iommu-proto.h             |    2 
 xen/include/asm-x86/hvm/trace.h                           |  252 +--
 xen/include/asm-x86/hvm/vmx/vmx.h                         |    2 
 xen/include/asm-x86/mm.h                                  |   20 
 xen/include/asm-x86/percpu.h                              |    2 
 xen/include/asm-x86/perfc_defn.h                          |    5 
 xen/include/asm-x86/softirq.h                             |    4 
 xen/include/asm-x86/uaccess.h                             |    4 
 xen/include/asm-x86/x86_32/uaccess.h                      |    2 
 xen/include/asm-x86/x86_64/uaccess.h                      |   20 
 xen/include/public/kexec.h                                |   22 
 xen/include/public/trace.h                                |   11 
 xen/include/xen/acpi.h                                    |   82 -
 xen/include/xen/compat.h                                  |   16 
 xen/include/xen/compiler.h                                |    6 
 xen/include/xen/mm.h                                      |    2 
 xen/include/xen/serial.h                                  |    8 
 xen/include/xen/xencomm.h                                 |    1 
 xen/tools/get-fields.sh                                   |    4 
 228 files changed, 10302 insertions(+), 2964 deletions(-)

diff -r 1201c7657832 -r 0034766b45c2 .hgignore
--- a/.hgignore Tue Jun 10 16:00:33 2008 +0900
+++ b/.hgignore Thu Jun 19 12:46:26 2008 +0900
@@ -1,6 +1,7 @@
 .*\.a$
 .*\.cmi$
 .*\.cmo$
+.*\.cmx$
 .*\.d$
 .*\.o$
 .*\.opic$
@@ -62,6 +63,7 @@
 ^extras/mini-os/h/hypervisor-ifs$
 ^extras/mini-os/h/xen-public$
 ^extras/mini-os/mini-os.*$
+^extras/mini-os/*-stubdom.*$
 ^install/.*$
 ^linux-[^/]*-paravirt/.*$
 ^linux-2.6[^/]*/.*$
@@ -88,10 +90,13 @@
 ^stubdom/ioemu$
 ^stubdom/libxc$
 ^stubdom/lwip-.*$
-^stubdom/mini-os$
+^stubdom/mini-os-.*$
 ^stubdom/newlib-.*$
 ^stubdom/pciutils-.*$
 ^stubdom/zlib-.*$
+^stubdom/grub-cvs$
+^stubdom/grub/stage2$
+^stubdom/grub/netboot$
 ^tools/.*/TAGS$
 ^tools/.*/build/lib.*/.*\.py$
 ^tools/blktap/Makefile\.smh$
diff -r 1201c7657832 -r 0034766b45c2 buildconfigs/select-repository
--- a/buildconfigs/select-repository    Tue Jun 10 16:00:33 2008 +0900
+++ b/buildconfigs/select-repository    Thu Jun 19 12:46:26 2008 +0900
@@ -32,31 +32,38 @@ if [ X"${LINUX_SRC_PATH}" != X ] ; then
     IFS="$IFS_saved"
 fi
 
-XEN=$(hg -R ${XEN_ROOT} path default)
-if [ $? -ne 0 ] || [ X"$XEN" = "X" ] ; then
-    echo "$ME: Unable to determine Xen repository parent." 1>&2
-    exit 1;
+if [ -d ${XEN_ROOT}/.hgxxx ] ; then
+    XEN=$(hg -R ${XEN_ROOT} path default)
+    if [ $? -ne 0 ] || [ X"$XEN" = "X" ] ; then
+       echo "$ME: Unable to determine Xen repository parent." 1>&2
+       exit 1;
+    fi
+
+    BASE=$(dirname ${XEN})
+    if [ $? -ne 0 ] || [ X"$BASE" = "X" ] ; then
+       echo "$ME: Unable to determine Xen repository base." 1>&2
+       exit 1;
+    fi
+    if [ -d "$XEN" ] && [ ! -d "$BASE/$REPO" ] ; then
+       echo "$ME: No such dir: $BASE/$REPO" 1>&2
+       exit 1
+    fi
+
+    echo "$ME: Found ${BASE}/${REPO}" 1>&2
+
+    # If ${BASE}/${REPO} is a local directory then prepend file:// so that
+    # the test in src.hg-clone will fail and we will clone instead of
+    # linking this repository. We only want to link repositories which
+    # were found via LINUX_SRC_PATH.
+    if [ -d "${BASE}/${REPO}" ] ; then
+       echo "file://${BASE}/${REPO}"
+    else
+       echo ${BASE}/${REPO}
+    fi
+else
+    echo "Unable to determine path to Linux source tree." 1>&2
+    echo "Falling back to linux-2.6.18-xen Mercurial repository." 1>&2
+    echo http://xenbits.xensource.com/linux-2.6.18-xen.hg
 fi
 
-BASE=$(dirname ${XEN})
-if [ $? -ne 0 ] || [ X"$BASE" = "X" ] ; then
-    echo "$ME: Unable to determine Xen repository base." 1>&2
-    exit 1;
-fi
-if [ -d "$XEN" ] && [ ! -d "$BASE/$REPO" ] ; then
-    echo "$ME: No such dir: $BASE/$REPO" 1>&2
-    exit 1
-fi
-
-echo "$ME: Found ${BASE}/${REPO}" 1>&2
-
-# If ${BASE}/${REPO} is a local directory then prepend file:// so that
-# the test in src.hg-clone will fail and we will clone instead of
-# linking this repository. We only want to link repositories which
-# were found via LINUX_SRC_PATH.
-if [ -d "${BASE}/${REPO}" ] ; then
-    echo "file://${BASE}/${REPO}"
-else
-    echo ${BASE}/${REPO}
-fi
 exit 0
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/Makefile
--- a/extras/mini-os/Makefile   Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/Makefile   Thu Jun 19 12:46:26 2008 +0900
@@ -6,6 +6,7 @@
 
 export XEN_ROOT = ../..
 include $(XEN_ROOT)/Config.mk
+OBJ_DIR ?= $(CURDIR)
 
 ifneq ($(stubdom),y)
 include Config.mk
@@ -20,7 +21,7 @@ include minios.mk
 # Define some default flags for linking.
 LDLIBS := 
 APP_LDLIBS := 
-LDARCHLIB := -L$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME)
+LDARCHLIB := -L$(OBJ_DIR)/$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME)
 LDFLAGS_FINAL := -T $(TARGET_ARCH_DIR)/minios-$(XEN_TARGET_ARCH).lds
 
 # Prefix for global API names. All other symbols are localised before
@@ -35,14 +36,14 @@ SUBDIRS := lib xenbus console
 
 # The common mini-os objects to build.
 APP_OBJS :=
-OBJS := $(patsubst %.c,%.o,$(wildcard *.c))
-OBJS += $(patsubst %.c,%.o,$(wildcard lib/*.c))
-OBJS += $(patsubst %.c,%.o,$(wildcard xenbus/*.c))
-OBJS += $(patsubst %.c,%.o,$(wildcard console/*.c))
+OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard *.c))
+OBJS += $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard lib/*.c))
+OBJS += $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard xenbus/*.c))
+OBJS += $(patsubst %.c,$(OBJ_DIR)/%.o,$(wildcard console/*.c))
 
 
 .PHONY: default
-default: $(TARGET)
+default: $(OBJ_DIR)/$(TARGET)
 
 # Create special architecture specific links. The function arch_links
 # has to be defined in arch.mk (see include above).
@@ -57,7 +58,7 @@ links:        $(ARCH_LINKS)
 
 .PHONY: arch_lib
 arch_lib:
-       $(MAKE) --directory=$(TARGET_ARCH_DIR) || exit 1;
+       $(MAKE) --directory=$(TARGET_ARCH_DIR) 
OBJ_DIR=$(OBJ_DIR)/$(TARGET_ARCH_DIR) || exit 1;
 
 ifeq ($(lwip),y)
 # lwIP library
@@ -66,14 +67,14 @@ LWC += lwip-arch.c lwip-net.c
 LWC    += lwip-arch.c lwip-net.c
 LWO    := $(patsubst %.c,%.o,$(LWC))
 
-lwip.a: $(LWO)
+$(OBJ_DIR)/lwip.a: $(LWO)
        $(RM) $@
        $(AR) cqs $@ $^
 
-OBJS += lwip.a
+OBJS += $(OBJ_DIR)/lwip.a
 endif
 
-OBJS := $(filter-out main.o lwip%.o $(LWO), $(OBJS))
+OBJS := $(filter-out $(OBJ_DIR)/lwip%.o $(LWO), $(OBJS))
 
 ifeq ($(libc),y)
 APP_LDLIBS += -L$(XEN_ROOT)/stubdom/libxc -whole-archive -lxenguest -lxenctrl 
-no-whole-archive
@@ -84,14 +85,14 @@ endif
 endif
 
 ifneq ($(APP_OBJS)-$(lwip),-y)
-OBJS := $(filter-out daytime.o, $(OBJS))
+OBJS := $(filter-out $(OBJ_DIR)/daytime.o, $(OBJS))
 endif
 
-$(TARGET)_app.o: $(APP_OBJS) app.lds
-       $(LD) -r -d $(LDFLAGS) $^ $(APP_LDLIBS) --undefined app_main -o $@
+$(OBJ_DIR)/$(TARGET)_app.o: $(APP_OBJS) app.lds
+       $(LD) -r -d $(LDFLAGS) $^ $(APP_LDLIBS) --undefined main -o $@
 
-$(TARGET): links $(OBJS) $(TARGET)_app.o arch_lib
-       $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(TARGET)_app.o $(OBJS) $(LDARCHLIB) 
$(LDLIBS) -o $@.o
+$(OBJ_DIR)/$(TARGET): links $(OBJS) $(OBJ_DIR)/$(TARGET)_app.o arch_lib
+       $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(OBJ_DIR)/$(TARGET)_app.o $(OBJS) 
$(LDARCHLIB) $(LDLIBS) -o $@.o
        $(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start $@.o $@.o
        $(LD) $(LDFLAGS) $(LDFLAGS_FINAL) $@.o $(EXTRA_OBJS) -o $@
        gzip -f -9 -c $@ >$@.gz
@@ -99,15 +100,15 @@ endif
 .PHONY: clean arch_clean
 
 arch_clean:
-       $(MAKE) --directory=$(TARGET_ARCH_DIR) clean || exit 1;
+       $(MAKE) --directory=$(TARGET_ARCH_DIR) 
OBJ_DIR=$(OBJ_DIR)/$(TARGET_ARCH_DIR) clean || exit 1;
 
 clean: arch_clean
-       for dir in $(SUBDIRS); do \
+       for dir in $(addprefix $(OBJ_DIR)/,$(SUBDIRS)); do \
                rm -f $$dir/*.o; \
        done
-       rm -f *.o *~ core $(TARGET).elf $(TARGET).raw $(TARGET) $(TARGET).gz
-       find . -type l | xargs rm -f
-       $(RM) lwip.a $(LWO)
+       rm -f $(OBJ_DIR)/*.o *~ $(OBJ_DIR)/core $(OBJ_DIR)/$(TARGET).elf 
$(OBJ_DIR)/$(TARGET).raw $(OBJ_DIR)/$(TARGET) $(OBJ_DIR)/$(TARGET).gz
+       find . $(OBJ_DIR) -type l | xargs rm -f
+       $(RM) $(OBJ_DIR)/lwip.a $(LWO)
        rm -f tags TAGS
 
 
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/arch/ia64/Makefile
--- a/extras/mini-os/arch/ia64/Makefile Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/arch/ia64/Makefile Thu Jun 19 12:46:26 2008 +0900
@@ -40,12 +40,13 @@ ARCH_OBJS += __udivdi3.o
 ARCH_OBJS += __udivdi3.o
 ARCH_OBJS += __udivsi3.o
 ARCH_OBJS += __divdi3.o
+ARCH_OBJS := $(addprefix $(OBJ_DIR)/,$(ARCH_OBJS))
 
 GEN_OFF_SRC := gen_off.c
 GEN_OFF_ASM := gen_off.s
 GEN_OFF_H   := $(MINI-OS_ROOT)/include/$(ARCH_INC)/offsets.h
 
-all: $(ARCH_LIB)
+all: $(OBJ_DIR)/$(ARCH_LIB)
 
 $(GEN_OFF_ASM): $(GEN_OFF_SRC)
        $(CC) -S -o $@ $(CPPFLAGS) $<
@@ -53,10 +54,10 @@ all: $(ARCH_LIB)
 $(GEN_OFF_H): $(GEN_OFF_ASM)
        sed -ne "/^->/ {s/->/#define /; p}" < $< > $@
 
-$(ARCH_LIB): $(GEN_OFF_H) $(ARCH_OBJS) $(HEAD_ARCH_OBJ)
+$(OBJ_DIR)/$(ARCH_LIB): $(GEN_OFF_H) $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
        $(AR) rv $(ARCH_LIB) $(ARCH_OBJS)
 
 clean:
-       rm -f $(ARCH_LIB) $(ARCH_OBJS) $(HEAD_ARCH_OBJ)
+       rm -f $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
        rm -f $(GEN_OFF_ASM)
        rm -f $(GEN_OFF_H)
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/arch/ia64/common.c
--- a/extras/mini-os/arch/ia64/common.c Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/arch/ia64/common.c Thu Jun 19 12:46:26 2008 +0900
@@ -236,6 +236,12 @@ arch_init(start_info_t *si)
 }
 
 void
+arch_fini(void)
+{
+       /* TODO */
+}
+
+void
 arch_print_info(void)
 {
        int major, minor;
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/arch/ia64/time.c
--- a/extras/mini-os/arch/ia64/time.c   Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/arch/ia64/time.c   Thu Jun 19 12:46:26 2008 +0900
@@ -280,3 +280,9 @@ init_time(void)
        ia64_set_itm(new);
        ia64_srlz_d();
 }
+
+void
+fini_time(void)
+{
+       /* TODO */
+}
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/arch/x86/Makefile
--- a/extras/mini-os/arch/x86/Makefile  Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/arch/x86/Makefile  Thu Jun 19 12:46:26 2008 +0900
@@ -17,15 +17,15 @@ ARCH_SRCS := $(wildcard *.c)
 ARCH_SRCS := $(wildcard *.c)
 
 # The objects built from the sources.
-ARCH_OBJS := $(patsubst %.c,%.o,$(ARCH_SRCS))
+ARCH_OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(ARCH_SRCS))
 
-all: $(ARCH_LIB)
+all: $(OBJ_DIR)/$(ARCH_LIB)
 
 # $(HEAD_ARCH_OBJ) is only build here, needed on linking
 # in ../../Makefile.
-$(ARCH_LIB): $(ARCH_OBJS) $(HEAD_ARCH_OBJ)
-       $(AR) rv $(ARCH_LIB) $(ARCH_OBJS)
+$(OBJ_DIR)/$(ARCH_LIB): $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
+       $(AR) rv $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS)
 
 clean:
-       rm -f $(ARCH_LIB) $(ARCH_OBJS) $(HEAD_ARCH_OBJ)
+       rm -f $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
 
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/arch/x86/mm.c
--- a/extras/mini-os/arch/x86/mm.c      Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/arch/x86/mm.c      Thu Jun 19 12:46:26 2008 +0900
@@ -59,7 +59,7 @@ void new_pt_frame(unsigned long *pt_pfn,
 {   
     pgentry_t *tab = (pgentry_t *)start_info.pt_base;
     unsigned long pt_page = (unsigned long)pfn_to_virt(*pt_pfn); 
-    unsigned long prot_e, prot_t;
+    pgentry_t prot_e, prot_t;
     mmu_update_t mmu_updates[1];
     
     prot_e = prot_t = 0;
@@ -69,7 +69,7 @@ void new_pt_frame(unsigned long *pt_pfn,
 
     /* We need to clear the page, otherwise we might fail to map it
        as a page table page */
-    memset((unsigned long*)pfn_to_virt(*pt_pfn), 0, PAGE_SIZE);  
+    memset((void*) pt_page, 0, PAGE_SIZE);  
  
     switch ( level )
     {
@@ -99,7 +99,7 @@ void new_pt_frame(unsigned long *pt_pfn,
 #endif
     tab = pte_to_virt(tab[l3_table_offset(pt_page)]);
 
-    mmu_updates[0].ptr = ((pgentry_t)tab[l2_table_offset(pt_page)] & 
PAGE_MASK) + 
+    mmu_updates[0].ptr = (tab[l2_table_offset(pt_page)] & PAGE_MASK) + 
                          sizeof(pgentry_t) * l1_table_offset(pt_page);
     mmu_updates[0].val = (pgentry_t)pfn_to_mfn(*pt_pfn) << PAGE_SHIFT | 
                          (prot_e & ~_PAGE_RW);
@@ -372,7 +372,7 @@ static pgentry_t *get_pgt(unsigned long 
     return &tab[offset];
 }
 
-static pgentry_t *need_pgt(unsigned long addr)
+pgentry_t *need_pgt(unsigned long addr)
 {
     unsigned long mfn;
     pgentry_t *tab;
@@ -474,7 +474,7 @@ void do_map_frames(unsigned long addr,
                 if (!pgt || !(addr & L1_MASK))
                     pgt = need_pgt(addr);
                mmu_updates[i].ptr = virt_to_mach(pgt);
-               mmu_updates[i].val = ((f[(done + i) * stride] + (done + i) * 
increment) << PAGE_SHIFT) | prot;
+               mmu_updates[i].val = ((pgentry_t)(f[(done + i) * stride] + 
(done + i) * increment) << PAGE_SHIFT) | prot;
            }
 
            rc = HYPERVISOR_mmu_update(mmu_updates, todo, NULL, id);
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/arch/x86/setup.c
--- a/extras/mini-os/arch/x86/setup.c   Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/arch/x86/setup.c   Thu Jun 19 12:46:26 2008 +0900
@@ -100,6 +100,16 @@ arch_init(start_info_t *si)
 }
 
 void
+arch_fini(void)
+{
+#ifdef __i386__
+       HYPERVISOR_set_callbacks(0, 0, 0, 0);
+#else
+       HYPERVISOR_set_callbacks(0, 0, 0);
+#endif
+}
+
+void
 arch_print_info(void)
 {
        printk("  stack:      %p-%p\n", stack, stack + sizeof(stack));
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/arch/x86/time.c
--- a/extras/mini-os/arch/x86/time.c    Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/arch/x86/time.c    Thu Jun 19 12:46:26 2008 +0900
@@ -222,10 +222,17 @@ static void timer_handler(evtchn_port_t 
 
 
 
+static evtchn_port_t port;
 void init_time(void)
 {
-    evtchn_port_t port;
     printk("Initialising timer interface\n");
     port = bind_virq(VIRQ_TIMER, &timer_handler, NULL);
     unmask_evtchn(port);
 }
+
+void fini_time(void)
+{
+    /* Clear any pending timer */
+    HYPERVISOR_set_timer_op(0);
+    unbind_evtchn(port);
+}
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/arch/x86/traps.c
--- a/extras/mini-os/arch/x86/traps.c   Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/arch/x86/traps.c   Thu Jun 19 12:46:26 2008 +0900
@@ -268,3 +268,7 @@ void trap_init(void)
     HYPERVISOR_set_trap_table(trap_table);    
 }
 
+void trap_fini(void)
+{
+    HYPERVISOR_set_trap_table(NULL);
+}
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/arch/x86/x86_32.S
--- a/extras/mini-os/arch/x86/x86_32.S  Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/arch/x86/x86_32.S  Thu Jun 19 12:46:26 2008 +0900
@@ -8,7 +8,7 @@
        .ascii  ",VIRT_BASE=0x0" /* &_text from minios_x86_32.lds */
        .ascii  ",ELF_PADDR_OFFSET=0x0"
        .ascii  ",HYPERCALL_PAGE=0x2"
-       .ascii  ",PAE=yes"
+       .ascii  ",PAE=yes[extended-cr3]"
        .ascii  ",LOADER=generic"
        .byte   0
 .text
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/blkfront.c
--- a/extras/mini-os/blkfront.c Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/blkfront.c Thu Jun 19 12:46:26 2008 +0900
@@ -63,7 +63,8 @@ void blkfront_handler(evtchn_port_t port
     struct blkfront_dev *dev = data;
     int fd = dev->fd;
 
-    files[fd].read = 1;
+    if (fd != -1)
+        files[fd].read = 1;
 #endif
     wake_up(&blkfront_queue);
 }
@@ -105,6 +106,9 @@ struct blkfront_dev *init_blkfront(char 
     dev = malloc(sizeof(*dev));
     memset(dev, 0, sizeof(*dev));
     dev->nodename = strdup(nodename);
+#ifdef HAVE_LIBC
+    dev->fd = -1;
+#endif
 
     snprintf(path, sizeof(path), "%s/backend-id", nodename);
     dev->dom = xenbus_read_integer(path); 
@@ -238,7 +242,15 @@ void shutdown_blkfront(struct blkfront_d
     err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
     xenbus_wait_for_value(path, "6", &dev->events);
 
+    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
+    xenbus_wait_for_value(path, "2", &dev->events);
+
     xenbus_unwatch_path(XBT_NIL, path);
+
+    snprintf(path, sizeof(path), "%s/ring-ref", nodename);
+    xenbus_rm(XBT_NIL, path);
+    snprintf(path, sizeof(path), "%s/event-channel", nodename);
+    xenbus_rm(XBT_NIL, path);
 
     free_blkfront(dev);
 }
@@ -323,14 +335,33 @@ void blkfront_aio(struct blkfront_aiocb 
     if(notify) notify_remote_via_evtchn(dev->evtchn);
 }
 
-void blkfront_aio_write(struct blkfront_aiocb *aiocbp)
-{
-    blkfront_aio(aiocbp, 1);
-}
-
-void blkfront_aio_read(struct blkfront_aiocb *aiocbp)
-{
-    blkfront_aio(aiocbp, 0);
+static void blkfront_aio_cb(struct blkfront_aiocb *aiocbp, int ret)
+{
+    aiocbp->data = (void*) 1;
+}
+
+void blkfront_io(struct blkfront_aiocb *aiocbp, int write)
+{
+    unsigned long flags;
+    ASSERT(!aiocbp->aio_cb);
+    aiocbp->aio_cb = blkfront_aio_cb;
+    blkfront_aio(aiocbp, write);
+    aiocbp->data = NULL;
+
+    local_irq_save(flags);
+    DEFINE_WAIT(w);
+    while (1) {
+       blkfront_aio_poll(aiocbp->aio_dev);
+       if (aiocbp->data)
+           break;
+
+       add_waiter(w, blkfront_queue);
+       local_irq_restore(flags);
+       schedule();
+       local_irq_save(flags);
+    }
+    remove_waiter(w);
+    local_irq_restore(flags);
 }
 
 static void blkfront_push_operation(struct blkfront_dev *dev, uint8_t op, 
uint64_t id)
@@ -397,8 +428,10 @@ int blkfront_aio_poll(struct blkfront_de
 
 moretodo:
 #ifdef HAVE_LIBC
-    files[dev->fd].read = 0;
-    mb(); /* Make sure to let the handler set read to 1 before we start 
looking at the ring */
+    if (dev->fd != -1) {
+        files[dev->fd].read = 0;
+        mb(); /* Make sure to let the handler set read to 1 before we start 
looking at the ring */
+    }
 #endif
 
     rp = dev->ring.sring->rsp_prod;
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/console/console.c
--- a/extras/mini-os/console/console.c  Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/console/console.c  Thu Jun 19 12:46:26 2008 +0900
@@ -49,17 +49,13 @@
    of standard dom0 handled console */
 #define USE_XEN_CONSOLE
 
-/* Low level functions defined in xencons_ring.c */
-extern int xencons_ring_init(void);
-extern int xencons_ring_send(const char *data, unsigned len);
-extern int xencons_ring_send_no_notify(const char *data, unsigned len);
-
 
 /* If console not initialised the printk will be sent to xen serial line 
    NOTE: you need to enable verbose in xen/Rules.mk for it to work. */
 static int console_initialised = 0;
 
 
+#ifndef HAVE_LIBC
 void xencons_rx(char *buf, unsigned len, struct pt_regs *regs)
 {
     if(len > 0)
@@ -77,6 +73,7 @@ void xencons_tx(void)
 {
     /* Do nothing, handled by _rx */
 }
+#endif
 
 
 void console_print(char *data, int length)
@@ -153,3 +150,8 @@ void init_console(void)
     /* This is also required to notify the daemon */
     printk("done.\n");
 }
+
+void fini_console(void)
+{
+    /* Destruct the console and get the parameters of the restarted one */
+}
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/console/xencons_ring.c
--- a/extras/mini-os/console/xencons_ring.c     Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/console/xencons_ring.c     Thu Jun 19 12:46:26 2008 +0900
@@ -8,6 +8,7 @@
 #include <xenbus.h>
 #include <xen/io/console.h>
 
+DECLARE_WAIT_QUEUE_HEAD(console_queue);
 
 static inline struct xencons_interface *xencons_interface(void)
 {
@@ -52,6 +53,9 @@ int xencons_ring_send(const char *data, 
 
 static void handle_input(evtchn_port_t port, struct pt_regs *regs, void *ign)
 {
+#ifdef HAVE_LIBC
+        wake_up(&console_queue);
+#else
        struct xencons_interface *intf = xencons_interface();
        XENCONS_RING_IDX cons, prod;
 
@@ -71,7 +75,47 @@ static void handle_input(evtchn_port_t p
        notify_daemon();
 
        xencons_tx();
+#endif
 }
+
+#ifdef HAVE_LIBC
+int xencons_ring_avail(void)
+{
+       struct xencons_interface *intf = xencons_interface();
+       XENCONS_RING_IDX cons, prod;
+
+       cons = intf->in_cons;
+       prod = intf->in_prod;
+       mb();
+       BUG_ON((prod - cons) > sizeof(intf->in));
+
+        return prod - cons;
+}
+
+int xencons_ring_recv(char *data, unsigned len)
+{
+       struct xencons_interface *intf = xencons_interface();
+       XENCONS_RING_IDX cons, prod;
+        unsigned filled = 0;
+
+       cons = intf->in_cons;
+       prod = intf->in_prod;
+       mb();
+       BUG_ON((prod - cons) > sizeof(intf->in));
+
+        while (filled < len && cons + filled != prod) {
+                data[filled] = *(intf->in + MASK_XENCONS_IDX(cons + filled, 
intf->in));
+                filled++;
+       }
+
+       mb();
+        intf->in_cons = cons + filled;
+
+       notify_daemon();
+
+        return filled;
+}
+#endif
 
 int xencons_ring_init(void)
 {
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/events.c
--- a/extras/mini-os/events.c   Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/events.c   Thu Jun 19 12:46:26 2008 +0900
@@ -39,19 +39,29 @@ void unbind_all_ports(void)
 void unbind_all_ports(void)
 {
     int i;
+    int cpu = 0;
+    shared_info_t *s = HYPERVISOR_shared_info;
+    vcpu_info_t   *vcpu_info = &s->vcpu_info[cpu];
 
     for (i = 0; i < NR_EVS; i++)
     {
+        if (i == start_info.console.domU.evtchn ||
+            i == start_info.store_evtchn)
+            continue;
         if (test_and_clear_bit(i, bound_ports))
         {
             struct evtchn_close close;
+            printk("port %d still bound!\n", i);
             mask_evtchn(i);
             close.port = i;
             HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
+            clear_evtchn(i);
         }
     }
-}
-  
+    vcpu_info->evtchn_upcall_pending = 0;
+    vcpu_info->evtchn_pending_sel = 0;
+}
+
 /*
  * Demux events to different handlers.
  */
@@ -86,17 +96,27 @@ evtchn_port_t bind_evtchn(evtchn_port_t 
        ev_actions[port].data = data;
        wmb();
        ev_actions[port].handler = handler;
+       set_bit(port, bound_ports);
 
        return port;
 }
 
 void unbind_evtchn(evtchn_port_t port )
 {
+       struct evtchn_close close;
+
        if (ev_actions[port].handler == default_handler)
                printk("WARN: No handler for port %d when unbinding\n", port);
+       mask_evtchn(port);
+       clear_evtchn(port);
+
        ev_actions[port].handler = default_handler;
        wmb();
        ev_actions[port].data = NULL;
+       clear_bit(port, bound_ports);
+
+       close.port = port;
+       HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
 }
 
 evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data)
@@ -112,7 +132,6 @@ evtchn_port_t bind_virq(uint32_t virq, e
                printk("Failed to bind virtual IRQ %d\n", virq);
                return -1;
     }
-    set_bit(op.port,bound_ports);
     bind_evtchn(op.port, handler, data);
        return op.port;
 }
@@ -145,6 +164,15 @@ void init_events(void)
         ev_actions[i].handler = default_handler;
         mask_evtchn(i);
     }
+}
+
+void fini_events(void)
+{
+    /* Dealloc all events */
+    unbind_all_ports();
+#if defined(__x86_64__)
+    wrmsrl(0xc0000101, NULL); /* 0xc0000101 is MSR_GS_BASE */
+#endif
 }
 
 void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore)
@@ -185,7 +213,6 @@ int evtchn_bind_interdomain(domid_t pal,
     int err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &op);
     if (err)
                return err;
-    set_bit(op.local_port,bound_ports);
     evtchn_port_t port = op.local_port;
     *local_port = bind_evtchn(port, handler, data);
     return err;
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/fbfront.c
--- a/extras/mini-os/fbfront.c  Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/fbfront.c  Thu Jun 19 12:46:26 2008 +0900
@@ -44,7 +44,8 @@ void kbdfront_handler(evtchn_port_t port
     struct kbdfront_dev *dev = data;
     int fd = dev->fd;
 
-    files[fd].read = 1;
+    if (fd != -1)
+        files[fd].read = 1;
 #endif
     wake_up(&kbdfront_queue);
 }
@@ -83,6 +84,9 @@ struct kbdfront_dev *init_kbdfront(char 
 
     dev = malloc(sizeof(*dev));
     dev->nodename = strdup(nodename);
+#ifdef HAVE_LIBC
+    dev->fd = -1;
+#endif
 
     snprintf(path, sizeof(path), "%s/backend-id", nodename);
     dev->dom = xenbus_read_integer(path); 
@@ -179,8 +183,10 @@ int kbdfront_receive(struct kbdfront_dev
     int i;
 
 #ifdef HAVE_LIBC
-    files[dev->fd].read = 0;
-    mb(); /* Make sure to let the handler set read to 1 before we start 
looking at the ring */
+    if (dev->fd != -1) {
+        files[dev->fd].read = 0;
+        mb(); /* Make sure to let the handler set read to 1 before we start 
looking at the ring */
+    }
 #endif
 
     prod = page->in_prod;
@@ -198,7 +204,7 @@ int kbdfront_receive(struct kbdfront_dev
     notify_remote_via_evtchn(dev->evtchn);
 
 #ifdef HAVE_LIBC
-    if (cons != prod)
+    if (cons != prod && dev->fd != -1)
         /* still some events to read */
         files[dev->fd].read = 1;
 #endif
@@ -223,7 +229,18 @@ void shutdown_kbdfront(struct kbdfront_d
     err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
     xenbus_wait_for_value(path, "6", &dev->events);
 
+    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
+    // does not work yet.
+    //xenbus_wait_for_value(path, "2", &dev->events);
+
     xenbus_unwatch_path(XBT_NIL, path);
+
+    snprintf(path, sizeof(path), "%s/page-ref", nodename);
+    xenbus_rm(XBT_NIL, path);
+    snprintf(path, sizeof(path), "%s/event-channel", nodename);
+    xenbus_rm(XBT_NIL, path);
+    snprintf(path, sizeof(path), "%s/request-abs-pointer", nodename);
+    xenbus_rm(XBT_NIL, path);
 
     free_kbdfront(dev);
 }
@@ -279,7 +296,8 @@ void fbfront_handler(evtchn_port_t port,
     struct fbfront_dev *dev = data;
     int fd = dev->fd;
 
-    files[fd].read = 1;
+    if (fd != -1)
+        files[fd].read = 1;
 #endif
     wake_up(&fbfront_queue);
 }
@@ -305,8 +323,10 @@ int fbfront_receive(struct fbfront_dev *
     int i;
 
 #ifdef HAVE_LIBC
-    files[dev->fd].read = 0;
-    mb(); /* Make sure to let the handler set read to 1 before we start 
looking at the ring */
+    if (dev->fd != -1) {
+        files[dev->fd].read = 0;
+        mb(); /* Make sure to let the handler set read to 1 before we start 
looking at the ring */
+    }
 #endif
 
     prod = page->in_prod;
@@ -324,7 +344,7 @@ int fbfront_receive(struct fbfront_dev *
     notify_remote_via_evtchn(dev->evtchn);
 
 #ifdef HAVE_LIBC
-    if (cons != prod)
+    if (cons != prod && dev->fd != -1)
         /* still some events to read */
         files[dev->fd].read = 1;
 #endif
@@ -352,6 +372,9 @@ struct fbfront_dev *init_fbfront(char *n
 
     dev = malloc(sizeof(*dev));
     dev->nodename = strdup(nodename);
+#ifdef HAVE_LIBC
+    dev->fd = -1;
+#endif
 
     snprintf(path, sizeof(path), "%s/backend-id", nodename);
     dev->dom = xenbus_read_integer(path); 
@@ -547,7 +570,20 @@ void shutdown_fbfront(struct fbfront_dev
     err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
     xenbus_wait_for_value(path, "6", &dev->events);
 
+    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
+    // does not work yet
+    //xenbus_wait_for_value(path, "2", &dev->events);
+
     xenbus_unwatch_path(XBT_NIL, path);
+
+    snprintf(path, sizeof(path), "%s/page-ref", nodename);
+    xenbus_rm(XBT_NIL, path);
+    snprintf(path, sizeof(path), "%s/event-channel", nodename);
+    xenbus_rm(XBT_NIL, path);
+    snprintf(path, sizeof(path), "%s/protocol", nodename);
+    xenbus_rm(XBT_NIL, path);
+    snprintf(path, sizeof(path), "%s/feature-update", nodename);
+    xenbus_rm(XBT_NIL, path);
 
     unbind_evtchn(dev->evtchn);
 
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/fs-front.c
--- a/extras/mini-os/fs-front.c Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/fs-front.c Thu Jun 19 12:46:26 2008 +0900
@@ -1127,3 +1127,5 @@ void init_fs_frontend(void)
     if (!fs_import)
        printk("No FS import\n");
 }
+
+/* TODO: shutdown */
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/gnttab.c
--- a/extras/mini-os/gnttab.c   Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/gnttab.c   Thu Jun 19 12:46:26 2008 +0900
@@ -35,7 +35,7 @@ static grant_ref_t gnttab_list[NR_GRANT_
 #ifdef GNT_DEBUG
 static char inuse[NR_GRANT_ENTRIES];
 #endif
-static __DECLARE_SEMAPHORE_GENERIC(gnttab_sem, NR_GRANT_ENTRIES);
+static __DECLARE_SEMAPHORE_GENERIC(gnttab_sem, 0);
 
 static void
 put_free_entry(grant_ref_t ref)
@@ -60,6 +60,7 @@ get_free_entry(void)
     down(&gnttab_sem);
     local_irq_save(flags);
     ref = gnttab_list[0];
+    BUG_ON(ref < NR_RESERVED_ENTRIES || ref >= NR_GRANT_ENTRIES);
     gnttab_list[0] = gnttab_list[ref];
 #ifdef GNT_DEBUG
     BUG_ON(inuse[ref]);
@@ -193,3 +194,14 @@ init_gnttab(void)
     gnttab_table = map_frames(frames, NR_GRANT_FRAMES);
     printk("gnttab_table mapped at %p.\n", gnttab_table);
 }
+
+void
+fini_gnttab(void)
+{
+    struct gnttab_setup_table setup;
+
+    setup.dom = DOMID_SELF;
+    setup.nr_frames = 0;
+
+    HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
+}
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/blkfront.h
--- a/extras/mini-os/include/blkfront.h Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/include/blkfront.h Thu Jun 19 12:46:26 2008 +0900
@@ -29,8 +29,11 @@ int blkfront_open(struct blkfront_dev *d
 int blkfront_open(struct blkfront_dev *dev);
 #endif
 void blkfront_aio(struct blkfront_aiocb *aiocbp, int write);
-void blkfront_aio_read(struct blkfront_aiocb *aiocbp);
-void blkfront_aio_write(struct blkfront_aiocb *aiocbp);
+#define blkfront_aio_read(aiocbp) blkfront_aio(aiocbp, 0)
+#define blkfront_aio_write(aiocbp) blkfront_aio(aiocbp, 1)
+void blkfront_io(struct blkfront_aiocb *aiocbp, int write);
+#define blkfront_read(aiocbp) blkfront_io(aiocbp, 0)
+#define blkfront_write(aiocbp) blkfront_io(aiocbp, 1)
 void blkfront_aio_push_operation(struct blkfront_aiocb *aiocbp, uint8_t op);
 int blkfront_aio_poll(struct blkfront_dev *dev);
 void blkfront_sync(struct blkfront_dev *dev);
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/byteswap.h
--- a/extras/mini-os/include/byteswap.h Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/include/byteswap.h Thu Jun 19 12:46:26 2008 +0900
@@ -2,21 +2,32 @@
 #define _BYTESWAP_H_
 
 /* Unfortunately not provided by newlib.  */
-#define bswap_16(x) \
-    ((((x) & 0xff00) >> 8) | (((x) & 0xff) << 8))
 
-#define bswap_32(x) \
-    ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) | \
-     (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
+#include <types.h>
+static inline uint16_t bswap_16(uint16_t x)
+{
+    return
+    ((((x) & 0xff00) >> 8) | (((x) & 0xff) << 8));
+}
 
-#define bswap_64(x) \
-    ((((x) & 0xff00000000000000ULL) >> 56) | \
-     (((x) & 0x00ff000000000000ULL) >> 40) | \
-     (((x) & 0x0000ff0000000000ULL) >> 24) | \
-     (((x) & 0x000000ff00000000ULL) >>  8) | \
-     (((x) & 0x00000000ff000000ULL) <<  8) | \
-     (((x) & 0x0000000000ff0000ULL) << 24) | \
-     (((x) & 0x000000000000ff00ULL) << 40) | \
-     (((x) & 0x00000000000000ffULL) << 56))
+static inline uint32_t bswap_32(uint32_t x)
+{
+    return
+    ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |
+     (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24));
+}
+
+static inline uint64_t bswap_64(uint64_t x)
+{
+    return
+    ((((x) & 0xff00000000000000ULL) >> 56) |
+     (((x) & 0x00ff000000000000ULL) >> 40) |
+     (((x) & 0x0000ff0000000000ULL) >> 24) |
+     (((x) & 0x000000ff00000000ULL) >>  8) |
+     (((x) & 0x00000000ff000000ULL) <<  8) |
+     (((x) & 0x0000000000ff0000ULL) << 24) |
+     (((x) & 0x000000000000ff00ULL) << 40) |
+     (((x) & 0x00000000000000ffULL) << 56));
+}
 
 #endif /* _BYTESWAP_H */
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/console.h
--- a/extras/mini-os/include/console.h  Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/include/console.h  Thu Jun 19 12:46:26 2008 +0900
@@ -51,5 +51,15 @@ void xencons_tx(void);
 
 void init_console(void);
 void console_print(char *data, int length);
+void fini_console(void);
+
+/* Low level functions defined in xencons_ring.c */
+extern struct wait_queue_head console_queue;
+int xencons_ring_init(void);
+int xencons_ring_send(const char *data, unsigned len);
+int xencons_ring_send_no_notify(const char *data, unsigned len);
+int xencons_ring_avail(void);
+int xencons_ring_recv(char *data, unsigned len);
+
 
 #endif /* _LIB_CONSOLE_H_ */
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/events.h
--- a/extras/mini-os/include/events.h   Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/include/events.h   Thu Jun 19 12:46:26 2008 +0900
@@ -45,5 +45,6 @@ static inline int notify_remote_via_evtc
     return HYPERVISOR_event_channel_op(EVTCHNOP_send, &op);
 }
 
+void fini_events(void);
 
 #endif /* _EVENTS_H_ */
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/gnttab.h
--- a/extras/mini-os/include/gnttab.h   Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/include/gnttab.h   Thu Jun 19 12:46:26 2008 +0900
@@ -11,5 +11,6 @@ unsigned long gnttab_end_transfer(grant_
 unsigned long gnttab_end_transfer(grant_ref_t gref);
 int gnttab_end_access(grant_ref_t ref);
 const char *gnttabop_error(int16_t status);
+void fini_gnttab(void);
 
 #endif /* !__GNTTAB_H__ */
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/ia64/os.h
--- a/extras/mini-os/include/ia64/os.h  Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/include/ia64/os.h  Thu Jun 19 12:46:26 2008 +0900
@@ -35,6 +35,7 @@
 #include "sal.h"
 #include "pal.h"
 #include "hypervisor.h"
+#include <kernel.h>
 
 
 typedef uint64_t paddr_t;              /* Physical address. */
@@ -46,9 +47,9 @@ typedef uint64_t caddr_t;             /* rr7/kernel
 #include "mm.h"
 
 
-void do_exit(void) __attribute__((noreturn));
 void arch_init(start_info_t *si);      /* in common.c */
 void arch_print_info(void);            /* in common.c */
+void arch_fini(void);
 
 
 /* Size of xen_ia64_boot_param.command_line */
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/ia64/traps.h
--- a/extras/mini-os/include/ia64/traps.h       Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/include/ia64/traps.h       Thu Jun 19 12:46:26 2008 +0900
@@ -38,6 +38,10 @@ inline static void trap_init(void)
 {
        //printk("trap_init() until now not needed!\n");
 }
+inline static void trap_fini(void)
+{
+       //printk("trap_fini() until now not needed!\n");
+}
 
 
 #endif /* !defined(__ASSEMBLY__) */
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/kernel.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/mini-os/include/kernel.h   Thu Jun 19 12:46:26 2008 +0900
@@ -0,0 +1,7 @@
+#ifndef _KERNEL_H_
+#define _KERNEL_H_
+
+extern void do_exit(void) __attribute__((noreturn));
+extern void stop_kernel(void);
+
+#endif /* _KERNEL_H_ */
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/mm.h
--- a/extras/mini-os/include/mm.h       Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/include/mm.h       Thu Jun 19 12:46:26 2008 +0900
@@ -75,5 +75,6 @@ extern unsigned long heap, brk, heap_map
 #endif
 
 int free_physical_pages(xen_pfn_t *mfns, int n);
+void fini_mm(void);
 
 #endif /* _MM_H_ */
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/netfront.h
--- a/extras/mini-os/include/netfront.h Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/include/netfront.h Thu Jun 19 12:46:26 2008 +0900
@@ -18,6 +18,7 @@ extern struct wait_queue_head netfront_q
  * N.B. _must_ be called from a thread; it's not safe to call this from 
  * app_main(). */
 void start_networking(void);
+void stop_networking(void);
 
 void networking_set_addr(struct ip_addr *ipaddr, struct ip_addr *netmask, 
struct ip_addr *gw);
 #endif
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/time.h
--- a/extras/mini-os/include/time.h     Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/include/time.h     Thu Jun 19 12:46:26 2008 +0900
@@ -54,6 +54,7 @@ typedef long suseconds_t;
 
 /* prototypes */
 void     init_time(void);
+void     fini_time(void);
 s_time_t get_s_time(void);
 s_time_t get_v_time(void);
 u64      monotonic_clock(void);
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/wait.h
--- a/extras/mini-os/include/wait.h     Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/include/wait.h     Thu Jun 19 12:46:26 2008 +0900
@@ -87,9 +87,9 @@ static inline void wake_up(struct wait_q
 
 #define wait_event_deadline(wq, condition, deadline) do {       \
     unsigned long flags;                                        \
+    DEFINE_WAIT(__wait);                                        \
     if(condition)                                               \
         break;                                                  \
-    DEFINE_WAIT(__wait);                                        \
     for(;;)                                                     \
     {                                                           \
         /* protect the list */                                  \
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/x86/arch_mm.h
--- a/extras/mini-os/include/x86/arch_mm.h      Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/include/x86/arch_mm.h      Thu Jun 19 12:46:26 2008 +0900
@@ -109,16 +109,16 @@ typedef unsigned long pgentry_t;
   (((_a) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES - 1))
 #endif
 
-#define _PAGE_PRESENT  0x001UL
-#define _PAGE_RW       0x002UL
-#define _PAGE_USER     0x004UL
-#define _PAGE_PWT      0x008UL
-#define _PAGE_PCD      0x010UL
-#define _PAGE_ACCESSED 0x020UL
-#define _PAGE_DIRTY    0x040UL
-#define _PAGE_PAT      0x080UL
-#define _PAGE_PSE      0x080UL
-#define _PAGE_GLOBAL   0x100UL
+#define _PAGE_PRESENT  0x001ULL
+#define _PAGE_RW       0x002ULL
+#define _PAGE_USER     0x004ULL
+#define _PAGE_PWT      0x008ULL
+#define _PAGE_PCD      0x010ULL
+#define _PAGE_ACCESSED 0x020ULL
+#define _PAGE_DIRTY    0x040ULL
+#define _PAGE_PAT      0x080ULL
+#define _PAGE_PSE      0x080ULL
+#define _PAGE_GLOBAL   0x100ULL
 
 #if defined(__i386__)
 #define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED)
@@ -140,7 +140,7 @@ typedef unsigned long pgentry_t;
 
 #define PFN_UP(x)      (((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT)
 #define PFN_DOWN(x)    ((x) >> L1_PAGETABLE_SHIFT)
-#define PFN_PHYS(x)    ((x) << L1_PAGETABLE_SHIFT)
+#define PFN_PHYS(x)    ((uint64_t)(x) << L1_PAGETABLE_SHIFT)
 #define PHYS_PFN(x)    ((x) >> L1_PAGETABLE_SHIFT)
 
 /* to align the pointer to the (next) page boundary */
@@ -221,4 +221,6 @@ static __inline__ paddr_t machine_to_phy
 #define map_zero(n, a) map_frames_ex(&mfn_zero, n, 0, 0, a, DOMID_SELF, 0, 
L1_PROT_RO)
 #define do_map_zero(start, n) do_map_frames(start, &mfn_zero, n, 0, 0, 
DOMID_SELF, 0, L1_PROT_RO)
 
+pgentry_t *need_pgt(unsigned long addr);
+
 #endif /* _ARCH_MM_H_ */
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/x86/os.h
--- a/extras/mini-os/include/x86/os.h   Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/include/x86/os.h   Thu Jun 19 12:46:26 2008 +0900
@@ -18,10 +18,10 @@
 #ifndef __ASSEMBLY__
 #include <types.h>
 #include <hypervisor.h>
+#include <kernel.h>
 
 #define USED    __attribute__ ((used))
 
-extern void do_exit(void) __attribute__((noreturn));
 #define BUG do_exit
 
 #endif
@@ -61,9 +61,11 @@ extern shared_info_t *HYPERVISOR_shared_
 extern shared_info_t *HYPERVISOR_shared_info;
 
 void trap_init(void);
+void trap_fini(void);
 
 void arch_init(start_info_t *si);
 void arch_print_info(void);
+void arch_fini(void);
 
 
 
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/include/xenbus.h
--- a/extras/mini-os/include/xenbus.h   Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/include/xenbus.h   Thu Jun 19 12:46:26 2008 +0900
@@ -90,4 +90,7 @@ char* xenbus_printf(xenbus_transaction_t
                                   char* node, char* path,
                                   char* fmt, ...);
 
+/* Reset the XenBus system. */
+void fini_xenbus(void);
+
 #endif /* XENBUS_H__ */
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/kernel.c
--- a/extras/mini-os/kernel.c   Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/kernel.c   Thu Jun 19 12:46:26 2008 +0900
@@ -46,6 +46,7 @@
 #include <xen/features.h>
 #include <xen/version.h>
 
+static struct netfront_dev *net_dev;
 
 u8 xen_features[XENFEAT_NR_SUBMAPS * 32];
 
@@ -87,7 +88,7 @@ static void periodic_thread(void *p)
 
 static void netfront_thread(void *p)
 {
-    init_netfront(NULL, NULL, NULL, NULL);
+    net_dev = init_netfront(NULL, NULL, NULL, NULL);
 }
 
 static struct blkfront_dev *blk_dev;
@@ -347,9 +348,9 @@ static void refresh_cursor(int new_x, in
     fbfront_update(fb_dev, new_x, new_y, 9, 9);
 }
 
+static struct kbdfront_dev *kbd_dev;
 static void kbdfront_thread(void *p)
 {
-    struct kbdfront_dev *kbd_dev;
     DEFINE_WAIT(w);
     int x = WIDTH / 2, y = HEIGHT / 2, z = 0;
 
@@ -509,6 +510,49 @@ void start_kernel(start_info_t *si)
     run_idle_thread();
 }
 
+void stop_kernel(void)
+{
+    if (net_dev)
+        shutdown_netfront(net_dev);
+
+    if (blk_dev)
+        shutdown_blkfront(blk_dev);
+
+    if (fb_dev)
+        shutdown_fbfront(fb_dev);
+
+    if (kbd_dev)
+        shutdown_kbdfront(kbd_dev);
+
+    /* TODO: fs import */
+
+    local_irq_disable();
+
+    /* Reset grant tables */
+    fini_gnttab();
+
+    /* Reset the console driver. */
+    fini_console();
+    /* TODO: record new ring mfn & event in start_info */
+
+    /* Reset XenBus */
+    fini_xenbus();
+
+    /* Reset timers */
+    fini_time();
+
+    /* Reset memory management. */
+    fini_mm();
+
+    /* Reset events. */
+    fini_events();
+
+    /* Reset traps */
+    trap_fini();
+
+    /* Reset arch details */
+    arch_fini();
+}
 
 /*
  * do_exit: This is called whenever an IRET fails in entry.S.
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/lib/sys.c
--- a/extras/mini-os/lib/sys.c  Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/lib/sys.c  Thu Jun 19 12:46:26 2008 +0900
@@ -43,7 +43,9 @@
 #include <stdlib.h>
 #include <math.h>
 
+#ifdef HAVE_LWIP
 #include <lwip/sockets.h>
+#endif
 #include <fs.h>
 
 #define debug(fmt, ...) \
@@ -213,8 +215,19 @@ int read(int fd, void *buf, size_t nbyte
 int read(int fd, void *buf, size_t nbytes)
 {
     switch (files[fd].type) {
-       case FTYPE_CONSOLE:
-           return 0;
+       case FTYPE_CONSOLE: {
+           int ret;
+            DEFINE_WAIT(w);
+            while(1) {
+                add_waiter(w, console_queue);
+                ret = xencons_ring_recv(buf, nbytes);
+                if (ret)
+                    break;
+                schedule();
+            }
+            remove_waiter(w);
+            return ret;
+        }
        case FTYPE_FILE: {
            ssize_t ret;
            if (nbytes > PAGE_SIZE)
@@ -229,8 +242,10 @@ int read(int fd, void *buf, size_t nbyte
            }
            return 0;
        }
+#ifdef HAVE_LWIP
        case FTYPE_SOCKET:
            return lwip_read(files[fd].socket.fd, buf, nbytes);
+#endif
        case FTYPE_TAP: {
            ssize_t ret;
            ret = netfront_receive(files[fd].tap.dev, buf, nbytes);
@@ -288,8 +303,10 @@ int write(int fd, const void *buf, size_
            }
            return 0;
        }
+#ifdef HAVE_LWIP
        case FTYPE_SOCKET:
            return lwip_write(files[fd].socket.fd, (void*) buf, nbytes);
+#endif
        case FTYPE_TAP:
            netfront_xmit(files[fd].tap.dev, (void*) buf, nbytes);
            return nbytes;
@@ -356,7 +373,7 @@ int close(int fd)
 {
     printk("close(%d)\n", fd);
     switch (files[fd].type) {
-       case FTYPE_CONSOLE:
+        default:
            files[fd].type = FTYPE_NONE;
            return 0;
        case FTYPE_FILE: {
@@ -371,11 +388,13 @@ int close(int fd)
        case FTYPE_XENBUS:
             xs_daemon_close((void*)(intptr_t) fd);
             return 0;
+#ifdef HAVE_LWIP
        case FTYPE_SOCKET: {
            int res = lwip_close(files[fd].socket.fd);
            files[fd].type = FTYPE_NONE;
            return res;
        }
+#endif
        case FTYPE_XC:
            xc_interface_close(fd);
            return 0;
@@ -544,6 +563,7 @@ int fcntl(int fd, int cmd, ...)
     va_end(ap);
 
     switch (cmd) {
+#ifdef HAVE_LWIP
        case F_SETFL:
            if (files[fd].type == FTYPE_SOCKET && !(arg & ~O_NONBLOCK)) {
                /* Only flag supported: non-blocking mode */
@@ -551,6 +571,7 @@ int fcntl(int fd, int cmd, ...)
                return lwip_ioctl(files[fd].socket.fd, FIONBIO, &nblock);
            }
            /* Fallthrough */
+#endif
        default:
            printk("fcntl(%d, %d, %lx/%lo)\n", fd, cmd, arg, arg);
            errno = ENOSYS;
@@ -655,9 +676,12 @@ static void dump_set(int nfds, fd_set *r
 /* Just poll without blocking */
 static int select_poll(int nfds, fd_set *readfds, fd_set *writefds, fd_set 
*exceptfds)
 {
-    int i, n = 0, sock_n, sock_nfds = 0;
+    int i, n = 0;
+#ifdef HAVE_LWIP
+    int sock_n, sock_nfds = 0;
     fd_set sock_readfds, sock_writefds, sock_exceptfds;
     struct timeval timeout = { .tv_sec = 0, .tv_usec = 0};
+#endif
 
 #ifdef LIBC_VERBOSE
     static int nb;
@@ -667,6 +691,7 @@ static int select_poll(int nfds, fd_set 
     nb++;
 #endif
 
+#ifdef HAVE_LWIP
     /* first poll network */
     FD_ZERO(&sock_readfds);
     FD_ZERO(&sock_writefds);
@@ -693,6 +718,7 @@ static int select_poll(int nfds, fd_set 
     sock_n = lwip_select(sock_nfds, &sock_readfds, &sock_writefds, 
&sock_exceptfds, &timeout);
     dump_set(nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout);
     DEBUG("\n");
+#endif
 
     /* Then see others as well. */
     for (i = 0; i < nfds; i++) {
@@ -707,7 +733,12 @@ static int select_poll(int nfds, fd_set 
            FD_CLR(i, exceptfds);
            break;
        case FTYPE_CONSOLE:
-           FD_CLR(i, readfds);
+           if (FD_ISSET(i, writefds)) {
+                if (xencons_ring_avail())
+                   n++;
+               else
+                   FD_CLR(i, readfds);
+            }
            if (FD_ISSET(i, writefds))
                 n++;
            FD_CLR(i, exceptfds);
@@ -736,6 +767,7 @@ static int select_poll(int nfds, fd_set 
            FD_CLR(i, writefds);
            FD_CLR(i, exceptfds);
            break;
+#ifdef HAVE_LWIP
        case FTYPE_SOCKET:
            if (FD_ISSET(i, readfds)) {
                /* Optimize no-network-packet case.  */
@@ -757,6 +789,7 @@ static int select_poll(int nfds, fd_set 
                    FD_CLR(i, exceptfds);
             }
            break;
+#endif
        }
 #ifdef LIBC_VERBOSE
        if (FD_ISSET(i, readfds))
@@ -809,6 +842,7 @@ int select(int nfds, fd_set *readfds, fd
     DEFINE_WAIT(w3);
     DEFINE_WAIT(w4);
     DEFINE_WAIT(w5);
+    DEFINE_WAIT(w6);
 
     assert(thread == main_thread);
 
@@ -830,6 +864,7 @@ int select(int nfds, fd_set *readfds, fd
     add_waiter(w3, blkfront_queue);
     add_waiter(w4, xenbus_watch_queue);
     add_waiter(w5, kbdfront_queue);
+    add_waiter(w6, console_queue);
 
     if (readfds)
         myread = *readfds;
@@ -916,9 +951,11 @@ out:
     remove_waiter(w3);
     remove_waiter(w4);
     remove_waiter(w5);
+    remove_waiter(w6);
     return ret;
 }
 
+#ifdef HAVE_LWIP
 int socket(int domain, int type, int protocol)
 {
     int fd, res;
@@ -970,6 +1007,7 @@ LWIP_STUB(ssize_t, send, (int s, void *b
 LWIP_STUB(ssize_t, send, (int s, void *buf, size_t len, int flags), (s, buf, 
len, flags))
 LWIP_STUB(ssize_t, sendto, (int s, void *buf, size_t len, int flags, struct 
sockaddr *to, socklen_t tolen), (s, buf, len, flags, to, tolen))
 LWIP_STUB(int, getsockname, (int s, struct sockaddr *name, socklen_t 
*namelen), (s, name, namelen))
+#endif
 
 int nanosleep(const struct timespec *req, struct timespec *rem)
 {
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/lwip-net.c
--- a/extras/mini-os/lwip-net.c Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/lwip-net.c Thu Jun 19 12:46:26 2008 +0900
@@ -376,3 +376,9 @@ void start_networking(void)
 
   tprintk("Network is ready.\n");
 }
+
+/* Shut down the network */
+void stop_networking(void)
+{
+  shutdown_netfront(dev);
+}
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/main.c
--- a/extras/mini-os/main.c     Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/main.c     Thu Jun 19 12:46:26 2008 +0900
@@ -4,6 +4,7 @@
  * Samuel Thibault <Samuel.Thibault@xxxxxxxxxxxxx>, October 2007
  */
 
+#ifdef HAVE_LIBC
 #include <os.h>
 #include <sched.h>
 #include <console.h>
@@ -41,24 +42,30 @@ extern char __app_bss_start, __app_bss_e
 extern char __app_bss_start, __app_bss_end;
 static void call_main(void *p)
 {
-    char *args, /**path,*/ *msg, *c;
+    char *c;
 #ifdef CONFIG_QEMU
-    char *domargs;
+    char *domargs, *msg;
 #endif
     int argc;
     char **argv;
     char *envp[] = { NULL };
+#ifdef CONFIG_QEMU
     char *vm;
+    char path[128];
+#endif
     int i;
-    char path[128];
 
     /* Let other parts initialize (including console output) before maybe
      * crashing. */
     //sleep(1);
 
+#ifndef CONFIG_GRUB
     sparse((unsigned long) &__app_bss_start, &__app_bss_end - 
&__app_bss_start);
+#ifdef HAVE_LWIP
     start_networking();
+#endif
     init_fs_frontend();
+#endif
 
 #ifdef CONFIG_QEMU
     if (!fs_import) {
@@ -92,22 +99,6 @@ static void call_main(void *p)
     }
 #endif
 
-    msg = xenbus_read(XBT_NIL, "vm", &vm);
-    if (msg) {
-        printk("Couldn't read vm path\n");
-        do_exit();
-    }
-
-    printk("my vm is at %s\n", vm);
-    snprintf(path, sizeof(path), "%s/image/cmdline", vm);
-    free(vm);
-    msg = xenbus_read(XBT_NIL, path, &args);
-
-    if (msg) {
-        printk("Couldn't get my args: %s\n", msg);
-        args = strdup("");
-    }
-
     argc = 1;
 
 #define PARSE_ARGS(ARGS,START,END) \
@@ -124,7 +115,7 @@ static void call_main(void *p)
        } \
     }
 
-    PARSE_ARGS(args, argc++, );
+    PARSE_ARGS((char*)start_info.cmd_line, argc++, );
 #ifdef CONFIG_QEMU
     PARSE_ARGS(domargs, argc++, );
 #endif
@@ -133,7 +124,7 @@ static void call_main(void *p)
     argv[0] = "main";
     argc = 1;
 
-    PARSE_ARGS(args, argv[argc++] = c, *c++ = 0)
+    PARSE_ARGS((char*)start_info.cmd_line, argv[argc++] = c, *c++ = 0)
 #ifdef CONFIG_QEMU
     PARSE_ARGS(domargs, argv[argc++] = c, *c++ = 0)
 #endif
@@ -162,7 +153,10 @@ void _exit(int ret)
     close_all_files();
     __libc_fini_array();
     printk("main returned %d\n", ret);
-    unbind_all_ports();
+#ifdef HAVE_LWIP
+    stop_networking();
+#endif
+    stop_kernel();
     if (!ret) {
        /* No problem, just shutdown.  */
         struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_poweroff };
@@ -177,3 +171,4 @@ int app_main(start_info_t *si)
     main_thread = create_thread("main", call_main, si);
     return 0;
 }
+#endif
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/minios.mk
--- a/extras/mini-os/minios.mk  Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/minios.mk  Thu Jun 19 12:46:26 2008 +0900
@@ -57,13 +57,13 @@ ARCH_LIB := lib$(ARCH_LIB_NAME).a
 # This object contains the entrypoint for startup from Xen.
 # $(HEAD_ARCH_OBJ) has to be built in the architecture specific directory.
 HEAD_ARCH_OBJ := $(XEN_TARGET_ARCH).o
-HEAD_OBJ := $(TARGET_ARCH_DIR)/$(HEAD_ARCH_OBJ)
+HEAD_OBJ := $(OBJ_DIR)/$(TARGET_ARCH_DIR)/$(HEAD_ARCH_OBJ)
 
 
-%.o: %.c $(HDRS) Makefile $(EXTRA_DEPS)
+$(OBJ_DIR)/%.o: %.c $(HDRS) Makefile $(EXTRA_DEPS)
        $(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
 
-%.o: %.S $(HDRS) Makefile $(EXTRA_DEPS)
+$(OBJ_DIR)/%.o: %.S $(HDRS) Makefile $(EXTRA_DEPS)
        $(CC) $(ASFLAGS) $(CPPFLAGS) -c $< -o $@
 
 
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/mm.c
--- a/extras/mini-os/mm.c       Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/mm.c       Thu Jun 19 12:46:26 2008 +0900
@@ -419,6 +419,10 @@ void init_mm(void)
     arch_init_demand_mapping_area(max_pfn);
 }
 
+void fini_mm(void)
+{
+}
+
 void sanity_check(void)
 {
     int x;
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/netfront.c
--- a/extras/mini-os/netfront.c Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/netfront.c Thu Jun 19 12:46:26 2008 +0900
@@ -259,7 +259,8 @@ void netfront_select_handler(evtchn_port
     network_tx_buf_gc(dev);
     local_irq_restore(flags);
 
-    files[fd].read = 1;
+    if (fd != -1)
+        files[fd].read = 1;
     wake_up(&netfront_queue);
 }
 #endif
@@ -323,6 +324,9 @@ struct netfront_dev *init_netfront(char 
     dev = malloc(sizeof(*dev));
     memset(dev, 0, sizeof(*dev));
     dev->nodename = strdup(nodename);
+#ifdef HAVE_LIBC
+    dev->fd = -1;
+#endif
 
     printk("net TX ring size %d\n", NET_TX_RING_SIZE);
     printk("net RX ring size %d\n", NET_RX_RING_SIZE);
@@ -493,13 +497,26 @@ void shutdown_netfront(struct netfront_d
     printk("close network: backend at %s\n",dev->backend);
 
     snprintf(path, sizeof(path), "%s/state", dev->backend);
+
     err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */
     xenbus_wait_for_value(path, "5", &dev->events);
 
     err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
     xenbus_wait_for_value(path, "6", &dev->events);
 
+    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
+    xenbus_wait_for_value(path, "2", &dev->events);
+
     xenbus_unwatch_path(XBT_NIL, path);
+
+    snprintf(path, sizeof(path), "%s/tx-ring-ref", nodename);
+    xenbus_rm(XBT_NIL, path);
+    snprintf(path, sizeof(path), "%s/rx-ring-ref", nodename);
+    xenbus_rm(XBT_NIL, path);
+    snprintf(path, sizeof(path), "%s/event-channel", nodename);
+    xenbus_rm(XBT_NIL, path);
+    snprintf(path, sizeof(path), "%s/request-rx-copy", nodename);
+    xenbus_rm(XBT_NIL, path);
 
     free_netfront(dev);
 }
@@ -597,7 +614,7 @@ ssize_t netfront_receive(struct netfront
 
     local_irq_save(flags);
     network_rx(dev);
-    if (!dev->rlen)
+    if (!dev->rlen && fd != -1)
        /* No data for us, make select stop returning */
        files[fd].read = 0;
     /* Before re-enabling the interrupts, in case a packet just arrived in the
diff -r 1201c7657832 -r 0034766b45c2 extras/mini-os/xenbus/xenbus.c
--- a/extras/mini-os/xenbus/xenbus.c    Tue Jun 10 16:00:33 2008 +0900
+++ b/extras/mini-os/xenbus/xenbus.c    Thu Jun 19 12:46:26 2008 +0900
@@ -124,7 +124,7 @@ static void xenbus_thread_func(void *ign
 static void xenbus_thread_func(void *ign)
 {
     struct xsd_sockmsg msg;
-    unsigned prod = 0;
+    unsigned prod = xenstore_buf->rsp_prod;
 
     for (;;) 
     {
@@ -174,9 +174,14 @@ static void xenbus_thread_func(void *ign
                         break;
                     }
 
-               event->next = *events;
-               *events = event;
-                wake_up(&xenbus_watch_queue);
+                if (events) {
+                    event->next = *events;
+                    *events = event;
+                    wake_up(&xenbus_watch_queue);
+                } else {
+                    printk("unexpected watch token %s\n", event->token);
+                    free(event);
+                }
             }
 
             else
@@ -263,6 +268,10 @@ void init_xenbus(void)
               NULL);
     unmask_evtchn(start_info.store_evtchn);
     DEBUG("xenbus on irq %d\n", err);
+}
+
+void fini_xenbus(void)
+{
 }
 
 /* Send data to xenbus.  This can block.  All of the requests are seen
diff -r 1201c7657832 -r 0034766b45c2 stubdom/Makefile
--- a/stubdom/Makefile  Tue Jun 10 16:00:33 2008 +0900
+++ b/stubdom/Makefile  Thu Jun 19 12:46:26 2008 +0900
@@ -1,4 +1,5 @@ XEN_ROOT = ..
 XEN_ROOT = ..
+MINI_OS = $(XEN_ROOT)/extras/mini-os
 
 export XEN_OS=MiniOS
 
@@ -12,7 +13,8 @@ ZLIB_VERSION=1.2.3
 ZLIB_VERSION=1.2.3
 LIBPCI_VERSION=2.2.9
 NEWLIB_DATE=2008-01-01
-LWIP_DATE=2008-02-08
+LWIP_DATE=2008-06-01
+GRUB_DATE=2008-06-01
 
 WGET=wget -c
 
@@ -23,9 +25,11 @@ endif
 
 ifeq ($(GNU_TARGET_ARCH), i686)
 TARGET_CFLAGS=
+NEWLIB_CFLAGS+=-D_I386MACH_ALLOW_HW_INTERRUPTS
 endif
 ifeq ($(GNU_TARGET_ARCH), x86_64)
 TARGET_CFLAGS=-mno-red-zone
+NEWLIB_CFLAGS+=-D_I386MACH_ALLOW_HW_INTERRUPTS
 endif
 ifeq ($(GNU_TARGET_ARCH), ia64)
 TARGET_CFLAGS=-mconstant-gp
@@ -36,8 +40,10 @@ export CROSS_COMPILE=$(GNU_TARGET_ARCH)-
 export CROSS_COMPILE=$(GNU_TARGET_ARCH)-xen-elf-
 export PATH:=$(CROSS_PREFIX)/bin:$(PATH)
 
+TARGETS=ioemu c caml grub
+
 .PHONY: all
-all: ioemu-stubdom c-stubdom
+all: ioemu-stubdom c-stubdom pv-grub
 
 ################
 # Cross-binutils
@@ -46,8 +52,8 @@ binutils-$(BINUTILS_VERSION).tar.bz2:
 binutils-$(BINUTILS_VERSION).tar.bz2:
        $(WGET) http://ftp.gnu.org/gnu/binutils/$@
 binutils-$(BINUTILS_VERSION): binutils-$(BINUTILS_VERSION).tar.bz2
-       tar xjf $@.tar.bz2
-       ( cd binutils-$(BINUTILS_VERSION) && patch -p1 < ../binutils.patch )
+       tar xjf $<
+       patch -d $@ -p1 < binutils.patch
        touch $@
 
 BINUTILS_STAMPFILE=$(CROSS_ROOT)/bin/$(GNU_TARGET_ARCH)-xen-elf-ar
@@ -68,10 +74,10 @@ gcc-$(GCC_VERSION).tar.bz2:
 gcc-$(GCC_VERSION).tar.bz2:
        $(WGET) 
http://ftp.gnu.org/gnu/gcc/gcc-$(GCC_VERSION)/gcc-$(GCC_VERSION).tar.bz2
 gcc-$(GCC_VERSION): gcc-$(GCC_VERSION).tar.bz2
-       tar xjf gcc-$(GCC_VERSION).tar.bz2
-       ( cd gcc-$(GCC_VERSION) && patch -p1 < ../gcc.patch )
+       tar xjf $<
+       patch -d $@ -p1 < gcc.patch
        touch $@
-       
+
 GCC_STAMPFILE=$(CROSS_ROOT)/bin/$(GNU_TARGET_ARCH)-xen-elf-gcc-$(GCC_VERSION)
 .PHONY: cross-gcc
 cross-gcc: $(GCC_STAMPFILE)
@@ -89,7 +95,7 @@ newlib-cvs:
 newlib-cvs:
        cvs -z 9 -d :pserver:anoncvs@xxxxxxxxxxxxxxxxxx:/cvs/src co -D 
$(NEWLIB_DATE) newlib
        mv src newlib-cvs
-       ( cd newlib-cvs && patch -p0 < ../newlib.patch)
+       patch -d $@ -p0 < newlib.patch
 
 NEWLIB_STAMPFILE=$(CROSS_ROOT)/$(GNU_TARGET_ARCH)-xen-elf/lib/libc.a
 .PHONY: cross-newlib
@@ -97,7 +103,7 @@ cross-newlib: $(NEWLIB_STAMPFILE)
 $(NEWLIB_STAMPFILE): newlib-cvs $(GCC_STAMPFILE)
        mkdir -p newlib-build
        ( cd newlib-build && \
-         CC_FOR_TARGET="$(GNU_TARGET_ARCH)-xen-elf-gcc $(TARGET_CFLAGS)" 
../newlib-cvs/configure --prefix=$(CROSS_PREFIX) --verbose 
--target=$(GNU_TARGET_ARCH)-xen-elf --enable-newlib-io-long-long && \
+         CC_FOR_TARGET="$(GNU_TARGET_ARCH)-xen-elf-gcc $(TARGET_CFLAGS) 
$(NEWLIB_CFLAGS)" ../newlib-cvs/configure --prefix=$(CROSS_PREFIX) --verbose 
--target=$(GNU_TARGET_ARCH)-xen-elf --enable-newlib-io-long-long && \
          $(MAKE) && \
          $(MAKE) install )
 
@@ -145,8 +151,7 @@ cross-libpci: $(LIBPCI_STAMPFILE)
 ######
 
 lwip-cvs:
-       cvs -z 9 -d :pserver:anonymous@xxxxxxxxxxxxxxxxxxxxxxx:/sources/lwip co 
-D $(LWIP_DATE) lwip
-       mv lwip lwip-cvs
+       cvs -z 9 -d :pserver:anonymous@xxxxxxxxxxxxxxxxxxxxxxx:/sources/lwip co 
-D $(LWIP_DATE) -d $@ lwip
 
 #######
 # Links
@@ -160,29 +165,36 @@ mk-symlinks:
        [ -h include ] || ln -sf ../tools/include .
        mkdir -p libxc
        [ -h libxc/Makefile ] || ( cd libxc && \
-         ln -sf ../../tools/libxc/*.h . && \
-         ln -sf ../../tools/libxc/*.c . && \
-         ln -sf ../../tools/libxc/Makefile . )
+         ln -sf ../$(XEN_ROOT)/tools/libxc/*.h . && \
+         ln -sf ../$(XEN_ROOT)/tools/libxc/*.c . && \
+         ln -sf ../$(XEN_ROOT)/tools/libxc/Makefile . )
        mkdir -p libxc/$(XEN_TARGET_ARCH)
        [ -h libxc/$(XEN_TARGET_ARCH) ] || ( cd libxc/$(XEN_TARGET_ARCH) && \
-         ln -sf ../../tools/libxc/$(XEN_TARGET_ARCH)/*.c . && \
-         ln -sf ../../tools/libxc/$(XEN_TARGET_ARCH)/*.h . && \
-         ln -sf ../../tools/libxc/$(XEN_TARGET_ARCH)/Makefile . )
+         ln -sf ../$(XEN_ROOT)/tools/libxc/$(XEN_TARGET_ARCH)/*.c . && \
+         ln -sf ../$(XEN_ROOT)/tools/libxc/$(XEN_TARGET_ARCH)/*.h . && \
+         ln -sf ../$(XEN_ROOT)/tools/libxc/$(XEN_TARGET_ARCH)/Makefile . )
        mkdir -p ioemu
        [ -h ioemu/Makefile ] || ( cd ioemu && \
-         ln -sf ../../tools/ioemu/* . && \
+         ln -sf ../$(XEN_ROOT)/tools/ioemu/* . && \
          ([ ! -h config-host.h ] || rm -f config-host.h) && \
          ([ ! -h config-host.mak ] || rm -f config-host.mak) )
-       [ -h mini-os ] || ln -sf ../extras/mini-os .
-       [ -h mini-os/include/xen ] || ln -sf ../../../xen/include/public 
mini-os/include/xen
+       $(MAKE) -C $(MINI_OS) links
+
+TARGETS_MINIOS=$(addprefix mini-os-,$(TARGETS))
+$(TARGETS_MINIOS): mini-os-%:
+       [ -d $@ ] || \
+       for i in $$(cd $(MINI_OS) ; find . -type d) ; do \
+                mkdir -p $@/$$i ; \
+       done
 
 #######
 # libxc
 #######
 
 .PHONY: libxc
-libxc: cross-zlib mk-symlinks
-       $(MAKE) -C $@
+libxc: libxc/libxenctrl.a libxc/libxenguest.a
+libxc/libxenctrl.a libxc/libxenguest.a: cross-zlib mk-symlinks
+       $(MAKE) -C libxc
 
 #######
 # ioemu
@@ -199,7 +211,7 @@ ioemu: cross-zlib cross-libpci mk-symlin
 ######
 
 .PHONY: caml
-caml: mk-symlinks
+caml: cross-newlib mk-symlinks
        $(MAKE) -C $@ LWIPDIR=$(CURDIR)/lwip-cvs 
 
 ###
@@ -207,33 +219,56 @@ caml: mk-symlinks
 ###
 
 .PHONY: c
-c: mk-symlinks
+c: cross-newlib mk-symlinks
        $(MAKE) -C $@ LWIPDIR=$(CURDIR)/lwip-cvs 
+
+######
+# Grub
+######
+
+grub-cvs:
+       cvs -z 9 -d :pserver:anonymous@xxxxxxxxxxxxxx:/sources/grub co -D 
$(GRUB_DATE) -d $@ grub
+       for i in grub.patches/* ; do \
+               patch -d $@ -p1 < $$i ; \
+       done
+
+.PHONY: grub
+grub: grub-cvs cross-newlib mk-symlinks
+       $(MAKE) -C $@
 
 ########
 # minios
 ########
 
 .PHONY: ioemu-stubdom
-ioemu-stubdom: lwip-cvs libxc ioemu
-       $(MAKE) -C mini-os TARGET=$@ LWIPDIR=$(CURDIR)/lwip-cvs 
APP_OBJS="$(CURDIR)/ioemu/i386-dm-stubdom/qemu.a 
$(CURDIR)/ioemu/i386-dm-stubdom/libqemu.a"
+ioemu-stubdom: mini-os-ioemu lwip-cvs libxc ioemu
+       DEF_CFLAGS=-DCONFIG_QEMU $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< 
LWIPDIR=$(CURDIR)/lwip-cvs APP_OBJS="$(CURDIR)/ioemu/i386-dm-stubdom/qemu.a 
$(CURDIR)/ioemu/i386-dm-stubdom/libqemu.a"
 
 CAMLLIB = $(shell ocamlc -where)
 .PHONY: caml-stubdom
-caml-stubdom: lwip-cvs libxc caml
-       $(MAKE) -C mini-os TARGET=$@ LWIPDIR=$(CURDIR)/lwip-cvs 
APP_OBJS="$(CURDIR)/caml/main-c.o $(CURDIR)/caml/main-caml.o 
$(CURDIR)/caml/caml.o $(CAMLLIB)/libasmrun.a"
+caml-stubdom: mini-os-caml lwip-cvs libxc caml
+       DEF_CFLAGS=-DCONFIG_CAML $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< 
LWIPDIR=$(CURDIR)/lwip-cvs APP_OBJS="$(CURDIR)/caml/main-caml.o 
$(CURDIR)/caml/caml.o $(CAMLLIB)/libasmrun.a"
 
 .PHONY: c-stubdom
-c-stubdom: lwip-cvs libxc c
-       $(MAKE) -C mini-os TARGET=$@ LWIPDIR=$(CURDIR)/lwip-cvs 
APP_OBJS=$(CURDIR)/c/main.a
+c-stubdom: mini-os-c lwip-cvs libxc c
+       DEF_CFLAGS=-DCONFIG_C $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< 
LWIPDIR=$(CURDIR)/lwip-cvs APP_OBJS=$(CURDIR)/c/main.a
+
+.PHONY: pv-grub
+pv-grub: mini-os-grub libxc grub
+       DEF_CFLAGS=-DCONFIG_GRUB $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< 
APP_OBJS=$(CURDIR)/grub/main.a
 
 #########
 # install
 #########
 
-install: mini-os/ioemu-stubdom.gz
+install: install-ioemu install-grub
+
+install-ioemu: mini-os-ioemu/mini-os.gz
        $(INSTALL_PROG) stubdom-dm "$(DESTDIR)/usr/lib/xen/bin"
-       $(INSTALL_PROG) $< "$(DESTDIR)/usr/lib/xen/boot/stubdom.gz"
+       $(INSTALL_PROG) $< "$(DESTDIR)/usr/lib/xen/boot/ioemu-stubdom.gz"
+
+install-grub: mini-os-grub/mini-os.gz
+       $(INSTALL_PROG) $< "$(DESTDIR)/usr/lib/xen/boot/pv-grub.gz"
 
 #######
 # clean
@@ -242,9 +277,13 @@ install: mini-os/ioemu-stubdom.gz
 # Only clean the libxc/ioemu/mini-os part
 .PHONY: clean
 clean:
-       -$(MAKE) -C mini-os LWIPDIR=$(CURDIR)/lwip-cvs clean
+       rm -fr mini-os-ioemu
+       rm -fr mini-os-c
+       rm -fr mini-os-caml
+       rm -fr mini-os-grub
        $(MAKE) -C caml clean
        $(MAKE) -C c clean
+       $(MAKE) -C grub clean
        rm -fr libxc ioemu mini-os include
 
 # clean the cross-compilation result
@@ -261,6 +300,7 @@ patchclean: crossclean
        rm -fr gcc-$(GCC_VERSION)
        rm -fr newlib-cvs
        rm -fr lwip-cvs
+       rm -fr grub-cvs
 
 # clean downloads
 .PHONY: downloadclean
diff -r 1201c7657832 -r 0034766b45c2 stubdom/README
--- a/stubdom/README    Tue Jun 10 16:00:33 2008 +0900
+++ b/stubdom/README    Thu Jun 19 12:46:26 2008 +0900
@@ -6,12 +6,19 @@ Then make install to install the result.
 
 Also, run make and make install in $XEN_ROOT/tools/fs-back
 
+
+
+                                IOEMU stubdom
+                                =============
+
+  This boosts HVM performance by putting ioemu in its own lightweight domain.
+
 General Configuration
 =====================
 
 In your HVM config "hvmconfig",
 
-- use /usr/lib/xen/bin/stubdom-dm as dm script
+- use /usr/lib/xen/bin/stubdom-dm as dm script:
 
 device_model = '/usr/lib/xen/bin/stubdom-dm'
 
@@ -19,11 +26,13 @@ device_model = '/usr/lib/xen/bin/stubdom
 
 #disk = [  'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 
'file:/tmp/test,hdb,r' ]
 
+- disable anything related to dom0, like pty serial assignments
+
 
 Create /etc/xen/stubdom-hvmconfig (where "hvmconfig" is the name of your HVM
 guest) with
 
-kernel = "/usr/lib/xen/boot/stubdom.gz"
+kernel = "/usr/lib/xen/boot/ioemu-stubdom.gz"
 vif = [ '', 'ip=10.0.1.1,mac=aa:00:00:12:23:34']
 disk = [  'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 
'file:/tmp/test,hdb,r' ]
 
@@ -40,34 +49,36 @@ There are three posibilities
 
 * Using SDL
 
-In hvmconfig, disable vnc:
+  - In hvmconfig, disable vnc and sdl:
 
 vnc = 0
+sdl = 0
 
-In stubdom-hvmconfig, set a vfb:
+  - In stubdom-hvmconfig, set an sdl vfb:
 
 vfb = [ 'type=sdl' ]
 
 * Using a VNC server in the stub domain
 
-In hvmconfig, set vnclisten to "172.30.206.1" for instance.  Do not use a host
-name as Mini-OS does not have a name resolver.  Do not use 127.0.0.1 since then
-you will not be able to connect to it.
+  - In hvmconfig, set vnclisten to "172.30.206.1" for instance.  Do not use a
+host name as Mini-OS does not have a name resolver.  Do not use 127.0.0.1 since
+then you will not be able to connect to it.
 
 vnc = 1
 vnclisten = "172.30.206.1"
 
-In stubdom-hvmconfig, fill the reserved vif with the same IP, for instance:
+  - In stubdom-hvmconfig, fill the reserved vif with the same IP, for instance:
 
 vif = [ 'ip=172.30.206.1', 'ip=10.0.1.1,mac=aa:00:00:12:23:34']
 
 * Using a VNC server in dom0
 
-In hvmconfig, disable vnc:
+  - In hvmconfig, disable vnc and sdl:
 
 vnc = 0
+sdl = 0
 
-In stubdom-hvmconfig, set a vfb:
+  - In stubdom-hvmconfig, set a vnc vfb:
 
 vfb = [ 'type=vnc' ]
 
@@ -83,3 +94,43 @@ ln -s /var/lib/xen /exports/var/lib
 /usr/sbin/fs-backend &
 
 xm create hvmconfig
+
+
+
+                                   PV-GRUB
+                                   =======
+
+  This replaces pygrub to boot domU images safely: it runs the regular grub
+inside the created domain itself and uses regular domU facilities to read the
+disk / fetch files from network etc. ; it eventually loads the PV kernel and
+chain-boots it.
+  
+Configuration
+=============
+
+In your PV config,
+
+- use /usr/lib/xen/boot/pv-grub.gz as kernel:
+
+kernel = "/usr/lib/xen/boot/pv-grub.gz"
+
+- set the path to menu.lst, as seen from the domU, in extra:
+
+extra = "(hd0,0)/boot/grub/menu.lst"
+
+you can also use a tftp path (dhcp will be automatically performed):
+
+extra = "(nd)/somepath/menu.lst"
+
+or you can set it in option 150 of your dhcp server and leave extra empty
+
+Limitations
+===========
+
+- You can not boot a 64bit kernel with a 32bit-compiled PV-GRUB and vice-versa.
+To cross-compile a 32bit PV-GRUB,
+
+export XEN_TARGET_ARCH=x86_32
+
+- bootsplash is supported, but the ioemu backend does not yet support restart
+for use by the booted kernel.
diff -r 1201c7657832 -r 0034766b45c2 stubdom/c/Makefile
--- a/stubdom/c/Makefile        Tue Jun 10 16:00:33 2008 +0900
+++ b/stubdom/c/Makefile        Thu Jun 19 12:46:26 2008 +0900
@@ -4,10 +4,7 @@ include $(XEN_ROOT)/Config.mk
 
 all: main.a
 
-main-c.c:
-       ln -sf $(XEN_ROOT)/extras/mini-os/main.c $@
-
-main.a: main-c.o main.o 
+main.a: main.o 
        $(AR) cr $@ $^
 
 clean:
diff -r 1201c7657832 -r 0034766b45c2 stubdom/caml/Makefile
--- a/stubdom/caml/Makefile     Tue Jun 10 16:00:33 2008 +0900
+++ b/stubdom/caml/Makefile     Thu Jun 19 12:46:26 2008 +0900
@@ -11,10 +11,7 @@ OBJS := hello.cmx
 OBJS := hello.cmx
 LIBS := 
 
-all: main-c.o main-caml.o caml.o
-
-main-c.c:
-       ln -sf $(XEN_ROOT)/extras/mini-os/main.c $@
+all: main-caml.o caml.o
 
 %.cmx: %.ml
        $(OCAMLFIND) $(OCAMLOPT) -c $< -o $@
diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub.patches/10graphics.diff
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/stubdom/grub.patches/10graphics.diff      Thu Jun 19 12:46:26 2008 +0900
@@ -0,0 +1,2299 @@
+diff -Naur grub-0.97.orig/configure.ac grub-0.97/configure.ac
+--- grub-0.97.orig/configure.ac        2005-05-07 23:36:03.000000000 -0300
++++ grub-0.97/configure.ac     2005-06-12 20:56:49.000000000 -0300
+@@ -595,6 +595,11 @@
+   [  --enable-diskless       enable diskless support])
+ AM_CONDITIONAL(DISKLESS_SUPPORT, test "x$enable_diskless" = xyes)
+ 
++dnl Graphical splashscreen support
++AC_ARG_ENABLE(graphics,
++  [  --disable-graphics      disable graphics terminal support])
++AM_CONDITIONAL(GRAPHICS_SUPPORT, test "x$enable_graphics" != xno)
++
+ dnl Hercules terminal
+ AC_ARG_ENABLE(hercules,
+   [  --disable-hercules      disable hercules terminal support])
+diff -Naur grub-0.97.orig/stage2/asm.S grub-0.97/stage2/asm.S
+--- grub-0.97.orig/stage2/asm.S        2004-06-19 13:55:22.000000000 -0300
++++ grub-0.97/stage2/asm.S     2005-06-13 14:05:31.000000000 -0300
+@@ -2216,7 +2216,304 @@
+       pop     %ebx
+       pop     %ebp
+       ret
+-              
++
++
++/* graphics mode functions */
++#ifdef SUPPORT_GRAPHICS
++VARIABLE(cursorX)
++.word 0
++VARIABLE(cursorY)
++.word 0
++VARIABLE(cursorCount)
++.word 0
++VARIABLE(cursorBuf)
++.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
++
++
++/*
++ * set_int1c_handler(void)
++ */
++ENTRY(set_int1c_handler)
++      pushl   %edi
++
++      /* save the original int1c handler */
++      movl    $0x70, %edi
++      movw    (%edi), %ax
++      movw    %ax, ABS(int1c_offset)
++      movw    2(%edi), %ax
++      movw    %ax, ABS(int1c_segment)
++
++      /* save the new int1c handler */
++      movw    $ABS(int1c_handler), %ax
++      movw    %ax, (%edi)
++      xorw    %ax, %ax
++      movw    %ax, 2(%edi)
++
++      popl    %edi
++      ret
++
++
++/*
++ * unset_int1c_handler(void)
++ */
++ENTRY(unset_int1c_handler)
++      pushl   %edi
++
++      /* check if int1c_handler is set */
++      movl    $0x70, %edi
++      movw    $ABS(int1c_handler), %ax
++      cmpw    %ax, (%edi)
++      jne     int1c_1
++      xorw    %ax, %ax
++      cmpw    %ax, 2(%edi)
++      jne     int1c_1
++
++      /* restore the original */
++      movw    ABS(int1c_offset), %ax
++      movw    %ax, (%edi)
++      movw    ABS(int1c_segment), %ax
++      movw    %ax, 2(%edi)
++
++int1c_1:
++      popl    %edi
++      ret
++
++
++/*
++ * blinks graphics cursor
++ */
++      .code16
++write_data:
++      movw    $0, %ax
++      movw    %ax, %ds
++
++      mov     $0xA000, %ax            /* video in es:di */
++      mov     %ax, %es
++      mov     $80, %ax
++      movw    $ABS(cursorY), %si
++      mov     %ds:(%si), %bx
++      mul     %bx
++      movw    $ABS(cursorX), %si
++      mov     %ds:(%si), %bx
++      shr     $3, %bx                 /* %bx /= 8 */
++      add     %bx, %ax
++      mov     %ax, %di
++
++      movw    $ABS(cursorBuf), %si    /* fontBuf in ds:si */
++
++      /* prepare for data moving */
++      mov     $16, %dx                /* altura da fonte */
++      mov     $80, %bx                /* bytes por linha */
++
++write_loop:
++      movb    %ds:(%si), %al
++      xorb    $0xff, %al
++      movb    %al, %ds:(%si)          /* invert cursorBuf */
++      movb    %al, %es:(%di)          /* write to video */
++      add     %bx, %di
++      inc     %si
++      dec     %dx
++      jg      write_loop
++      ret
++
++int1c_handler:
++      pusha
++      mov     $0, %ax
++      mov     %ax, %ds
++      mov     $ABS(cursorCount), %si
++      mov     %ds:(%si), %ax
++      inc     %ax
++      mov     %ax, %ds:(%si)
++      cmp     $9, %ax
++      jne     int1c_done
++
++      mov     $0, %ax
++      mov     %ax, %ds:(%si)
++      call    write_data
++
++int1c_done:
++      popa
++      iret
++      /* call previous int1c handler */
++      /* ljmp */
++      .byte   0xea
++int1c_offset:  .word   0
++int1c_segment: .word   0
++      .code32
++
++
++/*
++ * unsigned char set_videomode(unsigned char mode)
++ * BIOS call "INT 10H Function 0h" to set video mode
++ *    Call with       %ah = 0x0
++ *                    %al = video mode
++ *  Returns old videomode.
++ */
++ENTRY(set_videomode)
++      pushl   %ebp
++      movl    %esp,%ebp
++      pushl   %ebx
++      pushl   %ecx
++
++      movb    8(%ebp), %cl
++
++      call    EXT_C(prot_to_real)
++      .code16
++
++      xorb    %al, %al
++      movb    $0xf, %ah
++      int     $0x10                   /* Get Current Video mode */
++      movb    %al, %ch
++      xorb    %ah, %ah
++      movb    %cl, %al
++      int     $0x10                   /* Set Video mode */
++
++      DATA32  call    EXT_C(real_to_prot)
++      .code32
++
++      xorl    %eax, %eax
++      movb    %ch, %al
++
++      popl    %ecx
++      popl    %ebx
++      popl    %ebp
++      ret
++
++
++/*
++ * int get_videomode()
++ * BIOS call "INT 10H Function 0Fh" to get current video mode
++ *    Call with       %al = 0x0
++ *                    %ah = 0xF
++ *    Returns current videomode.
++ */
++ENTRY(get_videomode)
++      pushl   %ebp
++      movl    %esp,%ebp
++      pushl   %ebx
++      pushl   %ecx
++
++      call    EXT_C(prot_to_real)
++      .code16
++
++      xorb    %al, %al
++      movb    $0xF, %ah
++      int     $0x10                   /* Get Current Video mode */
++      movb    %al, %cl        /* For now we only want display mode */
++
++      DATA32  call    EXT_C(real_to_prot)
++      .code32
++
++      xorl    %eax, %eax
++      movb    %cl, %al
++
++      popl    %ecx
++      popl    %ebx
++      popl    %ebp
++      ret
++
++
++/*
++ * unsigned char * graphics_get_font()
++ * BIOS call "INT 10H Function 11h" to set font
++ *      Call with       %ah = 0x11
++ */
++ENTRY(graphics_get_font)
++      push    %ebp
++      push    %ebx
++      push    %ecx
++      push    %edx
++
++      call    EXT_C(prot_to_real)
++      .code16
++
++      movw    $0x1130, %ax
++      movb    $6, %bh         /* font 8x16 */
++      int     $0x10
++      movw    %bp, %dx
++      movw    %es, %cx
++
++      DATA32  call    EXT_C(real_to_prot)
++      .code32
++
++      xorl    %eax, %eax
++      movw    %cx, %ax
++      shll    $4, %eax
++      movw    %dx, %ax
++
++      pop     %edx
++      pop     %ecx
++      pop     %ebx
++      pop     %ebp
++      ret
++
++
++/*
++ * graphics_set_palette(index, red, green, blue)
++ * BIOS call "INT 10H Function 10h" to set individual dac register
++ *    Call with       %ah = 0x10
++ *                    %bx = register number
++ *                    %ch = new value for green (0-63)
++ *                    %cl = new value for blue (0-63)
++ *                    %dh = new value for red (0-63)
++ */
++
++ENTRY(graphics_set_palette)
++      push    %ebp
++      push    %eax
++      push    %ebx
++      push    %ecx
++      push    %edx
++
++      movw    $0x3c8, %bx             /* address write mode register */
++
++      /* wait vertical retrace */
++      movw    $0x3da, %dx
++l1b:
++      inb     %dx, %al        /* wait vertical active display */
++      test    $8, %al
++      jnz     l1b
++
++l2b:
++      inb     %dx, %al        /* wait vertical retrace */
++      test    $8, %al
++      jnz     l2b
++
++      mov     %bx, %dx
++      movb    0x18(%esp), %al         /* index */
++      outb    %al, %dx
++      inc     %dx
++
++      movb    0x1c(%esp), %al         /* red */
++      outb    %al, %dx
++
++      movb    0x20(%esp), %al         /* green */
++      outb    %al, %dx
++
++      movb    0x24(%esp), %al         /* blue */
++      outb    %al, %dx
++
++      movw    0x18(%esp), %bx
++
++      call    EXT_C(prot_to_real)
++      .code16
++
++      movb    %bl, %bh
++      movw    $0x1000, %ax
++      int     $0x10
++
++      DATA32  call    EXT_C(real_to_prot)
++      .code32
++
++      pop     %edx
++      pop     %ecx
++      pop     %ebx
++      pop     %eax
++      pop     %ebp
++      ret
++#endif /* SUPPORT_GRAPHICS */
++
++
+ /*
+  * getrtsecs()
+  *    if a seconds value can be read, read it and return it (BCD),
+diff -Naur grub-0.97.orig/stage2/builtins.c grub-0.97/stage2/builtins.c
+--- grub-0.97.orig/stage2/builtins.c   2005-02-15 19:58:23.000000000 -0200
++++ grub-0.97/stage2/builtins.c        2005-06-13 18:44:03.000000000 -0300
+@@ -28,6 +28,10 @@
+ #include <filesys.h>
+ #include <term.h>
+ 
++#ifdef SUPPORT_GRAPHICS
++# include <graphics.h>
++#endif
++
+ #ifdef SUPPORT_NETBOOT
+ # define GRUB 1
+ # include <etherboot.h>
+@@ -237,12 +241,22 @@
+ static int
+ boot_func (char *arg, int flags)
+ {
++  struct term_entry *prev_term = current_term;
+   /* Clear the int15 handler if we can boot the kernel successfully.
+      This assumes that the boot code never fails only if KERNEL_TYPE is
+      not KERNEL_TYPE_NONE. Is this assumption is bad?  */
+   if (kernel_type != KERNEL_TYPE_NONE)
+     unset_int15_handler ();
+ 
++  /* if our terminal needed initialization, we should shut it down
++   * before booting the kernel, but we want to save what it was so
++   * we can come back if needed */
++  if (current_term->shutdown) 
++    {
++      current_term->shutdown();
++      current_term = term_table; /* assumption: console is first */
++    }
++
+ #ifdef SUPPORT_NETBOOT
+   /* Shut down the networking.  */
+   cleanup_net ();
+@@ -306,6 +320,13 @@
+       return 1;
+     }
+ 
++  /* if we get back here, we should go back to what our term was before */
++  current_term = prev_term;
++  if (current_term->startup)
++      /* if our terminal fails to initialize, fall back to console since
++       * it should always work */
++      if (current_term->startup() == 0)
++          current_term = term_table; /* we know that console is first */
+   return 0;
+ }
+ 
+@@ -852,6 +873,251 @@
+ };
+ #endif /* SUPPORT_NETBOOT */
+ 
++#ifdef SUPPORT_GRAPHICS
++
++static int splashimage_func(char *arg, int flags) {
++  int i;
++    
++  /* filename can only be 256 characters due to our buffer size */
++  if (grub_strlen(arg) > 256) {
++    grub_printf("Splash image filename too large\n");
++    grub_printf("Press any key to continue...");
++    getkey();
++    return 1;
++  }
++
++  /* get rid of TERM_NEED_INIT from the graphics terminal. */
++  for (i = 0; term_table[i].name; i++) {
++    if (grub_strcmp (term_table[i].name, "graphics") == 0) {
++      term_table[i].flags &= ~TERM_NEED_INIT;
++      break;
++    }
++  }
++
++  graphics_set_splash(arg);
++
++  if (flags == BUILTIN_CMDLINE && graphics_inited) {
++    graphics_end();
++    if (graphics_init() == 0) {
++      /* Fallback to default term */
++      current_term = term_table;
++      max_lines = current_term->max_lines;
++      if (current_term->cls)
++        current_term->cls();
++      grub_printf("Failed to set splash image and/or graphics mode\n");
++      return 1;
++    }
++    graphics_cls();
++  }
++
++  if (flags == BUILTIN_MENU)
++    current_term = term_table + i;
++
++  return 0;
++}
++
++static struct builtin builtin_splashimage =
++{
++  "splashimage",
++  splashimage_func,
++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++  "splashimage FILE",
++  "Load FILE as the background image when in graphics mode."
++};
++
++
++/* shade */
++static int
++shade_func(char *arg, int flags)
++{
++    int new_shade;
++
++    if (!arg || safe_parse_maxint(&arg, &new_shade) == 0)
++       return (1);
++
++    if (shade != new_shade) {
++       shade = new_shade;
++       if (flags == BUILTIN_CMDLINE && graphics_inited) {
++           graphics_end();
++           graphics_init();
++           graphics_cls();
++       }
++    }
++
++    return 0;
++}
++
++static struct builtin builtin_shade =
++{
++  "shade",
++  shade_func,
++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++  "shade INTEGER",
++  "If set to 0, disables the use of shaded text, else enables it."
++};
++
++
++/* foreground */
++static int
++foreground_func(char *arg, int flags)
++{
++    if (grub_strlen(arg) == 6) {
++      int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
++      int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
++      int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
++
++      foreground = (r << 16) | (g << 8) | b;
++      if (graphics_inited)
++          graphics_set_palette(15, r, g, b);
++
++      return 0;
++    }
++
++    return 1;
++}
++
++static struct builtin builtin_foreground =
++{
++  "foreground",
++  foreground_func,
++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++  "foreground RRGGBB",
++  "Sets the foreground color when in graphics mode."
++  "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
++};
++
++
++/* background */
++static int
++background_func(char *arg, int flags)
++{
++    if (grub_strlen(arg) == 6) {
++      int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
++      int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
++      int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
++
++      background = (r << 16) | (g << 8) | b;
++      if (graphics_inited)
++          graphics_set_palette(0, r, g, b);
++      return 0;
++    }
++
++    return 1;
++}
++
++static struct builtin builtin_background =
++{
++  "background",
++  background_func,
++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++  "background RRGGBB",
++  "Sets the background color when in graphics mode."
++  "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
++};
++
++
++/* border */
++static int
++border_func(char *arg, int flags)
++{
++    if (grub_strlen(arg) == 6) {
++       int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
++       int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
++       int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
++
++       window_border = (r << 16) | (g << 8) | b;
++       if (graphics_inited)
++           graphics_set_palette(0x11, r, g, b);
++
++       return 0;
++    }
++
++    return 1;
++}
++
++static struct builtin builtin_border =
++{
++  "border",
++  border_func,
++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++  "border RRGGBB",
++  "Sets the border video color when in graphics mode."
++  "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
++};
++
++
++/* viewport */
++static int
++viewport_func (char *arg, int flags)
++{
++    int i;
++    int x0 = 0, y0 = 0, x1 = 80, y1 = 30;
++    int *pos[4] = { &x0, &y0, &x1, &y1 };
++
++    if (!arg)
++       return (1);
++    for (i = 0; i < 4; i++) {
++       if (!*arg)
++           return (1);
++    while (*arg && (*arg == ' ' || *arg == '\t'))
++           ++arg;
++       if (!safe_parse_maxint(&arg, pos[i]))
++           return (1);
++       while (*arg && (*arg != ' ' && *arg != '\t'))
++           ++arg;
++    }
++
++    /* minimum size is 65 colums and 16 rows */
++    if (x0 > x1 - 66 || y0 > y1 - 16 || x0 < 0 || y0 < 0 || x1 > 80 || y1 > 
30)
++       return 1;
++
++    view_x0 = x0;
++    view_y0 = y0;
++    view_x1 = x1;
++    view_y1 = y1;
++
++    if (flags == BUILTIN_CMDLINE && graphics_inited) {
++       graphics_end();
++       graphics_init();
++       graphics_cls();
++    }
++
++    return 0;
++}
++
++static struct builtin builtin_viewport =
++{
++  "viewport",
++  viewport_func,
++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++  "viewport x0 y0 x1 y1",
++  "Changes grub internals to output text in the window defined by"
++  " four parameters. The x and y parameters are 0 based. This option"
++  " only works with the graphics interface."
++};
++
++#endif /* SUPPORT_GRAPHICS */
++
++
++/* clear */
++static int 
++clear_func() 
++{
++  if (current_term->cls)
++    current_term->cls();
++
++  return 0;
++}
++
++static struct builtin builtin_clear =
++{
++  "clear",
++  clear_func,
++  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
++  "clear",
++  "Clear the screen"
++};
++
+ 
+ /* displayapm */
+ static int
+@@ -1454,14 +1720,20 @@
+ 
+ 
+ /* help */
+-#define MAX_SHORT_DOC_LEN     39
+-#define MAX_LONG_DOC_LEN      66
+-
+ static int
+ help_func (char *arg, int flags)
+ {
+-  int all = 0;
+-  
++  int all = 0, max_short_doc_len, max_long_doc_len;
++  max_short_doc_len = 39;
++  max_long_doc_len = 66;
++#ifdef SUPPORT_GRAPHICS
++  if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) 
== 0)
++    {
++      max_short_doc_len = (view_x1 - view_x0 + 1) / 2 - 1;
++      max_long_doc_len = (view_x1 - view_x0) - 14;
++    }
++#endif
++
+   if (grub_memcmp (arg, "--all", sizeof ("--all") - 1) == 0)
+     {
+       all = 1;
+@@ -1491,13 +1763,13 @@
+ 
+         len = grub_strlen ((*builtin)->short_doc);
+         /* If the length of SHORT_DOC is too long, truncate it.  */
+-        if (len > MAX_SHORT_DOC_LEN - 1)
+-          len = MAX_SHORT_DOC_LEN - 1;
++        if (len > max_short_doc_len - 1)
++          len = max_short_doc_len - 1;
+ 
+         for (i = 0; i < len; i++)
+           grub_putchar ((*builtin)->short_doc[i]);
+ 
+-        for (; i < MAX_SHORT_DOC_LEN; i++)
++        for (; i < max_short_doc_len; i++)
+           grub_putchar (' ');
+ 
+         if (! left)
+@@ -1546,10 +1818,10 @@
+                     int i;
+ 
+                     /* If LEN is too long, fold DOC.  */
+-                    if (len > MAX_LONG_DOC_LEN)
++                    if (len > max_long_doc_len)
+                       {
+                         /* Fold this line at the position of a space.  */
+-                        for (len = MAX_LONG_DOC_LEN; len > 0; len--)
++                        for (len = max_long_doc_len; len > 0; len--)
+                           if (doc[len - 1] == ' ')
+                             break;
+                       }
+@@ -4085,7 +4357,7 @@
+ };
+ 
+ 
+-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
++#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || 
defined(SUPPORT_GRAPHICS)
+ /* terminal */
+ static int
+ terminal_func (char *arg, int flags)
+@@ -4244,17 +4516,29 @@
+  end:
+   current_term = term_table + default_term;
+   current_term->flags = term_flags;
+-  
++
+   if (lines)
+     max_lines = lines;
+   else
+-    /* 24 would be a good default value.  */
+-    max_lines = 24;
+-  
++    max_lines = current_term->max_lines;
++
+   /* If the interface is currently the command-line,
+      restart it to repaint the screen.  */
+-  if (current_term != prev_term && (flags & BUILTIN_CMDLINE))
++  if ((current_term != prev_term) && (flags & BUILTIN_CMDLINE)){
++    if (prev_term->shutdown)
++      prev_term->shutdown();
++    if (current_term->startup) {
++      /* If startup fails, return to previous term */
++      if (current_term->startup() == 0) {
++        current_term = prev_term;
++        max_lines = current_term->max_lines;
++        if (current_term->cls) {
++          current_term->cls();
++        }
++      }
++    }
+     grub_longjmp (restart_cmdline_env, 0);
++  }
+   
+   return 0;
+ }
+@@ -4264,7 +4548,7 @@
+   "terminal",
+   terminal_func,
+   BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+-  "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] 
[--silent] [console] [serial] [hercules]",
++  "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] 
[--silent] [console] [serial] [hercules] [graphics]",
+   "Select a terminal. When multiple terminals are specified, wait until"
+   " you push any key to continue. If both console and serial are specified,"
+   " the terminal to which you input a key first will be selected. If no"
+@@ -4276,7 +4560,7 @@
+   " seconds. The option --lines specifies the maximum number of lines."
+   " The option --silent is used to suppress messages."
+ };
+-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
++#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
+ 
+ 
+ #ifdef SUPPORT_SERIAL
+@@ -4795,13 +5079,20 @@
+ /* The table of builtin commands. Sorted in dictionary order.  */
+ struct builtin *builtin_table[] =
+ {
++#ifdef SUPPORT_GRAPHICS
++  &builtin_background,
++#endif
+   &builtin_blocklist,
+   &builtin_boot,
+ #ifdef SUPPORT_NETBOOT
+   &builtin_bootp,
+ #endif /* SUPPORT_NETBOOT */
++#ifdef SUPPORT_GRAPHICS
++  &builtin_border,
++#endif
+   &builtin_cat,
+   &builtin_chainloader,
++  &builtin_clear,
+   &builtin_cmp,
+   &builtin_color,
+   &builtin_configfile,
+@@ -4821,6 +5112,9 @@
+   &builtin_embed,
+   &builtin_fallback,
+   &builtin_find,
++#ifdef SUPPORT_GRAPHICS
++  &builtin_foreground,
++#endif
+   &builtin_fstest,
+   &builtin_geometry,
+   &builtin_halt,
+@@ -4864,9 +5158,13 @@
+ #endif /* SUPPORT_SERIAL */
+   &builtin_setkey,
+   &builtin_setup,
+-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
++#ifdef SUPPORT_GRAPHICS
++  &builtin_shade,
++  &builtin_splashimage,
++#endif /* SUPPORT_GRAPHICS */
++#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || 
defined(SUPPORT_GRAPHICS)
+   &builtin_terminal,
+-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
++#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
+ #ifdef SUPPORT_SERIAL
+   &builtin_terminfo,
+ #endif /* SUPPORT_SERIAL */
+@@ -4880,5 +5178,8 @@
+   &builtin_unhide,
+   &builtin_uppermem,
+   &builtin_vbeprobe,
++#ifdef SUPPORT_GRAPHICS
++  &builtin_viewport,
++#endif
+   0
+ };
+diff -Naur grub-0.97.orig/stage2/char_io.c grub-0.97/stage2/char_io.c
+--- grub-0.97.orig/stage2/char_io.c    2005-02-01 18:51:23.000000000 -0200
++++ grub-0.97/stage2/char_io.c 2005-06-12 20:56:49.000000000 -0300
+@@ -29,12 +29,17 @@
+ # include <serial.h>
+ #endif
+ 
++#ifdef SUPPORT_GRAPHICS
++# include <graphics.h>
++#endif
++
+ #ifndef STAGE1_5
+ struct term_entry term_table[] =
+   {
+     {
+       "console",
+       0,
++      24,
+       console_putchar,
+       console_checkkey,
+       console_getkey,
+@@ -43,13 +48,16 @@
+       console_cls,
+       console_setcolorstate,
+       console_setcolor,
+-      console_setcursor
++      console_setcursor,
++      0, 
++      0
+     },
+ #ifdef SUPPORT_SERIAL
+     {
+       "serial",
+       /* A serial device must be initialized.  */
+       TERM_NEED_INIT,
++      24,
+       serial_putchar,
+       serial_checkkey,
+       serial_getkey,
+@@ -58,6 +66,8 @@
+       serial_cls,
+       serial_setcolorstate,
+       0,
++      0,
++      0, 
+       0
+     },
+ #endif /* SUPPORT_SERIAL */
+@@ -65,6 +75,7 @@
+     {
+       "hercules",
+       0,
++      24,
+       hercules_putchar,
+       console_checkkey,
+       console_getkey,
+@@ -73,11 +84,30 @@
+       hercules_cls,
+       hercules_setcolorstate,
+       hercules_setcolor,
+-      hercules_setcursor
++      hercules_setcursor,
++      0,
++      0
+     },      
+ #endif /* SUPPORT_HERCULES */
++#ifdef SUPPORT_GRAPHICS
++    { "graphics",
++      TERM_NEED_INIT, /* flags */
++      30, /* number of lines */
++      graphics_putchar, /* putchar */
++      console_checkkey, /* checkkey */
++      console_getkey, /* getkey */
++      graphics_getxy, /* getxy */
++      graphics_gotoxy, /* gotoxy */
++      graphics_cls, /* cls */
++      graphics_setcolorstate, /* setcolorstate */
++      graphics_setcolor, /* setcolor */
++      graphics_setcursor, /* nocursor */
++      graphics_init, /* initialize */
++      graphics_end /* shutdown */
++    },
++#endif /* SUPPORT_GRAPHICS */
+     /* This must be the last entry.  */
+-    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
++    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+   };
+ 
+ /* This must be console.  */
+@@ -305,9 +335,10 @@
+ 
+   /* XXX: These should be defined in shared.h, but I leave these here,
+      until this code is freezed.  */
+-#define CMDLINE_WIDTH 78
+ #define CMDLINE_MARGIN        10
+-  
++
++  /* command-line limits */
++  int cmdline_width = 78, col_start = 0;
+   int xpos, lpos, c, section;
+   /* The length of PROMPT.  */
+   int plen;
+@@ -338,7 +369,7 @@
+       
+       /* If the cursor is in the first section, display the first section
+        instead of the second.  */
+-      if (section == 1 && plen + lpos < CMDLINE_WIDTH)
++      if (section == 1 && plen + lpos < cmdline_width)
+       cl_refresh (1, 0);
+       else if (xpos - count < 1)
+       cl_refresh (1, 0);
+@@ -354,7 +385,7 @@
+               grub_putchar ('\b');
+           }
+         else
+-          gotoxy (xpos, getxy () & 0xFF);
++          gotoxy (xpos + col_start, getxy () & 0xFF);
+       }
+     }
+ 
+@@ -364,7 +395,7 @@
+       lpos += count;
+ 
+       /* If the cursor goes outside, scroll the screen to the right.  */
+-      if (xpos + count >= CMDLINE_WIDTH)
++      if (xpos + count >= cmdline_width)
+       cl_refresh (1, 0);
+       else
+       {
+@@ -383,7 +414,7 @@
+               }
+           }
+         else
+-          gotoxy (xpos, getxy () & 0xFF);
++          gotoxy (xpos + col_start, getxy () & 0xFF);
+       }
+     }
+ 
+@@ -398,14 +429,14 @@
+       if (full)
+       {
+         /* Recompute the section number.  */
+-        if (lpos + plen < CMDLINE_WIDTH)
++        if (lpos + plen < cmdline_width)
+           section = 0;
+         else
+-          section = ((lpos + plen - CMDLINE_WIDTH)
+-                     / (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) + 1);
++          section = ((lpos + plen - cmdline_width)
++                     / (cmdline_width - 1 - CMDLINE_MARGIN) + 1);
+ 
+         /* From the start to the end.  */
+-        len = CMDLINE_WIDTH;
++        len = cmdline_width;
+         pos = 0;
+         grub_putchar ('\r');
+ 
+@@ -445,8 +476,8 @@
+         if (! full)
+           offset = xpos - 1;
+         
+-        start = ((section - 1) * (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN)
+-                 + CMDLINE_WIDTH - plen - CMDLINE_MARGIN);
++        start = ((section - 1) * (cmdline_width - 1 - CMDLINE_MARGIN)
++                 + cmdline_width - plen - CMDLINE_MARGIN);
+         xpos = lpos + 1 - start;
+         start += offset;
+       }
+@@ -471,7 +502,7 @@
+       
+       /* If the cursor is at the last position, put `>' or a space,
+        depending on if there are more characters in BUF.  */
+-      if (pos == CMDLINE_WIDTH)
++      if (pos == cmdline_width)
+       {
+         if (start + len < llen)
+           grub_putchar ('>');
+@@ -488,7 +519,7 @@
+           grub_putchar ('\b');
+       }
+       else
+-      gotoxy (xpos, getxy () & 0xFF);
++      gotoxy (xpos + col_start, getxy () & 0xFF);
+     }
+ 
+   /* Initialize the command-line.  */
+@@ -518,10 +549,10 @@
+         
+         llen += l;
+         lpos += l;
+-        if (xpos + l >= CMDLINE_WIDTH)
++        if (xpos + l >= cmdline_width)
+           cl_refresh (1, 0);
+-        else if (xpos + l + llen - lpos > CMDLINE_WIDTH)
+-          cl_refresh (0, CMDLINE_WIDTH - xpos);
++        else if (xpos + l + llen - lpos > cmdline_width)
++          cl_refresh (0, cmdline_width - xpos);
+         else
+           cl_refresh (0, l + llen - lpos);
+       }
+@@ -533,12 +564,22 @@
+       grub_memmove (buf + lpos, buf + lpos + count, llen - count + 1);
+       llen -= count;
+       
+-      if (xpos + llen + count - lpos > CMDLINE_WIDTH)
+-      cl_refresh (0, CMDLINE_WIDTH - xpos);
++      if (xpos + llen + count - lpos > cmdline_width)
++      cl_refresh (0, cmdline_width - xpos);
+       else
+       cl_refresh (0, llen + count - lpos);
+     }
+ 
++  max_lines = current_term->max_lines;
++#ifdef SUPPORT_GRAPHICS
++  if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) 
== 0)
++    {
++      cmdline_width = (view_x1 - view_x0) - 2;
++      col_start = view_x0;
++      max_lines = view_y1 - view_y0;
++    }
++#endif
++
+   plen = grub_strlen (prompt);
+   llen = grub_strlen (cmdline);
+ 
+@@ -1006,6 +1047,48 @@
+ }
+ #endif /* ! STAGE1_5 */
+ 
++#ifndef STAGE1_5
++/* Internal pager.  */
++int
++do_more (void)
++{
++  if (count_lines >= 0)
++    {
++      count_lines++;
++      if (count_lines >= max_lines - 2)
++        {
++          int tmp;
++
++          /* It's important to disable the feature temporarily, because
++             the following grub_printf call will print newlines.  */
++          count_lines = -1;
++
++          grub_printf("\n");
++          if (current_term->setcolorstate)
++            current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
++
++          grub_printf ("[Hit return to continue]");
++
++          if (current_term->setcolorstate)
++            current_term->setcolorstate (COLOR_STATE_NORMAL);
++
++
++          do
++            {
++              tmp = ASCII_CHAR (getkey ());
++            }
++          while (tmp != '\n' && tmp != '\r');
++          grub_printf ("\r                        \r");
++
++          /* Restart to count lines.  */
++          count_lines = 0;
++          return 1;
++        }
++    }
++  return 0;
++}
++#endif
++
+ /* Display an ASCII character.  */
+ void
+ grub_putchar (int c)
+@@ -1034,38 +1117,11 @@
+ 
+   if (c == '\n')
+     {
++      int flag;
+       /* Internal `more'-like feature.  */
+-      if (count_lines >= 0)
+-      {
+-        count_lines++;
+-        if (count_lines >= max_lines - 2)
+-          {
+-            int tmp;
+-            
+-            /* It's important to disable the feature temporarily, because
+-               the following grub_printf call will print newlines.  */
+-            count_lines = -1;
+-
+-            if (current_term->setcolorstate)
+-              current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
+-            
+-            grub_printf ("\n[Hit return to continue]");
+-
+-            if (current_term->setcolorstate)
+-              current_term->setcolorstate (COLOR_STATE_NORMAL);
+-            
+-            do
+-              {
+-                tmp = ASCII_CHAR (getkey ());
+-              }
+-            while (tmp != '\n' && tmp != '\r');
+-            grub_printf ("\r                        \r");
+-            
+-            /* Restart to count lines.  */
+-            count_lines = 0;
+-            return;
+-          }
+-      }
++      flag = do_more ();
++      if (flag)
++        return;
+     }
+ 
+   current_term->putchar (c);
+@@ -1090,7 +1146,7 @@
+ cls (void)
+ {
+   /* If the terminal is dumb, there is no way to clean the terminal.  */
+-  if (current_term->flags & TERM_DUMB)
++  if (current_term->flags & TERM_DUMB) 
+     grub_putchar ('\n');
+   else
+     current_term->cls ();
+@@ -1217,6 +1273,16 @@
+   return ! errnum;
+ }
+ 
++void
++grub_memcpy(void *dest, const void *src, int len)
++{
++  int i;
++  register char *d = (char*)dest, *s = (char*)src;
++
++  for (i = 0; i < len; i++)
++    d[i] = s[i];
++}
++
+ void *
+ grub_memmove (void *to, const void *from, int len)
+ {
+diff -Naur grub-0.97.orig/stage2/cmdline.c grub-0.97/stage2/cmdline.c
+--- grub-0.97.orig/stage2/cmdline.c    2004-08-16 20:23:01.000000000 -0300
++++ grub-0.97/stage2/cmdline.c 2005-06-12 20:56:49.000000000 -0300
+@@ -50,10 +50,11 @@
+ void
+ print_cmdline_message (int forever)
+ {
+-  printf (" [ Minimal BASH-like line editing is supported.  For the first 
word, TAB\n"
+-        "   lists possible command completions.  Anywhere else TAB lists the 
possible\n"
+-        "   completions of a device/filename.%s ]\n",
+-        (forever ? "" : "  ESC at any time exits."));
++  grub_printf("       [ Minimal BASH-like line editing is supported.   For\n"
++              "         the   first   word,  TAB  lists  possible  command\n"
++              "         completions.  Anywhere else TAB lists the possible\n"
++              "         completions of a device/filename.%s ]\n",
++              (forever ? "" : "  ESC at any time\n         exits."));
+ }
+ 
+ /* Find the builtin whose command name is COMMAND and return the
+diff -Naur grub-0.97.orig/stage2/graphics.c grub-0.97/stage2/graphics.c
+--- grub-0.97.orig/stage2/graphics.c   1969-12-31 21:00:00.000000000 -0300
++++ grub-0.97/stage2/graphics.c        2005-06-13 19:13:31.000000000 -0300
+@@ -0,0 +1,585 @@
++/*
++ * graphics.c - graphics mode support for GRUB
++ * Implemented as a terminal type by Jeremy Katz <katzj@xxxxxxxxxx> based
++ * on a patch by Paulo César Pereira de Andrade <pcpa@xxxxxxxxxxxxxxxx>
++ * Options and enhancements made by Herton Ronaldo Krzesinski
++ * <herton@xxxxxxxxxxxx>
++ *
++ *  GRUB  --  GRand Unified Bootloader
++ *  Copyright (C) 2001,2002  Red Hat, Inc.
++ *  Portions copyright (C) 2000  Conectiva, Inc.
++ *
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the GNU General Public License as published by
++ *  the Free Software Foundation; either version 2 of the License, or
++ *  (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *  GNU General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifdef SUPPORT_GRAPHICS
++
++#include <term.h>
++#include <shared.h>
++#include <graphics.h>
++
++int saved_videomode;
++unsigned char *font8x16;
++
++int graphics_inited = 0;
++static char splashimage[256];
++
++int shade = 1, no_cursor = 0;
++
++#define VSHADOW VSHADOW1
++unsigned char VSHADOW1[38400];
++unsigned char VSHADOW2[38400];
++unsigned char VSHADOW4[38400];
++unsigned char VSHADOW8[38400];
++
++/* define the default viewable area */
++int view_x0 = 0;
++int view_y0 = 0;
++int view_x1 = 80;
++int view_y1 = 30;
++
++/* text buffer has to be kept around so that we can write things as we
++ * scroll and the like */
++unsigned short text[80 * 30];
++
++/* graphics options */
++int foreground = (63 << 16) | (63 << 8) | (63), background = 0, window_border 
= 0;
++
++/* current position */
++static int fontx = 0;
++static int fonty = 0;
++
++/* global state so that we don't try to recursively scroll or cursor */
++static int no_scroll = 0;
++
++/* color state */
++static int graphics_standard_color = A_NORMAL;
++static int graphics_normal_color = A_NORMAL;
++static int graphics_highlight_color = A_REVERSE;
++static int graphics_current_color = A_NORMAL;
++static color_state graphics_color_state = COLOR_STATE_STANDARD;
++
++static inline void outb(unsigned short port, unsigned char val)
++{
++    __asm __volatile ("outb %0,%1"::"a" (val), "d" (port));
++}
++
++static void MapMask(int value) {
++    outb(0x3c4, 2);
++    outb(0x3c5, value);
++}
++
++/* bit mask register */
++static void BitMask(int value) {
++    outb(0x3ce, 8);
++    outb(0x3cf, value);
++}
++
++/* move the graphics cursor location to col, row */
++static void graphics_setxy(int col, int row) {
++    if (col >= view_x0 && col < view_x1) {
++        fontx = col;
++        cursorX = col << 3;
++    }
++    if (row >= view_y0 && row < view_y1) {
++        fonty = row;
++        cursorY = row << 4;
++    }
++}
++
++/* scroll the screen */
++static void graphics_scroll() {
++    int i, j, k;
++
++    /* we don't want to scroll recursively... that would be bad */
++    if (no_scroll)
++        return;
++    no_scroll = 1;
++
++    /* disable pager temporarily */
++    k = count_lines;
++    count_lines = -1;
++    
++    /* move everything up a line */
++    for (j = view_y0 + 1; j < view_y1; j++) {
++        graphics_gotoxy(view_x0, j - 1);
++        for (i = view_x0; i < view_x1; i++) {
++            graphics_putchar(text[j * 80 + i]);
++        }
++    }
++
++    /* last line should be blank */
++    graphics_gotoxy(view_x0, view_y1 - 1);
++    for (i = view_x0; i < view_x1; i++)
++        graphics_putchar(' ');
++    graphics_setxy(view_x0, view_y1 - 1);
++
++    count_lines = k;
++
++    no_scroll = 0;
++}
++
++/* Set the splash image */
++void graphics_set_splash(char *splashfile) {
++    grub_strcpy(splashimage, splashfile);
++}
++
++/* Get the current splash image */
++char *graphics_get_splash(void) {
++    return splashimage;
++}
++
++/* 
++ * Initialize a vga16 graphics display with the palette based off of
++ * the image in splashimage.  If the image doesn't exist, leave graphics
++ * mode. The mode initiated is 12h. From "Ralf Brown's Interrupt List":
++ *      text/ text pixel   pixel   colors disply scrn  system
++ *      grph resol  box  resolution       pages  addr
++ * 12h   G   80x30  8x16  640x480  16/256K  .    A000  VGA,ATI VIP
++ *       G   80x30  8x16  640x480  16/64    .    A000  ATI EGA Wonder
++ *       G     .     .    640x480  16       .      .   UltraVision+256K EGA
++ */
++int graphics_init()
++{
++    if (!graphics_inited) {
++        saved_videomode = set_videomode(0x12);
++        if (get_videomode() != 0x12) {
++            set_videomode(saved_videomode);
++            return 0;
++        }
++        graphics_inited = 1;
++    }
++    else
++        return 1;
++
++    font8x16 = (unsigned char*)graphics_get_font();
++
++    /* make sure that the highlight color is set correctly */
++    graphics_highlight_color = ((graphics_normal_color >> 4) | 
++                                ((graphics_normal_color & 0xf) << 4));
++
++    graphics_cls();
++
++    if (!read_image(splashimage)) {
++        grub_printf("Failed to read splash image (%s)\n", splashimage);
++        grub_printf("Press any key to continue...");
++        getkey();
++        set_videomode(saved_videomode);
++        graphics_inited = 0;
++        return 0;
++    }
++
++    set_int1c_handler();
++
++    return 1;
++}
++
++/* Leave graphics mode */
++void graphics_end(void)
++{
++    if (graphics_inited) {
++        unset_int1c_handler();
++        set_videomode(saved_videomode);
++        graphics_inited = 0;
++        no_cursor = 0;
++    }
++}
++
++/* Print ch on the screen.  Handle any needed scrolling or the like */
++void graphics_putchar(int ch) {
++    ch &= 0xff;
++
++    graphics_cursor(0);
++
++    if (ch == '\n') {
++        if (fonty + 1 < view_y1)
++            graphics_setxy(fontx, fonty + 1);
++        else
++            graphics_scroll();
++        graphics_cursor(1);
++        return;
++    } else if (ch == '\r') {
++        graphics_setxy(view_x0, fonty);
++        graphics_cursor(1);
++        return;
++    }
++
++    graphics_cursor(0);
++
++    text[fonty * 80 + fontx] = ch;
++    text[fonty * 80 + fontx] &= 0x00ff;
++    if (graphics_current_color & 0xf0)
++        text[fonty * 80 + fontx] |= 0x100;
++
++    graphics_cursor(0);
++
++    if ((fontx + 1) >= view_x1) {
++        graphics_setxy(view_x0, fonty);
++        if (fonty + 1 < view_y1)
++            graphics_setxy(view_x0, fonty + 1);
++        else
++            graphics_scroll();
++        graphics_cursor(1);
++        do_more ();
++        graphics_cursor(0);
++    } else {
++        graphics_setxy(fontx + 1, fonty);
++    }
++
++    graphics_cursor(1);
++}
++
++/* get the current location of the cursor */
++int graphics_getxy(void) {
++    return (fontx << 8) | fonty;
++}
++
++void graphics_gotoxy(int x, int y) {
++    graphics_cursor(0);
++
++    graphics_setxy(x, y);
++
++    graphics_cursor(1);
++}
++
++void graphics_cls(void) {
++    int i;
++    unsigned char *mem, *s1, *s2, *s4, *s8;
++
++    graphics_cursor(0);
++    graphics_gotoxy(view_x0, view_y0);
++
++    mem = (unsigned char*)VIDEOMEM;
++    s1 = (unsigned char*)VSHADOW1;
++    s2 = (unsigned char*)VSHADOW2;
++    s4 = (unsigned char*)VSHADOW4;
++    s8 = (unsigned char*)VSHADOW8;
++
++    for (i = 0; i < 80 * 30; i++)
++        text[i] = ' ';
++    graphics_cursor(1);
++
++    BitMask(0xff);
++
++    /* plane 1 */
++    MapMask(1);
++    grub_memcpy(mem, s1, 38400);
++
++    /* plane 2 */
++    MapMask(2);
++    grub_memcpy(mem, s2, 38400);
++
++    /* plane 3 */
++    MapMask(4);
++    grub_memcpy(mem, s4, 38400);
++
++    /* plane 4 */
++    MapMask(8);
++    grub_memcpy(mem, s8, 38400);
++
++    MapMask(15);
++
++    if (no_cursor) {
++        no_cursor = 0;
++        set_int1c_handler();
++    }
++}
++
++void graphics_setcolorstate (color_state state) {
++    switch (state) {
++    case COLOR_STATE_STANDARD:
++        graphics_current_color = graphics_standard_color;
++        break;
++    case COLOR_STATE_NORMAL:
++        graphics_current_color = graphics_normal_color;
++        break;
++    case COLOR_STATE_HIGHLIGHT:
++        graphics_current_color = graphics_highlight_color;
++        break;
++    default:
++        graphics_current_color = graphics_standard_color;
++        break;
++    }
++
++    graphics_color_state = state;
++}
++
++void graphics_setcolor (int normal_color, int highlight_color) {
++    graphics_normal_color = normal_color;
++    graphics_highlight_color = highlight_color;
++
++    graphics_setcolorstate (graphics_color_state);
++}
++
++int graphics_setcursor (int on) {
++    if (!no_cursor && !on) {
++        no_cursor = 1;
++        unset_int1c_handler();
++        graphics_cursor(0);
++    }
++    else if(no_cursor && on) {
++        no_cursor = 0;
++        set_int1c_handler();
++        graphics_cursor(1);
++    }
++    return 0;
++}
++
++/* Read in the splashscreen image and set the palette up appropriately.
++ * Format of splashscreen is an xpm (can be gzipped) with 16 colors and
++ * 640x480. */
++int read_image(char *s)
++{
++    char buf[32], pal[16], c;
++    unsigned char base, mask, *s1, *s2, *s4, *s8;
++    unsigned i, len, idx, colors, x, y, width, height;
++
++    if (!grub_open(s))
++        return 0;
++
++    /* read header */
++    if (!grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) {
++        grub_close();
++        return 0;
++    }
++    
++    /* parse info */
++    while (grub_read(&c, 1)) {
++        if (c == '"')
++            break;
++    }
++
++    while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
++        ;
++
++    i = 0;
++    width = c - '0';
++    while (grub_read(&c, 1)) {
++        if (c >= '0' && c <= '9')
++            width = width * 10 + c - '0';
++        else
++            break;
++    }
++    while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
++        ;
++
++    height = c - '0';
++    while (grub_read(&c, 1)) {
++        if (c >= '0' && c <= '9')
++            height = height * 10 + c - '0';
++        else
++            break;
++    }
++    while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
++        ;
++
++    colors = c - '0';
++    while (grub_read(&c, 1)) {
++        if (c >= '0' && c <= '9')
++            colors = colors * 10 + c - '0';
++        else
++            break;
++    }
++
++    base = 0;
++    while (grub_read(&c, 1) && c != '"')
++        ;
++
++    /* palette */
++    for (i = 0, idx = 1; i < colors; i++) {
++        len = 0;
++
++        while (grub_read(&c, 1) && c != '"')
++            ;
++        grub_read(&c, 1);       /* char */
++        base = c;
++        grub_read(buf, 4);      /* \t c # */
++
++        while (grub_read(&c, 1) && c != '"') {
++            if (len < sizeof(buf))
++                buf[len++] = c;
++        }
++
++        if (len == 6 && idx < 15) {
++            int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2;
++            int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2;
++            int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2;
++
++            pal[idx] = base;
++            graphics_set_palette(idx, r, g, b);
++            ++idx;
++        }
++    }
++
++    x = y = len = 0;
++
++    s1 = (unsigned char*)VSHADOW1;
++    s2 = (unsigned char*)VSHADOW2;
++    s4 = (unsigned char*)VSHADOW4;
++    s8 = (unsigned char*)VSHADOW8;
++
++    for (i = 0; i < 38400; i++)
++        s1[i] = s2[i] = s4[i] = s8[i] = 0;
++
++    /* parse xpm data */
++    while (y < height) {
++        while (1) {
++            if (!grub_read(&c, 1)) {
++                grub_close();
++                return 0;
++            }
++            if (c == '"')
++                break;
++        }
++
++        while (grub_read(&c, 1) && c != '"') {
++            for (i = 1; i < 15; i++)
++                if (pal[i] == c) {
++                    c = i;
++                    break;
++                }
++
++            mask = 0x80 >> (x & 7);
++            if (c & 1)
++                s1[len + (x >> 3)] |= mask;
++            if (c & 2)
++                s2[len + (x >> 3)] |= mask;
++            if (c & 4)
++                s4[len + (x >> 3)] |= mask;
++            if (c & 8)
++                s8[len + (x >> 3)] |= mask;
++
++            if (++x >= 640) {
++                x = 0;
++
++                if (y < 480)
++                    len += 80;
++                ++y;
++            }
++        }
++    }
++
++    grub_close();
++
++    graphics_set_palette(0, (background >> 16), (background >> 8) & 63, 
++                background & 63);
++    graphics_set_palette(15, (foreground >> 16), (foreground >> 8) & 63, 
++                foreground & 63);
++    graphics_set_palette(0x11, (window_border >> 16), (window_border >> 8) & 
63, 
++                         window_border & 63);
++
++    return 1;
++}
++
++/* Convert a character which is a hex digit to the appropriate integer */
++int hex(int v)
++{
++    if (v >= 'A' && v <= 'F')
++        return (v - 'A' + 10);
++    if (v >= 'a' && v <= 'f')
++        return (v - 'a' + 10);
++    return (v - '0');
++}
++
++void graphics_cursor(int set) {
++    unsigned char *pat, *mem, *ptr, chr[16 << 2];
++    int i, ch, invert, offset;
++
++    if (set && (no_cursor || no_scroll))
++        return;
++
++    offset = cursorY * 80 + fontx;
++    ch = text[fonty * 80 + fontx] & 0xff;
++    invert = (text[fonty * 80 + fontx] & 0xff00) != 0;
++    pat = font8x16 + (ch << 4);
++
++    mem = (unsigned char*)VIDEOMEM + offset;
++
++    if (!set) {
++        for (i = 0; i < 16; i++) {
++            unsigned char mask = pat[i];
++
++            if (!invert) {
++                chr[i     ] = ((unsigned char*)VSHADOW1)[offset];
++                chr[16 + i] = ((unsigned char*)VSHADOW2)[offset];
++                chr[32 + i] = ((unsigned char*)VSHADOW4)[offset];
++                chr[48 + i] = ((unsigned char*)VSHADOW8)[offset];
++
++                if (shade) {
++                    if (ch == DISP_VERT || ch == DISP_LL ||
++                        ch == DISP_UR || ch == DISP_LR) {
++                        unsigned char pmask = ~(pat[i] >> 1);
++
++                        chr[i     ] &= pmask;
++                        chr[16 + i] &= pmask;
++                        chr[32 + i] &= pmask;
++                        chr[48 + i] &= pmask;
++                    }
++                    if (i > 0 && ch != DISP_VERT) {
++                        unsigned char pmask = ~(pat[i - 1] >> 1);
++
++                        chr[i     ] &= pmask;
++                        chr[16 + i] &= pmask;
++                        chr[32 + i] &= pmask;
++                        chr[48 + i] &= pmask;
++                        if (ch == DISP_HORIZ || ch == DISP_UR || ch == 
DISP_LR) {
++                            pmask = ~pat[i - 1];
++
++                            chr[i     ] &= pmask;
++                            chr[16 + i] &= pmask;
++                            chr[32 + i] &= pmask;
++                            chr[48 + i] &= pmask;
++                        }
++                    }
++                }
++                chr[i     ] |= mask;
++                chr[16 + i] |= mask;
++                chr[32 + i] |= mask;
++                chr[48 + i] |= mask;
++
++                offset += 80;
++            }
++            else {
++                chr[i     ] = mask;
++                chr[16 + i] = mask;
++                chr[32 + i] = mask;
++                chr[48 + i] = mask;
++            }
++        }
++    }
++    else {
++        MapMask(15);
++        ptr = mem;
++        for (i = 0; i < 16; i++, ptr += 80) {
++            cursorBuf[i] = pat[i];
++            *ptr = ~pat[i];
++        }
++        return;
++    }
++
++    offset = 0;
++    for (i = 1; i < 16; i <<= 1, offset += 16) {
++        int j;
++
++        MapMask(i);
++        ptr = mem;
++        for (j = 0; j < 16; j++, ptr += 80)
++            *ptr = chr[j + offset];
++    }
++
++    MapMask(15);
++}
++
++#endif /* SUPPORT_GRAPHICS */
+diff -Naur grub-0.97.orig/stage2/graphics.h grub-0.97/stage2/graphics.h
+--- grub-0.97.orig/stage2/graphics.h   1969-12-31 21:00:00.000000000 -0300
++++ grub-0.97/stage2/graphics.h        2005-06-12 20:56:49.000000000 -0300
+@@ -0,0 +1,44 @@
++/* graphics.h - graphics console interface */
++/*
++ *  GRUB  --  GRand Unified Bootloader
++ *  Copyright (C) 2002  Free Software Foundation, Inc.
++ *
++ *  This program is free software; you can redistribute it and/or modify
++ *  it under the terms of the GNU General Public License as published by
++ *  the Free Software Foundation; either version 2 of the License, or
++ *  (at your option) any later version.
++ *
++ *  This program is distributed in the hope that it will be useful,
++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *  GNU General Public License for more details.
++ *
++ *  You should have received a copy of the GNU General Public License
++ *  along with this program; if not, write to the Free Software
++ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef GRAPHICS_H
++#define GRAPHICS_H
++
++/* magic constant */
++#define VIDEOMEM 0xA0000
++
++/* function prototypes */
++char *graphics_get_splash(void);
++
++int read_image(char *s);
++void graphics_cursor(int set);
++
++/* function prototypes for asm functions */
++void * graphics_get_font();
++void graphics_set_palette(int idx, int red, int green, int blue);
++void set_int1c_handler();
++void unset_int1c_handler();
++
++extern short cursorX, cursorY;
++extern char cursorBuf[16];
++extern int shade;
++extern int view_x0, view_y0, view_x1, view_y1;
++
++#endif /* GRAPHICS_H */
+diff -Naur grub-0.97.orig/stage2/Makefile.am grub-0.97/stage2/Makefile.am
+--- grub-0.97.orig/stage2/Makefile.am  2005-02-02 18:37:35.000000000 -0200
++++ grub-0.97/stage2/Makefile.am       2005-06-12 20:56:49.000000000 -0300
+@@ -7,7 +7,7 @@
+         fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \
+       imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \
+       nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \
+-      terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h
++      terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h graphics.h
+ EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS)
+ 
+ # For <stage1.h>.
+@@ -19,7 +19,7 @@
+       disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \
+       fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \
+       fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \
+-      terminfo.c tparm.c
++      terminfo.c tparm.c graphics.c
+ libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
+       -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
+       -DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
+@@ -79,8 +79,14 @@
+ HERCULES_FLAGS =
+ endif
+ 
++if GRAPHICS_SUPPORT
++GRAPHICS_FLAGS = -DSUPPORT_GRAPHICS=1
++else
++GRAPHICS_FLAGS =
++endif
++
+ STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+-      $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS)
++      $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) $(GRAPHICS_FLAGS)
+ 
+ STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
+ STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1
+@@ -90,7 +96,8 @@
+       cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
+       fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
+       fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \
+-      hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c
++      hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c \
++      graphics.c
+ pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
+ pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
+ pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
+diff -Naur grub-0.97.orig/stage2/shared.h grub-0.97/stage2/shared.h
+--- grub-0.97.orig/stage2/shared.h     2004-06-19 13:40:09.000000000 -0300
++++ grub-0.97/stage2/shared.h  2005-06-12 20:56:49.000000000 -0300
+@@ -792,6 +792,11 @@
+ /* Set the cursor position. */
+ void gotoxy (int x, int y);
+ 
++/* Internal pager
++   Returns 1 = if pager was used
++           0 = if pager wasn't used  */
++int do_more (void);
++
+ /* Displays an ASCII character.  IBM displays will translate some
+    characters to special graphical ones (see the DISP_* constants). */
+ void grub_putchar (int c);
+@@ -871,6 +876,7 @@
+ int grub_tolower (int c);
+ int grub_isspace (int c);
+ int grub_strncat (char *s1, const char *s2, int n);
++void grub_memcpy(void *dest, const void *src, int len);
+ void *grub_memmove (void *to, const void *from, int len);
+ void *grub_memset (void *start, int c, int len);
+ int grub_strncat (char *s1, const char *s2, int n);
+diff -Naur grub-0.97.orig/stage2/stage2.c grub-0.97/stage2/stage2.c
+--- grub-0.97.orig/stage2/stage2.c     2005-03-19 14:51:57.000000000 -0300
++++ grub-0.97/stage2/stage2.c  2005-06-13 22:38:08.000000000 -0300
+@@ -20,6 +20,12 @@
+ #include <shared.h>
+ #include <term.h>
+ 
++#ifdef SUPPORT_GRAPHICS
++# include <graphics.h>
++#endif
++
++int col_start, col_end, row_start, box_size;
++
+ grub_jmp_buf restart_env;
+ 
+ #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS)
+@@ -105,13 +111,13 @@
+   if (highlight && current_term->setcolorstate)
+     current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
+ 
+-  gotoxy (2, y);
++  gotoxy (2 + col_start, y);
+   grub_putchar (' ');
+-  for (x = 3; x < 75; x++)
++  for (x = 3 + col_start; x < (col_end - 5); x++)
+     {
+-      if (*entry && x <= 72)
++      if (*entry && x <= (col_end - 8))
+       {
+-        if (x == 72)
++        if (x == (col_end - 8))
+           grub_putchar (DISP_RIGHT);
+         else
+           grub_putchar (*entry++);
+@@ -119,7 +125,7 @@
+       else
+       grub_putchar (' ');
+     }
+-  gotoxy (74, y);
++  gotoxy ((col_end - 6), y);
+ 
+   if (current_term->setcolorstate)
+     current_term->setcolorstate (COLOR_STATE_STANDARD);
+@@ -131,7 +137,7 @@
+ {
+   int i;
+   
+-  gotoxy (77, y + 1);
++  gotoxy ((col_end - 3), y + 1);
+ 
+   if (first)
+     grub_putchar (DISP_UP);
+@@ -151,14 +157,14 @@
+       menu_entries++;
+     }
+ 
+-  gotoxy (77, y + size);
++  gotoxy ((col_end - 3), y + size);
+ 
+   if (*menu_entries)
+     grub_putchar (DISP_DOWN);
+   else
+     grub_putchar (' ');
+ 
+-  gotoxy (74, y + entryno + 1);
++  gotoxy ((col_end - 6), y + entryno + 1);
+ }
+ 
+ static void
+@@ -196,30 +202,30 @@
+   if (current_term->setcolorstate)
+     current_term->setcolorstate (COLOR_STATE_NORMAL);
+   
+-  gotoxy (1, y);
++  gotoxy (1 + col_start, y);
+ 
+   grub_putchar (DISP_UL);
+-  for (i = 0; i < 73; i++)
++  for (i = col_start; i < (col_end - 7); i++)
+     grub_putchar (DISP_HORIZ);
+   grub_putchar (DISP_UR);
+ 
+   i = 1;
+   while (1)
+     {
+-      gotoxy (1, y + i);
++      gotoxy (1 + col_start, y + i);
+ 
+       if (i > size)
+       break;
+       
+       grub_putchar (DISP_VERT);
+-      gotoxy (75, y + i);
++      gotoxy ((col_end - 5), y + i);
+       grub_putchar (DISP_VERT);
+ 
+       i++;
+     }
+ 
+   grub_putchar (DISP_LL);
+-  for (i = 0; i < 73; i++)
++  for (i = col_start; i < (col_end - 7); i++)
+     grub_putchar (DISP_HORIZ);
+   grub_putchar (DISP_LR);
+ 
+@@ -233,6 +239,7 @@
+ {
+   int c, time1, time2 = -1, first_entry = 0;
+   char *cur_entry = 0;
++  struct term_entry *prev_term = NULL;
+ 
+   /*
+    *  Main loop for menu UI.
+@@ -250,6 +257,22 @@
+       }
+     }
+ 
++  col_start = 0;
++  col_end = 80;
++  row_start = 0;
++  box_size = 12;
++  /* if we're using viewport we need to make sure to setup
++     coordinates correctly.  */
++#ifdef SUPPORT_GRAPHICS
++  if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) 
== 0)
++    {
++      col_start = view_x0;
++      col_end = view_x1;
++      row_start = view_y0;
++      box_size = (view_y1 - view_y0) - 13;
++    }
++#endif
++
+   /* If the timeout was expired or wasn't set, force to show the menu
+      interface. */
+   if (grub_timeout < 0)
+@@ -302,36 +325,36 @@
+       if (current_term->flags & TERM_DUMB)
+       print_entries_raw (num_entries, first_entry, menu_entries);
+       else
+-      print_border (3, 12);
++      print_border (3 + row_start, box_size);
+ 
+       grub_printf ("\n\
+-      Use the %c and %c keys to select which entry is highlighted.\n",
++    Use the %c and %c keys to select which entry is highlighted.\n",
+                  DISP_UP, DISP_DOWN);
+       
+       if (! auth && password)
+       {
+         printf ("\
+-      Press enter to boot the selected OS or \'p\' to enter a\n\
+-      password to unlock the next set of features.");
++    Press enter to boot the selected OS or \'p\' to enter a\n\
++    password to unlock the next set of features.");
+       }
+       else
+       {
+         if (config_entries)
+           printf ("\
+-      Press enter to boot the selected OS, \'e\' to edit the\n\
+-      commands before booting, or \'c\' for a command-line.");
++    Press enter to boot the selected OS, \'e\' to edit the\n\
++    commands before booting, or \'c\' for a command-line.");
+         else
+           printf ("\
+-      Press \'b\' to boot, \'e\' to edit the selected command in the\n\
+-      boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\
+-      after (\'O\' for before) the selected line, \'d\' to remove the\n\
+-      selected line, or escape to go back to the main menu.");
++    Press \'b\' to boot, \'e\' to edit the selected command in the\n\
++    boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\
++    after (\'O\' for before) the selected line, \'d\' to remove the\n\
++    selected line, or escape to go back to the main menu.");
+       }
+ 
+       if (current_term->flags & TERM_DUMB)
+       grub_printf ("\n\nThe selected entry is %d ", entryno);
+       else
+-      print_entries (3, 12, first_entry, entryno, menu_entries);
++      print_entries (3 + row_start, box_size, first_entry, entryno, 
menu_entries);
+     }
+ 
+   /* XX using RT clock now, need to initialize value */
+@@ -358,10 +381,10 @@
+                          entryno, grub_timeout);
+         else
+           {
+-            gotoxy (3, 22);
+-            grub_printf ("The highlighted entry will be booted automatically 
in %d seconds.    ",
++            gotoxy (3 + col_start, 10 + box_size + row_start);
++            grub_printf (" The highlighted entry will be booted automatically 
in %d seconds.   ",
+                          grub_timeout);
+-            gotoxy (74, 4 + entryno);
++            gotoxy ((col_end - 6), 4 + entryno + row_start);
+         }
+         
+         grub_timeout--;
+@@ -387,12 +410,12 @@
+             if (current_term->flags & TERM_DUMB)
+               grub_putchar ('\r');
+             else
+-              gotoxy (3, 22);
++              gotoxy (3 + col_start, 10 + box_size + row_start);
+             printf ("                                                         
           ");
+             grub_timeout = -1;
+             fallback_entryno = -1;
+             if (! (current_term->flags & TERM_DUMB))
+-              gotoxy (74, 4 + entryno);
++              gotoxy ((col_end - 6), 4 + entryno + row_start);
+           }
+ 
+         /* We told them above (at least in SUPPORT_SERIAL) to use
+@@ -408,12 +431,12 @@
+               {
+                 if (entryno > 0)
+                   {
+-                    print_entry (4 + entryno, 0,
++                    print_entry (4 + entryno + row_start, 0,
+                                  get_entry (menu_entries,
+                                             first_entry + entryno,
+                                             0));
+                     entryno--;
+-                    print_entry (4 + entryno, 1,
++                    print_entry (4 + entryno + row_start, 1,
+                                  get_entry (menu_entries,
+                                             first_entry + entryno,
+                                             0));
+@@ -421,7 +444,7 @@
+                 else if (first_entry > 0)
+                   {
+                     first_entry--;
+-                    print_entries (3, 12, first_entry, entryno,
++                    print_entries (3 + row_start, box_size, first_entry, 
entryno,
+                                    menu_entries);
+                   }
+               }
+@@ -433,29 +456,29 @@
+               entryno++;
+             else
+               {
+-                if (entryno < 11)
++                if (entryno < (box_size - 1))
+                   {
+-                    print_entry (4 + entryno, 0,
++                    print_entry (4 + entryno + row_start, 0,
+                                  get_entry (menu_entries,
+                                             first_entry + entryno,
+                                             0));
+                     entryno++;
+-                    print_entry (4 + entryno, 1,
++                    print_entry (4 + entryno + row_start, 1,
+                                  get_entry (menu_entries,
+                                             first_entry + entryno,
+                                             0));
+                 }
+-              else if (num_entries > 12 + first_entry)
++              else if (num_entries > box_size + first_entry)
+                 {
+                   first_entry++;
+-                  print_entries (3, 12, first_entry, entryno, menu_entries);
++                  print_entries (3 + row_start, box_size, first_entry, 
entryno, menu_entries);
+                 }
+               }
+           }
+         else if (c == 7)
+           {
+             /* Page Up */
+-            first_entry -= 12;
++            first_entry -= box_size;
+             if (first_entry < 0)
+               {
+                 entryno += first_entry;
+@@ -463,20 +486,20 @@
+                 if (entryno < 0)
+                   entryno = 0;
+               }
+-            print_entries (3, 12, first_entry, entryno, menu_entries);
++            print_entries (3 + row_start, box_size, first_entry, entryno, 
menu_entries);
+           }
+         else if (c == 3)
+           {
+             /* Page Down */
+-            first_entry += 12;
++            first_entry += box_size;
+             if (first_entry + entryno + 1 >= num_entries)
+               {
+-                first_entry = num_entries - 12;
++                first_entry = num_entries - box_size;
+                 if (first_entry < 0)
+                   first_entry = 0;
+                 entryno = num_entries - first_entry - 1;
+               }
+-            print_entries (3, 12, first_entry, entryno, menu_entries);
++            print_entries (3 + row_start, box_size, first_entry, entryno, 
menu_entries);
+           }
+ 
+         if (config_entries)
+@@ -489,7 +512,7 @@
+             if ((c == 'd') || (c == 'o') || (c == 'O'))
+               {
+                 if (! (current_term->flags & TERM_DUMB))
+-                  print_entry (4 + entryno, 0,
++                  print_entry (4 + entryno + row_start, 0,
+                                get_entry (menu_entries,
+                                           first_entry + entryno,
+                                           0));
+@@ -537,7 +560,7 @@
+ 
+                     if (entryno >= num_entries)
+                       entryno--;
+-                    if (first_entry && num_entries < 12 + first_entry)
++                    if (first_entry && num_entries < box_size + first_entry)
+                       first_entry--;
+                   }
+ 
+@@ -549,7 +572,7 @@
+                     grub_printf ("\n");
+                   }
+                 else
+-                  print_entries (3, 12, first_entry, entryno, menu_entries);
++                  print_entries (3 + row_start, box_size, first_entry, 
entryno, menu_entries);
+               }
+ 
+             cur_entry = menu_entries;
+@@ -570,7 +593,7 @@
+                 if (current_term->flags & TERM_DUMB)
+                   grub_printf ("\r                                    ");
+                 else
+-                  gotoxy (1, 21);
++                  gotoxy (1 + col_start, 9 + box_size + row_start);
+ 
+                 /* Wipe out the previously entered password */
+                 grub_memset (entered, 0, sizeof (entered));
+@@ -714,6 +737,15 @@
+   
+   cls ();
+   setcursor (1);
++  /* if our terminal needed initialization, we should shut it down
++   * before booting the kernel, but we want to save what it was so
++   * we can come back if needed */
++  prev_term = current_term;
++  if (current_term->shutdown) 
++    {
++      current_term->shutdown();
++      current_term = term_table; /* assumption: console is first */
++    }
+   
+   while (1)
+     {
+@@ -748,6 +780,13 @@
+       break;
+     }
+ 
++  /* if we get back here, we should go back to what our term was before */
++  current_term = prev_term;
++  if (current_term->startup)
++      /* if our terminal fails to initialize, fall back to console since
++       * it should always work */
++      if (current_term->startup() == 0)
++          current_term = term_table; /* we know that console is first */
+   show_menu = 1;
+   goto restart;
+ }
+@@ -1050,6 +1089,16 @@
+         while (is_preset);
+       }
+ 
++      /* go ahead and make sure the terminal is setup */
++      if (current_term->startup)
++      {
++        /* If initialization fails, go back to default terminal */
++        if (current_term->startup() == 0)
++                {
++                    current_term = term_table;
++                }
++      }
++
+       if (! num_entries)
+       {
+         /* If no acceptable config file, goto command-line, starting
+diff -Naur grub-0.97.orig/stage2/term.h grub-0.97/stage2/term.h
+--- grub-0.97.orig/stage2/term.h       2003-07-09 08:45:53.000000000 -0300
++++ grub-0.97/stage2/term.h    2005-06-13 14:07:40.000000000 -0300
+@@ -60,6 +60,8 @@
+   const char *name;
+   /* The feature flags defined above.  */
+   unsigned long flags;
++  /* Default for maximum number of lines if not specified */
++  unsigned short max_lines;
+   /* Put a character.  */
+   void (*putchar) (int c);
+   /* Check if any input character is available.  */
+@@ -79,6 +81,10 @@
+   void (*setcolor) (int normal_color, int highlight_color);
+   /* Turn on/off the cursor.  */
+   int (*setcursor) (int on);
++  /* function to start a terminal */
++  int (*startup) (void);
++  /* function to use to shutdown a terminal */
++  void (*shutdown) (void);
+ };
+ 
+ /* This lists up available terminals.  */
+@@ -124,4 +130,24 @@
+ int hercules_setcursor (int on);
+ #endif
+ 
++#ifdef SUPPORT_GRAPHICS
++extern int foreground, background, window_border, graphics_inited, 
saved_videomode;
++
++void graphics_set_splash(char *splashfile);
++int set_videomode(int mode);
++int get_videomode(void);
++void graphics_putchar (int c);
++int graphics_getxy(void);
++void graphics_gotoxy(int x, int y);
++void graphics_cls(void);
++void graphics_setcolorstate (color_state state);
++void graphics_setcolor (int normal_color, int highlight_color);
++int graphics_setcursor (int on);
++int graphics_init(void);
++void graphics_end(void);
++
++int hex(int v);
++void graphics_set_palette(int idx, int red, int green, int blue);
++#endif /* SUPPORT_GRAPHICS */
++
+ #endif /* ! GRUB_TERM_HEADER */
diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub.patches/20print_func.diff
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/stubdom/grub.patches/20print_func.diff    Thu Jun 19 12:46:26 2008 +0900
@@ -0,0 +1,80 @@
+2006-01-05  Otavio Salvador  <otavio@xxxxxxxxxx>
+
+       * Rediff.
+
+2005-16-10  Samuel Thibault  <samuel.thibault@xxxxxxxxxxxx>
+
+       * docs/grub.texi: Added print command description.
+       * stage2/builtins.c(print_func): New function.
+       (builtin_print): New variable.
+       (builtin_table): Added builtin_print in table.
+
+Debian Status Following:
+   Added by: Otavio Salvador
+       Date: 2006-01-05
+
+diff -Nur grub-0.97-bkp/docs/grub.texi grub-0.97/docs/grub.texi
+--- grub-0.97-bkp/docs/grub.texi       2006-01-05 10:59:05.564347912 -0200
++++ grub-0.97/docs/grub.texi   2006-01-05 11:18:59.033912960 -0200
+@@ -2685,6 +2685,7 @@
+ * module::                      Load a module
+ * modulenounzip::               Load a module without decompression
+ * pause::                       Wait for a key press
++* print::                       Print a message
+ * quit::                        Exit from the grub shell
+ * reboot::                      Reboot your computer
+ * read::                        Read data from memory
+@@ -3091,6 +3092,16 @@
+ @end deffn
+ 
+ 
++@node print
++@subsection print
++
++@deffn Command print message @dots{}
++Print the @var{message}. Note that placing @key{^G} (ASCII code 7) in the
++message will cause the speaker to emit the standard beep sound, which is
++useful for visually impaired people.
++@end deffn
++
++
+ @node quit
+ @subsection quit
+ 
+diff -Nur grub-0.97-bkp/stage2/builtins.c grub-0.97/stage2/builtins.c
+--- grub-0.97-bkp/stage2/builtins.c    2006-01-05 10:59:05.550350040 -0200
++++ grub-0.97/stage2/builtins.c        2006-01-05 11:19:28.422445224 -0200
+@@ -2323,6 +2323,25 @@
+   "Probe I/O ports used for the drive DRIVE."
+ };
+ 
++/* print */
++static int
++print_func (char *arg, int flags)
++{
++  printf("%s\n", arg);
++
++  return 0;
++}
++
++static struct builtin builtin_print =
++{
++  "print",
++  print_func,
++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_NO_ECHO,
++  "print [MESSAGE ...]",
++  "Print MESSAGE."
++};
++
++
+ 
+ /* kernel */
+ static int
+@@ -4848,6 +4867,7 @@
+   &builtin_parttype,
+   &builtin_password,
+   &builtin_pause,
++  &builtin_print,
+ #ifdef GRUB_UTIL
+   &builtin_quit,
+ #endif /* GRUB_UTIL */
diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub.patches/30savedefault.diff
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/stubdom/grub.patches/30savedefault.diff   Thu Jun 19 12:46:26 2008 +0900
@@ -0,0 +1,186 @@
+Index: grub/stage2/builtins.c
+===================================================================
+--- grub.orig/stage2/builtins.c        2008-06-02 18:06:08.942580000 +0100
++++ grub/stage2/builtins.c     2008-06-06 18:35:07.548390000 +0100
+@@ -86,6 +86,10 @@
+    inside other functions.  */
+ static int configfile_func (char *arg, int flags);
+ 
++static int savedefault_helper (char *arg, int flags);
++
++static int savedefault_shell (char *arg, int flags);
++
+ /* Initialize the data for builtins.  */
+ void
+ init_builtins (void)
+@@ -3512,7 +3516,109 @@
+ static int
+ savedefault_func (char *arg, int flags)
+ {
+-#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
++#if !defined(SUPPORT_DISKLESS)
++  #if !defined(GRUB_UTIL)
++      return savedefault_helper(arg, flags);
++  #else
++      return savedefault_shell(arg, flags);
++  #endif
++#else /* !SUPPORT_DISKLESS */ 
++  errnum = ERR_UNRECOGNIZED;
++  return 1;
++#endif /* !SUPPORT_DISKLESS */
++}
++
++#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL)
++/* savedefault_shell */
++static int
++savedefault_shell(char *arg, int flags)
++ {
++  int once_only = 0;
++  int new_default;
++  int curr_default = -1;
++  int curr_prev_default = -1;
++  int new_prev_default = -1;
++  FILE *fp;
++  size_t bytes = 10;
++  char line[bytes];
++  char *default_file = (char *) DEFAULT_FILE_BUF;
++  char buf[bytes];
++  int i;
++  
++  while (1)
++    {
++      if (grub_memcmp ("--default=", arg, sizeof ("--default=") - 1) == 0)
++        {
++          char *p = arg + sizeof ("--default=") - 1;
++          if (! safe_parse_maxint (&p, &new_default))
++            return 1;
++          arg = skip_to (0, arg);
++        }
++      else if (grub_memcmp ("--once", arg, sizeof ("--once") - 1) == 0)
++        {
++         once_only = 1;
++         arg = skip_to (0, arg);
++      }
++      else
++        break;
++    }
++
++  *default_file = 0;
++  grub_strncat (default_file, config_file, DEFAULT_FILE_BUFLEN);
++  for (i = grub_strlen(default_file); i >= 0; i--)
++    if (default_file[i] == '/')
++    {
++      i++;
++      break;
++    }
++  default_file[i] = 0;
++  grub_strncat (default_file + i, "default", DEFAULT_FILE_BUFLEN - i);
++
++  if(!(fp = fopen(default_file,"r")))
++    {
++      errnum = ERR_READ;
++      goto fail;
++    }
++  
++  fgets(line, bytes, fp);
++  fclose(fp);
++ 
++  sscanf(line, "%d:%d", &curr_prev_default, &curr_default);
++     
++  if(curr_default != -1)
++    new_prev_default = curr_default;
++  else
++    {
++      if(curr_prev_default != -1)
++        new_prev_default = curr_prev_default;
++      else
++        new_prev_default = 0;
++    }
++     
++  if(once_only)
++    sprintf(buf, "%d:%d", new_prev_default, new_default);
++  else
++    sprintf(buf, "%d", new_default);
++
++  if(!(fp = fopen(default_file,"w")))
++    {
++      errnum = ERR_READ;
++      goto fail;
++    }
++     
++  fprintf(fp, buf);   
++     
++fail:
++  fclose(fp);
++  return errnum;
++}
++#endif
++
++/* savedefault_helper */
++static int
++savedefault_helper (char *arg, int flags)
++{
++#if !defined(SUPPORT_DISKLESS)
+   unsigned long tmp_drive = saved_drive;
+   unsigned long tmp_partition = saved_partition;
+   char *default_file = (char *) DEFAULT_FILE_BUF;
+@@ -3588,22 +3694,26 @@
+       
+       disk_read_hook = disk_read_savesect_func;
+       len = grub_read (buf, sizeof (buf));
++      buf[9]='\0';/* Make sure grub_strstr() below terminates */
+       disk_read_hook = 0;
+       grub_close ();
+       
+-      if (len != sizeof (buf))
+-      {
+-        /* This is too small. Do not modify the file manually, please!  */
+-        errnum = ERR_READ;
+-        goto fail;
+-      }
+-
+       if (sector_count > 2)
+       {
+         /* Is this possible?! Too fragmented!  */
+         errnum = ERR_FSYS_CORRUPT;
+         goto fail;
+       }
++
++      char *tmp;
++      if((tmp = grub_strstr(buf, ":")) != NULL)
++      {
++       int f_len = grub_strlen(buf) - grub_strlen(tmp);
++       char *def;
++       buf[f_len] = '\0';
++       def = buf;
++       safe_parse_maxint (&def, &entryno);
++      }
+       
+       /* Set up a string to be written.  */
+       grub_memset (buf, '\n', sizeof (buf));
+Index: grub/stage2/stage2.c
+===================================================================
+--- grub.orig/stage2/stage2.c  2008-06-02 18:06:08.858579000 +0100
++++ grub/stage2/stage2.c       2008-06-06 18:04:03.585354000 +0100
+@@ -49,7 +49,8 @@
+     return 0;
+ #endif /* GRUB_UTIL */
+   
+-  preset_menu_offset = 0;
++  if (preset_menu_offset)
++    return 0;
+   return preset_menu != 0;
+ }
+ 
+@@ -934,7 +935,11 @@
+             len = grub_read (buf, sizeof (buf));
+             if (len > 0)
+               {
++                char *tmp;
+                 buf[sizeof (buf) - 1] = 0;
++                if((tmp = grub_strstr(p, ":")) != NULL)
++                  p = tmp + 1;
++                
+                 safe_parse_maxint (&p, &saved_entryno);
+               }
+ 
diff -r 1201c7657832 -r 0034766b45c2 
stubdom/grub.patches/40ext3_256byte_inode.diff
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/stubdom/grub.patches/40ext3_256byte_inode.diff    Thu Jun 19 12:46:26 
2008 +0900
@@ -0,0 +1,114 @@
+
+Patch from Red Hat. See #463236, #463123.
+
+Index: grub/stage2/fsys_ext2fs.c
+===================================================================
+--- grub.orig/stage2/fsys_ext2fs.c     2008-05-27 18:47:19.045183000 +0100
++++ grub/stage2/fsys_ext2fs.c  2008-05-27 19:09:21.293187000 +0100
+@@ -79,7 +79,52 @@
+     __u32 s_rev_level;                /* Revision level */
+     __u16 s_def_resuid;               /* Default uid for reserved blocks */
+     __u16 s_def_resgid;               /* Default gid for reserved blocks */
+-    __u32 s_reserved[235];    /* Padding to the end of the block */
++    /*
++     * These fields are for EXT2_DYNAMIC_REV superblocks only.
++     *
++     * Note: the difference between the compatible feature set and
++     * the incompatible feature set is that if there is a bit set
++     * in the incompatible feature set that the kernel doesn't
++     * know about, it should refuse to mount the filesystem.
++     *
++     * e2fsck's requirements are more strict; if it doesn't know
++     * about a feature in either the compatible or incompatible
++     * feature set, it must abort and not try to meddle with
++     * things it doesn't understand...
++     */
++    __u32 s_first_ino;                /* First non-reserved inode */
++    __u16 s_inode_size;               /* size of inode structure */
++    __u16 s_block_group_nr;   /* block group # of this superblock */
++    __u32 s_feature_compat;   /* compatible feature set */
++    __u32 s_feature_incompat; /* incompatible feature set */
++    __u32 s_feature_ro_compat;        /* readonly-compatible feature set */
++    __u8  s_uuid[16];         /* 128-bit uuid for volume */
++    char  s_volume_name[16];  /* volume name */
++    char  s_last_mounted[64]; /* directory where last mounted */
++    __u32 s_algorithm_usage_bitmap; /* For compression */
++    /*
++     * Performance hints.  Directory preallocation should only
++     * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on.
++     */
++    __u8  s_prealloc_blocks;  /* Nr of blocks to try to preallocate*/
++    __u8  s_prealloc_dir_blocks;      /* Nr to preallocate for dirs */
++    __u16 s_reserved_gdt_blocks;/* Per group table for online growth */
++    /*
++     * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set.
++     */
++    __u8 s_journal_uuid[16];  /* uuid of journal superblock */
++    __u32 s_journal_inum;     /* inode number of journal file */
++    __u32 s_journal_dev;      /* device number of journal file */
++    __u32 s_last_orphan;      /* start of list of inodes to delete */
++    __u32 s_hash_seed[4];     /* HTREE hash seed */
++    __u8  s_def_hash_version; /* Default hash version to use */
++    __u8  s_jnl_backup_type;  /* Default type of journal backup */
++    __u16 s_reserved_word_pad;
++    __u32 s_default_mount_opts;
++    __u32 s_first_meta_bg;    /* First metablock group */
++    __u32 s_mkfs_time;                /* When the filesystem was created */
++    __u32 s_jnl_blocks[17];   /* Backup of the journal inode */
++    __u32 s_reserved[172];    /* Padding to the end of the block */
+   };
+ 
+ struct ext2_group_desc
+@@ -218,6 +263,9 @@
+ #define EXT2_ADDR_PER_BLOCK(s)          (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
+ #define EXT2_ADDR_PER_BLOCK_BITS(s)           (log2(EXT2_ADDR_PER_BLOCK(s)))
+ 
++#define EXT2_INODE_SIZE(s)            (SUPERBLOCK->s_inode_size)
++#define EXT2_INODES_PER_BLOCK(s)      (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
++
+ /* linux/ext2_fs.h */
+ #define EXT2_BLOCK_SIZE_BITS(s)        ((s)->s_log_block_size + 10)
+ /* kind of from ext2/super.c */
+@@ -242,7 +290,14 @@
+ static __inline__ unsigned long
+ ffz (unsigned long word)
+ {
+-  __asm__ ("bsfl %1,%0"
++  __asm__ ("bsf"
++#ifdef __i386__
++                "l"
++#endif
++#ifdef __x86_64__
++                "q"
++#endif
++                " %1,%0"
+ :        "=r" (word)
+ :        "r" (~word));
+   return word;
+@@ -553,7 +608,7 @@
+       gdp = GROUP_DESC;
+       ino_blk = gdp[desc].bg_inode_table +
+       (((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group))
+-       >> log2 (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)));
++       >> log2 (EXT2_INODES_PER_BLOCK (SUPERBLOCK)));
+ #ifdef E2DEBUG
+       printf ("inode table fsblock=%d\n", ino_blk);
+ #endif /* E2DEBUG */
+@@ -565,13 +620,12 @@
+       /* reset indirect blocks! */
+       mapblock2 = mapblock1 = -1;
+ 
+-      raw_inode = INODE +
+-      ((current_ino - 1)
+-       & (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode) - 1));
++      raw_inode = (struct ext2_inode *)((char *)INODE +
++      ((current_ino - 1) & (EXT2_INODES_PER_BLOCK (SUPERBLOCK) - 1)) *
++      EXT2_INODE_SIZE (SUPERBLOCK));
+ #ifdef E2DEBUG
+       printf ("ipb=%d, sizeof(inode)=%d\n",
+-            (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)),
+-            sizeof (struct ext2_inode));
++            EXT2_INODES_PER_BLOCK (SUPERBLOCK), EXT2_INODE_SIZE (SUPERBLOCK));
+       printf ("inode=%x, raw_inode=%x\n", INODE, raw_inode);
+       printf ("offset into inode table block=%d\n", (int) raw_inode - (int) 
INODE);
+       for (i = (unsigned char *) INODE; i <= (unsigned char *) raw_inode;
diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub.patches/99minios
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/stubdom/grub.patches/99minios     Thu Jun 19 12:46:26 2008 +0900
@@ -0,0 +1,1456 @@
+Index: grub/stage2/builtins.c
+===================================================================
+--- grub.orig/stage2/builtins.c        2008-06-16 15:18:14.649009000 +0100
++++ grub/stage2/builtins.c     2008-06-16 15:18:14.719009000 +0100
+@@ -45,8 +45,10 @@
+ #ifdef GRUB_UTIL
+ # include <device.h>
+ #else /* ! GRUB_UTIL */
++#ifndef __MINIOS
+ # include <apic.h>
+ # include <smp-imps.h>
++#endif
+ #endif /* ! GRUB_UTIL */
+ 
+ #ifdef USE_MD5_PASSWORDS
+@@ -246,11 +248,13 @@
+ boot_func (char *arg, int flags)
+ {
+   struct term_entry *prev_term = current_term;
++#ifndef __MINIOS__
+   /* Clear the int15 handler if we can boot the kernel successfully.
+      This assumes that the boot code never fails only if KERNEL_TYPE is
+      not KERNEL_TYPE_NONE. Is this assumption is bad?  */
+   if (kernel_type != KERNEL_TYPE_NONE)
+     unset_int15_handler ();
++#endif
+ 
+   /* if our terminal needed initialization, we should shut it down
+    * before booting the kernel, but we want to save what it was so
+@@ -261,13 +265,21 @@
+       current_term = term_table; /* assumption: console is first */
+     }
+ 
++#ifndef __MINIOS__
+ #ifdef SUPPORT_NETBOOT
+   /* Shut down the networking.  */
+   cleanup_net ();
+ #endif
++#endif
+   
+   switch (kernel_type)
+     {
++#ifdef __MINIOS__
++    case KERNEL_TYPE_PV:
++      /* Paravirtualized */
++      pv_boot();
++      break;
++#else
+     case KERNEL_TYPE_FREEBSD:
+     case KERNEL_TYPE_NETBSD:
+       /* *BSD */
+@@ -319,6 +331,7 @@
+       multi_boot ((int) entry_addr, (int) &mbi);
+       break;
+ 
++#endif
+     default:
+       errnum = ERR_BOOT_COMMAND;
+       return 1;
+@@ -1123,6 +1136,7 @@
+ };
+ 
+ 
++#ifndef __MINIOS__
+ /* displayapm */
+ static int
+ displayapm_func (char *arg, int flags)
+@@ -1163,8 +1177,10 @@
+   "displayapm",
+   "Display APM BIOS information."
+ };
++#endif
+ 
+ 
++#ifndef __MINIOS__
+ /* displaymem */
+ static int
+ displaymem_func (char *arg, int flags)
+@@ -1218,6 +1234,7 @@
+   "Display what GRUB thinks the system address space map of the"
+   " machine is, including all regions of physical RAM installed."
+ };
++#endif
+ 
+ 
+ /* dump FROM TO */
+@@ -1280,6 +1297,7 @@
+ #endif /* GRUB_UTIL */
+ 
+ 
++#ifndef __MINIOS__
+ static char embed_info[32];
+ /* embed */
+ /* Embed a Stage 1.5 in the first cylinder after MBR or in the
+@@ -1413,6 +1431,7 @@
+   " is a drive, or in the \"bootloader\" area if DEVICE is a FFS partition."
+   " Print the number of sectors which STAGE1_5 occupies if successful."
+ };
++#endif
+ 
+ 
+ /* fallback */
+@@ -1956,6 +1975,7 @@
+ #endif /* SUPPORT_NETBOOT */
+ 
+ 
++#ifndef __MINIOS__
+ /* impsprobe */
+ static int
+ impsprobe_func (char *arg, int flags)
+@@ -1982,6 +2002,7 @@
+   " configuration table and boot the various CPUs which are found into"
+   " a tight loop."
+ };
++#endif
+ 
+ 
+ /* initrd */
+@@ -1992,6 +2013,7 @@
+     {
+     case KERNEL_TYPE_LINUX:
+     case KERNEL_TYPE_BIG_LINUX:
++    case KERNEL_TYPE_PV:
+       if (! load_initrd (arg))
+       return 1;
+       break;
+@@ -2015,6 +2037,7 @@
+ };
+ 
+ 
++#ifndef __MINIOS__
+ /* install */
+ static int
+ install_func (char *arg, int flags)
+@@ -2555,8 +2578,10 @@
+   " for LBA mode. If the option `--stage2' is specified, rewrite the Stage"
+   " 2 via your OS's filesystem instead of the raw device."
+ };
++#endif
+ 
+ 
++#ifndef __MINIOS__
+ /* ioprobe */
+ static int
+ ioprobe_func (char *arg, int flags)
+@@ -2598,6 +2623,7 @@
+   "ioprobe DRIVE",
+   "Probe I/O ports used for the drive DRIVE."
+ };
++#endif
+ 
+ /* print */
+ static int
+@@ -3776,6 +3802,7 @@
+ };
+ 
+ 
++#ifndef __MINIOS__
+ #ifdef SUPPORT_SERIAL
+ /* serial */
+ static int
+@@ -3927,8 +3954,10 @@
+   " default values are COM1, 9600, 8N1."
+ };
+ #endif /* SUPPORT_SERIAL */
++#endif
+ 
+ 
++#ifndef __MINIOS__
+ /* setkey */
+ struct keysym
+ {
+@@ -4174,8 +4203,10 @@
+   " is a digit), and delete. If no argument is specified, reset key"
+   " mappings."
+ };
++#endif
+ 
+ 
++#ifndef __MINIOS__
+ /* setup */
+ static int
+ setup_func (char *arg, int flags)
+@@ -4484,6 +4515,7 @@
+   " partition where GRUB images reside, specify the option `--stage2'"
+   " to tell GRUB the file name under your OS."
+ };
++#endif
+ 
+ 
+ #if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || 
defined(SUPPORT_GRAPHICS)
+@@ -4788,6 +4820,7 @@
+ #endif /* SUPPORT_SERIAL */
+         
+ 
++#ifndef __MINIOS__
+ /* testload */
+ static int
+ testload_func (char *arg, int flags)
+@@ -4874,8 +4907,10 @@
+   " consistent offset error. If this test succeeds, then a good next"
+   " step is to try loading a kernel."
+ };
++#endif
+ 
+ 
++#ifndef __MINIOS__
+ /* testvbe MODE */
+ static int
+ testvbe_func (char *arg, int flags)
+@@ -4979,6 +5014,7 @@
+   "testvbe MODE",
+   "Test the VBE mode MODE. Hit any key to return."
+ };
++#endif
+ 
+ 
+ #ifdef SUPPORT_NETBOOT
+@@ -5075,6 +5111,7 @@
+ };
+ 
+ 
++#ifndef __MINIOS__
+ /* uppermem */
+ static int
+ uppermem_func (char *arg, int flags)
+@@ -5095,8 +5132,10 @@
+   "Force GRUB to assume that only KBYTES kilobytes of upper memory are"
+   " installed.  Any system address range maps are discarded."
+ };
++#endif
+ 
+ 
++#ifndef __MINIOS__
+ /* vbeprobe */
+ static int
+ vbeprobe_func (char *arg, int flags)
+@@ -5203,6 +5242,7 @@
+   "Probe VBE information. If the mode number MODE is specified, show only"
+   " the information about only the mode."
+ };
++#endif
+   
+ 
+ /* The table of builtin commands. Sorted in dictionary order.  */
+@@ -5233,12 +5273,16 @@
+ #ifdef SUPPORT_NETBOOT
+   &builtin_dhcp,
+ #endif /* SUPPORT_NETBOOT */
++#ifndef __MINIOS__
+   &builtin_displayapm,
+   &builtin_displaymem,
++#endif
+ #ifdef GRUB_UTIL
+   &builtin_dump,
+ #endif /* GRUB_UTIL */
++#ifndef __MINIOS__
+   &builtin_embed,
++#endif
+   &builtin_fallback,
+   &builtin_find,
+ #ifdef SUPPORT_GRAPHICS
+@@ -5253,10 +5297,14 @@
+ #ifdef SUPPORT_NETBOOT
+   &builtin_ifconfig,
+ #endif /* SUPPORT_NETBOOT */
++#ifndef __MINIOS__
+   &builtin_impsprobe,
++#endif
+   &builtin_initrd,
++#ifndef __MINIOS__
+   &builtin_install,
+   &builtin_ioprobe,
++#endif
+   &builtin_kernel,
+   &builtin_lock,
+   &builtin_makeactive,
+@@ -5283,11 +5331,13 @@
+   &builtin_root,
+   &builtin_rootnoverify,
+   &builtin_savedefault,
++#ifndef __MINIOS__
+ #ifdef SUPPORT_SERIAL
+   &builtin_serial,
+ #endif /* SUPPORT_SERIAL */
+   &builtin_setkey,
+   &builtin_setup,
++#endif
+ #ifdef SUPPORT_GRAPHICS
+   &builtin_shade,
+   &builtin_splashimage,
+@@ -5298,16 +5348,20 @@
+ #ifdef SUPPORT_SERIAL
+   &builtin_terminfo,
+ #endif /* SUPPORT_SERIAL */
++#ifndef __MINIOS__
+   &builtin_testload,
+   &builtin_testvbe,
++#endif
+ #ifdef SUPPORT_NETBOOT
+   &builtin_tftpserver,
+ #endif /* SUPPORT_NETBOOT */
+   &builtin_timeout,
+   &builtin_title,
+   &builtin_unhide,
++#ifndef __MINIOS__
+   &builtin_uppermem,
+   &builtin_vbeprobe,
++#endif
+ #ifdef SUPPORT_GRAPHICS
+   &builtin_viewport,
+ #endif
+Index: grub/stage2/char_io.c
+===================================================================
+--- grub.orig/stage2/char_io.c 2008-06-16 15:18:14.516009000 +0100
++++ grub/stage2/char_io.c      2008-06-16 15:18:14.726009000 +0100
+@@ -20,6 +20,7 @@
+ 
+ #include <shared.h>
+ #include <term.h>
++#include <stdarg.h>
+ 
+ #ifdef SUPPORT_HERCULES
+ # include <hercules.h>
+@@ -36,6 +37,7 @@
+ #ifndef STAGE1_5
+ struct term_entry term_table[] =
+   {
++#ifdef SUPPORT_CONSOLE
+     {
+       "console",
+       0,
+@@ -52,6 +54,7 @@
+       0, 
+       0
+     },
++#endif
+ #ifdef SUPPORT_SERIAL
+     {
+       "serial",
+@@ -131,9 +134,9 @@
+ }
+ 
+ char *
+-convert_to_ascii (char *buf, int c,...)
++convert_to_ascii (char *buf, int c, int _num)
+ {
+-  unsigned long num = *((&c) + 1), mult = 10;
++  unsigned long num = _num, mult = 10;
+   char *ptr = buf;
+ 
+ #ifndef STAGE1_5
+@@ -182,11 +185,11 @@
+ void
+ grub_printf (const char *format,...)
+ {
+-  int *dataptr = (int *) &format;
++  va_list ap;
+   char c, str[16];
+-  
+-  dataptr++;
+ 
++  va_start(ap, format);
++  
+   while ((c = *(format++)) != 0)
+     {
+       if (c != '%')
+@@ -200,21 +203,32 @@
+         case 'X':
+ #endif
+         case 'u':
+-          *convert_to_ascii (str, c, *((unsigned long *) dataptr++)) = 0;
++        {
++          unsigned i = va_arg(ap, unsigned);
++          *convert_to_ascii (str, c, i) = 0;
+           grub_putstr (str);
+           break;
++          }
+ 
+ #ifndef STAGE1_5
+         case 'c':
+-          grub_putchar ((*(dataptr++)) & 0xff);
++        {
++          int c = va_arg(ap, int);
++          grub_putchar (c & 0xff);
+           break;
++        }
+ 
+         case 's':
+-          grub_putstr ((char *) *(dataptr++));
++        {
++          char *s = va_arg(ap, char*);
++          grub_putstr (s);
+           break;
++        }
+ #endif
+         }
+     }
++
++  va_end(ap);
+ }
+ 
+ #ifndef STAGE1_5
+@@ -223,11 +237,11 @@
+ {
+   /* XXX hohmuth
+      ugly hack -- should unify with printf() */
+-  int *dataptr = (int *) &format;
++  va_list ap;
+   char c, *ptr, str[16];
+   char *bp = buffer;
+ 
+-  dataptr++;
++  va_start(ap, format);
+ 
+   while ((c = *format++) != 0)
+     {
+@@ -237,20 +251,27 @@
+       switch (c = *(format++))
+         {
+         case 'd': case 'u': case 'x':
+-          *convert_to_ascii (str, c, *((unsigned long *) dataptr++)) = 0;
++        {
++          unsigned i = va_arg(ap, unsigned);
++          *convert_to_ascii (str, c, i) = 0;
+ 
+           ptr = str;
+ 
+           while (*ptr)
+             *bp++ = *(ptr++); /* putchar(*(ptr++)); */
+           break;
++        }
+ 
+-        case 'c': *bp++ = (*(dataptr++))&0xff;
++        case 'c':
++        {
++          int c = va_arg(ap, int);
++          *bp++ = c&0xff;
+           /* putchar((*(dataptr++))&0xff); */
+           break;
++        }
+ 
+         case 's':
+-          ptr = (char *) (*(dataptr++));
++          ptr = va_arg(ap, char *);
+ 
+           while ((c = *ptr++) != 0)
+             *bp++ = c; /* putchar(c); */
+@@ -258,6 +279,8 @@
+         }
+     }
+ 
++  va_end(ap);
++
+   *bp = 0;
+   return bp - buffer;
+ }
+@@ -1263,12 +1286,14 @@
+     return ! errnum;
+ #endif /* GRUB_UTIL */
+ 
++#ifndef __MINIOS__
+   if ((addr < RAW_ADDR (0x1000))
+       || (addr < RAW_ADDR (0x100000)
+         && RAW_ADDR (mbi.mem_lower * 1024) < (addr + len))
+       || (addr >= RAW_ADDR (0x100000)
+         && RAW_ADDR (mbi.mem_upper * 1024) < ((addr - 0x100000) + len)))
+     errnum = ERR_WONT_FIT;
++#endif
+ 
+   return ! errnum;
+ }
+@@ -1342,7 +1367,7 @@
+ }
+ #endif /* ! STAGE1_5 */
+ 
+-#ifndef GRUB_UTIL
++#if !defined(GRUB_UTIL) && !defined(__MINIOS__)
+ # undef memcpy
+ /* GCC emits references to memcpy() for struct copies etc.  */
+ void *memcpy (void *dest, const void *src, int n)  __attribute__ ((alias 
("grub_memmove")));
+Index: grub/stage2/disk_io.c
+===================================================================
+--- grub.orig/stage2/disk_io.c 2008-06-16 15:18:03.327932000 +0100
++++ grub/stage2/disk_io.c      2008-06-16 15:18:14.733009000 +0100
+@@ -130,7 +130,14 @@
+ static inline unsigned long
+ log2 (unsigned long word)
+ {
+-  asm volatile ("bsfl %1,%0"
++  asm volatile ("bsf"
++#ifdef __i386__
++                "l"
++#endif
++#ifdef __x86_64__
++                "q"
++#endif  
++                " %1,%0"
+               : "=r" (word)
+               : "r" (word));
+   return word;
+Index: grub/stage2/fsys_fat.c
+===================================================================
+--- grub.orig/stage2/fsys_fat.c        2008-06-16 15:18:03.337934000 +0100
++++ grub/stage2/fsys_fat.c     2008-06-16 15:18:14.737009000 +0100
+@@ -57,7 +57,14 @@
+ static __inline__ unsigned long
+ log2 (unsigned long word)
+ {
+-  __asm__ ("bsfl %1,%0"
++  __asm__ ("bsf"
++#ifdef __i386__
++                "l"
++#endif
++#ifdef __x86_64__
++                "q"
++#endif
++                " %1,%0"
+          : "=r" (word)
+          : "r" (word));
+   return word;
+Index: grub/stage2/pc_slice.h
+===================================================================
+--- grub.orig/stage2/pc_slice.h        2008-06-16 15:18:03.347932000 +0100
++++ grub/stage2/pc_slice.h     2008-06-16 15:18:14.746009000 +0100
+@@ -38,50 +38,50 @@
+  */
+ 
+ #define PC_MBR_CHECK_SIG(mbr_ptr) \
+-  ( *( (unsigned short *) (((int) mbr_ptr) + PC_MBR_SIG_OFFSET) ) \
++  ( *( (unsigned short *) (((long) mbr_ptr) + PC_MBR_SIG_OFFSET) ) \
+    == PC_MBR_SIGNATURE )
+ 
+ #define PC_MBR_SIG(mbr_ptr) \
+-  ( *( (unsigned short *) (((int) mbr_ptr) + PC_MBR_SIG_OFFSET) ) )
++  ( *( (unsigned short *) (((long) mbr_ptr) + PC_MBR_SIG_OFFSET) ) )
+ 
+ #define PC_SLICE_FLAG(mbr_ptr, part) \
+-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET \
++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET \
+                         + (part << 4)) ) )
+ 
+ #define PC_SLICE_HEAD(mbr_ptr, part) \
+-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 1 \
++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 1 \
+                         + (part << 4)) ) )
+ 
+ #define PC_SLICE_SEC(mbr_ptr, part) \
+-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 2 \
++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 2 \
+                         + (part << 4)) ) )
+ 
+ #define PC_SLICE_CYL(mbr_ptr, part) \
+-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 3 \
++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 3 \
+                         + (part << 4)) ) )
+ 
+ #define PC_SLICE_TYPE(mbr_ptr, part) \
+-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 4 \
++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 4 \
+                         + (part << 4)) ) )
+ 
+ #define PC_SLICE_EHEAD(mbr_ptr, part) \
+-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 5 \
++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 5 \
+                         + (part << 4)) ) )
+ 
+ #define PC_SLICE_ESEC(mbr_ptr, part) \
+-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 6 \
++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 6 \
+                         + (part << 4)) ) )
+ 
+ #define PC_SLICE_ECYL(mbr_ptr, part) \
+-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 7 \
++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 7 \
+                         + (part << 4)) ) )
+ 
+ #define PC_SLICE_START(mbr_ptr, part) \
+-  ( *( (unsigned long *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 8 \
++  ( *( (unsigned long *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 8 \
+                         + (part << 4)) ) )
+ 
+ #define PC_SLICE_LENGTH(mbr_ptr, part) \
+-  ( *( (unsigned long *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 12 \
++  ( *( (unsigned long *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 12 \
+                         + (part << 4)) ) )
+ 
+ 
+Index: grub/stage2/shared.h
+===================================================================
+--- grub.orig/stage2/shared.h  2008-06-16 15:18:14.537009000 +0100
++++ grub/stage2/shared.h       2008-06-17 14:25:08.443906000 +0100
+@@ -39,6 +39,10 @@
+ extern char *grub_scratch_mem;
+ # define RAW_ADDR(x) ((x) + (int) grub_scratch_mem)
+ # define RAW_SEG(x) (RAW_ADDR ((x) << 4) >> 4)
++#elif defined(__MINIOS__)
++extern char grub_scratch_mem[];
++# define RAW_ADDR(x) ((x) + (int) grub_scratch_mem)
++# define RAW_SEG(x) (RAW_ADDR ((x) << 4) >> 4)
+ #else
+ # define RAW_ADDR(x) (x)
+ # define RAW_SEG(x) (x)
+@@ -707,7 +711,9 @@
+ 
+ /* Halt the system, using APM if possible. If NO_APM is true, don't use
+    APM even if it is available.  */
++#ifndef __MINIOS__
+ void grub_halt (int no_apm) __attribute__ ((noreturn));
++#endif
+ 
+ /* Copy MAP to the drive map and set up int13_handler.  */
+ void set_int13_handler (unsigned short *map);
+@@ -857,7 +863,8 @@
+   KERNEL_TYPE_BIG_LINUX,      /* Big Linux.  */
+   KERNEL_TYPE_FREEBSD,                /* FreeBSD.  */
+   KERNEL_TYPE_NETBSD,         /* NetBSD.  */
+-  KERNEL_TYPE_CHAINLOADER     /* Chainloader.  */
++  KERNEL_TYPE_CHAINLOADER,    /* Chainloader.  */
++  KERNEL_TYPE_PV              /* Paravirtualized.  */
+ }
+ kernel_t;
+ 
+@@ -890,7 +897,7 @@
+ int grub_strlen (const char *str);
+ char *grub_strcpy (char *dest, const char *src);
+ 
+-#ifndef GRUB_UTIL
++#if !defined(GRUB_UTIL) && !defined(__MINIOS__)
+ typedef unsigned long grub_jmp_buf[6];
+ #else
+ /* In the grub shell, use the libc jmp_buf instead.  */
+@@ -898,7 +905,7 @@
+ # define grub_jmp_buf jmp_buf
+ #endif
+ 
+-#ifdef GRUB_UTIL
++#if defined(GRUB_UTIL) || defined(__MINIOS__)
+ # define grub_setjmp  setjmp
+ # define grub_longjmp longjmp
+ #else /* ! GRUB_UTIL */
+@@ -914,7 +921,7 @@
+ /* misc */
+ void init_page (void);
+ void print_error (void);
+-char *convert_to_ascii (char *buf, int c, ...);
++char *convert_to_ascii (char *buf, int c, int num);
+ int get_cmdline (char *prompt, char *cmdline, int maxlen,
+                int echo_char, int history);
+ int substring (const char *s1, const char *s2);
+Index: grub/netboot/etherboot.h
+===================================================================
+--- grub.orig/netboot/etherboot.h      2008-06-16 15:18:03.446934000 +0100
++++ grub/netboot/etherboot.h   2008-06-16 15:18:14.760009000 +0100
+@@ -246,7 +246,7 @@
+ 
+ typedef struct
+ {
+-  unsigned long       s_addr;
++  unsigned int        s_addr;
+ }
+ in_addr;
+ 
+@@ -302,7 +302,7 @@
+   char bp_htype;
+   char bp_hlen;
+   char bp_hops;
+-  unsigned long bp_xid;
++  unsigned int bp_xid;
+   unsigned short bp_secs;
+   unsigned short unused;
+   in_addr bp_ciaddr;
+@@ -411,25 +411,25 @@
+     
+     struct
+     {
+-      long id;
+-      long type;
+-      long rpcvers;
+-      long prog;
+-      long vers;
+-      long proc;
+-      long data[1];
++      int id;
++      int type;
++      int rpcvers;
++      int prog;
++      int vers;
++      int proc;
++      int data[1];
+     }
+     call;
+     
+     struct
+     {
+-      long id;
+-      long type;
+-      long rstatus;
+-      long verifier;
+-      long v2;
+-      long astatus;
+-      long data[1];
++      int id;
++      int type;
++      int rstatus;
++      int verifier;
++      int v2;
++      int astatus;
++      int data[1];
+     }
+     reply;
+   }
+@@ -517,7 +517,9 @@
+ 
+ /* misc.c */
+ extern void twiddle (void);
++#ifndef __MINIOS__
+ extern void sleep (int secs);
++#endif
+ extern int getdec (char **s);
+ extern void etherboot_printf (const char *, ...);
+ extern int etherboot_sprintf (char *, const char *, ...);
+Index: grub/stage2/common.c
+===================================================================
+--- grub.orig/stage2/common.c  2008-06-16 15:18:03.366934000 +0100
++++ grub/stage2/common.c       2008-06-16 15:18:14.764009000 +0100
+@@ -137,6 +137,7 @@
+ }
+ #endif /* ! STAGE1_5 */
+ 
++#ifndef __MINIOS__
+ /* This queries for BIOS information.  */
+ void
+ init_bios_info (void)
+@@ -335,3 +336,4 @@
+   /* Start main routine here.  */
+   cmain ();
+ }
++#endif
+Index: grub/stage2/serial.c
+===================================================================
+--- grub.orig/stage2/serial.c  2008-06-16 15:18:03.376934000 +0100
++++ grub/stage2/serial.c       2008-06-16 15:18:14.769009000 +0100
+@@ -37,7 +37,7 @@
+ 
+ /* Hardware-dependent definitions.  */
+ 
+-#ifndef GRUB_UTIL
++#if !defined(GRUB_UTIL) && !defined(__MINIOS__)
+ /* The structure for speed vs. divisor.  */
+ struct divisor
+ {
+@@ -222,6 +222,8 @@
+       {('3' | ('~' << 8)), 4},
+       {('5' | ('~' << 8)), 7},
+       {('6' | ('~' << 8)), 3},
++      {('7' | ('~' << 8)), 1},
++      {('8' | ('~' << 8)), 5},
+     };
+   
+   /* The buffer must start with ``ESC [''.  */
+Index: grub/stage2/tparm.c
+===================================================================
+--- grub.orig/stage2/tparm.c   2008-06-16 15:18:03.390933000 +0100
++++ grub/stage2/tparm.c        2008-06-16 15:18:14.774010000 +0100
+@@ -48,6 +48,7 @@
+ #include "shared.h"
+ 
+ #include "tparm.h"
++#include <stdarg.h>
+ 
+ /*
+  * Common/troublesome character definitions
+@@ -320,7 +321,7 @@
+ #define isLOWER(c) ((c) >= 'a' && (c) <= 'z')
+ 
+ static inline char *
+-tparam_internal(const char *string, int *dataptr)
++tparam_internal(const char *string, va_list ap)
+ {
+ #define NUM_VARS 26
+     char *p_is_s[9];
+@@ -461,9 +462,9 @@
+        * a char* and an int may not be the same size on the stack.
+        */
+       if (p_is_s[i] != 0) {
+-        p_is_s[i] = (char *)(*(dataptr++));
++        p_is_s[i] = va_arg(ap, char *);
+       } else {
+-        param[i] = (int)(*(dataptr++));
++        param[i] = va_arg(ap, int);
+       }
+     }
+ 
+@@ -716,11 +717,13 @@
+ grub_tparm(const char *string,...)
+ {
+     char *result;
+-    int *dataptr = (int *) &string;
++    va_list ap;
+ 
+-    dataptr++;
++    va_start(ap, string);
+ 
+-    result = tparam_internal(string, dataptr);
++    result = tparam_internal(string, ap);
++
++    va_end(ap);
+ 
+     return result;
+ }
+Index: grub/stage2/fsys_iso9660.c
+===================================================================
+--- grub.orig/stage2/fsys_iso9660.c    2008-06-16 15:18:03.400933000 +0100
++++ grub/stage2/fsys_iso9660.c 2008-06-16 15:18:14.779009000 +0100
+@@ -59,7 +59,14 @@
+ static inline unsigned long
+ log2 (unsigned long word)
+ {
+-  asm volatile ("bsfl %1,%0"
++  asm volatile ("bsf"
++#ifdef __i386__
++                "l"
++#endif
++#ifdef __x86_64__
++                "q"
++#endif
++                " %1,%0"
+               :          "=r" (word)
+               :          "r" (word));
+   return word;
+Index: grub/stage2/fsys_reiserfs.c
+===================================================================
+--- grub.orig/stage2/fsys_reiserfs.c   2008-06-16 15:18:03.410933000 +0100
++++ grub/stage2/fsys_reiserfs.c        2008-06-16 15:18:14.786009000 +0100
+@@ -369,7 +369,14 @@
+ static __inline__ unsigned long
+ log2 (unsigned long word)
+ {
+-  __asm__ ("bsfl %1,%0"
++  __asm__ ("bsf"
++#ifdef __i386__
++                "l"
++#endif
++#ifdef __x86_64__
++                "q"
++#endif
++                " %1,%0"
+          : "=r" (word)
+          : "r" (word));
+   return word;
+Index: grub/netboot/misc.c
+===================================================================
+--- grub.orig/netboot/misc.c   2008-06-16 15:18:03.456934000 +0100
++++ grub/netboot/misc.c        2008-06-16 15:18:14.790009000 +0100
+@@ -21,7 +21,9 @@
+ 
+ #define GRUB  1
+ #include <etherboot.h>
++#include <stdarg.h>
+ 
++#ifndef __MINIOS__
+ void
+ sleep (int secs)
+ {
+@@ -30,6 +32,7 @@
+   while (currticks () < tmo)
+     ;
+ }
++#endif
+ 
+ void
+ twiddle (void)
+@@ -71,7 +74,7 @@
+       Note: width specification not supported
+ **************************************************************************/
+ static int
+-etherboot_vsprintf (char *buf, const char *fmt, const int *dp)
++etherboot_vsprintf (char *buf, const char *fmt, va_list ap)
+ {
+   char *p, *s;
+   
+@@ -86,7 +89,7 @@
+       
+       if (*++fmt == 's')
+       {
+-        for (p = (char *) *dp++; *p != '\0'; p++)
++        for (p = va_arg(ap, char *); *p != '\0'; p++)
+           buf ? *s++ = *p : grub_putchar (*p);
+       }
+       else
+@@ -121,11 +124,9 @@
+         if ((*fmt | 0x20) == 'x')
+           {
+             /* With x86 gcc, sizeof(long) == sizeof(int) */
+-            const long *lp = (const long *) dp;
+-            long h = *lp++;
++            long h = va_arg(ap, int);
+             int ncase = (*fmt & 0x20);
+             
+-            dp = (const int *) lp;
+             if (alt)
+               {
+                 *q++ = '0';
+@@ -136,7 +137,7 @@
+           }
+         else if (*fmt == 'd')
+           {
+-            int i = *dp++;
++            int i = va_arg(ap, int);
+             char *r;
+             
+             if (i < 0)
+@@ -171,10 +172,8 @@
+               unsigned char   c[4];
+             }
+             u;
+-            const long *lp = (const long *) dp;
+             
+-            u.l = *lp++;
+-            dp = (const int *) lp;
++            u.l = va_arg(ap, int);
+             
+             for (r = &u.c[0]; r < &u.c[4]; ++r)
+               q += etherboot_sprintf (q, "%d.", *r);
+@@ -184,7 +183,7 @@
+         else if (*fmt == '!')
+           {
+             char *r;
+-            p = (char *) *dp++;
++            p = va_arg(ap, char *);
+             
+             for (r = p + ETH_ALEN; p < r; ++p)
+               q += etherboot_sprintf (q, "%hhX:", *p);
+@@ -192,7 +191,7 @@
+             --q;
+           }
+         else if (*fmt == 'c')
+-          *q++ = *dp++;
++          *q++ = va_arg(ap, int);
+         else
+           *q++ = *fmt;
+         
+@@ -211,13 +210,21 @@
+ int
+ etherboot_sprintf (char *buf, const char *fmt, ...)
+ {
+-  return etherboot_vsprintf (buf, fmt, ((const int *) &fmt) + 1);
++  va_list ap;
++  int ret;
++  va_start(ap, fmt);
++  ret = etherboot_vsprintf (buf, fmt, ap);
++  va_end(ap);
++  return ret;
+ }
+ 
+ void
+ etherboot_printf (const char *fmt, ...)
+ {
+-  (void) etherboot_vsprintf (0, fmt, ((const int *) &fmt) + 1);
++  va_list ap;
++  va_start(ap, fmt);
++  etherboot_vsprintf (0, fmt, ap);
++  va_end(ap);
+ }
+ 
+ int
+Index: grub/netboot/main.c
+===================================================================
+--- grub.orig/netboot/main.c   2008-06-16 15:18:03.470932000 +0100
++++ grub/netboot/main.c        2008-06-16 15:18:14.797009000 +0100
+@@ -55,7 +55,7 @@
+ static int vendorext_isvalid;
+ static unsigned long netmask;
+ static struct bootpd_t bootp_data;
+-static unsigned long xid;
++static unsigned int xid;
+ 
+ #define       BOOTP_DATA_ADDR (&bootp_data)
+ 
+@@ -778,7 +778,7 @@
+ 
+             arpreply = (struct arprequest *) &nic.packet[ETH_HLEN];
+             
+-            if (arpreply->opcode == htons (ARP_REPLY)
++            if (arpreply->opcode == htons (ARP_REPLY) && ptr
+                 && ! grub_memcmp (arpreply->sipaddr, ptr, sizeof (in_addr))
+                 && type == AWAIT_ARP)
+               {
+@@ -827,7 +827,7 @@
+           {
+             arpreply = (struct arprequest *) &nic.packet[ETH_HLEN];
+             
+-            if (arpreply->opcode == htons (RARP_REPLY)
++            if (arpreply->opcode == htons (RARP_REPLY) && ptr
+                 && ! grub_memcmp (arpreply->thwaddr, ptr, ETH_ALEN))
+               {
+                 grub_memmove ((char *) arptable[ARP_SERVER].node,
+@@ -1135,7 +1135,7 @@
+ long
+ rfc2131_sleep_interval (int base, int exp)
+ {
+-  static long seed = 0;
++  static unsigned seed = 0;
+   long q;
+   unsigned long tmo;
+   
+Index: grub/stage2/graphics.c
+===================================================================
+--- grub.orig/stage2/graphics.c        2008-06-16 15:18:14.524009000 +0100
++++ grub/stage2/graphics.c     2008-06-17 14:29:05.204328000 +0100
+@@ -30,7 +30,29 @@
+ #include <shared.h>
+ #include <graphics.h>
+ 
++#ifdef __MINIOS__
++#include <stdint.h>
++typedef uint8_t Bit8u;
++#include <vgafonts.h>
++#include <fbfront.h>
++#include <malloc.h>
++#define set_int1c_handler() (void)0
++#define unset_int1c_handler() (void)0
++static uint32_t *VIDEOMEM;
++static struct fbfront_dev *fb_dev;
++static uint32_t palette[17];
++short cursorX, cursorY;
++/* TODO: blink */
++uint32_t cursorBuf32[16*8];
++#define WIDTH 640
++#define HEIGHT 480
++#define DEPTH 32
++#define RAMSIZE (WIDTH * HEIGHT * (DEPTH / 8))
++#else
++#define fbfront_update(dev, x, y, w, h) (void)0
+ int saved_videomode;
++#endif
++
+ unsigned char *font8x16;
+ 
+ int graphics_inited = 0;
+@@ -38,11 +60,15 @@
+ 
+ int shade = 1, no_cursor = 0;
+ 
++#ifdef __MINIOS__
++uint32_t VSHADOW[RAMSIZE];
++#else
+ #define VSHADOW VSHADOW1
+ unsigned char VSHADOW1[38400];
+ unsigned char VSHADOW2[38400];
+ unsigned char VSHADOW4[38400];
+ unsigned char VSHADOW8[38400];
++#endif
+ 
+ /* define the default viewable area */
+ int view_x0 = 0;
+@@ -129,6 +155,8 @@
+     count_lines = k;
+ 
+     no_scroll = 0;
++
++    fbfront_update(fb_dev, view_x0 * 8, view_y0 * 16, (view_x1 - view_x0) * 
8, (view_y1 - view_y0) * 16);
+ }
+ 
+ /* Set the splash image */
+@@ -154,17 +182,29 @@
+ int graphics_init()
+ {
+     if (!graphics_inited) {
++#ifdef __MINIOS__
++      VIDEOMEM = memalign(PAGE_SIZE, RAMSIZE);
++      if (!(fb_dev = fb_open(VIDEOMEM, WIDTH, HEIGHT, DEPTH))) {
++          free(VIDEOMEM);
++          return 0;
++      }
++#else
+         saved_videomode = set_videomode(0x12);
+         if (get_videomode() != 0x12) {
+             set_videomode(saved_videomode);
+             return 0;
+         }
++#endif
+         graphics_inited = 1;
+     }
+     else
+         return 1;
+ 
++#ifdef __MINIOS__
++    font8x16 = vgafont16;
++#else
+     font8x16 = (unsigned char*)graphics_get_font();
++#endif
+ 
+     /* make sure that the highlight color is set correctly */
+     graphics_highlight_color = ((graphics_normal_color >> 4) | 
+@@ -176,7 +216,11 @@
+         grub_printf("Failed to read splash image (%s)\n", splashimage);
+         grub_printf("Press any key to continue...");
+         getkey();
++#ifdef __MINIOS__
++      fb_close();
++#else
+         set_videomode(saved_videomode);
++#endif
+         graphics_inited = 0;
+         return 0;
+     }
+@@ -190,8 +234,13 @@
+ void graphics_end(void)
+ {
+     if (graphics_inited) {
++#ifdef __MINIOS__
++      fb_close();
++      free(VIDEOMEM);
++#else
+         unset_int1c_handler();
+         set_videomode(saved_videomode);
++#endif
+         graphics_inited = 0;
+         no_cursor = 0;
+     }
+@@ -204,15 +253,19 @@
+     graphics_cursor(0);
+ 
+     if (ch == '\n') {
++      fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
+         if (fonty + 1 < view_y1)
+             graphics_setxy(fontx, fonty + 1);
+         else
+             graphics_scroll();
+         graphics_cursor(1);
++      fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
+         return;
+     } else if (ch == '\r') {
++      fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
+         graphics_setxy(view_x0, fonty);
+         graphics_cursor(1);
++      fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
+         return;
+     }
+ 
+@@ -224,6 +277,7 @@
+         text[fonty * 80 + fontx] |= 0x100;
+ 
+     graphics_cursor(0);
++    fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
+ 
+     if ((fontx + 1) >= view_x1) {
+         graphics_setxy(view_x0, fonty);
+@@ -232,13 +286,16 @@
+         else
+             graphics_scroll();
+         graphics_cursor(1);
++      fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
+         do_more ();
+         graphics_cursor(0);
++      fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
+     } else {
+         graphics_setxy(fontx + 1, fonty);
+     }
+ 
+     graphics_cursor(1);
++    fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
+ }
+ 
+ /* get the current location of the cursor */
+@@ -248,10 +305,12 @@
+ 
+ void graphics_gotoxy(int x, int y) {
+     graphics_cursor(0);
++    fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
+ 
+     graphics_setxy(x, y);
+ 
+     graphics_cursor(1);
++    fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
+ }
+ 
+ void graphics_cls(void) {
+@@ -262,15 +321,21 @@
+     graphics_gotoxy(view_x0, view_y0);
+ 
+     mem = (unsigned char*)VIDEOMEM;
++#ifndef __MINIOS__
+     s1 = (unsigned char*)VSHADOW1;
+     s2 = (unsigned char*)VSHADOW2;
+     s4 = (unsigned char*)VSHADOW4;
+     s8 = (unsigned char*)VSHADOW8;
++#endif
+ 
+     for (i = 0; i < 80 * 30; i++)
+         text[i] = ' ';
+     graphics_cursor(1);
+ 
++#ifdef __MINIOS__
++    memcpy(mem, VSHADOW, RAMSIZE);
++    fbfront_update(fb_dev, 0, 0, 640, 480);
++#else
+     BitMask(0xff);
+ 
+     /* plane 1 */
+@@ -290,6 +355,7 @@
+     grub_memcpy(mem, s8, 38400);
+ 
+     MapMask(15);
++#endif
+ 
+     if (no_cursor) {
+         no_cursor = 0;
+@@ -337,6 +403,11 @@
+     return 0;
+ }
+ 
++void graphics_set_palette(int idx, int red, int green, int blue)
++{
++    palette[idx] = (red << (16 + 2)) | (green << (8 + 2)) | (blue << 2);
++}
++
+ /* Read in the splashscreen image and set the palette up appropriately.
+  * Format of splashscreen is an xpm (can be gzipped) with 16 colors and
+  * 640x480. */
+@@ -413,18 +484,19 @@
+         }
+ 
+         if (len == 6 && idx < 15) {
+-            int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2;
+-            int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2;
+-            int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2;
++            int r = ((hex(buf[0]) << 4) | hex(buf[1]));
++            int g = ((hex(buf[2]) << 4) | hex(buf[3]));
++            int b = ((hex(buf[4]) << 4) | hex(buf[5]));
+ 
+             pal[idx] = base;
+-            graphics_set_palette(idx, r, g, b);
++            graphics_set_palette(idx, r / 4, g / 4, b / 4);
+             ++idx;
+         }
+     }
+ 
+     x = y = len = 0;
+ 
++#ifndef __MINIOS__
+     s1 = (unsigned char*)VSHADOW1;
+     s2 = (unsigned char*)VSHADOW2;
+     s4 = (unsigned char*)VSHADOW4;
+@@ -432,6 +504,7 @@
+ 
+     for (i = 0; i < 38400; i++)
+         s1[i] = s2[i] = s4[i] = s8[i] = 0;
++#endif
+ 
+     /* parse xpm data */
+     while (y < height) {
+@@ -451,6 +524,9 @@
+                     break;
+                 }
+ 
++#ifdef __MINIOS__
++          VSHADOW[x + y * 640] = palette[i];
++#else
+             mask = 0x80 >> (x & 7);
+             if (c & 1)
+                 s1[len + (x >> 3)] |= mask;
+@@ -460,6 +536,7 @@
+                 s4[len + (x >> 3)] |= mask;
+             if (c & 8)
+                 s8[len + (x >> 3)] |= mask;
++#endif
+ 
+             if (++x >= 640) {
+                 x = 0;
+@@ -494,7 +571,13 @@
+ }
+ 
+ void graphics_cursor(int set) {
+-    unsigned char *pat, *mem, *ptr, chr[16 << 2];
++    unsigned char *pat;
++#ifdef __MINIOS__
++    uint32_t *mem, *ptr, chr[16 * 8];
++    int j;
++#else
++    unsigned char *mem, *ptr, chr[16 << 2];
++#endif
+     int i, ch, invert, offset;
+ 
+     if (set && (no_cursor || no_scroll))
+@@ -505,71 +588,127 @@
+     invert = (text[fonty * 80 + fontx] & 0xff00) != 0;
+     pat = font8x16 + (ch << 4);
+ 
+-    mem = (unsigned char*)VIDEOMEM + offset;
++    mem = (unsigned char*)VIDEOMEM + offset
++#ifdef __MINIOS__
++      * 8 * 4
++#endif
++      ;
+ 
+     if (!set) {
+         for (i = 0; i < 16; i++) {
+             unsigned char mask = pat[i];
+ 
+             if (!invert) {
++#ifdef __MINIOS__
++              memcpy(chr + i * 8, VSHADOW + offset * 8, 8 * 4);
++#else
+                 chr[i     ] = ((unsigned char*)VSHADOW1)[offset];
+                 chr[16 + i] = ((unsigned char*)VSHADOW2)[offset];
+                 chr[32 + i] = ((unsigned char*)VSHADOW4)[offset];
+                 chr[48 + i] = ((unsigned char*)VSHADOW8)[offset];
++#endif
+ 
+                 if (shade) {
+                     if (ch == DISP_VERT || ch == DISP_LL ||
+                         ch == DISP_UR || ch == DISP_LR) {
+                         unsigned char pmask = ~(pat[i] >> 1);
+ 
++#ifdef __MINIOS__
++                      for (j = 0; j < 8; j++)
++                          if (!(pmask & (1U << j)))
++                              chr[i * 8 + (7 - j)] = palette[0];
++#else
+                         chr[i     ] &= pmask;
+                         chr[16 + i] &= pmask;
+                         chr[32 + i] &= pmask;
+                         chr[48 + i] &= pmask;
++#endif
+                     }
+                     if (i > 0 && ch != DISP_VERT) {
+                         unsigned char pmask = ~(pat[i - 1] >> 1);
+ 
++#ifdef __MINIOS__
++                      for (j = 0; j < 8; j++)
++                          if (!(pmask & (1U << j)))
++                              chr[i * 8 + (7 - j)] = palette[0];
++#else
+                         chr[i     ] &= pmask;
+                         chr[16 + i] &= pmask;
+                         chr[32 + i] &= pmask;
+                         chr[48 + i] &= pmask;
++#endif
+                         if (ch == DISP_HORIZ || ch == DISP_UR || ch == 
DISP_LR) {
+                             pmask = ~pat[i - 1];
+ 
++#ifdef __MINIOS__
++                          for (j = 0; j < 8; j++)
++                              if (!(pmask & (1U << j)))
++                                  chr[i * 8 + (7 - j)] = palette[0];
++#else
+                             chr[i     ] &= pmask;
+                             chr[16 + i] &= pmask;
+                             chr[32 + i] &= pmask;
+                             chr[48 + i] &= pmask;
++#endif
+                         }
+                     }
+                 }
++#ifdef __MINIOS__
++              for (j = 0; j < 8; j++)
++                  if (mask & (1U << j))
++                      chr[i * 8 + (7 - j)] = palette[15];
++#else
+                 chr[i     ] |= mask;
+                 chr[16 + i] |= mask;
+                 chr[32 + i] |= mask;
+                 chr[48 + i] |= mask;
++#endif
+ 
+                 offset += 80;
+             }
+             else {
++#ifdef __MINIOS__
++              for (j = 0; j < 8; j++)
++                  if (mask & (1U << j))
++                      chr[i * 8 + (7 - j)] = palette[15];
++                  else
++                      chr[i * 8 + (7 - j)] = palette[0];
++#else
+                 chr[i     ] = mask;
+                 chr[16 + i] = mask;
+                 chr[32 + i] = mask;
+                 chr[48 + i] = mask;
++#endif
+             }
+         }
+     }
+     else {
++#ifdef __MINIOS__
++        ptr = mem;
++        for (i = 0; i < 16; i++, ptr += 80 * 8)
++          for (j = 0; j < 8; j++) {
++              if (pat[i] & (1U << (7 - j)))
++                  cursorBuf32[i * 8 + j] = ptr[j] = palette[0];
++              else
++                  cursorBuf32[i * 8 + j] = ptr[j] = palette[15];
++          }
++#else
+         MapMask(15);
+         ptr = mem;
+         for (i = 0; i < 16; i++, ptr += 80) {
+             cursorBuf[i] = pat[i];
+             *ptr = ~pat[i];
+         }
++#endif
+         return;
+     }
+ 
+     offset = 0;
++#ifdef __MINIOS__
++    ptr = mem;
++    for (j = 0; j < 16; j++, ptr += 80 * 8)
++      memcpy(ptr, chr + j * 8 + offset * 8, 8 * 4);
++#else
+     for (i = 1; i < 16; i <<= 1, offset += 16) {
+         int j;
+ 
+@@ -580,6 +719,7 @@
+     }
+ 
+     MapMask(15);
++#endif
+ }
+ 
+ #endif /* SUPPORT_GRAPHICS */
+Index: grub/stage2/graphics.h
+===================================================================
+--- grub.orig/stage2/graphics.h        2008-06-16 15:18:14.527010000 +0100
++++ grub/stage2/graphics.h     2008-06-16 15:18:14.805010000 +0100
+@@ -21,8 +21,10 @@
+ #ifndef GRAPHICS_H
+ #define GRAPHICS_H
+ 
++#ifndef __MINIOS__
+ /* magic constant */
+ #define VIDEOMEM 0xA0000
++#endif
+ 
+ /* function prototypes */
+ char *graphics_get_splash(void);
+Index: grub/stage2/stage2.c
+===================================================================
+--- grub.orig/stage2/stage2.c  2008-06-17 11:06:47.873523000 +0100
++++ grub/stage2/stage2.c       2008-06-17 11:07:05.225628000 +0100
+@@ -31,10 +31,10 @@
+ #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS)
+ 
+ # if defined(PRESET_MENU_STRING)
+-static const char *preset_menu = PRESET_MENU_STRING;
++const char *preset_menu = PRESET_MENU_STRING;
+ # elif defined(SUPPORT_DISKLESS)
+ /* Execute the command "bootp" automatically.  */
+-static const char *preset_menu = "bootp\n";
++const char *preset_menu = "bootp\n";
+ # endif /* SUPPORT_DISKLESS */
+ 
+ static int preset_menu_offset;
diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub/Makefile
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/stubdom/grub/Makefile     Thu Jun 19 12:46:26 2008 +0900
@@ -0,0 +1,76 @@
+XEN_ROOT = ../..
+
+include $(XEN_ROOT)/Config.mk
+vpath %.c ../grub-cvs
+
+BOOT=boot-$(XEN_TARGET_ARCH).o
+
+DEF_CPPFLAGS += -I$(XEN_ROOT)/tools/libxc -I.
+DEF_CPPFLAGS += -I../grub-cvs/stage1
+DEF_CPPFLAGS += -I../grub-cvs/stage2
+DEF_CPPFLAGS += -I../grub-cvs/netboot
+DEF_CPPFLAGS += -I$(XEN_ROOT)/tools/firmware/vgabios
+DEF_CPPFLAGS += -DWITHOUT_LIBC_STUBS
+DEF_CPPFLAGS += -DSUPPORT_NETBOOT
+DEF_CPPFLAGS += -DSUPPORT_GRAPHICS
+DEF_CPPFLAGS += -DSUPPORT_SERIAL
+DEF_CPPFLAGS += -DPRESET_MENU_STRING='""'
+DEF_CPPFLAGS += -DPACKAGE='"grubdom"' -DVERSION='"0.97"'
+
+all: main.a
+
+STAGE2_SOURCES=builtins.c char_io.c cmdline.c common.c console.c disk_io.c 
graphics.c gunzip.c md5.c serial.c stage2.c terminfo.c tparm.c
+
+NETBOOT_SOURCES=fsys_tftp.c main.c misc.c
+CPPFLAGS += -DFSYS_TFTP=1
+
+STAGE2_SOURCES+=fsys_ext2fs.c
+CPPFLAGS += -DFSYS_EXT2FS=1
+
+STAGE2_SOURCES+=fsys_fat.c
+CPPFLAGS += -DFSYS_FAT=1
+
+STAGE2_SOURCES+=fsys_ffs.c
+CPPFLAGS += -DFSYS_FFS=1
+
+STAGE2_SOURCES+=fsys_iso9660.c
+CPPFLAGS += -DFSYS_ISO9660=1
+
+STAGE2_SOURCES+=fsys_jfs.c
+CPPFLAGS += -DFSYS_JFS=1
+
+STAGE2_SOURCES+=fsys_minix.c
+CPPFLAGS += -DFSYS_MINIX=1
+
+STAGE2_SOURCES+=fsys_reiserfs.c
+CPPFLAGS += -DFSYS_REISERFS=1
+
+STAGE2_SOURCES+=fsys_ufs2.c
+CPPFLAGS += -DFSYS_UFS2=1
+
+STAGE2_SOURCES+=fsys_vstafs.c
+CPPFLAGS += -DFSYS_VSTAFS=1
+
+ifeq (0,1)
+STAGE2_SOURCES+=fsys_xfs.c
+CPPFLAGS += -DFSYS_XFS=1
+endif
+
+STAGE2_SOURCES:=$(addprefix stage2/,$(STAGE2_SOURCES))
+NETBOOT_SOURCES:=$(addprefix netboot/,$(NETBOOT_SOURCES))
+
+$(BOOT): DEF_CPPFLAGS+=-D__ASSEMBLY__
+
+OBJS = $(NETBOOT_SOURCES:.c=.o) $(STAGE2_SOURCES:.c=.o) kexec.o mini-os.o
+
+dirs:
+       mkdir -p netboot stage2
+       touch $@
+
+$(OBJS): dirs
+
+main.a: $(BOOT) $(OBJS)
+       $(AR) cr $@ $^
+
+clean:
+       rm -fr dirs *.a *.o stage2 netboot
diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub/boot-x86_32.S
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/stubdom/grub/boot-x86_32.S        Thu Jun 19 12:46:26 2008 +0900
@@ -0,0 +1,112 @@
+#include <os.h>
+#include <arch_limits.h>
+#include <xen/arch-x86_32.h>
+
+/* For simplicity, we keep all of this into just one data page */
+.data
+.globl _boot_page
+_boot_page:
+        .align __PAGE_SIZE
+
+/*
+ * The following data is initialized from C code
+ */
+
+/* Pte of this page */
+.globl _boot_page_entry
+_boot_page_entry:
+_boot_page_entry_lo:
+        .long 0
+_boot_page_entry_hi:
+        .long 0
+
+/* mmuext_op structure */
+/* Set new page directory */
+_boot_mmuext:
+        /* Op # */
+        .long MMUEXT_NEW_BASEPTR
+
+        /* MFN of target page table directory */
+.globl _boot_pdmfn
+_boot_pdmfn:
+        .long 0
+
+        /* Unused */
+        .long 0
+
+/* Unpin old page directory */
+        /* Op # */
+        .long MMUEXT_UNPIN_TABLE
+
+        /* MFN of old page table directory */
+.globl _boot_oldpdmfn
+_boot_oldpdmfn:
+        .long 0
+
+        /* Unused */
+        .long 0
+
+/* Target stack address, also target virtual address of this page */
+.globl _boot_stack
+_boot_stack:
+        .long 0
+        .long __KERNEL_SS
+.globl _boot_target
+_boot_target:
+        .long 0
+
+/* Target start info */
+.globl _boot_start_info
+_boot_start_info:
+        .long 0
+
+/* Target start address */
+.globl _boot_start
+_boot_start:
+        .long 0
+
+/*
+ * Boot target OS, does not return
+ */
+.globl _boot
+_boot:
+        /* Project ourselves at the target place. */
+        movl    _boot_target, %ebx
+        movl    %ebx, %ebp     /* also keep it in ebp for relative addressing 
*/
+        movl    _boot_page_entry_lo, %ecx
+        movl    _boot_page_entry_hi, %edx
+        movl    $2, %esi /* UVMF_INVLPG */
+        movl    $__HYPERVISOR_update_va_mapping, %eax
+        int     $0x82
+        testl   %eax, %eax
+        jz      0f
+        ud2
+
+0:
+        /* Go there. */
+        movl    $(0f - _boot_page), %eax
+        movl    _boot_target, %ebx
+        addl    %ebx, %eax
+        jmpl    *%eax
+0:
+        
+        /* Load target page table and unpin old page table.  */
+        /* We shouldn't have any problem since in the new page table our page 
is
+           mapped at the same place.  */
+        leal    (_boot_mmuext-_boot_page)(%ebp), %ebx
+        movl    $2, %ecx
+        xorl    %edx, %edx
+        movl    $0x7FF0, %esi /* DOMID_SELF */
+        movl    $__HYPERVISOR_mmuext_op, %eax
+        int     $0x82
+        testl   %eax, %eax
+        jns     0f
+        ud2
+
+0:
+        /* Initialize registers.  */
+        lss     (_boot_stack-_boot_page)(%ebp), %esp
+        movl    (_boot_start_info-_boot_page)(%ebp), %esi
+
+        /* Jump!  */
+        jmpl    *(_boot_start-_boot_page)(%ebp)
diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub/boot-x86_64.S
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/stubdom/grub/boot-x86_64.S        Thu Jun 19 12:46:26 2008 +0900
@@ -0,0 +1,108 @@
+#include <os.h>
+#include <arch_limits.h>
+#include <xen/arch-x86_64.h>
+
+/* For simplicity, we keep all of this into just one data page */
+.data
+.globl _boot_page
+_boot_page:
+        .align __PAGE_SIZE
+
+/*
+ * The following data is initialized from C code
+ */
+
+/* Pte of this page */
+.globl _boot_page_entry
+_boot_page_entry:
+        .quad 0
+
+/* mmuext_op structure */
+/* Set new page directory */
+_boot_mmuext:
+        /* Op # */
+        .long MMUEXT_NEW_BASEPTR
+        .long 0 /* pad */
+
+        /* MFN of target page table directory */
+.globl _boot_pdmfn
+_boot_pdmfn:
+        .quad 0
+
+        /* Unused */
+        .quad 0
+
+/* Unpin old page directory */
+        /* Op # */
+        .long MMUEXT_UNPIN_TABLE
+        .long 0 /* pad */
+
+        /* MFN of old page table directory */
+.globl _boot_oldpdmfn
+_boot_oldpdmfn:
+        .quad 0
+
+        /* Unused */
+        .quad 0
+
+/* Target stack address, also target virtual address of this page */
+.globl _boot_stack
+_boot_stack:
+        .quad 0
+.globl _boot_target
+_boot_target:
+        .quad 0
+
+/* Target start info */
+.globl _boot_start_info
+_boot_start_info:
+        .quad 0
+
+/* Target start address */
+.globl _boot_start
+_boot_start:
+        .quad 0
+
+/*
+ * Boot target OS, does not return
+ */
+.globl _boot
+_boot:
+        /* Project ourselves at the target place. */
+        movq    _boot_target, %rdi
+        movq    _boot_page_entry, %rsi
+        movq    $2, %rdx /* UVMF_INVLPG */
+        movq    $__HYPERVISOR_update_va_mapping, %rax
+        syscall
+        testq   %rax, %rax
+        jz      0f
+        ud2
+
+0:
+        /* Go there. */
+        movq    $(0f - _boot_page), %rax
+        movq    _boot_target, %rbx
+        addq    %rbx, %rax
+        jmpq    *%rax
+0:
+        
+        /* Load target page table and unpin old page table.  */
+        /* We shouldn't have any problem since in the new page table our page 
is
+           mapped at the same place.  */
+        leaq    _boot_mmuext(%rip), %rdi
+        movq    $2, %rsi
+        xorq    %rdx, %rdx
+        movq    $0x7FF0, %r10 /* DOMID_SELF */
+        movq    $__HYPERVISOR_mmuext_op, %rax
+        syscall
+        testq   %rax, %rax
+        jns     0f
+        ud2
+
+0:
+        /* Initialize registers.  */
+        movq    _boot_stack(%rip), %rsp
+        movq    _boot_start_info(%rip), %rsi
+
+        /* Jump!  */
+        jmpq    *_boot_start(%rip)
diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub/config.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/stubdom/grub/config.h     Thu Jun 19 12:46:26 2008 +0900
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#undef putchar
+#include <ctype.h>
+#include <string.h>
+#define debug _debug
+#define grub_halt(a) do_exit()
+#define printf grub_printf
+void kexec(void *kernel, long kernel_size, void *module, long module_size, 
char *cmdline);
+struct fbfront_dev *fb_open(void *fb, int width, int height, int depth);
+void fb_close(void);
+void pv_boot (void);
diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub/kexec.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/stubdom/grub/kexec.c      Thu Jun 19 12:46:26 2008 +0900
@@ -0,0 +1,324 @@
+/*
+ * This supports booting another PV kernel from Mini-OS
+ *
+ * The idea is to setup it using libxc, answer to day0 memory allocation
+ * requests, and using a trampoline boot page to switch to the new page table.
+ *
+ * The procedure of the boot page is:
+ * - map itself at the target position (that may overwrite some C stuff, but we
+ *   do not care any more)
+ * - jump there
+ * - switch to the target page table
+ * - unpin the old page table
+ * - jump to the new kernel
+ *
+ * Samuel Thibault <Samuel.Thibault@xxxxxxxxxxxxx>, May 2008
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+
+#include <xenctrl.h>
+#include <xc_dom.h>
+
+#include <kernel.h>
+#include <console.h>
+#include <os.h>
+#include <blkfront.h>
+#include <netfront.h>
+#include <fbfront.h>
+#include <shared.h>
+
+#include "mini-os.h"
+
+#if 0
+#define DEBUG(fmt, ...) printk(fmt, ## __VA_ARGS__)
+#else
+#define DEBUG(fmt, ...) (void)0
+#endif
+
+/* Assembly boot page from boot.S */
+extern void _boot_page;
+extern pgentry_t _boot_page_entry;
+extern unsigned long _boot_pdmfn;
+extern unsigned long _boot_stack, _boot_target, _boot_start_info, _boot_start;
+extern xen_pfn_t _boot_oldpdmfn;
+extern void _boot(void);
+
+static unsigned long *pages;
+static unsigned long *pages_mfns;
+static unsigned long allocated;
+
+int pin_table(int xc_handle, unsigned int type, unsigned long mfn,
+              domid_t dom);
+
+/* We need mfn to appear as target_pfn, so exchange with the MFN there */
+static void do_exchange(struct xc_dom_image *dom, xen_pfn_t target_pfn, 
xen_pfn_t source_mfn)
+{
+    xen_pfn_t source_pfn;
+    xen_pfn_t target_mfn;
+
+    for (source_pfn = 0; source_pfn < start_info.nr_pages; source_pfn++)
+        if (dom->p2m_host[source_pfn] == source_mfn)
+            break;
+    ASSERT(source_pfn < start_info.nr_pages);
+
+    target_mfn = dom->p2m_host[target_pfn];
+
+    /* Put target MFN at source PFN */
+    dom->p2m_host[source_pfn] = target_mfn;
+
+    /* Put source MFN at target PFN */
+    dom->p2m_host[target_pfn] = source_mfn;
+}
+
+int kexec_allocate(struct xc_dom_image *dom, xen_vaddr_t up_to)
+{
+    unsigned long new_allocated = (up_to - dom->parms.virt_base) / PAGE_SIZE;
+    unsigned long i;
+
+    pages = realloc(pages, new_allocated * sizeof(*pages));
+    pages_mfns = realloc(pages_mfns, new_allocated * sizeof(*pages_mfns));
+    for (i = allocated; i < new_allocated; i++) {
+        /* Exchange old page of PFN i with a newly allocated page.  */
+        xen_pfn_t old_mfn = dom->p2m_host[i];
+        xen_pfn_t new_pfn;
+        xen_pfn_t new_mfn;
+
+        pages[i] = alloc_page();
+        memset((void*) pages[i], 0, PAGE_SIZE);
+        new_pfn = PHYS_PFN(to_phys(pages[i]));
+        pages_mfns[i] = new_mfn = pfn_to_mfn(new_pfn);
+
+        /* Put old page at new PFN */
+        dom->p2m_host[new_pfn] = old_mfn;
+
+        /* Put new page at PFN i */
+        dom->p2m_host[i] = new_mfn;
+    }
+
+    allocated = new_allocated;
+
+    return 0;
+}
+
+void kexec(void *kernel, long kernel_size, void *module, long module_size, 
char *cmdline)
+{
+    struct xc_dom_image *dom;
+    int rc;
+    domid_t domid = DOMID_SELF;
+    xen_pfn_t pfn;
+    int xc_handle;
+    unsigned long i;
+    void *seg;
+    xen_pfn_t boot_page_mfn = virt_to_mfn(&_boot_page);
+    char features[] = "";
+    struct mmu_update *m2p_updates;
+    unsigned long nr_m2p_updates;
+
+    DEBUG("booting with cmdline %s\n", cmdline);
+    xc_handle = xc_interface_open();
+
+    dom = xc_dom_allocate(cmdline, features);
+    dom->allocate = kexec_allocate;
+
+    dom->kernel_blob = kernel;
+    dom->kernel_size = kernel_size;
+
+    dom->ramdisk_blob = module;
+    dom->ramdisk_size = module_size;
+
+    dom->flags = 0;
+    dom->console_evtchn = start_info.console.domU.evtchn;
+    dom->xenstore_evtchn = start_info.store_evtchn;
+
+    if ( (rc = xc_dom_boot_xen_init(dom, xc_handle, domid)) != 0 ) {
+        grub_printf("xc_dom_boot_xen_init returned %d\n", rc);
+        errnum = ERR_BOOT_FAILURE;
+        goto out;
+    }
+    if ( (rc = xc_dom_parse_image(dom)) != 0 ) {
+        grub_printf("xc_dom_parse_image returned %d\n", rc);
+        errnum = ERR_BOOT_FAILURE;
+        goto out;
+    }
+
+#ifdef __i386__
+    if (strcmp(dom->guest_type, "xen-3.0-x86_32p")) {
+        grub_printf("can only boot x86 32 PAE kernels, not %s\n", 
dom->guest_type);
+        errnum = ERR_EXEC_FORMAT;
+        goto out;
+    }
+#endif
+#ifdef __x86_64__
+    if (strcmp(dom->guest_type, "xen-3.0-x86_64")) {
+        grub_printf("can only boot x86 64 kernels, not %s\n", dom->guest_type);
+        errnum = ERR_EXEC_FORMAT;
+        goto out;
+    }
+#endif
+
+    /* equivalent of xc_dom_mem_init */
+    dom->arch_hooks = xc_dom_find_arch_hooks(dom->guest_type);
+    dom->total_pages = start_info.nr_pages;
+
+    /* equivalent of arch_setup_meminit */
+
+    /* setup initial p2m */
+    dom->p2m_host = malloc(sizeof(*dom->p2m_host) * dom->total_pages);
+
+    /* Start with our current P2M */
+    for (i = 0; i < dom->total_pages; i++)
+        dom->p2m_host[i] = pfn_to_mfn(i);
+
+    if ( (rc = xc_dom_build_image(dom)) != 0 ) {
+        grub_printf("xc_dom_build_image returned %d\n", rc);
+        errnum = ERR_BOOT_FAILURE;
+        goto out;
+    }
+
+    /* copy hypercall page */
+    /* TODO: domctl instead, but requires privileges */
+    if (dom->parms.virt_hypercall != -1) {
+        pfn = PHYS_PFN(dom->parms.virt_hypercall - dom->parms.virt_base);
+        memcpy((void *) pages[pfn], hypercall_page, PAGE_SIZE);
+    }
+
+    /* Equivalent of xc_dom_boot_image */
+    dom->shared_info_mfn = PHYS_PFN(start_info.shared_info);
+
+    if (!xc_dom_compat_check(dom)) {
+        grub_printf("xc_dom_compat_check failed\n");
+        errnum = ERR_EXEC_FORMAT;
+        goto out;
+    }
+
+    /* Move current console, xenstore and boot MFNs to the allocated place */
+    do_exchange(dom, dom->console_pfn, start_info.console.domU.mfn);
+    do_exchange(dom, dom->xenstore_pfn, start_info.store_mfn);
+    DEBUG("virt base at %llx\n", dom->parms.virt_base);
+    DEBUG("bootstack_pfn %lx\n", dom->bootstack_pfn);
+    _boot_target = dom->parms.virt_base + PFN_PHYS(dom->bootstack_pfn);
+    DEBUG("_boot_target %lx\n", _boot_target);
+    do_exchange(dom, PHYS_PFN(_boot_target - dom->parms.virt_base),
+            virt_to_mfn(&_boot_page));
+
+    /* Make sure the bootstrap page table does not RW-map any of our current
+     * page table frames */
+    kexec_allocate(dom, dom->virt_pgtab_end);
+
+    if ( (rc = xc_dom_update_guest_p2m(dom))) {
+        grub_printf("xc_dom_update_guest_p2m returned %d\n", rc);
+        errnum = ERR_BOOT_FAILURE;
+        goto out;
+    }
+
+    if ( dom->arch_hooks->setup_pgtables )
+        if ( (rc = dom->arch_hooks->setup_pgtables(dom))) {
+            grub_printf("setup_pgtables returned %d\n", rc);
+            errnum = ERR_BOOT_FAILURE;
+            goto out;
+        }
+
+    /* start info page */
+#undef start_info
+    if ( dom->arch_hooks->start_info )
+        dom->arch_hooks->start_info(dom);
+#define start_info (start_info_union.start_info)
+
+    xc_dom_log_memory_footprint(dom);
+
+    /* Unmap libxc's projection of the boot page table */
+    seg = xc_dom_seg_to_ptr(dom, &dom->pgtables_seg);
+    munmap(seg, dom->pgtables_seg.vend - dom->pgtables_seg.vstart);
+
+    /* Unmap day0 pages to avoid having a r/w mapping of the future page table 
*/
+    for (pfn = 0; pfn < allocated; pfn++)
+        munmap((void*) pages[pfn], PAGE_SIZE);
+
+    /* Pin the boot page table base */
+    if ( (rc = pin_table(dom->guest_xc, 
+#ifdef __i386__
+                MMUEXT_PIN_L3_TABLE,
+#endif
+#ifdef __x86_64__
+                MMUEXT_PIN_L4_TABLE,
+#endif
+                xc_dom_p2m_host(dom, dom->pgtables_seg.pfn),
+                dom->guest_domid)) != 0 ) {
+        grub_printf("pin_table(%lx) returned %d\n", xc_dom_p2m_host(dom,
+                    dom->pgtables_seg.pfn), rc);
+        errnum = ERR_BOOT_FAILURE;
+        goto out_remap;
+    }
+
+    /* We populate the Mini-OS page table here so that boot.S can just call
+     * update_va_mapping to project itself there.  */
+    need_pgt(_boot_target);
+    DEBUG("day0 pages %lx\n", allocated);
+    DEBUG("boot target page %lx\n", _boot_target);
+    DEBUG("boot page %p\n", &_boot_page);
+    DEBUG("boot page mfn %lx\n", boot_page_mfn);
+    _boot_page_entry = PFN_PHYS(boot_page_mfn) | L1_PROT;
+    DEBUG("boot page entry %llx\n", _boot_page_entry);
+    _boot_oldpdmfn = virt_to_mfn(start_info.pt_base);
+    DEBUG("boot old pd mfn %lx\n", _boot_oldpdmfn);
+    DEBUG("boot pd virt %lx\n", dom->pgtables_seg.vstart);
+    _boot_pdmfn = dom->p2m_host[PHYS_PFN(dom->pgtables_seg.vstart - 
dom->parms.virt_base)];
+    DEBUG("boot pd mfn %lx\n", _boot_pdmfn);
+    _boot_stack = _boot_target + PAGE_SIZE;
+    DEBUG("boot stack %lx\n", _boot_stack);
+    _boot_start_info = dom->parms.virt_base + PFN_PHYS(dom->start_info_pfn);
+    DEBUG("boot start info %lx\n", _boot_start_info);
+    _boot_start = dom->parms.virt_entry;
+    DEBUG("boot start %lx\n", _boot_start);
+
+    /* Keep only useful entries */
+    for (nr_m2p_updates = pfn = 0; pfn < start_info.nr_pages; pfn++)
+        if (dom->p2m_host[pfn] != pfn_to_mfn(pfn))
+            nr_m2p_updates++;
+
+    m2p_updates = malloc(sizeof(*m2p_updates) * nr_m2p_updates);
+    for (i = pfn = 0; pfn < start_info.nr_pages; pfn++)
+        if (dom->p2m_host[pfn] != pfn_to_mfn(pfn)) {
+            m2p_updates[i].ptr = PFN_PHYS(dom->p2m_host[pfn]) | 
MMU_MACHPHYS_UPDATE;
+            m2p_updates[i].val = pfn;
+            i++;
+        }
+
+    for (i = 0; i < blk_nb; i++)
+        shutdown_blkfront(blk_dev[i]);
+    if (net_dev)
+        shutdown_netfront(net_dev);
+    if (kbd_dev)
+        shutdown_kbdfront(kbd_dev);
+    stop_kernel();
+
+    /* Update M2P */
+    if ((rc = HYPERVISOR_mmu_update(m2p_updates, nr_m2p_updates, NULL, 
DOMID_SELF)) < 0) {
+        xprintk("Could not update M2P\n");
+        ASSERT(0);
+    }
+
+    xprintk("go!\n");
+
+    /* Jump to trampoline boot page */
+    _boot();
+
+    ASSERT(0);
+
+out_remap:
+    for (pfn = 0; pfn < allocated; pfn++)
+        do_map_frames(pages[pfn], &pages_mfns[pfn], 1, 0, 0, DOMID_SELF, 0, 
L1_PROT);
+out:
+    xc_dom_release(dom);
+    for (pfn = 0; pfn < allocated; pfn++)
+        free_page((void*)pages[pfn]);
+    free(pages);
+    free(pages_mfns);
+    pages = NULL;
+    pages_mfns = NULL;
+    allocated = 0;
+    xc_interface_close(xc_handle );
+}
diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub/mini-os.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/stubdom/grub/mini-os.c    Thu Jun 19 12:46:26 2008 +0900
@@ -0,0 +1,702 @@
+/*
+ * Mini-OS support for GRUB.
+ *
+ * Samuel Thibault <Samuel.Thibault@xxxxxxxxxxxxx>, May 2008
+ */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <malloc.h>
+#include <unistd.h>
+
+#include <hypervisor.h>
+#include <blkfront.h>
+#include <netfront.h>
+#include <fbfront.h>
+#include <semaphore.h>
+
+#include <osdep.h>
+#include <shared.h>
+#include <nic.h>
+#include <etherboot.h>
+#include <terminfo.h>
+#include <term.h>
+
+#include "mini-os.h"
+
+extern const char *preset_menu;
+char config_file[DEFAULT_FILE_BUFLEN] = "(hd0,0)/boot/grub/menu.lst";
+unsigned long boot_drive = NETWORK_DRIVE;
+unsigned long install_partition = 0xFFFFFF;
+
+char version_string[] = VERSION;
+
+/* Variables from asm.S */
+int saved_entryno;
+
+/*
+ * Disk
+ */
+
+struct blkfront_dev **blk_dev;
+int blk_nb;
+static struct blkfront_info *blk_info;
+
+static int vbdcmp(const void *_vbd1, const void *_vbd2) {
+    char *vbd1 = *(char **)_vbd1;
+    char *vbd2 = *(char **)_vbd2;
+    int vbdn1 = atoi(vbd1);
+    int vbdn2 = atoi(vbd2);
+    return vbdn1 - vbdn2;
+}
+
+void init_disk (void)
+{
+    char **list;
+    char *msg;
+    int i;
+    char *path;
+
+    msg = xenbus_ls(XBT_NIL, "device/vbd", &list);
+    if (msg) {
+        printk("Error %s while reading list of disks\n", msg);
+        free(msg);
+        return;
+    }
+    blk_nb = 0;
+    while (list[blk_nb])
+        blk_nb++;
+    blk_dev = malloc(blk_nb * sizeof(*blk_dev));
+    blk_info = malloc(blk_nb * sizeof(*blk_info));
+
+    qsort(list, blk_nb, sizeof(*list), vbdcmp);
+
+    for (i = 0; i < blk_nb; i++) {
+        printk("vbd %s is hd%d\n", list[i], i);
+        asprintf(&path, "device/vbd/%s", list[i]);
+        blk_dev[i] = init_blkfront(path, &blk_info[i]);
+        free(path);
+        free(list[i]);
+    }
+}
+
+/* Return the geometry of DRIVE in GEOMETRY. If an error occurs, return
+   non-zero, otherwise zero.  */
+int get_diskinfo (int drive, struct geometry *geometry)
+{
+    int i;
+    if (!(drive & 0x80))
+        return -1;
+
+    i = drive - 0x80;
+    if (i >= blk_nb)
+        return -1;
+
+    /* Bogus geometry */
+    geometry->cylinders = 65535;
+    geometry->heads = 255;
+    geometry->sectors = 63;
+
+    geometry->total_sectors = blk_info[i].sectors;
+    geometry->sector_size = blk_info[i].sector_size;
+    geometry->flags = BIOSDISK_FLAG_LBA_EXTENSION;
+    if (blk_info[i].info & VDISK_CDROM)
+        geometry->flags |= BIOSDISK_FLAG_CDROM;
+    return 0;
+}
+
+/* Read/write NSEC sectors starting from SECTOR in DRIVE disk with GEOMETRY
+   from/into SEGMENT segment. If READ is BIOSDISK_READ, then read it,
+   else if READ is BIOSDISK_WRITE, then write it. If an geometry error
+   occurs, return BIOSDISK_ERROR_GEOMETRY, and if other error occurs, then
+   return the error number. Otherwise, return 0.  */
+int
+biosdisk (int read, int drive, struct geometry *geometry,
+          unsigned int sector, int nsec, int segment)
+{
+    void *addr = (void *) ((unsigned long)segment << 4);
+    struct blkfront_aiocb aiocb;
+    int i;
+
+    if (!(drive & 0x80))
+        return -1;
+
+    i = drive - 0x80;
+    if (i >= blk_nb)
+        return -1;
+
+    aiocb.aio_dev = blk_dev[i];
+    aiocb.aio_buf = addr;
+    aiocb.aio_nbytes = (size_t)nsec * blk_info[i].sector_size;
+    aiocb.aio_offset = (off_t)sector * blk_info[i].sector_size;
+    aiocb.aio_cb = NULL;
+
+    blkfront_io(&aiocb, read == BIOSDISK_WRITE);
+
+    return 0;
+}
+
+static int
+load_file(char *name, void **ptr, long *size)
+{
+    char *buf = NULL;
+    int allocated = 1 * 1024 * 1024;
+    int len, filled = 0;
+
+    if (!grub_open (name))
+        return -1;
+
+    buf = malloc(allocated);
+
+    errnum = 0;
+    while (1) {
+        len = grub_read (buf + filled, allocated - filled);
+        if (! len) {
+            if (!errnum)
+                break;
+            grub_close ();
+            return -1;
+        }
+        filled += len;
+        if (filled < allocated)
+            break;
+        allocated *= 2;
+        buf = realloc(buf, allocated);
+    }
+    grub_close ();
+    *ptr = buf;
+    *size = filled;
+    return 0;
+}
+
+void *kernel_image, *module_image;
+long  kernel_size, module_size;
+char *kernel_arg, *module_arg;
+
+kernel_t
+load_image (char *kernel, char *arg, kernel_t suggested_type,
+            unsigned long load_flags)
+{
+    arg = skip_to(0, arg);
+    if (kernel_image)
+        free(kernel_image);
+    kernel_image = NULL;
+    if (load_file (kernel, &kernel_image, &kernel_size))
+        return KERNEL_TYPE_NONE;
+    if (kernel_arg)
+        free(kernel_arg);
+    kernel_arg = strdup(arg);
+    return KERNEL_TYPE_PV;
+}
+
+int
+load_initrd (char *initrd)
+{
+    if (module_image)
+        free(module_image);
+    module_image = NULL;
+    load_file (initrd, &module_image, &module_size);
+    return ! errnum;
+}
+
+int
+load_module (char *module, char *arg)
+{
+    if (module_image)
+        free(module_image);
+    module_image = NULL;
+    load_file (module, &module_image, &module_size);
+    if (module_arg)
+        free(module_arg);
+    module_arg = strdup(arg);
+    return ! errnum;
+}
+
+void
+pv_boot (void)
+{
+    kexec(kernel_image, kernel_size, module_image, module_size, kernel_arg);
+}
+
+/*
+ * Network
+ */
+
+struct netfront_dev *net_dev;
+
+int
+minios_probe (struct nic *nic)
+{
+    char *ip;
+
+    if (net_dev)
+        return 1;
+
+    /* Clear the ARP table.  */
+    grub_memset ((char *) arptable, 0,
+                 MAX_ARP * sizeof (struct arptable_t));
+
+    net_dev = init_netfront(NULL, (void*) -1, nic->node_addr, &ip);
+    if (!net_dev)
+        return 0;
+
+    return 1;
+}
+
+/* reset adapter */
+static void minios_reset(struct nic *nic)
+{
+    /* TODO? */
+}
+
+static void minios_disable(struct nic *nic)
+{
+}
+
+/* Wait for a frame */
+static int minios_poll(struct nic *nic)
+{
+    return !! (nic->packetlen = netfront_receive(net_dev, (void*) nic->packet, 
ETH_FRAME_LEN));
+}
+
+/* Transmit a frame */
+struct frame {
+        uint8_t dest[ETH_ALEN];
+        uint8_t src[ETH_ALEN];
+        uint16_t type;
+        unsigned char data[];
+};
+static void minios_transmit (struct nic *nic, const char *d, unsigned int t,
+                             unsigned int s, const char *p)
+{
+    struct frame *frame = alloca(sizeof(frame) + s);
+
+    memcpy(frame->dest, d, ETH_ALEN);
+    memcpy(frame->src, nic->node_addr, ETH_ALEN);
+    frame->type = htons(t);
+    memcpy(frame->data, p, s);
+
+    netfront_xmit(net_dev, (void*) frame, sizeof(*frame) + s);
+}
+
+static char packet[ETH_FRAME_LEN];
+
+struct nic nic = {
+    .reset = minios_reset,
+    .poll = minios_poll,
+    .transmit = minios_transmit,
+    .disable = minios_disable,
+    .flags = 0,
+    .rom_info = NULL,
+    .node_addr = arptable[ARP_CLIENT].node,
+    .packet = packet,
+    .packetlen = 0,
+    .priv_data = NULL,
+};
+
+int
+eth_probe (void)
+{
+    return minios_probe(&nic);
+}
+
+int
+eth_poll (void)
+{
+    return minios_poll (&nic);
+}
+
+void
+eth_disable (void)
+{
+    minios_disable (&nic);
+}
+
+void
+eth_transmit (const char *d, unsigned int t,
+              unsigned int s, const void *p)
+{
+    minios_transmit (&nic, d, t, s, p);
+    if (t == IP)
+        twiddle();
+}
+
+/*
+ * Console
+ */
+void
+serial_hw_put (int _c)
+{
+  char c = _c;
+  console_print(&c, 1);
+}
+
+int
+serial_hw_fetch (void)
+{
+    char key;
+
+    if (!xencons_ring_avail())
+        return -1;
+
+    read(STDIN_FILENO, &key, 1);
+    switch (key) {
+    case 0x7f: key = '\b'; break;
+    }
+    return key;
+}
+
+/*
+ * PVFB
+ */
+struct kbdfront_dev *kbd_dev;
+struct fbfront_dev *fb_dev;
+static union xenkbd_in_event ev;
+static int has_ev;
+int console_checkkey (void)
+{
+    if (has_ev)
+        return 1;
+    has_ev = kbdfront_receive(kbd_dev, &ev, 1);
+    return has_ev;
+}
+
+/* static QWERTY layout, that's what most PC BIOSes do anyway */
+static char linux2ascii[] = {
+    [ 1 ] = 27,
+    [ 2 ] = '1',
+    [ 3 ] = '2',
+    [ 4 ] = '3',
+    [ 5 ] = '4',
+    [ 6 ] = '5',
+    [ 7 ] = '6',
+    [ 8 ] = '7',
+    [ 9 ] = '8',
+    [ 10 ] = '9',
+    [ 11 ] = '0',
+    [ 12 ] = '-',
+    [ 13 ] = '=',
+    [ 14 ] = '\b',
+    [ 15 ] = '\t',
+    [ 16 ] = 'q',
+    [ 17 ] = 'w',
+    [ 18 ] = 'e',
+    [ 19 ] = 'r',
+    [ 20 ] = 't',
+    [ 21 ] = 'y',
+    [ 22 ] = 'u',
+    [ 23 ] = 'i',
+    [ 24 ] = 'o',
+    [ 25 ] = 'p',
+    [ 26 ] = '[',
+    [ 27 ] = ']',
+    [ 28 ] = '\n',
+
+    [ 30 ] = 'a',
+    [ 31 ] = 's',
+    [ 32 ] = 'd',
+    [ 33 ] = 'f',
+    [ 34 ] = 'g',
+    [ 35 ] = 'h',
+    [ 36 ] = 'j',
+    [ 37 ] = 'k',
+    [ 38 ] = 'l',
+    [ 39 ] = ';',
+    [ 40 ] = '\'',
+    [ 41 ] = '`',
+
+    [ 43 ] = '\\',
+    [ 44 ] = 'z',
+    [ 45 ] = 'x',
+    [ 46 ] = 'c',
+    [ 47 ] = 'v',
+    [ 48 ] = 'b',
+    [ 49 ] = 'n',
+    [ 50 ] = 'm',
+    [ 51 ] = ',',
+    [ 52 ] = '.',
+    [ 53 ] = '/',
+
+    [ 55 ] = '*',
+    [ 57 ] = ' ',
+
+    [ 71 ] = '7',
+    [ 72 ] = '8',
+    [ 73 ] = '9',
+    [ 74 ] = '-',
+    [ 75 ] = '4',
+    [ 76 ] = '5',
+    [ 77 ] = '6',
+    [ 78 ] = '+',
+    [ 79 ] = '1',
+    [ 80 ] = '2',
+    [ 81 ] = '3',
+    [ 82 ] = '0',
+    [ 83 ] = '.',
+
+    [ 86 ] = '<',
+
+    [ 96 ] = '\n',
+
+    [ 98 ] = '/',
+
+    [ 102 ] = 1,  /* home */
+    [ 103 ] = 16, /* up */
+    [ 104 ] = 7,  /* page up */
+    [ 105 ] = 2,  /* left */
+    [ 106 ] = 6,  /* right */
+    [ 107 ] = 5,  /* end */
+    [ 108 ] = 14, /* down */
+    [ 109 ] = 3,  /* page down */
+
+    [ 111 ] = 4,  /* delete */
+};
+
+static char linux2ascii_shifted[] = {
+    [ 1 ] = 27,
+    [ 2 ] = '!',
+    [ 3 ] = '@',
+    [ 4 ] = '#',
+    [ 5 ] = '$',
+    [ 6 ] = '%',
+    [ 7 ] = '^',
+    [ 8 ] = '&',
+    [ 9 ] = '*',
+    [ 10 ] = '(',
+    [ 11 ] = ')',
+    [ 12 ] = '_',
+    [ 13 ] = '+',
+    [ 14 ] = '\b',
+    [ 15 ] = '\t',
+    [ 16 ] = 'Q',
+    [ 17 ] = 'W',
+    [ 18 ] = 'E',
+    [ 19 ] = 'R',
+    [ 20 ] = 'T',
+    [ 21 ] = 'Y',
+    [ 22 ] = 'U',
+    [ 23 ] = 'I',
+    [ 24 ] = 'O',
+    [ 25 ] = 'P',
+    [ 26 ] = '{',
+    [ 27 ] = '}',
+    [ 28 ] = '\n',
+
+    [ 30 ] = 'A',
+    [ 31 ] = 'S',
+    [ 32 ] = 'D',
+    [ 33 ] = 'F',
+    [ 34 ] = 'G',
+    [ 35 ] = 'H',
+    [ 36 ] = 'J',
+    [ 37 ] = 'K',
+    [ 38 ] = 'L',
+    [ 39 ] = ':',
+    [ 40 ] = '"',
+    [ 41 ] = '~',
+
+    [ 43 ] = '|',
+    [ 44 ] = 'Z',
+    [ 45 ] = 'X',
+    [ 46 ] = 'C',
+    [ 47 ] = 'V',
+    [ 48 ] = 'B',
+    [ 49 ] = 'N',
+    [ 50 ] = 'M',
+    [ 51 ] = '<',
+    [ 52 ] = '>',
+    [ 53 ] = '?',
+
+    [ 55 ] = '*',
+    [ 57 ] = ' ',
+
+    [ 71 ] = '7',
+    [ 72 ] = '8',
+    [ 73 ] = '9',
+    [ 74 ] = '-',
+    [ 75 ] = '4',
+    [ 76 ] = '5',
+    [ 77 ] = '6',
+    [ 78 ] = '+',
+    [ 79 ] = '1',
+    [ 80 ] = '2',
+    [ 81 ] = '3',
+    [ 82 ] = '0',
+    [ 83 ] = '.',
+
+    [ 86 ] = '>',
+
+    [ 96 ] = '\n',
+
+    [ 98 ] = '/',
+
+    [ 102 ] = 1,  /* home */
+    [ 103 ] = 16, /* up */
+    [ 104 ] = 7,  /* page up */
+    [ 105 ] = 2,  /* left */
+    [ 106 ] = 6,  /* right */
+    [ 107 ] = 5,  /* end */
+    [ 108 ] = 14, /* down */
+    [ 109 ] = 3,  /* page down */
+
+    [ 111 ] = 4,  /* delete */
+};
+
+int console_getkey (void)
+{
+    static int shift, control, alt, caps_lock;
+
+    if (!has_ev)
+        has_ev = kbdfront_receive(kbd_dev, &ev, 1);
+    if (!has_ev)
+        return 0;
+
+    has_ev = 0;
+    if (ev.type != XENKBD_TYPE_KEY)
+        return 0;
+
+    if (ev.key.keycode == 42 || ev.key.keycode == 54) {
+        caps_lock = 0;
+        shift = ev.key.pressed;
+        return 0;
+    }
+    if (ev.key.keycode == 58) {
+        caps_lock ^= 1;
+        return 0;
+    }
+    if (ev.key.keycode == 29 || ev.key.keycode == 97) {
+        control = ev.key.pressed;
+        return 0;
+    }
+    if (ev.key.keycode == 56) {
+        alt = ev.key.pressed;
+        return 0;
+    }
+
+    if (!ev.key.pressed)
+        return 0;
+
+    if (ev.key.keycode < sizeof(linux2ascii) / sizeof(*linux2ascii)) {
+        char val;
+        if (shift || caps_lock)
+            val = linux2ascii_shifted[ev.key.keycode];
+        else
+            val = linux2ascii[ev.key.keycode];
+        if (control)
+            val &= ~0x60;
+        return val;
+    }
+
+    return 0;
+}
+
+static void kbd_thread(void *p)
+{
+    struct semaphore *sem = p;
+
+    kbd_dev = init_kbdfront(NULL, 1);
+    up(sem);
+}
+
+struct fbfront_dev *fb_open(void *fb, int width, int height, int depth)
+{
+    unsigned long *mfns;
+    int linesize = width * (depth / 8);
+    int memsize = linesize * height;
+    int numpages = (memsize + PAGE_SIZE - 1) / PAGE_SIZE;
+    DECLARE_MUTEX_LOCKED(sem);
+    int i;
+
+    create_thread("kbdfront", kbd_thread, &sem);
+
+    mfns = malloc(numpages * sizeof(*mfns));
+    for (i = 0; i < numpages; i++) {
+        memset(fb + i * PAGE_SIZE, 0, PAGE_SIZE);
+        mfns[i] = virtual_to_mfn(fb + i * PAGE_SIZE);
+    }
+    fb_dev = init_fbfront(NULL, mfns, width, height, depth, linesize, 
numpages);
+    free(mfns);
+
+    if (!fb_dev)
+        return NULL;
+
+    down(&sem);
+    if (!kbd_dev)
+        return NULL;
+
+    return fb_dev;
+}
+
+void kbd_close(void *foo)
+{
+    shutdown_kbdfront(kbd_dev);
+    kbd_dev = NULL;
+}
+
+void fb_close(void)
+{
+    create_thread("kbdfront close", kbd_close, NULL);
+    shutdown_fbfront(fb_dev);
+    fb_dev = NULL;
+}
+
+/*
+ * Misc
+ */
+
+int getrtsecs (void)
+{
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec;
+}
+
+int currticks (void)
+{
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return ((tv.tv_sec * 1000000ULL + tv.tv_usec) * TICKS_PER_SEC) / 1000000;
+}
+
+void __attribute__ ((noreturn)) grub_reboot (void)
+{
+    for ( ;; )
+    {
+        struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_reboot };
+        HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
+    }
+}
+
+#define SCRATCH_MEMSIZE (4 * 1024 * 1024)
+
+/* Note: not allocating it dynamically permits to make sure it lays below 4G
+ * for grub's 32bit pointers to work */
+char grub_scratch_mem[SCRATCH_MEMSIZE] __attribute__((aligned(PAGE_SIZE)));
+
+int main(int argc, char *argv[])
+{
+    if (argc > 1) {
+        strncpy(config_file, argv[1], sizeof(config_file) - 1);
+        config_file[sizeof(config_file) - 1] = 0;
+        if (!strncmp(config_file, "(nd)", 4))
+            preset_menu = "dhcp";
+    } else
+        preset_menu = "dhcp --with-configfile";
+
+    mbi.drives_addr = BOOTSEC_LOCATION + (60 * 1024);
+    mbi.drives_length = 0;
+
+    mbi.boot_loader_name = (unsigned long) "GNU GRUB " VERSION;
+    mbi.mem_lower = (start_info.nr_pages * PAGE_SIZE) / 1024;
+    mbi.mem_upper = 0;
+    saved_drive = boot_drive;
+    saved_partition = install_partition;
+
+    init_disk();
+
+    /* Try to make sure the client part got launched */
+    sleep(1);
+    cmain();
+    printk("cmain returned!\n");
+}
diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub/mini-os.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/stubdom/grub/mini-os.h    Thu Jun 19 12:46:26 2008 +0900
@@ -0,0 +1,5 @@
+extern int blk_nb;
+extern struct blkfront_dev **blk_dev;
+extern struct netfront_dev *net_dev;
+extern struct kbdfront_dev *kbd_dev;
+extern struct fbfront_dev *fb_dev;
diff -r 1201c7657832 -r 0034766b45c2 stubdom/grub/osdep.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/stubdom/grub/osdep.h      Thu Jun 19 12:46:26 2008 +0900
@@ -0,0 +1,30 @@
+#ifndef __OSDEP_H__
+#define __OSDEP_H__
+
+#include <byteswap.h>
+#define swap32(x) bswap_32(x)
+#define swap16(x) bswap_16(x)
+
+#include <machine/endian.h>
+#if BYTE_ORDER == BIG_ENDIAN
+#define htons(x) (x)
+#define ntohs(x) (x)
+#define htonl(x) (x)
+#define ntohl(x) (x)
+#else
+#define htons(x) swap16(x)
+#define ntohs(x) swap16(x)
+#define htonl(x) swap32(x)
+#define ntohl(x) swap32(x)
+#endif
+
+typedef unsigned long Address;
+
+/* ANSI prototyping macro */
+#ifdef  __STDC__
+#define P(x)   x
+#else
+#define P(x)   ()
+#endif
+
+#endif
diff -r 1201c7657832 -r 0034766b45c2 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/console/daemon/io.c Thu Jun 19 12:46:26 2008 +0900
@@ -525,7 +525,8 @@ static int domain_create_ring(struct dom
        } else
                dom->use_consolepath = 0;
 
-       sprintf(path, "%s/type", dom->use_consolepath ? dom->conspath: 
dom->serialpath);
+       snprintf(path, sizeof(path), "%s/type",
+               dom->use_consolepath ? dom->conspath: dom->serialpath);
        type = xs_read(xs, XBT_NULL, path, NULL);
        if (type && strcmp(type, "xenconsoled") != 0) {
                free(type);
diff -r 1201c7657832 -r 0034766b45c2 tools/examples/xmexample.hvm
--- a/tools/examples/xmexample.hvm      Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/examples/xmexample.hvm      Thu Jun 19 12:46:26 2008 +0900
@@ -256,16 +256,16 @@ serial='pty'
 #vcpus=5
 #
 #  Downgrade the cpuid to make a better compatibility for migration :
-# Look like a PIII :
-# cpuid = [ '0:eax=0x3',
+# Look like a generic 686 :
+# cpuid = [ '0:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0',
 #           '1:eax=0x06b1,
 #              ecx=xxxxxxxxxx0000xx00xxx0000000xx0,
 #              edx=xx00000xxxxxxx0xxxxxxxxx0xxxxxx',
-#           '4:eax=0x3,ebx=0x756e6547,ecx=0x6c65746e,edx=0x49656e69',
-#  '0x80000000:eax=0x3,ebx=0x756e6547,ecx=0x6c65746e,edx=0x49656e69']
+#           '4:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0',
+#  '0x80000000:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0']
 #  with the highest leaf
 #  - CPUID.0[EAX] : Set the highest leaf
-#  - CPUID.1[EAX] : Pentium III
+#  - CPUID.1[EAX] : 686 
 #  - CPUID.1[ECX] : Mask some features
 #  - CPUID.1[EDX] : Mask some features
 #  - CPUID.4 : Reply like the highest leaf, in our case CPUID.3
diff -r 1201c7657832 -r 0034766b45c2 tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c  Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/firmware/rombios/rombios.c  Thu Jun 19 12:46:26 2008 +0900
@@ -2311,10 +2311,31 @@ debugger_off()
 #define ACPI_FACS_OFFSET 0x10
 /* S3 resume status in CMOS 0Fh shutdown status byte*/
 
+Bit32u facs_get32(offs)
+Bit16u offs;
+{
+ASM_START
+  push bp
+  mov  bp, sp
+
+    push ds
+    mov ax, #(ACPI_FACS_ADDRESS >> 4)
+    mov ds, ax
+
+    mov bx, 4[bp]
+    mov ax, [bx]
+    mov dx, 2[bx]
+    pop ds
+
+  pop  bp
+ASM_END
+}
+
+
 void 
 s3_resume()
 {
-    Bit16u s3_wakeup_vector;
+    Bit32u s3_wakeup_vector;
     extern Bit16u s3_wakeup_ip;
     extern Bit16u s3_wakeup_cs;
     extern Bit8u s3_resume_flag;
@@ -2330,19 +2351,14 @@ ASM_END
     }
     s3_resume_flag = 0;
 
-ASM_START
-    mov ax, #0x0
-    mov ds, ax
-ASM_END
-
     /* get x_firmware_waking_vector */
-    s3_wakeup_vector = *((Bit16u*)(ACPI_FACS_ADDRESS+ACPI_FACS_OFFSET+24));
-    if (s3_wakeup_vector == 0){
+    s3_wakeup_vector = facs_get32(ACPI_FACS_OFFSET+24);
+    if (!s3_wakeup_vector) {
         /* get firmware_waking_vector */
-        s3_wakeup_vector = *((Bit16u*)(ACPI_FACS_ADDRESS+ACPI_FACS_OFFSET+12));
-        if (s3_wakeup_vector == 0){
+       s3_wakeup_vector = facs_get32(ACPI_FACS_OFFSET+12);
+       if (!s3_wakeup_vector) {
             goto s3_out;
-        }
+       }
     }
 
     /* setup wakeup vector */
@@ -2350,13 +2366,6 @@ ASM_END
     s3_wakeup_cs = s3_wakeup_vector >> 4;
 
 ASM_START
-    mov bx, [_s3_wakeup_cs]
-    mov dx, [_s3_wakeup_ip]
-
-    mov ax, #0xF000
-    mov ds, ax
-    mov [_s3_wakeup_cs], bx
-    mov [_s3_wakeup_ip], dx
     jmpf [_s3_wakeup_ip]
 
 ; S3 data
diff -r 1201c7657832 -r 0034766b45c2 tools/fs-back/fs-ops.c
--- a/tools/fs-back/fs-ops.c    Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/fs-back/fs-ops.c    Thu Jun 19 12:46:26 2008 +0900
@@ -55,7 +55,8 @@ void dispatch_file_open(struct mount *mo
     printf("File open issued for %s\n", file_name); 
     assert(BUFFER_SIZE > 
            strlen(file_name) + strlen(mount->export->export_path) + 1); 
-    sprintf(full_path, "%s/%s", mount->export->export_path, file_name);
+    snprintf(full_path, sizeof(full_path), "%s/%s",
+           mount->export->export_path, file_name);
     assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0);
     printf("Issuing open for %s\n", full_path);
     fd = open(full_path, O_RDWR);
@@ -311,7 +312,8 @@ void dispatch_remove(struct mount *mount
     printf("File remove issued for %s\n", file_name); 
     assert(BUFFER_SIZE > 
            strlen(file_name) + strlen(mount->export->export_path) + 1); 
-    sprintf(full_path, "%s/%s", mount->export->export_path, file_name);
+    snprintf(full_path, sizeof(full_path), "%s/%s",
+           mount->export->export_path, file_name);
     assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0);
     printf("Issuing remove for %s\n", full_path);
     ret = remove(full_path);
@@ -355,8 +357,10 @@ void dispatch_rename(struct mount *mount
            strlen(old_file_name) + strlen(mount->export->export_path) + 1); 
     assert(BUFFER_SIZE > 
            strlen(new_file_name) + strlen(mount->export->export_path) + 1); 
-    sprintf(old_full_path, "%s/%s", mount->export->export_path, old_file_name);
-    sprintf(new_full_path, "%s/%s", mount->export->export_path, new_file_name);
+    snprintf(old_full_path, sizeof(old_full_path), "%s/%s",
+           mount->export->export_path, old_file_name);
+    snprintf(new_full_path, sizeof(new_full_path), "%s/%s",
+           mount->export->export_path, new_file_name);
     assert(xc_gnttab_munmap(mount->gnth, buf, 1) == 0);
     printf("Issuing rename for %s -> %s\n", old_full_path, new_full_path);
     ret = rename(old_full_path, new_full_path);
@@ -398,7 +402,8 @@ void dispatch_create(struct mount *mount
     printf("File create issued for %s\n", file_name); 
     assert(BUFFER_SIZE > 
            strlen(file_name) + strlen(mount->export->export_path) + 1); 
-    sprintf(full_path, "%s/%s", mount->export->export_path, file_name);
+    snprintf(full_path, sizeof(full_path), "%s/%s",
+           mount->export->export_path, file_name);
     assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0);
     /* We can advance the request consumer index, from here on, the request
      * should not be used (it may be overrinden by a response) */
@@ -447,7 +452,8 @@ void dispatch_list(struct mount *mount, 
     printf("Dir list issued for %s\n", file_name); 
     assert(BUFFER_SIZE > 
            strlen(file_name) + strlen(mount->export->export_path) + 1); 
-    sprintf(full_path, "%s/%s", mount->export->export_path, file_name);
+    snprintf(full_path, sizeof(full_path), "%s/%s",
+           mount->export->export_path, file_name);
     /* We can advance the request consumer index, from here on, the request
      * should not be used (it may be overrinden by a response) */
     mount->ring.req_cons++;
@@ -540,7 +546,8 @@ void dispatch_fs_space(struct mount *mou
     printf("Fs space issued for %s\n", file_name); 
     assert(BUFFER_SIZE > 
            strlen(file_name) + strlen(mount->export->export_path) + 1); 
-    sprintf(full_path, "%s/%s", mount->export->export_path, file_name);
+    snprintf(full_path, sizeof(full_path), "%s/%s",
+           mount->export->export_path, file_name);
     assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0);
     printf("Issuing fs space for %s\n", full_path);
     ret = statfs(full_path, &stat);
diff -r 1201c7657832 -r 0034766b45c2 tools/fs-back/fs-xenbus.c
--- a/tools/fs-back/fs-xenbus.c Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/fs-back/fs-xenbus.c Thu Jun 19 12:46:26 2008 +0900
@@ -22,8 +22,8 @@ static bool xenbus_printf(struct xs_hand
     va_list args;
     
     va_start(args, fmt);
-    sprintf(fullpath,"%s/%s", node, path);
-    vsprintf(val, fmt, args);
+    snprintf(fullpath, sizeof(fullpath), "%s/%s", node, path);
+    vsnprintf(val, sizeof(val), fmt, args);
     va_end(args);
     printf("xenbus_printf (%s) <= %s.\n", fullpath, val);    
 
@@ -72,7 +72,7 @@ int xenbus_register_export(struct fs_exp
     printf("XS transaction is %d\n", xst); 
  
     /* Create node string */
-    sprintf(node, "%s/%d", EXPORTS_NODE, export->export_id); 
+    snprintf(node, sizeof(node), "%s/%d", EXPORTS_NODE, export->export_id); 
     /* Remove old export (if exists) */ 
     xs_rm(xsh, xst, node);
 
@@ -116,20 +116,20 @@ void xenbus_read_mount_request(struct mo
 
     assert(xsh != NULL);
 #if 0
-    sprintf(node, WATCH_NODE"/%d/%d/frontend", 
+    snprintf(node, sizeof(node), WATCH_NODE"/%d/%d/frontend", 
                            mount->dom_id, mount->export->export_id);
     frontend = xs_read(xsh, XBT_NULL, node, NULL);
 #endif
     mount->frontend = frontend;
-    sprintf(node, "%s/state", frontend);
+    snprintf(node, sizeof(node), "%s/state", frontend);
     s = xs_read(xsh, XBT_NULL, node, NULL);
     assert(strcmp(s, STATE_READY) == 0);
     free(s);
-    sprintf(node, "%s/ring-ref", frontend);
+    snprintf(node, sizeof(node), "%s/ring-ref", frontend);
     s = xs_read(xsh, XBT_NULL, node, NULL);
     mount->gref = atoi(s);
     free(s);
-    sprintf(node, "%s/event-channel", frontend);
+    snprintf(node, sizeof(node), "%s/event-channel", frontend);
     s = xs_read(xsh, XBT_NULL, node, NULL);
     mount->remote_evtchn = atoi(s);
     free(s);
@@ -158,12 +158,12 @@ void xenbus_write_backend_node(struct mo
     assert(xsh != NULL);
     self_id = get_self_id();
     printf("Our own dom_id=%d\n", self_id);
-    sprintf(node, "%s/backend", mount->frontend);
-    sprintf(backend_node, "/local/domain/%d/"ROOT_NODE"/%d",
+    snprintf(node, sizeof(node), "%s/backend", mount->frontend);
+    snprintf(backend_node, sizeof(backend_node), 
"/local/domain/%d/"ROOT_NODE"/%d",
                                 self_id, mount->mount_id);
     xs_write(xsh, XBT_NULL, node, backend_node, strlen(backend_node));
 
-    sprintf(node, ROOT_NODE"/%d/state", mount->mount_id);
+    snprintf(node, sizeof(node), ROOT_NODE"/%d/state", mount->mount_id);
     xs_write(xsh, XBT_NULL, node, STATE_INITIALISED, 
strlen(STATE_INITIALISED));
 }
 
@@ -174,7 +174,7 @@ void xenbus_write_backend_ready(struct m
 
     assert(xsh != NULL);
     self_id = get_self_id();
-    sprintf(node, ROOT_NODE"/%d/state", mount->mount_id);
+    snprintf(node, sizeof(node), ROOT_NODE"/%d/state", mount->mount_id);
     xs_write(xsh, XBT_NULL, node, STATE_READY, strlen(STATE_READY));
 }
 
diff -r 1201c7657832 -r 0034766b45c2 tools/include/xen-sys/NetBSD/privcmd.h
--- a/tools/include/xen-sys/NetBSD/privcmd.h    Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/include/xen-sys/NetBSD/privcmd.h    Thu Jun 19 12:46:26 2008 +0900
@@ -36,6 +36,7 @@ typedef struct privcmd_hypercall
 {
     unsigned long op;
     unsigned long arg[5];
+    long retval;
 } privcmd_hypercall_t;
 
 typedef struct privcmd_mmap_entry {
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/Makefile.target
--- a/tools/ioemu/Makefile.target       Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/ioemu/Makefile.target       Thu Jun 19 12:46:26 2008 +0900
@@ -358,13 +358,6 @@ endif
 endif
 
 ifdef CONFIG_STUBDOM
-VL_OBJS+=main-qemu.o
-CFLAGS += -DCONFIG_QEMU
-main-qemu.c:
-       ln -s $(XEN_ROOT)/extras/mini-os/main.c $@
-endif
-
-ifdef CONFIG_STUBDOM
 #CONFIG_PASSTHROUGH=1
 else
   ifeq (,$(wildcard /usr/include/pci))
@@ -444,7 +437,11 @@ VL_OBJS+= xen_machine_fv.o
 VL_OBJS+= xen_machine_fv.o
 VL_OBJS+= xen_machine_pv.o
 VL_OBJS+= xenfb.o
+ifdef CONFIG_STUBDOM
+VL_OBJS+= xenfbfront.o
+endif
 VL_OBJS+= xen_console.o
+VL_OBJS+= pci_emulation.o
 ifndef CONFIG_STUBDOM
 VL_OBJS+= tpm_tis.o
 VL_OBJS+= $(SOUND_HW) $(AUDIODRV) mixeng.o 
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/cocoa.m
--- a/tools/ioemu/cocoa.m       Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/ioemu/cocoa.m       Thu Jun 19 12:46:26 2008 +0900
@@ -96,7 +96,7 @@ static void cocoa_update(DisplayState *d
     cocoa_resize
  ------------------------------------------------------
 */
-static void cocoa_resize(DisplayState *ds, int w, int h, int linesize)
+static void cocoa_resize(DisplayState *ds, int w, int h)
 {
     const int device_bpp = 32;
     static void *screen_pixels;
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/pc.c
--- a/tools/ioemu/hw/pc.c       Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/ioemu/hw/pc.c       Thu Jun 19 12:46:26 2008 +0900
@@ -1090,6 +1090,13 @@ static void pc_init1(uint64_t ram_size, 
         }
     }
 #endif /* !CONFIG_DM */
+
+    if (pci_enabled) {
+        PCI_EMULATION_INFO *p;
+        for (p = PciEmulationInfoHead; p != NULL; p = p->next) {
+            pci_emulation_init(pci_bus, p);
+        }
+    }
 }
 
 static void pc_init_pci(uint64_t ram_size, int vga_ram_size, char *boot_device,
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/pci_emulation.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/hw/pci_emulation.c    Thu Jun 19 12:46:26 2008 +0900
@@ -0,0 +1,118 @@
+/*
+ * Changes to PCI emulation made by Marathon Technologies, June 2008
+ */
+
+#include "vl.h"
+
+typedef struct {
+    PCIDevice dev;
+}   PCI_EMULATION_State;
+
+void parse_pci_emulation_info(char *config_text, PCI_EMULATION_INFO 
*pci_emulation_info)
+{
+    char *p;
+    int i;
+    int ret;
+    for (p = config_text, i = 0; *p != '\0'; p++) {
+        if (*p == ':') {
+            break;
+        }
+        if (i < sizeof(pci_emulation_info->name) - 1) {
+            pci_emulation_info->name[i] = *p;
+            i++;
+        }
+    }
+    pci_emulation_info->name[i] = '\0';
+    if (*p == '\0') return;
+    p++;
+    ret = sscanf(p, "%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x",
+                 &(pci_emulation_info->vendorid),
+                 &(pci_emulation_info->deviceid),
+                 &(pci_emulation_info->command),
+                 &(pci_emulation_info->status),
+                 &(pci_emulation_info->revision),
+                 &(pci_emulation_info->classcode),
+                 &(pci_emulation_info->headertype),
+                 &(pci_emulation_info->subvendorid),
+                 &(pci_emulation_info->subsystemid),
+                 &(pci_emulation_info->interruputline),
+                 &(pci_emulation_info->interruputpin));
+#ifdef DEBUG
+    fprintf(logfile, "qemu: pciemulation 
%s:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x\n",
+            pci_emulation_info->name,
+            pci_emulation_info->vendorid,
+            pci_emulation_info->deviceid,
+            pci_emulation_info->command,
+            pci_emulation_info->status,
+            pci_emulation_info->revision,
+            pci_emulation_info->classcode,
+            pci_emulation_info->headertype,
+            pci_emulation_info->subvendorid,
+            pci_emulation_info->subsystemid,
+            pci_emulation_info->interruputline,
+            pci_emulation_info->interruputpin);
+#endif
+    return;
+}
+
+static void pci_emulation_save(QEMUFile *f, void *opaque)
+{
+    PCIDevice *d = opaque;
+
+    pci_device_save(d, f);
+}
+
+static int pci_emulation_load(QEMUFile *f, void *opaque, int version_id)
+{
+    PCIDevice *d = opaque;
+
+    if (version_id != 1)
+        return -EINVAL;
+
+    return pci_device_load(d, f);
+}
+
+
+void pci_emulation_init(PCIBus *bus, PCI_EMULATION_INFO *pci_emulation_info)
+{
+    int instance_id;
+    PCI_EMULATION_State *d;
+    uint8_t *pci_conf;
+
+#ifdef DEBUG
+    fprintf(logfile, "qemu: pciinit\n");
+#endif
+    
+    d = (PCI_EMULATION_State *)pci_register_device(bus,
+                                                   pci_emulation_info->name, 
+                                                   sizeof(PCI_EMULATION_State),
+                                                   -1, 
+                                                    NULL, NULL);
+    pci_conf = d->dev.config;
+    pci_conf[0x00] = pci_emulation_info->vendorid & 0xff;
+    pci_conf[0x01] = (pci_emulation_info->vendorid & 0xff00) >> 8;
+    pci_conf[0x02] = pci_emulation_info->deviceid & 0xff;
+    pci_conf[0x03] = (pci_emulation_info->deviceid & 0xff00) >> 8;
+    pci_conf[0x04] = pci_emulation_info->command & 0xff;
+    pci_conf[0x05] = (pci_emulation_info->command & 0xff00) >> 8;
+    pci_conf[0x06] = pci_emulation_info->status & 0xff;
+    pci_conf[0x07] = (pci_emulation_info->status & 0xff00) >> 8;
+    pci_conf[0x08] = pci_emulation_info->revision & 0xff;
+    pci_conf[0x09] = pci_emulation_info->classcode & 0xff;
+    pci_conf[0x0a] = (pci_emulation_info->classcode & 0xff00) >> 8;
+    pci_conf[0x0b] = (pci_emulation_info->classcode & 0xff0000) >> 16;
+    pci_conf[0x0e] = pci_emulation_info->headertype & 0xff;
+    pci_conf[0x2c] = pci_emulation_info->subvendorid & 0xff;
+    pci_conf[0x2d] = (pci_emulation_info->subvendorid & 0xff00) >> 8;
+    pci_conf[0x2e] = pci_emulation_info->subsystemid & 0xff;
+    pci_conf[0x2f] = (pci_emulation_info->subsystemid & 0xff00) >> 8;
+    pci_conf[0x3c] = pci_emulation_info->interruputline & 0xff;
+    pci_conf[0x3d] = pci_emulation_info->interruputpin & 0xff;
+
+    instance_id = pci_bus_num(bus) << 8 | d->dev.devfn;
+    register_savevm(pci_emulation_info->name, instance_id,
+                    1, pci_emulation_save, pci_emulation_load, d);
+
+
+    return;    
+}
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/pci_emulation.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/hw/pci_emulation.h    Thu Jun 19 12:46:26 2008 +0900
@@ -0,0 +1,24 @@
+/*
+ * Changes to PCI emulation made by Marathon Technologies, June 2008
+ */
+
+typedef struct PCI_EMULATION_INFO_t {
+    struct PCI_EMULATION_INFO_t *next;
+    char name[32];
+    unsigned int vendorid;
+    unsigned int deviceid;
+    unsigned int command;
+    unsigned int status;
+    unsigned int revision;
+    unsigned int classcode;
+    unsigned int headertype;
+    unsigned int subvendorid;
+    unsigned int subsystemid;
+    unsigned int interruputline;
+    unsigned int interruputpin;
+}   PCI_EMULATION_INFO;
+    
+void parse_pci_emulation_info(char *config_text, PCI_EMULATION_INFO 
*pci_emulation_info);
+void pci_emulation_init(PCIBus *bus, PCI_EMULATION_INFO *pci_emulation_info);
+
+extern PCI_EMULATION_INFO *PciEmulationInfoHead;
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/pl110.c
--- a/tools/ioemu/hw/pl110.c    Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/ioemu/hw/pl110.c    Thu Jun 19 12:46:26 2008 +0900
@@ -262,7 +262,7 @@ static void pl110_resize(pl110_state *s,
 {
     if (width != s->cols || height != s->rows) {
         if (pl110_enabled(s)) {
-            dpy_resize(s->ds, width, height, width * 4);
+            dpy_resize(s->ds, width, height);
         }
     }
     s->cols = width;
@@ -375,7 +375,7 @@ static void pl110_write(void *opaque, ta
         s->cr = val;
         s->bpp = (val >> 1) & 7;
         if (pl110_enabled(s)) {
-            dpy_resize(s->ds, s->cols, s->rows, s->cols * 4);
+            dpy_resize(s->ds, s->cols, s->rows);
         }
         break;
     case 10: /* LCDICR */
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/tcx.c
--- a/tools/ioemu/hw/tcx.c      Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/ioemu/hw/tcx.c      Thu Jun 19 12:46:26 2008 +0900
@@ -342,7 +342,7 @@ void tcx_init(DisplayState *ds, uint32_t
     register_savevm("tcx", addr, 1, tcx_save, tcx_load, s);
     qemu_register_reset(tcx_reset, s);
     tcx_reset(s);
-    dpy_resize(s->ds, width, height, width * 1);
+    dpy_resize(s->ds, width, height);
 }
 
 static void tcx_screen_dump(void *opaque, const char *filename)
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/usb-msd.c
--- a/tools/ioemu/hw/usb-msd.c  Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/ioemu/hw/usb-msd.c  Thu Jun 19 12:46:26 2008 +0900
@@ -510,7 +510,7 @@ static void usb_msd_handle_destroy(USBDe
     qemu_free(s);
 }
 
-USBDevice *usb_msd_init(const char *filename)
+USBDevice *usb_msd_init(const char *filename, BlockDriver *drv)
 {
     MSDState *s;
     BlockDriverState *bdrv;
@@ -520,7 +520,7 @@ USBDevice *usb_msd_init(const char *file
         return NULL;
 
     bdrv = bdrv_new("usb");
-    if (bdrv_open(bdrv, filename, 0) < 0)
+    if (bdrv_open2(bdrv, filename, 0, drv) < 0)
         goto fail;
     s->bs = bdrv;
 
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/usb.h
--- a/tools/ioemu/hw/usb.h      Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/ioemu/hw/usb.h      Thu Jun 19 12:46:26 2008 +0900
@@ -217,7 +217,7 @@ USBDevice *usb_tablet_init(void);
 USBDevice *usb_tablet_init(void);
 
 /* usb-msd.c */
-USBDevice *usb_msd_init(const char *filename);
+USBDevice *usb_msd_init(const char *filename, BlockDriver *drv);
 
 /* usb.c */
 void generic_usb_save(QEMUFile* f, void *opaque);
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/vga.c
--- a/tools/ioemu/hw/vga.c      Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/ioemu/hw/vga.c      Thu Jun 19 12:46:26 2008 +0900
@@ -1089,40 +1089,6 @@ static void vga_draw_text(VGAState *s, i
     /* Disable dirty bit tracking */
     xc_hvm_track_dirty_vram(xc_handle, domid, 0, 0, NULL);
 
-    if (s->ds->dpy_colourdepth != NULL && s->ds->depth != 0)
-        s->ds->dpy_colourdepth(s->ds, 0);
-    s->rgb_to_pixel = 
-        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
-
-    full_update |= update_palette16(s);
-    palette = s->last_palette;
-    
-    /* compute font data address (in plane 2) */
-    v = s->sr[3];
-    offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
-    if (offset != s->font_offsets[0]) {
-        s->font_offsets[0] = offset;
-        full_update = 1;
-    }
-    font_base[0] = s->vram_ptr + offset;
-
-    offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
-    font_base[1] = s->vram_ptr + offset;
-    if (offset != s->font_offsets[1]) {
-        s->font_offsets[1] = offset;
-        full_update = 1;
-    }
-    if (s->plane_updated & (1 << 2)) {
-        /* if the plane 2 was modified since the last display, it
-           indicates the font may have been modified */
-        s->plane_updated = 0;
-        full_update = 1;
-    }
-    full_update |= update_basic_params(s);
-
-    line_offset = s->line_offset;
-    s1 = s->vram_ptr + (s->start_addr * 4);
-
     /* total width & height */
     cheight = (s->cr[9] & 0x1f) + 1;
     cw = 8;
@@ -1130,7 +1096,6 @@ static void vga_draw_text(VGAState *s, i
         cw = 9;
     if (s->sr[1] & 0x08)
         cw = 16; /* NOTE: no 18 pixel wide */
-    x_incr = cw * ((s->ds->depth + 7) >> 3);
     width = (s->cr[0x01] + 1);
     if (s->cr[0x06] == 100) {
         /* ugly hack for CGA 160x100x16 - explain me the logic */
@@ -1146,17 +1111,52 @@ static void vga_draw_text(VGAState *s, i
         return;
     }
 
+    s->last_scr_width = width * cw;
+    s->last_scr_height = height * cheight;
     if (width != s->last_width || height != s->last_height ||
-        cw != s->last_cw || cheight != s->last_ch) {
-        s->last_scr_width = width * cw;
-        s->last_scr_height = height * cheight;
-        dpy_resize(s->ds, s->last_scr_width, s->last_scr_height, 
s->last_scr_width * (s->ds->depth / 8));
-        s->last_width = width;
-        s->last_height = height;
-        s->last_ch = cheight;
-        s->last_cw = cw;
+        cw != s->last_cw || cheight != s->last_ch || s->last_depth) {
+        dpy_resize(s->ds, s->last_scr_width, s->last_scr_height);
+        s->last_depth = 0;
         full_update = 1;
     }
+    s->last_width = width;
+    s->last_height = height;
+    s->last_ch = cheight;
+    s->last_cw = cw;
+
+    s->rgb_to_pixel = 
+        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
+
+    full_update |= update_palette16(s);
+    palette = s->last_palette;
+    
+    x_incr = cw * ((s->ds->depth + 7) >> 3);
+    /* compute font data address (in plane 2) */
+    v = s->sr[3];
+    offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2;
+    if (offset != s->font_offsets[0]) {
+        s->font_offsets[0] = offset;
+        full_update = 1;
+    }
+    font_base[0] = s->vram_ptr + offset;
+
+    offset = (((v >> 5) & 1) | ((v >> 1) & 6)) * 8192 * 4 + 2;
+    font_base[1] = s->vram_ptr + offset;
+    if (offset != s->font_offsets[1]) {
+        s->font_offsets[1] = offset;
+        full_update = 1;
+    }
+    if (s->plane_updated & (1 << 2)) {
+        /* if the plane 2 was modified since the last display, it
+           indicates the font may have been modified */
+        s->plane_updated = 0;
+        full_update = 1;
+    }
+    full_update |= update_basic_params(s);
+
+    line_offset = s->line_offset;
+    s1 = s->vram_ptr + (s->start_addr * 4);
+
     cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
     if (cursor_offset != s->cursor_offset ||
         s->cr[0xa] != s->cursor_start ||
@@ -1501,16 +1501,6 @@ static void vga_draw_graphic(VGAState *s
     s->get_resolution(s, &width, &height);
     disp_width = width;
 
-    ds_depth = s->ds->depth;
-    depth = s->get_bpp(s);
-    if (s->ds->dpy_colourdepth != NULL && 
-            (ds_depth != depth || !s->ds->shared_buf))
-        s->ds->dpy_colourdepth(s->ds, depth);
-    if (ds_depth != s->ds->depth) full_update = 1;
-
-    s->rgb_to_pixel = 
-        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
-
     shift_control = (s->gr[0x05] >> 5) & 3;
     double_scan = (s->cr[0x09] >> 7);
     if (shift_control != 1) {
@@ -1527,12 +1517,44 @@ static void vga_draw_graphic(VGAState *s
         s->shift_control = shift_control;
         s->double_scan = double_scan;
     }
-    
+    if (shift_control == 1 && (s->sr[0x01] & 8)) {
+        disp_width <<= 1;
+    }
+
+    ds_depth = s->ds->depth;
+    depth = s->get_bpp(s);
+    if (s->ds->dpy_resize_shared) {
+        if (s->line_offset != s->last_line_offset || 
+            disp_width != s->last_width ||
+            height != s->last_height ||
+            s->last_depth != depth) {
+            dpy_resize_shared(s->ds, disp_width, height, depth, 
s->line_offset, s->vram_ptr + (s->start_addr * 4));
+            s->last_scr_width = disp_width;
+            s->last_scr_height = height;
+            s->last_width = disp_width;
+            s->last_height = height;
+            s->last_line_offset = s->line_offset;
+            s->last_depth = depth;
+            full_update = 1;
+        } else if (s->ds->shared_buf && (full_update || s->ds->data != 
s->vram_ptr + (s->start_addr * 4)))
+            s->ds->dpy_setdata(s->ds, s->vram_ptr + (s->start_addr * 4));
+    } else if (disp_width != s->last_width ||
+               height != s->last_height) {
+        dpy_resize(s->ds, disp_width, height);
+        s->last_scr_width = disp_width;
+        s->last_scr_height = height;
+        s->last_width = disp_width;
+        s->last_height = height;
+        full_update = 1;
+    }
+
+    s->rgb_to_pixel = 
+        rgb_to_pixel_dup_table[get_depth_index(s->ds)];
+
     if (shift_control == 0) {
         full_update |= update_palette16(s);
         if (s->sr[0x01] & 8) {
             v = VGA_DRAW_LINE4D2;
-            disp_width <<= 1;
         } else {
             v = VGA_DRAW_LINE4;
         }
@@ -1541,7 +1563,6 @@ static void vga_draw_graphic(VGAState *s
         full_update |= update_palette16(s);
         if (s->sr[0x01] & 8) {
             v = VGA_DRAW_LINE2D2;
-            disp_width <<= 1;
         } else {
             v = VGA_DRAW_LINE2;
         }
@@ -1579,19 +1600,6 @@ static void vga_draw_graphic(VGAState *s
     }
 
     vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + 
get_depth_index(s->ds)];
-    if (s->line_offset != s->last_line_offset || 
-        disp_width != s->last_width ||
-        height != s->last_height) {
-        dpy_resize(s->ds, disp_width, height, s->line_offset);
-        s->last_scr_width = disp_width;
-        s->last_scr_height = height;
-        s->last_width = disp_width;
-        s->last_height = height;
-        s->last_line_offset = s->line_offset; 
-        full_update = 1;
-    }
-    if (s->ds->shared_buf && (full_update || s->ds->data != s->vram_ptr + 
(s->start_addr * 4)))
-        s->ds->dpy_setdata(s->ds, s->vram_ptr + (s->start_addr * 4));
     if (!s->ds->shared_buf && s->cursor_invalidate)
         s->cursor_invalidate(s);
     
@@ -2143,6 +2151,11 @@ void vga_common_init(VGAState *s, Displa
     /* Video RAM must be 128-bit aligned for SSE optimizations later */
     /* and page-aligned for PVFB memory sharing */
     s->vram_ptr = s->vram_alloc = qemu_memalign(TARGET_PAGE_SIZE, 
vga_ram_size);
+
+#ifdef CONFIG_STUBDOM
+    if (!cirrus_vga_enabled)
+        xenfb_pv_display_start(s->vram_ptr);
+#endif
 
     s->vram_offset = vga_ram_offset;
     s->vram_size = vga_ram_size;
@@ -2311,7 +2324,7 @@ static void vga_save_dpy_update(DisplayS
 {
 }
 
-static void vga_save_dpy_resize(DisplayState *s, int w, int h, int linesize)
+static void vga_save_dpy_resize(DisplayState *s, int w, int h)
 {
     s->linesize = w * 4;
     s->data = qemu_malloc(h * s->linesize);
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/vga_int.h
--- a/tools/ioemu/hw/vga_int.h  Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/ioemu/hw/vga_int.h  Thu Jun 19 12:46:26 2008 +0900
@@ -135,6 +135,7 @@
     uint8_t last_cw, last_ch;                                           \
     uint32_t last_width, last_height; /* in chars or pixels */          \
     uint32_t last_scr_width, last_scr_height; /* in pixels */           \
+    uint32_t last_depth; /* in bits */                                  \
     uint8_t cursor_start, cursor_end;                                   \
     uint32_t cursor_offset;                                             \
     unsigned int (*rgb_to_pixel)(unsigned int r,                        \
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/xenfb.c
--- a/tools/ioemu/hw/xenfb.c    Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/ioemu/hw/xenfb.c    Thu Jun 19 12:46:26 2008 +0900
@@ -19,12 +19,6 @@
 
 #include "xenfb.h"
 
-#ifdef CONFIG_STUBDOM
-#include <semaphore.h>
-#include <sched.h>
-#include <fbfront.h>
-#endif
-
 #ifndef BTN_LEFT
 #define BTN_LEFT 0x110 /* from <linux/input.h> */
 #endif
@@ -90,7 +84,7 @@ static int xenfb_register_console(struct
  * Scancodes are hardware-specific.  These maps assumes a 
  * standard AT or PS/2 keyboard which is what QEMU feeds us.
  */
-static const unsigned char atkbd_set2_keycode[512] = {
+const unsigned char atkbd_set2_keycode[512] = {
 
          0, 67, 65, 63, 61, 59, 60, 88,  0, 68, 66, 64, 62, 15, 41,117,
          0, 56, 42, 93, 29, 16,  2,  0,  0,  0, 44, 31, 30, 17,  3,  0,
@@ -112,7 +106,7 @@ static const unsigned char atkbd_set2_ke
 
 };
 
-static const unsigned char atkbd_unxlate_table[128] = {
+const unsigned char atkbd_unxlate_table[128] = {
 
          0,118, 22, 30, 38, 37, 46, 54, 61, 62, 70, 69, 78, 85,102, 13,
         21, 29, 36, 45, 44, 53, 60, 67, 68, 77, 84, 91, 90, 20, 28, 27,
@@ -587,10 +581,10 @@ static void xenfb_on_fb_event(struct xen
                                               event->resize.offset,
                                               event->resize.stride) < 0)
                                break;
-                       dpy_colourdepth(xenfb->ds, xenfb->depth);
-                       dpy_resize(xenfb->ds, xenfb->width, xenfb->height, 
xenfb->row_stride);
-                       if (xenfb->ds->shared_buf)
-                               dpy_setdata(xenfb->ds, xenfb->pixels + 
xenfb->offset);
+                       if (xenfb->ds->dpy_resize_shared)
+                           dpy_resize_shared(xenfb->ds, xenfb->width, 
xenfb->height, xenfb->depth, xenfb->row_stride, xenfb->pixels + xenfb->offset);
+                       else
+                           dpy_resize(xenfb->ds, xenfb->width, xenfb->height);
                        xenfb_invalidate(xenfb);
                        break;
                }
@@ -1324,10 +1318,10 @@ static int xenfb_register_console(struct
                             xenfb_invalidate,
                             xenfb_screen_dump,
                             xenfb);
-       dpy_colourdepth(xenfb->ds, xenfb->depth);
-        dpy_resize(xenfb->ds, xenfb->width, xenfb->height, xenfb->row_stride);
-       if (xenfb->ds->shared_buf)
-           dpy_setdata(xenfb->ds, xenfb->pixels);
+        if (xenfb->ds->dpy_resize_shared)
+            dpy_resize_shared(xenfb->ds, xenfb->width, xenfb->height, 
xenfb->depth, xenfb->row_stride, xenfb->pixels + xenfb->offset);
+        else
+            dpy_resize(xenfb->ds, xenfb->width, xenfb->height);
 
        if (qemu_set_fd_handler2(xc_evtchn_fd(xenfb->evt_xch), NULL, 
xenfb_dispatch_channel, NULL, xenfb) < 0)
                return -1;
@@ -1337,323 +1331,6 @@ static int xenfb_register_console(struct
         fprintf(stderr, "Xen Framebuffer registered\n");
         return 0;
 }
-
-#ifdef CONFIG_STUBDOM
-typedef struct XenFBState {
-    struct semaphore kbd_sem;
-    struct kbdfront_dev *kbd_dev;
-    struct fbfront_dev *fb_dev;
-    void *vga_vram, *nonshared_vram;
-    DisplayState *ds;
-} XenFBState;
-
-XenFBState *xs;
-
-static char *kbd_path, *fb_path;
-
-static unsigned char linux2scancode[KEY_MAX + 1];
-
-int xenfb_connect_vkbd(const char *path)
-{
-    kbd_path = strdup(path);
-    return 0;
-}
-
-int xenfb_connect_vfb(const char *path)
-{
-    fb_path = strdup(path);
-    return 0;
-}
-
-static void xenfb_pv_update(DisplayState *ds, int x, int y, int w, int h)
-{
-    XenFBState *xs = ds->opaque;
-    struct fbfront_dev *fb_dev = xs->fb_dev;
-    if (!fb_dev)
-        return;
-    fbfront_update(fb_dev, x, y, w, h);
-}
-
-static void xenfb_pv_resize(DisplayState *ds, int w, int h, int linesize)
-{
-    XenFBState *xs = ds->opaque;
-    struct fbfront_dev *fb_dev = xs->fb_dev;
-    fprintf(stderr,"resize to %dx%d, %d required\n", w, h, linesize);
-    ds->width = w;
-    ds->height = h;
-    if (!linesize)
-        ds->shared_buf = 0;
-    if (!ds->shared_buf)
-        linesize = w * 4;
-    ds->linesize = linesize;
-    if (!fb_dev)
-        return;
-    if (ds->shared_buf) {
-        ds->data = NULL;
-    } else {
-        ds->data = xs->nonshared_vram;
-        fbfront_resize(fb_dev, w, h, linesize, ds->depth, VGA_RAM_SIZE);
-    }
-}
-
-static void xenfb_pv_colourdepth(DisplayState *ds, int depth)
-{
-    XenFBState *xs = ds->opaque;
-    struct fbfront_dev *fb_dev = xs->fb_dev;
-    static int lastdepth = -1;
-    if (!depth) {
-        ds->shared_buf = 0;
-        ds->depth = 32;
-    } else {
-        ds->shared_buf = 1;
-        ds->depth = depth;
-    }
-    if (depth != lastdepth) {
-        fprintf(stderr,"redepth to %d required\n", depth);
-        lastdepth = depth;
-    } else return;
-    if (!fb_dev)
-        return;
-    if (ds->shared_buf) {
-        ds->data = NULL;
-    } else {
-        ds->data = xs->nonshared_vram;
-        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, 
VGA_RAM_SIZE);
-    }
-}
-
-static void xenfb_pv_setdata(DisplayState *ds, void *pixels)
-{
-    XenFBState *xs = ds->opaque;
-    struct fbfront_dev *fb_dev = xs->fb_dev;
-    int offset = pixels - xs->vga_vram;
-    ds->data = pixels;
-    if (!fb_dev)
-        return;
-    fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, 
offset);
-}
-
-static void xenfb_pv_refresh(DisplayState *ds)
-{
-    vga_hw_update();
-}
-
-static void xenfb_fb_handler(void *opaque)
-{
-#define FB_NUM_BATCH 4
-    union xenfb_in_event buf[FB_NUM_BATCH];
-    int n, i;
-    XenFBState *xs = opaque;
-    DisplayState *ds = xs->ds;
-
-    n = fbfront_receive(xs->fb_dev, buf, FB_NUM_BATCH);
-    for (i = 0; i < n; i++) {
-        switch (buf[i].type) {
-        case XENFB_TYPE_REFRESH_PERIOD:
-            if (buf[i].refresh_period.period == XENFB_NO_REFRESH) {
-                /* Sleeping interval */
-                ds->idle = 1;
-                ds->gui_timer_interval = 500;
-            } else {
-                /* Set interval */
-                ds->idle = 0;
-                ds->gui_timer_interval = buf[i].refresh_period.period;
-            }
-        default:
-            /* ignore unknown events */
-            break;
-        }
-    }
-}
-
-static void xenfb_kbd_handler(void *opaque)
-{
-#define KBD_NUM_BATCH 64
-    union xenkbd_in_event buf[KBD_NUM_BATCH];
-    int n, i;
-    XenFBState *xs = opaque;
-    DisplayState *s = xs->ds;
-    static int buttons;
-    static int x, y;
-
-    n = kbdfront_receive(xs->kbd_dev, buf, KBD_NUM_BATCH);
-    for (i = 0; i < n; i++) {
-        switch (buf[i].type) {
-
-            case XENKBD_TYPE_MOTION:
-                fprintf(stderr, "FB backend sent us relative mouse motion 
event!\n");
-                break;
-
-            case XENKBD_TYPE_POS:
-            {
-                int new_x = buf[i].pos.abs_x;
-                int new_y = buf[i].pos.abs_y;
-                if (new_x >= s->width)
-                    new_x = s->width - 1;
-                if (new_y >= s->height)
-                    new_y = s->height - 1;
-                if (kbd_mouse_is_absolute()) {
-                    kbd_mouse_event(
-                            new_x * 0x7FFF / (s->width - 1),
-                            new_y * 0x7FFF / (s->height - 1),
-                            buf[i].pos.rel_z,
-                            buttons);
-                } else {
-                    kbd_mouse_event(
-                            new_x - x,
-                            new_y - y,
-                            buf[i].pos.rel_z,
-                            buttons);
-                }
-                x = new_x;
-                y = new_y;
-                break;
-            }
-
-            case XENKBD_TYPE_KEY:
-            {
-                int keycode = buf[i].key.keycode;
-                int button = 0;
-
-                if (keycode == BTN_LEFT)
-                    button = MOUSE_EVENT_LBUTTON;
-                else if (keycode == BTN_RIGHT)
-                    button = MOUSE_EVENT_RBUTTON;
-                else if (keycode == BTN_MIDDLE)
-                    button = MOUSE_EVENT_MBUTTON;
-
-                if (button) {
-                    if (buf[i].key.pressed)
-                        buttons |=  button;
-                    else
-                        buttons &= ~button;
-                    if (kbd_mouse_is_absolute())
-                        kbd_mouse_event(
-                                x * 0x7FFF / (s->width - 1),
-                                y * 0x7FFF / (s->height - 1),
-                                0,
-                                buttons);
-                    else
-                        kbd_mouse_event(0, 0, 0, buttons);
-                } else {
-                    int scancode = linux2scancode[keycode];
-                    if (!scancode) {
-                        fprintf(stderr, "Can't convert keycode %x to 
scancode\n", keycode);
-                        break;
-                    }
-                    if (scancode & 0x80) {
-                        kbd_put_keycode(0xe0);
-                        scancode &= 0x7f;
-                    }
-                    if (!buf[i].key.pressed)
-                        scancode |= 0x80;
-                    kbd_put_keycode(scancode);
-                }
-                break;
-            }
-        }
-    }
-}
-
-static void kbdfront_thread(void *p)
-{
-    int scancode, keycode;
-    XenFBState *xs = p;
-    xs->kbd_dev = init_kbdfront(kbd_path, 1);
-    if (!xs->kbd_dev) {
-        fprintf(stderr,"can't open keyboard\n");
-        exit(1);
-    }
-    up(&xs->kbd_sem);
-    for (scancode = 0; scancode < 128; scancode++) {
-        keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode]];
-        linux2scancode[keycode] = scancode;
-        keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode] | 0x80];
-        linux2scancode[keycode] = scancode | 0x80;
-    }
-}
-
-int xenfb_pv_display_init(DisplayState *ds)
-{
-    if (!fb_path || !kbd_path)
-        return -1;
-
-    xs = qemu_mallocz(sizeof(XenFBState));
-    if (!xs)
-        return -1;
-
-    init_SEMAPHORE(&xs->kbd_sem, 0);
-    xs->ds = ds;
-
-    create_thread("kbdfront", kbdfront_thread, (void*) xs);
-
-    ds->data = xs->nonshared_vram = qemu_memalign(PAGE_SIZE, VGA_RAM_SIZE);
-    memset(ds->data, 0, VGA_RAM_SIZE);
-    ds->opaque = xs;
-    ds->depth = 32;
-    ds->bgr = 0;
-    ds->width = 640;
-    ds->height = 400;
-    ds->linesize = 640 * 4;
-    ds->dpy_update = xenfb_pv_update;
-    ds->dpy_resize = xenfb_pv_resize;
-    ds->dpy_colourdepth = xenfb_pv_colourdepth;
-    ds->dpy_setdata = xenfb_pv_setdata;
-    ds->dpy_refresh = xenfb_pv_refresh;
-    return 0;
-}
-
-int xenfb_pv_display_start(void *data)
-{
-    DisplayState *ds;
-    struct fbfront_dev *fb_dev;
-    int kbd_fd, fb_fd;
-    int offset = 0;
-    unsigned long *mfns;
-    int n = VGA_RAM_SIZE / PAGE_SIZE;
-    int i;
-
-    if (!fb_path || !kbd_path)
-        return 0;
-
-    ds = xs->ds;
-    xs->vga_vram = data;
-    mfns = malloc(2 * n * sizeof(*mfns));
-    for (i = 0; i < n; i++)
-        mfns[i] = virtual_to_mfn(xs->vga_vram + i * PAGE_SIZE);
-    for (i = 0; i < n; i++)
-        mfns[n + i] = virtual_to_mfn(xs->nonshared_vram + i * PAGE_SIZE);
-
-    fb_dev = init_fbfront(fb_path, mfns, ds->width, ds->height, ds->depth, 
ds->linesize, 2 * n);
-    free(mfns);
-    if (!fb_dev) {
-        fprintf(stderr,"can't open frame buffer\n");
-        exit(1);
-    }
-    free(fb_path);
-
-    if (ds->shared_buf) {
-        offset = (void*) ds->data - xs->vga_vram;
-    } else {
-        offset = VGA_RAM_SIZE;
-        ds->data = xs->nonshared_vram;
-    }
-    if (offset)
-        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, 
offset);
-
-    down(&xs->kbd_sem);
-    free(kbd_path);
-
-    kbd_fd = kbdfront_open(xs->kbd_dev);
-    qemu_set_fd_handler(kbd_fd, xenfb_kbd_handler, NULL, xs);
-
-    fb_fd = fbfront_open(fb_dev);
-    qemu_set_fd_handler(fb_fd, xenfb_fb_handler, NULL, xs);
-
-    xs->fb_dev = fb_dev;
-    return 0;
-}
-#endif
 
 /*
  * Local variables:
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/hw/xenfb.h
--- a/tools/ioemu/hw/xenfb.h    Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/ioemu/hw/xenfb.h    Thu Jun 19 12:46:26 2008 +0900
@@ -9,5 +9,7 @@ struct xenfb;
 
 struct xenfb *xenfb_new(int domid, DisplayState *ds);
 void xenfb_shutdown(struct xenfb *xenfb);
+extern const unsigned char atkbd_set2_keycode[512];
+extern const unsigned char atkbd_unxlate_table[128];
 
 #endif
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/monitor.c
--- a/tools/ioemu/monitor.c     Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/ioemu/monitor.c     Thu Jun 19 12:46:26 2008 +0900
@@ -387,7 +387,7 @@ static void do_change_block(const char *
     }
     if (eject_device(bs, 0) < 0)
         return;
-    bdrv_open(bs, filename, 0);
+    bdrv_open2(bs, filename, 0, &bdrv_raw);
     if (bdrv_is_encrypted(bs)) {
         term_printf("%s is encrypted.\n", device);
         for(i = 0; i < 3; i++) {
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/sdl.c
--- a/tools/ioemu/sdl.c Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/ioemu/sdl.c Thu Jun 19 12:46:26 2008 +0900
@@ -50,6 +50,8 @@ static int absolute_enabled = 0;
 static int absolute_enabled = 0;
 static int opengl_enabled;
 
+static void sdl_colourdepth(DisplayState *ds, int depth);
+
 #ifdef CONFIG_OPENGL
 static GLint tex_format;
 static GLint tex_type;
@@ -211,11 +213,13 @@ static void sdl_setdata(DisplayState *ds
     ds->data = pixels;
 }
 
-static void sdl_resize(DisplayState *ds, int w, int h, int linesize)
+static void sdl_resize_shared(DisplayState *ds, int w, int h, int depth, int 
linesize, void *pixels)
 {
     int flags;
 
     //    printf("resizing to %d %d\n", w, h);
+
+    sdl_colourdepth(ds, depth);
 
 #ifdef CONFIG_OPENGL
     if (ds->shared_buf && opengl_enabled)
@@ -245,7 +249,8 @@ static void sdl_resize(DisplayState *ds,
             opengl_enabled = 0;
             ds->dpy_update = sdl_update;
             ds->dpy_setdata = sdl_setdata;
-            sdl_resize(ds, w, h, linesize);
+            ds->dpy_resize_shared = sdl_resize_shared;
+            sdl_resize_shared(ds, w, h, depth, linesize, pixels);
             return;
         }
         exit(1);
@@ -272,6 +277,7 @@ static void sdl_resize(DisplayState *ds,
         } else {
             ds->bgr = 0;
         }
+        shared = NULL;
         ds->data = screen->pixels;
         ds->linesize = screen->pitch;
     } else {
@@ -296,21 +302,26 @@ static void sdl_resize(DisplayState *ds,
         };
 #endif
     }
+    if (ds->shared_buf) ds->dpy_setdata(ds, pixels);
+}
+
+static void sdl_resize(DisplayState *ds, int w, int h)
+{
+    sdl_resize_shared(ds, w, h, 0, w * (ds->depth / 8), NULL);
 }
 
 static void sdl_colourdepth(DisplayState *ds, int depth)
 {
     if (!depth || !ds->depth) {
         ds->shared_buf = 0;
+        ds->dpy_update = sdl_update;
         return;
     }
     ds->shared_buf = 1;
     ds->depth = depth;
-    ds->linesize = width * depth / 8;
 #ifdef CONFIG_OPENGL
     if (opengl_enabled) {
         ds->dpy_update = opengl_update;
-        ds->dpy_setdata = opengl_setdata;
     }
 #endif
 }
@@ -517,8 +528,7 @@ static void toggle_full_screen(DisplaySt
 static void toggle_full_screen(DisplayState *ds)
 {
     gui_fullscreen = !gui_fullscreen;
-    sdl_resize(ds, ds->width, ds->height, ds->linesize);
-    ds->dpy_setdata(ds, ds->data);
+    sdl_resize_shared(ds, ds->width, ds->height, ds->depth, ds->linesize, 
ds->data);
     if (gui_fullscreen) {
         gui_saved_grab = gui_grab;
         sdl_grab_start();
@@ -760,11 +770,16 @@ void sdl_display_init(DisplayState *ds, 
 
     ds->dpy_update = sdl_update;
     ds->dpy_resize = sdl_resize;
+    ds->dpy_resize_shared = sdl_resize_shared;
     ds->dpy_refresh = sdl_refresh;
-    ds->dpy_colourdepth = sdl_colourdepth;
-    ds->dpy_setdata = sdl_setdata;
-
-    sdl_resize(ds, 640, 400, 640 * 4);
+#ifdef CONFIG_OPENGL
+    if (opengl_enabled)
+        ds->dpy_setdata = opengl_setdata;
+    else
+        ds->dpy_setdata = sdl_setdata;
+#endif
+
+    sdl_resize(ds, 640, 400);
     sdl_update_caption();
     SDL_EnableKeyRepeat(250, 50);
     SDL_EnableUNICODE(1);
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c  Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/ioemu/vl.c  Thu Jun 19 12:46:26 2008 +0900
@@ -136,6 +136,9 @@
 
 /* XXX: use a two level table to limit memory usage */
 #define MAX_IOPORTS 65536
+
+/* Max number of PCI emulation */
+#define MAX_PCI_EMULATION 32
 
 const char *bios_dir = CONFIG_QEMU_SHAREDIR;
 void *ioport_opaque[MAX_IOPORTS];
@@ -211,6 +214,8 @@ int xc_handle;
 
 char domain_name[64] = "Xen-no-name";
 extern int domid;
+
+PCI_EMULATION_INFO *PciEmulationInfoHead = NULL;
 
 /***********************************************************/
 /* x86 ISA bus support */
@@ -4260,7 +4265,9 @@ static int usb_device_add(const char *de
     } else if (!strcmp(devname, "tablet")) {
        dev = usb_tablet_init();
     } else if (strstart(devname, "disk:", &p)) {
-        dev = usb_msd_init(p);
+        dev = usb_msd_init(p, &bdrv_raw);
+    } else if (strstart(devname, "disk-qcow:", &p)) {
+        dev = usb_msd_init(p, 0);
     } else {
         return -1;
     }
@@ -4399,6 +4406,17 @@ void do_pci_add(char *devname)
 #endif
 }
 
+static int pci_emulation_add(char *config_text)
+{
+    PCI_EMULATION_INFO *new;
+    if ((new = qemu_mallocz(sizeof(PCI_EMULATION_INFO))) == NULL) {
+        return -1;
+    }
+    parse_pci_emulation_info(config_text, new);
+    new->next = PciEmulationInfoHead;
+    PciEmulationInfoHead = new;
+    return 0;
+}
 
 /***********************************************************/
 /* pid file */
@@ -4463,7 +4481,6 @@ void dumb_display_init(DisplayState *ds)
     ds->depth = 0;
     ds->dpy_update = dumb_update;
     ds->dpy_resize = dumb_resize;
-    ds->dpy_colourdepth = NULL;
     ds->dpy_refresh = dumb_refresh;
     ds->gui_timer_interval = 500;
     ds->idle = 1;
@@ -6591,6 +6608,7 @@ void help(void)
 #endif
           "-option-rom rom load a file, rom, into the option ROM space\n"
            "-acpi           disable or enable ACPI of HVM domain \n"
+           "-pciemulation       
name:vendorid:deviceid:command:status:revision:classcode:headertype:subvendorid:subsystemid:interruputline:interruputpin\n"
            "\n"
            "During emulation, the following keys are useful:\n"
            "ctrl-alt-f      toggle full screen\n"
@@ -6689,6 +6707,7 @@ enum {
     QEMU_OPTION_vncviewer,
     QEMU_OPTION_vncunused,
     QEMU_OPTION_pci,
+    QEMU_OPTION_pci_emulation,
 };
 
 typedef struct QEMUOption {
@@ -6790,6 +6809,7 @@ const QEMUOption qemu_options[] = {
     { "vcpus", 1, QEMU_OPTION_vcpus },
     { "acpi", 0, QEMU_OPTION_acpi },
     { "pci", HAS_ARG, QEMU_OPTION_pci},
+    { "pciemulation", HAS_ARG, QEMU_OPTION_pci_emulation },
     { NULL },
 };
 
@@ -7074,6 +7094,8 @@ int main(int argc, char **argv)
     sigset_t set;
     char qemu_dm_logfilename[128];
     const char *direct_pci = direct_pci_str;
+    int nb_pci_emulation = 0;
+    char pci_emulation_config_text[MAX_PCI_EMULATION][256];
 
 #if !defined(__sun__) && !defined(CONFIG_STUBDOM)
     /* Maximise rlimits. Needed where default constraints are tight (*BSD). */
@@ -7599,6 +7621,16 @@ int main(int argc, char **argv)
             case QEMU_OPTION_vncunused:
                 vncunused++;
                 break;
+            case QEMU_OPTION_pci_emulation:
+                if (nb_pci_emulation >= MAX_PCI_EMULATION) {
+                    fprintf(stderr, "Too many PCI emulations\n");
+                    exit(1);
+                }
+                pstrcpy(pci_emulation_config_text[nb_pci_emulation],
+                        sizeof(pci_emulation_config_text[0]),
+                        optarg);
+                nb_pci_emulation++;
+                break;
             }
         }
     }
@@ -7898,6 +7930,13 @@ int main(int argc, char **argv)
         }
     }
 
+    for (i = 0; i < nb_pci_emulation; i++) {
+        if(pci_emulation_add(pci_emulation_config_text[i]) < 0) {
+            fprintf(stderr, "Warning: could not add PCI device %s\n",
+                    pci_emulation_config_text[i]);
+        }
+    }
+
     qemu_set_fd_handler(xenstore_fd(), xenstore_process_event, NULL, NULL);
 
     machine->init(ram_size, vga_ram_size, boot_device,
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/vl.h
--- a/tools/ioemu/vl.h  Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/ioemu/vl.h  Thu Jun 19 12:46:26 2008 +0900
@@ -945,9 +945,9 @@ struct DisplayState {
     int shared_buf;
     
     void (*dpy_update)(struct DisplayState *s, int x, int y, int w, int h);
-    void (*dpy_resize)(struct DisplayState *s, int w, int h, int linesize);
-    void (*dpy_colourdepth)(struct DisplayState *s, int depth);
+    void (*dpy_resize)(struct DisplayState *s, int w, int h);
     void (*dpy_setdata)(DisplayState *s, void *pixels);
+    void (*dpy_resize_shared)(DisplayState *s, int w, int h, int depth, int 
linesize, void *pixels);
     void (*dpy_refresh)(struct DisplayState *s);
     void (*dpy_copy)(struct DisplayState *s, int src_x, int src_y, int dst_x, 
int dst_y, int w, int h);
 };
@@ -957,14 +957,14 @@ static inline void dpy_update(DisplaySta
     s->dpy_update(s, x, y, w, h);
 }
 
-static inline void dpy_resize(DisplayState *s, int w, int h, int linesize)
-{
-    s->dpy_resize(s, w, h, linesize);
-}
-
-static inline void dpy_colourdepth(struct DisplayState *s, int depth)
-{
-    s->dpy_colourdepth(s, depth);
+static inline void dpy_resize(DisplayState *s, int w, int h)
+{
+    s->dpy_resize(s, w, h);
+}
+
+static inline void dpy_resize_shared(DisplayState *s, int w, int h, int depth, 
int linesize, void *pixels)
+{
+    s->dpy_resize_shared(s, w, h, depth, linesize, pixels);
 }
 
 static inline void dpy_setdata(DisplayState *s, void *pixels)
@@ -1560,6 +1560,10 @@ void pci_xen_platform_init(PCIBus *bus);
 void pci_xen_platform_init(PCIBus *bus);
 #endif
 
+/* pci_emulation.c */
+#ifndef QEMU_TOOL
+#include "hw/pci_emulation.h"
+#endif
 
 void kqemu_record_dump(void);
 
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/vnc.c
--- a/tools/ioemu/vnc.c Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/ioemu/vnc.c Thu Jun 19 12:46:26 2008 +0900
@@ -277,6 +277,7 @@ static void dequeue_framebuffer_update(V
 static void dequeue_framebuffer_update(VncState *vs);
 static int is_empty_queue(VncState *vs);
 static void free_queue(VncState *vs);
+static void vnc_colourdepth(DisplayState *ds, int depth);
 
 #if 0
 static inline void vnc_set_bit(uint32_t *d, int k)
@@ -363,13 +364,14 @@ static void vnc_framebuffer_update(VncSt
     vnc_write_s32(vs, encoding);
 }
 
-static void vnc_dpy_resize(DisplayState *ds, int w, int h, int linesize)
+static void vnc_dpy_resize_shared(DisplayState *ds, int w, int h, int depth, 
int linesize, void *pixels)
 {
     static int allocated;
     int size_changed;
     VncState *vs = ds->opaque;
     int o;
 
+    vnc_colourdepth(ds, depth);
     if (!ds->shared_buf) {
         ds->linesize = w * vs->depth;
         if (allocated)
@@ -419,6 +421,12 @@ static void vnc_dpy_resize(DisplayState 
     for (o = DIRTY_PIXEL_BITS; o < ds->width; o *= 2)
        vs->dirty_pixel_shift++;
     framebuffer_set_updated(vs, 0, 0, ds->width, ds->height);
+    if (ds->shared_buf) ds->data = pixels;
+}
+
+static void vnc_dpy_resize(DisplayState *ds, int w, int h)
+{
+    vnc_dpy_resize_shared(ds, w, h, 0, w * (ds->depth / 8), NULL);
 }
 
 /* fastest code */
@@ -1640,7 +1648,7 @@ static void vnc_dpy_setdata(DisplayState
     ds->data = pixels;
 }
 
-static void vnc_dpy_colourdepth(DisplayState *ds, int depth)
+static void vnc_colourdepth(DisplayState *ds, int depth)
 {
     int host_big_endian_flag;
     struct VncState *vs = ds->opaque;
@@ -1742,8 +1750,6 @@ static void vnc_dpy_colourdepth(DisplayS
             vs->write_pixels = vnc_write_pixels_generic;
         }
     }
-
-    vnc_dpy_resize(ds, ds->width, ds->height, ds->linesize);
 }
 
 static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
@@ -2502,14 +2508,14 @@ void vnc_display_init(DisplayState *ds)
     vs->ds->data = NULL;
     vs->ds->dpy_update = vnc_dpy_update;
     vs->ds->dpy_resize = vnc_dpy_resize;
-    vs->ds->dpy_colourdepth = vnc_dpy_colourdepth;
     vs->ds->dpy_setdata = vnc_dpy_setdata;
+    vs->ds->dpy_resize_shared = vnc_dpy_resize_shared;
     vs->ds->dpy_refresh = vnc_dpy_refresh;
 
     vs->ds->width = 640;
     vs->ds->height = 400;
     vs->ds->linesize = 640 * 4;
-    vnc_dpy_colourdepth(vs->ds, 24);
+    vnc_dpy_resize_shared(ds, ds->width, ds->height, 24, ds->linesize, NULL);
 }
 
 #if CONFIG_VNC_TLS
diff -r 1201c7657832 -r 0034766b45c2 tools/ioemu/xenfbfront.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/ioemu/xenfbfront.c  Thu Jun 19 12:46:26 2008 +0900
@@ -0,0 +1,315 @@
+#include <stdint.h>
+#include <xen/io/fbif.h>
+#include <xen/io/kbdif.h>
+#include <semaphore.h>
+#include <sched.h>
+#include <fbfront.h>
+
+#include <hw/xenfb.h>
+
+#include "vl.h"
+
+typedef struct XenFBState {
+    struct semaphore kbd_sem;
+    struct kbdfront_dev *kbd_dev;
+    struct fbfront_dev *fb_dev;
+    void *vga_vram, *nonshared_vram;
+    DisplayState *ds;
+} XenFBState;
+
+XenFBState *xs;
+
+static char *kbd_path, *fb_path;
+
+static unsigned char linux2scancode[KEY_MAX + 1];
+
+int xenfb_connect_vkbd(const char *path)
+{
+    kbd_path = strdup(path);
+    return 0;
+}
+
+int xenfb_connect_vfb(const char *path)
+{
+    fb_path = strdup(path);
+    return 0;
+}
+
+static void xenfb_pv_update(DisplayState *ds, int x, int y, int w, int h)
+{
+    XenFBState *xs = ds->opaque;
+    struct fbfront_dev *fb_dev = xs->fb_dev;
+    if (!fb_dev)
+        return;
+    fbfront_update(fb_dev, x, y, w, h);
+}
+
+static void xenfb_pv_resize_shared(DisplayState *ds, int w, int h, int depth, 
int linesize, void *pixels)
+{
+    XenFBState *xs = ds->opaque;
+    struct fbfront_dev *fb_dev = xs->fb_dev;
+    int offset;
+
+    fprintf(stderr,"resize to %dx%d@%d, %d required\n", w, h, depth, linesize);
+    ds->width = w;
+    ds->height = h;
+    if (!depth) {
+        ds->shared_buf = 0;
+        ds->depth = 32;
+    } else {
+        ds->shared_buf = 1;
+        ds->depth = depth;
+    }
+    if (!linesize)
+        ds->shared_buf = 0;
+    if (!ds->shared_buf)
+        linesize = w * 4;
+    ds->linesize = linesize;
+    if (!fb_dev)
+        return;
+    if (ds->shared_buf) {
+        offset = pixels - xs->vga_vram;
+        ds->data = pixels;
+        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, 
offset);
+    } else {
+        ds->data = xs->nonshared_vram;
+        fbfront_resize(fb_dev, w, h, linesize, ds->depth, VGA_RAM_SIZE);
+    }
+}
+
+static void xenfb_pv_resize(DisplayState *ds, int w, int h)
+{
+    xenfb_pv_resize_shared(ds, w, h, 0, 0, NULL);
+}
+
+static void xenfb_pv_setdata(DisplayState *ds, void *pixels)
+{
+    XenFBState *xs = ds->opaque;
+    struct fbfront_dev *fb_dev = xs->fb_dev;
+    int offset = pixels - xs->vga_vram;
+    ds->data = pixels;
+    if (!fb_dev)
+        return;
+    fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, 
offset);
+}
+
+static void xenfb_pv_refresh(DisplayState *ds)
+{
+    vga_hw_update();
+}
+
+static void xenfb_fb_handler(void *opaque)
+{
+#define FB_NUM_BATCH 4
+    union xenfb_in_event buf[FB_NUM_BATCH];
+    int n, i;
+    XenFBState *xs = opaque;
+    DisplayState *ds = xs->ds;
+
+    n = fbfront_receive(xs->fb_dev, buf, FB_NUM_BATCH);
+    for (i = 0; i < n; i++) {
+        switch (buf[i].type) {
+        case XENFB_TYPE_REFRESH_PERIOD:
+            if (buf[i].refresh_period.period == XENFB_NO_REFRESH) {
+                /* Sleeping interval */
+                ds->idle = 1;
+                ds->gui_timer_interval = 500;
+            } else {
+                /* Set interval */
+                ds->idle = 0;
+                ds->gui_timer_interval = buf[i].refresh_period.period;
+            }
+        default:
+            /* ignore unknown events */
+            break;
+        }
+    }
+}
+
+static void xenfb_kbd_handler(void *opaque)
+{
+#define KBD_NUM_BATCH 64
+    union xenkbd_in_event buf[KBD_NUM_BATCH];
+    int n, i;
+    XenFBState *xs = opaque;
+    DisplayState *s = xs->ds;
+    static int buttons;
+    static int x, y;
+
+    n = kbdfront_receive(xs->kbd_dev, buf, KBD_NUM_BATCH);
+    for (i = 0; i < n; i++) {
+        switch (buf[i].type) {
+
+            case XENKBD_TYPE_MOTION:
+                fprintf(stderr, "FB backend sent us relative mouse motion 
event!\n");
+                break;
+
+            case XENKBD_TYPE_POS:
+            {
+                int new_x = buf[i].pos.abs_x;
+                int new_y = buf[i].pos.abs_y;
+                if (new_x >= s->width)
+                    new_x = s->width - 1;
+                if (new_y >= s->height)
+                    new_y = s->height - 1;
+                if (kbd_mouse_is_absolute()) {
+                    kbd_mouse_event(
+                            new_x * 0x7FFF / (s->width - 1),
+                            new_y * 0x7FFF / (s->height - 1),
+                            buf[i].pos.rel_z,
+                            buttons);
+                } else {
+                    kbd_mouse_event(
+                            new_x - x,
+                            new_y - y,
+                            buf[i].pos.rel_z,
+                            buttons);
+                }
+                x = new_x;
+                y = new_y;
+                break;
+            }
+
+            case XENKBD_TYPE_KEY:
+            {
+                int keycode = buf[i].key.keycode;
+                int button = 0;
+
+                if (keycode == BTN_LEFT)
+                    button = MOUSE_EVENT_LBUTTON;
+                else if (keycode == BTN_RIGHT)
+                    button = MOUSE_EVENT_RBUTTON;
+                else if (keycode == BTN_MIDDLE)
+                    button = MOUSE_EVENT_MBUTTON;
+
+                if (button) {
+                    if (buf[i].key.pressed)
+                        buttons |=  button;
+                    else
+                        buttons &= ~button;
+                    if (kbd_mouse_is_absolute())
+                        kbd_mouse_event(
+                                x * 0x7FFF / (s->width - 1),
+                                y * 0x7FFF / (s->height - 1),
+                                0,
+                                buttons);
+                    else
+                        kbd_mouse_event(0, 0, 0, buttons);
+                } else {
+                    int scancode = linux2scancode[keycode];
+                    if (!scancode) {
+                        fprintf(stderr, "Can't convert keycode %x to 
scancode\n", keycode);
+                        break;
+                    }
+                    if (scancode & 0x80) {
+                        kbd_put_keycode(0xe0);
+                        scancode &= 0x7f;
+                    }
+                    if (!buf[i].key.pressed)
+                        scancode |= 0x80;
+                    kbd_put_keycode(scancode);
+                }
+                break;
+            }
+        }
+    }
+}
+
+static void kbdfront_thread(void *p)
+{
+    int scancode, keycode;
+    XenFBState *xs = p;
+    xs->kbd_dev = init_kbdfront(kbd_path, 1);
+    if (!xs->kbd_dev) {
+        fprintf(stderr,"can't open keyboard\n");
+        exit(1);
+    }
+    up(&xs->kbd_sem);
+    for (scancode = 0; scancode < 128; scancode++) {
+        keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode]];
+        linux2scancode[keycode] = scancode;
+        keycode = atkbd_set2_keycode[atkbd_unxlate_table[scancode] | 0x80];
+        linux2scancode[keycode] = scancode | 0x80;
+    }
+}
+
+int xenfb_pv_display_init(DisplayState *ds)
+{
+    if (!fb_path || !kbd_path)
+        return -1;
+
+    xs = qemu_mallocz(sizeof(XenFBState));
+    if (!xs)
+        return -1;
+
+    init_SEMAPHORE(&xs->kbd_sem, 0);
+    xs->ds = ds;
+
+    create_thread("kbdfront", kbdfront_thread, (void*) xs);
+
+    ds->data = xs->nonshared_vram = qemu_memalign(PAGE_SIZE, VGA_RAM_SIZE);
+    memset(ds->data, 0, VGA_RAM_SIZE);
+    ds->opaque = xs;
+    ds->depth = 32;
+    ds->bgr = 0;
+    ds->width = 640;
+    ds->height = 400;
+    ds->linesize = 640 * 4;
+    ds->dpy_update = xenfb_pv_update;
+    ds->dpy_resize = xenfb_pv_resize;
+    ds->dpy_resize_shared = xenfb_pv_resize_shared;
+    ds->dpy_setdata = xenfb_pv_setdata;
+    ds->dpy_refresh = xenfb_pv_refresh;
+    return 0;
+}
+
+int xenfb_pv_display_start(void *data)
+{
+    DisplayState *ds;
+    struct fbfront_dev *fb_dev;
+    int kbd_fd, fb_fd;
+    int offset = 0;
+    unsigned long *mfns;
+    int n = VGA_RAM_SIZE / PAGE_SIZE;
+    int i;
+
+    if (!fb_path || !kbd_path)
+        return 0;
+
+    ds = xs->ds;
+    xs->vga_vram = data;
+    mfns = malloc(2 * n * sizeof(*mfns));
+    for (i = 0; i < n; i++)
+        mfns[i] = virtual_to_mfn(xs->vga_vram + i * PAGE_SIZE);
+    for (i = 0; i < n; i++)
+        mfns[n + i] = virtual_to_mfn(xs->nonshared_vram + i * PAGE_SIZE);
+
+    fb_dev = init_fbfront(fb_path, mfns, ds->width, ds->height, ds->depth, 
ds->linesize, 2 * n);
+    free(mfns);
+    if (!fb_dev) {
+        fprintf(stderr,"can't open frame buffer\n");
+        exit(1);
+    }
+    free(fb_path);
+
+    if (ds->shared_buf) {
+        offset = (void*) ds->data - xs->vga_vram;
+    } else {
+        offset = VGA_RAM_SIZE;
+        ds->data = xs->nonshared_vram;
+    }
+    if (offset)
+        fbfront_resize(fb_dev, ds->width, ds->height, ds->linesize, ds->depth, 
offset);
+
+    down(&xs->kbd_sem);
+    free(kbd_path);
+
+    kbd_fd = kbdfront_open(xs->kbd_dev);
+    qemu_set_fd_handler(kbd_fd, xenfb_kbd_handler, NULL, xs);
+
+    fb_fd = fbfront_open(fb_dev);
+    qemu_set_fd_handler(fb_fd, xenfb_fb_handler, NULL, xs);
+
+    xs->fb_dev = fb_dev;
+    return 0;
+}
diff -r 1201c7657832 -r 0034766b45c2 tools/libfsimage/ufs/fsys_ufs.c
--- a/tools/libfsimage/ufs/fsys_ufs.c   Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/libfsimage/ufs/fsys_ufs.c   Thu Jun 19 12:46:26 2008 +0900
@@ -32,8 +32,9 @@
 #define SUPERBLOCK ((struct fs *)(FSYS_BUF + 0x2000))
 #define        INODE ((struct icommon *)(FSYS_BUF + 0x1000))
 #define DIRENT (FSYS_BUF + 0x4000)
+#define MAXBSIZE ((FSYS_BUFLEN - 0x4000) / 2)
 #define INDIRBLK1 ((grub_daddr32_t *)(FSYS_BUF + 0x4000)) /* 2+ indir blk */
-#define        INDIRBLK0 ((grub_daddr32_t *)(FSYS_BUF+ 0x6000))  /* 1st 
indirect blk */
+#define        INDIRBLK0 ((grub_daddr32_t *)(FSYS_BUF+ 0x4000 + MAXBSIZE))  /* 
1st indirect blk */
 
 #define        indirblk0 (*fsig_int1(ffi))
 #define        indirblk1 (*fsig_int2(ffi))
@@ -48,7 +49,8 @@ ufs_mount(fsi_file_t *ffi, const char *o
 {
        if (/*! IS_PC_SLICE_TYPE_SOLARIS(current_slice) || */
            !devread(ffi, UFS_SBLOCK, 0, UFS_SBSIZE, (char *)SUPERBLOCK) ||
-           SUPERBLOCK->fs_magic != UFS_MAGIC)
+           SUPERBLOCK->fs_magic != UFS_MAGIC ||
+           MAXBSIZE < SUPERBLOCK->fs_bsize)
                return 0;
 
        return 1;
diff -r 1201c7657832 -r 0034766b45c2 tools/libfsimage/zfs/fsys_zfs.c
--- a/tools/libfsimage/zfs/fsys_zfs.c   Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/libfsimage/zfs/fsys_zfs.c   Thu Jun 19 12:46:26 2008 +0900
@@ -776,11 +776,11 @@ dnode_get_path(fsi_file_t *ffi, dnode_ph
        while (*path == '/')
                path++;
 
-       while (*path && !isspace(*path)) {
+       while (*path && !isspace((uint8_t)*path)) {
 
                /* get the next component name */
                cname = path;
-               while (*path && !isspace(*path) && *path != '/')
+               while (*path && !isspace((uint8_t)*path) && *path != '/')
                        path++;
                ch = *path;
                *path = 0;   /* ensure null termination */
@@ -890,17 +890,17 @@ get_objset_mdn(fsi_file_t *ffi, dnode_ph
        }
 
        /* take out the pool name */
-       while (*fsname && !isspace(*fsname) && *fsname != '/')
+       while (*fsname && !isspace((uint8_t)*fsname) && *fsname != '/')
                fsname++;
 
-       while (*fsname && !isspace(*fsname)) {
+       while (*fsname && !isspace((uint8_t)*fsname)) {
                uint64_t childobj;
 
                while (*fsname == '/')
                        fsname++;
 
                cname = fsname;
-               while (*fsname && !isspace(*fsname) && *fsname != '/')
+               while (*fsname && !isspace((uint8_t)*fsname) && *fsname != '/')
                        fsname++;
                ch = *fsname;
                *fsname = 0;
@@ -1336,7 +1336,7 @@ zfs_open(fsi_file_t *ffi, char *filename
                        char zfs_bootstr[] = "zfs-bootfs=";
                        char zfs_bootpath[] = ",bootpath='";
 
-                       sprintf(temp, "%llu", (unsigned long long)
+                       snprintf(temp, sizeof(temp), "%llu", (unsigned long 
long)
                            current_bootfs_obj);
                        alloc_size = strlen(zfs_bootstr) +
                            strlen(current_rootpool) +
diff -r 1201c7657832 -r 0034766b45c2 tools/libxc/Makefile
--- a/tools/libxc/Makefile      Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/libxc/Makefile      Thu Jun 19 12:46:26 2008 +0900
@@ -32,7 +32,7 @@ GUEST_SRCS-$(CONFIG_MIGRATE) += xc_domai
 GUEST_SRCS-$(CONFIG_MIGRATE) += xc_domain_restore.c xc_domain_save.c
 GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c
 
-VPATH = ../../xen/common/libelf
+vpath %.c ../../xen/common/libelf
 CFLAGS += -I../../xen/common/libelf
 
 GUEST_SRCS-y += libelf-tools.c libelf-loader.c
diff -r 1201c7657832 -r 0034766b45c2 tools/libxc/ia64/dom_fw_acpi.c
--- a/tools/libxc/ia64/dom_fw_acpi.c    Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/libxc/ia64/dom_fw_acpi.c    Thu Jun 19 12:46:26 2008 +0900
@@ -1,14 +1,31 @@
 #include <inttypes.h>
 #include "xc_dom_ia64_util.h"
 #include <xen/acpi.h>
+#include <acpi/actables.h>
 
-uint8_t
-generate_acpi_checksum(void *tbl, unsigned long len)
+/* stolen from xen/drivers/acpi/tables/tbutils.c */
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_tb_checksum
+ *
+ * PARAMETERS:  Buffer          - Pointer to memory region to be checked
+ *              Length          - Length of this memory region
+ *
+ * RETURN:      Checksum (u8)
+ *
+ * DESCRIPTION: Calculates circular checksum of memory region.
+ *
+ 
******************************************************************************/
+
+u8 acpi_tb_checksum(u8 * buffer, acpi_native_uint length)
 {
-    uint8_t *ptr, sum = 0;
+       u8 sum = 0;
+       u8 *end = buffer + length;
 
-    for ( ptr = tbl; len > 0 ; len--, ptr++ )
-        sum += *ptr;
+       while (buffer < end) {
+               sum = (u8) (sum + *(buffer++));
+       }
 
-    return 0 - sum;
+       return sum;
 }
diff -r 1201c7657832 -r 0034766b45c2 tools/libxc/xc_cpuid_x86.c
--- a/tools/libxc/xc_cpuid_x86.c        Tue Jun 10 16:00:33 2008 +0900
+++ b/tools/libxc/xc_cpuid_x86.c        Thu Jun 19 12:46:26 2008 +0900
@@ -25,81 +25,17 @@
 #include <xen/hvm/params.h>
 
 #define bitmaskof(idx)      (1u << ((idx) & 31))
-#define clear_bit(idx, dst) ((dst) &= ~(1u << (idx)))
-#define set_bit(idx, dst)   ((dst) |= (1u << (idx)))
+#define clear_bit(idx, dst) ((dst) &= ~(1u << ((idx) & 31)))
+#define set_bit(idx, dst)   ((dst) |= (1u << ((idx) & 31)))
 
 #define DEF_MAX_BASE 0x00000004u
 #define DEF_MAX_EXT  0x80000008u
 
-static void amd_xc_cpuid_policy(
-    int xc, domid_t domid, const unsigned int *input, unsigned int *regs)
-{
-    unsigned long pae = 0;
-
-    xc_get_hvm_param(xc, domid, HVM_PARAM_PAE_ENABLED, &pae);
-
-    switch ( input[0] )
-    {
-    case 0x00000001:
-        /* Mask Intel-only features. */
-        regs[2] &= ~(bitmaskof(X86_FEATURE_SSSE3) |
-                     bitmaskof(X86_FEATURE_SSE4_1) |
-                     bitmaskof(X86_FEATURE_SSE4_2));
-        break;
-
-    case 0x00000002:
-    case 0x00000004:
-        regs[0] = regs[1] = regs[2] = 0;
-        break;
-
-    case 0x80000001:
-        if ( !pae )
-            clear_bit(X86_FEATURE_PAE & 31, regs[3]);
-        clear_bit(X86_FEATURE_PSE36 & 31, regs[3]);
-
-        /* Filter all other features according to a whitelist. */
-        regs[2] &= (bitmaskof(X86_FEATURE_LAHF_LM) |
-                    bitmaskof(X86_FEATURE_ALTMOVCR) |
-                    bitmaskof(X86_FEATURE_ABM) |
-                    bitmaskof(X86_FEATURE_SSE4A) |
-                    bitmaskof(X86_FEATURE_MISALIGNSSE) |
-                    bitmaskof(X86_FEATURE_3DNOWPF));
-        regs[3] &= (0x0183f3ff | /* features shared with 0x00000001:EDX */
-                    bitmaskof(X86_FEATURE_NX) |
-                    bitmaskof(X86_FEATURE_LM) |
-                    bitmaskof(X86_FEATURE_SYSCALL) |
-                    bitmaskof(X86_FEATURE_MP) |
-                    bitmaskof(X86_FEATURE_MMXEXT) |
-                    bitmaskof(X86_FEATURE_FFXSR) |
-                    bitmaskof(X86_FEATURE_3DNOW) |
-                    bitmaskof(X86_FEATURE_3DNOWEXT));
-        break;
-    }
-}
-
-static void intel_xc_cpuid_policy(
-    int xc, domid_t domid, const unsigned int *input, unsigned int *regs)
-{
-    switch ( input[0] )
-    {
-    case 0x00000001:
-        /* Mask AMD-only features. */
-        regs[2] &= ~(bitmaskof(X86_FEATURE_POPCNT));
-        break;
-
-    case 0x00000004:
-        regs[0] &= 0x3FF;
-        regs[3] &= 0x3FF;
-        break;
-
-    case 0x80000001:
-        /* Only a few features are advertised in Intel's 0x80000001. */
-        regs[2] &= (bitmaskof(X86_FEATURE_LAHF_LM));
-        regs[3] &= (bitmaskof(X86_FEATURE_NX) |
-                    bitmaskof(X86_FEATURE_LM) |
-                    bitmaskof(X86_FEATURE_SYSCALL));
-        break;
-    }
+static int hypervisor_is_64bit(int xc)
+{
+    xen_capabilities_info_t xen_caps = "";
+    return ((xc_version(xc, XENVER_capabilities, &xen_caps) == 0) &&
+            (strstr(xen_caps, "x86_64") != NULL));
 }
 
 static void cpuid(const unsigned int *input, unsigned int *regs)
@@ -129,15 +65,92 @@ static void xc_cpuid_brand_get(char *str
     str[12] = '\0';
 }
 
-static void xc_cpuid_policy(
+static void amd_xc_cpuid_policy(
+    int xc, domid_t domid, const unsigned int *input, unsigned int *regs,
+    int is_pae)
+{
+    switch ( input[0] )
+    {
+    case 0x00000001:
+        /* Mask Intel-only features. */
+        regs[2] &= ~(bitmaskof(X86_FEATURE_SSSE3) |
+                     bitmaskof(X86_FEATURE_SSE4_1) |
+                     bitmaskof(X86_FEATURE_SSE4_2));
+        break;
+
+    case 0x00000002:
+    case 0x00000004:
+        regs[0] = regs[1] = regs[2] = 0;
+        break;
+
+    case 0x80000001: {
+        int is_64bit = hypervisor_is_64bit(xc) && is_pae;
+
+        if ( !is_pae )
+            clear_bit(X86_FEATURE_PAE, regs[3]);
+        clear_bit(X86_FEATURE_PSE36, regs[3]);
+
+        /* Filter all other features according to a whitelist. */
+        regs[2] &= ((is_64bit ? bitmaskof(X86_FEATURE_LAHF_LM) : 0) |
+                    bitmaskof(X86_FEATURE_ALTMOVCR) |
+                    bitmaskof(X86_FEATURE_ABM) |
+                    bitmaskof(X86_FEATURE_SSE4A) |
+                    bitmaskof(X86_FEATURE_MISALIGNSSE) |
+                    bitmaskof(X86_FEATURE_3DNOWPF));
+        regs[3] &= (0x0183f3ff | /* features shared with 0x00000001:EDX */
+                    (is_pae ? bitmaskof(X86_FEATURE_NX) : 0) |
+                    (is_64bit ? bitmaskof(X86_FEATURE_LM) : 0) |
+                    bitmaskof(X86_FEATURE_SYSCALL) |
+                    bitmaskof(X86_FEATURE_MP) |
+                    bitmaskof(X86_FEATURE_MMXEXT) |
+                    bitmaskof(X86_FEATURE_FFXSR) |
+                    bitmaskof(X86_FEATURE_3DNOW) |
+                    bitmaskof(X86_FEATURE_3DNOWEXT));
+        break;
+    }
+    }

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.