--- /dev/null
+#
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+# $Id: Makefile 4855 2006-09-24 20:49:31Z nico $
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=grub
+PKG_VERSION:=0.97
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=ftp://alpha.gnu.org/gnu/grub
+PKG_MD5SUM:=cd3f3eb54446be6003156158d51f4884
+PKG_CAT:=zcat
+
+PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/grub-$(PKG_VERSION)
+PKG_TARGETS:=bin
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/grub
+ SECTION:=boot
+ DEPENDS:=@TARGET_x86
+ CATEGORY:=Boot Loaders
+ TITLE:=GRand Unified Bootloader
+ URL:=http://www.gnu.org/software/grub/
+endef
+
+ifeq ($(HOST_ARCH),x86_64)
+CONFIGURE_FLAGS:= \
+ --target=$(GNU_TARGET_NAME) \
+ --host=$(GNU_TARGET_NAME) \
+ --build=$(GNU_HOST_NAME)
+else
+CONFIGURE_FLAGS:=
+endif
+
+define Build/Configure
+ (cd $(PKG_BUILD_DIR); \
+ LDFLAGS="-static" \
+ ./configure \
+ $(CONFIGURE_FLAGS) \
+ --program-prefix="" \
+ --program-suffix="" \
+ --prefix=/usr \
+ --exec-prefix=/usr \
+ --bindir=/usr/bin \
+ --sbindir=/usr/sbin \
+ --libexecdir=/usr/lib \
+ --sysconfdir=/etc \
+ --datadir=/usr/share \
+ --localstatedir=/var \
+ --mandir=/usr/man \
+ --infodir=/usr/info \
+ $(DISABLE_NLS) \
+ --disable-auto-linux-mem-opt \
+ )
+endef
+
+#
+# ./configure detects whether the host compiler supports
+# -fno-stack-protector but only sets STAGE2_CFLAGS accordingly
+#
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ GRUB_CFLAGS="\$$$$(STAGE2_CFLAGS)" \
+ STAGE1_CFLAGS="\$$$$(STAGE2_CFLAGS)"
+endef
+
+define Build/InstallDev
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ DESTDIR="$(STAGING_DIR_HOST)" \
+ install
+ mv $(STAGING_DIR_HOST)/usr/sbin/grub $(STAGING_DIR_HOST)/bin
+endef
+
+$(eval $(call BuildPackage,grub))
--- /dev/null
+serial --unit=0 --speed=@BAUDRATE@ --word=8 --parity=no --stop=1
+terminal --timeout=2 console serial
+
+default 0
+timeout 5
+
+title OpenWrt
+root (hd0,0)
+kernel /boot/vmlinuz @CMDLINE@ noinitrd console=tty0 console=ttyS0,@BAUDRATE@n8 reboot=bios
+boot
+
+title OpenWrt (failsafe)
+root (hd0,0)
+kernel /boot/vmlinuz failsafe=true @CMDLINE@ noinitrd console=tty0 console=ttyS0,@BAUDRATE@n8 reboot=bios
+boot
--- /dev/null
+Submitted By: Jim Gifford (jim at linuxfromscratch dot org)
+Date: 2006-07-04
+Initial Package Version: 0.97
+Origin: Debian
+Upstream Status: Unknown
+Description: Contains various fixes and enhancements
+ Graphics mode support
+ Fixes for Raid Support
+ XFS Filesystem Boot Freeze Fixes
+ Removed 2GB Memory Limitation
+ Freebsd support
+ Fixes for initrd support
+ Grub installation Fixes
+ Linux 2.6 geometry Fixes
+ Intel Mac Support
+ Autoconf and aclocal updates
+
+http://trac.cross-lfs.org/browser/trunk/patches/grub-0.97-fixes-1.patch
+
+diff -Naur grub-0.97.orig/aclocal.m4 grub-0.97/aclocal.m4
+--- grub-0.97.orig/aclocal.m4 2005-05-07 19:41:18.000000000 -0700
++++ grub-0.97/aclocal.m4 2006-07-04 00:08:22.000000000 -0700
+@@ -1,7 +1,7 @@
+-# generated automatically by aclocal 1.9.4 -*- Autoconf -*-
++# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
+
+-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+-# Free Software Foundation, Inc.
++# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
++# 2005 Free Software Foundation, Inc.
+ # This file is free software; the Free Software Foundation
+ # gives unlimited permission to copy and/or distribute it,
+ # with or without modifications, as long as this notice is preserved.
+@@ -11,23 +11,11 @@
+ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ # PARTICULAR PURPOSE.
+
+-# -*- Autoconf -*-
+-# Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+-# Generated from amversion.in; do not edit by hand.
+-
+-# 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, 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., 59 Temple Place - Suite 330, Boston, MA
++# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
++#
++# This file is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
+
+ # AM_AUTOMAKE_VERSION(VERSION)
+ # ----------------------------
+@@ -40,26 +28,15 @@
+ # Call AM_AUTOMAKE_VERSION so it can be traced.
+ # This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
+ AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+- [AM_AUTOMAKE_VERSION([1.9.4])])
+-
+-# AM_AUX_DIR_EXPAND
+-
+-# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
++ [AM_AUTOMAKE_VERSION([1.9.6])])
+
+-# 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, or (at your option)
+-# any later version.
++# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+-# 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., 59 Temple Place - Suite 330, Boston, MA
+-# 02111-1307, USA.
++# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
++#
++# This file is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
+
+ # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+ # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+@@ -106,26 +83,16 @@
+ am_aux_dir=`cd $ac_aux_dir && pwd`
+ ])
+
+-# AM_CONDITIONAL -*- Autoconf -*-
++# AM_CONDITIONAL -*- Autoconf -*-
+
+-# Copyright (C) 1997, 2000, 2001, 2003, 2004 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, 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., 59 Temple Place - Suite 330, Boston, MA
+-# 02111-1307, USA.
++# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
++# Free Software Foundation, Inc.
++#
++# This file is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
+
+-# serial 6
++# serial 7
+
+ # AM_CONDITIONAL(NAME, SHELL-CONDITION)
+ # -------------------------------------
+@@ -149,26 +116,15 @@
+ Usually this means the macro was only invoked conditionally.]])
+ fi])])
+
+-# serial 7 -*- Autoconf -*-
+
+-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
++# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ # Free Software Foundation, Inc.
++#
++# This file is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
+
+-# 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, 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., 59 Temple Place - Suite 330, Boston, MA
+-# 02111-1307, USA.
+-
++# serial 8
+
+ # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+ # written in clear, in which case automake, when reading aclocal.m4,
+@@ -177,7 +133,6 @@
+ # CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+-
+ # _AM_DEPENDENCIES(NAME)
+ # ----------------------
+ # See how the compiler implements dependency checking.
+@@ -317,27 +272,16 @@
+ AC_SUBST([AMDEPBACKSLASH])
+ ])
+
+-# Generate code to set up dependency tracking. -*- Autoconf -*-
+-
+-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
+-# 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, or (at your option)
+-# any later version.
++# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+-# 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., 59 Temple Place - Suite 330, Boston, MA
+-# 02111-1307, USA.
++# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
++# Free Software Foundation, Inc.
++#
++# This file is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
+
+-#serial 2
++#serial 3
+
+ # _AM_OUTPUT_DEPENDENCY_COMMANDS
+ # ------------------------------
+@@ -396,30 +340,19 @@
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+ ])
+
+-# Do all the work for Automake. -*- Autoconf -*-
++# Do all the work for Automake. -*- Autoconf -*-
+
+-# This macro actually does too much some checks are only needed if
+-# your package does certain things. But this isn't really a big deal.
+-
+-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
++# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ # Free Software Foundation, Inc.
++#
++# This file is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
+
+-# 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, 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., 59 Temple Place - Suite 330, Boston, MA
+-# 02111-1307, USA.
++# serial 12
+
+-# serial 11
++# This macro actually does too much. Some checks are only needed if
++# your package does certain things. But this isn't really a big deal.
+
+ # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+ # AM_INIT_AUTOMAKE([OPTIONS])
+@@ -521,51 +454,27 @@
+ done
+ echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+
++# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
++#
++# This file is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
++
+ # AM_PROG_INSTALL_SH
+ # ------------------
+ # Define $install_sh.
+-
+-# Copyright (C) 2001, 2003 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, 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., 59 Temple Place - Suite 330, Boston, MA
+-# 02111-1307, USA.
+-
+ AC_DEFUN([AM_PROG_INSTALL_SH],
+ [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+ install_sh=${install_sh-"$am_aux_dir/install-sh"}
+ AC_SUBST(install_sh)])
+
+-# -*- Autoconf -*-
+-# Copyright (C) 2003 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, 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., 59 Temple Place - Suite 330, Boston, MA
+-# 02111-1307, USA.
++# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
++#
++# This file is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
+
+-# serial 1
++# serial 2
+
+ # Check whether the underlying file-system supports filenames
+ # with a leading dot. For instance MS-DOS doesn't.
+@@ -580,28 +489,17 @@
+ rmdir .tst 2>/dev/null
+ AC_SUBST([am__leading_dot])])
+
+-# Add --enable-maintainer-mode option to configure.
++# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+ # From Jim Meyering
+
+-# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004
++# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005
+ # Free Software Foundation, Inc.
++#
++# This file is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
+
+-# 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, 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., 59 Temple Place - Suite 330, Boston, MA
+-# 02111-1307, USA.
+-
+-# serial 3
++# serial 4
+
+ AC_DEFUN([AM_MAINTAINER_MODE],
+ [AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+@@ -620,26 +518,15 @@
+
+ AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+-# Check to see how 'make' treats includes. -*- Autoconf -*-
+-
+-# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
++# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+-# 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, 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., 59 Temple Place - Suite 330, Boston, MA
+-# 02111-1307, USA.
++# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
++#
++# This file is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
+
+-# serial 2
++# serial 3
+
+ # AM_MAKE_INCLUDE()
+ # -----------------
+@@ -683,27 +570,16 @@
+ rm -f confinc confmf
+ ])
+
+-# -*- Autoconf -*-
+-
+-
+-# Copyright (C) 1997, 1999, 2000, 2001, 2003 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, or (at your option)
+-# any later version.
++# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+-# 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., 59 Temple Place - Suite 330, Boston, MA
+-# 02111-1307, USA.
++# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005
++# Free Software Foundation, Inc.
++#
++# This file is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
+
+-# serial 3
++# serial 4
+
+ # AM_MISSING_PROG(NAME, PROGRAM)
+ # ------------------------------
+@@ -729,27 +605,16 @@
+ fi
+ ])
+
++# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
++#
++# This file is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
++
+ # AM_PROG_MKDIR_P
+ # ---------------
+ # Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
+-
+-# Copyright (C) 2003, 2004 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, 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., 59 Temple Place - Suite 330, Boston, MA
+-# 02111-1307, USA.
+-
++#
+ # Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
+ # created by `make install' are always world readable, even if the
+ # installer happens to have an overly restrictive umask (e.g. 077).
+@@ -803,26 +668,15 @@
+ fi
+ AC_SUBST([mkdir_p])])
+
+-# Helper functions for option handling. -*- Autoconf -*-
++# Helper functions for option handling. -*- Autoconf -*-
+
+-# Copyright (C) 2001, 2002, 2003 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, 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., 59 Temple Place - Suite 330, Boston, MA
+-# 02111-1307, USA.
++# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
++#
++# This file is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
+
+-# serial 2
++# serial 3
+
+ # _AM_MANGLE_OPTION(NAME)
+ # -----------------------
+@@ -847,28 +701,16 @@
+ AC_DEFUN([_AM_IF_OPTION],
+ [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+-#
+-# Check to make sure that the build environment is sane.
+-#
+-
+-# Copyright (C) 1996, 1997, 2000, 2001, 2003 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, or (at your option)
+-# any later version.
++# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+-# 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., 59 Temple Place - Suite 330, Boston, MA
+-# 02111-1307, USA.
++# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
++# Free Software Foundation, Inc.
++#
++# This file is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
+
+-# serial 3
++# serial 4
+
+ # AM_SANITY_CHECK
+ # ---------------
+@@ -911,25 +753,14 @@
+ fi
+ AC_MSG_RESULT(yes)])
+
+-# AM_PROG_INSTALL_STRIP
+-
+-# Copyright (C) 2001, 2003 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, 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., 59 Temple Place - Suite 330, Boston, MA
+-# 02111-1307, USA.
++# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
++#
++# This file is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
+
++# AM_PROG_INSTALL_STRIP
++# ---------------------
+ # One issue with vendor `install' (even GNU) is that you can't
+ # specify the program used to strip binaries. This is especially
+ # annoying in cross-compiling environments, where the build's strip
+@@ -952,25 +783,13 @@
+
+ # Check how to create a tarball. -*- Autoconf -*-
+
+-# Copyright (C) 2004 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, 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., 59 Temple Place - Suite 330, Boston, MA
+-# 02111-1307, USA.
+-
+-# serial 1
++# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
++#
++# This file is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
+
++# serial 2
+
+ # _AM_PROG_TAR(FORMAT)
+ # --------------------
+diff -Naur grub-0.97.orig/ChangeLog grub-0.97/ChangeLog
+--- grub-0.97.orig/ChangeLog 2005-05-07 19:47:02.000000000 -0700
++++ grub-0.97/ChangeLog 2006-07-04 00:01:50.000000000 -0700
+@@ -1,3 +1,51 @@
++2006-05-02 Pavel Roskin <proski@gnu.org>
++
++ * stage2/stage2.c (run_menu): Fix "savedefault" to save only top
++ level menu positions. Remember current position when calling a
++ submenu. Don't recalculate it when booting from a submenu.
++
++ * grub/main.c (main): Make sure the boot drive number doesn't
++ exceed 255.
++
++2006-05-02 Vesa Jaaskelainen <chaac@nic.fi>
++
++ * stage2/shared.h (vbe_mode): Back ported aligment fix from GRUB 2
++ to GRUB Legacy. Problem reported by Gerardo Richarte.
++
++2006-04-23 Robert Millan <robertmh@gnu.org>
++
++ * grub/asmstub.c (get_diskinfo): Optimize sysctl routine.
++
++2006-04-20 Robert Millan <robertmh@gnu.org>
++
++ Fixes for kernel of FreeBSD:
++ * grub/asmstub.c (get_diskinfo): Toggle "kern.geom.debugflags" sysctl
++ before opening a device for writing.
++ * util/grub-install.in: Devices don't have this "r" prefix anymore.
++
++2006-04-16 Yoshinori K. Okuji <okuji@enbug.org>
++
++ * docs/multiboot.texi: Correct the offset of address
++ fields. Reported by Jeroen Dekkers.
++
++2006-03-21 Yoshinori K. Okuji <okuji@enbug.org>
++
++ * stage2/builtins.c (setup_func): Specify the size of DEVICE to
++ grub_strncat instead of a strange number 256. Reported by Vitaly
++ Fertman <vitaly@namesys.com>.
++
++2005-09-29 Yoshinori K. Okuji <okuji@enbug.org>
++
++ * docs/multiboot.texi: Fix a bug in the byte order of
++ boot_device. I hope this won't affect any OS image.
++ Increased the version number to 0.6.94.
++
++2005-09-28 Yoshinori K. Okuji <okuji@enbug.org>
++
++ * stage2/boot.c (load_image): Even if an OS image is an ELF
++ object, use the a.out kludge if MULTIBOOT_AOUT_KLUDGE is
++ specified.
++
+ 2005-05-08 Yoshinori K. Okuji <okuji@enbug.org>
+
+ * configure.ac (AC_INIT): Upgraded to 0.97.
+diff -Naur grub-0.97.orig/configure grub-0.97/configure
+--- grub-0.97.orig/configure 2005-05-07 19:48:12.000000000 -0700
++++ grub-0.97/configure 2006-07-04 00:08:05.000000000 -0700
+@@ -311,7 +311,7 @@
+ # include <unistd.h>
+ #endif"
+
+-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar build build_cpu build_vendor build_os host host_cpu host_vendor host_os MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT PERL CC ac_ct_CC CFLAGS LDFLAGS CPPFLAGS EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CCAS RANLIB ac_ct_RANLIB STAGE1_CFLAGS STAGE2_CFLAGS GRUB_CFLAGS OBJCOPY ac_ct_OBJCOPY GRUB_LIBS CPP EGREP NETBOOT_SUPPORT_TRUE NETBOOT_SUPPORT_FALSE DISKLESS_SUPPORT_TRUE DISKLESS_SUPPORT_FALSE HERCULES_SUPPORT_TRUE HERCULES_SUPPORT_FALSE SERIAL_SUPPORT_TRUE SERIAL_SUPPORT_FALSE SERIAL_SPEED_SIMULATION_TRUE SERIAL_SPEED_SIMULATION_FALSE BUILD_EXAMPLE_KERNEL_TRUE BUILD_EXAMPLE_KERNEL_FALSE FSYS_CFLAGS NET_CFLAGS NET_EXTRAFLAGS NETBOOT_DRIVERS CCASFLAGS LIBOBJS LTLIBOBJS'
++ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar build build_cpu build_vendor build_os host host_cpu host_vendor host_os MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT PERL CC ac_ct_CC CFLAGS LDFLAGS CPPFLAGS EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CCAS RANLIB ac_ct_RANLIB STAGE1_CFLAGS STAGE2_CFLAGS GRUB_CFLAGS OBJCOPY ac_ct_OBJCOPY GRUB_LIBS CPP EGREP NETBOOT_SUPPORT_TRUE NETBOOT_SUPPORT_FALSE DISKLESS_SUPPORT_TRUE DISKLESS_SUPPORT_FALSE GRAPHICS_SUPPORT_TRUE GRAPHICS_SUPPORT_FALSE HERCULES_SUPPORT_TRUE HERCULES_SUPPORT_FALSE SERIAL_SUPPORT_TRUE SERIAL_SUPPORT_FALSE SERIAL_SPEED_SIMULATION_TRUE SERIAL_SPEED_SIMULATION_FALSE BUILD_EXAMPLE_KERNEL_TRUE BUILD_EXAMPLE_KERNEL_FALSE FSYS_CFLAGS NET_CFLAGS NET_EXTRAFLAGS NETBOOT_DRIVERS CCASFLAGS LIBOBJS LTLIBOBJS'
+ ac_subst_files=''
+
+ # Initialize some variables set by options.
+@@ -914,6 +914,7 @@
+ set the default memory location for WD/SMC
+ --enable-cs-scan=LIST probe for CS89x0 base address using LIST
+ --enable-diskless enable diskless support
++ --disable-graphics disable graphics terminal support
+ --disable-hercules disable hercules terminal support
+ --disable-serial disable serial terminal support
+ --enable-serial-speed-simulation
+@@ -5966,6 +5967,22 @@
+ fi
+
+
++# Check whether --enable-graphics or --disable-graphics was given.
++if test "${enable_graphics+set}" = set; then
++ enableval="$enable_graphics"
++
++fi;
++
++
++if test "x$enable_graphics" != xno; then
++ GRAPHICS_SUPPORT_TRUE=
++ GRAPHICS_SUPPORT_FALSE='#'
++else
++ GRAPHICS_SUPPORT_TRUE='#'
++ GRAPHICS_SUPPORT_FALSE=
++fi
++
++
+ # Check whether --enable-hercules or --disable-hercules was given.
+ if test "${enable_hercules+set}" = set; then
+ enableval="$enable_hercules"
+@@ -6270,6 +6287,13 @@
+ Usually this means the macro was only invoked conditionally." >&2;}
+ { (exit 1); exit 1; }; }
+ fi
++if test -z "${GRAPHICS_SUPPORT_TRUE}" && test -z "${GRAPHICS_SUPPORT_FALSE}"; then
++ { { echo "$as_me:$LINENO: error: conditional \"GRAPHICS_SUPPORT\" was never defined.
++Usually this means the macro was only invoked conditionally." >&5
++echo "$as_me: error: conditional \"GRAPHICS_SUPPORT\" was never defined.
++Usually this means the macro was only invoked conditionally." >&2;}
++ { (exit 1); exit 1; }; }
++fi
+ if test -z "${HERCULES_SUPPORT_TRUE}" && test -z "${HERCULES_SUPPORT_FALSE}"; then
+ { { echo "$as_me:$LINENO: error: conditional \"HERCULES_SUPPORT\" was never defined.
+ Usually this means the macro was only invoked conditionally." >&5
+@@ -6907,6 +6931,8 @@
+ s,@NETBOOT_SUPPORT_FALSE@,$NETBOOT_SUPPORT_FALSE,;t t
+ s,@DISKLESS_SUPPORT_TRUE@,$DISKLESS_SUPPORT_TRUE,;t t
+ s,@DISKLESS_SUPPORT_FALSE@,$DISKLESS_SUPPORT_FALSE,;t t
++s,@GRAPHICS_SUPPORT_TRUE@,$GRAPHICS_SUPPORT_TRUE,;t t
++s,@GRAPHICS_SUPPORT_FALSE@,$GRAPHICS_SUPPORT_FALSE,;t t
+ s,@HERCULES_SUPPORT_TRUE@,$HERCULES_SUPPORT_TRUE,;t t
+ s,@HERCULES_SUPPORT_FALSE@,$HERCULES_SUPPORT_FALSE,;t t
+ s,@SERIAL_SUPPORT_TRUE@,$SERIAL_SUPPORT_TRUE,;t t
+diff -Naur grub-0.97.orig/configure.ac grub-0.97/configure.ac
+--- grub-0.97.orig/configure.ac 2005-05-07 19:36:03.000000000 -0700
++++ grub-0.97/configure.ac 2006-07-03 23:58:41.000000000 -0700
+@@ -595,6 +595,11 @@
+ [ --enable-diskless enable diskless support])
+ AM_CONDITIONAL(DISKLESS_SUPPORT, test "x$enable_diskless" = xyes)
+
++dnl Graphical splashscreen support
++AC_ARG_ENABLE(graphics,
++ [ --disable-graphics disable graphics terminal support])
++AM_CONDITIONAL(GRAPHICS_SUPPORT, test "x$enable_graphics" != xno)
++
+ dnl Hercules terminal
+ AC_ARG_ENABLE(hercules,
+ [ --disable-hercules disable hercules terminal support])
+diff -Naur grub-0.97.orig/docs/grub.8 grub-0.97/docs/grub.8
+--- grub-0.97.orig/docs/grub.8 2005-05-07 19:48:56.000000000 -0700
++++ grub-0.97/docs/grub.8 2006-07-04 00:01:50.000000000 -0700
+@@ -1,5 +1,5 @@
+ .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.23.
+-.TH GRUB "8" "May 2005" "grub (GNU GRUB 0.97)" FSF
++.TH GRUB "8" "September 2005" "grub (GNU GRUB 0.97)" FSF
+ .SH NAME
+ grub \- the grub shell
+ .SH SYNOPSIS
+diff -Naur grub-0.97.orig/docs/grub.texi grub-0.97/docs/grub.texi
+--- grub-0.97.orig/docs/grub.texi 2005-05-07 19:59:59.000000000 -0700
++++ grub-0.97/docs/grub.texi 2006-07-04 00:00:54.000000000 -0700
+@@ -2199,6 +2199,7 @@
+ * rarp:: Initialize a network device via RARP
+ * serial:: Set up a serial device
+ * setkey:: Configure the key map
++* splashimage:: Use a splash image
+ * terminal:: Choose a terminal
+ * terminfo:: Define escape sequences for a terminal
+ * tftpserver:: Specify a TFTP server
+@@ -2578,6 +2579,16 @@
+ @end deffn
+
+
++@node splashimage
++@subsection splashimage
++
++@deffn Command splashimage file
++Select an image to use as the background image. This should be
++specified using normal GRUB device naming syntax. The format of the
++file is a gzipped xpm which is 640x480 with a 14 color palette.
++@end deffn
++
++
+ @node terminal
+ @subsection terminal
+
+@@ -2685,6 +2696,7 @@
+ * module:: Load a module
+ * modulenounzip:: Load a module without decompression
+ * pause:: Wait for a key press
++* print:: Print a message
+ * quit:: Exit from the grub shell
+ * reboot:: Reboot your computer
+ * read:: Read data from memory
+@@ -3091,6 +3103,16 @@
+ @end deffn
+
+
++@node print
++@subsection print
++
++@deffn Command print message @dots{}
++Print the @var{message}. Note that placing @key{^G} (ASCII code 7) in the
++message will cause the speaker to emit the standard beep sound, which is
++useful for visually impaired people.
++@end deffn
++
++
+ @node quit
+ @subsection quit
+
+diff -Naur grub-0.97.orig/docs/multiboot.texi grub-0.97/docs/multiboot.texi
+--- grub-0.97.orig/docs/multiboot.texi 2003-07-09 04:45:36.000000000 -0700
++++ grub-0.97/docs/multiboot.texi 2006-07-04 00:01:50.000000000 -0700
+@@ -25,7 +25,7 @@
+ @ifinfo
+ Copyright @copyright{} 1995, 96 Bryan Ford <baford@@cs.utah.edu>
+ Copyright @copyright{} 1995, 96 Erich Stefan Boleyn <erich@@uruk.org>
+-Copyright @copyright{} 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
++Copyright @copyright{} 1999, 2000, 2001, 2002, 2005, 2006 Free Software Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of
+ this manual provided the copyright notice and this permission notice
+@@ -57,7 +57,7 @@
+ @vskip 0pt plus 1filll
+ Copyright @copyright{} 1995, 96 Bryan Ford <baford@@cs.utah.edu>
+ Copyright @copyright{} 1995, 96 Erich Stefan Boleyn <erich@@uruk.org>
+-Copyright @copyright{} 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
++Copyright @copyright{} 1999, 2000, 2001, 2002, 2005, 2006 Free Software Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of
+ this manual provided the copyright notice and this permission notice
+@@ -80,7 +80,7 @@
+ @top Multiboot Specification
+
+ This file documents Multiboot Specification, the proposal for the boot
+-sequence standard. This edition documents version 0.6.93.
++sequence standard. This edition documents version 0.6.94.
+ @end ifnottex
+
+ @menu
+@@ -426,7 +426,7 @@
+ kernel.
+
+ If bit 16 in the @samp{flags} word is set, then the fields at offsets
+-8-24 in the Multiboot header are valid, and the boot loader should use
++12-28 in the Multiboot header are valid, and the boot loader should use
+ them instead of the fields in the actual executable header to calculate
+ where to load the OS image. This information does not need to be
+ provided if the kernel image is in @sc{elf} format, but it @emph{must}
+@@ -677,7 +677,7 @@
+ @example
+ @group
+ +-------+-------+-------+-------+
+-| drive | part1 | part2 | part3 |
++| part3 | part2 | part1 | drive |
+ +-------+-------+-------+-------+
+ @end group
+ @end example
+@@ -1199,6 +1199,13 @@
+ @email{bug-grub@@gnu.org}, from Bryan Ford and Erich Stefan Boleyn.
+ @end itemize
+
++@item
++The byte order of the @samp{boot_device} in Multiboot information is
++reversed. This was a mistake.
++
++@item
++The offset of the address fields were wrong.
++
+ @item 0.6
+ @itemize @bullet
+ @item
+diff -Naur grub-0.97.orig/grub/asmstub.c grub-0.97/grub/asmstub.c
+--- grub-0.97.orig/grub/asmstub.c 2005-02-16 12:45:14.000000000 -0800
++++ grub-0.97/grub/asmstub.c 2006-07-04 00:01:50.000000000 -0700
+@@ -42,6 +42,12 @@
+ #include <sys/time.h>
+ #include <termios.h>
+ #include <signal.h>
++#include <sys/mman.h>
++
++#include <limits.h>
++#ifndef PAGESIZE
++#define PAGESIZE 4096
++#endif
+
+ #ifdef __linux__
+ # include <sys/ioctl.h> /* ioctl */
+@@ -55,6 +61,10 @@
+ # endif /* ! BLKFLSBUF */
+ #endif /* __linux__ */
+
++#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
++# include <sys/sysctl.h>
++#endif
++
+ /* We want to prevent any circularararity in our stubs, as well as
+ libc name clashes. */
+ #define WITHOUT_LIBC_STUBS 1
+@@ -144,6 +154,22 @@
+ assert (grub_scratch_mem == 0);
+ scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15);
+ assert (scratch);
++
++ {
++ char *p;
++ int ret;
++
++ /* Align to a multiple of PAGESIZE, assumed to be a power of two. */
++ p = (char *) (((long) scratch) & ~(PAGESIZE - 1));
++
++ /* The simulated stack needs to be executable, since GCC uses stack
++ * trampolines to implement nested functions.
++ */
++ ret = mprotect (p, 0x100000 + EXTENDED_MEMSIZE + 15,
++ PROT_READ | PROT_WRITE | PROT_EXEC);
++ assert (ret == 0);
++ }
++
+ grub_scratch_mem = (char *) ((((int) scratch) >> 4) << 4);
+
+ /* FIXME: simulate the memory holes using mprot, if available. */
+@@ -777,7 +803,39 @@
+
+ /* Open read/write, or read-only if that failed. */
+ if (! read_only)
+- disks[drive].flags = open (devname, O_RDWR);
++ {
++/* By default, kernel of FreeBSD does not allow overwriting MBR */
++#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
++#define GEOM_SYSCTL "kern.geom.debugflags"
++ int old_flags, flags;
++ size_t sizeof_int = sizeof (int);
++
++ if (sysctlbyname (GEOM_SYSCTL, &old_flags, &sizeof_int, NULL, 0) != 0)
++ grub_printf ("failed to get " GEOM_SYSCTL "sysctl: %s\n", strerror (errno));
++
++ if ((old_flags & 0x10) == 0)
++ {
++ /* "allow foot shooting", see geom(4) */
++ flags = old_flags | 0x10;
++
++ if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, &flags, sizeof (int)) != 0)
++ {
++ flags = old_flags;
++ grub_printf ("failed to set " GEOM_SYSCTL "sysctl: %s\n", strerror (errno));
++ }
++ }
++ else
++ flags = old_flags;
++#endif
++ disks[drive].flags = open (devname, O_RDWR);
++#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
++ if (flags != old_flags)
++ {
++ if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, &old_flags, sizeof (int)) != 0)
++ grub_printf ("failed to set " GEOM_SYSCTL "sysctl: %s\n", strerror (errno));
++ }
++#endif
++ }
+
+ if (disks[drive].flags == -1)
+ {
+diff -Naur grub-0.97.orig/grub/main.c grub-0.97/grub/main.c
+--- grub-0.97.orig/grub/main.c 2003-07-09 04:45:36.000000000 -0700
++++ grub-0.97/grub/main.c 2006-07-04 00:01:50.000000000 -0700
+@@ -32,6 +32,7 @@
+ #define WITHOUT_LIBC_STUBS 1
+ #include <shared.h>
+ #include <term.h>
++#include <device.h>
+
+ char *program_name = 0;
+ int use_config_file = 1;
+@@ -192,6 +193,12 @@
+ perror ("strtoul");
+ exit (1);
+ }
++ if (boot_drive >= NUM_DISKS)
++ {
++ fprintf (stderr, "boot_drive should be from 0 to %d\n",
++ NUM_DISKS - 1);
++ exit (1);
++ }
+ break;
+
+ case OPT_NO_CONFIG_FILE:
+diff -Naur grub-0.97.orig/lib/device.c grub-0.97/lib/device.c
+--- grub-0.97.orig/lib/device.c 2005-03-27 15:14:25.000000000 -0800
++++ grub-0.97/lib/device.c 2006-07-04 00:00:44.000000000 -0700
+@@ -131,6 +131,152 @@
+ #include <shared.h>
+ #include <device.h>
+
++#if defined(__linux__)
++/* The 2.6 kernel has removed all of the geometry handling for IDE drives
++ * that did fixups for LBA, etc. This means that the geometry we get
++ * with the ioctl has a good chance of being wrong. So, we get to
++ * also know about partition tables and try to read what the geometry
++ * is there. *grumble* Very closely based on code from cfdisk
++ */
++static void get_kernel_geometry(int fd, long long *cyl, int *heads, int *sectors) {
++ struct hd_geometry hdg;
++
++ if (ioctl (fd, HDIO_GETGEO, &hdg))
++ return;
++
++ *cyl = hdg.cylinders;
++ *heads = hdg.heads;
++ *sectors = hdg.sectors;
++}
++
++struct partition {
++ unsigned char boot_ind; /* 0x80 - active */
++ unsigned char head; /* starting head */
++ unsigned char sector; /* starting sector */
++ unsigned char cyl; /* starting cylinder */
++ unsigned char sys_ind; /* What partition type */
++ unsigned char end_head; /* end head */
++ unsigned char end_sector; /* end sector */
++ unsigned char end_cyl; /* end cylinder */
++ unsigned char start4[4]; /* starting sector counting from 0 */
++ unsigned char size4[4]; /* nr of sectors in partition */
++};
++
++#define ALIGNMENT 2
++typedef union {
++ struct {
++ unsigned char align[ALIGNMENT];
++ unsigned char b[SECTOR_SIZE];
++ } c;
++ struct {
++ unsigned char align[ALIGNMENT];
++ unsigned char buffer[0x1BE];
++ struct partition part[4];
++ unsigned char magicflag[2];
++ } p;
++} partition_table;
++
++#define PART_TABLE_FLAG0 0x55
++#define PART_TABLE_FLAG1 0xAA
++
++static void
++get_partition_table_geometry(partition_table *bufp, long long *cyl, int *heads,
++ int *sectors) {
++ struct partition *p;
++ int i,h,s,hh,ss;
++ int first = 1;
++ int bad = 0;
++
++ if (bufp->p.magicflag[0] != PART_TABLE_FLAG0 ||
++ bufp->p.magicflag[1] != PART_TABLE_FLAG1) {
++ /* Matthew Wilcox: slightly friendlier version of
++ fatal(_("Bad signature on partition table"), 3);
++ */
++ fprintf(stderr, "Unknown partition table signature\n");
++ return;
++ }
++
++ hh = ss = 0;
++ for (i=0; i<4; i++) {
++ p = &(bufp->p.part[i]);
++ if (p->sys_ind != 0) {
++ h = p->end_head + 1;
++ s = (p->end_sector & 077);
++ if (first) {
++ hh = h;
++ ss = s;
++ first = 0;
++ } else if (hh != h || ss != s)
++ bad = 1;
++ }
++ }
++
++ if (!first && !bad) {
++ *heads = hh;
++ *sectors = ss;
++ }
++}
++
++static long long my_lseek (unsigned int fd, long long offset,
++ unsigned int origin)
++{
++#if defined(__linux__) && (!defined(__GLIBC__) || \
++ ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
++ /* Maybe libc doesn't have large file support. */
++ loff_t offset, result;
++ static int _llseek (uint filedes, ulong hi, ulong lo,
++ loff_t *res, uint wh);
++ _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
++ loff_t *, res, uint, wh);
++
++ if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET) < 0)
++ return (long long) -1;
++ return result;
++#else
++ return lseek(fd, offset, SEEK_SET);
++#endif
++}
++
++static void get_linux_geometry (int fd, struct geometry *geom) {
++ long long kern_cyl = 0; int kern_head = 0, kern_sectors = 0;
++ long long pt_cyl = 0; int pt_head = 0, pt_sectors = 0;
++ partition_table bufp;
++ char *buff, *buf_unaligned;
++
++ buf_unaligned = malloc(sizeof(partition_table) + 4095);
++ buff = (char *) (((unsigned long)buf_unaligned + 4096 - 1) &
++ (~(4096-1)));
++
++ get_kernel_geometry(fd, &kern_cyl, &kern_head, &kern_sectors);
++
++ if (my_lseek (fd, 0*SECTOR_SIZE, SEEK_SET) < 0) {
++ fprintf(stderr, "Unable to seek");
++ }
++
++ if (read(fd, buff, SECTOR_SIZE) == SECTOR_SIZE) {
++ memcpy(bufp.c.b, buff, SECTOR_SIZE);
++ get_partition_table_geometry(&bufp, &pt_cyl, &pt_head, &pt_sectors);
++ } else {
++ fprintf(stderr, "Unable to read partition table: %s\n", strerror(errno));
++ }
++
++ if (pt_head && pt_sectors) {
++ int cyl_size;
++
++ geom->heads = pt_head;
++ geom->sectors = pt_sectors;
++ cyl_size = pt_head * pt_sectors;
++ geom->cylinders = geom->total_sectors/cyl_size;
++ } else {
++ geom->heads = kern_head;
++ geom->sectors = kern_sectors;
++ geom->cylinders = kern_cyl;
++ }
++
++ return;
++}
++#endif
++
+ /* Get the geometry of a drive DRIVE. */
+ void
+ get_drive_geometry (struct geometry *geom, char **map, int drive)
+@@ -151,21 +297,16 @@
+ #if defined(__linux__)
+ /* Linux */
+ {
+- struct hd_geometry hdg;
+ unsigned long nr;
+-
+- if (ioctl (fd, HDIO_GETGEO, &hdg))
+- goto fail;
+
+ if (ioctl (fd, BLKGETSIZE, &nr))
+ goto fail;
+
+ /* Got the geometry, so save it. */
+- geom->cylinders = hdg.cylinders;
+- geom->heads = hdg.heads;
+- geom->sectors = hdg.sectors;
+ geom->total_sectors = nr;
+-
++ get_linux_geometry(fd, geom);
++ if (!geom->heads && !geom->cylinders && !geom->sectors)
++ goto fail;
+ goto success;
+ }
+
+@@ -403,6 +544,18 @@
+ }
+
+ static void
++get_cciss_disk_name (char *name, int controller, int drive)
++{
++ sprintf (name, "/dev/cciss/c%dd%d", controller, drive);
++}
++
++static void
++get_ida_disk_name (char *name, int controller, int drive)
++{
++ sprintf (name, "/dev/ida/c%dd%d", controller, drive);
++}
++
++static void
+ get_ataraid_disk_name (char *name, int unit)
+ {
+ sprintf (name, "/dev/ataraid/d%c", unit + '0');
+@@ -801,6 +954,74 @@
+ }
+ }
+ }
++
++ /* This is for CCISS, its like the DAC960 - we have
++ /dev/cciss/<controller>d<logical drive>p<partition>
++
++ It currently supports up to 3 controllers, 10 logical volumes
++ and 10 partitions
++
++ Code gratuitously copied from DAC960 above.
++ Horms <horms@verge.net.au> 23rd July 2004
++ */
++ {
++ int controller, drive;
++
++ for (controller = 0; controller < 2; controller++)
++ {
++ for (drive = 0; drive < 9; drive++)
++ {
++ char name[24];
++
++ get_cciss_disk_name (name, controller, drive);
++ if (check_device (name))
++ {
++ (*map)[num_hd + 0x80] = strdup (name);
++ assert ((*map)[num_hd + 0x80]);
++
++ /* If the device map file is opened, write the map. */
++ if (fp)
++ fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
++
++ num_hd++;
++ }
++ }
++ }
++ }
++
++ /* This is for Compaq Smart Array, its like the DAC960 - we have
++ /dev/ida/<controller>d<logical drive>p<partition>
++
++ It currently supports up to 3 controllers, 10 logical volumes
++ and 15 partitions
++
++ Code gratuitously copied from DAC960 above.
++ Piotr Roszatycki <dexter@debian.org>
++ */
++ {
++ int controller, drive;
++
++ for (controller = 0; controller < 2; controller++)
++ {
++ for (drive = 0; drive < 9; drive++)
++ {
++ char name[24];
++
++ get_ida_disk_name (name, controller, drive);
++ if (check_device (name))
++ {
++ (*map)[num_hd + 0x80] = strdup (name);
++ assert ((*map)[num_hd + 0x80]);
++
++ /* If the device map file is opened, write the map. */
++ if (fp)
++ fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
++
++ num_hd++;
++ }
++ }
++ }
++ }
+ #endif /* __linux__ */
+
+ /* OK, close the device map file if opened. */
+@@ -844,6 +1065,7 @@
+ {
+ char dev[PATH_MAX]; /* XXX */
+ int fd;
++ off_t offset = (off_t) sector * (off_t) SECTOR_SIZE;
+
+ if ((partition & 0x00FF00) != 0x00FF00)
+ {
+@@ -861,8 +1083,14 @@
+ if (strcmp (dev + strlen(dev) - 5, "/disc") == 0)
+ strcpy (dev + strlen(dev) - 5, "/part");
+ }
+- sprintf (dev + strlen(dev), "%d", ((partition >> 16) & 0xFF) + 1);
+-
++ sprintf (dev + strlen(dev), "%s%d",
++ /* Compaq smart and others */
++ (strncmp(dev, "/dev/ida/", 9) == 0 ||
++ strncmp(dev, "/dev/ataraid/", 13) == 0 ||
++ strncmp(dev, "/dev/cciss/", 11) == 0 ||
++ strncmp(dev, "/dev/rd/", 8) == 0) ? "p" : "",
++ ((partition >> 16) & 0xFF) + 1);
++
+ /* Open the partition. */
+ fd = open (dev, O_RDWR);
+ if (fd < 0)
+@@ -870,35 +1098,13 @@
+ errnum = ERR_NO_PART;
+ return 0;
+ }
+-
+-#if defined(__linux__) && (!defined(__GLIBC__) || \
+- ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
+- /* Maybe libc doesn't have large file support. */
+- {
+- loff_t offset, result;
+- static int _llseek (uint filedes, ulong hi, ulong lo,
+- loff_t *res, uint wh);
+- _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
+- loff_t *, res, uint, wh);
+
+- offset = (loff_t) sector * (loff_t) SECTOR_SIZE;
+- if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET))
+- {
+- errnum = ERR_DEV_VALUES;
+- return 0;
+- }
+- }
+-#else
+- {
+- off_t offset = (off_t) sector * (off_t) SECTOR_SIZE;
+
+- if (lseek (fd, offset, SEEK_SET) != offset)
+- {
+- errnum = ERR_DEV_VALUES;
+- return 0;
+- }
+- }
+-#endif
++ if (my_lseek(fd, offset, SEEK_SET) != offset)
++ {
++ errnum = ERR_DEV_VALUES;
++ return 0;
++ }
+
+ if (write (fd, buf, size * SECTOR_SIZE) != (size * SECTOR_SIZE))
+ {
+diff -Naur grub-0.97.orig/stage2/asm.S grub-0.97/stage2/asm.S
+--- grub-0.97.orig/stage2/asm.S 2004-06-19 09:55:22.000000000 -0700
++++ grub-0.97/stage2/asm.S 2006-07-04 00:01:19.000000000 -0700
+@@ -1651,7 +1651,29 @@
+ jnz 3f
+ ret
+
+-3: /* use keyboard controller */
++3: /*
++ * try to switch gateA20 using PORT92, the "Fast A20 and Init"
++ * register
++ */
++ mov $0x92, %dx
++ inb %dx, %al
++ /* skip the port92 code if it's unimplemented (read returns 0xff) */
++ cmpb $0xff, %al
++ jz 6f
++
++ /* set or clear bit1, the ALT_A20_GATE bit */
++ movb 4(%esp), %ah
++ testb %ah, %ah
++ jz 4f
++ orb $2, %al
++ jmp 5f
++4: and $0xfd, %al
++
++ /* clear the INIT_NOW bit don't accidently reset the machine */
++5: and $0xfe, %al
++ outb %al, %dx
++
++6: /* use keyboard controller */
+ pushl %eax
+
+ call gloop1
+@@ -1661,9 +1683,12 @@
+
+ gloopint1:
+ inb $K_STATUS
++ cmpb $0xff, %al
++ jz gloopint1_done
+ andb $K_IBUF_FUL, %al
+ jnz gloopint1
+
++gloopint1_done:
+ movb $KB_OUTPUT_MASK, %al
+ cmpb $0, 0x8(%esp)
+ jz gdoit
+@@ -1684,6 +1709,8 @@
+
+ gloop1:
+ inb $K_STATUS
++ cmpb $0xff, %al
++ jz gloop2ret
+ andb $K_IBUF_FUL, %al
+ jnz gloop1
+
+@@ -1991,6 +2018,11 @@
+ ENTRY(console_getkey)
+ push %ebp
+
++wait_for_key:
++ call EXT_C(console_checkkey)
++ incl %eax
++ jz wait_for_key
++
+ call EXT_C(prot_to_real)
+ .code16
+
+@@ -2216,7 +2248,304 @@
+ pop %ebx
+ pop %ebp
+ ret
+-
++
++
++/* graphics mode functions */
++#ifdef SUPPORT_GRAPHICS
++VARIABLE(cursorX)
++.word 0
++VARIABLE(cursorY)
++.word 0
++VARIABLE(cursorCount)
++.word 0
++VARIABLE(cursorBuf)
++.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
++
++
++/*
++ * set_int1c_handler(void)
++ */
++ENTRY(set_int1c_handler)
++ pushl %edi
++
++ /* save the original int1c handler */
++ movl $0x70, %edi
++ movw (%edi), %ax
++ movw %ax, ABS(int1c_offset)
++ movw 2(%edi), %ax
++ movw %ax, ABS(int1c_segment)
++
++ /* save the new int1c handler */
++ movw $ABS(int1c_handler), %ax
++ movw %ax, (%edi)
++ xorw %ax, %ax
++ movw %ax, 2(%edi)
++
++ popl %edi
++ ret
++
++
++/*
++ * unset_int1c_handler(void)
++ */
++ENTRY(unset_int1c_handler)
++ pushl %edi
++
++ /* check if int1c_handler is set */
++ movl $0x70, %edi
++ movw $ABS(int1c_handler), %ax
++ cmpw %ax, (%edi)
++ jne int1c_1
++ xorw %ax, %ax
++ cmpw %ax, 2(%edi)
++ jne int1c_1
++
++ /* restore the original */
++ movw ABS(int1c_offset), %ax
++ movw %ax, (%edi)
++ movw ABS(int1c_segment), %ax
++ movw %ax, 2(%edi)
++
++int1c_1:
++ popl %edi
++ ret
++
++
++/*
++ * blinks graphics cursor
++ */
++ .code16
++write_data:
++ movw $0, %ax
++ movw %ax, %ds
++
++ mov $0xA000, %ax /* video in es:di */
++ mov %ax, %es
++ mov $80, %ax
++ movw $ABS(cursorY), %si
++ mov %ds:(%si), %bx
++ mul %bx
++ movw $ABS(cursorX), %si
++ mov %ds:(%si), %bx
++ shr $3, %bx /* %bx /= 8 */
++ add %bx, %ax
++ mov %ax, %di
++
++ movw $ABS(cursorBuf), %si /* fontBuf in ds:si */
++
++ /* prepare for data moving */
++ mov $16, %dx /* altura da fonte */
++ mov $80, %bx /* bytes por linha */
++
++write_loop:
++ movb %ds:(%si), %al
++ xorb $0xff, %al
++ movb %al, %ds:(%si) /* invert cursorBuf */
++ movb %al, %es:(%di) /* write to video */
++ add %bx, %di
++ inc %si
++ dec %dx
++ jg write_loop
++ ret
++
++int1c_handler:
++ pusha
++ mov $0, %ax
++ mov %ax, %ds
++ mov $ABS(cursorCount), %si
++ mov %ds:(%si), %ax
++ inc %ax
++ mov %ax, %ds:(%si)
++ cmp $9, %ax
++ jne int1c_done
++
++ mov $0, %ax
++ mov %ax, %ds:(%si)
++ call write_data
++
++int1c_done:
++ popa
++ iret
++ /* call previous int1c handler */
++ /* ljmp */
++ .byte 0xea
++int1c_offset: .word 0
++int1c_segment: .word 0
++ .code32
++
++
++/*
++ * unsigned char set_videomode(unsigned char mode)
++ * BIOS call "INT 10H Function 0h" to set video mode
++ * Call with %ah = 0x0
++ * %al = video mode
++ * Returns old videomode.
++ */
++ENTRY(set_videomode)
++ pushl %ebp
++ movl %esp,%ebp
++ pushl %ebx
++ pushl %ecx
++
++ movb 8(%ebp), %cl
++
++ call EXT_C(prot_to_real)
++ .code16
++
++ xorb %al, %al
++ movb $0xf, %ah
++ int $0x10 /* Get Current Video mode */
++ movb %al, %ch
++ xorb %ah, %ah
++ movb %cl, %al
++ int $0x10 /* Set Video mode */
++
++ DATA32 call EXT_C(real_to_prot)
++ .code32
++
++ xorl %eax, %eax
++ movb %ch, %al
++
++ popl %ecx
++ popl %ebx
++ popl %ebp
++ ret
++
++
++/*
++ * int get_videomode()
++ * BIOS call "INT 10H Function 0Fh" to get current video mode
++ * Call with %al = 0x0
++ * %ah = 0xF
++ * Returns current videomode.
++ */
++ENTRY(get_videomode)
++ pushl %ebp
++ movl %esp,%ebp
++ pushl %ebx
++ pushl %ecx
++
++ call EXT_C(prot_to_real)
++ .code16
++
++ xorb %al, %al
++ movb $0xF, %ah
++ int $0x10 /* Get Current Video mode */
++ movb %al, %cl /* For now we only want display mode */
++
++ DATA32 call EXT_C(real_to_prot)
++ .code32
++
++ xorl %eax, %eax
++ movb %cl, %al
++
++ popl %ecx
++ popl %ebx
++ popl %ebp
++ ret
++
++
++/*
++ * unsigned char * graphics_get_font()
++ * BIOS call "INT 10H Function 11h" to set font
++ * Call with %ah = 0x11
++ */
++ENTRY(graphics_get_font)
++ push %ebp
++ push %ebx
++ push %ecx
++ push %edx
++
++ call EXT_C(prot_to_real)
++ .code16
++
++ movw $0x1130, %ax
++ movb $6, %bh /* font 8x16 */
++ int $0x10
++ movw %bp, %dx
++ movw %es, %cx
++
++ DATA32 call EXT_C(real_to_prot)
++ .code32
++
++ xorl %eax, %eax
++ movw %cx, %ax
++ shll $4, %eax
++ movw %dx, %ax
++
++ pop %edx
++ pop %ecx
++ pop %ebx
++ pop %ebp
++ ret
++
++
++/*
++ * graphics_set_palette(index, red, green, blue)
++ * BIOS call "INT 10H Function 10h" to set individual dac register
++ * Call with %ah = 0x10
++ * %bx = register number
++ * %ch = new value for green (0-63)
++ * %cl = new value for blue (0-63)
++ * %dh = new value for red (0-63)
++ */
++
++ENTRY(graphics_set_palette)
++ push %ebp
++ push %eax
++ push %ebx
++ push %ecx
++ push %edx
++
++ movw $0x3c8, %bx /* address write mode register */
++
++ /* wait vertical retrace */
++ movw $0x3da, %dx
++l1b:
++ inb %dx, %al /* wait vertical active display */
++ test $8, %al
++ jnz l1b
++
++l2b:
++ inb %dx, %al /* wait vertical retrace */
++ test $8, %al
++ jnz l2b
++
++ mov %bx, %dx
++ movb 0x18(%esp), %al /* index */
++ outb %al, %dx
++ inc %dx
++
++ movb 0x1c(%esp), %al /* red */
++ outb %al, %dx
++
++ movb 0x20(%esp), %al /* green */
++ outb %al, %dx
++
++ movb 0x24(%esp), %al /* blue */
++ outb %al, %dx
++
++ movw 0x18(%esp), %bx
++
++ call EXT_C(prot_to_real)
++ .code16
++
++ movb %bl, %bh
++ movw $0x1000, %ax
++ int $0x10
++
++ DATA32 call EXT_C(real_to_prot)
++ .code32
++
++ pop %edx
++ pop %ecx
++ pop %ebx
++ pop %eax
++ pop %ebp
++ ret
++#endif /* SUPPORT_GRAPHICS */
++
++
+ /*
+ * getrtsecs()
+ * if a seconds value can be read, read it and return it (BCD),
+diff -Naur grub-0.97.orig/stage2/boot.c grub-0.97/stage2/boot.c
+--- grub-0.97.orig/stage2/boot.c 2004-03-30 03:44:08.000000000 -0800
++++ grub-0.97/stage2/boot.c 2006-07-04 00:01:50.000000000 -0700
+@@ -1,7 +1,7 @@
+ /* boot.c - load and bootstrap a kernel */
+ /*
+ * GRUB -- GRand Unified Bootloader
+- * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
++ * Copyright (C) 1999,2000,2001,2002,2003,2004,2005 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
+@@ -29,6 +29,8 @@
+ entry_func entry_addr;
+ static struct mod_list mll[99];
+ static int linux_mem_size;
++static int elf_kernel_addr;
++static int elf_kernel_size;
+
+ /*
+ * The next two functions, 'load_image' and 'load_module', are the building
+@@ -96,7 +98,7 @@
+ lh = (struct linux_kernel_header *) buffer;
+
+ /* ELF loading supported if multiboot, FreeBSD and NetBSD. */
+- if ((type == KERNEL_TYPE_MULTIBOOT
++ if (((type == KERNEL_TYPE_MULTIBOOT && ! (flags & MULTIBOOT_AOUT_KLUDGE))
+ || pu.elf->e_ident[EI_OSABI] == ELFOSABI_FREEBSD
+ || grub_strcmp (pu.elf->e_ident + EI_BRAND, "FreeBSD") == 0
+ || suggested_type == KERNEL_TYPE_NETBSD)
+@@ -594,6 +596,7 @@
+
+ /* reset this to zero for now */
+ cur_addr = 0;
++ elf_kernel_addr = ~0;
+
+ /* scan for program segments */
+ for (i = 0; i < pu.elf->e_phnum; i++)
+@@ -630,6 +633,8 @@
+ /* mark memory as used */
+ if (cur_addr < memaddr + memsiz)
+ cur_addr = memaddr + memsiz;
++ if (elf_kernel_addr > cur_addr)
++ elf_kernel_addr = cur_addr;
+ printf (", <0x%x:0x%x:0x%x>", memaddr, filesiz,
+ memsiz - filesiz);
+ /* increment number of segments */
+@@ -647,6 +652,8 @@
+ }
+ }
+
++ elf_kernel_size = cur_addr - elf_kernel_addr;
++
+ if (! errnum)
+ {
+ if (! loaded)
+@@ -824,8 +831,11 @@
+ moveto = (mbi.mem_upper + 0x400) << 10;
+
+ moveto = (moveto - len) & 0xfffff000;
+- max_addr = (lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0203
+- ? lh->initrd_addr_max : LINUX_INITRD_MAX_ADDRESS);
++ max_addr = LINUX_INITRD_MAX_ADDRESS;
++ if (lh->header == LINUX_MAGIC_SIGNATURE &&
++ lh->version >= 0x0203 &&
++ lh->initrd_addr_max < max_addr)
++ max_addr = lh->initrd_addr_max;
+ if (moveto + len >= max_addr)
+ moveto = (max_addr - len) & 0xfffff000;
+
+@@ -864,6 +874,129 @@
+ }
+ #endif
+
++#define mem_align4k(p) ((p) + 0xFFF) & 0xFFFFF000
++
++static void
++kfreebsd_setenv (char *env, const char *var, const char *value)
++{
++ while (1)
++ {
++ if (env[0] == '\0' && env[1] == '\0')
++ {
++ env++;
++ break;
++ }
++ else
++ env++;
++ }
++
++ grub_sprintf (env, "%s=%s", var, value);
++ env[grub_strlen (env) + 1] = '\0';
++}
++
++static char *
++kfreebsd_read_hints (char *buf)
++{
++ char *buf_end = buf;
++
++ if (grub_open ("/boot/device.hints"))
++ {
++ char *line_start;
++ int line_len = 0;
++ char *envp;
++ int env_len;
++
++ env_len = grub_read (buf, -1);
++ if (env_len)
++ {
++ buf_end += env_len;
++ *(buf_end++) = '\0';
++ }
++ else
++ return buf_end;
++
++ grub_close ();
++
++ envp = line_start = buf;
++ while (*envp)
++ {
++ char *envp_current = envp;
++
++ switch (*envp)
++ {
++ case ' ':
++ while (*envp == ' ')
++ {
++ envp++;
++ env_len--;
++ }
++ grub_memmove (envp_current, envp, env_len + 1);
++ envp = envp_current;
++ break;
++ case '#':
++ while (*envp != '\n')
++ {
++ envp++;
++ env_len--;
++ }
++ if (!line_len)
++ envp++;
++ grub_memmove (envp_current, envp, env_len + 1);
++ envp = envp_current;
++ break;
++ case '\n':
++ if (!line_len)
++ {
++ env_len--;
++ grub_memmove (line_start, envp, env_len + 1);
++ }
++ *(envp++) = '\0';
++ line_len = 0;
++ line_start = envp;
++ default:
++ envp++;
++ line_len++;
++ break;
++ }
++ }
++
++ buf_end = buf + env_len;
++ *(buf_end++) = '\0';
++ }
++
++ return buf_end;
++}
++
++static u32_t *
++kfreebsd_set_module_string (u32_t type, u32_t *dst, char *src)
++{
++ int size;
++
++ *(dst++) = type;
++ *(dst++) = size = grub_strlen (src) + 1;
++ grub_strcpy ((void *) dst, src);
++
++ return dst + (size + sizeof(u32_t) - 1) / sizeof(u32_t);
++}
++
++static u32_t *
++kfreebsd_set_module_var (u32_t type, u32_t *dst, u32_t src)
++{
++ *(dst++) = type;
++ *(dst++) = sizeof(u32_t);
++ *(dst++) = src;
++
++ return dst;
++}
++
++static u32_t *
++kfreebsd_set_modules (u32_t *modulep)
++{
++ /* XXX: Need to copy the whole module structure. */
++ /* XXX: How to pass the module name ? */
++
++ return modulep;
++}
+
+ /*
+ * All "*_boot" commands depend on the images being loaded into memory
+@@ -877,7 +1010,10 @@
+ bsd_boot (kernel_t type, int bootdev, char *arg)
+ {
+ char *str;
+- int clval = 0, i;
++ char *kernelname;
++ char *bsd_root;
++ int clval = 0;
++ int i;
+ struct bootinfo bi;
+
+ #ifdef GRUB_UTIL
+@@ -886,8 +1022,21 @@
+ stop_floppy ();
+ #endif
+
++ while (*arg != '/')
++ arg++;
++ kernelname = arg;
++
+ while (*(++arg) && *arg != ' ');
++ *(arg++) = 0;
+ str = arg;
++
++ bsd_root = grub_strstr (str, "root=");
++ if (bsd_root)
++ {
++ bsd_root += 5;
++ /* XXX: should copy the str or terminate it. */
++ }
++
+ while (*str)
+ {
+ if (*str == '-')
+@@ -910,6 +1059,8 @@
+ clval |= RB_GDB;
+ if (*str == 'h')
+ clval |= RB_SERIAL;
++ if (*str == 'p')
++ clval |= RB_PAUSE;
+ if (*str == 'm')
+ clval |= RB_MUTE;
+ if (*str == 'r')
+@@ -927,14 +1078,17 @@
+
+ if (type == KERNEL_TYPE_FREEBSD)
+ {
++ char *envp;
++ u32_t *modp;
++
+ clval |= RB_BOOTINFO;
+
+ bi.bi_version = BOOTINFO_VERSION;
+
+- *arg = 0;
+- while ((--arg) > (char *) MB_CMDLINE_BUF && *arg != '/');
+- if (*arg == '/')
+- bi.bi_kernelname = arg + 1;
++ bi.bi_pad[0] = bi.bi_pad[1] = 0;
++
++ if (*kernelname == '/')
++ bi.bi_kernelname = kernelname;
+ else
+ bi.bi_kernelname = 0;
+
+@@ -961,6 +1115,30 @@
+ bi.bi_basemem = mbi.mem_lower;
+ bi.bi_extmem = extended_memory;
+
++ /* Setup the environment. */
++ bi.bi_envp = cur_addr = mem_align4k (cur_addr);
++ grub_memset ((void *) cur_addr, 0, 2);
++ cur_addr = (int) kfreebsd_read_hints ((void *) cur_addr);
++
++ envp = (char *) bi.bi_envp;
++ kfreebsd_setenv (envp, "kernelname", kernelname);
++ kfreebsd_setenv (envp, "vfs.root.mountfrom", bsd_root);
++
++ /* Setup the modules list. */
++ bi.bi_modulep = cur_addr = mem_align4k (cur_addr);
++ modp = (u32_t *) bi.bi_modulep;
++ /* The first module is the kernel. */
++ modp = kfreebsd_set_module_string (MODINFO_NAME, modp, kernelname);
++ modp = kfreebsd_set_module_string (MODINFO_TYPE, modp, "elf kernel");
++ modp = kfreebsd_set_module_string (MODINFO_ARGS, modp, arg);
++ modp = kfreebsd_set_module_var (MODINFO_ADDR, modp, elf_kernel_addr);
++ modp = kfreebsd_set_module_var (MODINFO_SIZE, modp, elf_kernel_size);
++ /* Now the real modules. */
++ modp = kfreebsd_set_modules(modp);
++
++ /* Set the kernel end. */
++ bi.bi_kernend = cur_addr = mem_align4k (((int) modp) + 1);
++
+ if (mbi.flags & MB_INFO_AOUT_SYMS)
+ {
+ bi.bi_symtab = mbi.syms.a.addr;
+@@ -970,8 +1148,9 @@
+ #if 0
+ else if (mbi.flags & MB_INFO_ELF_SHDR)
+ {
+- /* FIXME: Should check if a symbol table exists and, if exists,
+- pass the table to BI. */
++ bi.bi_symtab = mbi.syms.e.addr;
++ bi.bi_esymtab = mbi.syms.e.addr
++ + mbi.syms.e.size * mbi.syms.e.num * mbi.syms.e.shndx;
+ }
+ #endif
+ else
+diff -Naur grub-0.97.orig/stage2/builtins.c grub-0.97/stage2/builtins.c
+--- grub-0.97.orig/stage2/builtins.c 2005-02-15 13:58:23.000000000 -0800
++++ grub-0.97/stage2/builtins.c 2006-07-04 00:01:50.000000000 -0700
+@@ -28,6 +28,10 @@
+ #include <filesys.h>
+ #include <term.h>
+
++#ifdef SUPPORT_GRAPHICS
++# include <graphics.h>
++#endif
++
+ #ifdef SUPPORT_NETBOOT
+ # define GRUB 1
+ # include <etherboot.h>
+@@ -82,6 +86,10 @@
+ inside other functions. */
+ static int configfile_func (char *arg, int flags);
+
++static int savedefault_helper (char *arg, int flags);
++
++static int savedefault_shell (char *arg, int flags);
++
+ /* Initialize the data for builtins. */
+ void
+ init_builtins (void)
+@@ -237,12 +245,22 @@
+ static int
+ boot_func (char *arg, int flags)
+ {
++ struct term_entry *prev_term = current_term;
+ /* Clear the int15 handler if we can boot the kernel successfully.
+ This assumes that the boot code never fails only if KERNEL_TYPE is
+ not KERNEL_TYPE_NONE. Is this assumption is bad? */
+ if (kernel_type != KERNEL_TYPE_NONE)
+ unset_int15_handler ();
+
++ /* if our terminal needed initialization, we should shut it down
++ * before booting the kernel, but we want to save what it was so
++ * we can come back if needed */
++ if (current_term->shutdown)
++ {
++ current_term->shutdown();
++ current_term = term_table; /* assumption: console is first */
++ }
++
+ #ifdef SUPPORT_NETBOOT
+ /* Shut down the networking. */
+ cleanup_net ();
+@@ -306,6 +324,13 @@
+ return 1;
+ }
+
++ /* if we get back here, we should go back to what our term was before */
++ current_term = prev_term;
++ if (current_term->startup)
++ /* if our terminal fails to initialize, fall back to console since
++ * it should always work */
++ if (current_term->startup() == 0)
++ current_term = term_table; /* we know that console is first */
+ return 0;
+ }
+
+@@ -852,6 +877,251 @@
+ };
+ #endif /* SUPPORT_NETBOOT */
+
++#ifdef SUPPORT_GRAPHICS
++\f
++static int splashimage_func(char *arg, int flags) {
++ int i;
++
++ /* filename can only be 256 characters due to our buffer size */
++ if (grub_strlen(arg) > 256) {
++ grub_printf("Splash image filename too large\n");
++ grub_printf("Press any key to continue...");
++ getkey();
++ return 1;
++ }
++
++ /* get rid of TERM_NEED_INIT from the graphics terminal. */
++ for (i = 0; term_table[i].name; i++) {
++ if (grub_strcmp (term_table[i].name, "graphics") == 0) {
++ term_table[i].flags &= ~TERM_NEED_INIT;
++ break;
++ }
++ }
++
++ graphics_set_splash(arg);
++
++ if (flags == BUILTIN_CMDLINE && graphics_inited) {
++ graphics_end();
++ if (graphics_init() == 0) {
++ /* Fallback to default term */
++ current_term = term_table;
++ max_lines = current_term->max_lines;
++ if (current_term->cls)
++ current_term->cls();
++ grub_printf("Failed to set splash image and/or graphics mode\n");
++ return 1;
++ }
++ graphics_cls();
++ }
++
++ if (flags == BUILTIN_MENU)
++ current_term = term_table + i;
++
++ return 0;
++}
++
++static struct builtin builtin_splashimage =
++{
++ "splashimage",
++ splashimage_func,
++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++ "splashimage FILE",
++ "Load FILE as the background image when in graphics mode."
++};
++
++\f
++/* shade */
++static int
++shade_func(char *arg, int flags)
++{
++ int new_shade;
++
++ if (!arg || safe_parse_maxint(&arg, &new_shade) == 0)
++ return (1);
++
++ if (shade != new_shade) {
++ shade = new_shade;
++ if (flags == BUILTIN_CMDLINE && graphics_inited) {
++ graphics_end();
++ graphics_init();
++ graphics_cls();
++ }
++ }
++
++ return 0;
++}
++
++static struct builtin builtin_shade =
++{
++ "shade",
++ shade_func,
++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++ "shade INTEGER",
++ "If set to 0, disables the use of shaded text, else enables it."
++};
++
++\f
++/* 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."
++};
++
++\f
++/* 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."
++};
++
++\f
++/* border */
++static int
++border_func(char *arg, int flags)
++{
++ if (grub_strlen(arg) == 6) {
++ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
++ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
++ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
++
++ window_border = (r << 16) | (g << 8) | b;
++ if (graphics_inited)
++ graphics_set_palette(0x11, r, g, b);
++
++ return 0;
++ }
++
++ return 1;
++}
++
++static struct builtin builtin_border =
++{
++ "border",
++ border_func,
++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++ "border RRGGBB",
++ "Sets the border video color when in graphics mode."
++ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
++};
++
++\f
++/* viewport */
++static int
++viewport_func (char *arg, int flags)
++{
++ int i;
++ int x0 = 0, y0 = 0, x1 = 80, y1 = 30;
++ int *pos[4] = { &x0, &y0, &x1, &y1 };
++
++ if (!arg)
++ return (1);
++ for (i = 0; i < 4; i++) {
++ if (!*arg)
++ return (1);
++ while (*arg && (*arg == ' ' || *arg == '\t'))
++ ++arg;
++ if (!safe_parse_maxint(&arg, pos[i]))
++ return (1);
++ while (*arg && (*arg != ' ' && *arg != '\t'))
++ ++arg;
++ }
++
++ /* minimum size is 65 colums and 16 rows */
++ if (x0 > x1 - 66 || y0 > y1 - 16 || x0 < 0 || y0 < 0 || x1 > 80 || y1 > 30)
++ return 1;
++
++ view_x0 = x0;
++ view_y0 = y0;
++ view_x1 = x1;
++ view_y1 = y1;
++
++ if (flags == BUILTIN_CMDLINE && graphics_inited) {
++ graphics_end();
++ graphics_init();
++ graphics_cls();
++ }
++
++ return 0;
++}
++
++static struct builtin builtin_viewport =
++{
++ "viewport",
++ viewport_func,
++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
++ "viewport x0 y0 x1 y1",
++ "Changes grub internals to output text in the window defined by"
++ " four parameters. The x and y parameters are 0 based. This option"
++ " only works with the graphics interface."
++};
++
++#endif /* SUPPORT_GRAPHICS */
++
++\f
++/* 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"
++};
++
+ \f
+ /* displayapm */
+ static int
+@@ -1454,14 +1724,20 @@
+
+ \f
+ /* help */
+-#define MAX_SHORT_DOC_LEN 39
+-#define MAX_LONG_DOC_LEN 66
+-
+ static int
+ help_func (char *arg, int flags)
+ {
+- int all = 0;
+-
++ int all = 0, max_short_doc_len, max_long_doc_len;
++ max_short_doc_len = 39;
++ max_long_doc_len = 66;
++#ifdef SUPPORT_GRAPHICS
++ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0)
++ {
++ max_short_doc_len = (view_x1 - view_x0 + 1) / 2 - 1;
++ max_long_doc_len = (view_x1 - view_x0) - 14;
++ }
++#endif
++
+ if (grub_memcmp (arg, "--all", sizeof ("--all") - 1) == 0)
+ {
+ all = 1;
+@@ -1491,13 +1767,13 @@
+
+ len = grub_strlen ((*builtin)->short_doc);
+ /* If the length of SHORT_DOC is too long, truncate it. */
+- if (len > MAX_SHORT_DOC_LEN - 1)
+- len = MAX_SHORT_DOC_LEN - 1;
++ if (len > max_short_doc_len - 1)
++ len = max_short_doc_len - 1;
+
+ for (i = 0; i < len; i++)
+ grub_putchar ((*builtin)->short_doc[i]);
+
+- for (; i < MAX_SHORT_DOC_LEN; i++)
++ for (; i < max_short_doc_len; i++)
+ grub_putchar (' ');
+
+ if (! left)
+@@ -1546,10 +1822,10 @@
+ int i;
+
+ /* If LEN is too long, fold DOC. */
+- if (len > MAX_LONG_DOC_LEN)
++ if (len > max_long_doc_len)
+ {
+ /* Fold this line at the position of a space. */
+- for (len = MAX_LONG_DOC_LEN; len > 0; len--)
++ for (len = max_long_doc_len; len > 0; len--)
+ if (doc[len - 1] == ' ')
+ break;
+ }
+@@ -2323,6 +2599,25 @@
+ "Probe I/O ports used for the drive DRIVE."
+ };
+
++/* print */
++static int
++print_func (char *arg, int flags)
++{
++ printf("%s\n", arg);
++
++ return 0;
++}
++
++static struct builtin builtin_print =
++{
++ "print",
++ print_func,
++ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_NO_ECHO,
++ "print [MESSAGE ...]",
++ "Print MESSAGE."
++};
++
++
+ \f
+ /* kernel */
+ static int
+@@ -3221,7 +3516,102 @@
+ static int
+ savedefault_func (char *arg, int flags)
+ {
+-#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
++#if !defined(SUPPORT_DISKLESS)
++ #if !defined(GRUB_UTIL)
++ savedefault_helper(arg, flags);
++ #else
++ savedefault_shell(arg, flags);
++ #endif
++#else /* !SUPPORT_DISKLESS */
++ errnum = ERR_UNRECOGNIZED;
++ return 1;
++#endif /* !SUPPORT_DISKLESS */
++}
++
++#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL)
++/* savedefault_shell */
++static int
++savedefault_shell(char *arg, int flags)
++ {
++ int once_only = 0;
++ int new_default;
++ int curr_default = -1;
++ int curr_prev_default = -1;
++ int new_prev_default = -1;
++ FILE *fp;
++ size_t bytes = 10;
++ char line[bytes];
++ char *default_file = (char *) DEFAULT_FILE_BUF;
++ char buf[bytes];
++ int i;
++
++ while (1)
++ {
++ if (grub_memcmp ("--default=", arg, sizeof ("--default=") - 1) == 0)
++ {
++ char *p = arg + sizeof ("--default=") - 1;
++ if (! safe_parse_maxint (&p, &new_default))
++ return 1;
++ arg = skip_to (0, arg);
++ }
++ else if (grub_memcmp ("--once", arg, sizeof ("--once") - 1) == 0)
++ {
++ once_only = 1;
++ arg = skip_to (0, arg);
++ }
++ else
++ break;
++ }
++
++ *default_file = 0;
++ grub_strncat (default_file, config_file, DEFAULT_FILE_BUFLEN);
++ for (i = grub_strlen(default_file); i >= 0; i--)
++ if (default_file[i] == '/')
++ {
++ i++;
++ break;
++ }
++ default_file[i] = 0;
++ grub_strncat (default_file + i, "default", DEFAULT_FILE_BUFLEN - i);
++
++ if(!(fp = fopen(default_file,"w")))
++ {
++ errnum = ERR_READ;
++ goto fail;
++ }
++
++ read(&line, -1);
++
++ sscanf(line, "%d:%d", &curr_prev_default, &curr_default);
++
++ if(curr_default != -1)
++ new_prev_default = curr_default;
++ else
++ {
++ if(curr_prev_default != -1)
++ new_prev_default = curr_prev_default;
++ else
++ new_prev_default = 0;
++ }
++
++ if(once_only)
++ sprintf(buf, "%d:%d\n", new_prev_default, new_default);
++ else
++ sprintf(buf, "%d\n", new_default);
++
++ fprintf(fp, buf);
++
++fail:
++ fclose(fp);
++ return errnum;
++}
++#endif
++
++/* savedefault_helper */
++static int
++savedefault_helper (char *arg, int flags)
++{
++#if !defined(SUPPORT_DISKLESS)
+ unsigned long tmp_drive = saved_drive;
+ unsigned long tmp_partition = saved_partition;
+ char *default_file = (char *) DEFAULT_FILE_BUF;
+@@ -3300,19 +3690,23 @@
+ disk_read_hook = 0;
+ grub_close ();
+
+- if (len != sizeof (buf))
+- {
+- /* This is too small. Do not modify the file manually, please! */
+- errnum = ERR_READ;
+- goto fail;
+- }
+-
+ if (sector_count > 2)
+ {
+ /* Is this possible?! Too fragmented! */
+ errnum = ERR_FSYS_CORRUPT;
+ goto fail;
+ }
++
++ char *tmp;
++ if((tmp = grub_strstr(buf, ":")) != NULL)
++ {
++ int f_len = grub_strlen(buf) - grub_strlen(tmp);
++ char *def;
++ int a;
++ for(a = 0; a < f_len; a++)
++ grub_memcpy(&def[a], &buf[a], sizeof(char));
++ safe_parse_maxint (&def, &entryno);
++ }
+
+ /* Set up a string to be written. */
+ grub_memset (buf, '\n', sizeof (buf));
+@@ -3830,15 +4224,15 @@
+ {
+ char tmp[16];
+ grub_sprintf (tmp, ",%d", (partition >> 16) & 0xFF);
+- grub_strncat (device, tmp, 256);
++ grub_strncat (device, tmp, sizeof (device));
+ }
+ if ((partition & 0x00FF00) != 0x00FF00)
+ {
+ char tmp[16];
+ grub_sprintf (tmp, ",%c", 'a' + ((partition >> 8) & 0xFF));
+- grub_strncat (device, tmp, 256);
++ grub_strncat (device, tmp, sizeof (device));
+ }
+- grub_strncat (device, ")", 256);
++ grub_strncat (device, ")", sizeof (device));
+ }
+
+ int embed_stage1_5 (char *stage1_5, int drive, int partition)
+@@ -4085,7 +4479,7 @@
+ };
+
+ \f
+-#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 +4638,29 @@
+ end:
+ current_term = term_table + default_term;
+ current_term->flags = term_flags;
+-
++
+ if (lines)
+ max_lines = lines;
+ else
+- /* 24 would be a good default value. */
+- max_lines = 24;
+-
++ max_lines = current_term->max_lines;
++
+ /* If the interface is currently the command-line,
+ restart it to repaint the screen. */
+- if (current_term != prev_term && (flags & BUILTIN_CMDLINE))
++ if ((current_term != prev_term) && (flags & BUILTIN_CMDLINE)){
++ if (prev_term->shutdown)
++ prev_term->shutdown();
++ if (current_term->startup) {
++ /* If startup fails, return to previous term */
++ if (current_term->startup() == 0) {
++ current_term = prev_term;
++ max_lines = current_term->max_lines;
++ if (current_term->cls) {
++ current_term->cls();
++ }
++ }
++ }
+ grub_longjmp (restart_cmdline_env, 0);
++ }
+
+ return 0;
+ }
+@@ -4264,7 +4670,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 +4682,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 */
+
+ \f
+ #ifdef SUPPORT_SERIAL
+@@ -4795,13 +5201,20 @@
+ /* The table of builtin commands. Sorted in dictionary order. */
+ struct builtin *builtin_table[] =
+ {
++#ifdef SUPPORT_GRAPHICS
++ &builtin_background,
++#endif
+ &builtin_blocklist,
+ &builtin_boot,
+ #ifdef SUPPORT_NETBOOT
+ &builtin_bootp,
+ #endif /* SUPPORT_NETBOOT */
++#ifdef SUPPORT_GRAPHICS
++ &builtin_border,
++#endif
+ &builtin_cat,
+ &builtin_chainloader,
++ &builtin_clear,
+ &builtin_cmp,
+ &builtin_color,
+ &builtin_configfile,
+@@ -4821,6 +5234,9 @@
+ &builtin_embed,
+ &builtin_fallback,
+ &builtin_find,
++#ifdef SUPPORT_GRAPHICS
++ &builtin_foreground,
++#endif
+ &builtin_fstest,
+ &builtin_geometry,
+ &builtin_halt,
+@@ -4848,6 +5264,7 @@
+ &builtin_parttype,
+ &builtin_password,
+ &builtin_pause,
++ &builtin_print,
+ #ifdef GRUB_UTIL
+ &builtin_quit,
+ #endif /* GRUB_UTIL */
+@@ -4864,9 +5281,13 @@
+ #endif /* SUPPORT_SERIAL */
+ &builtin_setkey,
+ &builtin_setup,
+-#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
++#ifdef SUPPORT_GRAPHICS
++ &builtin_shade,
++ &builtin_splashimage,
++#endif /* SUPPORT_GRAPHICS */
++#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
+ &builtin_terminal,
+-#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
++#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
+ #ifdef SUPPORT_SERIAL
+ &builtin_terminfo,
+ #endif /* SUPPORT_SERIAL */
+@@ -4880,5 +5301,8 @@
+ &builtin_unhide,
+ &builtin_uppermem,
+ &builtin_vbeprobe,
++#ifdef SUPPORT_GRAPHICS
++ &builtin_viewport,
++#endif
+ 0
+ };
+diff -Naur grub-0.97.orig/stage2/char_io.c grub-0.97/stage2/char_io.c
+--- grub-0.97.orig/stage2/char_io.c 2005-02-01 12:51:23.000000000 -0800
++++ grub-0.97/stage2/char_io.c 2006-07-03 23:59:27.000000000 -0700
+@@ -29,12 +29,17 @@
+ # include <serial.h>
+ #endif
+
++#ifdef SUPPORT_GRAPHICS
++# include <graphics.h>
++#endif
++
+ #ifndef STAGE1_5
+ struct term_entry term_table[] =
+ {
+ {
+ "console",
+ 0,
++ 24,
+ console_putchar,
+ console_checkkey,
+ console_getkey,
+@@ -43,13 +48,16 @@
+ console_cls,
+ console_setcolorstate,
+ console_setcolor,
+- console_setcursor
++ console_setcursor,
++ 0,
++ 0
+ },
+ #ifdef SUPPORT_SERIAL
+ {
+ "serial",
+ /* A serial device must be initialized. */
+ TERM_NEED_INIT,
++ 24,
+ serial_putchar,
+ serial_checkkey,
+ serial_getkey,
+@@ -58,6 +66,8 @@
+ serial_cls,
+ serial_setcolorstate,
+ 0,
++ 0,
++ 0,
+ 0
+ },
+ #endif /* SUPPORT_SERIAL */
+@@ -65,6 +75,7 @@
+ {
+ "hercules",
+ 0,
++ 24,
+ hercules_putchar,
+ console_checkkey,
+ console_getkey,
+@@ -73,11 +84,30 @@
+ hercules_cls,
+ hercules_setcolorstate,
+ hercules_setcolor,
+- hercules_setcursor
++ hercules_setcursor,
++ 0,
++ 0
+ },
+ #endif /* SUPPORT_HERCULES */
++#ifdef SUPPORT_GRAPHICS
++ { "graphics",
++ TERM_NEED_INIT, /* flags */
++ 30, /* number of lines */
++ graphics_putchar, /* putchar */
++ console_checkkey, /* checkkey */
++ console_getkey, /* getkey */
++ graphics_getxy, /* getxy */
++ graphics_gotoxy, /* gotoxy */
++ graphics_cls, /* cls */
++ graphics_setcolorstate, /* setcolorstate */
++ graphics_setcolor, /* setcolor */
++ graphics_setcursor, /* nocursor */
++ graphics_init, /* initialize */
++ graphics_end /* shutdown */
++ },
++#endif /* SUPPORT_GRAPHICS */
+ /* This must be the last entry. */
+- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ };
+
+ /* This must be console. */
+@@ -305,9 +335,10 @@
+
+ /* XXX: These should be defined in shared.h, but I leave these here,
+ until this code is freezed. */
+-#define CMDLINE_WIDTH 78
+ #define CMDLINE_MARGIN 10
+-
++
++ /* command-line limits */
++ int cmdline_width = 78, col_start = 0;
+ int xpos, lpos, c, section;
+ /* The length of PROMPT. */
+ int plen;
+@@ -338,7 +369,7 @@
+
+ /* If the cursor is in the first section, display the first section
+ instead of the second. */
+- if (section == 1 && plen + lpos < CMDLINE_WIDTH)
++ if (section == 1 && plen + lpos < cmdline_width)
+ cl_refresh (1, 0);
+ else if (xpos - count < 1)
+ cl_refresh (1, 0);
+@@ -354,7 +385,7 @@
+ grub_putchar ('\b');
+ }
+ else
+- gotoxy (xpos, getxy () & 0xFF);
++ gotoxy (xpos + col_start, getxy () & 0xFF);
+ }
+ }
+
+@@ -364,7 +395,7 @@
+ lpos += count;
+
+ /* If the cursor goes outside, scroll the screen to the right. */
+- if (xpos + count >= CMDLINE_WIDTH)
++ if (xpos + count >= cmdline_width)
+ cl_refresh (1, 0);
+ else
+ {
+@@ -383,7 +414,7 @@
+ }
+ }
+ else
+- gotoxy (xpos, getxy () & 0xFF);
++ gotoxy (xpos + col_start, getxy () & 0xFF);
+ }
+ }
+
+@@ -398,14 +429,14 @@
+ if (full)
+ {
+ /* Recompute the section number. */
+- if (lpos + plen < CMDLINE_WIDTH)
++ if (lpos + plen < cmdline_width)
+ section = 0;
+ else
+- section = ((lpos + plen - CMDLINE_WIDTH)
+- / (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) + 1);
++ section = ((lpos + plen - cmdline_width)
++ / (cmdline_width - 1 - CMDLINE_MARGIN) + 1);
+
+ /* From the start to the end. */
+- len = CMDLINE_WIDTH;
++ len = cmdline_width;
+ pos = 0;
+ grub_putchar ('\r');
+
+@@ -445,8 +476,8 @@
+ if (! full)
+ offset = xpos - 1;
+
+- start = ((section - 1) * (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN)
+- + CMDLINE_WIDTH - plen - CMDLINE_MARGIN);
++ start = ((section - 1) * (cmdline_width - 1 - CMDLINE_MARGIN)
++ + cmdline_width - plen - CMDLINE_MARGIN);
+ xpos = lpos + 1 - start;
+ start += offset;
+ }
+@@ -471,7 +502,7 @@
+
+ /* If the cursor is at the last position, put `>' or a space,
+ depending on if there are more characters in BUF. */
+- if (pos == CMDLINE_WIDTH)
++ if (pos == cmdline_width)
+ {
+ if (start + len < llen)
+ grub_putchar ('>');
+@@ -488,7 +519,7 @@
+ grub_putchar ('\b');
+ }
+ else
+- gotoxy (xpos, getxy () & 0xFF);
++ gotoxy (xpos + col_start, getxy () & 0xFF);
+ }
+
+ /* Initialize the command-line. */
+@@ -518,10 +549,10 @@
+
+ llen += l;
+ lpos += l;
+- if (xpos + l >= CMDLINE_WIDTH)
++ if (xpos + l >= cmdline_width)
+ cl_refresh (1, 0);
+- else if (xpos + l + llen - lpos > CMDLINE_WIDTH)
+- cl_refresh (0, CMDLINE_WIDTH - xpos);
++ else if (xpos + l + llen - lpos > cmdline_width)
++ cl_refresh (0, cmdline_width - xpos);
+ else
+ cl_refresh (0, l + llen - lpos);
+ }
+@@ -533,12 +564,22 @@
+ grub_memmove (buf + lpos, buf + lpos + count, llen - count + 1);
+ llen -= count;
+
+- if (xpos + llen + count - lpos > CMDLINE_WIDTH)
+- cl_refresh (0, CMDLINE_WIDTH - xpos);
++ if (xpos + llen + count - lpos > cmdline_width)
++ cl_refresh (0, cmdline_width - xpos);
+ else
+ cl_refresh (0, llen + count - lpos);
+ }
+
++ max_lines = current_term->max_lines;
++#ifdef SUPPORT_GRAPHICS
++ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0)
++ {
++ cmdline_width = (view_x1 - view_x0) - 2;
++ col_start = view_x0;
++ max_lines = view_y1 - view_y0;
++ }
++#endif
++
+ plen = grub_strlen (prompt);
+ llen = grub_strlen (cmdline);
+
+@@ -1006,6 +1047,48 @@
+ }
+ #endif /* ! STAGE1_5 */
+
++#ifndef STAGE1_5
++/* Internal pager. */
++int
++do_more (void)
++{
++ if (count_lines >= 0)
++ {
++ count_lines++;
++ if (count_lines >= max_lines - 2)
++ {
++ int tmp;
++
++ /* It's important to disable the feature temporarily, because
++ the following grub_printf call will print newlines. */
++ count_lines = -1;
++
++ grub_printf("\n");
++ if (current_term->setcolorstate)
++ current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
++
++ grub_printf ("[Hit return to continue]");
++
++ if (current_term->setcolorstate)
++ current_term->setcolorstate (COLOR_STATE_NORMAL);
++
++
++ do
++ {
++ tmp = ASCII_CHAR (getkey ());
++ }
++ while (tmp != '\n' && tmp != '\r');
++ grub_printf ("\r \r");
++
++ /* Restart to count lines. */
++ count_lines = 0;
++ return 1;
++ }
++ }
++ return 0;
++}
++#endif
++
+ /* Display an ASCII character. */
+ void
+ grub_putchar (int c)
+@@ -1034,38 +1117,11 @@
+
+ if (c == '\n')
+ {
++ int flag;
+ /* Internal `more'-like feature. */
+- if (count_lines >= 0)
+- {
+- count_lines++;
+- if (count_lines >= max_lines - 2)
+- {
+- int tmp;
+-
+- /* It's important to disable the feature temporarily, because
+- the following grub_printf call will print newlines. */
+- count_lines = -1;
+-
+- if (current_term->setcolorstate)
+- current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
+-
+- grub_printf ("\n[Hit return to continue]");
+-
+- if (current_term->setcolorstate)
+- current_term->setcolorstate (COLOR_STATE_NORMAL);
+-
+- do
+- {
+- tmp = ASCII_CHAR (getkey ());
+- }
+- while (tmp != '\n' && tmp != '\r');
+- grub_printf ("\r \r");
+-
+- /* Restart to count lines. */
+- count_lines = 0;
+- return;
+- }
+- }
++ flag = do_more ();
++ if (flag)
++ return;
+ }
+
+ current_term->putchar (c);
+@@ -1090,7 +1146,7 @@
+ cls (void)
+ {
+ /* If the terminal is dumb, there is no way to clean the terminal. */
+- if (current_term->flags & TERM_DUMB)
++ if (current_term->flags & TERM_DUMB)
+ grub_putchar ('\n');
+ else
+ current_term->cls ();
+@@ -1175,13 +1231,13 @@
+ #endif /* ! STAGE1_5 */
+
+ int
+-memcheck (int addr, int len)
++memcheck (unsigned long int addr, unsigned long int len)
+ {
+ #ifdef GRUB_UTIL
+- auto int start_addr (void);
+- auto int end_addr (void);
++ auto unsigned long int start_addr (void);
++ auto int unsigned long end_addr (void);
+
+- auto int start_addr (void)
++ auto unsigned long int start_addr (void)
+ {
+ int ret;
+ # if defined(HAVE_START_SYMBOL)
+@@ -1192,7 +1248,7 @@
+ return ret;
+ }
+
+- auto int end_addr (void)
++ auto unsigned long int end_addr (void)
+ {
+ int ret;
+ # if defined(HAVE_END_SYMBOL)
+@@ -1217,6 +1273,16 @@
+ return ! errnum;
+ }
+
++void
++grub_memcpy(void *dest, const void *src, int len)
++{
++ int i;
++ register char *d = (char*)dest, *s = (char*)src;
++
++ for (i = 0; i < len; i++)
++ d[i] = s[i];
++}
++
+ void *
+ grub_memmove (void *to, const void *from, int len)
+ {
+diff -Naur grub-0.97.orig/stage2/cmdline.c grub-0.97/stage2/cmdline.c
+--- grub-0.97.orig/stage2/cmdline.c 2004-08-16 16:23:01.000000000 -0700
++++ grub-0.97/stage2/cmdline.c 2006-07-03 23:58:41.000000000 -0700
+@@ -50,10 +50,11 @@
+ void
+ print_cmdline_message (int forever)
+ {
+- printf (" [ Minimal BASH-like line editing is supported. For the first word, TAB\n"
+- " lists possible command completions. Anywhere else TAB lists the possible\n"
+- " completions of a device/filename.%s ]\n",
+- (forever ? "" : " ESC at any time exits."));
++ grub_printf(" [ Minimal BASH-like line editing is supported. For\n"
++ " the first word, TAB lists possible command\n"
++ " completions. Anywhere else TAB lists the possible\n"
++ " completions of a device/filename.%s ]\n",
++ (forever ? "" : " ESC at any time\n exits."));
+ }
+
+ /* Find the builtin whose command name is COMMAND and return the
+diff -Naur grub-0.97.orig/stage2/freebsd.h grub-0.97/stage2/freebsd.h
+--- grub-0.97.orig/stage2/freebsd.h 2003-07-09 04:45:52.000000000 -0700
++++ grub-0.97/stage2/freebsd.h 2006-07-03 23:59:36.000000000 -0700
+@@ -1,7 +1,7 @@
+
+ /*
+ * GRUB -- GRand Unified Bootloader
+- * Copyright (C) 2001 Free Software Foundation, Inc.
++ * Copyright (C) 2001, 2004 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
+@@ -35,6 +35,10 @@
+ #define RB_CDROM 0x2000 /* use cdrom as root */
+ #define RB_GDB 0x8000 /* use GDB remote debugger instead of DDB */
+ #define RB_MUTE 0x10000 /* Come up with the console muted */
++#define RB_SELFTEST 0x20000 /* don't complete the boot; do selftest */
++#define RB_RESERVED1 0x40000 /* reserved for internal use of boot blocks */
++#define RB_RESERVED2 0x80000 /* reserved for internal use of boot blocks */
++#define RB_PAUSE 0x100000 /* pause after each output line during probe */
+ #define RB_MULTIPLE 0x20000000 /* Use multiple consoles */
+
+ #define RB_BOOTINFO 0x80000000 /* have `struct bootinfo *' arg */
+@@ -70,6 +74,9 @@
+
+ #define N_BIOS_GEOM 8
+
++typedef unsigned char u8_t;
++typedef unsigned int u32_t;
++
+ /*
+ * A zero bootinfo field often means that there is no info available.
+ * Flags are used to indicate the validity of fields where zero is a
+@@ -77,19 +84,33 @@
+ */
+ struct bootinfo
+ {
+- unsigned int bi_version;
+- unsigned char *bi_kernelname;
+- struct nfs_diskless *bi_nfs_diskless;
++ u32_t bi_version;
++ u8_t *bi_kernelname;
++ u32_t bi_nfs_diskless;
+ /* End of fields that are always present. */
+ #define bi_endcommon bi_n_bios_used
+- unsigned int bi_n_bios_used;
+- unsigned long bi_bios_geom[N_BIOS_GEOM];
+- unsigned int bi_size;
+- unsigned char bi_memsizes_valid;
+- unsigned char bi_bios_dev;
+- unsigned char bi_pad[2];
+- unsigned long bi_basemem;
+- unsigned long bi_extmem;
+- unsigned long bi_symtab;
+- unsigned long bi_esymtab;
++ u32_t bi_n_bios_used;
++ u32_t bi_bios_geom[N_BIOS_GEOM];
++ u32_t bi_size;
++ u8_t bi_memsizes_valid;
++ u8_t bi_bios_dev;
++ u8_t bi_pad[2];
++ u32_t bi_basemem;
++ u32_t bi_extmem;
++ u32_t bi_symtab;
++ u32_t bi_esymtab;
++ /* Items below only from advanced bootloader */
++ u32_t bi_kernend;
++ u32_t bi_envp;
++ u32_t bi_modulep;
+ };
++
++#define MODINFO_END 0x0000 /* End of list */
++#define MODINFO_NAME 0x0001 /* Name of module (string) */
++#define MODINFO_TYPE 0x0002 /* Type of module (string) */
++#define MODINFO_ADDR 0x0003 /* Loaded address */
++#define MODINFO_SIZE 0x0004 /* Size of module */
++#define MODINFO_EMPTY 0x0005 /* Has been deleted */
++#define MODINFO_ARGS 0x0006 /* Parameters string */
++#define MODINFO_METADATA 0x8000 /* Module-specfic */
++
+diff -Naur grub-0.97.orig/stage2/graphics.c grub-0.97/stage2/graphics.c
+--- grub-0.97.orig/stage2/graphics.c 1969-12-31 16:00:00.000000000 -0800
++++ grub-0.97/stage2/graphics.c 2006-07-03 23:58:41.000000000 -0700
+@@ -0,0 +1,585 @@
++/*
++ * 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>
++ * Options and enhancements made by Herton Ronaldo Krzesinski
++ * <herton@mandriva.com>
++ *
++ * GRUB -- GRand Unified Bootloader
++ * Copyright (C) 2001,2002 Red Hat, Inc.
++ * Portions copyright (C) 2000 Conectiva, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifdef SUPPORT_GRAPHICS
++
++#include <term.h>
++#include <shared.h>
++#include <graphics.h>
++
++int saved_videomode;
++unsigned char *font8x16;
++
++int graphics_inited = 0;
++static char splashimage[256];
++
++int shade = 1, no_cursor = 0;
++
++#define VSHADOW VSHADOW1
++unsigned char VSHADOW1[38400];
++unsigned char VSHADOW2[38400];
++unsigned char VSHADOW4[38400];
++unsigned char VSHADOW8[38400];
++
++/* define the default viewable area */
++int view_x0 = 0;
++int view_y0 = 0;
++int view_x1 = 80;
++int view_y1 = 30;
++
++/* text buffer has to be kept around so that we can write things as we
++ * scroll and the like */
++unsigned short text[80 * 30];
++
++/* graphics options */
++int foreground = (63 << 16) | (63 << 8) | (63), background = 0, window_border = 0;
++
++/* current position */
++static int fontx = 0;
++static int fonty = 0;
++
++/* global state so that we don't try to recursively scroll or cursor */
++static int no_scroll = 0;
++
++/* color state */
++static int graphics_standard_color = A_NORMAL;
++static int graphics_normal_color = A_NORMAL;
++static int graphics_highlight_color = A_REVERSE;
++static int graphics_current_color = A_NORMAL;
++static color_state graphics_color_state = COLOR_STATE_STANDARD;
++
++static inline void outb(unsigned short port, unsigned char val)
++{
++ __asm __volatile ("outb %0,%1"::"a" (val), "d" (port));
++}
++
++static void MapMask(int value) {
++ outb(0x3c4, 2);
++ outb(0x3c5, value);
++}
++
++/* bit mask register */
++static void BitMask(int value) {
++ outb(0x3ce, 8);
++ outb(0x3cf, value);
++}
++
++/* move the graphics cursor location to col, row */
++static void graphics_setxy(int col, int row) {
++ if (col >= view_x0 && col < view_x1) {
++ fontx = col;
++ cursorX = col << 3;
++ }
++ if (row >= view_y0 && row < view_y1) {
++ fonty = row;
++ cursorY = row << 4;
++ }
++}
++
++/* scroll the screen */
++static void graphics_scroll() {
++ int i, j, k;
++
++ /* we don't want to scroll recursively... that would be bad */
++ if (no_scroll)
++ return;
++ no_scroll = 1;
++
++ /* disable pager temporarily */
++ k = count_lines;
++ count_lines = -1;
++
++ /* move everything up a line */
++ for (j = view_y0 + 1; j < view_y1; j++) {
++ graphics_gotoxy(view_x0, j - 1);
++ for (i = view_x0; i < view_x1; i++) {
++ graphics_putchar(text[j * 80 + i]);
++ }
++ }
++
++ /* last line should be blank */
++ graphics_gotoxy(view_x0, view_y1 - 1);
++ for (i = view_x0; i < view_x1; i++)
++ graphics_putchar(' ');
++ graphics_setxy(view_x0, view_y1 - 1);
++
++ count_lines = k;
++
++ no_scroll = 0;
++}
++
++/* Set the splash image */
++void graphics_set_splash(char *splashfile) {
++ grub_strcpy(splashimage, splashfile);
++}
++
++/* Get the current splash image */
++char *graphics_get_splash(void) {
++ return splashimage;
++}
++
++/*
++ * Initialize a vga16 graphics display with the palette based off of
++ * the image in splashimage. If the image doesn't exist, leave graphics
++ * mode. The mode initiated is 12h. From "Ralf Brown's Interrupt List":
++ * text/ text pixel pixel colors disply scrn system
++ * grph resol box resolution pages addr
++ * 12h G 80x30 8x16 640x480 16/256K . A000 VGA,ATI VIP
++ * G 80x30 8x16 640x480 16/64 . A000 ATI EGA Wonder
++ * G . . 640x480 16 . . UltraVision+256K EGA
++ */
++int graphics_init()
++{
++ if (!graphics_inited) {
++ saved_videomode = set_videomode(0x12);
++ if (get_videomode() != 0x12) {
++ set_videomode(saved_videomode);
++ return 0;
++ }
++ graphics_inited = 1;
++ }
++ else
++ return 1;
++
++ font8x16 = (unsigned char*)graphics_get_font();
++
++ /* make sure that the highlight color is set correctly */
++ graphics_highlight_color = ((graphics_normal_color >> 4) |
++ ((graphics_normal_color & 0xf) << 4));
++
++ graphics_cls();
++
++ if (!read_image(splashimage)) {
++ grub_printf("Failed to read splash image (%s)\n", splashimage);
++ grub_printf("Press any key to continue...");
++ getkey();
++ set_videomode(saved_videomode);
++ graphics_inited = 0;
++ return 0;
++ }
++
++ set_int1c_handler();
++
++ return 1;
++}
++
++/* Leave graphics mode */
++void graphics_end(void)
++{
++ if (graphics_inited) {
++ unset_int1c_handler();
++ set_videomode(saved_videomode);
++ graphics_inited = 0;
++ no_cursor = 0;
++ }
++}
++
++/* Print ch on the screen. Handle any needed scrolling or the like */
++void graphics_putchar(int ch) {
++ ch &= 0xff;
++
++ graphics_cursor(0);
++
++ if (ch == '\n') {
++ if (fonty + 1 < view_y1)
++ graphics_setxy(fontx, fonty + 1);
++ else
++ graphics_scroll();
++ graphics_cursor(1);
++ return;
++ } else if (ch == '\r') {
++ graphics_setxy(view_x0, fonty);
++ graphics_cursor(1);
++ return;
++ }
++
++ graphics_cursor(0);
++
++ text[fonty * 80 + fontx] = ch;
++ text[fonty * 80 + fontx] &= 0x00ff;
++ if (graphics_current_color & 0xf0)
++ text[fonty * 80 + fontx] |= 0x100;
++
++ graphics_cursor(0);
++
++ if ((fontx + 1) >= view_x1) {
++ graphics_setxy(view_x0, fonty);
++ if (fonty + 1 < view_y1)
++ graphics_setxy(view_x0, fonty + 1);
++ else
++ graphics_scroll();
++ graphics_cursor(1);
++ do_more ();
++ graphics_cursor(0);
++ } else {
++ graphics_setxy(fontx + 1, fonty);
++ }
++
++ graphics_cursor(1);
++}
++
++/* get the current location of the cursor */
++int graphics_getxy(void) {
++ return (fontx << 8) | fonty;
++}
++
++void graphics_gotoxy(int x, int y) {
++ graphics_cursor(0);
++
++ graphics_setxy(x, y);
++
++ graphics_cursor(1);
++}
++
++void graphics_cls(void) {
++ int i;
++ unsigned char *mem, *s1, *s2, *s4, *s8;
++
++ graphics_cursor(0);
++ graphics_gotoxy(view_x0, view_y0);
++
++ mem = (unsigned char*)VIDEOMEM;
++ s1 = (unsigned char*)VSHADOW1;
++ s2 = (unsigned char*)VSHADOW2;
++ s4 = (unsigned char*)VSHADOW4;
++ s8 = (unsigned char*)VSHADOW8;
++
++ for (i = 0; i < 80 * 30; i++)
++ text[i] = ' ';
++ graphics_cursor(1);
++
++ BitMask(0xff);
++
++ /* plane 1 */
++ MapMask(1);
++ grub_memcpy(mem, s1, 38400);
++
++ /* plane 2 */
++ MapMask(2);
++ grub_memcpy(mem, s2, 38400);
++
++ /* plane 3 */
++ MapMask(4);
++ grub_memcpy(mem, s4, 38400);
++
++ /* plane 4 */
++ MapMask(8);
++ grub_memcpy(mem, s8, 38400);
++
++ MapMask(15);
++
++ if (no_cursor) {
++ no_cursor = 0;
++ set_int1c_handler();
++ }
++}
++
++void graphics_setcolorstate (color_state state) {
++ switch (state) {
++ case COLOR_STATE_STANDARD:
++ graphics_current_color = graphics_standard_color;
++ break;
++ case COLOR_STATE_NORMAL:
++ graphics_current_color = graphics_normal_color;
++ break;
++ case COLOR_STATE_HIGHLIGHT:
++ graphics_current_color = graphics_highlight_color;
++ break;
++ default:
++ graphics_current_color = graphics_standard_color;
++ break;
++ }
++
++ graphics_color_state = state;
++}
++
++void graphics_setcolor (int normal_color, int highlight_color) {
++ graphics_normal_color = normal_color;
++ graphics_highlight_color = highlight_color;
++
++ graphics_setcolorstate (graphics_color_state);
++}
++
++int graphics_setcursor (int on) {
++ if (!no_cursor && !on) {
++ no_cursor = 1;
++ unset_int1c_handler();
++ graphics_cursor(0);
++ }
++ else if(no_cursor && on) {
++ no_cursor = 0;
++ set_int1c_handler();
++ graphics_cursor(1);
++ }
++ return 0;
++}
++
++/* Read in the splashscreen image and set the palette up appropriately.
++ * Format of splashscreen is an xpm (can be gzipped) with 16 colors and
++ * 640x480. */
++int read_image(char *s)
++{
++ char buf[32], pal[16], c;
++ unsigned char base, mask, *s1, *s2, *s4, *s8;
++ unsigned i, len, idx, colors, x, y, width, height;
++
++ if (!grub_open(s))
++ return 0;
++
++ /* read header */
++ if (!grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) {
++ grub_close();
++ return 0;
++ }
++
++ /* parse info */
++ while (grub_read(&c, 1)) {
++ if (c == '"')
++ break;
++ }
++
++ while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
++ ;
++
++ i = 0;
++ width = c - '0';
++ while (grub_read(&c, 1)) {
++ if (c >= '0' && c <= '9')
++ width = width * 10 + c - '0';
++ else
++ break;
++ }
++ while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
++ ;
++
++ height = c - '0';
++ while (grub_read(&c, 1)) {
++ if (c >= '0' && c <= '9')
++ height = height * 10 + c - '0';
++ else
++ break;
++ }
++ while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
++ ;
++
++ colors = c - '0';
++ while (grub_read(&c, 1)) {
++ if (c >= '0' && c <= '9')
++ colors = colors * 10 + c - '0';
++ else
++ break;
++ }
++
++ base = 0;
++ while (grub_read(&c, 1) && c != '"')
++ ;
++
++ /* palette */
++ for (i = 0, idx = 1; i < colors; i++) {
++ len = 0;
++
++ while (grub_read(&c, 1) && c != '"')
++ ;
++ grub_read(&c, 1); /* char */
++ base = c;
++ grub_read(buf, 4); /* \t c # */
++
++ while (grub_read(&c, 1) && c != '"') {
++ if (len < sizeof(buf))
++ buf[len++] = c;
++ }
++
++ if (len == 6 && idx < 15) {
++ int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2;
++ int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2;
++ int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2;
++
++ pal[idx] = base;
++ graphics_set_palette(idx, r, g, b);
++ ++idx;
++ }
++ }
++
++ x = y = len = 0;
++
++ s1 = (unsigned char*)VSHADOW1;
++ s2 = (unsigned char*)VSHADOW2;
++ s4 = (unsigned char*)VSHADOW4;
++ s8 = (unsigned char*)VSHADOW8;
++
++ for (i = 0; i < 38400; i++)
++ s1[i] = s2[i] = s4[i] = s8[i] = 0;
++
++ /* parse xpm data */
++ while (y < height) {
++ while (1) {
++ if (!grub_read(&c, 1)) {
++ grub_close();
++ return 0;
++ }
++ if (c == '"')
++ break;
++ }
++
++ while (grub_read(&c, 1) && c != '"') {
++ for (i = 1; i < 15; i++)
++ if (pal[i] == c) {
++ c = i;
++ break;
++ }
++
++ mask = 0x80 >> (x & 7);
++ if (c & 1)
++ s1[len + (x >> 3)] |= mask;
++ if (c & 2)
++ s2[len + (x >> 3)] |= mask;
++ if (c & 4)
++ s4[len + (x >> 3)] |= mask;
++ if (c & 8)
++ s8[len + (x >> 3)] |= mask;
++
++ if (++x >= 640) {
++ x = 0;
++
++ if (y < 480)
++ len += 80;
++ ++y;
++ }
++ }
++ }
++
++ grub_close();
++
++ graphics_set_palette(0, (background >> 16), (background >> 8) & 63,
++ background & 63);
++ graphics_set_palette(15, (foreground >> 16), (foreground >> 8) & 63,
++ foreground & 63);
++ graphics_set_palette(0x11, (window_border >> 16), (window_border >> 8) & 63,
++ window_border & 63);
++
++ return 1;
++}
++
++/* Convert a character which is a hex digit to the appropriate integer */
++int hex(int v)
++{
++ if (v >= 'A' && v <= 'F')
++ return (v - 'A' + 10);
++ if (v >= 'a' && v <= 'f')
++ return (v - 'a' + 10);
++ return (v - '0');
++}
++
++void graphics_cursor(int set) {
++ unsigned char *pat, *mem, *ptr, chr[16 << 2];
++ int i, ch, invert, offset;
++
++ if (set && (no_cursor || no_scroll))
++ return;
++
++ offset = cursorY * 80 + fontx;
++ ch = text[fonty * 80 + fontx] & 0xff;
++ invert = (text[fonty * 80 + fontx] & 0xff00) != 0;
++ pat = font8x16 + (ch << 4);
++
++ mem = (unsigned char*)VIDEOMEM + offset;
++
++ if (!set) {
++ for (i = 0; i < 16; i++) {
++ unsigned char mask = pat[i];
++
++ if (!invert) {
++ chr[i ] = ((unsigned char*)VSHADOW1)[offset];
++ chr[16 + i] = ((unsigned char*)VSHADOW2)[offset];
++ chr[32 + i] = ((unsigned char*)VSHADOW4)[offset];
++ chr[48 + i] = ((unsigned char*)VSHADOW8)[offset];
++
++ if (shade) {
++ if (ch == DISP_VERT || ch == DISP_LL ||
++ ch == DISP_UR || ch == DISP_LR) {
++ unsigned char pmask = ~(pat[i] >> 1);
++
++ chr[i ] &= pmask;
++ chr[16 + i] &= pmask;
++ chr[32 + i] &= pmask;
++ chr[48 + i] &= pmask;
++ }
++ if (i > 0 && ch != DISP_VERT) {
++ unsigned char pmask = ~(pat[i - 1] >> 1);
++
++ chr[i ] &= pmask;
++ chr[16 + i] &= pmask;
++ chr[32 + i] &= pmask;
++ chr[48 + i] &= pmask;
++ if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) {
++ pmask = ~pat[i - 1];
++
++ chr[i ] &= pmask;
++ chr[16 + i] &= pmask;
++ chr[32 + i] &= pmask;
++ chr[48 + i] &= pmask;
++ }
++ }
++ }
++ chr[i ] |= mask;
++ chr[16 + i] |= mask;
++ chr[32 + i] |= mask;
++ chr[48 + i] |= mask;
++
++ offset += 80;
++ }
++ else {
++ chr[i ] = mask;
++ chr[16 + i] = mask;
++ chr[32 + i] = mask;
++ chr[48 + i] = mask;
++ }
++ }
++ }
++ else {
++ MapMask(15);
++ ptr = mem;
++ for (i = 0; i < 16; i++, ptr += 80) {
++ cursorBuf[i] = pat[i];
++ *ptr = ~pat[i];
++ }
++ return;
++ }
++
++ offset = 0;
++ for (i = 1; i < 16; i <<= 1, offset += 16) {
++ int j;
++
++ MapMask(i);
++ ptr = mem;
++ for (j = 0; j < 16; j++, ptr += 80)
++ *ptr = chr[j + offset];
++ }
++
++ MapMask(15);
++}
++
++#endif /* SUPPORT_GRAPHICS */
+diff -Naur grub-0.97.orig/stage2/graphics.h grub-0.97/stage2/graphics.h
+--- grub-0.97.orig/stage2/graphics.h 1969-12-31 16:00:00.000000000 -0800
++++ grub-0.97/stage2/graphics.h 2006-07-03 23:58:41.000000000 -0700
+@@ -0,0 +1,44 @@
++/* graphics.h - graphics console interface */
++/*
++ * GRUB -- GRand Unified Bootloader
++ * Copyright (C) 2002 Free Software Foundation, Inc.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++
++#ifndef GRAPHICS_H
++#define GRAPHICS_H
++
++/* magic constant */
++#define VIDEOMEM 0xA0000
++
++/* function prototypes */
++char *graphics_get_splash(void);
++
++int read_image(char *s);
++void graphics_cursor(int set);
++
++/* function prototypes for asm functions */
++void * graphics_get_font();
++void graphics_set_palette(int idx, int red, int green, int blue);
++void set_int1c_handler();
++void unset_int1c_handler();
++
++extern short cursorX, cursorY;
++extern char cursorBuf[16];
++extern int shade;
++extern int view_x0, view_y0, view_x1, view_y1;
++
++#endif /* GRAPHICS_H */
+diff -Naur grub-0.97.orig/stage2/Makefile.am grub-0.97/stage2/Makefile.am
+--- grub-0.97.orig/stage2/Makefile.am 2005-02-02 12:37:35.000000000 -0800
++++ grub-0.97/stage2/Makefile.am 2006-07-03 23:58:41.000000000 -0700
+@@ -7,7 +7,7 @@
+ fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \
+ imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \
+ nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \
+- terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h
++ terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h graphics.h
+ EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS)
+
+ # For <stage1.h>.
+@@ -19,7 +19,7 @@
+ disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \
+ fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \
+ fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \
+- terminfo.c tparm.c
++ terminfo.c tparm.c graphics.c
+ libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
+ -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
+ -DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
+@@ -79,8 +79,14 @@
+ HERCULES_FLAGS =
+ endif
+
++if GRAPHICS_SUPPORT
++GRAPHICS_FLAGS = -DSUPPORT_GRAPHICS=1
++else
++GRAPHICS_FLAGS =
++endif
++
+ STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+- $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS)
++ $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) $(GRAPHICS_FLAGS)
+
+ STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
+ STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1
+@@ -90,7 +96,8 @@
+ cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
+ fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
+ fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \
+- hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c
++ hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c \
++ graphics.c
+ pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
+ pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
+ pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
+diff -Naur grub-0.97.orig/stage2/shared.h grub-0.97/stage2/shared.h
+--- grub-0.97.orig/stage2/shared.h 2004-06-19 09:40:09.000000000 -0700
++++ grub-0.97/stage2/shared.h 2006-07-04 00:01:50.000000000 -0700
+@@ -499,7 +499,11 @@
+ unsigned char linear_reserved_field_position;
+ unsigned long max_pixel_clock;
+
+- unsigned char reserved3[189];
++ /* Reserved field to make structure to be 256 bytes long, VESA BIOS
++ Extension 3.0 Specification says to reserve 189 bytes here but
++ that doesn't make structure to be 256 bytes. So additional one is
++ added here. */
++ unsigned char reserved3[189 + 1];
+ } __attribute__ ((packed));
+
+
+@@ -792,6 +796,11 @@
+ /* Set the cursor position. */
+ void gotoxy (int x, int y);
+
++/* Internal pager
++ Returns 1 = if pager was used
++ 0 = if pager wasn't used */
++int do_more (void);
++
+ /* Displays an ASCII character. IBM displays will translate some
+ characters to special graphical ones (see the DISP_* constants). */
+ void grub_putchar (int c);
+@@ -871,6 +880,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);
+@@ -911,7 +921,7 @@
+ int nul_terminate (char *str);
+ int get_based_digit (int c, int base);
+ int safe_parse_maxint (char **str_ptr, int *myint_ptr);
+-int memcheck (int start, int len);
++int memcheck (unsigned long int start, unsigned long int len);
+ void grub_putstr (const char *str);
+
+ #ifndef NO_DECOMPRESSION
+diff -Naur grub-0.97.orig/stage2/stage2.c grub-0.97/stage2/stage2.c
+--- grub-0.97.orig/stage2/stage2.c 2005-03-19 09:51:57.000000000 -0800
++++ grub-0.97/stage2/stage2.c 2006-07-04 00:01:50.000000000 -0700
+@@ -20,6 +20,12 @@
+ #include <shared.h>
+ #include <term.h>
+
++#ifdef SUPPORT_GRAPHICS
++# include <graphics.h>
++#endif
++
++int col_start, col_end, row_start, box_size;
++
+ grub_jmp_buf restart_env;
+
+ #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS)
+@@ -105,13 +111,13 @@
+ if (highlight && current_term->setcolorstate)
+ current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
+
+- gotoxy (2, y);
++ gotoxy (2 + col_start, y);
+ grub_putchar (' ');
+- for (x = 3; x < 75; x++)
++ for (x = 3 + col_start; x < (col_end - 5); x++)
+ {
+- if (*entry && x <= 72)
++ if (*entry && x <= (col_end - 8))
+ {
+- if (x == 72)
++ if (x == (col_end - 8))
+ grub_putchar (DISP_RIGHT);
+ else
+ grub_putchar (*entry++);
+@@ -119,7 +125,7 @@
+ else
+ grub_putchar (' ');
+ }
+- gotoxy (74, y);
++ gotoxy ((col_end - 6), y);
+
+ if (current_term->setcolorstate)
+ current_term->setcolorstate (COLOR_STATE_STANDARD);
+@@ -131,7 +137,7 @@
+ {
+ int i;
+
+- gotoxy (77, y + 1);
++ gotoxy ((col_end - 3), y + 1);
+
+ if (first)
+ grub_putchar (DISP_UP);
+@@ -151,14 +157,14 @@
+ menu_entries++;
+ }
+
+- gotoxy (77, y + size);
++ gotoxy ((col_end - 3), y + size);
+
+ if (*menu_entries)
+ grub_putchar (DISP_DOWN);
+ else
+ grub_putchar (' ');
+
+- gotoxy (74, y + entryno + 1);
++ gotoxy ((col_end - 6), y + entryno + 1);
+ }
+
+ static void
+@@ -196,30 +202,30 @@
+ if (current_term->setcolorstate)
+ current_term->setcolorstate (COLOR_STATE_NORMAL);
+
+- gotoxy (1, y);
++ gotoxy (1 + col_start, y);
+
+ grub_putchar (DISP_UL);
+- for (i = 0; i < 73; i++)
++ for (i = col_start; i < (col_end - 7); i++)
+ grub_putchar (DISP_HORIZ);
+ grub_putchar (DISP_UR);
+
+ i = 1;
+ while (1)
+ {
+- gotoxy (1, y + i);
++ gotoxy (1 + col_start, y + i);
+
+ if (i > size)
+ break;
+
+ grub_putchar (DISP_VERT);
+- gotoxy (75, y + i);
++ gotoxy ((col_end - 5), y + i);
+ grub_putchar (DISP_VERT);
+
+ i++;
+ }
+
+ grub_putchar (DISP_LL);
+- for (i = 0; i < 73; i++)
++ for (i = col_start; i < (col_end - 7); i++)
+ grub_putchar (DISP_HORIZ);
+ grub_putchar (DISP_LR);
+
+@@ -233,6 +239,7 @@
+ {
+ int c, time1, time2 = -1, first_entry = 0;
+ char *cur_entry = 0;
++ struct term_entry *prev_term = NULL;
+
+ /*
+ * Main loop for menu UI.
+@@ -250,6 +257,22 @@
+ }
+ }
+
++ col_start = 0;
++ col_end = 80;
++ row_start = 0;
++ box_size = 12;
++ /* if we're using viewport we need to make sure to setup
++ coordinates correctly. */
++#ifdef SUPPORT_GRAPHICS
++ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0)
++ {
++ col_start = view_x0;
++ col_end = view_x1;
++ row_start = view_y0;
++ box_size = (view_y1 - view_y0) - 13;
++ }
++#endif
++
+ /* If the timeout was expired or wasn't set, force to show the menu
+ interface. */
+ if (grub_timeout < 0)
+@@ -302,36 +325,36 @@
+ if (current_term->flags & TERM_DUMB)
+ print_entries_raw (num_entries, first_entry, menu_entries);
+ else
+- print_border (3, 12);
++ print_border (3 + row_start, box_size);
+
+ grub_printf ("\n\
+- Use the %c and %c keys to select which entry is highlighted.\n",
++ Use the %c and %c keys to select which entry is highlighted.\n",
+ DISP_UP, DISP_DOWN);
+
+ if (! auth && password)
+ {
+ printf ("\
+- Press enter to boot the selected OS or \'p\' to enter a\n\
+- password to unlock the next set of features.");
++ Press enter to boot the selected OS or \'p\' to enter a\n\
++ password to unlock the next set of features.");
+ }
+ else
+ {
+ if (config_entries)
+ printf ("\
+- Press enter to boot the selected OS, \'e\' to edit the\n\
+- commands before booting, or \'c\' for a command-line.");
++ Press enter to boot the selected OS, \'e\' to edit the\n\
++ commands before booting, or \'c\' for a command-line.");
+ else
+ printf ("\
+- Press \'b\' to boot, \'e\' to edit the selected command in the\n\
+- boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\
+- after (\'O\' for before) the selected line, \'d\' to remove the\n\
+- selected line, or escape to go back to the main menu.");
++ Press \'b\' to boot, \'e\' to edit the selected command in the\n\
++ boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\
++ after (\'O\' for before) the selected line, \'d\' to remove the\n\
++ selected line, or escape to go back to the main menu.");
+ }
+
+ if (current_term->flags & TERM_DUMB)
+ grub_printf ("\n\nThe selected entry is %d ", entryno);
+ else
+- print_entries (3, 12, first_entry, entryno, menu_entries);
++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
+ }
+
+ /* XX using RT clock now, need to initialize value */
+@@ -358,10 +381,10 @@
+ entryno, grub_timeout);
+ else
+ {
+- gotoxy (3, 22);
+- grub_printf ("The highlighted entry will be booted automatically in %d seconds. ",
++ gotoxy (3 + col_start, 10 + box_size + row_start);
++ grub_printf (" The highlighted entry will be booted automatically in %d seconds. ",
+ grub_timeout);
+- gotoxy (74, 4 + entryno);
++ gotoxy ((col_end - 6), 4 + entryno + row_start);
+ }
+
+ grub_timeout--;
+@@ -387,12 +410,12 @@
+ if (current_term->flags & TERM_DUMB)
+ grub_putchar ('\r');
+ else
+- gotoxy (3, 22);
++ gotoxy (3 + col_start, 10 + box_size + row_start);
+ printf (" ");
+ grub_timeout = -1;
+ fallback_entryno = -1;
+ if (! (current_term->flags & TERM_DUMB))
+- gotoxy (74, 4 + entryno);
++ gotoxy ((col_end - 6), 4 + entryno + row_start);
+ }
+
+ /* We told them above (at least in SUPPORT_SERIAL) to use
+@@ -408,12 +431,12 @@
+ {
+ if (entryno > 0)
+ {
+- print_entry (4 + entryno, 0,
++ print_entry (4 + entryno + row_start, 0,
+ get_entry (menu_entries,
+ first_entry + entryno,
+ 0));
+ entryno--;
+- print_entry (4 + entryno, 1,
++ print_entry (4 + entryno + row_start, 1,
+ get_entry (menu_entries,
+ first_entry + entryno,
+ 0));
+@@ -421,7 +444,7 @@
+ else if (first_entry > 0)
+ {
+ first_entry--;
+- print_entries (3, 12, first_entry, entryno,
++ print_entries (3 + row_start, box_size, first_entry, entryno,
+ menu_entries);
+ }
+ }
+@@ -433,29 +456,29 @@
+ entryno++;
+ else
+ {
+- if (entryno < 11)
++ if (entryno < (box_size - 1))
+ {
+- print_entry (4 + entryno, 0,
++ print_entry (4 + entryno + row_start, 0,
+ get_entry (menu_entries,
+ first_entry + entryno,
+ 0));
+ entryno++;
+- print_entry (4 + entryno, 1,
++ print_entry (4 + entryno + row_start, 1,
+ get_entry (menu_entries,
+ first_entry + entryno,
+ 0));
+ }
+- else if (num_entries > 12 + first_entry)
++ else if (num_entries > box_size + first_entry)
+ {
+ first_entry++;
+- print_entries (3, 12, first_entry, entryno, menu_entries);
++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
+ }
+ }
+ }
+ else if (c == 7)
+ {
+ /* Page Up */
+- first_entry -= 12;
++ first_entry -= box_size;
+ if (first_entry < 0)
+ {
+ entryno += first_entry;
+@@ -463,20 +486,20 @@
+ if (entryno < 0)
+ entryno = 0;
+ }
+- print_entries (3, 12, first_entry, entryno, menu_entries);
++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
+ }
+ else if (c == 3)
+ {
+ /* Page Down */
+- first_entry += 12;
++ first_entry += box_size;
+ if (first_entry + entryno + 1 >= num_entries)
+ {
+- first_entry = num_entries - 12;
++ first_entry = num_entries - box_size;
+ if (first_entry < 0)
+ first_entry = 0;
+ entryno = num_entries - first_entry - 1;
+ }
+- print_entries (3, 12, first_entry, entryno, menu_entries);
++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
+ }
+
+ if (config_entries)
+@@ -489,7 +512,7 @@
+ if ((c == 'd') || (c == 'o') || (c == 'O'))
+ {
+ if (! (current_term->flags & TERM_DUMB))
+- print_entry (4 + entryno, 0,
++ print_entry (4 + entryno + row_start, 0,
+ get_entry (menu_entries,
+ first_entry + entryno,
+ 0));
+@@ -537,7 +560,7 @@
+
+ if (entryno >= num_entries)
+ entryno--;
+- if (first_entry && num_entries < 12 + first_entry)
++ if (first_entry && num_entries < box_size + first_entry)
+ first_entry--;
+ }
+
+@@ -549,7 +572,7 @@
+ grub_printf ("\n");
+ }
+ else
+- print_entries (3, 12, first_entry, entryno, menu_entries);
++ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
+ }
+
+ cur_entry = menu_entries;
+@@ -570,7 +593,7 @@
+ if (current_term->flags & TERM_DUMB)
+ grub_printf ("\r ");
+ else
+- gotoxy (1, 21);
++ gotoxy (1 + col_start, 9 + box_size + row_start);
+
+ /* Wipe out the previously entered password */
+ grub_memset (entered, 0, sizeof (entered));
+@@ -651,7 +674,10 @@
+ *(new_heap++) = 0;
+
+ if (config_entries)
+- run_menu (heap, NULL, new_num_entries, new_heap, 0);
++ {
++ current_entryno = first_entry + entryno;
++ run_menu (heap, NULL, new_num_entries, new_heap, 0);
++ }
+ else
+ {
+ cls ();
+@@ -714,6 +740,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)
+ {
+@@ -727,7 +762,8 @@
+ cur_entry = get_entry (config_entries, first_entry + entryno, 1);
+
+ /* Set CURRENT_ENTRYNO for the command "savedefault". */
+- current_entryno = first_entry + entryno;
++ if (config_entries)
++ current_entryno = first_entry + entryno;
+
+ if (run_script (cur_entry, heap))
+ {
+@@ -748,6 +784,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;
+ }
+@@ -891,8 +934,18 @@
+ len = grub_read (buf, sizeof (buf));
+ if (len > 0)
+ {
++ char *tmp;
++ char *def;
+ buf[sizeof (buf) - 1] = 0;
+- safe_parse_maxint (&p, &saved_entryno);
++
++ if((tmp = grub_strstr(p, ":")) != NULL)
++ {
++ *tmp++;
++ grub_memcpy(&def, &tmp, sizeof(p));
++ }else
++ grub_memcpy(&def, &p, sizeof(p));
++
++ safe_parse_maxint (&def, &saved_entryno);
+ }
+
+ grub_close ();
+@@ -1050,6 +1103,16 @@
+ while (is_preset);
+ }
+
++ /* go ahead and make sure the terminal is setup */
++ if (current_term->startup)
++ {
++ /* If initialization fails, go back to default terminal */
++ if (current_term->startup() == 0)
++ {
++ current_term = term_table;
++ }
++ }
++
+ if (! num_entries)
+ {
+ /* If no acceptable config file, goto command-line, starting
+diff -Naur grub-0.97.orig/stage2/term.h grub-0.97/stage2/term.h
+--- grub-0.97.orig/stage2/term.h 2003-07-09 04:45:53.000000000 -0700
++++ grub-0.97/stage2/term.h 2006-07-03 23:58:41.000000000 -0700
+@@ -60,6 +60,8 @@
+ const char *name;
+ /* The feature flags defined above. */
+ unsigned long flags;
++ /* Default for maximum number of lines if not specified */
++ unsigned short max_lines;
+ /* Put a character. */
+ void (*putchar) (int c);
+ /* Check if any input character is available. */
+@@ -79,6 +81,10 @@
+ void (*setcolor) (int normal_color, int highlight_color);
+ /* Turn on/off the cursor. */
+ int (*setcursor) (int on);
++ /* function to start a terminal */
++ int (*startup) (void);
++ /* function to use to shutdown a terminal */
++ void (*shutdown) (void);
+ };
+
+ /* This lists up available terminals. */
+@@ -124,4 +130,24 @@
+ int hercules_setcursor (int on);
+ #endif
+
++#ifdef SUPPORT_GRAPHICS
++extern int foreground, background, window_border, graphics_inited, saved_videomode;
++
++void graphics_set_splash(char *splashfile);
++int set_videomode(int mode);
++int get_videomode(void);
++void graphics_putchar (int c);
++int graphics_getxy(void);
++void graphics_gotoxy(int x, int y);
++void graphics_cls(void);
++void graphics_setcolorstate (color_state state);
++void graphics_setcolor (int normal_color, int highlight_color);
++int graphics_setcursor (int on);
++int graphics_init(void);
++void graphics_end(void);
++
++int hex(int v);
++void graphics_set_palette(int idx, int red, int green, int blue);
++#endif /* SUPPORT_GRAPHICS */
++
+ #endif /* ! GRUB_TERM_HEADER */
+diff -Naur grub-0.97.orig/THANKS grub-0.97/THANKS
+--- grub-0.97.orig/THANKS 2005-05-07 19:17:43.000000000 -0700
++++ grub-0.97/THANKS 2006-07-04 00:01:50.000000000 -0700
+@@ -121,3 +121,4 @@
+ Yedidyah Bar-David <didi@post.tau.ac.il>
+ Yury V. Umanets <umka@namesys.com>
+ Yuri Zaporogets <yuriz@ukr.net>
++Vitaly Fertman <vitaly@namesys.com>
+diff -Naur grub-0.97.orig/util/grub-install.in grub-0.97/util/grub-install.in
+--- grub-0.97.orig/util/grub-install.in 2004-07-24 11:57:31.000000000 -0700
++++ grub-0.97/util/grub-install.in 2006-07-04 00:01:50.000000000 -0700
+@@ -81,6 +81,50 @@
+ EOF
+ }
+
++# Usage: getraid_mdadm mddevice
++# Routine to find a physical device from an md device
++# If found, the first grub BIOS device (from device.map) is returned
++# If no BIOS drives match the RAID devices, the first device returned
++# from mdadm -D is returned
++getraid_mdadm() {
++ device=$1
++ mdadm=$(mdadm -D "$device") || {
++ echo "$PROG: mdadm -D $device failed" >&2
++ exit 1
++ }
++ eval "$(
++ echo "$mdadm" | awk '
++ $1 == "Number" && $2 == "Major" { start = 1; next }
++ $1 == "UUID" { print "uuid=" $3; start = 0; next }
++ !start { next }
++ $2 == 0 && $3 == 0 { next }
++ { devices = devices "\n" $NF }
++ END { print "devices='\''" devices "'\''" }
++ '
++ )"
++
++ # Convert RAID devices list into a list of disks
++ tmp_disks=`echo "$devices" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' \
++ -e 's%\(d[0-9]*\)p[0-9]*$%\1%' \
++ -e 's%\(fd[0-9]*\)$%\1%' \
++ -e 's%/part[0-9]*$%/disc%' \
++ -e 's%\(c[0-7]d[0-9]*\).*$%\1%' \
++ -e '/^$/d' |
++ sed -n '1h;2,$H;${g;s/\n/|/g;p}'`
++
++ # Find first BIOS disk that's a member of the RAID array
++ # Default to first RAID member if no tmp_disks are BIOS devices
++ set -- `egrep $tmp_disks $device_map | \
++ sort | \
++ sed -n 1p `
++ device=${2:-${tmp_disks%%|*}}
++
++ # Return first partition on BIOS disk that's part of the RAID
++ echo "$devices" | \
++ sed -n "\:${device}:p" | \
++ sed -n 1p
++}
++
+ # Usage: convert os_device
+ # Convert an OS device to the corresponding GRUB drive.
+ # This part is OS-specific.
+@@ -96,6 +140,10 @@
+ # Break the device name into the disk part and the partition part.
+ case "$host_os" in
+ linux*)
++ # Find an actual physical device if we're passed a RAID device
++ case $1 in
++ /dev/md*) set -- `getraid_mdadm $1`
++ esac
+ tmp_disk=`echo "$1" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' \
+ -e 's%\(d[0-9]*\)p[0-9]*$%\1%' \
+ -e 's%\(fd[0-9]*\)$%\1%' \
+@@ -112,8 +160,8 @@
+ tmp_disk=`echo "$1" | sed 's%\([sh]d[0-9]*\).*%\1%'`
+ tmp_part=`echo "$1" | sed "s%$tmp_disk%%"` ;;
+ freebsd* | kfreebsd*-gnu)
+- tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%r\1%' \
+- | sed 's%r\{0,1\}\(da[0-9]*\).*$%r\1%'`
++ tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%\1%' \
++ | sed 's%r\{0,1\}\(da[0-9]*\).*$%\1%'`
+ tmp_part=`echo "$1" \
+ | sed "s%.*/r\{0,1\}[saw]d[0-9]\(s[0-9]*[a-h]\)%\1%" \
+ | sed "s%.*/r\{0,1\}da[0-9]\(s[0-9]*[a-h]\)%\1%"`
+@@ -131,7 +179,7 @@
+
+ # Get the drive name.
+ tmp_drive=`grep -v '^#' $device_map | grep "$tmp_disk *$" \
+- | sed 's%.*\(([hf]d[0-9][a-g0-9,]*)\).*%\1%'`
++ | sed 's%.*\(([hf]d[0-9][a-z0-9,]*)\).*%\1%'`
+
+ # If not found, print an error message and exit.
+ if test "x$tmp_drive" = x; then
+@@ -148,13 +196,13 @@
+ gnu*)
+ if echo $tmp_part | grep "^s" >/dev/null; then
+ tmp_pc_slice=`echo $tmp_part \
+- | sed "s%s\([0-9]*\)[a-g]*$%\1%"`
++ | sed "s%s\([0-9]*\)[a-z]*$%\1%"`
+ tmp_drive=`echo "$tmp_drive" \
+ | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
+ fi
+- if echo $tmp_part | grep "[a-g]$" >/dev/null; then
++ if echo $tmp_part | grep "[a-z]$" >/dev/null; then
+ tmp_bsd_partition=`echo "$tmp_part" \
+- | sed "s%[^a-g]*\([a-g]\)$%\1%"`
++ | sed "s%[^a-z]*\([a-z]\)$%\1%"`
+ tmp_drive=`echo "$tmp_drive" \
+ | sed "s%)%,$tmp_bsd_partition)%"`
+ fi
+@@ -336,6 +384,10 @@
+ # Create a safe temporary file.
+ test -n "$mklog" && log_file=`$mklog`
+
++ # Before all invocations of the grub shell, call sync to make sure
++ # the raw device is in sync with any bufferring in filesystems.
++ sync
++
+ $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
+ quit
+ EOF
+@@ -450,6 +502,24 @@
+ # Create a safe temporary file.
+ test -n "$mklog" && log_file=`$mklog`
+
++# Sync to prevent GRUB from not finding stage files (notably, on XFS)
++sync
++
++# XFS needs special magic
++xfs_frozen=false
++if which xfs_freeze > /dev/null ; then
++ cat << EOF
++Due to a bug in xfs_freeze, the following command might produce a segmentation
++fault when ${grubdir} is not in an XFS filesystem. This error is harmless and
++can be ignored.
++EOF
++ if xfs_freeze -f ${grubdir} ; then xfs_frozen=true ; fi
++fi
++
++# Before all invocations of the grub shell, call sync to make sure
++# the raw device is in sync with any bufferring in filesystems.
++sync
++
+ # Now perform the installation.
+ $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
+ root $root_drive
+@@ -457,6 +527,10 @@
+ quit
+ EOF
+
++if ${xfs_frozen} ; then
++ xfs_freeze -u ${grubdir}
++fi
++
+ if grep "Error [0-9]*: " $log_file >/dev/null || test $debug = yes; then
+ cat $log_file 1>&2
+ exit 1
bool "Build GRUB images (Linux x86 or x86_64 host only)"
depends TARGET_x86
depends TARGET_ROOTFS_EXT2FS || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS || TARGET_ROOTFS_ISO
+ select PACKAGE_grub
default y
config X86_GRUB_IMAGES_PAD
ifeq ($(CONFIG_X86_GRUB_IMAGES),y)
- define Build/Compile
- $(MAKE) -C grub compile
- endef
-
- define Build/Clean
- $(MAKE) -C grub clean
- endef
-
define Image/cmdline/squashfs
block2mtd.block2mtd=$(ROOTPART),65536,rootfs root=/dev/mtdblock0 rootfstype=squashfs init=/etc/preinit
endef
+++ /dev/null
-#
-# Copyright (C) 2006 OpenWrt.org
-#
-# This is free software, licensed under the GNU General Public License v2.
-# See /LICENSE for more information.
-#
-# $Id: Makefile 4855 2006-09-24 20:49:31Z nico $
-
-include $(TOPDIR)/rules.mk
-include $(INCLUDE_DIR)/kernel.mk
-
-PKG_NAME:=grub
-PKG_VERSION:=0.97
-PKG_RELEASE:=1
-
-PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=ftp://alpha.gnu.org/gnu/grub
-PKG_MD5SUM:=cd3f3eb54446be6003156158d51f4884
-PKG_CAT:=zcat
-
-PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/grub-$(PKG_VERSION)
-
-include $(INCLUDE_DIR)/package.mk
-
-ifeq ($(HOST_ARCH),x86_64)
-CONFIGURE_FLAGS:= \
- --target=$(GNU_TARGET_NAME) \
- --host=$(GNU_TARGET_NAME) \
- --build=$(GNU_HOST_NAME)
-else
-CONFIGURE_FLAGS:=
-endif
-
-define Build/Configure
- (cd $(PKG_BUILD_DIR); \
- LDFLAGS="-static" \
- ./configure \
- $(CONFIGURE_FLAGS) \
- --program-prefix="" \
- --program-suffix="" \
- --prefix=/usr \
- --exec-prefix=/usr \
- --bindir=/usr/bin \
- --sbindir=/usr/sbin \
- --libexecdir=/usr/lib \
- --sysconfdir=/etc \
- --datadir=/usr/share \
- --localstatedir=/var \
- --mandir=/usr/man \
- --infodir=/usr/info \
- $(DISABLE_NLS) \
- --disable-auto-linux-mem-opt \
- )
-endef
-
-#
-# ./configure detects whether the host compiler supports
-# -fno-stack-protector but only sets STAGE2_CFLAGS accordingly
-#
-define Build/Compile
- $(MAKE) -C $(PKG_BUILD_DIR) \
- GRUB_CFLAGS="\$$$$(STAGE2_CFLAGS)" \
- STAGE1_CFLAGS="\$$$$(STAGE2_CFLAGS)"
-endef
-
-define Build/InstallDev
- $(MAKE) -C $(PKG_BUILD_DIR) \
- DESTDIR="$(STAGING_DIR_HOST)" \
- install
- mv $(STAGING_DIR_HOST)/usr/sbin/grub $(STAGING_DIR_HOST)/bin
-endef
-
-$(eval $(call Build/DefaultTargets))
+++ /dev/null
-serial --unit=0 --speed=@BAUDRATE@ --word=8 --parity=no --stop=1
-terminal --timeout=2 console serial
-
-default 0
-timeout 5
-
-title OpenWrt
-root (hd0,0)
-kernel /boot/vmlinuz @CMDLINE@ noinitrd console=tty0 console=ttyS0,@BAUDRATE@n8 reboot=bios
-boot
-
-title OpenWrt (failsafe)
-root (hd0,0)
-kernel /boot/vmlinuz failsafe=true @CMDLINE@ noinitrd console=tty0 console=ttyS0,@BAUDRATE@n8 reboot=bios
-boot
+++ /dev/null
-Submitted By: Jim Gifford (jim at linuxfromscratch dot org)
-Date: 2006-07-04
-Initial Package Version: 0.97
-Origin: Debian
-Upstream Status: Unknown
-Description: Contains various fixes and enhancements
- Graphics mode support
- Fixes for Raid Support
- XFS Filesystem Boot Freeze Fixes
- Removed 2GB Memory Limitation
- Freebsd support
- Fixes for initrd support
- Grub installation Fixes
- Linux 2.6 geometry Fixes
- Intel Mac Support
- Autoconf and aclocal updates
-
-http://trac.cross-lfs.org/browser/trunk/patches/grub-0.97-fixes-1.patch
-
-diff -Naur grub-0.97.orig/aclocal.m4 grub-0.97/aclocal.m4
---- grub-0.97.orig/aclocal.m4 2005-05-07 19:41:18.000000000 -0700
-+++ grub-0.97/aclocal.m4 2006-07-04 00:08:22.000000000 -0700
-@@ -1,7 +1,7 @@
--# generated automatically by aclocal 1.9.4 -*- Autoconf -*-
-+# generated automatically by aclocal 1.9.6 -*- Autoconf -*-
-
--# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
--# Free Software Foundation, Inc.
-+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-+# 2005 Free Software Foundation, Inc.
- # This file is free software; the Free Software Foundation
- # gives unlimited permission to copy and/or distribute it,
- # with or without modifications, as long as this notice is preserved.
-@@ -11,23 +11,11 @@
- # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- # PARTICULAR PURPOSE.
-
--# -*- Autoconf -*-
--# Copyright (C) 2002, 2003 Free Software Foundation, Inc.
--# Generated from amversion.in; do not edit by hand.
--
--# 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, 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., 59 Temple Place - Suite 330, Boston, MA
-+# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
-+#
-+# This file is free software; the Free Software Foundation
-+# gives unlimited permission to copy and/or distribute it,
-+# with or without modifications, as long as this notice is preserved.
-
- # AM_AUTOMAKE_VERSION(VERSION)
- # ----------------------------
-@@ -40,26 +28,15 @@
- # Call AM_AUTOMAKE_VERSION so it can be traced.
- # This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
- AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-- [AM_AUTOMAKE_VERSION([1.9.4])])
--
--# AM_AUX_DIR_EXPAND
--
--# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
-+ [AM_AUTOMAKE_VERSION([1.9.6])])
-
--# 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, or (at your option)
--# any later version.
-+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-
--# 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., 59 Temple Place - Suite 330, Boston, MA
--# 02111-1307, USA.
-+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
-+#
-+# This file is free software; the Free Software Foundation
-+# gives unlimited permission to copy and/or distribute it,
-+# with or without modifications, as long as this notice is preserved.
-
- # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
- # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
-@@ -106,26 +83,16 @@
- am_aux_dir=`cd $ac_aux_dir && pwd`
- ])
-
--# AM_CONDITIONAL -*- Autoconf -*-
-+# AM_CONDITIONAL -*- Autoconf -*-
-
--# Copyright (C) 1997, 2000, 2001, 2003, 2004 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, 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., 59 Temple Place - Suite 330, Boston, MA
--# 02111-1307, USA.
-+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005
-+# Free Software Foundation, Inc.
-+#
-+# This file is free software; the Free Software Foundation
-+# gives unlimited permission to copy and/or distribute it,
-+# with or without modifications, as long as this notice is preserved.
-
--# serial 6
-+# serial 7
-
- # AM_CONDITIONAL(NAME, SHELL-CONDITION)
- # -------------------------------------
-@@ -149,26 +116,15 @@
- Usually this means the macro was only invoked conditionally.]])
- fi])])
-
--# serial 7 -*- Autoconf -*-
-
--# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
-+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
- # Free Software Foundation, Inc.
-+#
-+# This file is free software; the Free Software Foundation
-+# gives unlimited permission to copy and/or distribute it,
-+# with or without modifications, as long as this notice is preserved.
-
--# 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, 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., 59 Temple Place - Suite 330, Boston, MA
--# 02111-1307, USA.
--
-+# serial 8
-
- # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
- # written in clear, in which case automake, when reading aclocal.m4,
-@@ -177,7 +133,6 @@
- # CC etc. in the Makefile, will ask for an AC_PROG_CC use...
-
-
--
- # _AM_DEPENDENCIES(NAME)
- # ----------------------
- # See how the compiler implements dependency checking.
-@@ -317,27 +272,16 @@
- AC_SUBST([AMDEPBACKSLASH])
- ])
-
--# Generate code to set up dependency tracking. -*- Autoconf -*-
--
--# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
--# 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, or (at your option)
--# any later version.
-+# Generate code to set up dependency tracking. -*- Autoconf -*-
-
--# 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., 59 Temple Place - Suite 330, Boston, MA
--# 02111-1307, USA.
-+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005
-+# Free Software Foundation, Inc.
-+#
-+# This file is free software; the Free Software Foundation
-+# gives unlimited permission to copy and/or distribute it,
-+# with or without modifications, as long as this notice is preserved.
-
--#serial 2
-+#serial 3
-
- # _AM_OUTPUT_DEPENDENCY_COMMANDS
- # ------------------------------
-@@ -396,30 +340,19 @@
- [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
- ])
-
--# Do all the work for Automake. -*- Autoconf -*-
-+# Do all the work for Automake. -*- Autoconf -*-
-
--# This macro actually does too much some checks are only needed if
--# your package does certain things. But this isn't really a big deal.
--
--# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
-+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
- # Free Software Foundation, Inc.
-+#
-+# This file is free software; the Free Software Foundation
-+# gives unlimited permission to copy and/or distribute it,
-+# with or without modifications, as long as this notice is preserved.
-
--# 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, 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., 59 Temple Place - Suite 330, Boston, MA
--# 02111-1307, USA.
-+# serial 12
-
--# serial 11
-+# This macro actually does too much. Some checks are only needed if
-+# your package does certain things. But this isn't really a big deal.
-
- # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
- # AM_INIT_AUTOMAKE([OPTIONS])
-@@ -521,51 +454,27 @@
- done
- echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
-
-+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
-+#
-+# This file is free software; the Free Software Foundation
-+# gives unlimited permission to copy and/or distribute it,
-+# with or without modifications, as long as this notice is preserved.
-+
- # AM_PROG_INSTALL_SH
- # ------------------
- # Define $install_sh.
--
--# Copyright (C) 2001, 2003 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, 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., 59 Temple Place - Suite 330, Boston, MA
--# 02111-1307, USA.
--
- AC_DEFUN([AM_PROG_INSTALL_SH],
- [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
- install_sh=${install_sh-"$am_aux_dir/install-sh"}
- AC_SUBST(install_sh)])
-
--# -*- Autoconf -*-
--# Copyright (C) 2003 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, 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., 59 Temple Place - Suite 330, Boston, MA
--# 02111-1307, USA.
-+# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
-+#
-+# This file is free software; the Free Software Foundation
-+# gives unlimited permission to copy and/or distribute it,
-+# with or without modifications, as long as this notice is preserved.
-
--# serial 1
-+# serial 2
-
- # Check whether the underlying file-system supports filenames
- # with a leading dot. For instance MS-DOS doesn't.
-@@ -580,28 +489,17 @@
- rmdir .tst 2>/dev/null
- AC_SUBST([am__leading_dot])])
-
--# Add --enable-maintainer-mode option to configure.
-+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
- # From Jim Meyering
-
--# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004
-+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005
- # Free Software Foundation, Inc.
-+#
-+# This file is free software; the Free Software Foundation
-+# gives unlimited permission to copy and/or distribute it,
-+# with or without modifications, as long as this notice is preserved.
-
--# 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, 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., 59 Temple Place - Suite 330, Boston, MA
--# 02111-1307, USA.
--
--# serial 3
-+# serial 4
-
- AC_DEFUN([AM_MAINTAINER_MODE],
- [AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
-@@ -620,26 +518,15 @@
-
- AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
-
--# Check to see how 'make' treats includes. -*- Autoconf -*-
--
--# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
-+# Check to see how 'make' treats includes. -*- Autoconf -*-
-
--# 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, 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., 59 Temple Place - Suite 330, Boston, MA
--# 02111-1307, USA.
-+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
-+#
-+# This file is free software; the Free Software Foundation
-+# gives unlimited permission to copy and/or distribute it,
-+# with or without modifications, as long as this notice is preserved.
-
--# serial 2
-+# serial 3
-
- # AM_MAKE_INCLUDE()
- # -----------------
-@@ -683,27 +570,16 @@
- rm -f confinc confmf
- ])
-
--# -*- Autoconf -*-
--
--
--# Copyright (C) 1997, 1999, 2000, 2001, 2003 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, or (at your option)
--# any later version.
-+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-
--# 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., 59 Temple Place - Suite 330, Boston, MA
--# 02111-1307, USA.
-+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005
-+# Free Software Foundation, Inc.
-+#
-+# This file is free software; the Free Software Foundation
-+# gives unlimited permission to copy and/or distribute it,
-+# with or without modifications, as long as this notice is preserved.
-
--# serial 3
-+# serial 4
-
- # AM_MISSING_PROG(NAME, PROGRAM)
- # ------------------------------
-@@ -729,27 +605,16 @@
- fi
- ])
-
-+# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
-+#
-+# This file is free software; the Free Software Foundation
-+# gives unlimited permission to copy and/or distribute it,
-+# with or without modifications, as long as this notice is preserved.
-+
- # AM_PROG_MKDIR_P
- # ---------------
- # Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
--
--# Copyright (C) 2003, 2004 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, 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., 59 Temple Place - Suite 330, Boston, MA
--# 02111-1307, USA.
--
-+#
- # Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
- # created by `make install' are always world readable, even if the
- # installer happens to have an overly restrictive umask (e.g. 077).
-@@ -803,26 +668,15 @@
- fi
- AC_SUBST([mkdir_p])])
-
--# Helper functions for option handling. -*- Autoconf -*-
-+# Helper functions for option handling. -*- Autoconf -*-
-
--# Copyright (C) 2001, 2002, 2003 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, 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., 59 Temple Place - Suite 330, Boston, MA
--# 02111-1307, USA.
-+# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
-+#
-+# This file is free software; the Free Software Foundation
-+# gives unlimited permission to copy and/or distribute it,
-+# with or without modifications, as long as this notice is preserved.
-
--# serial 2
-+# serial 3
-
- # _AM_MANGLE_OPTION(NAME)
- # -----------------------
-@@ -847,28 +701,16 @@
- AC_DEFUN([_AM_IF_OPTION],
- [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-
--#
--# Check to make sure that the build environment is sane.
--#
--
--# Copyright (C) 1996, 1997, 2000, 2001, 2003 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, or (at your option)
--# any later version.
-+# Check to make sure that the build environment is sane. -*- Autoconf -*-
-
--# 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., 59 Temple Place - Suite 330, Boston, MA
--# 02111-1307, USA.
-+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
-+# Free Software Foundation, Inc.
-+#
-+# This file is free software; the Free Software Foundation
-+# gives unlimited permission to copy and/or distribute it,
-+# with or without modifications, as long as this notice is preserved.
-
--# serial 3
-+# serial 4
-
- # AM_SANITY_CHECK
- # ---------------
-@@ -911,25 +753,14 @@
- fi
- AC_MSG_RESULT(yes)])
-
--# AM_PROG_INSTALL_STRIP
--
--# Copyright (C) 2001, 2003 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, 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., 59 Temple Place - Suite 330, Boston, MA
--# 02111-1307, USA.
-+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
-+#
-+# This file is free software; the Free Software Foundation
-+# gives unlimited permission to copy and/or distribute it,
-+# with or without modifications, as long as this notice is preserved.
-
-+# AM_PROG_INSTALL_STRIP
-+# ---------------------
- # One issue with vendor `install' (even GNU) is that you can't
- # specify the program used to strip binaries. This is especially
- # annoying in cross-compiling environments, where the build's strip
-@@ -952,25 +783,13 @@
-
- # Check how to create a tarball. -*- Autoconf -*-
-
--# Copyright (C) 2004 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, 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., 59 Temple Place - Suite 330, Boston, MA
--# 02111-1307, USA.
--
--# serial 1
-+# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
-+#
-+# This file is free software; the Free Software Foundation
-+# gives unlimited permission to copy and/or distribute it,
-+# with or without modifications, as long as this notice is preserved.
-
-+# serial 2
-
- # _AM_PROG_TAR(FORMAT)
- # --------------------
-diff -Naur grub-0.97.orig/ChangeLog grub-0.97/ChangeLog
---- grub-0.97.orig/ChangeLog 2005-05-07 19:47:02.000000000 -0700
-+++ grub-0.97/ChangeLog 2006-07-04 00:01:50.000000000 -0700
-@@ -1,3 +1,51 @@
-+2006-05-02 Pavel Roskin <proski@gnu.org>
-+
-+ * stage2/stage2.c (run_menu): Fix "savedefault" to save only top
-+ level menu positions. Remember current position when calling a
-+ submenu. Don't recalculate it when booting from a submenu.
-+
-+ * grub/main.c (main): Make sure the boot drive number doesn't
-+ exceed 255.
-+
-+2006-05-02 Vesa Jaaskelainen <chaac@nic.fi>
-+
-+ * stage2/shared.h (vbe_mode): Back ported aligment fix from GRUB 2
-+ to GRUB Legacy. Problem reported by Gerardo Richarte.
-+
-+2006-04-23 Robert Millan <robertmh@gnu.org>
-+
-+ * grub/asmstub.c (get_diskinfo): Optimize sysctl routine.
-+
-+2006-04-20 Robert Millan <robertmh@gnu.org>
-+
-+ Fixes for kernel of FreeBSD:
-+ * grub/asmstub.c (get_diskinfo): Toggle "kern.geom.debugflags" sysctl
-+ before opening a device for writing.
-+ * util/grub-install.in: Devices don't have this "r" prefix anymore.
-+
-+2006-04-16 Yoshinori K. Okuji <okuji@enbug.org>
-+
-+ * docs/multiboot.texi: Correct the offset of address
-+ fields. Reported by Jeroen Dekkers.
-+
-+2006-03-21 Yoshinori K. Okuji <okuji@enbug.org>
-+
-+ * stage2/builtins.c (setup_func): Specify the size of DEVICE to
-+ grub_strncat instead of a strange number 256. Reported by Vitaly
-+ Fertman <vitaly@namesys.com>.
-+
-+2005-09-29 Yoshinori K. Okuji <okuji@enbug.org>
-+
-+ * docs/multiboot.texi: Fix a bug in the byte order of
-+ boot_device. I hope this won't affect any OS image.
-+ Increased the version number to 0.6.94.
-+
-+2005-09-28 Yoshinori K. Okuji <okuji@enbug.org>
-+
-+ * stage2/boot.c (load_image): Even if an OS image is an ELF
-+ object, use the a.out kludge if MULTIBOOT_AOUT_KLUDGE is
-+ specified.
-+
- 2005-05-08 Yoshinori K. Okuji <okuji@enbug.org>
-
- * configure.ac (AC_INIT): Upgraded to 0.97.
-diff -Naur grub-0.97.orig/configure grub-0.97/configure
---- grub-0.97.orig/configure 2005-05-07 19:48:12.000000000 -0700
-+++ grub-0.97/configure 2006-07-04 00:08:05.000000000 -0700
-@@ -311,7 +311,7 @@
- # include <unistd.h>
- #endif"
-
--ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar build build_cpu build_vendor build_os host host_cpu host_vendor host_os MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT PERL CC ac_ct_CC CFLAGS LDFLAGS CPPFLAGS EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CCAS RANLIB ac_ct_RANLIB STAGE1_CFLAGS STAGE2_CFLAGS GRUB_CFLAGS OBJCOPY ac_ct_OBJCOPY GRUB_LIBS CPP EGREP NETBOOT_SUPPORT_TRUE NETBOOT_SUPPORT_FALSE DISKLESS_SUPPORT_TRUE DISKLESS_SUPPORT_FALSE HERCULES_SUPPORT_TRUE HERCULES_SUPPORT_FALSE SERIAL_SUPPORT_TRUE SERIAL_SUPPORT_FALSE SERIAL_SPEED_SIMULATION_TRUE SERIAL_SPEED_SIMULATION_FALSE BUILD_EXAMPLE_KERNEL_TRUE BUILD_EXAMPLE_KERNEL_FALSE FSYS_CFLAGS NET_CFLAGS NET_EXTRAFLAGS NETBOOT_DRIVERS CCASFLAGS LIBOBJS LTLIBOBJS'
-+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar build build_cpu build_vendor build_os host host_cpu host_vendor host_os MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT PERL CC ac_ct_CC CFLAGS LDFLAGS CPPFLAGS EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CCAS RANLIB ac_ct_RANLIB STAGE1_CFLAGS STAGE2_CFLAGS GRUB_CFLAGS OBJCOPY ac_ct_OBJCOPY GRUB_LIBS CPP EGREP NETBOOT_SUPPORT_TRUE NETBOOT_SUPPORT_FALSE DISKLESS_SUPPORT_TRUE DISKLESS_SUPPORT_FALSE GRAPHICS_SUPPORT_TRUE GRAPHICS_SUPPORT_FALSE HERCULES_SUPPORT_TRUE HERCULES_SUPPORT_FALSE SERIAL_SUPPORT_TRUE SERIAL_SUPPORT_FALSE SERIAL_SPEED_SIMULATION_TRUE SERIAL_SPEED_SIMULATION_FALSE BUILD_EXAMPLE_KERNEL_TRUE BUILD_EXAMPLE_KERNEL_FALSE FSYS_CFLAGS NET_CFLAGS NET_EXTRAFLAGS NETBOOT_DRIVERS CCASFLAGS LIBOBJS LTLIBOBJS'
- ac_subst_files=''
-
- # Initialize some variables set by options.
-@@ -914,6 +914,7 @@
- set the default memory location for WD/SMC
- --enable-cs-scan=LIST probe for CS89x0 base address using LIST
- --enable-diskless enable diskless support
-+ --disable-graphics disable graphics terminal support
- --disable-hercules disable hercules terminal support
- --disable-serial disable serial terminal support
- --enable-serial-speed-simulation
-@@ -5966,6 +5967,22 @@
- fi
-
-
-+# Check whether --enable-graphics or --disable-graphics was given.
-+if test "${enable_graphics+set}" = set; then
-+ enableval="$enable_graphics"
-+
-+fi;
-+
-+
-+if test "x$enable_graphics" != xno; then
-+ GRAPHICS_SUPPORT_TRUE=
-+ GRAPHICS_SUPPORT_FALSE='#'
-+else
-+ GRAPHICS_SUPPORT_TRUE='#'
-+ GRAPHICS_SUPPORT_FALSE=
-+fi
-+
-+
- # Check whether --enable-hercules or --disable-hercules was given.
- if test "${enable_hercules+set}" = set; then
- enableval="$enable_hercules"
-@@ -6270,6 +6287,13 @@
- Usually this means the macro was only invoked conditionally." >&2;}
- { (exit 1); exit 1; }; }
- fi
-+if test -z "${GRAPHICS_SUPPORT_TRUE}" && test -z "${GRAPHICS_SUPPORT_FALSE}"; then
-+ { { echo "$as_me:$LINENO: error: conditional \"GRAPHICS_SUPPORT\" was never defined.
-+Usually this means the macro was only invoked conditionally." >&5
-+echo "$as_me: error: conditional \"GRAPHICS_SUPPORT\" was never defined.
-+Usually this means the macro was only invoked conditionally." >&2;}
-+ { (exit 1); exit 1; }; }
-+fi
- if test -z "${HERCULES_SUPPORT_TRUE}" && test -z "${HERCULES_SUPPORT_FALSE}"; then
- { { echo "$as_me:$LINENO: error: conditional \"HERCULES_SUPPORT\" was never defined.
- Usually this means the macro was only invoked conditionally." >&5
-@@ -6907,6 +6931,8 @@
- s,@NETBOOT_SUPPORT_FALSE@,$NETBOOT_SUPPORT_FALSE,;t t
- s,@DISKLESS_SUPPORT_TRUE@,$DISKLESS_SUPPORT_TRUE,;t t
- s,@DISKLESS_SUPPORT_FALSE@,$DISKLESS_SUPPORT_FALSE,;t t
-+s,@GRAPHICS_SUPPORT_TRUE@,$GRAPHICS_SUPPORT_TRUE,;t t
-+s,@GRAPHICS_SUPPORT_FALSE@,$GRAPHICS_SUPPORT_FALSE,;t t
- s,@HERCULES_SUPPORT_TRUE@,$HERCULES_SUPPORT_TRUE,;t t
- s,@HERCULES_SUPPORT_FALSE@,$HERCULES_SUPPORT_FALSE,;t t
- s,@SERIAL_SUPPORT_TRUE@,$SERIAL_SUPPORT_TRUE,;t t
-diff -Naur grub-0.97.orig/configure.ac grub-0.97/configure.ac
---- grub-0.97.orig/configure.ac 2005-05-07 19:36:03.000000000 -0700
-+++ grub-0.97/configure.ac 2006-07-03 23:58:41.000000000 -0700
-@@ -595,6 +595,11 @@
- [ --enable-diskless enable diskless support])
- AM_CONDITIONAL(DISKLESS_SUPPORT, test "x$enable_diskless" = xyes)
-
-+dnl Graphical splashscreen support
-+AC_ARG_ENABLE(graphics,
-+ [ --disable-graphics disable graphics terminal support])
-+AM_CONDITIONAL(GRAPHICS_SUPPORT, test "x$enable_graphics" != xno)
-+
- dnl Hercules terminal
- AC_ARG_ENABLE(hercules,
- [ --disable-hercules disable hercules terminal support])
-diff -Naur grub-0.97.orig/docs/grub.8 grub-0.97/docs/grub.8
---- grub-0.97.orig/docs/grub.8 2005-05-07 19:48:56.000000000 -0700
-+++ grub-0.97/docs/grub.8 2006-07-04 00:01:50.000000000 -0700
-@@ -1,5 +1,5 @@
- .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.23.
--.TH GRUB "8" "May 2005" "grub (GNU GRUB 0.97)" FSF
-+.TH GRUB "8" "September 2005" "grub (GNU GRUB 0.97)" FSF
- .SH NAME
- grub \- the grub shell
- .SH SYNOPSIS
-diff -Naur grub-0.97.orig/docs/grub.texi grub-0.97/docs/grub.texi
---- grub-0.97.orig/docs/grub.texi 2005-05-07 19:59:59.000000000 -0700
-+++ grub-0.97/docs/grub.texi 2006-07-04 00:00:54.000000000 -0700
-@@ -2199,6 +2199,7 @@
- * rarp:: Initialize a network device via RARP
- * serial:: Set up a serial device
- * setkey:: Configure the key map
-+* splashimage:: Use a splash image
- * terminal:: Choose a terminal
- * terminfo:: Define escape sequences for a terminal
- * tftpserver:: Specify a TFTP server
-@@ -2578,6 +2579,16 @@
- @end deffn
-
-
-+@node splashimage
-+@subsection splashimage
-+
-+@deffn Command splashimage file
-+Select an image to use as the background image. This should be
-+specified using normal GRUB device naming syntax. The format of the
-+file is a gzipped xpm which is 640x480 with a 14 color palette.
-+@end deffn
-+
-+
- @node terminal
- @subsection terminal
-
-@@ -2685,6 +2696,7 @@
- * module:: Load a module
- * modulenounzip:: Load a module without decompression
- * pause:: Wait for a key press
-+* print:: Print a message
- * quit:: Exit from the grub shell
- * reboot:: Reboot your computer
- * read:: Read data from memory
-@@ -3091,6 +3103,16 @@
- @end deffn
-
-
-+@node print
-+@subsection print
-+
-+@deffn Command print message @dots{}
-+Print the @var{message}. Note that placing @key{^G} (ASCII code 7) in the
-+message will cause the speaker to emit the standard beep sound, which is
-+useful for visually impaired people.
-+@end deffn
-+
-+
- @node quit
- @subsection quit
-
-diff -Naur grub-0.97.orig/docs/multiboot.texi grub-0.97/docs/multiboot.texi
---- grub-0.97.orig/docs/multiboot.texi 2003-07-09 04:45:36.000000000 -0700
-+++ grub-0.97/docs/multiboot.texi 2006-07-04 00:01:50.000000000 -0700
-@@ -25,7 +25,7 @@
- @ifinfo
- Copyright @copyright{} 1995, 96 Bryan Ford <baford@@cs.utah.edu>
- Copyright @copyright{} 1995, 96 Erich Stefan Boleyn <erich@@uruk.org>
--Copyright @copyright{} 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
-+Copyright @copyright{} 1999, 2000, 2001, 2002, 2005, 2006 Free Software Foundation, Inc.
-
- Permission is granted to make and distribute verbatim copies of
- this manual provided the copyright notice and this permission notice
-@@ -57,7 +57,7 @@
- @vskip 0pt plus 1filll
- Copyright @copyright{} 1995, 96 Bryan Ford <baford@@cs.utah.edu>
- Copyright @copyright{} 1995, 96 Erich Stefan Boleyn <erich@@uruk.org>
--Copyright @copyright{} 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
-+Copyright @copyright{} 1999, 2000, 2001, 2002, 2005, 2006 Free Software Foundation, Inc.
-
- Permission is granted to make and distribute verbatim copies of
- this manual provided the copyright notice and this permission notice
-@@ -80,7 +80,7 @@
- @top Multiboot Specification
-
- This file documents Multiboot Specification, the proposal for the boot
--sequence standard. This edition documents version 0.6.93.
-+sequence standard. This edition documents version 0.6.94.
- @end ifnottex
-
- @menu
-@@ -426,7 +426,7 @@
- kernel.
-
- If bit 16 in the @samp{flags} word is set, then the fields at offsets
--8-24 in the Multiboot header are valid, and the boot loader should use
-+12-28 in the Multiboot header are valid, and the boot loader should use
- them instead of the fields in the actual executable header to calculate
- where to load the OS image. This information does not need to be
- provided if the kernel image is in @sc{elf} format, but it @emph{must}
-@@ -677,7 +677,7 @@
- @example
- @group
- +-------+-------+-------+-------+
--| drive | part1 | part2 | part3 |
-+| part3 | part2 | part1 | drive |
- +-------+-------+-------+-------+
- @end group
- @end example
-@@ -1199,6 +1199,13 @@
- @email{bug-grub@@gnu.org}, from Bryan Ford and Erich Stefan Boleyn.
- @end itemize
-
-+@item
-+The byte order of the @samp{boot_device} in Multiboot information is
-+reversed. This was a mistake.
-+
-+@item
-+The offset of the address fields were wrong.
-+
- @item 0.6
- @itemize @bullet
- @item
-diff -Naur grub-0.97.orig/grub/asmstub.c grub-0.97/grub/asmstub.c
---- grub-0.97.orig/grub/asmstub.c 2005-02-16 12:45:14.000000000 -0800
-+++ grub-0.97/grub/asmstub.c 2006-07-04 00:01:50.000000000 -0700
-@@ -42,6 +42,12 @@
- #include <sys/time.h>
- #include <termios.h>
- #include <signal.h>
-+#include <sys/mman.h>
-+
-+#include <limits.h>
-+#ifndef PAGESIZE
-+#define PAGESIZE 4096
-+#endif
-
- #ifdef __linux__
- # include <sys/ioctl.h> /* ioctl */
-@@ -55,6 +61,10 @@
- # endif /* ! BLKFLSBUF */
- #endif /* __linux__ */
-
-+#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
-+# include <sys/sysctl.h>
-+#endif
-+
- /* We want to prevent any circularararity in our stubs, as well as
- libc name clashes. */
- #define WITHOUT_LIBC_STUBS 1
-@@ -144,6 +154,22 @@
- assert (grub_scratch_mem == 0);
- scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15);
- assert (scratch);
-+
-+ {
-+ char *p;
-+ int ret;
-+
-+ /* Align to a multiple of PAGESIZE, assumed to be a power of two. */
-+ p = (char *) (((long) scratch) & ~(PAGESIZE - 1));
-+
-+ /* The simulated stack needs to be executable, since GCC uses stack
-+ * trampolines to implement nested functions.
-+ */
-+ ret = mprotect (p, 0x100000 + EXTENDED_MEMSIZE + 15,
-+ PROT_READ | PROT_WRITE | PROT_EXEC);
-+ assert (ret == 0);
-+ }
-+
- grub_scratch_mem = (char *) ((((int) scratch) >> 4) << 4);
-
- /* FIXME: simulate the memory holes using mprot, if available. */
-@@ -777,7 +803,39 @@
-
- /* Open read/write, or read-only if that failed. */
- if (! read_only)
-- disks[drive].flags = open (devname, O_RDWR);
-+ {
-+/* By default, kernel of FreeBSD does not allow overwriting MBR */
-+#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
-+#define GEOM_SYSCTL "kern.geom.debugflags"
-+ int old_flags, flags;
-+ size_t sizeof_int = sizeof (int);
-+
-+ if (sysctlbyname (GEOM_SYSCTL, &old_flags, &sizeof_int, NULL, 0) != 0)
-+ grub_printf ("failed to get " GEOM_SYSCTL "sysctl: %s\n", strerror (errno));
-+
-+ if ((old_flags & 0x10) == 0)
-+ {
-+ /* "allow foot shooting", see geom(4) */
-+ flags = old_flags | 0x10;
-+
-+ if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, &flags, sizeof (int)) != 0)
-+ {
-+ flags = old_flags;
-+ grub_printf ("failed to set " GEOM_SYSCTL "sysctl: %s\n", strerror (errno));
-+ }
-+ }
-+ else
-+ flags = old_flags;
-+#endif
-+ disks[drive].flags = open (devname, O_RDWR);
-+#if defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
-+ if (flags != old_flags)
-+ {
-+ if (sysctlbyname (GEOM_SYSCTL, NULL, NULL, &old_flags, sizeof (int)) != 0)
-+ grub_printf ("failed to set " GEOM_SYSCTL "sysctl: %s\n", strerror (errno));
-+ }
-+#endif
-+ }
-
- if (disks[drive].flags == -1)
- {
-diff -Naur grub-0.97.orig/grub/main.c grub-0.97/grub/main.c
---- grub-0.97.orig/grub/main.c 2003-07-09 04:45:36.000000000 -0700
-+++ grub-0.97/grub/main.c 2006-07-04 00:01:50.000000000 -0700
-@@ -32,6 +32,7 @@
- #define WITHOUT_LIBC_STUBS 1
- #include <shared.h>
- #include <term.h>
-+#include <device.h>
-
- char *program_name = 0;
- int use_config_file = 1;
-@@ -192,6 +193,12 @@
- perror ("strtoul");
- exit (1);
- }
-+ if (boot_drive >= NUM_DISKS)
-+ {
-+ fprintf (stderr, "boot_drive should be from 0 to %d\n",
-+ NUM_DISKS - 1);
-+ exit (1);
-+ }
- break;
-
- case OPT_NO_CONFIG_FILE:
-diff -Naur grub-0.97.orig/lib/device.c grub-0.97/lib/device.c
---- grub-0.97.orig/lib/device.c 2005-03-27 15:14:25.000000000 -0800
-+++ grub-0.97/lib/device.c 2006-07-04 00:00:44.000000000 -0700
-@@ -131,6 +131,152 @@
- #include <shared.h>
- #include <device.h>
-
-+#if defined(__linux__)
-+/* The 2.6 kernel has removed all of the geometry handling for IDE drives
-+ * that did fixups for LBA, etc. This means that the geometry we get
-+ * with the ioctl has a good chance of being wrong. So, we get to
-+ * also know about partition tables and try to read what the geometry
-+ * is there. *grumble* Very closely based on code from cfdisk
-+ */
-+static void get_kernel_geometry(int fd, long long *cyl, int *heads, int *sectors) {
-+ struct hd_geometry hdg;
-+
-+ if (ioctl (fd, HDIO_GETGEO, &hdg))
-+ return;
-+
-+ *cyl = hdg.cylinders;
-+ *heads = hdg.heads;
-+ *sectors = hdg.sectors;
-+}
-+
-+struct partition {
-+ unsigned char boot_ind; /* 0x80 - active */
-+ unsigned char head; /* starting head */
-+ unsigned char sector; /* starting sector */
-+ unsigned char cyl; /* starting cylinder */
-+ unsigned char sys_ind; /* What partition type */
-+ unsigned char end_head; /* end head */
-+ unsigned char end_sector; /* end sector */
-+ unsigned char end_cyl; /* end cylinder */
-+ unsigned char start4[4]; /* starting sector counting from 0 */
-+ unsigned char size4[4]; /* nr of sectors in partition */
-+};
-+
-+#define ALIGNMENT 2
-+typedef union {
-+ struct {
-+ unsigned char align[ALIGNMENT];
-+ unsigned char b[SECTOR_SIZE];
-+ } c;
-+ struct {
-+ unsigned char align[ALIGNMENT];
-+ unsigned char buffer[0x1BE];
-+ struct partition part[4];
-+ unsigned char magicflag[2];
-+ } p;
-+} partition_table;
-+
-+#define PART_TABLE_FLAG0 0x55
-+#define PART_TABLE_FLAG1 0xAA
-+
-+static void
-+get_partition_table_geometry(partition_table *bufp, long long *cyl, int *heads,
-+ int *sectors) {
-+ struct partition *p;
-+ int i,h,s,hh,ss;
-+ int first = 1;
-+ int bad = 0;
-+
-+ if (bufp->p.magicflag[0] != PART_TABLE_FLAG0 ||
-+ bufp->p.magicflag[1] != PART_TABLE_FLAG1) {
-+ /* Matthew Wilcox: slightly friendlier version of
-+ fatal(_("Bad signature on partition table"), 3);
-+ */
-+ fprintf(stderr, "Unknown partition table signature\n");
-+ return;
-+ }
-+
-+ hh = ss = 0;
-+ for (i=0; i<4; i++) {
-+ p = &(bufp->p.part[i]);
-+ if (p->sys_ind != 0) {
-+ h = p->end_head + 1;
-+ s = (p->end_sector & 077);
-+ if (first) {
-+ hh = h;
-+ ss = s;
-+ first = 0;
-+ } else if (hh != h || ss != s)
-+ bad = 1;
-+ }
-+ }
-+
-+ if (!first && !bad) {
-+ *heads = hh;
-+ *sectors = ss;
-+ }
-+}
-+
-+static long long my_lseek (unsigned int fd, long long offset,
-+ unsigned int origin)
-+{
-+#if defined(__linux__) && (!defined(__GLIBC__) || \
-+ ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
-+ /* Maybe libc doesn't have large file support. */
-+ loff_t offset, result;
-+ static int _llseek (uint filedes, ulong hi, ulong lo,
-+ loff_t *res, uint wh);
-+ _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
-+ loff_t *, res, uint, wh);
-+
-+ if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET) < 0)
-+ return (long long) -1;
-+ return result;
-+#else
-+ return lseek(fd, offset, SEEK_SET);
-+#endif
-+}
-+
-+static void get_linux_geometry (int fd, struct geometry *geom) {
-+ long long kern_cyl = 0; int kern_head = 0, kern_sectors = 0;
-+ long long pt_cyl = 0; int pt_head = 0, pt_sectors = 0;
-+ partition_table bufp;
-+ char *buff, *buf_unaligned;
-+
-+ buf_unaligned = malloc(sizeof(partition_table) + 4095);
-+ buff = (char *) (((unsigned long)buf_unaligned + 4096 - 1) &
-+ (~(4096-1)));
-+
-+ get_kernel_geometry(fd, &kern_cyl, &kern_head, &kern_sectors);
-+
-+ if (my_lseek (fd, 0*SECTOR_SIZE, SEEK_SET) < 0) {
-+ fprintf(stderr, "Unable to seek");
-+ }
-+
-+ if (read(fd, buff, SECTOR_SIZE) == SECTOR_SIZE) {
-+ memcpy(bufp.c.b, buff, SECTOR_SIZE);
-+ get_partition_table_geometry(&bufp, &pt_cyl, &pt_head, &pt_sectors);
-+ } else {
-+ fprintf(stderr, "Unable to read partition table: %s\n", strerror(errno));
-+ }
-+
-+ if (pt_head && pt_sectors) {
-+ int cyl_size;
-+
-+ geom->heads = pt_head;
-+ geom->sectors = pt_sectors;
-+ cyl_size = pt_head * pt_sectors;
-+ geom->cylinders = geom->total_sectors/cyl_size;
-+ } else {
-+ geom->heads = kern_head;
-+ geom->sectors = kern_sectors;
-+ geom->cylinders = kern_cyl;
-+ }
-+
-+ return;
-+}
-+#endif
-+
- /* Get the geometry of a drive DRIVE. */
- void
- get_drive_geometry (struct geometry *geom, char **map, int drive)
-@@ -151,21 +297,16 @@
- #if defined(__linux__)
- /* Linux */
- {
-- struct hd_geometry hdg;
- unsigned long nr;
--
-- if (ioctl (fd, HDIO_GETGEO, &hdg))
-- goto fail;
-
- if (ioctl (fd, BLKGETSIZE, &nr))
- goto fail;
-
- /* Got the geometry, so save it. */
-- geom->cylinders = hdg.cylinders;
-- geom->heads = hdg.heads;
-- geom->sectors = hdg.sectors;
- geom->total_sectors = nr;
--
-+ get_linux_geometry(fd, geom);
-+ if (!geom->heads && !geom->cylinders && !geom->sectors)
-+ goto fail;
- goto success;
- }
-
-@@ -403,6 +544,18 @@
- }
-
- static void
-+get_cciss_disk_name (char *name, int controller, int drive)
-+{
-+ sprintf (name, "/dev/cciss/c%dd%d", controller, drive);
-+}
-+
-+static void
-+get_ida_disk_name (char *name, int controller, int drive)
-+{
-+ sprintf (name, "/dev/ida/c%dd%d", controller, drive);
-+}
-+
-+static void
- get_ataraid_disk_name (char *name, int unit)
- {
- sprintf (name, "/dev/ataraid/d%c", unit + '0');
-@@ -801,6 +954,74 @@
- }
- }
- }
-+
-+ /* This is for CCISS, its like the DAC960 - we have
-+ /dev/cciss/<controller>d<logical drive>p<partition>
-+
-+ It currently supports up to 3 controllers, 10 logical volumes
-+ and 10 partitions
-+
-+ Code gratuitously copied from DAC960 above.
-+ Horms <horms@verge.net.au> 23rd July 2004
-+ */
-+ {
-+ int controller, drive;
-+
-+ for (controller = 0; controller < 2; controller++)
-+ {
-+ for (drive = 0; drive < 9; drive++)
-+ {
-+ char name[24];
-+
-+ get_cciss_disk_name (name, controller, drive);
-+ if (check_device (name))
-+ {
-+ (*map)[num_hd + 0x80] = strdup (name);
-+ assert ((*map)[num_hd + 0x80]);
-+
-+ /* If the device map file is opened, write the map. */
-+ if (fp)
-+ fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
-+
-+ num_hd++;
-+ }
-+ }
-+ }
-+ }
-+
-+ /* This is for Compaq Smart Array, its like the DAC960 - we have
-+ /dev/ida/<controller>d<logical drive>p<partition>
-+
-+ It currently supports up to 3 controllers, 10 logical volumes
-+ and 15 partitions
-+
-+ Code gratuitously copied from DAC960 above.
-+ Piotr Roszatycki <dexter@debian.org>
-+ */
-+ {
-+ int controller, drive;
-+
-+ for (controller = 0; controller < 2; controller++)
-+ {
-+ for (drive = 0; drive < 9; drive++)
-+ {
-+ char name[24];
-+
-+ get_ida_disk_name (name, controller, drive);
-+ if (check_device (name))
-+ {
-+ (*map)[num_hd + 0x80] = strdup (name);
-+ assert ((*map)[num_hd + 0x80]);
-+
-+ /* If the device map file is opened, write the map. */
-+ if (fp)
-+ fprintf (fp, "(hd%d)\t%s\n", num_hd, name);
-+
-+ num_hd++;
-+ }
-+ }
-+ }
-+ }
- #endif /* __linux__ */
-
- /* OK, close the device map file if opened. */
-@@ -844,6 +1065,7 @@
- {
- char dev[PATH_MAX]; /* XXX */
- int fd;
-+ off_t offset = (off_t) sector * (off_t) SECTOR_SIZE;
-
- if ((partition & 0x00FF00) != 0x00FF00)
- {
-@@ -861,8 +1083,14 @@
- if (strcmp (dev + strlen(dev) - 5, "/disc") == 0)
- strcpy (dev + strlen(dev) - 5, "/part");
- }
-- sprintf (dev + strlen(dev), "%d", ((partition >> 16) & 0xFF) + 1);
--
-+ sprintf (dev + strlen(dev), "%s%d",
-+ /* Compaq smart and others */
-+ (strncmp(dev, "/dev/ida/", 9) == 0 ||
-+ strncmp(dev, "/dev/ataraid/", 13) == 0 ||
-+ strncmp(dev, "/dev/cciss/", 11) == 0 ||
-+ strncmp(dev, "/dev/rd/", 8) == 0) ? "p" : "",
-+ ((partition >> 16) & 0xFF) + 1);
-+
- /* Open the partition. */
- fd = open (dev, O_RDWR);
- if (fd < 0)
-@@ -870,35 +1098,13 @@
- errnum = ERR_NO_PART;
- return 0;
- }
--
--#if defined(__linux__) && (!defined(__GLIBC__) || \
-- ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))))
-- /* Maybe libc doesn't have large file support. */
-- {
-- loff_t offset, result;
-- static int _llseek (uint filedes, ulong hi, ulong lo,
-- loff_t *res, uint wh);
-- _syscall5 (int, _llseek, uint, filedes, ulong, hi, ulong, lo,
-- loff_t *, res, uint, wh);
-
-- offset = (loff_t) sector * (loff_t) SECTOR_SIZE;
-- if (_llseek (fd, offset >> 32, offset & 0xffffffff, &result, SEEK_SET))
-- {
-- errnum = ERR_DEV_VALUES;
-- return 0;
-- }
-- }
--#else
-- {
-- off_t offset = (off_t) sector * (off_t) SECTOR_SIZE;
-
-- if (lseek (fd, offset, SEEK_SET) != offset)
-- {
-- errnum = ERR_DEV_VALUES;
-- return 0;
-- }
-- }
--#endif
-+ if (my_lseek(fd, offset, SEEK_SET) != offset)
-+ {
-+ errnum = ERR_DEV_VALUES;
-+ return 0;
-+ }
-
- if (write (fd, buf, size * SECTOR_SIZE) != (size * SECTOR_SIZE))
- {
-diff -Naur grub-0.97.orig/stage2/asm.S grub-0.97/stage2/asm.S
---- grub-0.97.orig/stage2/asm.S 2004-06-19 09:55:22.000000000 -0700
-+++ grub-0.97/stage2/asm.S 2006-07-04 00:01:19.000000000 -0700
-@@ -1651,7 +1651,29 @@
- jnz 3f
- ret
-
--3: /* use keyboard controller */
-+3: /*
-+ * try to switch gateA20 using PORT92, the "Fast A20 and Init"
-+ * register
-+ */
-+ mov $0x92, %dx
-+ inb %dx, %al
-+ /* skip the port92 code if it's unimplemented (read returns 0xff) */
-+ cmpb $0xff, %al
-+ jz 6f
-+
-+ /* set or clear bit1, the ALT_A20_GATE bit */
-+ movb 4(%esp), %ah
-+ testb %ah, %ah
-+ jz 4f
-+ orb $2, %al
-+ jmp 5f
-+4: and $0xfd, %al
-+
-+ /* clear the INIT_NOW bit don't accidently reset the machine */
-+5: and $0xfe, %al
-+ outb %al, %dx
-+
-+6: /* use keyboard controller */
- pushl %eax
-
- call gloop1
-@@ -1661,9 +1683,12 @@
-
- gloopint1:
- inb $K_STATUS
-+ cmpb $0xff, %al
-+ jz gloopint1_done
- andb $K_IBUF_FUL, %al
- jnz gloopint1
-
-+gloopint1_done:
- movb $KB_OUTPUT_MASK, %al
- cmpb $0, 0x8(%esp)
- jz gdoit
-@@ -1684,6 +1709,8 @@
-
- gloop1:
- inb $K_STATUS
-+ cmpb $0xff, %al
-+ jz gloop2ret
- andb $K_IBUF_FUL, %al
- jnz gloop1
-
-@@ -1991,6 +2018,11 @@
- ENTRY(console_getkey)
- push %ebp
-
-+wait_for_key:
-+ call EXT_C(console_checkkey)
-+ incl %eax
-+ jz wait_for_key
-+
- call EXT_C(prot_to_real)
- .code16
-
-@@ -2216,7 +2248,304 @@
- pop %ebx
- pop %ebp
- ret
--
-+
-+
-+/* graphics mode functions */
-+#ifdef SUPPORT_GRAPHICS
-+VARIABLE(cursorX)
-+.word 0
-+VARIABLE(cursorY)
-+.word 0
-+VARIABLE(cursorCount)
-+.word 0
-+VARIABLE(cursorBuf)
-+.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-+
-+
-+/*
-+ * set_int1c_handler(void)
-+ */
-+ENTRY(set_int1c_handler)
-+ pushl %edi
-+
-+ /* save the original int1c handler */
-+ movl $0x70, %edi
-+ movw (%edi), %ax
-+ movw %ax, ABS(int1c_offset)
-+ movw 2(%edi), %ax
-+ movw %ax, ABS(int1c_segment)
-+
-+ /* save the new int1c handler */
-+ movw $ABS(int1c_handler), %ax
-+ movw %ax, (%edi)
-+ xorw %ax, %ax
-+ movw %ax, 2(%edi)
-+
-+ popl %edi
-+ ret
-+
-+
-+/*
-+ * unset_int1c_handler(void)
-+ */
-+ENTRY(unset_int1c_handler)
-+ pushl %edi
-+
-+ /* check if int1c_handler is set */
-+ movl $0x70, %edi
-+ movw $ABS(int1c_handler), %ax
-+ cmpw %ax, (%edi)
-+ jne int1c_1
-+ xorw %ax, %ax
-+ cmpw %ax, 2(%edi)
-+ jne int1c_1
-+
-+ /* restore the original */
-+ movw ABS(int1c_offset), %ax
-+ movw %ax, (%edi)
-+ movw ABS(int1c_segment), %ax
-+ movw %ax, 2(%edi)
-+
-+int1c_1:
-+ popl %edi
-+ ret
-+
-+
-+/*
-+ * blinks graphics cursor
-+ */
-+ .code16
-+write_data:
-+ movw $0, %ax
-+ movw %ax, %ds
-+
-+ mov $0xA000, %ax /* video in es:di */
-+ mov %ax, %es
-+ mov $80, %ax
-+ movw $ABS(cursorY), %si
-+ mov %ds:(%si), %bx
-+ mul %bx
-+ movw $ABS(cursorX), %si
-+ mov %ds:(%si), %bx
-+ shr $3, %bx /* %bx /= 8 */
-+ add %bx, %ax
-+ mov %ax, %di
-+
-+ movw $ABS(cursorBuf), %si /* fontBuf in ds:si */
-+
-+ /* prepare for data moving */
-+ mov $16, %dx /* altura da fonte */
-+ mov $80, %bx /* bytes por linha */
-+
-+write_loop:
-+ movb %ds:(%si), %al
-+ xorb $0xff, %al
-+ movb %al, %ds:(%si) /* invert cursorBuf */
-+ movb %al, %es:(%di) /* write to video */
-+ add %bx, %di
-+ inc %si
-+ dec %dx
-+ jg write_loop
-+ ret
-+
-+int1c_handler:
-+ pusha
-+ mov $0, %ax
-+ mov %ax, %ds
-+ mov $ABS(cursorCount), %si
-+ mov %ds:(%si), %ax
-+ inc %ax
-+ mov %ax, %ds:(%si)
-+ cmp $9, %ax
-+ jne int1c_done
-+
-+ mov $0, %ax
-+ mov %ax, %ds:(%si)
-+ call write_data
-+
-+int1c_done:
-+ popa
-+ iret
-+ /* call previous int1c handler */
-+ /* ljmp */
-+ .byte 0xea
-+int1c_offset: .word 0
-+int1c_segment: .word 0
-+ .code32
-+
-+
-+/*
-+ * unsigned char set_videomode(unsigned char mode)
-+ * BIOS call "INT 10H Function 0h" to set video mode
-+ * Call with %ah = 0x0
-+ * %al = video mode
-+ * Returns old videomode.
-+ */
-+ENTRY(set_videomode)
-+ pushl %ebp
-+ movl %esp,%ebp
-+ pushl %ebx
-+ pushl %ecx
-+
-+ movb 8(%ebp), %cl
-+
-+ call EXT_C(prot_to_real)
-+ .code16
-+
-+ xorb %al, %al
-+ movb $0xf, %ah
-+ int $0x10 /* Get Current Video mode */
-+ movb %al, %ch
-+ xorb %ah, %ah
-+ movb %cl, %al
-+ int $0x10 /* Set Video mode */
-+
-+ DATA32 call EXT_C(real_to_prot)
-+ .code32
-+
-+ xorl %eax, %eax
-+ movb %ch, %al
-+
-+ popl %ecx
-+ popl %ebx
-+ popl %ebp
-+ ret
-+
-+
-+/*
-+ * int get_videomode()
-+ * BIOS call "INT 10H Function 0Fh" to get current video mode
-+ * Call with %al = 0x0
-+ * %ah = 0xF
-+ * Returns current videomode.
-+ */
-+ENTRY(get_videomode)
-+ pushl %ebp
-+ movl %esp,%ebp
-+ pushl %ebx
-+ pushl %ecx
-+
-+ call EXT_C(prot_to_real)
-+ .code16
-+
-+ xorb %al, %al
-+ movb $0xF, %ah
-+ int $0x10 /* Get Current Video mode */
-+ movb %al, %cl /* For now we only want display mode */
-+
-+ DATA32 call EXT_C(real_to_prot)
-+ .code32
-+
-+ xorl %eax, %eax
-+ movb %cl, %al
-+
-+ popl %ecx
-+ popl %ebx
-+ popl %ebp
-+ ret
-+
-+
-+/*
-+ * unsigned char * graphics_get_font()
-+ * BIOS call "INT 10H Function 11h" to set font
-+ * Call with %ah = 0x11
-+ */
-+ENTRY(graphics_get_font)
-+ push %ebp
-+ push %ebx
-+ push %ecx
-+ push %edx
-+
-+ call EXT_C(prot_to_real)
-+ .code16
-+
-+ movw $0x1130, %ax
-+ movb $6, %bh /* font 8x16 */
-+ int $0x10
-+ movw %bp, %dx
-+ movw %es, %cx
-+
-+ DATA32 call EXT_C(real_to_prot)
-+ .code32
-+
-+ xorl %eax, %eax
-+ movw %cx, %ax
-+ shll $4, %eax
-+ movw %dx, %ax
-+
-+ pop %edx
-+ pop %ecx
-+ pop %ebx
-+ pop %ebp
-+ ret
-+
-+
-+/*
-+ * graphics_set_palette(index, red, green, blue)
-+ * BIOS call "INT 10H Function 10h" to set individual dac register
-+ * Call with %ah = 0x10
-+ * %bx = register number
-+ * %ch = new value for green (0-63)
-+ * %cl = new value for blue (0-63)
-+ * %dh = new value for red (0-63)
-+ */
-+
-+ENTRY(graphics_set_palette)
-+ push %ebp
-+ push %eax
-+ push %ebx
-+ push %ecx
-+ push %edx
-+
-+ movw $0x3c8, %bx /* address write mode register */
-+
-+ /* wait vertical retrace */
-+ movw $0x3da, %dx
-+l1b:
-+ inb %dx, %al /* wait vertical active display */
-+ test $8, %al
-+ jnz l1b
-+
-+l2b:
-+ inb %dx, %al /* wait vertical retrace */
-+ test $8, %al
-+ jnz l2b
-+
-+ mov %bx, %dx
-+ movb 0x18(%esp), %al /* index */
-+ outb %al, %dx
-+ inc %dx
-+
-+ movb 0x1c(%esp), %al /* red */
-+ outb %al, %dx
-+
-+ movb 0x20(%esp), %al /* green */
-+ outb %al, %dx
-+
-+ movb 0x24(%esp), %al /* blue */
-+ outb %al, %dx
-+
-+ movw 0x18(%esp), %bx
-+
-+ call EXT_C(prot_to_real)
-+ .code16
-+
-+ movb %bl, %bh
-+ movw $0x1000, %ax
-+ int $0x10
-+
-+ DATA32 call EXT_C(real_to_prot)
-+ .code32
-+
-+ pop %edx
-+ pop %ecx
-+ pop %ebx
-+ pop %eax
-+ pop %ebp
-+ ret
-+#endif /* SUPPORT_GRAPHICS */
-+
-+
- /*
- * getrtsecs()
- * if a seconds value can be read, read it and return it (BCD),
-diff -Naur grub-0.97.orig/stage2/boot.c grub-0.97/stage2/boot.c
---- grub-0.97.orig/stage2/boot.c 2004-03-30 03:44:08.000000000 -0800
-+++ grub-0.97/stage2/boot.c 2006-07-04 00:01:50.000000000 -0700
-@@ -1,7 +1,7 @@
- /* boot.c - load and bootstrap a kernel */
- /*
- * GRUB -- GRand Unified Bootloader
-- * Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
-+ * Copyright (C) 1999,2000,2001,2002,2003,2004,2005 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
-@@ -29,6 +29,8 @@
- entry_func entry_addr;
- static struct mod_list mll[99];
- static int linux_mem_size;
-+static int elf_kernel_addr;
-+static int elf_kernel_size;
-
- /*
- * The next two functions, 'load_image' and 'load_module', are the building
-@@ -96,7 +98,7 @@
- lh = (struct linux_kernel_header *) buffer;
-
- /* ELF loading supported if multiboot, FreeBSD and NetBSD. */
-- if ((type == KERNEL_TYPE_MULTIBOOT
-+ if (((type == KERNEL_TYPE_MULTIBOOT && ! (flags & MULTIBOOT_AOUT_KLUDGE))
- || pu.elf->e_ident[EI_OSABI] == ELFOSABI_FREEBSD
- || grub_strcmp (pu.elf->e_ident + EI_BRAND, "FreeBSD") == 0
- || suggested_type == KERNEL_TYPE_NETBSD)
-@@ -594,6 +596,7 @@
-
- /* reset this to zero for now */
- cur_addr = 0;
-+ elf_kernel_addr = ~0;
-
- /* scan for program segments */
- for (i = 0; i < pu.elf->e_phnum; i++)
-@@ -630,6 +633,8 @@
- /* mark memory as used */
- if (cur_addr < memaddr + memsiz)
- cur_addr = memaddr + memsiz;
-+ if (elf_kernel_addr > cur_addr)
-+ elf_kernel_addr = cur_addr;
- printf (", <0x%x:0x%x:0x%x>", memaddr, filesiz,
- memsiz - filesiz);
- /* increment number of segments */
-@@ -647,6 +652,8 @@
- }
- }
-
-+ elf_kernel_size = cur_addr - elf_kernel_addr;
-+
- if (! errnum)
- {
- if (! loaded)
-@@ -824,8 +831,11 @@
- moveto = (mbi.mem_upper + 0x400) << 10;
-
- moveto = (moveto - len) & 0xfffff000;
-- max_addr = (lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0203
-- ? lh->initrd_addr_max : LINUX_INITRD_MAX_ADDRESS);
-+ max_addr = LINUX_INITRD_MAX_ADDRESS;
-+ if (lh->header == LINUX_MAGIC_SIGNATURE &&
-+ lh->version >= 0x0203 &&
-+ lh->initrd_addr_max < max_addr)
-+ max_addr = lh->initrd_addr_max;
- if (moveto + len >= max_addr)
- moveto = (max_addr - len) & 0xfffff000;
-
-@@ -864,6 +874,129 @@
- }
- #endif
-
-+#define mem_align4k(p) ((p) + 0xFFF) & 0xFFFFF000
-+
-+static void
-+kfreebsd_setenv (char *env, const char *var, const char *value)
-+{
-+ while (1)
-+ {
-+ if (env[0] == '\0' && env[1] == '\0')
-+ {
-+ env++;
-+ break;
-+ }
-+ else
-+ env++;
-+ }
-+
-+ grub_sprintf (env, "%s=%s", var, value);
-+ env[grub_strlen (env) + 1] = '\0';
-+}
-+
-+static char *
-+kfreebsd_read_hints (char *buf)
-+{
-+ char *buf_end = buf;
-+
-+ if (grub_open ("/boot/device.hints"))
-+ {
-+ char *line_start;
-+ int line_len = 0;
-+ char *envp;
-+ int env_len;
-+
-+ env_len = grub_read (buf, -1);
-+ if (env_len)
-+ {
-+ buf_end += env_len;
-+ *(buf_end++) = '\0';
-+ }
-+ else
-+ return buf_end;
-+
-+ grub_close ();
-+
-+ envp = line_start = buf;
-+ while (*envp)
-+ {
-+ char *envp_current = envp;
-+
-+ switch (*envp)
-+ {
-+ case ' ':
-+ while (*envp == ' ')
-+ {
-+ envp++;
-+ env_len--;
-+ }
-+ grub_memmove (envp_current, envp, env_len + 1);
-+ envp = envp_current;
-+ break;
-+ case '#':
-+ while (*envp != '\n')
-+ {
-+ envp++;
-+ env_len--;
-+ }
-+ if (!line_len)
-+ envp++;
-+ grub_memmove (envp_current, envp, env_len + 1);
-+ envp = envp_current;
-+ break;
-+ case '\n':
-+ if (!line_len)
-+ {
-+ env_len--;
-+ grub_memmove (line_start, envp, env_len + 1);
-+ }
-+ *(envp++) = '\0';
-+ line_len = 0;
-+ line_start = envp;
-+ default:
-+ envp++;
-+ line_len++;
-+ break;
-+ }
-+ }
-+
-+ buf_end = buf + env_len;
-+ *(buf_end++) = '\0';
-+ }
-+
-+ return buf_end;
-+}
-+
-+static u32_t *
-+kfreebsd_set_module_string (u32_t type, u32_t *dst, char *src)
-+{
-+ int size;
-+
-+ *(dst++) = type;
-+ *(dst++) = size = grub_strlen (src) + 1;
-+ grub_strcpy ((void *) dst, src);
-+
-+ return dst + (size + sizeof(u32_t) - 1) / sizeof(u32_t);
-+}
-+
-+static u32_t *
-+kfreebsd_set_module_var (u32_t type, u32_t *dst, u32_t src)
-+{
-+ *(dst++) = type;
-+ *(dst++) = sizeof(u32_t);
-+ *(dst++) = src;
-+
-+ return dst;
-+}
-+
-+static u32_t *
-+kfreebsd_set_modules (u32_t *modulep)
-+{
-+ /* XXX: Need to copy the whole module structure. */
-+ /* XXX: How to pass the module name ? */
-+
-+ return modulep;
-+}
-
- /*
- * All "*_boot" commands depend on the images being loaded into memory
-@@ -877,7 +1010,10 @@
- bsd_boot (kernel_t type, int bootdev, char *arg)
- {
- char *str;
-- int clval = 0, i;
-+ char *kernelname;
-+ char *bsd_root;
-+ int clval = 0;
-+ int i;
- struct bootinfo bi;
-
- #ifdef GRUB_UTIL
-@@ -886,8 +1022,21 @@
- stop_floppy ();
- #endif
-
-+ while (*arg != '/')
-+ arg++;
-+ kernelname = arg;
-+
- while (*(++arg) && *arg != ' ');
-+ *(arg++) = 0;
- str = arg;
-+
-+ bsd_root = grub_strstr (str, "root=");
-+ if (bsd_root)
-+ {
-+ bsd_root += 5;
-+ /* XXX: should copy the str or terminate it. */
-+ }
-+
- while (*str)
- {
- if (*str == '-')
-@@ -910,6 +1059,8 @@
- clval |= RB_GDB;
- if (*str == 'h')
- clval |= RB_SERIAL;
-+ if (*str == 'p')
-+ clval |= RB_PAUSE;
- if (*str == 'm')
- clval |= RB_MUTE;
- if (*str == 'r')
-@@ -927,14 +1078,17 @@
-
- if (type == KERNEL_TYPE_FREEBSD)
- {
-+ char *envp;
-+ u32_t *modp;
-+
- clval |= RB_BOOTINFO;
-
- bi.bi_version = BOOTINFO_VERSION;
-
-- *arg = 0;
-- while ((--arg) > (char *) MB_CMDLINE_BUF && *arg != '/');
-- if (*arg == '/')
-- bi.bi_kernelname = arg + 1;
-+ bi.bi_pad[0] = bi.bi_pad[1] = 0;
-+
-+ if (*kernelname == '/')
-+ bi.bi_kernelname = kernelname;
- else
- bi.bi_kernelname = 0;
-
-@@ -961,6 +1115,30 @@
- bi.bi_basemem = mbi.mem_lower;
- bi.bi_extmem = extended_memory;
-
-+ /* Setup the environment. */
-+ bi.bi_envp = cur_addr = mem_align4k (cur_addr);
-+ grub_memset ((void *) cur_addr, 0, 2);
-+ cur_addr = (int) kfreebsd_read_hints ((void *) cur_addr);
-+
-+ envp = (char *) bi.bi_envp;
-+ kfreebsd_setenv (envp, "kernelname", kernelname);
-+ kfreebsd_setenv (envp, "vfs.root.mountfrom", bsd_root);
-+
-+ /* Setup the modules list. */
-+ bi.bi_modulep = cur_addr = mem_align4k (cur_addr);
-+ modp = (u32_t *) bi.bi_modulep;
-+ /* The first module is the kernel. */
-+ modp = kfreebsd_set_module_string (MODINFO_NAME, modp, kernelname);
-+ modp = kfreebsd_set_module_string (MODINFO_TYPE, modp, "elf kernel");
-+ modp = kfreebsd_set_module_string (MODINFO_ARGS, modp, arg);
-+ modp = kfreebsd_set_module_var (MODINFO_ADDR, modp, elf_kernel_addr);
-+ modp = kfreebsd_set_module_var (MODINFO_SIZE, modp, elf_kernel_size);
-+ /* Now the real modules. */
-+ modp = kfreebsd_set_modules(modp);
-+
-+ /* Set the kernel end. */
-+ bi.bi_kernend = cur_addr = mem_align4k (((int) modp) + 1);
-+
- if (mbi.flags & MB_INFO_AOUT_SYMS)
- {
- bi.bi_symtab = mbi.syms.a.addr;
-@@ -970,8 +1148,9 @@
- #if 0
- else if (mbi.flags & MB_INFO_ELF_SHDR)
- {
-- /* FIXME: Should check if a symbol table exists and, if exists,
-- pass the table to BI. */
-+ bi.bi_symtab = mbi.syms.e.addr;
-+ bi.bi_esymtab = mbi.syms.e.addr
-+ + mbi.syms.e.size * mbi.syms.e.num * mbi.syms.e.shndx;
- }
- #endif
- else
-diff -Naur grub-0.97.orig/stage2/builtins.c grub-0.97/stage2/builtins.c
---- grub-0.97.orig/stage2/builtins.c 2005-02-15 13:58:23.000000000 -0800
-+++ grub-0.97/stage2/builtins.c 2006-07-04 00:01:50.000000000 -0700
-@@ -28,6 +28,10 @@
- #include <filesys.h>
- #include <term.h>
-
-+#ifdef SUPPORT_GRAPHICS
-+# include <graphics.h>
-+#endif
-+
- #ifdef SUPPORT_NETBOOT
- # define GRUB 1
- # include <etherboot.h>
-@@ -82,6 +86,10 @@
- inside other functions. */
- static int configfile_func (char *arg, int flags);
-
-+static int savedefault_helper (char *arg, int flags);
-+
-+static int savedefault_shell (char *arg, int flags);
-+
- /* Initialize the data for builtins. */
- void
- init_builtins (void)
-@@ -237,12 +245,22 @@
- static int
- boot_func (char *arg, int flags)
- {
-+ struct term_entry *prev_term = current_term;
- /* Clear the int15 handler if we can boot the kernel successfully.
- This assumes that the boot code never fails only if KERNEL_TYPE is
- not KERNEL_TYPE_NONE. Is this assumption is bad? */
- if (kernel_type != KERNEL_TYPE_NONE)
- unset_int15_handler ();
-
-+ /* if our terminal needed initialization, we should shut it down
-+ * before booting the kernel, but we want to save what it was so
-+ * we can come back if needed */
-+ if (current_term->shutdown)
-+ {
-+ current_term->shutdown();
-+ current_term = term_table; /* assumption: console is first */
-+ }
-+
- #ifdef SUPPORT_NETBOOT
- /* Shut down the networking. */
- cleanup_net ();
-@@ -306,6 +324,13 @@
- return 1;
- }
-
-+ /* if we get back here, we should go back to what our term was before */
-+ current_term = prev_term;
-+ if (current_term->startup)
-+ /* if our terminal fails to initialize, fall back to console since
-+ * it should always work */
-+ if (current_term->startup() == 0)
-+ current_term = term_table; /* we know that console is first */
- return 0;
- }
-
-@@ -852,6 +877,251 @@
- };
- #endif /* SUPPORT_NETBOOT */
-
-+#ifdef SUPPORT_GRAPHICS
-+\f
-+static int splashimage_func(char *arg, int flags) {
-+ int i;
-+
-+ /* filename can only be 256 characters due to our buffer size */
-+ if (grub_strlen(arg) > 256) {
-+ grub_printf("Splash image filename too large\n");
-+ grub_printf("Press any key to continue...");
-+ getkey();
-+ return 1;
-+ }
-+
-+ /* get rid of TERM_NEED_INIT from the graphics terminal. */
-+ for (i = 0; term_table[i].name; i++) {
-+ if (grub_strcmp (term_table[i].name, "graphics") == 0) {
-+ term_table[i].flags &= ~TERM_NEED_INIT;
-+ break;
-+ }
-+ }
-+
-+ graphics_set_splash(arg);
-+
-+ if (flags == BUILTIN_CMDLINE && graphics_inited) {
-+ graphics_end();
-+ if (graphics_init() == 0) {
-+ /* Fallback to default term */
-+ current_term = term_table;
-+ max_lines = current_term->max_lines;
-+ if (current_term->cls)
-+ current_term->cls();
-+ grub_printf("Failed to set splash image and/or graphics mode\n");
-+ return 1;
-+ }
-+ graphics_cls();
-+ }
-+
-+ if (flags == BUILTIN_MENU)
-+ current_term = term_table + i;
-+
-+ return 0;
-+}
-+
-+static struct builtin builtin_splashimage =
-+{
-+ "splashimage",
-+ splashimage_func,
-+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
-+ "splashimage FILE",
-+ "Load FILE as the background image when in graphics mode."
-+};
-+
-+\f
-+/* shade */
-+static int
-+shade_func(char *arg, int flags)
-+{
-+ int new_shade;
-+
-+ if (!arg || safe_parse_maxint(&arg, &new_shade) == 0)
-+ return (1);
-+
-+ if (shade != new_shade) {
-+ shade = new_shade;
-+ if (flags == BUILTIN_CMDLINE && graphics_inited) {
-+ graphics_end();
-+ graphics_init();
-+ graphics_cls();
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static struct builtin builtin_shade =
-+{
-+ "shade",
-+ shade_func,
-+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
-+ "shade INTEGER",
-+ "If set to 0, disables the use of shaded text, else enables it."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* 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."
-+};
-+
-+\f
-+/* border */
-+static int
-+border_func(char *arg, int flags)
-+{
-+ if (grub_strlen(arg) == 6) {
-+ int r = ((hex(arg[0]) << 4) | hex(arg[1])) >> 2;
-+ int g = ((hex(arg[2]) << 4) | hex(arg[3])) >> 2;
-+ int b = ((hex(arg[4]) << 4) | hex(arg[5])) >> 2;
-+
-+ window_border = (r << 16) | (g << 8) | b;
-+ if (graphics_inited)
-+ graphics_set_palette(0x11, r, g, b);
-+
-+ return 0;
-+ }
-+
-+ return 1;
-+}
-+
-+static struct builtin builtin_border =
-+{
-+ "border",
-+ border_func,
-+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
-+ "border RRGGBB",
-+ "Sets the border video color when in graphics mode."
-+ "RR is red, GG is green, and BB blue. Numbers must be in hexadecimal."
-+};
-+
-+\f
-+/* viewport */
-+static int
-+viewport_func (char *arg, int flags)
-+{
-+ int i;
-+ int x0 = 0, y0 = 0, x1 = 80, y1 = 30;
-+ int *pos[4] = { &x0, &y0, &x1, &y1 };
-+
-+ if (!arg)
-+ return (1);
-+ for (i = 0; i < 4; i++) {
-+ if (!*arg)
-+ return (1);
-+ while (*arg && (*arg == ' ' || *arg == '\t'))
-+ ++arg;
-+ if (!safe_parse_maxint(&arg, pos[i]))
-+ return (1);
-+ while (*arg && (*arg != ' ' && *arg != '\t'))
-+ ++arg;
-+ }
-+
-+ /* minimum size is 65 colums and 16 rows */
-+ if (x0 > x1 - 66 || y0 > y1 - 16 || x0 < 0 || y0 < 0 || x1 > 80 || y1 > 30)
-+ return 1;
-+
-+ view_x0 = x0;
-+ view_y0 = y0;
-+ view_x1 = x1;
-+ view_y1 = y1;
-+
-+ if (flags == BUILTIN_CMDLINE && graphics_inited) {
-+ graphics_end();
-+ graphics_init();
-+ graphics_cls();
-+ }
-+
-+ return 0;
-+}
-+
-+static struct builtin builtin_viewport =
-+{
-+ "viewport",
-+ viewport_func,
-+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
-+ "viewport x0 y0 x1 y1",
-+ "Changes grub internals to output text in the window defined by"
-+ " four parameters. The x and y parameters are 0 based. This option"
-+ " only works with the graphics interface."
-+};
-+
-+#endif /* SUPPORT_GRAPHICS */
-+
-+\f
-+/* 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"
-+};
-+
- \f
- /* displayapm */
- static int
-@@ -1454,14 +1724,20 @@
-
- \f
- /* help */
--#define MAX_SHORT_DOC_LEN 39
--#define MAX_LONG_DOC_LEN 66
--
- static int
- help_func (char *arg, int flags)
- {
-- int all = 0;
--
-+ int all = 0, max_short_doc_len, max_long_doc_len;
-+ max_short_doc_len = 39;
-+ max_long_doc_len = 66;
-+#ifdef SUPPORT_GRAPHICS
-+ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0)
-+ {
-+ max_short_doc_len = (view_x1 - view_x0 + 1) / 2 - 1;
-+ max_long_doc_len = (view_x1 - view_x0) - 14;
-+ }
-+#endif
-+
- if (grub_memcmp (arg, "--all", sizeof ("--all") - 1) == 0)
- {
- all = 1;
-@@ -1491,13 +1767,13 @@
-
- len = grub_strlen ((*builtin)->short_doc);
- /* If the length of SHORT_DOC is too long, truncate it. */
-- if (len > MAX_SHORT_DOC_LEN - 1)
-- len = MAX_SHORT_DOC_LEN - 1;
-+ if (len > max_short_doc_len - 1)
-+ len = max_short_doc_len - 1;
-
- for (i = 0; i < len; i++)
- grub_putchar ((*builtin)->short_doc[i]);
-
-- for (; i < MAX_SHORT_DOC_LEN; i++)
-+ for (; i < max_short_doc_len; i++)
- grub_putchar (' ');
-
- if (! left)
-@@ -1546,10 +1822,10 @@
- int i;
-
- /* If LEN is too long, fold DOC. */
-- if (len > MAX_LONG_DOC_LEN)
-+ if (len > max_long_doc_len)
- {
- /* Fold this line at the position of a space. */
-- for (len = MAX_LONG_DOC_LEN; len > 0; len--)
-+ for (len = max_long_doc_len; len > 0; len--)
- if (doc[len - 1] == ' ')
- break;
- }
-@@ -2323,6 +2599,25 @@
- "Probe I/O ports used for the drive DRIVE."
- };
-
-+/* print */
-+static int
-+print_func (char *arg, int flags)
-+{
-+ printf("%s\n", arg);
-+
-+ return 0;
-+}
-+
-+static struct builtin builtin_print =
-+{
-+ "print",
-+ print_func,
-+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_NO_ECHO,
-+ "print [MESSAGE ...]",
-+ "Print MESSAGE."
-+};
-+
-+
- \f
- /* kernel */
- static int
-@@ -3221,7 +3516,102 @@
- static int
- savedefault_func (char *arg, int flags)
- {
--#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
-+#if !defined(SUPPORT_DISKLESS)
-+ #if !defined(GRUB_UTIL)
-+ savedefault_helper(arg, flags);
-+ #else
-+ savedefault_shell(arg, flags);
-+ #endif
-+#else /* !SUPPORT_DISKLESS */
-+ errnum = ERR_UNRECOGNIZED;
-+ return 1;
-+#endif /* !SUPPORT_DISKLESS */
-+}
-+
-+#if !defined(SUPPORT_DISKLESS) && defined(GRUB_UTIL)
-+/* savedefault_shell */
-+static int
-+savedefault_shell(char *arg, int flags)
-+ {
-+ int once_only = 0;
-+ int new_default;
-+ int curr_default = -1;
-+ int curr_prev_default = -1;
-+ int new_prev_default = -1;
-+ FILE *fp;
-+ size_t bytes = 10;
-+ char line[bytes];
-+ char *default_file = (char *) DEFAULT_FILE_BUF;
-+ char buf[bytes];
-+ int i;
-+
-+ while (1)
-+ {
-+ if (grub_memcmp ("--default=", arg, sizeof ("--default=") - 1) == 0)
-+ {
-+ char *p = arg + sizeof ("--default=") - 1;
-+ if (! safe_parse_maxint (&p, &new_default))
-+ return 1;
-+ arg = skip_to (0, arg);
-+ }
-+ else if (grub_memcmp ("--once", arg, sizeof ("--once") - 1) == 0)
-+ {
-+ once_only = 1;
-+ arg = skip_to (0, arg);
-+ }
-+ else
-+ break;
-+ }
-+
-+ *default_file = 0;
-+ grub_strncat (default_file, config_file, DEFAULT_FILE_BUFLEN);
-+ for (i = grub_strlen(default_file); i >= 0; i--)
-+ if (default_file[i] == '/')
-+ {
-+ i++;
-+ break;
-+ }
-+ default_file[i] = 0;
-+ grub_strncat (default_file + i, "default", DEFAULT_FILE_BUFLEN - i);
-+
-+ if(!(fp = fopen(default_file,"w")))
-+ {
-+ errnum = ERR_READ;
-+ goto fail;
-+ }
-+
-+ read(&line, -1);
-+
-+ sscanf(line, "%d:%d", &curr_prev_default, &curr_default);
-+
-+ if(curr_default != -1)
-+ new_prev_default = curr_default;
-+ else
-+ {
-+ if(curr_prev_default != -1)
-+ new_prev_default = curr_prev_default;
-+ else
-+ new_prev_default = 0;
-+ }
-+
-+ if(once_only)
-+ sprintf(buf, "%d:%d\n", new_prev_default, new_default);
-+ else
-+ sprintf(buf, "%d\n", new_default);
-+
-+ fprintf(fp, buf);
-+
-+fail:
-+ fclose(fp);
-+ return errnum;
-+}
-+#endif
-+
-+/* savedefault_helper */
-+static int
-+savedefault_helper (char *arg, int flags)
-+{
-+#if !defined(SUPPORT_DISKLESS)
- unsigned long tmp_drive = saved_drive;
- unsigned long tmp_partition = saved_partition;
- char *default_file = (char *) DEFAULT_FILE_BUF;
-@@ -3300,19 +3690,23 @@
- disk_read_hook = 0;
- grub_close ();
-
-- if (len != sizeof (buf))
-- {
-- /* This is too small. Do not modify the file manually, please! */
-- errnum = ERR_READ;
-- goto fail;
-- }
--
- if (sector_count > 2)
- {
- /* Is this possible?! Too fragmented! */
- errnum = ERR_FSYS_CORRUPT;
- goto fail;
- }
-+
-+ char *tmp;
-+ if((tmp = grub_strstr(buf, ":")) != NULL)
-+ {
-+ int f_len = grub_strlen(buf) - grub_strlen(tmp);
-+ char *def;
-+ int a;
-+ for(a = 0; a < f_len; a++)
-+ grub_memcpy(&def[a], &buf[a], sizeof(char));
-+ safe_parse_maxint (&def, &entryno);
-+ }
-
- /* Set up a string to be written. */
- grub_memset (buf, '\n', sizeof (buf));
-@@ -3830,15 +4224,15 @@
- {
- char tmp[16];
- grub_sprintf (tmp, ",%d", (partition >> 16) & 0xFF);
-- grub_strncat (device, tmp, 256);
-+ grub_strncat (device, tmp, sizeof (device));
- }
- if ((partition & 0x00FF00) != 0x00FF00)
- {
- char tmp[16];
- grub_sprintf (tmp, ",%c", 'a' + ((partition >> 8) & 0xFF));
-- grub_strncat (device, tmp, 256);
-+ grub_strncat (device, tmp, sizeof (device));
- }
-- grub_strncat (device, ")", 256);
-+ grub_strncat (device, ")", sizeof (device));
- }
-
- int embed_stage1_5 (char *stage1_5, int drive, int partition)
-@@ -4085,7 +4479,7 @@
- };
-
- \f
--#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 +4638,29 @@
- end:
- current_term = term_table + default_term;
- current_term->flags = term_flags;
--
-+
- if (lines)
- max_lines = lines;
- else
-- /* 24 would be a good default value. */
-- max_lines = 24;
--
-+ max_lines = current_term->max_lines;
-+
- /* If the interface is currently the command-line,
- restart it to repaint the screen. */
-- if (current_term != prev_term && (flags & BUILTIN_CMDLINE))
-+ if ((current_term != prev_term) && (flags & BUILTIN_CMDLINE)){
-+ if (prev_term->shutdown)
-+ prev_term->shutdown();
-+ if (current_term->startup) {
-+ /* If startup fails, return to previous term */
-+ if (current_term->startup() == 0) {
-+ current_term = prev_term;
-+ max_lines = current_term->max_lines;
-+ if (current_term->cls) {
-+ current_term->cls();
-+ }
-+ }
-+ }
- grub_longjmp (restart_cmdline_env, 0);
-+ }
-
- return 0;
- }
-@@ -4264,7 +4670,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 +4682,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 */
-
- \f
- #ifdef SUPPORT_SERIAL
-@@ -4795,13 +5201,20 @@
- /* The table of builtin commands. Sorted in dictionary order. */
- struct builtin *builtin_table[] =
- {
-+#ifdef SUPPORT_GRAPHICS
-+ &builtin_background,
-+#endif
- &builtin_blocklist,
- &builtin_boot,
- #ifdef SUPPORT_NETBOOT
- &builtin_bootp,
- #endif /* SUPPORT_NETBOOT */
-+#ifdef SUPPORT_GRAPHICS
-+ &builtin_border,
-+#endif
- &builtin_cat,
- &builtin_chainloader,
-+ &builtin_clear,
- &builtin_cmp,
- &builtin_color,
- &builtin_configfile,
-@@ -4821,6 +5234,9 @@
- &builtin_embed,
- &builtin_fallback,
- &builtin_find,
-+#ifdef SUPPORT_GRAPHICS
-+ &builtin_foreground,
-+#endif
- &builtin_fstest,
- &builtin_geometry,
- &builtin_halt,
-@@ -4848,6 +5264,7 @@
- &builtin_parttype,
- &builtin_password,
- &builtin_pause,
-+ &builtin_print,
- #ifdef GRUB_UTIL
- &builtin_quit,
- #endif /* GRUB_UTIL */
-@@ -4864,9 +5281,13 @@
- #endif /* SUPPORT_SERIAL */
- &builtin_setkey,
- &builtin_setup,
--#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
-+#ifdef SUPPORT_GRAPHICS
-+ &builtin_shade,
-+ &builtin_splashimage,
-+#endif /* SUPPORT_GRAPHICS */
-+#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES) || defined(SUPPORT_GRAPHICS)
- &builtin_terminal,
--#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
-+#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES || SUPPORT_GRAPHICS */
- #ifdef SUPPORT_SERIAL
- &builtin_terminfo,
- #endif /* SUPPORT_SERIAL */
-@@ -4880,5 +5301,8 @@
- &builtin_unhide,
- &builtin_uppermem,
- &builtin_vbeprobe,
-+#ifdef SUPPORT_GRAPHICS
-+ &builtin_viewport,
-+#endif
- 0
- };
-diff -Naur grub-0.97.orig/stage2/char_io.c grub-0.97/stage2/char_io.c
---- grub-0.97.orig/stage2/char_io.c 2005-02-01 12:51:23.000000000 -0800
-+++ grub-0.97/stage2/char_io.c 2006-07-03 23:59:27.000000000 -0700
-@@ -29,12 +29,17 @@
- # include <serial.h>
- #endif
-
-+#ifdef SUPPORT_GRAPHICS
-+# include <graphics.h>
-+#endif
-+
- #ifndef STAGE1_5
- struct term_entry term_table[] =
- {
- {
- "console",
- 0,
-+ 24,
- console_putchar,
- console_checkkey,
- console_getkey,
-@@ -43,13 +48,16 @@
- console_cls,
- console_setcolorstate,
- console_setcolor,
-- console_setcursor
-+ console_setcursor,
-+ 0,
-+ 0
- },
- #ifdef SUPPORT_SERIAL
- {
- "serial",
- /* A serial device must be initialized. */
- TERM_NEED_INIT,
-+ 24,
- serial_putchar,
- serial_checkkey,
- serial_getkey,
-@@ -58,6 +66,8 @@
- serial_cls,
- serial_setcolorstate,
- 0,
-+ 0,
-+ 0,
- 0
- },
- #endif /* SUPPORT_SERIAL */
-@@ -65,6 +75,7 @@
- {
- "hercules",
- 0,
-+ 24,
- hercules_putchar,
- console_checkkey,
- console_getkey,
-@@ -73,11 +84,30 @@
- hercules_cls,
- hercules_setcolorstate,
- hercules_setcolor,
-- hercules_setcursor
-+ hercules_setcursor,
-+ 0,
-+ 0
- },
- #endif /* SUPPORT_HERCULES */
-+#ifdef SUPPORT_GRAPHICS
-+ { "graphics",
-+ TERM_NEED_INIT, /* flags */
-+ 30, /* number of lines */
-+ graphics_putchar, /* putchar */
-+ console_checkkey, /* checkkey */
-+ console_getkey, /* getkey */
-+ graphics_getxy, /* getxy */
-+ graphics_gotoxy, /* gotoxy */
-+ graphics_cls, /* cls */
-+ graphics_setcolorstate, /* setcolorstate */
-+ graphics_setcolor, /* setcolor */
-+ graphics_setcursor, /* nocursor */
-+ graphics_init, /* initialize */
-+ graphics_end /* shutdown */
-+ },
-+#endif /* SUPPORT_GRAPHICS */
- /* This must be the last entry. */
-- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
-+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
- };
-
- /* This must be console. */
-@@ -305,9 +335,10 @@
-
- /* XXX: These should be defined in shared.h, but I leave these here,
- until this code is freezed. */
--#define CMDLINE_WIDTH 78
- #define CMDLINE_MARGIN 10
--
-+
-+ /* command-line limits */
-+ int cmdline_width = 78, col_start = 0;
- int xpos, lpos, c, section;
- /* The length of PROMPT. */
- int plen;
-@@ -338,7 +369,7 @@
-
- /* If the cursor is in the first section, display the first section
- instead of the second. */
-- if (section == 1 && plen + lpos < CMDLINE_WIDTH)
-+ if (section == 1 && plen + lpos < cmdline_width)
- cl_refresh (1, 0);
- else if (xpos - count < 1)
- cl_refresh (1, 0);
-@@ -354,7 +385,7 @@
- grub_putchar ('\b');
- }
- else
-- gotoxy (xpos, getxy () & 0xFF);
-+ gotoxy (xpos + col_start, getxy () & 0xFF);
- }
- }
-
-@@ -364,7 +395,7 @@
- lpos += count;
-
- /* If the cursor goes outside, scroll the screen to the right. */
-- if (xpos + count >= CMDLINE_WIDTH)
-+ if (xpos + count >= cmdline_width)
- cl_refresh (1, 0);
- else
- {
-@@ -383,7 +414,7 @@
- }
- }
- else
-- gotoxy (xpos, getxy () & 0xFF);
-+ gotoxy (xpos + col_start, getxy () & 0xFF);
- }
- }
-
-@@ -398,14 +429,14 @@
- if (full)
- {
- /* Recompute the section number. */
-- if (lpos + plen < CMDLINE_WIDTH)
-+ if (lpos + plen < cmdline_width)
- section = 0;
- else
-- section = ((lpos + plen - CMDLINE_WIDTH)
-- / (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) + 1);
-+ section = ((lpos + plen - cmdline_width)
-+ / (cmdline_width - 1 - CMDLINE_MARGIN) + 1);
-
- /* From the start to the end. */
-- len = CMDLINE_WIDTH;
-+ len = cmdline_width;
- pos = 0;
- grub_putchar ('\r');
-
-@@ -445,8 +476,8 @@
- if (! full)
- offset = xpos - 1;
-
-- start = ((section - 1) * (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN)
-- + CMDLINE_WIDTH - plen - CMDLINE_MARGIN);
-+ start = ((section - 1) * (cmdline_width - 1 - CMDLINE_MARGIN)
-+ + cmdline_width - plen - CMDLINE_MARGIN);
- xpos = lpos + 1 - start;
- start += offset;
- }
-@@ -471,7 +502,7 @@
-
- /* If the cursor is at the last position, put `>' or a space,
- depending on if there are more characters in BUF. */
-- if (pos == CMDLINE_WIDTH)
-+ if (pos == cmdline_width)
- {
- if (start + len < llen)
- grub_putchar ('>');
-@@ -488,7 +519,7 @@
- grub_putchar ('\b');
- }
- else
-- gotoxy (xpos, getxy () & 0xFF);
-+ gotoxy (xpos + col_start, getxy () & 0xFF);
- }
-
- /* Initialize the command-line. */
-@@ -518,10 +549,10 @@
-
- llen += l;
- lpos += l;
-- if (xpos + l >= CMDLINE_WIDTH)
-+ if (xpos + l >= cmdline_width)
- cl_refresh (1, 0);
-- else if (xpos + l + llen - lpos > CMDLINE_WIDTH)
-- cl_refresh (0, CMDLINE_WIDTH - xpos);
-+ else if (xpos + l + llen - lpos > cmdline_width)
-+ cl_refresh (0, cmdline_width - xpos);
- else
- cl_refresh (0, l + llen - lpos);
- }
-@@ -533,12 +564,22 @@
- grub_memmove (buf + lpos, buf + lpos + count, llen - count + 1);
- llen -= count;
-
-- if (xpos + llen + count - lpos > CMDLINE_WIDTH)
-- cl_refresh (0, CMDLINE_WIDTH - xpos);
-+ if (xpos + llen + count - lpos > cmdline_width)
-+ cl_refresh (0, cmdline_width - xpos);
- else
- cl_refresh (0, llen + count - lpos);
- }
-
-+ max_lines = current_term->max_lines;
-+#ifdef SUPPORT_GRAPHICS
-+ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0)
-+ {
-+ cmdline_width = (view_x1 - view_x0) - 2;
-+ col_start = view_x0;
-+ max_lines = view_y1 - view_y0;
-+ }
-+#endif
-+
- plen = grub_strlen (prompt);
- llen = grub_strlen (cmdline);
-
-@@ -1006,6 +1047,48 @@
- }
- #endif /* ! STAGE1_5 */
-
-+#ifndef STAGE1_5
-+/* Internal pager. */
-+int
-+do_more (void)
-+{
-+ if (count_lines >= 0)
-+ {
-+ count_lines++;
-+ if (count_lines >= max_lines - 2)
-+ {
-+ int tmp;
-+
-+ /* It's important to disable the feature temporarily, because
-+ the following grub_printf call will print newlines. */
-+ count_lines = -1;
-+
-+ grub_printf("\n");
-+ if (current_term->setcolorstate)
-+ current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
-+
-+ grub_printf ("[Hit return to continue]");
-+
-+ if (current_term->setcolorstate)
-+ current_term->setcolorstate (COLOR_STATE_NORMAL);
-+
-+
-+ do
-+ {
-+ tmp = ASCII_CHAR (getkey ());
-+ }
-+ while (tmp != '\n' && tmp != '\r');
-+ grub_printf ("\r \r");
-+
-+ /* Restart to count lines. */
-+ count_lines = 0;
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+#endif
-+
- /* Display an ASCII character. */
- void
- grub_putchar (int c)
-@@ -1034,38 +1117,11 @@
-
- if (c == '\n')
- {
-+ int flag;
- /* Internal `more'-like feature. */
-- if (count_lines >= 0)
-- {
-- count_lines++;
-- if (count_lines >= max_lines - 2)
-- {
-- int tmp;
--
-- /* It's important to disable the feature temporarily, because
-- the following grub_printf call will print newlines. */
-- count_lines = -1;
--
-- if (current_term->setcolorstate)
-- current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
--
-- grub_printf ("\n[Hit return to continue]");
--
-- if (current_term->setcolorstate)
-- current_term->setcolorstate (COLOR_STATE_NORMAL);
--
-- do
-- {
-- tmp = ASCII_CHAR (getkey ());
-- }
-- while (tmp != '\n' && tmp != '\r');
-- grub_printf ("\r \r");
--
-- /* Restart to count lines. */
-- count_lines = 0;
-- return;
-- }
-- }
-+ flag = do_more ();
-+ if (flag)
-+ return;
- }
-
- current_term->putchar (c);
-@@ -1090,7 +1146,7 @@
- cls (void)
- {
- /* If the terminal is dumb, there is no way to clean the terminal. */
-- if (current_term->flags & TERM_DUMB)
-+ if (current_term->flags & TERM_DUMB)
- grub_putchar ('\n');
- else
- current_term->cls ();
-@@ -1175,13 +1231,13 @@
- #endif /* ! STAGE1_5 */
-
- int
--memcheck (int addr, int len)
-+memcheck (unsigned long int addr, unsigned long int len)
- {
- #ifdef GRUB_UTIL
-- auto int start_addr (void);
-- auto int end_addr (void);
-+ auto unsigned long int start_addr (void);
-+ auto int unsigned long end_addr (void);
-
-- auto int start_addr (void)
-+ auto unsigned long int start_addr (void)
- {
- int ret;
- # if defined(HAVE_START_SYMBOL)
-@@ -1192,7 +1248,7 @@
- return ret;
- }
-
-- auto int end_addr (void)
-+ auto unsigned long int end_addr (void)
- {
- int ret;
- # if defined(HAVE_END_SYMBOL)
-@@ -1217,6 +1273,16 @@
- return ! errnum;
- }
-
-+void
-+grub_memcpy(void *dest, const void *src, int len)
-+{
-+ int i;
-+ register char *d = (char*)dest, *s = (char*)src;
-+
-+ for (i = 0; i < len; i++)
-+ d[i] = s[i];
-+}
-+
- void *
- grub_memmove (void *to, const void *from, int len)
- {
-diff -Naur grub-0.97.orig/stage2/cmdline.c grub-0.97/stage2/cmdline.c
---- grub-0.97.orig/stage2/cmdline.c 2004-08-16 16:23:01.000000000 -0700
-+++ grub-0.97/stage2/cmdline.c 2006-07-03 23:58:41.000000000 -0700
-@@ -50,10 +50,11 @@
- void
- print_cmdline_message (int forever)
- {
-- printf (" [ Minimal BASH-like line editing is supported. For the first word, TAB\n"
-- " lists possible command completions. Anywhere else TAB lists the possible\n"
-- " completions of a device/filename.%s ]\n",
-- (forever ? "" : " ESC at any time exits."));
-+ grub_printf(" [ Minimal BASH-like line editing is supported. For\n"
-+ " the first word, TAB lists possible command\n"
-+ " completions. Anywhere else TAB lists the possible\n"
-+ " completions of a device/filename.%s ]\n",
-+ (forever ? "" : " ESC at any time\n exits."));
- }
-
- /* Find the builtin whose command name is COMMAND and return the
-diff -Naur grub-0.97.orig/stage2/freebsd.h grub-0.97/stage2/freebsd.h
---- grub-0.97.orig/stage2/freebsd.h 2003-07-09 04:45:52.000000000 -0700
-+++ grub-0.97/stage2/freebsd.h 2006-07-03 23:59:36.000000000 -0700
-@@ -1,7 +1,7 @@
-
- /*
- * GRUB -- GRand Unified Bootloader
-- * Copyright (C) 2001 Free Software Foundation, Inc.
-+ * Copyright (C) 2001, 2004 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
-@@ -35,6 +35,10 @@
- #define RB_CDROM 0x2000 /* use cdrom as root */
- #define RB_GDB 0x8000 /* use GDB remote debugger instead of DDB */
- #define RB_MUTE 0x10000 /* Come up with the console muted */
-+#define RB_SELFTEST 0x20000 /* don't complete the boot; do selftest */
-+#define RB_RESERVED1 0x40000 /* reserved for internal use of boot blocks */
-+#define RB_RESERVED2 0x80000 /* reserved for internal use of boot blocks */
-+#define RB_PAUSE 0x100000 /* pause after each output line during probe */
- #define RB_MULTIPLE 0x20000000 /* Use multiple consoles */
-
- #define RB_BOOTINFO 0x80000000 /* have `struct bootinfo *' arg */
-@@ -70,6 +74,9 @@
-
- #define N_BIOS_GEOM 8
-
-+typedef unsigned char u8_t;
-+typedef unsigned int u32_t;
-+
- /*
- * A zero bootinfo field often means that there is no info available.
- * Flags are used to indicate the validity of fields where zero is a
-@@ -77,19 +84,33 @@
- */
- struct bootinfo
- {
-- unsigned int bi_version;
-- unsigned char *bi_kernelname;
-- struct nfs_diskless *bi_nfs_diskless;
-+ u32_t bi_version;
-+ u8_t *bi_kernelname;
-+ u32_t bi_nfs_diskless;
- /* End of fields that are always present. */
- #define bi_endcommon bi_n_bios_used
-- unsigned int bi_n_bios_used;
-- unsigned long bi_bios_geom[N_BIOS_GEOM];
-- unsigned int bi_size;
-- unsigned char bi_memsizes_valid;
-- unsigned char bi_bios_dev;
-- unsigned char bi_pad[2];
-- unsigned long bi_basemem;
-- unsigned long bi_extmem;
-- unsigned long bi_symtab;
-- unsigned long bi_esymtab;
-+ u32_t bi_n_bios_used;
-+ u32_t bi_bios_geom[N_BIOS_GEOM];
-+ u32_t bi_size;
-+ u8_t bi_memsizes_valid;
-+ u8_t bi_bios_dev;
-+ u8_t bi_pad[2];
-+ u32_t bi_basemem;
-+ u32_t bi_extmem;
-+ u32_t bi_symtab;
-+ u32_t bi_esymtab;
-+ /* Items below only from advanced bootloader */
-+ u32_t bi_kernend;
-+ u32_t bi_envp;
-+ u32_t bi_modulep;
- };
-+
-+#define MODINFO_END 0x0000 /* End of list */
-+#define MODINFO_NAME 0x0001 /* Name of module (string) */
-+#define MODINFO_TYPE 0x0002 /* Type of module (string) */
-+#define MODINFO_ADDR 0x0003 /* Loaded address */
-+#define MODINFO_SIZE 0x0004 /* Size of module */
-+#define MODINFO_EMPTY 0x0005 /* Has been deleted */
-+#define MODINFO_ARGS 0x0006 /* Parameters string */
-+#define MODINFO_METADATA 0x8000 /* Module-specfic */
-+
-diff -Naur grub-0.97.orig/stage2/graphics.c grub-0.97/stage2/graphics.c
---- grub-0.97.orig/stage2/graphics.c 1969-12-31 16:00:00.000000000 -0800
-+++ grub-0.97/stage2/graphics.c 2006-07-03 23:58:41.000000000 -0700
-@@ -0,0 +1,585 @@
-+/*
-+ * 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>
-+ * Options and enhancements made by Herton Ronaldo Krzesinski
-+ * <herton@mandriva.com>
-+ *
-+ * GRUB -- GRand Unified Bootloader
-+ * Copyright (C) 2001,2002 Red Hat, Inc.
-+ * Portions copyright (C) 2000 Conectiva, Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#ifdef SUPPORT_GRAPHICS
-+
-+#include <term.h>
-+#include <shared.h>
-+#include <graphics.h>
-+
-+int saved_videomode;
-+unsigned char *font8x16;
-+
-+int graphics_inited = 0;
-+static char splashimage[256];
-+
-+int shade = 1, no_cursor = 0;
-+
-+#define VSHADOW VSHADOW1
-+unsigned char VSHADOW1[38400];
-+unsigned char VSHADOW2[38400];
-+unsigned char VSHADOW4[38400];
-+unsigned char VSHADOW8[38400];
-+
-+/* define the default viewable area */
-+int view_x0 = 0;
-+int view_y0 = 0;
-+int view_x1 = 80;
-+int view_y1 = 30;
-+
-+/* text buffer has to be kept around so that we can write things as we
-+ * scroll and the like */
-+unsigned short text[80 * 30];
-+
-+/* graphics options */
-+int foreground = (63 << 16) | (63 << 8) | (63), background = 0, window_border = 0;
-+
-+/* current position */
-+static int fontx = 0;
-+static int fonty = 0;
-+
-+/* global state so that we don't try to recursively scroll or cursor */
-+static int no_scroll = 0;
-+
-+/* color state */
-+static int graphics_standard_color = A_NORMAL;
-+static int graphics_normal_color = A_NORMAL;
-+static int graphics_highlight_color = A_REVERSE;
-+static int graphics_current_color = A_NORMAL;
-+static color_state graphics_color_state = COLOR_STATE_STANDARD;
-+
-+static inline void outb(unsigned short port, unsigned char val)
-+{
-+ __asm __volatile ("outb %0,%1"::"a" (val), "d" (port));
-+}
-+
-+static void MapMask(int value) {
-+ outb(0x3c4, 2);
-+ outb(0x3c5, value);
-+}
-+
-+/* bit mask register */
-+static void BitMask(int value) {
-+ outb(0x3ce, 8);
-+ outb(0x3cf, value);
-+}
-+
-+/* move the graphics cursor location to col, row */
-+static void graphics_setxy(int col, int row) {
-+ if (col >= view_x0 && col < view_x1) {
-+ fontx = col;
-+ cursorX = col << 3;
-+ }
-+ if (row >= view_y0 && row < view_y1) {
-+ fonty = row;
-+ cursorY = row << 4;
-+ }
-+}
-+
-+/* scroll the screen */
-+static void graphics_scroll() {
-+ int i, j, k;
-+
-+ /* we don't want to scroll recursively... that would be bad */
-+ if (no_scroll)
-+ return;
-+ no_scroll = 1;
-+
-+ /* disable pager temporarily */
-+ k = count_lines;
-+ count_lines = -1;
-+
-+ /* move everything up a line */
-+ for (j = view_y0 + 1; j < view_y1; j++) {
-+ graphics_gotoxy(view_x0, j - 1);
-+ for (i = view_x0; i < view_x1; i++) {
-+ graphics_putchar(text[j * 80 + i]);
-+ }
-+ }
-+
-+ /* last line should be blank */
-+ graphics_gotoxy(view_x0, view_y1 - 1);
-+ for (i = view_x0; i < view_x1; i++)
-+ graphics_putchar(' ');
-+ graphics_setxy(view_x0, view_y1 - 1);
-+
-+ count_lines = k;
-+
-+ no_scroll = 0;
-+}
-+
-+/* Set the splash image */
-+void graphics_set_splash(char *splashfile) {
-+ grub_strcpy(splashimage, splashfile);
-+}
-+
-+/* Get the current splash image */
-+char *graphics_get_splash(void) {
-+ return splashimage;
-+}
-+
-+/*
-+ * Initialize a vga16 graphics display with the palette based off of
-+ * the image in splashimage. If the image doesn't exist, leave graphics
-+ * mode. The mode initiated is 12h. From "Ralf Brown's Interrupt List":
-+ * text/ text pixel pixel colors disply scrn system
-+ * grph resol box resolution pages addr
-+ * 12h G 80x30 8x16 640x480 16/256K . A000 VGA,ATI VIP
-+ * G 80x30 8x16 640x480 16/64 . A000 ATI EGA Wonder
-+ * G . . 640x480 16 . . UltraVision+256K EGA
-+ */
-+int graphics_init()
-+{
-+ if (!graphics_inited) {
-+ saved_videomode = set_videomode(0x12);
-+ if (get_videomode() != 0x12) {
-+ set_videomode(saved_videomode);
-+ return 0;
-+ }
-+ graphics_inited = 1;
-+ }
-+ else
-+ return 1;
-+
-+ font8x16 = (unsigned char*)graphics_get_font();
-+
-+ /* make sure that the highlight color is set correctly */
-+ graphics_highlight_color = ((graphics_normal_color >> 4) |
-+ ((graphics_normal_color & 0xf) << 4));
-+
-+ graphics_cls();
-+
-+ if (!read_image(splashimage)) {
-+ grub_printf("Failed to read splash image (%s)\n", splashimage);
-+ grub_printf("Press any key to continue...");
-+ getkey();
-+ set_videomode(saved_videomode);
-+ graphics_inited = 0;
-+ return 0;
-+ }
-+
-+ set_int1c_handler();
-+
-+ return 1;
-+}
-+
-+/* Leave graphics mode */
-+void graphics_end(void)
-+{
-+ if (graphics_inited) {
-+ unset_int1c_handler();
-+ set_videomode(saved_videomode);
-+ graphics_inited = 0;
-+ no_cursor = 0;
-+ }
-+}
-+
-+/* Print ch on the screen. Handle any needed scrolling or the like */
-+void graphics_putchar(int ch) {
-+ ch &= 0xff;
-+
-+ graphics_cursor(0);
-+
-+ if (ch == '\n') {
-+ if (fonty + 1 < view_y1)
-+ graphics_setxy(fontx, fonty + 1);
-+ else
-+ graphics_scroll();
-+ graphics_cursor(1);
-+ return;
-+ } else if (ch == '\r') {
-+ graphics_setxy(view_x0, fonty);
-+ graphics_cursor(1);
-+ return;
-+ }
-+
-+ graphics_cursor(0);
-+
-+ text[fonty * 80 + fontx] = ch;
-+ text[fonty * 80 + fontx] &= 0x00ff;
-+ if (graphics_current_color & 0xf0)
-+ text[fonty * 80 + fontx] |= 0x100;
-+
-+ graphics_cursor(0);
-+
-+ if ((fontx + 1) >= view_x1) {
-+ graphics_setxy(view_x0, fonty);
-+ if (fonty + 1 < view_y1)
-+ graphics_setxy(view_x0, fonty + 1);
-+ else
-+ graphics_scroll();
-+ graphics_cursor(1);
-+ do_more ();
-+ graphics_cursor(0);
-+ } else {
-+ graphics_setxy(fontx + 1, fonty);
-+ }
-+
-+ graphics_cursor(1);
-+}
-+
-+/* get the current location of the cursor */
-+int graphics_getxy(void) {
-+ return (fontx << 8) | fonty;
-+}
-+
-+void graphics_gotoxy(int x, int y) {
-+ graphics_cursor(0);
-+
-+ graphics_setxy(x, y);
-+
-+ graphics_cursor(1);
-+}
-+
-+void graphics_cls(void) {
-+ int i;
-+ unsigned char *mem, *s1, *s2, *s4, *s8;
-+
-+ graphics_cursor(0);
-+ graphics_gotoxy(view_x0, view_y0);
-+
-+ mem = (unsigned char*)VIDEOMEM;
-+ s1 = (unsigned char*)VSHADOW1;
-+ s2 = (unsigned char*)VSHADOW2;
-+ s4 = (unsigned char*)VSHADOW4;
-+ s8 = (unsigned char*)VSHADOW8;
-+
-+ for (i = 0; i < 80 * 30; i++)
-+ text[i] = ' ';
-+ graphics_cursor(1);
-+
-+ BitMask(0xff);
-+
-+ /* plane 1 */
-+ MapMask(1);
-+ grub_memcpy(mem, s1, 38400);
-+
-+ /* plane 2 */
-+ MapMask(2);
-+ grub_memcpy(mem, s2, 38400);
-+
-+ /* plane 3 */
-+ MapMask(4);
-+ grub_memcpy(mem, s4, 38400);
-+
-+ /* plane 4 */
-+ MapMask(8);
-+ grub_memcpy(mem, s8, 38400);
-+
-+ MapMask(15);
-+
-+ if (no_cursor) {
-+ no_cursor = 0;
-+ set_int1c_handler();
-+ }
-+}
-+
-+void graphics_setcolorstate (color_state state) {
-+ switch (state) {
-+ case COLOR_STATE_STANDARD:
-+ graphics_current_color = graphics_standard_color;
-+ break;
-+ case COLOR_STATE_NORMAL:
-+ graphics_current_color = graphics_normal_color;
-+ break;
-+ case COLOR_STATE_HIGHLIGHT:
-+ graphics_current_color = graphics_highlight_color;
-+ break;
-+ default:
-+ graphics_current_color = graphics_standard_color;
-+ break;
-+ }
-+
-+ graphics_color_state = state;
-+}
-+
-+void graphics_setcolor (int normal_color, int highlight_color) {
-+ graphics_normal_color = normal_color;
-+ graphics_highlight_color = highlight_color;
-+
-+ graphics_setcolorstate (graphics_color_state);
-+}
-+
-+int graphics_setcursor (int on) {
-+ if (!no_cursor && !on) {
-+ no_cursor = 1;
-+ unset_int1c_handler();
-+ graphics_cursor(0);
-+ }
-+ else if(no_cursor && on) {
-+ no_cursor = 0;
-+ set_int1c_handler();
-+ graphics_cursor(1);
-+ }
-+ return 0;
-+}
-+
-+/* Read in the splashscreen image and set the palette up appropriately.
-+ * Format of splashscreen is an xpm (can be gzipped) with 16 colors and
-+ * 640x480. */
-+int read_image(char *s)
-+{
-+ char buf[32], pal[16], c;
-+ unsigned char base, mask, *s1, *s2, *s4, *s8;
-+ unsigned i, len, idx, colors, x, y, width, height;
-+
-+ if (!grub_open(s))
-+ return 0;
-+
-+ /* read header */
-+ if (!grub_read((char*)&buf, 10) || grub_memcmp(buf, "/* XPM */\n", 10)) {
-+ grub_close();
-+ return 0;
-+ }
-+
-+ /* parse info */
-+ while (grub_read(&c, 1)) {
-+ if (c == '"')
-+ break;
-+ }
-+
-+ while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
-+ ;
-+
-+ i = 0;
-+ width = c - '0';
-+ while (grub_read(&c, 1)) {
-+ if (c >= '0' && c <= '9')
-+ width = width * 10 + c - '0';
-+ else
-+ break;
-+ }
-+ while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
-+ ;
-+
-+ height = c - '0';
-+ while (grub_read(&c, 1)) {
-+ if (c >= '0' && c <= '9')
-+ height = height * 10 + c - '0';
-+ else
-+ break;
-+ }
-+ while (grub_read(&c, 1) && (c == ' ' || c == '\t'))
-+ ;
-+
-+ colors = c - '0';
-+ while (grub_read(&c, 1)) {
-+ if (c >= '0' && c <= '9')
-+ colors = colors * 10 + c - '0';
-+ else
-+ break;
-+ }
-+
-+ base = 0;
-+ while (grub_read(&c, 1) && c != '"')
-+ ;
-+
-+ /* palette */
-+ for (i = 0, idx = 1; i < colors; i++) {
-+ len = 0;
-+
-+ while (grub_read(&c, 1) && c != '"')
-+ ;
-+ grub_read(&c, 1); /* char */
-+ base = c;
-+ grub_read(buf, 4); /* \t c # */
-+
-+ while (grub_read(&c, 1) && c != '"') {
-+ if (len < sizeof(buf))
-+ buf[len++] = c;
-+ }
-+
-+ if (len == 6 && idx < 15) {
-+ int r = ((hex(buf[0]) << 4) | hex(buf[1])) >> 2;
-+ int g = ((hex(buf[2]) << 4) | hex(buf[3])) >> 2;
-+ int b = ((hex(buf[4]) << 4) | hex(buf[5])) >> 2;
-+
-+ pal[idx] = base;
-+ graphics_set_palette(idx, r, g, b);
-+ ++idx;
-+ }
-+ }
-+
-+ x = y = len = 0;
-+
-+ s1 = (unsigned char*)VSHADOW1;
-+ s2 = (unsigned char*)VSHADOW2;
-+ s4 = (unsigned char*)VSHADOW4;
-+ s8 = (unsigned char*)VSHADOW8;
-+
-+ for (i = 0; i < 38400; i++)
-+ s1[i] = s2[i] = s4[i] = s8[i] = 0;
-+
-+ /* parse xpm data */
-+ while (y < height) {
-+ while (1) {
-+ if (!grub_read(&c, 1)) {
-+ grub_close();
-+ return 0;
-+ }
-+ if (c == '"')
-+ break;
-+ }
-+
-+ while (grub_read(&c, 1) && c != '"') {
-+ for (i = 1; i < 15; i++)
-+ if (pal[i] == c) {
-+ c = i;
-+ break;
-+ }
-+
-+ mask = 0x80 >> (x & 7);
-+ if (c & 1)
-+ s1[len + (x >> 3)] |= mask;
-+ if (c & 2)
-+ s2[len + (x >> 3)] |= mask;
-+ if (c & 4)
-+ s4[len + (x >> 3)] |= mask;
-+ if (c & 8)
-+ s8[len + (x >> 3)] |= mask;
-+
-+ if (++x >= 640) {
-+ x = 0;
-+
-+ if (y < 480)
-+ len += 80;
-+ ++y;
-+ }
-+ }
-+ }
-+
-+ grub_close();
-+
-+ graphics_set_palette(0, (background >> 16), (background >> 8) & 63,
-+ background & 63);
-+ graphics_set_palette(15, (foreground >> 16), (foreground >> 8) & 63,
-+ foreground & 63);
-+ graphics_set_palette(0x11, (window_border >> 16), (window_border >> 8) & 63,
-+ window_border & 63);
-+
-+ return 1;
-+}
-+
-+/* Convert a character which is a hex digit to the appropriate integer */
-+int hex(int v)
-+{
-+ if (v >= 'A' && v <= 'F')
-+ return (v - 'A' + 10);
-+ if (v >= 'a' && v <= 'f')
-+ return (v - 'a' + 10);
-+ return (v - '0');
-+}
-+
-+void graphics_cursor(int set) {
-+ unsigned char *pat, *mem, *ptr, chr[16 << 2];
-+ int i, ch, invert, offset;
-+
-+ if (set && (no_cursor || no_scroll))
-+ return;
-+
-+ offset = cursorY * 80 + fontx;
-+ ch = text[fonty * 80 + fontx] & 0xff;
-+ invert = (text[fonty * 80 + fontx] & 0xff00) != 0;
-+ pat = font8x16 + (ch << 4);
-+
-+ mem = (unsigned char*)VIDEOMEM + offset;
-+
-+ if (!set) {
-+ for (i = 0; i < 16; i++) {
-+ unsigned char mask = pat[i];
-+
-+ if (!invert) {
-+ chr[i ] = ((unsigned char*)VSHADOW1)[offset];
-+ chr[16 + i] = ((unsigned char*)VSHADOW2)[offset];
-+ chr[32 + i] = ((unsigned char*)VSHADOW4)[offset];
-+ chr[48 + i] = ((unsigned char*)VSHADOW8)[offset];
-+
-+ if (shade) {
-+ if (ch == DISP_VERT || ch == DISP_LL ||
-+ ch == DISP_UR || ch == DISP_LR) {
-+ unsigned char pmask = ~(pat[i] >> 1);
-+
-+ chr[i ] &= pmask;
-+ chr[16 + i] &= pmask;
-+ chr[32 + i] &= pmask;
-+ chr[48 + i] &= pmask;
-+ }
-+ if (i > 0 && ch != DISP_VERT) {
-+ unsigned char pmask = ~(pat[i - 1] >> 1);
-+
-+ chr[i ] &= pmask;
-+ chr[16 + i] &= pmask;
-+ chr[32 + i] &= pmask;
-+ chr[48 + i] &= pmask;
-+ if (ch == DISP_HORIZ || ch == DISP_UR || ch == DISP_LR) {
-+ pmask = ~pat[i - 1];
-+
-+ chr[i ] &= pmask;
-+ chr[16 + i] &= pmask;
-+ chr[32 + i] &= pmask;
-+ chr[48 + i] &= pmask;
-+ }
-+ }
-+ }
-+ chr[i ] |= mask;
-+ chr[16 + i] |= mask;
-+ chr[32 + i] |= mask;
-+ chr[48 + i] |= mask;
-+
-+ offset += 80;
-+ }
-+ else {
-+ chr[i ] = mask;
-+ chr[16 + i] = mask;
-+ chr[32 + i] = mask;
-+ chr[48 + i] = mask;
-+ }
-+ }
-+ }
-+ else {
-+ MapMask(15);
-+ ptr = mem;
-+ for (i = 0; i < 16; i++, ptr += 80) {
-+ cursorBuf[i] = pat[i];
-+ *ptr = ~pat[i];
-+ }
-+ return;
-+ }
-+
-+ offset = 0;
-+ for (i = 1; i < 16; i <<= 1, offset += 16) {
-+ int j;
-+
-+ MapMask(i);
-+ ptr = mem;
-+ for (j = 0; j < 16; j++, ptr += 80)
-+ *ptr = chr[j + offset];
-+ }
-+
-+ MapMask(15);
-+}
-+
-+#endif /* SUPPORT_GRAPHICS */
-diff -Naur grub-0.97.orig/stage2/graphics.h grub-0.97/stage2/graphics.h
---- grub-0.97.orig/stage2/graphics.h 1969-12-31 16:00:00.000000000 -0800
-+++ grub-0.97/stage2/graphics.h 2006-07-03 23:58:41.000000000 -0700
-@@ -0,0 +1,44 @@
-+/* graphics.h - graphics console interface */
-+/*
-+ * GRUB -- GRand Unified Bootloader
-+ * Copyright (C) 2002 Free Software Foundation, Inc.
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#ifndef GRAPHICS_H
-+#define GRAPHICS_H
-+
-+/* magic constant */
-+#define VIDEOMEM 0xA0000
-+
-+/* function prototypes */
-+char *graphics_get_splash(void);
-+
-+int read_image(char *s);
-+void graphics_cursor(int set);
-+
-+/* function prototypes for asm functions */
-+void * graphics_get_font();
-+void graphics_set_palette(int idx, int red, int green, int blue);
-+void set_int1c_handler();
-+void unset_int1c_handler();
-+
-+extern short cursorX, cursorY;
-+extern char cursorBuf[16];
-+extern int shade;
-+extern int view_x0, view_y0, view_x1, view_y1;
-+
-+#endif /* GRAPHICS_H */
-diff -Naur grub-0.97.orig/stage2/Makefile.am grub-0.97/stage2/Makefile.am
---- grub-0.97.orig/stage2/Makefile.am 2005-02-02 12:37:35.000000000 -0800
-+++ grub-0.97/stage2/Makefile.am 2006-07-03 23:58:41.000000000 -0700
-@@ -7,7 +7,7 @@
- fat.h filesys.h freebsd.h fs.h hercules.h i386-elf.h \
- imgact_aout.h iso9660.h jfs.h mb_header.h mb_info.h md5.h \
- nbi.h pc_slice.h serial.h shared.h smp-imps.h term.h \
-- terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h
-+ terminfo.h tparm.h nbi.h ufs2.h vstafs.h xfs.h graphics.h
- EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS)
-
- # For <stage1.h>.
-@@ -19,7 +19,7 @@
- disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \
- fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \
- fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \
-- terminfo.c tparm.c
-+ terminfo.c tparm.c graphics.c
- libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
- -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
- -DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
-@@ -79,8 +79,14 @@
- HERCULES_FLAGS =
- endif
-
-+if GRAPHICS_SUPPORT
-+GRAPHICS_FLAGS = -DSUPPORT_GRAPHICS=1
-+else
-+GRAPHICS_FLAGS =
-+endif
-+
- STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
-- $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS)
-+ $(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS) $(GRAPHICS_FLAGS)
-
- STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
- STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1
-@@ -90,7 +96,8 @@
- cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
- fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
- fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \
-- hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c
-+ hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c \
-+ graphics.c
- pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
- pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
- pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
-diff -Naur grub-0.97.orig/stage2/shared.h grub-0.97/stage2/shared.h
---- grub-0.97.orig/stage2/shared.h 2004-06-19 09:40:09.000000000 -0700
-+++ grub-0.97/stage2/shared.h 2006-07-04 00:01:50.000000000 -0700
-@@ -499,7 +499,11 @@
- unsigned char linear_reserved_field_position;
- unsigned long max_pixel_clock;
-
-- unsigned char reserved3[189];
-+ /* Reserved field to make structure to be 256 bytes long, VESA BIOS
-+ Extension 3.0 Specification says to reserve 189 bytes here but
-+ that doesn't make structure to be 256 bytes. So additional one is
-+ added here. */
-+ unsigned char reserved3[189 + 1];
- } __attribute__ ((packed));
-
-
-@@ -792,6 +796,11 @@
- /* Set the cursor position. */
- void gotoxy (int x, int y);
-
-+/* Internal pager
-+ Returns 1 = if pager was used
-+ 0 = if pager wasn't used */
-+int do_more (void);
-+
- /* Displays an ASCII character. IBM displays will translate some
- characters to special graphical ones (see the DISP_* constants). */
- void grub_putchar (int c);
-@@ -871,6 +880,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);
-@@ -911,7 +921,7 @@
- int nul_terminate (char *str);
- int get_based_digit (int c, int base);
- int safe_parse_maxint (char **str_ptr, int *myint_ptr);
--int memcheck (int start, int len);
-+int memcheck (unsigned long int start, unsigned long int len);
- void grub_putstr (const char *str);
-
- #ifndef NO_DECOMPRESSION
-diff -Naur grub-0.97.orig/stage2/stage2.c grub-0.97/stage2/stage2.c
---- grub-0.97.orig/stage2/stage2.c 2005-03-19 09:51:57.000000000 -0800
-+++ grub-0.97/stage2/stage2.c 2006-07-04 00:01:50.000000000 -0700
-@@ -20,6 +20,12 @@
- #include <shared.h>
- #include <term.h>
-
-+#ifdef SUPPORT_GRAPHICS
-+# include <graphics.h>
-+#endif
-+
-+int col_start, col_end, row_start, box_size;
-+
- grub_jmp_buf restart_env;
-
- #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS)
-@@ -105,13 +111,13 @@
- if (highlight && current_term->setcolorstate)
- current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
-
-- gotoxy (2, y);
-+ gotoxy (2 + col_start, y);
- grub_putchar (' ');
-- for (x = 3; x < 75; x++)
-+ for (x = 3 + col_start; x < (col_end - 5); x++)
- {
-- if (*entry && x <= 72)
-+ if (*entry && x <= (col_end - 8))
- {
-- if (x == 72)
-+ if (x == (col_end - 8))
- grub_putchar (DISP_RIGHT);
- else
- grub_putchar (*entry++);
-@@ -119,7 +125,7 @@
- else
- grub_putchar (' ');
- }
-- gotoxy (74, y);
-+ gotoxy ((col_end - 6), y);
-
- if (current_term->setcolorstate)
- current_term->setcolorstate (COLOR_STATE_STANDARD);
-@@ -131,7 +137,7 @@
- {
- int i;
-
-- gotoxy (77, y + 1);
-+ gotoxy ((col_end - 3), y + 1);
-
- if (first)
- grub_putchar (DISP_UP);
-@@ -151,14 +157,14 @@
- menu_entries++;
- }
-
-- gotoxy (77, y + size);
-+ gotoxy ((col_end - 3), y + size);
-
- if (*menu_entries)
- grub_putchar (DISP_DOWN);
- else
- grub_putchar (' ');
-
-- gotoxy (74, y + entryno + 1);
-+ gotoxy ((col_end - 6), y + entryno + 1);
- }
-
- static void
-@@ -196,30 +202,30 @@
- if (current_term->setcolorstate)
- current_term->setcolorstate (COLOR_STATE_NORMAL);
-
-- gotoxy (1, y);
-+ gotoxy (1 + col_start, y);
-
- grub_putchar (DISP_UL);
-- for (i = 0; i < 73; i++)
-+ for (i = col_start; i < (col_end - 7); i++)
- grub_putchar (DISP_HORIZ);
- grub_putchar (DISP_UR);
-
- i = 1;
- while (1)
- {
-- gotoxy (1, y + i);
-+ gotoxy (1 + col_start, y + i);
-
- if (i > size)
- break;
-
- grub_putchar (DISP_VERT);
-- gotoxy (75, y + i);
-+ gotoxy ((col_end - 5), y + i);
- grub_putchar (DISP_VERT);
-
- i++;
- }
-
- grub_putchar (DISP_LL);
-- for (i = 0; i < 73; i++)
-+ for (i = col_start; i < (col_end - 7); i++)
- grub_putchar (DISP_HORIZ);
- grub_putchar (DISP_LR);
-
-@@ -233,6 +239,7 @@
- {
- int c, time1, time2 = -1, first_entry = 0;
- char *cur_entry = 0;
-+ struct term_entry *prev_term = NULL;
-
- /*
- * Main loop for menu UI.
-@@ -250,6 +257,22 @@
- }
- }
-
-+ col_start = 0;
-+ col_end = 80;
-+ row_start = 0;
-+ box_size = 12;
-+ /* if we're using viewport we need to make sure to setup
-+ coordinates correctly. */
-+#ifdef SUPPORT_GRAPHICS
-+ if (grub_memcmp (current_term->name, "graphics", sizeof ("graphics") - 1) == 0)
-+ {
-+ col_start = view_x0;
-+ col_end = view_x1;
-+ row_start = view_y0;
-+ box_size = (view_y1 - view_y0) - 13;
-+ }
-+#endif
-+
- /* If the timeout was expired or wasn't set, force to show the menu
- interface. */
- if (grub_timeout < 0)
-@@ -302,36 +325,36 @@
- if (current_term->flags & TERM_DUMB)
- print_entries_raw (num_entries, first_entry, menu_entries);
- else
-- print_border (3, 12);
-+ print_border (3 + row_start, box_size);
-
- grub_printf ("\n\
-- Use the %c and %c keys to select which entry is highlighted.\n",
-+ Use the %c and %c keys to select which entry is highlighted.\n",
- DISP_UP, DISP_DOWN);
-
- if (! auth && password)
- {
- printf ("\
-- Press enter to boot the selected OS or \'p\' to enter a\n\
-- password to unlock the next set of features.");
-+ Press enter to boot the selected OS or \'p\' to enter a\n\
-+ password to unlock the next set of features.");
- }
- else
- {
- if (config_entries)
- printf ("\
-- Press enter to boot the selected OS, \'e\' to edit the\n\
-- commands before booting, or \'c\' for a command-line.");
-+ Press enter to boot the selected OS, \'e\' to edit the\n\
-+ commands before booting, or \'c\' for a command-line.");
- else
- printf ("\
-- Press \'b\' to boot, \'e\' to edit the selected command in the\n\
-- boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\
-- after (\'O\' for before) the selected line, \'d\' to remove the\n\
-- selected line, or escape to go back to the main menu.");
-+ Press \'b\' to boot, \'e\' to edit the selected command in the\n\
-+ boot sequence, \'c\' for a command-line, \'o\' to open a new line\n\
-+ after (\'O\' for before) the selected line, \'d\' to remove the\n\
-+ selected line, or escape to go back to the main menu.");
- }
-
- if (current_term->flags & TERM_DUMB)
- grub_printf ("\n\nThe selected entry is %d ", entryno);
- else
-- print_entries (3, 12, first_entry, entryno, menu_entries);
-+ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
- }
-
- /* XX using RT clock now, need to initialize value */
-@@ -358,10 +381,10 @@
- entryno, grub_timeout);
- else
- {
-- gotoxy (3, 22);
-- grub_printf ("The highlighted entry will be booted automatically in %d seconds. ",
-+ gotoxy (3 + col_start, 10 + box_size + row_start);
-+ grub_printf (" The highlighted entry will be booted automatically in %d seconds. ",
- grub_timeout);
-- gotoxy (74, 4 + entryno);
-+ gotoxy ((col_end - 6), 4 + entryno + row_start);
- }
-
- grub_timeout--;
-@@ -387,12 +410,12 @@
- if (current_term->flags & TERM_DUMB)
- grub_putchar ('\r');
- else
-- gotoxy (3, 22);
-+ gotoxy (3 + col_start, 10 + box_size + row_start);
- printf (" ");
- grub_timeout = -1;
- fallback_entryno = -1;
- if (! (current_term->flags & TERM_DUMB))
-- gotoxy (74, 4 + entryno);
-+ gotoxy ((col_end - 6), 4 + entryno + row_start);
- }
-
- /* We told them above (at least in SUPPORT_SERIAL) to use
-@@ -408,12 +431,12 @@
- {
- if (entryno > 0)
- {
-- print_entry (4 + entryno, 0,
-+ print_entry (4 + entryno + row_start, 0,
- get_entry (menu_entries,
- first_entry + entryno,
- 0));
- entryno--;
-- print_entry (4 + entryno, 1,
-+ print_entry (4 + entryno + row_start, 1,
- get_entry (menu_entries,
- first_entry + entryno,
- 0));
-@@ -421,7 +444,7 @@
- else if (first_entry > 0)
- {
- first_entry--;
-- print_entries (3, 12, first_entry, entryno,
-+ print_entries (3 + row_start, box_size, first_entry, entryno,
- menu_entries);
- }
- }
-@@ -433,29 +456,29 @@
- entryno++;
- else
- {
-- if (entryno < 11)
-+ if (entryno < (box_size - 1))
- {
-- print_entry (4 + entryno, 0,
-+ print_entry (4 + entryno + row_start, 0,
- get_entry (menu_entries,
- first_entry + entryno,
- 0));
- entryno++;
-- print_entry (4 + entryno, 1,
-+ print_entry (4 + entryno + row_start, 1,
- get_entry (menu_entries,
- first_entry + entryno,
- 0));
- }
-- else if (num_entries > 12 + first_entry)
-+ else if (num_entries > box_size + first_entry)
- {
- first_entry++;
-- print_entries (3, 12, first_entry, entryno, menu_entries);
-+ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
- }
- }
- }
- else if (c == 7)
- {
- /* Page Up */
-- first_entry -= 12;
-+ first_entry -= box_size;
- if (first_entry < 0)
- {
- entryno += first_entry;
-@@ -463,20 +486,20 @@
- if (entryno < 0)
- entryno = 0;
- }
-- print_entries (3, 12, first_entry, entryno, menu_entries);
-+ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
- }
- else if (c == 3)
- {
- /* Page Down */
-- first_entry += 12;
-+ first_entry += box_size;
- if (first_entry + entryno + 1 >= num_entries)
- {
-- first_entry = num_entries - 12;
-+ first_entry = num_entries - box_size;
- if (first_entry < 0)
- first_entry = 0;
- entryno = num_entries - first_entry - 1;
- }
-- print_entries (3, 12, first_entry, entryno, menu_entries);
-+ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
- }
-
- if (config_entries)
-@@ -489,7 +512,7 @@
- if ((c == 'd') || (c == 'o') || (c == 'O'))
- {
- if (! (current_term->flags & TERM_DUMB))
-- print_entry (4 + entryno, 0,
-+ print_entry (4 + entryno + row_start, 0,
- get_entry (menu_entries,
- first_entry + entryno,
- 0));
-@@ -537,7 +560,7 @@
-
- if (entryno >= num_entries)
- entryno--;
-- if (first_entry && num_entries < 12 + first_entry)
-+ if (first_entry && num_entries < box_size + first_entry)
- first_entry--;
- }
-
-@@ -549,7 +572,7 @@
- grub_printf ("\n");
- }
- else
-- print_entries (3, 12, first_entry, entryno, menu_entries);
-+ print_entries (3 + row_start, box_size, first_entry, entryno, menu_entries);
- }
-
- cur_entry = menu_entries;
-@@ -570,7 +593,7 @@
- if (current_term->flags & TERM_DUMB)
- grub_printf ("\r ");
- else
-- gotoxy (1, 21);
-+ gotoxy (1 + col_start, 9 + box_size + row_start);
-
- /* Wipe out the previously entered password */
- grub_memset (entered, 0, sizeof (entered));
-@@ -651,7 +674,10 @@
- *(new_heap++) = 0;
-
- if (config_entries)
-- run_menu (heap, NULL, new_num_entries, new_heap, 0);
-+ {
-+ current_entryno = first_entry + entryno;
-+ run_menu (heap, NULL, new_num_entries, new_heap, 0);
-+ }
- else
- {
- cls ();
-@@ -714,6 +740,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)
- {
-@@ -727,7 +762,8 @@
- cur_entry = get_entry (config_entries, first_entry + entryno, 1);
-
- /* Set CURRENT_ENTRYNO for the command "savedefault". */
-- current_entryno = first_entry + entryno;
-+ if (config_entries)
-+ current_entryno = first_entry + entryno;
-
- if (run_script (cur_entry, heap))
- {
-@@ -748,6 +784,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;
- }
-@@ -891,8 +934,18 @@
- len = grub_read (buf, sizeof (buf));
- if (len > 0)
- {
-+ char *tmp;
-+ char *def;
- buf[sizeof (buf) - 1] = 0;
-- safe_parse_maxint (&p, &saved_entryno);
-+
-+ if((tmp = grub_strstr(p, ":")) != NULL)
-+ {
-+ *tmp++;
-+ grub_memcpy(&def, &tmp, sizeof(p));
-+ }else
-+ grub_memcpy(&def, &p, sizeof(p));
-+
-+ safe_parse_maxint (&def, &saved_entryno);
- }
-
- grub_close ();
-@@ -1050,6 +1103,16 @@
- while (is_preset);
- }
-
-+ /* go ahead and make sure the terminal is setup */
-+ if (current_term->startup)
-+ {
-+ /* If initialization fails, go back to default terminal */
-+ if (current_term->startup() == 0)
-+ {
-+ current_term = term_table;
-+ }
-+ }
-+
- if (! num_entries)
- {
- /* If no acceptable config file, goto command-line, starting
-diff -Naur grub-0.97.orig/stage2/term.h grub-0.97/stage2/term.h
---- grub-0.97.orig/stage2/term.h 2003-07-09 04:45:53.000000000 -0700
-+++ grub-0.97/stage2/term.h 2006-07-03 23:58:41.000000000 -0700
-@@ -60,6 +60,8 @@
- const char *name;
- /* The feature flags defined above. */
- unsigned long flags;
-+ /* Default for maximum number of lines if not specified */
-+ unsigned short max_lines;
- /* Put a character. */
- void (*putchar) (int c);
- /* Check if any input character is available. */
-@@ -79,6 +81,10 @@
- void (*setcolor) (int normal_color, int highlight_color);
- /* Turn on/off the cursor. */
- int (*setcursor) (int on);
-+ /* function to start a terminal */
-+ int (*startup) (void);
-+ /* function to use to shutdown a terminal */
-+ void (*shutdown) (void);
- };
-
- /* This lists up available terminals. */
-@@ -124,4 +130,24 @@
- int hercules_setcursor (int on);
- #endif
-
-+#ifdef SUPPORT_GRAPHICS
-+extern int foreground, background, window_border, graphics_inited, saved_videomode;
-+
-+void graphics_set_splash(char *splashfile);
-+int set_videomode(int mode);
-+int get_videomode(void);
-+void graphics_putchar (int c);
-+int graphics_getxy(void);
-+void graphics_gotoxy(int x, int y);
-+void graphics_cls(void);
-+void graphics_setcolorstate (color_state state);
-+void graphics_setcolor (int normal_color, int highlight_color);
-+int graphics_setcursor (int on);
-+int graphics_init(void);
-+void graphics_end(void);
-+
-+int hex(int v);
-+void graphics_set_palette(int idx, int red, int green, int blue);
-+#endif /* SUPPORT_GRAPHICS */
-+
- #endif /* ! GRUB_TERM_HEADER */
-diff -Naur grub-0.97.orig/THANKS grub-0.97/THANKS
---- grub-0.97.orig/THANKS 2005-05-07 19:17:43.000000000 -0700
-+++ grub-0.97/THANKS 2006-07-04 00:01:50.000000000 -0700
-@@ -121,3 +121,4 @@
- Yedidyah Bar-David <didi@post.tau.ac.il>
- Yury V. Umanets <umka@namesys.com>
- Yuri Zaporogets <yuriz@ukr.net>
-+Vitaly Fertman <vitaly@namesys.com>
-diff -Naur grub-0.97.orig/util/grub-install.in grub-0.97/util/grub-install.in
---- grub-0.97.orig/util/grub-install.in 2004-07-24 11:57:31.000000000 -0700
-+++ grub-0.97/util/grub-install.in 2006-07-04 00:01:50.000000000 -0700
-@@ -81,6 +81,50 @@
- EOF
- }
-
-+# Usage: getraid_mdadm mddevice
-+# Routine to find a physical device from an md device
-+# If found, the first grub BIOS device (from device.map) is returned
-+# If no BIOS drives match the RAID devices, the first device returned
-+# from mdadm -D is returned
-+getraid_mdadm() {
-+ device=$1
-+ mdadm=$(mdadm -D "$device") || {
-+ echo "$PROG: mdadm -D $device failed" >&2
-+ exit 1
-+ }
-+ eval "$(
-+ echo "$mdadm" | awk '
-+ $1 == "Number" && $2 == "Major" { start = 1; next }
-+ $1 == "UUID" { print "uuid=" $3; start = 0; next }
-+ !start { next }
-+ $2 == 0 && $3 == 0 { next }
-+ { devices = devices "\n" $NF }
-+ END { print "devices='\''" devices "'\''" }
-+ '
-+ )"
-+
-+ # Convert RAID devices list into a list of disks
-+ tmp_disks=`echo "$devices" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' \
-+ -e 's%\(d[0-9]*\)p[0-9]*$%\1%' \
-+ -e 's%\(fd[0-9]*\)$%\1%' \
-+ -e 's%/part[0-9]*$%/disc%' \
-+ -e 's%\(c[0-7]d[0-9]*\).*$%\1%' \
-+ -e '/^$/d' |
-+ sed -n '1h;2,$H;${g;s/\n/|/g;p}'`
-+
-+ # Find first BIOS disk that's a member of the RAID array
-+ # Default to first RAID member if no tmp_disks are BIOS devices
-+ set -- `egrep $tmp_disks $device_map | \
-+ sort | \
-+ sed -n 1p `
-+ device=${2:-${tmp_disks%%|*}}
-+
-+ # Return first partition on BIOS disk that's part of the RAID
-+ echo "$devices" | \
-+ sed -n "\:${device}:p" | \
-+ sed -n 1p
-+}
-+
- # Usage: convert os_device
- # Convert an OS device to the corresponding GRUB drive.
- # This part is OS-specific.
-@@ -96,6 +140,10 @@
- # Break the device name into the disk part and the partition part.
- case "$host_os" in
- linux*)
-+ # Find an actual physical device if we're passed a RAID device
-+ case $1 in
-+ /dev/md*) set -- `getraid_mdadm $1`
-+ esac
- tmp_disk=`echo "$1" | sed -e 's%\([sh]d[a-z]\)[0-9]*$%\1%' \
- -e 's%\(d[0-9]*\)p[0-9]*$%\1%' \
- -e 's%\(fd[0-9]*\)$%\1%' \
-@@ -112,8 +160,8 @@
- tmp_disk=`echo "$1" | sed 's%\([sh]d[0-9]*\).*%\1%'`
- tmp_part=`echo "$1" | sed "s%$tmp_disk%%"` ;;
- freebsd* | kfreebsd*-gnu)
-- tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%r\1%' \
-- | sed 's%r\{0,1\}\(da[0-9]*\).*$%r\1%'`
-+ tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([saw]d[0-9]*\).*$%\1%' \
-+ | sed 's%r\{0,1\}\(da[0-9]*\).*$%\1%'`
- tmp_part=`echo "$1" \
- | sed "s%.*/r\{0,1\}[saw]d[0-9]\(s[0-9]*[a-h]\)%\1%" \
- | sed "s%.*/r\{0,1\}da[0-9]\(s[0-9]*[a-h]\)%\1%"`
-@@ -131,7 +179,7 @@
-
- # Get the drive name.
- tmp_drive=`grep -v '^#' $device_map | grep "$tmp_disk *$" \
-- | sed 's%.*\(([hf]d[0-9][a-g0-9,]*)\).*%\1%'`
-+ | sed 's%.*\(([hf]d[0-9][a-z0-9,]*)\).*%\1%'`
-
- # If not found, print an error message and exit.
- if test "x$tmp_drive" = x; then
-@@ -148,13 +196,13 @@
- gnu*)
- if echo $tmp_part | grep "^s" >/dev/null; then
- tmp_pc_slice=`echo $tmp_part \
-- | sed "s%s\([0-9]*\)[a-g]*$%\1%"`
-+ | sed "s%s\([0-9]*\)[a-z]*$%\1%"`
- tmp_drive=`echo "$tmp_drive" \
- | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
- fi
-- if echo $tmp_part | grep "[a-g]$" >/dev/null; then
-+ if echo $tmp_part | grep "[a-z]$" >/dev/null; then
- tmp_bsd_partition=`echo "$tmp_part" \
-- | sed "s%[^a-g]*\([a-g]\)$%\1%"`
-+ | sed "s%[^a-z]*\([a-z]\)$%\1%"`
- tmp_drive=`echo "$tmp_drive" \
- | sed "s%)%,$tmp_bsd_partition)%"`
- fi
-@@ -336,6 +384,10 @@
- # Create a safe temporary file.
- test -n "$mklog" && log_file=`$mklog`
-
-+ # Before all invocations of the grub shell, call sync to make sure
-+ # the raw device is in sync with any bufferring in filesystems.
-+ sync
-+
- $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
- quit
- EOF
-@@ -450,6 +502,24 @@
- # Create a safe temporary file.
- test -n "$mklog" && log_file=`$mklog`
-
-+# Sync to prevent GRUB from not finding stage files (notably, on XFS)
-+sync
-+
-+# XFS needs special magic
-+xfs_frozen=false
-+if which xfs_freeze > /dev/null ; then
-+ cat << EOF
-+Due to a bug in xfs_freeze, the following command might produce a segmentation
-+fault when ${grubdir} is not in an XFS filesystem. This error is harmless and
-+can be ignored.
-+EOF
-+ if xfs_freeze -f ${grubdir} ; then xfs_frozen=true ; fi
-+fi
-+
-+# Before all invocations of the grub shell, call sync to make sure
-+# the raw device is in sync with any bufferring in filesystems.
-+sync
-+
- # Now perform the installation.
- $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
- root $root_drive
-@@ -457,6 +527,10 @@
- quit
- EOF
-
-+if ${xfs_frozen} ; then
-+ xfs_freeze -u ${grubdir}
-+fi
-+
- if grep "Error [0-9]*: " $log_file >/dev/null || test $debug = yes; then
- cat $log_file 1>&2
- exit 1