ia64/xen-unstable

changeset 17877:c8d9ade45781

Add PV-GRUB

This fetches GRUB1 sources, applies the {graphical, print function,
save default, and ext3_256byte} patches from debian, and applies a
patch to make it work on x86_64 and port it to Mini-OS. By using
libxc, PV-GRUB can then "kexec" the loaded kernel from inside the
domain itself, hence permitting to avoid the security-concerned
pygrub.

Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Jun 18 09:36:47 2008 +0100 (2008-06-18)
parents 8a0656950b1c
children 75e60df67e36
files .hgignore extras/mini-os/arch/x86/mm.c extras/mini-os/blkfront.c extras/mini-os/fbfront.c extras/mini-os/include/x86/arch_mm.h extras/mini-os/main.c extras/mini-os/netfront.c stubdom/Makefile stubdom/README stubdom/grub.patches/10graphics.diff stubdom/grub.patches/20print_func.diff stubdom/grub.patches/30savedefault.diff stubdom/grub.patches/40ext3_256byte_inode.diff stubdom/grub.patches/99minios stubdom/grub/Makefile stubdom/grub/boot-x86_32.S stubdom/grub/boot-x86_64.S stubdom/grub/config.h stubdom/grub/kexec.c stubdom/grub/mini-os.c stubdom/grub/mini-os.h stubdom/grub/osdep.h tools/libxc/xc_dom.h tools/libxc/xc_dom_core.c
line diff
     1.1 --- a/.hgignore	Wed Jun 18 09:35:06 2008 +0100
     1.2 +++ b/.hgignore	Wed Jun 18 09:36:47 2008 +0100
     1.3 @@ -94,6 +94,9 @@
     1.4  ^stubdom/newlib-.*$
     1.5  ^stubdom/pciutils-.*$
     1.6  ^stubdom/zlib-.*$
     1.7 +^stubdom/grub-cvs$
     1.8 +^stubdom/grub/stage2$
     1.9 +^stubdom/grub/netboot$
    1.10  ^tools/.*/TAGS$
    1.11  ^tools/.*/build/lib.*/.*\.py$
    1.12  ^tools/blktap/Makefile\.smh$
     2.1 --- a/extras/mini-os/arch/x86/mm.c	Wed Jun 18 09:35:06 2008 +0100
     2.2 +++ b/extras/mini-os/arch/x86/mm.c	Wed Jun 18 09:36:47 2008 +0100
     2.3 @@ -372,7 +372,7 @@ static pgentry_t *get_pgt(unsigned long 
     2.4      return &tab[offset];
     2.5  }
     2.6  
     2.7 -static pgentry_t *need_pgt(unsigned long addr)
     2.8 +pgentry_t *need_pgt(unsigned long addr)
     2.9  {
    2.10      unsigned long mfn;
    2.11      pgentry_t *tab;
     3.1 --- a/extras/mini-os/blkfront.c	Wed Jun 18 09:35:06 2008 +0100
     3.2 +++ b/extras/mini-os/blkfront.c	Wed Jun 18 09:36:47 2008 +0100
     3.3 @@ -242,9 +242,15 @@ void shutdown_blkfront(struct blkfront_d
     3.4      err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
     3.5      xenbus_wait_for_value(path, "6", &dev->events);
     3.6  
     3.7 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
     3.8 +    xenbus_wait_for_value(path, "2", &dev->events);
     3.9 +
    3.10      xenbus_unwatch_path(XBT_NIL, path);
    3.11  
    3.12 -    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
    3.13 +    snprintf(path, sizeof(path), "%s/ring-ref", nodename);
    3.14 +    xenbus_rm(XBT_NIL, path);
    3.15 +    snprintf(path, sizeof(path), "%s/event-channel", nodename);
    3.16 +    xenbus_rm(XBT_NIL, path);
    3.17  
    3.18      free_blkfront(dev);
    3.19  }
     4.1 --- a/extras/mini-os/fbfront.c	Wed Jun 18 09:35:06 2008 +0100
     4.2 +++ b/extras/mini-os/fbfront.c	Wed Jun 18 09:36:47 2008 +0100
     4.3 @@ -229,9 +229,18 @@ void shutdown_kbdfront(struct kbdfront_d
     4.4      err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
     4.5      xenbus_wait_for_value(path, "6", &dev->events);
     4.6  
     4.7 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
     4.8 +    // does not work yet.
     4.9 +    //xenbus_wait_for_value(path, "2", &dev->events);
    4.10 +
    4.11      xenbus_unwatch_path(XBT_NIL, path);
    4.12  
    4.13 -    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
    4.14 +    snprintf(path, sizeof(path), "%s/page-ref", nodename);
    4.15 +    xenbus_rm(XBT_NIL, path);
    4.16 +    snprintf(path, sizeof(path), "%s/event-channel", nodename);
    4.17 +    xenbus_rm(XBT_NIL, path);
    4.18 +    snprintf(path, sizeof(path), "%s/request-abs-pointer", nodename);
    4.19 +    xenbus_rm(XBT_NIL, path);
    4.20  
    4.21      free_kbdfront(dev);
    4.22  }
    4.23 @@ -561,9 +570,20 @@ void shutdown_fbfront(struct fbfront_dev
    4.24      err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
    4.25      xenbus_wait_for_value(path, "6", &dev->events);
    4.26  
    4.27 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
    4.28 +    // does not work yet
    4.29 +    //xenbus_wait_for_value(path, "2", &dev->events);
    4.30 +
    4.31      xenbus_unwatch_path(XBT_NIL, path);
    4.32  
    4.33 -    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
    4.34 +    snprintf(path, sizeof(path), "%s/page-ref", nodename);
    4.35 +    xenbus_rm(XBT_NIL, path);
    4.36 +    snprintf(path, sizeof(path), "%s/event-channel", nodename);
    4.37 +    xenbus_rm(XBT_NIL, path);
    4.38 +    snprintf(path, sizeof(path), "%s/protocol", nodename);
    4.39 +    xenbus_rm(XBT_NIL, path);
    4.40 +    snprintf(path, sizeof(path), "%s/feature-update", nodename);
    4.41 +    xenbus_rm(XBT_NIL, path);
    4.42  
    4.43      unbind_evtchn(dev->evtchn);
    4.44  
     5.1 --- a/extras/mini-os/include/x86/arch_mm.h	Wed Jun 18 09:35:06 2008 +0100
     5.2 +++ b/extras/mini-os/include/x86/arch_mm.h	Wed Jun 18 09:36:47 2008 +0100
     5.3 @@ -221,4 +221,6 @@ static __inline__ paddr_t machine_to_phy
     5.4  #define map_zero(n, a) map_frames_ex(&mfn_zero, n, 0, 0, a, DOMID_SELF, 0, L1_PROT_RO)
     5.5  #define do_map_zero(start, n) do_map_frames(start, &mfn_zero, n, 0, 0, DOMID_SELF, 0, L1_PROT_RO)
     5.6  
     5.7 +pgentry_t *need_pgt(unsigned long addr);
     5.8 +
     5.9  #endif /* _ARCH_MM_H_ */
     6.1 --- a/extras/mini-os/main.c	Wed Jun 18 09:35:06 2008 +0100
     6.2 +++ b/extras/mini-os/main.c	Wed Jun 18 09:36:47 2008 +0100
     6.3 @@ -59,11 +59,13 @@ static void call_main(void *p)
     6.4       * crashing. */
     6.5      //sleep(1);
     6.6  
     6.7 +#ifndef CONFIG_GRUB
     6.8      sparse((unsigned long) &__app_bss_start, &__app_bss_end - &__app_bss_start);
     6.9  #ifdef HAVE_LWIP
    6.10      start_networking();
    6.11  #endif
    6.12      init_fs_frontend();
    6.13 +#endif
    6.14  
    6.15  #ifdef CONFIG_QEMU
    6.16      if (!fs_import) {
    6.17 @@ -154,7 +156,7 @@ void _exit(int ret)
    6.18  #ifdef HAVE_LWIP
    6.19      stop_networking();
    6.20  #endif
    6.21 -    unbind_all_ports();
    6.22 +    stop_kernel();
    6.23      if (!ret) {
    6.24  	/* No problem, just shutdown.  */
    6.25          struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_poweroff };
     7.1 --- a/extras/mini-os/netfront.c	Wed Jun 18 09:35:06 2008 +0100
     7.2 +++ b/extras/mini-os/netfront.c	Wed Jun 18 09:36:47 2008 +0100
     7.3 @@ -497,15 +497,26 @@ void shutdown_netfront(struct netfront_d
     7.4      printk("close network: backend at %s\n",dev->backend);
     7.5  
     7.6      snprintf(path, sizeof(path), "%s/state", dev->backend);
     7.7 +
     7.8      err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 5); /* closing */
     7.9      xenbus_wait_for_value(path, "5", &dev->events);
    7.10  
    7.11      err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 6);
    7.12      xenbus_wait_for_value(path, "6", &dev->events);
    7.13  
    7.14 +    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
    7.15 +    xenbus_wait_for_value(path, "2", &dev->events);
    7.16 +
    7.17      xenbus_unwatch_path(XBT_NIL, path);
    7.18  
    7.19 -    err = xenbus_printf(XBT_NIL, nodename, "state", "%u", 1);
    7.20 +    snprintf(path, sizeof(path), "%s/tx-ring-ref", nodename);
    7.21 +    xenbus_rm(XBT_NIL, path);
    7.22 +    snprintf(path, sizeof(path), "%s/rx-ring-ref", nodename);
    7.23 +    xenbus_rm(XBT_NIL, path);
    7.24 +    snprintf(path, sizeof(path), "%s/event-channel", nodename);
    7.25 +    xenbus_rm(XBT_NIL, path);
    7.26 +    snprintf(path, sizeof(path), "%s/request-rx-copy", nodename);
    7.27 +    xenbus_rm(XBT_NIL, path);
    7.28  
    7.29      free_netfront(dev);
    7.30  }
     8.1 --- a/stubdom/Makefile	Wed Jun 18 09:35:06 2008 +0100
     8.2 +++ b/stubdom/Makefile	Wed Jun 18 09:36:47 2008 +0100
     8.3 @@ -14,6 +14,7 @@ ZLIB_VERSION=1.2.3
     8.4  LIBPCI_VERSION=2.2.9
     8.5  NEWLIB_DATE=2008-01-01
     8.6  LWIP_DATE=2008-06-01
     8.7 +GRUB_DATE=2008-06-01
     8.8  
     8.9  WGET=wget -c
    8.10  
    8.11 @@ -39,10 +40,10 @@ CROSS_PREFIX=$(CURDIR)/$(CROSS_ROOT)
    8.12  export CROSS_COMPILE=$(GNU_TARGET_ARCH)-xen-elf-
    8.13  export PATH:=$(CROSS_PREFIX)/bin:$(PATH)
    8.14  
    8.15 -TARGETS=ioemu c caml
    8.16 +TARGETS=ioemu c caml grub
    8.17  
    8.18  .PHONY: all
    8.19 -all: ioemu-stubdom c-stubdom
    8.20 +all: ioemu-stubdom c-stubdom pv-grub
    8.21  
    8.22  ################
    8.23  # Cross-binutils
    8.24 @@ -221,30 +222,53 @@ caml: cross-newlib mk-symlinks
    8.25  c: cross-newlib mk-symlinks
    8.26  	$(MAKE) -C $@ LWIPDIR=$(CURDIR)/lwip-cvs 
    8.27  
    8.28 +######
    8.29 +# Grub
    8.30 +######
    8.31 +
    8.32 +grub-cvs:
    8.33 +	cvs -z 9 -d :pserver:anonymous@cvs.sv.gnu.org:/sources/grub co -D $(GRUB_DATE) -d $@ grub
    8.34 +	for i in grub.patches/* ; do \
    8.35 +		patch -d $@ -p1 < $$i ; \
    8.36 +	done
    8.37 +
    8.38 +.PHONY: grub
    8.39 +grub: grub-cvs cross-newlib mk-symlinks
    8.40 +	$(MAKE) -C $@
    8.41 +
    8.42  ########
    8.43  # minios
    8.44  ########
    8.45  
    8.46  .PHONY: ioemu-stubdom
    8.47  ioemu-stubdom: mini-os-ioemu lwip-cvs libxc ioemu
    8.48 -	$(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" CFLAGS=-DCONFIG_QEMU
    8.49 +	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"
    8.50  
    8.51  CAMLLIB = $(shell ocamlc -where)
    8.52  .PHONY: caml-stubdom
    8.53  caml-stubdom: mini-os-caml lwip-cvs libxc caml
    8.54 -	$(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" CFLAGS=-DCONFIG_CAML
    8.55 +	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"
    8.56  
    8.57  .PHONY: c-stubdom
    8.58  c-stubdom: mini-os-c lwip-cvs libxc c
    8.59 -	$(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip-cvs APP_OBJS=$(CURDIR)/c/main.a CFLAGS=-DCONFIG_C
    8.60 +	DEF_CFLAGS=-DCONFIG_C $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< LWIPDIR=$(CURDIR)/lwip-cvs APP_OBJS=$(CURDIR)/c/main.a
    8.61 +
    8.62 +.PHONY: pv-grub
    8.63 +pv-grub: mini-os-grub libxc grub
    8.64 +	DEF_CFLAGS=-DCONFIG_GRUB $(MAKE) -C $(MINI_OS) OBJ_DIR=$(CURDIR)/$< APP_OBJS=$(CURDIR)/grub/main.a
    8.65  
    8.66  #########
    8.67  # install
    8.68  #########
    8.69  
    8.70 -install: mini-os-ioemu/mini-os.gz
    8.71 +install: install-ioemu install-grub
    8.72 +
    8.73 +install-ioemu: mini-os-ioemu/mini-os.gz
    8.74  	$(INSTALL_PROG) stubdom-dm "$(DESTDIR)/usr/lib/xen/bin"
    8.75 -	$(INSTALL_PROG) $< "$(DESTDIR)/usr/lib/xen/boot/stubdom.gz"
    8.76 +	$(INSTALL_PROG) $< "$(DESTDIR)/usr/lib/xen/boot/ioemu-stubdom.gz"
    8.77 +
    8.78 +install-grub: mini-os-grub/mini-os.gz
    8.79 +	$(INSTALL_PROG) $< "$(DESTDIR)/usr/lib/xen/boot/pv-grub.gz"
    8.80  
    8.81  #######
    8.82  # clean
    8.83 @@ -256,8 +280,10 @@ clean:
    8.84  	rm -fr mini-os-ioemu
    8.85  	rm -fr mini-os-c
    8.86  	rm -fr mini-os-caml
    8.87 +	rm -fr mini-os-grub
    8.88  	$(MAKE) -C caml clean
    8.89  	$(MAKE) -C c clean
    8.90 +	$(MAKE) -C grub clean
    8.91  	rm -fr libxc ioemu mini-os include
    8.92  
    8.93  # clean the cross-compilation result
    8.94 @@ -274,6 +300,7 @@ patchclean: crossclean
    8.95  	rm -fr gcc-$(GCC_VERSION)
    8.96  	rm -fr newlib-cvs
    8.97  	rm -fr lwip-cvs
    8.98 +	rm -fr grub-cvs
    8.99  
   8.100  # clean downloads
   8.101  .PHONY: downloadclean
     9.1 --- a/stubdom/README	Wed Jun 18 09:35:06 2008 +0100
     9.2 +++ b/stubdom/README	Wed Jun 18 09:36:47 2008 +0100
     9.3 @@ -6,12 +6,19 @@ Then make install to install the result.
     9.4  
     9.5  Also, run make and make install in $XEN_ROOT/tools/fs-back
     9.6  
     9.7 +
     9.8 +
     9.9 +                                IOEMU stubdom
    9.10 +                                =============
    9.11 +
    9.12 +  This boosts HVM performance by putting ioemu in its own lightweight domain.
    9.13 +
    9.14  General Configuration
    9.15  =====================
    9.16  
    9.17  In your HVM config "hvmconfig",
    9.18  
    9.19 -- use /usr/lib/xen/bin/stubdom-dm as dm script
    9.20 +- use /usr/lib/xen/bin/stubdom-dm as dm script:
    9.21  
    9.22  device_model = '/usr/lib/xen/bin/stubdom-dm'
    9.23  
    9.24 @@ -25,7 +32,7 @@ device_model = '/usr/lib/xen/bin/stubdom
    9.25  Create /etc/xen/stubdom-hvmconfig (where "hvmconfig" is the name of your HVM
    9.26  guest) with
    9.27  
    9.28 -kernel = "/usr/lib/xen/boot/stubdom.gz"
    9.29 +kernel = "/usr/lib/xen/boot/ioemu-stubdom.gz"
    9.30  vif = [ '', 'ip=10.0.1.1,mac=aa:00:00:12:23:34']
    9.31  disk = [  'file:/tmp/install.iso,hdc:cdrom,r', 'phy:/dev/sda6,hda,w', 'file:/tmp/test,hdb,r' ]
    9.32  
    9.33 @@ -42,34 +49,36 @@ There are three posibilities
    9.34  
    9.35  * Using SDL
    9.36  
    9.37 -In hvmconfig, disable vnc:
    9.38 +  - In hvmconfig, disable vnc and sdl:
    9.39  
    9.40  vnc = 0
    9.41 +sdl = 0
    9.42  
    9.43 -In stubdom-hvmconfig, set a vfb:
    9.44 +  - In stubdom-hvmconfig, set an sdl vfb:
    9.45  
    9.46  vfb = [ 'type=sdl' ]
    9.47  
    9.48  * Using a VNC server in the stub domain
    9.49  
    9.50 -In hvmconfig, set vnclisten to "172.30.206.1" for instance.  Do not use a host
    9.51 -name as Mini-OS does not have a name resolver.  Do not use 127.0.0.1 since then
    9.52 -you will not be able to connect to it.
    9.53 +  - In hvmconfig, set vnclisten to "172.30.206.1" for instance.  Do not use a
    9.54 +host name as Mini-OS does not have a name resolver.  Do not use 127.0.0.1 since
    9.55 +then you will not be able to connect to it.
    9.56  
    9.57  vnc = 1
    9.58  vnclisten = "172.30.206.1"
    9.59  
    9.60 -In stubdom-hvmconfig, fill the reserved vif with the same IP, for instance:
    9.61 +  - In stubdom-hvmconfig, fill the reserved vif with the same IP, for instance:
    9.62  
    9.63  vif = [ 'ip=172.30.206.1', 'ip=10.0.1.1,mac=aa:00:00:12:23:34']
    9.64  
    9.65  * Using a VNC server in dom0
    9.66  
    9.67 -In hvmconfig, disable vnc:
    9.68 +  - In hvmconfig, disable vnc and sdl:
    9.69  
    9.70  vnc = 0
    9.71 +sdl = 0
    9.72  
    9.73 -In stubdom-hvmconfig, set a vfb:
    9.74 +  - In stubdom-hvmconfig, set a vnc vfb:
    9.75  
    9.76  vfb = [ 'type=vnc' ]
    9.77  
    9.78 @@ -85,3 +94,43 @@ ln -s /var/lib/xen /exports/var/lib
    9.79  /usr/sbin/fs-backend &
    9.80  
    9.81  xm create hvmconfig
    9.82 +
    9.83 +
    9.84 +
    9.85 +                                   PV-GRUB
    9.86 +                                   =======
    9.87 +
    9.88 +  This replaces pygrub to boot domU images safely: it runs the regular grub
    9.89 +inside the created domain itself and uses regular domU facilities to read the
    9.90 +disk / fetch files from network etc. ; it eventually loads the PV kernel and
    9.91 +chain-boots it.
    9.92 +  
    9.93 +Configuration
    9.94 +=============
    9.95 +
    9.96 +In your PV config,
    9.97 +
    9.98 +- use /usr/lib/xen/boot/pv-grub.gz as kernel:
    9.99 +
   9.100 +kernel = "/usr/lib/xen/boot/pv-grub.gz"
   9.101 +
   9.102 +- set the path to menu.lst, as seen from the domU, in extra:
   9.103 +
   9.104 +extra = "(hd0,0)/boot/grub/menu.lst"
   9.105 +
   9.106 +you can also use a tftp path (dhcp will be automatically performed):
   9.107 +
   9.108 +extra = "(nd)/somepath/menu.lst"
   9.109 +
   9.110 +or you can set it in option 150 of your dhcp server and leave extra empty
   9.111 +
   9.112 +Limitations
   9.113 +===========
   9.114 +
   9.115 +- You can not boot a 64bit kernel with a 32bit-compiled PV-GRUB and vice-versa.
   9.116 +To cross-compile a 32bit PV-GRUB,
   9.117 +
   9.118 +export XEN_TARGET_ARCH=x86_32
   9.119 +
   9.120 +- bootsplash is supported, but the ioemu backend does not yet support restart
   9.121 +for use by the booted kernel.
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/stubdom/grub.patches/10graphics.diff	Wed Jun 18 09:36:47 2008 +0100
    10.3 @@ -0,0 +1,2299 @@
    10.4 +diff -Naur grub-0.97.orig/configure.ac grub-0.97/configure.ac
    10.5 +--- grub-0.97.orig/configure.ac	2005-05-07 23:36:03.000000000 -0300
    10.6 ++++ grub-0.97/configure.ac	2005-06-12 20:56:49.000000000 -0300
    10.7 +@@ -595,6 +595,11 @@
    10.8 +   [  --enable-diskless       enable diskless support])
    10.9 + AM_CONDITIONAL(DISKLESS_SUPPORT, test "x$enable_diskless" = xyes)
   10.10 + 
   10.11 ++dnl Graphical splashscreen support
   10.12 ++AC_ARG_ENABLE(graphics,
   10.13 ++  [  --disable-graphics      disable graphics terminal support])
   10.14 ++AM_CONDITIONAL(GRAPHICS_SUPPORT, test "x$enable_graphics" != xno)
   10.15 ++
   10.16 + dnl Hercules terminal
   10.17 + AC_ARG_ENABLE(hercules,
   10.18 +   [  --disable-hercules      disable hercules terminal support])
   10.19 +diff -Naur grub-0.97.orig/stage2/asm.S grub-0.97/stage2/asm.S
   10.20 +--- grub-0.97.orig/stage2/asm.S	2004-06-19 13:55:22.000000000 -0300
   10.21 ++++ grub-0.97/stage2/asm.S	2005-06-13 14:05:31.000000000 -0300
   10.22 +@@ -2216,7 +2216,304 @@
   10.23 + 	pop	%ebx
   10.24 + 	pop	%ebp
   10.25 + 	ret
   10.26 +-		
   10.27 ++
   10.28 ++
   10.29 ++/* graphics mode functions */
   10.30 ++#ifdef SUPPORT_GRAPHICS
   10.31 ++VARIABLE(cursorX)
   10.32 ++.word	0
   10.33 ++VARIABLE(cursorY)
   10.34 ++.word	0
   10.35 ++VARIABLE(cursorCount)
   10.36 ++.word 0
   10.37 ++VARIABLE(cursorBuf)
   10.38 ++.byte	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
   10.39 ++
   10.40 ++
   10.41 ++/*
   10.42 ++ * set_int1c_handler(void)
   10.43 ++ */
   10.44 ++ENTRY(set_int1c_handler)
   10.45 ++	pushl   %edi
   10.46 ++
   10.47 ++	/* save the original int1c handler */
   10.48 ++	movl    $0x70, %edi
   10.49 ++	movw    (%edi), %ax
   10.50 ++	movw    %ax, ABS(int1c_offset)
   10.51 ++	movw    2(%edi), %ax
   10.52 ++	movw    %ax, ABS(int1c_segment)
   10.53 ++
   10.54 ++	/* save the new int1c handler */
   10.55 ++	movw    $ABS(int1c_handler), %ax
   10.56 ++	movw    %ax, (%edi)
   10.57 ++	xorw    %ax, %ax
   10.58 ++	movw    %ax, 2(%edi)
   10.59 ++
   10.60 ++	popl    %edi
   10.61 ++	ret
   10.62 ++
   10.63 ++
   10.64 ++/*
   10.65 ++ * unset_int1c_handler(void)
   10.66 ++ */
   10.67 ++ENTRY(unset_int1c_handler)
   10.68 ++	pushl   %edi
   10.69 ++
   10.70 ++	/* check if int1c_handler is set */
   10.71 ++	movl    $0x70, %edi
   10.72 ++	movw    $ABS(int1c_handler), %ax
   10.73 ++	cmpw    %ax, (%edi)
   10.74 ++	jne     int1c_1
   10.75 ++	xorw    %ax, %ax
   10.76 ++	cmpw    %ax, 2(%edi)
   10.77 ++	jne     int1c_1
   10.78 ++
   10.79 ++	/* restore the original */
   10.80 ++	movw    ABS(int1c_offset), %ax
   10.81 ++	movw    %ax, (%edi)
   10.82 ++	movw    ABS(int1c_segment), %ax
   10.83 ++	movw    %ax, 2(%edi)
   10.84 ++
   10.85 ++int1c_1:
   10.86 ++	popl    %edi
   10.87 ++	ret
   10.88 ++
   10.89 ++
   10.90 ++/*
   10.91 ++ * blinks graphics cursor
   10.92 ++ */
   10.93 ++	.code16
   10.94 ++write_data:
   10.95 ++	movw    $0, %ax
   10.96 ++	movw    %ax, %ds
   10.97 ++
   10.98 ++	mov     $0xA000, %ax            /* video in es:di */
   10.99 ++	mov     %ax, %es
  10.100 ++	mov     $80, %ax
  10.101 ++	movw    $ABS(cursorY), %si
  10.102 ++	mov     %ds:(%si), %bx
  10.103 ++	mul     %bx
  10.104 ++	movw    $ABS(cursorX), %si
  10.105 ++	mov     %ds:(%si), %bx
  10.106 ++	shr     $3, %bx                 /* %bx /= 8 */
  10.107 ++	add     %bx, %ax
  10.108 ++	mov     %ax, %di
  10.109 ++
  10.110 ++	movw    $ABS(cursorBuf), %si    /* fontBuf in ds:si */
  10.111 ++
  10.112 ++	/* prepare for data moving */
  10.113 ++	mov     $16, %dx                /* altura da fonte */
  10.114 ++	mov     $80, %bx                /* bytes por linha */
  10.115 ++
  10.116 ++write_loop:
  10.117 ++	movb    %ds:(%si), %al
  10.118 ++	xorb    $0xff, %al
  10.119 ++	movb    %al, %ds:(%si)          /* invert cursorBuf */
  10.120 ++	movb    %al, %es:(%di)          /* write to video */
  10.121 ++	add     %bx, %di
  10.122 ++	inc     %si
  10.123 ++	dec     %dx
  10.124 ++	jg      write_loop
  10.125 ++	ret
  10.126 ++
  10.127 ++int1c_handler:
  10.128 ++	pusha
  10.129 ++	mov     $0, %ax
  10.130 ++	mov     %ax, %ds
  10.131 ++	mov     $ABS(cursorCount), %si
  10.132 ++	mov     %ds:(%si), %ax
  10.133 ++	inc     %ax
  10.134 ++	mov     %ax, %ds:(%si)
  10.135 ++	cmp     $9, %ax
  10.136 ++	jne     int1c_done
  10.137 ++
  10.138 ++	mov     $0, %ax
  10.139 ++	mov     %ax, %ds:(%si)
  10.140 ++	call    write_data
  10.141 ++
  10.142 ++int1c_done:
  10.143 ++	popa
  10.144 ++	iret
  10.145 ++	/* call previous int1c handler */
  10.146 ++	/* ljmp */
  10.147 ++	.byte   0xea
  10.148 ++int1c_offset:  .word   0
  10.149 ++int1c_segment: .word   0
  10.150 ++	.code32
  10.151 ++
  10.152 ++
  10.153 ++/*
  10.154 ++ * unsigned char set_videomode(unsigned char mode)
  10.155 ++ * BIOS call "INT 10H Function 0h" to set video mode
  10.156 ++ *	Call with	%ah = 0x0
  10.157 ++ *			%al = video mode
  10.158 ++ *  Returns old videomode.
  10.159 ++ */
  10.160 ++ENTRY(set_videomode)
  10.161 ++	pushl	%ebp
  10.162 ++	movl	%esp,%ebp
  10.163 ++	pushl	%ebx
  10.164 ++	pushl	%ecx
  10.165 ++
  10.166 ++	movb	8(%ebp), %cl
  10.167 ++
  10.168 ++	call	EXT_C(prot_to_real)
  10.169 ++	.code16
  10.170 ++
  10.171 ++	xorb	%al, %al
  10.172 ++	movb	$0xf, %ah
  10.173 ++	int	$0x10			/* Get Current Video mode */
  10.174 ++	movb	%al, %ch
  10.175 ++	xorb	%ah, %ah
  10.176 ++	movb	%cl, %al
  10.177 ++	int	$0x10			/* Set Video mode */
  10.178 ++
  10.179 ++	DATA32	call	EXT_C(real_to_prot)
  10.180 ++	.code32
  10.181 ++
  10.182 ++	xorl	%eax, %eax
  10.183 ++	movb	%ch, %al
  10.184 ++
  10.185 ++	popl	%ecx
  10.186 ++	popl	%ebx
  10.187 ++	popl	%ebp
  10.188 ++	ret
  10.189 ++
  10.190 ++
  10.191 ++/*
  10.192 ++ * int get_videomode()
  10.193 ++ * BIOS call "INT 10H Function 0Fh" to get current video mode
  10.194 ++ *	Call with	%al = 0x0
  10.195 ++ *			%ah = 0xF
  10.196 ++ *	Returns current videomode.
  10.197 ++ */
  10.198 ++ENTRY(get_videomode)
  10.199 ++	pushl	%ebp
  10.200 ++	movl	%esp,%ebp
  10.201 ++	pushl	%ebx
  10.202 ++	pushl	%ecx
  10.203 ++
  10.204 ++	call	EXT_C(prot_to_real)
  10.205 ++	.code16
  10.206 ++
  10.207 ++	xorb	%al, %al
  10.208 ++	movb	$0xF, %ah
  10.209 ++	int	$0x10			/* Get Current Video mode */
  10.210 ++	movb	%al, %cl	/* For now we only want display mode */
  10.211 ++
  10.212 ++	DATA32	call	EXT_C(real_to_prot)
  10.213 ++	.code32
  10.214 ++
  10.215 ++	xorl	%eax, %eax
  10.216 ++	movb	%cl, %al
  10.217 ++
  10.218 ++	popl	%ecx
  10.219 ++	popl	%ebx
  10.220 ++	popl	%ebp
  10.221 ++	ret
  10.222 ++
  10.223 ++
  10.224 ++/*
  10.225 ++ * unsigned char * graphics_get_font()
  10.226 ++ * BIOS call "INT 10H Function 11h" to set font
  10.227 ++ *      Call with       %ah = 0x11
  10.228 ++ */
  10.229 ++ENTRY(graphics_get_font)
  10.230 ++	push	%ebp
  10.231 ++	push	%ebx
  10.232 ++	push	%ecx
  10.233 ++	push	%edx
  10.234 ++
  10.235 ++	call	EXT_C(prot_to_real)
  10.236 ++	.code16
  10.237 ++
  10.238 ++	movw	$0x1130, %ax
  10.239 ++	movb	$6, %bh		/* font 8x16 */
  10.240 ++	int	$0x10
  10.241 ++	movw	%bp, %dx
  10.242 ++	movw	%es, %cx
  10.243 ++
  10.244 ++	DATA32	call	EXT_C(real_to_prot)
  10.245 ++	.code32
  10.246 ++
  10.247 ++	xorl	%eax, %eax
  10.248 ++	movw	%cx, %ax
  10.249 ++	shll	$4, %eax
  10.250 ++	movw	%dx, %ax
  10.251 ++
  10.252 ++	pop	%edx
  10.253 ++	pop	%ecx
  10.254 ++	pop	%ebx
  10.255 ++	pop	%ebp
  10.256 ++	ret
  10.257 ++
  10.258 ++
  10.259 ++/*
  10.260 ++ * graphics_set_palette(index, red, green, blue)
  10.261 ++ * BIOS call "INT 10H Function 10h" to set individual dac register
  10.262 ++ *	Call with	%ah = 0x10
  10.263 ++ *			%bx = register number
  10.264 ++ *			%ch = new value for green (0-63)
  10.265 ++ *			%cl = new value for blue (0-63)
  10.266 ++ *			%dh = new value for red (0-63)
  10.267 ++ */
  10.268 ++
  10.269 ++ENTRY(graphics_set_palette)
  10.270 ++	push	%ebp
  10.271 ++	push	%eax
  10.272 ++	push	%ebx
  10.273 ++	push	%ecx
  10.274 ++	push	%edx
  10.275 ++
  10.276 ++	movw	$0x3c8, %bx		/* address write mode register */
  10.277 ++
  10.278 ++	/* wait vertical retrace */
  10.279 ++	movw	$0x3da, %dx
  10.280 ++l1b:
  10.281 ++	inb	%dx, %al	/* wait vertical active display */
  10.282 ++	test	$8, %al
  10.283 ++	jnz	l1b
  10.284 ++
  10.285 ++l2b:
  10.286 ++	inb	%dx, %al	/* wait vertical retrace */
  10.287 ++	test	$8, %al
  10.288 ++	jnz	l2b
  10.289 ++
  10.290 ++	mov	%bx, %dx
  10.291 ++	movb	0x18(%esp), %al		/* index */
  10.292 ++	outb	%al, %dx
  10.293 ++	inc	%dx
  10.294 ++
  10.295 ++	movb	0x1c(%esp), %al		/* red */
  10.296 ++	outb	%al, %dx
  10.297 ++
  10.298 ++	movb	0x20(%esp), %al		/* green */
  10.299 ++	outb	%al, %dx
  10.300 ++
  10.301 ++	movb	0x24(%esp), %al		/* blue */
  10.302 ++	outb	%al, %dx
  10.303 ++
  10.304 ++	movw	0x18(%esp), %bx
  10.305 ++
  10.306 ++	call	EXT_C(prot_to_real)
  10.307 ++	.code16
  10.308 ++
  10.309 ++	movb	%bl, %bh
  10.310 ++	movw	$0x1000, %ax
  10.311 ++	int	$0x10
  10.312 ++
  10.313 ++	DATA32	call	EXT_C(real_to_prot)
  10.314 ++	.code32
  10.315 ++
  10.316 ++	pop	%edx
  10.317 ++	pop	%ecx
  10.318 ++	pop	%ebx
  10.319 ++	pop	%eax
  10.320 ++	pop	%ebp
  10.321 ++	ret
  10.322 ++#endif /* SUPPORT_GRAPHICS */
  10.323 ++
  10.324 ++
  10.325 + /*
  10.326 +  * getrtsecs()
  10.327 +  *	if a seconds value can be read, read it and return it (BCD),
  10.328 +diff -Naur grub-0.97.orig/stage2/builtins.c grub-0.97/stage2/builtins.c
  10.329 +--- grub-0.97.orig/stage2/builtins.c	2005-02-15 19:58:23.000000000 -0200
  10.330 ++++ grub-0.97/stage2/builtins.c	2005-06-13 18:44:03.000000000 -0300
  10.331 +@@ -28,6 +28,10 @@
  10.332 + #include <filesys.h>
  10.333 + #include <term.h>
  10.334 + 
  10.335 ++#ifdef SUPPORT_GRAPHICS
  10.336 ++# include <graphics.h>
  10.337 ++#endif
  10.338 ++
  10.339 + #ifdef SUPPORT_NETBOOT
  10.340 + # define GRUB	1
  10.341 + # include <etherboot.h>
  10.342 +@@ -237,12 +241,22 @@
  10.343 + static int
  10.344 + boot_func (char *arg, int flags)
  10.345 + {
  10.346 ++  struct term_entry *prev_term = current_term;
  10.347 +   /* Clear the int15 handler if we can boot the kernel successfully.
  10.348 +      This assumes that the boot code never fails only if KERNEL_TYPE is
  10.349 +      not KERNEL_TYPE_NONE. Is this assumption is bad?  */
  10.350 +   if (kernel_type != KERNEL_TYPE_NONE)
  10.351 +     unset_int15_handler ();
  10.352 + 
  10.353 ++  /* if our terminal needed initialization, we should shut it down
  10.354 ++   * before booting the kernel, but we want to save what it was so
  10.355 ++   * we can come back if needed */
  10.356 ++  if (current_term->shutdown) 
  10.357 ++    {
  10.358 ++      current_term->shutdown();
  10.359 ++      current_term = term_table; /* assumption: console is first */
  10.360 ++    }
  10.361 ++
  10.362 + #ifdef SUPPORT_NETBOOT
  10.363 +   /* Shut down the networking.  */
  10.364 +   cleanup_net ();
  10.365 +@@ -306,6 +320,13 @@
  10.366 +       return 1;
  10.367 +     }
  10.368 + 
  10.369 ++  /* if we get back here, we should go back to what our term was before */
  10.370 ++  current_term = prev_term;
  10.371 ++  if (current_term->startup)
  10.372 ++      /* if our terminal fails to initialize, fall back to console since
  10.373 ++       * it should always work */
  10.374 ++      if (current_term->startup() == 0)
  10.375 ++          current_term = term_table; /* we know that console is first */
  10.376 +   return 0;
  10.377 + }
  10.378 + 
  10.379 +@@ -852,6 +873,251 @@
  10.380 + };
  10.381 + #endif /* SUPPORT_NETBOOT */
  10.382 + 
  10.383 ++#ifdef SUPPORT_GRAPHICS
  10.384 ++
  10.385 ++static int splashimage_func(char *arg, int flags) {
  10.386 ++  int i;
  10.387 ++    
  10.388 ++  /* filename can only be 256 characters due to our buffer size */
  10.389 ++  if (grub_strlen(arg) > 256) {
  10.390 ++    grub_printf("Splash image filename too large\n");
  10.391 ++    grub_printf("Press any key to continue...");
  10.392 ++    getkey();
  10.393 ++    return 1;
  10.394 ++  }
  10.395 ++
  10.396 ++  /* get rid of TERM_NEED_INIT from the graphics terminal. */
  10.397 ++  for (i = 0; term_table[i].name; i++) {
  10.398 ++    if (grub_strcmp (term_table[i].name, "graphics") == 0) {
  10.399 ++      term_table[i].flags &= ~TERM_NEED_INIT;
  10.400 ++      break;
  10.401 ++    }
  10.402 ++  }
  10.403 ++
  10.404 ++  graphics_set_splash(arg);
  10.405 ++
  10.406 ++  if (flags == BUILTIN_CMDLINE && graphics_inited) {
  10.407 ++    graphics_end();
  10.408 ++    if (graphics_init() == 0) {
  10.409 ++      /* Fallback to default term */
  10.410 ++      current_term = term_table;
  10.411 ++      max_lines = current_term->max_lines;
  10.412 ++      if (current_term->cls)
  10.413 ++        current_term->cls();
  10.414 ++      grub_printf("Failed to set splash image and/or graphics mode\n");
  10.415 ++      return 1;
  10.416 ++    }
  10.417 ++    graphics_cls();
  10.418 ++  }
  10.419 ++
  10.420 ++  if (flags == BUILTIN_MENU)
  10.421 ++    current_term = term_table + i;
  10.422 ++
  10.423 ++  return 0;
  10.424 ++}
  10.425 ++
  10.426 ++static struct builtin builtin_splashimage =
  10.427 ++{
  10.428 ++  "splashimage",
  10.429 ++  splashimage_func,
  10.430 ++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
  10.431 ++  "splashimage FILE",
  10.432 ++  "Load FILE as the background image when in graphics mode."
  10.433 ++};
  10.434 ++
  10.435 ++
  10.436 ++/* shade */
  10.437 ++static int
  10.438 ++shade_func(char *arg, int flags)
  10.439 ++{
  10.440 ++    int new_shade;
  10.441 ++
  10.442 ++    if (!arg || safe_parse_maxint(&arg, &new_shade) == 0)
  10.443 ++       return (1);
  10.444 ++
  10.445 ++    if (shade != new_shade) {
  10.446 ++       shade = new_shade;
  10.447 ++       if (flags == BUILTIN_CMDLINE && graphics_inited) {
  10.448 ++           graphics_end();
  10.449 ++           graphics_init();
  10.450 ++           graphics_cls();
  10.451 ++       }
  10.452 ++    }
  10.453 ++
  10.454 ++    return 0;
  10.455 ++}
  10.456 ++
  10.457 ++static struct builtin builtin_shade =
  10.458 ++{
  10.459 ++  "shade",
  10.460 ++  shade_func,
  10.461 ++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
  10.462 ++  "shade INTEGER",
  10.463 ++  "If set to 0, disables the use of shaded text, else enables it."
  10.464 ++};
  10.465 ++
  10.466 ++
  10.467 ++/* foreground */
  10.468 ++static int
  10.469 ++foreground_func(char *arg, int flags)
  10.470 ++{
  10.471 ++    if (grub_strlen(arg) == 6) {
  10.472 ++	int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
  10.473 ++	int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
  10.474 ++	int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
  10.475 ++
  10.476 ++	foreground = (r << 16) | (g << 8) | b;
  10.477 ++	if (graphics_inited)
  10.478 ++	    graphics_set_palette(15, r, g, b);
  10.479 ++
  10.480 ++	return 0;
  10.481 ++    }
  10.482 ++
  10.483 ++    return 1;
  10.484 ++}
  10.485 ++
  10.486 ++static struct builtin builtin_foreground =
  10.487 ++{
  10.488 ++  "foreground",
  10.489 ++  foreground_func,
  10.490 ++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
  10.491 ++  "foreground RRGGBB",
  10.492 ++  "Sets the foreground color when in graphics mode."
  10.493 ++  "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
  10.494 ++};
  10.495 ++
  10.496 ++
  10.497 ++/* background */
  10.498 ++static int
  10.499 ++background_func(char *arg, int flags)
  10.500 ++{
  10.501 ++    if (grub_strlen(arg) == 6) {
  10.502 ++	int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
  10.503 ++	int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
  10.504 ++	int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
  10.505 ++
  10.506 ++	background = (r << 16) | (g << 8) | b;
  10.507 ++	if (graphics_inited)
  10.508 ++	    graphics_set_palette(0, r, g, b);
  10.509 ++	return 0;
  10.510 ++    }
  10.511 ++
  10.512 ++    return 1;
  10.513 ++}
  10.514 ++
  10.515 ++static struct builtin builtin_background =
  10.516 ++{
  10.517 ++  "background",
  10.518 ++  background_func,
  10.519 ++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
  10.520 ++  "background RRGGBB",
  10.521 ++  "Sets the background color when in graphics mode."
  10.522 ++  "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
  10.523 ++};
  10.524 ++
  10.525 ++
  10.526 ++/* border */
  10.527 ++static int
  10.528 ++border_func(char *arg, int flags)
  10.529 ++{
  10.530 ++    if (grub_strlen(arg) == 6) {
  10.531 ++       int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
  10.532 ++       int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
  10.533 ++       int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
  10.534 ++
  10.535 ++       window_border = (r << 16) | (g << 8) | b;
  10.536 ++       if (graphics_inited)
  10.537 ++           graphics_set_palette(0x11, r, g, b);
  10.538 ++
  10.539 ++       return 0;
  10.540 ++    }
  10.541 ++
  10.542 ++    return 1;
  10.543 ++}
  10.544 ++
  10.545 ++static struct builtin builtin_border =
  10.546 ++{
  10.547 ++  "border",
  10.548 ++  border_func,
  10.549 ++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
  10.550 ++  "border RRGGBB",
  10.551 ++  "Sets the border video color when in graphics mode."
  10.552 ++  "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
  10.553 ++};
  10.554 ++
  10.555 ++
  10.556 ++/* viewport */
  10.557 ++static int
  10.558 ++viewport_func (char *arg, int flags)
  10.559 ++{
  10.560 ++    int i;
  10.561 ++    int x0 = 0, y0 = 0, x1 = 80, y1 = 30;
  10.562 ++    int *pos[4] = { &x0, &y0, &x1, &y1 };
  10.563 ++
  10.564 ++    if (!arg)
  10.565 ++       return (1);
  10.566 ++    for (i = 0; i < 4; i++) {
  10.567 ++       if (!*arg)
  10.568 ++           return (1);
  10.569 ++    while (*arg && (*arg == ' ' || *arg == '\t'))
  10.570 ++           ++arg;
  10.571 ++       if (!safe_parse_maxint(&arg, pos[i]))
  10.572 ++           return (1);
  10.573 ++       while (*arg && (*arg != ' ' && *arg != '\t'))
  10.574 ++           ++arg;
  10.575 ++    }
  10.576 ++
  10.577 ++    /* minimum size is 65 colums and 16 rows */
  10.578 ++    if (x0 > x1 - 66 || y0 > y1 - 16 || x0 < 0 || y0 < 0 || x1 > 80 || y1 > 30)
  10.579 ++       return 1;
  10.580 ++
  10.581 ++    view_x0 = x0;
  10.582 ++    view_y0 = y0;
  10.583 ++    view_x1 = x1;
  10.584 ++    view_y1 = y1;
  10.585 ++
  10.586 ++    if (flags == BUILTIN_CMDLINE && graphics_inited) {
  10.587 ++       graphics_end();
  10.588 ++       graphics_init();
  10.589 ++       graphics_cls();
  10.590 ++    }
  10.591 ++
  10.592 ++    return 0;
  10.593 ++}
  10.594 ++
  10.595 ++static struct builtin builtin_viewport =
  10.596 ++{
  10.597 ++  "viewport",
  10.598 ++  viewport_func,
  10.599 ++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
  10.600 ++  "viewport x0 y0 x1 y1",
  10.601 ++  "Changes grub internals to output text in the window defined by"
  10.602 ++  " four parameters. The x and y parameters are 0 based. This option"
  10.603 ++  " only works with the graphics interface."
  10.604 ++};
  10.605 ++
  10.606 ++#endif /* SUPPORT_GRAPHICS */
  10.607 ++
  10.608 ++
  10.609 ++/* clear */
  10.610 ++static int 
  10.611 ++clear_func() 
  10.612 ++{
  10.613 ++  if (current_term->cls)
  10.614 ++    current_term->cls();
  10.615 ++
  10.616 ++  return 0;
  10.617 ++}
  10.618 ++
  10.619 ++static struct builtin builtin_clear =
  10.620 ++{
  10.621 ++  "clear",
  10.622 ++  clear_func,
  10.623 ++  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
  10.624 ++  "clear",
  10.625 ++  "Clear the screen"
  10.626 ++};
  10.627 ++
  10.628 + 
  10.629 + /* displayapm */
  10.630 + static int
  10.631 +@@ -1454,14 +1720,20 @@
  10.632 + 
  10.633 + 
  10.634 + /* help */
  10.635 +-#define MAX_SHORT_DOC_LEN	39
  10.636 +-#define MAX_LONG_DOC_LEN	66
  10.637 +-
  10.638 + static int
  10.639 + help_func (char *arg, int flags)
  10.640 + {
  10.641 +-  int all = 0;
  10.642 +-  
  10.643 ++  int all = 0, max_short_doc_len, max_long_doc_len;
  10.644 ++  max_short_doc_len = 39;
  10.645 ++  max_long_doc_len = 66;
  10.646 ++#ifdef SUPPORT_GRAPHICS
  10.647 ++  if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0)
  10.648 ++    {
  10.649 ++      max_short_doc_len = (view_x1 - view_x0 + 1) / 2 - 1;
  10.650 ++      max_long_doc_len = (view_x1 - view_x0) - 14;
  10.651 ++    }
  10.652 ++#endif
  10.653 ++
  10.654 +   if (grub_memcmp (arg, "--all", sizeof ("--all") - 1) == 0)
  10.655 +     {
  10.656 +       all = 1;
  10.657 +@@ -1491,13 +1763,13 @@
  10.658 + 
  10.659 + 	  len = grub_strlen ((*builtin)->short_doc);
  10.660 + 	  /* If the length of SHORT_DOC is too long, truncate it.  */
  10.661 +-	  if (len > MAX_SHORT_DOC_LEN - 1)
  10.662 +-	    len = MAX_SHORT_DOC_LEN - 1;
  10.663 ++	  if (len > max_short_doc_len - 1)
  10.664 ++	    len = max_short_doc_len - 1;
  10.665 + 
  10.666 + 	  for (i = 0; i < len; i++)
  10.667 + 	    grub_putchar ((*builtin)->short_doc[i]);
  10.668 + 
  10.669 +-	  for (; i < MAX_SHORT_DOC_LEN; i++)
  10.670 ++	  for (; i < max_short_doc_len; i++)
  10.671 + 	    grub_putchar (' ');
  10.672 + 
  10.673 + 	  if (! left)
  10.674 +@@ -1546,10 +1818,10 @@
  10.675 + 		      int i;
  10.676 + 
  10.677 + 		      /* If LEN is too long, fold DOC.  */
  10.678 +-		      if (len > MAX_LONG_DOC_LEN)
  10.679 ++		      if (len > max_long_doc_len)
  10.680 + 			{
  10.681 + 			  /* Fold this line at the position of a space.  */
  10.682 +-			  for (len = MAX_LONG_DOC_LEN; len > 0; len--)
  10.683 ++			  for (len = max_long_doc_len; len > 0; len--)
  10.684 + 			    if (doc[len - 1] == ' ')
  10.685 + 			      break;
  10.686 + 			}
  10.687 +@@ -4085,7 +4357,7 @@
  10.688 + };
  10.689 + 
  10.690 + 
  10.691 +-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
  10.692 ++#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
  10.693 + /* terminal */
  10.694 + static int
  10.695 + terminal_func (char *arg, int flags)
  10.696 +@@ -4244,17 +4516,29 @@
  10.697 +  end:
  10.698 +   current_term = term_table + default_term;
  10.699 +   current_term->flags = term_flags;
  10.700 +-  
  10.701 ++
  10.702 +   if (lines)
  10.703 +     max_lines = lines;
  10.704 +   else
  10.705 +-    /* 24 would be a good default value.  */
  10.706 +-    max_lines = 24;
  10.707 +-  
  10.708 ++    max_lines = current_term->max_lines;
  10.709 ++
  10.710 +   /* If the interface is currently the command-line,
  10.711 +      restart it to repaint the screen.  */
  10.712 +-  if (current_term != prev_term && (flags & BUILTIN_CMDLINE))
  10.713 ++  if ((current_term != prev_term) && (flags & BUILTIN_CMDLINE)){
  10.714 ++    if (prev_term->shutdown)
  10.715 ++      prev_term->shutdown();
  10.716 ++    if (current_term->startup) {
  10.717 ++      /* If startup fails, return to previous term */
  10.718 ++      if (current_term->startup() == 0) {
  10.719 ++        current_term = prev_term;
  10.720 ++        max_lines = current_term->max_lines;
  10.721 ++        if (current_term->cls) {
  10.722 ++          current_term->cls();
  10.723 ++        }
  10.724 ++      }
  10.725 ++    }
  10.726 +     grub_longjmp (restart_cmdline_env, 0);
  10.727 ++  }
  10.728 +   
  10.729 +   return 0;
  10.730 + }
  10.731 +@@ -4264,7 +4548,7 @@
  10.732 +   "terminal",
  10.733 +   terminal_func,
  10.734 +   BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
  10.735 +-  "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules]",
  10.736 ++  "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules] [graphics]",
  10.737 +   "Select a terminal. When multiple terminals are specified, wait until"
  10.738 +   " you push any key to continue. If both console and serial are specified,"
  10.739 +   " the terminal to which you input a key first will be selected. If no"
  10.740 +@@ -4276,7 +4560,7 @@
  10.741 +   " seconds. The option --lines specifies the maximum number of lines."
  10.742 +   " The option --silent is used to suppress messages."
  10.743 + };
  10.744 +-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
  10.745 ++#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
  10.746 + 
  10.747 + 
  10.748 + #ifdef SUPPORT_SERIAL
  10.749 +@@ -4795,13 +5079,20 @@
  10.750 + /* The table of builtin commands. Sorted in dictionary order.  */
  10.751 + struct builtin *builtin_table[] =
  10.752 + {
  10.753 ++#ifdef SUPPORT_GRAPHICS
  10.754 ++  &builtin_background,
  10.755 ++#endif
  10.756 +   &builtin_blocklist,
  10.757 +   &builtin_boot,
  10.758 + #ifdef SUPPORT_NETBOOT
  10.759 +   &builtin_bootp,
  10.760 + #endif /* SUPPORT_NETBOOT */
  10.761 ++#ifdef SUPPORT_GRAPHICS
  10.762 ++  &builtin_border,
  10.763 ++#endif
  10.764 +   &builtin_cat,
  10.765 +   &builtin_chainloader,
  10.766 ++  &builtin_clear,
  10.767 +   &builtin_cmp,
  10.768 +   &builtin_color,
  10.769 +   &builtin_configfile,
  10.770 +@@ -4821,6 +5112,9 @@
  10.771 +   &builtin_embed,
  10.772 +   &builtin_fallback,
  10.773 +   &builtin_find,
  10.774 ++#ifdef SUPPORT_GRAPHICS
  10.775 ++  &builtin_foreground,
  10.776 ++#endif
  10.777 +   &builtin_fstest,
  10.778 +   &builtin_geometry,
  10.779 +   &builtin_halt,
  10.780 +@@ -4864,9 +5158,13 @@
  10.781 + #endif /* SUPPORT_SERIAL */
  10.782 +   &builtin_setkey,
  10.783 +   &builtin_setup,
  10.784 +-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
  10.785 ++#ifdef SUPPORT_GRAPHICS
  10.786 ++  &builtin_shade,
  10.787 ++  &builtin_splashimage,
  10.788 ++#endif /* SUPPORT_GRAPHICS */
  10.789 ++#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
  10.790 +   &builtin_terminal,
  10.791 +-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
  10.792 ++#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
  10.793 + #ifdef SUPPORT_SERIAL
  10.794 +   &builtin_terminfo,
  10.795 + #endif /* SUPPORT_SERIAL */
  10.796 +@@ -4880,5 +5178,8 @@
  10.797 +   &builtin_unhide,
  10.798 +   &builtin_uppermem,
  10.799 +   &builtin_vbeprobe,
  10.800 ++#ifdef SUPPORT_GRAPHICS
  10.801 ++  &builtin_viewport,
  10.802 ++#endif
  10.803 +   0
  10.804 + };
  10.805 +diff -Naur grub-0.97.orig/stage2/char_io.c grub-0.97/stage2/char_io.c
  10.806 +--- grub-0.97.orig/stage2/char_io.c	2005-02-01 18:51:23.000000000 -0200
  10.807 ++++ grub-0.97/stage2/char_io.c	2005-06-12 20:56:49.000000000 -0300
  10.808 +@@ -29,12 +29,17 @@
  10.809 + # include <serial.h>
  10.810 + #endif
  10.811 + 
  10.812 ++#ifdef SUPPORT_GRAPHICS
  10.813 ++# include <graphics.h>
  10.814 ++#endif
  10.815 ++
  10.816 + #ifndef STAGE1_5
  10.817 + struct term_entry term_table[] =
  10.818 +   {
  10.819 +     {
  10.820 +       "console",
  10.821 +       0,
  10.822 ++      24,
  10.823 +       console_putchar,
  10.824 +       console_checkkey,
  10.825 +       console_getkey,
  10.826 +@@ -43,13 +48,16 @@
  10.827 +       console_cls,
  10.828 +       console_setcolorstate,
  10.829 +       console_setcolor,
  10.830 +-      console_setcursor
  10.831 ++      console_setcursor,
  10.832 ++      0, 
  10.833 ++      0
  10.834 +     },
  10.835 + #ifdef SUPPORT_SERIAL
  10.836 +     {
  10.837 +       "serial",
  10.838 +       /* A serial device must be initialized.  */
  10.839 +       TERM_NEED_INIT,
  10.840 ++      24,
  10.841 +       serial_putchar,
  10.842 +       serial_checkkey,
  10.843 +       serial_getkey,
  10.844 +@@ -58,6 +66,8 @@
  10.845 +       serial_cls,
  10.846 +       serial_setcolorstate,
  10.847 +       0,
  10.848 ++      0,
  10.849 ++      0, 
  10.850 +       0
  10.851 +     },
  10.852 + #endif /* SUPPORT_SERIAL */
  10.853 +@@ -65,6 +75,7 @@
  10.854 +     {
  10.855 +       "hercules",
  10.856 +       0,
  10.857 ++      24,
  10.858 +       hercules_putchar,
  10.859 +       console_checkkey,
  10.860 +       console_getkey,
  10.861 +@@ -73,11 +84,30 @@
  10.862 +       hercules_cls,
  10.863 +       hercules_setcolorstate,
  10.864 +       hercules_setcolor,
  10.865 +-      hercules_setcursor
  10.866 ++      hercules_setcursor,
  10.867 ++      0,
  10.868 ++      0
  10.869 +     },      
  10.870 + #endif /* SUPPORT_HERCULES */
  10.871 ++#ifdef SUPPORT_GRAPHICS
  10.872 ++    { "graphics",
  10.873 ++      TERM_NEED_INIT, /* flags */
  10.874 ++      30, /* number of lines */
  10.875 ++      graphics_putchar, /* putchar */
  10.876 ++      console_checkkey, /* checkkey */
  10.877 ++      console_getkey, /* getkey */
  10.878 ++      graphics_getxy, /* getxy */
  10.879 ++      graphics_gotoxy, /* gotoxy */
  10.880 ++      graphics_cls, /* cls */
  10.881 ++      graphics_setcolorstate, /* setcolorstate */
  10.882 ++      graphics_setcolor, /* setcolor */
  10.883 ++      graphics_setcursor, /* nocursor */
  10.884 ++      graphics_init, /* initialize */
  10.885 ++      graphics_end /* shutdown */
  10.886 ++    },
  10.887 ++#endif /* SUPPORT_GRAPHICS */
  10.888 +     /* This must be the last entry.  */
  10.889 +-    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
  10.890 ++    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
  10.891 +   };
  10.892 + 
  10.893 + /* This must be console.  */
  10.894 +@@ -305,9 +335,10 @@
  10.895 + 
  10.896 +   /* XXX: These should be defined in shared.h, but I leave these here,
  10.897 +      until this code is freezed.  */
  10.898 +-#define CMDLINE_WIDTH	78
  10.899 + #define CMDLINE_MARGIN	10
  10.900 +-  
  10.901 ++
  10.902 ++  /* command-line limits */
  10.903 ++  int cmdline_width = 78, col_start = 0;
  10.904 +   int xpos, lpos, c, section;
  10.905 +   /* The length of PROMPT.  */
  10.906 +   int plen;
  10.907 +@@ -338,7 +369,7 @@
  10.908 +       
  10.909 +       /* If the cursor is in the first section, display the first section
  10.910 + 	 instead of the second.  */
  10.911 +-      if (section == 1 && plen + lpos < CMDLINE_WIDTH)
  10.912 ++      if (section == 1 && plen + lpos < cmdline_width)
  10.913 + 	cl_refresh (1, 0);
  10.914 +       else if (xpos - count < 1)
  10.915 + 	cl_refresh (1, 0);
  10.916 +@@ -354,7 +385,7 @@
  10.917 + 		grub_putchar ('\b');
  10.918 + 	    }
  10.919 + 	  else
  10.920 +-	    gotoxy (xpos, getxy () & 0xFF);
  10.921 ++	    gotoxy (xpos + col_start, getxy () & 0xFF);
  10.922 + 	}
  10.923 +     }
  10.924 + 
  10.925 +@@ -364,7 +395,7 @@
  10.926 +       lpos += count;
  10.927 + 
  10.928 +       /* If the cursor goes outside, scroll the screen to the right.  */
  10.929 +-      if (xpos + count >= CMDLINE_WIDTH)
  10.930 ++      if (xpos + count >= cmdline_width)
  10.931 + 	cl_refresh (1, 0);
  10.932 +       else
  10.933 + 	{
  10.934 +@@ -383,7 +414,7 @@
  10.935 + 		}
  10.936 + 	    }
  10.937 + 	  else
  10.938 +-	    gotoxy (xpos, getxy () & 0xFF);
  10.939 ++	    gotoxy (xpos + col_start, getxy () & 0xFF);
  10.940 + 	}
  10.941 +     }
  10.942 + 
  10.943 +@@ -398,14 +429,14 @@
  10.944 +       if (full)
  10.945 + 	{
  10.946 + 	  /* Recompute the section number.  */
  10.947 +-	  if (lpos + plen < CMDLINE_WIDTH)
  10.948 ++	  if (lpos + plen < cmdline_width)
  10.949 + 	    section = 0;
  10.950 + 	  else
  10.951 +-	    section = ((lpos + plen - CMDLINE_WIDTH)
  10.952 +-		       / (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) + 1);
  10.953 ++	    section = ((lpos + plen - cmdline_width)
  10.954 ++		       / (cmdline_width - 1 - CMDLINE_MARGIN) + 1);
  10.955 + 
  10.956 + 	  /* From the start to the end.  */
  10.957 +-	  len = CMDLINE_WIDTH;
  10.958 ++	  len = cmdline_width;
  10.959 + 	  pos = 0;
  10.960 + 	  grub_putchar ('\r');
  10.961 + 
  10.962 +@@ -445,8 +476,8 @@
  10.963 + 	  if (! full)
  10.964 + 	    offset = xpos - 1;
  10.965 + 	  
  10.966 +-	  start = ((section - 1) * (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN)
  10.967 +-		   + CMDLINE_WIDTH - plen - CMDLINE_MARGIN);
  10.968 ++	  start = ((section - 1) * (cmdline_width - 1 - CMDLINE_MARGIN)
  10.969 ++		   + cmdline_width - plen - CMDLINE_MARGIN);
  10.970 + 	  xpos = lpos + 1 - start;
  10.971 + 	  start += offset;
  10.972 + 	}
  10.973 +@@ -471,7 +502,7 @@
  10.974 +       
  10.975 +       /* If the cursor is at the last position, put `>' or a space,
  10.976 + 	 depending on if there are more characters in BUF.  */
  10.977 +-      if (pos == CMDLINE_WIDTH)
  10.978 ++      if (pos == cmdline_width)
  10.979 + 	{
  10.980 + 	  if (start + len < llen)
  10.981 + 	    grub_putchar ('>');
  10.982 +@@ -488,7 +519,7 @@
  10.983 + 	    grub_putchar ('\b');
  10.984 + 	}
  10.985 +       else
  10.986 +-	gotoxy (xpos, getxy () & 0xFF);
  10.987 ++	gotoxy (xpos + col_start, getxy () & 0xFF);
  10.988 +     }
  10.989 + 
  10.990 +   /* Initialize the command-line.  */
  10.991 +@@ -518,10 +549,10 @@
  10.992 + 	  
  10.993 + 	  llen += l;
  10.994 + 	  lpos += l;
  10.995 +-	  if (xpos + l >= CMDLINE_WIDTH)
  10.996 ++	  if (xpos + l >= cmdline_width)
  10.997 + 	    cl_refresh (1, 0);
  10.998 +-	  else if (xpos + l + llen - lpos > CMDLINE_WIDTH)
  10.999 +-	    cl_refresh (0, CMDLINE_WIDTH - xpos);
 10.1000 ++	  else if (xpos + l + llen - lpos > cmdline_width)
 10.1001 ++	    cl_refresh (0, cmdline_width - xpos);
 10.1002 + 	  else
 10.1003 + 	    cl_refresh (0, l + llen - lpos);
 10.1004 + 	}
 10.1005 +@@ -533,12 +564,22 @@
 10.1006 +       grub_memmove (buf + lpos, buf + lpos + count, llen - count + 1);
 10.1007 +       llen -= count;
 10.1008 +       
 10.1009 +-      if (xpos + llen + count - lpos > CMDLINE_WIDTH)
 10.1010 +-	cl_refresh (0, CMDLINE_WIDTH - xpos);
 10.1011 ++      if (xpos + llen + count - lpos > cmdline_width)
 10.1012 ++	cl_refresh (0, cmdline_width - xpos);
 10.1013 +       else
 10.1014 + 	cl_refresh (0, llen + count - lpos);
 10.1015 +     }
 10.1016 + 
 10.1017 ++  max_lines = current_term->max_lines;
 10.1018 ++#ifdef SUPPORT_GRAPHICS
 10.1019 ++  if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0)
 10.1020 ++    {
 10.1021 ++      cmdline_width = (view_x1 - view_x0) - 2;
 10.1022 ++      col_start = view_x0;
 10.1023 ++      max_lines = view_y1 - view_y0;
 10.1024 ++    }
 10.1025 ++#endif
 10.1026 ++
 10.1027 +   plen = grub_strlen (prompt);
 10.1028 +   llen = grub_strlen (cmdline);
 10.1029 + 
 10.1030 +@@ -1006,6 +1047,48 @@
 10.1031 + }
 10.1032 + #endif /* ! STAGE1_5 */
 10.1033 + 
 10.1034 ++#ifndef STAGE1_5
 10.1035 ++/* Internal pager.  */
 10.1036 ++int
 10.1037 ++do_more (void)
 10.1038 ++{
 10.1039 ++  if (count_lines >= 0)
 10.1040 ++    {
 10.1041 ++      count_lines++;
 10.1042 ++      if (count_lines >= max_lines - 2)
 10.1043 ++        {
 10.1044 ++          int tmp;
 10.1045 ++
 10.1046 ++          /* It's important to disable the feature temporarily, because
 10.1047 ++             the following grub_printf call will print newlines.  */
 10.1048 ++          count_lines = -1;
 10.1049 ++
 10.1050 ++          grub_printf("\n");
 10.1051 ++          if (current_term->setcolorstate)
 10.1052 ++            current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
 10.1053 ++
 10.1054 ++          grub_printf ("[Hit return to continue]");
 10.1055 ++
 10.1056 ++          if (current_term->setcolorstate)
 10.1057 ++            current_term->setcolorstate (COLOR_STATE_NORMAL);
 10.1058 ++
 10.1059 ++
 10.1060 ++          do
 10.1061 ++            {
 10.1062 ++              tmp = ASCII_CHAR (getkey ());
 10.1063 ++            }
 10.1064 ++          while (tmp != '\n' && tmp != '\r');
 10.1065 ++          grub_printf ("\r                        \r");
 10.1066 ++
 10.1067 ++          /* Restart to count lines.  */
 10.1068 ++          count_lines = 0;
 10.1069 ++          return 1;
 10.1070 ++        }
 10.1071 ++    }
 10.1072 ++  return 0;
 10.1073 ++}
 10.1074 ++#endif
 10.1075 ++
 10.1076 + /* Display an ASCII character.  */
 10.1077 + void
 10.1078 + grub_putchar (int c)
 10.1079 +@@ -1034,38 +1117,11 @@
 10.1080 + 
 10.1081 +   if (c == '\n')
 10.1082 +     {
 10.1083 ++      int flag;
 10.1084 +       /* Internal `more'-like feature.  */
 10.1085 +-      if (count_lines >= 0)
 10.1086 +-	{
 10.1087 +-	  count_lines++;
 10.1088 +-	  if (count_lines >= max_lines - 2)
 10.1089 +-	    {
 10.1090 +-	      int tmp;
 10.1091 +-	      
 10.1092 +-	      /* It's important to disable the feature temporarily, because
 10.1093 +-		 the following grub_printf call will print newlines.  */
 10.1094 +-	      count_lines = -1;
 10.1095 +-
 10.1096 +-	      if (current_term->setcolorstate)
 10.1097 +-		current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
 10.1098 +-	      
 10.1099 +-	      grub_printf ("\n[Hit return to continue]");
 10.1100 +-
 10.1101 +-	      if (current_term->setcolorstate)
 10.1102 +-		current_term->setcolorstate (COLOR_STATE_NORMAL);
 10.1103 +-	      
 10.1104 +-	      do
 10.1105 +-		{
 10.1106 +-		  tmp = ASCII_CHAR (getkey ());
 10.1107 +-		}
 10.1108 +-	      while (tmp != '\n' && tmp != '\r');
 10.1109 +-	      grub_printf ("\r                        \r");
 10.1110 +-	      
 10.1111 +-	      /* Restart to count lines.  */
 10.1112 +-	      count_lines = 0;
 10.1113 +-	      return;
 10.1114 +-	    }
 10.1115 +-	}
 10.1116 ++      flag = do_more ();
 10.1117 ++      if (flag)
 10.1118 ++        return;
 10.1119 +     }
 10.1120 + 
 10.1121 +   current_term->putchar (c);
 10.1122 +@@ -1090,7 +1146,7 @@
 10.1123 + cls (void)
 10.1124 + {
 10.1125 +   /* If the terminal is dumb, there is no way to clean the terminal.  */
 10.1126 +-  if (current_term->flags & TERM_DUMB)
 10.1127 ++  if (current_term->flags & TERM_DUMB) 
 10.1128 +     grub_putchar ('\n');
 10.1129 +   else
 10.1130 +     current_term->cls ();
 10.1131 +@@ -1217,6 +1273,16 @@
 10.1132 +   return ! errnum;
 10.1133 + }
 10.1134 + 
 10.1135 ++void
 10.1136 ++grub_memcpy(void *dest, const void *src, int len)
 10.1137 ++{
 10.1138 ++  int i;
 10.1139 ++  register char *d = (char*)dest, *s = (char*)src;
 10.1140 ++
 10.1141 ++  for (i = 0; i < len; i++)
 10.1142 ++    d[i] = s[i];
 10.1143 ++}
 10.1144 ++
 10.1145 + void *
 10.1146 + grub_memmove (void *to, const void *from, int len)
 10.1147 + {
 10.1148 +diff -Naur grub-0.97.orig/stage2/cmdline.c grub-0.97/stage2/cmdline.c
 10.1149 +--- grub-0.97.orig/stage2/cmdline.c	2004-08-16 20:23:01.000000000 -0300
 10.1150 ++++ grub-0.97/stage2/cmdline.c	2005-06-12 20:56:49.000000000 -0300
 10.1151 +@@ -50,10 +50,11 @@
 10.1152 + void
 10.1153 + print_cmdline_message (int forever)
 10.1154 + {
 10.1155 +-  printf (" [ Minimal BASH-like line editing is supported.  For the first word, TAB\n"
 10.1156 +-	  "   lists possible command completions.  Anywhere else TAB lists the possible\n"
 10.1157 +-	  "   completions of a device/filename.%s ]\n",
 10.1158 +-	  (forever ? "" : "  ESC at any time exits."));
 10.1159 ++  grub_printf("       [ Minimal BASH-like line editing is supported.   For\n"
 10.1160 ++              "         the   first   word,  TAB  lists  possible  command\n"
 10.1161 ++              "         completions.  Anywhere else TAB lists the possible\n"
 10.1162 ++              "         completions of a device/filename.%s ]\n",
 10.1163 ++              (forever ? "" : "  ESC at any time\n         exits."));
 10.1164 + }
 10.1165 + 
 10.1166 + /* Find the builtin whose command name is COMMAND and return the
 10.1167 +diff -Naur grub-0.97.orig/stage2/graphics.c grub-0.97/stage2/graphics.c
 10.1168 +--- grub-0.97.orig/stage2/graphics.c	1969-12-31 21:00:00.000000000 -0300
 10.1169 ++++ grub-0.97/stage2/graphics.c	2005-06-13 19:13:31.000000000 -0300
 10.1170 +@@ -0,0 +1,585 @@
 10.1171 ++/*
 10.1172 ++ * graphics.c - graphics mode support for GRUB
 10.1173 ++ * Implemented as a terminal type by Jeremy Katz <katzj@redhat.com> based
 10.1174 ++ * on a patch by Paulo CÚsar Pereira de Andrade <pcpa@conectiva.com.br>
 10.1175 ++ * Options and enhancements made by Herton Ronaldo Krzesinski
 10.1176 ++ * <herton@mandriva.com>
 10.1177 ++ *
 10.1178 ++ *  GRUB  --  GRand Unified Bootloader
 10.1179 ++ *  Copyright (C) 2001,2002  Red Hat, Inc.
 10.1180 ++ *  Portions copyright (C) 2000  Conectiva, Inc.
 10.1181 ++ *
 10.1182 ++ *  This program is free software; you can redistribute it and/or modify
 10.1183 ++ *  it under the terms of the GNU General Public License as published by
 10.1184 ++ *  the Free Software Foundation; either version 2 of the License, or
 10.1185 ++ *  (at your option) any later version.
 10.1186 ++ *
 10.1187 ++ *  This program is distributed in the hope that it will be useful,
 10.1188 ++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 10.1189 ++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 10.1190 ++ *  GNU General Public License for more details.
 10.1191 ++ *
 10.1192 ++ *  You should have received a copy of the GNU General Public License
 10.1193 ++ *  along with this program; if not, write to the Free Software
 10.1194 ++ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 10.1195 ++ */
 10.1196 ++
 10.1197 ++#ifdef SUPPORT_GRAPHICS
 10.1198 ++
 10.1199 ++#include <term.h>
 10.1200 ++#include <shared.h>
 10.1201 ++#include <graphics.h>
 10.1202 ++
 10.1203 ++int saved_videomode;
 10.1204 ++unsigned char *font8x16;
 10.1205 ++
 10.1206 ++int graphics_inited = 0;
 10.1207 ++static char splashimage[256];
 10.1208 ++
 10.1209 ++int shade = 1, no_cursor = 0;
 10.1210 ++
 10.1211 ++#define VSHADOW VSHADOW1
 10.1212 ++unsigned char VSHADOW1[38400];
 10.1213 ++unsigned char VSHADOW2[38400];
 10.1214 ++unsigned char VSHADOW4[38400];
 10.1215 ++unsigned char VSHADOW8[38400];
 10.1216 ++
 10.1217 ++/* define the default viewable area */
 10.1218 ++int view_x0 = 0;
 10.1219 ++int view_y0 = 0;
 10.1220 ++int view_x1 = 80;
 10.1221 ++int view_y1 = 30;
 10.1222 ++
 10.1223 ++/* text buffer has to be kept around so that we can write things as we
 10.1224 ++ * scroll and the like */
 10.1225 ++unsigned short text[80 * 30];
 10.1226 ++
 10.1227 ++/* graphics options */
 10.1228 ++int foreground = (63 << 16) | (63 << 8) | (63), background = 0, window_border = 0;
 10.1229 ++
 10.1230 ++/* current position */
 10.1231 ++static int fontx = 0;
 10.1232 ++static int fonty = 0;
 10.1233 ++
 10.1234 ++/* global state so that we don't try to recursively scroll or cursor */
 10.1235 ++static int no_scroll = 0;
 10.1236 ++
 10.1237 ++/* color state */
 10.1238 ++static int graphics_standard_color = A_NORMAL;
 10.1239 ++static int graphics_normal_color = A_NORMAL;
 10.1240 ++static int graphics_highlight_color = A_REVERSE;
 10.1241 ++static int graphics_current_color = A_NORMAL;
 10.1242 ++static color_state graphics_color_state = COLOR_STATE_STANDARD;
 10.1243 ++
 10.1244 ++static inline void outb(unsigned short port, unsigned char val)
 10.1245 ++{
 10.1246 ++    __asm __volatile ("outb %0,%1"::"a" (val), "d" (port));
 10.1247 ++}
 10.1248 ++
 10.1249 ++static void MapMask(int value) {
 10.1250 ++    outb(0x3c4, 2);
 10.1251 ++    outb(0x3c5, value);
 10.1252 ++}
 10.1253 ++
 10.1254 ++/* bit mask register */
 10.1255 ++static void BitMask(int value) {
 10.1256 ++    outb(0x3ce, 8);
 10.1257 ++    outb(0x3cf, value);
 10.1258 ++}
 10.1259 ++
 10.1260 ++/* move the graphics cursor location to col, row */
 10.1261 ++static void graphics_setxy(int col, int row) {
 10.1262 ++    if (col >= view_x0 && col < view_x1) {
 10.1263 ++        fontx = col;
 10.1264 ++        cursorX = col << 3;
 10.1265 ++    }
 10.1266 ++    if (row >= view_y0 && row < view_y1) {
 10.1267 ++        fonty = row;
 10.1268 ++        cursorY = row << 4;
 10.1269 ++    }
 10.1270 ++}
 10.1271 ++
 10.1272 ++/* scroll the screen */
 10.1273 ++static void graphics_scroll() {
 10.1274 ++    int i, j, k;
 10.1275 ++
 10.1276 ++    /* we don't want to scroll recursively... that would be bad */
 10.1277 ++    if (no_scroll)
 10.1278 ++        return;
 10.1279 ++    no_scroll = 1;
 10.1280 ++
 10.1281 ++    /* disable pager temporarily */
 10.1282 ++    k = count_lines;
 10.1283 ++    count_lines = -1;
 10.1284 ++    
 10.1285 ++    /* move everything up a line */
 10.1286 ++    for (j = view_y0 + 1; j < view_y1; j++) {
 10.1287 ++        graphics_gotoxy(view_x0, j - 1);
 10.1288 ++        for (i = view_x0; i < view_x1; i++) {
 10.1289 ++            graphics_putchar(text[j * 80 + i]);
 10.1290 ++        }
 10.1291 ++    }
 10.1292 ++
 10.1293 ++    /* last line should be blank */
 10.1294 ++    graphics_gotoxy(view_x0, view_y1 - 1);
 10.1295 ++    for (i = view_x0; i < view_x1; i++)
 10.1296 ++        graphics_putchar(' ');
 10.1297 ++    graphics_setxy(view_x0, view_y1 - 1);
 10.1298 ++
 10.1299 ++    count_lines = k;
 10.1300 ++
 10.1301 ++    no_scroll = 0;
 10.1302 ++}
 10.1303 ++
 10.1304 ++/* Set the splash image */
 10.1305 ++void graphics_set_splash(char *splashfile) {
 10.1306 ++    grub_strcpy(splashimage, splashfile);
 10.1307 ++}
 10.1308 ++
 10.1309 ++/* Get the current splash image */
 10.1310 ++char *graphics_get_splash(void) {
 10.1311 ++    return splashimage;
 10.1312 ++}
 10.1313 ++
 10.1314 ++/* 
 10.1315 ++ * Initialize a vga16 graphics display with the palette based off of
 10.1316 ++ * the image in splashimage.  If the image doesn't exist, leave graphics
 10.1317 ++ * mode. The mode initiated is 12h. From "Ralf Brown's Interrupt List":
 10.1318 ++ *      text/ text pixel   pixel   colors disply scrn  system
 10.1319 ++ *      grph resol  box  resolution       pages  addr
 10.1320 ++ * 12h   G   80x30  8x16  640x480  16/256K  .    A000  VGA,ATI VIP
 10.1321 ++ *       G   80x30  8x16  640x480  16/64    .    A000  ATI EGA Wonder
 10.1322 ++ *       G     .     .    640x480  16       .      .   UltraVision+256K EGA
 10.1323 ++ */
 10.1324 ++int graphics_init()
 10.1325 ++{
 10.1326 ++    if (!graphics_inited) {
 10.1327 ++        saved_videomode = set_videomode(0x12);
 10.1328 ++        if (get_videomode() != 0x12) {
 10.1329 ++            set_videomode(saved_videomode);
 10.1330 ++            return 0;
 10.1331 ++        }
 10.1332 ++        graphics_inited = 1;
 10.1333 ++    }
 10.1334 ++    else
 10.1335 ++        return 1;
 10.1336 ++
 10.1337 ++    font8x16 = (unsigned char*)graphics_get_font();
 10.1338 ++
 10.1339 ++    /* make sure that the highlight color is set correctly */
 10.1340 ++    graphics_highlight_color = ((graphics_normal_color >> 4) | 
 10.1341 ++                                ((graphics_normal_color & 0xf) << 4));
 10.1342 ++
 10.1343 ++    graphics_cls();
 10.1344 ++
 10.1345 ++    if (!read_image(splashimage)) {
 10.1346 ++        grub_printf("Failed to read splash image (%s)\n", splashimage);
 10.1347 ++        grub_printf("Press any key to continue...");
 10.1348 ++        getkey();
 10.1349 ++        set_videomode(saved_videomode);
 10.1350 ++        graphics_inited = 0;
 10.1351 ++        return 0;
 10.1352 ++    }
 10.1353 ++
 10.1354 ++    set_int1c_handler();
 10.1355 ++
 10.1356 ++    return 1;
 10.1357 ++}
 10.1358 ++
 10.1359 ++/* Leave graphics mode */
 10.1360 ++void graphics_end(void)
 10.1361 ++{
 10.1362 ++    if (graphics_inited) {
 10.1363 ++        unset_int1c_handler();
 10.1364 ++        set_videomode(saved_videomode);
 10.1365 ++        graphics_inited = 0;
 10.1366 ++        no_cursor = 0;
 10.1367 ++    }
 10.1368 ++}
 10.1369 ++
 10.1370 ++/* Print ch on the screen.  Handle any needed scrolling or the like */
 10.1371 ++void graphics_putchar(int ch) {
 10.1372 ++    ch &= 0xff;
 10.1373 ++
 10.1374 ++    graphics_cursor(0);
 10.1375 ++
 10.1376 ++    if (ch == '\n') {
 10.1377 ++        if (fonty + 1 < view_y1)
 10.1378 ++            graphics_setxy(fontx, fonty + 1);
 10.1379 ++        else
 10.1380 ++            graphics_scroll();
 10.1381 ++        graphics_cursor(1);
 10.1382 ++        return;
 10.1383 ++    } else if (ch == '\r') {
 10.1384 ++        graphics_setxy(view_x0, fonty);
 10.1385 ++        graphics_cursor(1);
 10.1386 ++        return;
 10.1387 ++    }
 10.1388 ++
 10.1389 ++    graphics_cursor(0);
 10.1390 ++
 10.1391 ++    text[fonty * 80 + fontx] = ch;
 10.1392 ++    text[fonty * 80 + fontx] &= 0x00ff;
 10.1393 ++    if (graphics_current_color & 0xf0)
 10.1394 ++        text[fonty * 80 + fontx] |= 0x100;
 10.1395 ++
 10.1396 ++    graphics_cursor(0);
 10.1397 ++
 10.1398 ++    if ((fontx + 1) >= view_x1) {
 10.1399 ++        graphics_setxy(view_x0, fonty);
 10.1400 ++        if (fonty + 1 < view_y1)
 10.1401 ++            graphics_setxy(view_x0, fonty + 1);
 10.1402 ++        else
 10.1403 ++            graphics_scroll();
 10.1404 ++        graphics_cursor(1);
 10.1405 ++        do_more ();
 10.1406 ++        graphics_cursor(0);
 10.1407 ++    } else {
 10.1408 ++        graphics_setxy(fontx + 1, fonty);
 10.1409 ++    }
 10.1410 ++
 10.1411 ++    graphics_cursor(1);
 10.1412 ++}
 10.1413 ++
 10.1414 ++/* get the current location of the cursor */
 10.1415 ++int graphics_getxy(void) {
 10.1416 ++    return (fontx << 8) | fonty;
 10.1417 ++}
 10.1418 ++
 10.1419 ++void graphics_gotoxy(int x, int y) {
 10.1420 ++    graphics_cursor(0);
 10.1421 ++
 10.1422 ++    graphics_setxy(x, y);
 10.1423 ++
 10.1424 ++    graphics_cursor(1);
 10.1425 ++}
 10.1426 ++
 10.1427 ++void graphics_cls(void) {
 10.1428 ++    int i;
 10.1429 ++    unsigned char *mem, *s1, *s2, *s4, *s8;
 10.1430 ++
 10.1431 ++    graphics_cursor(0);
 10.1432 ++    graphics_gotoxy(view_x0, view_y0);
 10.1433 ++
 10.1434 ++    mem = (unsigned char*)VIDEOMEM;
 10.1435 ++    s1 = (unsigned char*)VSHADOW1;
 10.1436 ++    s2 = (unsigned char*)VSHADOW2;
 10.1437 ++    s4 = (unsigned char*)VSHADOW4;
 10.1438 ++    s8 = (unsigned char*)VSHADOW8;
 10.1439 ++
 10.1440 ++    for (i = 0; i < 80 * 30; i++)
 10.1441 ++        text[i] = ' ';
 10.1442 ++    graphics_cursor(1);
 10.1443 ++
 10.1444 ++    BitMask(0xff);
 10.1445 ++
 10.1446 ++    /* plane 1 */
 10.1447 ++    MapMask(1);
 10.1448 ++    grub_memcpy(mem, s1, 38400);
 10.1449 ++
 10.1450 ++    /* plane 2 */
 10.1451 ++    MapMask(2);
 10.1452 ++    grub_memcpy(mem, s2, 38400);
 10.1453 ++
 10.1454 ++    /* plane 3 */
 10.1455 ++    MapMask(4);
 10.1456 ++    grub_memcpy(mem, s4, 38400);
 10.1457 ++
 10.1458 ++    /* plane 4 */
 10.1459 ++    MapMask(8);
 10.1460 ++    grub_memcpy(mem, s8, 38400);
 10.1461 ++
 10.1462 ++    MapMask(15);
 10.1463 ++
 10.1464 ++    if (no_cursor) {
 10.1465 ++        no_cursor = 0;
 10.1466 ++        set_int1c_handler();
 10.1467 ++    }
 10.1468 ++}
 10.1469 ++
 10.1470 ++void graphics_setcolorstate (color_state state) {
 10.1471 ++    switch (state) {
 10.1472 ++    case COLOR_STATE_STANDARD:
 10.1473 ++        graphics_current_color = graphics_standard_color;
 10.1474 ++        break;
 10.1475 ++    case COLOR_STATE_NORMAL:
 10.1476 ++        graphics_current_color = graphics_normal_color;
 10.1477 ++        break;
 10.1478 ++    case COLOR_STATE_HIGHLIGHT:
 10.1479 ++        graphics_current_color = graphics_highlight_color;
 10.1480 ++        break;
 10.1481 ++    default:
 10.1482 ++        graphics_current_color = graphics_standard_color;
 10.1483 ++        break;
 10.1484 ++    }
 10.1485 ++
 10.1486 ++    graphics_color_state = state;
 10.1487 ++}
 10.1488 ++
 10.1489 ++void graphics_setcolor (int normal_color, int highlight_color) {
 10.1490 ++    graphics_normal_color = normal_color;
 10.1491 ++    graphics_highlight_color = highlight_color;
 10.1492 ++
 10.1493 ++    graphics_setcolorstate (graphics_color_state);
 10.1494 ++}
 10.1495 ++
 10.1496 ++int graphics_setcursor (int on) {
 10.1497 ++    if (!no_cursor && !on) {
 10.1498 ++        no_cursor = 1;
 10.1499 ++        unset_int1c_handler();
 10.1500 ++        graphics_cursor(0);
 10.1501 ++    }
 10.1502 ++    else if(no_cursor && on) {
 10.1503 ++        no_cursor = 0;
 10.1504 ++        set_int1c_handler();
 10.1505 ++        graphics_cursor(1);
 10.1506 ++    }
 10.1507 ++    return 0;
 10.1508 ++}
 10.1509 ++
 10.1510 ++/* Read in the splashscreen image and set the palette up appropriately.
 10.1511 ++ * Format of splashscreen is an xpm (can be gzipped) with 16 colors and
 10.1512 ++ * 640x480. */
 10.1513 ++int read_image(char *s)
 10.1514 ++{
 10.1515 ++    char buf[32], pal[16], c;
 10.1516 ++    unsigned char base, mask, *s1, *s2, *s4, *s8;
 10.1517 ++    unsigned i, len, idx, colors, x, y, width, height;
 10.1518 ++
 10.1519 ++    if (!grub_open(s))
 10.1520 ++        return 0;
 10.1521 ++
 10.1522 ++    /* read header */
 10.1523 ++    if (!grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) {
 10.1524 ++        grub_close();
 10.1525 ++        return 0;
 10.1526 ++    }
 10.1527 ++    
 10.1528 ++    /* parse info */
 10.1529 ++    while (grub_read(&c, 1)) {
 10.1530 ++        if (c == '"')
 10.1531 ++            break;
 10.1532 ++    }
 10.1533 ++
 10.1534 ++    while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
 10.1535 ++        ;
 10.1536 ++
 10.1537 ++    i = 0;
 10.1538 ++    width = c - '0';
 10.1539 ++    while (grub_read(&c, 1)) {
 10.1540 ++        if (c >= '0' && c <= '9')
 10.1541 ++            width = width * 10 + c - '0';
 10.1542 ++        else
 10.1543 ++            break;
 10.1544 ++    }
 10.1545 ++    while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
 10.1546 ++        ;
 10.1547 ++
 10.1548 ++    height = c - '0';
 10.1549 ++    while (grub_read(&c, 1)) {
 10.1550 ++        if (c >= '0' && c <= '9')
 10.1551 ++            height = height * 10 + c - '0';
 10.1552 ++        else
 10.1553 ++            break;
 10.1554 ++    }
 10.1555 ++    while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
 10.1556 ++        ;
 10.1557 ++
 10.1558 ++    colors = c - '0';
 10.1559 ++    while (grub_read(&c, 1)) {
 10.1560 ++        if (c >= '0' && c <= '9')
 10.1561 ++            colors = colors * 10 + c - '0';
 10.1562 ++        else
 10.1563 ++            break;
 10.1564 ++    }
 10.1565 ++
 10.1566 ++    base = 0;
 10.1567 ++    while (grub_read(&c, 1) && c != '"')
 10.1568 ++        ;
 10.1569 ++
 10.1570 ++    /* palette */
 10.1571 ++    for (i = 0, idx = 1; i < colors; i++) {
 10.1572 ++        len = 0;
 10.1573 ++
 10.1574 ++        while (grub_read(&c, 1) && c != '"')
 10.1575 ++            ;
 10.1576 ++        grub_read(&c, 1);       /* char */
 10.1577 ++        base = c;
 10.1578 ++        grub_read(buf, 4);      /* \t c # */
 10.1579 ++
 10.1580 ++        while (grub_read(&c, 1) && c != '"') {
 10.1581 ++            if (len < sizeof(buf))
 10.1582 ++                buf[len++] = c;
 10.1583 ++        }
 10.1584 ++
 10.1585 ++        if (len == 6 && idx < 15) {
 10.1586 ++            int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2;
 10.1587 ++            int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2;
 10.1588 ++            int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2;
 10.1589 ++
 10.1590 ++            pal[idx] = base;
 10.1591 ++            graphics_set_palette(idx, r, g, b);
 10.1592 ++            ++idx;
 10.1593 ++        }
 10.1594 ++    }
 10.1595 ++
 10.1596 ++    x = y = len = 0;
 10.1597 ++
 10.1598 ++    s1 = (unsigned char*)VSHADOW1;
 10.1599 ++    s2 = (unsigned char*)VSHADOW2;
 10.1600 ++    s4 = (unsigned char*)VSHADOW4;
 10.1601 ++    s8 = (unsigned char*)VSHADOW8;
 10.1602 ++
 10.1603 ++    for (i = 0; i < 38400; i++)
 10.1604 ++        s1[i] = s2[i] = s4[i] = s8[i] = 0;
 10.1605 ++
 10.1606 ++    /* parse xpm data */
 10.1607 ++    while (y < height) {
 10.1608 ++        while (1) {
 10.1609 ++            if (!grub_read(&c, 1)) {
 10.1610 ++                grub_close();
 10.1611 ++                return 0;
 10.1612 ++            }
 10.1613 ++            if (c == '"')
 10.1614 ++                break;
 10.1615 ++        }
 10.1616 ++
 10.1617 ++        while (grub_read(&c, 1) && c != '"') {
 10.1618 ++            for (i = 1; i < 15; i++)
 10.1619 ++                if (pal[i] == c) {
 10.1620 ++                    c = i;
 10.1621 ++                    break;
 10.1622 ++                }
 10.1623 ++
 10.1624 ++            mask = 0x80 >> (x & 7);
 10.1625 ++            if (c & 1)
 10.1626 ++                s1[len + (x >> 3)] |= mask;
 10.1627 ++            if (c & 2)
 10.1628 ++                s2[len + (x >> 3)] |= mask;
 10.1629 ++            if (c & 4)
 10.1630 ++                s4[len + (x >> 3)] |= mask;
 10.1631 ++            if (c & 8)
 10.1632 ++                s8[len + (x >> 3)] |= mask;
 10.1633 ++
 10.1634 ++            if (++x >= 640) {
 10.1635 ++                x = 0;
 10.1636 ++
 10.1637 ++                if (y < 480)
 10.1638 ++                    len += 80;
 10.1639 ++                ++y;
 10.1640 ++            }
 10.1641 ++        }
 10.1642 ++    }
 10.1643 ++
 10.1644 ++    grub_close();
 10.1645 ++
 10.1646 ++    graphics_set_palette(0, (background >> 16), (background >> 8) & 63, 
 10.1647 ++                background & 63);
 10.1648 ++    graphics_set_palette(15, (foreground >> 16), (foreground >> 8) & 63, 
 10.1649 ++                foreground & 63);
 10.1650 ++    graphics_set_palette(0x11, (window_border >> 16), (window_border >> 8) & 63, 
 10.1651 ++                         window_border & 63);
 10.1652 ++
 10.1653 ++    return 1;
 10.1654 ++}
 10.1655 ++
 10.1656 ++/* Convert a character which is a hex digit to the appropriate integer */
 10.1657 ++int hex(int v)
 10.1658 ++{
 10.1659 ++    if (v >= 'A' && v <= 'F')
 10.1660 ++        return (v - 'A' + 10);
 10.1661 ++    if (v >= 'a' && v <= 'f')
 10.1662 ++        return (v - 'a' + 10);
 10.1663 ++    return (v - '0');
 10.1664 ++}
 10.1665 ++
 10.1666 ++void graphics_cursor(int set) {
 10.1667 ++    unsigned char *pat, *mem, *ptr, chr[16 << 2];
 10.1668 ++    int i, ch, invert, offset;
 10.1669 ++
 10.1670 ++    if (set && (no_cursor || no_scroll))
 10.1671 ++        return;
 10.1672 ++
 10.1673 ++    offset = cursorY * 80 + fontx;
 10.1674 ++    ch = text[fonty * 80 + fontx] & 0xff;
 10.1675 ++    invert = (text[fonty * 80 + fontx] & 0xff00) != 0;
 10.1676 ++    pat = font8x16 + (ch << 4);
 10.1677 ++
 10.1678 ++    mem = (unsigned char*)VIDEOMEM + offset;
 10.1679 ++
 10.1680 ++    if (!set) {
 10.1681 ++        for (i = 0; i < 16; i++) {
 10.1682 ++            unsigned char mask = pat[i];
 10.1683 ++
 10.1684 ++            if (!invert) {
 10.1685 ++                chr[i     ] = ((unsigned char*)VSHADOW1)[offset];
 10.1686 ++                chr[16 + i] = ((unsigned char*)VSHADOW2)[offset];
 10.1687 ++                chr[32 + i] = ((unsigned char*)VSHADOW4)[offset];
 10.1688 ++                chr[48 + i] = ((unsigned char*)VSHADOW8)[offset];
 10.1689 ++
 10.1690 ++                if (shade) {
 10.1691 ++                    if (ch == DISP_VERT || ch == DISP_LL ||
 10.1692 ++                        ch == DISP_UR || ch == DISP_LR) {
 10.1693 ++                        unsigned char pmask = ~(pat[i] >> 1);
 10.1694 ++
 10.1695 ++                        chr[i     ] &= pmask;
 10.1696 ++                        chr[16 + i] &= pmask;
 10.1697 ++                        chr[32 + i] &= pmask;
 10.1698 ++                        chr[48 + i] &= pmask;
 10.1699 ++                    }
 10.1700 ++                    if (i > 0 && ch != DISP_VERT) {
 10.1701 ++                        unsigned char pmask = ~(pat[i - 1] >> 1);
 10.1702 ++
 10.1703 ++                        chr[i     ] &= pmask;
 10.1704 ++                        chr[16 + i] &= pmask;
 10.1705 ++                        chr[32 + i] &= pmask;
 10.1706 ++                        chr[48 + i] &= pmask;
 10.1707 ++                        if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) {
 10.1708 ++                            pmask = ~pat[i - 1];
 10.1709 ++
 10.1710 ++                            chr[i     ] &= pmask;
 10.1711 ++                            chr[16 + i] &= pmask;
 10.1712 ++                            chr[32 + i] &= pmask;
 10.1713 ++                            chr[48 + i] &= pmask;
 10.1714 ++                        }
 10.1715 ++                    }
 10.1716 ++                }
 10.1717 ++                chr[i     ] |= mask;
 10.1718 ++                chr[16 + i] |= mask;
 10.1719 ++                chr[32 + i] |= mask;
 10.1720 ++                chr[48 + i] |= mask;
 10.1721 ++
 10.1722 ++                offset += 80;
 10.1723 ++            }
 10.1724 ++            else {
 10.1725 ++                chr[i     ] = mask;
 10.1726 ++                chr[16 + i] = mask;
 10.1727 ++                chr[32 + i] = mask;
 10.1728 ++                chr[48 + i] = mask;
 10.1729 ++            }
 10.1730 ++        }
 10.1731 ++    }
 10.1732 ++    else {
 10.1733 ++        MapMask(15);
 10.1734 ++        ptr = mem;
 10.1735 ++        for (i = 0; i < 16; i++, ptr += 80) {
 10.1736 ++            cursorBuf[i] = pat[i];
 10.1737 ++            *ptr = ~pat[i];
 10.1738 ++        }
 10.1739 ++        return;
 10.1740 ++    }
 10.1741 ++
 10.1742 ++    offset = 0;
 10.1743 ++    for (i = 1; i < 16; i <<= 1, offset += 16) {
 10.1744 ++        int j;
 10.1745 ++
 10.1746 ++        MapMask(i);
 10.1747 ++        ptr = mem;
 10.1748 ++        for (j = 0; j < 16; j++, ptr += 80)
 10.1749 ++            *ptr = chr[j + offset];
 10.1750 ++    }
 10.1751 ++
 10.1752 ++    MapMask(15);
 10.1753 ++}
 10.1754 ++
 10.1755 ++#endif /* SUPPORT_GRAPHICS */
 10.1756 +diff -Naur grub-0.97.orig/stage2/graphics.h grub-0.97/stage2/graphics.h
 10.1757 +--- grub-0.97.orig/stage2/graphics.h	1969-12-31 21:00:00.000000000 -0300
 10.1758 ++++ grub-0.97/stage2/graphics.h	2005-06-12 20:56:49.000000000 -0300
 10.1759 +@@ -0,0 +1,44 @@
 10.1760 ++/* graphics.h - graphics console interface */
 10.1761 ++/*
 10.1762 ++ *  GRUB  --  GRand Unified Bootloader
 10.1763 ++ *  Copyright (C) 2002  Free Software Foundation, Inc.
 10.1764 ++ *
 10.1765 ++ *  This program is free software; you can redistribute it and/or modify
 10.1766 ++ *  it under the terms of the GNU General Public License as published by
 10.1767 ++ *  the Free Software Foundation; either version 2 of the License, or
 10.1768 ++ *  (at your option) any later version.
 10.1769 ++ *
 10.1770 ++ *  This program is distributed in the hope that it will be useful,
 10.1771 ++ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 10.1772 ++ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 10.1773 ++ *  GNU General Public License for more details.
 10.1774 ++ *
 10.1775 ++ *  You should have received a copy of the GNU General Public License
 10.1776 ++ *  along with this program; if not, write to the Free Software
 10.1777 ++ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 10.1778 ++ */
 10.1779 ++
 10.1780 ++#ifndef GRAPHICS_H
 10.1781 ++#define GRAPHICS_H
 10.1782 ++
 10.1783 ++/* magic constant */
 10.1784 ++#define VIDEOMEM 0xA0000
 10.1785 ++
 10.1786 ++/* function prototypes */
 10.1787 ++char *graphics_get_splash(void);
 10.1788 ++
 10.1789 ++int read_image(char *s);
 10.1790 ++void graphics_cursor(int set);
 10.1791 ++
 10.1792 ++/* function prototypes for asm functions */
 10.1793 ++void * graphics_get_font();
 10.1794 ++void graphics_set_palette(int idx, int red, int green, int blue);
 10.1795 ++void set_int1c_handler();
 10.1796 ++void unset_int1c_handler();
 10.1797 ++
 10.1798 ++extern short cursorX, cursorY;
 10.1799 ++extern char cursorBuf[16];
 10.1800 ++extern int shade;
 10.1801 ++extern int view_x0, view_y0, view_x1, view_y1;
 10.1802 ++
 10.1803 ++#endif /* GRAPHICS_H */
 10.1804 +diff -Naur grub-0.97.orig/stage2/Makefile.am grub-0.97/stage2/Makefile.am
 10.1805 +--- grub-0.97.orig/stage2/Makefile.am	2005-02-02 18:37:35.000000000 -0200
 10.1806 ++++ grub-0.97/stage2/Makefile.am	2005-06-12 20:56:49.000000000 -0300
 10.1807 +@@ -7,7 +7,7 @@
 10.1808 +         fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \
 10.1809 + 	imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \
 10.1810 + 	nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \
 10.1811 +-	terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h
 10.1812 ++	terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h graphics.h
 10.1813 + EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS)
 10.1814 + 
 10.1815 + # For <stage1.h>.
 10.1816 +@@ -19,7 +19,7 @@
 10.1817 + 	disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \
 10.1818 + 	fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \
 10.1819 + 	fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \
 10.1820 +-	terminfo.c tparm.c
 10.1821 ++	terminfo.c tparm.c graphics.c
 10.1822 + libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
 10.1823 + 	-DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
 10.1824 + 	-DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
 10.1825 +@@ -79,8 +79,14 @@
 10.1826 + HERCULES_FLAGS =
 10.1827 + endif
 10.1828 + 
 10.1829 ++if GRAPHICS_SUPPORT
 10.1830 ++GRAPHICS_FLAGS = -DSUPPORT_GRAPHICS=1
 10.1831 ++else
 10.1832 ++GRAPHICS_FLAGS =
 10.1833 ++endif
 10.1834 ++
 10.1835 + STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
 10.1836 +-	$(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS)
 10.1837 ++	$(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) $(GRAPHICS_FLAGS)
 10.1838 + 
 10.1839 + STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
 10.1840 + STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1
 10.1841 +@@ -90,7 +96,8 @@
 10.1842 + 	cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
 10.1843 + 	fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
 10.1844 + 	fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \
 10.1845 +-	hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c
 10.1846 ++	hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c \
 10.1847 ++	graphics.c
 10.1848 + pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
 10.1849 + pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
 10.1850 + pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
 10.1851 +diff -Naur grub-0.97.orig/stage2/shared.h grub-0.97/stage2/shared.h
 10.1852 +--- grub-0.97.orig/stage2/shared.h	2004-06-19 13:40:09.000000000 -0300
 10.1853 ++++ grub-0.97/stage2/shared.h	2005-06-12 20:56:49.000000000 -0300
 10.1854 +@@ -792,6 +792,11 @@
 10.1855 + /* Set the cursor position. */
 10.1856 + void gotoxy (int x, int y);
 10.1857 + 
 10.1858 ++/* Internal pager
 10.1859 ++   Returns 1 = if pager was used
 10.1860 ++           0 = if pager wasn't used  */
 10.1861 ++int do_more (void);
 10.1862 ++
 10.1863 + /* Displays an ASCII character.  IBM displays will translate some
 10.1864 +    characters to special graphical ones (see the DISP_* constants). */
 10.1865 + void grub_putchar (int c);
 10.1866 +@@ -871,6 +876,7 @@
 10.1867 + int grub_tolower (int c);
 10.1868 + int grub_isspace (int c);
 10.1869 + int grub_strncat (char *s1, const char *s2, int n);
 10.1870 ++void grub_memcpy(void *dest, const void *src, int len);
 10.1871 + void *grub_memmove (void *to, const void *from, int len);
 10.1872 + void *grub_memset (void *start, int c, int len);
 10.1873 + int grub_strncat (char *s1, const char *s2, int n);
 10.1874 +diff -Naur grub-0.97.orig/stage2/stage2.c grub-0.97/stage2/stage2.c
 10.1875 +--- grub-0.97.orig/stage2/stage2.c	2005-03-19 14:51:57.000000000 -0300
 10.1876 ++++ grub-0.97/stage2/stage2.c	2005-06-13 22:38:08.000000000 -0300
 10.1877 +@@ -20,6 +20,12 @@
 10.1878 + #include <shared.h>
 10.1879 + #include <term.h>
 10.1880 + 
 10.1881 ++#ifdef SUPPORT_GRAPHICS
 10.1882 ++# include <graphics.h>
 10.1883 ++#endif
 10.1884 ++
 10.1885 ++int col_start, col_end, row_start, box_size;
 10.1886 ++
 10.1887 + grub_jmp_buf restart_env;
 10.1888 + 
 10.1889 + #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS)
 10.1890 +@@ -105,13 +111,13 @@
 10.1891 +   if (highlight && current_term->setcolorstate)
 10.1892 +     current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
 10.1893 + 
 10.1894 +-  gotoxy (2, y);
 10.1895 ++  gotoxy (2 + col_start, y);
 10.1896 +   grub_putchar (' ');
 10.1897 +-  for (x = 3; x < 75; x++)
 10.1898 ++  for (x = 3 + col_start; x < (col_end - 5); x++)
 10.1899 +     {
 10.1900 +-      if (*entry && x <= 72)
 10.1901 ++      if (*entry && x <= (col_end - 8))
 10.1902 + 	{
 10.1903 +-	  if (x == 72)
 10.1904 ++	  if (x == (col_end - 8))
 10.1905 + 	    grub_putchar (DISP_RIGHT);
 10.1906 + 	  else
 10.1907 + 	    grub_putchar (*entry++);
 10.1908 +@@ -119,7 +125,7 @@
 10.1909 +       else
 10.1910 + 	grub_putchar (' ');
 10.1911 +     }
 10.1912 +-  gotoxy (74, y);
 10.1913 ++  gotoxy ((col_end - 6), y);
 10.1914 + 
 10.1915 +   if (current_term->setcolorstate)
 10.1916 +     current_term->setcolorstate (COLOR_STATE_STANDARD);
 10.1917 +@@ -131,7 +137,7 @@
 10.1918 + {
 10.1919 +   int i;
 10.1920 +   
 10.1921 +-  gotoxy (77, y + 1);
 10.1922 ++  gotoxy ((col_end - 3), y + 1);
 10.1923 + 
 10.1924 +   if (first)
 10.1925 +     grub_putchar (DISP_UP);
 10.1926 +@@ -151,14 +157,14 @@
 10.1927 + 	menu_entries++;
 10.1928 +     }
 10.1929 + 
 10.1930 +-  gotoxy (77, y + size);
 10.1931 ++  gotoxy ((col_end - 3), y + size);
 10.1932 + 
 10.1933 +   if (*menu_entries)
 10.1934 +     grub_putchar (DISP_DOWN);
 10.1935 +   else
 10.1936 +     grub_putchar (' ');
 10.1937 + 
 10.1938 +-  gotoxy (74, y + entryno + 1);
 10.1939 ++  gotoxy ((col_end - 6), y + entryno + 1);
 10.1940 + }
 10.1941 + 
 10.1942 + static void
 10.1943 +@@ -196,30 +202,30 @@
 10.1944 +   if (current_term->setcolorstate)
 10.1945 +     current_term->setcolorstate (COLOR_STATE_NORMAL);
 10.1946 +   
 10.1947 +-  gotoxy (1, y);
 10.1948 ++  gotoxy (1 + col_start, y);
 10.1949 + 
 10.1950 +   grub_putchar (DISP_UL);
 10.1951 +-  for (i = 0; i < 73; i++)
 10.1952 ++  for (i = col_start; i < (col_end - 7); i++)
 10.1953 +     grub_putchar (DISP_HORIZ);
 10.1954 +   grub_putchar (DISP_UR);
 10.1955 + 
 10.1956 +   i = 1;
 10.1957 +   while (1)
 10.1958 +     {
 10.1959 +-      gotoxy (1, y + i);
 10.1960 ++      gotoxy (1 + col_start, y + i);
 10.1961 + 
 10.1962 +       if (i > size)
 10.1963 + 	break;
 10.1964 +       
 10.1965 +       grub_putchar (DISP_VERT);
 10.1966 +-      gotoxy (75, y + i);
 10.1967 ++      gotoxy ((col_end - 5), y + i);
 10.1968 +       grub_putchar (DISP_VERT);
 10.1969 + 
 10.1970 +       i++;
 10.1971 +     }
 10.1972 + 
 10.1973 +   grub_putchar (DISP_LL);
 10.1974 +-  for (i = 0; i < 73; i++)
 10.1975 ++  for (i = col_start; i < (col_end - 7); i++)
 10.1976 +     grub_putchar (DISP_HORIZ);
 10.1977 +   grub_putchar (DISP_LR);
 10.1978 + 
 10.1979 +@@ -233,6 +239,7 @@
 10.1980 + {
 10.1981 +   int c, time1, time2 = -1, first_entry = 0;
 10.1982 +   char *cur_entry = 0;
 10.1983 ++  struct term_entry *prev_term = NULL;
 10.1984 + 
 10.1985 +   /*
 10.1986 +    *  Main loop for menu UI.
 10.1987 +@@ -250,6 +257,22 @@
 10.1988 + 	}
 10.1989 +     }
 10.1990 + 
 10.1991 ++  col_start = 0;
 10.1992 ++  col_end = 80;
 10.1993 ++  row_start = 0;
 10.1994 ++  box_size = 12;
 10.1995 ++  /* if we're using viewport we need to make sure to setup
 10.1996 ++     coordinates correctly.  */
 10.1997 ++#ifdef SUPPORT_GRAPHICS
 10.1998 ++  if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0)
 10.1999 ++    {
 10.2000 ++      col_start = view_x0;
 10.2001 ++      col_end = view_x1;
 10.2002 ++      row_start = view_y0;
 10.2003 ++      box_size = (view_y1 - view_y0) - 13;
 10.2004 ++    }
 10.2005 ++#endif
 10.2006 ++
 10.2007 +   /* If the timeout was expired or wasn't set, force to show the menu
 10.2008 +      interface. */
 10.2009 +   if (grub_timeout < 0)
 10.2010 +@@ -302,36 +325,36 @@
 10.2011 +       if (current_term->flags & TERM_DUMB)
 10.2012 + 	print_entries_raw (num_entries, first_entry, menu_entries);
 10.2013 +       else
 10.2014 +-	print_border (3, 12);
 10.2015 ++	print_border (3 + row_start, box_size);
 10.2016 + 
 10.2017 +       grub_printf ("\n\
 10.2018 +-      Use the %c and %c keys to select which entry is highlighted.\n",
 10.2019 ++    Use the %c and %c keys to select which entry is highlighted.\n",
 10.2020 + 		   DISP_UP, DISP_DOWN);
 10.2021 +       
 10.2022 +       if (! auth && password)
 10.2023 + 	{
 10.2024 + 	  printf ("\
 10.2025 +-      Press enter to boot the selected OS or \'p\' to enter a\n\
 10.2026 +-      password to unlock the next set of features.");
 10.2027 ++    Press enter to boot the selected OS or \'p\' to enter a\n\
 10.2028 ++    password to unlock the next set of features.");
 10.2029 + 	}
 10.2030 +       else
 10.2031 + 	{
 10.2032 + 	  if (config_entries)
 10.2033 + 	    printf ("\
 10.2034 +-      Press enter to boot the selected OS, \'e\' to edit the\n\
 10.2035 +-      commands before booting, or \'c\' for a command-line.");
 10.2036 ++    Press enter to boot the selected OS, \'e\' to edit the\n\
 10.2037 ++    commands before booting, or \'c\' for a command-line.");
 10.2038 + 	  else
 10.2039 + 	    printf ("\
 10.2040 +-      Press \'b\' to boot, \'e\' to edit the selected command in the\n\
 10.2041 +-      boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\
 10.2042 +-      after (\'O\' for before) the selected line, \'d\' to remove the\n\
 10.2043 +-      selected line, or escape to go back to the main menu.");
 10.2044 ++    Press \'b\' to boot, \'e\' to edit the selected command in the\n\
 10.2045 ++    boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\
 10.2046 ++    after (\'O\' for before) the selected line, \'d\' to remove the\n\
 10.2047 ++    selected line, or escape to go back to the main menu.");
 10.2048 + 	}
 10.2049 + 
 10.2050 +       if (current_term->flags & TERM_DUMB)
 10.2051 + 	grub_printf ("\n\nThe selected entry is %d ", entryno);
 10.2052 +       else
 10.2053 +-	print_entries (3, 12, first_entry, entryno, menu_entries);
 10.2054 ++	print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
 10.2055 +     }
 10.2056 + 
 10.2057 +   /* XX using RT clock now, need to initialize value */
 10.2058 +@@ -358,10 +381,10 @@
 10.2059 + 			   entryno, grub_timeout);
 10.2060 + 	  else
 10.2061 + 	    {
 10.2062 +-	      gotoxy (3, 22);
 10.2063 +-	      grub_printf ("The highlighted entry will be booted automatically in %d seconds.    ",
 10.2064 ++	      gotoxy (3 + col_start, 10 + box_size + row_start);
 10.2065 ++	      grub_printf (" The highlighted entry will be booted automatically in %d seconds.   ",
 10.2066 + 			   grub_timeout);
 10.2067 +-	      gotoxy (74, 4 + entryno);
 10.2068 ++	      gotoxy ((col_end - 6), 4 + entryno + row_start);
 10.2069 + 	  }
 10.2070 + 	  
 10.2071 + 	  grub_timeout--;
 10.2072 +@@ -387,12 +410,12 @@
 10.2073 + 	      if (current_term->flags & TERM_DUMB)
 10.2074 + 		grub_putchar ('\r');
 10.2075 + 	      else
 10.2076 +-		gotoxy (3, 22);
 10.2077 ++		gotoxy (3 + col_start, 10 + box_size + row_start);
 10.2078 + 	      printf ("                                                                    ");
 10.2079 + 	      grub_timeout = -1;
 10.2080 + 	      fallback_entryno = -1;
 10.2081 + 	      if (! (current_term->flags & TERM_DUMB))
 10.2082 +-		gotoxy (74, 4 + entryno);
 10.2083 ++		gotoxy ((col_end - 6), 4 + entryno + row_start);
 10.2084 + 	    }
 10.2085 + 
 10.2086 + 	  /* We told them above (at least in SUPPORT_SERIAL) to use
 10.2087 +@@ -408,12 +431,12 @@
 10.2088 + 		{
 10.2089 + 		  if (entryno > 0)
 10.2090 + 		    {
 10.2091 +-		      print_entry (4 + entryno, 0,
 10.2092 ++		      print_entry (4 + entryno + row_start, 0,
 10.2093 + 				   get_entry (menu_entries,
 10.2094 + 					      first_entry + entryno,
 10.2095 + 					      0));
 10.2096 + 		      entryno--;
 10.2097 +-		      print_entry (4 + entryno, 1,
 10.2098 ++		      print_entry (4 + entryno + row_start, 1,
 10.2099 + 				   get_entry (menu_entries,
 10.2100 + 					      first_entry + entryno,
 10.2101 + 					      0));
 10.2102 +@@ -421,7 +444,7 @@
 10.2103 + 		  else if (first_entry > 0)
 10.2104 + 		    {
 10.2105 + 		      first_entry--;
 10.2106 +-		      print_entries (3, 12, first_entry, entryno,
 10.2107 ++		      print_entries (3 + row_start, box_size, first_entry, entryno,
 10.2108 + 				     menu_entries);
 10.2109 + 		    }
 10.2110 + 		}
 10.2111 +@@ -433,29 +456,29 @@
 10.2112 + 		entryno++;
 10.2113 + 	      else
 10.2114 + 		{
 10.2115 +-		  if (entryno < 11)
 10.2116 ++		  if (entryno < (box_size - 1))
 10.2117 + 		    {
 10.2118 +-		      print_entry (4 + entryno, 0,
 10.2119 ++		      print_entry (4 + entryno + row_start, 0,
 10.2120 + 				   get_entry (menu_entries,
 10.2121 + 					      first_entry + entryno,
 10.2122 + 					      0));
 10.2123 + 		      entryno++;
 10.2124 +-		      print_entry (4 + entryno, 1,
 10.2125 ++		      print_entry (4 + entryno + row_start, 1,
 10.2126 + 				   get_entry (menu_entries,
 10.2127 + 					      first_entry + entryno,
 10.2128 + 					      0));
 10.2129 + 		  }
 10.2130 +-		else if (num_entries > 12 + first_entry)
 10.2131 ++		else if (num_entries > box_size + first_entry)
 10.2132 + 		  {
 10.2133 + 		    first_entry++;
 10.2134 +-		    print_entries (3, 12, first_entry, entryno, menu_entries);
 10.2135 ++		    print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
 10.2136 + 		  }
 10.2137 + 		}
 10.2138 + 	    }
 10.2139 + 	  else if (c == 7)
 10.2140 + 	    {
 10.2141 + 	      /* Page Up */
 10.2142 +-	      first_entry -= 12;
 10.2143 ++	      first_entry -= box_size;
 10.2144 + 	      if (first_entry < 0)
 10.2145 + 		{
 10.2146 + 		  entryno += first_entry;
 10.2147 +@@ -463,20 +486,20 @@
 10.2148 + 		  if (entryno < 0)
 10.2149 + 		    entryno = 0;
 10.2150 + 		}
 10.2151 +-	      print_entries (3, 12, first_entry, entryno, menu_entries);
 10.2152 ++	      print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
 10.2153 + 	    }
 10.2154 + 	  else if (c == 3)
 10.2155 + 	    {
 10.2156 + 	      /* Page Down */
 10.2157 +-	      first_entry += 12;
 10.2158 ++	      first_entry += box_size;
 10.2159 + 	      if (first_entry + entryno + 1 >= num_entries)
 10.2160 + 		{
 10.2161 +-		  first_entry = num_entries - 12;
 10.2162 ++		  first_entry = num_entries - box_size;
 10.2163 + 		  if (first_entry < 0)
 10.2164 + 		    first_entry = 0;
 10.2165 + 		  entryno = num_entries - first_entry - 1;
 10.2166 + 		}
 10.2167 +-	      print_entries (3, 12, first_entry, entryno, menu_entries);
 10.2168 ++	      print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
 10.2169 + 	    }
 10.2170 + 
 10.2171 + 	  if (config_entries)
 10.2172 +@@ -489,7 +512,7 @@
 10.2173 + 	      if ((c == 'd') || (c == 'o') || (c == 'O'))
 10.2174 + 		{
 10.2175 + 		  if (! (current_term->flags & TERM_DUMB))
 10.2176 +-		    print_entry (4 + entryno, 0,
 10.2177 ++		    print_entry (4 + entryno + row_start, 0,
 10.2178 + 				 get_entry (menu_entries,
 10.2179 + 					    first_entry + entryno,
 10.2180 + 					    0));
 10.2181 +@@ -537,7 +560,7 @@
 10.2182 + 
 10.2183 + 		      if (entryno >= num_entries)
 10.2184 + 			entryno--;
 10.2185 +-		      if (first_entry && num_entries < 12 + first_entry)
 10.2186 ++		      if (first_entry && num_entries < box_size + first_entry)
 10.2187 + 			first_entry--;
 10.2188 + 		    }
 10.2189 + 
 10.2190 +@@ -549,7 +572,7 @@
 10.2191 + 		      grub_printf ("\n");
 10.2192 + 		    }
 10.2193 + 		  else
 10.2194 +-		    print_entries (3, 12, first_entry, entryno, menu_entries);
 10.2195 ++		    print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
 10.2196 + 		}
 10.2197 + 
 10.2198 + 	      cur_entry = menu_entries;
 10.2199 +@@ -570,7 +593,7 @@
 10.2200 + 		  if (current_term->flags & TERM_DUMB)
 10.2201 + 		    grub_printf ("\r                                    ");
 10.2202 + 		  else
 10.2203 +-		    gotoxy (1, 21);
 10.2204 ++		    gotoxy (1 + col_start, 9 + box_size + row_start);
 10.2205 + 
 10.2206 + 		  /* Wipe out the previously entered password */
 10.2207 + 		  grub_memset (entered, 0, sizeof (entered));
 10.2208 +@@ -714,6 +737,15 @@
 10.2209 +   
 10.2210 +   cls ();
 10.2211 +   setcursor (1);
 10.2212 ++  /* if our terminal needed initialization, we should shut it down
 10.2213 ++   * before booting the kernel, but we want to save what it was so
 10.2214 ++   * we can come back if needed */
 10.2215 ++  prev_term = current_term;
 10.2216 ++  if (current_term->shutdown) 
 10.2217 ++    {
 10.2218 ++      current_term->shutdown();
 10.2219 ++      current_term = term_table; /* assumption: console is first */
 10.2220 ++    }
 10.2221 +   
 10.2222 +   while (1)
 10.2223 +     {
 10.2224 +@@ -748,6 +780,13 @@
 10.2225 + 	break;
 10.2226 +     }
 10.2227 + 
 10.2228 ++  /* if we get back here, we should go back to what our term was before */
 10.2229 ++  current_term = prev_term;
 10.2230 ++  if (current_term->startup)
 10.2231 ++      /* if our terminal fails to initialize, fall back to console since
 10.2232 ++       * it should always work */
 10.2233 ++      if (current_term->startup() == 0)
 10.2234 ++          current_term = term_table; /* we know that console is first */
 10.2235 +   show_menu = 1;
 10.2236 +   goto restart;
 10.2237 + }
 10.2238 +@@ -1050,6 +1089,16 @@
 10.2239 + 	  while (is_preset);
 10.2240 + 	}
 10.2241 + 
 10.2242 ++      /* go ahead and make sure the terminal is setup */
 10.2243 ++      if (current_term->startup)
 10.2244 ++	{
 10.2245 ++	  /* If initialization fails, go back to default terminal */
 10.2246 ++	  if (current_term->startup() == 0)
 10.2247 ++		  {
 10.2248 ++		      current_term = term_table;
 10.2249 ++		  }
 10.2250 ++	}
 10.2251 ++
 10.2252 +       if (! num_entries)
 10.2253 + 	{
 10.2254 + 	  /* If no acceptable config file, goto command-line, starting
 10.2255 +diff -Naur grub-0.97.orig/stage2/term.h grub-0.97/stage2/term.h
 10.2256 +--- grub-0.97.orig/stage2/term.h	2003-07-09 08:45:53.000000000 -0300
 10.2257 ++++ grub-0.97/stage2/term.h	2005-06-13 14:07:40.000000000 -0300
 10.2258 +@@ -60,6 +60,8 @@
 10.2259 +   const char *name;
 10.2260 +   /* The feature flags defined above.  */
 10.2261 +   unsigned long flags;
 10.2262 ++  /* Default for maximum number of lines if not specified */
 10.2263 ++  unsigned short max_lines;
 10.2264 +   /* Put a character.  */
 10.2265 +   void (*putchar) (int c);
 10.2266 +   /* Check if any input character is available.  */
 10.2267 +@@ -79,6 +81,10 @@
 10.2268 +   void (*setcolor) (int normal_color, int highlight_color);
 10.2269 +   /* Turn on/off the cursor.  */
 10.2270 +   int (*setcursor) (int on);
 10.2271 ++  /* function to start a terminal */
 10.2272 ++  int (*startup) (void);
 10.2273 ++  /* function to use to shutdown a terminal */
 10.2274 ++  void (*shutdown) (void);
 10.2275 + };
 10.2276 + 
 10.2277 + /* This lists up available terminals.  */
 10.2278 +@@ -124,4 +130,24 @@
 10.2279 + int hercules_setcursor (int on);
 10.2280 + #endif
 10.2281 + 
 10.2282 ++#ifdef SUPPORT_GRAPHICS
 10.2283 ++extern int foreground, background, window_border, graphics_inited, saved_videomode;
 10.2284 ++
 10.2285 ++void graphics_set_splash(char *splashfile);
 10.2286 ++int set_videomode(int mode);
 10.2287 ++int get_videomode(void);
 10.2288 ++void graphics_putchar (int c);
 10.2289 ++int graphics_getxy(void);
 10.2290 ++void graphics_gotoxy(int x, int y);
 10.2291 ++void graphics_cls(void);
 10.2292 ++void graphics_setcolorstate (color_state state);
 10.2293 ++void graphics_setcolor (int normal_color, int highlight_color);
 10.2294 ++int graphics_setcursor (int on);
 10.2295 ++int graphics_init(void);
 10.2296 ++void graphics_end(void);
 10.2297 ++
 10.2298 ++int hex(int v);
 10.2299 ++void graphics_set_palette(int idx, int red, int green, int blue);
 10.2300 ++#endif /* SUPPORT_GRAPHICS */
 10.2301 ++
 10.2302 + #endif /* ! GRUB_TERM_HEADER */
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/stubdom/grub.patches/20print_func.diff	Wed Jun 18 09:36:47 2008 +0100
    11.3 @@ -0,0 +1,80 @@
    11.4 +2006-01-05  Otavio Salvador  <otavio@debian.org>
    11.5 +
    11.6 +       * Rediff.
    11.7 +
    11.8 +2005-16-10  Samuel Thibault  <samuel.thibault@ens-lyon.org>
    11.9 +
   11.10 +       * docs/grub.texi: Added print command description.
   11.11 +       * stage2/builtins.c(print_func): New function.
   11.12 +       (builtin_print): New variable.
   11.13 +       (builtin_table): Added builtin_print in table.
   11.14 +
   11.15 +Debian Status Following:
   11.16 +   Added by: Otavio Salvador
   11.17 +       Date: 2006-01-05
   11.18 +
   11.19 +diff -Nur grub-0.97-bkp/docs/grub.texi grub-0.97/docs/grub.texi
   11.20 +--- grub-0.97-bkp/docs/grub.texi	2006-01-05 10:59:05.564347912 -0200
   11.21 ++++ grub-0.97/docs/grub.texi	2006-01-05 11:18:59.033912960 -0200
   11.22 +@@ -2685,6 +2685,7 @@
   11.23 + * module::                      Load a module
   11.24 + * modulenounzip::               Load a module without decompression
   11.25 + * pause::                       Wait for a key press
   11.26 ++* print::                       Print a message
   11.27 + * quit::                        Exit from the grub shell
   11.28 + * reboot::                      Reboot your computer
   11.29 + * read::                        Read data from memory
   11.30 +@@ -3091,6 +3092,16 @@
   11.31 + @end deffn
   11.32 + 
   11.33 + 
   11.34 ++@node print
   11.35 ++@subsection print
   11.36 ++
   11.37 ++@deffn Command print message @dots{}
   11.38 ++Print the @var{message}. Note that placing @key{^G} (ASCII code 7) in the
   11.39 ++message will cause the speaker to emit the standard beep sound, which is
   11.40 ++useful for visually impaired people.
   11.41 ++@end deffn
   11.42 ++
   11.43 ++
   11.44 + @node quit
   11.45 + @subsection quit
   11.46 + 
   11.47 +diff -Nur grub-0.97-bkp/stage2/builtins.c grub-0.97/stage2/builtins.c
   11.48 +--- grub-0.97-bkp/stage2/builtins.c	2006-01-05 10:59:05.550350040 -0200
   11.49 ++++ grub-0.97/stage2/builtins.c	2006-01-05 11:19:28.422445224 -0200
   11.50 +@@ -2323,6 +2323,25 @@
   11.51 +   "Probe I/O ports used for the drive DRIVE."
   11.52 + };
   11.53 + 
   11.54 ++/* print */
   11.55 ++static int
   11.56 ++print_func (char *arg, int flags)
   11.57 ++{
   11.58 ++  printf("%s\n", arg);
   11.59 ++
   11.60 ++  return 0;
   11.61 ++}
   11.62 ++
   11.63 ++static struct builtin builtin_print =
   11.64 ++{
   11.65 ++  "print",
   11.66 ++  print_func,
   11.67 ++  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_NO_ECHO,
   11.68 ++  "print [MESSAGE ...]",
   11.69 ++  "Print MESSAGE."
   11.70 ++};
   11.71 ++
   11.72 ++
   11.73 + 
   11.74 + /* kernel */
   11.75 + static int
   11.76 +@@ -4848,6 +4867,7 @@
   11.77 +   &builtin_parttype,
   11.78 +   &builtin_password,
   11.79 +   &builtin_pause,
   11.80 ++  &builtin_print,
   11.81 + #ifdef GRUB_UTIL
   11.82 +   &builtin_quit,
   11.83 + #endif /* GRUB_UTIL */
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/stubdom/grub.patches/30savedefault.diff	Wed Jun 18 09:36:47 2008 +0100
    12.3 @@ -0,0 +1,186 @@
    12.4 +Index: grub/stage2/builtins.c
    12.5 +===================================================================
    12.6 +--- grub.orig/stage2/builtins.c	2008-06-02 18:06:08.942580000 +0100
    12.7 ++++ grub/stage2/builtins.c	2008-06-06 18:35:07.548390000 +0100
    12.8 +@@ -86,6 +86,10 @@
    12.9 +    inside other functions.  */
   12.10 + static int configfile_func (char *arg, int flags);
   12.11 + 
   12.12 ++static int savedefault_helper (char *arg, int flags);
   12.13 ++
   12.14 ++static int savedefault_shell (char *arg, int flags);
   12.15 ++
   12.16 + /* Initialize the data for builtins.  */
   12.17 + void
   12.18 + init_builtins (void)
   12.19 +@@ -3512,7 +3516,109 @@
   12.20 + static int
   12.21 + savedefault_func (char *arg, int flags)
   12.22 + {
   12.23 +-#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
   12.24 ++#if !defined(SUPPORT_DISKLESS)
   12.25 ++  #if !defined(GRUB_UTIL)
   12.26 ++	return savedefault_helper(arg, flags);
   12.27 ++  #else
   12.28 ++	return savedefault_shell(arg, flags);
   12.29 ++  #endif
   12.30 ++#else /* !SUPPORT_DISKLESS */ 
   12.31 ++  errnum = ERR_UNRECOGNIZED;
   12.32 ++  return 1;
   12.33 ++#endif /* !SUPPORT_DISKLESS */
   12.34 ++}
   12.35 ++
   12.36 ++#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL)
   12.37 ++/* savedefault_shell */
   12.38 ++static int
   12.39 ++savedefault_shell(char *arg, int flags)
   12.40 ++ {
   12.41 ++  int once_only = 0;
   12.42 ++  int new_default;
   12.43 ++  int curr_default = -1;
   12.44 ++  int curr_prev_default = -1;
   12.45 ++  int new_prev_default = -1;
   12.46 ++  FILE *fp;
   12.47 ++  size_t bytes = 10;
   12.48 ++  char line[bytes];
   12.49 ++  char *default_file = (char *) DEFAULT_FILE_BUF;
   12.50 ++  char buf[bytes];
   12.51 ++  int i;
   12.52 ++  
   12.53 ++  while (1)
   12.54 ++    {
   12.55 ++      if (grub_memcmp ("--default=", arg, sizeof ("--default=") - 1) == 0)
   12.56 ++        {
   12.57 ++          char *p = arg + sizeof ("--default=") - 1;
   12.58 ++          if (! safe_parse_maxint (&p, &new_default))
   12.59 ++            return 1;
   12.60 ++          arg = skip_to (0, arg);
   12.61 ++        }
   12.62 ++      else if (grub_memcmp ("--once", arg, sizeof ("--once") - 1) == 0)
   12.63 ++        {
   12.64 ++         once_only = 1;
   12.65 ++         arg = skip_to (0, arg);
   12.66 ++	}
   12.67 ++      else
   12.68 ++        break;
   12.69 ++    }
   12.70 ++
   12.71 ++  *default_file = 0;
   12.72 ++  grub_strncat (default_file, config_file, DEFAULT_FILE_BUFLEN);
   12.73 ++  for (i = grub_strlen(default_file); i >= 0; i--)
   12.74 ++    if (default_file[i] == '/')
   12.75 ++    {
   12.76 ++      i++;
   12.77 ++      break;
   12.78 ++    }
   12.79 ++  default_file[i] = 0;
   12.80 ++  grub_strncat (default_file + i, "default", DEFAULT_FILE_BUFLEN - i);
   12.81 ++
   12.82 ++  if(!(fp = fopen(default_file,"r")))
   12.83 ++    {
   12.84 ++      errnum = ERR_READ;
   12.85 ++      goto fail;
   12.86 ++    }
   12.87 ++  
   12.88 ++  fgets(line, bytes, fp);
   12.89 ++  fclose(fp);
   12.90 ++ 
   12.91 ++  sscanf(line, "%d:%d", &curr_prev_default, &curr_default);
   12.92 ++     
   12.93 ++  if(curr_default != -1)
   12.94 ++    new_prev_default = curr_default;
   12.95 ++  else
   12.96 ++    {
   12.97 ++      if(curr_prev_default != -1)
   12.98 ++        new_prev_default = curr_prev_default;
   12.99 ++      else
  12.100 ++        new_prev_default = 0;
  12.101 ++    }
  12.102 ++     
  12.103 ++  if(once_only)
  12.104 ++    sprintf(buf, "%d:%d", new_prev_default, new_default);
  12.105 ++  else
  12.106 ++    sprintf(buf, "%d", new_default);
  12.107 ++
  12.108 ++  if(!(fp = fopen(default_file,"w")))
  12.109 ++    {
  12.110 ++      errnum = ERR_READ;
  12.111 ++      goto fail;
  12.112 ++    }
  12.113 ++     
  12.114 ++  fprintf(fp, buf);   
  12.115 ++     
  12.116 ++fail:
  12.117 ++  fclose(fp);
  12.118 ++  return errnum;
  12.119 ++}
  12.120 ++#endif
  12.121 ++
  12.122 ++/* savedefault_helper */
  12.123 ++static int
  12.124 ++savedefault_helper (char *arg, int flags)
  12.125 ++{
  12.126 ++#if !defined(SUPPORT_DISKLESS)
  12.127 +   unsigned long tmp_drive = saved_drive;
  12.128 +   unsigned long tmp_partition = saved_partition;
  12.129 +   char *default_file = (char *) DEFAULT_FILE_BUF;
  12.130 +@@ -3588,22 +3694,26 @@
  12.131 +       
  12.132 +       disk_read_hook = disk_read_savesect_func;
  12.133 +       len = grub_read (buf, sizeof (buf));
  12.134 ++      buf[9]='\0';/* Make sure grub_strstr() below terminates */
  12.135 +       disk_read_hook = 0;
  12.136 +       grub_close ();
  12.137 +       
  12.138 +-      if (len != sizeof (buf))
  12.139 +-	{
  12.140 +-	  /* This is too small. Do not modify the file manually, please!  */
  12.141 +-	  errnum = ERR_READ;
  12.142 +-	  goto fail;
  12.143 +-	}
  12.144 +-
  12.145 +       if (sector_count > 2)
  12.146 + 	{
  12.147 + 	  /* Is this possible?! Too fragmented!  */
  12.148 + 	  errnum = ERR_FSYS_CORRUPT;
  12.149 + 	  goto fail;
  12.150 + 	}
  12.151 ++
  12.152 ++      char *tmp;
  12.153 ++      if((tmp = grub_strstr(buf, ":")) != NULL)
  12.154 ++      {
  12.155 ++       int f_len = grub_strlen(buf) - grub_strlen(tmp);
  12.156 ++       char *def;
  12.157 ++       buf[f_len] = '\0';
  12.158 ++       def = buf;
  12.159 ++       safe_parse_maxint (&def, &entryno);
  12.160 ++      }
  12.161 +       
  12.162 +       /* Set up a string to be written.  */
  12.163 +       grub_memset (buf, '\n', sizeof (buf));
  12.164 +Index: grub/stage2/stage2.c
  12.165 +===================================================================
  12.166 +--- grub.orig/stage2/stage2.c	2008-06-02 18:06:08.858579000 +0100
  12.167 ++++ grub/stage2/stage2.c	2008-06-06 18:04:03.585354000 +0100
  12.168 +@@ -49,7 +49,8 @@
  12.169 +     return 0;
  12.170 + #endif /* GRUB_UTIL */
  12.171 +   
  12.172 +-  preset_menu_offset = 0;
  12.173 ++  if (preset_menu_offset)
  12.174 ++    return 0;
  12.175 +   return preset_menu != 0;
  12.176 + }
  12.177 + 
  12.178 +@@ -934,7 +935,11 @@
  12.179 + 	      len = grub_read (buf, sizeof (buf));
  12.180 + 	      if (len > 0)
  12.181 + 		{
  12.182 ++		  char *tmp;
  12.183 + 		  buf[sizeof (buf) - 1] = 0;
  12.184 ++		  if((tmp = grub_strstr(p, ":")) != NULL)
  12.185 ++		    p = tmp + 1;
  12.186 ++		  
  12.187 + 		  safe_parse_maxint (&p, &saved_entryno);
  12.188 + 		}
  12.189 + 
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/stubdom/grub.patches/40ext3_256byte_inode.diff	Wed Jun 18 09:36:47 2008 +0100
    13.3 @@ -0,0 +1,114 @@
    13.4 +
    13.5 +Patch from Red Hat. See #463236, #463123.
    13.6 +
    13.7 +Index: grub/stage2/fsys_ext2fs.c
    13.8 +===================================================================
    13.9 +--- grub.orig/stage2/fsys_ext2fs.c	2008-05-27 18:47:19.045183000 +0100
   13.10 ++++ grub/stage2/fsys_ext2fs.c	2008-05-27 19:09:21.293187000 +0100
   13.11 +@@ -79,7 +79,52 @@
   13.12 +     __u32 s_rev_level;		/* Revision level */
   13.13 +     __u16 s_def_resuid;		/* Default uid for reserved blocks */
   13.14 +     __u16 s_def_resgid;		/* Default gid for reserved blocks */
   13.15 +-    __u32 s_reserved[235];	/* Padding to the end of the block */
   13.16 ++    /*
   13.17 ++     * These fields are for EXT2_DYNAMIC_REV superblocks only.
   13.18 ++     *
   13.19 ++     * Note: the difference between the compatible feature set and
   13.20 ++     * the incompatible feature set is that if there is a bit set
   13.21 ++     * in the incompatible feature set that the kernel doesn't
   13.22 ++     * know about, it should refuse to mount the filesystem.
   13.23 ++     *
   13.24 ++     * e2fsck's requirements are more strict; if it doesn't know
   13.25 ++     * about a feature in either the compatible or incompatible
   13.26 ++     * feature set, it must abort and not try to meddle with
   13.27 ++     * things it doesn't understand...
   13.28 ++     */
   13.29 ++    __u32 s_first_ino;		/* First non-reserved inode */
   13.30 ++    __u16 s_inode_size;		/* size of inode structure */
   13.31 ++    __u16 s_block_group_nr;	/* block group # of this superblock */
   13.32 ++    __u32 s_feature_compat;	/* compatible feature set */
   13.33 ++    __u32 s_feature_incompat;	/* incompatible feature set */
   13.34 ++    __u32 s_feature_ro_compat;	/* readonly-compatible feature set */
   13.35 ++    __u8  s_uuid[16];		/* 128-bit uuid for volume */
   13.36 ++    char  s_volume_name[16];	/* volume name */
   13.37 ++    char  s_last_mounted[64];	/* directory where last mounted */
   13.38 ++    __u32 s_algorithm_usage_bitmap; /* For compression */
   13.39 ++    /*
   13.40 ++     * Performance hints.  Directory preallocation should only
   13.41 ++     * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on.
   13.42 ++     */
   13.43 ++    __u8  s_prealloc_blocks;	/* Nr of blocks to try to preallocate*/
   13.44 ++    __u8  s_prealloc_dir_blocks;	/* Nr to preallocate for dirs */
   13.45 ++    __u16 s_reserved_gdt_blocks;/* Per group table for online growth */
   13.46 ++    /*
   13.47 ++     * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set.
   13.48 ++     */
   13.49 ++    __u8 s_journal_uuid[16];	/* uuid of journal superblock */
   13.50 ++    __u32 s_journal_inum;	/* inode number of journal file */
   13.51 ++    __u32 s_journal_dev;	/* device number of journal file */
   13.52 ++    __u32 s_last_orphan;	/* start of list of inodes to delete */
   13.53 ++    __u32 s_hash_seed[4];	/* HTREE hash seed */
   13.54 ++    __u8  s_def_hash_version;	/* Default hash version to use */
   13.55 ++    __u8  s_jnl_backup_type; 	/* Default type of journal backup */
   13.56 ++    __u16 s_reserved_word_pad;
   13.57 ++    __u32 s_default_mount_opts;
   13.58 ++    __u32 s_first_meta_bg;	/* First metablock group */
   13.59 ++    __u32 s_mkfs_time;		/* When the filesystem was created */
   13.60 ++    __u32 s_jnl_blocks[17]; 	/* Backup of the journal inode */
   13.61 ++    __u32 s_reserved[172];	/* Padding to the end of the block */
   13.62 +   };
   13.63 + 
   13.64 + struct ext2_group_desc
   13.65 +@@ -218,6 +263,9 @@
   13.66 + #define EXT2_ADDR_PER_BLOCK(s)          (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
   13.67 + #define EXT2_ADDR_PER_BLOCK_BITS(s)		(log2(EXT2_ADDR_PER_BLOCK(s)))
   13.68 + 
   13.69 ++#define EXT2_INODE_SIZE(s)		(SUPERBLOCK->s_inode_size)
   13.70 ++#define EXT2_INODES_PER_BLOCK(s)	(EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
   13.71 ++
   13.72 + /* linux/ext2_fs.h */
   13.73 + #define EXT2_BLOCK_SIZE_BITS(s)        ((s)->s_log_block_size + 10)
   13.74 + /* kind of from ext2/super.c */
   13.75 +@@ -242,7 +290,14 @@
   13.76 + static __inline__ unsigned long
   13.77 + ffz (unsigned long word)
   13.78 + {
   13.79 +-  __asm__ ("bsfl %1,%0"
   13.80 ++  __asm__ ("bsf"
   13.81 ++#ifdef __i386__
   13.82 ++		  "l"
   13.83 ++#endif
   13.84 ++#ifdef __x86_64__
   13.85 ++		  "q"
   13.86 ++#endif
   13.87 ++		  " %1,%0"
   13.88 + :	   "=r" (word)
   13.89 + :	   "r" (~word));
   13.90 +   return word;
   13.91 +@@ -553,7 +608,7 @@
   13.92 +       gdp = GROUP_DESC;
   13.93 +       ino_blk = gdp[desc].bg_inode_table +
   13.94 + 	(((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group))
   13.95 +-	 >> log2 (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)));
   13.96 ++	 >> log2 (EXT2_INODES_PER_BLOCK (SUPERBLOCK)));
   13.97 + #ifdef E2DEBUG
   13.98 +       printf ("inode table fsblock=%d\n", ino_blk);
   13.99 + #endif /* E2DEBUG */
  13.100 +@@ -565,13 +620,12 @@
  13.101 +       /* reset indirect blocks! */
  13.102 +       mapblock2 = mapblock1 = -1;
  13.103 + 
  13.104 +-      raw_inode = INODE +
  13.105 +-	((current_ino - 1)
  13.106 +-	 & (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode) - 1));
  13.107 ++      raw_inode = (struct ext2_inode *)((char *)INODE +
  13.108 ++	((current_ino - 1) & (EXT2_INODES_PER_BLOCK (SUPERBLOCK) - 1)) *
  13.109 ++	EXT2_INODE_SIZE (SUPERBLOCK));
  13.110 + #ifdef E2DEBUG
  13.111 +       printf ("ipb=%d, sizeof(inode)=%d\n",
  13.112 +-	      (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)),
  13.113 +-	      sizeof (struct ext2_inode));
  13.114 ++	      EXT2_INODES_PER_BLOCK (SUPERBLOCK), EXT2_INODE_SIZE (SUPERBLOCK));
  13.115 +       printf ("inode=%x, raw_inode=%x\n", INODE, raw_inode);
  13.116 +       printf ("offset into inode table block=%d\n", (int) raw_inode - (int) INODE);
  13.117 +       for (i = (unsigned char *) INODE; i <= (unsigned char *) raw_inode;
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/stubdom/grub.patches/99minios	Wed Jun 18 09:36:47 2008 +0100
    14.3 @@ -0,0 +1,1456 @@
    14.4 +Index: grub/stage2/builtins.c
    14.5 +===================================================================
    14.6 +--- grub.orig/stage2/builtins.c	2008-06-16 15:18:14.649009000 +0100
    14.7 ++++ grub/stage2/builtins.c	2008-06-16 15:18:14.719009000 +0100
    14.8 +@@ -45,8 +45,10 @@
    14.9 + #ifdef GRUB_UTIL
   14.10 + # include <device.h>
   14.11 + #else /* ! GRUB_UTIL */
   14.12 ++#ifndef __MINIOS
   14.13 + # include <apic.h>
   14.14 + # include <smp-imps.h>
   14.15 ++#endif
   14.16 + #endif /* ! GRUB_UTIL */
   14.17 + 
   14.18 + #ifdef USE_MD5_PASSWORDS
   14.19 +@@ -246,11 +248,13 @@
   14.20 + boot_func (char *arg, int flags)
   14.21 + {
   14.22 +   struct term_entry *prev_term = current_term;
   14.23 ++#ifndef __MINIOS__
   14.24 +   /* Clear the int15 handler if we can boot the kernel successfully.
   14.25 +      This assumes that the boot code never fails only if KERNEL_TYPE is
   14.26 +      not KERNEL_TYPE_NONE. Is this assumption is bad?  */
   14.27 +   if (kernel_type != KERNEL_TYPE_NONE)
   14.28 +     unset_int15_handler ();
   14.29 ++#endif
   14.30 + 
   14.31 +   /* if our terminal needed initialization, we should shut it down
   14.32 +    * before booting the kernel, but we want to save what it was so
   14.33 +@@ -261,13 +265,21 @@
   14.34 +       current_term = term_table; /* assumption: console is first */
   14.35 +     }
   14.36 + 
   14.37 ++#ifndef __MINIOS__
   14.38 + #ifdef SUPPORT_NETBOOT
   14.39 +   /* Shut down the networking.  */
   14.40 +   cleanup_net ();
   14.41 + #endif
   14.42 ++#endif
   14.43 +   
   14.44 +   switch (kernel_type)
   14.45 +     {
   14.46 ++#ifdef __MINIOS__
   14.47 ++    case KERNEL_TYPE_PV:
   14.48 ++      /* Paravirtualized */
   14.49 ++      pv_boot();
   14.50 ++      break;
   14.51 ++#else
   14.52 +     case KERNEL_TYPE_FREEBSD:
   14.53 +     case KERNEL_TYPE_NETBSD:
   14.54 +       /* *BSD */
   14.55 +@@ -319,6 +331,7 @@
   14.56 +       multi_boot ((int) entry_addr, (int) &mbi);
   14.57 +       break;
   14.58 + 
   14.59 ++#endif
   14.60 +     default:
   14.61 +       errnum = ERR_BOOT_COMMAND;
   14.62 +       return 1;
   14.63 +@@ -1123,6 +1136,7 @@
   14.64 + };
   14.65 + 
   14.66 + 
   14.67 ++#ifndef __MINIOS__
   14.68 + /* displayapm */
   14.69 + static int
   14.70 + displayapm_func (char *arg, int flags)
   14.71 +@@ -1163,8 +1177,10 @@
   14.72 +   "displayapm",
   14.73 +   "Display APM BIOS information."
   14.74 + };
   14.75 ++#endif
   14.76 + 
   14.77 + 
   14.78 ++#ifndef __MINIOS__
   14.79 + /* displaymem */
   14.80 + static int
   14.81 + displaymem_func (char *arg, int flags)
   14.82 +@@ -1218,6 +1234,7 @@
   14.83 +   "Display what GRUB thinks the system address space map of the"
   14.84 +   " machine is, including all regions of physical RAM installed."
   14.85 + };
   14.86 ++#endif
   14.87 + 
   14.88 + 
   14.89 + /* dump FROM TO */
   14.90 +@@ -1280,6 +1297,7 @@
   14.91 + #endif /* GRUB_UTIL */
   14.92 + 
   14.93 + 
   14.94 ++#ifndef __MINIOS__
   14.95 + static char embed_info[32];
   14.96 + /* embed */
   14.97 + /* Embed a Stage 1.5 in the first cylinder after MBR or in the
   14.98 +@@ -1413,6 +1431,7 @@
   14.99 +   " is a drive, or in the \"bootloader\" area if DEVICE is a FFS partition."
  14.100 +   " Print the number of sectors which STAGE1_5 occupies if successful."
  14.101 + };
  14.102 ++#endif
  14.103 + 
  14.104 + 
  14.105 + /* fallback */
  14.106 +@@ -1956,6 +1975,7 @@
  14.107 + #endif /* SUPPORT_NETBOOT */
  14.108 + 
  14.109 + 
  14.110 ++#ifndef __MINIOS__
  14.111 + /* impsprobe */
  14.112 + static int
  14.113 + impsprobe_func (char *arg, int flags)
  14.114 +@@ -1982,6 +2002,7 @@
  14.115 +   " configuration table and boot the various CPUs which are found into"
  14.116 +   " a tight loop."
  14.117 + };
  14.118 ++#endif
  14.119 + 
  14.120 + 
  14.121 + /* initrd */
  14.122 +@@ -1992,6 +2013,7 @@
  14.123 +     {
  14.124 +     case KERNEL_TYPE_LINUX:
  14.125 +     case KERNEL_TYPE_BIG_LINUX:
  14.126 ++    case KERNEL_TYPE_PV:
  14.127 +       if (! load_initrd (arg))
  14.128 + 	return 1;
  14.129 +       break;
  14.130 +@@ -2015,6 +2037,7 @@
  14.131 + };
  14.132 + 
  14.133 + 
  14.134 ++#ifndef __MINIOS__
  14.135 + /* install */
  14.136 + static int
  14.137 + install_func (char *arg, int flags)
  14.138 +@@ -2555,8 +2578,10 @@
  14.139 +   " for LBA mode. If the option `--stage2' is specified, rewrite the Stage"
  14.140 +   " 2 via your OS's filesystem instead of the raw device."
  14.141 + };
  14.142 ++#endif
  14.143 + 
  14.144 + 
  14.145 ++#ifndef __MINIOS__
  14.146 + /* ioprobe */
  14.147 + static int
  14.148 + ioprobe_func (char *arg, int flags)
  14.149 +@@ -2598,6 +2623,7 @@
  14.150 +   "ioprobe DRIVE",
  14.151 +   "Probe I/O ports used for the drive DRIVE."
  14.152 + };
  14.153 ++#endif
  14.154 + 
  14.155 + /* print */
  14.156 + static int
  14.157 +@@ -3776,6 +3802,7 @@
  14.158 + };
  14.159 + 
  14.160 + 
  14.161 ++#ifndef __MINIOS__
  14.162 + #ifdef SUPPORT_SERIAL
  14.163 + /* serial */
  14.164 + static int
  14.165 +@@ -3927,8 +3954,10 @@
  14.166 +   " default values are COM1, 9600, 8N1."
  14.167 + };
  14.168 + #endif /* SUPPORT_SERIAL */
  14.169 ++#endif
  14.170 + 
  14.171 + 
  14.172 ++#ifndef __MINIOS__
  14.173 + /* setkey */
  14.174 + struct keysym
  14.175 + {
  14.176 +@@ -4174,8 +4203,10 @@
  14.177 +   " is a digit), and delete. If no argument is specified, reset key"
  14.178 +   " mappings."
  14.179 + };
  14.180 ++#endif
  14.181 + 
  14.182 + 
  14.183 ++#ifndef __MINIOS__
  14.184 + /* setup */
  14.185 + static int
  14.186 + setup_func (char *arg, int flags)
  14.187 +@@ -4484,6 +4515,7 @@
  14.188 +   " partition where GRUB images reside, specify the option `--stage2'"
  14.189 +   " to tell GRUB the file name under your OS."
  14.190 + };
  14.191 ++#endif
  14.192 + 
  14.193 + 
  14.194 + #if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
  14.195 +@@ -4788,6 +4820,7 @@
  14.196 + #endif /* SUPPORT_SERIAL */
  14.197 + 	  
  14.198 + 
  14.199 ++#ifndef __MINIOS__
  14.200 + /* testload */
  14.201 + static int
  14.202 + testload_func (char *arg, int flags)
  14.203 +@@ -4874,8 +4907,10 @@
  14.204 +   " consistent offset error. If this test succeeds, then a good next"
  14.205 +   " step is to try loading a kernel."
  14.206 + };
  14.207 ++#endif
  14.208 + 
  14.209 + 
  14.210 ++#ifndef __MINIOS__
  14.211 + /* testvbe MODE */
  14.212 + static int
  14.213 + testvbe_func (char *arg, int flags)
  14.214 +@@ -4979,6 +5014,7 @@
  14.215 +   "testvbe MODE",
  14.216 +   "Test the VBE mode MODE. Hit any key to return."
  14.217 + };
  14.218 ++#endif
  14.219 + 
  14.220 + 
  14.221 + #ifdef SUPPORT_NETBOOT
  14.222 +@@ -5075,6 +5111,7 @@
  14.223 + };
  14.224 + 
  14.225 + 
  14.226 ++#ifndef __MINIOS__
  14.227 + /* uppermem */
  14.228 + static int
  14.229 + uppermem_func (char *arg, int flags)
  14.230 +@@ -5095,8 +5132,10 @@
  14.231 +   "Force GRUB to assume that only KBYTES kilobytes of upper memory are"
  14.232 +   " installed.  Any system address range maps are discarded."
  14.233 + };
  14.234 ++#endif
  14.235 + 
  14.236 + 
  14.237 ++#ifndef __MINIOS__
  14.238 + /* vbeprobe */
  14.239 + static int
  14.240 + vbeprobe_func (char *arg, int flags)
  14.241 +@@ -5203,6 +5242,7 @@
  14.242 +   "Probe VBE information. If the mode number MODE is specified, show only"
  14.243 +   " the information about only the mode."
  14.244 + };
  14.245 ++#endif
  14.246 +   
  14.247 + 
  14.248 + /* The table of builtin commands. Sorted in dictionary order.  */
  14.249 +@@ -5233,12 +5273,16 @@
  14.250 + #ifdef SUPPORT_NETBOOT
  14.251 +   &builtin_dhcp,
  14.252 + #endif /* SUPPORT_NETBOOT */
  14.253 ++#ifndef __MINIOS__
  14.254 +   &builtin_displayapm,
  14.255 +   &builtin_displaymem,
  14.256 ++#endif
  14.257 + #ifdef GRUB_UTIL
  14.258 +   &builtin_dump,
  14.259 + #endif /* GRUB_UTIL */
  14.260 ++#ifndef __MINIOS__
  14.261 +   &builtin_embed,
  14.262 ++#endif
  14.263 +   &builtin_fallback,
  14.264 +   &builtin_find,
  14.265 + #ifdef SUPPORT_GRAPHICS
  14.266 +@@ -5253,10 +5297,14 @@
  14.267 + #ifdef SUPPORT_NETBOOT
  14.268 +   &builtin_ifconfig,
  14.269 + #endif /* SUPPORT_NETBOOT */
  14.270 ++#ifndef __MINIOS__
  14.271 +   &builtin_impsprobe,
  14.272 ++#endif
  14.273 +   &builtin_initrd,
  14.274 ++#ifndef __MINIOS__
  14.275 +   &builtin_install,
  14.276 +   &builtin_ioprobe,
  14.277 ++#endif
  14.278 +   &builtin_kernel,
  14.279 +   &builtin_lock,
  14.280 +   &builtin_makeactive,
  14.281 +@@ -5283,11 +5331,13 @@
  14.282 +   &builtin_root,
  14.283 +   &builtin_rootnoverify,
  14.284 +   &builtin_savedefault,
  14.285 ++#ifndef __MINIOS__
  14.286 + #ifdef SUPPORT_SERIAL
  14.287 +   &builtin_serial,
  14.288 + #endif /* SUPPORT_SERIAL */
  14.289 +   &builtin_setkey,
  14.290 +   &builtin_setup,
  14.291 ++#endif
  14.292 + #ifdef SUPPORT_GRAPHICS
  14.293 +   &builtin_shade,
  14.294 +   &builtin_splashimage,
  14.295 +@@ -5298,16 +5348,20 @@
  14.296 + #ifdef SUPPORT_SERIAL
  14.297 +   &builtin_terminfo,
  14.298 + #endif /* SUPPORT_SERIAL */
  14.299 ++#ifndef __MINIOS__
  14.300 +   &builtin_testload,
  14.301 +   &builtin_testvbe,
  14.302 ++#endif
  14.303 + #ifdef SUPPORT_NETBOOT
  14.304 +   &builtin_tftpserver,
  14.305 + #endif /* SUPPORT_NETBOOT */
  14.306 +   &builtin_timeout,
  14.307 +   &builtin_title,
  14.308 +   &builtin_unhide,
  14.309 ++#ifndef __MINIOS__
  14.310 +   &builtin_uppermem,
  14.311 +   &builtin_vbeprobe,
  14.312 ++#endif
  14.313 + #ifdef SUPPORT_GRAPHICS
  14.314 +   &builtin_viewport,
  14.315 + #endif
  14.316 +Index: grub/stage2/char_io.c
  14.317 +===================================================================
  14.318 +--- grub.orig/stage2/char_io.c	2008-06-16 15:18:14.516009000 +0100
  14.319 ++++ grub/stage2/char_io.c	2008-06-16 15:18:14.726009000 +0100
  14.320 +@@ -20,6 +20,7 @@
  14.321 + 
  14.322 + #include <shared.h>
  14.323 + #include <term.h>
  14.324 ++#include <stdarg.h>
  14.325 + 
  14.326 + #ifdef SUPPORT_HERCULES
  14.327 + # include <hercules.h>
  14.328 +@@ -36,6 +37,7 @@
  14.329 + #ifndef STAGE1_5
  14.330 + struct term_entry term_table[] =
  14.331 +   {
  14.332 ++#ifdef SUPPORT_CONSOLE
  14.333 +     {
  14.334 +       "console",
  14.335 +       0,
  14.336 +@@ -52,6 +54,7 @@
  14.337 +       0, 
  14.338 +       0
  14.339 +     },
  14.340 ++#endif
  14.341 + #ifdef SUPPORT_SERIAL
  14.342 +     {
  14.343 +       "serial",
  14.344 +@@ -131,9 +134,9 @@
  14.345 + }
  14.346 + 
  14.347 + char *
  14.348 +-convert_to_ascii (char *buf, int c,...)
  14.349 ++convert_to_ascii (char *buf, int c, int _num)
  14.350 + {
  14.351 +-  unsigned long num = *((&c) + 1), mult = 10;
  14.352 ++  unsigned long num = _num, mult = 10;
  14.353 +   char *ptr = buf;
  14.354 + 
  14.355 + #ifndef STAGE1_5
  14.356 +@@ -182,11 +185,11 @@
  14.357 + void
  14.358 + grub_printf (const char *format,...)
  14.359 + {
  14.360 +-  int *dataptr = (int *) &format;
  14.361 ++  va_list ap;
  14.362 +   char c, str[16];
  14.363 +-  
  14.364 +-  dataptr++;
  14.365 + 
  14.366 ++  va_start(ap, format);
  14.367 ++  
  14.368 +   while ((c = *(format++)) != 0)
  14.369 +     {
  14.370 +       if (c != '%')
  14.371 +@@ -200,21 +203,32 @@
  14.372 + 	  case 'X':
  14.373 + #endif
  14.374 + 	  case 'u':
  14.375 +-	    *convert_to_ascii (str, c, *((unsigned long *) dataptr++)) = 0;
  14.376 ++	  {
  14.377 ++	    unsigned i = va_arg(ap, unsigned);
  14.378 ++	    *convert_to_ascii (str, c, i) = 0;
  14.379 + 	    grub_putstr (str);
  14.380 + 	    break;
  14.381 ++          }
  14.382 + 
  14.383 + #ifndef STAGE1_5
  14.384 + 	  case 'c':
  14.385 +-	    grub_putchar ((*(dataptr++)) & 0xff);
  14.386 ++	  {
  14.387 ++	    int c = va_arg(ap, int);
  14.388 ++	    grub_putchar (c & 0xff);
  14.389 + 	    break;
  14.390 ++	  }
  14.391 + 
  14.392 + 	  case 's':
  14.393 +-	    grub_putstr ((char *) *(dataptr++));
  14.394 ++	  {
  14.395 ++	    char *s = va_arg(ap, char*);
  14.396 ++	    grub_putstr (s);
  14.397 + 	    break;
  14.398 ++	  }
  14.399 + #endif
  14.400 + 	  }
  14.401 +     }
  14.402 ++
  14.403 ++  va_end(ap);
  14.404 + }
  14.405 + 
  14.406 + #ifndef STAGE1_5
  14.407 +@@ -223,11 +237,11 @@
  14.408 + {
  14.409 +   /* XXX hohmuth
  14.410 +      ugly hack -- should unify with printf() */
  14.411 +-  int *dataptr = (int *) &format;
  14.412 ++  va_list ap;
  14.413 +   char c, *ptr, str[16];
  14.414 +   char *bp = buffer;
  14.415 + 
  14.416 +-  dataptr++;
  14.417 ++  va_start(ap, format);
  14.418 + 
  14.419 +   while ((c = *format++) != 0)
  14.420 +     {
  14.421 +@@ -237,20 +251,27 @@
  14.422 + 	switch (c = *(format++))
  14.423 + 	  {
  14.424 + 	  case 'd': case 'u': case 'x':
  14.425 +-	    *convert_to_ascii (str, c, *((unsigned long *) dataptr++)) = 0;
  14.426 ++	  {
  14.427 ++	    unsigned i = va_arg(ap, unsigned);
  14.428 ++	    *convert_to_ascii (str, c, i) = 0;
  14.429 + 
  14.430 + 	    ptr = str;
  14.431 + 
  14.432 + 	    while (*ptr)
  14.433 + 	      *bp++ = *(ptr++); /* putchar(*(ptr++)); */
  14.434 + 	    break;
  14.435 ++	  }
  14.436 + 
  14.437 +-	  case 'c': *bp++ = (*(dataptr++))&0xff;
  14.438 ++	  case 'c':
  14.439 ++	  {
  14.440 ++	    int c = va_arg(ap, int);
  14.441 ++	    *bp++ = c&0xff;
  14.442 + 	    /* putchar((*(dataptr++))&0xff); */
  14.443 + 	    break;
  14.444 ++	  }
  14.445 + 
  14.446 + 	  case 's':
  14.447 +-	    ptr = (char *) (*(dataptr++));
  14.448 ++	    ptr = va_arg(ap, char *);
  14.449 + 
  14.450 + 	    while ((c = *ptr++) != 0)
  14.451 + 	      *bp++ = c; /* putchar(c); */
  14.452 +@@ -258,6 +279,8 @@
  14.453 + 	  }
  14.454 +     }
  14.455 + 
  14.456 ++  va_end(ap);
  14.457 ++
  14.458 +   *bp = 0;
  14.459 +   return bp - buffer;
  14.460 + }
  14.461 +@@ -1263,12 +1286,14 @@
  14.462 +     return ! errnum;
  14.463 + #endif /* GRUB_UTIL */
  14.464 + 
  14.465 ++#ifndef __MINIOS__
  14.466 +   if ((addr < RAW_ADDR (0x1000))
  14.467 +       || (addr < RAW_ADDR (0x100000)
  14.468 + 	  && RAW_ADDR (mbi.mem_lower * 1024) < (addr + len))
  14.469 +       || (addr >= RAW_ADDR (0x100000)
  14.470 + 	  && RAW_ADDR (mbi.mem_upper * 1024) < ((addr - 0x100000) + len)))
  14.471 +     errnum = ERR_WONT_FIT;
  14.472 ++#endif
  14.473 + 
  14.474 +   return ! errnum;
  14.475 + }
  14.476 +@@ -1342,7 +1367,7 @@
  14.477 + }
  14.478 + #endif /* ! STAGE1_5 */
  14.479 + 
  14.480 +-#ifndef GRUB_UTIL
  14.481 ++#if !defined(GRUB_UTIL) && !defined(__MINIOS__)
  14.482 + # undef memcpy
  14.483 + /* GCC emits references to memcpy() for struct copies etc.  */
  14.484 + void *memcpy (void *dest, const void *src, int n)  __attribute__ ((alias ("grub_memmove")));
  14.485 +Index: grub/stage2/disk_io.c
  14.486 +===================================================================
  14.487 +--- grub.orig/stage2/disk_io.c	2008-06-16 15:18:03.327932000 +0100
  14.488 ++++ grub/stage2/disk_io.c	2008-06-16 15:18:14.733009000 +0100
  14.489 +@@ -130,7 +130,14 @@
  14.490 + static inline unsigned long
  14.491 + log2 (unsigned long word)
  14.492 + {
  14.493 +-  asm volatile ("bsfl %1,%0"
  14.494 ++  asm volatile ("bsf"
  14.495 ++#ifdef __i386__
  14.496 ++		  "l"
  14.497 ++#endif
  14.498 ++#ifdef __x86_64__
  14.499 ++		  "q"
  14.500 ++#endif  
  14.501 ++		  " %1,%0"
  14.502 + 		: "=r" (word)
  14.503 + 		: "r" (word));
  14.504 +   return word;
  14.505 +Index: grub/stage2/fsys_fat.c
  14.506 +===================================================================
  14.507 +--- grub.orig/stage2/fsys_fat.c	2008-06-16 15:18:03.337934000 +0100
  14.508 ++++ grub/stage2/fsys_fat.c	2008-06-16 15:18:14.737009000 +0100
  14.509 +@@ -57,7 +57,14 @@
  14.510 + static __inline__ unsigned long
  14.511 + log2 (unsigned long word)
  14.512 + {
  14.513 +-  __asm__ ("bsfl %1,%0"
  14.514 ++  __asm__ ("bsf"
  14.515 ++#ifdef __i386__
  14.516 ++		  "l"
  14.517 ++#endif
  14.518 ++#ifdef __x86_64__
  14.519 ++		  "q"
  14.520 ++#endif
  14.521 ++		  " %1,%0"
  14.522 + 	   : "=r" (word)
  14.523 + 	   : "r" (word));
  14.524 +   return word;
  14.525 +Index: grub/stage2/pc_slice.h
  14.526 +===================================================================
  14.527 +--- grub.orig/stage2/pc_slice.h	2008-06-16 15:18:03.347932000 +0100
  14.528 ++++ grub/stage2/pc_slice.h	2008-06-16 15:18:14.746009000 +0100
  14.529 +@@ -38,50 +38,50 @@
  14.530 +  */
  14.531 + 
  14.532 + #define PC_MBR_CHECK_SIG(mbr_ptr) \
  14.533 +-  ( *( (unsigned short *) (((int) mbr_ptr) + PC_MBR_SIG_OFFSET) ) \
  14.534 ++  ( *( (unsigned short *) (((long) mbr_ptr) + PC_MBR_SIG_OFFSET) ) \
  14.535 +    == PC_MBR_SIGNATURE )
  14.536 + 
  14.537 + #define PC_MBR_SIG(mbr_ptr) \
  14.538 +-  ( *( (unsigned short *) (((int) mbr_ptr) + PC_MBR_SIG_OFFSET) ) )
  14.539 ++  ( *( (unsigned short *) (((long) mbr_ptr) + PC_MBR_SIG_OFFSET) ) )
  14.540 + 
  14.541 + #define PC_SLICE_FLAG(mbr_ptr, part) \
  14.542 +-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET \
  14.543 ++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET \
  14.544 + 			  + (part << 4)) ) )
  14.545 + 
  14.546 + #define PC_SLICE_HEAD(mbr_ptr, part) \
  14.547 +-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 1 \
  14.548 ++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 1 \
  14.549 + 			  + (part << 4)) ) )
  14.550 + 
  14.551 + #define PC_SLICE_SEC(mbr_ptr, part) \
  14.552 +-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 2 \
  14.553 ++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 2 \
  14.554 + 			  + (part << 4)) ) )
  14.555 + 
  14.556 + #define PC_SLICE_CYL(mbr_ptr, part) \
  14.557 +-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 3 \
  14.558 ++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 3 \
  14.559 + 			  + (part << 4)) ) )
  14.560 + 
  14.561 + #define PC_SLICE_TYPE(mbr_ptr, part) \
  14.562 +-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 4 \
  14.563 ++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 4 \
  14.564 + 			  + (part << 4)) ) )
  14.565 + 
  14.566 + #define PC_SLICE_EHEAD(mbr_ptr, part) \
  14.567 +-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 5 \
  14.568 ++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 5 \
  14.569 + 			  + (part << 4)) ) )
  14.570 + 
  14.571 + #define PC_SLICE_ESEC(mbr_ptr, part) \
  14.572 +-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 6 \
  14.573 ++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 6 \
  14.574 + 			  + (part << 4)) ) )
  14.575 + 
  14.576 + #define PC_SLICE_ECYL(mbr_ptr, part) \
  14.577 +-  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 7 \
  14.578 ++  ( *( (unsigned char *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 7 \
  14.579 + 			  + (part << 4)) ) )
  14.580 + 
  14.581 + #define PC_SLICE_START(mbr_ptr, part) \
  14.582 +-  ( *( (unsigned long *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 8 \
  14.583 ++  ( *( (unsigned long *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 8 \
  14.584 + 			  + (part << 4)) ) )
  14.585 + 
  14.586 + #define PC_SLICE_LENGTH(mbr_ptr, part) \
  14.587 +-  ( *( (unsigned long *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 12 \
  14.588 ++  ( *( (unsigned long *) (((long) mbr_ptr) + PC_SLICE_OFFSET + 12 \
  14.589 + 			  + (part << 4)) ) )
  14.590 + 
  14.591 + 
  14.592 +Index: grub/stage2/shared.h
  14.593 +===================================================================
  14.594 +--- grub.orig/stage2/shared.h	2008-06-16 15:18:14.537009000 +0100
  14.595 ++++ grub/stage2/shared.h	2008-06-17 14:25:08.443906000 +0100
  14.596 +@@ -39,6 +39,10 @@
  14.597 + extern char *grub_scratch_mem;
  14.598 + # define RAW_ADDR(x) ((x) + (int) grub_scratch_mem)
  14.599 + # define RAW_SEG(x) (RAW_ADDR ((x) << 4) >> 4)
  14.600 ++#elif defined(__MINIOS__)
  14.601 ++extern char grub_scratch_mem[];
  14.602 ++# define RAW_ADDR(x) ((x) + (int) grub_scratch_mem)
  14.603 ++# define RAW_SEG(x) (RAW_ADDR ((x) << 4) >> 4)
  14.604 + #else
  14.605 + # define RAW_ADDR(x) (x)
  14.606 + # define RAW_SEG(x) (x)
  14.607 +@@ -707,7 +711,9 @@
  14.608 + 
  14.609 + /* Halt the system, using APM if possible. If NO_APM is true, don't use
  14.610 +    APM even if it is available.  */
  14.611 ++#ifndef __MINIOS__
  14.612 + void grub_halt (int no_apm) __attribute__ ((noreturn));
  14.613 ++#endif
  14.614 + 
  14.615 + /* Copy MAP to the drive map and set up int13_handler.  */
  14.616 + void set_int13_handler (unsigned short *map);
  14.617 +@@ -857,7 +863,8 @@
  14.618 +   KERNEL_TYPE_BIG_LINUX,	/* Big Linux.  */
  14.619 +   KERNEL_TYPE_FREEBSD,		/* FreeBSD.  */
  14.620 +   KERNEL_TYPE_NETBSD,		/* NetBSD.  */
  14.621 +-  KERNEL_TYPE_CHAINLOADER	/* Chainloader.  */
  14.622 ++  KERNEL_TYPE_CHAINLOADER,	/* Chainloader.  */
  14.623 ++  KERNEL_TYPE_PV		/* Paravirtualized.  */
  14.624 + }
  14.625 + kernel_t;
  14.626 + 
  14.627 +@@ -890,7 +897,7 @@
  14.628 + int grub_strlen (const char *str);
  14.629 + char *grub_strcpy (char *dest, const char *src);
  14.630 + 
  14.631 +-#ifndef GRUB_UTIL
  14.632 ++#if !defined(GRUB_UTIL) && !defined(__MINIOS__)
  14.633 + typedef unsigned long grub_jmp_buf[6];
  14.634 + #else
  14.635 + /* In the grub shell, use the libc jmp_buf instead.  */
  14.636 +@@ -898,7 +905,7 @@
  14.637 + # define grub_jmp_buf jmp_buf
  14.638 + #endif
  14.639 + 
  14.640 +-#ifdef GRUB_UTIL
  14.641 ++#if defined(GRUB_UTIL) || defined(__MINIOS__)
  14.642 + # define grub_setjmp	setjmp
  14.643 + # define grub_longjmp	longjmp
  14.644 + #else /* ! GRUB_UTIL */
  14.645 +@@ -914,7 +921,7 @@
  14.646 + /* misc */
  14.647 + void init_page (void);
  14.648 + void print_error (void);
  14.649 +-char *convert_to_ascii (char *buf, int c, ...);
  14.650 ++char *convert_to_ascii (char *buf, int c, int num);
  14.651 + int get_cmdline (char *prompt, char *cmdline, int maxlen,
  14.652 + 		 int echo_char, int history);
  14.653 + int substring (const char *s1, const char *s2);
  14.654 +Index: grub/netboot/etherboot.h
  14.655 +===================================================================
  14.656 +--- grub.orig/netboot/etherboot.h	2008-06-16 15:18:03.446934000 +0100
  14.657 ++++ grub/netboot/etherboot.h	2008-06-16 15:18:14.760009000 +0100
  14.658 +@@ -246,7 +246,7 @@
  14.659 + 
  14.660 + typedef struct
  14.661 + {
  14.662 +-  unsigned long	s_addr;
  14.663 ++  unsigned int	s_addr;
  14.664 + }
  14.665 + in_addr;
  14.666 + 
  14.667 +@@ -302,7 +302,7 @@
  14.668 +   char bp_htype;
  14.669 +   char bp_hlen;
  14.670 +   char bp_hops;
  14.671 +-  unsigned long bp_xid;
  14.672 ++  unsigned int bp_xid;
  14.673 +   unsigned short bp_secs;
  14.674 +   unsigned short unused;
  14.675 +   in_addr bp_ciaddr;
  14.676 +@@ -411,25 +411,25 @@
  14.677 +     
  14.678 +     struct
  14.679 +     {
  14.680 +-      long id;
  14.681 +-      long type;
  14.682 +-      long rpcvers;
  14.683 +-      long prog;
  14.684 +-      long vers;
  14.685 +-      long proc;
  14.686 +-      long data[1];
  14.687 ++      int id;
  14.688 ++      int type;
  14.689 ++      int rpcvers;
  14.690 ++      int prog;
  14.691 ++      int vers;
  14.692 ++      int proc;
  14.693 ++      int data[1];
  14.694 +     }
  14.695 +     call;
  14.696 +     
  14.697 +     struct
  14.698 +     {
  14.699 +-      long id;
  14.700 +-      long type;
  14.701 +-      long rstatus;
  14.702 +-      long verifier;
  14.703 +-      long v2;
  14.704 +-      long astatus;
  14.705 +-      long data[1];
  14.706 ++      int id;
  14.707 ++      int type;
  14.708 ++      int rstatus;
  14.709 ++      int verifier;
  14.710 ++      int v2;
  14.711 ++      int astatus;
  14.712 ++      int data[1];
  14.713 +     }
  14.714 +     reply;
  14.715 +   }
  14.716 +@@ -517,7 +517,9 @@
  14.717 + 
  14.718 + /* misc.c */
  14.719 + extern void twiddle (void);
  14.720 ++#ifndef __MINIOS__
  14.721 + extern void sleep (int secs);
  14.722 ++#endif
  14.723 + extern int getdec (char **s);
  14.724 + extern void etherboot_printf (const char *, ...);
  14.725 + extern int etherboot_sprintf (char *, const char *, ...);
  14.726 +Index: grub/stage2/common.c
  14.727 +===================================================================
  14.728 +--- grub.orig/stage2/common.c	2008-06-16 15:18:03.366934000 +0100
  14.729 ++++ grub/stage2/common.c	2008-06-16 15:18:14.764009000 +0100
  14.730 +@@ -137,6 +137,7 @@
  14.731 + }
  14.732 + #endif /* ! STAGE1_5 */
  14.733 + 
  14.734 ++#ifndef __MINIOS__
  14.735 + /* This queries for BIOS information.  */
  14.736 + void
  14.737 + init_bios_info (void)
  14.738 +@@ -335,3 +336,4 @@
  14.739 +   /* Start main routine here.  */
  14.740 +   cmain ();
  14.741 + }
  14.742 ++#endif
  14.743 +Index: grub/stage2/serial.c
  14.744 +===================================================================
  14.745 +--- grub.orig/stage2/serial.c	2008-06-16 15:18:03.376934000 +0100
  14.746 ++++ grub/stage2/serial.c	2008-06-16 15:18:14.769009000 +0100
  14.747 +@@ -37,7 +37,7 @@
  14.748 + 
  14.749 + /* Hardware-dependent definitions.  */
  14.750 + 
  14.751 +-#ifndef GRUB_UTIL
  14.752 ++#if !defined(GRUB_UTIL) && !defined(__MINIOS__)
  14.753 + /* The structure for speed vs. divisor.  */
  14.754 + struct divisor
  14.755 + {
  14.756 +@@ -222,6 +222,8 @@
  14.757 +       {('3' | ('~' << 8)), 4},
  14.758 +       {('5' | ('~' << 8)), 7},
  14.759 +       {('6' | ('~' << 8)), 3},
  14.760 ++      {('7' | ('~' << 8)), 1},
  14.761 ++      {('8' | ('~' << 8)), 5},
  14.762 +     };
  14.763 +   
  14.764 +   /* The buffer must start with ``ESC [''.  */
  14.765 +Index: grub/stage2/tparm.c
  14.766 +===================================================================
  14.767 +--- grub.orig/stage2/tparm.c	2008-06-16 15:18:03.390933000 +0100
  14.768 ++++ grub/stage2/tparm.c	2008-06-16 15:18:14.774010000 +0100
  14.769 +@@ -48,6 +48,7 @@
  14.770 + #include "shared.h"
  14.771 + 
  14.772 + #include "tparm.h"
  14.773 ++#include <stdarg.h>
  14.774 + 
  14.775 + /*
  14.776 +  * Common/troublesome character definitions
  14.777 +@@ -320,7 +321,7 @@
  14.778 + #define isLOWER(c) ((c) >= 'a' && (c) <= 'z')
  14.779 + 
  14.780 + static inline char *
  14.781 +-tparam_internal(const char *string, int *dataptr)
  14.782 ++tparam_internal(const char *string, va_list ap)
  14.783 + {
  14.784 + #define NUM_VARS 26
  14.785 +     char *p_is_s[9];
  14.786 +@@ -461,9 +462,9 @@
  14.787 + 	 * a char* and an int may not be the same size on the stack.
  14.788 + 	 */
  14.789 + 	if (p_is_s[i] != 0) {
  14.790 +-	  p_is_s[i] = (char *)(*(dataptr++));
  14.791 ++	  p_is_s[i] = va_arg(ap, char *);
  14.792 + 	} else {
  14.793 +-	  param[i] = (int)(*(dataptr++));
  14.794 ++	  param[i] = va_arg(ap, int);
  14.795 + 	}
  14.796 +     }
  14.797 + 
  14.798 +@@ -716,11 +717,13 @@
  14.799 + grub_tparm(const char *string,...)
  14.800 + {
  14.801 +     char *result;
  14.802 +-    int *dataptr = (int *) &string;
  14.803 ++    va_list ap;
  14.804 + 
  14.805 +-    dataptr++;
  14.806 ++    va_start(ap, string);
  14.807 + 
  14.808 +-    result = tparam_internal(string, dataptr);
  14.809 ++    result = tparam_internal(string, ap);
  14.810 ++
  14.811 ++    va_end(ap);
  14.812 + 
  14.813 +     return result;
  14.814 + }
  14.815 +Index: grub/stage2/fsys_iso9660.c
  14.816 +===================================================================
  14.817 +--- grub.orig/stage2/fsys_iso9660.c	2008-06-16 15:18:03.400933000 +0100
  14.818 ++++ grub/stage2/fsys_iso9660.c	2008-06-16 15:18:14.779009000 +0100
  14.819 +@@ -59,7 +59,14 @@
  14.820 + static inline unsigned long
  14.821 + log2 (unsigned long word)
  14.822 + {
  14.823 +-  asm volatile ("bsfl %1,%0"
  14.824 ++  asm volatile ("bsf"
  14.825 ++#ifdef __i386__
  14.826 ++		  "l"
  14.827 ++#endif
  14.828 ++#ifdef __x86_64__
  14.829 ++		  "q"
  14.830 ++#endif
  14.831 ++		  " %1,%0"
  14.832 + 		:          "=r" (word)
  14.833 + 		:          "r" (word));
  14.834 +   return word;
  14.835 +Index: grub/stage2/fsys_reiserfs.c
  14.836 +===================================================================
  14.837 +--- grub.orig/stage2/fsys_reiserfs.c	2008-06-16 15:18:03.410933000 +0100
  14.838 ++++ grub/stage2/fsys_reiserfs.c	2008-06-16 15:18:14.786009000 +0100
  14.839 +@@ -369,7 +369,14 @@
  14.840 + static __inline__ unsigned long
  14.841 + log2 (unsigned long word)
  14.842 + {
  14.843 +-  __asm__ ("bsfl %1,%0"
  14.844 ++  __asm__ ("bsf"
  14.845 ++#ifdef __i386__
  14.846 ++		  "l"
  14.847 ++#endif
  14.848 ++#ifdef __x86_64__
  14.849 ++		  "q"
  14.850 ++#endif
  14.851 ++		  " %1,%0"
  14.852 + 	   : "=r" (word)
  14.853 + 	   : "r" (word));
  14.854 +   return word;
  14.855 +Index: grub/netboot/misc.c
  14.856 +===================================================================
  14.857 +--- grub.orig/netboot/misc.c	2008-06-16 15:18:03.456934000 +0100
  14.858 ++++ grub/netboot/misc.c	2008-06-16 15:18:14.790009000 +0100
  14.859 +@@ -21,7 +21,9 @@
  14.860 + 
  14.861 + #define GRUB	1
  14.862 + #include <etherboot.h>
  14.863 ++#include <stdarg.h>
  14.864 + 
  14.865 ++#ifndef __MINIOS__
  14.866 + void
  14.867 + sleep (int secs)
  14.868 + {
  14.869 +@@ -30,6 +32,7 @@
  14.870 +   while (currticks () < tmo)
  14.871 +     ;
  14.872 + }
  14.873 ++#endif
  14.874 + 
  14.875 + void
  14.876 + twiddle (void)
  14.877 +@@ -71,7 +74,7 @@
  14.878 + 	Note: width specification not supported
  14.879 + **************************************************************************/
  14.880 + static int
  14.881 +-etherboot_vsprintf (char *buf, const char *fmt, const int *dp)
  14.882 ++etherboot_vsprintf (char *buf, const char *fmt, va_list ap)
  14.883 + {
  14.884 +   char *p, *s;
  14.885 +   
  14.886 +@@ -86,7 +89,7 @@
  14.887 +       
  14.888 +       if (*++fmt == 's')
  14.889 + 	{
  14.890 +-	  for (p = (char *) *dp++; *p != '\0'; p++)
  14.891 ++	  for (p = va_arg(ap, char *); *p != '\0'; p++)
  14.892 + 	    buf ? *s++ = *p : grub_putchar (*p);
  14.893 + 	}
  14.894 +       else
  14.895 +@@ -121,11 +124,9 @@
  14.896 + 	  if ((*fmt | 0x20) == 'x')
  14.897 + 	    {
  14.898 + 	      /* With x86 gcc, sizeof(long) == sizeof(int) */
  14.899 +-	      const long *lp = (const long *) dp;
  14.900 +-	      long h = *lp++;
  14.901 ++	      long h = va_arg(ap, int);
  14.902 + 	      int ncase = (*fmt & 0x20);
  14.903 + 	      
  14.904 +-	      dp = (const int *) lp;
  14.905 + 	      if (alt)
  14.906 + 		{
  14.907 + 		  *q++ = '0';
  14.908 +@@ -136,7 +137,7 @@
  14.909 + 	    }
  14.910 + 	  else if (*fmt == 'd')
  14.911 + 	    {
  14.912 +-	      int i = *dp++;
  14.913 ++	      int i = va_arg(ap, int);
  14.914 + 	      char *r;
  14.915 + 	      
  14.916 + 	      if (i < 0)
  14.917 +@@ -171,10 +172,8 @@
  14.918 + 		unsigned char	c[4];
  14.919 + 	      }
  14.920 + 	      u;
  14.921 +-	      const long *lp = (const long *) dp;
  14.922 + 	      
  14.923 +-	      u.l = *lp++;
  14.924 +-	      dp = (const int *) lp;
  14.925 ++	      u.l = va_arg(ap, int);
  14.926 + 	      
  14.927 + 	      for (r = &u.c[0]; r < &u.c[4]; ++r)
  14.928 + 		q += etherboot_sprintf (q, "%d.", *r);
  14.929 +@@ -184,7 +183,7 @@
  14.930 + 	  else if (*fmt == '!')
  14.931 + 	    {
  14.932 + 	      char *r;
  14.933 +-	      p = (char *) *dp++;
  14.934 ++	      p = va_arg(ap, char *);
  14.935 + 	      
  14.936 + 	      for (r = p + ETH_ALEN; p < r; ++p)
  14.937 + 		q += etherboot_sprintf (q, "%hhX:", *p);
  14.938 +@@ -192,7 +191,7 @@
  14.939 + 	      --q;
  14.940 + 	    }
  14.941 + 	  else if (*fmt == 'c')
  14.942 +-	    *q++ = *dp++;
  14.943 ++	    *q++ = va_arg(ap, int);
  14.944 + 	  else
  14.945 + 	    *q++ = *fmt;
  14.946 + 	  
  14.947 +@@ -211,13 +210,21 @@
  14.948 + int
  14.949 + etherboot_sprintf (char *buf, const char *fmt, ...)
  14.950 + {
  14.951 +-  return etherboot_vsprintf (buf, fmt, ((const int *) &fmt) + 1);
  14.952 ++  va_list ap;
  14.953 ++  int ret;
  14.954 ++  va_start(ap, fmt);
  14.955 ++  ret = etherboot_vsprintf (buf, fmt, ap);
  14.956 ++  va_end(ap);
  14.957 ++  return ret;
  14.958 + }
  14.959 + 
  14.960 + void
  14.961 + etherboot_printf (const char *fmt, ...)
  14.962 + {
  14.963 +-  (void) etherboot_vsprintf (0, fmt, ((const int *) &fmt) + 1);
  14.964 ++  va_list ap;
  14.965 ++  va_start(ap, fmt);
  14.966 ++  etherboot_vsprintf (0, fmt, ap);
  14.967 ++  va_end(ap);
  14.968 + }
  14.969 + 
  14.970 + int
  14.971 +Index: grub/netboot/main.c
  14.972 +===================================================================
  14.973 +--- grub.orig/netboot/main.c	2008-06-16 15:18:03.470932000 +0100
  14.974 ++++ grub/netboot/main.c	2008-06-16 15:18:14.797009000 +0100
  14.975 +@@ -55,7 +55,7 @@
  14.976 + static int vendorext_isvalid;
  14.977 + static unsigned long netmask;
  14.978 + static struct bootpd_t bootp_data;
  14.979 +-static unsigned long xid;
  14.980 ++static unsigned int xid;
  14.981 + 
  14.982 + #define	BOOTP_DATA_ADDR	(&bootp_data)
  14.983 + 
  14.984 +@@ -778,7 +778,7 @@
  14.985 + 
  14.986 + 	      arpreply = (struct arprequest *) &nic.packet[ETH_HLEN];
  14.987 + 	      
  14.988 +-	      if (arpreply->opcode == htons (ARP_REPLY)
  14.989 ++	      if (arpreply->opcode == htons (ARP_REPLY) && ptr
  14.990 + 		  && ! grub_memcmp (arpreply->sipaddr, ptr, sizeof (in_addr))
  14.991 + 		  && type == AWAIT_ARP)
  14.992 + 		{
  14.993 +@@ -827,7 +827,7 @@
  14.994 + 	    {
  14.995 + 	      arpreply = (struct arprequest *) &nic.packet[ETH_HLEN];
  14.996 + 	      
  14.997 +-	      if (arpreply->opcode == htons (RARP_REPLY)
  14.998 ++	      if (arpreply->opcode == htons (RARP_REPLY) && ptr
  14.999 + 		  && ! grub_memcmp (arpreply->thwaddr, ptr, ETH_ALEN))
 14.1000 + 		{
 14.1001 + 		  grub_memmove ((char *) arptable[ARP_SERVER].node,
 14.1002 +@@ -1135,7 +1135,7 @@
 14.1003 + long
 14.1004 + rfc2131_sleep_interval (int base, int exp)
 14.1005 + {
 14.1006 +-  static long seed = 0;
 14.1007 ++  static unsigned seed = 0;
 14.1008 +   long q;
 14.1009 +   unsigned long tmo;
 14.1010 +   
 14.1011 +Index: grub/stage2/graphics.c
 14.1012 +===================================================================
 14.1013 +--- grub.orig/stage2/graphics.c	2008-06-16 15:18:14.524009000 +0100
 14.1014 ++++ grub/stage2/graphics.c	2008-06-17 14:29:05.204328000 +0100
 14.1015 +@@ -30,7 +30,29 @@
 14.1016 + #include <shared.h>
 14.1017 + #include <graphics.h>
 14.1018 + 
 14.1019 ++#ifdef __MINIOS__
 14.1020 ++#include <stdint.h>
 14.1021 ++typedef uint8_t Bit8u;
 14.1022 ++#include <vgafonts.h>
 14.1023 ++#include <fbfront.h>
 14.1024 ++#include <malloc.h>
 14.1025 ++#define set_int1c_handler() (void)0
 14.1026 ++#define unset_int1c_handler() (void)0
 14.1027 ++static uint32_t *VIDEOMEM;
 14.1028 ++static struct fbfront_dev *fb_dev;
 14.1029 ++static uint32_t palette[17];
 14.1030 ++short cursorX, cursorY;
 14.1031 ++/* TODO: blink */
 14.1032 ++uint32_t cursorBuf32[16*8];
 14.1033 ++#define WIDTH 640
 14.1034 ++#define HEIGHT 480
 14.1035 ++#define DEPTH 32
 14.1036 ++#define RAMSIZE (WIDTH * HEIGHT * (DEPTH / 8))
 14.1037 ++#else
 14.1038 ++#define fbfront_update(dev, x, y, w, h) (void)0
 14.1039 + int saved_videomode;
 14.1040 ++#endif
 14.1041 ++
 14.1042 + unsigned char *font8x16;
 14.1043 + 
 14.1044 + int graphics_inited = 0;
 14.1045 +@@ -38,11 +60,15 @@
 14.1046 + 
 14.1047 + int shade = 1, no_cursor = 0;
 14.1048 + 
 14.1049 ++#ifdef __MINIOS__
 14.1050 ++uint32_t VSHADOW[RAMSIZE];
 14.1051 ++#else
 14.1052 + #define VSHADOW VSHADOW1
 14.1053 + unsigned char VSHADOW1[38400];
 14.1054 + unsigned char VSHADOW2[38400];
 14.1055 + unsigned char VSHADOW4[38400];
 14.1056 + unsigned char VSHADOW8[38400];
 14.1057 ++#endif
 14.1058 + 
 14.1059 + /* define the default viewable area */
 14.1060 + int view_x0 = 0;
 14.1061 +@@ -129,6 +155,8 @@
 14.1062 +     count_lines = k;
 14.1063 + 
 14.1064 +     no_scroll = 0;
 14.1065 ++
 14.1066 ++    fbfront_update(fb_dev, view_x0 * 8, view_y0 * 16, (view_x1 - view_x0) * 8, (view_y1 - view_y0) * 16);
 14.1067 + }
 14.1068 + 
 14.1069 + /* Set the splash image */
 14.1070 +@@ -154,17 +182,29 @@
 14.1071 + int graphics_init()
 14.1072 + {
 14.1073 +     if (!graphics_inited) {
 14.1074 ++#ifdef __MINIOS__
 14.1075 ++	VIDEOMEM = memalign(PAGE_SIZE, RAMSIZE);
 14.1076 ++	if (!(fb_dev = fb_open(VIDEOMEM, WIDTH, HEIGHT, DEPTH))) {
 14.1077 ++	    free(VIDEOMEM);
 14.1078 ++	    return 0;
 14.1079 ++	}
 14.1080 ++#else
 14.1081 +         saved_videomode = set_videomode(0x12);
 14.1082 +         if (get_videomode() != 0x12) {
 14.1083 +             set_videomode(saved_videomode);
 14.1084 +             return 0;
 14.1085 +         }
 14.1086 ++#endif
 14.1087 +         graphics_inited = 1;
 14.1088 +     }
 14.1089 +     else
 14.1090 +         return 1;
 14.1091 + 
 14.1092 ++#ifdef __MINIOS__
 14.1093 ++    font8x16 = vgafont16;
 14.1094 ++#else
 14.1095 +     font8x16 = (unsigned char*)graphics_get_font();
 14.1096 ++#endif
 14.1097 + 
 14.1098 +     /* make sure that the highlight color is set correctly */
 14.1099 +     graphics_highlight_color = ((graphics_normal_color >> 4) | 
 14.1100 +@@ -176,7 +216,11 @@
 14.1101 +         grub_printf("Failed to read splash image (%s)\n", splashimage);
 14.1102 +         grub_printf("Press any key to continue...");
 14.1103 +         getkey();
 14.1104 ++#ifdef __MINIOS__
 14.1105 ++	fb_close();
 14.1106 ++#else
 14.1107 +         set_videomode(saved_videomode);
 14.1108 ++#endif
 14.1109 +         graphics_inited = 0;
 14.1110 +         return 0;
 14.1111 +     }
 14.1112 +@@ -190,8 +234,13 @@
 14.1113 + void graphics_end(void)
 14.1114 + {
 14.1115 +     if (graphics_inited) {
 14.1116 ++#ifdef __MINIOS__
 14.1117 ++	fb_close();
 14.1118 ++	free(VIDEOMEM);
 14.1119 ++#else
 14.1120 +         unset_int1c_handler();
 14.1121 +         set_videomode(saved_videomode);
 14.1122 ++#endif
 14.1123 +         graphics_inited = 0;
 14.1124 +         no_cursor = 0;
 14.1125 +     }
 14.1126 +@@ -204,15 +253,19 @@
 14.1127 +     graphics_cursor(0);
 14.1128 + 
 14.1129 +     if (ch == '\n') {
 14.1130 ++	fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 14.1131 +         if (fonty + 1 < view_y1)
 14.1132 +             graphics_setxy(fontx, fonty + 1);
 14.1133 +         else
 14.1134 +             graphics_scroll();
 14.1135 +         graphics_cursor(1);
 14.1136 ++	fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 14.1137 +         return;
 14.1138 +     } else if (ch == '\r') {
 14.1139 ++	fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 14.1140 +         graphics_setxy(view_x0, fonty);
 14.1141 +         graphics_cursor(1);
 14.1142 ++	fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 14.1143 +         return;
 14.1144 +     }
 14.1145 + 
 14.1146 +@@ -224,6 +277,7 @@
 14.1147 +         text[fonty * 80 + fontx] |= 0x100;
 14.1148 + 
 14.1149 +     graphics_cursor(0);
 14.1150 ++    fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 14.1151 + 
 14.1152 +     if ((fontx + 1) >= view_x1) {
 14.1153 +         graphics_setxy(view_x0, fonty);
 14.1154 +@@ -232,13 +286,16 @@
 14.1155 +         else
 14.1156 +             graphics_scroll();
 14.1157 +         graphics_cursor(1);
 14.1158 ++	fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 14.1159 +         do_more ();
 14.1160 +         graphics_cursor(0);
 14.1161 ++	fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 14.1162 +     } else {
 14.1163 +         graphics_setxy(fontx + 1, fonty);
 14.1164 +     }
 14.1165 + 
 14.1166 +     graphics_cursor(1);
 14.1167 ++    fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 14.1168 + }
 14.1169 + 
 14.1170 + /* get the current location of the cursor */
 14.1171 +@@ -248,10 +305,12 @@
 14.1172 + 
 14.1173 + void graphics_gotoxy(int x, int y) {
 14.1174 +     graphics_cursor(0);
 14.1175 ++    fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 14.1176 + 
 14.1177 +     graphics_setxy(x, y);
 14.1178 + 
 14.1179 +     graphics_cursor(1);
 14.1180 ++    fbfront_update(fb_dev, cursorX, cursorY, 8, 16);
 14.1181 + }
 14.1182 + 
 14.1183 + void graphics_cls(void) {
 14.1184 +@@ -262,15 +321,21 @@
 14.1185 +     graphics_gotoxy(view_x0, view_y0);
 14.1186 + 
 14.1187 +     mem = (unsigned char*)VIDEOMEM;
 14.1188 ++#ifndef __MINIOS__
 14.1189 +     s1 = (unsigned char*)VSHADOW1;
 14.1190 +     s2 = (unsigned char*)VSHADOW2;
 14.1191 +     s4 = (unsigned char*)VSHADOW4;
 14.1192 +     s8 = (unsigned char*)VSHADOW8;
 14.1193 ++#endif
 14.1194 + 
 14.1195 +     for (i = 0; i < 80 * 30; i++)
 14.1196 +         text[i] = ' ';
 14.1197 +     graphics_cursor(1);
 14.1198 + 
 14.1199 ++#ifdef __MINIOS__
 14.1200 ++    memcpy(mem, VSHADOW, RAMSIZE);
 14.1201 ++    fbfront_update(fb_dev, 0, 0, 640, 480);
 14.1202 ++#else
 14.1203 +     BitMask(0xff);
 14.1204 + 
 14.1205 +     /* plane 1 */
 14.1206 +@@ -290,6 +355,7 @@
 14.1207 +     grub_memcpy(mem, s8, 38400);
 14.1208 + 
 14.1209 +     MapMask(15);
 14.1210 ++#endif
 14.1211 + 
 14.1212 +     if (no_cursor) {
 14.1213 +         no_cursor = 0;
 14.1214 +@@ -337,6 +403,11 @@
 14.1215 +     return 0;
 14.1216 + }
 14.1217 + 
 14.1218 ++void graphics_set_palette(int idx, int red, int green, int blue)
 14.1219 ++{
 14.1220 ++    palette[idx] = (red << (16 + 2)) | (green << (8 + 2)) | (blue << 2);
 14.1221 ++}
 14.1222 ++
 14.1223 + /* Read in the splashscreen image and set the palette up appropriately.
 14.1224 +  * Format of splashscreen is an xpm (can be gzipped) with 16 colors and
 14.1225 +  * 640x480. */
 14.1226 +@@ -413,18 +484,19 @@
 14.1227 +         }
 14.1228 + 
 14.1229 +         if (len == 6 && idx < 15) {
 14.1230 +-            int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2;
 14.1231 +-            int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2;
 14.1232 +-            int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2;
 14.1233 ++            int r = ((hex(buf[0]) << 4) | hex(buf[1]));
 14.1234 ++            int g = ((hex(buf[2]) << 4) | hex(buf[3]));
 14.1235 ++            int b = ((hex(buf[4]) << 4) | hex(buf[5]));
 14.1236 + 
 14.1237 +             pal[idx] = base;
 14.1238 +-            graphics_set_palette(idx, r, g, b);
 14.1239 ++            graphics_set_palette(idx, r / 4, g / 4, b / 4);
 14.1240 +             ++idx;
 14.1241 +         }
 14.1242 +     }
 14.1243 + 
 14.1244 +     x = y = len = 0;
 14.1245 + 
 14.1246 ++#ifndef __MINIOS__
 14.1247 +     s1 = (unsigned char*)VSHADOW1;
 14.1248 +     s2 = (unsigned char*)VSHADOW2;
 14.1249 +     s4 = (unsigned char*)VSHADOW4;
 14.1250 +@@ -432,6 +504,7 @@
 14.1251 + 
 14.1252 +     for (i = 0; i < 38400; i++)
 14.1253 +         s1[i] = s2[i] = s4[i] = s8[i] = 0;
 14.1254 ++#endif
 14.1255 + 
 14.1256 +     /* parse xpm data */
 14.1257 +     while (y < height) {
 14.1258 +@@ -451,6 +524,9 @@
 14.1259 +                     break;
 14.1260 +                 }
 14.1261 + 
 14.1262 ++#ifdef __MINIOS__
 14.1263 ++	    VSHADOW[x + y * 640] = palette[i];
 14.1264 ++#else
 14.1265 +             mask = 0x80 >> (x & 7);
 14.1266 +             if (c & 1)
 14.1267 +                 s1[len + (x >> 3)] |= mask;
 14.1268 +@@ -460,6 +536,7 @@
 14.1269 +                 s4[len + (x >> 3)] |= mask;
 14.1270 +             if (c & 8)
 14.1271 +                 s8[len + (x >> 3)] |= mask;
 14.1272 ++#endif
 14.1273 + 
 14.1274 +             if (++x >= 640) {
 14.1275 +                 x = 0;
 14.1276 +@@ -494,7 +571,13 @@
 14.1277 + }
 14.1278 + 
 14.1279 + void graphics_cursor(int set) {
 14.1280 +-    unsigned char *pat, *mem, *ptr, chr[16 << 2];
 14.1281 ++    unsigned char *pat;
 14.1282 ++#ifdef __MINIOS__
 14.1283 ++    uint32_t *mem, *ptr, chr[16 * 8];
 14.1284 ++    int j;
 14.1285 ++#else
 14.1286 ++    unsigned char *mem, *ptr, chr[16 << 2];
 14.1287 ++#endif
 14.1288 +     int i, ch, invert, offset;
 14.1289 + 
 14.1290 +     if (set && (no_cursor || no_scroll))
 14.1291 +@@ -505,71 +588,127 @@
 14.1292 +     invert = (text[fonty * 80 + fontx] & 0xff00) != 0;
 14.1293 +     pat = font8x16 + (ch << 4);
 14.1294 + 
 14.1295 +-    mem = (unsigned char*)VIDEOMEM + offset;
 14.1296 ++    mem = (unsigned char*)VIDEOMEM + offset
 14.1297 ++#ifdef __MINIOS__
 14.1298 ++	* 8 * 4
 14.1299 ++#endif
 14.1300 ++	;
 14.1301 + 
 14.1302 +     if (!set) {
 14.1303 +         for (i = 0; i < 16; i++) {
 14.1304 +             unsigned char mask = pat[i];
 14.1305 + 
 14.1306 +             if (!invert) {
 14.1307 ++#ifdef __MINIOS__
 14.1308 ++		memcpy(chr + i * 8, VSHADOW + offset * 8, 8 * 4);
 14.1309 ++#else
 14.1310 +                 chr[i     ] = ((unsigned char*)VSHADOW1)[offset];
 14.1311 +                 chr[16 + i] = ((unsigned char*)VSHADOW2)[offset];
 14.1312 +                 chr[32 + i] = ((unsigned char*)VSHADOW4)[offset];
 14.1313 +                 chr[48 + i] = ((unsigned char*)VSHADOW8)[offset];
 14.1314 ++#endif
 14.1315 + 
 14.1316 +                 if (shade) {
 14.1317 +                     if (ch == DISP_VERT || ch == DISP_LL ||
 14.1318 +                         ch == DISP_UR || ch == DISP_LR) {
 14.1319 +                         unsigned char pmask = ~(pat[i] >> 1);
 14.1320 + 
 14.1321 ++#ifdef __MINIOS__
 14.1322 ++			for (j = 0; j < 8; j++)
 14.1323 ++			    if (!(pmask & (1U << j)))
 14.1324 ++				chr[i * 8 + (7 - j)] = palette[0];
 14.1325 ++#else
 14.1326 +                         chr[i     ] &= pmask;
 14.1327 +                         chr[16 + i] &= pmask;
 14.1328 +                         chr[32 + i] &= pmask;
 14.1329 +                         chr[48 + i] &= pmask;
 14.1330 ++#endif
 14.1331 +                     }
 14.1332 +                     if (i > 0 && ch != DISP_VERT) {
 14.1333 +                         unsigned char pmask = ~(pat[i - 1] >> 1);
 14.1334 + 
 14.1335 ++#ifdef __MINIOS__
 14.1336 ++			for (j = 0; j < 8; j++)
 14.1337 ++			    if (!(pmask & (1U << j)))
 14.1338 ++				chr[i * 8 + (7 - j)] = palette[0];
 14.1339 ++#else
 14.1340 +                         chr[i     ] &= pmask;
 14.1341 +                         chr[16 + i] &= pmask;
 14.1342 +                         chr[32 + i] &= pmask;
 14.1343 +                         chr[48 + i] &= pmask;
 14.1344 ++#endif
 14.1345 +                         if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) {
 14.1346 +                             pmask = ~pat[i - 1];
 14.1347 + 
 14.1348 ++#ifdef __MINIOS__
 14.1349 ++			    for (j = 0; j < 8; j++)
 14.1350 ++				if (!(pmask & (1U << j)))
 14.1351 ++				    chr[i * 8 + (7 - j)] = palette[0];
 14.1352 ++#else
 14.1353 +                             chr[i     ] &= pmask;
 14.1354 +                             chr[16 + i] &= pmask;
 14.1355 +                             chr[32 + i] &= pmask;
 14.1356 +                             chr[48 + i] &= pmask;
 14.1357 ++#endif
 14.1358 +                         }
 14.1359 +                     }
 14.1360 +                 }
 14.1361 ++#ifdef __MINIOS__
 14.1362 ++		for (j = 0; j < 8; j++)
 14.1363 ++		    if (mask & (1U << j))
 14.1364 ++			chr[i * 8 + (7 - j)] = palette[15];
 14.1365 ++#else
 14.1366 +                 chr[i     ] |= mask;
 14.1367 +                 chr[16 + i] |= mask;
 14.1368 +                 chr[32 + i] |= mask;
 14.1369 +                 chr[48 + i] |= mask;
 14.1370 ++#endif
 14.1371 + 
 14.1372 +                 offset += 80;
 14.1373 +             }
 14.1374 +             else {
 14.1375 ++#ifdef __MINIOS__
 14.1376 ++		for (j = 0; j < 8; j++)
 14.1377 ++		    if (mask & (1U << j))
 14.1378 ++			chr[i * 8 + (7 - j)] = palette[15];
 14.1379 ++		    else
 14.1380 ++			chr[i * 8 + (7 - j)] = palette[0];
 14.1381 ++#else
 14.1382 +                 chr[i     ] = mask;
 14.1383 +                 chr[16 + i] = mask;
 14.1384 +                 chr[32 + i] = mask;
 14.1385 +                 chr[48 + i] = mask;
 14.1386 ++#endif
 14.1387 +             }
 14.1388 +         }
 14.1389 +     }
 14.1390 +     else {
 14.1391 ++#ifdef __MINIOS__
 14.1392 ++        ptr = mem;
 14.1393 ++        for (i = 0; i < 16; i++, ptr += 80 * 8)
 14.1394 ++	    for (j = 0; j < 8; j++) {
 14.1395 ++		if (pat[i] & (1U << (7 - j)))
 14.1396 ++		    cursorBuf32[i * 8 + j] = ptr[j] = palette[0];
 14.1397 ++		else
 14.1398 ++		    cursorBuf32[i * 8 + j] = ptr[j] = palette[15];
 14.1399 ++	    }
 14.1400 ++#else
 14.1401 +         MapMask(15);
 14.1402 +         ptr = mem;
 14.1403 +         for (i = 0; i < 16; i++, ptr += 80) {
 14.1404 +             cursorBuf[i] = pat[i];
 14.1405 +             *ptr = ~pat[i];
 14.1406 +         }
 14.1407 ++#endif
 14.1408 +         return;
 14.1409 +     }
 14.1410 + 
 14.1411 +     offset = 0;
 14.1412 ++#ifdef __MINIOS__
 14.1413 ++    ptr = mem;
 14.1414 ++    for (j = 0; j < 16; j++, ptr += 80 * 8)
 14.1415 ++	memcpy(ptr, chr + j * 8 + offset * 8, 8 * 4);
 14.1416 ++#else
 14.1417 +     for (i = 1; i < 16; i <<= 1, offset += 16) {
 14.1418 +         int j;
 14.1419 + 
 14.1420 +@@ -580,6 +719,7 @@
 14.1421 +     }
 14.1422 + 
 14.1423 +     MapMask(15);
 14.1424 ++#endif
 14.1425 + }
 14.1426 + 
 14.1427 + #endif /* SUPPORT_GRAPHICS */
 14.1428 +Index: grub/stage2/graphics.h
 14.1429 +===================================================================
 14.1430 +--- grub.orig/stage2/graphics.h	2008-06-16 15:18:14.527010000 +0100
 14.1431 ++++ grub/stage2/graphics.h	2008-06-16 15:18:14.805010000 +0100
 14.1432 +@@ -21,8 +21,10 @@
 14.1433 + #ifndef GRAPHICS_H
 14.1434 + #define GRAPHICS_H
 14.1435 + 
 14.1436 ++#ifndef __MINIOS__
 14.1437 + /* magic constant */
 14.1438 + #define VIDEOMEM 0xA0000
 14.1439 ++#endif
 14.1440 + 
 14.1441 + /* function prototypes */
 14.1442 + char *graphics_get_splash(void);
 14.1443 +Index: grub/stage2/stage2.c
 14.1444 +===================================================================
 14.1445 +--- grub.orig/stage2/stage2.c	2008-06-17 11:06:47.873523000 +0100
 14.1446 ++++ grub/stage2/stage2.c	2008-06-17 11:07:05.225628000 +0100
 14.1447 +@@ -31,10 +31,10 @@
 14.1448 + #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS)
 14.1449 + 
 14.1450 + # if defined(PRESET_MENU_STRING)
 14.1451 +-static const char *preset_menu = PRESET_MENU_STRING;
 14.1452 ++const char *preset_menu = PRESET_MENU_STRING;
 14.1453 + # elif defined(SUPPORT_DISKLESS)
 14.1454 + /* Execute the command "bootp" automatically.  */
 14.1455 +-static const char *preset_menu = "bootp\n";
 14.1456 ++const char *preset_menu = "bootp\n";
 14.1457 + # endif /* SUPPORT_DISKLESS */
 14.1458 + 
 14.1459 + static int preset_menu_offset;
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/stubdom/grub/Makefile	Wed Jun 18 09:36:47 2008 +0100
    15.3 @@ -0,0 +1,76 @@
    15.4 +XEN_ROOT = ../..
    15.5 +
    15.6 +include $(XEN_ROOT)/Config.mk
    15.7 +vpath %.c ../grub-cvs
    15.8 +
    15.9 +BOOT=boot-$(XEN_TARGET_ARCH).o
   15.10 +
   15.11 +DEF_CPPFLAGS += -I$(XEN_ROOT)/tools/libxc -I.
   15.12 +DEF_CPPFLAGS += -I../grub-cvs/stage1
   15.13 +DEF_CPPFLAGS += -I../grub-cvs/stage2
   15.14 +DEF_CPPFLAGS += -I../grub-cvs/netboot
   15.15 +DEF_CPPFLAGS += -I$(XEN_ROOT)/tools/firmware/vgabios
   15.16 +DEF_CPPFLAGS += -DWITHOUT_LIBC_STUBS
   15.17 +DEF_CPPFLAGS += -DSUPPORT_NETBOOT
   15.18 +DEF_CPPFLAGS += -DSUPPORT_GRAPHICS
   15.19 +DEF_CPPFLAGS += -DSUPPORT_SERIAL
   15.20 +DEF_CPPFLAGS += -DPRESET_MENU_STRING='""'
   15.21 +DEF_CPPFLAGS += -DPACKAGE='"grubdom"' -DVERSION='"0.97"'
   15.22 +
   15.23 +all: main.a
   15.24 +
   15.25 +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
   15.26 +
   15.27 +NETBOOT_SOURCES=fsys_tftp.c main.c misc.c
   15.28 +CPPFLAGS += -DFSYS_TFTP=1
   15.29 +
   15.30 +STAGE2_SOURCES+=fsys_ext2fs.c
   15.31 +CPPFLAGS += -DFSYS_EXT2FS=1
   15.32 +
   15.33 +STAGE2_SOURCES+=fsys_fat.c
   15.34 +CPPFLAGS += -DFSYS_FAT=1
   15.35 +
   15.36 +STAGE2_SOURCES+=fsys_ffs.c
   15.37 +CPPFLAGS += -DFSYS_FFS=1
   15.38 +
   15.39 +STAGE2_SOURCES+=fsys_iso9660.c
   15.40 +CPPFLAGS += -DFSYS_ISO9660=1
   15.41 +
   15.42 +STAGE2_SOURCES+=fsys_jfs.c
   15.43 +CPPFLAGS += -DFSYS_JFS=1
   15.44 +
   15.45 +STAGE2_SOURCES+=fsys_minix.c
   15.46 +CPPFLAGS += -DFSYS_MINIX=1
   15.47 +
   15.48 +STAGE2_SOURCES+=fsys_reiserfs.c
   15.49 +CPPFLAGS += -DFSYS_REISERFS=1
   15.50 +
   15.51 +STAGE2_SOURCES+=fsys_ufs2.c
   15.52 +CPPFLAGS += -DFSYS_UFS2=1
   15.53 +
   15.54 +STAGE2_SOURCES+=fsys_vstafs.c
   15.55 +CPPFLAGS += -DFSYS_VSTAFS=1
   15.56 +
   15.57 +ifeq (0,1)
   15.58 +STAGE2_SOURCES+=fsys_xfs.c
   15.59 +CPPFLAGS += -DFSYS_XFS=1
   15.60 +endif
   15.61 +
   15.62 +STAGE2_SOURCES:=$(addprefix stage2/,$(STAGE2_SOURCES))
   15.63 +NETBOOT_SOURCES:=$(addprefix netboot/,$(NETBOOT_SOURCES))
   15.64 +
   15.65 +$(BOOT): DEF_CPPFLAGS+=-D__ASSEMBLY__
   15.66 +
   15.67 +OBJS = $(NETBOOT_SOURCES:.c=.o) $(STAGE2_SOURCES:.c=.o) kexec.o mini-os.o
   15.68 +
   15.69 +dirs:
   15.70 +	mkdir -p netboot stage2
   15.71 +	touch $@
   15.72 +
   15.73 +$(OBJS): dirs
   15.74 +
   15.75 +main.a: $(BOOT) $(OBJS)
   15.76 +	$(AR) cr $@ $^
   15.77 +
   15.78 +clean:
   15.79 +	rm -fr dirs *.a *.o stage2 netboot
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/stubdom/grub/boot-x86_32.S	Wed Jun 18 09:36:47 2008 +0100
    16.3 @@ -0,0 +1,112 @@
    16.4 +#include <os.h>
    16.5 +#include <arch_limits.h>
    16.6 +#include <xen/arch-x86_32.h>
    16.7 +
    16.8 +/* For simplicity, we keep all of this into just one data page */
    16.9 +.data
   16.10 +.globl _boot_page
   16.11 +_boot_page:
   16.12 +        .align __PAGE_SIZE
   16.13 +
   16.14 +/*
   16.15 + * The following data is initialized from C code
   16.16 + */
   16.17 +
   16.18 +/* Pte of this page */
   16.19 +.globl _boot_page_entry
   16.20 +_boot_page_entry:
   16.21 +_boot_page_entry_lo:
   16.22 +        .long 0
   16.23 +_boot_page_entry_hi:
   16.24 +        .long 0
   16.25 +
   16.26 +/* mmuext_op structure */
   16.27 +/* Set new page directory */
   16.28 +_boot_mmuext:
   16.29 +        /* Op # */
   16.30 +        .long MMUEXT_NEW_BASEPTR
   16.31 +
   16.32 +        /* MFN of target page table directory */
   16.33 +.globl _boot_pdmfn
   16.34 +_boot_pdmfn:
   16.35 +        .long 0
   16.36 +
   16.37 +        /* Unused */
   16.38 +        .long 0
   16.39 +
   16.40 +/* Unpin old page directory */
   16.41 +        /* Op # */
   16.42 +        .long MMUEXT_UNPIN_TABLE
   16.43 +
   16.44 +        /* MFN of old page table directory */
   16.45 +.globl _boot_oldpdmfn
   16.46 +_boot_oldpdmfn:
   16.47 +        .long 0
   16.48 +
   16.49 +        /* Unused */
   16.50 +        .long 0
   16.51 +
   16.52 +/* Target stack address, also target virtual address of this page */
   16.53 +.globl _boot_stack
   16.54 +_boot_stack:
   16.55 +        .long 0
   16.56 +        .long __KERNEL_SS
   16.57 +.globl _boot_target
   16.58 +_boot_target:
   16.59 +        .long 0
   16.60 +
   16.61 +/* Target start info */
   16.62 +.globl _boot_start_info
   16.63 +_boot_start_info:
   16.64 +        .long 0
   16.65 +
   16.66 +/* Target start address */
   16.67 +.globl _boot_start
   16.68 +_boot_start:
   16.69 +        .long 0
   16.70 +
   16.71 +/*
   16.72 + * Boot target OS, does not return
   16.73 + */
   16.74 +.globl _boot
   16.75 +_boot:
   16.76 +        /* Project ourselves at the target place. */
   16.77 +        movl    _boot_target, %ebx
   16.78 +        movl    %ebx, %ebp     /* also keep it in ebp for relative addressing */
   16.79 +        movl    _boot_page_entry_lo, %ecx
   16.80 +        movl    _boot_page_entry_hi, %edx
   16.81 +        movl    $2, %esi /* UVMF_INVLPG */
   16.82 +        movl    $__HYPERVISOR_update_va_mapping, %eax
   16.83 +        int     $0x82
   16.84 +        testl   %eax, %eax
   16.85 +        jz      0f
   16.86 +        ud2
   16.87 +
   16.88 +0:
   16.89 +        /* Go there. */
   16.90 +        movl    $(0f - _boot_page), %eax
   16.91 +        movl    _boot_target, %ebx
   16.92 +        addl    %ebx, %eax
   16.93 +        jmpl    *%eax
   16.94 +0:
   16.95 +        
   16.96 +        /* Load target page table and unpin old page table.  */
   16.97 +        /* We shouldn't have any problem since in the new page table our page is
   16.98 +           mapped at the same place.  */
   16.99 +        leal    (_boot_mmuext-_boot_page)(%ebp), %ebx
  16.100 +        movl    $2, %ecx
  16.101 +        xorl    %edx, %edx
  16.102 +        movl    $0x7FF0, %esi /* DOMID_SELF */
  16.103 +        movl    $__HYPERVISOR_mmuext_op, %eax
  16.104 +        int     $0x82
  16.105 +        testl   %eax, %eax
  16.106 +        jns     0f
  16.107 +        ud2
  16.108 +
  16.109 +0:
  16.110 +        /* Initialize registers.  */
  16.111 +        lss     (_boot_stack-_boot_page)(%ebp), %esp
  16.112 +        movl    (_boot_start_info-_boot_page)(%ebp), %esi
  16.113 +
  16.114 +        /* Jump!  */
  16.115 +        jmpl    *(_boot_start-_boot_page)(%ebp)
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/stubdom/grub/boot-x86_64.S	Wed Jun 18 09:36:47 2008 +0100
    17.3 @@ -0,0 +1,108 @@
    17.4 +#include <os.h>
    17.5 +#include <arch_limits.h>
    17.6 +#include <xen/arch-x86_64.h>
    17.7 +
    17.8 +/* For simplicity, we keep all of this into just one data page */
    17.9 +.data
   17.10 +.globl _boot_page
   17.11 +_boot_page:
   17.12 +        .align __PAGE_SIZE
   17.13 +
   17.14 +/*
   17.15 + * The following data is initialized from C code
   17.16 + */
   17.17 +
   17.18 +/* Pte of this page */
   17.19 +.globl _boot_page_entry
   17.20 +_boot_page_entry:
   17.21 +        .quad 0
   17.22 +
   17.23 +/* mmuext_op structure */
   17.24 +/* Set new page directory */
   17.25 +_boot_mmuext:
   17.26 +        /* Op # */
   17.27 +        .long MMUEXT_NEW_BASEPTR
   17.28 +        .long 0 /* pad */
   17.29 +
   17.30 +        /* MFN of target page table directory */
   17.31 +.globl _boot_pdmfn
   17.32 +_boot_pdmfn:
   17.33 +        .quad 0
   17.34 +
   17.35 +        /* Unused */
   17.36 +        .quad 0
   17.37 +
   17.38 +/* Unpin old page directory */
   17.39 +        /* Op # */
   17.40 +        .long MMUEXT_UNPIN_TABLE
   17.41 +        .long 0 /* pad */
   17.42 +
   17.43 +        /* MFN of old page table directory */
   17.44 +.globl _boot_oldpdmfn
   17.45 +_boot_oldpdmfn:
   17.46 +        .quad 0
   17.47 +
   17.48 +        /* Unused */
   17.49 +        .quad 0
   17.50 +
   17.51 +/* Target stack address, also target virtual address of this page */
   17.52 +.globl _boot_stack
   17.53 +_boot_stack:
   17.54 +        .quad 0
   17.55 +.globl _boot_target
   17.56 +_boot_target:
   17.57 +        .quad 0
   17.58 +
   17.59 +/* Target start info */
   17.60 +.globl _boot_start_info
   17.61 +_boot_start_info:
   17.62 +        .quad 0
   17.63 +
   17.64 +/* Target start address */
   17.65 +.globl _boot_start
   17.66 +_boot_start:
   17.67 +        .quad 0
   17.68 +
   17.69 +/*
   17.70 + * Boot target OS, does not return
   17.71 + */
   17.72 +.globl _boot
   17.73 +_boot:
   17.74 +        /* Project ourselves at the target place. */
   17.75 +        movq    _boot_target, %rdi
   17.76 +        movq    _boot_page_entry, %rsi
   17.77 +        movq    $2, %rdx /* UVMF_INVLPG */
   17.78 +        movq    $__HYPERVISOR_update_va_mapping, %rax
   17.79 +        syscall
   17.80 +        testq   %rax, %rax
   17.81 +        jz      0f
   17.82 +        ud2
   17.83 +
   17.84 +0:
   17.85 +        /* Go there. */
   17.86 +        movq    $(0f - _boot_page), %rax
   17.87 +        movq    _boot_target, %rbx
   17.88 +        addq    %rbx, %rax
   17.89 +        jmpq    *%rax
   17.90 +0:
   17.91 +        
   17.92 +        /* Load target page table and unpin old page table.  */
   17.93 +        /* We shouldn't have any problem since in the new page table our page is
   17.94 +           mapped at the same place.  */
   17.95 +        leaq    _boot_mmuext(%rip), %rdi
   17.96 +        movq    $2, %rsi
   17.97 +        xorq    %rdx, %rdx
   17.98 +        movq    $0x7FF0, %r10 /* DOMID_SELF */
   17.99 +        movq    $__HYPERVISOR_mmuext_op, %rax
  17.100 +        syscall
  17.101 +        testq   %rax, %rax
  17.102 +        jns     0f
  17.103 +        ud2
  17.104 +
  17.105 +0:
  17.106 +        /* Initialize registers.  */
  17.107 +        movq    _boot_stack(%rip), %rsp
  17.108 +        movq    _boot_start_info(%rip), %rsi
  17.109 +
  17.110 +        /* Jump!  */
  17.111 +        jmpq    *_boot_start(%rip)
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/stubdom/grub/config.h	Wed Jun 18 09:36:47 2008 +0100
    18.3 @@ -0,0 +1,11 @@
    18.4 +#include <stdio.h>
    18.5 +#undef putchar
    18.6 +#include <ctype.h>
    18.7 +#include <string.h>
    18.8 +#define debug _debug
    18.9 +#define grub_halt(a) do_exit()
   18.10 +#define printf grub_printf
   18.11 +void kexec(void *kernel, long kernel_size, void *module, long module_size, char *cmdline);
   18.12 +struct fbfront_dev *fb_open(void *fb, int width, int height, int depth);
   18.13 +void fb_close(void);
   18.14 +void pv_boot (void);
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/stubdom/grub/kexec.c	Wed Jun 18 09:36:47 2008 +0100
    19.3 @@ -0,0 +1,324 @@
    19.4 +/*
    19.5 + * This supports booting another PV kernel from Mini-OS
    19.6 + *
    19.7 + * The idea is to setup it using libxc, answer to day0 memory allocation
    19.8 + * requests, and using a trampoline boot page to switch to the new page table.
    19.9 + *
   19.10 + * The procedure of the boot page is:
   19.11 + * - map itself at the target position (that may overwrite some C stuff, but we
   19.12 + *   do not care any more)
   19.13 + * - jump there
   19.14 + * - switch to the target page table
   19.15 + * - unpin the old page table
   19.16 + * - jump to the new kernel
   19.17 + *
   19.18 + * Samuel Thibault <Samuel.Thibault@eu.citrix.com>, May 2008
   19.19 + */
   19.20 +#include <stdio.h>
   19.21 +#include <unistd.h>
   19.22 +#include <stdlib.h>
   19.23 +#include <sys/mman.h>
   19.24 +
   19.25 +#include <xenctrl.h>
   19.26 +#include <xc_dom.h>
   19.27 +
   19.28 +#include <kernel.h>
   19.29 +#include <console.h>
   19.30 +#include <os.h>
   19.31 +#include <blkfront.h>
   19.32 +#include <netfront.h>
   19.33 +#include <fbfront.h>
   19.34 +#include <shared.h>
   19.35 +
   19.36 +#include "mini-os.h"
   19.37 +
   19.38 +#if 0
   19.39 +#define DEBUG(fmt, ...) printk(fmt, ## __VA_ARGS__)
   19.40 +#else
   19.41 +#define DEBUG(fmt, ...) (void)0
   19.42 +#endif
   19.43 +
   19.44 +/* Assembly boot page from boot.S */
   19.45 +extern void _boot_page;
   19.46 +extern pgentry_t _boot_page_entry;
   19.47 +extern unsigned long _boot_pdmfn;
   19.48 +extern unsigned long _boot_stack, _boot_target, _boot_start_info, _boot_start;
   19.49 +extern xen_pfn_t _boot_oldpdmfn;
   19.50 +extern void _boot(void);
   19.51 +
   19.52 +static unsigned long *pages;
   19.53 +static unsigned long *pages_mfns;
   19.54 +static unsigned long allocated;
   19.55 +
   19.56 +int pin_table(int xc_handle, unsigned int type, unsigned long mfn,
   19.57 +              domid_t dom);
   19.58 +
   19.59 +/* We need mfn to appear as target_pfn, so exchange with the MFN there */
   19.60 +static void do_exchange(struct xc_dom_image *dom, xen_pfn_t target_pfn, xen_pfn_t source_mfn)
   19.61 +{
   19.62 +    xen_pfn_t source_pfn;
   19.63 +    xen_pfn_t target_mfn;
   19.64 +
   19.65 +    for (source_pfn = 0; source_pfn < start_info.nr_pages; source_pfn++)
   19.66 +        if (dom->p2m_host[source_pfn] == source_mfn)
   19.67 +            break;
   19.68 +    ASSERT(source_pfn < start_info.nr_pages);
   19.69 +
   19.70 +    target_mfn = dom->p2m_host[target_pfn];
   19.71 +
   19.72 +    /* Put target MFN at source PFN */
   19.73 +    dom->p2m_host[source_pfn] = target_mfn;
   19.74 +
   19.75 +    /* Put source MFN at target PFN */
   19.76 +    dom->p2m_host[target_pfn] = source_mfn;
   19.77 +}
   19.78 +
   19.79 +int kexec_allocate(struct xc_dom_image *dom, xen_vaddr_t up_to)
   19.80 +{
   19.81 +    unsigned long new_allocated = (up_to - dom->parms.virt_base) / PAGE_SIZE;
   19.82 +    unsigned long i;
   19.83 +
   19.84 +    pages = realloc(pages, new_allocated * sizeof(*pages));
   19.85 +    pages_mfns = realloc(pages_mfns, new_allocated * sizeof(*pages_mfns));
   19.86 +    for (i = allocated; i < new_allocated; i++) {
   19.87 +        /* Exchange old page of PFN i with a newly allocated page.  */
   19.88 +        xen_pfn_t old_mfn = dom->p2m_host[i];
   19.89 +        xen_pfn_t new_pfn;
   19.90 +        xen_pfn_t new_mfn;
   19.91 +
   19.92 +        pages[i] = alloc_page();
   19.93 +        memset((void*) pages[i], 0, PAGE_SIZE);
   19.94 +        new_pfn = PHYS_PFN(to_phys(pages[i]));
   19.95 +        pages_mfns[i] = new_mfn = pfn_to_mfn(new_pfn);
   19.96 +
   19.97 +        /* Put old page at new PFN */
   19.98 +        dom->p2m_host[new_pfn] = old_mfn;
   19.99 +
  19.100 +        /* Put new page at PFN i */
  19.101 +        dom->p2m_host[i] = new_mfn;
  19.102 +    }
  19.103 +
  19.104 +    allocated = new_allocated;
  19.105 +
  19.106 +    return 0;
  19.107 +}
  19.108 +
  19.109 +void kexec(void *kernel, long kernel_size, void *module, long module_size, char *cmdline)
  19.110 +{
  19.111 +    struct xc_dom_image *dom;
  19.112 +    int rc;
  19.113 +    domid_t domid = DOMID_SELF;
  19.114 +    xen_pfn_t pfn;
  19.115 +    int xc_handle;
  19.116 +    unsigned long i;
  19.117 +    void *seg;
  19.118 +    xen_pfn_t boot_page_mfn = virt_to_mfn(&_boot_page);
  19.119 +    char features[] = "";
  19.120 +    struct mmu_update *m2p_updates;
  19.121 +    unsigned long nr_m2p_updates;
  19.122 +
  19.123 +    DEBUG("booting with cmdline %s\n", cmdline);
  19.124 +    xc_handle = xc_interface_open();
  19.125 +
  19.126 +    dom = xc_dom_allocate(cmdline, features);
  19.127 +    dom->allocate = kexec_allocate;
  19.128 +
  19.129 +    dom->kernel_blob = kernel;
  19.130 +    dom->kernel_size = kernel_size;
  19.131 +
  19.132 +    dom->ramdisk_blob = module;
  19.133 +    dom->ramdisk_size = module_size;
  19.134 +
  19.135 +    dom->flags = 0;
  19.136 +    dom->console_evtchn = start_info.console.domU.evtchn;
  19.137 +    dom->xenstore_evtchn = start_info.store_evtchn;
  19.138 +
  19.139 +    if ( (rc = xc_dom_boot_xen_init(dom, xc_handle, domid)) != 0 ) {
  19.140 +        grub_printf("xc_dom_boot_xen_init returned %d\n", rc);
  19.141 +        errnum = ERR_BOOT_FAILURE;
  19.142 +        goto out;
  19.143 +    }
  19.144 +    if ( (rc = xc_dom_parse_image(dom)) != 0 ) {
  19.145 +        grub_printf("xc_dom_parse_image returned %d\n", rc);
  19.146 +        errnum = ERR_BOOT_FAILURE;
  19.147 +        goto out;
  19.148 +    }
  19.149 +
  19.150 +#ifdef __i386__
  19.151 +    if (strcmp(dom->guest_type, "xen-3.0-x86_32p")) {
  19.152 +        grub_printf("can only boot x86 32 PAE kernels, not %s\n", dom->guest_type);
  19.153 +        errnum = ERR_EXEC_FORMAT;
  19.154 +        goto out;
  19.155 +    }
  19.156 +#endif
  19.157 +#ifdef __x86_64__
  19.158 +    if (strcmp(dom->guest_type, "xen-3.0-x86_64")) {
  19.159 +        grub_printf("can only boot x86 64 kernels, not %s\n", dom->guest_type);
  19.160 +        errnum = ERR_EXEC_FORMAT;
  19.161 +        goto out;
  19.162 +    }
  19.163 +#endif
  19.164 +
  19.165 +    /* equivalent of xc_dom_mem_init */
  19.166 +    dom->arch_hooks = xc_dom_find_arch_hooks(dom->guest_type);
  19.167 +    dom->total_pages = start_info.nr_pages;
  19.168 +
  19.169 +    /* equivalent of arch_setup_meminit */
  19.170 +
  19.171 +    /* setup initial p2m */
  19.172 +    dom->p2m_host = malloc(sizeof(*dom->p2m_host) * dom->total_pages);
  19.173 +
  19.174 +    /* Start with our current P2M */
  19.175 +    for (i = 0; i < dom->total_pages; i++)
  19.176 +        dom->p2m_host[i] = pfn_to_mfn(i);
  19.177 +
  19.178 +    if ( (rc = xc_dom_build_image(dom)) != 0 ) {
  19.179 +        grub_printf("xc_dom_build_image returned %d\n", rc);
  19.180 +        errnum = ERR_BOOT_FAILURE;
  19.181 +        goto out;
  19.182 +    }
  19.183 +
  19.184 +    /* copy hypercall page */
  19.185 +    /* TODO: domctl instead, but requires privileges */
  19.186 +    if (dom->parms.virt_hypercall != -1) {
  19.187 +        pfn = PHYS_PFN(dom->parms.virt_hypercall - dom->parms.virt_base);
  19.188 +        memcpy((void *) pages[pfn], hypercall_page, PAGE_SIZE);
  19.189 +    }
  19.190 +
  19.191 +    /* Equivalent of xc_dom_boot_image */
  19.192 +    dom->shared_info_mfn = PHYS_PFN(start_info.shared_info);
  19.193 +
  19.194 +    if (!xc_dom_compat_check(dom)) {
  19.195 +        grub_printf("xc_dom_compat_check failed\n");
  19.196 +        errnum = ERR_EXEC_FORMAT;
  19.197 +        goto out;
  19.198 +    }
  19.199 +
  19.200 +    /* Move current console, xenstore and boot MFNs to the allocated place */
  19.201 +    do_exchange(dom, dom->console_pfn, start_info.console.domU.mfn);
  19.202 +    do_exchange(dom, dom->xenstore_pfn, start_info.store_mfn);
  19.203 +    DEBUG("virt base at %llx\n", dom->parms.virt_base);
  19.204 +    DEBUG("bootstack_pfn %lx\n", dom->bootstack_pfn);
  19.205 +    _boot_target = dom->parms.virt_base + PFN_PHYS(dom->bootstack_pfn);
  19.206 +    DEBUG("_boot_target %lx\n", _boot_target);
  19.207 +    do_exchange(dom, PHYS_PFN(_boot_target - dom->parms.virt_base),
  19.208 +            virt_to_mfn(&_boot_page));
  19.209 +
  19.210 +    /* Make sure the bootstrap page table does not RW-map any of our current
  19.211 +     * page table frames */
  19.212 +    kexec_allocate(dom, dom->virt_pgtab_end);
  19.213 +
  19.214 +    if ( (rc = xc_dom_update_guest_p2m(dom))) {
  19.215 +        grub_printf("xc_dom_update_guest_p2m returned %d\n", rc);
  19.216 +        errnum = ERR_BOOT_FAILURE;
  19.217 +        goto out;
  19.218 +    }
  19.219 +
  19.220 +    if ( dom->arch_hooks->setup_pgtables )
  19.221 +        if ( (rc = dom->arch_hooks->setup_pgtables(dom))) {
  19.222 +            grub_printf("setup_pgtables returned %d\n", rc);
  19.223 +            errnum = ERR_BOOT_FAILURE;
  19.224 +            goto out;
  19.225 +        }
  19.226 +
  19.227 +    /* start info page */
  19.228 +#undef start_info
  19.229 +    if ( dom->arch_hooks->start_info )
  19.230 +        dom->arch_hooks->start_info(dom);
  19.231 +#define start_info (start_info_union.start_info)
  19.232 +
  19.233 +    xc_dom_log_memory_footprint(dom);
  19.234 +
  19.235 +    /* Unmap libxc's projection of the boot page table */
  19.236 +    seg = xc_dom_seg_to_ptr(dom, &dom->pgtables_seg);
  19.237 +    munmap(seg, dom->pgtables_seg.vend - dom->pgtables_seg.vstart);
  19.238 +
  19.239 +    /* Unmap day0 pages to avoid having a r/w mapping of the future page table */
  19.240 +    for (pfn = 0; pfn < allocated; pfn++)
  19.241 +        munmap((void*) pages[pfn], PAGE_SIZE);
  19.242 +
  19.243 +    /* Pin the boot page table base */
  19.244 +    if ( (rc = pin_table(dom->guest_xc, 
  19.245 +#ifdef __i386__
  19.246 +                MMUEXT_PIN_L3_TABLE,
  19.247 +#endif
  19.248 +#ifdef __x86_64__
  19.249 +                MMUEXT_PIN_L4_TABLE,
  19.250 +#endif
  19.251 +                xc_dom_p2m_host(dom, dom->pgtables_seg.pfn),
  19.252 +                dom->guest_domid)) != 0 ) {
  19.253 +        grub_printf("pin_table(%lx) returned %d\n", xc_dom_p2m_host(dom,
  19.254 +                    dom->pgtables_seg.pfn), rc);
  19.255 +        errnum = ERR_BOOT_FAILURE;
  19.256 +        goto out_remap;
  19.257 +    }
  19.258 +
  19.259 +    /* We populate the Mini-OS page table here so that boot.S can just call
  19.260 +     * update_va_mapping to project itself there.  */
  19.261 +    need_pgt(_boot_target);
  19.262 +    DEBUG("day0 pages %lx\n", allocated);
  19.263 +    DEBUG("boot target page %lx\n", _boot_target);
  19.264 +    DEBUG("boot page %p\n", &_boot_page);
  19.265 +    DEBUG("boot page mfn %lx\n", boot_page_mfn);
  19.266 +    _boot_page_entry = PFN_PHYS(boot_page_mfn) | L1_PROT;
  19.267 +    DEBUG("boot page entry %llx\n", _boot_page_entry);
  19.268 +    _boot_oldpdmfn = virt_to_mfn(start_info.pt_base);
  19.269 +    DEBUG("boot old pd mfn %lx\n", _boot_oldpdmfn);
  19.270 +    DEBUG("boot pd virt %lx\n", dom->pgtables_seg.vstart);
  19.271 +    _boot_pdmfn = dom->p2m_host[PHYS_PFN(dom->pgtables_seg.vstart - dom->parms.virt_base)];
  19.272 +    DEBUG("boot pd mfn %lx\n", _boot_pdmfn);
  19.273 +    _boot_stack = _boot_target + PAGE_SIZE;
  19.274 +    DEBUG("boot stack %lx\n", _boot_stack);
  19.275 +    _boot_start_info = dom->parms.virt_base + PFN_PHYS(dom->start_info_pfn);
  19.276 +    DEBUG("boot start info %lx\n", _boot_start_info);
  19.277 +    _boot_start = dom->parms.virt_entry;
  19.278 +    DEBUG("boot start %lx\n", _boot_start);
  19.279 +
  19.280 +    /* Keep only useful entries */
  19.281 +    for (nr_m2p_updates = pfn = 0; pfn < start_info.nr_pages; pfn++)
  19.282 +        if (dom->p2m_host[pfn] != pfn_to_mfn(pfn))
  19.283 +            nr_m2p_updates++;
  19.284 +
  19.285 +    m2p_updates = malloc(sizeof(*m2p_updates) * nr_m2p_updates);
  19.286 +    for (i = pfn = 0; pfn < start_info.nr_pages; pfn++)
  19.287 +        if (dom->p2m_host[pfn] != pfn_to_mfn(pfn)) {
  19.288 +            m2p_updates[i].ptr = PFN_PHYS(dom->p2m_host[pfn]) | MMU_MACHPHYS_UPDATE;
  19.289 +            m2p_updates[i].val = pfn;
  19.290 +            i++;
  19.291 +        }
  19.292 +
  19.293 +    for (i = 0; i < blk_nb; i++)
  19.294 +        shutdown_blkfront(blk_dev[i]);
  19.295 +    if (net_dev)
  19.296 +        shutdown_netfront(net_dev);
  19.297 +    if (kbd_dev)
  19.298 +        shutdown_kbdfront(kbd_dev);
  19.299 +    stop_kernel();
  19.300 +
  19.301 +    /* Update M2P */
  19.302 +    if ((rc = HYPERVISOR_mmu_update(m2p_updates, nr_m2p_updates, NULL, DOMID_SELF)) < 0) {
  19.303 +        xprintk("Could not update M2P\n");
  19.304 +        ASSERT(0);
  19.305 +    }
  19.306 +
  19.307 +    xprintk("go!\n");
  19.308 +
  19.309 +    /* Jump to trampoline boot page */
  19.310 +    _boot();
  19.311 +
  19.312 +    ASSERT(0);
  19.313 +
  19.314 +out_remap:
  19.315 +    for (pfn = 0; pfn < allocated; pfn++)
  19.316 +        do_map_frames(pages[pfn], &pages_mfns[pfn], 1, 0, 0, DOMID_SELF, 0, L1_PROT);
  19.317 +out:
  19.318 +    xc_dom_release(dom);
  19.319 +    for (pfn = 0; pfn < allocated; pfn++)
  19.320 +        free_page((void*)pages[pfn]);
  19.321 +    free(pages);
  19.322 +    free(pages_mfns);
  19.323 +    pages = NULL;
  19.324 +    pages_mfns = NULL;
  19.325 +    allocated = 0;
  19.326 +    xc_interface_close(xc_handle );
  19.327 +}
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/stubdom/grub/mini-os.c	Wed Jun 18 09:36:47 2008 +0100
    20.3 @@ -0,0 +1,702 @@
    20.4 +/*
    20.5 + * Mini-OS support for GRUB.
    20.6 + *
    20.7 + * Samuel Thibault <Samuel.Thibault@eu.citrix.com>, May 2008
    20.8 + */
    20.9 +#include <sys/types.h>
   20.10 +#include <sys/time.h>
   20.11 +#include <stdarg.h>
   20.12 +#include <stdlib.h>
   20.13 +#include <malloc.h>
   20.14 +#include <unistd.h>
   20.15 +
   20.16 +#include <hypervisor.h>
   20.17 +#include <blkfront.h>
   20.18 +#include <netfront.h>
   20.19 +#include <fbfront.h>
   20.20 +#include <semaphore.h>
   20.21 +
   20.22 +#include <osdep.h>
   20.23 +#include <shared.h>
   20.24 +#include <nic.h>
   20.25 +#include <etherboot.h>
   20.26 +#include <terminfo.h>
   20.27 +#include <term.h>
   20.28 +
   20.29 +#include "mini-os.h"
   20.30 +
   20.31 +extern const char *preset_menu;
   20.32 +char config_file[DEFAULT_FILE_BUFLEN] = "(hd0,0)/boot/grub/menu.lst";
   20.33 +unsigned long boot_drive = NETWORK_DRIVE;
   20.34 +unsigned long install_partition = 0xFFFFFF;
   20.35 +
   20.36 +char version_string[] = VERSION;
   20.37 +
   20.38 +/* Variables from asm.S */
   20.39 +int saved_entryno;
   20.40 +
   20.41 +/*
   20.42 + * Disk
   20.43 + */
   20.44 +
   20.45 +struct blkfront_dev **blk_dev;
   20.46 +int blk_nb;
   20.47 +static struct blkfront_info *blk_info;
   20.48 +
   20.49 +static int vbdcmp(const void *_vbd1, const void *_vbd2) {
   20.50 +    char *vbd1 = *(char **)_vbd1;
   20.51 +    char *vbd2 = *(char **)_vbd2;
   20.52 +    int vbdn1 = atoi(vbd1);
   20.53 +    int vbdn2 = atoi(vbd2);
   20.54 +    return vbdn1 - vbdn2;
   20.55 +}
   20.56 +
   20.57 +void init_disk (void)
   20.58 +{
   20.59 +    char **list;
   20.60 +    char *msg;
   20.61 +    int i;
   20.62 +    char *path;
   20.63 +
   20.64 +    msg = xenbus_ls(XBT_NIL, "device/vbd", &list);
   20.65 +    if (msg) {
   20.66 +        printk("Error %s while reading list of disks\n", msg);
   20.67 +        free(msg);
   20.68 +        return;
   20.69 +    }
   20.70 +    blk_nb = 0;
   20.71 +    while (list[blk_nb])
   20.72 +        blk_nb++;
   20.73 +    blk_dev = malloc(blk_nb * sizeof(*blk_dev));
   20.74 +    blk_info = malloc(blk_nb * sizeof(*blk_info));
   20.75 +
   20.76 +    qsort(list, blk_nb, sizeof(*list), vbdcmp);
   20.77 +
   20.78 +    for (i = 0; i < blk_nb; i++) {
   20.79 +        printk("vbd %s is hd%d\n", list[i], i);
   20.80 +        asprintf(&path, "device/vbd/%s", list[i]);
   20.81 +        blk_dev[i] = init_blkfront(path, &blk_info[i]);
   20.82 +        free(path);
   20.83 +        free(list[i]);
   20.84 +    }
   20.85 +}
   20.86 +
   20.87 +/* Return the geometry of DRIVE in GEOMETRY. If an error occurs, return
   20.88 +   non-zero, otherwise zero.  */
   20.89 +int get_diskinfo (int drive, struct geometry *geometry)
   20.90 +{
   20.91 +    int i;
   20.92 +    if (!(drive & 0x80))
   20.93 +        return -1;
   20.94 +
   20.95 +    i = drive - 0x80;
   20.96 +    if (i >= blk_nb)
   20.97 +        return -1;
   20.98 +
   20.99 +    /* Bogus geometry */
  20.100 +    geometry->cylinders = 65535;
  20.101 +    geometry->heads = 255;
  20.102 +    geometry->sectors = 63;
  20.103 +
  20.104 +    geometry->total_sectors = blk_info[i].sectors;
  20.105 +    geometry->sector_size = blk_info[i].sector_size;
  20.106 +    geometry->flags = BIOSDISK_FLAG_LBA_EXTENSION;
  20.107 +    if (blk_info[i].info & VDISK_CDROM)
  20.108 +        geometry->flags |= BIOSDISK_FLAG_CDROM;
  20.109 +    return 0;
  20.110 +}
  20.111 +
  20.112 +/* Read/write NSEC sectors starting from SECTOR in DRIVE disk with GEOMETRY
  20.113 +   from/into SEGMENT segment. If READ is BIOSDISK_READ, then read it,
  20.114 +   else if READ is BIOSDISK_WRITE, then write it. If an geometry error
  20.115 +   occurs, return BIOSDISK_ERROR_GEOMETRY, and if other error occurs, then
  20.116 +   return the error number. Otherwise, return 0.  */
  20.117 +int
  20.118 +biosdisk (int read, int drive, struct geometry *geometry,
  20.119 +          unsigned int sector, int nsec, int segment)
  20.120 +{
  20.121 +    void *addr = (void *) ((unsigned long)segment << 4);
  20.122 +    struct blkfront_aiocb aiocb;
  20.123 +    int i;
  20.124 +
  20.125 +    if (!(drive & 0x80))
  20.126 +        return -1;
  20.127 +
  20.128 +    i = drive - 0x80;
  20.129 +    if (i >= blk_nb)
  20.130 +        return -1;
  20.131 +
  20.132 +    aiocb.aio_dev = blk_dev[i];
  20.133 +    aiocb.aio_buf = addr;
  20.134 +    aiocb.aio_nbytes = (size_t)nsec * blk_info[i].sector_size;
  20.135 +    aiocb.aio_offset = (off_t)sector * blk_info[i].sector_size;
  20.136 +    aiocb.aio_cb = NULL;
  20.137 +
  20.138 +    blkfront_io(&aiocb, read == BIOSDISK_WRITE);
  20.139 +
  20.140 +    return 0;
  20.141 +}
  20.142 +
  20.143 +static int
  20.144 +load_file(char *name, void **ptr, long *size)
  20.145 +{
  20.146 +    char *buf = NULL;
  20.147 +    int allocated = 1 * 1024 * 1024;
  20.148 +    int len, filled = 0;
  20.149 +
  20.150 +    if (!grub_open (name))
  20.151 +        return -1;
  20.152 +
  20.153 +    buf = malloc(allocated);
  20.154 +
  20.155 +    errnum = 0;
  20.156 +    while (1) {
  20.157 +        len = grub_read (buf + filled, allocated - filled);
  20.158 +        if (! len) {
  20.159 +            if (!errnum)
  20.160 +                break;
  20.161 +            grub_close ();
  20.162 +            return -1;
  20.163 +        }
  20.164 +        filled += len;
  20.165 +        if (filled < allocated)
  20.166 +            break;
  20.167 +        allocated *= 2;
  20.168 +        buf = realloc(buf, allocated);
  20.169 +    }
  20.170 +    grub_close ();
  20.171 +    *ptr = buf;
  20.172 +    *size = filled;
  20.173 +    return 0;
  20.174 +}
  20.175 +
  20.176 +void *kernel_image, *module_image;
  20.177 +long  kernel_size, module_size;
  20.178 +char *kernel_arg, *module_arg;
  20.179 +
  20.180 +kernel_t
  20.181 +load_image (char *kernel, char *arg, kernel_t suggested_type,
  20.182 +            unsigned long load_flags)
  20.183 +{
  20.184 +    arg = skip_to(0, arg);
  20.185 +    if (kernel_image)
  20.186 +        free(kernel_image);
  20.187 +    kernel_image = NULL;
  20.188 +    if (load_file (kernel, &kernel_image, &kernel_size))
  20.189 +        return KERNEL_TYPE_NONE;
  20.190 +    if (kernel_arg)
  20.191 +        free(kernel_arg);
  20.192 +    kernel_arg = strdup(arg);
  20.193 +    return KERNEL_TYPE_PV;
  20.194 +}
  20.195 +
  20.196 +int
  20.197 +load_initrd (char *initrd)
  20.198 +{
  20.199 +    if (module_image)
  20.200 +        free(module_image);
  20.201 +    module_image = NULL;
  20.202 +    load_file (initrd, &module_image, &module_size);
  20.203 +    return ! errnum;
  20.204 +}
  20.205 +
  20.206 +int
  20.207 +load_module (char *module, char *arg)
  20.208 +{
  20.209 +    if (module_image)
  20.210 +        free(module_image);
  20.211 +    module_image = NULL;
  20.212 +    load_file (module, &module_image, &module_size);
  20.213 +    if (module_arg)
  20.214 +        free(module_arg);
  20.215 +    module_arg = strdup(arg);
  20.216 +    return ! errnum;
  20.217 +}
  20.218 +
  20.219 +void
  20.220 +pv_boot (void)
  20.221 +{
  20.222 +    kexec(kernel_image, kernel_size, module_image, module_size, kernel_arg);
  20.223 +}
  20.224 +
  20.225 +/*
  20.226 + * Network
  20.227 + */
  20.228 +
  20.229 +struct netfront_dev *net_dev;
  20.230 +
  20.231 +int
  20.232 +minios_probe (struct nic *nic)
  20.233 +{
  20.234 +    char *ip;
  20.235 +
  20.236 +    if (net_dev)
  20.237 +        return 1;
  20.238 +
  20.239 +    /* Clear the ARP table.  */
  20.240 +    grub_memset ((char *) arptable, 0,
  20.241 +                 MAX_ARP * sizeof (struct arptable_t));
  20.242 +
  20.243 +    net_dev = init_netfront(NULL, (void*) -1, nic->node_addr, &ip);
  20.244 +    if (!net_dev)
  20.245 +        return 0;
  20.246 +
  20.247 +    return 1;
  20.248 +}
  20.249 +
  20.250 +/* reset adapter */
  20.251 +static void minios_reset(struct nic *nic)
  20.252 +{
  20.253 +    /* TODO? */
  20.254 +}
  20.255 +
  20.256 +static void minios_disable(struct nic *nic)
  20.257 +{
  20.258 +}
  20.259 +
  20.260 +/* Wait for a frame */
  20.261 +static int minios_poll(struct nic *nic)
  20.262 +{
  20.263 +    return !! (nic->packetlen = netfront_receive(net_dev, (void*) nic->packet, ETH_FRAME_LEN));
  20.264 +}
  20.265 +
  20.266 +/* Transmit a frame */
  20.267 +struct frame {
  20.268 +        uint8_t dest[ETH_ALEN];
  20.269 +        uint8_t src[ETH_ALEN];
  20.270 +        uint16_t type;
  20.271 +        unsigned char data[];
  20.272 +};
  20.273 +static void minios_transmit (struct nic *nic, const char *d, unsigned int t,
  20.274 +                             unsigned int s, const char *p)
  20.275 +{
  20.276 +    struct frame *frame = alloca(sizeof(frame) + s);
  20.277 +
  20.278 +    memcpy(frame->dest, d, ETH_ALEN);
  20.279 +    memcpy(frame->src, nic->node_addr, ETH_ALEN);
  20.280 +    frame->type = htons(t);
  20.281 +    memcpy(frame->data, p, s);
  20.282 +
  20.283 +    netfront_xmit(net_dev, (void*) frame, sizeof(*frame) + s);
  20.284 +}
  20.285 +
  20.286 +static char packet[ETH_FRAME_LEN];
  20.287 +
  20.288 +struct nic nic = {
  20.289 +    .reset = minios_reset,
  20.290 +    .poll = minios_poll,
  20.291 +    .transmit = minios_transmit,
  20.292 +    .disable = minios_disable,
  20.293 +    .flags = 0,
  20.294 +    .rom_info = NULL,
  20.295 +    .node_addr = arptable[ARP_CLIENT].node,
  20.296 +    .packet = packet,
  20.297 +    .packetlen = 0,
  20.298 +    .priv_data = NULL,
  20.299 +};
  20.300 +
  20.301 +int
  20.302 +eth_probe (void)
  20.303 +{
  20.304 +    return minios_probe(&nic);
  20.305 +}
  20.306 +
  20.307 +int
  20.308 +eth_poll (void)
  20.309 +{
  20.310 +    return minios_poll (&nic);
  20.311 +}
  20.312 +
  20.313 +void
  20.314 +eth_disable (void)
  20.315 +{
  20.316 +    minios_disable (&nic);
  20.317 +}
  20.318 +
  20.319 +void
  20.320 +eth_transmit (const char *d, unsigned int t,
  20.321 +              unsigned int s, const void *p)
  20.322 +{
  20.323 +    minios_transmit (&nic, d, t, s, p);
  20.324 +    if (t == IP)
  20.325 +        twiddle();
  20.326 +}
  20.327 +
  20.328 +/*
  20.329 + * Console
  20.330 + */
  20.331 +void
  20.332 +serial_hw_put (int _c)
  20.333 +{
  20.334 +  char c = _c;
  20.335 +  console_print(&c, 1);
  20.336 +}
  20.337 +
  20.338 +int
  20.339 +serial_hw_fetch (void)
  20.340 +{
  20.341 +    char key;
  20.342 +
  20.343 +    if (!xencons_ring_avail())
  20.344 +        return -1;
  20.345 +
  20.346 +    read(STDIN_FILENO, &key, 1);
  20.347 +    switch (key) {
  20.348 +    case 0x7f: key = '\b'; break;
  20.349 +    }
  20.350 +    return key;
  20.351 +}
  20.352 +
  20.353 +/*
  20.354 + * PVFB
  20.355 + */
  20.356 +struct kbdfront_dev *kbd_dev;
  20.357 +struct fbfront_dev *fb_dev;
  20.358 +static union xenkbd_in_event ev;
  20.359 +static int has_ev;
  20.360 +int console_checkkey (void)
  20.361 +{
  20.362 +    if (has_ev)
  20.363 +        return 1;
  20.364 +    has_ev = kbdfront_receive(kbd_dev, &ev, 1);
  20.365 +    return has_ev;
  20.366 +}
  20.367 +
  20.368 +/* static QWERTY layout, that's what most PC BIOSes do anyway */
  20.369 +static char linux2ascii[] = {
  20.370 +    [ 1 ] = 27,
  20.371 +    [ 2 ] = '1',
  20.372 +    [ 3 ] = '2',
  20.373 +    [ 4 ] = '3',
  20.374 +    [ 5 ] = '4',
  20.375 +    [ 6 ] = '5',
  20.376 +    [ 7 ] = '6',
  20.377 +    [ 8 ] = '7',
  20.378 +    [ 9 ] = '8',
  20.379 +    [ 10 ] = '9',
  20.380 +    [ 11 ] = '0',
  20.381 +    [ 12 ] = '-',
  20.382 +    [ 13 ] = '=',
  20.383 +    [ 14 ] = '\b',
  20.384 +    [ 15 ] = '\t',
  20.385 +    [ 16 ] = 'q',
  20.386 +    [ 17 ] = 'w',
  20.387 +    [ 18 ] = 'e',
  20.388 +    [ 19 ] = 'r',
  20.389 +    [ 20 ] = 't',
  20.390 +    [ 21 ] = 'y',
  20.391 +    [ 22 ] = 'u',
  20.392 +    [ 23 ] = 'i',
  20.393 +    [ 24 ] = 'o',
  20.394 +    [ 25 ] = 'p',
  20.395 +    [ 26 ] = '[',
  20.396 +    [ 27 ] = ']',
  20.397 +    [ 28 ] = '\n',
  20.398 +
  20.399 +    [ 30 ] = 'a',
  20.400 +    [ 31 ] = 's',
  20.401 +    [ 32 ] = 'd',
  20.402 +    [ 33 ] = 'f',
  20.403 +    [ 34 ] = 'g',
  20.404 +    [ 35 ] = 'h',
  20.405 +    [ 36 ] = 'j',
  20.406 +    [ 37 ] = 'k',
  20.407 +    [ 38 ] = 'l',
  20.408 +    [ 39 ] = ';',
  20.409 +    [ 40 ] = '\'',
  20.410 +    [ 41 ] = '`',
  20.411 +
  20.412 +    [ 43 ] = '\\',
  20.413 +    [ 44 ] = 'z',
  20.414 +    [ 45 ] = 'x',
  20.415 +    [ 46 ] = 'c',
  20.416 +    [ 47 ] = 'v',
  20.417 +    [ 48 ] = 'b',
  20.418 +    [ 49 ] = 'n',
  20.419 +    [ 50 ] = 'm',
  20.420 +    [ 51 ] = ',',
  20.421 +    [ 52 ] = '.',
  20.422 +    [ 53 ] = '/',
  20.423 +
  20.424 +    [ 55 ] = '*',
  20.425 +    [ 57 ] = ' ',
  20.426 +
  20.427 +    [ 71 ] = '7',
  20.428 +    [ 72 ] = '8',
  20.429 +    [ 73 ] = '9',
  20.430 +    [ 74 ] = '-',
  20.431 +    [ 75 ] = '4',
  20.432 +    [ 76 ] = '5',
  20.433 +    [ 77 ] = '6',
  20.434 +    [ 78 ] = '+',
  20.435 +    [ 79 ] = '1',
  20.436 +    [ 80 ] = '2',
  20.437 +    [ 81 ] = '3',
  20.438 +    [ 82 ] = '0',
  20.439 +    [ 83 ] = '.',
  20.440 +
  20.441 +    [ 86 ] = '<',
  20.442 +
  20.443 +    [ 96 ] = '\n',
  20.444 +
  20.445 +    [ 98 ] = '/',
  20.446 +
  20.447 +    [ 102 ] = 1,  /* home */
  20.448 +    [ 103 ] = 16, /* up */
  20.449 +    [ 104 ] = 7,  /* page up */
  20.450 +    [ 105 ] = 2,  /* left */
  20.451 +    [ 106 ] = 6,  /* right */
  20.452 +    [ 107 ] = 5,  /* end */
  20.453 +    [ 108 ] = 14, /* down */
  20.454 +    [ 109 ] = 3,  /* page down */
  20.455 +
  20.456 +    [ 111 ] = 4,  /* delete */
  20.457 +};
  20.458 +
  20.459 +static char linux2ascii_shifted[] = {
  20.460 +    [ 1 ] = 27,
  20.461 +    [ 2 ] = '!',
  20.462 +    [ 3 ] = '@',
  20.463 +    [ 4 ] = '#',
  20.464 +    [ 5 ] = '$',
  20.465 +    [ 6 ] = '%',
  20.466 +    [ 7 ] = '^',
  20.467 +    [ 8 ] = '&',
  20.468 +    [ 9 ] = '*',
  20.469 +    [ 10 ] = '(',
  20.470 +    [ 11 ] = ')',
  20.471 +    [ 12 ] = '_',
  20.472 +    [ 13 ] = '+',
  20.473 +    [ 14 ] = '\b',
  20.474 +    [ 15 ] = '\t',
  20.475 +    [ 16 ] = 'Q',
  20.476 +    [ 17 ] = 'W',
  20.477 +    [ 18 ] = 'E',
  20.478 +    [ 19 ] = 'R',
  20.479 +    [ 20 ] = 'T',
  20.480 +    [ 21 ] = 'Y',
  20.481 +    [ 22 ] = 'U',
  20.482 +    [ 23 ] = 'I',
  20.483 +    [ 24 ] = 'O',
  20.484 +    [ 25 ] = 'P',
  20.485 +    [ 26 ] = '{',
  20.486 +    [ 27 ] = '}',
  20.487 +    [ 28 ] = '\n',
  20.488 +
  20.489 +    [ 30 ] = 'A',
  20.490 +    [ 31 ] = 'S',
  20.491 +    [ 32 ] = 'D',
  20.492 +    [ 33 ] = 'F',
  20.493 +    [ 34 ] = 'G',
  20.494 +    [ 35 ] = 'H',
  20.495 +    [ 36 ] = 'J',
  20.496 +    [ 37 ] = 'K',
  20.497 +    [ 38 ] = 'L',
  20.498 +    [ 39 ] = ':',
  20.499 +    [ 40 ] = '"',
  20.500 +    [ 41 ] = '~',
  20.501 +
  20.502 +    [ 43 ] = '|',
  20.503 +    [ 44 ] = 'Z',
  20.504 +    [ 45 ] = 'X',
  20.505 +    [ 46 ] = 'C',
  20.506 +    [ 47 ] = 'V',
  20.507 +    [ 48 ] = 'B',
  20.508 +    [ 49 ] = 'N',
  20.509 +    [ 50 ] = 'M',
  20.510 +    [ 51 ] = '<',
  20.511 +    [ 52 ] = '>',
  20.512 +    [ 53 ] = '?',
  20.513 +
  20.514 +    [ 55 ] = '*',
  20.515 +    [ 57 ] = ' ',
  20.516 +
  20.517 +    [ 71 ] = '7',
  20.518 +    [ 72 ] = '8',
  20.519 +    [ 73 ] = '9',
  20.520 +    [ 74 ] = '-',
  20.521 +    [ 75 ] = '4',
  20.522 +    [ 76 ] = '5',
  20.523 +    [ 77 ] = '6',
  20.524 +    [ 78 ] = '+',
  20.525 +    [ 79 ] = '1',
  20.526 +    [ 80 ] = '2',
  20.527 +    [ 81 ] = '3',
  20.528 +    [ 82 ] = '0',
  20.529 +    [ 83 ] = '.',
  20.530 +
  20.531 +    [ 86 ] = '>',
  20.532 +
  20.533 +    [ 96 ] = '\n',
  20.534 +
  20.535 +    [ 98 ] = '/',
  20.536 +
  20.537 +    [ 102 ] = 1,  /* home */
  20.538 +    [ 103 ] = 16, /* up */
  20.539 +    [ 104 ] = 7,  /* page up */
  20.540 +    [ 105 ] = 2,  /* left */
  20.541 +    [ 106 ] = 6,  /* right */
  20.542 +    [ 107 ] = 5,  /* end */
  20.543 +    [ 108 ] = 14, /* down */
  20.544 +    [ 109 ] = 3,  /* page down */
  20.545 +
  20.546 +    [ 111 ] = 4,  /* delete */
  20.547 +};
  20.548 +
  20.549 +int console_getkey (void)
  20.550 +{
  20.551 +    static int shift, control, alt, caps_lock;
  20.552 +
  20.553 +    if (!has_ev)
  20.554 +        has_ev = kbdfront_receive(kbd_dev, &ev, 1);
  20.555 +    if (!has_ev)
  20.556 +        return 0;
  20.557 +
  20.558 +    has_ev = 0;
  20.559 +    if (ev.type != XENKBD_TYPE_KEY)
  20.560 +        return 0;
  20.561 +
  20.562 +    if (ev.key.keycode == 42 || ev.key.keycode == 54) {
  20.563 +        caps_lock = 0;
  20.564 +        shift = ev.key.pressed;
  20.565 +        return 0;
  20.566 +    }
  20.567 +    if (ev.key.keycode == 58) {
  20.568 +        caps_lock ^= 1;
  20.569 +        return 0;
  20.570 +    }
  20.571 +    if (ev.key.keycode == 29 || ev.key.keycode == 97) {
  20.572 +        control = ev.key.pressed;
  20.573 +        return 0;
  20.574 +    }
  20.575 +    if (ev.key.keycode == 56) {
  20.576 +        alt = ev.key.pressed;
  20.577 +        return 0;
  20.578 +    }
  20.579 +
  20.580 +    if (!ev.key.pressed)
  20.581 +        return 0;
  20.582 +
  20.583 +    if (ev.key.keycode < sizeof(linux2ascii) / sizeof(*linux2ascii)) {
  20.584 +        char val;
  20.585 +        if (shift || caps_lock)
  20.586 +            val = linux2ascii_shifted[ev.key.keycode];
  20.587 +        else
  20.588 +            val = linux2ascii[ev.key.keycode];
  20.589 +        if (control)
  20.590 +            val &= ~0x60;
  20.591 +        return val;
  20.592 +    }
  20.593 +
  20.594 +    return 0;
  20.595 +}
  20.596 +
  20.597 +static void kbd_thread(void *p)
  20.598 +{
  20.599 +    struct semaphore *sem = p;
  20.600 +
  20.601 +    kbd_dev = init_kbdfront(NULL, 1);
  20.602 +    up(sem);
  20.603 +}
  20.604 +
  20.605 +struct fbfront_dev *fb_open(void *fb, int width, int height, int depth)
  20.606 +{
  20.607 +    unsigned long *mfns;
  20.608 +    int linesize = width * (depth / 8);
  20.609 +    int memsize = linesize * height;
  20.610 +    int numpages = (memsize + PAGE_SIZE - 1) / PAGE_SIZE;
  20.611 +    DECLARE_MUTEX_LOCKED(sem);
  20.612 +    int i;
  20.613 +
  20.614 +    create_thread("kbdfront", kbd_thread, &sem);
  20.615 +
  20.616 +    mfns = malloc(numpages * sizeof(*mfns));
  20.617 +    for (i = 0; i < numpages; i++) {
  20.618 +        memset(fb + i * PAGE_SIZE, 0, PAGE_SIZE);
  20.619 +        mfns[i] = virtual_to_mfn(fb + i * PAGE_SIZE);
  20.620 +    }
  20.621 +    fb_dev = init_fbfront(NULL, mfns, width, height, depth, linesize, numpages);
  20.622 +    free(mfns);
  20.623 +
  20.624 +    if (!fb_dev)
  20.625 +        return NULL;
  20.626 +
  20.627 +    down(&sem);
  20.628 +    if (!kbd_dev)
  20.629 +        return NULL;
  20.630 +
  20.631 +    return fb_dev;
  20.632 +}
  20.633 +
  20.634 +void kbd_close(void *foo)
  20.635 +{
  20.636 +    shutdown_kbdfront(kbd_dev);
  20.637 +    kbd_dev = NULL;
  20.638 +}
  20.639 +
  20.640 +void fb_close(void)
  20.641 +{
  20.642 +    create_thread("kbdfront close", kbd_close, NULL);
  20.643 +    shutdown_fbfront(fb_dev);
  20.644 +    fb_dev = NULL;
  20.645 +}
  20.646 +
  20.647 +/*
  20.648 + * Misc
  20.649 + */
  20.650 +
  20.651 +int getrtsecs (void)
  20.652 +{
  20.653 +    struct timeval tv;
  20.654 +    gettimeofday(&tv, NULL);
  20.655 +    return tv.tv_sec;
  20.656 +}
  20.657 +
  20.658 +int currticks (void)
  20.659 +{
  20.660 +    struct timeval tv;
  20.661 +    gettimeofday(&tv, NULL);
  20.662 +    return ((tv.tv_sec * 1000000ULL + tv.tv_usec) * TICKS_PER_SEC) / 1000000;
  20.663 +}
  20.664 +
  20.665 +void __attribute__ ((noreturn)) grub_reboot (void)
  20.666 +{
  20.667 +    for ( ;; )
  20.668 +    {
  20.669 +        struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_reboot };
  20.670 +        HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
  20.671 +    }
  20.672 +}
  20.673 +
  20.674 +#define SCRATCH_MEMSIZE (4 * 1024 * 1024)
  20.675 +
  20.676 +/* Note: not allocating it dynamically permits to make sure it lays below 4G
  20.677 + * for grub's 32bit pointers to work */
  20.678 +char grub_scratch_mem[SCRATCH_MEMSIZE] __attribute__((aligned(PAGE_SIZE)));
  20.679 +
  20.680 +int main(int argc, char *argv[])
  20.681 +{
  20.682 +    if (argc > 1) {
  20.683 +        strncpy(config_file, argv[1], sizeof(config_file) - 1);
  20.684 +        config_file[sizeof(config_file) - 1] = 0;
  20.685 +        if (!strncmp(config_file, "(nd)", 4))
  20.686 +            preset_menu = "dhcp";
  20.687 +    } else
  20.688 +        preset_menu = "dhcp --with-configfile";
  20.689 +
  20.690 +    mbi.drives_addr = BOOTSEC_LOCATION + (60 * 1024);
  20.691 +    mbi.drives_length = 0;
  20.692 +
  20.693 +    mbi.boot_loader_name = (unsigned long) "GNU GRUB " VERSION;
  20.694 +    mbi.mem_lower = (start_info.nr_pages * PAGE_SIZE) / 1024;
  20.695 +    mbi.mem_upper = 0;
  20.696 +    saved_drive = boot_drive;
  20.697 +    saved_partition = install_partition;
  20.698 +
  20.699 +    init_disk();
  20.700 +
  20.701 +    /* Try to make sure the client part got launched */
  20.702 +    sleep(1);
  20.703 +    cmain();
  20.704 +    printk("cmain returned!\n");
  20.705 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/stubdom/grub/mini-os.h	Wed Jun 18 09:36:47 2008 +0100
    21.3 @@ -0,0 +1,5 @@
    21.4 +extern int blk_nb;
    21.5 +extern struct blkfront_dev **blk_dev;
    21.6 +extern struct netfront_dev *net_dev;
    21.7 +extern struct kbdfront_dev *kbd_dev;
    21.8 +extern struct fbfront_dev *fb_dev;
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/stubdom/grub/osdep.h	Wed Jun 18 09:36:47 2008 +0100
    22.3 @@ -0,0 +1,30 @@
    22.4 +#ifndef __OSDEP_H__
    22.5 +#define __OSDEP_H__
    22.6 +
    22.7 +#include <byteswap.h>
    22.8 +#define swap32(x) bswap_32(x)
    22.9 +#define swap16(x) bswap_16(x)
   22.10 +
   22.11 +#include <machine/endian.h>
   22.12 +#if BYTE_ORDER == BIG_ENDIAN
   22.13 +#define htons(x) (x)
   22.14 +#define ntohs(x) (x)
   22.15 +#define htonl(x) (x)
   22.16 +#define ntohl(x) (x)
   22.17 +#else
   22.18 +#define htons(x) swap16(x)
   22.19 +#define ntohs(x) swap16(x)
   22.20 +#define htonl(x) swap32(x)
   22.21 +#define ntohl(x) swap32(x)
   22.22 +#endif
   22.23 +
   22.24 +typedef unsigned long Address;
   22.25 +
   22.26 +/* ANSI prototyping macro */
   22.27 +#ifdef  __STDC__
   22.28 +#define P(x)	x
   22.29 +#else
   22.30 +#define P(x)	()
   22.31 +#endif
   22.32 +
   22.33 +#endif
    23.1 --- a/tools/libxc/xc_dom.h	Wed Jun 18 09:35:06 2008 +0100
    23.2 +++ b/tools/libxc/xc_dom.h	Wed Jun 18 09:36:47 2008 +0100
    23.3 @@ -107,6 +107,8 @@ struct xc_dom_image {
    23.4  
    23.5      /* kernel loader */
    23.6      struct xc_dom_arch *arch_hooks;
    23.7 +    /* allocate up to virt_alloc_end */
    23.8 +    int (*allocate) (struct xc_dom_image * dom, xen_vaddr_t up_to);
    23.9  };
   23.10  
   23.11  /* --- pluggable kernel loader ------------------------------------- */
   23.12 @@ -167,6 +169,7 @@ int xc_dom_ramdisk_mem(struct xc_dom_ima
   23.13                         size_t memsize);
   23.14  
   23.15  int xc_dom_parse_image(struct xc_dom_image *dom);
   23.16 +struct xc_dom_arch *xc_dom_find_arch_hooks(char *guest_type);
   23.17  int xc_dom_build_image(struct xc_dom_image *dom);
   23.18  int xc_dom_update_guest_p2m(struct xc_dom_image *dom);
   23.19  
    24.1 --- a/tools/libxc/xc_dom_core.c	Wed Jun 18 09:35:06 2008 +0100
    24.2 +++ b/tools/libxc/xc_dom_core.c	Wed Jun 18 09:36:47 2008 +0100
    24.3 @@ -409,6 +409,8 @@ int xc_dom_alloc_segment(struct xc_dom_i
    24.4      seg->vend = start + pages * page_size;
    24.5      seg->pfn = (seg->vstart - dom->parms.virt_base) / page_size;
    24.6      dom->virt_alloc_end = seg->vend;
    24.7 +    if (dom->allocate)
    24.8 +        dom->allocate(dom, dom->virt_alloc_end);
    24.9  
   24.10      xc_dom_printf("%-20s:   %-12s : 0x%" PRIx64 " -> 0x%" PRIx64
   24.11                    "  (pfn 0x%" PRIpfn " + 0x%" PRIpfn " pages)\n",
   24.12 @@ -431,6 +433,8 @@ int xc_dom_alloc_page(struct xc_dom_imag
   24.13  
   24.14      start = dom->virt_alloc_end;
   24.15      dom->virt_alloc_end += page_size;
   24.16 +    if (dom->allocate)
   24.17 +        dom->allocate(dom, dom->virt_alloc_end);
   24.18      pfn = (start - dom->parms.virt_base) / page_size;
   24.19  
   24.20      xc_dom_printf("%-20s:   %-12s : 0x%" PRIx64 " (pfn 0x%" PRIpfn ")\n",
   24.21 @@ -506,7 +510,7 @@ void xc_dom_register_arch_hooks(struct x
   24.22      first_hook = hooks;
   24.23  }
   24.24  
   24.25 -static struct xc_dom_arch *xc_dom_find_arch_hooks(char *guest_type)
   24.26 +struct xc_dom_arch *xc_dom_find_arch_hooks(char *guest_type)
   24.27  {
   24.28      struct xc_dom_arch *hooks = first_hook;
   24.29