WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 02 Jul 2008 05:40:15 -0700
Delivery-date: Wed, 02 Jul 2008 05:40:46 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>