diff -Naur grub-0.96.1-orig/config.h.in grub-0.96.1/config.h.in
--- grub-0.96.1-orig/config.h.in	2005-02-23 15:06:00.000000000 +0200
+++ grub-0.96.1/config.h.in	2005-02-23 15:17:33.000000000 +0200
@@ -27,9 +27,16 @@
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
+/* Define to 1 if you have the `aal-minimal' library (-laal-minimal). */
+#undef HAVE_LIBAAL_MINIMAL
+
 /* Define if you have a curses library */
 #undef HAVE_LIBCURSES
 
+/* Define to 1 if you have the `reiser4-minimal' library (-lreiser4-minimal).
+   */
+#undef HAVE_LIBREISER4_MINIMAL
+
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
diff -Naur grub-0.96.1-orig/configure.ac grub-0.96.1/configure.ac
--- grub-0.96.1-orig/configure.ac	2005-02-23 15:06:00.000000000 +0200
+++ grub-0.96.1/configure.ac	2005-02-23 15:17:40.000000000 +0200
@@ -263,6 +263,77 @@
   FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_REISERFS=1"
 fi
 
+dnl Checking for reiser4
+REISER4_LIBS=""
+REISER4_CFLAGS=""
+
+OLD_LIBS=$LIBS
+OLD_CFLAGS=$CFLAGS
+LIBS=""
+CFLAGS=""
+
+AC_ARG_ENABLE(reiser4,
+  [  --disable-reiser4       disable Reiser4 support in Stage 2])
+
+if test x"$enable_reiser4" != xno; then
+  AC_CHECK_LIB(aal-minimal, aal_mem_init, , 
+    AC_MSG_WARN(
+Reiser4 support is disabled due to inability find libaal-minimal with 
+memory manager support turned on.)
+    enable_reiser4=no
+  )
+fi
+  
+if test x"$enable_reiser4" != xno; then
+  AC_CHECK_HEADER(aal/libaal.h, ,
+  AC_MSG_WARN(
+Libaal header files are not found. Reiser4 support is disabled
+  )
+  enable_reiser4=no)
+fi
+  
+if test x"$enable_reiser4" != xno; then
+  AC_CHECK_LIB(reiser4-minimal, reiser4_fs_open, , 
+  AC_MSG_WARN(
+Reiser4 support is disabled due to inability find valid libreiser4-minimal.)
+    enable_reiser4=no, 
+    -laal-minimal
+  )
+fi
+
+if test x"$enable_reiser4" != xno; then
+  AC_CHECK_HEADER(reiser4/libreiser4.h, ,
+  AC_MSG_WARN(
+Reiser4 header files are not found. Reiser4 support is disabled.
+  )
+  enable_reiser4=no)
+fi
+
+if test x"$enable_reiser4" != xno; then
+  REISER4_CFLAGS="$REISER4_CFLAGS -DFSYS_REISER4=1"
+  REISER4_LIBS=$LIBS
+fi
+
+if test x"$enable_reiser4" != xno; then
+  AC_CHECK_LIB(reiser4-minimal, __sym40_plug_init, 
+    REISER4_CFLAGS="$REISER4_CFLAGS -DENABLE_SYMLINKS=1",
+AC_MSG_WARN(Reiser4 symlinks support is disabled.), 
+    -laal-minimal
+  )
+fi
+
+LIBS=$OLD_LIBS
+CFLAGS=$OLD_CFLAGS
+
+if test x"$enable_reiser4" != xno; then
+  enable_reiser4_support=yes
+  FSYS_CFLAGS="$FSYS_CFLAGS $REISER4_CFLAGS"
+fi
+
+AC_SUBST(REISER4_LIBS)
+AC_SUBST(REISER4_CFLAGS)
+AM_CONDITIONAL(ENABLE_REISER4_SUPPORT, test x"$enable_reiser4" != xno)
+
 AC_ARG_ENABLE(vstafs,
   [  --disable-vstafs        disable VSTa FS support in Stage 2])
 
@@ -595,6 +666,11 @@
   [  --enable-diskless       enable diskless support])
 AM_CONDITIONAL(DISKLESS_SUPPORT, test "x$enable_diskless" = xyes)
 
+dnl Graphical splashscreen support
+AC_ARG_ENABLE(graphics,
+  [  --disable-graphics      disable graphics terminal support])
+AM_CONDITIONAL(GRAPHICS_SUPPORT, test "x$enable_graphics" != xno)
+
 dnl Hercules terminal
 AC_ARG_ENABLE(hercules,
   [  --disable-hercules      disable hercules terminal support])
diff -Naur grub-0.96.1-orig/docs/grub.texi grub-0.96.1/docs/grub.texi
--- grub-0.96.1-orig/docs/grub.texi	2005-02-23 15:06:00.000000000 +0200
+++ grub-0.96.1/docs/grub.texi	2005-02-23 15:17:34.000000000 +0200
@@ -283,7 +283,7 @@
 Support multiple filesystem types transparently, plus a useful explicit
 blocklist notation. The currently supported filesystem types are
 @dfn{BSD FFS}, @dfn{DOS FAT16 and FAT32}, @dfn{Minix fs}, @dfn{Linux
-ext2fs}, @dfn{ReiserFS}, @dfn{JFS}, @dfn{XFS}, and @dfn{VSTa
+ext2fs}, @dfn{ReiserFS}, @dfn{ReiserFS}, @dfn{JFS}, @dfn{XFS}, and @dfn{VSTa
 fs}. @xref{Filesystem}, for more information.
 
 @item Support automatic decompression
@@ -1776,6 +1776,7 @@
 @itemx jfs_stage1_5
 @itemx minix_stage1_5
 @itemx reiserfs_stage1_5
+@itemx reiser4_stage1_5
 @itemx vstafs_stage1_5
 @itemx xfs_stage1_5
 
diff -Naur grub-0.96.1-orig/grub/Makefile.am grub-0.96.1/grub/Makefile.am
--- grub-0.96.1-orig/grub/Makefile.am	2005-02-23 15:06:00.000000000 +0200
+++ grub-0.96.1/grub/Makefile.am	2005-02-23 15:17:34.000000000 +0200
@@ -16,4 +16,4 @@
 AM_CFLAGS = $(GRUB_CFLAGS)
 
 grub_SOURCES = main.c asmstub.c
