debuggers.hg
changeset 17909: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>
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>
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