-grub_LDADD = ../stage2/libgrub.a  ../lib/libcommon.a $(GRUB_LIBS)
+grub_LDADD = ../stage2/libgrub.a  ../lib/libcommon.a $(GRUB_LIBS) $(REISER4_LIBS)
diff -Naur grub-0.96.1-orig/INSTALL grub-0.96.1/INSTALL
--- grub-0.96.1-orig/INSTALL	2005-02-23 15:06:00.000000000 +0200
+++ grub-0.96.1/INSTALL	2005-02-23 15:17:34.000000000 +0200
@@ -207,6 +207,9 @@
 `--disable-reiserfs'
      Omit the ReiserFS support in Stage 2.
 
+`--disable-reiser4'
+     Omit the Reiser4 support in Stage 2.
+
 `--disable-vstafs'
      Omit the VSTa filesystem support in Stage 2.
 
diff -Naur grub-0.96.1-orig/stage2/asm.S grub-0.96.1/stage2/asm.S
--- grub-0.96.1-orig/stage2/asm.S	2005-02-23 15:06:00.000000000 +0200
+++ grub-0.96.1/stage2/asm.S	2005-02-23 15:17:40.000000000 +0200
@@ -2216,6 +2216,156 @@
 	pop	%ebx
 	pop	%ebp
 	ret
+
+/* graphics mode functions */
+#ifdef SUPPORT_GRAPHICS
+VARIABLE(cursorX)
+.word	0
+VARIABLE(cursorY)
+.word	0
+VARIABLE(cursorCount)
+.word 0
+VARIABLE(cursorBuf)
+.byte	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+
+	
+/*
+ * int set_videomode(mode)
+ * BIOS call "INT 10H Function 0h" to set video mode
+ *	Call with	%ah = 0x0
+ *			%al = video mode
+ *      Returns old videomode.
+ */
+ENTRY(set_videomode)
+	push	%ebp
+	push	%ebx
+	push	%ecx
+
+	movb	0x10(%esp), %cl
+
+	call	EXT_C(prot_to_real)
+	.code16
+
+	xorw	%bx, %bx
+	movb	$0xf, %ah
+	int	$0x10			/* Get Current Video mode */
+	movb	%al, %ch
+	xorb	%ah, %ah
+	movb	%cl, %al
+        int	$0x10			/* Set Video mode */
+
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	xorb	%ah, %ah
+	movb	%ch, %al
+
+	pop	%ecx
+	pop	%ebx
+	pop	%ebp
+	ret
+
+
+/*
+ * unsigned char * graphics_get_font()
+ * BIOS call "INT 10H Function 11h" to set font
+ *      Call with       %ah = 0x11
+ */
+ENTRY(graphics_get_font)
+	push	%ebp
+	push	%ebx
+	push	%ecx
+	push	%edx
+
+	call	EXT_C(prot_to_real)
+	.code16
+
+	movw	$0x1130, %ax
+	movb	$6, %bh		/* font 8x16 */
+	int	$0x10
+	movw	%bp, %dx
+	movw	%es, %cx
+
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	xorl	%eax, %eax
+	movw	%cx, %ax
+	shll	$4, %eax
+	movw	%dx, %ax
+
+	pop	%edx
+	pop	%ecx
+	pop	%ebx
+	pop	%ebp
+	ret
+	
+
+	
+/*
+ * graphics_set_palette(index, red, green, blue)
+ * BIOS call "INT 10H Function 10h" to set individual dac register
+ *	Call with	%ah = 0x10
+ *			%bx = register number
+ *			%ch = new value for green (0-63)
+ *			%cl = new value for blue (0-63)
+ *			%dh = new value for red (0-63)
+ */
+
+ENTRY(graphics_set_palette)
+	push	%ebp
+	push	%eax
+	push	%ebx
+	push	%ecx
+	push	%edx
+
+	movw	$0x3c8, %bx		/* address write mode register */
+
+	/* wait vertical retrace */
+
+	movw	$0x3da, %dx
+l1b:	inb	%dx, %al	/* wait vertical active display */
+	test	$8, %al
+	jnz	l1b
+
+l2b:	inb	%dx, %al	/* wait vertical retrace */
+	test	$8, %al
+	jnz	l2b
+
+	mov	%bx, %dx
+	movb	0x18(%esp), %al		/* index */
+	outb	%al, %dx
+	inc	%dx
+
+	movb	0x1c(%esp), %al		/* red */
+	outb	%al, %dx
+
+	movb	0x20(%esp), %al		/* green */
+	outb	%al, %dx
+
+	movb	0x24(%esp), %al		/* blue */
+	outb	%al, %dx
+
+	movw	0x18(%esp), %bx
+
+	call	EXT_C(prot_to_real)
+	.code16
+
+	movb	%bl, %bh
+	movw	$0x1000, %ax
+	int	$0x10
+
+	DATA32	call	EXT_C(real_to_prot)
+	.code32	
+
+	pop	%edx
+	pop	%ecx
+	pop	%ebx
+	pop	%eax
+	pop	%ebp
+	ret
+
+#endif /* SUPPORT_GRAPHICS */
 		
 /*
  * getrtsecs()
diff -Naur grub-0.96.1-orig/stage2/builtins.c grub-0.96.1/stage2/builtins.c
--- grub-0.96.1-orig/stage2/builtins.c	2005-02-23 15:06:00.000000000 +0200
+++ grub-0.96.1/stage2/builtins.c	2005-02-23 15:17:41.000000000 +0200
@@ -852,6 +852,138 @@
 };
 #endif /* SUPPORT_NETBOOT */
 
+static int terminal_func (char *arg, int flags);
+
+#ifdef SUPPORT_GRAPHICS
+
+static int splashimage_func(char *arg, int flags) {
+    char splashimage[64];
+    int i;
+    
+    /* filename can only be 64 characters due to our buffer size */
+    if (strlen(arg) > 63)
+	return 1;
+    if (flags == BUILTIN_CMDLINE) {
+	if (!grub_open(arg))
+	    return 1;
+	grub_close();
+    }
+
+    strcpy(splashimage, arg);
+
+    /* get rid of TERM_NEED_INIT from the graphics terminal. */
+    for (i = 0; term_table[i].name; i++) {
+	if (grub_strcmp (term_table[i].name, "graphics") == 0) {
+	    term_table[i].flags &= ~TERM_NEED_INIT;
+	    break;
+	}
+    }
+    
+    graphics_set_splash(splashimage);
+
+    if (flags == BUILTIN_CMDLINE && graphics_inited) {
+	graphics_end();
+	graphics_init();
+	graphics_cls();
+    }
+
+    /* FIXME: should we be explicitly switching the terminal as a 
+     * side effect here? */
+    terminal_func("graphics", flags);
+
+    return 0;
+}
+
+static struct builtin builtin_splashimage =
+{
+  "splashimage",
+  splashimage_func,
+  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
+  "splashimage FILE",
+  "Load FILE as the background image when in graphics mode."
+};
+
+
+/* foreground */
+static int
+foreground_func(char *arg, int flags)
+{
+    if (grub_strlen(arg) == 6) {
+	int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
+	int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
+	int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
+
+	foreground = (r << 16) | (g << 8) | b;
+	if (graphics_inited)
+	    graphics_set_palette(15, r, g, b);
+
+	return (0);
+    }
+
+    return (1);
+}
+
+static struct builtin builtin_foreground =
+{
+  "foreground",
+  foreground_func,
+  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
+  "foreground RRGGBB",
+  "Sets the foreground color when in graphics mode."
+  "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
+};
+
+
+/* background */
+static int
+background_func(char *arg, int flags)
+{
+    if (grub_strlen(arg) == 6) {
+	int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
+	int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
+	int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
+
+	background = (r << 16) | (g << 8) | b;
+	if (graphics_inited)
+	    graphics_set_palette(0, r, g, b);
+	return (0);
+    }
+
+    return (1);
+}
+
+static struct builtin builtin_background =
+{
+  "background",
+  background_func,
+  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
+  "background RRGGBB",
+  "Sets the background color when in graphics mode."
+  "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
+};
+
+#endif /* SUPPORT_GRAPHICS */
+
+
+/* clear */
+static int 
+clear_func() 
+{
+  if (current_term->cls)
+    current_term->cls();
+
+  return 0;
+}
+
+static struct builtin builtin_clear =
+{
+  "clear",
+  clear_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "clear",
+  "Clear the screen"
+};
+
 
 /* displayapm */
 static int
@@ -3880,6 +4012,7 @@
     {"jfs",      "/jfs_stage1_5"},
     {"minix",    "/minix_stage1_5"},
     {"reiserfs", "/reiserfs_stage1_5"},
+    {"reiser4",  "/reiser4_stage1_5"},
     {"vstafs",   "/vstafs_stage1_5"},
     {"xfs",      "/xfs_stage1_5"}
   };
@@ -4085,7 +4218,7 @@
 };
 
 
-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
+#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
 /* terminal */
 static int
 terminal_func (char *arg, int flags)
@@ -4244,17 +4377,21 @@
  end:
   current_term = term_table + default_term;
   current_term->flags = term_flags;
-  
+
   if (lines)
     max_lines = lines;
   else
-    /* 24 would be a good default value.  */
-    max_lines = 24;
-  
+    max_lines = current_term->max_lines;
+
   /* If the interface is currently the command-line,
      restart it to repaint the screen.  */
-  if (current_term != prev_term && (flags & BUILTIN_CMDLINE))
+  if ((current_term != prev_term) && (flags & BUILTIN_CMDLINE)){
+    if (prev_term->shutdown)
+      prev_term->shutdown();
+    if (current_term->startup)
+      current_term->startup();
     grub_longjmp (restart_cmdline_env, 0);
+  }
   
   return 0;
 }
@@ -4264,7 +4401,7 @@
   "terminal",
   terminal_func,
   BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
-  "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules]",
+  "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules] [graphics]",
   "Select a terminal. When multiple terminals are specified, wait until"
   " you push any key to continue. If both console and serial are specified,"
   " the terminal to which you input a key first will be selected. If no"
@@ -4276,7 +4413,7 @@
   " seconds. The option --lines specifies the maximum number of lines."
   " The option --silent is used to suppress messages."
 };
-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
+#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
 
 
 #ifdef SUPPORT_SERIAL
@@ -4795,6 +4932,9 @@
 /* The table of builtin commands. Sorted in dictionary order.  */
 struct builtin *builtin_table[] =
 {
+#ifdef SUPPORT_GRAPHICS
+  &builtin_background,
+#endif
   &builtin_blocklist,
   &builtin_boot,
 #ifdef SUPPORT_NETBOOT
@@ -4802,6 +4942,7 @@
 #endif /* SUPPORT_NETBOOT */
   &builtin_cat,
   &builtin_chainloader,
+  &builtin_clear,
   &builtin_cmp,
   &builtin_color,
   &builtin_configfile,
@@ -4821,6 +4962,9 @@
   &builtin_embed,
   &builtin_fallback,
   &builtin_find,
+#ifdef SUPPORT_GRAPHICS
+  &builtin_foreground,
+#endif
   &builtin_fstest,
   &builtin_geometry,
   &builtin_halt,
@@ -4864,9 +5008,12 @@
 #endif /* SUPPORT_SERIAL */
   &builtin_setkey,
   &builtin_setup,
-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
+#ifdef SUPPORT_GRAPHICS
+  &builtin_splashimage,
+#endif /* SUPPORT_GRAPHICS */
+#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
   &builtin_terminal,
-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
+#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
 #ifdef SUPPORT_SERIAL
   &builtin_terminfo,
 #endif /* SUPPORT_SERIAL */
diff -Naur grub-0.96.1-orig/stage2/char_io.c grub-0.96.1/stage2/char_io.c
--- grub-0.96.1-orig/stage2/char_io.c	2005-02-23 15:06:00.000000000 +0200
+++ grub-0.96.1/stage2/char_io.c	2005-02-23 15:17:41.000000000 +0200
@@ -35,6 +35,7 @@
     {
       "console",
       0,
+      24,
       console_putchar,
       console_checkkey,
       console_getkey,
@@ -43,13 +44,16 @@
       console_cls,
       console_setcolorstate,
       console_setcolor,
-      console_setcursor
+      console_setcursor,
+      0, 
+      0
     },
 #ifdef SUPPORT_SERIAL
     {
       "serial",
       /* A serial device must be initialized.  */
       TERM_NEED_INIT,
+      24,
       serial_putchar,
       serial_checkkey,
       serial_getkey,
@@ -58,6 +62,8 @@
       serial_cls,
       serial_setcolorstate,
       0,
+      0,
+      0, 
       0
     },
 #endif /* SUPPORT_SERIAL */
@@ -65,6 +71,7 @@
     {
       "hercules",
       0,
+      24,
       hercules_putchar,
       console_checkkey,
       console_getkey,
@@ -73,9 +80,28 @@
       hercules_cls,
       hercules_setcolorstate,
       hercules_setcolor,
-      hercules_setcursor
+      hercules_setcursor,
+      0,
+      0
     },      
 #endif /* SUPPORT_HERCULES */
+#ifdef SUPPORT_GRAPHICS
+    { "graphics",
+      TERM_NEED_INIT, /* flags */
+      30, /* number of lines */
+      graphics_putchar, /* putchar */
+      console_checkkey, /* checkkey */
+      console_getkey, /* getkey */
+      graphics_getxy, /* getxy */
+      graphics_gotoxy, /* gotoxy */
+      graphics_cls, /* cls */
+      graphics_setcolorstate, /* setcolorstate */
+      graphics_setcolor, /* setcolor */
+      graphics_setcursor, /* nocursor */
+      graphics_init, /* initialize */
+      graphics_end /* shutdown */
+    },
+#endif /* SUPPORT_GRAPHICS */
     /* This must be the last entry.  */
     { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
   };
@@ -1046,13 +1072,15 @@
 		 the following grub_printf call will print newlines.  */
 	      count_lines = -1;
 
+	      grub_printf("\n");
 	      if (current_term->setcolorstate)
 		current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
 	      
-	      grub_printf ("\n[Hit return to continue]");
+	      grub_printf ("[Hit return to continue]");
 
 	      if (current_term->setcolorstate)
 		current_term->setcolorstate (COLOR_STATE_NORMAL);
+	        
 	      
 	      do
 		{
@@ -1090,7 +1118,7 @@
 cls (void)
 {
   /* If the terminal is dumb, there is no way to clean the terminal.  */
-  if (current_term->flags & TERM_DUMB)
+  if (current_term->flags & TERM_DUMB) 
     grub_putchar ('\n');
   else
     current_term->cls ();
@@ -1217,6 +1245,16 @@
   return ! errnum;
 }
 
+void
+grub_memcpy(void *dest, const void *src, int len)
+{
+  int i;
+  register char *d = (char*)dest, *s = (char*)src;
+
+  for (i = 0; i < len; i++)
+    d[i] = s[i];
+}
+
 void *
 grub_memmove (void *to, const void *from, int len)
 {
diff -Naur grub-0.96.1-orig/stage2/disk_io.c grub-0.96.1/stage2/disk_io.c
--- grub-0.96.1-orig/stage2/disk_io.c	2005-02-23 15:06:00.000000000 +0200
+++ grub-0.96.1/stage2/disk_io.c	2005-02-23 15:17:34.000000000 +0200
@@ -63,6 +63,9 @@
 # ifdef FSYS_REISERFS
   {"reiserfs", reiserfs_mount, reiserfs_read, reiserfs_dir, 0, reiserfs_embed},
 # endif
+# ifdef FSYS_REISER4
+  {"reiser4", reiser4_mount, reiser4_read, reiser4_dir, 0, reiser4_embed},
+# endif
 # ifdef FSYS_VSTAFS
   {"vstafs", vstafs_mount, vstafs_read, vstafs_dir, 0, 0},
 # endif
diff -Naur grub-0.96.1-orig/stage2/filesys.h grub-0.96.1/stage2/filesys.h
--- grub-0.96.1-orig/stage2/filesys.h	2005-02-23 15:06:00.000000000 +0200
+++ grub-0.96.1/stage2/filesys.h	2005-02-23 15:17:34.000000000 +0200
@@ -77,6 +77,16 @@
 #define FSYS_REISERFS_NUM 0
 #endif
 
+#ifdef FSYS_REISER4
+#define FSYS_REISER4_NUM 1
+int reiser4_mount (void);
+int reiser4_read (char *buf, int len);
+int reiser4_dir (char *dirname);
+int reiser4_embed (int *start_sector, int needed_sectors);
+#else
+#define FSYS_REISER4_NUM 0
+#endif
+
 #ifdef FSYS_VSTAFS
 #define FSYS_VSTAFS_NUM 1
 int vstafs_mount (void);
@@ -127,8 +137,8 @@
 #ifndef NUM_FSYS
 #define NUM_FSYS	\
   (FSYS_FFS_NUM + FSYS_FAT_NUM + FSYS_EXT2FS_NUM + FSYS_MINIX_NUM	\
-   + FSYS_REISERFS_NUM + FSYS_VSTAFS_NUM + FSYS_JFS_NUM + FSYS_XFS_NUM	\
-   + FSYS_TFTP_NUM + FSYS_ISO9660_NUM + FSYS_UFS2_NUM)
+   + FSYS_REISERFS_NUM + FSYS_REISER4_NUM + FSYS_VSTAFS_NUM + FSYS_JFS_NUM \
+   + FSYS_XFS_NUM + FSYS_TFTP_NUM + FSYS_ISO9660_NUM + FSYS_UFS2_NUM)
 #endif
 
 /* defines for the block filesystem info area */
diff -Naur grub-0.96.1-orig/stage2/fsys_reiser4.c grub-0.96.1/stage2/fsys_reiser4.c
--- grub-0.96.1-orig/stage2/fsys_reiser4.c	1970-01-01 02:00:00.000000000 +0200
+++ grub-0.96.1/stage2/fsys_reiser4.c	2005-02-23 15:17:34.000000000 +0200
@@ -0,0 +1,260 @@
+/* 
+ *  fsys_reiser4.c -- reiser4 filesystem support.
+ *  Copyright (C) 2000, 2001   Free Software Foundation, Inc.
+ *  
+ *  GRUB  --  GRand Unified Bootloader
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifdef FSYS_REISER4
+#include "shared.h"
+#include "filesys.h"
+
+#define ENABLE_MINIMAL
+#include <reiser4/libreiser4.h>
+
+static reiser4_fs_t *fs = NULL;
+static aal_device_t *dev = NULL;
+static reiser4_object_t *object = NULL;
+
+/* Read callback of grub specific device. It uses devread() for reading passed
+   @count of device blocks starting from @blk to passed @buff. */
+static errno_t grub_dev_read(aal_device_t *device,
+			     void *buff, blk_t blk,
+			     count_t count)
+{
+	unsigned int size;
+	unsigned int factor;
+	unsigned int sector;
+
+	/* Calculating actual sector and size in bytes to be read from
+	   device. */
+	factor = device->blksize / SECTOR_SIZE;
+	sector = (unsigned int)blk << aal_log2(factor);
+	size = (unsigned int)count * (SECTOR_SIZE * factor);
+	
+	/* Reading from the current device */
+        if (!devread(sector, 0, size, buff))
+    	        return -EIO;
+		
+	return 0;
+}
+
+/* Length callback of grub device */
+static count_t grub_dev_len(aal_device_t *device) {
+	unsigned int factor;
+
+	/* Getting partition length in device blocks */
+	factor = device->blksize / SECTOR_SIZE;
+	return (part_length >> aal_log2(factor));
+}
+
+/*
+  Initializing grub device abstraction instance. It will use devread and friends
+  for providing needed functionality.
+*/
+struct aal_device_ops grub_dev_ops = {
+	.read   = grub_dev_read,
+	.len    = grub_dev_len
+};
+
+/* Initializes reiser4 */
+static int reiser4_init(void) {
+	extern aal_hash_table_t *plugins;
+	
+	plugins = NULL;
+
+	/* Initializing memory manager */
+	aal_mem_init((void *)FSYS_BUF, FSYS_BUFLEN);
+
+	/* Initializing device abstraction on current device GRUB uses. */
+	if (!(dev = aal_device_open(&grub_dev_ops, NULL,
+				    SECTOR_SIZE, 0)))
+	{
+		return 0;
+	}
+
+	/* Initializing libreiser4 (plugins, etc) */
+	return !libreiser4_init();
+}
+
+#define MEMORY_WATERMARK 8192
+
+/* Memory pressure detect function. */
+static int mpressure_detect(reiser4_tree_t *tree) {
+	return (aal_mem_free() <= MEMORY_WATERMARK);
+}
+
+/* Reiser4 mount() routine */
+int reiser4_mount(void) {
+	
+	/* Initialize all reiser4 related stuff first */
+	if (!reiser4_init())
+		return 0;
+	
+	/* Open filesystem on @dev. */
+	if (!(fs = reiser4_fs_open(dev)))
+		return 0;
+
+	fs->tree->mpc_func = mpressure_detect;
+	
+	object = NULL;
+	return 1;
+}
+
+/* Reiser4 read() handler */
+int reiser4_read(char *buf, int len) {
+	int64_t read;
+
+	if (object == NULL)
+		return 0;
+
+	/* Seet at current position denoted by @filepos */
+	if (objplug(object)->o.object_ops->seek) {
+		plug_call(objplug(object)->o.object_ops,
+			  seek, object->ent, filepos);
+	}
+	
+	/* Reading current file data starting from @filepos */
+	disk_read_func = disk_read_hook;
+	read = objplug(object)->o.object_ops->read ?
+		plug_call(objplug(object)->o.object_ops, read, 
+			  object->ent, buf, len) : -EINVAL;
+	disk_read_func = NULL;
+
+	if (read < 0) {
+		errnum = ERR_FSYS_CORRUPT;
+		return 0;
+	}
+
+    	filepos += read;
+	return read;
+}
+
+/* Reiser4 file open() routine */
+int reiser4_dir(char *dirname) {
+	char *ch;
+	
+	if (fs == NULL)
+		return 0;
+
+	if (object != NULL) {
+		plug_call(objplug(object)->o.object_ops, 
+			  close, object->ent);
+		aal_free(object);
+		object = NULL;
+	}
+
+	/* Cutting out string after first space character */
+    	if ((ch = aal_strchr(dirname, ' ')))
+		*ch = '\0';
+		
+	/* This function is also called for getting directory list for
+	   maintaining the bash-like completion. */
+#ifndef STAGE1_5
+	if (print_possibilities) {
+		char entry[256];
+		entry_hint_t entry_hint;
+		
+		/* Getting last part of name (jsut after last '/') */
+		if (*(dirname + aal_strlen(dirname) - 1) != '/') {
+		
+			if (!(ch = aal_strrchr(dirname, '/'))) {
+				errnum = ERR_BAD_FILETYPE;
+				return 0;
+			}
+
+			aal_strncpy(entry, ch + 1, sizeof(entry));
+			*(ch + 1) = '\0';
+		} else {
+			aal_memset(entry, 0, sizeof(entry));
+		}
+
+		/* Open obejct by @dirname */
+		if (!(object = reiser4_semantic_open(fs->tree, dirname, 
+						     NULL, 1))) 
+		{
+			errnum = ERR_FILE_NOT_FOUND;
+			return 0;
+		}
+
+		/* Checking if it is a directory object */
+		if (object->ent->opset.plug[OPSET_OBJ]->id.group != DIR_OBJECT)
+		{
+			/* If not, cutting out last '/' character */
+    			if ((ch = aal_strrchr(dirname, '/')))
+				*ch = '\0';
+
+			/* Close current object */
+			plug_call(objplug(object)->o.object_ops, 
+				  close, object->ent);
+			aal_free(object);
+			return 0;
+		}
+		
+		/* Reading the opened directory to build the completion list. */
+		if (objplug(object)->o.object_ops->readdir) {
+			while (plug_call(objplug(object)->o.object_ops, readdir,
+					 object->ent, &entry_hint) > 0) 
+			{
+				if (substring(entry, entry_hint.name) <= 0) {
+					if (print_possibilities > 0)
+						print_possibilities = 
+							-print_possibilities;
+				
+					print_a_completion(entry_hint.name);
+				}
+			}
+		}
+	} else {
+#endif
+		/* This is the case when resier4_dir() is called for open the
+		   file @dirname, not for building completion list. */
+		if (!(object = reiser4_semantic_open(fs->tree, dirname,
+						     NULL, 1))) 
+		{
+			errnum = ERR_FILE_NOT_FOUND;
+			return 0;
+		}
+		
+		if (object->ent->opset.plug[OPSET_OBJ]->id.group != REG_OBJECT)
+		{
+			errnum = ERR_BAD_FILETYPE;
+			return 0;
+		}
+		
+		/* Initializing GRUB global variables @filepos and @filemax. */
+		filepos = 0;
+		filemax = reiser4_object_size(object);
+	
+		return 1;
+#ifndef STAGE1_5
+	}
+
+	return 1;
+#endif
+
+	errnum = ERR_FILE_NOT_FOUND;
+	return 0;
+}
+
+/* Returns how many sectors may be used for embeding reiser4_stage1_5 in teh
+   case of installing GRUB to partition instead of MBR. */
+int reiser4_embed (int *start_sector, int needed_sectors) {
+	*start_sector = 1;
+	return needed_sectors <= ((REISER4_MASTER_OFFSET >> SECTOR_BITS) - 1);
+}
+#endif /* FSYS_REISER4 */
diff -Naur grub-0.96.1-orig/stage2/graphics.c grub-0.96.1/stage2/graphics.c
--- grub-0.96.1-orig/stage2/graphics.c	1970-01-01 02:00:00.000000000 +0200
+++ grub-0.96.1/stage2/graphics.c	2005-02-23 15:17:41.000000000 +0200
@@ -0,0 +1,552 @@
+/* graphics.c - graphics mode support for GRUB */
+/* Implemented as a terminal type by Jeremy Katz <katzj@redhat.com> based
+ * on a patch by Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
+ */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2001,2002  Red Hat, Inc.
+ *  Portions copyright (C) 2000  Conectiva, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+
+#ifdef SUPPORT_GRAPHICS
+
+#include <term.h>
+#include <shared.h>
+#include <graphics.h>
+
+int saved_videomode;
+unsigned char *font8x16;
+
+int graphics_inited = 0;
+static char splashimage[64];
+
+#define VSHADOW VSHADOW1
+unsigned char VSHADOW1[38400];
+unsigned char VSHADOW2[38400];
+unsigned char VSHADOW4[38400];
+unsigned char VSHADOW8[38400];
+
+/* constants to define the viewable area */
+const int x0 = 0;
+const int x1 = 80;
+const int y0 = 0;
+const int y1 = 30;
+
+/* text buffer has to be kept around so that we can write things as we
+ * scroll and the like */
+unsigned short text[80 * 30];
+
+/* why do these have to be kept here? */
+int foreground = (63 << 16) | (63 << 8) | (63), background = 0, border = 0;
+
+/* current position */
+static int fontx = 0;
+static int fonty = 0;
+
+/* global state so that we don't try to recursively scroll or cursor */
+static int no_scroll = 0;
+
+/* color state */
+static int graphics_standard_color = A_NORMAL;
+static int graphics_normal_color = A_NORMAL;
+static int graphics_highlight_color = A_REVERSE;
+static int graphics_current_color = A_NORMAL;
+static color_state graphics_color_state = COLOR_STATE_STANDARD;
+
+
+/* graphics local functions */
+static void graphics_setxy(int col, int row);
+static void graphics_scroll();
+
+/* FIXME: where do these really belong? */
+static inline void outb(unsigned short port, unsigned char val)
+{
+    __asm __volatile ("outb %0,%1"::"a" (val), "d" (port));
+}
+
+static void MapMask(int value) {
+    outb(0x3c4, 2);
+    outb(0x3c5, value);
+}
+
+/* bit mask register */
+static void BitMask(int value) {
+    outb(0x3ce, 8);
+    outb(0x3cf, value);
+}
+
+
+
+/* Set the splash image */
+void graphics_set_splash(char *splashfile) {
+    grub_strcpy(splashimage, splashfile);
+}
+
+/* Get the current splash image */
+char *graphics_get_splash(void) {
+    return splashimage;
+}
+
+/* Initialize a vga16 graphics display with the palette based off of
+ * the image in splashimage.  If the image doesn't exist, leave graphics
+ * mode.  */
+int graphics_init()
+{
+    if (!graphics_inited) {
+        saved_videomode = set_videomode(0x12);
+    }
+
+    if (!read_image(splashimage)) {
+        set_videomode(saved_videomode);
+        grub_printf("failed to read image\n");
+        return 0;
+    }
+
+    font8x16 = (unsigned char*)graphics_get_font();
+
+    graphics_inited = 1;
+
+    /* make sure that the highlight color is set correctly */
+    graphics_highlight_color = ((graphics_normal_color >> 4) | 
+				((graphics_normal_color & 0xf) << 4));
+
+    return 1;
+}
+
+/* Leave graphics mode */
+void graphics_end(void)
+{
+    if (graphics_inited) {
+        set_videomode(saved_videomode);
+        graphics_inited = 0;
+    }
+}
+
+/* Print ch on the screen.  Handle any needed scrolling or the like */
+void graphics_putchar(int ch) {
+    ch &= 0xff;
+
+    graphics_cursor(0);
+
+    if (ch == '\n') {
+        if (fonty + 1 < y1)
+            graphics_setxy(fontx, fonty + 1);
+        else
+            graphics_scroll();
+        graphics_cursor(1);
+        return;
+    } else if (ch == '\r') {
+        graphics_setxy(x0, fonty);
+        graphics_cursor(1);
+        return;
+    }
+
+    graphics_cursor(0);
+
+    text[fonty * 80 + fontx] = ch;
+    text[fonty * 80 + fontx] &= 0x00ff;
+    if (graphics_current_color & 0xf0)
+        text[fonty * 80 + fontx] |= 0x100;
+
+    graphics_cursor(0);
+
+    if ((fontx + 1) >= x1) {
+        graphics_setxy(x0, fonty);
+        if (fonty + 1 < y1)
+            graphics_setxy(x0, fonty + 1);
+        else
+            graphics_scroll();
+    } else {
+        graphics_setxy(fontx + 1, fonty);
+    }
+
+    graphics_cursor(1);
+}
+
+/* get the current location of the cursor */
+int graphics_getxy(void) {
+    return (fontx << 8) | fonty;
+}
+
+void graphics_gotoxy(int x, int y) {
+    graphics_cursor(0);
+
+    graphics_setxy(x, y);
+
+    graphics_cursor(1);
+}
+
+void graphics_cls(void) {
+    int i;
+    unsigned char *mem, *s1, *s2, *s4, *s8;
+
+    graphics_cursor(0);
+    graphics_gotoxy(x0, y0);
+
+    mem = (unsigned char*)VIDEOMEM;
+    s1 = (unsigned char*)VSHADOW1;
+    s2 = (unsigned char*)VSHADOW2;
+    s4 = (unsigned char*)VSHADOW4;
+    s8 = (unsigned char*)VSHADOW8;
+
+    for (i = 0; i < 80 * 30; i++)
+        text[i] = ' ';
+    graphics_cursor(1);
+
+    BitMask(0xff);
+
+    /* plano 1 */
+    MapMask(1);
+    grub_memcpy(mem, s1, 38400);
+
+    /* plano 2 */
+    MapMask(2);
+    grub_memcpy(mem, s2, 38400);
+
+    /* plano 3 */
+    MapMask(4);
+    grub_memcpy(mem, s4, 38400);
+
+    /* plano 4 */
+    MapMask(8);
+    grub_memcpy(mem, s8, 38400);
+
+    MapMask(15);
+ 
+}
+
+void graphics_setcolorstate (color_state state) {
+    switch (state) {
+    case COLOR_STATE_STANDARD:
+        graphics_current_color = graphics_standard_color;
+        break;
+    case COLOR_STATE_NORMAL:
+        graphics_current_color = graphics_normal_color;
+        break;
+    case COLOR_STATE_HIGHLIGHT:
+        graphics_current_color = graphics_highlight_color;
+        break;
+    default:
+        graphics_current_color = graphics_standard_color;
+        break;
+    }
+
+    graphics_color_state = state;
+}
+
+void graphics_setcolor (int normal_color, int highlight_color) {
+    graphics_normal_color = normal_color;
+    graphics_highlight_color = highlight_color;
+
+    graphics_setcolorstate (graphics_color_state);
+}
+
+void graphics_setcursor (int on) {
+    /* FIXME: we don't have a cursor in graphics */
+    return;
+}
+
+/* Read in the splashscreen image and set the palette up appropriately.
+ * Format of splashscreen is an xpm (can be gzipped) with 16 colors and
+ * 640x480. */
+int read_image(char *s)
+{
+    char buf[32], pal[16];
+    unsigned char c, base, mask, *s1, *s2, *s4, *s8;
+    unsigned i, len, idx, colors, x, y, width, height;
+
+    if (!grub_open(s))
+        return 0;
+
+    /* read header */
+    if (!grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) {
+        grub_close();
+        return 0;
+    }
+    
+    /* parse info */
+    while (grub_read(&c, 1)) {
+        if (c == '"')
+            break;
+    }
+
+    while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
+        ;
+
+    i = 0;
+    width = c - '0';
+    while (grub_read(&c, 1)) {
+        if (c >= '0' && c <= '9')
+            width = width * 10 + c - '0';
+        else
+            break;
+    }
+    while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
+        ;
+
+    height = c - '0';
+    while (grub_read(&c, 1)) {
+        if (c >= '0' && c <= '9')
+            height = height * 10 + c - '0';
+        else
+            break;
+    }
+    while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
+        ;
+
+    colors = c - '0';
+    while (grub_read(&c, 1)) {
+        if (c >= '0' && c <= '9')
+            colors = colors * 10 + c - '0';
+        else
+            break;
+    }
+
+    base = 0;
+    while (grub_read(&c, 1) && c != '"')
+        ;
+
+    /* palette */
+    for (i = 0, idx = 1; i < colors; i++) {
+        len = 0;
+
+        while (grub_read(&c, 1) && c != '"')
+            ;
+        grub_read(&c, 1);       /* char */
+        base = c;
+        grub_read(buf, 4);      /* \t c # */
+
+        while (grub_read(&c, 1) && c != '"') {
+            if (len < sizeof(buf))
+                buf[len++] = c;
+        }
+
+        if (len == 6 && idx < 15) {
+            int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2;
+            int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2;
+            int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2;
+
+            pal[idx] = base;
+            graphics_set_palette(idx, r, g, b);
+            ++idx;
+        }
+    }
+
+    x = y = len = 0;
+
+    s1 = (unsigned char*)VSHADOW1;
+    s2 = (unsigned char*)VSHADOW2;
+    s4 = (unsigned char*)VSHADOW4;
+    s8 = (unsigned char*)VSHADOW8;
+
+    for (i = 0; i < 38400; i++)
+        s1[i] = s2[i] = s4[i] = s8[i] = 0;
+
+    /* parse xpm data */
+    while (y < height) {
+        while (1) {
+            if (!grub_read(&c, 1)) {
+                grub_close();
+                return 0;
+            }
+            if (c == '"')
+                break;
+        }
+
+        while (grub_read(&c, 1) && c != '"') {
+            for (i = 1; i < 15; i++)
+                if (pal[i] == c) {
+                    c = i;
+                    break;
+                }
+
+            mask = 0x80 >> (x & 7);
+            if (c & 1)
+                s1[len + (x >> 3)] |= mask;
+            if (c & 2)
+                s2[len + (x >> 3)] |= mask;
+            if (c & 4)
+                s4[len + (x >> 3)] |= mask;
+            if (c & 8)
+                s8[len + (x >> 3)] |= mask;
+
+            if (++x >= 640) {
+                x = 0;
+
+                if (y < 480)
+                    len += 80;
+                ++y;
+            }
+        }
+    }
+
+    grub_close();
+
+    graphics_set_palette(0, (background >> 16), (background >> 8) & 63, 
+                background & 63);
+    graphics_set_palette(15, (foreground >> 16), (foreground >> 8) & 63, 
+                foreground & 63);
+    graphics_set_palette(0x11, (border >> 16), (border >> 8) & 63, 
+                         border & 63);
+
+    return 1;
+}
+
+
+/* Convert a character which is a hex digit to the appropriate integer */
+int hex(int v)
+{
+    if (v >= 'A' && v <= 'F')
+        return (v - 'A' + 10);
+    if (v >= 'a' && v <= 'f')
+        return (v - 'a' + 10);
+    return (v - '0');
+}
+
+
+/* move the graphics cursor location to col, row */
+static void graphics_setxy(int col, int row) {
+    if (col >= x0 && col < x1) {
+        fontx = col;
+        cursorX = col << 3;
+    }
+    if (row >= y0 && row < y1) {
+        fonty = row;
+        cursorY = row << 4;
+    }
+}
+
+/* scroll the screen */
+static void graphics_scroll() {
+    int i, j;
+
+    /* we don't want to scroll recursively... that would be bad */
+    if (no_scroll)
+        return;
+    no_scroll = 1;
+
+    /* move everything up a line */
+    for (j = y0 + 1; j < y1; j++) {
+        graphics_gotoxy(x0, j - 1);
+        for (i = x0; i < x1; i++) {
+            graphics_putchar(text[j * 80 + i]);
+        }
+    }
+
+    /* last line should be blank */
+    graphics_gotoxy(x0, y1 - 1);
+    for (i = x0; i < x1; i++)
+        graphics_putchar(' ');
+    graphics_setxy(x0, y1 - 1);
+
+    no_scroll = 0;
+}
+
+
+void graphics_cursor(int set) {
+    unsigned char *pat, *mem, *ptr, chr[16 << 2];
+    int i, ch, invert, offset;
+
+    if (set && no_scroll)
+        return;
+
+    offset = cursorY * 80 + fontx;
+    ch = text[fonty * 80 + fontx] & 0xff;
+    invert = (text[fonty * 80 + fontx] & 0xff00) != 0;
+    pat = font8x16 + (ch << 4);
+
+    mem = (unsigned char*)VIDEOMEM + offset;
+
+    if (!set) {
+        for (i = 0; i < 16; i++) {
+            unsigned char mask = pat[i];
+
+            if (!invert) {
+                chr[i     ] = ((unsigned char*)VSHADOW1)[offset];
+                chr[16 + i] = ((unsigned char*)VSHADOW2)[offset];
+                chr[32 + i] = ((unsigned char*)VSHADOW4)[offset];
+                chr[48 + i] = ((unsigned char*)VSHADOW8)[offset];
+
+                /* FIXME: if (shade) */
+                if (1) {
+                    if (ch == DISP_VERT || ch == DISP_LL ||
+                        ch == DISP_UR || ch == DISP_LR) {
+                        unsigned char pmask = ~(pat[i] >> 1);
+
+                        chr[i     ] &= pmask;
+                        chr[16 + i] &= pmask;
+                        chr[32 + i] &= pmask;
+                        chr[48 + i] &= pmask;
+                    }
+                    if (i > 0 && ch != DISP_VERT) {
+                        unsigned char pmask = ~(pat[i - 1] >> 1);
+
+                        chr[i     ] &= pmask;
+                        chr[16 + i] &= pmask;
+                        chr[32 + i] &= pmask;
+                        chr[48 + i] &= pmask;
+                        if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) {
+                            pmask = ~pat[i - 1];
+
+                            chr[i     ] &= pmask;
+                            chr[16 + i] &= pmask;
+                            chr[32 + i] &= pmask;
+                            chr[48 + i] &= pmask;
+                        }
+                    }
+                }
+                chr[i     ] |= mask;
+                chr[16 + i] |= mask;
+                chr[32 + i] |= mask;
+                chr[48 + i] |= mask;
+
+                offset += 80;
+            }
+            else {
+                chr[i     ] = mask;
+                chr[16 + i] = mask;
+                chr[32 + i] = mask;
+                chr[48 + i] = mask;
+            }
+        }
+    }
+    else {
+        MapMask(15);
+        ptr = mem;
+        for (i = 0; i < 16; i++, ptr += 80) {
+            cursorBuf[i] = pat[i];
+            *ptr = ~pat[i];
+        }
+        return;
+    }
+
+    offset = 0;
+    for (i = 1; i < 16; i <<= 1, offset += 16) {
+        int j;
+
+        MapMask(i);
+        ptr = mem;
+        for (j = 0; j < 16; j++, ptr += 80)
+            *ptr = chr[j + offset];
+    }
+
+    MapMask(15);
+}
+
+#endif /* SUPPORT_GRAPHICS */
diff -Naur grub-0.96.1-orig/stage2/graphics.h grub-0.96.1/stage2/graphics.h
--- grub-0.96.1-orig/stage2/graphics.h	1970-01-01 02:00:00.000000000 +0200
+++ grub-0.96.1/stage2/graphics.h	2005-02-23 15:17:41.000000000 +0200
@@ -0,0 +1,42 @@
+/* graphics.h - graphics console interface */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002  Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef GRAPHICS_H
+#define GRAPHICS_H
+
+/* magic constant */
+#define VIDEOMEM 0xA0000
+
+/* function prototypes */
+char *graphics_get_splash(void);
+
+int read_image(char *s);
+void graphics_cursor(int set);
+
+/* function prototypes for asm functions */
+void * graphics_get_font();
+void graphics_set_palette(int idx, int red, int green, int blue);
+void set_int1c_handler();
+void unset_int1c_handler();
+
+extern short cursorX, cursorY;
+extern char cursorBuf[16];
+
+#endif /* GRAPHICS_H */
diff -Naur grub-0.96.1-orig/stage2/Makefile.am grub-0.96.1/stage2/Makefile.am
--- grub-0.96.1-orig/stage2/Makefile.am	2005-02-23 15:06:00.000000000 +0200
+++ grub-0.96.1/stage2/Makefile.am	2005-02-23 15:20:51.000000000 +0200
@@ -7,23 +7,32 @@
         fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \
 	imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \
 	nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \
-	terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h
+	terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h graphics.h
 EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS)
 
 # For <stage1.h>.
 INCLUDES = -I$(top_srcdir)/stage1
 
+if ENABLE_REISER4_SUPPORT
+REISER4_STAGE1_5 = reiser4_stage1_5
+REISER4_STAGE1_5_EXEC = reiser4_stage1_5.exec
+else
+REISER4_STAGE1_5 =
+REISER4_STAGE1_5_EXEC =
+endif
+
+
 # The library for /sbin/grub.
 noinst_LIBRARIES = libgrub.a
 libgrub_a_SOURCES = boot.c builtins.c char_io.c cmdline.c common.c \
 	disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \
-	fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \
+	fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_reiser4.c fsys_ufs2.c \
 	fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \
-	terminfo.c tparm.c
+	terminfo.c tparm.c graphics.c
 libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
 	-DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
 	-DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
-	-DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \
+	$(REISER4_CFLAGS) -DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \
 	-DUSE_MD5_PASSWORDS=1 -DSUPPORT_SERIAL=1 -DSUPPORT_HERCULES=1
 
 # Stage 2 and Stage 1.5's.
@@ -34,24 +43,26 @@
 if DISKLESS_SUPPORT
 pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
 	ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \
-	reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5 \
-	nbgrub pxegrub
+	reiserfs_stage1_5 $(REISER4_STAGE1_5) ufs2_stage1_5 \
+	vstafs_stage1_5 xfs_stage1_5 nbgrub pxegrub
 noinst_DATA = pre_stage2 start start_eltorito nbloader pxeloader diskless
 noinst_PROGRAMS = pre_stage2.exec start.exec start_eltorito.exec \
 	e2fs_stage1_5.exec fat_stage1_5.exec ffs_stage1_5.exec \
 	iso9660_stage1_5.exec jfs_stage1_5.exec minix_stage1_5.exec \
-	reiserfs_stage1_5.exec ufs2_stage1_5.exec vstafs_stage1_5.exec \
-	xfs_stage1_5.exec nbloader.exec pxeloader.exec diskless.exec
+	reiserfs_stage1_5.exec $(REISER4_STAGE1_5_EXEC) ufs2_stage1_5.exec \
+	vstafs_stage1_5.exec xfs_stage1_5.exec nbloader.exec pxeloader.exec \
+	diskless.exec
 else
 pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
 	ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \
-	reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5
+	reiserfs_stage1_5 $(REISER4_STAGE1_5) ufs2_stage1_5 \
+	vstafs_stage1_5 xfs_stage1_5
 noinst_DATA = pre_stage2 start start_eltorito
 noinst_PROGRAMS = pre_stage2.exec start.exec start_eltorito.exec \
 	e2fs_stage1_5.exec fat_stage1_5.exec ffs_stage1_5.exec \
 	iso9660_stage1_5.exec jfs_stage1_5.exec minix_stage1_5.exec \
-	reiserfs_stage1_5.exec ufs2_stage1_5.exec vstafs_stage1_5.exec \
-	xfs_stage1_5.exec
+	reiserfs_stage1_5.exec $(REISER4_STAGE1_5_EXEC) ufs2_stage1_5.exec \
+	vstafs_stage1_5.exec xfs_stage1_5.exec
 endif
 MOSTLYCLEANFILES = $(noinst_PROGRAMS)
 
@@ -79,8 +90,14 @@
 HERCULES_FLAGS =
 endif
 
-STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
-	$(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS)
+if GRAPHICS_SUPPORT
+GRAPHICS_FLAGS = -DSUPPORT_GRAPHICS=1
+else
+GRAPHICS_FLAGS =
+endif
+
+STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin \
+	$(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) $(GRAPHICS_FLAGS)
 
 STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
 STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1
@@ -89,14 +106,17 @@
 pre_stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c char_io.c \
 	cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
 	fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
-	fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \
-	hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c
+	fsys_reiserfs.c fsys_reiser4.c fsys_ufs2.c fsys_vstafs.c \
+	fsys_xfs.c gunzip.c hercules.c md5.c serial.c smp-imps.c \
+	stage2.c terminfo.c tparm.c graphics.c
 pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
 pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
 pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
 
 if NETBOOT_SUPPORT
-pre_stage2_exec_LDADD = ../netboot/libdrivers.a
+pre_stage2_exec_LDADD = ../netboot/libdrivers.a $(REISER4_LIBS)
+else
+pre_stage2_exec_LDADD = $(REISER4_LIBS)
 endif
 
 if DISKLESS_SUPPORT
@@ -190,6 +210,16 @@
 	-DNO_BLOCK_FILES=1
 reiserfs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
 
+# For reiser4_stage1_5 target.
+reiser4_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \
+	disk_io.c stage1_5.c fsys_reiser4.c bios.c
+reiser4_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) $(REISER4_CFLAGS) \
+	-DNO_BLOCK_FILES=1
+reiser4_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) $(REISER4_CFLAGS) \
+	-DNO_BLOCK_FILES=1
+reiser4_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+reiser4_stage1_5_exec_LDADD = $(REISER4_LIBS)
+
 # For vstafs_stage1_5 target.
 vstafs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \
 	disk_io.c stage1_5.c fsys_vstafs.c bios.c
diff -Naur grub-0.96.1-orig/stage2/shared.h grub-0.96.1/stage2/shared.h
--- grub-0.96.1-orig/stage2/shared.h	2005-02-23 15:06:00.000000000 +0200
+++ grub-0.96.1/stage2/shared.h	2005-02-23 15:17:41.000000000 +0200
@@ -207,11 +207,12 @@
 #define STAGE2_ID_FAT_STAGE1_5		3
 #define STAGE2_ID_MINIX_STAGE1_5	4
 #define STAGE2_ID_REISERFS_STAGE1_5	5
-#define STAGE2_ID_VSTAFS_STAGE1_5	6
-#define STAGE2_ID_JFS_STAGE1_5		7
-#define STAGE2_ID_XFS_STAGE1_5		8
-#define STAGE2_ID_ISO9660_STAGE1_5	9
-#define STAGE2_ID_UFS2_STAGE1_5		10
+#define STAGE2_ID_REISER4_STAGE1_5	6
+#define STAGE2_ID_VSTAFS_STAGE1_5	7
+#define STAGE2_ID_JFS_STAGE1_5		8
+#define STAGE2_ID_XFS_STAGE1_5		9
+#define STAGE2_ID_ISO9660_STAGE1_5	10
+#define STAGE2_ID_UFS2_STAGE1_5		11
 
 #ifndef STAGE1_5
 # define STAGE2_ID	STAGE2_ID_STAGE2
@@ -226,6 +227,8 @@
 #  define STAGE2_ID	STAGE2_ID_MINIX_STAGE1_5
 # elif defined(FSYS_REISERFS)
 #  define STAGE2_ID	STAGE2_ID_REISERFS_STAGE1_5
+# elif defined(FSYS_REISER4)
+#  define STAGE2_ID	STAGE2_ID_REISER4_STAGE1_5
 # elif defined(FSYS_VSTAFS)
 #  define STAGE2_ID	STAGE2_ID_VSTAFS_STAGE1_5
 # elif defined(FSYS_JFS)
@@ -871,6 +874,7 @@
 int grub_tolower (int c);
 int grub_isspace (int c);
 int grub_strncat (char *s1, const char *s2, int n);
+void grub_memcpy(void *dest, const void *src, int len);
 void *grub_memmove (void *to, const void *from, int len);
 void *grub_memset (void *start, int c, int len);
 int grub_strncat (char *s1, const char *s2, int n);
diff -Naur grub-0.96.1-orig/stage2/stage2.c grub-0.96.1/stage2/stage2.c
--- grub-0.96.1-orig/stage2/stage2.c	2005-02-23 15:06:00.000000000 +0200
+++ grub-0.96.1/stage2/stage2.c	2005-02-23 15:17:41.000000000 +0200
@@ -233,6 +233,7 @@
 {
   int c, time1, time2 = -1, first_entry = 0;
   char *cur_entry = 0;
+  struct term_entry *prev_term = NULL;
 
   /*
    *  Main loop for menu UI.
@@ -714,6 +715,15 @@
   
   cls ();
   setcursor (1);
+  /* if our terminal needed initialization, we should shut it down
+   * before booting the kernel, but we want to save what it was so
+   * we can come back if needed */
+  prev_term = current_term;
+  if (current_term->shutdown) 
+    {
+      (*current_term->shutdown)();
+      current_term = term_table; /* assumption: console is first */
+    }
   
   while (1)
     {
@@ -748,6 +758,13 @@
 	break;
     }
 
+  /* if we get back here, we should go back to what our term was before */
+  current_term = prev_term;
+  if (current_term->startup)
+      /* if our terminal fails to initialize, fall back to console since
+       * it should always work */
+      if ((*current_term->startup)() == 0)
+          current_term = term_table; /* we know that console is first */
   show_menu = 1;
   goto restart;
 }
@@ -1049,6 +1066,10 @@
 	  while (is_preset);
 	}
 
+      /* go ahead and make sure the terminal is setup */
+      if (current_term->startup)
+        (*current_term->startup)();
+
       if (! num_entries)
 	{
 	  /* If no acceptable config file, goto command-line, starting
diff -Naur grub-0.96.1-orig/stage2/term.h grub-0.96.1/stage2/term.h
--- grub-0.96.1-orig/stage2/term.h	2005-02-23 15:06:00.000000000 +0200
+++ grub-0.96.1/stage2/term.h	2005-02-23 15:17:41.000000000 +0200
@@ -60,6 +60,8 @@
   const char *name;
   /* The feature flags defined above.  */
   unsigned long flags;
+  /* Default for maximum number of lines if not specified */
+  unsigned short max_lines;
   /* Put a character.  */
   void (*putchar) (int c);
   /* Check if any input character is available.  */
@@ -79,6 +81,11 @@
   void (*setcolor) (int normal_color, int highlight_color);
   /* Turn on/off the cursor.  */
   int (*setcursor) (int on);
+
+  /* function to start a terminal */
+  int (*startup) (void);
+  /* function to use to shutdown a terminal */
+  void (*shutdown) (void);
 };
 
 /* This lists up available terminals.  */
@@ -124,4 +131,23 @@
 int hercules_setcursor (int on);
 #endif
 
+#ifdef SUPPORT_GRAPHICS
+extern int foreground, background, border, graphics_inited;
+
+void graphics_set_splash(char *splashfile);
+int set_videomode (int mode);
+void graphics_putchar (int c);
+int graphics_getxy(void);
+void graphics_gotoxy(int x, int y);
+void graphics_cls(void);
+void graphics_setcolorstate (color_state state);
+void graphics_setcolor (int normal_color, int highlight_color);
+void graphics_setcursor (int on);
+int graphics_init(void);
+void graphics_end(void);
+
+int hex(int v);
+void graphics_set_palette(int idx, int red, int green, int blue);
+#endif /* SUPPORT_GRAPHICS */
+
 #endif /* ! GRUB_TERM_HEADER */
