auto import from //depot/cupcake/@135843
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..ea8cb4a
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,54 @@
+VaX#n8 (real name unknown) wrote shared_src/fsys_ext2fs.c.
+
+Heiko Schroeder rewrote shared_src/stage1.S to be more readable.
+
+The following authors assigned copyright on their work to the Free
+Software Foundation:
+
+Erich Stefan Boleyn originally designed and implemented GRUB.
+
+Gordon Matzigkeit adopted GRUB into the GNU Project.  He fixed several
+bugs, added symbolic link support to shared_src/fsys_ext2fs.c, and
+began the implementation of /sbin/grub. He was an official maintainer.
+
+Yoshinori K. Okuji contributed many bugfixes and new features, such as
+working LBA support, /sbin/grub support for configuration files, the
+script /sbin/grub-install, the utility /bin/mbchk, the new engine for
+builtin commands, disk swapping support, keyboard configuration support,
+network support, online help support, command-line history support,
+hidden menu support, the new Linux loader, serial terminal support,
+single-line editing support, the utility /sbin/grub-md5-crypt, the new
+GRUB manual, and several new commands. He is the current official
+maintainer.
+
+Peter Astrand added support for a color menu.
+
+Pavel Roskin contributed many bugfixes and new features, such as FreeBSD
+support for the grub shell, and configure process cleanups.
+
+Klaus Reichl wrote stage2/fsys_minix.c.
+
+Per Lundberg added graphics support to the Multiboot Specification.
+
+Jochen Hoenicke rewrote stage2/fsys_fat.c and wrote
+stage2/fsys_reiserfs.c and stage2/md5.c.
+
+Christoph Plattner added support for Net Boot Image Proposal.
+
+Frank Mehnert added support for hercules console.
+
+Kristoffer Branemyr added VSTa filesystem support.
+
+Serguei Tzukanov added JFS and XFS support.
+
+Jason Thomas added Linux DAC960 support and support for hiding/unhiding
+logical partitions, and did a significant bugfix for the terminal stuff.
+
+Tilmann Bubeck added support for vt100-incompatible terminals.
+
+KB Sriram added a better detection of FAT filesystem and fixed a
+network device completion.
+
+Eric Kvaalen fixed a lot of problems in the GRUB manual.
+
+Leonid Lisovskiy added El Torito support.
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..0d000a4
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,192 @@
+## Copyright 2008, The Android Open Source Project
+##
+## Licensed under the Apache License, Version 2.0 (the "License");
+## you may not use this file except in compliance with the License.
+## You may obtain a copy of the License at
+##
+##     http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+##
+
+
+LOCAL_PATH := $(call my-dir)
+
+ifneq ($(TARGET_SIMULATOR),true)
+ifeq ($(TARGET_ARCH),x86)
+
+include $(CLEAR_VARS)
+
+############################
+# First, build stage1
+
+LOCAL_SRC_FILES := \
+        stage1/stage1.S
+
+LOCAL_CFLAGS := \
+        -Wall -Wmissing-prototypes -Wunused -Wshadow \
+        -Wpointer-arith -falign-jumps=1 -falign-loops=1 \
+        -falign-functions=1 -Wundef
+LOCAL_CFLAGS += -m32 -O2 -fno-builtin -nostdinc
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/stage1
+
+LOCAL_MODULE := grub_stage1
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/grub
+
+LOCAL_SYSTEM_SHARED_LIBRARIES :=
+LOCAL_SHARED_LIBRARIES :=
+
+include $(BUILD_RAW_EXECUTABLE)
+
+$(LOCAL_BUILT_MODULE) : PRIVATE_LINK_SCRIPT :=
+$(LOCAL_BUILT_MODULE) : PRIVATE_LIBS :=
+$(LOCAL_BUILT_MODULE) : PRIVATE_RAW_EXECUTABLE_LDFLAGS := \
+	-nostdlib -N -Ttext=7C00 -melf_i386
+
+###################################################################
+###################################################################
+## For stage2, we have to do it in several parts.
+##   1) Build pre_stage2 that contains all the source.
+##   2) Get the size of pre_stage2 from (1) and generate a header file.
+##   3) Build the "start sector" with the header file.
+##   4) concatenate start + pre_stage2 into stage2.
+###################################################################
+###################################################################
+
+###################################
+## So, build pre_stage2 target  (1)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+	stage2/asm.S \
+	stage2/bios.c \
+	stage2/boot.c \
+	stage2/builtins.c \
+	stage2/char_io.c \
+	stage2/cmdline.c \
+	stage2/common.c \
+	stage2/console.c \
+	stage2/disk_io.c \
+	stage2/fsys_ext2fs.c \
+	stage2/gunzip.c \
+	stage2/serial.c \
+	stage2/smp-imps.c \
+	stage2/stage2.c \
+	stage2/terminfo.c \
+	stage2/tparm.c \
+	stage2/preset_menu.c
+
+LOCAL_CFLAGS := \
+	-Wall -Wmissing-prototypes -Wunused -Wshadow \
+	-Wpointer-arith -falign-jumps=1 -falign-loops=1 \
+	-falign-functions=1 -Wundef
+
+LOCAL_CFLAGS += -m32 -Os -fno-builtin -nostdinc
+
+LOCAL_CFLAGS += -DHAVE_CONFIG_H -DFSYS_EXT2FS=1 -DSUPPORT_SERIAL=1
+
+LOCAL_CFLAGS += -DPRESET_MENU_EXTERNAL
+
+LOCAL_C_INCLUDES := \
+	$(LOCAL_PATH)/stage1 \
+	$(LOCAL_PATH)/stage2
+
+LOCAL_MODULE := grub_pre_stage2
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/grub
+
+LOCAL_SYSTEM_SHARED_LIBRARIES :=
+LOCAL_SHARED_LIBRARIES :=
+
+include $(BUILD_RAW_EXECUTABLE)
+
+$(LOCAL_BUILT_MODULE) : PRIVATE_LINK_SCRIPT :=
+$(LOCAL_BUILT_MODULE) : PRIVATE_LIBS :=
+$(LOCAL_BUILT_MODULE) : PRIVATE_RAW_EXECUTABLE_LDFLAGS := \
+	-nostdlib -N -Ttext=8200 -melf_i386
+
+#############################################
+## Generate the stage2 start file  (2) + (3)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+	stage2/start.S
+
+LOCAL_CFLAGS := \
+	-Wall -Wmissing-prototypes -Wunused -Wshadow \
+	-Wpointer-arith -falign-jumps=1 -falign-loops=1 \
+	-falign-functions=1 -Wundef
+
+LOCAL_CFLAGS += -m32 -Os -fno-builtin -nostdinc
+
+LOCAL_CFLAGS += -DHAVE_CONFIG_H -DFSYS_EXT2FS=1 -DSUPPORT_SERIAL=1
+
+LOCAL_C_INCLUDES := \
+	$(LOCAL_PATH)/stage1 \
+	$(LOCAL_PATH)/stage2
+
+LOCAL_SYSTEM_SHARED_LIBRARIES :=
+LOCAL_SHARED_LIBRARIES :=
+
+LOCAL_MODULE := grub_start_stage2
+LOCAL_MODULE_PATH := $(PRODUCT_OUT)/grub
+
+# <generate the header file>
+LOCAL_MODULE_CLASS := EXECUTABLES
+intermediates := $(call local-intermediates-dir)
+
+STAGE2_SIZE_OBJ := $(intermediates)/stage2_size.h
+$(STAGE2_SIZE_OBJ) : PRIVATE_CUSTOM_TOOL = \
+	echo "\#define STAGE2_SIZE `stat -c '%s' $<`" > $@
+
+LOCAL_GENERATED_SOURCES := $(STAGE2_SIZE_OBJ)
+$(STAGE2_SIZE_OBJ): $(PRODUCT_OUT)/grub/grub_pre_stage2
+	@echo "target Generating: $@" 
+	$(transform-generated-source)
+# </generate the header file>
+
+include $(BUILD_RAW_EXECUTABLE)
+
+$(all_objects): $(STAGE2_SIZE_OBJ)
+$(LOCAL_BUILT_MODULE) : PRIVATE_LINK_SCRIPT :=
+$(LOCAL_BUILT_MODULE) : PRIVATE_LIBS :=
+$(LOCAL_BUILT_MODULE) : PRIVATE_RAW_EXECUTABLE_LDFLAGS := \
+	-nostdlib -N -Ttext=8200 -melf_i386
+
+#############################################
+## Generate the real deal stage2  (4)
+
+include $(CLEAR_VARS)
+
+my_files := $(PRODUCT_OUT)/grub/grub_start_stage2 \
+	$(PRODUCT_OUT)/grub/grub_pre_stage2
+
+file := $(PRODUCT_OUT)/grub/grub_stage2
+$(file) : $(my_files) 
+	@echo "target Creating: $@"
+	$(hide) cat $^ > $@
+ALL_PREBUILT += $(file)
+
+
+#############################################################################
+## Generate a full stage1+stage2 bin that we can just drop @ offset 0 on disk
+include $(CLEAR_VARS)
+grub_stage1 := $(PRODUCT_OUT)/grub/grub_stage1
+grub_stage2 := $(PRODUCT_OUT)/grub/grub_stage2
+grub_full := $(PRODUCT_OUT)/grub/grub.bin
+
+$(grub_full) : $(grub_stage1) $(grub_stage2)
+	@echo "target Generating GRUB bin: $@"
+	$(hide) rm -f $@
+	$(hide) dd if=$(grub_stage1) of=$@ bs=512 count=1 2>/dev/null
+	$(hide) dd if=$(grub_stage2) of=$@ bs=512 seek=1 2>/dev/null
+ALL_PREBUILT += $(grub_full)
+
+endif # x86
+endif # ! sim
diff --git a/BUGS b/BUGS
new file mode 100644
index 0000000..14c1f72
--- /dev/null
+++ b/BUGS
@@ -0,0 +1,7 @@
+See the Bug Tracking System for GNU GRUB on Savannah. The URL is:
+
+http://savannah.gnu.org/bugs/?group_id=68 (without SSL)
+
+or
+
+https://savannah.gnu.org/bugs/?group_id=68 (with SSL)
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..eeb586b
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) 19yy  <name of author>
+
+    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) 19yy name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..0f93033
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,9075 @@
+2005-05-08  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* configure.ac (AC_INIT): Upgraded to 0.97.
+
+	* compile: Copied from Automake 1.9.4.
+	* config.guess: Likewise.
+	* config.sub: Likewise.
+	* depcomp: Likewise.
+	* install-sh: Likewise.
+	* missing: Likewise.
+	* mkinstalldirs: Likewise.
+	* mdate-sh: Likewise.
+	* docs/texinfo.tex: Likewise.
+
+2005-05-08  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/fsys_xfs.c (next_dentry): Use arrays of arrays instead of
+	arrays of pointers for USUAL, to avoid read-only strings. Reported
+	by Sven Wegener <swegener@gentoo.org>.
+
+2005-03-28  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* lib/device.c (get_drive_geometry): Use ST.ST_SIZE instead of
+	ST.ST_BLOCKS to get the total number of sectors, because st_blocks
+	is not the same if it is a sparse file.
+
+2005-03-19  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/stage2.c (cmain): Initialize DEFAULT_FILE to an empty
+	string. Reported by NATORI Shin <natori@adm.s.u-tokyo.ac.jp>.
+
+2005-03-15  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/fsys_fat.c (fat_mount): Ignore the 3rd bit of a media
+	descriptor, because some BIOSes overwrite this value, according
+	to the storage mode (e.g. USB Floppy or USB HDD).
+
+2005-02-16  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* grub/asmstub.c (grub_stage2): Remove the attribute `volatile'
+	from doit. I hope this change is safe for all compilers.
+
+2005-02-15  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/builtins.c (install_func): If DEST_DRIVE is a hard
+	disk, enable the workaround in Stage 1 by replacing the jmp
+	with double nop's.
+
+	* stage1/stage1.h (STAGE1_BOOT_DRIVE_CHECK): New macro.
+	(STAGE1_BOOT_DRIVE_MASK): Removed.
+
+	* stage1/stage1.S (boot_drive_check): New label. This implements
+	a different workaround for buggy BIOSes which don't pass boot
+	drive correctly. This is effective for BIOSes which pass a value
+	without the seventh bit (0x80).
+	(boot_drive_mask): Removed.
+
+2005-02-03  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* grub/asmstub.c (console_current_color): Make it global as
+	declared.
+	(grub_stage2): Tweak the declaration and the definition of the
+	nested function doit.
+
+2005-02-02  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/smp-imps.h (imps_any_new_apics): Removed.
+	(imps_enabled): Likewise.
+	(imps_lapic_addr): Likewise.
+	(imps_num_cpus): Likewise.
+	(imps_cpu_apic_map): Likewise.
+	(imps_apic_cpu_map): Likewise.
+
+	* stage2/Makefile.am (libgrub_a_CFLAGS): Remove
+	-fwritable-strings. Not required for the grub shell actually.
+
+	* grub/Makefile.am (AM_CFLAGS): Likewise.
+
+2005-02-01  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* grub/asmstub.c (grub_stage2): Use auto instead of static for
+	nested functions.
+
+	* stage2/char_io.c (memcheck) [GRUB_UTIL]: Likewise.
+
+	* stage2/builtins.c (blocklist_func): Likewise.
+	(color_func): Likewise.
+	(install_func): Likewise.
+	(setkey_func): Likewise.
+
+	* lib/device.c (read_device_map): Likewise.
+
+2005-01-30  Yoshinori K. Okuji  <okuji@enbug.org>
+
+        * configure.ac (AC_INIT): Upgraded to 0.96.
+
+2004-10-11 Jason Thomas <jason@staff.pnc.com.au>
+
+	Patch from Stefanus Du Toit  <sjdutoit@uwaterloo.ca>
+	* docs/kernel.c.texi (cmain): Incremement mod by one, instead of
+	sizeof(module_t), since it's already a pointer of type module_t.
+	* docs/kernel.c (cmain): Do the same.
+
+2004-09-20  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* docs/internals.texi (Internals): Changed to an appendix.
+
+	* docs/grub.texi (@setchapternewpage): Changed to odd from off.
+	(@contents): Moved to the beginning.
+	(Future): Changed to an appendix.
+
+2004-08-17  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/cmdline.c (run_script): Fix a reversed conditional.
+	Reported by Alban Crequy <alban.crequy@apinc.org>.
+
+2004-08-07  Jason Thomas  <jason@staff.pnc.com.au>
+	
+	From Michael Hohnbaum <hohnbaum@us.ibm.com>:
+	* stage2/fsys_ext2fs.c (ext2fs_read): Handle sparse files.
+
+2004-07-24  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/stage2.c (cmain): Terminate DEFAULT_FILE with NUL
+	correctly. Reported by Alban Crequy <alban.crequy@apinc.org>.
+
+2004-07-21  Robert Millan  <robertmh@gnu.org>
+
+	Patch from David Weinehall <tao@debian.org>
+	* util/mkbimage: Fix XSI-isms (for supporting POSIX-only shells).
+
+2004-07-20  Robert Millan  <robertmh@gnu.org>
+
+	* util/grub-install.in: Detect GNU/k*BSD systems as well.
+
+2004-07-16  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* util/grub-install.in (convert): Fix the sed statement for
+	Linux. The expression was ambigious in some cases.
+
+2004-06-29  Robert Millan  <robertmh@gnu.org>
+
+	* util/grub-set-default.in: Fix minor syntax error (non-escaped
+	characters).
+
+2004-06-24  Robert Millan  <robertmh@gnu.org>
+
+	Fixes for FHS compliance. (/usr/share is for arch-independant data)
+	* stage1/Makefile.am: Move stage files to pkglibdir.
+	* stage2/Makefile.am: Likewise.
+	* docs/grub.texi: s,/usr/share,/usr/lib,g.
+	* util/grub-image.in: Look for stage files in pkglibdir.
+	* util/grub-install.in: Likewise.
+
+	* util/grub-install.in: Improve usage message.
+
+2004-06-20  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	This is a big change on saving a default entry. This change
+	makes it possible to set up a quite robust system using GRUB.
+	Now we do not use the second sector of Stage 2 to store an
+	entry number but use the file /boot/grub/default. This file
+	must be generated by grub-set-default, although this file is
+	plain-text.
+	
+	* util/grub-set-default.in: New file.
+	
+	* util/grub-install.in (grub_set_default): New variable.
+	Use /grub instead of /boot/grub on OpenBSD as well as NetBSD.
+	Run grub-set-default to make a default file.
+
+	* util/Makefile.am (sbin_SCRIPTS): Added grub-set-default.
+
+	* stage2/stage2.c (run_menu): Change the fallback handling to
+	support multiple fallback entries.
+	(cmain): Likewise. Also, get a saved entry from a default file
+	if possible, before reading a config file.
+
+	* stage2/shared.h (DEFAULT_FILE_BUF): New macro.
+	(DEFAULT_FILE_BUFLEN): Likewise.
+	(CMDLINE_BUF): Set to DEFAULT_FILE_BUF + DEFAULT_FILE_BUFLEN.
+	(MENU_BUFLEN): Set to 0x8000 + PASSWORD_BUF - MENU_BUF.
+	(fallback_entry): Removed.
+	(fallback_entries): Declared.
+	(fallback_entryno): Likewise.
+	(MAX_FALLBACK_ENTRIES): New macro.
+
+	* stage2/cmdline.c (run_script): Use FALLBACK_ENTRYNO instead of
+	FALLBACK_ENTRY.
+
+	* stage2/builtins.c (fallback_entry): Removed.
+	(fallback_entryno): New variable.
+	(fallback_entries): Likewise.
+	(init_config): Initialize FALLBACK_ENTRYNO and FALLBACK_ENTRIES.
+	(fallback_func): Rewritten completely.
+	(savedefault_func): Likewise.
+
+	* docs/grub.texi (grub-set-default): New direntry.
+	(Installation): Describe grub-set-default for manual
+	installations.
+	(Making your system robust): New section.
+	(Booting once-only): New subsection.
+	(Booting fallback systems): Likewise.
+	(fallback): Describe multiple fallback entries.
+	(savedefault): Describe an optional argument.
+	(Invoking grub-set-default): New chapter.
+	(Future): Replaced with a description about GRUB 2.
+
+	* configure.ac (AC_CONFIG_FILES): Added util/grub-set-default.
+
+2004-06-19  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/ufs2.h (int8_t): Renamed to ...
+	(grub_uint8_t): ... this.
+	(int16_t): Renamed to ...
+	(grub_int16_t): ... this.
+	(int32_t): Renamed to ...
+	(grub_int32_t): ... this.
+	(int64_t): Renamed to ...
+	(grub_int64_t): ... this.
+	(uint8_t): Renamed to ...
+	(grub_uint8_t): ... this.
+	(uint16_t): Renamed to ...
+	(grub_uint16_t): ... this.
+	(uint32_t): Renamed to ...
+	(grub_uint32_t): ... this.
+	(uint64_t): Renamed to ...
+	(grub_uint64_t): ... this.
+	(u_char): Renamed to ...
+	(grub_u_char): ... this.
+	(u_int): Renamed to ...
+	(grub_u_int): ... this.
+	(u_int8_t): Renamed to ...
+	(grub_u_int8_t): ... this.
+	(u_int16_t): Renamed to ...
+	(grub_u_int16_t): ... this.
+	(u_int32_t): Renamed to ...
+	(grub_u_int32_t): ... this.
+	(u_int64_t): Renamed to ...
+	(grub_u_int64_t): ... this.
+	(ino_t): Renamed to ...
+	(grub_ino_t): ... this.
+	All callers are changed.
+
+2004-06-14  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* stage2/ufs2.h (__uint8_t): Remove.
+	(__uint16_t): Likewise.
+	(__uint32_t): Likewise.
+	(__uint64_t): Likewise.
+	(ino_t): Typedef to uint32_t.
+
+2004-06-13  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/Makefile.am (noinst_HEADERS): Added ufs2.h.
+	
+2004-06-13  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* configure.ac (AC_INIT): Upgraded to 0.95.
+
+2004-05-23  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/char_io.c (grub_isspace): Use a switch sentense instead
+	of an if sentense, because that reduces the size.
+
+	* lib/device.c (read_device_map): Change the max number of DRIVE
+	to 127 from 8. This was too strict.
+
+	* stage2/asm.S (stop_floppy): Call pusha and popa outside the
+	block of real mode code. Reported by Guillem Jover
+	<guillem@debian.org>.
+
+2004-05-20  Damian Ivereigh  <damian@cisco.com>
+
+	* netboot/main.c: Fixed bootp only code so that options
+	work properly. This fix is obvious when compared with the
+	DHCP code.
+
+2004-05-17  Pavel Roskin  <proski@gnu.org>
+
+	* stage2/char_io.c (safe_parse_maxint): Disable for stage 1.5.
+	(grub_tolower): Disable for stage 1.5 except fat_stage1_5.
+	(grub_memcmp): Disable for stage 1.5 except iso9660_stage1_5.
+
+2004-05-14  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	From Sergey Matveychuk <sem@ciam.ru>:
+	* stage2/size_test: Added a check for ufs2_stage1_5.
+
+	* stage2/shared.h (STAGE2_ID_UFS2_STAGE1_5): New macro.
+	[FSYS_UFS2] (STAGE2_ID): Set to STAGE2_ID_UFS2_STAGE1_5.
+
+	* stage2/filesys.h (FSYS_UFS2_NUM): New macro.
+	[FSYS_UFS2] (ufs2_mount): New prototype.
+	[FSYS_UFS2] (ufs2_read): Likewise.
+	[FSYS_UFS2] (ufs2_dir): Likewise.
+	[FSYS_UFS2] (ufs2_embed): Likewise.
+	(NUM_FSYS): Added FSYS_UFS2_NUM.
+
+	* stage2/disk_io.c (fsys_table): Added an ufs2 entry.
+
+	* stage2/builtins.c (setup_func): Added ufs2 into the
+	STAGE1_5_MAP.
+
+	* stage2/Makefile.am (libgrub_a_SOURCES): Added fsys_ufs2.c.
+	(libgrub_a_CFLAGS): Added -DFSYS_UFS2=1.
+	(pkgdata_DATA): Added ufs2_stage1_5.
+	(noinst_PROGRAMS): Added ufs2_stage1_5.exec.
+	(ufs2_stage1_5_exec_SOURCES): New variable.
+	(ufs2_stage1_5_exec_CFLAGS): Likewise.
+	(ufs2_stage1_5_exec_CCASFLAGS): Likewise.
+	(ufs2_stage1_5_exec_LDFLAGS): Likewise.
+
+	* grub/Makefile.am (AM_CPPFLAGS): Added -DFSYS_ISO9660=1,
+	-DFSYS_JFS=1, -DFSYS_REISERFS=1, -DFSYS_UFS2=1, -DFSYS_VSTAFS=1,
+	-DFSYS_XFS=1, and -DUSE_MD5_PASSWORDS=1.
+
+	* configure.ac (--disable-ufs2): New option.
+
+	* stage2/fsys_ufs2.c: New file.
+	* stage2/ufs2.h: Likewise.
+
+2004-05-10  Robert Millan  <robertmh@gnu.org>
+
+	* lib/device.c: Mangle __FreeBSD_* macro usage to support
+	kFreeBSD-based non-FreeBSD systems (i.e. GNU/kFreeBSD).
+
+	Implement runtime detection of version of kFreeBSD. Now if
+	we build against kFreeBSD 5.x headers the GRUB shell will work on
+	both 4.x and 5.x.
+
+	Replace `u_int_t' types with portable `unsigned int' and old
+	reference to `geometry' structure to new `geom' one.
+
+	* docs/menu.lst: Split GNU/kFreeBSD and GNU/kNetBSD as separate
+	options than FreeBSD and NetBSD, respectively. There are minor
+	differences now (different paths).
+
+2004-05-03  Pavel Roskin  <proski@gnu.org>
+
+	* stage2/char_io.c (convert_to_ascii): Remove "%b" support.
+	It's non-standard and is not used anymore.
+	(grub_printf): Likewise.
+
+2004-04-29  Robert Millan  <robertmh@gnu.org>
+
+	From Yann Dirson  <dirson@debian.org>:
+	* util/mkbimage: Misc syntax fixes.
+
+2004-04-29  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* stage2/char_io.c (grub_memcmp): Define for stage1.5 too.
+
+	* stage2/fsys_iso9660.c (iso9660_mount): Use memcmp() instead of
+	__builtin_memcmp().
+	(iso9660_dir): Likewise.
+
+2004-04-26  Christian Jones  <chjones@aleph0.com>
+
+	* docs/grub.texi (Making a GRUB bootable CD-ROM): minor edits,
+	including a few compatibility notes and a change to
+	-boot-load-size 4 for the mkisofs command.
+
+2004-04-22  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* Makefile.am (AUTOMAKE_OPTIONS): Add "gnu".
+	* configure.ac: Update to work with automake 1.8, quote all
+	AC_DEFUN's correctly and provide descriptions for AC_DEFINE's.
+	* acinclude.m4: Likewise.
+	* acconfig.h: Removed.
+	
+	* stage1/Makefile.am (.exec): Use suffix rules instead of pattern
+	rules.
+	* stage2/Makefile.am (.exec): Likewise.
+
+2004-04-18  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* docs/grub.texi (Making a GRUB bootable CD-ROM): New section.
+
+	* stage2/disk_io.c (set_device): Use CH instead of *DEVICE to
+	test the first character of DEVICE, because DEVICE is
+	incremented.
+	Reported by Bernhard Treutwein.
+
+2004-04-15  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* netboot/fsys_tftp.c (buf_fill): Cast 1 to unsigned short
+	explicitly so that the constant doesn't extend unsigned short
+	to int automatically.
+	Reported by Eduard Guzovsky <eguzovsk@enterasys.com>.
+
+	* docs/grub.texi (Invoking grub-md5-crypt): Fixed the chapter
+	name.
+	Reported by Martin Pool <mbp@sourcefrog.net>.
+
+2004-04-04  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* configure.ac (STAGE2_CFLAGS): Check if -fno-stack-protector is
+	supported by GCC. If yes, added the option. This is necessary
+	for OpenBSD, because the stack protector defines additional
+	symbols. Reported by uc.sheda <uc.sheda@laposte.net>.
+
+2004-03-28  Pavel Roskin  <proski@gnu.org>
+
+	* stage2/boot.c: Imply --no-mem-option for Linux kernels with
+	protocol version 2.03 and above (Linux 2.4.18 and newer).
+
+2004-03-27  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/char_io.c [!GRUB_UTIL] (memcpy): New function. It is
+	defined as an alias of grub_memmove. This is copied from GRUB 2.
+
+	* stage2/disk_io.c (print_completions): Simplified conditionals
+	to make it easier to edit the file with Emacs.
+	Added support for (cd).
+	(set_device): Likewise.
+
+	* stage2/common.c (init_bios_info): Check if BOOT_DRIVE is a
+	CDROM drive. If it is true, set CDROM_DRIVE to BOOT_DRIVE.
+	(cdrom_drive): New variable.
+
+	From Leonid Lisovskiy <lly@pisem.net>:
+	* stage2/start_eltorito.S: New file.
+
+	* stage2/stage2.c (run_menu): Use GRUB_INVALID_DRIVE instead of
+	0xFF.
+
+	* stage2/shared.h (STAGE2_ID_ISO9660_STAGE1_5): New macro.
+	[FSYS_ISO9660] (STAGE2_ID): Set to STAGE2_ID_ISO9660_STAGE1_5.
+	(struct geometry): Added a new member ``sector_size''.
+	(BIOSDISK_FLAG_CDROM): New macro.
+	(cdrom_drive): Declared.
+
+	* stage2/fsys_iso9660.c: New file.
+	* stage2/iso9660.h: Likewise.
+
+	* stage2/filesys.h (FSYS_ISO9660_NUM): New macro.
+	[FSYS_ISO9660] (iso9660_mount): Declared.
+	[FSYS_ISO9660] (iso9660_read): Likewise.
+	[FSYS_ISO9660] (iso9660_dir): Likewise.
+	(NUM_FSYS): Added FSYS_ISO9660_NUM.
+
+	* stage2/disk_io.c (fsys_table) [FSYS_ISO9660]: Added iso9660.
+	(current_drive): Use GRUB_INVALID_DRIVE.
+	(log2): New function.
+	(rawread): Use BUF_GEOM.SECTOR_SIZE instead of SECTOR_SIZE.
+	Change the type of BUFADDR from int to char *.
+	Use a virtual track to make sure that one track fits in the
+	buffer.
+	(sane_partition): Allow CURRENT_DRIVE to be CDROM_DRIVE, because
+	a bios drive for a CD-ROM is often assigned to greater than
+	0x88.
+	(set_device): Use GRUB_INVALID_DRIVE instead of 0xFF.
+	(setup_part): Likewise.
+
+	* stage2/cmdline.c (init_cmdline): Use GRUB_INVALID_DRIVE.
+
+	* stage2/builtins.c (install_func): Use GRUB_INVALID_DRIVE.
+	(setup_func): Added iso9660_stage1_5.
+
+	* stage2/bios.c (biosdisk): Don't fall back to the CHS mode
+	if the drive is a CDROM.
+	(get_cdinfo): New function.
+	(get_diskinfo): Call get_cdinfo if the drive is greater than or
+	equal to 0x88 or the drive supports LBA.
+	Set the sector size to SECTOR_SIZE if it is not a CD-ROM.
+
+	* stage2/asm.S (biosdisk_int13_extensions): Take a word
+	argument AX instead of a byte argument AH.
+	(get_diskinfo_int13_extensions): Removed.
+
+	* stage2/Makefile.am (noinst_HEADERS): Added iso9660.h.
+	(libgrub_a_SOURCES): Added fsys_iso9660.c.
+	(libgrub_a_CFLAGS): Added -DFSYS_ISO9660=1.
+	(pkgdata_DATA): Added iso9660_stage1_5 and stage2_eltorito.
+	(noinst_PROGRAMS): Added iso9660_stage1_5.exec and
+	start_eltorito.exec.
+	(noinst_DATA): Added start_eltorito.
+	(pre_stage2_exec_SOURCES): Added fsys_iso9660.c.
+	(START_ELTORITO_LINK): New variable.
+	(start_eltorito_exec_SOURCES): Likewise.
+	(start_eltorito_exec_CCASFLAGS): Likewise.
+	(start_eltorito_exec_LDFLAGS): Likewise.
+	(start_eltorito_exec-start.$(OBJEXT)): New dependency.
+	(stage2_eltorito): New target.
+	(iso9660_stage1_5_exec_SOURCES): New variable.
+	(iso9660_stage1_5_exec_CFLAGS): Likewise.
+	(iso9660_stage1_5_exec_CCASFLAGS): Likewise.
+	(iso9660_stage1_5_exec_LDFLAGS): Likewise.
+
+	* stage1/stage1.h (GRUB_INVALID_DRIVE): New macro.
+
+	* stage1/stage1.S (boot_drive): Use the macro GRUB_INVALID_DRIVE.
+	(real_start): Likewise.
+
+	* lib/device.c (get_drive_geometry): Set GEOM->SECTOR_SIZE to
+	SECTOR_SIZE by default.
+
+	* configure.ac (--disable-iso9660): New option.
+
+2004-03-13  Yoshinori K. Okuji  <okuji@enbug.org>
+	
+	From Daniele Zelante <zeldan@email.it>:
+	* stage2/asm.S (stop_floppy): Use INT 13, AH=00h to stop the
+	floppy controller instead of a direct I/O.
+
+2004-03-12  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/serial.c (serial_putchar): Handle the character code
+	127 as a backspace. Reported by Florian Engelhardt
+	<f.engelhardt@gmx.net>.
+
+2004-03-12  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	From Boji Tony Kannanthanam <boji.t.kannanthanam@intel.com>:
+	* util/grub-install.in (convert): Add support for ATARAID
+	device names.
+	* lib/device.c (get_ataraid_disk_name) [__linux__]: New
+	function.
+	(init_device_map) [__linux__]: Probe ATARAID disks.
+
+	* stage2/size_test (check): Don't use the local statement any
+	longer. It was unneeded actually. Reported by Paul Jarc.
+
+2004-03-12  Yoshinori K. Okuji  <okuji@enbug.org>
+	
+	From Sergey Matveychuk <sem@ciam.ru>:
+	* lib/device.c (get_drive_geometry): Do not open the same device
+	more than once unnecessarily.
+	(get_drive_geometry) [__FreeBSD_version >= 500040]: Use new
+	ioctl methods.
+	(get_floppy_disk_name) [__FreeBSD__ >= 4]: Use /dev/fd%d rather
+	than /dev/rfd%d.
+	(get_ide_disk_name) [__FreeBSD__ >= 4]: Use /dev/ad%d rather
+	than /dev/rad%d.
+	(get_scsi_disk_name) [__FreeBSD__ >= 4]: Use /dev/da%d rather
+	than /dev/rda%d.
+	* grub/asmstub.c (get_diskinfo): Check if ERRNO is EPERM as
+	well.
+
+2004-02-28  Jeroen Dekkers  <jeroen@dekkers.cx>
+
+	* docs/grub.texi (partnew): Change @var{to} to @var{len}.
+
+2004-02-18  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	From Yury V. Umanets <umka@namesys.com>:
+	* stage2/fsys_reiserfs.c (REISER3FS_SUPER_MAGIC_STRING): New
+	macro.
+	(reiserfs_mount): Added checks for ReiserFS 3.
+	(reiserfs_embed): Likewise.
+
+2004-01-25  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* docs/grub.texi (Obtaining and Building GRUB): Instead of
+	describing how to use the anoncvs method, specify the URL of
+	the description page on Savannah.
+	Reported by Bernhard Treutwein.
+
+2004-01-18  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	From Thomas Schwinge <kischde@gmx.net>:
+	* grub/Makefile.am (AM_CPPFLAGS): New variable.
+	(AM_CFLAGS): Removed all cpp flags.
+
+	* stage2/xfs.h (__int8_t): Renamed to ...
+	(xfs_int8_t): ... this.
+	(__uint8_t): Renamed to ...
+	(xfs_uint8_t): ... this.
+	(__int16_t): Renamed to ...
+	(xfs_int16_t): ... this.
+	(__uint16_t): Renamed to ...
+	(xfs_uint16_t): ... this.
+	(__int32_t): Renamed to ...
+	(xfs_int32_t): ... this.
+	(__uint32_t): Renamed to ...
+	(xfs_uint32_t): ... this.
+	(__int64_t): Renamed to ...
+	(xfs_int64_t): ... this.
+	(__uint64_t): Renamed to ...
+	(xfs_uint64_t): ... this.
+	All callers are changed.x
+
+	From Egmont Koblinger <egmont@uhulinux.hu>:
+	* util/grub-install.in: Support an install devices in GRUB's
+	notation without parentheses.
+
+	* docs/grub.texi (Installing GRUB using grub-install): Added an
+	example of using grub-install without parentheses.
+
+2004-01-18  Yoshinori K. Okuji  <okuji@enbug.org>
+	
+	* util/grub-install.in: Use the first word of GRUB_SHELL when
+	checking if the grub shell is present. This is necessary to
+	support options to the grub shell (e.g. grub --read-only).
+
+	From Eric Kvaalen <E_Kvaalen.Arnesen@noos.fr>:
+	* docs/grub.texi: Many bug fixes.
+
+2004-01-17  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* lib/device.c [__linux__] (MAJOR): Support 32 bit and 64 bit
+	dev_t. This code is stolen from glibc.
+	Suggested by Shen Feng <shen@nanjing-fnst.com>.
+
+2004-01-11  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/terminfo.c (ti_set_term): Use a pointer to struct
+	terminfo instead to avoid GCC's bug, which inserts a reference
+	to memcpy implicitly.
+	(ti_get_term): Likewise.
+	All callers are fixed.
+
+	* stage2/terminfo.h (ti_set_term): Updated.
+	(ti_get_term): Likewise.
+
+	* stage2/shared.h (struct linux_kernel_header): New member,
+	initrd_max_address. Defined in the boot protocol 2.03 or higher.
+
+	* stage2/boot.c (load_initrd): If the boot protocol is greater
+	than or equal to 2.03, use the field ``initrd_max_address''
+	instead of LINUX_INITRD_MAX_ADDRESS.
+
+2003-12-30  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/fsys_ext2fs.c (ext2_is_fast_symlink): New function.
+	(ext2fs_dir): Use ext2_is_fast_symlink to check if the current
+	inode is a fast or slow symlink. This change was required
+	because Linux now uses acl seriously (i.e. incompatibility).
+	Reported by Chris PeBenito <pebenito@gentoo.org> and Seemant
+	Kulleen <seemant@gentoo.org>
+
+2003-11-30  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* lib/device.c (read_device_map) (sho_warning): New internal
+	function.
+	(read_device_map): If DRIVE is greater than 8, emit a warning
+	and ignore the drive, rather than exiting abnormally.
+	Reported by Greg Newby <newby@arsc.edu>.
+
+2003-10-19  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Migrated to newer autotools. Also, don't install mkbimage
+	because its name is too general and it does not conform to the
+	GNU Coding Standards in some points.
+	
+	* util/Makefile.am (EXTRA_DIST): New variable.
+	(sbin_SCRIPTS): Removed mkbimage.
+	(noinst_SCRIPTS): Added mkbimage.
+
+	* stage1/Makefile.am (AM_ASFLAGS): Renamed to ...
+	(AM_CCASFLAGS): ... this.
+
+	* stage2/Makefile.am (pre_stage2_exec_ASFLAGS): Renamed to ...
+	(pre_stage2_exec_CCASFLAGS): ... this.
+	(start_exec_ASFLAGS): Renamed to ...
+	(start_exec_CCASFLAGS): ... this.
+	(e2fs_stage1_5_exec_ASFLAGS): Renamed to ...
+	(e2fs_stage1_5_exec_CCASFLAGS): ... this.
+	(fat_stage1_5_exec_ASFLAGS): Renamed to ...
+	(fat_stage1_5_exec_CCASFLAGS): ... this.
+	(ffs_stage1_5_exec_ASFLAGS): Renamed to ...
+	(ffs_stage1_5_exec_CCASFLAGS): ... this.
+	(minix_stage1_5_exec_ASFLAGS): Renamed to ...
+	(minix_stage1_5_exec_CCASFLAGS): ... this.
+	(reiserfs_stage1_5_exec_ASFLAGS): Renamed to ...
+	(reiserfs_stage1_5_exec_CCASFLAGS): ... this.
+	(vstafs_stage1_5_exec_ASFLAGS): Renamed to ...
+	(vstafs_stage1_5_exec_CCASFLAGS): ... this.
+	(jfs_stage1_5_exec_ASFLAGS): Renamed to ...
+	(jfs_stage1_5_exec_CCASFLAGS): ... this.
+	(xfs_stage1_5_exec_ASFLAGS): Renamed to ...
+	(xfs_stage1_5_exec_CCASFLAGS): ... this.
+	(diskless_exec_ASFLAGS): Renamed to ...
+	(diskless_exec_CCASFLAGS): ... this.
+	(nbloader_exec_ASFLAGS): Renamed to ...
+	(nbloader_exec_CCASFLAGS): ... this.
+	(pxeloader_exec_ASFLAGS): Renamed to ...
+	(pxeloader_exec_CCASFLAGS): ... this.
+
+	* configure.in: Removed.
+	* configure.ac: New file. Mostly derived from configure.in.
+	
+2003-10-19  Yoshinori OKUJI  <okuji@enbug.org>
+
+	From KB Sriram <mail_kb@yahoo.com>:
+	* stage2/disk_io.c (set_device) [SUPPORT_NETBOOT]: Added support
+	for a completion of a network device.
+	(print_completions): Likewise.
+
+2003-10-10  Robert Millan  <robertmh@gnu.org>
+
+	* config.guess: Update from official source (CVS).
+	* config.sub: Likewise.
+
+2003-09-18  Robert Millan  <robertmh@gnu.org>
+
+	* docs/texinfo.tex: Update from ftp.gnu.org.
+
+2003-09-05  KB Sriram  <mail_kb@yahoo.com>
+
+	* stage2/fsys_fat.c: Fix missdetection of ext2fs as fatfs.
+
+2003-09-05  Robert Millan  <robertmh@gnu.org>
+
+	* docs/menu.lst (GNU/Linux): Add commented initrd command, which
+	is consistent with documentation.
+
+2003-09-01  Robert Millan  <robertmh@gnu.org>
+
+	* docs/menu.lst: Add NetBSD, OpenBSD, GNU/KFreeBSD and
+	GNU/KNetBSD.
+
+2003-08-13  Jason Thomas  <jason@intology.com.au>
+
+	* util/grub-install.in (resolve_symlink): New function to
+	resolve symlinks.
+	(find_device): Moved symlink code to new function.
+	Before we convert the install_device we attempt to resolve it if
+	its a symlink using the new function.
+	* util/mbchk.c (check_multiboot): The sense of an error message
+	was inverted.
+	Reported by Timothy Baldwin <T.E.Baldwin99@members.leeds.ac.uk>.
+
+2003-08-12  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/fsys_reiserfs.c (read_tree_node): Fixed a typo; only
+	matters for very large fs when tree doesn't fit in cache.
+	(IH_KEY_OFFSET): Don't check for INFO->version.  There are
+	actually old version file systems that use new version items.
+	(IH_KEY_ISTYPE): Likewise.
+	(reiserfs_dir): Likewise.
+
+2003-08-09  Thierry Laronde  <tlaronde@polynum.org>
+
+	* util/mkbimage: New File. `mkbimage' depends on GRUB and
+	existed	elsewhere. It is now part of GRUB so that people can
+	fix/contribute.
+	* util/Makefile.am (sbin_SCRIPTS): Added script `mkbimage'
+
+2003-08-01  Jason Thomas  <jason@intology.com.au>
+
+	* util/grub-install.in: support --no-floppy
+	This allow users to specify the --no-floppy option which
+	is passed onto the grub shell, so it does not probe the floppy
+	drive. 
+	Patch from kesha@diedas.soften.ktu.lt
+
+2003-06-17  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/fsys_reiserfs.c (reiserfs_mount): Clear the node cache.
+	This fixes a problem where files from other partitions appear at
+	the wrong partition.  Problem reported by Johan Regin.
+
+2003-05-04  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* docs/grub.texi (partnew): Fixed the inconsistency between the
+	implementation and the documentation. The last argument is the
+	length instead of the ending address.
+	Reported by Daniel Farrell <s2108287@student.rmit.edu.au>.
+
+2003-03-19  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	From Adam Lackorzynski <adam@os.inf.tu-dresden.de>:
+	* stage2/shared.h (KEY_NPAGE): Changed to 0x5100.
+	(KEY_PPAGE): Changed to 0x4900.
+
+2003-03-19  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/boot.c (load_image): Check if DATA_LEN plus SECTOR_SIZE
+	is less than or equal to MULTIBOOT_SEARCH, instead of if
+	DATA_LEN is less than or equal to MULTIBOOT_SEARCH.
+	Reported by Neelkanth Natu <neelnatu@yahoo.com>.
+
+2003-03-10  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	From Andrew Walrond <andrew@walrond.org>:
+	* stage2/fsys_reiserfs.c (struct reiserfs_journal_header):
+	Remove an unnecessary ``long''.
+
+2003-03-10  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	From Tilmann Bubeck:
+	* stage2/builtins.c [SUPPORT_SERIAL] (terminfo_func): Unescape
+	arguments before copying them, and escape sequences before
+	printing them.
+	* stage2/terminfo.h (TERMINFO_LEN): Changed to 40.
+
+2003-02-20  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* util/grub-install.in (find_device): Fix the sed script.
+
+2003-02-17  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* lib/device.c (check_device): If DEVICE is empty, just return
+	1.
+	(get_scsi_disk_name) [__QNXNTO__]: Make NAME empty, because SCSI
+	disks are detected as IDE disks on QNX RTP.
+
+	From Taketo Kabe <kabe@sra-tohoku.co.jp>:
+	* lib/device.c (get_ide_disk_name) [__QNXNTO__]: Set NAME to
+	"/dev/hdX".
+	(get_floppy_disk_name) [__QNXNTO__]: Set NAME to "/dev/fdX".
+	* stage2/mb_info.h (struct AddrRangeDesc): Specified with the
+	attribute packed.
+	* stage2/shared.h (struct mmar_desc): Likewise.
+
+2003-01-29  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	From Ilguiz Latypov:
+	* configure.in: Fix a syntax error in a sed script.
+	* stage2/bios.c (get_diskinfo): PhoenixBIOS 4.0 Revision 6.0 
+	for ZF Micro might understand the greater buffer size for the
+	"get drive parameters" int 0x13 call in its own way.  
+	Supposedly the BIOS assumes even bigger space is available and
+	thus corrupts the stack.  This is why we specify the exactly 
+	necessary size of 0x42 bytes.
+
+2003-01-25  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	From Steven Dick <ssd.gnu@mmae.ucf.edu>:
+	* stage2/pc_slice.h (PC_SLICE_TYPE_DELL_UTIL): New macro.
+	(IS_PC_SLICE_TYPE_FAT): Recognize PC_SLIDE_TYPE_DELL_UTIL as
+	well.
+
+2003-01-25  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	From Karsten Scheibler <karsten.scheibler@student.uni-halle.de>:
+	* stage2/terminfo.c (term): Don't use a C99-style initializer.
+
+2003-01-16  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	From H.J. Lu <hjl@gnu.org>:
+	* stage2/disk_io.c (part_start): Use unsigned long to support
+	large disks.
+	(part_length): Likewise.
+	* stage2/shared.h (part_start): Likewise.
+	(part_length): Likewise.
+
+2003-01-05  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* configure.in (CFLAGS): When the default CFLAGS is used,
+	eliminate -O2 and -g from CFLAGS, because Autoconf may
+	automatically set CFLAGS to them.
+
+2003-01-02  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	From Jeremy Katz:
+	* configure.in: Support building on x86_64 with gcc -m32.
+
+2003-01-02  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	From Jeremy Katz:
+	* stage2/fsys_ext2fs.c (ext2fs_dir): Initialize STR_CHK to shut
+	up GCC.
+	* stage2/fsys_minix.c (minix_dir): Likewise.
+
+2002-12-21  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/asm.S (gateA20): First, try a BIOS call (INT 15H,
+	AX=2400/2401). Use the keyboard controller, only if that failed.
+
+2002-12-11  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Add a workaround for buggy BIOSes which don't pass boot drive
+	correctly. The idea is that GRUB forces the fixed disk flag
+	when booted from a hard disk. When BIOS loads GRUB directly,
+	the boot drive must be either of 0x00 and 0x80, so this should
+	work, if those BIOSes always pass zero to %dl. AFAIK, this
+	assumption is always correct.
+
+	* stage2/builtins.c (install_func): Store the fixed disk flag of
+	the destination drive in BOOT_DRIVE_MASK in Stage 1.
+
+	* stage1/stage1.h (STAGE1_BOOT_DRIVE_MASK): New macro.
+
+	* stage1/stage1.S (boot_drive_mask): New variable. It is or'ed
+	to %dl.
+
+2002-12-09  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/char_io.c (init_page): Change the software name from
+	"GRUB" to "GNU GRUB". This was inaccurate. Reported by Ciaran
+	O'Riordan <coriordan@compsoc.com>.
+
+2002-12-04  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/builtins.c (embed_func): When checking if the disk can
+	store Stage 1.5, check every partition, if it isn't empty.
+
+2002-12-04  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/stage2.c (print_entry): Put a right arrow, if the entry
+	is longer than 71 characters. Reported by Pavel Roskin.
+
+2002-12-04  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/disk_io.c (set_device): If '(n' is given, add 'd' into
+	DEVICE. Reported by Pavel Roskin.
+
+2002-12-03  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Change the terminal structure a bit, to turn the cursor state
+	explicitly. Suggested by Pavel Roskin.
+	
+	* stage2/term.h (struct term_entry): Remove the member
+	`nocursor' and add `setcursor'.
+	[!STAGE1_5] (console_setcursor): New prototype.
+	[SUPPORT_HERCULES] (hercules_setcursor): Likewise.
+	[!STAGE1_5] (console_nocursor): Removed.
+	[SUPPORT_HERCULES] (hercules_nocursor): Likewise.
+
+	* stage2/stage2.c (run_menu): Call setcursor instead of
+	nocursor.
+	Call setcursor with 1 before starting a boot entry.
+
+	* stage2/shared.h (nocursor): Removed.
+	(setcursor): New prototype.
+
+	* stage2/hercules.c (herc_cursor_state): New variable.
+	(herc_turn_cursor): Removed.
+	(hercules_nocursor): Likewise.
+	(hercules_setcursor): New function.
+
+	* stage2/char_io.c (get_cmdline): Turn on the cursor at the
+	beginning, and restore it before returning.
+	(nocursor): Removed.
+	(setcursor): New function.
+
+	* stage2/asm.S (console_cursor_state): New variable.
+	(console_cursor_shape): Likewise.
+	(console_setcursor): New function.
+	(console_nocursor): Removed.
+
+	* grub/asmstub.c (console_setcursor): New function.
+	(hercules_setcursor): Likewise.
+	(console_nocursor): Removed.
+	(hercules_nocursor): Likewise.
+
+2002-12-03  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* docs/grub.texi (terminfo): Fix a misleading English sentence.
+	Reported by Pavel Roskin.
+	* stage2/builtins.c (builtin_terminfo): Likewise.
+
+2002-12-01  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	From Alexander Langer <alex@big.endian.de>:
+	* stage2/freebsd.h (RB_GDB): New macro.
+	(RB_MUTE): Likewise.
+	(RB_MULTIPLE): Likewise.
+
+	* stage2/boot.c (bsd_boot): Set the bits of RB_MULTIPLE, RB_GDB
+	and RB_MUTE when "-D", "-g" and "-m" are specified,
+	respectively.
+
+2002-12-01  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* docs/grub.texi (Reporting bugs): Specify the project page of
+	the BTS instead of the BTS itself.
+
+2002-11-30  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* docs/Makefile.am (man_MANS): Added grub-terminfo.8.
+	($(srcdir)/grub_terminfo.8): New target.
+	* utils/grub-terminfo.in: New file.
+	* util/Makefile.am (sbin_SCRIPTS): Added grub-terminfo.
+	* configure.in (AC_OUTPUT): Added util/grub-terminfo.
+
+	* docs/grub.texi (terminfo): New subsection.
+	(Invoking grub-terminfo): New chapter.
+
+	From Tilmann Bubeck <t.bubeck@reinform.de>:
+	* stage2/Makefile.am (noinst_HEADERS): Added terminfo.h and
+	tparm.h.
+	(libgrub_a_SOURCES): Added terminfo.c and tparm.c.
+	(pre_stage2_exe_SOURCES): Likewise.
+	* stage2/terminfo.c: New file.
+	* stage2/terminfo.h: Likewise.
+	* stage2/tparm.c: Likewise.
+	* stage2/tparm.h: Likewise.
+	* stage2/stage2.c (get_line_from_config): Fix handling of
+	backslashes.
+	* stage2/char_io.c (grub_putstr): New function.
+	(grub_printf): Use grub_putstr.
+	(substring): Add const into both arguments.
+	* stage2/builtins.c [SUPPORT_SERIAL]: Include terminfo.h.
+	[SUPPORT_SERIAL] (terminfo_func): New function.
+	[SUPPORT_SERIAL] (builtin_terminfo): New variable.
+	 (builtin_table) [SUPPORT_SERIAL]: Added a pointer to
+	BUILTIN_TERMINFO.
+	* stage2/serial.c (serial_gotoxy): Use ti_cursor_address.
+	(serial_cls): Use ti_clear_screen.
+	(serial_highlight): use ti_enter_standout_mode and
+	ti_exit_standout_mode.
+
+2002-11-30  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/disk_io.c (rawread): Make sure that SECTOR is valid.
+	If not, set ERRNUM to ERR_GEOM and return zero. This check is
+	critical when a partition table is corrupted.
+
+2002-11-28  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/asm.S (console_cls): Write spaces to the entire screen
+	instead of getting/setting the video mode, because this flickers
+	the screen and is quite annoying, if using a LCD.
+
+2002-11-15  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* docs/grub.texi (QNX): New subsection. Reported by
+	Marian-Nicolae V. ION <marian_ion@noos.fr>.
+
+2002-10-28  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* grub/asmstub.c (console_translate_key): Deal with KEY_PPAGE
+	and KEY_NPAGE.
+	* stage2/serial.c (serial_translate_key_sequence): Added two new
+	codes for Page Up and Page Down.
+	* stage2/asm.S (translation_table): Added entries for KEY_PPAGE
+	and KEY_NPAGE.
+	* stage2/stage2.c (run_menu): Deal with Page Up and Page Down.
+	Also recognize the right key for the selection of a boot entry.
+	Suggested by Adam Lackorzynski <adam@os.inf.tu-dresden.de>.
+
+2002-10-10  Jason Thomas  <jason@topic.com.au>
+
+	* stage2/builtins.c (setup_func): Added missing space to --force-lba
+	option. Reported by Kenneth Crudup <kenny@panix.com>
+
+2002-10-06  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/asm.S (gateA20): Output a dummy command (0xff), as a
+	workaround for USB keyboard hanging problem. Suggested by
+	Hidetoshi Nishimaki <nishimaki@mxs.nes.nec.co.jp>.
+
+2002-10-06  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* configure.in (falign_loop_flag): New variable. Set to if GCC
+	supports `-falign-*'. If true, use `-falign-jumps',
+	`-falign-loops' and `-falign-functions' instead of
+	`-malign-jumps', `-malign-loops' and `-malign-functions',
+	because `-malign-*' are obsolete in GCC 3.x. Reported by Jeremy
+	Katz.
+
+2002-09-13  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/serial.c (fill_input_buf): Take a new argument NOWAIT.
+	If NOWAIT is true, don't loop.
+	All callers are changed.
+
+2002-09-08  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* configure.in (--disable-serial): Fix a typo in the
+	description.
+
+2002-08-20  Jason Thomas <jason@topic.com.au>
+
+	Changed highlight state code for hercules, console and serial.
+	The state was 0 - normal or 1 - highlight.
+	The state is now defined using an enum called color_state.
+
+	* stage2/term.h (color_state): New enum.
+	(COLOR_STATE_STANDARD): Standard color to use when not using
+	user defined.
+	(COLOR_STATE_NORMAL): User defined normal color.
+	(COLOR_STATE_HIGHLIGHT): User defined highlight color.
+	(console_highlight): Renamed to console_setcolorstate.
+	(serial_highlight): Renamed to serial_setcolorstate.
+	(hercules_highlight): Renamed to hercules_setcolorstate.
+	* stage2/hercules.c (herc_highlight_state): Removed.
+	(herc_standard_color): New variable.
+	(herc_color_state): Likewise.
+	(herc_highlight): Renamed to herc_setcolorstate.
+	(herc_setcolorstate): Added switch to handle new states.
+	* stage2/console.c (console_highlight_state): Removed.
+	(console_standard_color): New variable.
+	(console_color_state): Likewise.
+	(console_highlight): Renamed to console_setcolorstate.
+	(console_setcolorstate): Added switch to handle new states.
+	* stage2/serial.c (serial_highlight): Renamed to
+	serial_setcolorstate.
+	(serial_setcolorstate): Adjusted 'if' to suit new states.
+	* grub/asmstub.c (console_highlight): Renamed to
+	console_setcolorstate.
+	(console_setcolorstate): Adjusted 'if' to suit new states.
+	* stage2/stage2.c (print_entry): Set color states using new
+	states.
+	(print_border): Likewise.
+	* stage2/stage2.c (run_menu): Reverse if (!) to if () for
+	uniformitty.
+
+2002-07-12  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/boot.c (load_image): Rewrite the Linux booting support
+	radically. Now it should work even on a machine having, say,
+	only 128KB, theoretically. Of course, GRUB itself doesn't work
+	on such a system, though.
+	(load_initrd): Initialize LH based on CUR_ADDR, because the
+	location becomes dynamic.
+	* stage2/shared.h (LINUX_MAX_SETUP_SECTS): Set to 64.
+	(LINUX_HEAP_END_OFFSET): Set to (0x9000 - 0x200).
+	(LINUX_STAGING_AREA): Removed.
+	(LINUX_SETUP): Likewise.
+	(LINUX_KERNEL): Likewise.
+	(LINUX_KERNEL_MAXLEN): Likewise.
+	(LINUX_SETUP_SEG): Likewise.
+	(LINUX_INIT_SEG): Likewise.
+	(LINUX_SETUP_STACK): Set to 0x9000.
+	(LINUX_BZIMAGE_ADDR): New macro.
+	(LINUX_ZIMAGE_ADDR): Likewise.
+	(LINUX_OLD_REAL_MODE_ADDR): Likewise.
+	(CL_MY_LOCATION): Removed.
+	(CL_MY_END_ADDR): Likewise.
+	(CL_BASE_ADDR): Likewise.
+	(CL_MAGIC): Renamed to ...
+	(LINUX_CL_MAGIC): ... this.
+	(LINUX_CL_OFFSET): New macro.
+	(LINUX_CL_END_OFFSET): Likewise.
+	(LINUX_SETUP_MOVE_SIZE): Likewise.
+	(struct linux_kernel_header): Change the type of the member
+	"cmd_line_ptr" to char *.
+	(linux_data_tmp_addr): Declared.
+	(linux_data_real_addr): Likewise.
+	* stage2/asm.S [!STAGE1_5] (linux_data_tmp_addr): New variable.
+	[!STAGE1_5] (linux_data_real_addr): Likewise.
+	[!STAGE1_5] (big_linux_boot): Copy the real mode part from
+	LINUX_DATA_TMP_ADDR to LINUX_DATA_REAL_ADDR.
+	* grub/asmstub.c (linux_data_tmp_addr): New variable.
+	(linux_data_real_addr): Likewise.
+
+2002-07-09  Yoshinori K. Okuji  <okuji@enbug.org>
+	
+	From Mark Kettenis <kettenis@chello.nl>:
+	* stage2/boot.c (load_image): Recognize newer FreeBSD kernels.
+	* stage2/i386-elf.h (EI_OSABI): New macro.
+	(EI_ABIVERSION): Likewise.
+	(ELFOSABI_FREEBSD): Likewise.
+	(EI_PAD): Set to 9.
+
+2002-07-06  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/shared.h (boot_part_offset): Removed.
+	
+	* stage2/disk_io.c (set_bootdev): Copy the partition information
+	here. Now this function can call rawread, so it can fail.
+	(boot_part_offset): Removed.
+
+	* stage2/builtins.c (boot_func): Don't copy the partition
+	information here.
+	(real_root_func): Check ERRNUM after calling set_bootdev.
+
+2002-07-04  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* docs/grub.texi (Reporting bugs): Use the group name (i.e.
+	grub) instead of the group id (i.e. 68) for the URL of the BTS.
+
+2002-07-03  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/serial.c [!GRUB_UTIL] (inb): Added a delay into this
+	function itself.
+	[!GRUB_UTIL] (outb): Likewise.
+	[!GRUB_UTIL] (serial_hw_put): Increase the timeout value, and
+	don't call serial_hw_delay explicitly any longer.
+	(fill_input_buf): Increase the maximum number of retries, reset
+	the counter to zero after getting a valid character, and don't
+	call serial_hw_delay explicitly any longer.
+
+2002-07-03  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/serial.c [!GRUB_UTIL] (serial_hw_fetch): Fixed a typo.
+	Reported by Ilguiz Latypov.
+
+2002-07-01  Yoshinori K. Okuji <okuji@enbug.org>
+
+	* Makefile.am (AUTOMAKE_OPTIONS): New variable. Specify the
+	required Automake version explicitly.
+	
+2002-06-30  Yoshinori K. Okuji <okuji@enbug.org>
+
+	* stage2/builtins.c [SUPPORT_SERIAL || SUPPORT_HERCULES]
+	(terminal_func): Set CURRENT_TERM to each of selected terminals
+	before calling grub_printf, and restore CURRENT_TERM after it.
+	Reported by Ilguiz Latypov.
+	Prepend a carriage return to the prompting message, because it
+	is ugly that the same messages fulfill the whole screen.
+
+2002-06-30  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/serial.c [!GRUB_UTIL] (serial_hw_fetch): Fixed the
+	conditional statement. Reported by Ilguiz Latypov.
+	
+2002-06-24  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* MAINTENANCE: New file.
+	
+2002-06-15  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/disk_io.c [SUPPORT_NETBOOT] (GRUB): Defined.
+	[SUPPORT_NETBOOT]: Include etherboot.h.
+	[!STAGE1_5] (print_completions) [SUPPORT_NETBOOT]: When
+	completing a disk name, if NETWORK_READY is true, add "nd" as a
+	completion.
+	
+2002-06-15  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/fsys_xfs.c (le32): Don't use bswap, but use xchgb and
+	roll, because 386 doesn't have bswap. Reported by Frode Vatvedt
+	Fjeld <frodef@acm.org>.
+	
+2002-06-12  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* netboot/main.c (ifconfig): If GW is specified, clear out the
+	ARP entry for the gateway. If SVR is specified, clear out the
+	ARP entry for the server. Reported by Uwe Dannowski
+	<ud3@ira.uka.de>.
+	
+2002-06-12  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* util/grub-md5-crypt.in: Prompt to retype a password, and check
+	if the passwords matches. Suggested by Matt Perry
+	<matt@primefactor.com>.
+	Also, don't use Perl any longer, because *BSD's sh and GNU
+	support ``read -r'', and GRUB doesn't support any other
+	operating system anyway.
+	
+2002-06-12  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	The terminal handling code is rewritten radically.
+	
+	* stage2/console.c: New file.
+	* stage2/term.h: Likewise.
+	
+	* stage2/Makefile.am (noinst_HEADERS): Added term.h.
+	(libgrub_a_SOURCES): Added serial.c.
+	(pre_stage2_exec_SOURCES): Added console.c.
+
+	* stage2/asm.S (console_putchar): Rewritten from scratch.
+	[!STAGE1_5] (translation_table): New variable.
+	[!STAGE1_5] (translate_keycode): New function.
+	[!STAGE1_5] (console_getkey): Call translate_keycode.
+	[!STAGE1_5] (console_checkkey): Likewise.
+	[!STAGE1_5] (nocursor): Renamed to ...
+	[!STAGE1_5] (console_nocursor): ... this.
+	[!STAGE1_5] (console_set_attrib): Removed.
+
+	* stage2/builtins.c: Include term.h.
+	(terminal): Removed.
+	(normal_color): Likewise.
+	(highlight_color): Likewise.
+	(cat_func): Display a question mark when a non-printable
+	character was read.
+	(terminal_func): Rewritten almost from scratch.
+
+	* stage2/char_io.c: Include term.h.
+	[!STAGE1_5] (auto_fill): Removed.
+	[!STAGE1_5] (term_table): New variable.
+	[!STAGE1_5] (current_term): Likewise.
+	[!STAGE1_5] (real_get_cmdline): New function. The code was
+	stolen from the previous version of get_cmdline.
+	[!STAGE1_5] (get_cmdline): Rewritten from scratch.
+	[!STAGE1_5] (translate_keycode): Removed.
+	[!STAGE1_5] (getkey): Rewritten from scratch.
+	[!STAGE1_5] (checkkey): Likewise.
+	(grub_putchar): Likewise.
+	[!STAGE1_5] (gotoxy): Likewise.
+	[!STAGE1_5] (getxy): Likewise.
+	[!STAGE1_5] (cls): Likewise.
+	[!STAGE1_5] (nocursor): New function.
+	[SUPPORT_SERIAL] (serial_getxy): Removed.
+	[SUPPORT_SERIAL] (serial_gotoxy): Likewise.
+	[SUPPORT_SERIAL] (serial_cls): Likewise.
+	[SUPPORT_SERIAL] (serial_getxy): Likewise.
+	[!STAGE1_5] (set_attrib): Likewise.
+
+	* stage2/cmdline.c (init_cmdline): Set COUNT_LINES to -1.
+
+	* stage2/common.c [!STAGE1_5] (err_list): Removed
+	ERR_NEED_SERIAL and added ERR_DEV_NEED_INIT.
+
+	* stage2/hercules.c: Rewritten almost from scratch.
+	* stage2/hercules.h (herc_putchar): Removed.
+	(herc_cls): Likewise.
+	(herc_getxy): Likewise.
+	(herc_gotoxy): Likewise.
+	(herc_set_attrib): Likewise.
+
+	* stage2/serial.c: Rewritten almost from scratch.
+	* stage2/serial.h: Likewise.
+
+	* stage2/shared.h [GRUB_UTIL] (DISP_UL): Set to the same value
+	as VGA's.
+	[GRUB_UTIL] (DISP_UR): Likewise.
+	[GRUB_UTIL] (DISP_LL): Likewise.
+	[GRUB_UTIL] (DISP_LR): Likewise.
+	[GRUB_UTIL] (DISP_HORIZ): Likewise.
+	[GRUB_UTIL] (DISP_VERT): Likewise.
+	[GRUB_UTIL] (DISP_LEFT): Likewise.
+	[GRUB_UTIL] (DISP_RIGHT): Likewise.
+	[GRUB_UTIL] (DISP_UP): Likewise.
+	[GRUB_UTIL] (DISP_DOWN): Likewise.
+	(grub_error_t): Removed ERR_NEED_SERIAL.
+	Added ERR_DEV_NEED_INIT.
+	(normal_color): Removed.
+	(highlight_color): Likewise.
+	(console_cls): Removed, because this is declared in term.h.
+	(console_getxy): Likewise.
+	(console_gotoxy): Likewise.
+	(console_putchar): Likewise.
+	(console_getkey): Likewise.
+	(console_checkkey): Likewise.
+	(console_set_attrib): Removed.
+	(set_attrib): Likewise.
+	[GRUB_UTIL] (nocursor): Declared.
+	(auto_fill): Removed.
+	(terminal): Likewise.
+	(TERMINAL_CONSOLE): Likewise.
+	(TERMINAL_SERIAL): Likewise.
+	(TERMINAL_HERCULES): Likewise.
+	(TERMINAL_DUMB): Likewise.
+	(translate_keycode): Likewise.
+
+	* stage2/stage2.c: Include term.h.
+	(print_entry): Rewritten from scratch.
+	(print_entries): Likewise.
+	(print_border): Likewise.
+	(set_line): Removed.
+	(set_line_normal): Likewise.
+	(set_line_highlight): Likewise.
+	
+	* grub/Makefile.am (AM_CFLAGS): Added -DSUPPORT_HERCULES=1.
+	
+	* grub/asmstub.c: Don't include hercules.h. Include term.h.
+	(console_current_color): New variable.
+	(console_translate_key): New function.
+	(console_checkkey): Rewritten from scratch.
+	(console_getkey): Likewise.
+	(console_putchar): Likewise.
+	(console_set_attrib): Removed.
+	(console_highlight): New function.
+	(console_setcolor): Likewise.
+	(console_nocursor): Likewise.
+	(serial_getkey): Removed.
+	(serial_checkkey): Likewise.
+	(serial_putchar): Likewise.
+	(serial_exists): Likewise.
+	(serial_get_port): Likewise.
+	(serial_init): Likewise.
+	(serial_hw_fetch): New function.
+	(serial_hw_put): Likewise.
+	(serial_hw_delay): Likewise.
+	(serial_hw_get_port): Likewise.
+	(serial_hw_init): Likewise.
+	(set_serial_device): Renamed to ...
+	(serial_set_device): ... this.
+	(herc_putchar): Renamed to ...
+	(hercules_putchar): ... this.
+	(herc_cls): Renamed to ...
+	(hercules_cls): ... this.
+	(herc_getxy): Renamed to ...
+	(hercules_getxy): ... this.
+	(herc_gotoxy): Renamed to ...
+	(hercules_gotoxy): ... this.
+	(hercules_highlight): New function.
+	(hercules_setcolor): Likewise.
+	(hercules_nocursor): Likewise.
+	(herc_set_attrib): Removed.
+
+	* grub/main.c: Include term.h.
+	(main): If USE_CURSES is false, set CURRENT_TERM->FLAGS to
+	TERM_NO_EDIT | TERM_DUMB. TERMINAL is not used any longer.
+	
+2002-06-01  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* docs/grub.texi (FAQ): Removed. See the GNU GRUB FAQ on the web
+	instead.
+	
+2002-05-31  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* docs/grub.texi (Reporting bugs): Recommend using the BTS on
+	Savannah rather than the list bug-grub.
+	
+2002-05-25  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/builtins.c (boot_func): Load the boot partition
+	information, only if the address of the boot partition entry is
+	set appropriately.
+	(real_root_func): If ATTEMPT_MOUNT is false, call open_partition
+	and if successful, call set_bootdev, to set the offset of the
+	boot partition and the address of the boot paetition entry.
+	IF ATTEMPT_MOUNT is false, don't set BOOTDEV. The BSD evil hack
+	is useless with the command "rootnoverify" anyway.
+	* stage2/disk_io.c (boot_part_addr): Initialized with zero
+	explicitly, to emphasize that it is invalid.
+	
+2002-05-24  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/builtins.c (real_root_func): New function.
+	(root_func): Just call real_root_func.
+	(rootnoverify_func): Likewise.
+	
+2002-05-23  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* configure.in (AM_INIT_AUTOMAKE): Changed the version number to
+	0.93.
+	
+2002-05-23  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	Define the behavior of the boot loader when the load end address
+	and the bss end address are zero in the Multiboot Specification,
+	and add the support into GRUB. I've modified a patch from Yuri
+	Zaporogets <yuriz@ukr.net>.
+	
+	* stage2/boot.c (load_image): In the case of Multiboot a.out
+	kludge, set the load end address to the load address plus the
+	size of the OS image file, if it is zero. Similarly, set the bss
+	end address to the load end address, if it is zero.
+	
+	* util/mbchk.c (check_multiboot): Don't check if the load
+	address is greater than or equal to the load end address, if the
+	load end address is zero. Don't check if the load end address is
+	greater than the bss end address, if the bss end address is
+	zero. And, don't check if the load end address is less than or
+	equal to the entry address, if the load end address is zero.
+	
+	* docs/multiboot.texi (The address fields of Multiboot header):
+	Added descriptions about the behavior of the boot loader when
+	LOAD_END_ADDR is zero and BSS_END_ADDR is zero.
+	
+2002-05-22  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/builtins.c (boot_func): If DEBUG is true, print
+	BOOT_DRIVE and BOOT_PART_OFFSET.
+	Don't set ERRNUM after rawread failed, because rawread should
+	set ERRNUM itself.
+	
+2002-05-20  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* lib/device.c (read_device_map): Show an error message and exit
+	abnormally, if MAP[DRIVE] has already been filled.
+	* util/grub-install.in: If there is any dulicated entry, print
+	an error message and exit abnormally.
+	
+2002-05-20  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* lib/device.c: Don't include linux/hdreg.h, linux/major.h,
+	or linux/kdev_t.h.
+	[__linux__] (HDIO_GETGEO): Defined.
+	[__linux__] (hd_geometry): Likewise.
+	[__linux__] (FLOPPY_MAJOR): Likewise.
+	[__linux__] (MINORBITS): Likewise.
+	[__linux__] (MAJOR): Likewise.
+	
+2002-05-08  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* netboot/fsys_tftp.c (tftp_read): Don't call buf_fill unless
+	SIZE is positive.
+	
+2002-05-08  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* netboot/etherboot.h (ETH_MAX_MTU): Because some DHCP/BOOTP
+	servers don't treat the maximum length the same as Etherboot,
+	subtract the size of an IP header and that of an UDP header.
+	
+2002-04-30  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	From Jean-Jacques Michel <jjmichel@linbox.com>:
+	* stage2/boot.c (load_image): For Linux, check if DATA_LEN is
+	greater than MULTIBOOT_SEARCH. If that's true, read the rest
+	after copying data already read in BUFFER.
+	
+2002-04-30  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/boot.c (load_image): For Linux, don't check if the
+	length of protected mode code is greater than or equal to the
+	expected length minus 16. Instead, just check if no error
+	occurred. That was problematic, because memdisk has no protected
+	mode code. Also, I don't see what the magic number 16 was for.
+	
+2002-04-29  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/builtins.c [SUPPORT_SERIAL] (terminal_func): Added a
+	new option ``--silent''. This suppresses messages, if specified.
+	
+2002-04-29  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* config.guess: New upstream version.
+	* config.sub: Likewise.
+	
+2002-04-20  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* netboot/config.c (PCI_NIC) [INCLUDE_DAVICOM]: Fix typos.
+	Reported by Julien Perrot <julien.perrot@iie.cnam.fr>.
+	
+2002-04-17  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/builtins.c [SUPPORT_SERIAL] (terminal_func): Set
+	COUNT_LINES to -1, to disable the pager.
+	
+2002-04-16  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* docs/grub.texi (Obtaining and Building GRUB): Update the link
+	to the binutils site.
+
+2002-04-06  Pavel Roskin  <proski@gnu.org>
+
+	* util/grub-install.in: Fix hardcoded /dev/hda1.
+
+2002-04-06  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/builtins.c [GRUB_UTIL] (dump_func): New function.
+	[GRUB_UTIL] (builtin_dump): New variable.
+	(builtin_table) [GRUB_UTIL]: Added a pointer to BUILTIN_DUMP.
+	* util/grub-install.in: Make sure that GRUB reads the same
+	images as the host operating system by comparing the result of
+	running the command "dump" with the contents of the OS file.
+	
+2002-04-04  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/builtins.c (setup_func): Don't embed a drive number, if
+	unnecessary.
+	
+2002-03-29  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* docs/grub.texi (General commands): Added ``pager'' into the
+	menu.
+	(pager): New subsection.
+	(terminal): Added a description about the option
+	``--lines=LINES''.
+
+	* configure.in (AC_INIT_AUTOMAKE): Set the version number to
+	0.92.
+	
+2002-03-26  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* netboot/eepro100.c (eepro100_probe): Increase the delay at the
+	initialization.
+	
+2002-03-26  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/boot.c (linux_mem_size): New variable.
+	(load_image): Check a mem= option and set LINUX_MEM_SIZE to the
+	specified memory size, if any. Otherwise, to zero. When an
+	overflow is detected, use LINUX_INITRD_MAX_ADDRESS instead.
+	(load_initrd): If LINUX_MEM_SIZE is non-zero, use it instead of
+	the actual memory size.
+	* stage2/char_io.c (safe_parse_maxint): Use ERR_NUMBER_OVERFLOW
+	instead of ERR_NUMBER_PARSING, when an overflow occurs.
+	* stage2/common.c [!STAGE1_5] (err_list): Added
+	ERR_NUMBER_OVERFLOW.
+	* stage2/shared.h (ERR_NUMBER_OVERFLOW): New constant.
+	
+2002-03-24  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/stage2.c (run_menu): Call cls outside the loop to run
+	scripts.
+	* stage2/cmdline.c (run_script): Prompt a user's intervention,
+	only when FALLBACK_ENTRY is negative.
+	
+2002-02-11  Pavel Roskin  <proski@gnu.org>
+
+	* util/grub-install.in (find_device): New function - find block
+	device for given file or directory.  Resolve symlinks to fix
+	problem on Linux with devfs and old device names in /etc/fstab.
+	Use find_device() for root_device, bootdir_device and
+	grubdir_device.
+
+2002-02-08  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* grub/main.c (OPT_NO_PAGER): New macro.
+	(longopts): Added an entry for "--no-pager".
+	(usage): Added a description about "--no-pager".
+	(main): In case of OPT_NO_PAGER, set USE_PAGER to zero. The same
+	thing is done with OPT_BATCH, because the pager is just harmful
+	in batch mode.
+	
+2002-02-08  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/builtins.c (help_func): Show all the commands runnable
+	with the command-line interface, if "--all" is specified.
+	
+2002-02-08  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	An internal pager is implemented.
+	
+	* stage2/builtins.c (pager_func): New function.
+	(builtin_pager): New variable.
+	(terminal_func): New option, "--lines=LINES" is added. If this
+	option is specified, set MAX_LINES to the value. Otherwise, set
+	MAX_LINES to 24.
+	(vbeprobe_func): Remove the pager code specific to this
+	function.
+	(builtin_table): Added a pointer to BUILTIN_PAGER.
+	* stage2/char_io.c (max_lines) [!STAGE1_5]: New variable.
+	(count_lines) [!STAGE1_5]: Likewise.
+	(use_pager) [!STAGE1_5]: Likewise.
+	(grub_putchar) [!STAGE1_5]: if C is a newline and COUNT_LINES is
+	not -1, count up the number of lines. If it exceeds the maximum
+	number of lines minus 2, show a message and wait for input of
+	return key. "minus 2" is to reserve space for the message
+	printed by this internal pager.
+	* stage2/cmdline.c (enter_cmdline): If USE_PAGER is true, set
+	COUNT_LINES to zero, before running a command, and reset
+	COUNT_LINES to -1 after that.
+	* stage2/shared.h (max_lines) [!STAGE1_5]: Declared.
+	(count_lines) [!STAGE1_5]: Likewise.
+	(use_pager) [!STAGE1_5]: Likewise.
+	
+2002-02-08  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/fsys_jfs.c (jfs_read) [STAGE1_5]: Set and reset
+	DISK_READ_FUNC even in Stage 1.5.
+	* stage2/fsys_xfs.c (xfs_read) [STAGE1_5]: Likewise.
+
+	* stage2/stage1_5.c (saved_sector): Initialized with -1.
+	(cmain): Check if SAVED_SECTOR was set appropriately after
+	reading the second sector of Stage 2. If SAVED_SECTOR is not
+	set (i.e. it is equal to -1), print an error and stop.
+	
+2002-02-05  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/builtins.c (setup_func): Add a VSTa fs entry into
+	STAGE1_5_MAP.
+	
+2002-02-05  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/shared.h (BUILTIN_HELP_LIST): New macro. Used for
+	commands whose help messages are listed when no argument is
+	specified to the command "help".
+	* stage2/builtins.c (builtin_blocklist): Added the attribute
+	BUILTIN_HELP_LIST.
+	(builtin_boot): Likewise.
+	(builtin_bootp): Likewise.
+	(builtin_cat): Likewise.
+	(builtin_chainloader): Likewise.
+	(builtin_color): Likewise.
+	(builtin_configfile): Likewise.
+	(builtin_device): Likewise.
+	(builtin_dhcp): Likewise.
+	(builtin_displayapm): Likewise.
+	(builtin_displaymem): Likewise.
+	(builtin_find): Likewise.
+	(builtin_geometry): Likewise.
+	(builtin_halt): Likewise.
+	(builtin_help): Likewise.
+	(builtin_hide): Likewise.
+	(builtin_ifconfig): Likewise.
+	(builtin_initrd): Likewise.
+	(builtin_kernel): Likewise.
+	(builtin_makeactive): Likewise.
+	(builtin_map): Likewise.
+	(builtin_md5crypt): Likewise.
+	(builtin_module): Likewise.
+	(builtin_modulenounzip): Likewise.
+	(builtin_partnew): Likewise.
+	(builtin_parttype): Likewise.
+	(builtin_quit): Likewise.
+	(builtin_rarp): Likewise.
+	(builtin_reboot): Likewise.
+	(builtin_root): Likewise.
+	(builtin_rootnoverify): Likewise.
+	(builtin_serial): Likewise.
+	(builtin_setkey): Likewise.
+	(builtin_setup): Likewise.
+	(builtin_terminal): Likewise.
+	(builtin_testvbe): Likewise.
+	(builtin_tftpserver): Likewise.
+	(builtin_unhide): Likewise.
+	(builtin_uppermem): Likewise.
+	(builtin_vbeprobe): Likewise.
+
+	(help_func): When no argument is specified, if the last entry
+	was at the left column, print an extra newline.
+	
+2002-02-05  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/shared.h (BUILTIN_HIDDEN): Renamed to ...
+	(BUILTIN_NO_ECHO): ... this. The old name was too difficult to
+	see _what_ was hidden.
+	
+2002-02-05  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* netboot/misc.c (twiddle): Go back to the bar progress, copied
+	from etherboot-5.0.5/src/misc.c. Execute the code only if DEBUG
+	is true.
+	
+2002-02-05  Yoshinori K. Okuji  <okuji@enbug.org>
+
+	* stage2/builtins.c (displaymem_func): Use hex digits to display
+	for consistency.
+	
+2002-02-04  Jason Thomas  <jason@topic.com.ah>
+
+	From Denis Kitzman  <dkitzman@blue.weeg.uiowa.edu>:
+	* stage2/Makefile.am (libgrub_a_CFLAGS): Fixed a typo.
+	FSYS_XFS, USE_MD5_PASSWORDS, SUPPORT_SERIAL, and
+	SUPPORT_HERCULES did not get defined.
+
+2002-01-20  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* util/grub-image.in: Check stage2 instead of stage2.c to
+	determine where the script is invoked, because srcdir may not
+	be used for the compilation.
+	
+2002-01-20  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* grub/asmstub.c (console_putchar): When not using curses,
+	ignore a carriage return, because a newline in Unix is only a
+	line feed.
+	
+2002-01-18  Klaus Reichl  <Klaus.Reichl@alcatel.at>
+
+	* stage2/fsys_minix.c (minix_dir): Fixed bug getting filenames
+	with MAXNAMELEN right.
+
+	* stage2/char_io.c (get_cmdline, cl_refresh): If TERMINAL_DUMB
+	section is always 0.
+	Line is only cleared if !TERMINAL_DUMB.
+
+	* grub/main.c (use_curses): Initialize to 0 if !HAVE_LIBCURSES
+	(main): Check for curses use and set terminal to dumb if we
+	don't use it (helps for --batch and variants of non-curses
+	setup).
+
+2002-01-15  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* configure.in (AM_INIT_AUTOMAKE): The version number is
+	upgraded to 0.91.
+	
+2002-01-15  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* docs/grub.texi (Preset Menu): New chapter.
+	
+2002-01-15  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* docs/grub.texi: Added some text about JFS and XFS.
+	
+2002-01-08  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* grub/main.c (use_preset_menu): New variable.
+	(OPT_PRESET_MENU): New macro.
+	(longopts): Added an entry for "--preset-menu".
+	(usage): Added a description for "--preset-menu". Also, change
+	the first character of the description for "--device-map" to
+	lower case for consistency.
+	(main): Set USE_PRESET_MENU to 1 in the case of OPT_PRESET_MENU.
+	* stage2/shared.h (use_preset_menu): Declared.
+	* stage2/stage2.c [PRESET_MENU_STRING || SUPPORT_DISKLESS]
+	(open_preset_menu) [GRUB_UTIL]: If USE_PRESET_MENU is false,
+	return zero immediately.
+
+2002-01-08  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* stage2/common.c [SUPPORT_DISKLESS]
+	(setup_diskless_environment): Removed. The feature is moved to
+	the preset menu.
+	* stage2/stage2.c [SUPPORT_DISKLESS] (preset_menu): Set to the
+	string "bootp\n".
+	[SUPPORT_DISKLESS] (preset_menu_offset): Defined, as if
+	PRESET_MENU_STRING is defined.
+	[SUPPORT_DISKLESS] (open_preset_menu): Likewise.
+	[SUPPORT_DISKLESS] (read_from_preset_menu): Likewise.
+	[SUPPORT_DISKLESS] (close_preset_menu): Likewise.
+	
+2002-01-06  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	The preset menu has a priority over the configuration file.
+	Suggested by Christoph Plattner.
+	
+	* stage2/stage2.c [PRESET_MENU_STRING] (open_preset_menu):
+	Check if PRESET_MENU is not NULL.
+	[PRESET_MENU_STRING] (close_preset_menu): Set PRESET_MENU to
+	NULL.
+	(cmain): New internal function, reset. This function resets
+	AUTO_FILL, CONFIG_LEN, MENU_LEN, NUM_ENTRIES, CONFIG_ENTRIES,
+	MENU_ENTRIES and call init_config.
+	Try to open the preset menu first, and try to open the
+	configuration file, only if that failed.
+	Even if the preset menu was read, try to open the configuration
+	file. This time, opening the preset menu never succeed, because
+	close_preset_menu ensures that the preset menu is available at
+	most once.
+	
+2002-01-06  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* netboot/misc.c (inet_aton): Don't check if *P is an asterisk,
+	if I is 3. Reported by Rick (his real name and address are
+	unknown).
+	
+2002-01-03  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	Update the netboot stuff to Etherboot-5.0.5.
+	
+	* configure.in (--enable-3c590): Removed. This was a mistake.
+	(--enable-davicom): New option.
+	(--enable-eepro): Likewise.
+	(--enable-natsemi): Likewise.
+	(--enable-ni5010): Likewise.
+	(--enable-sis900): Likewise.
+	(--enable-w89c840): Likewise.
+	(--enable-3c509-hack): Removed.
+	(--enable-ns8390-force-16bit): Likewise.
+
+	* netboot/Makefile.am (libdrivers_a_SOURCES): Added timer.c and
+	timer.h.
+	(EXTRA_libdrivers_a_SOURCES): Added davicom.c, eepro.c, fa311.c,
+	natsemi.c, ni5010.c, sis900.c, sis900.h, tlan.c and w89c840.c.
+	(EXTRA_DIST): Added sis900.txt.
+	(3c595_drivers): Remove 3c590.o from this.
+	(davicom_drivers): New variable.
+	(eepro_drivers): Likewise.
+	(natsemi_drivers): Likewise.
+	(ni5010_drivers): Likewise.
+	(sis900_drivers): Likewise.
+	(w89c840_drivers): Likewise.
+	(3c590_o_CFLAGS): Removed.
+	(davicom_o_CFLAGS): New variable.
+	(eepro_o_CFLAGS): Likewise.
+	(natsemi_o_CFLAGS): Likewise.
+	(ni5010_o_CFLAGS): Likewise.
+	(sis900_o_CFLAGS): Likewise.
+	(w89c840_o_CFLAGS): Likewise.
+
+	* netboot/davicom.c: New file, from Etherboot-5.0.5.
+	* netboot/eepro.c: Likewise.
+	* netboot/natsemi.c: Likewise.
+	* netboot/ni5010.c: Likewise.
+	* netboot/sis900.c: Likewise.
+	* netboot/sis900.h: Likewise.
+	* netboot/sis900.txt: Likewise.
+	* netboot/timer.c: Likewise.
+	* netboot/timer.h: Likewise.
+	* netboot/w89c840.c: Likewise.
+	* netboot/fa311.c: Likewise.
+	* netboot/tlan.c: Likewise.
+	
+	* netboot/3c509.c: Copied from Etherboot-5.0.5.
+	* netboot/3c509.h: Likewise.
+	* netboot/3c595.c: Likewise.
+	* netboot/3c90x.c: Likewise.
+	* netboot/3c90x.txt: Likewise.
+	* netboot/cards.h: Likewise.
+	* netboot/cs89x0.c: Likewise.
+	* netboot/depca.c: Likewise.
+	* netboot/eepro100.c: Likewise.
+	* netboot/epic100.c: Likewise.
+	* netboot/i82586.c: Likewise.
+	* netboot/lance.c: Likewise.
+	* netboot/linux-asm-string.h: Likewise.
+	* netboot/nic.h: Likewise.
+	* netboot/ns8390.c: Likewise.
+	* netboot/ns8390.h: Likewise.
+	* netboot/otulip.c: Likewise.
+	* netboot/pci.h: Likewise.
+	* netboot/rtl8139.c: Likewise.
+	* netboot/sk_g16.c: Likewise.
+	* netboot/smc9000.c: Likewise.
+	* netboot/tiara.c: Likewise.
+	* netboot/tulip.c: Likewise.
+	* netboot/via-rhine.c: Likewise.
+	
+	* netboot/config.c: Applied a diff between Etherboot-4.6.4 and
+	Etherboot-5.0.5 manually.
+	* netboot/main.c: Likewise.
+	* netboot/pci.c: Likewise.
+	* netboot/etherboot.h: Rewritten mostly from scratch, based on
+	the same file in Etherboot-5.0.5.
+	* netboot/misc.c: Likewise.
+	* netboot/osdep.h: Likewise.
+	* netboot/fsys_tftp.c (GRUB): Defined.
+	(buf_fill): Use rfc2131_sleep_interval instead of rfc951_sleep.
+
+	* stage2/builtins.c [SUPPORT_NETBOOT] (GRUB): Defined.
+	(boot_func) [SUPPORT_NETBOOT]: Call cleanup_net.
+	* stage2/cmdline.c [SUPPORT_DISKLESS] (GRUB): Defined.
+	* stage2/common.c [SUPPORT_DISKLESS] (GRUB): Likewise.
+	
+2002-01-02  Jeremy Katz  <katzj@redhat.com>
+	
+	* util/grub-install.in: Support using mktemp as well as tempfile
+	for secure temporary file creation.
+
+2002-01-02  Jeremy Katz  <katzj@redhat.com>
+	
+	* stage2/md5.c (md5_password): Ensure the password exists before
+	trying to check against the md5 crypted version.
+
+2001-12-30  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* stage1/stage1.S: Don't call INT 13, AH=48H, because it is
+	difficult to call this function with the workaround implemented
+	in the previous change due to the size limit of Stage 1.
+	
+	(lba_mode) [NO_BUGGY_BIOS_IN_THE_WORLD]: Don't check the
+	geometry explicitly. This shouldn't be harmful, as INT 13,
+	AH=42H should take care of it, and if you cannot read Stage 2
+	even with LBA because of a geometry problem, you can never read
+	it.
+
+	* stage2/start.S (lba_mode) [NO_BUGGY_BIOS_IN_THE_WORLD]:
+	Likewise.
+	
+2001-12-30  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* stage2/bios.c (get_diskinfo): Clear out the structure DRP
+	before calling get_diskinfo_int13_extensions, because the Ralf
+	Brown's Interrupt List says that Dell machines using PhoenixBIOS
+	4.0 Release 6.0 fail, if DRP.FLAGS is not zero. Setting the
+	entire structure to zero may be overkill, but it should be safe.
+	
+	* stage2/char_io.c [STAGE1_5] (grub_memset): Defined.
+	
+2001-12-30  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	From John Goerzen <jgoerzen@complete.org>:
+	* util/grub-install.in (convert): Added NetBSD support.
+	
+2001-12-30  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* util/grub-install.in: Set GRUB_PREFIX and BOOTDIR to "/grub"
+	and "${rootdir}" respectively in NetBSD.
+	
+2001-12-30  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* stage2/builtins.c (builtin_geometry): Add extra space
+	characters into the long description.
+	(builtin_kernel): Likewise.
+	(builtin_vbeprobe): Likewise.
+	
+2001-12-19  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	From Michael Sullivan <mike@trdlnk.com>:
+	* stage1/stage1.S (real_start): Added a workaround for AST BIOS,
+	because it clobbers %dl with INT 13, AH=41H.
+
+2001-12-19  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* stage2/fsys_fat.c (fat_read): Fix the contradictory comment.
+	Reported by Filip Van Raemdonck <mechanix@digibel.org>.
+	
+2001-12-11  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* stage2/builtins.c (displayapm_func): Don't use multi-line
+	string literals but string concatenation instead, to suppress
+	warnings from gcc-3.0.x.
+	* stage2/cmdline.c (print_cmdline_message): Likewise.
+	* util/mbchk.c (usage): Likewise.
+	
+	* stage2/smp-imps.c (imps_read_config_table): Add a break
+	statement after the label ``default''.
+	
+	* util/mbchk.c: Include <stdlib.h> for the prototype of exit.
+
+	* stage2/serial.c (serial_port): Initialize with 0 instead of
+	-1, as an invalid value, because SERIAL_PORT is unsigned. This
+	change shouldn't affect anything.
+	(serial_exists): For the above change, check SERIAL_PORT with 0
+	instead of -1.
+	
+2001-12-10  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* stage2/shared.h (ERR_NO_DISK_SPACE): New constant.
+	* stage2/common.c (err_list): Added an entry for
+	ERR_NO_DISK_SPACE.
+	* docs/grub.texi (Stage2 errors): Added the description.
+	* stage2/builtins.c (embed_func): Use ERR_NO_DISK_SPACE instead
+	of ERR_DEV_VALUES when the spare space is too small. Suggested
+	by Eric Mumpower <nocturne@permabit.com>.
+	
+2001-12-10  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* grub/asmstub.c: Include <signal.h>.
+	(grub_stage2) [HAVE_LIBCURSES]: If USE_CURSES is true, ignore
+	the signal SIGWINCH. Reported by Christian Hudon
+	<chrish@debian.org>.
+
+2001-11-29  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	From Jason Thomas:
+	* stage2/disk_io.c (set_partition_hidden_flag): Complete rewrite
+	of this function which now supports logical partitions.
+	
+2001-11-12  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* docs/grub.texi: The copyright of this file is only held by
+	Free Software Foundation, Inc., as Erich Boleyn has assigned his
+	copyright to the FSF.
+	* stage1/stage1.S: Likewise.
+	* stage2/asm.S: Likewise.
+	* stage2/boot.c: Likewise.
+	* stage2/builtins.c: Likewise.
+	* stage2/char_io.c: Likewise.
+	* stage2/cmdline.c: Likewise.
+	* stage2/common.c: Likewise.
+	* stage2/disk_io.c: Likewise.
+	* stage2/fat.h: Likewise.
+	* stage2/filesys.h: Likewise.
+	* stage2/freebsd.h: Likewise.
+	* stage2/fsys_ext2fs.c: Likewise.
+	* stage2/fsys_fat.c: Likewise.
+	* stage2/fsys_ffs.c: Likewise.
+	* stage2/gunzip.c: Likewise.
+	* stage2/i386-elf.h: Likewise.
+	* stage2/mb_header.h: Likewise.
+	* stage2/mb_info.h: Likewise.
+	* stage2/pc_slice.h: Likewise.
+	* stage2/shared.h: Likewise.
+	* stage2/stage1_5.c: Likewise.
+	* stage2/stage2.c: Likewise.
+	* stage2/start.S: Likewise.
+	
+2001-11-07  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* stage2/builtins.c (terminal_func) [!SUPPORT_SERIAL]: Disable
+	the wait code, as it is usable only when serial support is on.
+	Reported by Karl Hammar <karl@kalle.csb.ki.se>.
+	
+2001-10-27  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	JFS and XFS support is added.
+	
+	From Serguei Tzukanov <tzukanov@narod.ru>:
+	* configure.in (--disable-jfs): New option.
+	(--disable-xfs): Likewise.
+	* stage2/Makefile.am (noinst_HEADERS): Added jfs.h and xfs.h.
+	(libgrub_a_SOURCES): Added fsys_jfs.c and fsys_xfs.c.
+	(libgrub_a_CFLAGS): Added -DFSYS_JFS=1 and -DFSYS_XFS=1.
+	(pkgdata_DATA): Added jfs_stage1_5 and xfs_stage1_5.
+	(noinst_PROGRAMS): Added jfs_stage1_5.exec and
+	xfs_stage1_5.exec.
+	(pre_stage2_exec_SOURCES): Added fsys_jfs.c and fsys_xfs.c.
+	(jfs_stage1_5_exec_SOURCES): New variable.
+	(jfs_stage1_5_exec_CFLAGS): Likewise.
+	(jfs_stage1_5_exec_ASFLAGS): Likewise.
+	(jfs_stage1_5_exec_LDFLAGS): Likewise.
+	(xfs_stage1_5_exec_SOURCES): Likewise.
+	(xfs_stage1_5_exec_CFLAGS): Likewise.
+	(xfs_stage1_5_exec_ASFLAGS): Likewise.
+	(xfs_stage1_5_exec_LDFLAGS): Likewise.
+	* stage2/builtins.c (setup_func): Add items for JFS and XFS into
+	STAGE1_5_MAP.
+	* stage2/disk_io.c (fsys_table): Added entries for JFS and XFS.
+	* stage2/filesys.h [FSYS_JFS] (FSYS_JFS_NUM): Set to 1.
+	[FSYS_JFS] (jfs_mount): Declared.
+	[FSYS_JFS] (jfs_read): Likewise.
+	[FSYS_JFS] (jfs_dir): Likewise.
+	[FSYS_JFS] (jfs_embed): Likewise.
+	[!FSYS_JFS] (FSYS_JFS_NUM): Set to 0.
+	[FSYS_XFS] (FSYS_XFS_NUM): Set to 1.
+	[FSYS_XFS] (xfs_mount): Declared.
+	[FSYS_XFS] (xfs_read): Likewise.
+	[FSYS_XFS] (xfs_dir): Likewise.
+	(NUM_FSYS): Added FSYS_JFS_NUM and FSYS_XFS_NUM.
+	* stage2/shared.h (STAGE2_ID_JFS_STAGE1_5): New macro.
+	(STAGE2_ID_XFS_STAGE1_5): Likewise.
+	[FSYS_JFS] (STAGE2_ID): Set to STAGE2_ID_JFS_STAGE1_5.
+	[FSYS_XFS] (STAGE2_ID): Set to STAGE2_ID_XFS_STAGE1_5.
+	* stage2/fsys_jfs.c: New file.
+	* stage2/fsys_xfs.c: Likewise.
+	* stage2/jfs.h: Likewise.
+	* stage2/xfs.h: Likewise.
+
+2001-10-27  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* stage2/apm.S: Always disconnect from APM. Written by Erich
+	Stefan Boleyn.
+
+	* util/Makefile.am (noinst_DATA): Removed.
+	(EXTRA_DIST): Likewise.
+	
+2001-10-14  Gordon Matzigkeit  <gord@fig.org>
+
+	* configure.in: Explicitly call _AM_DEPENDENCIES(CC) for the
+	benefit of older Autoconfs.
+
+2001-10-13  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	* netboot/fsys_tftp.c (tftp_read): Move the unused data
+	forwards, only if AMT is more than zero. If AMT is not positive,
+	subtract BUF_READ from SAVED_FILEPOS and set BUF_READ to zero,
+	to skip the whole buffer. Reported by Frank Mehnert.
+	
+2001-10-13  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	Don't use get_diskinfo_floppy. Reported by Ben Liblit
+	<liblit@eecs.berkeley.edu>.
+	
+	* stage2/asm.S (get_diskinfo_floppy): Removed (by cpp).
+	* stage2/bios.c (get_diskinfo_floppy): Removed.
+	(get_diskinfo): Don't call get_diskinfo_floppy any longer.
+	
+2001-10-13  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	Based on a patch from Jeremy Katz <katzj@redhat.com>:
+	* docs/grub.texi (Stage2 errors): Added documentation on the
+	error number 33 (Serial device not configured).
+	* grub/asmstub.c (serial_exists): New function.
+	* stage2/serial.c (serial_exists): Likewise.
+	* stage2/serial.h (serial_exists): New prototype.
+	* stage2/shared.h (grub_error_t): ERR_NEED_SERIAL is added.
+	* stage2/builtins.c (terminal_func) [SUPPORT_SERIAL]: If a
+	serial device is not configured yet, restore the terminal and
+	set ERRNUM to ERR_NEED_SERIAL.
+	* stage2/common.c (err_list): Added an item for ERR_NEED_SERIAL.
+	
+2001-10-13  Yoshinori K. Okuji  <okuji@gnu.org>
+
+	From Jason Thomas <jason@topic.com.au>:
+	* util/grub-install.in (convert): Add support for DAC960.
+
+	From Adrian Phillips <a.phillips@dnmi.no>:
+	* lib/device.c (get_dac960_disk_name): New function.
+	(init_device_map) [__linux__]: Add support for DAC960.
+	
+2001-10-11  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/fsys_reiserfs.c (reiserfs_super_block): Updated
+	to better match recent reiserfs versions.
+	(reiserfs_mount): Handle cases where journal can't be found,
+	e.g. journal on another disk or unexpected journal parameters.
+	In that case the journal isn't used.
+	
+2001-10-10  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/fsys_reiserfs.c (reiserfs_mount):  Don't look at
+	the superblock field s_journal_block_count anymore.  It used
+	to contain 0, it never contained a valid value, and now I
+	have a report that it can contain an invalid value.
+	Bug reported by Jim Caley <caley@chesco.com>.
+	
+2001-09-24  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/fsys_reiserfs.c (reiserfs_dir):  Set errnum to 
+	ERR_FSYS_CORRUPT if a symlink can't be read for some reason,
+	but no error is set by read.
+	
+2001-08-08  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Derrik Pates <dpates@dsdk12.net>:
+	* stage2/asm.S [!STAGE1_5] (grub_halt): Set the level of APM
+	support to 1.1, before turning off the power state.
+	
+2001-08-08  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* util/grub-md5-crypt.in: Prefix backquotes with backslashes in
+	strings.  From Fernando Silveira.
+	
+2001-08-02  Gordon Matzigkeit  <gord@fig.org>
+
+	* stage2/common.c (init_bios_info): Ignore zero-length memory
+	ranges.  From Derrik Pates <dpates@dsdk12.net>.
+
+2001-07-26  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/Makefile.am (libgrub_a_CFLAGS): Enable USE_MD5_PASSWORDS
+	for libgrub.  Previously that was implicitly done by configure.in
+	until the patch from 2001-07-04, which moved that flag from CFLAGS
+	to FSYS_CFLAGS.  Reported by YAMAGUCHI Shingo
+	<shingo@kip.iis.toyama-u.ac.jp>
+
+2001-07-13  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* util/grub-install.in (convert): Recognize the naming scheme
+	for Linux devfs floppy devices. Reported by Jason Thomas
+	<jason@topic.com.au>.
+	
+2001-07-07  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* netboot/compile: New file. This was also missing... How many
+	``compile''s does automake want?
+	
+2001-07-07  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Jan Zerebecki <jan.list@elite-pferde.de>:
+	* acinclude.m4 (grub_DEFINE_FILE): Escape double-quotations as
+	well.
+	
+2001-07-05  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* configure.in (AM_INIT_AUTOMAKE): Set the version number to
+	0.90.
+
+2001-07-05  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Ughh! I forgot to add this file to the CVS.
+
+	* docs/compile: New file.
+	
+2001-07-05  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/grub.texi: Updated.
+	
+2001-07-05  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/boot.c (load_initrd) [!NO_DECOMPRESSION]: Set
+	NO_DECOMPRESSION to one before opening INITRD, so that GRUB
+	doesn't decompress an initrd automatically. Reported by
+	Thierry Laronde.
+	
+2001-07-04  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/compile: New file.
+	* docs/mdate-sh: Likewise.
+	* docs/texinfo.tex: Likewise.
+	* compile: Removed.
+	* mdate-sh: Likewise.
+	* texinfo.tex: Likewise.
+	* config.guess: Updated from automake-1.4h.
+	* config.sub: Likewise.
+	* depcomp: Likewise.
+	* install-sh: Likewise.
+	* missing: Likewise.
+	* mkinstalldirs: Likewise.
+	* configure.in (AS): New variable.
+	(ASFLAGS): Likewise.
+	(--disable-md5-password): Use FSYS_CFLAGS instead of CFLAGS.
+	* stage1/Makefile.am (AM_CFLAGS): Renamed to ...
+	(AM_ASFLAGS): ... this.
+	* stage2/Makefile.am (pre_stage2_exec_ASFLAGS): New variable.
+	(start_exec_CFLAGS): Renamed to ...
+	(start_exec_ASFLAGS): ... this.
+	(start_exec-start.o): Renamed to ...
+	(start_exec-start.$(OBJEXT)): ... this.
+	(e2fs_stage1_5_exec_ASFLAGS): New variable.
+	(fat_stage1_5_exec_ASFLAGS): Likewise.
+	(ffs_stage1_5_exec_ASFLAGS): Likewise.
+	(minix_stage1_5_exec_ASFLAGS): Likewise.
+	(reiserfs_stage1_5_exec_ASFLAGS): Likewise.
+	(vstafs_stage1_5_exec_ASFLAGS): Likewise.
+	(diskless_exec_ASFLAGS): Likewise.
+	(nbloader_exec_CFLAGS): Renamed to ...
+	(nbloader_exec_ASFLAGS): ... this.
+	(nbloader_exec-nbloader.o): Renamed to ...
+	(nbloader_exec-nbloader.$(OBJEXT)): ... this.
+	(pxeloader_exec_CFLAGS): Renamed to ...
+	(pxeloader_exec_ASFLAGS): ... this.
+	(pxeloader_exec-pxeloader.$(OBJEXT)): New target.
+
+2001-07-03  OKUJI Yoshinori  <okuji@gnu.org>
+	
+	From Julien Bordet <julien.bordet@int-evry.fr>:
+	* stage2/i386-elf.h (Elf32_Shdr): New type.
+	* stage2/boot.c (load_image): Added ELF symbol loading support.
+	
+2001-06-22  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/char_io.c [STAGE1_5] (grub_strcmp): Defined, even
+	for Stage 1.5. See thecomment, for a possible future strategy.
+	* stage2/fsys_vstafs.c [!FSYS_VSTAFS]: Don't define anything.
+	[STAGE1_5] (grub_strcmp): Removed.
+	(get_file_info): Made static.
+	(vstafs_readdir): Likewise.
+	(vstafs_nextdir): Likewise.
+	(curr_ext): Likewise.
+	(current_direntry): Likewise.
+	(current_blockpos): Likewise.
+	(a): Likewise.
+	
+2001-06-22  OKUJI Yoshinori  <okuji@gnu.org>
+
+	VSTa filesystem support is added.
+	
+	From Kristoffer Brånemyr <ztion@swipnet.se>:
+	* stage2/configure.in (--disable-vstafs): New option.
+	* stage2/Makefile.am (noinst_HEADERS): Added vstafs.h.
+	(libgrub_a_SOURCES): Added fsys_vstafs.c.
+	(libgrub_a_CFLAGS): Added -DFSYS_VSTAFS=1.
+	(pkgdata_DATA): Added vstafs_stage1_5.
+	(noinst_PROGRAMS): Added vstafs_stage1_5.exec.
+	(pre_stage2_exec_SOURCES): Added fsys_vstafs.c.
+	(vstafs_stage1_5_exec_SOURCES): New variable.
+	(vstafs_stage1_5_exec_CFLAGS): Likewise.
+	(vstafs_stage1_5_exec_LDFLAGS): Likewise.
+	* stage2/disk_io.c (fsys_table): Added an entry for vstafs.
+	* stage2/filesys.h [FSYS_VSTAFS] (FSYS_VSTAFS_NUM): Defined as
+	1.
+	[FSYS_VSTAFS] (vstafs_mount): New prototype.
+	[FSYS_VSTAFS] (vstafs_read): Likewise.
+	[FSYS_VSTAFS] (vstafs_dir): Likewise.
+	[!FSYS_VSTAFS] (FSYS_VSTAFS_NUM): Defined as 0.
+	(NUM_FSYS): Added FSYS_VSTAFS_NUM.
+	* stage2/pc_slice.h (PC_SLICE_TYPE_VSTAFS): New macro.
+	* stage2/shared.h (STAGE2_ID_VSTAFS_STAGE1_5): Likewise.
+	[STAGE1_5 && FSYS_VSTAFS] (STAGE2_ID): Defined as
+	STAGE2_ID_VSTAFS_STAGE1_5.
+	* stage2/vstafs.h: New file.
+	* stage2/fsys_vstafs.c: Likewise.
+	
+2001-06-22  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Thierry Laronde <thierry@cri74.org>:
+	* stage2/builtins.c (configfile_func): Added a prototype.
+	(bootp_func): If `--with-configfile' is given, set
+	WITH_CONFIGFILE to one, and call configfile_func with
+	CONFIG_FILE.
+	
+2001-06-21  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/grub.texi: Update the location of the CVS repository
+	[/home/cvs -> /cvsroot/grub].
+	* README: Likewise.
+	
+2001-06-19  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/boot.c (load_image): If the image is a Multiboot ELF OS
+	image, get the physical entry address, when a loaded memory
+	segment contains it. And, set ENTRY_ADDR to it, after printing
+	out the virtual one. Suggested by Rogelio M. Serrano Jr.
+	<rogelio@victorio.com>.
+	
+2001-05-30  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/grub.texi: Fix some typos. Reported by Florian Hatat
+	<mininet@wanadoo.fr>.
+	
+2001-05-29  Pavel Roskin  <proski@gnu.org>
+
+	* configure.in (AC_OUTPUT): Remove debian/Makefile.
+
+2001-05-28  Gordon Matzigkeit  <gord@fig.org>
+
+	* Makefile.am (SUBDIRS): Remove reference to debian directory.
+	Packaging is no longer done by the GRUB team.
+
+2001-05-03  Gordon Matzigkeit  <gord@fig.org>
+
+	* stage1/stage1.S (nt_magic): Explicitly reserve space for the NT
+	magic number.
+
+2001-05-25  Klaus Reichl  <Klaus.Reichl@alcatel.at>
+
+	* stage2/stage2.c (print_entries_raw): New function.
+	(run_menu): Use it to implement menu & command-list if on dumb
+	terminals.  
+	Changes are:
+	  Adjust FIRST_ENTRY only on non-dumb terminals.
+	  Setting of SHOW_MENU is honoured also on dumb
+	    terminals. 
+	  Likely if SHOW_MENU is false, ESC brings her to the
+	    menu - not to the command-line as before.
+	  PRINT_BORDER, GOTOXY, SET_LINE_xxx are only called if
+	    not on dumb terminals.
+	  Show entry number when timeout is running if terminal is dumb.
+	  Prompt with entry number when waiting for keys.
+
+2001-05-14  Pavel Roskin  <proski@gnu.org>
+
+	* stage2/shared.h (ENTRY): Remove unnecessary `##'.
+
+2001-05-03  Jochen Hoenicke  <jochen@gnu.org>
+
+	* grub/asmstub.c (biosdisk): Work around a bug in linux's ez
+	remapping.  Problem reported by Ben Byer <bbyer@rice.edu>.
+	
+2001-03-28  Gordon Matzigkeit  <gord@fig.org>
+
+	* stage2/boot.c (load_image): Don't cast entry_addr to an int, or
+	the top bit will be interpreted as the sign.
+
+2001-03-16  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Bodo Rueskamp <br@itchigo.com>:
+	* stage2/boot.c (load_initrd): Avoid the last 64kb for
+	Linux 2.2.x bug.
+	
+2001-03-03  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/multiboot.texi (History): Written.
+	
+2001-02-28  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From HASEGAWA Tomoki <thasegawa@mta.biglobe.ne.jp>:
+	* lib/device.c (get_ide_disk_name) [__FreeBSD__]: Add support
+	for FreeBSD-4.0 or later. Use "/dev/rad0".
+	* util/grub-install.in (convert): Add code for FreeBSD
+	disklabels.
+
+2001-02-28  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Thierry Laronde <thierry@cri74.org>:
+	* stage2/stage2.c (cmain): If the default entry is wrong, set it
+	to FALLBACK_ENTRY if FALLBACK_ENTRY is valid, otherwise set it
+	to zero. Suggested by Nicolas Boos <nicolas.boos@wanadoo.fr>.
+	
+2001-02-28  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* acconfig.h (AUTO_LINUX_MEM_OPT): New entry.
+	* configure.in (--disable-auto-linux-mem-opt): New option.
+	* stage2/builtins.c (kernel_func) [!AUTO_LINUX_MEM_OPT]: Add
+	KERNEL_LOAD_NO_MEM_OPTION into LOAD_FLAGS, whether the user
+	specifies --no-mem-option or not.
+	
+2001-02-27  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (chainloader_func): Don't check if the
+	current partition is FAT, but check if it has a FAT partition
+	type and the BPB has a system id starting with "MSWIN".
+	
+2001-02-27  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Added hercules support based on a patch by Frank Mehnert
+	<fm3@os.inf.tu-dresden.de>. I translated his assembly code into
+	C, and separated hercules from the normal console.
+	
+	* configure.in (--disable-hercules): New option.
+	
+	* grub/asmstub.c: Include <hercules.h>.
+	(set_attrib): Renamed to ...
+	(console_set_attrib): ... this.
+	(herc_cls): New function.
+	(herc_getxy): Likewise.
+	(herc_gotoxy): Likewise.
+	(herc_putchar): Likewise.
+	(herc_set_attrib): Likewise.
+	
+	* stage2/Makefile.am (noinst_HEADERS): Added hercules.h.
+	(libgrub_a_CFLAGS): Added -DSUPPORT_HERCULES=1.
+	(HERCULES_FLAGS): New variable.
+	(STAGE2_COMPILE): Added $(HERCULES_FLAGS).
+	(pre_stage2_exec_SOURCES): Added hercules.c.
+	* stage2/asm.S [!STAGE1_5] (set_attrib) Renamed to ...
+	[!STAGE1_5] (console_set_attrib): ... this.
+	* stage2/builtins.c [SUPPORT_HERCULES] (terminal_func): Added
+	hercules support.
+	(builtin_table) [SUPPORT_HERCULES]: Added a pointer to
+	BUILTIN_TERMINAL.
+	* stage2/char_io.c [SUPPORT_HERCULES]: Include <hercules.h>.
+	[!STAGE1_5] (get_cmdline) [SUPPORT_HERCULES]: Added hercules
+	support.
+	[!STAGE1_5] (getkey) [SUPPORT_HERCULES]: Likewise.
+	[!STAGE1_5] (checkkey) [SUPPORT_HERCULES]: Likewise.
+	(grub_putchar) [SUPPORT_HERCULES]: Likewise.
+	[!STAGE1_5] (gotoxy) [SUPPORT_HERCULES]: Likewise.
+	[!STAGE1_5] (getxy) [SUPPORT_HERCULES]: Likewise.
+	[!STAGE1_5] (cls) [SUPPORT_HERCULES]: Likewise.
+	(set_attrib): New function.
+	* stage2/shared.h (console_set_attrib): Declared.
+	(TERMINAL_HERCULES): New macro.
+	* stage2/stage2.c (run_menu) [SUPPORT_HERCULES]: Added hercules
+	support.
+	* stage2/hercules.h: New file.
+	* stage2/hercules.c: Likewise.
+	
+2001-02-17  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From "Treutwein; Bernhard"
+	<Bernhard.Treutwein@Verwaltung.Uni-Muenchen.DE>:
+	* docs/grub.texi (DOS/Windows): Improved the readability.
+	
+2001-02-11  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/grub.texi (Command-line and menu commands): Renamed to ...
+	(General commands): ... this.
+	
+2001-02-08  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/asm.S [STAGE1_5] (chain_stage2): Save the second sector
+	of stage2 in %ecx temporarily, and set %ebp to %ecx after
+	switching to protected mode. I forgot that %ebp is broken by
+	rot_to_real. Reported by Torvald Riegel
+	<tr16@inf.tu-dresden.de>.
+	
+2001-02-08  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/grub-new.texi: Moved to ...
+	* docs/grub.texi: ... here. And, include internals.texi.
+	* docs/internals.texi: New file.
+	* docs/prog-ref.texi: Removed.
+	* docs/user-ref.texi: Likewise.
+	* docs/tutorial.texi: Likewise.
+	* docs/appendices.texi: Likewise.
+	* docs/Makefile.am (grub_TEXINFOS): Removed prog-ref.texi,
+	user-ref.texi, tutorial.texi, and appendices.texi. Added
+	internals.texi.
+	
+2001-02-03  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Erik Schoenfelder <schoenfr@gaertner.de>:
+	* stage2/shared.h (LINUX_INITRD_MAX_ADDRESS): Changed from
+	0x3C000000 to 0x38000000.
+	
+2001-02-03  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (savedefault_func)
+	[!SUPPORT_DISKLESS && !GRUB_UTIL]: Check if the version
+	contained in the buffer matches to current one as well.
+	
+2001-02-02  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (savedefault_func)
+	[!SUPPORT_DISKLESS && !GRUB_UTIL]: Check if the stage2 id is
+	STAGE2_ID_STAGE2. Suggested by Jochen Hoenicke.
+	
+	* stage2/stage2.c (cmain): If DEFAULT_ENTRY is out of entries,
+	reset DEFAULT_ENTRY to zero.
+	
+2001-02-02  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Make savedefault workable even with Stage 1.5. Reported by
+	Thierry Laronde <thierry@cri74.org>.
+	
+	* grub/asmstub.c (chain_stage2): Added an additional argument,
+	SECOND_SECTOR.
+	* stage2/asm.S [STAGE1_5] (chain_stage2): Set %ebp to
+	SECOND_SECTOR.
+	* stage2/disk_io.c [STAGE1_5] (disk_read_hook): Defined.
+	[STAGE1_5] (disk_read_func): Likewise.
+	(rawread) [STAGE1_5]: Handle DISK_READ_FUNC.
+	(grub_read) [STAGE1_5]: Likewise.
+	* stage2/fsys_ext2fs.c (ext2fs_read) [STAGE1_5]: Likewise.
+	* stage2/fsys_fat.c (fat_read) [STAGE1_5]: Likewise.
+	* stage2/fsys_ffs.c (ffs_read) [STAGE1_5]: Likewise.
+	* stage2/fsys_minix.c (minix_read) [STAGE1_5]: Likewise.
+	* stage2/fsys_reiserfs.c (reiserfs_read) [STAGE1_5]: Likewise.
+	
+2001-02-02  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* netboot/config.c [GRUB && INCLUDE_PCI] (pci_dispatch_table):
+	New structure.
+	[GRUB && INCLUDE_PCI] (PCI_NIC): New variable.
+	(eth_probe) [GRUB && INCLUDE_PCI]: If a PCI NIC candidate is
+	present, probe it first.
+	
+2001-01-27  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Danilo Godec <danci@agenda.si>:
+	* stage2/pc_slice.h (PC_SLICE_TYPE_LINUX_RAID): New macro.
+	* stage2/fsys_ext2fs.c (ext2fs_mount): Add a check for
+	PC_SLICE_LINUX_RAID.
+	
+2001-01-27  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Bernhard Treutwein
+	<Bernhard.Treutwein@Verwaltung.Uni-Muenchen.DE>:
+	* docs/grub-new.texi (DOS/Windows): Made more readable.
+	
+2001-01-27  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/multiboot.texi: Start reorganizing Multiboot
+	Specification.
+	
+2001-01-15  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Thierry Laronde <thierry.laronde@polynum.com>:
+	* docs/user-ref.texi (Command-line and menu commands): Update
+	the description about setkey.
+	* stage2/builtins.c (setkey_func): When checking if TO_KEY and
+	FROM_KEY are specified, see *TO_KEY and *FROM_KEY instead of
+	TO_KEY and FROM_KEY, respectively.
+	
+2001-01-13  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Thierry Laronde <thierry.laronde@polynum.com>:
+	* util/grub-md5-crypt.in (prefix): New variable.
+	(exec_prefix): Likewise.
+	(sbindir): Likewise.
+	
+2001-01-12  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/multiboot.h [__ELF__] (MULTIBOOT_HEADER_FLAGS): Defined
+	as 0x00000003 instead of 0x00010003.
+	* docs/boot.S (multiboot_header) [__ELF__]: Don't define a.out
+	kludge information.
+	
+	* docs/Makefile.am (EXTRA_PROGRAMS): New variable.
+	[BUILD_EXAMPLE_KERNEL] (noinst_DATA): Removed.
+	[BUILD_EXAMPLE_KERNEL] (noinst_PROGRAMS): Changed to kernel.
+	[BUILD_EXAMPLE_KERNEL] (kernel_exec_SOURCES): Renamed to ...
+	[BUILD_EXAMPLE_KERNEL] (kernel_SOURCES): ... this.
+	[BUILD_EXAMPLE_KERNEL] (kernel_exec_CFLAGS): Renamed to ...
+	[BUILD_EXAMPLE_KERNEL] (kernel_CFLAGS): ... this.
+	[BUILD_EXAMPLE_KERNEL] (kernel_exec_LDFLAGS): Renamed to ...
+	[BUILD_EXAMPLE_KERNEL] (kernel_LDFLAGS): ... this.
+	[BUILD_EXAMPLE_KERNEL] (kernel): Removed.
+	[BUILD_EXAMPLE_KERNEL] (boot.o): New dependency.
+	(CLEANFILES): New variable.
+	
+2001-01-11  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c [SUPPORT_NETBOOT] (ifconfig_func): Always
+	print current network configuration.
+	[SUPPORT_NETBOOT] (tftpserver_func): Use ifconfig instead of
+	arp_server_override.
+	* netboot/main.c (arp_server_override): Removed.
+	* netboot/etherboot.h (arp_server_override): Likewise.
+
+2001-01-11  Eugene Doudine  <dudin@np.nk.nornik.ru>
+	
+	* stage2/builtins.c [SUPPORT_NETBOOT] (ifconfig_func): New
+	function to configure network interface from command line.
+	[SUPPORT_NETBOOT] (builtin_ifconfig): New variable.
+	[SUPPORT_NETBOOT] (builtin_table): Added a pointer to
+	BUILTIN_IFCONFIG.
+	* netboot/main.c (ifconfig): New function.
+	* netboot/etherboot.h (ifconfig): Added the prototype.
+	
+2001-01-11  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/Makefile.am [BUILD_EXAMPLE_KERNEL] (noinst_DATA): New
+	variable.
+	[BUILD_EXAMPLE_KERNEL] (noinst_PROGRAMS): Likewise.
+	[BUILD_EXAMPLE_KERNEL] (kernel_exec_SOURCES): Likewise.
+	[BUILD_EXAMPLE_KERNEL] (kernel_exec_CFLAGS): Likewise.
+	[BUILD_EXAMPLE_KERNEL] (kernel_exec_LDFLAGS): Likewise.
+	[BUILD_EXAMPLE_KERNEL] (kernel): New target.
+	* configure.in (--enable-example-kernel): New option.
+
+	* docs/kernel.c (cmain): Cast unsigned long variables to
+	unsigned explicitly, to suppress GCC warnings.
+	
+2001-01-08  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/shared.h (BOOTSEC_BPB_HIDDEN_SECTORS): New macro.
+	
+	* stage2/builtins.c (chainloader_func): If CURRENT_PARTITION is
+	FAT, set the hidden sectors field of the BPB to PART_START, to
+	avoid a Windows bug which affects only when Windows is booted
+	from a logical partition. And, clear ERRNUM after testing if a
+	partition is FAT, because open_partition or fat_mount may set
+	ERRNUM. Reported by Ingo Korb <ingo@akana.de>.
+	
+2001-01-07  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (boot_func): In the chain-loading mode,
+	clear the active flag of each of the loaded partition entries,
+	and then set the active flag of the booted partition image.
+	
+2001-01-04  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/builtins.c (embed_func): Call open_partition() even for
+ 	MBR, so that part_start is correct.  This fixes a bug reported by
+ 	Matthias Granberry <matthias@slurpee.org>.
+	
+2000-12-22  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/disk_io.c (make_saved_active): Change the variable name
+	``MBR'' to lower case.
+	(set_partition_hidden_flag): Likewise.
+	
+2000-12-20  Jochen Hoenicke  <jochen@gnu.org>
+
+	From Cedric Ware <ware@com.enst.fr>:
+	* stage2/fsys_ext2.c (ext2fs_mount): Detect ext2 partitions in
+	a OpenBSD/NetBSD FS_EXT2FS slice.
+	* stage2/pc_slice.h (FS_ADOS): New Macro from OpenBSD/NetBSD.
+	(FS_HFS): Likewise.
+	(FS_FILECORE): Likewise.
+	(FS_EXT2FS): Likewise.
+	
+2000-12-17  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/disk_io.c (rawread): Check if there is a EZD partition
+	and remap sector 0 to sector 1 like EZ-BIOS does.
+	(rawwrite): New function to write to disk.  Also does EZD
+	remapping.
+	(devwrite): New function.  Does the special remapping to
+	partitions needed for linux.  This contains the code that was
+	previously duplicated in embed_func and install_func at several
+	places.
+	(make_saved_active): Use rawwrite. Don't use SCRATCHSEG, as it is
+	needed by devwrite.
+	(set_partition_hidden_flag): Likewise.	
+	* stage2/disk_io.h (rawwrite): New function.
+	(devwrite): Likewise.
+	* stage2/pc_slice.h (PC_SLICE_TYPE_EZD): New macro.
+	* stage2/builtins.c (embed_info): New variable to store the
+	position of the embedded stage1_5 for setup_func.
+	(embed_func): Don't embed after the MBR if an EZ-BIOS is detected
+	there.  Use the new devwrite method.  If embedding is successful
+	store position in embed_info.
+	(install_func): Use devwrite.  Don't use SCRATCHSEG.
+	(partnew_func): Use rawwrite.  Don't use SCRATCHSEG.
+	(parttype_func): Likewise.
+	(savedefault_func): Likewise.
+	(setup_func): New nested function embed_stage1_5.  Stage1_5 is now
+	also be embedded into filesystems which supports that.
+	
+2000-12-17  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (chainloader_func): Set ERRNUM to
+	ERR_EXEC_FORMAT, when ERRNUM is ERR_NONE, even if grub_read
+	fails in reading one sector.
+	
+2000-12-14  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/prog-ref.texi (Partition types): Rewrite the footnotes.
+	Suggested by Ralf.Medow@t-online.de (Ralf Medow).
+	
+2000-12-14  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Erik Schoenfelder <schoenfr@gaertner.de>:
+	* util/grub-install.in (convert): Revised the fix for floppy
+	device handling.
+	
+2000-12-14  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From HORIKAWA Kazunori <kaz-hori@tkd.att.ne.jp>:
+	* stage2/bios.c (get_diskinfo): Append 16 bytes dummy data to
+	DRP, because the BIOS of Thinkpad X20 write a garbage beyond the
+	size of the structure.
+	
+2000-12-09  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/disk_io.c (next_partition): Mask out bsd partition sub
+	type when checking if last partition was a bsd partition.
+	Reported by Heikki Vatiainen <hessu@cs.tut.fi>.
+	
+2000-12-09  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Leendert Meyer <leen.meyer@home.nl>:
+	* util/grub-install.in (convert): If a floppy device is
+	specified, remove everything from $tmp_part.
+	
+2000-12-09  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* lib/device.c [__linux__] (write_to_partition): Use strcpy
+	instead of strcat, to overwrite "/disc". Reported by Thiago
+	Macieira <thiagom@mail.com>.
+	
+2000-12-05  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/fsys_minix.c (minix_mount): Corrected the check for
+	IS_PC_SLICE_TYPE_MINIX; minix was only working if slice type was
+	wrong! Reported by Ralf Medow <ralf.medow@t-online.de>.
+	
+2000-11-27  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/fsys_reiserfs.c: Handle items with old version key on
+	new version reiserfs partition.
+	(K_OFFSET): Removed.
+	(IH_KEY_OFFSET): New Macro, which checks item head version.
+	(IH_KEY_ISOFFSET): Likewise.
+	(reiserfs_read): Use new macros.
+	(reiserfs_dir): Fixed version check for >4GB stat entries.
+	
+2000-11-27  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/common.c (init_bios_info) [!STAGE1_5]: Don't call
+	track_int13, because the current implementation hangs up in some
+	environments.
+	
+2000-11-27  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* grub/asmstub.c (serial_init) [!O_SYNC]: Don't specify O_SYNC
+	to open SERIAL_DEVICE.
+	(serial_init) [O_FSYNC]: Specify O_FSYNC to open SERIAL_DEVICE.
+	Reported by Farid Hajji <farid.hajji@ob.kamp.net>.
+	
+2000-11-22  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Vesa Jaaskelainen <jaaskela@tietomyrsky.fi>:
+	* stage2/builtins.c (testvbe_func): Don't set the bit 14 of a
+	VBE mode number explicitly when calling get_vbe_mode_info.
+	(vbeprobe_func): Likewise.
+	
+2000-11-22  OKUJI Yoshinori  <okuji@gnu.org>
+
+	The code for the "INT 13H tracking technique" is somewhat
+	simplified.
+
+	* stage2/asm.S [!STAGE1_5] (track_int13): Don't replace an int13
+	handler with set_tf_int13_handler. Instead, track_int13 itself
+	emulates an int13 interrupt.
+	[!STAGE1_5] (set_tf_int13_handler): Removed.
+	[!STAGE1_5] (int1_handler): Use movzbw instead of xorb and movb.
+	
+2000-11-15  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* acconfig.h (PRESET_MENU_STRING): New entry.
+	* acinclude.m4 (grub_DEFINE_FILE): New M4 macro.
+	* configure.in (--enable-preset-menu): New option.
+	* stage2/stage2.c [PRESET_MENU_STRING] (preset_menu): New
+	variable.
+	[PRESET_MENU_STRING] (preset_menu_offset): Likewise.
+	[PRESET_MENU_STRING] (open_preset_menu): New function.
+	[PRESET_MENU_STRING] (read_from_preset_menu): Likewise.
+	[PRESET_MENU_STRING] (close_preset_menu): Likewise.
+	[!PRESET_MENU_STRING] (open_preset_menu): New macro.
+	[!PRESET_MENU_STRING] (read_from_preset_menu): Likewise.
+	[!PRESET_MENU_STRING] (close_preset_menu): Likewise.
+	(get_line_from_config): Accept a new argument READ_FROM_FILE.
+	If it is false, read data from the preset menu instead.
+	(cmain): If grub_open fails in opening the configuration file,
+	then try to open the preset menu.
+	
+2000-11-11  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Jan Fricke <fricke@uni-greifswald.de>:
+	* stage2/asm.S [!STAGE1_5] (set_vbe_mode): Add a missing `$'
+	prefix.
+	
+2000-11-11  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/bios.c (get_diskinfo): If BIOS supports LBA but doesn't
+	return the correct total number of sectors, compute this by
+	C/H/S returned by get_diskinfo_int13_extensions instead of
+	get_diskinfo_standard.
+	
+2000-11-09  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/disk_io.c (make_saved_active): Set ERRNUM to
+	ERR_DEV_VALUES instead of ERR_NO_PART, when the save partition
+	is not a primary partition.
+	
+2000-11-05  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/user-ref.texi (Features): Update the URL of grub/98.
+	
+2000-11-03  OKUJI Yoshinori  <okuji@gnu.org>
+
+	VBE support is _partially_ implemented.
+	
+	* stage2/mb_header.h (multiboot_header): Added new fields,
+	mode_type, width, height, and depth.
+	(MULTIBOOT_FOUND): Check if MULTIBOOT_VIDEO_MODE is set, and
+	check if LEN is greater than or equal to 48, if set.
+	(MULTIBOOT_UNSUPPORTED): Set to 0x0000FFF8.
+	(MULTIBOOT_VIDEO_MODE): New macro.
+	* stage2/mb_info.h (multiboot_info): Added new fields,
+	vbe_control_info, vbe_mode_info, vbe_mode, vbe_interface_seg,
+	vbe_interface_off, and vbe_interface_len.
+	(MB_INFO_VIDEO_INFO): New macro.
+	
+	* stage2/shared.h (vbe_controller): New structure.
+	(vbe_mode): Likewise.
+	(get_vbe_controller_info): Declared.
+	(get_vbe_mode_info): Likewise.
+	(set_vbe_mode): Likewise.
+	* stage2/asm.S [!STAGE1_5] (get_vbe_controller_info): New
+	function.
+	[!STAGE1_5] (get_vbe_mode_info): Likewise.
+	[!STAGE1_5] (set_vbe_mode): Likewise.
+	* grub/asmstub.c (get_vbe_controller_info): Likewise.
+	(get_vbe_mode_info): Likewise.
+	(set_vbe_mode): Likewise.
+
+	* stage2/builtins.c (testvbe_func): New function.
+	(builtin_testvbe): New variable.
+	(vbeprobe_func): New function.
+	(builtin_vbeprobe): New variable.
+	(builtin_table): Added pointers to BUILTIN_TESTVBE and
+	BUILTIN_VBEPROBE.
+	
+2000-11-01  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/help2man: Copied from help2man-1.23.
+	
+2000-10-29  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/asm.S [STAGE1_5]: Don't include setjmp.S or apm.S.
+	
+2000-10-27  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* lib/device.c (read_device_map): Don't parse a line, if it is
+	empty. Reported by Holger Bauer <bauer@itsm.uni-stuttgart.de>.
+	
+2000-10-25  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/builtins.c (md5crypt_func): Use all bits of currticks ()
+	to generate the salt.  The old code would often produce the same
+	one character salt.
+
+2000-10-25  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/apm.S (get_apm_info): Fix a serious typo: prot_to_real
+	-> real_to_prot. Umm, I can't understand why it worked for me!
+	
+2000-10-24  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/builtins.c (setup_func): When invoking install with an
+ 	embedded stage1_5 give the path to menu.lst as real_config_file.
+
+2000-10-23  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/multiboot.texi: Upgraded to 0.6.92.
+	(Boot information format): Re-designed the graphics table.
+	
+2000-10-22  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/tutorial.texi: Miscellaneous updates.
+	* docs/user-ref.texi: Likewise.
+	* docs/appendices.texi: Likewise.
+	
+2000-10-22  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* util/grub-install.in (usage): Removed unnecessary commas.
+	
+	* util/grub-md5-crypt.in: New file.
+	* util/Makefile.am (sbin_SCRIPTS): Added grub-md5-crypt.
+	* configure.in (AC_OUTPUT): Added util/grub-md5-crypt.
+	* docs/Makefile.am (man_MANS): Added grub-md5-crypt.8.
+	[MAINTAINER_MODE] ($(srcdir)/grub-md5-crypt.8): New target.
+	* docs/grub-md5-crypt.8: New file. Generated by help2man.
+
+	* docs/grub.texi (grub-md5-crypt): New direntry.
+	(Invoking grub-md5-crypt): New entry.
+	* docs/user-ref.texi (Invoking grub-md5-crypt): New chapter.
+	
+2000-10-22  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Matthias Granberry <matthias@slurpee.org>:
+	* util/grub-install.in (convert): Added backslashes into
+	continuous lines.
+	
+2000-10-21  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/md5.c (check_md5_password): Removed.
+	(md5_password): New function. Mostly copied from
+	check_md5_password.
+	(md5_init): Made static.
+	(md5_update): Likewise.
+	(md5_final): Likewise.
+	* stage2/md5.h (check_md5_password): Changed to just a macro.
+	(md5_password): Declared.
+	(make_md5_password): New macro.
+	* stage2/char_io.c [!STAGE1_5] (grub_strstr): Rewriten, because
+	it was too buggy.
+	* stage2/builtins.c [USE_MD5_PASSWORDS] (md5crypt_func): New
+	function.
+	[USE_MD5_PASSWORDS] (builtin_md5crypt): New variable.
+	(builtin_table) [USE_MD5_PASSWORDS]: Added a pointer to
+	BUILTIN_MD5CRYPT.
+	* docs/tutorial.texi (Security): Added a paragraph about
+	md5crypt.
+	
+2000-10-21  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/user-ref.texi: Fixed several typos and some inappropriate
+	texinfo commands, and update the descriptions about some
+	commands.
+	
+2000-10-20  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (displayapm_func): New function.
+	(builtin_displayapm): New variable.
+	(builtin_table): Added a pointer to BUILTIN_DISPLAYAPM.
+	
+2000-10-20  OKUJI Yoshinori  <okuji@gnu.org>
+
+	APM BIOS table support is added, based on a patch by Matt Yourst
+	<yourst@mit.edu>.
+	
+	* docs/multiboot.texi (Boot information format): Added the
+	definition of APM table format.
+	
+	* stage2/mb_info.h (apm_info): New structure.
+	(multiboot_info): Added a new element, apm_table.
+	(MB_INFO_APM_TABLE): New macro.
+	* stage2/asm.S (apm_bios_info): New variable.
+	Include "apm.S".
+	* stage2/apm.S: New file.
+	* stage2/common.c (init_bios_info) [!STAGE1_5]: Added APM BIOS
+	table support.
+	* stage2/shared.h (apm_bios_info): Declared.
+	(get_apm_info): Likewise.
+	* stage2/Makefile.am (EXTRA_DIST): Added apm.S.
+	* grub/asmstub.c (apm_bios_info): New variable.
+	(get_apm_info): New function.
+	
+2000-10-19  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Segregate functions which are copyrighted differently.
+	
+	* stage2/setjmp.S: New file.
+	* stage2/Makefile.am (EXTRA_DIST): Added setjmp.S.
+	* stage2/asm.S: Include "setjmp.S".
+	(grub_setjmp): Moved to ...
+	* stage2/setjmp.S (grub_setjmp): ... here.
+	* stage2/asm.S (grub_longjmp): Moved to ...
+	* stage2/setjmp.S (grub_longjmp): ... here.
+	
+2000-10-18  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/Makefile.am (noinst_HEADERS): Added md5.h. Reported by
+	Volker Augustin <Volker.Augustin@stud.uni-regensburg.de>.
+	
+2000-10-17  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* configure.in (--disable-md5password): Renamed to ...
+	(--disable-md5-password): ... this. Just for my preference.
+	
+2000-10-17  Jochen Hoenicke  <jochen@gnu.org>
+
+	Added MD5 passwords and extended password command:
+	
+	* configure.in (--disable-md5password): New option.
+	* stage2/Makefile.am (libgrub_a_SOURCES): Added md5.c.
+	(pre_stage2_exec_SOURCES): Likewise.
+	* stage2/md5.c: New file.
+	* stage2/shared.h (password_t): New type.
+	(password_type): New variable.
+	(BUILTIN_HIDDEN): New flag, describing that a command should not
+	be printed when booting the entry.
+	(check_password): New function.
+	* stage2/cmdline.c (run_script): Don't show commands that have
+	the hidden attribute.
+	* stage2/builtins.c (password_type): New variable.
+	(check_password): New function.
+	(password_func): Handle the --md5 option and set password_type.
+	Check if in CMDLINE or SCRIPT mode and ask password immediately.
+	(builtin_password): Also allow passwords in CMDLINE mode, make
+	it hidden, so the user wont see the password he should enter.
+	Changed command description.
+	(builtin_pause): Make the command hidden.
+	(pause_func): Print argument, since the command is now hidden.
+	* stage2/stage2.c (run_menu): Call check_password to check password.
+	* docs/tutorial.texi (Security): Describe the new features of the
+	password commands.
+	* docs/user-ref.texi (Menu-specific commands): password command
+ 	moved ...
+	(Command-line and menu commands): ... to here.  New features 
+	doumented.
+	
+2000-10-17  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (setkey_func): Clear the all elements of
+	BIOS_KEY_MAP and ASCII_KEY_MAP instead of only the first
+	elements, when TO_KEY is NULL.
+	
+2000-10-16  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/boot.c (load_image): When handling Linux cmdline, don't
+	copy a null character from SRC to DEST, because this inserted an
+	extra null character into the cmdline. Reported by Robert
+	Bihlmeyer <robbe@orcus.priv.at>.
+	
+2000-10-16  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Some of the new Multiboot features are supported. APM support
+	and VESA support are not strictly defined or implemented yet.
+	
+	* docs/multiboot.texi (Top): Increase the version number.
+	(Boot information format): Changed the drive information format,
+	because it was not straightforward.
+	
+	* grub/asmstub.c (io_map): New variable.
+	(track_int13): New function.
+	(get_rom_config_table): Likewise.
+	* stage2/stage2.c (cmain): Set CONFIG_ENTRIES to MBI.DRIVES_ADDR
+	+ MBI.DRIVES.LENGTH instead of MBI.MMAP_ADDR + MBI.MMAP_LENGTH.
+	* stage2/common.c (init_bios_info) [!STAGE1_5]: Added support
+	for drive info, ROM config table, and boot loader name features
+	of the Multiboot Specification.
+	* stage2/mb_info.h (drive_info): New structure.
+	(MB_DI_CHS_MODE): New macro.
+	(MB_DI_LBA_MODE): Likewise.
+	(multiboot_info): Added drives_length, drives_addr,
+	config_table, and boot_loader_name.
+	(MB_INFO_DRIVE_INFO): New macro.
+	(MB_INFO_CONFIG_TABLE): Likewise.
+	(MB_INFO_BOOT_LOADER_NAME): Likewise.
+	* stage2/asm.S (get_rom_config_table): New function.
+	* stage2/shared.h (get_rom_config_table): Declared.
+	
+2000-10-16  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* util/grub-install.in (convert): Check only if the file exists,
+	instead of checking if the file is a block device as well.
+	Because, in a sane operating system, it should be a char device
+	but not a block device (unlike Linux), and it may be a symbolic
+	link (this can happen if you use Linux's devfs without devfsd).
+	(recheck): New variable. Set to "no" by default, and set to
+	"yes", if you specify the new option ``--recheck''. If $recheck
+	is "yes", remove the device map file, if present.
+	
+2000-10-16  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Roderich Schupp:
+	* lib/device.c: Include <limits.h>.
+	[__linux__] (have_devfs): New function.
+	(get_floppy_disk_name) [__linux__]: If devfs is supported, use
+	the name "/dev/floppy/N" instead.
+	(init_device_map) [__linux__]: If devfs is supported, use
+	"/dev/discs/discN" instead.
+	[__linux__] (write_to_partition): Change the size of DEV to
+	PATH_MAX instead of 64.
+	If devfs is supported, replace "/disc" in the device name with
+	"/part".
+	
+2000-10-15  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Roderich Schupp <rsch@ExperTeam.de>:
+	* util/grub-install.in (convert): Added support for "native"
+	devfs device names.
+	
+2000-10-14  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/tutorial.texi (Serial terminal): Fixed a typo.
+	* docs/user-ref.texi (GRUB images): New chapter.
+	* docs/grub.texi: Added an entry for the chapter "GRUB images".
+	
+2000-10-14  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (setkey_func): If TO_KEY is NULL (i.e. the
+	user specifies no argument), clear BIOS_KEY_MAP and
+	ASCII_KEY_MAP.
+	If TO_KEY is non-NULL but FROM_KEY is NULL, set ERRNUM to
+	ERR_BAD_ARGUMENT and return one.
+	
+2000-10-13  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/grub.texi: Added an entry for the new chapter "Security",
+	and the order of the chapters in the Tutorial Manual was
+	changed.
+	* docs/tutorial.texi (Configuration): Moved to right after the
+	chapter "Booting".
+	(Security): New chapter.
+	
+2000-10-10  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Alessandro Rubini:
+	* util/grub-install.in (root_device): Use the regular expression
+	's%.*\(/dev/[^ 	]*\).*%\1%' instead of
+	's%.*\(/dev/[a-z0-9]*\).*%\1%'.
+	(bootdir_device): Likewise.
+	(grubdir_device): Likewise.
+	
+2000-10-10  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/start.S (copy_buffer): Use pusha and popa instead of
+	pushing and poping %di and %si individually, to reduce the code
+	size and save %cx as well. Reported by Herbert Nachtnebel
+	<nachtneb@iaee.tuwien.ac.at>.
+	
+2000-10-10  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Daniel Pittman <daniel@rimspace.net>:
+	* stage2/builtins.c (setkey_func): Check if
+	KEYSYM_TABLE[I].UNSHIFTED_NAME and KEYSYM_TABLE[I].SHIFTED_NAME
+	are not NULLs, before calling grub_strcmp.
+	
+2000-10-08  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* util/grub-install.in (grub_prefix): New variable. The default
+	is "/boot/grub".
+	If the user has a separate boot partition, set grub_prefix
+	instead of grubdir to "/grub".
+	When running the command "setup", specify $grub_prefix instead
+	of $grubdir to the option "--prefix".
+	Report by Thierry Laronde.
+	
+2000-10-08  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (find_func): Clear ERRNUM after the last
+	call of next_partition, because it always sets ERRNUM. Reported
+	by Thierry Laronde <thierry.laronde@polynum.com>.
+	
+2000-10-07  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* lib/device.c [__linux__] (write_to_partition): Open DEV with
+	O_RDWR instead of O_ORONLY.
+	
+2000-10-06  Alessandro Rubini  <rubini@gnu.org>
+
+	* docs/user-ref.texi (Commands): Added missing commands and
+	reworded part of the text.
+
+	* stage2/builtins.c (serial_func): Unswap the setting of "speed"
+	and "port".
+
+2000-10-06  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (setup_func): Append "... " to the
+	messages when calling embed_func and install_func, and print
+	the result.
+	Don't jump to the label "fail", even when embed_func failed.
+	
+2000-10-05  Gordon Matzigkeit  <gord@fig.org>
+
+	* stage2/disk_io.c (real_open_partition): Make sure that buf_geom
+	corresponds to the current drive before using it.
+
+	* lib/device.c (get_drive_geometry): Use fstat if the native
+	geometry methods fail, such as when the drive is mapped to a
+	regular file.
+
+	* docs/tutorial.texi: Add `@kbd{...}' to examples in order to
+	differentiate between command output and characters the user
+	should type.
+	* docs/user-ref.texi: Likewise.
+
+2000-10-05  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/grub.texi: Added an entry for the chapter "Serial
+	terminal".
+	* docs/tutorial.texi (Serial terminal): New chapter.
+	
+2000-10-04  Gordon Matzigkeit  <gord@fig.org>
+
+	* util/grub-image (VERSION): Fix version calculation to tolerate
+	`(GNU GRUB 0.5.96)'-style versions.
+
+	* docs/grub.texi: Remove braces from `@unnumbered' sections so
+	that texi2html doesn't complain.
+
+	* debian/rules: Build HTML documentation to appease the Debian
+	masses.
+
+2000-10-04  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/fsys_reiserfs.c (reiserfs_mount): Compare PART_LENGTH
+	with SUPERBLOCK + (sizeof(super) >> SECTOR_BITS) instead of
+	sizeof(struct reiserfs_super_block). Reported by Jochen
+	Hoenicke.
+	
+2000-10-05  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* configure.in (AM_INIT_AUTOMAKE): The version number is set to
+	0.5.97. This version number is a dummy, as we will never release
+	0.5.97 actually.
+	
+2000-10-01  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* lib/device.c [__linux__]: Don't include <linux/cdrom.h>.
+	[__linux__ && !CDROM_GET_CAPABILITY] (CDROM_GET_CAPABILITY):
+	Defined as 0x5331.
+	
+2000-10-01  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* lib/device.c (get_drive_geometry) [__GNU__]: Get the number of
+	total sectors by fstat. The rest are filled with arbitrary
+	values.
+	
+2000-09-30  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* util/grub-install.in (convert): The code for gnu* (i.e.
+	GNU/Hurd) was rewritten, since it didn't work for BSD
+	partitions.
+	Use "$tmp_disk *$" instead of "$tmp_disk" to get the drive name.
+	
+2000-09-30  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/fsys_reiserfs.c (reiserfs_mount): Check if the length
+	of the partition is less than the size of a super block, before
+	attempting to read the super block.
+
+	* grub/asmstub.c (console_putchar)
+	[HAVE_LIBCURSES_H && REFRESH_IMMEDIATELY]: Call refresh, to ease
+	debugging.
+	
+2000-09-30  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Added two new commands, "partnew" and "parttype", based on the
+	patch by Stefan Ondrejicka <ondrej@idata.sk>:
+	* stage2/builtins.c (partnew_func): New function.
+	(builtin_partnew): New variable.
+	(parttype_func): New function.
+	(builtin_parttype): New variable.
+	(builtin_table): Added pointers to BUILTIN_PARTNEW and to
+	BUILTIN_PARTTYPE.
+	
+2000-09-29  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (find_func): New variable GOT_FILE is set to
+	one if FILENAME is found. Otherwise, it is set to zero.
+	Clear ERRNUM at the end in the loop for floppies, to ensure that
+	ERRNUM is cleared before examining hard disks.
+	Rewrite the loop for hard disks using next_partitions, so this
+	function now checks all partitions you have certainly.
+	If GOT_FILE is non-zero, set ERRNUM to ERR_FILE_NOT_FOUND and
+	return one.
+	
+2000-09-29  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/disk_io.c (check_BSD_parts): Removed.
+	(next_partition): New function.
+	(real_open_partition): Rewritten using next_partition.
+	(set_device) [!STAGE1_5]: Skip a comma in DEVICE, even when the
+	BSD partition is not specified.
+	[!STAGE1_5] (print_completions): Don't append ')' if the
+	partition is a PC slice which may have BSD partitions. Instead,
+	try to complete the command-line with possible partitions.
+	* stage2/shared.h (next_partition): Declared.
+	
+2000-09-27  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* configure.in (--enable-serial): Changed to ...
+	(--disable-serial): ... this. Now the serial support is enabled
+	by default.
+	
+2000-09-27  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/char_io.c [!STAGE1_5] (get_cmdline) [!SUPPORT_SERIAL]: 
+	Don't check if the terminal is dumb. If the terminal is console,
+	always use console functions.
+	* stage2/builtins.c [!SUPPORT_NETBOOT] (bootp_func): Undefined.
+	[!SUPPORT_NETBOOT] (builtin_bootp): Likewise.
+	[!GRUB_UTIL] (device_func): Likewise.
+	[!GRUB_UTIL] (builtin_device): Likewise.
+	[!SUPPORT_NETBOOT] (dhcp_func): Likewise.
+	[!SUPPORT_NETBOOT] (builtin_dhcp): Likewise.
+	[!GRUB_UTIL] (quit_func): Likewise.
+	[!GRUB_UTIL] (builtin_quit): Likewise.
+	[!SUPPORT_NETBOOT] (rarp_func): Likewise.
+	[!SUPPORT_NETBOOT] (builtin_rarp): Likewise.
+	[!SUPPORT_SERIAL] (serial_func): Likewise.
+	[!SUPPORT_SERIAL] (builtin_serial): Likewise.
+	[!SUPPORT_SERIAL] (terminal_func): Likewise.
+	[!SUPPORT_SERIAL] (builtin_terminal): Likewise.
+	[!SUPPORT_NETBOOT] (tftpserver_func): Likewise.
+	[!SUPPORT_NETBOOT] (builtin_tftpserver): Likewise.
+	(builtin_table) [!SUPPORT_NETBOOT]: Removed the pointers to
+	BUILTIN_BOOTP, BUILTIN_DHCP, BUILTIN_RARP, and
+	BUILTIN_TFTPSERVER.
+	(builtin_table) [!SUPPORT_SERIAL]: Removed the pointers to
+	BUILTIN_SERIAL and BUILTIN_TERMINAL.
+	(builtin_table) [!GRUB_UTIL]: Removed the pointers to
+	BUILTIN_DEVICE and BUILTIN_QUIT.
+	
+2000-09-26  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* util/grub-install.in (bootdir_device): New variable. If
+	$bootdir_device is not the same as $root_device, set root_device
+	and grubdir to $bootdir_device and "/grub", respectively.
+	Add --prefix=$grubdir into the command "setup".
+	
+2000-09-26  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Add --prefix=DIR to the command "setup".
+	
+	* stage2/builtins.c (setup_func): New nested function,
+	check_file checks if the file FILE exists.
+	Remove the prefix "/boot/grub" in STAGE1_5_MAP.
+	Don't hardcode "/boot/grub/stage1", "/boot/grub/stage2", or
+	"/boot/grub/menu.lst". Instead, check if ARG contains
+	"--prefix=", and if specified, set PREFIX to the value.
+	If not specified, check "/boot/grub/stage1" and, if not found,
+	check "/grub/stage1". If a stage1 was found, set PREFIX to the
+	directory which contains the stage1.
+	
+2000-09-12  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Add additional magic to avoid a bug in Linux. *sigh*
+	
+	* stage2/boot.c (load_image): Copy SRC to DEST first, and append
+	a "mem=" option to DEST instead of prepending.
+	
+2000-09-11  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Reported by Alessandro Rubini:
+	* stage2/fsys_minix.c (minix_mount): Check if CURRENT_SLICE is a
+	partition type for minix fs, using the macro
+	IS_PC_SLICE_TYPE_MINIX.
+	* stage2/pc_slice.h (PC_SLICE_TYPE_LINUX_MINIX): New macro.
+	(IS_PC_SLICE_TYPE_MINIX): Likewise.
+	
+2000-09-09  Alessandro Rubini  <rubini@morgana.systemy.it>
+
+	* stage1/stage1.S (notification_string): Print "GRUB " instead
+	of "stage1 ".
+	* stage2/start.S [STAGE1_5] (notification_string): Print
+	"Loading stage1.5" instead of "stage1.5 ".
+	[!STAGE1_5] (notification_string): Print "Loading stage2"
+	instead of "stage2 ".
+	(notification_step): New label, followed by a string ".".
+	(notification_done): New label, followed by a string "\r\n".
+	(copy_buffer): Print NOTIFICATION_STEP after copying the buffer.
+	(bootit): Print NOTIFICATION_DONE before restoring %dx.
+	
+2000-09-09  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Alessandro Rubini:
+	* configure.in (CPPFLAGS): Added -malign-jumps=1,
+	-malign-loops=1 and -malign-functions=1.
+	
+2000-09-07  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Hal Snyder <hal@vailsys.com>:
+	* lib/device.c (get_drive_geometry) [__FreeBSD__ || __NetBSD__
+	|| __OpenBSD__]: Call ioctl for FD instead of
+	DISKS[DRIVE].FLAGS. This was a mistake when I segregated this
+	function from asmstub.c.
+	
+2000-09-07  Alessandro Rubini  <rubini@gnu.org>
+
+	* docs/tutorial.texi: Fixed a few typos and minor imprecisions.
+	* docs/prog-ref.texi: Likewise.
+	* docs/user-ref.texi: Likewise.
+
+2000-09-07  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Alessandro Rubini:
+	* stage2/builtins.c (terminal_func): Rename TIMEOUT to TO, to
+	suppress GCC warnings.
+	* grub/asmstub.c (serial_checkkey): Likewise.
+	
+2000-09-06  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/char_io.c [!STAGE1_5] (auto_fill): New variable.
+	[!STAGE1_5] (get_cmdline): Save AUTO_FILL in SAVED_AUTO_FILL in
+	the beginning and restore AUTO_FILL before return.
+	Set AUTO_FILL to one and zero before and after calling
+	print_completions, respectively.
+	(grub_putchar) [!STAGE1_5]: Use a static variable COL to track
+	the position of the cursor. If C is a carriage return, clear
+	COL. If C is a backspace and COL is positive, decrease COL. If C
+	is a printable character, increase COL. In this case, if
+	AUTO_FILL is non-zero and COL is greater than or equal to 79,
+	put a newline automatically.
+	* stage2/shared.h (auto_fill): Declared.
+	* stage2/stage2.c (run_menu): In the menu interface, disable the
+	auto fill mode (i.e. set AUTO_FILL to zero), and enable it again
+	when booting an entry.
+	(cmain): Initialize AUTO_FILL (i.e. set it to one) in the
+	beginning of the loop.
+	
+2000-09-06  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Add support for "boot previously booted entry by default", based
+	on the patch by Mike Meyer <mwm@mired.org>, but I've modified
+	his patch thoroughly.
+	
+	* grub/asmstub.c (saved_entryno): New variable. This is a dummy.
+	* stage1/stage1.h (COMPAT_VERSION_MINOR): Incremented.
+	* stage2/asm.S (saved_entryno): New variable.
+	(codestart) [!SUPPORT_DISKLESS]: Set INSTALL_SECOND_SECTOR to
+	%ebp. %ebp is set in start.S.
+	(install_second_sector): New variable.
+	* stage2/builtins.c (current_entryno): New variable.
+	(default_func) [!SUPPORT_DISKLESS]: If ARG is "saved", set
+	DEFAULT_ENTRY to SAVED_ENTRYNO.
+	(savedefault_func): New function.
+	(builtin_savedefault): New variable.
+	(builtin_table): Added a pointer to BUILTIN_SAVEDEFAULT.
+	* stage2/shared.h (STAGE2_SAVED_ENTRYNO): New macro.
+	(STAGE2_STAGE2_ID): Changed to 0x10.
+	(STAGE2_FORCE_LBA): Chaged to 0x11.
+	(STAGE2_VER_STR_OFFS): Changed to 0x12.
+	(install_second_sector): Declared.
+	(saved_entryno): Likewise.
+	(current_entryno): Likewise.
+	* stage2/stage2.c (run_menu): Set CURRENT_ENTRYNO to FIRST_ENTRY
+	+ ENTRYNO, right before calling run_script.
+	* stage2/start.S (start): Save the sector number of the second
+	sector in %ebp.
+	
+2000-09-05  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage1/stage1.S (lba_mode) [!NO_BUGGY_BIOS_IN_THE_WORLD]:
+	Don't check for the geometry, since some BIOSes don't return the
+	number of total sectors correctly, even if they have working LBA
+	support.
+	* stage2/start.S (lba_mode) [!NO_BUGGY_BIOS_IN_THE_WORLD]:
+	Likewise.
+	* stage2/bios.c (biosdisk) [!NO_BUGGY_BIOS_IN_THE_WORLD]:
+	Likewise.
+	Reported by Jan Fricke <fricke@uni-greifswald.de> and Pixel
+	<pixel@mandrakesoft.com>.
+	
+2000-09-05  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Alessandro Rubini <rubini@gnu.org>:
+	* stage2/char_io.c (print_error) [!STAGE1_5]: Print ERRNUM like
+	"Error 9: Unknown boot failure".
+	(print_error) [STAGE1_5]: Don't print a colon.
+	* util/grub-install.in: When checking if an error occurred, use
+	the expression "Error [0-9]*: " instead of "Error: ".
+	* docs/user-ref.texi (Stage1.5 errors): Updated, since the error
+	form changed.
+	
+2000-09-04  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/stage2.c (run_menu) [GRUB_UTIL]: Set DISP_UP and
+	DISP_DOWN to ACS_UARROW and ACS_DARROW, respectively. Don't call
+	grub_printf here.
+	(run_menu) [!GRUB_UTIL]: Don't call grub_printf here. Instead,
+	call it...
+	(run_menu): ... here.
+	* stage2/shared.h (ACS_ULCORNER): Always define this ourselves,
+	whether your curses library has the definition.
+	(ACS_URCORNER): Likewise.
+	(ACS_LLCORNER): Likewise.
+	(ACS_LRCORNER): Likewise.
+	(ACS_HLINE): Likewise.
+	(ACS_VLINE): Likewise.
+	(ACS_LARROW): Likewise.
+	(ACS_RARROW): Likewise.
+	(ACS_UARROW): Likewise.
+	(ACS_DARROW): Likewise.
+
+	* stage2/char_io.c [SUPPORT_SERIAL] (serial_cls): If the
+	terminal is dumb, just put a newline.
+	* stage2/builtins.c (terminal_func) [SUPPORT_SERIAL]: When
+	choosing a terminal, don't set TERMINAL to the type of the
+	terminal. Instead, apply a logical AND operation with
+	TERMINAL_DUMB, since previous code brushed off the dumb
+	attribute.
+	
+2000-09-04  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/stage2.c (run_menu): If SHOW_MENU is zero, print a
+	message with the timeout per second.
+	If GRUB_TIMEOUT is negative, set SHOW_MENU to one, since the
+	condition "no timeout and no interface" is nonsense.
+	If GRUB_TIMEOUT is equal to or greater than zero and the
+	terminal is dumb, set SHOW_MENU to zero.
+	If SHOW_MENU is non-zero and the terminal is dumb, enter the
+	command-line interface instead. If AUTH is false and PASSWORD is
+	non-NULL, prompt the user to enter a password until the entered
+	password is identical to PASSWORD.
+	
+2000-09-03  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* util/grub-install.in: Fix a typo: grub_dir -> grubdir.
+	* stage2/builtins.c (install_func) [GRUB_UTIL]: Open a Stage 2
+	with "r+" instead of "r", as GRUB needs to overwrite it.
+	
+2000-09-02  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/stage2.c (run_menu): Don't use either `p' or `n' to
+	move the cursor, because `p' is already used for another
+	purpose (password).
+	(run_menu) [SUPPORT_SERIAL]: Don't set the variables DISP_UP and
+	DISP_DOWN at the start time. Instead, set them just before using
+	them actually, because TERMINAL may change when running a menu.
+	
+2000-09-01  Klaus Reichl  <Klaus.Reichl@alcatel.at>
+
+	* stage2/stage2.c (run_menu): Setup and use disp_up, disp_down
+	depending on the terminal mode.
+	(run_menu): Allow '^' (resp. 'p') and 'v' (resp 'n') keys we
+	described in our help above (resp. authors preferences).
+
+2000-08-31  Klaus Reichl  <Klaus.Reichl@alcatel.at>
+
+	* stage2/stage2.c (set_line): Go back one char, which is
+	consistent with the original situation, when a timeout was
+	running.  
+	(run_menu): If GRUB_TIMEOUT is stopped don't loop busy over
+	CHECKKEY, just relax in GETKEY. 
+
+	* stage2/builtins.c (serial_func): --speed handling: corrected
+	typo: set SPEED instead of PORT. 
+	
+2000-08-31  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (terminal_func): Added two new options,
+	--dumb and --timeout=SECS.
+	* stage2/char_io.c [!STAGE1_5] (getkey): Use logical AND
+	operations, when checking if the terminal is a console or a
+	serial terminal.
+	[!STAGE1_5] (getkey) [SUPPORT_SERIAL]: Don't check if both
+	TERMINAL_CONSOLE and TERMINAL_SERIAL are set in TERMINAL.
+	
+2000-08-31  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage1/stage1.S (MOV_MEM_TO_AL): New macro.
+	(real_start): Use the macro MOV_MEM_TO_AL instead of using movb
+	directly, because binutils-2.9.1.0.x doesn't produce a short
+	opcode for it automatically. Reported by Alessandro Rubini
+	<rubini@gnu.org>.
+
+2000-08-30  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* configure.in (CPPFLAGS): Remove -Wundef by default. Add the
+	option only if the C compiler supports it, because GCC 2.7.x
+	doesn't support it.
+	* grub/main.c (longopts): The type of the argument for "hold" is
+	changed to OPTIONAL_ARGUMENT.
+	(main): If --hold is specified, check if OPTARG is zero. If so,
+	set HOLD to -1, otherwise, set it to the digit OPTARG.
+	If HOLD is greater than zero, decrease it once per loop.
+	
+2000-08-30  OKUJI Yoshinori  <okuji@gnu.org>
+
+	The command-line interface is switched to single-line editing
+	mode.
+	
+	* stage2/char_io.c [!STAGE1_5] (get_cmdline): Extensively
+	rewritten. The nested functions cl_print and cl_kill_to_end are
+	removed, cl_refresh, cl_backward, cl_forward and cl_delete are
+	added, and, cl_init and cl_insert are rewritten from scratch.
+	See the source code, for more information. I don't think this
+	kind of changes can be represented in ChangeLog.
+	[!STAGE1_5] (CMDLINE_WIDTH): New macro.
+	[!STAGE1_5] (CMDLINE_MARGIN): Likewise.
+	* stage2/shared.h (TERMINAL_DUMB): Likewise.
+	
+2000-08-28  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* grub/asmstub.c (console_putchar) [HAVE_LIBCURSES]: If
+	USE_CURSES is true, emulate a new line like a ordinary terminal,
+	because ncurses treats it badly. If current position on y-axis
+	is the bottom of the screen, call scroll. Otherwise, call move
+	with the arguments, Y + 1 and X, where X and Y are current
+	position of the cursor.
+	
+2000-08-28  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/asm.S (console_putchar): Don't print a carriage return
+	when C is a newline.
+	* stage2/char_io.c (grub_putchar): Call grub_putchar with the
+	arugment set to a carriage return, if C is a newline.
+	[!STAGE1_5 && SUPPORT_SERIAL]: Don't print a carriage return
+	when C is a newline.
+	
+2000-08-27  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* lib/device.c [__linux__]: Don't include linux/fs.h.
+	[!BLKGETSIZE] (BLKGETSIZE): Defined as _IO(0x12,96).
+	* grub/asmstub.c [__linux__]: Don't include linux/fs.h.
+	
+2000-08-27  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Preserve a magic number used by Windows NT in a MBR. Shit!
+	Reported by Khimenko Victor.
+	
+	* stage1/stage1.h (STAGE1_WINDOWS_NT_MAGIC): New macro.
+	* stage1/stage1.S (copy_buffer): Use pusha and popa, instead of
+	pushing/poping %cx and %si separately, to reduce the code size.
+	(nt_magic): New label. Set the offset to _start plus
+	STAGE1_WINDOWS_NT_MAGIC
+	(part_start): New label.
+	* stage2/builtins.c (install_func): If DEST_DRIVE is a hard
+	disk, copy the possible partition table and Windows NT magic to
+	STAGE1_BUFFER from OLD_SECT.
+	
+2000-08-26  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/char_io.c (translate_keycode) [SUPPORT_SERIAL]: Don't
+	drain the input buffer, since that was irritating.
+	
+2000-08-26  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Don't save/restore fragile registers unnecessarily.
+	
+	* stage2/asm.S [!STAGE1_5] (track_int13): Don't save/restore
+	%ecx, %edx, or %eax.
+	[!STAGE1_5] (set_int13_handler): Likewise.
+	(biosdisk_int13_extensions): Likewise.
+	(biosdisk_standard): Likewise.
+	(check_int13_extensions): Likewise.
+	(get_diskinfo_int13_extensions): Likewise.
+	(get_diskinfo_standard): Likewise.
+	(get_diskinfo_floppy): Likewise.
+	[!STAGE1_5] (get_eisamemsize): Likewise.
+	[!STAGE1_5] (get_mmap_entry): Likewise.
+	[!STAGE1_5] (console_cls): Likewise.
+	[!STAGE1_5] (nocursor): Likewise.
+	[!STAGE1_5] (console_getxy): Likewise.
+	[!STAGE1_5] (console_gotoxy): Likewise.
+	[!STAGE1_5] (set_attrib): Likewise.
+	[!STAGE1_5] (getrtsecs): Likewise.
+	[!STAGE1_5] (currticks): Likewise, and don't zero %eax
+	explicitly, since prot_to_real does that.
+	
+2000-08-25  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/char_io.c [!STAGE1_5] (translate_keycode): New
+	function. The serial part is stolen from the patch by Christoph
+	Plattner.
+	[!STAGE1_5] (get_cmdline): Call translate_keycode instead of
+	translating special key codes into ASCII characters by itself.
+	* stage2/stage2.c (run_menu): Wrap getkey with the macro
+	ASCII_CHAR, when checking if ESC is pressed.
+	Call translate_keycode as well as getkey, unless checkkey
+	returns -1. So don't check if C is KEY_DOWN or KEY_UP. And don't
+	use the macro ASCII_CHAR for C explicitly.
+	* stage2/shared.h (translate_keycode): Declared.
+	
+2000-08-24  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c [GRUB_UTIL]: Include stdio.h before
+	shared.h. Reported by Mathieu Chouquet-Stringer
+	<mchouque@cs.stevens-tech.edu>.
+	
+2000-08-21  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* configure.in (--enable-serial-speed-emulation): New option.
+	(SERIAL_SPEED_SIMULATION): New conditional.
+	* grub/Makefile.am (SERIAL_FLAGS): New variable. Set
+	-DSUPPORT_SERIAL=1 and -DSIMULATE_SLOWNESS_OF_SERIAL=1, if
+	SERIAL_SPEED_SIMULATION is defined, otherwise, set it to
+	only -DSUPPORT_SERIAL=1.
+	(AM_CFLAGS): Removed -DSUPPORT_SERIAL=1 and added
+	$(SERIAL_FLAGS).
+	* grub/asmstub.c [SIMULATE_SLOWNESS_OF_SERIAL] (serial_speed):
+	New variable.
+	(grub_setjmp): Removed.
+	(grub_longjmp): Likewise.
+	(serial_getkey) [SIMULATE_SLOWNESS_OF_SERIAL]: Wait for
+	1000000 / (SERIAL_SPEED >> 3) microseconds using gettimeofday.
+	(serial_putchar) [SIMULATE_SLOWNESS_OF_SERIAL]: Likewise.
+	(serial_init) [SIMULATE_SLOWNESS_OF_SERIAL]: Set SERIAL_SPEED to
+	SPEED.
+	* stage2/builtins.c (serial_func) [SUPPORT_SERIAL]: Added
+	a new option, `--speed'.
+	(builtin_serial): Added a description about --speed.
+	(terminal_func): When get a key from a serial device, if GRUB is
+	in the command-line interface, call grub_longjmp with
+	RESTART_CMDLINE_ENV, instead of init_page.
+	* stage2/cmdline.c (restart_cmdline_env): New variable.
+	(enter_cmdline): Call grub_setjmp with RESTART_CMDLINE_ENV after
+	calling init_cmdline.
+	(run_script): Run BUILTIN->FUNC with BUILTIN_SCRIPT instead of
+	BUILTIN_CMDLINE.
+	* stage2/shared.h (BUILTIN_SCRIPT): New macro.
+	[GRUB_UTIL] (grub_setjmp): Defined as setjmp.
+	[GRUB_UTIL] (grub_longjmp): Defined as longjmp.
+	(restart_cmdline_env): Declared.
+	
+2000-08-20  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* configure.in (--enable-serial): New option. Serial terminal
+	support will be enabled by default, once it is stabilized.
+	(SERIAL_SUPPORT): New conditional.
+	* grub/Makefile.am (AM_CFLAGS): Added -DSUPPORT_SERIAL=1.
+	* grub/asmstub.c (cls): Renamed to ...
+	(console_cls): ... this.
+	(getxy): Renamed to ...
+	(console_getxy): ... this.
+	(gotoxy): Renamed to ...
+	(console_gotoxy): ... this.
+	* stage2/Makefile.am (libgrub_a_CFLAGS): Added
+	-DSUPPORT_SERIAL=1.
+	(NETBOOT_FLAGS): New variable.
+	(SERIAL_FLAGS): Likewise.
+	(STAGE2_COMPILE): Added $(NETBOOT_FLAGS) and $(SERIAL_FLAGS).
+	* stage2/asm.S [!STAGE1_5] (cls): Renamed to ...
+	[!STAGE1_5] (console_cls): ... this.
+	[!STAGE1_5] (getxy): Renamed to ...
+	[!STAGE1_5] (console_getxy): ... this.
+	[!STAGE1_5] (gotoxy): Renamed to ...
+	[!STAGE1_5] (console_gotoxy): ... this.
+	* stage2/builtins.c (terminal_func): If the bit flag
+	BUILTIN_CMDLINE in FLAGS is set, call init_page. But this should
+	be fixed so that it restarts enter_cmdline instead.
+	* stage2/char_io.c [!STAGE1_5] (gotoxy): New function.
+	[!STAGE1_5] (serial_gotoxy): Likewise.
+	[!STAGE1_5] (getxy): Likewise.
+	[!STAGE1_5] (serial_getxy): Likewise.
+	[!STAGE1_5] (cls): Likewise.
+	[!STAGE1_5] (serial_cls): Likewise.
+	* stage2/serial.h (serial_cls): Declared.
+	(serial_getxy): Likewise.
+	(serial_gotoxy): Likewise.
+	* stage2/shared.h (console_cls): Likewise.
+	(console_getxy): Likewise.
+	(console_gotoxy): Likewise.
+	* stage2/stage2.c (print_entries): If serial terminal is
+	enabled, print ACS_UARROW and ACS_DARROW instead of DISP_UP and
+	DISP_DOWN, respectively.
+	(print_border): If serial terminal is enabled, print
+	ACS_ULCORNER, ACS_URCORNER, ACS_LLCORNER, ACS_LRCORNER,
+	ACS_HLINE and ACS_VLINE instead of DISP_UL, DISP_UR, DISP_LL,
+	DISP_LR, DISP_HORIZ and DISP_VERT, respectively.
+	(print_border) [SUPPORT_SERIAL]: Color the menu only if console
+	is used.
+	(set_line): Take two more arguments, ENTRYNO and MENU_ENTRIES.
+	(set_line_normal): Likewise.
+	(set_line_highlight): Likewise.
+	(set_line) [SUPPORT_SERIAL]: If serial terminal is enabled, get
+	the menu entry whose attributes are being changed and redraw the
+	line.
+	(set_line_highlight) [SUPPORT_SERIAL]: If serial terminal is
+	enabled, print `ESC [ 7 m' and `ESC [ 0 m' before and after
+	calling set_line, respectively.
+	(run_menu) [SUPPORT_SERIAL]: Call nocursor only if console is
+	used.
+	
+2000-08-20  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Now the serial console support is partially working.
+	
+	* grub/asmstub.c (serial_checkkey): Specify a pointer to TIMEOUT
+	as the fifth argument to select.
+	(serial_get_port): New function. Just a dummy.
+	(serial_init): If a serial device is opened, close SERIAL_FD
+	before opeing a new serial device.
+	Don't specify O_NDELAY to open.
+	* stage2/builtins.c [SUPPORT_SERIAL]: Include serial.h.
+	(serial_func): New function.
+	(builtin_serial): New variable.
+	(terminal_func): New function.
+	(builtin_terminal): New variable.
+	(builtin_table): Add pointers to BUILTIN_SERIAL and
+	BUILTIN_TERMINAL.
+	* stage2/char_io.c [SUPPORT_SERIAL]: Include serial.h.
+	(getkey) [SUPPORT_SERIAL]: If both TERMINAL_CONSOLE and
+	TERMINAL_SERIAL are set in TERMINAL simultaneously, print a
+	warning and force the console terminal.
+	(checkkey) [SUPPORT_SERIAL]: If TERMINAL_SERIAL is set in
+	TERMINAL, call serial_checkkey.
+	(grub_putchar) [SUPPORT_SERIAL]: If TERMINAL_SERIAL is set in
+	TERMINAL, call serial_putchar. If C is a newline, print a
+	carriage return, before printing a newline.
+	
+2000-08-15  OKUJI Yoshinori  <okuji@gnu.org>
+
+	The image `nbgrub' now relocates itself from 0x10000 to 0x8000,
+	since the Network Boot Image Proposal doesn't permit a second
+	loader to be loaded below 0x10000. Reported by Matthias
+	Kretschmer <McCratch@gmx.net>.
+	
+	* Makefile.am (NBLOADER_LINK): New variable.
+	(nbloader_exec_LDFLAGS): Set to $(NBLOADER_LINK) instead of
+	$(START_LINK).
+	* stage2/nbi.h (NBI_DEST_ADDR): Changed to 0x10000.
+	(NBI_DEST_SEG): New macro.
+	(NBI_DEST_OFF): Likewise.
+	(RELOCATED_ADDR): Likewise.
+	(RELOCATED_SEG): Likewise.
+	(RELOCATED_OFF): Likewise.
+	(STAGE2_START_ADDR): Likewise.
+	* stage2/nbloader.S: Added .code16 directive at the start of the
+	code.
+	Set the segment and the offset of the load address to
+	NBI_DEST_SEG and NBI_DEST_OFF, respectively.
+	Set the segment and the offset of the start address to
+	NBI_DEST_SEG and NBI_DEST_OFF + relocate - _start, respectively.
+	Added a routine for relocating itself.
+	(relocate): New label.
+	(copy_rest): Likewise.
+	(copy_loop): Likewise.
+	(copy): Likewise.
+	(boot_stage2): Likewise.
+	
+2000-08-13  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* grub/main.c (main): Move the version number inside the
+	parentheses, since the grub shell is merely one of the programs
+	included in GNU GRUB.
+	
+2000-08-13  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Add a serial device emulation into the grub shell.
+	
+	* grub/asmstub.c: Include sys/time.h and termios.h.
+	(serial_fd): New variable.
+	(serial_device): Likewise.
+	(serial_getkey): New function.
+	(serial_checkkey): Likewise.
+	(serial_putchar): Likewise.
+	(get_termios_speed): Likewise.
+	(serial_init): Likewise.
+	(set_serial_device): Likewise.
+	(grub_stage2): Restore SERIAL_DEVICE and SERIAL_FD, if they were
+	allocated.
+	* stage2/serial.h [GRUB_UTIL] (set_serial_device): Declared.
+	
+2000-08-13  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/asm.S (codestart) [SUPPORT_DISKLESS]: Don't reset a
+	disk system. That is not only uncessary but also harmful.
+	
+2000-08-12  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Add a serial device driver (but only the driver).
+	
+	* stage2/serial.c: New file.
+	* stage2/serial.h: Likewise.
+	* stage2/shared.h (serial_getkey): Moved to stage2/serial.h.
+	(serial_checkkey): Likewise.
+	(serial_putchar): Likewise.
+	* stage2/Makefile.am (noinst_HEADERS): Added serial.h.
+	(pre_stage2_exec_SOURCES): Added serial.c.
+
+2000-08-10  Pavel Roskin  <proski@gnu.org>
+
+	* docs/tutorial.texi: Minor fixes.
+
+2000-08-10  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/tutorial.texi (Installation): Divided into three sections
+	instead of two sections. Don't describe the usage of the the
+	grub shell any longer. Instead, how to use grub-install is
+	documented.
+	
+2000-08-09  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c [GRUB_UTIL]: Include stdio.h.
+	(embed_func) [GRUB_UTIL && __linux__]: When embedding a Stage
+	1.5 into a partition, call write_to_partition instead of
+	biosdisk.
+	(install_func): Set DEST_PARTITION to the partition where Stage
+	1 resides.
+	Set SRC_PART_START to the starting address of the partition
+	where Stage 2 resides.
+	(install_func) [GRUB_UTIL]: Set STAGE2_OS_FILE to the file name
+	of Stage 2 under an OS, if the new option "--stage2" is
+	specified. Otherwise, set it to null.
+	If STAGE2_OS_FILE is not null, modify the Stage 2 via the
+	filesystem serviced by the OS.
+	(install_func) [GRUB_UTIL && __linux__]: If STAGE2_OS_FILE is
+	null but the Stage2 resides in a partition, use
+	write_to_partition.
+	If DEST_PARTITION is not 0xFFFFFF, use write_to_partition, to
+	embed Stage 1.
+	(setup_func) [GRUB_UTIL]: If --stage2 is specified, set
+	STAGE2_ARG to the string pointing to the option. Otherwise, set
+	it to null.
+	(setup_func) [!GRUB_UTIL]: Set STAGE2_ARG to null.
+	(setup_func): If STAGE2_ARG is not null, add STAGE2_ARG and a
+	space character into CMD_ARG.
+	* lib/device.c (_LARGEFILE_SOURCE): Defined.
+	(_FILE_OFFSET_BITS): Likewise.
+	[__linux__] (write_to_partition): New function.
+	* lib/device.h [__linux__] (write_to_partition): Declared.
+	* util/grub-install.in: Specify the option "--stage2" for the
+	command "setup".
+	
+2000-08-04  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/fsys_fat.c (fat_superblock): clust_eof_marker added.
+	(fat_mount): Initialize clust_eof_marker to 0xff8, 0xfff8, or
+	0xffffff8, depending on fat size.  Support for single active FAT
+	added (FAT32 extension). Changed the boundary between FAT12 and
+	FAT16, again.  The Microsoft KB article Q65541 seems to be wrong
+	here, I go with mtools and the previous behaviour of grub: FAT12
+	iff number of clusters (without counting the two nonexisting
+	clusters) is less or equal 4095.
+	(fat_read): Report error if cluster number is too big, but not
+	greater or equal clust_eof_marker.
+	* stage2/fsys_reiserfs.c (journal_init): Fixed calculation of
+	journal_transaction.
+	
+2000-08-01  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/fsys_reiserfs.c: Symlink support added.
+	(S_ISLNK): New macro.
+	(PATH_MAX): Likewise.
+	(MAX_LINK_COUNT): Likewise.
+	(reiserfs_dir): Check for symlink and handle them.
+	(read_tree_node): Take a block number and check if tree node was
+ 	already read in.  If not update the INFO->blocks field.
+	(next_key): Changed call of read_tree_node.
+	(search_stat): Likewise.
+	(journal_init): Fixed a small bug.  Some debugging messages added.
+	
+2000-07-31  Pavel Roskin  <proski@gnu.org>
+
+	* grub/asmstub.c (biosdisk) [__linux__]: The first argument for
+	_llseek renamed from "seeked_fd" to "filedes".
+
+2000-07-30  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/appendices.texi (FAQ): Added the answer for the separate
+	boot partition problem.
+	
+2000-07-30  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Update the network support to Etherboot-4.6.4.
+	
+	From Daniel Wagner <wagi@gmx.ch>:
+	* netboot/3c509.c: Copied from Etherboot-4.6.4.
+	* netboot/3c509.h: Likewise.
+	* netboot/cards.h: Likewise.
+	* netboot/ns8390.c: Likewise.
+	* netboot/sk_g16.c: Likewise.
+	* netboot/sk_g16.h: Likewise.
+	* netboot/tulip.c: Likewise.
+	* netboot/pci.h: Likewise.
+	* netboot/main.c (dhcpdiscover): Updated.
+	(dhcprequest): Likewise.
+	(bootp): Likewise.
+	* netboot/README.netboot: Added the information about the new
+	option --enable-ns8390-force-16bit.
+	* configure.in (--enable-ns8390-force-16bit): New option.
+
+	* netboot/config.c: Updated.
+
+2000-07-29  OKUJI Yoshinori  <okuji@gnu.org>
+
+	The Linux zImage support is working now.
+	
+	* stage2/asm.S (linux_boot): Add 3 into %ecx and shift %ecx to
+	the right by 2 bits, instead of shift %ecx to the left by 2
+	bits.
+	
+2000-07-29  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/fsys_reiserfs.c (block_read): Changed the variable "len"
+	to "j_len" (it shadowed a parameter).
+	
+2000-07-29  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* configure.in (CPPFLAGS): Added -Wshadow, -Wpointer-arith and
+	-Wundef, as GCC sometimes more clever than me. :)
+	* stage2/shared.h [!ASM_FILE] (multi_boot): Change the name of
+	the second argument from "mbi" to "mb_info".
+	[!ASM_FILE] (biosdisk): Rename the first argument "read" to
+	"subfunc".
+	* lib/device.h (init_device_map): Change the name of the third
+	argument from "floppy_disks" to "no_floppies".
+	* lib/device.c (read_device_map): Rename the internal function
+	"print_error" to "show_error".
+	* stage2/builtins.c (install_func): Rename CONFIG_FILE to
+	REAL_CONFIG.
+	(setup_func): Rename INSTALL_DRIVE, INSTALL_PARTITION and
+	CONFIG_FILE to INSTALLED_DRIVE, INSTALLED_PARTITION and
+	CONFIG_FILENAME, respectively.
+	* stage2/char_io.c (convert_to_ascii): Rename the internal
+	variable C to TMP.
+	(get_cmdline): Rename KILL to KILL_BUF.
+	Rename the second argument for cl_print to REAL_ECHO_CHAR from
+	ECHO_CHAR.
+	* stage2/stage2.c (run_menu): Rename the internal variable
+	NUM_ENTRIES to NEW_NUM_ENTRIES.
+	(cmain): Rename KILL to KILL_BUF.
+	* stage2/disk_inode_ffs.h: Check if BYTE_MSF is defined before
+	checking the value.
+	* stage2/fsys_ext2fs.c (ext2fs_dir): Check if E2DEBUG is
+	defined, instead of if the value is non-zero.
+	* grub/asmstub.c: Check if __GLIBC__ is defined before checking
+	the value.
+	(biosdisk) [__linux__]: Likewise.
+	Rename the first argument for _llseek to "seeked_fd" from "fd".
+	(multi_boot): Rename the second argument to "mb_info" from
+	"mbi".
+	
+2000-07-27  Gordon Matzigkeit  <gord@fig.org>
+
+	* util/grub-image.in: Initial cut at a script for creating GRUB
+	boot images.
+	* util/Makefile.am (noinst_SCRIPTS): Added grub-image.
+	* configure.in (AC_OUTPUT): Added util/grub-image.
+
+2000-07-27  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/asm.S (check_int13_extensions): Fixed the effect of
+	the --force-lba switch in stage2/stage1_5.
+	
+2000-07-25  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/fsys_fat.c (fat_mount): Fixed calculation of num_clust.
+	It was off by two, since the two non existing clusters 0 and 1
+	were not taken into account.  Also fixed the boundary between
+	FAT12 and FAT16.
+	
+2000-07-25  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/asm.S [!STAGE1_5] (linux_text_len): New variable.
+	[!STAGE1_5] (linux_boot): Don't set %eax to LINUX_SETUP
+	meaninglessly.
+	Set %ecx to LINUX_TEXT_LEN instead of LINUX_KERNEL_MAXLEN.
+	[!STAGE1_5] (big_linux_boot): Disable interrupts before changing
+	the stack pointer.
+	Change %ss right before %sp.
+	Reverse the arguments for ljmp. A segment must be after an
+	offset. *sigh*
+	* stage2/boot.c (load_image): Set LINUX_TEXT_LEN to TEXT_LEN,
+	if a Linux kernel is loaded successfully.
+	* stage2/shared.h (LINUX_VID_MODE_OFFSET): Removed.
+	[!ASM_FILE] (linux_kernel_header): Change the type of the member
+	`heap_end_ptr' to unsigned short.
+	[!ASM_FILE] (linux_text_len): Declared.
+	
+2000-07-24  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Comply with the Linux/i386 boot protocol version 2.02.
+	
+	* stage2/asm.S [!STAGE1_5] (linux_boot): Set the length of moved
+	bytes to LINUX_KERNEL_MAXLEN instead of
+	LINUX_KERNEL_LEN_OFFSET(%eax), since the field is obsolete.
+	[!STAGE1_5] (big_linux_boot): Don't use SEGMENT or OFFSET.
+	Instead, embed the segment and the offset in the code itself.
+	Set %ds, %es, %fs and %gs to %ax (LINUX_INIT_SEG).
+	* stage2/boot.c (load_image): Rewrite the Linux support code
+	heavily. Use a structure instead of a batch of macros, to access
+	a Linux kernel header.
+	(load_initrd): If MOVETO plus LEN is greater than or equal to
+	LINUX_INITRD_MAX_ADDRESS, set MOVETO to LINUX_INITRD_MAX_ADDRESS
+	minus LEN with page aligned.
+	* stage2/shared.h (LINUX_MAGIC_SIGNATURE): New macro.
+	(LINUX_DEFAULT_SETUP_SECTS): Likewise.
+	(LINUX_FLAG_CAN_USE_HEAP): Likewise.
+	(LINUX_INITRD_MAX_ADDRESS): Likewise.
+	(LINUX_MAX_SETUP_SECTS): Likewise.
+	(LINUX_BOOT_LOADER_TYPE): Likewise.
+	(LINUX_HEAP_END_OFFSET): Likewise.
+	(LINUX_SETUP_MAXLEN): Removed.
+	(LINUX_KERNEL_LEN_OFFSET): Likewise.
+	(LINUX_SETUP_LEN_OFFSET): Likewise.
+	(LINUX_SETUP_STACK): Set to 0x7F00 instead of 0x3FF4 (why was it
+	this value?).
+	(LINUX_SETUP_LOADER): Removed.
+	(LINUX_SETUP_LOAD_FLAGS): Likewise.
+	(LINUX_SETUP_CODE_START): Likewise.
+	(LINUX_SETUP_INITRD): Likewise.
+	(CL_MY_LOCATION): Set to RAW_ADDR(0x97F00) instead of
+	RAW_ADDR(0x92000).
+	(CL_MY_END_ADDR): Set to RAW_addr(0x97FFF) instead of
+	RAW_ADDR(0x920FF).
+	(CL_MAGIC_ADDR): Removed.
+	(CL_OFFSET): Likewise.
+	[!ASM_FILE] (struct linux_kernel_header): New structure tag.
+	
+2000-07-23  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/tutorial.texi: Fix some syntax errors and ambiguous
+	sentences. Suggested by M. Meiarashi <mes@st.rim.or.jp>.
+	
+2000-07-14  Khimenko Victor  <grub@khim.sch57.msk.ru>
+
+	* stage2/boot.c (load_image): When getting the text length of a 
+	Linux kernel, use unsigned long instead of unsigned short.
+	
+2000-07-13  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* lib/device.c: Include errno.h. Reported by Thierry DELHAISE
+	<thierry.delhaise@delhaise.com>.
+	
+2000-07-12  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Just to start implementing serial console support...
+	
+	* stage2/asm.S (grub_putchar): Renamed to ...
+	(console_putchar): ... this.
+	[!STAGE1_5] (getkey): Renamed to ...
+	[!STAGE1_5] (console_getkey): ... this.
+	[!STAGE1_5] (checkkey): Renamed to ...
+	[!STAGE1_5] (console_checkkey): ... this.
+	* stage2/char_io.c [!STAGE1_5] (getkey): New function.
+	[!STAGE1_5] (checkkey): Likewise.
+	(grub_putchar): Likewise.
+	* stage2/shared.h [!STAGE1_5] (terminal): Declared.
+	[!STAGE1_5] (TERMINAL_CONSOLE): New macro.
+	[!STAGE1_5] (TERMINAL_SERIAL): Likewise.
+	(console_putchar): Declared.
+	(serial_putchar): Likewise.
+	(console_getkey): Likewise.
+	(serial_getkey): Likewise.
+	(console_checkkey): Likewise.
+	(serial_checkkey): Likewise.
+	* stage2/builtins.c (terminal): New global variable. The default
+	is TERMINAL_CONSOLE.
+	* grub/asmstub.c (grub_putchar): Renamed to ...
+	(console_putchar): ... this.
+	(getkey): Renamed to ...
+	(console_getkey): ... this.
+	(checkkey): Renamed to ...
+	(console_checkkey): ... this.
+	
+2000-07-12  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/Makefile.am (libgrub_a_CFLAGS): Added
+	-I$(top_srcdir)/lib.
+	* stage2/builtins.c [GRUB_UTIL]: Include device.h.
+	
+2000-07-12  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Segreate OS-specific helper functions from asmstub.c.
+	
+	* grub/asmstub.c [__linux__]: Don't include linux/hdreg.h,
+	linux/major.h, linux/kdev_t.h, or linux/cdrom.h.
+	[__FreeBSD__ || __NetBSD__ || __OpenBSD__]: Don't include
+	sys/ioctl.h, sys/disklabel.h, or sys/ioctl.h.
+	[HAVE_OPENDISK]: Don't include util.h.
+	Include device.h.
+	(DEFAULT_FD_CYLINDERS): Removed.
+	(DEFAULT_FD_HEADS): Likewise.
+	(DEFAULT_FD_SECTORS): Likewise.
+	(DEFAULT_HD_CYLINDERS): Likewise.
+	(DEFAULT_HD_HEADS): Likewise.
+	(DEFAULT_HD_SECTORS): Likewise.
+	(NUM_DISKS): Likewise.
+	(init_device_map): Likewise.
+	(get_floppy_disk_name): Likewise.
+	(get_ide_disk_name): Likewise.
+	(get_scsi_disk_name): Likewise.
+	(check_device): Likewise.
+	(get_drive_geometry): Likewise.
+	* grub/main.c (no_floppy): Removed.
+	(probe_second_floppy): Likewise.
+	(floppy_disks): New global variable.
+	(main): Set FLOPPY_DISKS to zero, if OPT_NO_FLOPPY. Set
+	FLOPPY_DISKS to two, if OPT_PROBE_SECOND_FLOPPY.
+	* lib/Makefile.am (AM_CFLAGS): New variable.
+	* lib/device.h: New file.
+	* lib/device.c: Likewise.
+	* stage2/shared.h (no_floppy): Removed.
+	(probe_second_floppy): Likewise.
+	(check_device): Likewise.
+	(floppy_disks): Declared.
+	
+2000-07-02  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* grub/main.c (usage): Enclose the mail address with parentheses
+	and add a period into the end of the line. That's just a
+	cosmetic change.
+	
+2000-07-02  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/appendices.texi (Obtaining and Building GRUB): Indicate
+	the Cygnus's binutils webpage instead of the hjl's site, since
+	you can now use a public release (i.e. 2.10).
+	
+2000-06-23  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/boot.c (load_image): Take an additional argument
+	LOAD_FLAGS.
+	If the kernel type is Linux and the bit
+	KERNEL_LOAD_NO_MEM_OPTION in LOAD_FLAGS is set, don't pass a
+	Linux's mem option automatically.
+	* stage2/shared.h (load_image): Added the new argument.
+	* stage2/builtins.c (kernel_func): If `--no-mem-option' is
+	specified, set the bit KERNEL_LOAD_NO_MEM_OPTION in LOAD_FLAGS,
+	otherwise, LOAD_FLAGS is zero.
+	
+2000-06-22  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/tutorial.texi: Fixed some typos and syntax errors.
+	* docs/user-ref.texi: Likewise.
+	
+2000-06-21  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/stage2.c (run_menu): Initialize CUR_ENTRY at the
+	definition.
+	If SHOW_MENU is zero, don't display the menu interface. Instead,
+	wait until the timeout is expired and then boot the default
+	entry. If the user presses `ESC' during the timeout, set
+	SHOW_MENU to one and break the loop.
+	Display the menu if SHOW_MENU is true, instead of if
+	GRUB_TIMEOUT is non-zero.
+	Set SHOW_MENU to one before go to the label `restart'.
+	* stage2/builtins.c (show_menu): New global variable.
+	(hiddenmenu_func): New function.
+	(builtin_hiddenmenu): New variable.
+	(builtin_table): Added a pointer to BUILTIN_HIDDENMENU.
+	* stage2/shared.h (show_menu): Declared.
+	
+2000-06-19  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/mdate-sh: Moved to ...
+	* mdate-sh: ... here.
+	* docs/texinfo.tex: Moved to ...
+	* texinfo.tex: ... here.
+	
+2000-06-09  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/mb_info.h (AddrRangeDesc): Use one 64bits field instead
+	of two 32bits fields for BaseAddr and Length, respectively.
+	BaseAddrLow + BaseAddrHigh -> BaseAddr, LengthLow + LengthHigh
+	-> Length.
+	* stage2/builtins.c (displaymem_func): Print BaseAddr >> 32,
+	BaseAddr & 0xFFFFFFFF, Length >> 32 and Length & 0xFFFFFFFF,
+	instead of BaseAddrLow, BaseAddrHigh, LengthLow and LengthHigh,
+	for MAP.
+	* stage2/common.c (fakemap): Adjusted to the new definition of
+	AddrRangeDesc.
+	(mmap_avail_at): Change the type of TOP to unsigned long long.
+	If TOP is greater than 0xFFFFFFFF, set it to 0xFFFFFFFF, since
+	GRUB itself cannot deal with 64bits addresses at the moment.
+	(init_bios_info): When getting a maximum available address from
+	the memory map, use a new unsigned long long variable MAX_ADDR
+	as the temporary variable instead of MEMTMP. This should allow
+	GRUB to detect at most 4TB.
+	
+2000-06-18  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/appendices.texi (FAQ): Added an question about Linux's
+	`mem=' option and the answer.
+	
+2000-06-17  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/boot.c (load_image): Pass a mem option to Linux, only
+	if SRC has no substring "mem=".
+	
+2000-06-17  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/compile: Removed.
+	* netboot/compile: Likewise.
+	* compile: New file. Copied from Automake.
+	
+2000-06-16  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/boot.c (load_image): Don't remove the vga option after
+	parsing it. Suggested by Tim Riker.
+
+2000-06-15  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/asm.S (grub_halt): Use jmp instead of jc, if INT 15
+	AX=5307h fails.
+	
+2000-06-15  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* configure.in (AM_INIT_AUTOMAKE): Increase the version number.
+	I wish that 0.5.96 will not be released actually...
+	
+	* stage2/builtins.c (halt_func): New function.
+	(builtin_halt): New variable.
+	(reboot_func): New function.
+	(builtin_reboot): New variable.
+	(builtin_table): Added pointers to BUILTIN_HALT and
+	BUILTIN_REBOOT.
+	* stage2/asm.S (grub_halt): New function.
+	(grub_reboot): Likewise.
+	* stage2/shared.h (grub_halt): Declared.
+	(grub_reboot): Likewise.
+	* grub/asmstub.c (grub_reboot): New function.
+	(grub_halt): Likewise.
+	
+2000-06-12  Gordon Matzigkeit  <gord@fig.org>
+
+	* stage2/stage2.c (run_menu): Don't display the menu if the
+	timeout is zero.  This makes for cleaner use as a noninteractive
+	bootloader.
+
+2000-06-11  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/tutorial.texi (GNU/Linux): Added a caution about the
+	"mem=" option.
+	
+2000-06-11  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* util/grub-install.in (convert): When $host_os is linux*, use
+	the expression 's%\([sh]d[a-z]\)[0-9]*$%\1%' instead of
+	's%[0-9]*$%%', to get rid of the partition part. This fixes the
+	bug "/dev/fd0" -> "/dev/fd". (But don't you think the naming is
+	quite inconsistent with hard disks? Why not /dev/fd[a-z]?)
+	Report by Pavel Roskin.
+	
+2000-06-08  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/tutorial.texi (Network): The body is moved to ...
+	(General usage of network support): ... this new section.
+	(Diskless): New section.
+	* docs/user-ref.texi (General commands): Added a description
+	about the command "tftpserver".
+	
+2000-06-08  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* netboot/main.c (decode_rfc1533) [GRUB]: Eliminate trailing
+	NULs in the NVT string for a configuration file name, if any.
+	(decode_rfc1533): Likewise, if Extensions Path is present,
+	eliminate the trailing NULs, if any.
+	Also, check the length carefully to ensure that EXTPATH can fit
+	in FNAME.
+	
+2000-06-06  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/fsys_reiserfs.c: Added journaling to reiser.
+	(reiserfs_journal_desc): new structure.
+	(reiserfs_journal_commit): likewise.
+ 	(reiserfs_journal_header): likewise.
+	(fsys_reiser_info): Added fields for journaling.
+	(journal_read): new function.
+	(journal_init) likewise.
+	(block_read): New function to read reiserfs blocks, which reads
+	from the journal if it contains newer versions. All relevant
+	devread calls are replaced with calls to this method.
+	(reiserfs_mount): Check for journaling super block and call
+	journal_init.
+
+2000-06-06  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* netboot/main.c (dhcprequest) [GRUB]: Set the length of the
+	Parameter Request List to (4 + 2).
+	Set the list to RFC1533_VENDOR_MAGIC and
+	RFC1533_VENDOR_CONFIGFILE in addition to the standard
+	parameters.
+	(decode_rfc1533) [GRUB]: If C is equal to
+	RFC1533_VENDOR_CONFIGFILE, copy the contents of the tag to
+	CONFIG_FILE.
+	If C is equal to RFC1533_VENDOR_MAGIC, increment
+	VENDOREXT_ISVALID.
+	* netboot/etherboot.h [GRUB] (RFC1533_VENDOR_CONFIGFILE): New
+	macro. Defined as 150.
+	
+2000-06-03  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/asm.S (check_int13_extensions): Check the bitmap only
+	if FORCE_LBA is zero.
+	* stage2/bios.c (get_diskinfo): Get rid of the wrong check for
+	the bit 0 of DRP.FLAGS. Now the bitmap check is correctly
+	performed in the function check_int13_extensions.
+	
+2000-06-02  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/user-ref.texi (Invoking the grub shell): Added a caution.
+	Why don't so many people still understand that BIOS drive
+	numbering are different from OS device naming? How many cautions
+	and warnings should we write in the documentation? Sigh.
+	
+2000-06-01  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Chip Salzenberg:
+	* stage2/cmdline.c (enter_cmdline) [SUPPORT_DISKLESS]: Redisplay
+	network configuration after clearing screen, before first prompt.
+
+	* stage2/cmdline.c: Include <shared.h> instead of "shared.h".
+	[SUPPORT_DISKLESS]: Include <etherboot.h>.
+
+2000-06-01  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (setup_func): Check if INSTALL_DRIVE is a
+	hard disk as well as IMAGE_DRIVE, before trying to install a
+	Stage 1.5. Reported by Pavel Roskin.
+	
+2000-05-31  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* acinclude.m4 (grub_ASM_ABSOLUTE_WITHOUT_ASTERISK): New
+	function. Check if GAS requires absolute indirect calls/jumps
+	with NO asterisk.
+	* configure.in: Call grub_ASM_ABSOLUTE_WITHOUT_ASTERISK.
+	* acconfig.h (ABSOLUTE_WITHOUT_ASTERISK): New macro entry.
+	* netboot/pci.c (bios32_service) [!ABSOLUTE_WITHOUT_ASTERISK]:
+	Prefix the operand to "lcall" with `*'.
+	(pcibios_read_config_byte) [!ABSOLUTE_WITHOUT_ASTERISK]:
+	Likewise.
+	(pcibios_read_config_word) [!ABSOLUTE_WITHOUT_ASTERISK]:
+	Likewise.
+	(pcibios_read_config_dword) [!ABSOLUTE_WITHOUT_ASTERISK]:
+	Likewise.
+	(pcibios_write_config_byte) [!ABSOLUTE_WITHOUT_ASTERISK]:
+	Likewise.
+	(pcibios_write_config_word) [!ABSOLUTE_WITHOUT_ASTERISK]:
+	Likewise.
+	(pcibios_write_config_dword) [!ABSOLUTE_WITHOUT_ASTERISK]:
+	Likewise.
+	(check_pcibios) [!ABSOLUTE_WITHOUT_ASTERISK]: Likewise.
+	* stage2/asm.S (chain_stage1) [!ABSOLUTE_WITHOUT_ASTERISK]:
+	Prefix the operand to "ljmp" with `*'.
+	(chain_stage2) [!ABSOLUTE_WITHOUT_ASTERISK]: Likewise.
+	(big_linux_boot) [!ABSOLUTE_WITHOUT_ASTERISK]: Likewise.
+	
+2000-05-29  Chip Salzenberg  <chip@valinux.com>
+
+	* stage2/shared.h (grub_memmove): Prototype to use void *.
+	* stage2/char_io.c (grub_memmove): Define likewise.
+
+2000-05-30  Gordon Matzigkeit  <gord@fig.org>
+
+	* docs/user-ref.texi (Stage2 errors): Update error messages.
+
+2000-05-29  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* util/grub-install.in: Fix a typo that prevented error messages
+	from appearing.
+	Copy and remove files individually and exit with an error as
+	soon as it fails.
+	Show $log_file if --debug was given on the command line.
+
+2000-04-19  Gordon Matzigkeit  <gord@fig.org>
+
+	* stage2/cmdline.c (enter_cmdline): Don't give errors on empty
+	command lines.
+
+	* stage2/common.c (err_list): Clean up wordings slightly.
+
+2000-05-29  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Based on a patch by Neal H Walfield <neal@walfield.org>:
+	* netboot/misc.c [GRUB] (inet_aton): Defined.
+	* netboot/main.c (arp_server_override): New function.
+	* netboot/etherboot.h [GRUB] (arp_server_override): Declared.
+	(inet_aton): Likewise.
+	* stage2/builtins.c (tftpserver_func): New function.
+	(builtin_tftpserver): New variable.
+	(builtin_table): Added a pointer to BUILTIN_TFTPSERVER.
+	
+2000-05-28  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/asm.S (codestart): Fix a typo: DISKLESS_SUPPORT ->
+	SUPPORT_DISKLESS.
+	* stage2/nbloader.S: Fix the image length and the memory length
+	fields. They shouldn't contain the first sector for a tag.
+	Mmh..., that is unclear as far as I see the Net Boot Image
+	Proposal...
+	* stage2/shared.h (STACKOFF): Enclosed with parentheses.
+	(PROTSTACKINIT): Likewise.
+	
+2000-05-27  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Add diskless support, mostly based on patches by Christoph
+	Plattner <Christoph.Plattner@dot.at>, but also based on a patch
+	by Chip Salzenberg <chip@valinux.com> for PXE. Of course, I've
+	modified both the patches thoroughly to adapt them to my
+	preference.
+
+	* configure.in (--enable-diskless): New option. Set a
+	conditional DISKLESS_SUPPORT.
+	* stage2/Makefile.am (noinst_HEADERS): Added nbi.h.
+	(EXTRA_PROGRAMS): New variable.
+	(pkgdata_DATA) [DISKLESS_SUPPORT]: Added
+	nbgrub and pxegrub.
+	(noinst_DATA) [DISKLESS_SUPPORT]: Added nbloader, pxeloader and
+	diskless.
+	(noinst_PROGRAMS) [DISKLESS_SUPPORT]: Added nbloader.exec,
+	pxeloader.exec and diskless.exec.
+	(PXELOADER_LINK): New variable.
+	(BUILT_SOURCES) [DISKLESS_SUPPORT]: Added diskless_size.h.
+	(diskless_exec_SOURCES): New variable.
+	(diskless_exec_CFLAGS): Likewise.
+	(diskless_exec_LDFLAGS): Likewise.
+	(diskless_exec_LDADD): Likewise.
+	(diskless_size.h): New target.
+	(nbloader_exec_SOURCES): New variable.
+	(nbloader_exec_CFLAGS): Likewise.
+	(nbloader_exec_LDFLAGS): Likewise.
+	(nbloader_exec-nbloader.o): New dependency.
+	(nbgrub): New target.
+	(pxeloader_exec_SOURCES): new variable.
+	(pxeloader_exec_CFLAGS): Likewise.
+	(pxeloader_exec_LDFLAGS): Likewise.
+	(pxegrub): New target.
+	* stage2/asm.S (install_partition): Set to 0xFFFFFF instead of
+	0x020000. What was the benefit from the previous setting?
+	(codestart) [SUPPORT_DISKLESS]: Don't move %dl to BOOT_DRIVE.
+	(boot_drive) [SUPPORT_DISKLESS]: Set to NETWORK_DRIVE instead of
+	zero.
+	* stage2/common.c: Include <shared.h> instead of "shared.h",
+	just for a cosmetic reason.
+	[SUPPORT_DISKLESS]: Include etherboot.h.
+	[SUPPORT_DISKLESS] (setup_diskless_environment): New internal
+	function.
+	(init_bios_info) [SUPPORT_DISKLESS]: Call
+	setup_diskless_environment after the memory initialization is
+	finished. Return if fails.
+	* stage2/nbloader.S: New file.
+	* stage2/pxeloader.S: Likewise.
+	* stage2/nbi.h: Likewise.
+	
+2000-05-25  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* netboot/fsys_tftp.c (buf_fill): Warn when amazing things
+	happen.
+	(tftp_dir): Revert previous change. Don't use TFTP_MIN_PACKET
+	but calculate the appropriate length.
+	
+2000-05-23  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* netboot/fsys_tftp.c (tftp_dir): Append "0\0" to the request
+	string, because the "tsize" option must be followed by zero,
+	according to RFC 2349.
+	
+2000-05-22  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Synchronize the documentation with the code.
+	
+	* docs/user-ref.texi: Added ReiserFS as a supported filesystem.
+	Updated the descriptions about `password', `install', `kernel',
+	and `setup'.
+	Added a description about `lock'.
+	Added descriptions about ERR_UNALIGNED and ERR_PRIVILEGED.
+	Added a description about the option `--force-lba' of
+	the program `grub-install'.
+	* docs/tutorial.texi: Updated the subsection for NetBSD.
+	
+2000-05-21  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/asm.S (set_int13_handler): Don't use MBI to get the
+	lower memory size. Instead, decrease it in the BIOS memory
+	directly and set %eax to it, since MBI.MEM_LOWER may not be the
+	same as [0x413] any longer due to the previous change.
+
+	* grub/asmstub.c (CONVENTIONAL_MEMSIZE): Changed to 640 * 1024
+	from 640. You didn't like the inconsistency between
+	EXTENDED_MEMSIZE and CONVENTIONAL_MEMSIZE, did you?
+	(get_memsize): Return CONVENTIONAL_MEMSIZE >> 10 instead of
+	CONVENTIONAL_MEMSIZE, if TYPE is zero.
+	(get_eisamemsize): Return EXTENDED_MEMSIZE >> 10 instead of
+	EXTENDED_MEMSIZE / 1024. Just a cosmetic change.
+	(MMAR_DESC_LENGTH): New macro. Defined as 20.
+	(get_mmap_entry): Define a new variable DESC_TABLE statically, 
+	and copy the CONTth entry to *DESC if CONT is a correct index.
+	
+2000-05-21  Chip Salzenberg  <chip@valinux.com>
+
+	* stage2/common.c (mmap_avail_at): New function, abstracted out
+	of init_bios_info, to scan E820 memory map.
+	(init_bios_info): Use mmap_avail_at for _both_ MBI.MEM_UPPER and
+	MBI.MEM_LOWER.
+
+2000-05-17  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Update the network support to Etherboot-4.6.1.
+
+	* netboot/config.c (pci_nic_list) [INCLUDE_TULIP]: Added an
+	entry for Davicom 9102.
+	* netboot/epic100.c: Just copied.
+	* netboot/pci.h: Likewise.
+	* netboot/tulip.c: Likewise.
+	* netboot/etherboot.h (tftp): Change the type of the first
+	argument to const char * from char *.
+	* netboot/main.c (tftp): Likewise.
+	
+2000-05-13  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* util/grub-install.in: If the program `cp' fails, exit with the
+	status code 1. Suggested by Pavel Roskin.
+	
+2000-05-13  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Pixel <pixel@mandrakesoft.com>:
+	* stage2/pc_slice.h (PC_SLICE_TYPE_LINUX_EXTENDED): New macro.
+	(IS_PC_SLICE_TYPE_EXTENDED): Added a check for
+	PC_SLICE_TYPE_LINUX_EXTENDED.
+	
+2000-05-05  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/common.c (init_bios_info) [!STAGE1_5]: When the memory
+	map is present, search the maximum for MEMTMP in bytes instead
+	of kilobytes and set EXTENDED_MEMORY to MEMTMP minus 1MB in
+	kilobytes.
+	
+2000-05-05  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Ignore any memory holes when passing the maximum memory address
+	to non-Multiboot kernels (i.e. Linux and *BSD).
+	
+	* stage2/common.c [!STAGE1_5] (extended_memory): New global
+	variable.
+	(init_bios_info) [!STAGE1_5]: Change the type of CONT, MEMTMP
+	and ADDR to unsigned long from int.
+	Set EXTENDED_MEMORY to MBI.MEM_UPPER by default.
+	If MBI.MMAP_LENGTH is not zero, set EXTENDED_MEMORY to the
+	maximum available address, ignoring any memory holes.
+	If MBI.MMAP_LENGTH is zero but get_eisamemsize returns other
+	than -1, set EXTENDED_MEMORY to (CONT >> 10) + 0x3c00 if CONT is
+	non-zero, otherwise, set it to MEMTMP.
+	* stage2/shared.h [!STAGE1_5] (extended_memory): Declared.
+	* stage2/boot.c (load_image): Always pass the "mem=" option to a
+	Linux kernel, using EXTENDED_MEMORY instead of MBI.MEM_UPPER.
+	(bsd_boot): Use EXTENDED_MEMORY instead of MBI.MEM_UPPER.
+	
+2000-04-30  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage1/stage1.S (message): Use lodsb instead of incw and movb.
+	From Andrew Clausen <clausen@gnu.org>.
+
+	* stage1/stage1.S (copy_buffer): Set %cx to 0x100 and use movsw
+	instead of movsb, since it is guaranteed that the region is
+	properly aligned.
+	
+2000-04-29  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (setup_func): Use SECTOR_BITS instead of
+	SECTOR_SIZE to compute BLOCKSIZE.
+
+2000-04-26  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* netboot/depca.c: Copied from Etherboot-4.6.0.
+	
+2000-04-23  OKUJI Yoshinori  <okuji@gnu.org>
+
+	More security-related features.
+	
+	* stage2/builtins.c (auth): New global variable.
+	(configfile_func): Clear AUTH before jumping to cmain.
+	(lock_func): New function.
+	(builtin_lock): New variable.
+	(password_func): Make sure that LEN + 2 is less than or equal to
+	PASSWORD_BUFLEN, because now the password must be terminated
+	with double NULs, in order to permit an empty configuration file
+	name.
+	Copy LEN bytes from ARG to PASSWORD, instead of LEN + 1 bytes.
+	Clear the rest of the buffer PASSWORD.
+	(builtin_table): Added a pointer to BUILTIN_LOCK.
+	* stage2/common.c (err_list): Added an entry for ERR_PRIVILEGED.
+	* stage2/stage2.c (run_menu): If AUTH is true, show the messages
+	for a non-password configuration, even if PASSWORD is not NULL.
+	Likewise, if AUTH is true, allow the user to use privileged
+	instructions (such as `c').
+	If a correct password is entered, check if *PPTR is NUL or not.
+	If it is NUL, set AUTH to 1 and go to the label restart,
+	otherwise, copy PPTR to NEW_FILE, clear AUTH, and return.
+	* stage2/shared.h (grub_error_t): Added a new constant
+	ERR_PRIVILEGED.
+	(auth): Declared.
+	
+2000-04-23  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/user-ref.texi (Command-line-specific commands): Don't use
+	the command @var for the argument "file" to the command
+	"configfile" on the definition.
+	
+2000-04-22  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Update the network support to Etherboot 4.5.8.
+
+	* configure.in (--enable-3c590): New option.
+	(--enable-3c595): Likewise.
+	(--enable-depca): Likewise.
+	(--enable-lance): Likewise.
+	(--enable-ns8390): Likewise.
+	(--enable-ntulip): Likewise.
+	(--enable-lancepci): Removed.
+	(--enable-nepci): Likewise.
+	(--enable-otulip): Likewise.
+	(--enable-smc9000): The duplicated one is named to ...
+	(--enable-smc9000-scan): ... this. This was a typo, perhaps.
+	
+	* netboot/Makefile.am (libdrivers_a_SOURCES): Removed
+	byteorder.h, if.h, netboot_config.h and netdevice.h, and added
+	cards.h.
+	(EXTRA_libdrivers_a_SOURCES): Removed ntulip.c and tulip.h, and
+	added 3c595.c, 3c595.h, depca.c, otulip.c and otulip.h.
+	(libdrivers_a_CFLAGS): Define FSYS_TFTP as 1 instead of empty.
+	(EXTRA_DIST): Removed ntulip.txt, and added cs89x0.txt and
+	tulip.txt.
+	(3c595_drivers): New variable.
+	(depca_drivers): Likewise.
+	(lance_drivers): Removed lancepci.o and added lance.o.
+	(ns8390_drivers): Removed nepci.o and added ns8390.o.
+	(ntulip_drivers): Deleted.
+	(otulip_drivers): New variable.
+	($(3c595_drivers)): New target.
+	($(depca_drivers)): Likewise.
+	($(ntulip_drivers)): Deleted.
+	($(otulip_drivers)): New target.
+	(3c590_o_CFLAGS): New variable.
+	(3c595_o_CFLAGS): Likewise.
+	(depca_o_CFLAGS): Likewise.
+	(lancepci_o_CFLAGS): Deleted.
+	(lance_o_CFLAGS): New variable.
+	(nepci_o_CFLAGS): Deleted.
+	(ns8390_o_CFLAGS): New variable.
+	(ntulip_o_CFLAGS): Deleted.
+	(otulip_o_CFLAGS): New variable.
+	
+	* netboot/3c90x.c: Updated to Etherboot-4.5.8.
+	* netboot/3c90x.txt: Likewise.
+	* netboot/cs89x0.c: Likewise.
+	* netboot/cs89x0.h: Likewise.
+	* netboot/eepro100.c: Likewise.
+	* netboot/epic100.c: Likewise.
+	* netboot/epic100.h: Likewise.
+	* netboot/i82586.c: Likewise.
+	* netboot/lance.c: Likewise.
+	* netboot/linux-asm-io.h: Likewise.
+	* netboot/linux-asm-string.h: Likewise.
+	* netboot/nic.h: Likewise.
+	* netboot/ns8390.c: Likewise.
+	* netboot/ns8390.h: Likewise.
+	* netboot/pci.c: Likewise.
+	* netboot/pci.h: Likewise.
+	* netboot/rtl8139.c: Likewise.
+	* netboot/sk_g16.c: Likewise.
+	* netboot/sk_g16.h: Likewise.
+	* netboot/smc9000.c: Likewise.
+	* netboot/smc9000.h: Likewise.
+	* netboot/tiara.c: Likewise.
+	* netboot/tulip.c: Likewise.
+	* netboot/via-rhine.c: Likewise.
+
+	* netboot/config.c: Updated to Etherboot-4.5.8 and modified (see
+	below).
+	[GRUB] (print_config): Undefined.
+	(eth_probe) [GRUB]: If PROBED is true, do nothing. Otherwise,
+	clear NETWORK_READY and ARPTABLE, set ROM to ROM_INFO_LOCATION,
+	and set PROBED to 1 if succeeds.
+	* netboot/etherboot.h: Likewise,
+	(GRUB): New macro.
+	[GRUB]: Include <shared.h>.
+	[GRUB] (NO_DHCP_SUPPORT): Undefined.
+	[GRUB] (RELOC): Defined as zero.
+	[GRUB] (INTERNAL_BOOTP_DATA): Defined as one.
+	[GRUB] (USE_INTERNAL_BUFFER): Likewise.
+	[GRUB] (BACKOFF_LIMIT): Defined as 7.
+	[GRUB] (CTRL_C): New macro.
+	[GRUB] (print_network_configuration): Declared.
+	[GRUB] (ip_abort): Likewise.
+	[GRUB] (network_ready): Likewise.
+	* netboot/fsys_tftp.c: Don't include <netboot_config.h>.
+	(isocket): Renamed to ...
+	(iport): ... this.
+	(osocket): Renamed to ...
+	(oport): ... this.
+	(bcounter): New variable.
+	(buf_fill): When checking the block order, see BCOUNTER as well
+	as BLOCK.
+	Don't process a packet, if BLOCK minus PREVBLOCK is not 1,
+	instead of if BLOCK is less than or equal to PREVBLOCK.
+	Increment BCOUNTER after reseting RETRY.
+	(send_rrq): Clear BCOUNTER.
+	Call await_reply with AWAIT_QDRAIN.
+	* netboot/main.c: Don't include <netboot_config.h>.
+	(dhcpdiscover): Made const.
+	(dhcprequest): Likewise. Updated the contents.
+	(broadcast): Made const.
+	(udp_transmit): Copied.
+	(tftp): Likewise.
+	(bootp): Likewise.
+	(rarp): Likewise.
+	(await_reply): Likewise.
+	(decode_rfc1533): Likewise.
+	(rfc951_sleep): Likewise.
+	(cleanup_net): Likewise.
+	* netboot/misc.c (sleep): Copied.
+	(twiddle): Likewise.
+	(getdec): Likewise.
+	* netboot/osdep.h: Copied and modified (see below).
+	[GRUB] (ETHERBOOT32): Used the same definition as Linux and
+	FreeBSD.
+	[GRUB] (ntohl): Likewise.
+	[GRUB] (htonl): Likewise.
+	[GRUB] (ntohs): Likewise.
+	[GRUB] (htons): Likewise.
+	[GRUB] (swap32): Likewise.
+	[GRUB] (swap16): Likewise.
+	[GRUB]: Include "linux-asm-io.h".
+
+	* netboot/byteorder.h: Removed.
+	* netboot/if.h: Likewise.
+	* netboot/netboot_config.h: Likewise.
+	* netboot/netdevice.h: Likewise.
+	* netboot/ntulip.c: Likewise.
+	* netboot/ntulip.txt: Likewise.
+	* netboot/tulip.h: Likewise.
+	
+	* netboot/3c595.c: New file. Copied from Etherboot-4.5.8.
+	* netboot/3c595.h: Likewise.
+	* netboot/cards.h: Likewise.
+	* netboot/cs89x0.txt: Likewise.
+	* netboot/depca.c: Likewise.
+	* netboot/otulip.c: Likewise.
+	* netboot/otulip.h: Likewise.
+	* netboot/tulip.txt: Likewise.
+	
+2000-02-29  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/common.c (err_list): Added message for ERR_UNALIGNED.
+	* stage2/shared.h [!STAGE1_5] (disk_read_hook,disk_read_func): New
+ 	parameters offset and length.
+	(ERR_UNALIGNED): New error code.
+	* stage2/disk_io.c (rawread) [!STAGE1_5]: Call disk_read_func with
+	offset and length.
+	* stage2/builtin.c (disk_read_print_func): Print offset and length.
+	(blocklist_func): Print detailed byte ranges for partial sectors.
+	(install_func): Detect partial sectors and print error message.
+
+2000-04-18  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* util/grub-install.in: Don't use `!' in `test' for more
+	portability.
+	Don't use `for' without `in' for compatability with ash.
+	Check install_device before running grub if possible. Added
+	error messages if install_device is not set or not unique.
+	Exit if mkdir fails.
+	Add a message about successful installation.
+	Remove unneeded backslash in the final message.
+	(convert): use `test -b' instead of `test -e' because ash
+	doesn't	understand the later. Correct error message accordingly.
+	
+2000-04-17  OKUJI Yoshinori  <okuji@gnu.org>
+
+	The user doesn't have to recompile GRUB for his/her buggy BIOS
+	any longer. It is configurable to ignore the LBA support bitmap
+	at the installation time.
+	
+	* stage1/stage1.S (force_lba): New variable.
+	(stage2_address): Moved forwards, to align some variables in
+	natural boundaries.
+	(real_start): Check if FORCE_LBA is non-zero, if so, jump to
+	skip_lba_bitmap_check, otherwise, check if bit 0 of the support
+	bitmap is non-zero.
+	Don't use #ifdef for CHECK_LBA_SUPPORT_BITMAP.
+	(skip_lba_bitmap_check): New label.
+	* stage1/stage1.h (COMPAT_VERSION_MINOR): Set to 1.
+	(STAGE1_FORCE_LBA): New macro.
+	(STAGE1_STAGE2_ADDRESS): Set to 0x42.
+	(STAGE1_STAGE2_SECTOR): Set to 0x44.
+	(STAGE1_STAGE2_SEGMENT): Set to 0x48.
+	* stage2/asm.S (force_lba): New variable.
+	* stage2/bios.c (get_diskinfo): Don't use #ifdef for
+	CHECK_LBA_SUPPORT_BITMAP. Instead, check if FORCE_LBA is
+	non-zero. If so, don't check the bit 0 of DRP.FLAG.
+	* stage2/builtins.c (install_func): Check if a new option
+	`--force-lba' is specified. If specified, set IS_FORCE_LBA to 1
+	and set ARG to a value returned by skip_to. Otherwise,
+	IS_FORCE_LBA is zero.
+	Set the "force LBA" flag in STAGE1_BUFFER (the offset is
+	STAGE1_FORCE_LBA) to IS_FORCE_LBA.
+	Likewise, set the "force LBA" flag in STAGE2_SECOND_BUFFER
+	(the offset is STAGE2_FORCE_LBA) to IS_FORCE_LBA.
+	If IS_STAGE1_5 is true, then modify the Stage2, regardless of
+	the presence of the option REAL_CONFIG_FILE. Set the "force LBA"
+	flag in SCRATCHADDR (the offset is STAGE2_FORCE_LBA) to
+	IS_FORCE_LBA.
+	(builtin_install): Added description about `--force-lba' into
+	the docs.
+	(setup_func): Check if `--force-lba' is specified in ARG. If
+	specified, set IS_FORCE_LBA to 1 and set ARG to a value returned
+	by skip_to. Otherwise, IS_FORCE_LBA is zero.
+	If IS_FORCE_LBA is true, prepend "--force-lba " to CMD_ARG.
+	(builtin_setup): Added descriptions about `--force-lba' into the
+	docs.
+	* stage2/shared.h (STAGE2_FORCE_LBA): New macro.
+	(STAGE2_VER_STR_OFFS): Set to 0xe.
+	(force_lba): Declared.
+	* util/grub-install.in (force_lba): New variable. Set to an
+	empty sting by default.
+	(usage): Added a description about `--force-lba'.
+	(--force-lba): Checked in the option handling code. If
+	specified, set FORCE_LBA to "--force-lba".
+	Run the command "setup" with $force_lba added before
+	$install_drive.
+	* configure.in (--disable-lba-support-bitmap): Removed.
+	
+2000-04-15  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* util/grub-install.in (root_device): Append `/' to ${rootdir},
+	since ROOTDIR may be empty. Reported by Satoshi Nagayasu
+	<snaga@oak.forus.or.jp>.
+	
+2000-04-15  Jochen Hoenicke  <jochen@gnu.org>
+
+	* configure.in: Added --disable-reiserfs option.
+	* stage2/Makefile.am (libgrub_a_SOURCES): Added fsys_reiserfs.c.
+	(libgrub_a_CFLAGS): Added -DFSYS_REISERFS=1.
+	(pkgdata_DATA): Added reiserfs_stage1_5.
+	(noinst_PROGRAMS): Added reiserfs_stage1_5.exec.
+	(pre_stage2_exec_SOURCES): Added fsys_reiserfs.c.
+	(reiserfs_stage1_5_exec_SOURCES): New variable.
+	(reiserfs_stage1_5_exec_CFLAGS): Likewise.
+	(reiserfs_stage1_5_exec_LDFLAGS): Likewise.
+	* stage2/disk_io.c (fsys_table): Added reiserfs entry.
+	* stage2/filesys.h (FSYS_REISERFS_NUM): New macro.
+	[FSYS_REISERFS] (reiserfs_mount, reiserfs_read, reiserfs_dir,
+ 	reiserfs_embed): Declare external function from fsys_reiserfs.c.
+	[!NUM_FSYS] (NUM_FSYS): Added FSYS_REISERFS_NUM.
+	* stage2/builtins.c (setup_func): Added reiserfs to
+	STAGE1_5_MAP.
+	* stage2/shared.h (STAGE2_ID_REISERFS_STAGE1_5): New macro.
+	[STAGE1_5] [FSYS_REISERFS] (STAGE2_ID): Defined to
+ 	STAGE2_ID_REISERFS_STAGE1_5.
+	* stage2/fsys_reiserfs.c: New file.
+
+	* stage2/builtins.c (embed_func): Call open_device instead of
+	open_partition.
+	Don't check if the filesystem is FFS. Instead, check if
+	FSYS_TABLE[FSYS_TYPE].EMBED_FUNC is NULL and, if not, call it.
+	(find_func): When CURRENT_SLICE is not a BSD slice, check if the
+	file can be opened, only if open_device succeeds.
+	* stage2/filesys.h (fsys_table): New entry embed_func.
+	(ffs_embed): Declared.
+	* stage2/disk_io.c (fsys_table): Fill embed_func entries. The
+	entry for FFS is ffs_embed and the others are NULLs.
+	* stage2/fsys_ffs.c (ffs_embed): New function.
+
+	* stage2/shared.h (SECTOR_SHIFT): New constant with
+	(1 << SECTOR_SHIFT) == SECTOR_SIZE.
+	* stage2/shared.h [!NO_BLOCK_FILES] (block_files): No longer
+	extern.
+	* stage2/disk_io.c [!NO_BLOCK_FILES] (block_files): Likewise.
+	(rawread, devread): Use SECTOR_BITS.
+	(rawread): Fixed calculation of BUFADDR if an error occured. Set
+	it to BUFFERADDR + BYTE_OFFSET instead of BUFFERSEG +
+	BYTE_OFFSET.
+	(grub_close) [!NO_BLOCK_FILES]: If BLOCK_FILE is non-zero,
+	return immediately.
+	(grub_close): Don't check if FSYS_TYPE is NUM_FSYS.
+	* stage2/fsys_fat.c (log2): New inline function.
+	(fat_mount): Use log2 instead of calculating the size/bit by a
+	loop.
+
+2000-04-12  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* configure.in: Use AC_PATH_PROG instead of AC_PATH_TOOL,
+	because I don't want to use the CVS version. Now you can use
+	autoconf 2.13.
+	
+2000-04-10  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/stage2.c (run_menu): In the case where C is `o', check
+	if ENTRYNO is less than 11. If not, increase FIRST_ENTRY instead
+	of ENTRYNO. Reported by Pixel <pixel@mandrakesoft.com>.
+	
+2000-04-09  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage1/depcomp: Removed, because it makes `make dist'
+	unworkable.
+
+	For developers: Don't run automake with --add-missing. Instead,
+	you should specify --force-missing. If you really want to add a
+	script from automake, copy it at hand. *sigh*
+	
+2000-04-05  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (kernel_func): Added missing ``size''
+	arguments into `grub_memcmp's. Reported by Christoph Plattner
+	<christoph.plattner@dot.at>.
+
+	From Torsten Duwe <duwe@caldera.de>:
+	* stage2/boot.c (load_initrd): Mask the address with 0x3FFFFFFF
+	instead of 0xFFFFFFFF to place the initrd below 1GB.
+	(load_image): In Linux boot, add the option "mem=" only if more
+	than 64MB are present.
+	* grub/asmstub.c [__linux__]: Include <linux/cdrom.h> for
+	CDROM_GET_CAPABILITY.
+	[__FreeBSD__ || __NetBSD__ || __OpenBSD__]: Include <sys/cdio.h>
+	for CDIOCCLRDEBUG.
+	(check_device) [__linux__] [CDROM_GET_CAPABILITY]: If ioctl for
+	CDROM_GET_CAPAIBILITY succeeds, return zero.
+	[__FreeBSD__ || __NetBSD__ || __OpenBSD__] [CDIOCCLRDEBUG]: If
+	ioctl for CDIOCCLRDEBUG succeeds, return zero.
+
+	* stage2/boot.c (load_initrd): Subtract 0x1000 (one page size)
+	from MOVETO, to avoid a Linux 2.3.xx's bug.
+	
+2000-04-03  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Add a dirty hack into the kernel loader so that the user can
+	force GRUB to load NetBSD ELF kernels. The support code is
+	mostly stolen from a patch by Pavel Roskin.
+	
+	* stage2/boot.c (load_image): Added an optional argument
+	SUGGESTED_TYPE.
+	If BUFFER is a bootable ELF image and SUGGESTED_TYPE is
+	KERNEL_TYPE_NETBSD, then load it as an ELF image and set STR2 to
+	"NetBSD" and TYPE to SUGGESTED_TYPE.
+	If the image is a Linux kernel and SUGGESTED_TYPE is not
+	KERNEL_TYPE_NONE, make sure that SUGGESTED_TYPE matches up to
+	the Linux kernel type.
+	If TYPE is KERNEL_TYPE_NETBSD, set MEMADDR to
+	RAW_ADDR (phdr->paddr & 0xFFFFFF) like FreeBSD.
+	If SUGGESTED_TYPE is not KERNEL_TYPE_NONE, make sure that
+	SUGGESTED_TYPE is equal to TYPE.
+	(bsd_boot): If TYPE is not KERNEL_TYPE_FREEBSD (i.e. NetBSD or
+	OpenBSD) and the bit MB_INFO_AOUT_SYMS is set, set END_MARK to
+	MBI.SYMS.A.ADDR + 4 + MBI.SYMS.A.TABSIZE + MBI.SYMS.A.STRSIZE.
+	If the bit is clear, set END_MARK to 0.
+	Pass END_MARK to *ENTRY_ADDR instead of directly calculating the
+	end of symbols.
+	* stage2/shared.h (load_image): Added the argument
+	SUGGESTED_TYPE to the prototype.
+	* stage2/builtins.c (kernel_func): Added a new option,
+	`--type=TYPE'. Check if ARG is started with "--type=".
+	If so, set SUGGESTED_TYPE to KERNEL_TYPE_NETBSD,
+	KERNEL_TYPE_FREEBSD, KERNEL_TYPE_NETBSD, KERNEL_TYPE_LINUX,
+	KERNEL_TYPE_BIG_LINUX, KERNEL_TYPE_MULTIBOOT if ARG is "netbsd",
+	"freebsd", "openbsd", "linux", "biglinux", "multiboot",
+	respectively. Otherwise, set ERRNUM to ERR_BAD_ARGUMENT and
+	return 1. Set KERNEL_ARG to a string after the option.
+	(builtin_kernel): Added a description about the new option.
+	
+2000-04-03  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/stage2.c (run_menu) [GRUB_UTIL]: Removed a nested
+	"#ifdef GRUB_UTIL" ... "#endif".
+	* stage2/builtins.c (unhide_func): Don't modify SAVED_DRIVE or
+	SAVED_PARTITION.
+	(hide_func): Likewise.
+	* stage2/disk_io.c (set_partition_hidden_flag): Use
+	CURRENT_DRIVE and CURRENT_PARTITION instead of SAVED_DRIVE and
+	SAVED_PARTITION. Check if bit 7 in CURRENT_DRIVE is non-zero
+	instead of if CURRENT_DRIVE is non-zero.
+
+	* grub/asmstub.c (init_device_map): Change the message
+	"Probe devices..." to "Probing devices...". Suggested by Neal H
+	Walfield.
+
+	* stage2/pc_slice.h (PC_SLICE_TYPE_HIDDEN_FLAG): Move the
+	definition before the PC partition type definitions.
+	(IS_PC_SLICE_TYPE_FAT): Clear the hidden flag in TYPE before
+	checking if TYPE is either of the FAT partition types. Reported
+	by Thomas Schweikle <tschweikle@fiducia.de>.
+	
+2000-04-02  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (setup_func): Don't read a stage 1.5 to get
+	the size. Use FILEMAX instead.
+	If embed_func fails (i.e. ERRNUM is non-zero), goto fail.
+	
+2000-04-02  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Suggested by Neal H Walfield <neal@walfield.org>:
+	* stage2/common.c (init_bios_info): Removed a nested
+	"#ifndef STAGE1_5" ... "#endif".
+	* util/grub-install.in: Quote most of the references to
+	shell variables by double quotation marks.
+	(usage): Added a description about the argument.
+	* stage2/builtins.c (setup_func): Change each of the messages
+	when running embed_func and install_func. "Run" -> "Running".
+	If install_func succeeds, print a message ("Done.").
+
+	From Frank Mehnert <fm3@os.inf.tu-dresden.de>:
+	* stage2/char_io.c (convert_to_ascii) [!STAGE1_5]: Accept 'X'
+	and 'b' as well. If C is 'X' or 'b', then set MULT to 16.
+	(grub_printf): Set a new variable MASK to 0xFFFFFFFF by default.
+	Mask *DATAPTR with MASK when calling convert_to_ascii.
+	(grub_printf) [!STAGE1_5]: Added 'b' and 'X'. If C is 'b', set
+	MASK to 0xFF and fall through to the case 'u'. 'X' is the same
+	as 'x'.
+
+	From Josip Rodin <joy@cibalia.gkvk.hr>:
+	* grub.texi: Several awkward English sentences are fixed.
+	* tutorial.texi: Likewise.
+	* user-ref.texi: Likewise.
+	* appendices.texi: Likewise.
+	
+2000-03-27  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage1/depcomp: New file. Automake forces to install it. This
+	is a known bug, so I will remove this when Tom fixes it.
+	* configure.in (AM_INIT_AUTOMAKE): Don't get the package name
+	and the version from debian/changelog. This is a workaround.
+	
+2000-03-20  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/Makefile.am (nodist_pkgdata_DATA): Renamed to ...
+	(pkgdata_DATA): ... this. DATA is not distributed by default.
+	(CLEANFILES): Delete the first one. I don't know why this
+	variable was duplicated.
+	Set to $(pkgdata_DATA) instead of $(nodist_pkgdata_DATA).
+	(start_exec_DEPENDENCIES): Removed. This doesn't make sense.
+	(start_exec-start.o): New rule.
+	* depcomp: New file. Copied from automake.
+	* missing: Updated from automake.
+	
+2000-03-15  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* netboot/Makefile.am (EXTRA_libdrivers_a_SOURCES): 3c89x0.h ->
+	cs89x0.h. Just a typo.
+	
+2000-03-10  Gordon Matzigkeit  <gord@fig.org>
+
+	* debian/rules: Strip mbchk.
+
+	* debian/postinst: Fix up /usr/doc symlink creation.
+
+2000-03-01  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* netboot/fsys_tftp.c (tftp_dir): Add BUF_READ into FILEMAX
+	after BUF_EOF becomes non-zero. Reported by Per Lundberg.
+	
+2000-03-01  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (color_func): Return 1 if safe_parse_maxint
+	returns zero instead of non-zero. Reported by Magnus Holmberg
+	<pucko@lysator.liu.se>.
+	
+2000-02-29  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* grub/asmstub.c [__linux__]: Include <linux/kdev_t.h> for the
+	macro MAJOR. From Kalle Olavi Niemitalo <tosi@ees2.oulu.fi>.
+	
+2000-02-27  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/tutorial.texi (Network): New chapter.
+	
+2000-02-26  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/help2man: Upgraded to 1.020.
+	* docs/grub.8: Regenerated.
+	* docs/grub-install.8: Likewise.
+	* docs/mbchk.1: Likewise.
+
+	* docs/tutorial.texi (Boot): Rewritten heavily. Added the notes
+	on FreeBSD, NetBSD, OpenBSD, DOS/Windows and SCO UnixWare.
+	* docs/menu.lst: Load "/boot/loader" instead of "/kernel" in the
+	FreeBSD entry. This is consistent with the documentation.
+	
+2000-02-25  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* netboot/fsys_tftp.c (tftp_read): Set BUF_READ to zero if
+	FILEPOS is less than SAVED_FILEPOS, before calling buf_fill.
+	Don't discard all of the copied data so that we can move FILEPOS
+	backwards cheaply. Now SAVED_FILEPOS indicates the file position
+	corresponding to the first byte of BUF. If (FILEPOS -
+	SAVED_FILEPOS) is greater than (FSYS_BUFLEN / 2), move the data
+	forwards and add (FSYS_BUFLEN / 2) into SAVED_FILEPOS and
+	subtract the same value from BUF_READ.
+	
+2000-02-24  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/disk_io.c [!STAGE1_5] (print_fsys_type): Mask
+	CURRENT_SLICE with 0xFF when printing the partition type.
+
+	* grub/asmstub.c [__linux__]: Include <linux/major.h> for the
+	definition FLOPPY_MAJOR.
+	(check_device) [__linux__]: Skip the HDIO_GETGEO ioctl if the
+	major number of ST.ST_RDEV is FLOPPY_MAJOR.
+	
+2000-02-21  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/disk_io.c (check_BSD_parts) [!STAGE1_5]: Use the term
+	"BSD sub-partition" instead of "BSD slice" for consistency.
+
+	* stage2/builtins.c (boot_func): Copy the partition table to
+	BOOT_PART_TABLE instead of (BOOTSEC_LOCATION +
+	BOOTSEC_PART_OFFSET). Don't use grub_memmove, but copy it
+	directly, since memcheck is too strict.
+	* stage2/disk_io.c (real_open_partition) [!STAGE1_5]: Set
+	CUR_PART_ADDR to (BOOT_PART_TABLE + (i << 4)).
+	* stage2/shared.h (BOOT_PART_TABLE): New macro.
+	(chain_stage1): Change the types of all the arguments to
+	unsigned long.
+	(chain_stage2): Likewise.
+	* grub/asmstub.c (chain_stage1): Adjusted to the prototype.
+	(chain_stage2): Likewise.
+	
+2000-02-21  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/disk_io.c (check_BSD_parts) [!STAGE1_5]: If the BSD
+	label is invalid, print a message with the partition type in the
+	case where FLAGS is non-zero and DO_COMPLETION is zero.
+	
+2000-02-20  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/user-ref.texi (Command-line-specific commands): Added a
+	description about "cmp".
+	* docs/appendices.texi (Reporting bugs): Rewritten.
+	
+2000-02-20  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Update the netboot code to Etherboot 4.4.3.
+	
+	* netboot/netboot_config.h: Copied from etherboot-4.4.3.
+	* netboot/cs89x0.h: Likewise.
+	* netboot/cs89x0.c: Likewise.
+	* netboot/i82586.c: Likewise.
+	* netboot/lance.c: Likewise.
+	* netboot/linux-asm-string.h: Likewise.
+	* netboot/nic.h: Likewise.
+	* netboot/ntulip.c: Likewise.
+	* netboot/osdep.h: Likewise.
+	* netboot/pci.h: Likewise.
+	* netboot/pci.c: Likewise.
+	* netboot/rtl8139.c: Likewise.
+	* netboot/tiara.c: Likewise.
+	
+2000-02-19  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (cmp_func): New function.
+	(builtin_cmp): New variable.
+	(builtin_table): Added a pointer to BUILTIN_CMP.
+
+	* stage2/fsys_fat.c (fat_mount): Check if BPB.SECTS_PER_CLUST is
+	zero after reading the BPB to avoid zero division.
+	
+2000-02-18  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/disk_io.c [!STAGE1_5] (make_saved_active): Make sure
+	that SAVED_PARTITION is not an extended partition.
+	If SAVED_DRIVE is not a hard disk drive, set ERRNUM to
+	ERR_DEV_VALUES and return zero.
+
+	* netboot/3c59x.c: Removed.
+	* netboot/Makefile.am (EXTRA_libdrivers_a_SOURCES): Deleted
+	3c59x.c.
+	(3c59x_drivers): Deleted.
+	(3c59x_o_CFLAGS): Likewise.
+	* configure.in (--enable-3c59x): Likewise.
+	
+2000-02-17  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* configure.in (--enable-3c90x): Add -DINCLUDE_3C90X=1 instead
+	of -DINCLUDE_3C90x=1. This was just a typo. Reported by Per
+	Lundberg.
+	
+2000-02-17  Jochen Hoenicke  <jochen@gnu.org>
+	
+	* stage2/fsys_fat.c (fat_read): Forgot to increase BUF.
+	(fat_dir): Use fat_read instead of grub_read; this makes
+	setting the FSMAX unnecessary.
+	(fat_mount): FSMAX is no longer set.
+	
+2000-02-16  Jochen Hoenicke  <jochen@gnu.org>
+
+	* stage2/char_io.c (grub_isspace): Make carriage return a white
+	space.
+	
+	* stage2/fsys_fat.c (fat_dir): Long filename support.
+	(NAME_BUF): New macro.
+	* stage2/fat.h (FAT_LONGDIR_ID, FAT_LONGDIR_ALIASCHECKSUM,
+	FAT_ATTRIB_LONGNAME): New Macros.
+
+	* stage2/fsys_fat.c (fat_create_blocklist): Deleted, instead
+	fat_read is implemented.
+	(fat_read): new function.
+	* stage2/disk_io.c (fsys_table): Use fat_read.
+	* stage2/filesys.h: Declare fat_read, remove NO_BLOCK_FILES
+	hack.
+	* stage2/Makefile.am: Compile fat_stage1_5 with
+	-DNO_BLOCK_FILES=1.
+	
+	* stage2/fat.h (fat_bpb): New structure describing bpb.
+	(FAT_CVT_U16): New macro.
+	(FAT_BPB_CHECK_SIG, FAT_BPB_NUM_SECTORS,
+	FAT_BPB_BYTES_PER_SECTOR, FAT_BPB_SECT_PER_CLUS, FAT_BPB_NUMFAT,
+	FAT_BPB_RESERVED_SECTORS, FAT_BPB_FAT_SECTORS_16,
+	FAT_BPB_FAT_SECTORS_32, FAT_BPB_IS_FAT32, FAT_BPB_FAT_SECTORS,
+	FAT_BPB_FAT_START, FAT_BPB_ROOT_DIR_CLUSTER,
+	FAT_BPB_HIDDEN_SECTORS, FAT_BPB_ROOT_DIR_START,
+	FAT_BPB_ROOT_DIR_LENGTH, FAT_BPB_DATA_OFFSET,
+	FAT_BPB_NUM_CLUST): Macros removed.
+	* stage2/fsys_fat.c (fat_superblock): New structure containing
+	all info about currently mounted filesystem.
+	(FAT_SUPER): New Macro.
+	(BPB): Macro removod.
+	(fat_mount): Use fat_bpb structure, fill FAT_SUPER.
+	(fat_read, fat_dir): Use FAT_SUPER info.
+
+2000-02-16  OKUJI Yoshinori  <okuji@gnu.org>
+
+	Pass the boot partition information to a chain-loader, in the
+	partition table area of the loader, instead of right before the
+	loaded address. Reported by takehiro@coral.ocn.ne.jp (Takehiro
+	Suzuki).
+	
+	* stage2/builtins.c (chainloader_func): Embed the partition
+	table of the boot drive in the partition table area of the
+	chain-loader, if the boot drive is a hard disk drive.
+	Pass BOOT_PART_ADDR instead of (BOOTSEC_LOCATION - 16) as the
+	third argument for the function chain_stage1.
+	* stage2/disk_io.c [!STAGE1_5] (boot_part_addr): New variable.
+	[!STAGE1_5] (boot_part_offset): Likewise.
+	[!STAGE1_5] (cur_part_offset): Likewise.
+	[!STAGE1_5] (cur_part_addr): Likewise.
+	[!STAGE1_5] (cur_part_desc): Removed.
+	(real_open_partition) [!STAGE1_5]: Set CUR_PART_OFFSET and
+	CUR_PART_ADDR to PART_OFFSET and (BOOTSEC_LOCATION +
+	PC_SLICE_OFFSET + (i << 4)), respectively.
+	[!STAGE1_5] (set_bootdev): Set BOOT_PART_OFFSET and
+	BOOT_PART_ADDR to CUR_PART_OFFSET and CUR_PART_ADDR,
+	respectively.
+	* stage2/shared.h (boot_part_addr): Declared.
+	(boot_part_offset): Likewise.
+	
+2000-02-12  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (geometry_func): Attempt to read the first
+	sector to examine if LBA mode is really supported.
+
+	* netboot/fsys_tftp.c (buf_fill) [TFTP_DEBUG]: Added some debug
+	messages.
+	(send_rrq) [TFTP_DEBUG]: Likewise.
+	(tftp_read) [TFTP_DEBUG]: Likewise.
+	(tftp_dir) [TFTP_DEBUG]: Likewise.
+	(tftp_close) [TFTP_DEBUG]: Likewise.
+	(tftp_read): Call buf_fill with the argument 1 first, if FILEPOS
+	has been moved backwards, and use grub_memmove for copying
+	SAVED_TP to TP instead of a direct assignment.
+	If send_rrq fails, set ERRNUM to ERR_WRITE instead of ERR_READ.
+	Check if BUF_READ is zero instead of if BUF_EOF is non-zero at
+	the end of the loop.
+	(tftp_dir): Set ERRNUM to ERR_WRITE instead of ERR_READ, if
+	send_rrq fails.
+	Save TP and LEN in SAVED_TP and SAVED_LEN respectively before
+	buf_fill instead of after it, because it destroys the contents
+	of TP.
+	* netboot/main.c (print_network_configuration): The order of the
+	arguments for grub_sprintf in the local function sprint_ip_addr
+	is reversed.
+
+	* configure.in (--enable-packet_retransmission): Renamed to ...
+	(--disable-packet-retransmission): ... this. Assume that a
+	network	is congested by default.
+	
+2000-02-11  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Pavel Roskin:
+	* stage2/shared.h [!GRUB_SHARED_HEADER] (GRUB_SHARED_HEADER):
+	Defined.
+	[GRUB_SHARED_HEADER]: Don't declare or define anything.
+
+	* netboot/main.c (print_network_configuration): New function.
+	(await_reply): Check for Control-C instead of ESC, because GRUB
+	already uses ESC for another purpose.
+	(rfc951_sleep): Check for the key input in the loop. If
+	Control-C is pushed, return immediately.
+	* netboot/etherboot (print_network_configuration): Declared.
+	(CTRL_C): New macro.
+	(ESC): Undefined.
+	* netboot/config.c (eth_probe): Clear ARPTABLE after clearing
+	NETWORK_READY.
+	* stage2/builtins.c (bootp_func): Call
+	print_network_configuration if bootp succeeds.
+	(rarp_func): Call print_network_configuration if rarp succeeds.
+	
+2000-02-11  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Per Lundberg <plundis@byggdok.se>:
+	* docs/multiboot.texi: Added graphics support.
+	
+2000-02-10  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/multiboot.texi (Top): Downgrade the version to 0.6.90,
+	since we need more work to release it as 0.7.
+	
+2000-02-10  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/Makefile.am [NETBOOT_SUPPORT] (STAGE2_COMPILE): Added
+	-I$(top_srcdir)/netboot and -DSUPPORT_NETBOOT=1.
+	* stage2/builtins.c (bootp_func): New function.
+	(dhcp_func): Likewise.
+	(rarp_func): Likewise.
+	(builtin_bootp): New variable.
+	(builtin_dhcp): Likewise.
+	(builtin_rarp): Likewise.
+	(builtin_table): Added pointers to BUILTIN_BOOTP, BUILTIN_DHCP
+	and BUILTIN_RARP.
+	* docs/user-ref.texi (General Commands): Added descriptions
+	about "bootp", "dhcp" and "rarp".
+	
+	* netboot/main.c (bootp) [!NO_DHCP_SUPPORT]: Added casts to
+	suppress gcc warnings.
+	(decode_rfc1533) [!NO_DHCP_SUPPORT]: Likewise.
+	* netboot/3c90x.c: Include the local "pci.h" instead of
+	<linux/pci.h> even if __FreeBSD__ is undefined.
+	
+2000-02-09  OKUJI Yoshinori  <okuji@gnu.org>
+
+	From Jochen Hoenicke:
+	* stage2/fsys_fat.c (fat_create_blocklist): The previous change
+	is reversed. Set FIRST_FAT_ENTRY to a unsigned long value in
+	FAT_BUF + (NEW_MAPBLOCK - MAPBLOCK) instead of a unsigned short
+	value. Mask FIRST_FAT_ENTRY with 0xFFF if FAT_SIZE is equal to
+	3, whether the bit 0 of LAST_FAT_ENTRY is set or not.
+
+	* netboot/config.c (eth_probe): If PROBED is set to non-zero,
+	return 1 without probing ethernet cards. Clear NETWORK_READY. If
+	*T->ETH_PROBE return sucessfully, set PROBED to 1.
+	* netboot/main.c (rarp): Call eth_probe and return zero if
+	fails. Clear NETWORK_READY at first, and set NETWORK_READY to 1
+	if RETRY is less than MAX_ARP_RETRIES. If IP_ABORT is non-zero,
+	return zero instead of one.
+	(bootp): Call eth_probe and return zero if fails. Clear
+	NETWORK_READY at first, and set NETWORK_READY to 1 if
+	await_reply returns successfully.
+	(bootp) [T509HACK]: If FLAG is non-zero, skip calling
+	await_reply. Don't call await_reply here any more.
+	(bootp) [!NO_DHCP_SUPPORT]: If any ack packet is not reached
+	within MAX_BOOTP_RETRIES times, return zero. If DHCP_REPLY isn't
+	DHCPOFFER, set NETWORK_READY to one and return one.
+	* netboot/etherboot.h (NO_DHCP_SUPPORT): Undefined.
+
+	* stage2/builtins.c (print_root_device): Use the macro
+	NETWORK_DRIVE instead of 0x20.
+	* stage2/disk_io.c [!STAGE1_5] (sane_partition): Likewise.
+	(real_open_partition) [!STAGE1_5]: Likewise.
+	(set_device) [!STAGE1_5]: Likewise.
+	
+2000-02-08  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* grub/asmstub.c (biosdisk) [__linux__]: Use _llseek when
+	__GLIBC_MINOR__ is less than 1 even if __GLIBC__ is 2. Reported
+	by Goran Koruga <goran.koruga@hermes.si>.
+
+	* configure.in (--disable-lba-support-bitmap-check): New option.
+	Don't define CHECK_LBA_SUPPORT_BITMAP if specified.
+	* stage1/stage1.S (real_start): Check if AH=0x42 is supported if
+	CHECK_LBA_SUPPORT_BITMAP instead of NO_BUGGY_BIOS_IN_THE_WORLD
+	is defined.
+	* stage2/bios.c (get_diskinfo): Check if LBA read/write
+	functions are supported iff CHECK_LBA_SUPPORT_BITMAP is defined,
+	instead of NO_BUGGY_BIOS_IN_THE_WORLD.
+	
+2000-02-07  OKUJI Yoshinori  <okuji@gnu.org>
+
+	The netboot support is heavily rewritten, based on
+	Etherboot-4.4.2. The current one doesn't work yet, so check out
+	GRUB with the tag "dresden_netboot_code" if you need working
+	one.
+	
+	* configure.in (--enable-tftp): Deleted.
+	(FSYS_CFLAGS): `AC_SUBST'ed right before AC_OUTPUT.
+	(NETBOOT_DRIVERS): New variable. AC_SUBST this after examining
+	the driver options.
+	(--enable-packet-retransmission): New option.
+	(--enable-pci-direct): Likewise.
+	(--enable-3c509): Likewise.
+	(--enable-3c529): Likewise.
+	(--enable-3c90x): Likewise.
+	(--enable-cs89x0): Likewise.
+	(--enable-epic100): Likewise.
+	(--enable-3c507): Likewise.
+	(--enable-exos205): Likewise.
+	(--enable-ni5210): Likewise.
+	(--enable-lancepci): Likewise.
+	(--enable-ne2100): Likewise.
+	(--enable-ni6510): Likewise.
+	(--enable-3c503): Likewise.
+	(--enable-ntulip): Likewise.
+	(--enable-rtl8139): Likewise.
+	(--enable-sk-g16): Likewise.
+	(--enable-smc9000): Likewise.
+	(--enable-tiara): Likewise.
+	(--enable-tulip): Likewise.
+	(--enable-via-rhine): Likewise.
+	(--enable-3c503-shmem): Likewise.
+	(--enable-3c503-aui): Likewise.
+	(--enable-3c509-hack): Likewise.
+	(--enable-compex-rl2000-fix): Likewise.
+	(--enable-smc9000-scan): Likewise.
+	(--enable-t503): Deleted.
+	(--enable-lance): Likewise.
+	(--enable-cs): Likewise.
+
+	* netboot/main.c: New file. Copied and modified.
+	* netboot/linux-asm-io.h: Likewise.
+	* netboot/etherboot.h: Likewise.
+	* netboot/misc.c: Likewise.
+	* netboot/via-rhine.c: Likewise.
+	* netboot/3c90x.c: Likewise.
+	* netboot/3c90x.txt: Likewise.
+	* netboot/epic100.c: Likewise.
+	* netboot/epic100.h: Likewise.
+	* netboot/i82586.c: Likewise.
+	* netboot/linux-asm-string.h: Likewise.
+	* netboot/ntulip.c: Likewise.
+	* netboot/ntulip.txt: Likewise.
+	* netboot/osdep.h: Likewise.
+	* netboot/rtl8139.c: Likewise.
+	* netboot/sk_g16.c: Likewise.
+	* netboot/sk_g16.h: Likewise.
+	* netboot/smc9000.c: Likewise.
+	* netboot/smc9000.h: Likewise.
+	* netboot/tiara.c: Likewise.
+	* netboot/tulip.c: Likewise.
+	* netboot/tulip.h: Likewise.
+	* netboot/README.netboot: New file. Most information is stolen
+	from Makefile and Config.32 in Etherboot.
+	* netboot/3c509.c: Copied from Etherboot. The original is
+	removed.
+	* netboot/3c509.h: Likewise.
+	* netboot/cs89x0.c: Likewise.
+	* netboot/eepro100.c: Likewise.
+	* netboot/lance.c: Likewise.
+	* netboot/ns8390.c: Likewise.
+	* netboot/ns8390.h: Likewise.
+	* netboot/pci.c: Likewise.
+	
+	* netboot/3c59x.c: Include etherboot.h instead netboot.h.
+	* netboot/config.c: Copied from Etherboot and added the 3c59x
+	entries.
+	* netboot/pci.h: Likewise.
+	* netboot/fsys_tftp.c: Entirely rewritten based on main.c in
+	Etherboot.
+
+	* netboot/io.h: Removed.
+	* netboot/ip.h: Likewise.
+	* netboot/ip.c: Likewise.
+	* netboot/netboot.h: Likewise.
+	
+	* netboot/Makefile.am (INCLUDES): Added -I$(top_srcdir)/stage2.
+	(DRIVERS): Removed.
+	(libdrivers_a_SOURCES): Added etherboot.h, linux-asm-io.h,
+	linux-asm-string.h, main.c, misc.c and osdep.h. Deleted io.h,
+	ip.h, ip.c, netboot.h and $(DRIVERS).
+	(EXTRA_libdrivers_a_SOURCES): New variable.
+	(libdrivers_a_LIBADD): Set to @NETBOOT_DRIVERS@.
+	(libdrivers_a_DEPENDENCIES): New variable.
+	(EXTRA_DIST): Likewise.
+	(3c509_drivers): New variable. Define a new rule for the value.
+	(3c59x_drivers): Likewise.
+	(3c90x_drivers): Likewise.
+	(cs89x0_drivers): Likewise.
+	(eepro100_drivers): Likewise.
+	(epic100_drivers): Likewise.
+	(i82586_drivers): Likewise.
+	(lance_drivers): Likewise.
+	(ns8390_drivers): Likewise.
+	(ntulip_drivers): Likewise.
+	(rtl8139_drivers): Likewise.
+	(sk_g16_drivers): Likewise.
+	(smc9000_drivers): Likewise.
+	(tiara_drivers): Likewise.
+	(tulip_drivers): Likewise.
+	(via_rhine_drivers): Likewise.
+	(t503_o_CFLAGS): Removed.
+	(nepci_o_CFLAGS): Set to -DINCLUDE_NEPCI=1.
+	(ne_o_CFLAGS): Set to -DINCLUDE_NE=1.
+	(wd_o_CFLAGS): Set to -DINCLUDE_WD=1.
+	(3c509_o_CFLAGS): Likewise.
+	(3c529_o_CFLAGS): Likewise.
+	(3c59x_o_CFLAGS): Likewise.
+	(3c90x_o_CFLAGS): Likewise.
+	(cs89x0_o_CFLAGS): Likewise.
+	(eepro100_o_CFLAGS): Likewise.
+	(epic100_o_CFLAGS): Likewise.
+	(3c507_o_CFLAGS): Likewise.
+	(exos205_o_CFLAGS): Likewise.
+	(ni5210_o_CFLAGS): Likewise.
+	(lancepci_o_CFLAGS): Likewise.
+	(ne2100_o_CFLAGS): Likewise.
+	(ni6510_o_CFLAGS): Likewise.
+	(3c503_o_CFLAGS): Likewise.
+	(ntulip_o_CFLAGS): Likewise.
+	(rtl8139_o_CFLAGS): Likewise.
+	(sk_g16_o_CFLAGS): Likewise.
+	(smc9000_o_CFLAGS): Likewise.
+	(tiara_o_CFLAGS): Likewise.
+	(tulip_o_CFLAGS): Likewise.
+	(via_rhine_o_CFLAGS): Likewise.
+
+	* stage2/char_io.c (nul_terminate): Changed the type of the
+	return value to int. Return the original character changed to
+	NUL.
+	* stage2/shared.h (NETWORK_DRIVE): New macro.
+	(nul_terminate): Adjusted to the definition.
+	* stage2/gunzip.c (gunzip_test_header): Removed the TFTP check
+	entirely. It is no longer necessary because we now can obtain
+	the correct size of a file even for TFTP.
+	
+2000-02-07  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/asm.S: Undo the previous changes. Is
+	binutils-2.9.5.0.25 too strict to retain the compatibility?
+	Reported by Kalle Olavi Niemitalo <tosi@ees2.oulu.fi>.
+	
+2000-02-03  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/cmdline.c (enter_cmdline): Set BUF_DRIVE to -1 before
+	running a command to invalidate the cache.
+	(run_script): Likewise.
+	* stage2/char_io.c (get_cmdline): Set BUF_DRIVE to -1 before the
+	completion to invalidate the cache.
+	Reported by Jeff Sheinberg <jeffsh@erols.com>.
+
+	* configure.in: Use AC_PATH_TOOL instead of AC_PATH_PROG.
+	* stage2/asm.S (chain_stage1): Prepend `*' to the argument for
+	ljmp.
+	(chain_stage2): Likewise.
+	(big_linux_boot): Likewise.
+	
+2000-01-19  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* util/grub-install.in (--root): Renamed to ...
+	(--root-directory): ... this, since "root" is vague.
+	* docs/user-ref.texi (Invoking grub-install): Adjusted to the
+	change above, and added an example how to use --root-directory.
+	* docs/grub-install.8: Regenerated.
+
+	* docs/appendices.texi (FAQ): Added an item about the sucked
+	SCSI problem.
+	
+2000-01-15  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (chainloader_func): If --force is specified
+	in ARG, don't check for the signature.
+	* docs/tutorial.texi (Chain-loading): Added a caution about some
+	defective boot loaders and --force.
+	* docs/user-ref.texi (Command-line-specific commands): Added a
+	description about --force.
+	
+2000-01-11  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/prog-ref.texi (LBA mode disk I/O): Added a footnote about
+	a buggy BIOS.
+	
+2000-01-11  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage1/stage1.S [!NO_BUGGY_BIOS_IN_THE_WORLD]: Don't check if
+	LBA read is supported. Anyway, fallback to the CHS mode if
+	fails.
+	
+2000-01-10  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/bios.c (NO_INT13_FALLBACK): Undefined.
+	(get_diskinfo) [!NO_BUGGY_BIOS_IN_THE_WORLD]: Do not check if
+	bit 0 in DRP.FLAGS is set, because at least one BIOS does not
+	set it correctly. Reported by "Forever shall I be."
+	<zinx@linuxfreak.com>.
+
+	* util/grub-install.in: Handle the new options `--root' and
+	`--grub-shell'.
+	(rootdir): New variable.
+	(usage): Print the help messages about the options --root and
+	--grub-shell.
+	(bootdir): Initialized after the option analysis.
+	(grubdir): Likewise.
+	(device_map): Likewise.
+	(root_device): Set to the result for the directory ROOTDIR
+	instead of "/".
+	* docs/user-ref.texi (Invoking grub-install): Added the
+	descriptions about --root and --grub-shell.
+	* docs/grub-install.8: Regenerated.
+	
+2000-01-08  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* util/grub-install.in (grubdir_device): New variable.
+	If GRUBDIR_DEVICE is not equal to ROOT_DEVICE, print an error
+	message and exit.
+	* README: Added a caution about Automake.
+	* TODO: Updated. Only the things that should be done until 0.6
+	have one or more exclamations. Things with zero exclamation
+	will be done after 0.6 unless someone sends a patch for it.
+	
+2000-01-05  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* grub/asmstub.c: Include the header shared.h after including
+	all the system headers, but not before.
+	(EXTENDED_MEMSIZE): Reduced to 3MB.
+	(grub_setjmp): New function.
+	(grub_longjmp): Likewise.
+	* grub/main.c: Include setjmp.h.
+	* stage2/asm.S (grub_setjmp): New function. Stolen from the
+	OSKit (which stole it from Mach).
+	(grub_longjmp): Likewise.
+	* stage2/shared.h [GRUB_UTIL] (grub_jmp_buf): New type.
+	[!GRUB_UTIL] (grub_jmp_buf): New macro. Defined as jmp_buf.
+	(grub_setjmp): Declared.
+	(grub_longjmp): Likewise.
+	(restart_env): Likewise.
+	* stage2/builtins.c (configfile_func): Use grub_longjmp instead
+	of invoking cmain again.
+	* stage2/stage2.c (restart_env): New variable.
+	(cmain): Call grub_setjmp first to initialize RESTART_ENV.
+	
+2000-01-03  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* docs/multiboot.texi (Boot information format): Added the
+	descriptions about the fields "config_table" and
+	"boot_loader_name".
+	
+1999-12-31  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (setup_func) [!NO_BUGGY_BIOS_IN_THE_WORLD]:
+	Specify the option `d', whether INSTALL_DRIVE is identical with
+	IMAGE_DRIVE or not.
+	* docs/user-ref.texi (Command-line-specific commands): Added a
+	caution about buggy BIOSes which don't pass a booting drive
+	properly.
+
+	* docs/src2texi: Added an extra space into the first line, for
+	the portability issue.
+
+	* docs/appendices.texi (Obtaining and Building GRUB): Update the
+	information on the ftp site and the CVS repository.
+	
+1999-12-30  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/builtins.c (blocklist_func): New function.
+	(builtin_blocklist): New variable.
+	(builtin_table): Added a pointer to BUILTIN_BLOCKLIST.
+	* docs/user-ref.texi (Command-line-specific commands): Added a
+	description about the command "blocklist".
+	
+1999-12-30  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* stage2/disk_io.c (grub_seek): New function.
+	* stage2/shared.h (grub_seek): Declared.
+	* stage2/boot.c (load_image): Use grub_seek instead of setting
+	FILEPOS to a new value directly.
+	* stage2/builtins.c (install_func): Likewise.
+	(testload_func): Likewise.
+
+	* docs/grub.texi: Use a single direntry command for all the
+	entries instead of one per entry.
+	
+1999-12-29  OKUJI Yoshinori  <okuji@gnu.org>
+
+	* grub/asmstub.c (check_device) [__linux__]: Check if DEVICE is
+	a CD-ROM drive by the HDIO_GETGEO ioctl. If so, then return
+	zero. Reported by Pavel Roskin.
+
+	* stage2/Makefile.am (nodist_noinst_DATA): Renamed to ...
+	(noinst_DATA): ... this. The primary DATA is `nodist' by
+	default, at least theoretically. Reported by Klaus Reichl.
+
+	* stage2/bios.c (get_diskinfo): Set the LBA flag in GEOMETRY
+	only if bit 0 in DRP.FLAGS is set. Reported by Zack Weinberg
+	<zack@rabi.columbia.edu>.
+
+	From Pavel Roskin:
+	* grub/asmstub.c (init_device_map): Increase the number of
+	devices to be probed to 8 for IDE disks and 16 for SCSI
+	disks. Reported by Anton Anisimov <aa@bestlinux.net>.
+	
+1999-12-06  Gordon Matzigkeit  <gord@fig.org>
+
+	* README (DEVELOPERS): Change CVS location to subversions.
+
+1999-11-30  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/disk_io.c (real_open_partition): If SLICE_NO is greater
+	than or equal to PC_SLICE_MAX, skip any extended partition, when
+	searching for the right partition. Reported by Weil, Stefan 3732
+	EPE-24 <Stefan.Weil@de.heidelberg.com>.
+
+1999-11-19  Gordon Matzigkeit  <gord@fig.org>
+
+	* grub/asmstub.c (getkey): Stop immediately if we get an EOF.
+
+	* stage2/stage2.c (cmain): Tell enter_cmdline to run forever.
+	(run_menu): Tell print_cmdline_message and enter_cmdline that we
+	won't run forever.
+	* stage2/cmdline.c (enter_cmdline): New argument, FOREVER, for
+	when ESC shouldn't allow an exit.  Pass it to
+	print_cmdline_message.
+	(print_cmdline_message): Use new argument, FOREVER, to decide
+	whether to tell the user that ESC exits.
+
+1999-11-18  Gordon Matzigkeit  <gord@fig.org>
+
+	* debian/rules (binary-arch): Don't strip or generate shared
+	library dependencies for /usr/sbin/grub-install, since it's a
+	script.
+
+	* util/grub-install.in: Create safe temporary log files using
+	/bin/tempfile if it is executable.
+
+1999-11-17  Gordon Matzigkeit  <gord@fig.org>
+
+	* stage1/Makefile.am (LDFLAGS): Consolidate multiple -Wl flags.
+	* stage2/Makefile.am (PRE_STAGE2_LINK): Likewise.
+	(START_LINK): Likewise.
+	(STAGE1_5_LINK): Likewise.
+
+1999-11-19  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* util/grub-install.in (debug): New variable.
+	(convert): If the device file does not exist, then emit an
+	error. Get the GRUB drive instead of the OS device.
+	If --debug is specified, then set $debug to yes.
+	If $debug is yes, run "set -x".
+	Make sure that stage1 and stage2 exist.
+	When checking for INSTALL_DEVICE, use "case" instead of "elif"s.
+	Make sure that $install_drive is not empty.
+	Likewise, make sure that $root_drive is not empty.
+	Any error message is redirected to the standard error.
+
+1999-11-19  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* stage2/Makefile.am (noinst_DATA): Renamed to ...
+	(nodist_noinst_DATA): ... this.
+	* util/Makefile.am: sbin_SCRIPS -> sbin_SCRIPTS.
+	* util/grub-install.in: grub_dir -> grubdir.
+	Check if $grub_shell exists before running it.
+	(convert): Added a missing "test" after "if".
+
+1999-11-18  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* configure.in: Output grub-install.
+	* util/Makefile.am (sbin_SCRIPTS): New variable.
+	* util/grub-install.in: New file.
+	* docs/Makefile.am (man_MANS): Added grub-install.8.
+	[MAINTAINER_MODE] ($(srcdir)/grub-install.8): New target.
+	* docs/grub-install.8: New file. Generated by help2man.
+	* docs/user-ref.texi (Invoking grub-install): New chapter.
+
+1999-11-16  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From Pavel Roskin:
+	* stage1/stage1.S: Check for the API subset support bitmap
+	returned by INT 13 AH=48h, and jump to chs_mode if AH=42h is not
+	supported.
+
+1999-11-13  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/builtins.c (install_func): When using a Stage 1.5, set
+	CURRENT_DRIVE to SAVED_DRIVE and CURRENT_PARTITION to
+	SAVED_PARTITION if set_device fails. If CURRENT_DRIVE is equal
+	to SRC_DRIVE, then set CURRENT_DRIVE to 0xFF. We don't want to
+	embed any drive number whenever possible.
+	* stage2/disk_io.c (set_device) [STAGE1_5]: Always set
+	CURRENT_PARTITION to PARTITION.
+
+1999-11-13  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From Pavel Roskin:
+	* stage1/stage1.S (lba_mode): Jump to chs_mode if INT 13 AH=42h
+	fails.
+
+1999-11-12  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	Do not use the device map file unless --device-map is specified.
+
+	* grub/main.c (device_map_file): Set to 0.
+	(default_device_map_file): Removed.
+	(usage): Do not print DEFAULT_DEVICE_MAP_FILE.
+	* grub/asmstub.c (init_device_map): If DEVICE_MAP_FILE is NULL,
+	do not try to open the device map file.
+	Set FP to NULL by default.
+	* docs/grub.8: Regenerated.
+
+1999-11-11  Michael Hohmuth  <hohmuth@innocent.com>
+
+	* stage2/boot.c (load_image): grub_close was called after
+	return, so exchange the order.
+	* stage2/stage1_5.c (cmain): Call grub_close after grub_read.
+	Set RET to the value returned by grub_read, and if RET is
+	non-zero, call chain_stage2.
+	* stage1/Makefile.am (BUILT_SOURCES): Removed.
+	(CLEANFILES): Set to $(nodist_pkgdata_DATA).
+
+1999-11-11  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	Suggested by Klaus Reichl:
+	* stage2/builtins.c (print_root_device): New function.
+	(root_func): If no argument is specified, call the function
+	print_root_device and return.
+	(rootnoverify_func): Likewise.
+	* stage2/disk_io.c [!STAGE1_5] (print_completions): Call
+	print_error even if IS_FILENAME is zero.
+	If ERRNUM is non-zero, then return -1.
+	* stage2/char_io.c [!STAGE1_5] (get_cmdline): Clear ERRNUM after
+	calling print_completions to print the list as well.
+
+	* stage2/asm.S [!STAGE1_5] (currticks): Set %eax to %cx:%dx
+	correctly. Reported by Michael Hohmuth.
+
+1999-11-06  Klaus Reichl  <Klaus.Reichl@alcatel.at>
+
+	* grub/asmstub.c (get_diskinfo) [__linux__]: After opening the
+	drive, flush the cache, other progs may have left over something
+	in the cache.
+
+1999-11-03  Gordon Matzigkeit  <gord@fig.org>
+
+	* debian/rules: Add variables for cross-compilation.
+
+	* debian/control (Standards-Version): Update to version 3.1.0.
+	* debian/rules (build): Install manpages into /usr/share/man, and
+	info into /usr/share/info in accordance with FHS.
+	(binary-arch): Likewise, and put docs into /usr/share/doc.
+	* debian/postinst: Use /usr/share/info, and manage compatibility
+	/usr/doc/grub -> /usr/share/doc/grub symlink.
+	* debian/prerm: Likewise.
+
+	* stage2/Makefile.am (CLEANFILES): Change to
+	$(nodist_pkgdata_DATA) so that the raw binary files are deleted.
+	* stage1/Makefile.am (CLEANFILES): Likewise.
+
+1999-11-06  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* grub/asmstub.c (grub_putchar) [HAVE_LIBCURSES]: Do not call
+	wrefresh. This was just an accident. Sorry.
+
+	Reported by Alan McLean <amcl@flash.net>:
+	* stage2/builtins.c (embed_func): The sector argument for the
+	function biosdisk is changed from SECTOR + I * SECTOR_SIZE to
+	SECTOR + I.
+	(find_func): Clear ERRNUM before each of the attempts.
+
+1999-11-05  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* docs/multiboot.texi (Boot information format): Add the members
+	`drives_addr' and `drives_count' into the Multiboot information
+	structure, and added the descriptions.
+
+1999-11-03  Gordon Matzigkeit  <gord@fig.org>
+
+	* util/mbchk.c (main): Move the version number inside the
+	parentheses since it is the GRUB package version, not just an
+	mbchk-specific version.
+
+1999-10-30  Gordon Matzigkeit  <gord@fig.org>
+
+	* debian/rules (binary-arch): Compress man pages.
+	Strip the grub shell.
+	Install examples.
+
+1999-11-03  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* docs/tutorial.texi: Fix typos by ispell.
+	* docs/user-ref.texi: Likewise.
+	* docs/prog-ref.texi: Likewise.
+	* docs/appendices.texi: Likewise.
+
+1999-11-03  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/fsys_ext2fs.c (struct ext2_dir_entry): Changed the type
+	of `name_len' to __u8 and added the new member `file_type' after
+	it. This is stolen from linux/ext2_fs.h in Linux 2.2.13.
+	Reported by Ben Harris <bjh21@cam.ac.uk>.
+
+	* stage2/builtins.c (device_func) [GRUB_UTIL]: Call
+	nul_terminate before calling check_device.
+
+1999-11-02  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/disk_io.c (real_open_partition): Check for the right
+	partition for any extended partition as well. Set EXT to I after
+	the check is done. Reported by Jeff Scheinberg
+	<jeffsh@erols.com>.
+
+	* stage2/builtins.c (color_func): Use the function
+	nul_terminate.
+	(device_func) [GRUB_UTIL]: Likewise.
+	(help_func): Likewise.
+	(install_func): Save CURRENT_DRIVE, CURRENT_PARTITION and
+	BUG_GEOM in SRC_DRIVE, SRC_PARTITION and SRC_GEOM respectively,
+	and use them when patching the Stage 2.
+	NUL-terminate the configuration filename CONFIG_FILENAME.
+	If IS_STAGE1_5 is true, then check if the "real config file"
+	option is present, and, if so, patch the Stage 2 CONFIG_FILENAME
+	with the configuration filename REAL_CONFIG_FILENAME.
+	(setkey_func): Use nul_terminate instead of the local function
+	null_terminate.
+	* stage2/char_io.c [!STAGE1_5] (nul_terminate): New function.
+	* stage2/shared.h (nul_terminate): Declared.
+
+1999-11-01  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* docs/grub.texi: Add "I/O ports detection" into the menu.
+	* docs/user-ref.texi: Added a description about the command
+	"ioprobe".
+	* docs/prog-ref.texi (I/O ports detection): New chapter.
+
+1999-11-01  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From Pavel Roskin:
+	* stage2/asm.S (int1_handler): Use EXT_C(io_map) instead of
+	io_map.
+	(int1_handler): Use EXT_C(bios_key_map) instead of bios_key_map.
+	* grub/asmstub.c [__OpenBSD__]: Include <sys/ioctl.h> and
+	<sys/disklabel.h>.
+	[__OpenBSD__] (get_floppy_disk_name): Added support for OpenBSD.
+	[__OpenBSD__] (get_ide_disk_name): Likewise.
+	[__OpenBSD__] (get_scsi_disk_name): Likewise.
+	(get_drive_geometry) [__OpenBSD__]: Use for OpenBSD the same
+	ioctl as for NetBSD and FreeBSD.
+
+1999-10-31  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* grub/asmstub.c (init_device_map): Add a floppy device name
+	into the device map file even if check_device fails.
+	* stage2/char_io.c [!STAGE1_5] (get_cmdline): Clear ERRNUM after
+	calling print_completions.
+
+1999-10-29  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/asm.S (track_int13): Defined unconditionally. Do not
+	use int3 any more, but replace the int13 handler with
+	set_tf_int13_handler.
+	(int1_handler): Defined unconditionally. Do not check for 0x0F.
+	Add missing `$'s. If the code is 0xEC-0xEF, use %dx instead of
+	immediate. If the code is 0xE4-0xE7, use immediate instead of
+	%dx. Set %ds to zero before scanning IO_MAP. Check for the
+	buffer overrun of IO_MAP before adding a port.
+	[!DEFINE_TRACK_INT13] (int13_first_instruction): Removed.
+	[!DEFINE_TRACK_INT13] (int3_handler): Likewise.
+	(set_tf_int13_handler): New interrupt handler.
+	(set_tf_int13_offset): New variable.
+	(set_tf_int13_segment): Likewise.
+	* stage2/builtins.c (ioprobe_func): New function.
+	(builtin_ioprobe): New variable.
+	(builtin_table): Added a pointer to BUILTIN_IOPROBE.
+	* stage2/shared.h (IO_MAP_SIZE): New macro.
+	(track_int13): Declared.
+	(io_map): Likewise.
+
+1999-10-29  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/char_io.c (print_error) [!STAGE1_5]: Print "Error:"
+	before print the error message.
+	(print_error): Do not clear ERRNUM.
+	* stage2/cmdline.c (run_script): If ERRNUM is non-zero, set
+	ERRNUM to ERR_NONE.
+	(enter_cmdline): Clear ERRNUM after print_error.
+
+1999-10-28  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From Pavel Roskin:
+	* stage2/stage2.c (run_menu) [GRUB_UTIL]: Do not use IBM special
+	characters in the message, but use ascii names instead.
+	(run_menu) [!GRUB_UTIL]: Use DISP_UP and DISP_DOWN instead of
+	the ascii codes.
+	* stage2/shared.h [!ACS_ULCORNER] (ACS_ULCORNER): New macro.
+	[!ACS_ULCORNER] (ACS_URCORNER): Likewise.
+	[!ACS_ULCORNER] (ACS_LLCORNER): Likewise.
+	[!ACS_ULCORNER] (ACS_LRCORNER): Likewise.
+	[!ACS_ULCORNER] (ACS_HLINE): Likewise.
+	[!ACS_ULCORNER] (ACS_VLINE): Likewise.
+	[!ACS_ULCORNER] (ACS_LARROW): Likewise.
+	[!ACS_ULCORNER] (ACS_RARROW): Likewise.
+	[!ACS_ULCORNER] (ACS_UARROW): Likewise.
+	[!ACS_ULCORNER] (ACS_DARROW): Likewise.
+	[GRUB_UTIL] (DISP_UL): Set to ACS_ULCORNER.
+	[GRUB_UTIL] (DISP_UR): Set to ACS_URCORNER.
+	[GRUB_UTIL] (DISP_LL): Set to ACS_LLCORNER.
+	[GRUB_UTIL] (DISP_LR): Set to ACS_LRCORNER.
+	[GRUB_UTIL] (DISP_HORIZ): Set to ACS_HLINE.
+	[GRUB_UTIL] (DISP_VERT): Set to ACS_VLINE.
+	[GRUB_UTIL] (DISP_LEFT): Set to ACS_LARROW.
+	[GRUB_UTIL] (DISP_RIGHT): Set to ACS_RARROW.
+	[GRUB_UTIL] (DISP_UP): Set to ACS_UARROW.
+	[GRUB_UTIL] (DISP_DOWN): Set to ACS_DARROW.
+
+1999-10-28  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/builtins.c (keycode_func): Removed.
+	(builtin_keycode): Likewise.
+	(struct keysym): New structure.
+	(keysym_table): New variable.
+	(setkey_func): New function.
+	(builtin_setkey): New variable.
+	(builtin_table): Removed the pointer to BUILTIN_KEYCODE, and
+	added a pointer to BUILTIN_SETKEY.
+	* stage2/common.c [!STAGE1_5] (err_list): Added
+	ERR_BAD_ARGUMENT.
+	* stage2/shared.h (grub_error_t): Added ERR_BAD_ARGUMENT.
+	(KEY_MAP_SIZE): Set to 128.
+	(ascii_key_map): Declared.
+	* stage2/asm.S [!STAGE1_5] (remap_ascii_char): New function.
+	[!STAGE1_5] (ascii_key_map): New variable.
+	[!STAGE1_5] (getkey): Call remap_ascii_char after int16.
+	[!STAGE1_5] (checkkey): Likewise.
+	* grub/asmstub.c (ascii_key_map): New variable.
+	* docs/user-ref.texi (General commands): Added a description
+	about the command "setkey".
+	(Stage2 errors): Added a description about ERR_BAD_ARGUMENT.
+
+1999-10-27  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/disk_io.c (set_device) [!STAGE1_5]: Remove the
+	preliminary Mach-style device name support. I've decided that
+	the support is not necessary.
+	(setup_part) [!STAGE1_5]: Do not strip the leading "/dev/".
+	* docs/help2man: Upgraded to 1.016.
+	* docs/mbchk.1: Regenerated.
+	* docs/grub.8: Likewise.
+	* grub/asmstub.c: Rename KEY_MAP to BIOS_KEY_MAP.
+
+	* stage2/asm.S [!STAGE1_5] (set_int15_handler): Use 0 instead of
+	the maximum number for the segment.
+	[!STAGE1_5] (unset_int15_handler): Likewise.
+	[!STAGE1_5] (int15_handler): Almost rewritten. If non-carrier,
+	ignore the scancode. If the scancode is E1 or E0, then set
+	INT15_SKIP_FLAG to 0x74, and if the previous scancode is E1 or
+	E0, set INT15_SKIP_FLAG to 0xea. Clear bit 7 in %dl. Save bit 7
+	of %al in %bl. Do not lcall. Use ljmp instead.
+	[!STAGE1_5] (key_map): Renamed to ...
+	[!STAGE1_5] (bios_key_map): ... this.
+	* stage2/builtins.c (keycode_func): Check if FROM is greater
+	than 0xff instead of double-checking for TO. Use BIOS_KEY_MAP
+	instead of KEY_MAP.
+	* stage2/shared.h (KEY_MAP_SIZE): Set to 32.
+	(key_map): Removed.
+	(bios_key_map): Declared.
+
+1999-10-26  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	Now the BIOS drive remapping is functional.
+
+	* stage2/asm.S [DEFINE_TRACK_INT13] (track_int13): Use %edi
+	instead of direct addresses.
+	Prefix DATA32 to the calls for real_to_prot and prot_to_real.
+	Fix the address of DRIVE: 4(%ebp) -> 8(%ebp).
+	(set_int15_handler): Use %edi instead of direct addresses.
+	(unset_int15_handler): Likewise.
+	(set_int13_handler): Copy DRIVE_MAP_SIZE * 2 bytes instead of
+	DRIVE_MAP_SIZE bytes of MAP.
+	Fix the address of MAP: 4(%ebp) -> 8(%ebp).
+	Use %edi instead of direct addresses.
+	(int13_handler): Do not set %ds to %cs. Use the segment override
+	prefix of %cs instead.
+	Push the flags pushed by the callee instead of the current.
+	Set the flags in the stack to the flags returned by the original
+	int13 call.
+	(drive_map): 4bytes-aligned.
+	* stage2/disk_io.c (grub_close): Do not set ERRNUM even if
+	FSYS_TYPE is NUM_FSYS.
+
+1999-10-25  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage1/stage1.S: Long jump to real_start, because some bogus
+	BIOSes jump to 07C0:0000 instead of 0000:7C00.
+	(real_start): New label.
+	* docs/Makefile.am (grub.info): Removed. Use the default rule
+	instead.
+
+1999-10-25  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/asm.S [DEFINE_TRACK_INT13] (int3_handler): Save the
+	modified FLAGS in 6(%bp) instead of 4(%bp).
+	Decrease %bx before restoring the first instruction.
+	[DEFINE_TRACK_INT13] (track_int13): Go to the real mode before
+	setting up the registers for the int13 call.
+
+1999-10-24  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	Add the prototype of a function to probe I/O ports used for a
+	BIOS drive.
+
+	* stage2/asm.S [DEFINE_TRACK_INT13] (track_int13): New function.
+	[DEFINE_TRACK_INT13] (int1_handler): New interrupt handler for
+	the real mode.
+	[DEFINE_TRACK_INT13] (int3_handler): Likewise.
+	[DEFINE_TRACK_INT13] (io_map): New variable.
+
+	* stage2/builtins.c (quit_func) [!GRUB_UTIL]: Fix a typo.
+
+1999-10-24  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	The new GRUB manual becomes official.
+
+	* docs/grub.texi: Replaced with new-grub.texi.
+	* docs/new-grub.texi: Removed.
+	* docs/Makefile.am (grub_TEXINFOS): New variable.
+	(UNFINISHED_MANUALS): Removed.
+	(EXTRA_DIST): Deleted $(UNFINISHED_MANUALS).
+
+1999-10-24  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/builtins.c (device_func) [!GRUB_UTIL]: Set ERRNUM to
+	ERR_UNRECOGINIZED and return 1.
+	(impsprobe_func) [GRUB_UTIL]: Likewise.
+	(quit_func) [!GRUB_UTIL]: Likewise.
+	* docs/tutorial.texi: Rename "Device Syntax" to "Filename".
+	Added many cross-references.
+	* docs/new-grub.texi: "Device Syntax" -> "Filename".
+	* docs/user-ref.texi: Fix typos and added some cross-references.
+	* docs/prog-ref.texi: Likewise.
+	* docs/appendices.texi: Likewise.
+
+1999-10-23  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/builtins.c (map_func): If BIOS_DRIVE_MAP already
+	contains FROM, override the existsing entry.
+	If TO is equal to FROM, delete the existing entry if any.
+	(keycode_func): Likewise.
+	* docs/user-ref.texi (Command): Use the list of `@deffn's
+	instead of @table.
+	(Basic usage): Use @option instead of @code.
+	(Invoking mbchk): Likewise.
+
+1999-10-23  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/asm.S [!STAGE1_5] (set_int15_handler): New function.
+	[!STAGE1_5] (unset_int15_handler): Likewise.
+	[!STAGE1_5] (int15_handler): New interrupt handler for the real
+	mode.
+	[!STAGE1_5] (int15_offset): New variable.
+	[!STAGE1_5] (int15_segment): Likewise.
+	[!STAGE1_5] (key_map): Likewise.
+	[!STAGE1_5] (set_int13_handler): Use the macro ABS for
+	INT13_OFFSET and INT13_SEGMENT.
+	* stage2/shared.h (KEY_MAP_SIZE): New macro.
+	(set_int15_handler): Declared.
+	(unset_int15_handler): Likewise.
+	* stage2/builtins.c (boot_func): Do not allow I to be equal to
+	DRIVE_MAP_SIZE.
+	Call unset_int15_handler unless KERNEL_TYPE is KERNEL_TYPE_NONE.
+	(map_func): Search for an empty slot till I is less than
+	DRIVE_MAP_SIZE.
+	Check if I is equal to DRIVE_MAP_SIZE instead of if I is greater
+	than DRIVE_MAP_SIZE.
+	(keycode_func): New function.
+	(builtin_keycode): New variable.
+	(builtin_table): Added a pointer to BUILTIN_KEYCODE.
+	* grub/asmstub.c (set_int15_handler): New function.
+	(unset_int15_handler): Likewise.
+	(key_map): New variable.
+
+1999-10-23  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From Michael Hohmuth <hohmuth@innocent.com>:
+	* acconfig.h (HAVE_USCORE_USCORE_BSS_START_SYMBOL): Added the
+	`undef' entry.
+	(HAVE_EDATA_SYMBOL): Likewise.
+	(HAVE_USCORE_EDATA_SYMBOL): Likewise.
+	* acinclude.m4 (grub_CHECK_USCORE_USCORE_BSS_START_SYMBOL): New
+	function.
+	(grub_CHECK_EDATA_SYMBOL): Likewise.
+	(grub_CHECK_USCORE_EDATA_SYMBOL): Likewise.
+	* configure.in: Check for __bss, edata and _edata.
+	* netboot/Makefile.am (DRIVERS): Deleted ns8390.c and ns8390.h.
+	(libdrivers_a_LIBADD): New variable.
+	($(libdrivers_a_LIBADD)): New target.
+	(nepci_o_CFLAGS): New variable.
+	(ne_o_CFLAGS): Likewise.
+	(wd_o_CFLAGS): Likewise.
+	(t503_o_CFLAGS): Likewise.
+	* netboot/fsys_tftp.c (tftp_close): New function.
+	* stage2/boot.c (load_image): Call grub_close before return.
+	(load_initrd): Likewise.
+	(load_module): Likewise.
+	* stage2/builtins.c (cat_func): Likewise.
+	(chainloader_func): Likewise.
+	(configfile_func): Likewise.
+	(embed_func): Likewise.
+	(find_func): Likewise.
+	(install_func): Set IS_OPEN to the value returned by grub_open.
+	If IS_OPEN is non-zero, call grub_close before return.
+	(setup_func): Call grub_close after grub_open.
+	(testload): Call grub_close before return.
+	* stage2/disk_io.c (fsys_table): Add the `close' member into
+	each of the entries. For TFTP, tftp_close is added, and for the
+	rest, NULL is added.
+	(grub_read): "|" -> "||".
+	(grub_close): New function.
+	* stage2/filesys.h [FSYS_TFTP] (tftp_close): Declared.
+	(struct fsys_entry): Added close_func.
+	* stage2/shared.h (grub_close): Declared.
+	* stage2/stage1_5.c (cmain): Call grub_close after grub_open.
+	* stage2/stage2.c (cmain): Clear ERRNUM after calling
+	find_command to just ignore the error code.
+	Call grub_close after loading the configuration file.
+
+	* stage2/asm.S (main): Clean out the bss.
+
+1999-10-23  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* docs/new-grub.texi: Updated.
+	* docs/user-ref.texi: Likewise.
+	* docs/tutorial.texi: Likewise.
+	* docs/prog-ref.texi: Likewise.
+	* docs/appendices.texi: Likewise.
+
+1999-10-22  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* docs/prog-ref.texi: New file.
+	* docs/appendices.texi: Likewise.
+	* docs/Makefile.am (UNFINISHED_MANUALS): Added prog-ref.texi and
+	appendices.texi.
+
+1999-10-22  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* docs/user-ref.texi: New file.
+	* docs/Makefile.am (UNFINISHED_MANUALS): Added user-red.texi.
+
+1999-10-21  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	Add BIOS drive remapping support for chain-loading some foolish
+	operating systems.
+
+	* stage2/builtins.c (bios_drive_map): New variable.
+	(boot_func): If KERNEL_TYPE is KERNEL_TYPE_CHAINLOADER, check
+	if BIOS_DRIVE_MAP contains meaningful values. If so, search for
+	SAVED_DRIVE in BIOS_DRIVE_MAP and exchange SAVED_DRIVE with the
+	mapped drive if found. And then call set_int13_handler.
+	(map_func): New function.
+	(builtin_map): New variable.
+	(builtin_table): Added a pointer to BUILTIN_MAP.
+	* stage2/asm.S (ABS): New macro.
+	[!STAGE1_5] (set_int13_handler): New function.
+	[!STAGE1_5] (int13_handler): New interrupt handler for the real
+	mode.
+	[!STAGE1_5] (drive_map): New variable.
+	[!STAGE1_5] (int13_handler_end): New label used for just
+	computing the end address of int13_handler.
+	* stage2/shared.h (DRIVE_MAP_SIZE): New macro.
+	(set_int13_handler): Declared.
+	* grub/asmstub.c (set_int13_handler): New function. Do nothing.
+
+1999-10-20  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/builtins.c (find_func): Print only the device names.
+	* docs/tutorial.texi: New file.
+	* docs/Makefile.am (UNFINISHED_MANUALS): Added tutorial.texi.
+	(%.c.texi): Use $(SHELL) instead of /bin/sh.
+	(%.h.texi): Likewise.
+	(%.S.texi): Likewise.
+
+1999-10-20  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/char_io.c (memcheck): Fix the checks: "<=" -> "<".
+	Reported by Mike Hicks <hick0088@umn.edu>.
+
+1999-10-19  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/builtins.c (find_func): New function.
+	(builtin_find): New variable.
+	(hide_func): Save SAVED_DRIVE and SAVED_PARTITION to TMP_DRIVE
+	and TMP_PARTITION, respectively, and resotre them before return.
+	(unhide_func): Likewise.
+	(setup_func): Likewise. And set SAVED_DRIVE and SAVED_PARTITION
+	instead of CURRENT_DRIVE and CURRENT_PARTITION to IMAGE_DRIVE
+	and IMAGE_PARTITION before running install_func.
+	(builtin_table): Added a pointer to BUILTIN_FIND.
+
+1999-10-19  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* docs/Makefile.am (UNFINISHED_MANUALS): New variable.
+	(EXTRA_DIST): Added $(UNFINISHED_MANUALS).
+	* docs/new-grub.texi: New file.
+
+1999-10-19  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* docs/Makefile.am (man_MANS): Added mbchk.1.
+	[MAINTAINER_MODE] (mbchk.1): New target.
+	* docs/mbchk.1: New file. Generated by help2man.
+
+1999-10-18  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* Makefile.am (SUBDIRS): Added util.
+	* configure.in: Output util/Makefile.
+	* util/Makefile.am: New file.
+	* util/mbchk.c: Likewise.
+	* util/Makefile.in: Likewise. Generated by automake.
+
+1999-10-17  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* docs/Makefile.am (.texi): Canceled because the dependecies can
+	be circulated.
+	* stage2/builtins.c (embed_func): Set BUF_TRACK to -1 before
+	writing	the Stage 1.5 to the disk to clear the cache.
+
+1999-10-17  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/boot.c (load_initrd): Change types of *RAMDISK and
+	MOVETO to unsigned long.
+	Apply the macro RAW_ADDR to MOVETO.
+
+1999-10-16  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* docs/multiboot.texi: Include the example source files of a
+	Multiboot kernel.
+	* docs/src2texi: New file.
+	* docs/boot.S: Likewise.
+	* docs/multiboot.h: Likewise.
+	* docs/kernel.c: Likewise.
+	* docs/boot.S.texi: Likewise.
+	* docs/multiboot.h.texi: Likewise.
+	* docs/kernel.c.texi: Likewise.
+	* docs/Makefile.am (EXAMPLES): New varilable.
+	(multiboot_TEXINFOS): Likewise.
+	(SRC2TEXI): Likewise.
+	(noinst_SCRIPTS): Added $(SRC2TEXI).
+	(EXTRA_DIST): Added $(EXAMPLES) and $(multiboot_TEXINFOS).
+	(%.c.texi): New target.
+	(%.h.texi): Likewise.
+	(%.S.texi): Likewise.
+
+1999-09-22  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+        * multiboot.texi (BIOS device mapping techniques): New section.
+        Stolen from bios_mapping.txt in grub-0.5.
+        (Data comparison technique): New subsection.
+        (I/O restriction technique): Likewise.
+        (Example OS code): Rewrited from scratch.
+
+1999-09-21  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+        * multiboot.texi: Rename Multiboot Standard to Multiboot
+        Specification and upgrade the version to 0.7. Many cleanups
+        are done.
+
+1999-10-15  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/builtins.c (setup_func): Save CURRENT_DRIVE and
+	CURRENT_PARTITION into IMAGE_DRIVE and IMAGE_PARTITION
+	respectively, and restore them before running install_func.
+	Use DEVICE instead of BUFFER to store the device name.
+	Change each type of STAGE1, STAGE2 and CONFIG_FILE to an array
+	of char.
+	If installing the Stage 1 into a MBR, embed the Stage 1.5 in the
+	sectors right after it.
+	Return the result of install_func instead of zero.
+
+1999-10-14  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* configure.in: Check for opendisk in libutil.
+	* grub/asmstub.c [__FreeBSD__ || __NetBSD__]: Include
+	<sys/ioctl.h>.
+	[HAVE_OPENDISK]: Include <util.h>.
+	[__NetBSD__] (get_floppy_disk_name): Added support for NetBSD.
+	[__NetBSD__ && HAVE_OPENDISK] (get_ide_disk_name): Likewise.
+	[__NetBSD__ && HAVE_OPENDISK] (get_scsi_disk_name): Likewise.
+	(get_drive_geometry) [__NetBSD__]: Use for NetBSD the same ioctl
+	as for FreeBSD.
+
+1999-10-13  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* grub/asmstub.c (assign_device_name): If DEVICE is NULL, set
+	DEVICE_MAP[DRIVE] to NULL.
+	(get_diskinfo): If open or read fails, call assign_device_name
+	to disable accessing the drive DRIVE.
+	(grub_stage2): The device mapping routine is moved to ...
+	(init_device_map): ... here. This new function also reads/writes
+	a device map file. If DEVICE_MAP_FILE already exists, then use
+	the data in it instead of probing devices. Otherwise, guess the
+	map between BIOS drives and OS devices, and write it to the file
+	DEVICE_MAP_FILE if it can be opened.
+	* grub/main.c (device_map_file): New variable.
+	(default_device_map_file): Likewise.
+	(OPT_DEVICE_MAP): New macro.
+	(longopts): Added an entry for "device-map".
+	(usage): Print the usage about --device-map as well.
+	(main): Set DEFAULT_DEVICE_MAP_FILE to DEVICE_MAP_FILE. If
+	OPT_DEVICE_MAP is found, set DEVICE_MAP_FILE to a duplicated
+	string of OPTARG.
+	* stage2/shared.h [GRUB_UTIL] (device_map_file): Declared.
+	* docs/grub.8: Regenerated.
+
+1999-10-13  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/builtins.c (color_func): Do not set NORMAL_COLOR or
+	HIGHLIGHT_COLOR directly, but use NEW_NORMAL_COLOR and
+	NEW_HIGHLIGHT_COLOR as temporary storages instead.
+	New internal function `color_number' is used to convert a
+	symbolic color representation into a color number.
+	Try color_number at first, and if fails, then try
+	safe_parse_maxint for each of NORMAL and HIGHLIGHT.
+	(builtin_color): The long doc does not describe the raw number
+	syntax but the symbolic color name syntax.
+	* docs/grub.texi (Commands): Adjusted to the long doc of
+	BUILTIN_COLOR.
+	* docs/menu.lst: Add examples of "fallback" and "color".
+
+1999-10-13  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/char_io.c [!STAGE1_5] (get_cmdline): If C is a newline
+	or a return, then set LPOS to LLEN and call the function
+	cl_setcpos.
+	[!STAGE1_5] (grub_strncat): New function.
+	* stage2/builtins.c (embed_func): New function.
+	(builtin_embed): New varilable.
+	(setup_func): New function.
+	(builtin_setup): New varilable.
+	(builtin_table): Added a pointer to BUILTIN_EMBED and a pointer
+	to BUILTIN_SETUP.
+	* stage2/shared.h (grub_strncat): Declared.
+
+	* stage2/Makefile.am (stage2_size.h): ../stage2/stage2 ->
+	pre_stage2. Reported by Pavel Roskin.
+
+1999-10-12  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From Pavel Roskin:
+	* acinclude.m4 (grub_PROG_OBJCOPY_ABSOLUTE): main -> cmain.
+	* stage2/boot.c (load_image): Only CUR_ADDR, not ENTRY_ADDR
+	should be 1M-aligned for NetBSD. Don't align symbol table on 4k
+	boundaries if the kernel doesn't require it.
+
+1999-10-10  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/asm.S [!STAGE1_5] (start): New label to force ld quiet.
+	[!STAGE1_5] (_start): Likewise.
+	* stage2/builtins.c (install_func): Rewritten heavily almost
+	from scratch. As the blocklist was moved to the first sector of
+	Stage 2, always write sectors of Stage 2 to the disk.
+	* stage1/stage1.h (STAGE1_STAGE2_SECTOR): 0x40 -> 0x41.
+	(STAGE1_STAGE2_ADDRESS): 0x44 -> 0x45.
+	(STAGE1_STAGE2_SEGMENT): 0x46 -> 0x47.
+	(STAGE1_BOOT_DRIVE): 0x3f -> 0x40.
+
+1999-10-09  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	Stage1 supports both the CHS mode and the LBA mode.
+
+	* stage1/Makefile.am (nodist_pkgdata_DATA): Removed stage1_lba.
+	(BUILT_SOURCES): Deleted.
+	(CLEANFILES): Likewise.
+	(noinst_PROGRAMS): Removed stage1_lba.exec.
+	(stage1_exec_SOURCES): Removed stage2_size.h.
+	(stage2_size.h): Deleted.
+	(stage1_lba_exec_SOURCES): Likewise.
+	* stage1/stage1.S: Rewritten from scratch.
+	* stage1/stage1_lba.S: Deleted.
+	* stage1/stage1.h (COMPAT_VERSION_MAJOR): Set to 3.
+	(COMPAT_VERSION_MINOR): Set to 0.
+	(STAGE1_VER_MAJ_OFFS): Set to 0x3e.
+	(STAGE1_FIRSTLIST): Deleted.
+	(STAGE1_INSTALLSEG): Likewise.
+	(STAGE1_INSTALLADDR): Likewise.
+	(STAGE1_MINPARAMSIZE): Likewise.
+	(STAGE1_LISTSIZE): Likewise.
+	(STAGE1_ID_OFFSET): Likewise.
+	(STAGE1_ID_CHS): Likewise.
+	(STAGE1_ID_LBA): Likewise.
+	(STAGE1_STAGE2_SECTOR): New macro.
+	(STAGE1_STAGE2_ADDRESS): Likewise.
+	(STAGE1_STAGE2_SEGMENT): Likewise.
+	(STAGE1_BOOT_DRIVE): Likewise.
+	* stage2/start.S: New file.
+	* stage2/Makefile.am (noinst_DATA): New variable.
+	(CLEANFILES): Set to "$(nodist_pkgdata_DATA) $(noinst_DATA)
+	$(BUILT_SOURCES)".
+	(noinst_PROGRAMS): Removed stage2.exec, and added start.exec and
+	pre_stage2.exec.
+	(STAGE2_LINK): Deleted.
+	(PRE_STAGE2_LINK): New variable.
+	(START_LINK): Likewise.
+	(stage2_exec_SOURCES): Deleted.
+	(stage2_exec_CFLAGS): Likewise.
+	(stage2_exec_LDFLAGS): Likewise.
+	[NETBOOT_SUPPORT] (stage2_exec_LDADD): Likewise.
+	(pre_stage2_exec_SOURCES): New variable.
+	(pre_stage2_exec_CFLAGS): Likewise.
+	(pre_stage2_exec_LDFLAGS): Likewise.
+	[NETBOOT_SUPPORT] (pre_stage2_exec_LDADD): Likewise.
+	(BUILT_SOURCES): Likewise.
+	(start_exec_SOURCES): Likewise.
+	(start_exec_CFLAGS): Likewise.
+	(start_exec_LDFLAGS): Likewise.
+	(start_exec_DEPENDENCIES): Likewise.
+	(stage2_size.h): New rule.
+	(stage2): Likewise.
+	(e2fs_stage1_5_exec_SOURCES): Added start.S.
+	(fat_stage1_5_exec_SOURCES): Likewise.
+	(ffs_stage1_5_exec_SOURCES): Likewise.
+	(minix_stage1_5_exec_SOURCES): Likewise.
+	* stage2/asm.S (start): Renamed to ...
+	(main): ... this.
+	[STAGE1_5] (main): Jump to (codestart - EXT_C(main) + 0x2200)
+	instead of (codestart - EXT_C(start) + 0x2000).
+	[!STAGE1_5] (main): Jump to (codestart - EXT_C(main) + 0x8200)
+	instead of (codestart - EXT_C(start) + 0x8000).
+	[STAGE1_5] (chain_stage2): Use main instead of start.
+	* stage2/shared.h (BOOTSEC_LISTSIZE): New macro.
+	* stage2/stage1_5.c: Change the second argument for chain_stage2
+	to 0x8200.
+
+1999-10-08  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* configure.in (--with-binutils): New option to specify a
+	directory to find binutils.
+	(CFLAGS): If WITH_BINUTILS is not empty, added the option `-B'.
+	(LD): Do not check for this. We don't use ld directly anyway.
+	(RANLIB): If WITH_BINUTILS is not empty, search the directory
+	WITH_BINUTILS first.
+	(OBJCOPY): Likewise.
+	* acinclude.m4 (grub_ASM_USCORE): Add CFLAGS into
+	AC_TRY_COMMAND.
+	(grub_ASM_ADDR32): Likewise.
+	(grub_ASM_PREFIX_REQUIREMENT): Likewise.
+	(grub_PROG_OBJCOPY_ABSOLUTE): Use CC instead of LD.
+
+1999-10-04  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* stage2/freebsd.h (struct bootinfo): New member, bi_bios_dev.
+	* stage2/boot.c (bsd_boot): Set BI.BI_BIOS_DEV to SAVED_DRIVE.
+
+1999-10-04  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From Pavel Roskin:
+	* docs/grub.texi: Fix typos.
+	* stage2/builtins.c (install_func): Reformat the warning message
+	about the option `d'.
+
+1999-10-03  Gordon Matzigkeit  <gord@fig.org>
+
+	* stage2/builtins.c (install_func): Fix check for the Stage 2 id.
+	From Pavel Roskin.
+
+	* debian/Makefile.am (EXTRA_DIST): Add postinst and prerm.
+
+1999-10-03  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/builtins.c (boot_func): Pass MBI.CMDLINE instead of ARG
+	to bsd_boot.
+
+1999-10-03  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/gunzip.c (gunzip_test_header): Check if CURRENT_DRIVE
+	is 0x20 instead of if the fs type is TFTP, because GRUB does not
+	mount CURRENT_DRIVE when using a block file. Reported by Pavel
+	Roskin.
+
+1999-10-02  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/builtins.c (cat_func): Do not read the whole of a file
+	at one time. Instead, repeat reading one byte and print it on
+	the screen.
+	* docs/grub.texi (Command line): List the available key
+	bindings.
+	(Commands): Added descriptions about "geometry", "device" and
+	"cat".
+
+1999-10-02  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	Now it is possible to build the grub shell with old BSD curses.
+
+	* stage2/shared.h [!A_NORMAL] (A_NORMAL): Set to zero.
+	[!A_REVERSE && A_STANDOUT] (A_REVERSE): Set to A_STANDOUT.
+	[!A_REVERSE && !A_STANDOUT] (A_REVERSE): Set to zero.
+
+1999-09-30  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* stage2/disk_io.c (set_bootdev): Mask 0x7F instead of 0x79 of
+	the device number.
+
+1999-10-01  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* configure.in (--without-curses): New option. If WITH_CURSES is
+	no, do not check for curses.
+
+	* stage2/disk_io.c (set_device) [STAGE1_5]: Change the type of
+	DEV to unsigned long.
+	* stage2/builtins.c (install_func): Always check for the Stage 2
+	id in FILE.
+	Reported by Pavel Roskin.
+
+1999-09-30  Gordon Matzigkeit  <gord@fig.org>
+
+	* debian/postinst: New file to call install-info.
+	* debian/prerm: Likewise.
+	* debian/rules (binary-arch): Add postinst and prerm, compress the
+	info files, and call dpkg-shlibdeps.
+
+	* stage2/cmdline.c (skip_to): Restructure, and count tabs as
+	whitespace.
+	(find_command): Likewise.
+
+1999-09-30  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* grub/getopt.c: Moved to ...
+	* lib/getopt.c: ... here.
+	* grub/getopt1.c: Moved to ...
+	* lib/getopt1.c: ... here.
+	* grub/getopt.h: Moved to ...
+	* lib/getopt.h: ... here.
+	* grub/Makefile.am (AM_CFLAGS): Added -I$(top_srcdir)/lib.
+	(grub_LDADD): Added ../lib/libcommon.a.
+	* lib/Makefile.am: New file.
+	* Makefile.am (SUBDIRS): Added lib.
+	* configure.in: lib/Makefile is added into the arguments for
+	AC_OUTPUT.
+
+1999-09-30  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From Pavel Roskin:
+	* stage2/defs.h (time_t): Renamed to ...
+	(mach_time_t): ... this.
+	(daddr_t): Renamed to ...
+	(mach_daddr_t): ... this.
+	(uid_t): Renamed to ...
+	(mach_uid_t): ... this.
+	(gid_t): Renamed to ...
+	(mach_gid_t): ... this.
+	(ino_t): Renamed to ...
+	(mach_ino_t): ... this.
+	* stage2/disk_inode.h (FFS_MAX_FASTLINK_SIZE): Use mach_daddr_t
+	instead of daddr_t.
+	(struct icommon): Use mach_uid_t, mach_gid_t, mach_time_t and
+	mach_daddr_t, instead of uid_t, gid_t, time_t and daddr_t.
+	* stage2/fs.h (BBLOCK): Use mach_daddr_t instead of addr_t.
+	(SBLOCK): Likewise.
+	(ROOTINO): Use mach_ino_t instead of ino_t.
+	(struct fs): Use mach_daddr_t and mach_time_t instead of daddr_t
+	and time_t.
+	(struct cg): Use mach_time_t instead of time_t.
+	(struct ocg): Likewise.
+	(cgbase): Use mach_daddr_t instead of daddr_t.
+	(itod): Likewise.
+
+1999-09-30  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* acinclude.m4 (grub_CHECK_START_SYMBOL): Use AC_TRY_LINK
+	instead of AC_TRY_COMMAND.
+	(grub_CHECK_USCORE_START_SYMBOL): Likewise.
+	(grub_CHECK_END_SYMBOL): Likewise.
+	(grub_CHECK_USCORE_END_SYMBOL): Likewise.
+
+	* stage2/disk_io.c (set_device) [!STAGE1_5]: Use RESULT instead
+	of RETVAL to check if the analysis succeeds.
+
+1999-09-29  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/builtins.c (install_func): If the Stage 2 id in FILE is
+	not STAGE2_ID_STAGE2, set IS_STAGE1_5 to 1, otherwise to 0.
+	Use CONFIG_FILE_LOCATION to point to the location of the name of
+	a configuration file in Stage 2.
+	If the option `p' is present and IS_STAGE1_5 is non-zero, reset
+	the device information in CONFIG_FILE_LOCATION.
+	(cat_func): New function.
+	(builtin_cat): New variable.
+	(builtin_table): Added a pointer to BUILTIN_CAT.
+	(geometry_func): Call real_open_partition with the argument 1
+	after printing out the drive information.
+	* stage2/disk_io.c (real_open_partition): Made global.
+	[!STAGE1_5] (print_completions): In the command completion and
+	the filename completion, print a newline at the last if
+	IS_COMPLETION is zero.
+	* stage2/shared.h (real_open_partition): Declared.
+	* stage2/fsys_ext2fs.c (ext2fs_dir): Do not print a newline even
+	if PRINT_POSSIBILITIES is less than zero.
+	* stage2/fsys_ffs.c (ffs_dir): Likewise.
+	* stage2/fsys_fat.c (fat_dir): Likewise.
+	* stage2/fsys_minix.c (minix_dir): Likewise.
+
+1999-09-29  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage1/stage1.S [!FFS_STAGE1_5] (blocklist_default_len): Do
+	not divide the size by 512, but shift the size to the right by
+	9 instead, because of a binutils-2.9.1.0.x bug.
+	* stage1/stage1_lba.S [!FFS_STAGE1_5] (blocklist_default_len):
+	Likewise.
+	* stage2/builtins.c (install_func): When installing Stage 1.5,
+	if set_device returns NULL, then set CURRENT_DRIVE to 0xFF and
+	CONFIG_FILE to PTR.
+
+1999-09-26  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/char_io.c [!STAGE1_5] (get_cmdline): In cl_insert, call
+	cl_setcpos before printing BUF, even if LPOS is equal to LLEN.
+	In the completion, if RET is zero, do not call cl_init.
+	* stage2/disk_io.c [!STAGE1_5] (print_completions): In the
+	filename completion, if UNIQUE is 1, check if UNIQUE_STRING is a
+	directory or not. If so, append '/' to BUF.
+	In the partition completion, if IS_COMPLETION is non-zero and
+	*UNIQUE_STRING is not NUL, copy UNIQUE_STRING to PTR. Do not
+	append '/'.
+	(real_open_partition) [!STAGE1_5]: If DO_COMPRESSION is non-zero,
+	call print_a_completion.
+	(check_BSD_parts) [!STAGE1_5]: Likewise.
+	[!STAGE1_5] (print_a_completion): Ignore NAME if it is "." or
+	"..".
+
+1999-09-25  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* acinclude.m4 (grub_CHECK_USCORE_END_SYMBOL): Do not call
+	AC_DEFINE within AC_CACHE_VAL. Call it after AC_CACHE_VAL.
+	* stage2/Makefile.am (STAGE1_5_COMPILE): Do not define
+	CONFIG_FILE_ASM.
+	* stage2/asm.S (config_file) [STAGE1_5]: Set the first 4 bytes
+	to 0xffffffff and the following to "/boot/grub/stage2".
+	(config_file) [!STAGE1_5]: Set to "/boot/grub/menu.lst".
+	* stage2/builtins.c (install_func): Read a Stage 2 before
+	handling the `p' option.
+	If the `configfile' option is present and FILE is a Stage 2,
+	translate the device name to the internal device representation
+	and copy the result to STR.
+	* stage2/disk_io.c [STAGE1_5] (sane_partition): Eliminated.
+	[STAGE1_5] (incomplete): Likewise.
+	[STAGE1_5] (disk_choice): Likewise.
+	[STAGE1_5] (part_choice): Likewise.
+	(set_device) [STAGE1_5]: Assume that the first 4 bytes of DEVICE
+	is a device number. Set DRIVE to the forth byte of DEV and
+	PARTITION to the first 3 bytes of DEV. If DRIVE is 0xFF, set
+	CURRENT_DRIVE and CURRENT_PARTITION to SAVED_DRIVE and
+	SAVED_PARTITION, respectively. Otherwise set to DRIVE and
+	PARTITION, respectively.
+	(setup_part) [STAGE1_5]: Always call set_device.
+
+1999-09-24  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* acinclude.m4 (grub_CHECK_END_SYMBOL): Add a missing
+	double-quote. Reported by Johannes Kroeger
+	<hanne@squirrel.owl.de>.
+
+1999-09-14  Gordon Matzigkeit  <gord@fig.org>
+
+	* stage1/stage1.S (blocklist_default_start): New label for default
+	blocklist start sector.
+	(blocklist_default_len): New label for default blocklist length.
+	(blocklist_default_seg): New label for default blocklist segment.
+	* stage1/stage1_lba.S (blocklist_default_start): Likewise.
+	(blocklist_default_len): Likewise.
+	(blocklist_default_seg): Likewise.
+
+1999-09-23  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* acinclude.m4 (grub_ASM_ADDR32): First, create a template
+	source file "conftest.s.in", and then, replace @ADDR32@ with
+	"addr32" if GRUB_CV_ASM_PREFIX_REQUIREMENT is yes, otherwise,
+	replace it with "addr32;". Reported by John Tobey
+	<spam@john-edwin-tobey.org>.
+
+1999-09-23  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/builtins.c (debug_fs_print_func): Renamed to ...
+	(disk_read_print_func): ... this.
+	(fstest_func): Use DISK_READ_HOOK instead of DEBUG_FS.
+	(install_func): Rename debug_fs_savesect_func to
+	disk_read_savesect_func.
+	Rename debug_fs_blocklist_func to disk_read_blocklist_func.
+	Use DISK_READ_HOOK instead of DEBUG_FS.
+	(testload_func): Use DISK_READ_HOOK instead of DEBUG_FS.
+	* stage2/disk_io.c [!STAGE1_5] (debug_fs): Renamed to ...
+	[!STAGE1_5] (disk_read_hook): ... this.
+	[!STAGE1_5] (debug_fs_func): Renamed to ...
+	[!STAGE1_5] (disk_read_func): ... this.
+	(rawread) [!STAGE1_5]: Use DISK_READ_HOOK and DISK_READ_FUNC
+	instead	of DEBUG_FS and DEBUG_FS_FUNC.
+	(grub_read) [!STAGE1_5]: Likewise.
+	(devread) [!STAGE1_5]: Use DISK_READ_HOOK instead of DEBUG_FS.
+	* stage2/fsys_ext2fs.c (ext2fs_read) [!STAGE1_5]: Use
+	DISK_READ_HOOK and DISK_READ_FUNC instead of DEBUG_FS and
+	DEBUG_FS_FUNC.
+	* stage2/fsys_ffs.c (ffs_read) [!STAGE1_5]: Likewise.
+	* stage2/fsys_minix.c (minix_read) [!STAGE1_5]: Likewise.
+	* stage2/shared.h [!STAGE1_5] (debug_fs): Renamed to ...
+	[!STAGE1_5] (disk_read_hook): ... this.
+	[!STAGE1_5] (debug_fs_func): Renamed to ...
+	[!STAGE1_5] (disk_read_func): ... this.
+	* docs/grub.texi: Likewise, replace debug_fs and debug_fs_func
+	with disk_read_hook and disk_read_func, respectively.
+
+1999-09-23  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* stage2/builtins.c (install_func): New local function,
+	debug_fs_savesect_func. Use debug_fs_savesect_func to determine
+	the first sector of Stage2. Write Stage 1 after patching Stage
+	2.
+
+1999-09-22  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* acinclude.m4 (grub_ASM_USCORE): Do not define HAVE_ASM_USCORE
+	within AC_CACHE_VAL. Define it after AC_CACHE_VAL if
+	GRUB_CV_ASM_USCORE is yes.
+
+1999-09-20  Edmund GRIMLEY EVANS  <edmundo@rano.demon.co.uk>
+
+	* netboot/3c59x.c: INCLUDE_3c59x is replaced by INCLUDE_3C59X
+ 	throughout.
+	* netboot/config.c: Likewise.
+	* netboot/io.h (__INS): New macro.
+	(__OUTS): Likewise.
+	(outl): Likewise.
+	(inl): Likewise.
+	(outl_p): Likewise.
+	(inl_p): Likewise.
+	Call __INS with the argument `b', with `w' and with `l' to
+	define insb, insw and insl, respectively. Likewise, Call __OUTS
+	with `b', with `w' and with `l' to define outsb, outw and outl,
+	respectively.
+	* netboot/pci.h (PCI_VENDOR_ID_VORTEX): New macro.
+ 	(PCI_DEVICE_ID_VORTEX_3c595): Likewise. Defined as a random
+	value.
+
+1999-09-20  Edward Killips  <ekillips@triton.net>
+
+	* stage2/disk_io.c (set_partition_hidden_flag): Set/clear the
+	hidden flag, whether the hidden flag is set or not.
+
+1999-09-21  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/builtins.c (install_func): Do not set DEBUG_FS at the
+	first read. Set it to DEBUG_FS_BLOCKLIST_FUNC when reading the
+	whole of Stage 2. Set FILEPOS to zero at the same time to read
+	from the beginning of Stage 2. Reported by Pavel Roskin.
+
+1999-09-20  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	The argument ADDR for the command install is now optional.
+
+	* stage2/builtins.c (install_func): If parsing ADDR fails, set
+	INSTALLADDR to zero and set PTR to ADDR.
+	If INSTALLADDR is zero after parsing the command-line, check if
+	the Stage 2 id is STAGE2_ID_STAGE2. If so, set INSTALLADDR to
+	0x8000, otherwise set it to 0x2000.
+	Set the install address in the Stage 1 after the automatic
+	determination is completed.
+	(builtin_install): Say that ADDR is optional in the help
+	message.
+	* docs/grub.texi: Synchronize the description about install to
+	builtins.c. Remove explicit address arguments from all the
+	examples. Add a description about help.
+	* docs/menu.lst: Do not specify the address argument for
+	install.
+
+1999-09-19  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	The completion code is heavily modified.
+
+	* stage2/char_io.c [!STAGE1_5] (get_cmdline): In the completion
+	code, use COMPLETION_BUFFER to get the completion instead of
+	writing to BUF directly.
+	Save the position of a possible equal character after a command
+	in EQUAL_POS and replace the equal character with a space
+	temporarily for the code simplicity.
+	At first, just get completions, and, if there is more than one
+	completions, then print the list of the completions.
+	* stage2/disk_io.c [!STAGE1_5] (do_completion): New variable.
+	[!STAGE1_5] (unique): Moved the definition near the beginning.
+	[!STAGE1_5] (unique_string): Likewise. And changed the type to
+	char *.
+	(check_BSD_parts) [!STAGE1_5]: If DO_COMPLETION is non-zero, do
+	not print anything.
+	(real_open_partition) [!STAGE1_5]: Likewise.
+	[!STAGE1_5] (print_fsys_type): Likewise.
+	[!STAGE1_5] (print_a_completion): The argument FILENAME is
+	renamed	to NAME.
+	If DO_COMPLETION is non-zero, get the unique part from NAME and
+	set UNIQUE_STRING to it.
+	If DO_COMPLETION is zero, just print NAME.
+	Do not call printf unconditionally.
+	[!STAGE1_5] (print_completions): Accept two arguements
+	IS_FILENAME and IS_COMPLETION instead of FILENAME.
+	Set UNIQUE_STRING to UNIQUE_BUF.
+	Set DO_COMPLETION to IS_COMPLETION and set it to zero before
+	returning.
+	If IS_FILENAME is zero, then complete builtin commands and
+	return UNIQUE - 1.
+	Use BUF instead of FILENAME.
+	If IS_COMPLETION is non-zero, do not print anything.
+	Copy UNIQUE_STRING to PTR only if IS_COMPLETION and
+	*UNIQUE_STRING are non-zero.
+	* stage2/shared.h (COMPLETION_BUF): New macro.
+	(COMPLETION_BUFLEN): Likewise.
+	(UNIQUE_BUF): Likewise.
+	(UNIQUE_BUFLEN): Likewise.
+	(MENU_BUF): Set to UNIQUE_BUF + UNIQUE_BUFLEN.
+	(MENU_BUFLEN): Set to 0x8000 + PASSWORD_BUF - UNIQUE_BUF.
+	(print_completions): Adjusted to the definition.
+
+1999-09-19  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* acinclude.m4 (grub_ASM_PREFIX_REQUIREMENT): Do not call
+	AC_DEFINE_UNQUOTEs within AC_CACHE_VAL. Define ADDR32 and DATA32
+	after it.
+	(grub_CHECK_START_SYMBOL): Do not call AC_DEFINE within
+	AC_CACHE_VAL. Define HAVE_START_SYMBOL after it.
+	(grub_CHECK_USCORE_START_SYMBOL): Do not call AC_DEFINE within
+	AC_CACHE_VAL. Define HAVE_USCORE_START_SYMBOL after it.
+	(grub_CHECK_END_SYMBOL): Do not call AC_DEFINE within
+	AC_CACHE_VAL. Define HAVE_END_SYMBOL after it.
+	(grub_CHECK_USCORE_END_SYMBOL): Do not call AC_DEFINE within
+	AC_CACHE_VAL. Define HAVE_USCORE_END_SYMBOL after it.
+
+1999-09-17  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* acconfig.h (ADDR32): Removed. This entry is automatically
+	created by autoheader.
+	(DATA32): Likewise.
+	* acinclude.m4 (grub_ASM_ADD32): Use ADDR32 instead of addr32.
+	Require grub_ASM_PREFIX_REQUIREMENT.
+	(grub_ASM_PREFIX_REQUIREMENT): Define ADDR32 and DATA32.
+	* configure.in: Call grub_ASM_PREFIX_REQUIREMENT before
+	grub_ASM_ADDR32. Do not define ADDR32 and DATA32.
+	* stage1/stage1.S (after_BPB): Use ABS(firstlist) instead of
+	firstlist.
+	(MSG): Use ABS(x) instead of x.
+	(probe_loop): Use the macro MSG for fd_probe_error_string.
+	* stage1/stage1_lba.S (after_BPB): Use ABS(firstlist) instead of
+	firstlist.
+	(MSG): Use ABS(x) instead of x.
+	* stage2/asm.S (putchar): Renamed to ...
+	(grub_putchar): ... this.
+
+1999-09-18  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/gunzip.c (reset_linalloc): Use the macro RAW_ADDR
+	before setting LINALLOC_TOPADDR.
+	* stage2/shared.h [!GRUB_UTIL] (RAW_ADDR): Added parenthesises
+	to avoid a gcc warning.
+	[!GRUB_UTIL] (RAW_SEG): Likewise.
+
+1999-09-18  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* acinclude.m4 (grub_CHECK_START_SYMBOL): New function.
+	(grub_CHECK_USCORE_START_SYMBOL): Likewise.
+	(grub_CHECK_END_SYMBOL): Likewise.
+	(grub_CHECK_USCORE_SYMBOL): Likewise.
+	* configure.in: Call grub_CHECK_START_SYMBOL and
+	grub_CHECK_USCORE_START_SYMBOL, and if neither start nor _start
+	is defined, print an error message and exit.
+	Likewise, call grub_CHECK_END_SYMBOL and
+	grub_CHECK_USCORE_END_SYMBOL, and if neither end nor _end is
+	defined, print an error message and exit.
+	* acconfig.h (HAVE_START_SYMBOL): Added the "undef" entry.
+	(HAVE_USCORE_START_SYMBOL): Likewise.
+	(HAVE_END_SYMBOL): Likewise.
+	(HAVE_USCORE_END_SYMBOL): Likewise.
+	* stage2/char_io.c (memcheck): Rename the argument START to
+	ADDR. Added two missing equal characters.
+	[GRUB_UTIL]: Define new local functions start_addr and end_addr.
+	[GRUB_UTIL && HAVE_START_SYMBOL]: The function start_addr
+	returns START.
+	[GRUB_UTIL && HAVE_USCORE_START_SYMBOL]: The function start_addr
+	returns _START.
+	[GRUB_UTIL && HAVE_END_SYMBOL]: The function end_addr returns
+	END.
+	[GRUB_UTIL && HAVE_USCORE_END_SYMBOL]: The function end_addr
+	returns _END.
+	[GRUB_UTIL]: If ADDR is equal to or greater than the address
+	returned by start_addr, and ADDR plus LEN is less than the
+	address returned by end_addr, return ! ERRNUM.
+	* stage2/asm.S (get_code_end) [HAVE_END_SYMBOL]: Use $end as the
+	end of the bss.
+	[HAVE_USCORE_END_SYMBOL]: Use $_end as the end of the bss.
+	* stage2/disk_io.c [!STAGE1_5] (cur_part_desc): Made static.
+	Need not to be global any longer.
+
+1999-09-17  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/char_io.c [!STAGE1_5] (get_cmdline): The argument
+	COMPLETION is renamed to READLINE.
+	Do not initialize KILL here.
+	TAB, C-a, C-e, C-f, C-b, C-u, C-k, C-y, C-p and C-n are handled
+	only if READLINE is non-zero.
+	If ECHO_CHAR is not NUL, do not remove the leading spaces in BUF.
+	Add CMDLINE into the history list only if READLINE is non-zero.
+	* stage2/stage2.c (cmain): Initialize the kill buffer.
+
+1999-09-17  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	Killing, yanking and manipulating the history are supported.
+
+	* stage2/shared.h (cur_cmdline): Removed.
+	(MAX_CMDLINE): Moved near the beginning of the file.
+	(NEW_HEAPSIZE): Likewise.
+	(CMDLINE_BUFLEN): Set to MAX_CMDLINE.
+	(KILL_BUF): New macro.
+	(KILL_BUFLEN): Likewise.
+	(HISTORY_BUF): Likewise.
+	(HISTORY_SIZE): Likewise.
+	(HISTORY_BUFLEN): Likewise.
+	(MENU_BUF): Set to HISTORY_BUF + HISTORY_BUFLEN.
+	(MENU_BUFLEN): Set to 0x8000 + PASSWORD_BUF - HISTORY_BUF.
+	(strcpy): New macro.
+	(grub_strcpy): Delared.
+	* stage2/boot.c (cur_cmdline): Removed.
+	* stage2/char_io.c [!STAGE1_5] (grub_strcpy): New function.
+	[!STAGE1_5] (get_history): Likewise.
+	[!STAGE1_5] (add_history): Likewise.
+	[!STAGE1_5] (get_cmdline): Use BUF instead of CMDLINE for the
+	working buffer for the command-line.
+	A new function cl_insert is used to insert a string to the
+	command-line.
+	In the case where C-u or C-k is pressed, copy the string being
+	deleted to KILL.
+	If C-y is pressed, insert KILL to the command-line.
+	If C-p is pressed, fetch the previous command from the history
+	list HISTORY, and if C-n is pressed, fetch the next command from
+	it.
+	If LPOS is less than LLEN, add CMDLINE into the history list.
+	If C is equal to KEY_UP, set C to 16, and if C is equal to
+	KEY_DOWN, set C to 14.
+	[!STAGE1_5] (num_history): New variable.
+
+1999-09-15  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/size_test: Do not check for the size of Stage 2.
+	* stage1/Makefile.am (stage2_size.h): Use `set' and `echo'
+	instead of awk, since we cannot expect awk is present. Remove
+	stage2_size.h before creating it.
+
+1999-09-15  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* Makefile.am (SUBDIRS): Put stage1 after stage2 so that stage2
+	is built before stage1.
+	* stage1/Makefile.am (BUILT_SOURCES): New varilable.
+	(CLEANFILES): Added BUILT_SOURCES.
+	(stage1_exec_SOURCES): Added stage2_size.h.
+	(stage1_lba_exec_SOURCES): Likewise.
+	(stage2_size.h): New rule.
+	* stage1/stage1.S: Include <stage2_size.h> and use STAGE2_SIZE
+	to determine how much number of sectors to be read when loading
+	Stage 2.
+	* stage1/stage1_lba.S: Likewise.
+
+1999-09-15  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* netboot/config.h: Moved to ...
+	* netboot/netboot_config.h: ... here.
+	* netboot/config.c: Include netboot_config.h instead of config.h.
+	* netboot/fsys_tftp.c: Likewise.
+	* netboot/ip.c: Likewise.
+	* netboot/Makefile.am (libdrivers_a_SOURCES): Removed config.h
+	and added netboot_config.h.
+
+1999-09-14  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* grub/asmstub.c [__linux__]: On GLibc 2.0 and newer use lseek,
+	don't include <linux/fs.h> and define BLKFLSBUF if needed.
+
+1999-09-14  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	Now the grub shell works fine on FreeBSD. A patch by Pavel
+	Roskin is modified and applied.
+
+	* grub/asmstub.c (get_drive_geometry): New function.
+	(get_diskinfo): Use get_drive_geometry to set the geometry of
+	DRIVE.
+
+1999-09-14  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* configure.in (--enable-ne): Made the description more clear.
+	(--enable-nepci): Likewise.
+	(--enable-wd): Likewise.
+	(--enable-t503): Likewise.
+	(--enable-t509): Likewise.
+	(--enable-3c59x): Likewise.
+	(--enable-lance): Likewise.
+	(--enable-cs): Likewise.
+	(--enable-eepro100): Likewise.
+	(--enable-wd-default_mem): Renamed to ...
+	(--enable-wd-default-mem): ... this.
+	(--enable-cs-scan): Corrected the description.
+	(NETBOOT_SUPPORT): Defined if NET_CFLAGS is not empty.
+	* stage2/Makefile.am (stage2_exec_LDADD): Defined only if
+	NETBOOT_SUPPORT is true.
+	* netboot/Makefile.am (LIBDRIVERS): New variable. If
+	NETBOOT_SUPPORT is true, set to libdriver.a, otherwise set to an
+	empty string.
+	(noinst_LIBRARIES): Set to LIBDRIVERS.
+	(DRIVERS): Added 3c509.h, cs89x0.h and ns8390.h.
+	(libdrivers_a_SOURCES): Added byteorder.h, config.h, if.h, io.h,
+	ip.h, netboot.h, netdevice.h, nic.h and pic.h.
+	(libdrivers_a_CFLAGS): Added -fno-builtin and -nostdinc and
+	removed -O2.
+	* stage2/char_io.c (grub_sprintf): Added parenthesises to avoid
+	gcc warnings.
+	* stage2/gunzip.c (gunzip_test_header): Check if FSYS_TYPE is
+	TFTP. If so, set IS_TFTP to non-zero, otherwise to zero. And,
+	use IS_TFTP to check if we have GZIP_CRC instead of the equation
+	"FILEMAX == 16 * 1024 * 1024".
+
+1999-09-13  Edmund GRIMLEY EVANS  <edmundo@rano.demon.co.uk>
+
+	The netboot support in the Dresden version of GRUB is integrated.
+
+	* Makefile.am (SUBDIRS): Added netboot.
+	* configure.in (--enable-tftp): New option.
+	(--enable-ne): Likewise.
+	(--enable-nepci): Likewise.
+	(--enable-wd): Likewise.
+	(--enable-t503): Likewise.
+	(--enable-t509): Likewise.
+	(--enable-3c59x): Likewise.
+	(--enable-lance): Likewise.
+	(--enable-cs): Likewise.
+	(--enable-eepro100): Likewise.
+	(--enable-ne-scan): Likewise.
+	(--enable-wd-default_mem): Likewise.
+	(--enable-cs-scan): Likewise.
+	(NET_CFLAGS): New variable.
+	(NET_EXTRAFLAGS): Likewise.
+	Do AC_OUTPUT for netboot/Makefile as well.
+	* stage1/stage1.S: Set the number of sectors for Stage 2 to 130.
+	* stage1/stage1_lba.S: Likewise.
+	* stage2/Makefile.am (stage2_exec_LDADD): Added
+	../netboot/libdrivers.a.
+	* stage2/asm.S [!STAGE1_5] (currticks): New function.
+	* stage2/char_io.c [!STAGE1_5] (grub_sprintf): Likewise.
+	[!STAGE1_5] (grub_memcmp): Likewise.
+	* stage2/disk_io.c (fsys_table) [FSYS_TFTP]: Added an entry for
+	tftp.
+	(sane_partition) [!STAGE1_5]: If CURRENT_DRIVE is a network
+	drive, return 1.
+	(real_open_partition) [!STAGE1_5]: Likewise.
+	(set_device): If DEVICE contains a network drive, set
+	CURRENT_DRIVE to 0x20.
+	* stage2/filesys.h [FSYS_TFTP] (FSYS_TFTP_NUM): Defined as 1.
+	[!FSYS_TFTP] (FSYS_TFTP_NUM): Defined as 0.
+	(NUM_FSYS): Added FSYS_TFTP_NUM.
+	* stage2/gunzip.c (gunzip_test_header): If FILEMAX >= 16MB, do
+	not try to examine the last 8 bytes of the file. This is
+	required for compressed files by TFTP.
+	* stage2/shared.h (sprintf): New macro.
+	(memcmp): Likewise.
+	(currticks): Declared.
+	(grub_sprintf): Likewise.
+	(grub_memcmp): Likewise.
+	* stage2/size_test: Set the maximum size of Stage 2 to 66560.
+	* netboot/3c509.c: New file.
+	* netboot/3c509.h: Likewise.
+	* netboot/3c59x.c: Likewise.
+	* netboot/Makefile.am: Likewise.
+	* netboot/Makefile.in: Likewise.
+	* netboot/byteorder.h: Likewise.
+	* netboot/compile: Likewise.
+	* netboot/config.c: Likewise.
+	* netboot/config.h: Likewise.
+	* netboot/cs89x0.c: Likewise.
+	* netboot/cs89x0.h: Likewise.
+	* netboot/eepro100.c: Likewise.
+	* netboot/fsys_tftp.c: Likewise.
+	* netboot/if.h: Likewise.
+	* netboot/io.h: Likewise.
+	* netboot/ip.c: Likewise.
+	* netboot/ip.h: Likewise.
+	* netboot/lance.c: Likewise.
+	* netboot/netboot.h: Likewise.
+	* netboot/netdevice.h: Likewise.
+	* netboot/nic.h: Likewise.
+	* netboot/ns8390.c: Likewise.
+	* netboot/ns8390.h: Likewise.
+	* netboot/pci.c: Likewise.
+	* netboot/pci.h: Likewise.
+
+1999-09-13  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* configure.in (--enable-maintainer-mode): Do not use our own
+	rule, but use AM_MAINTAINER_MODE instead. If the maintainer mode
+	is enabled, then check for perl, and if it is not found, print
+	an error message and abort.
+	* docs/Makefile.am (grub.8): Regenerated if MAINTAINER_MODE is
+	defined, instead of GRUB_MAINT. Use the variable PERL rather
+	than running help2man directly.
+
+1999-09-13  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* stage2/pc_slice.h (IS_PC_SLICE_TYPE_EXTENDED): New macro.
+	* stage2/disk_io.c (real_open_partition): Use
+	IS_PC_SLICE_TYPE_EXTENDED instead of comparing CURRENT_SLICE
+	with the extended partition types.
+
+1999-09-11  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* acconfig.h: New file for autoheader support.
+	* acinclude.m4 (grub_ASM_EXT_C) Renamed to ...
+	(grub_ASM_USCORE): ... this. Define HAVE_ASM_USCORE if a C
+	symbol gets an underscore after compiling to assembler.
+	* configure.in: Added AM_CONFIG_HEADER. Autoconf 2.13 is now
+	required. Test for wgetch(), not getch() in -l[n]curses.
+	* stage2/shared.h (EXT_C): Defined.
+	Include the best existing header for [n]curses.
+
+1999-09-12  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/boot.c (load_image): Use CURRENT_DRIVE and
+	CURRENT_PARTITION instead of SAVED_DRIVE and SAVED_PARTITION for
+	the boot device in the Multiboot information. Reported by
+	Stephen Early <steve@greenend.org.uk>.
+
+1999-09-12  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/disk_io.c (sane_partition) [STAGE1_5]: Defined.
+	(set_device): Use sane_partition to make sure that CURRENT_DRIVE
+	has a valid value. Reported by Pavel Roskin.
+
+1999-09-11  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From Pavel Roskin:
+	* stage2/builtins.c (device_func) [GRUB_UTIL]: Use check_device
+	in order to make sure that DEVICE exists.
+	* grub/asmstub.c (check_device): New function.
+	(grub_stage2): Use check_device to probe a device.
+
+	* stage2/builtins.c (geometry_func) [GRUB_UTIL]: Copy the
+	modified geometry to GEOM and reset BUF_DRIVE. Reported by Pavel
+	Roskin.
+
+	* grub/main.c (no_floppy): New variable.
+	(probe_second_floppy): Likewise.
+	(OPT_NO_FLOPPY): New macro.
+	(OPT_PROBE_SECOND_FLOPPY): Likewise.
+	(longopts): Added no-floppy and probe-second-floppy.
+	(usage): Added the descriptions about --no-floppy and
+	--probe-second-floppy.
+	(main): Handle OPT_PROBE_SECOND_FLOPPY and OPT_NO_FLOPPY.
+	* grub/asmstub.c (grub_stage2): Print a message before the probe
+	routine. If NO_FLOPPY is non-zero, do not probe any floppy drive.
+	If PROBE_SECOND_FLOPPY is zero, skip the probe of the second
+	floppy drive.
+	(get_floppy_disk_name): New function.
+	(get_ide_disk_name): Likewise.
+	(get_scsi_disk_name): Likewise.
+
+1999-09-10  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/builtins.c (device_func): New function.
+	(builtin_device): New variable.
+	(builtin_table): Added the pointer to BUILTIN_DEVICE.
+	(builtin_geometry) [GRUB_UTIL]: Accept extra arguments,
+	CYLINDER, HEAD, SECTOR and TOTAL_SECTOR, and, if they are found,
+	set the geometry of a drive specified to them.
+	* grub/asmstub.c (disks): Made global.
+	(assign_device_name): New function.
+
+1999-09-09  Gordon Matzigkeit  <gord@fig.org>
+
+	* docs/grub.texi (Commands): Synchronize descriptions with
+	builtins.c.
+
+	* stage2/builtins.c (hide_func): Use set_partition_hidden_flag.
+	(unhide_func): Likewise.
+	Many help message cleanups.  From Pavel Roskin.
+
+	* stage2/shared.h (set_partition_hidden_flag): Declare.
+
+	* stage2/disk_io.c (set_partition_hidden_flag): New function
+	merged from hide_partition and unhide_partition.  Make sure we OR
+	with the inverse of the flag bit rather than XORing to unhide the
+	partition.
+
+1999-09-10  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* grub/asmstub.c (_FILE_OFFSET_BITS): Defined.
+	(biosdisk) [!__linux__]: Pass the offset argument as off_t
+	instead of int to lseek, and compare the return value with
+	OFFSET. Reported by Pavel Roskin.
+	(grub_stage2) [!__linux__ && !__GNU__]: Print a warning message.
+
+1999-09-08  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/stage2.c (run_menu): If run_script is successfully
+	finished, break the loop. Reported by Pavel Roskin.
+	Do not wait an input character when FALLBACK_ENTRY is less than
+	zero.
+	* stage2/cmdline.c (run_script): If ERRNUM is non-zero, wait an
+	input character, whether FALLBACK is less than zero or not.
+
+1999-09-06  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/builtins.c (configfile_func): New function.
+	(builtin_configfile): New variable.
+	(builtin_table): Added the pointer to BUILTIN_CONFIGFILE.
+
+1999-09-06  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From Pavel Roskin:
+	* stage2/asm.S [!STAGE1_5] (chain_stage2): Deleted.
+	[STAGE1_5] (get_code_end): Likewise.
+	* stage2/char_io.c (grub_strncat): Likewise.
+	* stage2/common.c [STAGE1_5] (saved_mem_upper): Likewise.
+	* stage2/smp-imps.c (imps_release_cpus): Likewise.
+	(imps_any_new_apics): Made static.
+	(imps_enabled): Likewise.
+	(imps_num_cpus): Likewise.
+	(imps_lapic_addr): Likewise.
+	(imps_cpu_apic_map): Likewise.
+	(imps_apic_cpu_map): Likewise.
+
+1999-09-06  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/builtins.c (testload_func): Fix the typos: 0x2000000 ->
+	0x200000 and 0x3000000 -> 0x300000.
+
+1999-09-06  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From Hisazumi Kenji <nel@soraneko.com>:
+	* stage2/fsys_ffs.c (mapblock_offset): New variable.
+	(mapblock_bsize): Likewise.
+	(MAPBUF): New macro.
+	(MAPBUF_LEN): Likewise.
+	(ffs_mount): Set MAPBLOCK_OFFSET to -1.
+	(block_map): Added partial read support.
+
+1999-09-06  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/cmdline.c (find_command): If COMMAND is less than
+	(*BUILTIN)->NAME in dictionary order, break the loop.
+	* stage2/builtins.c (builtin_chainloader): Capitalize the
+	variable name in the short doc.
+	(builtin_color): Likewise.
+	(builtin_geometry): Likewise.
+	(builtin_help): Likewise.
+	(builtin_hide): Likewise.
+	(builtin_initrd): Likewise.
+	(builtin_install): Likewise.
+	(builtin_kernel): Likewise.
+	(builtin_module): Likewise.
+	(builtin_modulenounzip): Likewise.
+	(builtin_pause): Likewise.
+	(builtin_read): Likewise.
+	(builtin_root): Likewise.
+	(builtin_testload): Likewise.
+	(builtin_unhide): Likewise.
+	(builtin_uppermem): Likewise.
+
+1999-09-05  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	The internal of the command handling is heavily modified, and
+	a new command "help" is added.
+
+	* stage1/stage1.S: Set the number of sectors for Stage 2 to 110.
+	* stage1/stage1_lba.S: Likewise.
+	* stage2/builtins.c: New file.
+	* stage2/Makefile.am (libgrub_a_SOURCES): Added builtins.c.
+	(stage2_exec_SOURCES): Likewise.
+	* stage2/boot.c (load_image): Return kernel_t instead int.
+	(bsd_boot): Change the type of the first argument to kernel_t.
+	* stage2/char_io.c (get_cmdline): Do not accept the argument
+	COMMANDS and accept the argument COMPLETION.
+	Print completions only if COMPLETION is non-zero.
+	Print the list of short docs when the command is completed.
+	* stage2/cmdline.c [GRUB_UTIL]: Do not include apic.h and
+	smp-imps.h.
+	(fallback): Deleted.
+	(password): Likewise.
+	(debug): Likewise.
+	(normal_color): Likewise.
+	(highlight_color): Likewise.
+	(print_cmdline_message): New function.
+	(commands): Deleted.
+	(debug_fs_print_func): Likewise.
+	(installaddr): Likewise.
+	(installlist): Likewise.
+	(installsect): Likewise.
+	(debug_fs_blocklist_func): Likewise.
+	(find_command): New function.
+	(init_cmdline): Initialize the data for the command-line
+	interface. The function to print the message is moved to
+	print_cmdline_message.
+	(enter_cmdline): Rewritten from scratch. Now deal with only the
+	pure command-line and the function to deal with a menu entry is
+	moved to run_script.
+	(run_script): New function.
+	* stage2/shared.h (PASSWORD_BUF): New macro.
+	(PASSWORD_BUFLEN): Likewise.
+	(CMDLINE_BUF): Likewise.
+	(CMDLINE_BUFLEN): Likewise.
+	(MENU_BUF): Likewise.
+	(MENU_BUFLEN): Likewise.
+	(fallback): Deleted.
+	(fallback_entry): Declared.
+	(default_entry): Likewise.
+	(BUILTIN_CMDLINE): New macro.
+	(BUILTIN_MENU): Likewise.
+	(BUILTIN_TITLE): Likewise.
+	(struct builtin): New tag.
+	(builtin_table): Declared.
+	(cmdline_t): Deleted.
+	(kernel_t): New type.
+	(kernel_type): Declared.
+	(grub_timeout): Likewise.
+	(init_builtins): Likewise.
+	(init_config): Likewise.
+	(find_command): Likewise.
+	(print_cmdline_message): Likewise.
+	(run_script): Likewise.
+	[!STAGE1_5] (bsd_boot): Deleted.
+	[!STAGE1_5] (load_image): Likewise.
+	[!STAGE1_5] (load_module): Likewise.
+	[!STAGE1_5] (load_initrd): Likewise.
+	* stage2/size_test: Set the maximum size of Stage 2 to 56320.
+	* stage2/stage2.c (grub_timeout): Deleted.
+	(menu_t): Likewise.
+	(run_menu): Changed the return type to void.
+	Use FALLBACK_ENTRY instead of FALLBACK.
+	Do not check the return value of enter_cmdline.
+	(run_menu) [GRUB_UTIL]: Call stop instead of returning
+	MENU_ABORT.
+	(cmain): Set MENU_ENTRIES to MENU_BUF.
+	Call init_config instead of clearing the variables directly.
+	Use CMDLINE_BUF for the command-line buffer instead of the
+	stack.
+	Adapted the analysis routine for the configuration file to the
+	new builtin commands interface.
+	Run enter_cmdline forever.
+	If run_menu returns, restart the loop.
+
+1999-09-04  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* docs/menu.lst: More meaningful examples. Not using (0x80,0)
+	notation anymore.
+	* stage2/stage2.c (run_menu): Erase the entered password before
+	get_cmdline(). Help on TAB disabled when entering the password.
+	* stage2/char_io.c (get_cmdline): Restore command-line even if
+	there is no help string.
+	* configure.in: --disable-gunzip disables decompression in
+	stage2.
+	* stage2/gunzip.c [NO_DECOMPRESSION]: Disable all code if
+	decompression is disabled.
+
+1999-09-03  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/boot.c (load_image): Use PHDR->P_PADDR instead of
+	PHDR->P_VADDR. Reported by Ramon van Handel <vhandel@chem.vu.nl>.
+
+1999-09-03  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* docs/help2man: Upgraded to 1.013.
+	* docs/grub.8: Regenerated.
+
+1999-09-02  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* stage2/cmdline.c (enter_cmdline) [GRUB_UTIL]: Add a space in
+	the LBA warning	message.
+
+1999-09-02  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	The character `=' after a command is now optional.
+
+	* stage2/char_io.c (get_cmdline): Search for a space or a equal
+	character after the first word in CMDLINE when TAB lists
+	completions, instead of just searching for a eqaul character.
+	* stage2/cmdline.c (skip_to): Treat the character `=' as a space
+	if AFTER_EQUAL is non-zero.
+	(commands): Delete all the equal characters.
+	* docs/menu.lst: Likewise.
+	* docs/grub.texi: Likewise.
+
+1999-09-01  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* grub/asmstub.c (env_for_exit): New variable.
+	(grub_stage2): Do a setjmp in doit, and when it returns
+	non-zero, set STATUS to 1 if ERRNUM is non-zero.
+	(stop): Call longjmp instead of exit.
+
+1999-08-31  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* stage2/boot.c [GRUB_UTIL] (bsd_boot_entry): New function.
+	(bsd_boot) [GRUB_UTIL]: Set ENTRY_ADDR to BSD_BOOT_ENTRY to fake
+	the *BSD boot.
+
+1999-08-31  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/fsys_fat.c (fat_create_blocklist): Cast FAT_BUF to
+	unsigned short * instead of unsigned long *. Suggested by Pavel
+	Roskin.
+
+1999-08-30  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From Edward Killips <ekillips@triton.net>:
+	* stage2/cmdline.c (commands): Added hide and unhide.
+	(enter_cmdline): Likewise.
+	* stage2/disk_io.c (unhide_partition): New function.
+	(hide_partition): Likewise.
+	* stage2/pc_slice.h (PC_SLICE_TYPE_HIDDEN_FLAG): New macro.
+
+1999-08-29  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From Pavel Roskin <pavel_roskin@geocities.com>:
+	* stage2/fsys_minix.c (namelen): New variable.
+	(MINIX_NAME_LEN): Deleted.
+	(minix_mount): Set NAMELEN to 14 if SUPRTBLOCK->S_MAGIC is
+	MINIX_SUPER_MAGIC, and set NAMELEN to 30 if it is
+	MINIX_SUPER_MAGIC2.
+	(minix_dir): Use NAMELEN instead of MINIX_NAME_LEN.
+
+1999-08-29  Pavel Roskin  <pavel_roslin@geocities.com>
+
+	* grub/Makefile.am, stage1/Makefile.am, stage2/Makefile.am:
+	Avoid using variables inclosed in '@' because they cannot be
+	overridden at the make time.
+
+1999-08-29  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* stage2/fsys_fat.c (fat_create_blocklist): Return 1 for the
+	root directory on FAT12 and FAT16.
+
+1999-08-27  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/boot.c (load_image): Accept two arguments, KERNEL and
+	ARG. And use them instead of CUR_CMDLINE.
+	(load_module): Accept two arguments, MODULE and ARG. And use
+	them instead of CUR_CMDLINE.
+	(load_initrd): Accept one argument, INITRD. And use it instead
+	of CUR_CMDLINE.
+	(bsd_boot): Accept one additional argument, ARG. And use it
+	instead of CUR_CMDLINE.
+	* stage2/cmdline.c (enter_cmdline): Use MB_CMDLINE instead of
+	HEAP for the Multiboot command-line buffer.
+	* stage2/shared.h (MB_CMDLINE_BUF): New macro.
+	(MB_CMDLINE_BUFLEN): Likewise.
+
+1999-08-26  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* docs/Makefile.am [GRUB_MAINT] (grub.8): The argument for the
+	option --name is changed to "the grub shell".
+	* docs/grub.8: Regenerated.
+	* docs/grub.texi: Do not use the name "the Stage 2 emulator" any
+	more. Use the name "the grub shell" instead.
+
+1999-08-26  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From Klaus Reichl <klaus.reichl@alcatel.at>:
+	* stage2/fsys_minix.c: New file.
+	* stage2/size_test: Added a check for the size of minix_stage1_5.
+	* stage2/Makefile.am (libgrub_a_SOURCES): Added fsys_minix.c.
+	(libgrub_a_CFLAGS): Added -DFSYS_MINIX=1.
+	(nodist_pkgdata_DATA): Added minix_stage1_5.
+	(noinst_PROGRAMS): Added minix_stage1_5.exec.
+	(stage2_exec_SOURCES): Added fsys_minix.c.
+	(minix_stage1_5_exec_SOURCES): New variable.
+	(minix_stage1_5_exec_CFLAGS): Likewise.
+	(minix_stage1_5_exec_LDFLAGS): Likewise.
+	* stage2/pc_slice.h (PC_SLICE_TYPE_MINIX): New macro.
+	* stage2/disk_io.c (fsys_table) [FSYS_MINIX]: Added minix entry.
+	* stage2/filesys.h [FSYS_MINIX] (FSYS_MINIX_NUM): Set to 1.
+	[!FSYS_MINIX] (FSYS_MINIX_NUM): Set to 0.
+	[!NUM_FSYS] (NUM_FSYS): Added FSYS_MINIX_NUM.
+	* stage2/shared.h (STAGE2_ID_MINIX_STAGE1_5): New macro.
+	[STAGE1_5 && FSYS_MINIX] (STAGE2_ID): Set to
+	STAGE2_ID_MINIX_STAGE1_5.
+	* grub/Makefile.am (AM_CFLAGS): Added -DFSYS_MINIX=1.
+	* configure.in (--disable-minix): New option.
+
+1999-08-25  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From Jochen Hoenicke <jochen@gnu.org>:
+	* stage2/fat.h (FAT_BPB_FAT_SECTORS_16): New macro.
+	(FAT_BPB_FAT_SECTORS_32): Likewise.
+	(FAT_BPB_IS_FAT32): Likewise.
+	(FAT_BPB_ROOT_DIR_CLUSTER): Likewise.
+	(FAT_BPB_FAT_SECTORS): If FAT_BPB_FAT_SECTORS_16 returns
+	a non-zero value, return it. Otherwise return
+	FAT_BPB_FAT_SECTORS_32.
+	(FAT_DIRENTRY_FIRST_CLUSTER): Corrected.
+	* stage2/fsys_fat.c (root_dir): New variable.
+	(fat_mount): Use the macro IS_PC_SLICE_TYPE_FAT instead of
+	checking for each fs types directly.
+	Omit the >64 sectors check.
+	If the current fs type is FAT32, then set FAT_SIZE to 8 and
+	get the root from BPB.
+	(fat_create_blocklist): Use the macro SECTOR_SIZE instead of a
+	magic number.
+	(fat_dir): Set MAP to ROOT_DIR instead of -1.
+	* stage2/pc_slice.h (PC_SLICE_TYPE_FAT32): New macro.
+	(PC_SLICE_TYPE_FAT32_LBA): Likewise.
+	(PC_SLICE_TYPE_FAT16_LBA): Likewise.
+	(IS_PC_SLICE_TYPE_FAT): Likewise.
+
+1999-08-25  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/fsys_ffs.c (ffs_mount): Do not shift the fs type
+	FS_BSDFFS. Reported by Takehiro Suzuki
+	<takehiro@coral.ocn.ne.jp>.
+	* stage2/fsys_fat.c (fat_mount): Do not shift the fs type
+	FS_MSDOS.
+
+1999-08-13  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	Pavel Roskin's patch that adds new options to disable arbitrary
+	filesystems is heavily modified and applied.
+
+	* configure.in (--disable-ext2fs): New option.
+	(--disable-fat): Likewise.
+	(--disable-ffs): Likewise.
+	(FSYS_CFLAGS): New variable. Set to filesystems the user choose.
+	* grub/Makefile.am (AM_CFLAGS): Added -DFSYS_EXT2FS=1,
+	-DFSYS_FAT=1 and -DFSYS_FFS=1.
+	* stage2/Makefile.am (libgrub_a_CFLAGS): Likewise.
+	(stage2_exec_CFLAGS): Added @FSYS_CFLAGS@.
+	* stage2/filesys.h
+	[!(FSYS_FFS || FSYS_FAT || FSYS_EXT2FS)] (FSYS_FFS): Deleted.
+	[!(FSYS_FFS || FSYS_FAT || FSYS_EXT2FS)] (FSYS_FAT): Likewise.
+	[!(FSYS_FFS || FSYS_FAT || FSYS_EXT2FS)] (FSYS_EXT2FS): Likewise.
+	* stage2/fsys_ext2fs.c [!FSYS_EXT2FS]: Do not define anything.
+	* stage2/fsys_fat.c [!FSYS_FAT]: Likewise.
+	* stage2/fsys_ffs.c [!FSYS_FFS]: Likewise.
+
+1999-08-12  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage1/stage1_lba.S: Use STAGE1_DRP_ADDR for the address of
+	drive parameters instead of DRIVE_PARAMETER.
+	(drive_parameter): Deleted.
+	* stage1/stage1.h (STAGE1_DRP_ADDR): New macro.
+	(STAGE1_DRP_SIZE): Likewise.
+
+1999-08-11  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/bios.c (get_diskinfo): In LBA mode, set TOTAL_SECTORS
+	to the low 32bits of DRP.TOTAL_SECTORS instead of the multiple
+	of CHS.
+	* stage2/cmdline.c (enter_cmdline) [GRUB_UTIL]: In the command
+	"geometry", print the device file name instead of CHS/LBA
+	information.
+	* stage2/shared.h (device_map): Declared.
+	* grub/asmstub.c (device_map): Defined as a global variable
+	instead of a local variable.
+
+1999-08-10  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	Support the NetBSD and OpenBSD partition slices.
+
+	* stage2/pc_slice.h (PC_SLICE_TYPE_BSD): Deleted.
+	(PC_SLICE_TYPE_FREEBSD): New macro.
+	(PC_SLICE_TYPE_OPENBSD): Likewise.
+	(PC_SLICE_TYPE_NETBSD): Likewise.
+	(IS_PC_SLICE_TYPE_BSD_WITH_FS): Likewise.
+	(IS_PC_SLICE_TYPE_BSD): Likewise.
+	* stage2/fsys_ffs.c (ffs_mount): Use the macro
+	IS_PC_SLICE_TYPE_BSD_WITH_FS instead of checking if
+	CURRECT_SLICE is equal to the BSD partition type directly.
+	* stage2/fsys_ext2fs.c (ext2fs_mount): Likewise.
+	* stage2/fsys_fat.c (fat_mount): Likewise.
+	* stage2/disk_io.c (check_BSD_parts): Set the low bits of
+	CURRENT_SLICE to PC_SLICE_TYPE_FREEBSD instead of
+	PC_SLICE_TYPE_BSD.
+	(real_open_partition): Use the macro IS_PC_SLICE_TYPE_BSD instead
+	of checking if CURRENT_SLICE is	equal to the BSD partition type
+	directly.
+
+1999-08-09  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/cmdline.c (commands): Added geometry.
+	(enter_cmdline): If CUR_HEAP has the string "geometry", print
+	out the information about a drive that the argument represents.
+
+1999-08-09  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/stage2.c (run_menu): Terminate the string PASSWORD
+	before checking if ENTERED is identical to PASSWORD. Reported
+	by Mark Lundeberg <aa026@pgfn.bc.ca>.
+
+1999-08-08  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/stage2.c (set_line_normal): New function.
+	(set_line_highlight): Likewise.
+	(run_menu): Do not call the function set_line directly any
+	longer, call set_line_normal and set_line_highlight instead.
+
+	From Pavel Roskin:
+	* stage2/stage2.c (run_menu) [GRUB_UTIL]: Quit when pushing the
+	key `q'.
+
+1999-08-05  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* acinclude.m4 (grub_ASM_PREFIX_REQUIREMENT): New function.
+	* configure.in: Call grub_ASM_PREFIX_REQUIREMENT, and define
+	ADDR32 and DATA32 based on the result.
+	* stage2/asm.S: Replace addr32 and data32 prefixes with	ADDR32
+	and DATA32 respectively.
+
+1999-08-05  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* stage2/boot.c (load_image): Use RAW_ADDR macro when loading
+	an a.out kernel.
+
+1999-08-04  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/asm.S: Make each of the addr32 and data32 prefixes
+	appear in the same line as it modifies, as the gas manual in
+	binutils-2.9.5.0.4 says "it must be in the same line".
+
+1999-08-04  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* boot.c (load_image): Fix a strcmp test. Reported by Pavel
+	Roskin <pavel_roskin@geocities.com>.
+
+1999-08-03  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From "Dan J. Walters" <djw@cs.utexas.edu>:
+	* stage2/i386-elf.h (EI_BRAND): New macro.
+	* stage2/boot.c (load_image): If the kernel is ELF, check if it
+	is a FreeBSD kernel as well as a Multiboot kernel, and if it is
+	a FreeBSD kernel, then mask ENTRY_ADDR since FreeBSD requires
+	that. Likewise, mask MEMADDR.
+	(bsd_boot): Set the bi_symtab and the bi_esymtab members of BI
+	only if MBI.FLAGS has the flag MB_INFO_AOUT_SYMS. Otherwise,
+	clear them.
+
+1999-07-30  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From Pavel Roskin <pavel_roskin@geocities.com>:
+	* grub/getopt.c: New file. Copied from texinfo-3.12n.
+	* grub/getopt1.c: Likewise.
+	* grub/getopt.h: Likewise.
+	* grub/Makefile.am (grub_SOURCES): Added getopt.c, getopt1.c and
+	getopt.h.
+	* configure.in: Check for string.h and strings.h.
+	* grub/asmstub.c (grub_stage2): Fix a misordering in the output
+	format of the inline assembly.
+
+1999-07-30  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From Pavel Roskin <pavel_roskin@geocities.com>:
+	* stage2/asm.S (get_diskinfo_standard): If the number of sectors
+	returned is zero, then return an error code, even if non-carrier.
+
+1999-07-15  Gordon Matzigkeit  <gord@zen.fig.org>
+
+	* docs/Makefile.am (grub.info): Use an ugly hack to downgrade
+ 	grub.texi so that it works with Debian's version of texinfo.
+
+1999-07-26  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/bios.c (get_diskinfo): When DRIVE is a floppy drive,
+	try standard probe routine at first. Reported by Peter Astrand
+	<altic@lysator.liu.se>.
+
+	* grub/main.c (main): Call printf instead of grub_printf.
+	Reported by Klaus Reichl <a8709182@unet.univie.ac.at>.
+
+1999-07-15  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/cmdline.c (skip_to): Don't increase CMDLINE if the
+	character to which CMDLINE points is NUL.
+
+	* stage2/Makefile.am (EXTRA_DIST): Removed smp-imps.c.
+	(stage2_exec_SOURCES): Added smp-imps.c.
+	* stage2/cmdline.c [!GRUB_UTIL] (IMPS_DEBUG) (KERNEL_PRINT)
+	(CMOS_WRITE_BYTE) (CMOS_READ_BYTE) (PHYS_TO_VIRTUAL)
+	(VIRTUAL_TO_PHYS) (inb) (outb) (cmos_write_byte)
+	(cmos_read_byte): These are now defined in ...
+	* stage2/smp-imps.c (IMPS_DEBUG) (KERNEL_PRINT)
+	(CMOS_WRITE_BYTE) (CMOS_READ_BYTE) (PHYS_TO_VIRTUAL)
+	(VIRTUAL_TO_PHYS) (inb) (outb) (cmos_write_byte)
+	(cmos_read_byte): ... here.
+	* stage2/cmdline.c [!GRUB_UTIL]: Include apic.h and smp-imps.h.
+
+1999-07-14  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	The function ungetch is simulated so that the user can use a
+	buggy curses.
+
+	* grub/asmstub.c [HAVE_LIBCURSES] (save_char): New variable.
+	(getkey) [HAVE_LIBCURSES]: If SAVE_CHAR is not ERR, return
+	SAVE_CHAR and clear it.
+	(checkkey) [HAVE_LIBCURSES]: If SAVE_CHAR is not ERR, return
+	SAVE_CHAR. If C is not ERR, set SAVE_CHAR to C.
+
+1999-07-14  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* stage2/char_io.c (get_cmdline) [GRUB_UTIL]: Recognize
+	backspace when ncurses fails to do this.
+
+	* grub/asmstub.c (grub_stage2) [HAVE_LIBCURSES]: Call wtimeout
+	instead of nodelay.
+	(getkey) [HAVE_LIBCURSES]: Likewise.
+
+1999-07-14  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage1/stage1_lba.S (probe_values): New variable. This is not
+	used actually, but prevents `install' command from failing
+	bogusly.
+
+1999-07-14  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	All constants in stage1s are moved to stage1.h and renamed
+	appropriately, and include stage1.h instead.
+
+	* grub/Makefile.am (AM_CFLAGS): Added the include path to stage1.
+	* stage2/Makefile.am (INCLUDES): New variable.
+	* stage1/Makefile.am (stage1_exec_SOURCES): Added stage1.h
+	(stage1_lba_exec_SOURCES): Likewise.
+	* stage1/stage1.h: New file.
+	* stage1/stage1.S (SIGNATURE): Renamed to ...
+	* stage1/stage1.h (STAGE1_SIGNATURE): ... this.
+	* stage1/stage1.S (BPBEND): Renamed to ...
+	* stage1/stage1.h (STAGE1_BPBEND): ... this.
+	* stage1/stage1.S (PARTSTART): Renamed to ...
+	* stage1/stage1.h (STAGE1_PARTSTART): ... this.
+	* stage1/stage1.S (MINPARMSIZ): Renamed to ...
+	* stage1/stage1.h (STAGE1_MINPARMSIZE): ... this.
+	* stage1/stage1.S (LISTSIZ): Renamed to ...
+	* stage1/stage1.h (STAGE1_LISTSIZE): ... this.
+	* stage1/stage1.S (REALSTACK): Renamed to ...
+	* stage1/stage1.h (STAGE1_STACKSEG): ... this.
+	* stage1/stage1.S (BUFFERSEG): Renamed to ...
+	* stage1/stage1.h (STAGE1_BUFFERSEG): ... this.
+	* stage1/stage1.S (BIOS_HD_FLAG): Renamed to ...
+	* stage1/stage1.h (STAGE1_BIOS_HD_FLAG): ... this.
+	* stage1/stage1_lba.S (SIGNATURE): Removed.
+	* stage1/stage1_lba.S (BPBEND): Likewise.
+	* stage1/stage1_lba.S (PARTSTART): Likewise.
+	* stage1/stage1_lba.S (MINPARMSIZ): Likewise.
+	* stage1/stage1_lba.S (LISTSIZ): Likewise.
+	* stage1/stage1_lba.S (REALSTACK): Likewise.
+	* stage1/stage1_lba.S (BUFFERSEG): Likewise.
+	* stage1/stage1_lba.S (BIOS_HD_FLAG): Likewise.
+
+	* stage1/stage1.S (stage1_id): New variable.
+	* stage1/stage1_lba.S (stage1_id): Likewise.
+	* stage1/stage1.h (COMPAT_VERSION_MINOR): Set to 2.
+	(STAGE1_ID_OFFSET): New macro.
+	(STAGE1_ID_CHS): Likewise.
+	(STAGE1_ID_LBA): Likewise.
+	* stage2/cmdline.c (enter_cmdline) [!GRUB_UTIL]: When running
+	the command `install' and STAGE1_FILE is stage1_lba, check if
+	LBA is supported.
+	(enter_cmdline) [GRUB_UTIL]: In the same case above, check only
+	if CURRENT_DRIVE is a hard disk and, if so, print a warning
+	message, because /sbin/grub cannot detect if LBA is supported or
+	not.
+
+	* stage1/stage1_lba.S: Fix a bug that incorrectly assigns the
+	segment of buffer address.
+
+1999-07-13  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/boot.c (load_image): When removing "vga=...", memmove
+	the length of VGA_END plus one.
+
+1999-07-12  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/bios.c (get_diskinfo): In LBA mode, compute
+	TOTAL_SECTORS from DRP instead of GEOMETRY.
+	Clear GEOMETRY->FLAGS first.
+
+	* stage2/boot.c (load_image): Fix inverted lines.
+
+1999-07-12  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	Support Linux video mode selection.
+
+	* stage2/shared.h (LINUX_VID_MODE_OFFSET): New macro.
+	(LINUX_VID_MODE_NORMAL): Likewise.
+	(LINUX_VID_MODE_EXTENDED): Likewise.
+	(LINUX_VID_MODE_ASK): Likewise.
+	[!WITHOUT_LIBC_STUBS] (strlen): Likewise.
+	(grub_strlen): Declared.
+	* stage2/boot.c (load_image): Added Linux video mode selection.
+	* stage2/char_io.c [!STAGE1_5] (grub_strlen): New function.
+
+1999-07-12  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/char_io.c (print_error): Print ERRNUM in the format of
+	%u instead of %d.
+	(convert_to_ascii) [STAGE1_5]: Eliminate the `x' and `d'
+	handling code.
+	(grub_printf): Declare FORMAT as `const char *'.
+	(grub_printf) [STAGE1_5]: Eliminate the `x' and `d' handling
+	code.
+	(get_based_digit): Removed.
+	(safe_parse_maxint): Remove unnecessary `register' prefixes,
+	because GCC does better optimization.
+	Declare DIGIT as `unsigned int' and calculate the value by more
+	compact instructions.
+	[!STAGE1_5] (grub_strncat): Declare S2 as `const char *'.
+	[!STAGE1_5] (grub_strcmp): Declare S1 and S2 as `const char *'.
+	[!STAGE1_5] (grub_strstr): Likewise.
+	(grub_memmove): Declare FROM as `const char *'.
+	The copy code is replaced with inline assembly code stolen from
+	Linux-2.2.2.
+
+	* stage2/shared.h (grub_printf) : Corrected.
+	(grub_strncat): Likewise.
+	(grub_memmove): Likewise.
+	(grub_strstr): Likewise.
+	(grub_strcmp): Likewise.
+
+1999-07-11  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage1/stage1.S (sectors): Change the size to long.
+	(heads): Likewise.
+	(sector_start): New variable.
+	(head_start): Likewise.
+	(cylinder_start): Likewise.
+	(final_init): Set %si to SECTORS first, and use %si for memory
+	references.
+	Zero %eax so that the high 16 bits are always zero.
+	Set %di to FIRSTLIST - LISTSIZ instead of FIRSTLIST.
+	(bootloop): Omit the complex CHS recomputation, and always
+	compute them from LBA address instead.
+	Call 32bits div instructions instead of 16bits div instructions.
+	Update the position where to load data from at the end of this
+	loop, instead of the beginning.
+
+	* stage1/stage1_lba.S: New file.
+	* stage1/Makefile.am (nodist_pkgdata_DATA): Added stage1_lba.
+	(LDFLAGS): New variable.
+	(noinst_PROGRAMS): Added stage1_lba.exec.
+	(stage1_lba_exec_SOURCES): New variable.
+	(%: %.exec): New rule.
+
+1999-06-28  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* grub/main.c (main): The third argument for strtoul is changed
+	to 0 in the case where an option is OPT_INSTALL_PARTIION.
+	Reported by Pavel Roskin <pavel_roskin@geocities.com>.
+
+1999-06-27  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/shared.h (STAGE2_STAGE2_ID): New macro.
+	(STAGE2_VER_STR_OFFS): Set to 0xd.
+	(STAGE2_ID_STAGE2): New macro.
+	(STAGE2_ID_FFS_STAGE1_5): Likewise.
+	(STAGE2_ID_E2FS_STAGE1_5): Likewise.
+	(STAGE2_ID_FAT_STAGE1_5): Likewise.
+	(STAGE2_ID) [!STAGE1_5]: Defined as STAGE2_ID_STAGE2.
+	(STAGE2_ID) [STAGE1_5] [FSYS_FFS]: Defined as
+	STAGE2_ID_FFS_STAGE1_5.
+	(STAGE2_ID) [STAGE1_5] [FSYS_EXT2FS]: Defined as
+	STAGE2_ID_STAGE1_5.
+	(STAGE2_ID) [STAGE1_5] [FSYS_FAT]: Defined as
+	STAGE2_ID_FAT_STAGE1_5.
+	(COMPAT_VERSION_MINOR): Set to 1.
+	* stage2/asm.S (stage2_id): New variable.
+	* stage1/stage1.S: Change the minor version to 1.
+
+1999-06-27  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* configure.in (CFLAGS): Set to "-g", since only this flag is
+	always sharable.
+	(STAGE1_CFLAGS): Set to "-O2", and AC_SUBST this.
+	(GRUB_CFLAGS): Likewise.
+	(saved_CFLAGS): New variable for temporarily saving CFLAGS.
+	(STAGE2_CFLAGS): Set to "-Os" if this option is available,
+	otherwise set to "-fno-strength-reduce -fno-unroll-loops",
+	and then AC_SUBST this.
+	* grub/Makefile.am (AM_CFLAGS): Prepended @GRUB_CFLAGS@.
+	* stage1/Makefile.am (AM_CFLAGS): Prepended @STAGE1_CFLAGS@.
+	* stage2/Makefile.am (libgrub_a_CFLAGS): Prepened @GRUB_CFLAGS@.
+	(STAGE2_COMPILE): Prepended @STAGE2_CFLAGS@.
+
+	* stage2/asm.S (chain_stage2): Pass CURRENT_PARTITION and
+	CURRENT_DRIVE, instead of INSTALL_PARTITION and BOOT_DRIVE.
+
+1999-06-27  Pavel Roskin  <pavel_roskin@geocities.com>
+
+	* configure.in: set CFLAGS to "-Os -g" for compilers which
+	understand "-Os" if CFLAGS is not already set. Use
+	"-O2 -fno-strength-reduce -fno-unroll-loops -g" for older gcc
+	versions.
+
+1999-06-25  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage2/disk_io.c (attempt_mount) [STAGE1_5]: Set FSYS_TYPE to
+	0, and set it to NUM_FSYS if mount fails.
+	(real_open_partition): Call rawread in Stage 1.5 as well.
+
+1999-06-24  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* Makefile.am (SUBDIRS): Change the order of the directories so
+	that a directory will be made after the dependent directories
+	are made. `grub' depends on `stage2', and `docs' depends on
+	`grub'. Do not make in parallel.
+	* docs/help2man: Copied from help2man-1.012, which contains my
+	previous change.
+	* docs/grub.8: Regenerated.
+
+1999-06-24  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	Build process is cleaned up. Stage 2 and Stage 1.5's are all
+	built in the directory stage2.
+
+	From Pavel Roskin <pavel_roskin@geocities.com>:
+	* Makefile.am (SUBDIRS): e2fs_stage1_5, ffs_stage1_5,
+	fat_stage1_5 and shared_src are removed.
+	(DISTCLEANFILES): Deleted.
+	* configure.in: Call AC_PROG_RANLIB.
+	(AC_INIT): Change the argument to stage2/stage2.c.
+	(LIBS): Renamed to ...
+	(GRUB_LIBS): ... this, and call AC_SUBST for this.
+	Our own rules are removed.
+	(AC_OUTPUT): e2fs_stage1_5/Makefile, ffs_stage1_5/Makefile,
+	fat_stage1_5/Makefile and shared_src/Makefile are removed.
+	* docs/Makefile.am (HELP2MAN): The prefix $(srcdir) is removed.
+	[GRUB_MAINT]: Prepend $(srcdir) to $(HELP2MAN).
+	* e2fs_stage1_5/Makefile.am: Deleted.
+	* e2fs_stage1_5/Makefile.in: Likewise.
+	* fat_stage1_5/Makefile.am: Likewise.
+	* fat_stage1_5/Makefile.in: Likewise.
+	* ffs_stage1_5/Makefile.am: Likewise.
+	* ffs_stage1_5/Makefile.in: Likewise.
+	* grub/Makefile.am (CLEANFILES): Likewise.
+	(COMPILE): Likewise.
+	(INCLUDES): Likewise.
+	(DEP_FILES): Likewise.
+	(@SHARED_SRC_RULES@): Likewise.
+	(AM_CFLAGS): New variable.
+	(grub_LDADD): Set to the library libgrub.a and @GRUB_LIBS@.
+	* shared_src/Makefile.am: Deleted.
+	* shared_src/Makefile.in: Likewise.
+	* shared_src/apic.h: Moved to ...
+	* stage2/apic.h: ... here.
+	* shared_src/asm.S: Moved to ...
+	* stage2/asm.S: ... here.
+	* shared_src/bios.c: Moved to ...
+	* stage2/bios.c: ... here.
+	* shared_src/boot.c: Moved to ...
+	* stage2/boot.c: ... here.
+	* shared_src/char_io.c: Moved to ...
+	* stage2/char_io.c: ... here.
+	* shared_src/cmdline.c: Moved to ...
+	* stage2/cmdline.c: ... here.
+	* shared_src/common.c: Moved to ...
+	* stage2/common.c: ... here.
+	* shared_src/defs.h: Moved to ...
+	* stage2/defs.h: ... here.
+	* shared_src/dir.h: Moved to ...
+	* stage2/dir.h: ... here.
+	* shared_src/disk_inode.h: Moved to ...
+	* stage2/disk_inode.h: ... here.
+	* shared_src/disk_inode_ffs.h: Moved to ...
+	* stage2/disk_inode_ffs.h: ... here.
+	* shared_src/disk_io.c: Moved to ...
+	* stage2/disk_io.c: ... here.
+	* shared_src/fat.h: Moved to ...
+	* stage2/fat.h: ... here.
+	* shared_src/filesys.h: Moved to ...
+	* stage2/filesys.h: ... here.
+	* shared_src/freebsd.h: Moved to ...
+	* stage2/freebsd.h: ... here.
+	* shared_src/fs.h: Moved to ...
+	* stage2/fs.h: ... here.
+	* shared_src/fsys_ext2fs.c: Moved to ...
+	* stage2/fsys_ext2fs.c: ... here.
+	* shared_src/fsys_fat.c: Moved to ...
+	* stage2/fsys_fat.c: ... here.
+	* shared_src/fsys_ffs.c: Moved to ...
+	* stage2/fsys_ffs.c: ... here.
+	* shared_src/gunzip.c: Moved to ...
+	* stage2/gunzip.c: ... here.
+	* shared_src/i386-elf.h: Moved to ...
+	* stage2/i386-elf.h: ... here.
+	* shared_src/imgact_aout.h: Moved to ...
+	* stage2/imgact_aout.h: ... here.
+	* shared_src/mb_header.h: Moved to ...
+	* stage2/mb_header.h: ... here.
+	* shared_src/mb_info.h: Moved to ...
+	* stage2/mb_info.h: ... here.
+	* shared_src/pc_slice.h: Moved to ...
+	* stage2/pc_slice.h: ... here.
+	* shared_src/shared.h: Moved to ...
+	* stage2/shared.h: ... here.
+	* shared_src/smp-imps.c: Moved to ...
+	* stage2/smp-imps.c: ... here.
+	* shared_src/smp-imps.h: Moved to ...
+	* stage2/smp-imps.h: ... here.
+	* shared_src/stage1_5.c: Moved to ...
+	* stage2/stage1_5.c: ... here.
+	* shared_src/stage2.c: Moved to ...
+	* stage2/stage2.c: ... here.
+	* stage1/Makefile.am (pkgdata_DATA): Renamed to ...
+	(nodist_pkgdata_DATA): ... this.
+	(COMPILE): Deleted.
+	(AM_CFLAGS): New variable.
+	* stage2/Makefile.am: Completely rewritten from scratch.
+	(TESTS): New variable.
+	(noinst_SCRIPTS): Likewise.
+	(noinst_HEADERS): Likewise.
+	(EXTRA_DIST): Set to smp-imps.c and $(noinst_SCRIPTS).
+	(noinst_LIBRARIES): New variable.
+	(libgrub_a_SOURCES): Likewise.
+	(libgrub_a_CFLAGS): Likewise.
+	(pkgdata_DATA): Deleted.
+	(nodist_pkgdata_DATA): New variable.
+	(MOSTLYCLEANFILES): Set to $(noinst_PROGRAMS).
+	(COMPILE): Deleted.
+	(INCLUDES): Likewise.
+	(stage2_exec_LDADD): Likewise.
+	(DEP_FILES): Likewise.
+	(stage2_exec_SOURCES): Set to the actual source files instead of
+	dummy.
+	(DISTFILES): Deleted.
+	(stage2.exec): Likewise.
+	(stage2): Likewise.
+	(@SHARED_SRC_RULES@): Likewise.
+	(noinst_PROGRAMS): Set to executable formats of Stage 2 and
+	Stage 1.5's.
+	(STAGE2_LINK): New variable.
+	(STAGE2_COMPILE): Likewise.
+	(STAGE1_5_LINK): Likewise.
+	(STAGE1_5_COMPILE): Likewise.
+	(stage2_exec_CFLAGS): Likewise.
+	(stage2_exec_LDFLAGS): Likewise.
+	(e2fs_stage1_5_exec_SOURCES): Likewise.
+	(e2fs_stage1_5_exec_CFLAGS): Likewise.
+	(e2fs_stage1_5_exec_LDFLAGS): Likewise.
+	(fat_stage1_5_exec_SOURCES): Likewise.
+	(fat_stage1_5_exec_CFLAGS): Likewise.
+	(fat_stage1_5_exec_LDFLAGS): Likewise.
+	(ffs_stage1_5_exec_SOURCES): Likewise.
+	(ffs_stage1_5_exec_CFLAGS): Likewise.
+	(ffs_stage1_5_exec_LDFLAGS): Likewise.
+	(% : %.exec): New rule.
+
+	* stage2/size_test: New file, for checking for the sizes of
+	Stage 2 and Stage 1.5's.
+
+1999-06-24  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* stage1/stage1.S: Call testb instead of andb when checking if
+	the drive is a floppy.
+
+1999-06-23  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* grub/asmstub.c [__linux__]: Include linux/fs.h for BLKFLSBUF.
+	(grub_stage2): Call sync before and after calling doit.
+	(gurb_stage2) [__linux__]: Invalidate buffer caches by BLKFLSBUF
+	ioctl.
+	* grub/main.c (main): Call sync first. Suggested by Pavel Roskin
+	<pavel_roskin@geocities.com>.
+
+	* configure.in: Curses libraries are always checked.
+	(--enable-sbin-grub): Deleted. Now /sbin/grub is always built.
+	(--enable-maintainer-mode): New option.
+	* grub/Makefile.am (EXTRA_PROGRAMS): Deleted.
+	(sbin_PROGRAMS): Just set to grub.
+	* docs/Makefile.am (man_MANS): New variable.
+	(HELP2MAN): Likewise.
+	(noinst_SCRIPTS): Likewise.
+	(EXTRA_DIST): Add $(man_MANS) and $(noinst_SCRIPTS).
+	[GRUB_MAINT]: Define the rule for the /sbin/grub manual.
+	* docs/help2man: Copied from texinfo-3.12i.
+	(--section): New option to specify which section a manual
+	belongs	to.
+	(opt_section): New variable.
+	(section): Likewise.
+	* docs/grub.8: Produced by help2man automatically.
+
+1999-06-22  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* shared_src/char_io.c (get_cmdline): Add two missing `break's.
+
+	* shared_src/cmdline.c (commands): Add quit.
+	(enter_cmdline): Change the return type	to cmdline_t, and return
+	CMDLINE_OK if successful, otherwise CMDLINE_ERROR if fail.
+	(enter_cmdline) [GRUB_UTIL]: Return CMDLINE_ABORT if CUR_HEAP
+	contains "quit".
+	[!GRUB_UTIL]: Just print an annotation message.
+	* shared_src/shared.h (cmdline_t): New enum type.
+	(enter_cmdline): Change the return type to cmdline_t.
+	(cmain): Remove ``noreturn'' attribute.
+	* shared_src/stage2.c (menu_t): New enum type.
+	(run_menu): Change the return type to menu_t.
+	If enter_cmdline returns CMDLINE_ABORT, then return MENU_ABORT,
+	otherwise return MENU_OK.
+	(cmain): If enter_cmdline aborts, then break the command-line
+	loop and return. If run_menu aborts, then return.
+
+1999-06-22  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* shared_src/Makefile.am (EXTRA_DIST): Add bios.c. Reported by
+	Pavel Roskin <pavel_roskin@geocities.com>.
+
+1999-06-21  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* docs/Makefile.am (html): Deleted.
+	(txt): Likewise.
+	(EXTRA_DIST): $(txt) and $(html) are removed.
+	* docs/boot-proposal.html: Removed.
+	* docs/errors.html: Likewise.
+	* docs/faq.html: Likewise.
+	* docs/grub.html: Likewise.
+	* docs/install.html: Likewise.
+	* docs/mem64mb.html: Likewise.
+	* docs/technical.html: Likewise.
+	* docs/using.html: Likewise.
+	* docs/PC_partitioning.txt: Likewise.
+	* docs/bios_mapping.txt: Likewise.
+	* docs/commands.txt: Likewise.
+	* docs/embedded_data.txt: Likewise.
+	* docs/filesystem.txt: Likewise.
+
+1999-06-21  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	From Alexander K. Hudek <alexhudek@home.com>:
+	* shared_src/disk_io.c (real_open_partition): Check if
+	CURRENT_SLICE is equal to PC_SLICE_TYPE_WIN95_EXTENDED as well.
+	* shared_src/pc_slice.c (PC_SLICE_TYPE_WIN95_EXTENDED): New
+	macro.
+	* shared_src/bios.c (biosdisk): Clear the reserved member of DAP.
+
+1999-06-08  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	Color-menu support based on Peter Astrand
+	<altic@lysator.liu.se>'s patch.
+
+	* shared_src/asm.S (nocursor): New function.
+	* shared_src/cmdline.c (normal_color): New variable.
+	(highlight_color): Likewise.
+	(commands): Added "color" command.
+	(enter_cmdline): Handle the color command.
+	* shared_src/shared.h (normal_color): Declared.
+	(highlight_color): Likewise.
+	[!GRUB_UTIL] (nocursor): Likewise.
+	* shared_src/stage2.c (print_border) [!GRUB_UTIL]: Color the
+	menu.
+	(run_menu) [!GRUB_UTIL]: Call nocursor, and call set_line with
+	the second argument HIGHLIGHT_COLOR when highlighting a line,
+	and NORMAL_COLOR when drawing a normal line.
+	(cmain): Initialize normal_color and highlight_color. Handle
+	the color command in the same way as the command-line
+	interface.
+
+1999-06-07  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* e2fs_stage1_5/Makefile.am (IMPORTANT_SIZE_LIMIT): Set to 31744.
+	* fat_stage1_5/Makefile.am (IMPORTANT_SIZE_LIMIT): Likewise.
+
+1999-06-06  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	The debug version of Stage 2 is removed.
+
+	* shared_src/cmdline.c: The imps code is now defined if GRUB_UTIL
+	is not defined, but not if DEBUG.
+	(debug): New global variable.
+	(commands): All commands are always enabled, and added "debug".
+	(debug_fs_print_func): Defined unconditionally.
+	(debug_fs_blocklist_func): If DEBUG is true, then call printf.
+	(enter_cmdline): Handle "testload", "read", "fstest",
+	"impsprobe" and "displaymem" unconditionally, and added "debug"
+	handling.
+	[GRUB_UTIL]: If a command is impsprobe, just fails.
+	* shared_src/disk_io.c (devread) [!STAGE1_5]: If DEBUG_FS and
+	DEBUG are true, then call printf.
+	* shared_src/asm.S (patch_code): Defined unconditionally.
+	(patch_code_end): Likewise.
+	* stage1/stage1.S (firstlist) [!FFS_STAGE1_5]: Increase the
+	number of sectors to 90, because Stage 2 is larger than 80
+	sectors.
+	* configure.in: The option --enable-debug is removed, and do
+	not output "stage2_debug/Makefile".
+	* Makefile.am (SUBDIRS): stage2_debug is removed.
+	* stage2_debug/Makefile.am: Deleted.
+	* stage2_debug/Makefile.in: Likewise.
+
+1999-06-02  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* grub/main.c (verbose): New variable.
+	(read_only): Likewise.
+	(OPT_VERBOSE): New macro.
+	(OPT_READ_ONLY): Likewise.
+	(longopts): Add --read-only and --verbose options.
+	(usage): Add the descriptions about --read-only and --verbose.
+	(main): Handle OPT_VERBOSE and OPT_READ_ONLY.
+	If HOLD and VERBOSE are non-zero, then display the message
+	about how to restart /sbin/grub.
+
+	* shared_src/shared.h (verbose) [GRUB_UTIL]: Declared.
+	(read_only) [GRUB_UTIL]: Likewise.
+
+	* grub/asmstub.c (hex_dump): New function.
+	(biosdisk): In the case where SUBFUNC is
+	BIOSDISK_WRITE, check for READ_ONLY and call nwrite if
+	READ_ONLY is zero. If VERBOSE is non-zero, display what GRUB
+	will try to do.
+	(get_diskinfo): Open DEVNAME with the mode O_RDWR if READ_ONLY
+	is zero, and attempt to open DEVNAME with the mode O_RDONLY
+	regardless of ERRNO if READ_ONLY is non-zero. If VERBOSE is
+	non-zero, then display the drive DRIVE and the file DEVNAME.
+
+	* shared_src/disk_io.c (set_device) [STAGE1_5]: Eliminate
+	completion code.
+
+1999-06-01  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* grub/asmstub.c: Do not use I_AM_VERY_BRAVE any more.
+	(grub_stage2): Delete first_scsi_disk and add a variable
+	num_hd, which is used for counting how many drives are
+	detected.
+	Initialize the flags member of each element of disks to -1
+	instead of 0, and check if it is equal to -1 instead of 0 when
+	close it.
+	(get_diskinfo): Treat -1 as non-caching state instead of 0.
+
+1999-06-01  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	Reported from Klaus Reichl <a8709182@unet.univie.ac.at>:
+	* docs/.cvsignore: New file.
+	* shared_src/disk_io.c (print_a_completion): New function
+	which saves what has been printed to UNIQUE_STRING and printf
+	it.
+	(unique) [!STAGE1_5]: New variable.
+	(unique_string): Likewise.
+	(print_completions): Use print_a_completion, and improve the
+	completion facility.
+	* shared_src/fsys_ext2fs.c (ext2fs_dir) [!STAGE1_5]: Use
+	print_a_completion instead of just printf.
+	* shared_src/fsys_ffs.c (ffs_dir) [!STAGE1_5]: Likewise.
+	* shared_src/fsys_fat.c (fat_dir) [!STAGE1_5]: Likewise.
+	* shared_src/shared.h (print_a_completion): Declared.
+	* shared_src/cmdline.c (enter_cmdline): Explicitly cast
+	int to pointer to char for grub_read.
+	* grub/asmstub.c (grub_stage2) [__linux__]: Don't use /dev/fd1.
+	Probe 4 IDE drives instead of 2.
+	(biosdisk) [__linux__]: Add a prototype for _llseek.
+	* shared_src/char_io.c (get_cmdline): Update LPOS and LLEN_OLD
+	when the functon print_completion modifies CMDLINE.
+	* shared_src/stage2.c (get_line_from_config): Fix LITERAL
+	handling.
+
+1999-05-25  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* grub/asmstub.c (grub_stage2): Fix a memory leak that FP is
+	not closed.
+
+1999-05-25  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* grub/main.c: Replace OPT_DISABLE_CONFIG_FILE and
+	OPT_DISABLE_CURSES with OPT_NO_CONFIG_FILE and OPT_NO_CURSES
+	respectively.
+	(longopts): Rename from "disable-config-file" to
+	"no-config-file", and from "disable-curses" to "no-curses".
+	(usage): Use "grub" instead of ARGV[0], read the standards.
+	Change the help message according to the changes above.
+	(main): Handle OPT_NO_CONFIG_FILE and OPT_NO_CURSES, instead
+	of OPT_DISABLE_CONFIG_FILE and OPT_DISABLE_CURSES.
+
+1999-05-21  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* docs/TODO: Moved to ...
+	* TODO: ... here.
+	* docs/BUGS: Moved to ...
+	* BUGS: ... here.
+	* docs/COPYING: Removed.
+	* docs/Makefile.am (EXTRA_DIST): Get rid of BUGS.
+	* Makefile.am (EXTRA_DIST): Set to BUGS.
+
+1999-05-17  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* acinclude.m4 (grub_ASM_EXT_C): Do not overrun the command
+	shift. Reported by Pavel Roskin <pabel_roskin@geocities.com>.
+
+1999-05-14  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* docs/Makefile.am (info_TEXINFOS): Added multiboot.texi.
+	* docs/multiboot.texi: New file. From Kunihiro Ishiguro.
+
+1999-05-12  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* grub/asmstub.c: Include <errno.h>. Reported by Kunihiro
+	Ishiguro <kunihiro@zebra.org>.
+
+1999-05-11  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	Reported by Brian Brunswick <brian@skarpsey.demon.co.uk>:
+	* shared_src/asm.S (start) [STAGE1_5]: Jump to 0x0:0x2000.
+	* shared_src/cmdline.c (enter_cmdline): Doesn't check for the jump
+	address in stage2. We are not paranoid.
+	Add a missing RAW_ADDR macro.
+	* shared_src/diskio.c (grub_open): Call setup_part even in stage1.5.
+	And, include necessary functions that were eliminated incorrectly.
+	* shared_src/char_io.c [STAGE1_5]: Eliminate unnecessary functions
+	for stage1.5.
+
+	* grub/asmstub.c (nread): New function. Handle EINTR.
+	(nwrite): Likewise.
+	(biosdisk) [I_AM_VERY_BRAVE]: When SUBFUNC is BIOSDISK_WRITE, call
+	nwrite.
+
+	Reported by Pavel Roskin <pavel_roskin@geocities.com>:
+	* shared_src/fsys_ext2fs.c (off_t): Renamed to ...
+	(linux_off_t): ... this.
+	* shared_src/defs.h (off_t): Renamed to ...
+	(mach_off_t): ... this.
+	* shared_src/fs.h (BBOFF): Use mach_off_t instead of off_t.
+	(SBOFF): Likewise.
+
+	* e2fs_stage1_5/Makefile.am (IMPORTANT_SIZE_LIMIT): Set to 81920.
+	* fat_stage1_5/Makefile.am (IMPORTANT_SIZE_LIMIT): Likewise.
+	* ffs_stage1_5/Makefile.am (IMPORTANT_SIZE_LIMIT): Set to 7168.
+
+1999-05-03  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	From Pavel Roskin:
+	* shared_src/shared.h: Redeclare.
+
+	* grub/main.c (main): Use strncpy rather than pointer assignment
+	to set the config file name.
+
+	* grub/asmstub.c: Make config_file a static array, not a pointer.
+	Correct the value of VERSION_STRING.
+
+1999-04-10  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* debian/rules (build): Install into /lib instead of /share.
+
+1999-05-03  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	Preliminary non-interactive use support.
+
+	* grub/main.c (use_config_file): New variable.
+	(use_curses): Likewise.
+	(OPT_DISABLE_CONFIG_FILE): New constant.
+	(OPT_DISABLE_CURSES): Likewise.
+	(OPT_BATCH): Likewise.
+	(longopts): Add new options, --disable-config-file, --disable-curses,
+	and --batch.
+	(usage): Print the help messages about these new options.
+	(main): Handle them.
+
+	* grub/asmstub.c (grub_stage2) [HAVE_LIBCURSES]: If ! USE_CURSES,
+	fallback non-curses code.
+	(stop) [HAVE_LIBCURSES]: Likewise.
+	(cls) [HAVE_LIBCURSES]: Likewise.
+	(getxy) [HAVE_LIBCURSES]: Likewise.
+	(gotoxy) [HAVE_LIBCURSES]: Likewise.
+	(grub_putchar) [HAVE_LIBCURSES]: Likewise.
+	(getkey) [HAVE_LIBCURSES]: Likewise.
+	(checkkey) [HAVE_LIBCURSES]: Likewise.
+	(set_attrib) [HAVE_LIBCURSES]: Likewise.
+
+	* shared_src/cmdline.c (enter_cmdline): Do not use getc, but use
+	getkey.
+
+	* shared_src/stage2.c (cmain) [GRUB_UTIL]: Check if USE_CONFIG_FILE
+	is non-zero or not.
+
+	* shared_src/shared.h (getc): Removed.
+	(use_config_file) [GRUB_UTIL]: Add the declaration.
+	(use_curses) [GRUB_UTIL]: Likewise.
+
+1999-05-02  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* shared_src/asm.S (biosdisk_standard): Pop %ebp correctly, reported
+	by Pavel Roskin <pavel_roskin@geocities.com>.
+
+1999-04-25  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* docs/menu.lst: Rewritten, so that it contains up-to-date
+	information and FAQish configuration examples.
+
+1999-04-09  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* shared_src/asm.S (get_diskinfo_floppy): Correct the number of heads
+	and the one of cylinders.
+
+1999-04-06  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* grub/asmstub.c (get_diskinfo): Compute the total number of sectors
+	for DRIVE.
+
+	* shared_src/asm.S (get_diskinfo_standard): Clear the data segment
+	after calling int 0x13. Restore the base pointer after returning
+	to protected mode.
+	(get_diskinfo_floppy): Likewise.
+
+	* shared_src/bios.c (get_diskinfo): Always set the size of DRP to
+	the max size of DRP, regardless of the major version of extensions.
+
+1999-04-03  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* shared_src/shared.h (struct geometry): Declare total_sectors as
+	unsigned long instead of unsigned long long, because GRUB represents
+	a sector number by 4bytes integer, so it doesn't make sense.
+
+	* shared_src/bios.c (biosdisk) [!NO_INT13_FALLBACK]: Recompute
+	TOTAL_SECTORS according to CHS information.
+	(get_diskinfo) [DEBUG]: Print the geometry of DRIVE.
+
+	* shared_src/disk_io.c (real_open_partition): Set PART_LENGTH to
+	BUF_GEOM.TOTAL_SECTORS.
+
+1999-04-01  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* docs/texinfo.tex: Copied from automake-1.4a.
+
+	* configure.in (SHARED_SRC_RULES): Add bios into shared sources.
+
+	* e2fs_stage1_5/Makefile.am (e2fs_stage1_5_exec_LDADD): Added bios.o.
+	* fat_stage1_5/Makefile.am (fat_stage1_5_exec_LDADD): Likewise.
+	* ffs_stage1_5/Makefile.am (ffs_stage1_5_exec_LDADD): Likewise.
+	* stage2/Makefile.am (stage2_exec_LDADD): Likewise.
+	* stage2_debug/Makefile.am (stage2_debug_exec_LDADD): Likewise.
+
+	* shared_src/Makefile.am (EXTRA_DIST): Added bios.c.
+
+	* shared_src/asm.S (biosdisk): Deleted. Now defined in bios.c.
+	(get_diskinfo): Likewise.
+	(biosdisk_int13_extensions): New function.
+	(biosdisk_standard): Likewise.
+	(check_int13_extensions): Likewise.
+	(get_diskinfo_int13_extensions): Likewise.
+	(get_diskinfo_standard): Likewise.
+	(get_diskinfo_floppy): Likewise.
+
+	* shared_src/bios.c: New file.
+
+	* shared_src/shared.h (struct geometry): Added new member,
+	total_sectors.
+
+1999-03-28  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* shared_src/stage2.c (print_entries): Correctly assign MENU_ENTRIES
+	the entries starting from FIRST.
+
+1999-03-27  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* Change everything to use memset and memmove instead of bzero and
+	bcopy.  GNB's Not BSD.
+
+	* shared_src/shared.h (grub_memset): Adapted from grub_bzero.
+	(grub_memmove): Adapted from grub_bcopy.
+
+	* grub/asmstub.c (checkkey): Fix unterminated comment.
+
+	* shared_src/char_io.c (grub_printf): Renamed from printf.
+	(grub_tolower): Renamed from tolower.
+	(grub_isspace): Renamed from isspace.
+	(grub_strncat): Renamed from strncat.
+	(grub_strstr): Renamed from strstr.
+	(grub_bcopy): Renamed from bcopy.
+	(grub_bzero): Renamed from bzero.
+
+	From Bradford Hovinen:
+	* shared_src/char_io.c (get_cmdline): Add new argument to hide
+	password entry.
+	(grub_strcmp): New function.
+	* shared_src/shared.h (get_cmdline): Fix declaration.
+	(grub_strcmp): Declare.
+	* shared_src/stage2.c (run_menu): Use get_cmdline with an
+	ECHO_CHAR of `*'.  This protects against both brute-force and
+	sidelong-glance password cracking attempts.
+
+	* grub/main.c (usage): Display defaults for stage2 options.
+
+	* grub/asmstub.c [WITHOUT_LIBC_STUBS]: Renamed from
+	NO_REMAPPING_LIBC_FUNCTIONS.
+	* grub/main.c: Likewise.
+	* shared_src/shared.h: Likewise.
+
+1999-03-27  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* grub/asmstub.c (set_attrib): Use inch and addch, instead of
+	chgat, because chgat doesn't work as expected.
+
+1999-03-26  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* grub/asmstub.c (grub_stage2) [HAVE_LIBCURSES]: Call nodelay.
+	(checkkey) [HAVE_LIBCURSES]: If getting an input character, then
+	ungetch it, because checkkey shouldn't modify the input queue.
+
+	Use file descriptors instead of file pointers to support
+	>4GB disks in Linux.
+
+	* grub/asmstub.c (grub_stage2): Call close instead of fclose.
+	(get_diskinfo): Call open instead of fopen.
+	(biosdisk) [__linux__]: Use _llseek instead of lseek.
+	(biosdisk): Call read instead of fread.
+
+	Add options so that the user can specify the config file.
+
+	* grub/Makefile.am (CPPFLAGS): Use -fwritable-strings, because
+	grub assumes that all strings resides at the data section.
+
+	* grub/main.c: Define NO_REMAPPING_LIBC_FUNCTIONS before including
+	shared.h.
+	(OPT_CONFIG_FILE): New macro.
+	(OPT_INSTALL_PARTITION): Likewise.
+	(OPT_BOOT_DRIVE): Likewise.
+	(longopts): Add new options, config-file, install-partition and
+	boot-drive.
+	(usage): Add the documentation for them.
+	(main): Add handling code for OPT_CONFIG_FILE, OPT_INSTALL_PARTITION
+	and OPT_BOOT_DRIVE.
+
+	* grub/asmstub.c: Define NO_REMAPPING_LIBC_FUNCTIONS before including
+	shared.h.
+	(config_file): Make it char * instead of char [].
+	(getrtsecs): Return current time instead of 0xff.
+
+	* shared_src/shared.h [NO_REMAPPING_LIBC_FUNCTIONS]: Don't define
+	libc-API-compatible function names.
+	(config_file): Change the prototype from char [] to char *.
+	(grub_putchar): Renamed from putchar.
+
+1999-03-25  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* char_io.c (get_cmdline): Call cl_setcpos even if lpos == llen,
+	because ncurses won't update the cursor position.
+
+	* grub/main.c (OPT_HOLD): New macro.
+	(longopts): New option --hold.
+	(usage): Add the documentation about --hold.
+	(main): Set hold if --hold is specified. Wait until cleared.
+
+1999-03-22  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* shared_src/cmdline.c (enter_cmdline): Check the return value of
+	set_device in the `root' command.
+
+	* shared_src/char_io.c (memcheck): Special-case cur_part_desc and
+	reenable memory checking.
+
+1999-03-21  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* shared_src/boot.c (load_image): Make sure we use the mapped
+	address before actually writing data to memaddr.
+
+	* shared_src/char_io.c (get_cmdline): Only zero-terminate if there
+	were leading blanks.  This prevents accidental truncation of
+	commands.
+
+	* grub/asmstub.c (get_diskinfo): Cache device geometries as well
+	as file handles.
+	Use the Linux HDIO_GETGEO ioctl to make a better guess at hard
+	disk geometries.
+
+1999-03-16  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* shared_src/shared.h (geometry_t): Delete typedef, until we
+	actually use it.
+
+1999-03-16  OKUJI Yoshinori  <okuji@kuicr.kyoto-u.ac.jp>
+
+	* shared_src/asm.S (biosdisk): Use a structure for geometry
+	instead of a integer.
+	(get_diskinfo): Take a pointer to a geometry structure as the
+	second argument, and fill a geometry in it. Return 1 if an error
+	occurs, otherwise return 0.
+	* shared_src/boot.c (bsd_boot): Compute BIOS geometries for BSD.
+	* shared_src/cmdline.c (enter_cmdline): Declare dest_geom as
+	struct geometry.
+	* shared_src/disk_io.c (buf_geom): Declare as struct geometry.
+	* shared_src/filesys.h (SECTORS): Deleted.
+	(HEADS): Likewise.
+	(CYLINDERS): Likewise.
+	* shared_src/shared.h (BIOSDISK_FLAG_LBA_EXTENSION): New macro.
+	(struct geometry): New structure.
+	(buf_geom): Correct the prototype.
+	(get_diskinfo): Likewise.
+	(biosdisk): Likewise.
+
+1999-03-15  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* grub/asmstub.c (doit): Nested function to get a clean stack
+	frame while in grub_stage2.
+	Use different assembler magic.  From OKUJI Yoshinori.
+
+1999-03-14  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* shared_src/stage2.c (run_menu): Use A_REVERSE and A_NORMAL
+	constants instead of magic numbers.
+
+	* shared_src/shared.h (A_REVERSE): Renamed from ATTR_INVERSE for
+	compatibility with curses.
+	(A_NORMAL): Renamed from ATTR_NORMAL.
+
+	* shared_src/cmdline.c (enter_cmdline): Change prompt to "grub> ".
+	(enter_cmdline): Only abort the boot if we are in a script.
+
+	* shared_src/stage2.c (run_menu): Change prompts to "grub edit> ".
+
+	* shared_src/char_io.c (memcheck): Use RAW_ADDR to compute memory
+	locations.
+	(get_cmdline): Change the `goto next line' code to account for
+	newlines deleting to end of line under curses.
+
+	* Innumerable cleanups to fix warnings.  There are still too many
+	typecasts in the wrong places (int variables used to hold
+	pointers, then casted to a pointer type), but things look better.
+
+	* configure.in (CPPFLAGS): Bump up GCC warnings to -Wall
+	-Wmissing-prototypes -Wunused.
+
+	* shared_src/shared.h: Delete stupid declarations, and totally
+	rearrange for clarity.
+	(inb, outb): Move to cmdline.c, since it's only used there.
+	(print_possibilities, fsmax, fsys_table): Move definitions to
+	disk_io.c.
+
+	* grub/asmstub.c: Fill in more stubs.
+
+1999-03-13  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* shared_src/gunzip.c (border): Rename to bitorder, to resolve
+	clash with curses.
+	* shared_src/stage2.c (timeout): Rename to grub_timeout.
+
+	* configure.in: Check for curses libraries for use with
+	/sbin/grub.
+
+	* shared_src/shared.h (KEY_DELETE): Rename to KEY_DC, for
+	compatibility with curses.
+	(KEY_INSERT): Rename to KEY_IC.
+	(KEY_PGDN): Rename to KEY_NPAGE.
+	(KEY_PGUP): Rename to KEY_PPAGE.
+
+	* shared_src/asm.S (asm_getkey): Renamed to getkey.
+
+	* shared_src/char_io.c (getkey): Delete, because it's useless.
+
+	* shared_src/shared.h: Resolve name clashes with libc by renaming
+	overlapping functions to have grub_ prefixes, then defining
+	macros.
+
+	* grub/asmstub.c (start_stage2): Make some assertions about our
+	scratch memory area.
+
+	* shared_src/shared.h (end): Delete declaration.
+	(RAW_ADDR, RAW_SEG): Macros to redirect /sbin/grub memory requests
+	through grub_scratch_mem.
+
+	* grub/asmstub.c (get_mem_map): Implement, simulating 4MB
+	contiguous memory.
+	(get_code_end): Implement, simulating with a malloced area.
+	grub/asmstub.c (start_stage2): Initialize grub_scratch_mem.
+
+	* shared_src/asm.S (get_mem_map): Some BIOSes expect the high word
+	of %eax to be zero.
+	(get_code_end): Move this from common.c so that we can stub it out
+	in the simulator.
+
+	* debian/rules: Make sure info files end up in /usr/info, not
+	/info.
+
+1999-03-10  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* shared_src/asm.S (biosdisk): Make LBA mode work correctly.  From
+	OKUJI Yoshinori.
+	Unconditionally define NO_INT13_FALLBACK until we release GRUB
+	0.6.  This will help debug any problems with the LBA support until
+	then.
+
+1999-03-09  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* shared_src/asm.S (biosdisk): Compute location of
+	disk_address_packet correctly.  From OKUJI Yoshinori.
+
+1999-03-08  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* docs/grub.texi: New Texinfo documentation.
+
+	* shared_src/disk_io.c (set_device): First stab at interpreting
+	Mach-style partition naming.
+
+	* shared_src/stage2.c (run_menu): Don't say it was a failure if
+	enter_cmdline returns nonzero... just wait for a key.
+
+	* shared_src/cmdline.c (enter_cmdline): Return nonzero, and avoid
+	the fallback command if we did an install.
+
+	* shared_src/asm.S (_start): New explicit symbol to supress
+	warnings.
+
+	* e2fs_stage1_5/Makefile.am (NO_FANCY_STUFF): Renamed to STAGE1_5,
+	since that describes this conditional more accurately.
+	* fat_stage1_5/Makefile.am: Likewise.
+	* ffs_stage1_5/Makefile.am: Likewise.
+	* shared_src/asm.S: Likewise.
+	* shared_src/char_io.c: Likewise.
+	* shared_src/common.c: Likewise.
+	* shared_src/disk_io.c: Likewise.
+	* shared_src/fsys_ext2fs.c: Likewise.
+	* shared_src/fsys_ffs.c: Likewise.
+	* shared_src/shared.h: Likewise.
+
+1999-03-07  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* configure.in (SHARED_SRC_RULES): Automatically generate
+	Makefile dependencies for files in shared_src.
+	e2fs_stage1_5/Makefile.am: Use them.
+	fat_stage1_5/Makefile.am: Likewise.
+	ffs_stage1_5/Makefile.am: Likewise.
+	grub/Makefile.am: Likewise.
+	stage2/Makefile.am: Likewise.
+	stage2_debug/Makefile.am: Likewise.
+
+	* shared_src/disk_inode.h: Fix typo: i_ic shouldn't be defined.
+
+	* shared_src/fsys_ffs.c (block_map): Make static, since this
+	function isn't used outside of its defining file.
+
+	* shared_src/disk_io.c [NO_FANCY_STUFF]: Eliminate a whole bunch
+	more functions from the stage1.5.  From OKUJI Yoshinori.
+	* shared_src/fsys_ffs.c: Likewise.
+	* shared_src/char_io.c: Likewise.
+
+1999-03-05  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* shared_src/char_io.c (getkey): Don't set BUF_DRIVE to -1.
+	BUF_DRIVE has nothing at all to do with getkey.
+
+	* shared_src/common.c (err_list): Change description of ERR_GEOM
+	to be more informative.
+
+	* Makefile.am (configure): Depend on debian/changelog.
+
+	* configure.in (host_cpu): Make all fully i386-compatible CPUs be
+	identified as i386.
+	(AM_INIT_AUTOMAKE): Fetch values for PACKAGE and VERSION from
+	debian/changelog, so that we only have one file to update.
+
+	* shared_src/asm.S (get_diskinfo): Fix a few bit-twiddling bugs in
+	the BIOS extension detection code.
+	(biosdisk) [AWARD_INT13_EXTENSIONS]: Preliminary implementation
+	of Award's encoding of cylinder bits 10 and 11.
+	(biosdisk) [NO_INT13_FALLBACK]: If defined, don't use the standard
+	disk interface if the extended interface fails.
+
+	* configure.in: Make sure $(host_cpu) and $(host_vendor) are
+	substituted into the Makefile.
+
+	* e2fs_stage1_5/Makefile.am (pkgdatadir): Install files in
+	$(datadir)/grub/$(host_cpu)-$(host_vendor).
+	* fat_stage1_5/Makefile.am: Likewise.
+	* ffs_stage1_5/Makefile.am: Likewise.
+	* stage1/Makefile.am: Likewise.
+	* stage2/Makefile.am: Likewise.
+	* stage2_debug/Makefile.am: Likewise.
+
+1999-03-03  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* shared_src/asm.S (biosdisk): Use LBA mode if high nibble of
+	GEOMETRY is nonzero.
+	(get_diskinfo): Set high nibble of GEOMETRY (0xf0000000) to 1 if
+	LBA mode is detected.
+
+1999-03-02  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* shared_src/disk_io.c (make_saved_active): Use BIOSDISK_READ and
+	BIOSDISK_WRITE.
+
+	* shared_src/cmdline.c (enter_cmdline): Use BIOSDISK_WRITE.
+
+	* shared_src/shared.h (BIOSDISK_SUBFUNC_READ,
+	BIOSDISK_SUBFUNC_WRITE): Delete constants.
+
+	* shared_src/asm.S (biosdisk): Change subfunc argument to be
+	read=0, write=1.
+
+	* configure.in: Drop redundant AC_PROG_INSTALL.  From OKUJI
+	Yoshinori.
+
+1999-03-01  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* debian/rules (binary-arch): Properly install README.debian.
+
+	* acinclude.m4 (grub_OBJCOPY_ABSOLUTE): Don't forget to move the
+	old binary out of the way before reentering the loop.
+	(grub_ASM_ADDR32): Delete conftest files after running the test.
+
+	* debian/rules (binary-arch): Remove empty /sbin directory until
+	/sbin/grub is installed.  Use $(DESTDIR) instead of $(prefix) to
+	install files.
+
+	* shared_src/asm.S (version_string): Set the version string from
+	the VERSION specified in configure.in.
+
+	* Change all Makefiles into Makefile.ams.  Many major build
+	environment changes to get Automake/Autoconf working nicely.
+
+1999-02-28  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* NEWS: Moved from docs/NEWS.
+
+	* configure.in, acinclude.m4: New files for Autoconf.  From OKUJI
+	Yoshinori.
+
+	* AUTHORS, INSTALL: New files.
+
+1999-02-24  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* stage1/stage1.S (after_BPB): Do a hard disk probe first, so that
+	we can work with IDE floppies (like the LS-120).
+
+	* Run GNU Indent on */*.[ch].
+
+1999-02-21  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* debian: Add to the distribution, since we maintain the GRUB
+	Debian package ourselves.
+
+	* grub/asmstub.c: New file to implement stubbed assembly functions
+	under Unix.
+
+	* stage1/Makefile: Delete spurious dependencies on Makefile.
+	* stage2/Makefile: Likewise.
+	* stage2_debug/Makefile: Likewise.
+	* grub/Makefile: Likewise.
+
+	* shared_src/fsys_ext2fs.c (ext2fs_dir): Follow symbolic links
+	rather than giving an error.
+
+	* shared_src/common.c (err_list): Use labeled elements to
+	associate messages with error codes.
+	* shared_src/shared.h: Make error codes into an enumerated type.
+
+	* shared_src/common.c (err_list): Add ERR_SYMLINK_LOOP.
+	* shared_src/shared.h: Likewise.
+
+	* shared_src/char_io.c (bcopy): Don't make any assumptions about
+	the length of an unsigned long.
+
+	* grub/Makefile: Treat CFLAGS, CPPFLAGS, LDFLAGS according to
+	GNU standards.
+	* stage2/Makefile: Likewise.
+	* e2fs_stage1_5/Makefile: Likewise.
+	* fat_stage1_5/Makefile: Likewise.
+	* ffs_stage1_5/Makefile: Likewise.
+
+1999-02-20  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* docs/index.html: Rename to grub.html, so that we don't hide
+	files in this directory from a web browser.
+
+1999-02-15  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* Makefile.end (PROGS): Add grub.
+
+	* grub/main.c: New file.
+
+	* grub/Makefile: New directory to contain the stage2 Unix program.
+
+	* shared_src/cmdline.c: Use substring.
+	* shared_src/fsys_ext2fs.c: Likewise.
+	* shared_src/fsys_fat.c: Likewise.
+	* shared_src/fsys_ffs.c: Likewise.
+	* shared_src/stage2.c: Likewise.
+
+	* shared_src/shared.h: Delete strcmp, declare substring.
+
+	* shared_src/char_io.c (strcmp): Rename to `substring', because
+	this function doesn't behave the same as libc's strcmp.
+
+1999-02-14  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* shared_src/shared.h: (addr32, data32): Delete definitions.
+
+	* stage1/stage1.S: Modify to use GAS's new .code16 semantics.
+	shared_src/asm.S: Likewise.
+
+	* configure: Test to see if the `addr32' instruction is supported.
+	Ian Lance Taylor says that GAS's interpretation of `.code16' has
+	changed.  Older versions always generated 32-bit code, but
+	implicitly inserted addr32 and data32 when .code16 was given.
+	Newer versions generate 16-bit code, and require manual addr32 and
+	data32 overrides.
+
+	* shared_src/shared.h: Add some assertions to check that buffer
+	addresses are properly defined.
+
+1999-02-12  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* shared_src/stage2.c (run_menu): Pause if we failed to boot both
+	the default and fallback entries.
+
+	* configure: Check to make sure that GAS actually honors .code16
+	directives.
+
+1999-02-02  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* shared_src/asm.S: Fix typo that called interrupt 0xd (decimal
+	13) instead of 0x13.
+
+1999-01-31  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* e2fs_stage1_5/Makefile: Avoid gratuitous dependencies on
+	Makefile.
+	* fat_stage1_5/Makefile: Likewise.
+	* ffs_stage1_5/Makefile: Likewise.
+
+	* Makefile.end (PROGS): Add e2fs_stage1_5, fat_stage1_5, and
+	grubinst.
+	(distclean): New GNU standard rule.
+
+1998-10-23  Gordon Matzigkeit  <gord@trick.fig.org>
+
+	* configure: Accept `--host' as a synonym for `--target', and
+	accept a non-optional argument as the target name.  Join the
+	prefix to the tool name with a hyphen.
+
+	* shared_src/disk_io.c (print_fsys_type): Always print the
+	partition type.
+
+	* shared_src/stage2.c (run_menu): Check to make sure that the
+	fallback entry is nonnegative.
+	(run_menu): For consistency, use `e' rather than enter to edit the
+	command entry.
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..1ba68a6
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,266 @@
+-*- Text -*-
+
+This is the GRUB.  Welcome.
+
+This file contains instructions for compiling and installing the GRUB.
+
+The Requirements
+================
+
+GRUB depends on some software packages installed into your system. If
+you don't have any of them, please obtain and install them before
+configuring the GRUB.
+
+* GCC
+
+  Probably every recent GCC should work, but we recommend GCC 2.95 and
+  later, since you can create smaller binary images. See the web page
+  <http://gcc.gnu.org/>.
+
+* GNU Make
+
+  For now, the Makefiles produced by Automake depends on GNU Make. See
+  the web page <http://www.gnu.org/software/make/make.html>.
+
+* GNU binutils 2.9.1.0.23 or later
+
+  Binutils has changed the behavior of 16bit assembler between 2.9.1
+  and 2.9.1.0.x, and we support only 2.9.1.0.x and higher. In
+  particular, we recommend using binutils 2.10, since it is the only
+  public release that supports real 16bit mode. Please take a look at
+  the web page <http://sourceware.cygnus.com/binutils/>, for more
+  information. Note that you don't have to install it into any system
+  directory. See the section "Operation Controls", if you want to
+  install binutils into your own directory.
+
+If you'd like to develop GRUB, these below are also required. Don't
+forget to specify the option `--enable-maintainer-mode' when running the
+configure script.
+
+* Texinfo 4.0 or later
+
+  We use some new macros in the documents, so you need a recent
+  Texinfo release. See the web page
+  <http://www.gnu.org/software/texinfo/texinfo.html>.
+
+* Developers: GNU Autoconf 2.5x and GNU Automake 1.7 or later
+
+  You should not need Automake just to compile GRUB, but you will need
+  it if you edit any of the build files (Makefile.am, configure.in,
+  etc).  We use the new "per-executable flags" feature found in the
+  latest release of automake.  See the web page
+  <http://www.gnu.org/software/automake/automake.html>.
+
+
+Configuring the GRUB
+====================
+
+The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a
+file `config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+If you need to do unusual things to compile the package, please try to
+figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+The file `configure.in' is used to create `configure' by a program
+called `autoconf'.  You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+
+Building the GRUB
+=================
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and
+     type `./configure' to configure the package for your system.  If
+     you're using `csh' on an old version of System V, you might need
+     to type `sh ./configure' instead to prevent `csh' from trying to
+     execute `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  `cd' to the directory where you want the object files
+and executables to go and run the `configure' script.  `configure'
+automatically checks for the source code in the directory that
+`configure' is in and in `..'.
+
+
+Installation Names
+==================
+
+By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix by giving `configure' the option `--prefix=PATH'.
+
+You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If
+you give `configure' the option `--exec-prefix=PATH', the package will
+use PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for
+particular kinds of files.  Run `configure --help' for a list of the
+directories you can set and what kinds of files go in them.
+
+If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure'
+the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Please note, however, that the GRUB knows where it is located in the
+filesystem.  If you have installed it in an unusual location, the
+system might not work properly, or at all.  The chief utility of these
+options for the GRUB is to allow you to "install" in some alternate
+location, and then copy these to the actual root filesystem later.
+
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+
+Operation Controls
+==================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+     Use and save the results of the tests in FILE instead of
+     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
+     debugging `configure'.
+
+`--help'
+     Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--version'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--enable-maintainer-mode'
+     Enable make rules and dependencies not useful (and sometimes
+     confusing) to the casual installer. If you are a GRUB developer,
+     it is a good idea to specify this option.
+
+`--disable-ext2fs'
+     Omit the ext2fs support in Stage 2.
+
+`--disable-fat'
+     Omit the FAT support in Stage 2.
+
+`--disable-ffs'
+     Omit the FFS support in Stage 2.
+
+`--disable-minix'
+     Omit the Minix fs support in Stage 2.
+
+`--disable-reiserfs'
+     Omit the ReiserFS support in Stage 2.
+
+`--disable-vstafs'
+     Omit the VSTa filesystem support in Stage 2.
+
+`--disable-jfs'
+     Omit the JFS support in Stage 2.
+
+`--disable-xfs'
+     Omit the XFS support in Stage 2.
+
+`--disable-ufs2'
+     Omit the UFS2 support in Stage 2.
+
+`--disable-iso9660'
+     Omit the ISO9660 support in Stage 2.
+
+`--disable-gunzip'
+     Omit the decompression support in Stage 2.
+
+`--disable-md5-password'
+     Omit the MD5 password support in Stage2.
+
+`--with-binutils=PATH'
+     Search the path PATH to find binutils. If you have installed your
+     binutils executables into an unusual location where GCC doesn't
+     search by default, use this option.
+
+`--without-curses'
+     Don't use the curses library.
+
+`--disable-hercules'
+     Omit the hercules console support in Stage 2.
+
+`--disable-serial'
+     Omit the serial terminal support in Stage 2.
+
+`--enable-serial-speed-simulation'
+     Simulate the slowness of a serial device in the grub shell. This
+     option is useful for GRUB developers, as you can test the
+     performance of a terminal emulation even on pseudo terminals.
+
+`--enable-preset-menu=FILE'
+     Preset a menu file FILE in Stage 2. This is useful, if you cannot
+     put a configuration file on a filesystem for some reason (e.g. when
+     you need to set the default terminal to a serial terminal in an
+     embedded system).
+
+`--enable-example-kernel'
+     Build the example Multiboot kernel in the directory "docs". You
+     will be able to boot the image "kernel" with GRUB.
+
+`--disable-auto-linux-mem-opt'
+     Don't pass the "mem=" option automatically, when booting Linux.
+     You can also disable the feature at run time.
+
+
+`configure' also accepts several options for the network support. See
+the file `netboot/README.netboot', for more information.
diff --git a/MAINTENANCE b/MAINTENANCE
new file mode 100644
index 0000000..3ce7b3f
--- /dev/null
+++ b/MAINTENANCE
@@ -0,0 +1,60 @@
+-*- text -*-
+
+This is a list of random notes for GRUB maintainers. If you are not a
+maintainer, you need to ask maintainers to do these instead of doing
+these yourself.
+
+How to update the online manual: (FIXME: this is obsoelete)
+1. Copy docs/*.texi (excluding "multiboot.texi") to fencepost.gnu.org.
+2. Make a symbolic link from ~mohit/gnudoc/gnudoc_template to the
+   directory under which *.texi were copied, if the link isn't present.
+3. Run ``~mohit/gnudoc/gendocs.sh grub "GNU GRUB Manual"''.
+4. Copy the contents of the directory ``manual'' to
+   gnudist.gnu.org:~ftp/gnu/Manuals/grub-VERSION (VERSION is, for
+   example, 1.0).
+5. Run ``ln -sf grub-VERSION grub'' in gnudist.gnu.org:~ftp/gnu/Manuals.
+6. Run ``cd grub; ln -s grub.html index.html''.
+7. Verify the new online manual with a WWW browser.
+8. Update manual.html by hand.
+
+How to release a version:
+1. Check out the source tree from the CVS from scratch.
+2. Check if ``make distcheck'' succeeds.
+3. Run ``util/grub-image''.
+4. Check the resulted images, for example, using bochs.
+5. Copy grub-VERSION.tar.gz, grub-VERSION-i386-pc.tar.gz and
+   grub-VERSION-i386-pc.ext2fs to fencepost.gnu.org:~ftp/gnu/grub.
+6. Move older files in that directory above to the directory ``old'',
+   if you think they are eyesores.
+7. Post an announcement to bug-grub@gnu.org. It would be a good idea to
+   send a carbon copy to bug-hurd@gnu.org and
+   debian-hurd@lists.debian.org. If the announcement is for a stable
+   version, you can inform info-gnu@gnu.org as well.
+8. Optionally, post an announcement to Freshmeat.net.
+
+Legal issues:
+1. If a patch is not significant (in size), you don't have to care about
+   the copyright.
+2. If a patch is significant, you shouldn't apply the patch to the CVS.
+   Before doing that, you must ask the contributor to assign or disclaim
+   the copyright. Send ``/gd/gnuorg/request-assign.changes'' or
+   ``/gd/gnuorg/request-assign.future'' to the contributor, and wait
+   until the FSF finishes the legal work.
+3. You can check if a contributor has already assigned his/her copyright
+   to the FSF by looking at ``/gd/gnuorg/copyright.list''.
+
+What you should have in your mind:
+1. Don't add features unnecessarily! You may think it is a Good Thing to
+   have more features, but you must be prepared for more burdens.
+   DO THAT ONLY IF YOU BELIEVE THAT THE FEATURE IS ESSENTIAL.
+2. Don't break backward-compatibility! Don't apply any patch which could
+   break existing features. Otherwise you would receive a lot of
+   complaints. DO THAT ONLY IF YOU BELIEVE THAT THE INCOMPATIBILITY IS
+   INEVITABLE.
+3. Write good code. Be not satisfied with ad hoc workarounds or quick
+   hacks. NEVER WRITE BAD CODE.
+
+Resources:
+* http://www.gnu.org/prep/maintain_toc.html
+* http://www.gnu.org/prep/standards_toc.html
+* http://www.gnu.org/server/fsf-html-style-sheet.html
diff --git a/MODULE_LICENSE_GPL b/MODULE_LICENSE_GPL
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_GPL
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..63a9a4f
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,4 @@
+# Do not change this order if you don't know what you are doing.
+AUTOMAKE_OPTIONS = 1.7 gnu
+SUBDIRS = netboot stage2 stage1 lib grub util docs
+EXTRA_DIST = BUGS MAINTENANCE
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..6652366
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,605 @@
+# Makefile.in generated by automake 1.9.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  Free Software Foundation, Inc.
+# This Makefile.in 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 distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = .
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in $(srcdir)/config.h.in \
+	$(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \
+	THANKS TODO compile config.guess config.sub depcomp install-sh \
+	missing mkinstalldirs
+subdir = .
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno configure.status.lineno
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+	html-recursive info-recursive install-data-recursive \
+	install-exec-recursive install-info-recursive \
+	install-recursive installcheck-recursive installdirs-recursive \
+	pdf-recursive ps-recursive uninstall-info-recursive \
+	uninstall-recursive
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  { test ! -d $(distdir) \
+    || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
+         && rm -fr $(distdir); }; }
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_EXAMPLE_KERNEL_FALSE = @BUILD_EXAMPLE_KERNEL_FALSE@
+BUILD_EXAMPLE_KERNEL_TRUE = @BUILD_EXAMPLE_KERNEL_TRUE@
+CC = @CC@
+CCAS = @CCAS@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISKLESS_SUPPORT_FALSE = @DISKLESS_SUPPORT_FALSE@
+DISKLESS_SUPPORT_TRUE = @DISKLESS_SUPPORT_TRUE@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FSYS_CFLAGS = @FSYS_CFLAGS@
+GRUB_CFLAGS = @GRUB_CFLAGS@
+GRUB_LIBS = @GRUB_LIBS@
+HERCULES_SUPPORT_FALSE = @HERCULES_SUPPORT_FALSE@
+HERCULES_SUPPORT_TRUE = @HERCULES_SUPPORT_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
+NETBOOT_SUPPORT_FALSE = @NETBOOT_SUPPORT_FALSE@
+NETBOOT_SUPPORT_TRUE = @NETBOOT_SUPPORT_TRUE@
+NET_CFLAGS = @NET_CFLAGS@
+NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
+OBJCOPY = @OBJCOPY@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+RANLIB = @RANLIB@
+SERIAL_SPEED_SIMULATION_FALSE = @SERIAL_SPEED_SIMULATION_FALSE@
+SERIAL_SPEED_SIMULATION_TRUE = @SERIAL_SPEED_SIMULATION_TRUE@
+SERIAL_SUPPORT_FALSE = @SERIAL_SUPPORT_FALSE@
+SERIAL_SUPPORT_TRUE = @SERIAL_SUPPORT_TRUE@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STAGE1_CFLAGS = @STAGE1_CFLAGS@
+STAGE2_CFLAGS = @STAGE2_CFLAGS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_OBJCOPY = @ac_ct_OBJCOPY@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+
+# Do not change this order if you don't know what you are doing.
+AUTOMAKE_OPTIONS = 1.7 gnu
+SUBDIRS = netboot stage2 stage1 lib grub util docs
+EXTRA_DIST = BUGS MAINTENANCE
+all: config.h
+	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+am--refresh:
+	@:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \
+	      cd $(srcdir) && $(AUTOMAKE) --gnu  \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu  Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    echo ' $(SHELL) ./config.status'; \
+	    $(SHELL) ./config.status;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	$(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+
+config.h: stamp-h1
+	@if test ! -f $@; then \
+	  rm -f stamp-h1; \
+	  $(MAKE) stamp-h1; \
+	else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+	@rm -f stamp-h1
+	cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) 
+	cd $(top_srcdir) && $(AUTOHEADER)
+	rm -f stamp-h1
+	touch $@
+
+distclean-hdr:
+	-rm -f config.h stamp-h1
+uninstall-info-am:
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+	@set fnord $$MAKEFLAGS; amf=$$2; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	   || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+	@set fnord $$MAKEFLAGS; amf=$$2; \
+	dot_seen=no; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	rev=''; for subdir in $$list; do \
+	  if test "$$subdir" = "."; then :; else \
+	    rev="$$subdir $$rev"; \
+	  fi; \
+	done; \
+	rev="$$rev ."; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	   || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+ctags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	    $$tags $$unique; \
+	fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$tags $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	$(am__remove_distdir)
+	mkdir $(distdir)
+	$(mkdir_p) $(distdir)/util
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+	list='$(DISTFILES)'; for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+	  esac; \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+	    dir="/$$dir"; \
+	    $(mkdir_p) "$(distdir)$$dir"; \
+	  else \
+	    dir=''; \
+	  fi; \
+	  if test -d $$d/$$file; then \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+	list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d "$(distdir)/$$subdir" \
+	    || $(mkdir_p) "$(distdir)/$$subdir" \
+	    || exit 1; \
+	    distdir=`$(am__cd) $(distdir) && pwd`; \
+	    top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
+	    (cd $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$top_distdir" \
+	        distdir="$$distdir/$$subdir" \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+	-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+	  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
+	|| chmod -R a+r $(distdir)
+dist-gzip: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__remove_distdir)
+
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+	$(am__remove_distdir)
+
+dist-tarZ: distdir
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__remove_distdir)
+
+dist-shar: distdir
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__remove_distdir)
+
+dist dist-all: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+	case '$(DIST_ARCHIVES)' in \
+	*.tar.gz*) \
+	  GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.Z*) \
+	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+	*.shar.gz*) \
+	  GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir); chmod a+w $(distdir)
+	mkdir $(distdir)/_build
+	mkdir $(distdir)/_inst
+	chmod a-w $(distdir)
+	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+	  && cd $(distdir)/_build \
+	  && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+	    $(DISTCHECK_CONFIGURE_FLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) check \
+	  && $(MAKE) $(AM_MAKEFLAGS) install \
+	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+	  && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+	  && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+	        distuninstallcheck \
+	  && chmod -R a-w "$$dc_install_base" \
+	  && ({ \
+	       (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+	            distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+	      } || { rm -rf "$$dc_destdir"; exit 1; }) \
+	  && rm -rf "$$dc_destdir" \
+	  && $(MAKE) $(AM_MAKEFLAGS) dist \
+	  && rm -rf $(DIST_ARCHIVES) \
+	  && $(MAKE) $(AM_MAKEFLAGS) distcleancheck
+	$(am__remove_distdir)
+	@(echo "$(distdir) archives ready for distribution: "; \
+	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+	  sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
+distuninstallcheck:
+	@cd $(distuninstallcheck_dir) \
+	&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+	   || { echo "ERROR: files left after uninstall:" ; \
+	        if test -n "$(DESTDIR)"; then \
+	          echo "  (check DESTDIR support)"; \
+	        fi ; \
+	        $(distuninstallcheck_listfiles) ; \
+	        exit 1; } >&2
+distcleancheck: distclean
+	@if test '$(srcdir)' = . ; then \
+	  echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+	  exit 1 ; \
+	fi
+	@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+	  || { echo "ERROR: files left in build directory after distclean:" ; \
+	       $(distcleancheck_listfiles) ; \
+	       exit 1; } >&2
+check-am: all-am
+check: check-recursive
+all-am: Makefile config.h
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-generic mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-hdr distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-recursive
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf $(top_srcdir)/autom4te.cache
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-generic
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+uninstall-info: uninstall-info-recursive
+
+.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \
+	check-am clean clean-generic clean-recursive ctags \
+	ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-shar \
+	dist-tarZ dist-zip distcheck distclean distclean-generic \
+	distclean-hdr distclean-recursive distclean-tags \
+	distcleancheck distdir distuninstallcheck dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-exec install-exec-am install-info \
+	install-info-am install-man install-strip installcheck \
+	installcheck-am installdirs installdirs-am maintainer-clean \
+	maintainer-clean-generic maintainer-clean-recursive \
+	mostlyclean mostlyclean-generic mostlyclean-recursive pdf \
+	pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
+	uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..cb37450
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,558 @@
+NEWS - list of user-visible changes between releases of GRUB
+
+New in 0.97 - 2005-05-08:
+* Fix the prototypes and the definitions of nested functions. This was
+  required for gcc-4.
+* Implement a more robust workaround for buggy BIOSes which don't pass
+  boot drive correctly (notably for HP Vectra).
+
+New in 0.96 - 2005-01-30:
+* The command "fallback" supports mutiple fallback entries.
+* The command "savedefault" supports an optional argument which
+  is the number of next boot entry or the special keyword `fallback'.
+* New utility "grub-set-default".
+* New section "Making your system robust" in the manual.
+
+New in 0.95 - 2004-06-13:
+* Add support for ReiserFS 3.
+* Fix support for FreeBSD 5.
+* Support ATARAID for Linux in the grub shell and grub-install.
+* Add CDROM support for El Torito with no emulation mode. You can use
+  (cd) as a CDROM drive in the config file.
+* Option --no-mem-option is implied for Linux 2.4.18 and newer.
+* Add support for UFS2.
+
+New in 0.94 - 2004-01-25:
+* Support building on x86-64 with gcc -m32.
+* Use a BIOS call to turn on/off Gate A20. This should solve various
+  problems related to Gate A20 in modern BIOSes.
+* Add a workaround for buggy BIOSes (notably HP Vectra series) which
+  don't pass the boot drive correctly.
+* Display "GNU GRUB" instead of "GRUB" in the menu.
+* Add support for QNX RTP into the grub shell.
+* Add support for the initrd max address of a kernel header in Linux.
+* Support 32 bit and 64 bit dev_t.
+* Add support for an install device in GRUB's notation with no
+  parenthesis (e.g. grub-install hd0).
+* Improve the manual a lot.
+
+New in 0.93 - 2002-12-08:
+* Define the behavior of the boot loader when the load end address is
+  zero and the bss end address is zero in the Multiboot Specification.
+  Also, add the support into GRUB.
+* Finally, we have a Bug Tracking System! Now the preferable way to
+  report bugs is to use the BTS rather than sending e-mail to bug-grub.
+  See <http://bugcomm.enbug.org/?project=grub&mode=project>, for more
+  details.
+* The appendix "FAQ" in the manual is removed. See the GNU GRUB FAQ on
+  the web <http://www.gnu.org/software/grub/grub-faq.html> instead.
+* The terminal handling code is rewritten radically, and many bugfixes
+  are made at the same time.
+* The command "color" is effective even in the command-line.
+* The command "terminal" takes two new options, ``--no-echo'' and
+  ``--no-edit''. If you specify ``--no-echo'', GRUB won't echo back
+  input characters. If you specify ``--no-edit'', GRUB will disable the
+  BASH-like editing feature. These options are useful when using an
+  intelligent terminal (such as the comint mode in GNU Emacs).
+* The utility ``grub-md5-crypt'' prompts to retype a password and checks
+  if the passwords match.
+* Support for booting Linux is rewritten, so GRUB now supports
+  large-EBDA systems.
+* The menu interfaces supports Page Up, Page Down, and Right Key.
+* New command "terminfo", for vt100-incompatible terminals.
+* New options, ``-D'', ``-g'' and ``-m'' are supported for FreeBSD.
+
+New in 0.92 - 2002-04-30:
+* The command "displaymem" uses only hex digits for consistency.
+* The netboot code goes back to the progress bars instead of dots, for
+  the notation of data transfers. And, that is displayed only in debug
+  mode, that is to say, nothing is displayed by default. Remember that
+  you can turn on debug mode via the command "debug".
+* The command "help" doesn't show all the available commands by default,
+  when no argument is specified. Rarely used commands (such as
+  "testload") and useless commands in interactive use (such as
+  "savedefault") are hidden. If you want to see help messages for those
+  commands, specify the new option "--all".
+* A built-in, `more'-like pager is added. When a command prints too many
+  lines to fit the screen, GRUB waits until you hit return key. This
+  feature can be turned off by the new command "pager".
+* The command "terminal" accepts a new option, "--lines=LINES". You can
+  set the maximum number of lines arbitrarily with this option. If you
+  don't specify it, the maximum number will be 24.
+* The command "terminal" accepts another new option, "--silent". You can
+  suppress the "Press any key to continue" message with this option.
+* The mem= option for Linux is recognized and used to limit the maximum
+  address of initrd.
+* A fallback entry is executed immediately after a default entry,
+  without prompting a user's intervention, as the manual has ever been
+  saying.
+* The utility ``grub-install'' makes sure that GRUB images have been
+  written to a physical disk completely. To assist this feature, a new
+  command "dump" is added.
+
+New in 0.91 - 2002-01-21:
+* Support for Linux DAC960 is added.
+* JFS and XFS support is added.
+* The commands "hide" and "unhide" support logical partitions.
+* The utility ``grub-install'' supports NetBSD.
+* The network support is updated to Etherboot-5.0.5.
+* The manner of handling the preset menu changes. In the previous
+  implementation, the preset menu is used only when opening the
+  configuration file failed. Now try to use the preset menu first. And,
+  if the configuration file is available, it is read after readoing the
+  preset menu. In this case, menu entries in the preset menu (if any)
+  are overrided by the configuration file.
+* Diskless support is a bit changed. In the previous, GRUB set up a
+  network automatically via a special function. In the current, the
+  function is gone and the preset menu feature is used (i.e. just
+  execute the command "bootp" as if you specified it in the preset
+  menu). This has no impact against most users, but you should take care
+  if using the preset menu for your own purpose, because GRUB doesn't
+  call "bootp" implicitly when the preset menu is used explicitly. In
+  this case, you would probably need to insert commands to initialize a
+  network into your preset menu.
+* Important bugfixes are made for ReiserFS, APM, TFTP, LBA, etc.
+
+New in 0.90 - 2001-07-11:
+* The command "setkey" resets key mappings, when no argument is
+  specified.
+* Linux devfs support is added.
+* The utility ``grub-install'' accepts a new option, `--recheck'. If
+  this option is specified, probe a device map, even if it already
+  exists. You should use this option whenever you add/remove a disk.
+* The command "password" supports a md5 password if the option `--md5'
+  is given.  This command can now also be used to protect specific menu
+  items with their own passwords.
+* New command, "displayapm".
+* New command, "md5crypt".
+* The new utility ``grub-md5-crypt'' is a frontend of the grub shell. It
+  encrypts a password in MD5 format.
+* New commands, "testvbe" and "vbeprobe".
+* The configure script accepts a new option, `--enable-preset-menu'. You
+  can embed an arbitrary configuration which will be used when Stage 2
+  cannot open a real configuration file, with this option. The argument
+  must be an existing file.
+* EZ-BIOS support is added.
+* Booting Windows from a logical partition is supported.
+* The example Multiboot kernel in the directory "docs" is built, if you
+  specify the option `--enable-example-kernel' to the configure script.
+* New command, "ifconfig".
+* Linux software RAID support is added (only for RAID-1).
+* Hercules support is added.
+* The configure script now accepts `--disable-auto-linux-mem-opt', which
+  has the same meaning as you specify the option `--no-mem-option' to the
+  command "kernel".
+* Jump to the physical entry address of a Multiboot kernel when booting
+  it up. The old behavior was to use the virtual one, regardless of the
+  setting of the physical address.
+* The commands "bootp" and "dhcp" accepts a new option
+  `--with-configfile', so that you can load a remotely specified
+  configuration file automatically, like the network boot images.
+* VSTa filesystem support is added.
+* ELF symbol loading support is added.
+
+New in 0.5.96 - 2000-10-04:
+* New commands, "reboot" and "halt".
+* New command, "hiddenmenu". You can hide the menu interface by default
+  with this command.
+* You can specify `--no-mem-option' to the command "kernel", if you want
+  GRUB not to pass a Linux's mem option automatically.
+* Now GRUB is compliant with the Linux/i386 boot protocol version 2.02.
+* The network support is updated to Etherboot-4.6.4.
+* Symlinks in ReiserFS are supported.
+* Add a workaround into the grub shell, so that it works fine even under
+  Linux 2.4.
+* Add a new option `--stage2' into the commands "install" and "setup",
+  to let the grub shell know what the file name of Stage 2 is under your
+  operating system. You must specify the option correctly, if you cannot
+  unmount the partition where GRUB images reside. We'd recommend _not_
+  using those commands directly, but using the utility "grub-install"
+  instead, because this is safer.
+* One violation against the Network Boot Image Proposal was found and
+  fixed. So now the image `nbgrub' can work fine even with a card such
+  as rtl8139.
+* Serial terminal support is added. The configure script accepts
+  a new option `--disable-serial'. Unless it is specified, you can use
+  two new commands, "serial" and "terminal" in the command-line and the
+  menu. See the manual, for more details.
+* Preserve the possible magic number used by Windows NT in a MBR.
+* The command-line interface is switched to single-line editing mode.
+* Only for developers: the configure script accepts
+  `--enable-serial-speed-simulation', which is useful when you want to
+  simulate the speed of a serial device on a psuedo terminal.
+* Also only for developers: you can specify an optional argument to the
+  option `--hold' for the grub shell. The argument means how many
+  seconds the grub shell should wait until diving into the main routine.
+* New command, "savedefault". Now you can save current entry number to
+  your disk with this command and then you can set the default boot
+  entry to it by the command "default saved".
+* Add a new option `--prefix' into the command "setup", so that you can
+  specify the name of a directory which contains GRUB images. And, the
+  behavior of this command changed slightly, that is, this command now
+  searchs stage1 automatically under "/boot/grub" and "/grub", unless
+  you specify the option `--prefix'.
+* The utility `grub-install' recognizes a separate boot partition
+  automatically.
+* New commands, "partnew" and "parttype". You can modify partition
+  tables with these commands.
+
+New in 0.5.95 - 2000-06-27:
+* NetBSD ELF kernel support is added. You have to specify the new option
+  to the command "kernel". See below.
+* Added a new option `--type=TYPE' into the command "kernel". This
+  option suggests what type of kernel you want to load. TYPE must be
+  either of "netbsd", "freebsd", "openbsd", "linux", "biglinux" and
+  "multiboot". Actually, this option will be necessary only if you want
+  to load a NetBSD ELF kernel, because GRUB can automatically determine
+  a kernel type in the other cases.
+* ReiserFS support is added.
+* Added a new option `--force-lba' into the command "install". This
+  option disables some sanity checks for LBA mode (but not all). If you
+  are sure that your machine supports LBA mode but GRUB doesn't work in
+  LBA mode, you should specify it. It is necessary if your BIOS is too
+  buggy. In the previous version, it was a compile-time option, but you
+  don't have to recompile GRUB any longer.
+* Likewise, now the command "setup" and the script "grub-install" also
+  accept `--force-lba' option. Specifying this option to "setup" or
+  "grub-install" has the same effect as to the command "install".
+* The configure script doesn't accept the option
+  `--disable-lba-support-bitmap-check' any longer. Use the option above.
+* The network support is updated to Etherboot-4.6.1. So now we have
+  3Com59x and DEPCA drivers.
+* Now you can omit the configuration file argument to the command
+  "password". If you omit it, then GRUB will just unlock privileged
+  instructions (such as `c') when you enter a correct password.
+* The new command "lock" can be used to prevent end-users from executing
+  arbitrary menu entries. This command will emit an error until the user
+  enters a correct password.
+* Recognize the Linux extended partition type.
+* Pass a correct memory size to Linux and *BSD.
+* Diskless support is added. Now configure accepts --enable-diskless,
+  and "make" will produce two additional images, ``nbgrub'' for Net Boot
+  Image Proposal and ``pxegrub'' for Preboot Execution Environment. See
+  the documentation, for more details.
+* The command "tftpserver" overrides a TFTP server address returned by a
+  BOOTP server, a DHCP server or a RARP server.
+* Fix a serious bug about LBA support. It is possible that you don't
+  disable the LBA support bitmap check any longer. Please send a report,
+  if you must still disable it. We need to know if we should get rid of
+  the option.
+
+New in 0.5.94 - 2000-03-06:
+* Stage 1 supports both the LBA mode and the CHS mode.
+* The NetBSD and OpenBSD boot bug is fixed.
+* The more automatic installation command "setup" is added.
+* The command "embed" embeds a Stage 1.5 in the sectors after a MBR.
+* Support symbolic color name syntax in the command "color".
+* The grub shell loads the BIOS drive mapping information from a device
+  map file if it is specified and can be opened. If not found, try to
+  create it based on the guessed information.
+* NetBSD support in the grub shell is improved.
+* A simple checker for the format of a Multiboot kernel, ``mbchk'', is
+  added.
+* The command "find" searches for a filename in all devices and print
+  the list of the devices which contain the file.
+* The command "map" maps a drive to another drive so that we can
+  chain-load some foolish operating systems (such as DOS) even if such
+  an operating system resides at a non-first drive.
+* The command "setkey" maps a key to another.
+* The GRUB manual is rewritten, and now consists of three parts and
+  appendices.
+* The command "ioprobe" detects what I/O ports are used for a BIOS
+  drive.
+* OpenBSD support in the grub shell is improved.
+* The command "install" can now patch a Stage 2 with a different
+  filename from "/boot/grub/menu.lst" even if a Stage 1.5 is used.
+* New program, ``grub-install''.
+* The command "blocklist" prints the blocklist notation of a file.
+* The command "chainloader" now accepts an option "--force", which is
+  required if you want to chain-load a boot loader defective in the
+  signature, such as SCO Unixware 7.1.
+* The netboot support is heavily rewritten, based on Etherboot-4.4.3.
+  Most of the device drivers are stolen from it, so we now have many
+  network drivers. See netboot/README.netboot for more details.
+* Now configure accepts the option `--disable-lba-support-bitmap-check'
+  to ignore an incorrect LBA support bitmap returned by a buggy BIOS. If
+  you are sure that your BIOS does support LBA mode but GRUB doesn't
+  work in LBA mode, recompile GRUB with this option specified. You can
+  check if GRUB accesses a drive in LBA mode by the command "geometry".
+* New commands "bootp", "dhcp" and "rarp" can be used to initialize a
+  network device and get IP addresses from a network.
+* Long filename support in the FAT filesystem is added.
+* The command "cmp" compares each bytes in two files.
+
+New in 0.5.93 - 1999-10-30:
+* ELF format of FreeBSD kernel is supported.
+* Support the partition ids for NetBSD and OpenBSD.
+* Exit from the grub shell just by pushing the key `q' in the menu.
+* New options for configure can disable some functions in Stage 2. See
+  the output from `configure --help' for more information.
+* FAT32 support is added.
+* Minix fs support is added.
+* New commands "hide" and "unhide".
+* The character `=' after a command is not necessary any longer, but it
+  is supported for backward compatibility.
+* The command "help" displays helpful information about builtin
+  commands.
+* The command "geometry" displays the information of a drive specified
+  and set the geometry to arbitrary C/H/S values if the optional
+  arguments are used.
+* The command "configfile" loads a configuration file interactively.
+* The command "device" assigns a BIOS drive to an arbitrary filename in
+  the grub shell.
+* The option `--no-floppy' force the grub shell to assume that there is
+  no floppy, and the option `--probe-second-floppy' enables the probe of
+  the second floppy drive.
+* Integrated the netboot support in the Dresden version of GRUB.
+* FreeBSD support in the grub shell is improved.
+* Killing (C-u and C-k), yanking (C-y) and manipulating the history
+  (C-p and C-n) are supported.
+* The address argument for the command "install" is now optional.
+* Better completion support.
+* The command "cat" displays the contents of a file.
+
+New in 0.5.92 - 1999-07-26:
+* Bug fixes (i.e. Stage 1.5 can work fine again).
+* The /sbin/grub stage2 simulator now works at least on GNU/Linux, and
+  uses the Linux HDIO_GETGEO ioctl to determine hard disk geometry.
+* TAB not only lists filenames, but also completes a filename when the
+  filename is unique.
+* Password is not echoed back, put an asterisk for each of input
+  characters.
+* stage2_debug is removed, and the debugging features are added into
+  stage2.
+* Color menu support.
+* New command "quit".
+* The man page for /sbin/grub.
+* All documents become Texinfo.
+* Linux video mode selection is supported.
+* The new Stage 1 `stage1_lba' supports LBA addressing mode.
+
+New in 0.5.91 - 1999-03-14, Gordon Matzigkeit:
+* LBA and preliminary AWARD BIOS disk extension support.
+* Started docs/grub.texi.
+* /sbin/grub GUI now works (but it doesn't yet access disks properly).
+  Run `configure --enable-sbin-grub' to build this program in the grub
+  subdirectory.
+
+New in 0.5.90 - 1999-03-01, Gordon Matzigkeit:
+* Bug fixes.
+* GRUB understands symlinks on ext2fs (but still not ffs).
+* Many source code and build cleanups to comply with GNU standards.
+
+New in 0.5 - 1998-08-20, Erich Boleyn:
+
+* Improved error messages in the stage1 to be strings (easier to read
+  than the previous case of single characters), and removed any
+  display in the case of no error (less confusing).
+
+* New document describing error conditions and messages.
+
+* Improved configure/build process.
+
+* Made the early bootup interrupt-safe.  Wasn't doing cli/sti when
+  necessary sometimes.
+
+* GRUB now shuts off the floppy before transferring control to any
+  other programs/modules/loaders.  (chain-loading doesn't matter here,
+  just loading 32-bit modules/kernels)
+
+* Fixed a few stupid bugs, including a several in the ext2fs code.
+
+* Linux boot format support extended from just "zImage" to include
+  "bzImage" and initial ramdisk (also called "initrd") support for
+  both.  "initrd" support is untested, but the critical parts were
+  taken from a supplied patch and seem OK.
+
+* Several new command features.  See the command-listing for details.
+
+New in 0.4 - 1998-03-19, Erich Boleyn:
+
+* GRUB now correctly points ES:SI at a partition descriptor when
+  chain-loading.
+
+* Many minor bugs fixed (some in the build scripts).
+
+* Intel MPS 1.4 config/check code is totally new, and the "syscmd="
+  command is completely removed.  Check command-listing for details.
+
+Version 0.4-pre, Erich Boleyn:
+
+* Reorganized docs, moved most "NOTE" items to a FAQ (with new entries
+  as well).
+
+* Now supports automatic decompression of any files loaded via the
+  GRUB stage2 filesystem code.  Simply compress the file using GNU
+  gzip normally, then when loading, the GRUB internals will see the
+  contents in the decompressed state...  i.e. all GRUB functions
+  operate normally as if it is the uncompressed file.  An extra
+  version of the "module" loading function has been added which
+  disables this functionality if desired (in all the other cases, not
+  decompressing doesn't make sense).
+
+* Changed device strings used in filesystem code to more logical
+  format.  Added "relative" disk and partition capability, see
+  command-listing and filesystem syntax description for details.
+
+* "install=" command vastly improved.  Also moved to non-debug area.
+  Check command-listing and install documentation for details.
+
+* Added several new commands: "rootnoverify=", "uppermem=", and a new
+  debug command "displaymem".  Check command-listing for details.
+
+* Added versioning numbers (and subsequently broke compatibility with
+  some of the previous code, so GRUB should be re-installed!).
+
+* Added unattended booting support via new "fallback=" command.
+
+* During debug probe of SMP configuration table compatible with Intel
+  MPS 1.4 standard, GRUB now checks for a pointer in the EBDA.
+
+* Using a "default=" entry greater than 11 caused the UI to do funny
+  things (it didn't pre-scroll the list to the appropriate place).
+
+* Reading files on FAT floppies had yet more problems related by many
+  users of version 0.3 6/17/96.  Again, all known problems fixed.
+
+* "Extended" partitions now work (still cannot make an extended
+  partition active with "makeactive" command).
+
+* The build environment is greatly simplified, now using an
+  autoconf-like "configure" script.
+
+New in 0.3-19960617 - 1996-06-17, Erich Boleyn:
+
+* Yet more documentation improvements.
+
+* Known bugs in floppy operation fixed (12-bit FAT didn't work for
+  most cases, and inserting other floppies didn't flush the filesystem
+  cache).
+
+* NASTY uninitialized pointer bug causing "raw" floppy operation to
+  crash on several PCs is now fixed.  This seems to have been the root
+  cause of all of the compatibility problems that have currently been
+  observed.
+
+* debug-mode command added to automate most difficult step of
+  installation for common cases (new install method #4).
+
+* Testing "mini-debugger" now merged with command-line when "DEBUG"
+  defined in compile (no SYSDEBUG option anymore).  See description of
+  commands in the command-line for details.
+
+New in 0.3-19960602 - 1996-06-02, Erich Boleyn:
+
+* Completed initial licenses.
+
+* Initial filesystem documentation written.
+
+* Block-list and FAT filesystems now work as documented (in
+  particular, for the blocklist filesystem, shortcuts like "+1" for
+  "0+1,512" now work correctly).
+
+* Fixed several problems (old and new) in the various filesystems (for
+  example, the ext2fs filesystem code is now much faster, as it caches
+  some mapping blocks where it didn't at all before).  Filesystem
+  semantics are much more uniform as well (symbolic links and reading
+  a directory as a file now return errors where it would silently fail
+  before).
+
+* "makeactive" now works for standard PC partitions on hard disks (not
+  extended partitions...  so any PC partition number above 3 will give
+  a "no such partition" error).  If a BSD sub-partition is is used, it
+  will ignore it, and only use the primary PC partition number.
+
+New in 0.3-19960520 - 1996-05-20, Erich Boleyn:
+
+* Updated instructions (though still very sparse).
+
+* New floppy probe (works much like the Linux floppy boot probe)
+  attempts to find the size of a floppy in a drive.  Might still need
+  work!  Please try on various floppy drives with various media!
+
+* New floppy handler will claim a non-existent drive if the floppy
+  disk isn't present in the drive.  (for example, it won't be on the
+  list of installed drives unless a floppy is present)
+
+* Stage1 now compatible with both a hard disk MBR and the DOS BIOS
+  parameter block (see "install/README" for more details on how this
+  can be used).
+
+* Block-list filesystem partially works, as described in the file
+  "NOTES".  Loading an a.out or elf kernel won't work with it, but all
+  other filetypes pretty much should.  (certainly chain-loading works
+  OK)
+
+  NOTE: you must use the full format "0+1,512" for just he first
+  block...  no parameters can be implicit in this version.. THis is
+  being fixed too.
+
+* Linux ext2 filesystem works.  (it's very slow for big files, but
+  this is being fixed)
+
+* Linux boot type now supported.  Use a standard piggybacked image as
+  with LILO.  Put in hack to support >64MB via GRUB placing the RAM
+  size as the first item on the command-line automatically.  Must pass
+  root partition on command-line using normal Linux syntax...  if not,
+  it uses it's builtin root partition.
+
+* Supports chain-loading.  For details, see "COMMANDS" and the
+  examples directory.  (was able to boot DOS and Windows NT on my test
+  box).  NOTE that the "root partition" must be set to work right.
+  "makeactive" is currently a no-op.
+
+* Several weird bugs fixed.  One important note: If you recompile, it
+  will warn about a clash with builtin "strcmp".  This is normal...
+  do NOT remove the strcmp definition, as then GCC will possibly put
+  inline code from it's own builtin function in some places. (my
+  strcmp has slightly different functionality, hence the problem)
+
+* Mini-debugger is currently broken.
+
+New in 0.2 - 1996-04-12, Erich Boleyn:
+
+* Completely new menu-based UI.  See "COMMANDS" and the examples
+  directory for details.  NOTE that the argument to a command must be
+  preceded by a space between it and the '=', in both the config file
+  and the command-line.  This will be fixed.
+
+New in 0.1 - 1996-03-31, Erich Boleyn:
+
+* Newer version of Multiboot Standard (version 0.6) supported.
+
+* Autodetects kernel types.  Supports Multiboot, FreeBSD, NetBSD
+  (Linux isn't finished).
+
+* Stage 1.5 works now.  Default setup is now for working with a BSD
+  FFS floppy loading "/grub/stage2" as the main bootloader.
+
+* Filesystem support improved.  It didn't work on many floppies before
+  (problem with the partition-detection code).
+
+* Memory probe now supports arbitrary amounts of RAM (some technical
+  limitations exist, see Multiboot standard version 0.6 for details).
+
+* A mini-debugger is included by default, activated by hitting '~' on
+  the command-line (it might interfere with things, but it seems OK
+  for my alpha-testing).  The commands are in the function
+  "enter_sysdebug" defined in "common.c".  If you have an Intel MPS-
+  compatible machine, there are extra commands enabled for SMP cpu
+  testing.  'q' exits and goes back to what you were doing before.
+
+New in 0.0-19960206 - 1996-02-06, Erich Boleyn:
+
+* Newer version of Multiboot Standard (version 0.4) supported.
+
+New in 0.0-19951210 - 1995-12-10, Erich Boleyn:
+
+* You can now perform TAB-based completion listing of any valid
+  partially completed disk/partition/file-name combination.  Try it
+  out to see what you like, examples are in the NOTES file under
+  "Device completion".
+
+* Fixed a bug causing the memory size routine to sometimes report
+  ridiculous values.
+
+* Fixed some documentation (what little there is :-/ and a few
+  assembly bugs in the BIOS access routines that nobody reported yet,
+  so I won't detail it here.
diff --git a/README b/README
new file mode 100644
index 0000000..10233f7
--- /dev/null
+++ b/README
@@ -0,0 +1,23 @@
+This is GNU GRUB, the GRand Unified Bootloader.  GRUB is intended to
+provide important bootloader features that are missing from typical
+personal computer BIOSes:
+
+  - provides fully-featured command line and graphical interfaces
+  - recognizes fdisk partitions and BSD disklabels
+  - can dynamically read Linux ext2fs, ReiserFS, JFS and XFS, BSD ufs,
+    MS-DOS FAT16 and FAT32, Minix fs, and VSTa fs filesystems, plus
+    hardcoded blocklists
+  - can boot Multiboot-compliant kernels (such as GNU Mach), as well
+    as standard Linux and *BSD kernels
+
+See the file NEWS for a description of recent changes to GRUB.
+
+If you are interested in the network support, see the file
+README.netboot under the directory netboot.
+
+See the file INSTALL for instructions on how to build and install the
+GRUB data and program files. See the GRUB manual for details about
+using GRUB as your boot loader. Type "info grub" in the shell prompt.
+
+Please visit the official web page of GNU GRUB, for more information.
+The URL is <http://www.gnu.org/software/grub/grub.html>.
diff --git a/THANKS b/THANKS
new file mode 100644
index 0000000..853da1a
--- /dev/null
+++ b/THANKS
@@ -0,0 +1,123 @@
+GRUB would not be what it is today without the invaluable help of
+everybody who was kind enough to spend time testing it and reporting
+bugs.
+
+The following people made especially gracious contributions of their
+time and energy in helping to track down bugs, add new features, and
+generally assist in the GRUB maintainership process:
+
+Adam Lackorzynski <adam@os.inf.tu-dresden.de>
+Adrian Phillips <a.phillips@dnmi.no>
+Alban Crequy <alban.crequy@apinc.org>
+Alessandro Rubini <rubini@gnu.org>
+Alexander K. Hudek <alexhudek@home.com>
+Alexander Langer <alex@big.endian.de>
+Alfred M. Szmidt <ams@kemisten.nu>
+Andrew Clausen <clausen@gnu.org>
+Andrew Walrond <andrew@walrond.org>
+Ben Liblit <liblit@eecs.berkeley.edu>
+Bernhard Treutwein <Bernhard.Treutwein@Verwaltung.Uni-Muenchen.DE>
+Bodo Rueskamp <br@itchigo.com>.
+Boji Tony Kannanthanam <boji.t.kannanthanam@intel.com>
+Bradford Hovinen <hovinen@redrose.net>
+Brian Brunswick <brian@skarpsey.demon.co.uk>
+Bryan Ford <baford@cs.utah.edu>
+Cedric Ware <ware@com.enst.fr>
+Chip Salzenberg <chip@valinux.com>
+Christian Jones <chjones@aleph0.com>
+Christoph Plattner <Christoph.Plattner@dot.at>
+Damian Ivereigh <damian@cisco.com>
+David Weinehall <tao@debian.org>
+Dan J. Walters <djw@cs.utexas.edu>
+Daniel Farrell <s2108287@student.rmit.edu.au>
+Daniel Pittman <daniel@rimspace.net>
+Daniel Wagner <wagi@gmx.ch>
+Danilo Godec <danci@agenda.si>
+Dennis Kitzman <dennis-kitzman@uiowa.edu>
+Derrik Pates <dpates@dsdk12.net>
+Edmund GRIMLEY EVANS <edmundo@rano.demon.co.uk>
+Eduard Guzovsky <eguzovsk@enterasys.com>
+Edward Killips <ekillips@triton.net>
+Egmont Koblinger <egmont@uhulinux.hu>
+Eric Hanchrow <erich@microsoft.com>
+Erik Schoenfelder <schoenfr@gaertner.de>
+Eugene Doudine <dudin@np.nk.nornik.ru>
+Florian Hatat <mininet@wanadoo.fr>
+Frank Mehnert <fm3@os.inf.tu-dresden.de>
+Gary Poppitz <gpoppitz@tachyon.net>
+Goran Koruga <goran.koruga@hermes.si>
+Hal Snyder <hal@vailsys.com>
+HASEGAWA Tomoki <thasegawa@mta.biglobe.ne.jp>
+Heikki Vatiainen <hessu@cs.tut.fi>
+Heiko Schroeder <heiko@pool.informatik.rwth-aachen.de>
+Henrik Nordstrom <hno@marasystems.com>
+Herbert Nachtnebel <nachtneb@iaee.tuwien.ac.at>
+Hidetoshi Nishimaki <nishimaki@mxs.nes.nec.co.jp>
+Hisazumi Kenji <nel@soraneko.com>
+HORIKAWA Kazunori <kaz-hori@tkd.att.ne.jp>
+Ilguiz Latypov <ilatypov@superbt.com>
+Jan Fricke <fricke@uni-greifswald.de>
+Jan Zerebecki <jan.list@elite-pferde.de>
+Jason Thomas <jason@topic.com.au>
+Jean-Jacques Michel <jjmichel@linbox.com>
+Jeremy Katz <katzj@redhat.com>
+Jochen Hoenicke <jochen@gnu.org>
+Johannes Kroeger <hanne@squirrel.owl.de>
+John Goerzen <jgoerzen@complete.org>
+John Tobey <spam@john-edwin-tobey.org>
+Josip Rodin <joy@cibalia.gkvk.hr>
+Julien Bordet <julien.bordet@int-evry.fr>
+Julien Perrot <julien.perrot@iie.cnam.fr>
+Kalle Olavi Niemitalo <tosi@ees2.oulu.fi>
+Karsten Scheibler <karsten.scheibler@student.uni-halle.de>
+KB Sriram <mail_kb@yahoo.com>
+Khimenko Victor <grub@khim.sch57.msk.ru>
+Klaus Reichl <klaus.reichl@alcatel.at>
+Kristoffer Branemyr <ztion@swipnet.se>
+Kunihiro Ishiguro <kunihiro@zebra.org>
+Leendert Meyer <leen.meyer@home.nl>
+Leonid Lisovskiy <lly@pisem.net>
+M. Meiarashi <mes@st.rim.or.jp>
+Mark Kettenis <kettenis@chello.nl>
+Mark Lundeberg <aa026@pgfn.bc.ca>
+Matt Perry <matt@primefactor.com>
+Matt Yourst <yourst@mit.edu>
+Matthias Granberry <matthias@slurpee.org>
+Matthias Kretschmer <m.kretschmer@bsdger.org>
+Michael Hohmuth <hohmuth@innocent.com>
+Michael Sullivan <mike@trdlnk.com>
+Mike Meyer <mwm@mired.org>
+Miles Bader <miles@gnu.org>
+NATORI Shin <natori@adm.s.u-tokyo.ac.jp>
+Neal H Walfield <neal@walfield.org>
+Neelkanth Natu <neelnatu@yahoo.com>
+OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
+Pavel Roskin <pavel_roskin@geocities.com>
+Per Lundberg <plundis@byggdok.se>
+Peter Astrand <altic@lysator.liu.se>
+Ralf Medow <ralf.medow@t-online.de>
+Ramon van Handel <vhandel@chem.vu.nl>
+Robert Millan  <robertmh@gnu.org>
+Roderich Schupp <rsch@ExperTeam.de>
+Rogelio M. Serrano Jr. <rogelio@victorio.com>
+Sergey Matveychuk <sem@ciam.ru>
+Serguei Tzukanov <tzukanov@narod.ru>
+Stefan Ondrejicka <ondrej@idata.sk>
+Stephen Early <steve@greenend.org.uk>
+Steven Dick <ssd.gnu@mmae.ucf.edu>
+Sven Wegener <swegener@gentoo.org>
+Takehiro Suzuki <takehiro@coral.ocn.ne.jp>
+Taketo Kabe <kabe@sra-tohoku.co.jp>
+Thierry DELHAISE <thierry.delhaise@delhaise.com>
+Thierry Laronde <thierry.laronde@polynum.com>
+Thomas Schweikle <tschweikle@fiducia.de>
+Thomas Schwinge <kischde@gmx.net>
+Tilmann Bubeck <t.bubeck@reinform.de>
+Timothy Baldwin <T.E.Baldwin99@members.leeds.ac.uk>
+Torsten Duwe <duwe@caldera.de>
+Uwe Dannowski <ud3@ira.uka.de>
+VaX#n8 <vax@linkdead.paranoia.com>
+Vesa Jaaskelainen <jaaskela@tietomyrsky.fi>
+Yedidyah Bar-David <didi@post.tau.ac.il>
+Yury V. Umanets <umka@namesys.com>
+Yuri Zaporogets <yuriz@ukr.net>
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..adbc8d0
--- /dev/null
+++ b/TODO
@@ -0,0 +1,102 @@
+-*- Mode: Outline -*-
+
+Before working on anything in this file, it's very important that you
+make contact with the core GRUB developers. Things herein might be
+slightly out of date or otherwise not easy to understand at first
+glance. So write to <bug-grub@gnu.org> first.
+
+Priorities:
+  Reported bugs generally have top priority.
+  Non-reported and non-encountered bugs (things we know don't work,
+    but don't really impede things) have lower priority.
+  Things in this file are ranked with one to three !; the more, the
+  higher priority.
+
+
+Things that should be done before 1.0:
+
+* Finish the Multiboot Speicification 0.7. !!!
+
+* Add more --disable-FOO options to configure, so that you can create a
+  minimum GRUB image. This is useful for boot floppies because of the size
+  restriction. !
+
+* Implement a new version of track_int13, using Virtual 8086 Mode. !!!
+
+* Add missing features of graphics support. !!
+
+Things that should _not_ be done before 1.0:
+
+* Add configuration inclusion support by adding a command "include". !
+
+* Add automatic configuration support.
+
+* Add bunzip2 support.
+
+* Define the module system.
+
+* Add BSD syntax support, using results of ioprobe to map drives. !
+  (0x1f0-0x1f7 = primary IDE, 0x170-0x176 = secondary,
+   0x1e8-0x1ef = tertiary, 0x168-0x16f = quaternary).
+
+* Add a real scripting language, possibly retaining backward
+  compatibility so that old config files can be used.
+
+* Add internationalization support, emulating gettext as much as is
+  feasible.
+
+* Support other architectures than i386-pc.
+
+* Add real memory management.
+
+
+Things that may be done anytime:
+
+* Port the script ``grub-install'' to OpenBSD. At least you will have to
+  modify the function `convert' so that it can translate a native device
+  name into the corresponding GRUB drive representation. !
+
+* Add a command to run a GRUB script file. !!
+
+* Add commands to manipulate the menu from the command-line interface. !
+
+* Make symbolic links work for BSD FFS.
+
+* Add indirect block support to the BSD FFS filesystem code, so files
+  larger than 16MB can be read.
+
+* Fix-up FreeBSD, NetBSD (and OpenBSD ?) command-line boot
+  parameters.
+
+* Support embedding a Stage 1.5 in the "bootloader" area of a FFS
+  partition. (We already have the code, but need an approval by an
+  expert before turning on the support. Any volunteers?)
+
+* Support embedding a Stage 1.5 in the EXT2_BOOT_LOADER_INO of an ext2fs
+  partition, so that it won't be accidentally erased or modified by
+  the kernel.
+
+* Add ISA PnP support.
+
+* Add more filesystems support (NTFS, etc.)
+
+* Add more remote console support (parallel and net).
+
+* Add (real) RAID support.
+
+? Add a partition naming syntax that means ``the first partition of
+  this type''.  We need this for clean Hurd install floppies.
+  Nope.  Improving the `find' command would solve this problem.
+
+* Add CDROM-chainloading support. It would be enough to support only
+  BIOSes which have bootable-CDROM support (so you may use the "Bootable
+  CDROM" BIOS calls). It is not trivial to support BIOSes without the
+  capability to boot CDROM.
+
+? Divide pxegrub into two parts, so the initial image doesn't exceed
+  the 32KB limit. I'm not sure if this is really necessary, because the
+  PXE standard just says that it is _recommended_ to improve the
+  modularity of a boot image. Obviously, this reason doesn't apply to
+  GRUB, as pxegrub is merely a secondary boot loader. So whether this
+  task should be done depends on if existing PXE ROMs support >32KB
+  images or not, after all.
diff --git a/acinclude.m4 b/acinclude.m4
new file mode 100644
index 0000000..368839c
--- /dev/null
+++ b/acinclude.m4
@@ -0,0 +1,366 @@
+dnl grub_ASM_USCORE checks if C symbols get an underscore after
+dnl compiling to assembler.
+dnl Written by Pavel Roskin. Based on grub_ASM_EXT_C written by
+dnl Erich Boleyn and modified by OKUJI Yoshinori
+AC_DEFUN([grub_ASM_USCORE],
+[AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING([if C symbols get an underscore after compilation])
+AC_CACHE_VAL(grub_cv_asm_uscore,
+[cat > conftest.c <<\EOF
+int
+func (int *list)
+{
+  *list = 0;
+  return *list;
+}
+EOF
+
+if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -S conftest.c]) && test -s conftest.s; then
+  true
+else
+  AC_MSG_ERROR([${CC-cc} failed to produce assembly code])
+fi
+
+if grep _func conftest.s >/dev/null 2>&1; then
+  grub_cv_asm_uscore=yes
+else
+  grub_cv_asm_uscore=no
+fi
+
+rm -f conftest*])
+
+if test "x$grub_cv_asm_uscore" = xyes; then
+  AC_DEFINE_UNQUOTED([HAVE_ASM_USCORE], $grub_cv_asm_uscore,
+    [Define if C symbols get an underscore after compilation])
+fi
+
+AC_MSG_RESULT([$grub_cv_asm_uscore])
+])
+
+
+dnl Some versions of `objcopy -O binary' vary their output depending
+dnl on the link address.
+AC_DEFUN([grub_PROG_OBJCOPY_ABSOLUTE],
+[AC_MSG_CHECKING([whether ${OBJCOPY} works for absolute addresses])
+AC_CACHE_VAL(grub_cv_prog_objcopy_absolute,
+[cat > conftest.c <<\EOF
+void
+cmain (void)
+{
+   *((int *) 0x1000) = 2;
+}
+EOF
+
+if AC_TRY_EVAL(ac_compile) && test -s conftest.o; then :
+else
+  AC_MSG_ERROR([${CC-cc} cannot compile C source code])
+fi
+grub_cv_prog_objcopy_absolute=yes
+for link_addr in 2000 8000 7C00; do
+  if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec]); then :
+  else
+    AC_MSG_ERROR([${CC-cc} cannot link at address $link_addr])
+  fi
+  if AC_TRY_COMMAND([${OBJCOPY-objcopy} -O binary conftest.exec conftest]); then :
+  else
+    AC_MSG_ERROR([${OBJCOPY-objcopy} cannot create binary files])
+  fi
+  if test ! -f conftest.old || AC_TRY_COMMAND([cmp -s conftest.old conftest]); then
+    mv -f conftest conftest.old
+  else
+    grub_cv_prog_objcopy_absolute=no
+    break
+  fi
+done
+rm -f conftest*])
+AC_MSG_RESULT([$grub_cv_prog_objcopy_absolute])])
+
+dnl Mass confusion!
+dnl Older versions of GAS interpret `.code16' to mean ``generate 32-bit
+dnl instructions, but implicitly insert addr32 and data32 bytes so
+dnl that the code works in real mode''.
+dnl
+dnl Newer versions of GAS interpret `.code16' to mean ``generate 16-bit
+dnl instructions,'' which seems right.  This requires the programmer
+dnl to explicitly insert addr32 and data32 instructions when they want
+dnl them.
+dnl
+dnl We only support the newer versions, because the old versions cause
+dnl major pain, by requiring manual assembly to get 16-bit instructions into
+dnl stage1/stage1.S.
+AC_DEFUN([grub_ASM_ADDR32],
+[AC_REQUIRE([AC_PROG_CC])
+AC_REQUIRE([grub_ASM_PREFIX_REQUIREMENT])
+AC_MSG_CHECKING([for .code16 addr32 assembler support])
+AC_CACHE_VAL(grub_cv_asm_addr32,
+[cat > conftest.s.in <<\EOF
+	.code16
+l1:	@ADDR32@	movb	%al, l1
+EOF
+
+if test "x$grub_cv_asm_prefix_requirement" = xyes; then
+  sed -e s/@ADDR32@/addr32/ < conftest.s.in > conftest.s
+else
+  sed -e s/@ADDR32@/addr32\;/ < conftest.s.in > conftest.s
+fi
+
+if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then
+  grub_cv_asm_addr32=yes
+else
+  grub_cv_asm_addr32=no
+fi
+
+rm -f conftest*])
+
+AC_MSG_RESULT([$grub_cv_asm_addr32])])
+
+dnl
+dnl Later versions of GAS requires that addr32 and data32 prefixes
+dnl appear in the same lines as the instructions they modify, while
+dnl earlier versions requires that they appear in separate lines.
+AC_DEFUN([grub_ASM_PREFIX_REQUIREMENT],
+[AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING(dnl
+[whether addr32 must be in the same line as the instruction])
+AC_CACHE_VAL(grub_cv_asm_prefix_requirement,
+[cat > conftest.s <<\EOF
+	.code16
+l1:	addr32	movb	%al, l1
+EOF
+
+if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then
+  grub_cv_asm_prefix_requirement=yes
+else
+  grub_cv_asm_prefix_requirement=no
+fi
+
+rm -f conftest*])
+
+if test "x$grub_cv_asm_prefix_requirement" = xyes; then
+  grub_tmp_addr32="addr32"
+  grub_tmp_data32="data32"
+else
+  grub_tmp_addr32="addr32;"
+  grub_tmp_data32="data32;"
+fi
+
+AC_DEFINE_UNQUOTED([ADDR32], $grub_tmp_addr32,
+  [Define it to \"addr32\" or \"addr32;\" to make GAS happy])
+AC_DEFINE_UNQUOTED([DATA32], $grub_tmp_data32,
+  [Define it to \"data32\" or \"data32;\" to make GAS happy])
+
+AC_MSG_RESULT([$grub_cv_asm_prefix_requirement])])
+
+dnl
+dnl Older versions of GAS require that absolute indirect calls/jumps are
+dnl not prefixed with `*', while later versions warn if not prefixed.
+AC_DEFUN([grub_ASM_ABSOLUTE_WITHOUT_ASTERISK],
+[AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING(dnl
+[whether an absolute indirect call/jump must not be prefixed with an asterisk])
+AC_CACHE_VAL(grub_cv_asm_absolute_without_asterisk,
+[cat > conftest.s <<\EOF
+	lcall	*(offset)	
+offset:
+	.long	0
+	.word	0
+EOF
+
+if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} -c conftest.s]) && test -s conftest.o; then
+  grub_cv_asm_absolute_without_asterisk=no
+else
+  grub_cv_asm_absolute_without_asterisk=yes
+fi
+
+rm -f conftest*])
+
+if test "x$grub_cv_asm_absolute_without_asterisk" = xyes; then
+  AC_DEFINE(ABSOLUTE_WITHOUT_ASTERISK, 1, [Define if an absolute indirect call/jump must NOT be prefixed with `*'])
+fi
+
+AC_MSG_RESULT([$grub_cv_asm_absolute_without_asterisk])])
+
+dnl
+dnl grub_CHECK_START_SYMBOL checks if start is automatically defined by
+dnl the compiler.
+dnl Written by OKUJI Yoshinori
+AC_DEFUN([grub_CHECK_START_SYMBOL],
+[AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING([if start is defined by the compiler])
+AC_CACHE_VAL(grub_cv_check_start_symbol,
+[AC_TRY_LINK([], [asm ("incl start")],
+   grub_cv_check_start_symbol=yes,
+   grub_cv_check_start_symbol=no)])
+
+if test "x$grub_cv_check_start_symbol" = xyes; then
+  AC_DEFINE(HAVE_START_SYMBOL, 1, [Define if start is defined])
+fi
+
+AC_MSG_RESULT([$grub_cv_check_start_symbol])
+])
+
+dnl
+dnl grub_CHECK_USCORE_START_SYMBOL checks if _start is automatically
+dnl defined by the compiler.
+dnl Written by OKUJI Yoshinori
+AC_DEFUN([grub_CHECK_USCORE_START_SYMBOL],
+[AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING([if _start is defined by the compiler])
+AC_CACHE_VAL(grub_cv_check_uscore_start_symbol,
+[AC_TRY_LINK([], [asm ("incl _start")],
+   grub_cv_check_uscore_start_symbol=yes,
+   grub_cv_check_uscore_start_symbol=no)])
+
+if test "x$grub_cv_check_uscore_start_symbol" = xyes; then
+  AC_DEFINE(HAVE_USCORE_START_SYMBOL, 1, [Define if _start is defined])
+fi
+
+AC_MSG_RESULT([$grub_cv_check_uscore_start_symbol])
+])
+
+dnl
+dnl grub_CHECK_USCORE_USCORE_BSS_START_SYMBOL checks if __bss_start is
+dnl automatically defined by the compiler.
+dnl Written by Michael Hohmoth.
+AC_DEFUN([grub_CHECK_USCORE_USCORE_BSS_START_SYMBOL],
+[AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING([if __bss_start is defined by the compiler])
+AC_CACHE_VAL(grub_cv_check_uscore_uscore_bss_start_symbol,
+[AC_TRY_LINK([], [asm ("incl __bss_start")],
+   grub_cv_check_uscore_uscore_bss_start_symbol=yes,
+   grub_cv_check_uscore_uscore_bss_start_symbol=no)])
+
+if test "x$grub_cv_check_uscore_uscore_bss_start_symbol" = xyes; then
+  AC_DEFINE(HAVE_USCORE_USCORE_BSS_START_SYMBOL, 1, [Define if __bss_start is defined])
+fi
+
+AC_MSG_RESULT([$grub_cv_check_uscore_uscore_bss_start_symbol])
+])
+
+dnl
+dnl grub_CHECK_EDATA_SYMBOL checks if edata is automatically defined by the
+dnl compiler.
+dnl Written by Michael Hohmuth.
+AC_DEFUN([grub_CHECK_EDATA_SYMBOL],
+[AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING([if edata is defined by the compiler])
+AC_CACHE_VAL(grub_cv_check_edata_symbol,
+[AC_TRY_LINK([], [asm ("incl edata")],
+   grub_cv_check_edata_symbol=yes,
+   grub_cv_check_edata_symbol=no)])
+
+if test "x$grub_cv_check_edata_symbol" = xyes; then
+  AC_DEFINE(HAVE_EDATA_SYMBOL, 1, [Define if edata is defined])
+fi
+
+AC_MSG_RESULT([$grub_cv_check_edata_symbol])
+])
+
+dnl
+dnl grub_CHECK_USCORE_EDATA_SYMBOL checks if _edata is automatically
+dnl defined by the compiler.
+dnl Written by Michael Hohmuth.
+AC_DEFUN([grub_CHECK_USCORE_EDATA_SYMBOL],
+[AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING([if _edata is defined by the compiler])
+AC_CACHE_VAL(grub_cv_check_uscore_edata_symbol,
+[AC_TRY_LINK([], [asm ("incl _edata")],
+   grub_cv_check_uscore_edata_symbol=yes,
+   grub_cv_check_uscore_edata_symbol=no)])
+
+if test "x$grub_cv_check_uscore_edata_symbol" = xyes; then
+  AC_DEFINE(HAVE_USCORE_EDATA_SYMBOL, 1, [Define if _edata is defined])
+fi
+
+AC_MSG_RESULT([$grub_cv_check_uscore_edata_symbol])
+])
+
+dnl
+dnl grub_CHECK_END_SYMBOL checks if end is automatically defined by the
+dnl compiler.
+dnl Written by OKUJI Yoshinori
+AC_DEFUN([grub_CHECK_END_SYMBOL],
+[AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING([if end is defined by the compiler])
+AC_CACHE_VAL(grub_cv_check_end_symbol,
+[AC_TRY_LINK([], [asm ("incl end")],
+   grub_cv_check_end_symbol=yes,
+   grub_cv_check_end_symbol=no)])
+
+if test "x$grub_cv_check_end_symbol" = xyes; then
+  AC_DEFINE(HAVE_END_SYMBOL, 1, [Define if end is defined])
+fi
+
+AC_MSG_RESULT([$grub_cv_check_end_symbol])
+])
+
+dnl
+dnl grub_CHECK_USCORE_END_SYMBOL checks if _end is automatically defined
+dnl by the compiler.
+dnl Written by OKUJI Yoshinori
+AC_DEFUN([grub_CHECK_USCORE_END_SYMBOL],
+[AC_REQUIRE([AC_PROG_CC])
+AC_MSG_CHECKING([if _end is defined by the compiler])
+AC_CACHE_VAL(grub_cv_check_uscore_end_symbol,
+[AC_TRY_LINK([], [asm ("incl _end")],
+   grub_cv_check_uscore_end_symbol=yes,
+   grub_cv_check_uscore_end_symbol=no)])
+
+if test "x$grub_cv_check_uscore_end_symbol" = xyes; then
+  AC_DEFINE(HAVE_USCORE_END_SYMBOL, 1, [Define if end is defined])
+fi
+
+AC_MSG_RESULT([$grub_cv_check_uscore_end_symbol])
+])
+
+dnl grub_DEFINE_FILE(MACRO_NAME, FILE_NAME, DESCRIPTION)
+dnl grub_DEFINE_FILE defines a macro as the contents of a file safely.
+dnl Replace some escape sequences, because autoconf doesn't handle them
+dnl gracefully.
+dnl Written by OKUJI Yoshinori.
+AC_DEFUN([grub_DEFINE_FILE],
+[AC_REQUIRE([AC_PROG_CC])
+# Because early versions of GNU sed 3.x are too buggy, use a C program
+# instead of shell commands. *sigh*
+cat >conftest.c <<\EOF
+#include <stdio.h>
+
+int
+main (void)
+{
+  int c;
+
+  while ((c = getchar ()) != EOF)
+    {
+      switch (c)
+        {
+	case '\n':
+	  fputs ("\\n", stdout);
+	  break;
+	case '\r':
+	  fputs ("\\r", stdout);
+	  break;
+	case '\\':
+	  fputs ("\\\\", stdout);
+	  break;
+	case '"':
+	  fputs ("\\\"", stdout);
+	  break;
+	default:
+	  putchar (c);
+	}
+    }
+
+  return 0;
+}
+EOF
+
+if AC_TRY_COMMAND([${CC-cc} ${CFLAGS} conftest.c -o conftest]) && test -s conftest; then
+  grub_tmp_value=`./conftest < "[$2]"`
+else
+  AC_MSG_ERROR([${CC-cc} failed to produce an executable file])
+fi
+
+AC_DEFINE_UNQUOTED([$1], "$grub_tmp_value", [$3])
+rm -f conftest*
+])
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..aa691f6
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,1061 @@
+# generated automatically by aclocal 1.9.4 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+# 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 distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# 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
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# 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.
+
+# 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.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# 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.
+
+# serial 6
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+	[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])
+AC_SUBST([$1_FALSE])
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# serial 7						-*- 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.
+
+# 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.
+
+
+# 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,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery.  Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC,   [depcc="$CC"   am_compiler_list=],
+       [$1], CXX,  [depcc="$CXX"  am_compiler_list=],
+       [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+       [$1], GCJ,  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
+                   [depcc="$$1"   am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+               [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_$1_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+  fi
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    case $depmode in
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    none) break ;;
+    esac
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.
+    if depmode=$depmode \
+       source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_$1_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+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.
+
+# 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 2
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[for mf in $CONFIG_FILES; do
+  # Strip MF so we end up with the name of the file.
+  mf=`echo "$mf" | sed -e 's/:.*$//'`
+  # Check whether this is an Automake generated Makefile or not.
+  # We used to match only the files named `Makefile.in', but
+  # some people rename them; so instead we look at the file content.
+  # Grep'ing the first line is not enough: some people post-process
+  # each Makefile.in and add a new line on top of each file to say so.
+  # So let's grep whole file.
+  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+    dirpart=`AS_DIRNAME("$mf")`
+  else
+    continue
+  fi
+  # Extract the definition of DEPDIR, am__include, and am__quote
+  # from the Makefile without running `make'.
+  DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+  test -z "$DEPDIR" && continue
+  am__include=`sed -n 's/^am__include = //p' < "$mf"`
+  test -z "am__include" && continue
+  am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+  # When using ansi2knr, U may be empty or an underscore; expand it
+  U=`sed -n 's/^U = //p' < "$mf"`
+  # Find all dependency output files, they are included files with
+  # $(DEPDIR) in their names.  We invoke sed twice because it is the
+  # simplest approach to changing $(DEPDIR) to its actual value in the
+  # expansion.
+  for file in `sed -n "
+    s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+       sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+    # Make sure the directory exists.
+    test -f "$dirpart/$file" && continue
+    fdir=`AS_DIRNAME(["$file"])`
+    AS_MKDIR_P([$dirpart/$fdir])
+    # echo "creating $dirpart/$file"
+    echo '# dummy' > "$dirpart/$file"
+  done
+done
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled.  FIXME.  This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# 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
+# 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 11
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.58])dnl
+dnl Autoconf wants to disallow AM_ names.  We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+   test -f $srcdir/config.status; then
+  AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AM_PROG_INSTALL_SH
+AM_PROG_INSTALL_STRIP
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+              [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+	      		     [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+                  [_AM_DEPENDENCIES(CC)],
+                  [define([AC_PROG_CC],
+                          defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+                  [_AM_DEPENDENCIES(CXX)],
+                  [define([AC_PROG_CXX],
+                          defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+])
+])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $1 | $1:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
+
+# 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.
+
+# serial 1
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot.  For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 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.
+
+# 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
+
+AC_DEFUN([AM_MAINTAINER_MODE],
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+  dnl maintainer-mode is disabled by default
+  AC_ARG_ENABLE(maintainer-mode,
+[  --enable-maintainer-mode  enable make rules and dependencies not useful
+			  (and sometimes confusing) to the casual installer],
+      USE_MAINTAINER_MODE=$enableval,
+      USE_MAINTAINER_MODE=no)
+  AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+  AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes])
+  MAINT=$MAINTAINER_MODE_TRUE
+  AC_SUBST(MAINT)dnl
+]
+)
+
+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.
+
+# 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 2
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+   am__include=include
+   am__quote=
+   _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+      am__include=.include
+      am__quote="\""
+      _am_result=BSD
+   fi
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+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.
+
+# 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
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# 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).
+# This was a mistake.  There are at least two reasons why we must not
+# use `-m 0755':
+#   - it causes special bits like SGID to be ignored,
+#   - it may be too restrictive (some setups expect 775 directories).
+#
+# Do not use -m 0755 and let people choose whatever they expect by
+# setting umask.
+#
+# We cannot accept any implementation of `mkdir' that recognizes `-p'.
+# Some implementations (such as Solaris 8's) are not thread-safe: if a
+# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
+# concurrently, both version can detect that a/ is missing, but only
+# one can create it and the other will error out.  Consequently we
+# restrict ourselves to GNU make (using the --version option ensures
+# this.)
+AC_DEFUN([AM_PROG_MKDIR_P],
+[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+  # We used to keeping the `.' as first argument, in order to
+  # allow $(mkdir_p) to be used without argument.  As in
+  #   $(mkdir_p) $(somedir)
+  # where $(somedir) is conditionally defined.  However this is wrong
+  # for two reasons:
+  #  1. if the package is installed by a user who cannot write `.'
+  #     make install will fail,
+  #  2. the above comment should most certainly read
+  #     $(mkdir_p) $(DESTDIR)$(somedir)
+  #     so it does not work when $(somedir) is undefined and
+  #     $(DESTDIR) is not.
+  #  To support the latter case, we have to write
+  #     test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
+  #  so the `.' trick is pointless.
+  mkdir_p='mkdir -p --'
+else
+  # On NextStep and OpenStep, the `mkdir' command does not
+  # recognize any option.  It will interpret all options as
+  # directories to create, and then abort because `.' already
+  # exists.
+  for d in ./-p ./--version;
+  do
+    test -d $d && rmdir $d
+  done
+  # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+  if test -f "$ac_aux_dir/mkinstalldirs"; then
+    mkdir_p='$(mkinstalldirs)'
+  else
+    mkdir_p='$(install_sh) -d'
+  fi
+fi
+AC_SUBST([mkdir_p])])
+
+# 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.
+
+# serial 2
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+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.
+
+# 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
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+   if test "$[*]" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$[*]" != "X $srcdir/configure conftest.file" \
+      && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+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.
+
+# 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
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# 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
+
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+#     tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+#     $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+     [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+     [m4_case([$1], [ustar],, [pax],,
+              [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+  case $_am_tool in
+  gnutar)
+    for _am_tar in tar gnutar gtar;
+    do
+      AM_RUN_LOG([$_am_tar --version]) && break
+    done
+    am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+    am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+    am__untar="$_am_tar -xf -"
+    ;;
+  plaintar)
+    # Must skip GNU tar: if it does not support --format= it doesn't create
+    # ustar tarball either.
+    (tar --version) >/dev/null 2>&1 && continue
+    am__tar='tar chf - "$$tardir"'
+    am__tar_='tar chf - "$tardir"'
+    am__untar='tar xf -'
+    ;;
+  pax)
+    am__tar='pax -L -x $1 -w "$$tardir"'
+    am__tar_='pax -L -x $1 -w "$tardir"'
+    am__untar='pax -r'
+    ;;
+  cpio)
+    am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+    am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+    am__untar='cpio -i -H $1 -d'
+    ;;
+  none)
+    am__tar=false
+    am__tar_=false
+    am__untar=false
+    ;;
+  esac
+
+  # If the value was cached, stop now.  We just wanted to have am__tar
+  # and am__untar set.
+  test -n "${am_cv_prog_tar_$1}" && break
+
+  # tar/untar a dummy directory, and stop if the command works
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  echo GrepMe > conftest.dir/file
+  AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+  rm -rf conftest.dir
+  if test -s conftest.tar; then
+    AM_RUN_LOG([$am__untar <conftest.tar])
+    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+  fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([acinclude.m4])
diff --git a/android.lst b/android.lst
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/android.lst
diff --git a/compile b/compile
new file mode 100755
index 0000000..3d21703
--- /dev/null
+++ b/compile
@@ -0,0 +1,142 @@
+#! /bin/sh
+# Wrapper for compilers which do not understand `-c -o'.
+
+scriptversion=2004-10-12.08
+
+# Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+# Written by Tom Tromey <tromey@cygnus.com>.
+#
+# 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.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: compile [--help] [--version] PROGRAM [ARGS]
+
+Wrapper for compilers which do not understand `-c -o'.
+Remove `-o dest.o' from ARGS, run PROGRAM with the remaining
+arguments, and rename the output as expected.
+
+If you are trying to build a whole package this is not the
+right script to run: please start by reading the file `INSTALL'.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit 0
+    ;;
+  -v | --v*)
+    echo "compile $scriptversion"
+    exit 0
+    ;;
+esac
+
+ofile=
+cfile=
+eat=
+
+for arg
+do
+  if test -n "$eat"; then
+    eat=
+  else
+    case $1 in
+      -o)
+	# configure might choose to run compile as `compile cc -o foo foo.c'.
+	# So we strip `-o arg' only if arg is an object.
+	eat=1
+	case $2 in
+	  *.o | *.obj)
+	    ofile=$2
+	    ;;
+	  *)
+	    set x "$@" -o "$2"
+	    shift
+	    ;;
+	esac
+	;;
+      *.c)
+	cfile=$1
+	set x "$@" "$1"
+	shift
+	;;
+      *)
+	set x "$@" "$1"
+	shift
+	;;
+    esac
+  fi
+  shift
+done
+
+if test -z "$ofile" || test -z "$cfile"; then
+  # If no `-o' option was seen then we might have been invoked from a
+  # pattern rule where we don't need one.  That is ok -- this is a
+  # normal compilation that the losing compiler can handle.  If no
+  # `.c' file was seen then we are probably linking.  That is also
+  # ok.
+  exec "$@"
+fi
+
+# Name of file we expect compiler to create.
+cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'`
+
+# Create the lock directory.
+# Note: use `[/.-]' here to ensure that we don't use the same name
+# that we are using for the .o file.  Also, base the name on the expected
+# object file name, since that is what matters with a parallel build.
+lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d
+while true; do
+  if mkdir "$lockdir" >/dev/null 2>&1; then
+    break
+  fi
+  sleep 1
+done
+# FIXME: race condition here if user kills between mkdir and trap.
+trap "rmdir '$lockdir'; exit 1" 1 2 15
+
+# Run the compile.
+"$@"
+ret=$?
+
+if test -f "$cofile"; then
+  mv "$cofile" "$ofile"
+elif test -f "${cofile}bj"; then
+  mv "${cofile}bj" "$ofile"
+fi
+
+rmdir "$lockdir"
+exit $ret
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/config.guess b/config.guess
new file mode 100755
index 0000000..8229471
--- /dev/null
+++ b/config.guess
@@ -0,0 +1,1453 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+timestamp='2004-11-12'
+
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit 0 ;;
+    amd64:OpenBSD:*:*)
+	echo x86_64-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    cats:OpenBSD:*:*)
+	echo arm-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    luna88k:OpenBSD:*:*)
+    	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mips64-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:MirBSD:*:*)
+	echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit 0 ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit 0;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit 0 ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit 0 ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit 0 ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit 0 ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit 0 ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit 0 ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7 && exit 0 ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit 0 ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c \
+	  && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && exit 0
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit 0 ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    # avoid double evaluation of $set_cc_for_build
+	    test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit 0 ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit 0 ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit 0 ;;
+    x86:Interix*:[34]*)
+	echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+	exit 0 ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit 0 ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit 0 ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit 0 ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit 0 ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit 0 ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit 0 ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit 0 ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit 0 ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit 0 ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit 0 ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit 0 ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit 0 ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit 0 ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit 0 ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#ifdef __INTEL_COMPILER
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit 0 ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit 0 ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit 0 ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit 0 ;;
+	i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit 0 ;;
+    i*86:*:5:[78]*)
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit 0 ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit 0 ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit 0 ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit 0 ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit 0 ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit 0 ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit 0 ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    *86) UNAME_PROCESSOR=i686 ;;
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit 0 ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit 0 ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit 0 ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit 0 ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit 0 ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit 0 ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit 0 ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit 0 ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit 0 ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit 0 ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit 0 ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms && exit 0 ;;
+	    I*) echo ia64-dec-vms && exit 0 ;;
+	    V*) echo vax-dec-vms && exit 0 ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/config.h b/config.h
new file mode 100644
index 0000000..d21372c
--- /dev/null
+++ b/config.h
@@ -0,0 +1,107 @@
+/* config.h.  Generated by configure.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define if an absolute indirect call/jump must NOT be prefixed with `*' */
+/* #undef ABSOLUTE_WITHOUT_ASTERISK */
+
+/* Define it to \"addr32\" or \"addr32;\" to make GAS happy */
+#define ADDR32 addr32
+
+/* Define if you don't want to pass the mem= option to Linux */
+/* #undef AUTO_LINUX_MEM_OPT */
+
+/* Define it to \"data32\" or \"data32;\" to make GAS happy */
+#define DATA32 data32
+
+/* Define if C symbols get an underscore after compilation */
+/* #undef HAVE_ASM_USCORE */
+
+/* Define to 1 if you have the <curses.h> header file. */
+#define HAVE_CURSES_H 1
+
+/* Define if edata is defined */
+#define HAVE_EDATA_SYMBOL 1
+
+/* Define if end is defined */
+#define HAVE_END_SYMBOL 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define if you have a curses library */
+#define HAVE_LIBCURSES 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <ncurses/curses.h> header file. */
+/* #undef HAVE_NCURSES_CURSES_H */
+
+/* Define to 1 if you have the <ncurses.h> header file. */
+#define HAVE_NCURSES_H 1
+
+/* Define if opendisk() in -lutil can be used */
+/* #undef HAVE_OPENDISK */
+
+/* Define if start is defined */
+/* #undef HAVE_START_SYMBOL */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define if _edata is defined */
+#define HAVE_USCORE_EDATA_SYMBOL 1
+
+/* Define if end is defined */
+#define HAVE_USCORE_END_SYMBOL 1
+
+/* Define if _start is defined */
+#define HAVE_USCORE_START_SYMBOL 1
+
+/* Define if __bss_start is defined */
+#define HAVE_USCORE_USCORE_BSS_START_SYMBOL 1
+
+/* Name of package */
+#define PACKAGE "grub"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "bug-grub@gnu.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "GRUB"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "GRUB 0.97"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "grub"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "0.97"
+
+/* Define if there is user specified preset menu string */
+/* #undef PRESET_MENU_STRING */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "0.97"
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 0000000..68d7c8c
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,106 @@
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define if an absolute indirect call/jump must NOT be prefixed with `*' */
+#undef ABSOLUTE_WITHOUT_ASTERISK
+
+/* Define it to \"addr32\" or \"addr32;\" to make GAS happy */
+#undef ADDR32
+
+/* Define if you don't want to pass the mem= option to Linux */
+#undef AUTO_LINUX_MEM_OPT
+
+/* Define it to \"data32\" or \"data32;\" to make GAS happy */
+#undef DATA32
+
+/* Define if C symbols get an underscore after compilation */
+#undef HAVE_ASM_USCORE
+
+/* Define to 1 if you have the <curses.h> header file. */
+#undef HAVE_CURSES_H
+
+/* Define if edata is defined */
+#undef HAVE_EDATA_SYMBOL
+
+/* Define if end is defined */
+#undef HAVE_END_SYMBOL
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define if you have a curses library */
+#undef HAVE_LIBCURSES
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <ncurses/curses.h> header file. */
+#undef HAVE_NCURSES_CURSES_H
+
+/* Define to 1 if you have the <ncurses.h> header file. */
+#undef HAVE_NCURSES_H
+
+/* Define if opendisk() in -lutil can be used */
+#undef HAVE_OPENDISK
+
+/* Define if start is defined */
+#undef HAVE_START_SYMBOL
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define if _edata is defined */
+#undef HAVE_USCORE_EDATA_SYMBOL
+
+/* Define if end is defined */
+#undef HAVE_USCORE_END_SYMBOL
+
+/* Define if _start is defined */
+#undef HAVE_USCORE_START_SYMBOL
+
+/* Define if __bss_start is defined */
+#undef HAVE_USCORE_USCORE_BSS_START_SYMBOL
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define if there is user specified preset menu string */
+#undef PRESET_MENU_STRING
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
diff --git a/config.log b/config.log
new file mode 100644
index 0000000..b756fd4
--- /dev/null
+++ b/config.log
@@ -0,0 +1,957 @@
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by GRUB configure 0.97, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ ./configure --disable-auto-linux-mem-opt --enable-preset-menu=android.lst --disable-ffs --disable-ufs2 --disable-minix --disable-reiserfs --disable-vstafs --disable-jfs --disable-xfs --disable-iso9660
+
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = weppard.corp.google.com
+uname -m = x86_64
+uname -r = 2.6.18.5-gg26workstation-mixed64-32
+uname -s = Linux
+uname -v = #1 SMP Mon Feb 11 16:45:49 PST 2008
+
+/usr/bin/uname -p = unknown
+/bin/uname -X     = unknown
+
+/bin/arch              = x86_64
+/usr/bin/arch -k       = unknown
+/usr/convex/getsysinfo = unknown
+hostinfo               = unknown
+/bin/machine           = unknown
+/usr/bin/oslevel       = unknown
+/bin/universe          = unknown
+
+PATH: /usr/local/xfce4.4/bin
+PATH: /usr/local/xfce4.4/bin
+PATH: /usr/local/symlinks
+PATH: /usr/local/scripts
+PATH: /usr/local/sbin
+PATH: /usr/local/bin
+PATH: /usr/sbin
+PATH: /usr/bin
+PATH: /sbin
+PATH: /bin
+PATH: /usr/bin/X11
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+configure:1434: checking for a BSD-compatible install
+configure:1489: result: /usr/bin/install -c
+configure:1500: checking whether build environment is sane
+configure:1543: result: yes
+configure:1608: checking for gawk
+configure:1624: found /usr/bin/gawk
+configure:1634: result: gawk
+configure:1644: checking whether make sets $(MAKE)
+configure:1664: result: yes
+configure:1839: checking build system type
+configure:1857: result: x86_64-unknown-linux-gnu
+configure:1865: checking host system type
+configure:1879: result: x86_64-unknown-linux-gnu
+configure:1903: checking whether to enable maintainer-specific portions of Makefiles
+configure:1912: result: no
+configure:2028: checking for gcc
+configure:2044: found /usr/bin/gcc
+configure:2054: result: gcc
+configure:2112: checking for gcc
+configure:2138: result: gcc
+configure:2382: checking for C compiler version
+configure:2385: gcc --version </dev/null >&5
+gcc (GCC) 4.0.3 (Ubuntu 4.0.3-1ubuntu5)
+Copyright (C) 2006 Free Software Foundation, Inc.
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+configure:2388: $? = 0
+configure:2390: gcc -v </dev/null >&5
+Using built-in specs.
+Target: i486-linux-gnu
+Configured with: ../src/configure -v --enable-languages=c,c++,java,f95,objc,ada,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.0 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-awt=gtk-default --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-4.0-1.4.2.0/jre --enable-mpfr --disable-werror --with-tune=pentium4 --enable-checking=release i486-linux-gnu
+Thread model: posix
+gcc version 4.0.3 (Ubuntu 4.0.3-1ubuntu5)
+configure:2393: $? = 0
+configure:2395: gcc -V </dev/null >&5
+gcc: '-V' option must have argument
+configure:2398: $? = 1
+configure:2421: checking for C compiler default output file name
+configure:2424: gcc -m32    conftest.c  >&5
+configure:2427: $? = 0
+configure:2473: result: a.out
+configure:2478: checking whether the C compiler works
+configure:2484: ./a.out
+configure:2487: $? = 0
+configure:2504: result: yes
+configure:2511: checking whether we are cross compiling
+configure:2513: result: no
+configure:2516: checking for suffix of executables
+configure:2518: gcc -o conftest -m32    conftest.c  >&5
+configure:2521: $? = 0
+configure:2546: result: 
+configure:2552: checking for suffix of object files
+configure:2573: gcc -c -m32   conftest.c >&5
+configure:2576: $? = 0
+configure:2598: result: o
+configure:2602: checking whether we are using the GNU C compiler
+configure:2626: gcc -c -m32   conftest.c >&5
+configure:2632: $? = 0
+configure:2636: test -z 
+			 || test ! -s conftest.err
+configure:2639: $? = 0
+configure:2642: test -s conftest.o
+configure:2645: $? = 0
+configure:2658: result: yes
+configure:2664: checking whether gcc accepts -g
+configure:2685: gcc -c -g  conftest.c >&5
+configure:2691: $? = 0
+configure:2695: test -z 
+			 || test ! -s conftest.err
+configure:2698: $? = 0
+configure:2701: test -s conftest.o
+configure:2704: $? = 0
+configure:2715: result: yes
+configure:2732: checking for gcc option to accept ANSI C
+configure:2802: gcc  -c -m32   conftest.c >&5
+configure:2808: $? = 0
+configure:2812: test -z 
+			 || test ! -s conftest.err
+configure:2815: $? = 0
+configure:2818: test -s conftest.o
+configure:2821: $? = 0
+configure:2839: result: none needed
+configure:2857: gcc -c -m32   conftest.c >&5
+conftest.c:2: error: syntax error before 'me'
+configure:2863: $? = 1
+configure: failed program was:
+| #ifndef __cplusplus
+|   choke me
+| #endif
+configure:3007: checking for style of include used by make
+configure:3035: result: GNU
+configure:3063: checking dependency style of gcc
+configure:3153: result: gcc3
+configure:3174: checking dependency style of gcc
+configure:3264: result: gcc3
+configure:3376: checking for ranlib
+configure:3392: found /usr/bin/ranlib
+configure:3403: result: ranlib
+configure:3429: checking whether optimization for size works
+configure:3453: gcc -c -Os -g  conftest.c >&5
+configure:3459: $? = 0
+configure:3463: test -z 
+			 || test ! -s conftest.err
+configure:3466: $? = 0
+configure:3469: test -s conftest.o
+configure:3472: $? = 0
+configure:3485: result: yes
+configure:3494: checking whether gcc has -fno-stack-protector
+configure:3518: gcc -c -fno-stack-protector  conftest.c >&5
+cc1: error: unrecognized command line option "-fno-stack-protector"
+configure:3524: $? = 1
+configure: failed program was:
+| /* confdefs.h.  */
+| 
+| #define PACKAGE_NAME "GRUB"
+| #define PACKAGE_TARNAME "grub"
+| #define PACKAGE_VERSION "0.97"
+| #define PACKAGE_STRING "GRUB 0.97"
+| #define PACKAGE_BUGREPORT "bug-grub@gnu.org"
+| #define PACKAGE "grub"
+| #define VERSION "0.97"
+| /* end confdefs.h.  */
+| 
+| int
+| main ()
+| {
+| 
+|   ;
+|   return 0;
+| }
+configure:3550: result: no
+configure:3566: checking whether -Wundef works
+configure:3590: gcc -c -m32 -g -Wundef conftest.c >&5
+configure:3596: $? = 0
+configure:3600: test -z 
+			 || test ! -s conftest.err
+configure:3603: $? = 0
+configure:3606: test -s conftest.o
+configure:3609: $? = 0
+configure:3622: result: yes
+configure:3627: checking whether -falign-loops works
+configure:3651: gcc -c -m32 -g -falign-loops=1 conftest.c >&5
+configure:3657: $? = 0
+configure:3661: test -z 
+			 || test ! -s conftest.err
+configure:3664: $? = 0
+configure:3667: test -s conftest.o
+configure:3670: $? = 0
+configure:3683: result: yes
+configure:3780: checking for objcopy
+configure:3796: found /usr/bin/objcopy
+configure:3806: result: objcopy
+configure:3822: checking if C symbols get an underscore after compilation
+configure:3837: gcc -m32 -g -S conftest.c
+configure:3840: $? = 0
+configure:3867: result: no
+configure:3870: checking whether objcopy works for absolute addresses
+configure:3883: gcc -c -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c >&5
+conftest.c:3: warning: no previous prototype for 'cmain'
+configure:3886: $? = 0
+configure:3896: gcc -m32 -g -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000 conftest.o -o conftest.exec
+/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000002000
+configure:3899: $? = 0
+configure:3907: objcopy -O binary conftest.exec conftest
+configure:3910: $? = 0
+configure:3896: gcc -m32 -g -nostdlib -Wl,-N -Wl,-Ttext -Wl,8000 conftest.o -o conftest.exec
+/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000008000
+configure:3899: $? = 0
+configure:3907: objcopy -O binary conftest.exec conftest
+configure:3910: $? = 0
+configure:3918: cmp -s conftest.old conftest
+configure:3921: $? = 0
+configure:3896: gcc -m32 -g -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00 conftest.o -o conftest.exec
+/usr/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000007c00
+configure:3899: $? = 0
+configure:3907: objcopy -O binary conftest.exec conftest
+configure:3910: $? = 0
+configure:3918: cmp -s conftest.old conftest
+configure:3921: $? = 0
+configure:3932: result: yes
+configure:3941: checking whether addr32 must be in the same line as the instruction
+configure:3952: gcc -m32 -g -c conftest.s
+configure:3955: $? = 0
+configure:3985: result: yes
+configure:3990: checking for .code16 addr32 assembler support
+configure:4007: gcc -m32 -g -c conftest.s
+configure:4010: $? = 0
+configure:4021: result: yes
+configure:4030: checking whether an absolute indirect call/jump must not be prefixed with an asterisk
+configure:4043: gcc -m32 -g -c conftest.s
+configure:4046: $? = 0
+configure:4065: result: no
+configure:4069: checking if start is defined by the compiler
+configure:4090: gcc -o conftest -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef  conftest.c  >&5
+/tmp/ccnTvoRl.o: In function `main':/home/dmitriyz/src-lcl/android-x86/device/tools/grub-0.97/conftest.c:17: undefined reference to `start'
+collect2: ld returned 1 exit status
+configure:4096: $? = 1
+configure: failed program was:
+| /* confdefs.h.  */
+| 
+| #define PACKAGE_NAME "GRUB"
+| #define PACKAGE_TARNAME "grub"
+| #define PACKAGE_VERSION "0.97"
+| #define PACKAGE_STRING "GRUB 0.97"
+| #define PACKAGE_BUGREPORT "bug-grub@gnu.org"
+| #define PACKAGE "grub"
+| #define VERSION "0.97"
+| #define ADDR32 addr32
+| #define DATA32 data32
+| /* end confdefs.h.  */
+| 
+| int
+| main ()
+| {
+| asm ("incl start")
+|   ;
+|   return 0;
+| }
+configure:4131: result: no
+configure:4135: checking if _start is defined by the compiler
+configure:4156: gcc -o conftest -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef  conftest.c  >&5
+configure:4162: $? = 0
+configure:4166: test -z 
+			 || test ! -s conftest.err
+configure:4169: $? = 0
+configure:4172: test -s conftest
+configure:4175: $? = 0
+configure:4197: result: yes
+configure:4208: checking if __bss_start is defined by the compiler
+configure:4229: gcc -o conftest -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef  conftest.c  >&5
+configure:4235: $? = 0
+configure:4239: test -z 
+			 || test ! -s conftest.err
+configure:4242: $? = 0
+configure:4245: test -s conftest
+configure:4248: $? = 0
+configure:4270: result: yes
+configure:4274: checking if _edata is defined by the compiler
+configure:4295: gcc -o conftest -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef  conftest.c  >&5
+configure:4301: $? = 0
+configure:4305: test -z 
+			 || test ! -s conftest.err
+configure:4308: $? = 0
+configure:4311: test -s conftest
+configure:4314: $? = 0
+configure:4336: result: yes
+configure:4340: checking if edata is defined by the compiler
+configure:4361: gcc -o conftest -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef  conftest.c  >&5
+configure:4367: $? = 0
+configure:4371: test -z 
+			 || test ! -s conftest.err
+configure:4374: $? = 0
+configure:4377: test -s conftest
+configure:4380: $? = 0
+configure:4402: result: yes
+configure:4414: checking if end is defined by the compiler
+configure:4435: gcc -o conftest -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef  conftest.c  >&5
+configure:4441: $? = 0
+configure:4445: test -z 
+			 || test ! -s conftest.err
+configure:4448: $? = 0
+configure:4451: test -s conftest
+configure:4454: $? = 0
+configure:4476: result: yes
+configure:4480: checking if _end is defined by the compiler
+configure:4501: gcc -o conftest -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef  conftest.c  >&5
+configure:4507: $? = 0
+configure:4511: test -z 
+			 || test ! -s conftest.err
+configure:4514: $? = 0
+configure:4517: test -s conftest
+configure:4520: $? = 0
+configure:4542: result: yes
+configure:4562: checking for opendisk in -lutil
+configure:4592: gcc -o conftest -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef  conftest.c -lutil   >&5
+/tmp/ccO7pDXI.o: In function `main':/home/dmitriyz/src-lcl/android-x86/device/tools/grub-0.97/conftest.c:30: undefined reference to `opendisk'
+collect2: ld returned 1 exit status
+configure:4598: $? = 1
+configure: failed program was:
+| /* confdefs.h.  */
+| 
+| #define PACKAGE_NAME "GRUB"
+| #define PACKAGE_TARNAME "grub"
+| #define PACKAGE_VERSION "0.97"
+| #define PACKAGE_STRING "GRUB 0.97"
+| #define PACKAGE_BUGREPORT "bug-grub@gnu.org"
+| #define PACKAGE "grub"
+| #define VERSION "0.97"
+| #define ADDR32 addr32
+| #define DATA32 data32
+| #define HAVE_USCORE_START_SYMBOL 1
+| #define HAVE_USCORE_USCORE_BSS_START_SYMBOL 1
+| #define HAVE_USCORE_EDATA_SYMBOL 1
+| #define HAVE_EDATA_SYMBOL 1
+| #define HAVE_END_SYMBOL 1
+| #define HAVE_USCORE_END_SYMBOL 1
+| /* end confdefs.h.  */
+| 
+| /* Override any gcc2 internal prototype to avoid an error.  */
+| #ifdef __cplusplus
+| extern "C"
+| #endif
+| /* We use char because int might match the return type of a gcc2
+|    builtin and then its argument prototype would still apply.  */
+| char opendisk ();
+| int
+| main ()
+| {
+| opendisk ();
+|   ;
+|   return 0;
+| }
+configure:4624: result: no
+configure:4638: checking for wgetch in -lncurses
+configure:4668: gcc -o conftest -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef  conftest.c -lncurses   >&5
+configure:4674: $? = 0
+configure:4678: test -z 
+			 || test ! -s conftest.err
+configure:4681: $? = 0
+configure:4684: test -s conftest
+configure:4687: $? = 0
+configure:4700: result: yes
+configure:4795: checking how to run the C preprocessor
+configure:4830: gcc -E  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c
+configure:4836: $? = 0
+configure:4868: gcc -E  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c
+conftest.c:20:28: error: ac_nonexistent.h: No such file or directory
+configure:4874: $? = 1
+configure: failed program was:
+| /* confdefs.h.  */
+| 
+| #define PACKAGE_NAME "GRUB"
+| #define PACKAGE_TARNAME "grub"
+| #define PACKAGE_VERSION "0.97"
+| #define PACKAGE_STRING "GRUB 0.97"
+| #define PACKAGE_BUGREPORT "bug-grub@gnu.org"
+| #define PACKAGE "grub"
+| #define VERSION "0.97"
+| #define ADDR32 addr32
+| #define DATA32 data32
+| #define HAVE_USCORE_START_SYMBOL 1
+| #define HAVE_USCORE_USCORE_BSS_START_SYMBOL 1
+| #define HAVE_USCORE_EDATA_SYMBOL 1
+| #define HAVE_EDATA_SYMBOL 1
+| #define HAVE_END_SYMBOL 1
+| #define HAVE_USCORE_END_SYMBOL 1
+| #define HAVE_LIBCURSES 1
+| /* end confdefs.h.  */
+| #include <ac_nonexistent.h>
+configure:4913: result: gcc -E
+configure:4937: gcc -E  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c
+configure:4943: $? = 0
+configure:4975: gcc -E  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c
+conftest.c:20:28: error: ac_nonexistent.h: No such file or directory
+configure:4981: $? = 1
+configure: failed program was:
+| /* confdefs.h.  */
+| 
+| #define PACKAGE_NAME "GRUB"
+| #define PACKAGE_TARNAME "grub"
+| #define PACKAGE_VERSION "0.97"
+| #define PACKAGE_STRING "GRUB 0.97"
+| #define PACKAGE_BUGREPORT "bug-grub@gnu.org"
+| #define PACKAGE "grub"
+| #define VERSION "0.97"
+| #define ADDR32 addr32
+| #define DATA32 data32
+| #define HAVE_USCORE_START_SYMBOL 1
+| #define HAVE_USCORE_USCORE_BSS_START_SYMBOL 1
+| #define HAVE_USCORE_EDATA_SYMBOL 1
+| #define HAVE_EDATA_SYMBOL 1
+| #define HAVE_END_SYMBOL 1
+| #define HAVE_USCORE_END_SYMBOL 1
+| #define HAVE_LIBCURSES 1
+| /* end confdefs.h.  */
+| #include <ac_nonexistent.h>
+configure:5025: checking for egrep
+configure:5035: result: grep -E
+configure:5040: checking for ANSI C header files
+configure:5065: gcc -c -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c >&5
+configure:5071: $? = 0
+configure:5075: test -z 
+			 || test ! -s conftest.err
+configure:5078: $? = 0
+configure:5081: test -s conftest.o
+configure:5084: $? = 0
+configure:5173: gcc -o conftest -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef  conftest.c  >&5
+conftest.c: In function 'main':
+conftest.c:37: warning: implicit declaration of function 'exit'
+conftest.c:37: warning: incompatible implicit declaration of built-in function 'exit'
+configure:5176: $? = 0
+configure:5178: ./conftest
+configure:5181: $? = 0
+configure:5196: result: yes
+configure:5220: checking for sys/types.h
+configure:5236: gcc -c -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c >&5
+conftest.c:22:5: warning: "HAVE_SYS_TYPES_H" is not defined
+conftest.c:25:5: warning: "HAVE_SYS_STAT_H" is not defined
+conftest.c:36:5: warning: "HAVE_STRING_H" is not defined
+conftest.c:42:5: warning: "HAVE_STRINGS_H" is not defined
+conftest.c:45:5: warning: "HAVE_INTTYPES_H" is not defined
+conftest.c:48:6: warning: "HAVE_STDINT_H" is not defined
+conftest.c:52:5: warning: "HAVE_UNISTD_H" is not defined
+configure:5242: $? = 0
+configure:5246: test -z 
+			 || test ! -s conftest.err
+configure:5249: $? = 0
+configure:5252: test -s conftest.o
+configure:5255: $? = 0
+configure:5266: result: yes
+configure:5220: checking for sys/stat.h
+configure:5236: gcc -c -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c >&5
+conftest.c:26:5: warning: "HAVE_SYS_STAT_H" is not defined
+conftest.c:37:5: warning: "HAVE_STRING_H" is not defined
+conftest.c:43:5: warning: "HAVE_STRINGS_H" is not defined
+conftest.c:46:5: warning: "HAVE_INTTYPES_H" is not defined
+conftest.c:49:6: warning: "HAVE_STDINT_H" is not defined
+conftest.c:53:5: warning: "HAVE_UNISTD_H" is not defined
+configure:5242: $? = 0
+configure:5246: test -z 
+			 || test ! -s conftest.err
+configure:5249: $? = 0
+configure:5252: test -s conftest.o
+configure:5255: $? = 0
+configure:5266: result: yes
+configure:5220: checking for stdlib.h
+configure:5236: gcc -c -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c >&5
+conftest.c:38:5: warning: "HAVE_STRING_H" is not defined
+conftest.c:44:5: warning: "HAVE_STRINGS_H" is not defined
+conftest.c:47:5: warning: "HAVE_INTTYPES_H" is not defined
+conftest.c:50:6: warning: "HAVE_STDINT_H" is not defined
+conftest.c:54:5: warning: "HAVE_UNISTD_H" is not defined
+configure:5242: $? = 0
+configure:5246: test -z 
+			 || test ! -s conftest.err
+configure:5249: $? = 0
+configure:5252: test -s conftest.o
+configure:5255: $? = 0
+configure:5266: result: yes
+configure:5220: checking for string.h
+configure:5236: gcc -c -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c >&5
+conftest.c:39:5: warning: "HAVE_STRING_H" is not defined
+conftest.c:45:5: warning: "HAVE_STRINGS_H" is not defined
+conftest.c:48:5: warning: "HAVE_INTTYPES_H" is not defined
+conftest.c:51:6: warning: "HAVE_STDINT_H" is not defined
+conftest.c:55:5: warning: "HAVE_UNISTD_H" is not defined
+configure:5242: $? = 0
+configure:5246: test -z 
+			 || test ! -s conftest.err
+configure:5249: $? = 0
+configure:5252: test -s conftest.o
+configure:5255: $? = 0
+configure:5266: result: yes
+configure:5220: checking for memory.h
+configure:5236: gcc -c -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c >&5
+conftest.c:46:5: warning: "HAVE_STRINGS_H" is not defined
+conftest.c:49:5: warning: "HAVE_INTTYPES_H" is not defined
+conftest.c:52:6: warning: "HAVE_STDINT_H" is not defined
+conftest.c:56:5: warning: "HAVE_UNISTD_H" is not defined
+configure:5242: $? = 0
+configure:5246: test -z 
+			 || test ! -s conftest.err
+configure:5249: $? = 0
+configure:5252: test -s conftest.o
+configure:5255: $? = 0
+configure:5266: result: yes
+configure:5220: checking for strings.h
+configure:5236: gcc -c -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c >&5
+conftest.c:47:5: warning: "HAVE_STRINGS_H" is not defined
+conftest.c:50:5: warning: "HAVE_INTTYPES_H" is not defined
+conftest.c:53:6: warning: "HAVE_STDINT_H" is not defined
+conftest.c:57:5: warning: "HAVE_UNISTD_H" is not defined
+configure:5242: $? = 0
+configure:5246: test -z 
+			 || test ! -s conftest.err
+configure:5249: $? = 0
+configure:5252: test -s conftest.o
+configure:5255: $? = 0
+configure:5266: result: yes
+configure:5220: checking for inttypes.h
+configure:5236: gcc -c -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c >&5
+conftest.c:51:5: warning: "HAVE_INTTYPES_H" is not defined
+conftest.c:54:6: warning: "HAVE_STDINT_H" is not defined
+conftest.c:58:5: warning: "HAVE_UNISTD_H" is not defined
+configure:5242: $? = 0
+configure:5246: test -z 
+			 || test ! -s conftest.err
+configure:5249: $? = 0
+configure:5252: test -s conftest.o
+configure:5255: $? = 0
+configure:5266: result: yes
+configure:5220: checking for stdint.h
+configure:5236: gcc -c -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c >&5
+conftest.c:59:5: warning: "HAVE_UNISTD_H" is not defined
+configure:5242: $? = 0
+configure:5246: test -z 
+			 || test ! -s conftest.err
+configure:5249: $? = 0
+configure:5252: test -s conftest.o
+configure:5255: $? = 0
+configure:5266: result: yes
+configure:5220: checking for unistd.h
+configure:5236: gcc -c -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c >&5
+conftest.c:60:5: warning: "HAVE_UNISTD_H" is not defined
+configure:5242: $? = 0
+configure:5246: test -z 
+			 || test ! -s conftest.err
+configure:5249: $? = 0
+configure:5252: test -s conftest.o
+configure:5255: $? = 0
+configure:5266: result: yes
+configure:5287: checking for string.h
+configure:5292: result: yes
+configure:5287: checking for strings.h
+configure:5292: result: yes
+configure:5296: checking ncurses/curses.h usability
+configure:5308: gcc -c -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c >&5
+conftest.c:66:28: error: ncurses/curses.h: No such file or directory
+configure:5314: $? = 1
+configure: failed program was:
+| /* confdefs.h.  */
+| 
+| #define PACKAGE_NAME "GRUB"
+| #define PACKAGE_TARNAME "grub"
+| #define PACKAGE_VERSION "0.97"
+| #define PACKAGE_STRING "GRUB 0.97"
+| #define PACKAGE_BUGREPORT "bug-grub@gnu.org"
+| #define PACKAGE "grub"
+| #define VERSION "0.97"
+| #define ADDR32 addr32
+| #define DATA32 data32
+| #define HAVE_USCORE_START_SYMBOL 1
+| #define HAVE_USCORE_USCORE_BSS_START_SYMBOL 1
+| #define HAVE_USCORE_EDATA_SYMBOL 1
+| #define HAVE_EDATA_SYMBOL 1
+| #define HAVE_END_SYMBOL 1
+| #define HAVE_USCORE_END_SYMBOL 1
+| #define HAVE_LIBCURSES 1
+| #define STDC_HEADERS 1
+| #define HAVE_SYS_TYPES_H 1
+| #define HAVE_SYS_STAT_H 1
+| #define HAVE_STDLIB_H 1
+| #define HAVE_STRING_H 1
+| #define HAVE_MEMORY_H 1
+| #define HAVE_STRINGS_H 1
+| #define HAVE_INTTYPES_H 1
+| #define HAVE_STDINT_H 1
+| #define HAVE_UNISTD_H 1
+| #define HAVE_STRING_H 1
+| #define HAVE_STRINGS_H 1
+| /* end confdefs.h.  */
+| #include <stdio.h>
+| #if HAVE_SYS_TYPES_H
+| # include <sys/types.h>
+| #endif
+| #if HAVE_SYS_STAT_H
+| # include <sys/stat.h>
+| #endif
+| #if STDC_HEADERS
+| # include <stdlib.h>
+| # include <stddef.h>
+| #else
+| # if HAVE_STDLIB_H
+| #  include <stdlib.h>
+| # endif
+| #endif
+| #if HAVE_STRING_H
+| # if !STDC_HEADERS && HAVE_MEMORY_H
+| #  include <memory.h>
+| # endif
+| # include <string.h>
+| #endif
+| #if HAVE_STRINGS_H
+| # include <strings.h>
+| #endif
+| #if HAVE_INTTYPES_H
+| # include <inttypes.h>
+| #else
+| # if HAVE_STDINT_H
+| #  include <stdint.h>
+| # endif
+| #endif
+| #if HAVE_UNISTD_H
+| # include <unistd.h>
+| #endif
+| #include <ncurses/curses.h>
+configure:5337: result: no
+configure:5341: checking ncurses/curses.h presence
+configure:5351: gcc -E  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c
+conftest.c:32:28: error: ncurses/curses.h: No such file or directory
+configure:5357: $? = 1
+configure: failed program was:
+| /* confdefs.h.  */
+| 
+| #define PACKAGE_NAME "GRUB"
+| #define PACKAGE_TARNAME "grub"
+| #define PACKAGE_VERSION "0.97"
+| #define PACKAGE_STRING "GRUB 0.97"
+| #define PACKAGE_BUGREPORT "bug-grub@gnu.org"
+| #define PACKAGE "grub"
+| #define VERSION "0.97"
+| #define ADDR32 addr32
+| #define DATA32 data32
+| #define HAVE_USCORE_START_SYMBOL 1
+| #define HAVE_USCORE_USCORE_BSS_START_SYMBOL 1
+| #define HAVE_USCORE_EDATA_SYMBOL 1
+| #define HAVE_EDATA_SYMBOL 1
+| #define HAVE_END_SYMBOL 1
+| #define HAVE_USCORE_END_SYMBOL 1
+| #define HAVE_LIBCURSES 1
+| #define STDC_HEADERS 1
+| #define HAVE_SYS_TYPES_H 1
+| #define HAVE_SYS_STAT_H 1
+| #define HAVE_STDLIB_H 1
+| #define HAVE_STRING_H 1
+| #define HAVE_MEMORY_H 1
+| #define HAVE_STRINGS_H 1
+| #define HAVE_INTTYPES_H 1
+| #define HAVE_STDINT_H 1
+| #define HAVE_UNISTD_H 1
+| #define HAVE_STRING_H 1
+| #define HAVE_STRINGS_H 1
+| /* end confdefs.h.  */
+| #include <ncurses/curses.h>
+configure:5377: result: no
+configure:5412: checking for ncurses/curses.h
+configure:5419: result: no
+configure:5296: checking ncurses.h usability
+configure:5308: gcc -c -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c >&5
+configure:5314: $? = 0
+configure:5318: test -z 
+			 || test ! -s conftest.err
+configure:5321: $? = 0
+configure:5324: test -s conftest.o
+configure:5327: $? = 0
+configure:5337: result: yes
+configure:5341: checking ncurses.h presence
+configure:5351: gcc -E  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c
+configure:5357: $? = 0
+configure:5377: result: yes
+configure:5412: checking for ncurses.h
+configure:5419: result: yes
+configure:5296: checking curses.h usability
+configure:5308: gcc -c -m32 -g  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c >&5
+configure:5314: $? = 0
+configure:5318: test -z 
+			 || test ! -s conftest.err
+configure:5321: $? = 0
+configure:5324: test -s conftest.o
+configure:5327: $? = 0
+configure:5337: result: yes
+configure:5341: checking curses.h presence
+configure:5351: gcc -E  -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef conftest.c
+configure:5357: $? = 0
+configure:5377: result: yes
+configure:5412: checking for curses.h
+configure:5419: result: yes
+configure:6072: gcc -m32 -g conftest.c -o conftest
+configure:6075: $? = 0
+configure:6305: creating ./config.status
+
+## ---------------------- ##
+## Running config.status. ##
+## ---------------------- ##
+
+This file was extended by GRUB config.status 0.97, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = 
+  CONFIG_HEADERS  = 
+  CONFIG_LINKS    = 
+  CONFIG_COMMANDS = 
+  $ ./config.status 
+
+on weppard.corp.google.com
+
+config.status:739: creating Makefile
+config.status:739: creating stage1/Makefile
+config.status:739: creating stage2/Makefile
+config.status:739: creating docs/Makefile
+config.status:739: creating lib/Makefile
+config.status:739: creating util/Makefile
+config.status:739: creating grub/Makefile
+config.status:739: creating netboot/Makefile
+config.status:739: creating util/grub-image
+config.status:739: creating util/grub-install
+config.status:739: creating util/grub-md5-crypt
+config.status:739: creating util/grub-terminfo
+config.status:739: creating util/grub-set-default
+config.status:843: creating config.h
+config.status:1157: executing depfiles commands
+
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+
+ac_cv_build=x86_64-unknown-linux-gnu
+ac_cv_build_alias=x86_64-unknown-linux-gnu
+ac_cv_c_compiler_gnu=yes
+ac_cv_env_CC_set=
+ac_cv_env_CC_value=
+ac_cv_env_CFLAGS_set=
+ac_cv_env_CFLAGS_value=
+ac_cv_env_CPPFLAGS_set=
+ac_cv_env_CPPFLAGS_value=
+ac_cv_env_CPP_set=
+ac_cv_env_CPP_value=
+ac_cv_env_LDFLAGS_set=
+ac_cv_env_LDFLAGS_value=
+ac_cv_env_build_alias_set=
+ac_cv_env_build_alias_value=
+ac_cv_env_host_alias_set=
+ac_cv_env_host_alias_value=
+ac_cv_env_target_alias_set=
+ac_cv_env_target_alias_value=
+ac_cv_exeext=
+ac_cv_header_curses_h=yes
+ac_cv_header_inttypes_h=yes
+ac_cv_header_memory_h=yes
+ac_cv_header_ncurses_curses_h=no
+ac_cv_header_ncurses_h=yes
+ac_cv_header_stdc=yes
+ac_cv_header_stdint_h=yes
+ac_cv_header_stdlib_h=yes
+ac_cv_header_string_h=yes
+ac_cv_header_strings_h=yes
+ac_cv_header_sys_stat_h=yes
+ac_cv_header_sys_types_h=yes
+ac_cv_header_unistd_h=yes
+ac_cv_host=x86_64-unknown-linux-gnu
+ac_cv_host_alias=x86_64-unknown-linux-gnu
+ac_cv_lib_ncurses_wgetch=yes
+ac_cv_lib_util_opendisk=no
+ac_cv_objext=o
+ac_cv_path_install='/usr/bin/install -c'
+ac_cv_prog_AWK=gawk
+ac_cv_prog_CPP='gcc -E'
+ac_cv_prog_ac_ct_CC=gcc
+ac_cv_prog_ac_ct_OBJCOPY=objcopy
+ac_cv_prog_ac_ct_RANLIB=ranlib
+ac_cv_prog_cc_g=yes
+ac_cv_prog_cc_stdc=
+ac_cv_prog_egrep='grep -E'
+ac_cv_prog_make_make_set=yes
+am_cv_CC_dependencies_compiler_type=gcc3
+grub_cv_asm_absolute_without_asterisk=no
+grub_cv_asm_addr32=yes
+grub_cv_asm_prefix_requirement=yes
+grub_cv_asm_uscore=no
+grub_cv_check_edata_symbol=yes
+grub_cv_check_end_symbol=yes
+grub_cv_check_start_symbol=no
+grub_cv_check_uscore_edata_symbol=yes
+grub_cv_check_uscore_end_symbol=yes
+grub_cv_check_uscore_start_symbol=yes
+grub_cv_check_uscore_uscore_bss_start_symbol=yes
+grub_cv_prog_objcopy_absolute=yes
+
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+
+ACLOCAL='${SHELL} /home/dmitriyz/src-lcl/android-x86/device/tools/grub-0.97/missing --run aclocal-1.9'
+AMDEPBACKSLASH='\'
+AMDEP_FALSE='#'
+AMDEP_TRUE=''
+AMTAR='${SHELL} /home/dmitriyz/src-lcl/android-x86/device/tools/grub-0.97/missing --run tar'
+AUTOCONF='${SHELL} /home/dmitriyz/src-lcl/android-x86/device/tools/grub-0.97/missing --run autoconf'
+AUTOHEADER='${SHELL} /home/dmitriyz/src-lcl/android-x86/device/tools/grub-0.97/missing --run autoheader'
+AUTOMAKE='${SHELL} /home/dmitriyz/src-lcl/android-x86/device/tools/grub-0.97/missing --run automake-1.9'
+AWK='gawk'
+BUILD_EXAMPLE_KERNEL_FALSE=''
+BUILD_EXAMPLE_KERNEL_TRUE='#'
+CC='gcc'
+CCAS='gcc'
+CCASFLAGS='$(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)'
+CCDEPMODE='depmode=gcc3'
+CFLAGS='-m32 -g'
+CPP='gcc -E'
+CPPFLAGS=' -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef'
+CYGPATH_W='echo'
+DEFS='-DHAVE_CONFIG_H'
+DEPDIR='.deps'
+DISKLESS_SUPPORT_FALSE=''
+DISKLESS_SUPPORT_TRUE='#'
+ECHO_C=''
+ECHO_N='-n'
+ECHO_T=''
+EGREP='grep -E'
+EXEEXT=''
+FSYS_CFLAGS=' -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DUSE_MD5_PASSWORDS=1'
+GRUB_CFLAGS='-O2'
+GRUB_LIBS=' -lncurses'
+HERCULES_SUPPORT_FALSE='#'
+HERCULES_SUPPORT_TRUE=''
+INSTALL_DATA='${INSTALL} -m 644'
+INSTALL_PROGRAM='${INSTALL}'
+INSTALL_SCRIPT='${INSTALL}'
+INSTALL_STRIP_PROGRAM='${SHELL} $(install_sh) -c -s'
+LDFLAGS=''
+LIBOBJS=''
+LIBS=''
+LTLIBOBJS=''
+MAINT='#'
+MAINTAINER_MODE_FALSE=''
+MAINTAINER_MODE_TRUE='#'
+MAKEINFO='${SHELL} /home/dmitriyz/src-lcl/android-x86/device/tools/grub-0.97/missing --run makeinfo'
+NETBOOT_DRIVERS=''
+NETBOOT_SUPPORT_FALSE=''
+NETBOOT_SUPPORT_TRUE='#'
+NET_CFLAGS=''
+NET_EXTRAFLAGS=' -DCONGESTED=1 -DNE_SCAN=0x280,0x300,0x320,0x340 -DWD_DEFAULT_MEM=0xCC000'
+OBJCOPY='objcopy'
+OBJEXT='o'
+PACKAGE='grub'
+PACKAGE_BUGREPORT='bug-grub@gnu.org'
+PACKAGE_NAME='GRUB'
+PACKAGE_STRING='GRUB 0.97'
+PACKAGE_TARNAME='grub'
+PACKAGE_VERSION='0.97'
+PATH_SEPARATOR=':'
+PERL=''
+RANLIB='ranlib'
+SERIAL_SPEED_SIMULATION_FALSE=''
+SERIAL_SPEED_SIMULATION_TRUE='#'
+SERIAL_SUPPORT_FALSE='#'
+SERIAL_SUPPORT_TRUE=''
+SET_MAKE=''
+SHELL='/bin/sh'
+STAGE1_CFLAGS='-O2'
+STAGE2_CFLAGS='-Os'
+STRIP=''
+VERSION='0.97'
+ac_ct_CC='gcc'
+ac_ct_OBJCOPY='objcopy'
+ac_ct_RANLIB='ranlib'
+ac_ct_STRIP=''
+am__fastdepCC_FALSE='#'
+am__fastdepCC_TRUE=''
+am__include='include'
+am__leading_dot='.'
+am__quote=''
+am__tar='${AMTAR} chof - "$$tardir"'
+am__untar='${AMTAR} xf -'
+bindir='${exec_prefix}/bin'
+build='x86_64-unknown-linux-gnu'
+build_alias=''
+build_cpu='x86_64'
+build_os='linux-gnu'
+build_vendor='unknown'
+datadir='${prefix}/share'
+exec_prefix='${prefix}'
+host='x86_64-unknown-linux-gnu'
+host_alias=''
+host_cpu='x86_64'
+host_os='linux-gnu'
+host_vendor='unknown'
+includedir='${prefix}/include'
+infodir='${prefix}/info'
+install_sh='/home/dmitriyz/src-lcl/android-x86/device/tools/grub-0.97/install-sh'
+libdir='${exec_prefix}/lib'
+libexecdir='${exec_prefix}/libexec'
+localstatedir='${prefix}/var'
+mandir='${prefix}/man'
+mkdir_p='mkdir -p --'
+oldincludedir='/usr/include'
+prefix='/usr/local'
+program_transform_name='s,x,x,'
+sbindir='${exec_prefix}/sbin'
+sharedstatedir='${prefix}/com'
+sysconfdir='${prefix}/etc'
+target_alias=''
+
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+
+#define ADDR32 addr32
+#define DATA32 data32
+#define HAVE_CURSES_H 1
+#define HAVE_EDATA_SYMBOL 1
+#define HAVE_END_SYMBOL 1
+#define HAVE_INTTYPES_H 1
+#define HAVE_LIBCURSES 1
+#define HAVE_MEMORY_H 1
+#define HAVE_NCURSES_H 1
+#define HAVE_STDINT_H 1
+#define HAVE_STDLIB_H 1
+#define HAVE_STRINGS_H 1
+#define HAVE_STRINGS_H 1
+#define HAVE_STRING_H 1
+#define HAVE_STRING_H 1
+#define HAVE_SYS_STAT_H 1
+#define HAVE_SYS_TYPES_H 1
+#define HAVE_UNISTD_H 1
+#define HAVE_USCORE_EDATA_SYMBOL 1
+#define HAVE_USCORE_END_SYMBOL 1
+#define HAVE_USCORE_START_SYMBOL 1
+#define HAVE_USCORE_USCORE_BSS_START_SYMBOL 1
+#define PACKAGE "grub"
+#define PACKAGE_BUGREPORT "bug-grub@gnu.org"
+#define PACKAGE_NAME "GRUB"
+#define PACKAGE_STRING "GRUB 0.97"
+#define PACKAGE_TARNAME "grub"
+#define PACKAGE_VERSION "0.97"
+#define PRESET_MENU_STRING ""
+#define STDC_HEADERS 1
+#define VERSION "0.97"
+
+configure: exit 0
diff --git a/config.status b/config.status
new file mode 100755
index 0000000..38461ed
--- /dev/null
+++ b/config.status
@@ -0,0 +1,1248 @@
+#! /bin/sh
+# Generated by configure.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=${CONFIG_SHELL-/bin/sh}
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by GRUB $as_me 0.97, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+config_files=" Makefile stage1/Makefile stage2/Makefile docs/Makefile lib/Makefile util/Makefile grub/Makefile netboot/Makefile util/grub-image util/grub-install util/grub-md5-crypt util/grub-terminfo util/grub-set-default"
+config_headers=" config.h"
+config_commands=" depfiles"
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+		   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+		   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+ac_cs_version="\
+GRUB config.status 0.97
+configured by ./configure, generated by GNU Autoconf 2.59,
+  with options \"'--disable-auto-linux-mem-opt' '--enable-preset-menu=android.lst' '--disable-ffs' '--disable-ufs2' '--disable-minix' '--disable-reiserfs' '--disable-vstafs' '--disable-jfs' '--disable-xfs' '--disable-iso9660'\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=.
+INSTALL="/usr/bin/install -c"
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+if $ac_cs_recheck; then
+  echo "running /bin/sh ./configure " '--disable-auto-linux-mem-opt' '--enable-preset-menu=android.lst' '--disable-ffs' '--disable-ufs2' '--disable-minix' '--disable-reiserfs' '--disable-vstafs' '--disable-jfs' '--disable-xfs' '--disable-iso9660' $ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec /bin/sh ./configure '--disable-auto-linux-mem-opt' '--enable-preset-menu=android.lst' '--disable-ffs' '--disable-ufs2' '--disable-minix' '--disable-reiserfs' '--disable-vstafs' '--disable-jfs' '--disable-xfs' '--disable-iso9660' $ac_configure_extra_args --no-create --no-recursion
+fi
+
+#
+# INIT-COMMANDS section.
+#
+
+AMDEP_TRUE="" ac_aux_dir="."
+
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "stage1/Makefile" ) CONFIG_FILES="$CONFIG_FILES stage1/Makefile" ;;
+  "stage2/Makefile" ) CONFIG_FILES="$CONFIG_FILES stage2/Makefile" ;;
+  "docs/Makefile" ) CONFIG_FILES="$CONFIG_FILES docs/Makefile" ;;
+  "lib/Makefile" ) CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;;
+  "util/Makefile" ) CONFIG_FILES="$CONFIG_FILES util/Makefile" ;;
+  "grub/Makefile" ) CONFIG_FILES="$CONFIG_FILES grub/Makefile" ;;
+  "netboot/Makefile" ) CONFIG_FILES="$CONFIG_FILES netboot/Makefile" ;;
+  "util/grub-image" ) CONFIG_FILES="$CONFIG_FILES util/grub-image" ;;
+  "util/grub-install" ) CONFIG_FILES="$CONFIG_FILES util/grub-install" ;;
+  "util/grub-md5-crypt" ) CONFIG_FILES="$CONFIG_FILES util/grub-md5-crypt" ;;
+  "util/grub-terminfo" ) CONFIG_FILES="$CONFIG_FILES util/grub-terminfo" ;;
+  "util/grub-set-default" ) CONFIG_FILES="$CONFIG_FILES util/grub-set-default" ;;
+  "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+  "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t$/@;t t/; /@;t t$/s/[\\&,]/\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t$/,;t t/' >$tmp/subs.sed <<\CEOF
+s,@SHELL@,/bin/sh,;t t
+s,@PATH_SEPARATOR@,:,;t t
+s,@PACKAGE_NAME@,GRUB,;t t
+s,@PACKAGE_TARNAME@,grub,;t t
+s,@PACKAGE_VERSION@,0.97,;t t
+s,@PACKAGE_STRING@,GRUB 0.97,;t t
+s,@PACKAGE_BUGREPORT@,bug-grub@gnu.org,;t t
+s,@exec_prefix@,${prefix},;t t
+s,@prefix@,/usr/local,;t t
+s,@program_transform_name@,s,x,x,,;t t
+s,@bindir@,${exec_prefix}/bin,;t t
+s,@sbindir@,${exec_prefix}/sbin,;t t
+s,@libexecdir@,${exec_prefix}/libexec,;t t
+s,@datadir@,${prefix}/share,;t t
+s,@sysconfdir@,${prefix}/etc,;t t
+s,@sharedstatedir@,${prefix}/com,;t t
+s,@localstatedir@,${prefix}/var,;t t
+s,@libdir@,${exec_prefix}/lib,;t t
+s,@includedir@,${prefix}/include,;t t
+s,@oldincludedir@,/usr/include,;t t
+s,@infodir@,${prefix}/info,;t t
+s,@mandir@,${prefix}/man,;t t
+s,@build_alias@,,;t t
+s,@host_alias@,,;t t
+s,@target_alias@,,;t t
+s,@DEFS@,-DHAVE_CONFIG_H,;t t
+s,@ECHO_C@,,;t t
+s,@ECHO_N@,-n,;t t
+s,@ECHO_T@,,;t t
+s,@LIBS@,,;t t
+s,@INSTALL_PROGRAM@,${INSTALL},;t t
+s,@INSTALL_SCRIPT@,${INSTALL},;t t
+s,@INSTALL_DATA@,${INSTALL} -m 644,;t t
+s,@CYGPATH_W@,echo,;t t
+s,@PACKAGE@,grub,;t t
+s,@VERSION@,0.97,;t t
+s,@ACLOCAL@,${SHELL} /home/dmitriyz/src-lcl/android-x86/device/tools/grub-0.97/missing --run aclocal-1.9,;t t
+s,@AUTOCONF@,${SHELL} /home/dmitriyz/src-lcl/android-x86/device/tools/grub-0.97/missing --run autoconf,;t t
+s,@AUTOMAKE@,${SHELL} /home/dmitriyz/src-lcl/android-x86/device/tools/grub-0.97/missing --run automake-1.9,;t t
+s,@AUTOHEADER@,${SHELL} /home/dmitriyz/src-lcl/android-x86/device/tools/grub-0.97/missing --run autoheader,;t t
+s,@MAKEINFO@,${SHELL} /home/dmitriyz/src-lcl/android-x86/device/tools/grub-0.97/missing --run makeinfo,;t t
+s,@install_sh@,/home/dmitriyz/src-lcl/android-x86/device/tools/grub-0.97/install-sh,;t t
+s,@STRIP@,,;t t
+s,@ac_ct_STRIP@,,;t t
+s,@INSTALL_STRIP_PROGRAM@,${SHELL} $(install_sh) -c -s,;t t
+s,@mkdir_p@,mkdir -p --,;t t
+s,@AWK@,gawk,;t t
+s,@SET_MAKE@,,;t t
+s,@am__leading_dot@,.,;t t
+s,@AMTAR@,${SHELL} /home/dmitriyz/src-lcl/android-x86/device/tools/grub-0.97/missing --run tar,;t t
+s,@am__tar@,${AMTAR} chof - "$$tardir",;t t
+s,@am__untar@,${AMTAR} xf -,;t t
+s,@build@,x86_64-unknown-linux-gnu,;t t
+s,@build_cpu@,x86_64,;t t
+s,@build_vendor@,unknown,;t t
+s,@build_os@,linux-gnu,;t t
+s,@host@,x86_64-unknown-linux-gnu,;t t
+s,@host_cpu@,x86_64,;t t
+s,@host_vendor@,unknown,;t t
+s,@host_os@,linux-gnu,;t t
+s,@MAINTAINER_MODE_TRUE@,#,;t t
+s,@MAINTAINER_MODE_FALSE@,,;t t
+s,@MAINT@,#,;t t
+s,@PERL@,,;t t
+s,@CC@,gcc,;t t
+s,@ac_ct_CC@,gcc,;t t
+s,@CFLAGS@,-m32 -g,;t t
+s,@LDFLAGS@,,;t t
+s,@CPPFLAGS@, -Wall -Wmissing-prototypes -Wunused -Wshadow -Wpointer-arith -falign-jumps=1 -falign-loops=1 -falign-functions=1 -Wundef,;t t
+s,@EXEEXT@,,;t t
+s,@OBJEXT@,o,;t t
+s,@DEPDIR@,.deps,;t t
+s,@am__include@,include,;t t
+s,@am__quote@,,;t t
+s,@AMDEP_TRUE@,,;t t
+s,@AMDEP_FALSE@,#,;t t
+s,@AMDEPBACKSLASH@,\,;t t
+s,@CCDEPMODE@,depmode=gcc3,;t t
+s,@am__fastdepCC_TRUE@,,;t t
+s,@am__fastdepCC_FALSE@,#,;t t
+s,@CCAS@,gcc,;t t
+s,@RANLIB@,ranlib,;t t
+s,@ac_ct_RANLIB@,ranlib,;t t
+s,@STAGE1_CFLAGS@,-O2,;t t
+s,@STAGE2_CFLAGS@,-Os,;t t
+s,@GRUB_CFLAGS@,-O2,;t t
+s,@OBJCOPY@,objcopy,;t t
+s,@ac_ct_OBJCOPY@,objcopy,;t t
+s,@GRUB_LIBS@, -lncurses,;t t
+s,@CPP@,gcc -E,;t t
+s,@EGREP@,grep -E,;t t
+s,@NETBOOT_SUPPORT_TRUE@,#,;t t
+s,@NETBOOT_SUPPORT_FALSE@,,;t t
+s,@DISKLESS_SUPPORT_TRUE@,#,;t t
+s,@DISKLESS_SUPPORT_FALSE@,,;t t
+s,@HERCULES_SUPPORT_TRUE@,,;t t
+s,@HERCULES_SUPPORT_FALSE@,#,;t t
+s,@SERIAL_SUPPORT_TRUE@,,;t t
+s,@SERIAL_SUPPORT_FALSE@,#,;t t
+s,@SERIAL_SPEED_SIMULATION_TRUE@,#,;t t
+s,@SERIAL_SPEED_SIMULATION_FALSE@,,;t t
+s,@BUILD_EXAMPLE_KERNEL_TRUE@,#,;t t
+s,@BUILD_EXAMPLE_KERNEL_FALSE@,,;t t
+s,@FSYS_CFLAGS@, -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DUSE_MD5_PASSWORDS=1,;t t
+s,@NET_CFLAGS@,,;t t
+s,@NET_EXTRAFLAGS@, -DCONGESTED=1 -DNE_SCAN=0x280,0x300,0x320,0x340 -DWD_DEFAULT_MEM=0xCC000,;t t
+s,@NETBOOT_DRIVERS@,,;t t
+s,@CCASFLAGS@,$(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) $(CFLAGS),;t t
+s,@LIBOBJS@,,;t t
+s,@LTLIBOBJS@,,;t t
+CEOF
+
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+				     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  sed "/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[	 ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[	 ]*$//;
+}
+
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([	 ]*\)#\([	 ]*define[	 ][	 ]*\)'
+ac_dB='[	 ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([	 ]*\)#\([	 ]*\)undef\([	 ][	 ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 # Do quote $f, to prevent DOS paths from being IFS'd.
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[	 ]*$//' $ac_file_inputs >$tmp/in
+
+  # Handle all the #define templates only if necessary.
+  if grep "^[	 ]*#[	 ]*define" $tmp/in >/dev/null; then
+  # If there are no defines, we may have an empty if/fi
+  :
+  cat >$tmp/defines.sed <<CEOF
+/^[	 ]*#[	 ]*define/!b
+t clr
+: clr
+${ac_dA}PACKAGE_NAME${ac_dB}PACKAGE_NAME${ac_dC}"GRUB"${ac_dD}
+${ac_dA}PACKAGE_TARNAME${ac_dB}PACKAGE_TARNAME${ac_dC}"grub"${ac_dD}
+${ac_dA}PACKAGE_VERSION${ac_dB}PACKAGE_VERSION${ac_dC}"0.97"${ac_dD}
+${ac_dA}PACKAGE_STRING${ac_dB}PACKAGE_STRING${ac_dC}"GRUB 0.97"${ac_dD}
+${ac_dA}PACKAGE_BUGREPORT${ac_dB}PACKAGE_BUGREPORT${ac_dC}"bug-grub@gnu.org"${ac_dD}
+${ac_dA}PACKAGE${ac_dB}PACKAGE${ac_dC}"grub"${ac_dD}
+${ac_dA}VERSION${ac_dB}VERSION${ac_dC}"0.97"${ac_dD}
+${ac_dA}ADDR32${ac_dB}ADDR32${ac_dC}addr32${ac_dD}
+${ac_dA}DATA32${ac_dB}DATA32${ac_dC}data32${ac_dD}
+${ac_dA}HAVE_USCORE_START_SYMBOL${ac_dB}HAVE_USCORE_START_SYMBOL${ac_dC}1${ac_dD}
+${ac_dA}HAVE_USCORE_USCORE_BSS_START_SYMBOL${ac_dB}HAVE_USCORE_USCORE_BSS_START_SYMBOL${ac_dC}1${ac_dD}
+${ac_dA}HAVE_USCORE_EDATA_SYMBOL${ac_dB}HAVE_USCORE_EDATA_SYMBOL${ac_dC}1${ac_dD}
+${ac_dA}HAVE_EDATA_SYMBOL${ac_dB}HAVE_EDATA_SYMBOL${ac_dC}1${ac_dD}
+${ac_dA}HAVE_END_SYMBOL${ac_dB}HAVE_END_SYMBOL${ac_dC}1${ac_dD}
+${ac_dA}HAVE_USCORE_END_SYMBOL${ac_dB}HAVE_USCORE_END_SYMBOL${ac_dC}1${ac_dD}
+${ac_dA}HAVE_LIBCURSES${ac_dB}HAVE_LIBCURSES${ac_dC}1${ac_dD}
+${ac_dA}STDC_HEADERS${ac_dB}STDC_HEADERS${ac_dC}1${ac_dD}
+${ac_dA}HAVE_SYS_TYPES_H${ac_dB}HAVE_SYS_TYPES_H${ac_dC}1${ac_dD}
+${ac_dA}HAVE_SYS_STAT_H${ac_dB}HAVE_SYS_STAT_H${ac_dC}1${ac_dD}
+${ac_dA}HAVE_STDLIB_H${ac_dB}HAVE_STDLIB_H${ac_dC}1${ac_dD}
+${ac_dA}HAVE_STRING_H${ac_dB}HAVE_STRING_H${ac_dC}1${ac_dD}
+${ac_dA}HAVE_MEMORY_H${ac_dB}HAVE_MEMORY_H${ac_dC}1${ac_dD}
+${ac_dA}HAVE_STRINGS_H${ac_dB}HAVE_STRINGS_H${ac_dC}1${ac_dD}
+${ac_dA}HAVE_INTTYPES_H${ac_dB}HAVE_INTTYPES_H${ac_dC}1${ac_dD}
+${ac_dA}HAVE_STDINT_H${ac_dB}HAVE_STDINT_H${ac_dC}1${ac_dD}
+${ac_dA}HAVE_UNISTD_H${ac_dB}HAVE_UNISTD_H${ac_dC}1${ac_dD}
+${ac_dA}HAVE_STRING_H${ac_dB}HAVE_STRING_H${ac_dC}1${ac_dD}
+${ac_dA}HAVE_STRINGS_H${ac_dB}HAVE_STRINGS_H${ac_dC}1${ac_dD}
+${ac_dA}HAVE_NCURSES_H${ac_dB}HAVE_NCURSES_H${ac_dC}1${ac_dD}
+${ac_dA}HAVE_CURSES_H${ac_dB}HAVE_CURSES_H${ac_dC}1${ac_dD}
+${ac_dA}PRESET_MENU_STRING${ac_dB}PRESET_MENU_STRING${ac_dC}""${ac_dD}
+CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+
+  fi # grep
+
+  # Handle all the #undef templates
+  cat >$tmp/undefs.sed <<CEOF
+/^[	 ]*#[	 ]*undef/!b
+t clr
+: clr
+${ac_uA}PACKAGE_NAME${ac_uB}PACKAGE_NAME${ac_uC}"GRUB"${ac_uD}
+${ac_uA}PACKAGE_TARNAME${ac_uB}PACKAGE_TARNAME${ac_uC}"grub"${ac_uD}
+${ac_uA}PACKAGE_VERSION${ac_uB}PACKAGE_VERSION${ac_uC}"0.97"${ac_uD}
+${ac_uA}PACKAGE_STRING${ac_uB}PACKAGE_STRING${ac_uC}"GRUB 0.97"${ac_uD}
+${ac_uA}PACKAGE_BUGREPORT${ac_uB}PACKAGE_BUGREPORT${ac_uC}"bug-grub@gnu.org"${ac_uD}
+${ac_uA}PACKAGE${ac_uB}PACKAGE${ac_uC}"grub"${ac_uD}
+${ac_uA}VERSION${ac_uB}VERSION${ac_uC}"0.97"${ac_uD}
+${ac_uA}ADDR32${ac_uB}ADDR32${ac_uC}addr32${ac_uD}
+${ac_uA}DATA32${ac_uB}DATA32${ac_uC}data32${ac_uD}
+${ac_uA}HAVE_USCORE_START_SYMBOL${ac_uB}HAVE_USCORE_START_SYMBOL${ac_uC}1${ac_uD}
+${ac_uA}HAVE_USCORE_USCORE_BSS_START_SYMBOL${ac_uB}HAVE_USCORE_USCORE_BSS_START_SYMBOL${ac_uC}1${ac_uD}
+${ac_uA}HAVE_USCORE_EDATA_SYMBOL${ac_uB}HAVE_USCORE_EDATA_SYMBOL${ac_uC}1${ac_uD}
+${ac_uA}HAVE_EDATA_SYMBOL${ac_uB}HAVE_EDATA_SYMBOL${ac_uC}1${ac_uD}
+${ac_uA}HAVE_END_SYMBOL${ac_uB}HAVE_END_SYMBOL${ac_uC}1${ac_uD}
+${ac_uA}HAVE_USCORE_END_SYMBOL${ac_uB}HAVE_USCORE_END_SYMBOL${ac_uC}1${ac_uD}
+${ac_uA}HAVE_LIBCURSES${ac_uB}HAVE_LIBCURSES${ac_uC}1${ac_uD}
+${ac_uA}STDC_HEADERS${ac_uB}STDC_HEADERS${ac_uC}1${ac_uD}
+${ac_uA}HAVE_SYS_TYPES_H${ac_uB}HAVE_SYS_TYPES_H${ac_uC}1${ac_uD}
+${ac_uA}HAVE_SYS_STAT_H${ac_uB}HAVE_SYS_STAT_H${ac_uC}1${ac_uD}
+${ac_uA}HAVE_STDLIB_H${ac_uB}HAVE_STDLIB_H${ac_uC}1${ac_uD}
+${ac_uA}HAVE_STRING_H${ac_uB}HAVE_STRING_H${ac_uC}1${ac_uD}
+${ac_uA}HAVE_MEMORY_H${ac_uB}HAVE_MEMORY_H${ac_uC}1${ac_uD}
+${ac_uA}HAVE_STRINGS_H${ac_uB}HAVE_STRINGS_H${ac_uC}1${ac_uD}
+${ac_uA}HAVE_INTTYPES_H${ac_uB}HAVE_INTTYPES_H${ac_uC}1${ac_uD}
+${ac_uA}HAVE_STDINT_H${ac_uB}HAVE_STDINT_H${ac_uC}1${ac_uD}
+${ac_uA}HAVE_UNISTD_H${ac_uB}HAVE_UNISTD_H${ac_uC}1${ac_uD}
+${ac_uA}HAVE_STRING_H${ac_uB}HAVE_STRING_H${ac_uC}1${ac_uD}
+${ac_uA}HAVE_STRINGS_H${ac_uB}HAVE_STRINGS_H${ac_uC}1${ac_uD}
+${ac_uA}HAVE_NCURSES_H${ac_uB}HAVE_NCURSES_H${ac_uC}1${ac_uD}
+${ac_uA}HAVE_CURSES_H${ac_uB}HAVE_CURSES_H${ac_uC}1${ac_uD}
+${ac_uA}PRESET_MENU_STRING${ac_uB}PRESET_MENU_STRING${ac_uC}""${ac_uD}
+s,^[	 ]*#[	 ]*undef[	 ][	 ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+# Compute $ac_file's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $ac_file | $ac_file:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null ||
+$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X$ac_file : 'X\(//\)[^/]' \| \
+	 X$ac_file : 'X\(//\)$' \| \
+	 X$ac_file : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X$ac_file |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`/stamp-h$_am_stamp_count
+done
+
+#
+# CONFIG_COMMANDS section.
+#
+for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
+  ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
+  ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
+  ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
+$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_dest" : 'X\(//\)[^/]' \| \
+	 X"$ac_dest" : 'X\(//\)$' \| \
+	 X"$ac_dest" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_dest" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
+echo "$as_me: executing $ac_dest commands" >&6;}
+  case $ac_dest in
+    depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
+  # Strip MF so we end up with the name of the file.
+  mf=`echo "$mf" | sed -e 's/:.*$//'`
+  # Check whether this is an Automake generated Makefile or not.
+  # We used to match only the files named `Makefile.in', but
+  # some people rename them; so instead we look at the file content.
+  # Grep'ing the first line is not enough: some people post-process
+  # each Makefile.in and add a new line on top of each file to say so.
+  # So let's grep whole file.
+  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+    dirpart=`(dirname "$mf") 2>/dev/null ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$mf" : 'X\(//\)[^/]' \| \
+	 X"$mf" : 'X\(//\)$' \| \
+	 X"$mf" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  else
+    continue
+  fi
+  # Extract the definition of DEPDIR, am__include, and am__quote
+  # from the Makefile without running `make'.
+  DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+  test -z "$DEPDIR" && continue
+  am__include=`sed -n 's/^am__include = //p' < "$mf"`
+  test -z "am__include" && continue
+  am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+  # When using ansi2knr, U may be empty or an underscore; expand it
+  U=`sed -n 's/^U = //p' < "$mf"`
+  # Find all dependency output files, they are included files with
+  # $(DEPDIR) in their names.  We invoke sed twice because it is the
+  # simplest approach to changing $(DEPDIR) to its actual value in the
+  # expansion.
+  for file in `sed -n "
+    s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+       sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+    # Make sure the directory exists.
+    test -f "$dirpart/$file" && continue
+    fdir=`(dirname "$file") 2>/dev/null ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$file" : 'X\(//\)[^/]' \| \
+	 X"$file" : 'X\(//\)$' \| \
+	 X"$file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    { if $as_mkdir_p; then
+    mkdir -p $dirpart/$fdir
+  else
+    as_dir=$dirpart/$fdir
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5
+echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+    # echo "creating $dirpart/$file"
+    echo '# dummy' > "$dirpart/$file"
+  done
+done
+ ;;
+  esac
+done
+
+{ (exit 0); exit 0; }
diff --git a/config.sub b/config.sub
new file mode 100755
index 0000000..987b17d
--- /dev/null
+++ b/config.sub
@@ -0,0 +1,1566 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+timestamp='2004-11-30'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
+  kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| msp430 \
+	| ns16k | ns32k \
+	| openrisc | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \
+	| strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* \
+	| bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| msp430-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16c)
+		basic_machine=cr16c-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	or32 | or32-*)
+		basic_machine=or32-unknown
+		os=-coff
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+    c4x-* | tic4x-*)
+        os=-coff
+        ;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/configure b/configure
new file mode 100755
index 0000000..537ab89
--- /dev/null
+++ b/configure
@@ -0,0 +1,7639 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59 for GRUB 0.97.
+#
+# Report bugs to <bug-grub@gnu.org>.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME='GRUB'
+PACKAGE_TARNAME='grub'
+PACKAGE_VERSION='0.97'
+PACKAGE_STRING='GRUB 0.97'
+PACKAGE_BUGREPORT='bug-grub@gnu.org'
+
+ac_unique_file="stage2/stage2.c"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# 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_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+	      localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$0" : 'X\(//\)[^/]' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures GRUB 0.97 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+			  [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+			  [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of GRUB 0.97:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-maintainer-mode  enable make rules and dependencies not useful
+			  (and sometimes confusing) to the casual installer
+  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors
+  --disable-ext2fs        disable ext2fs support in Stage 2
+  --disable-fat           disable FAT support in Stage 2
+  --disable-ffs           disable FFS support in Stage 2
+  --disable-ufs2          disable UFS2 support in Stage 2
+  --disable-minix         disable Minix fs support in Stage 2
+  --disable-reiserfs      disable ReiserFS support in Stage 2
+  --disable-vstafs        disable VSTa FS support in Stage 2
+  --disable-jfs           disable IBM JFS support in Stage 2
+  --disable-xfs           disable SGI XFS support in Stage 2
+  --disable-iso9660       disable ISO9660 support in Stage 2
+  --disable-gunzip        disable decompression in Stage 2
+  --disable-md5-password  disable MD5 password support in Stage 2
+  --disable-packet-retransmission
+                          turn off packet retransmission
+  --enable-pci-direct     access PCI directly instead of using BIOS
+  --enable-3c509          enable 3Com509 driver
+  --enable-3c529          enable 3Com529 driver
+  --enable-3c595          enable 3Com595 driver
+  --enable-3c90x          enable 3Com90x driver
+  --enable-cs89x0         enable CS89x0 driver
+  --enable-davicom        enable Davicom driver
+  --enable-depca          enable DEPCA and EtherWORKS driver
+  --enable-eepro          enable Etherexpress Pro/10 driver
+  --enable-eepro100       enable Etherexpress Pro/100 driver
+  --enable-epic100        enable SMC 83c170 EPIC/100 driver
+  --enable-3c507          enable 3Com507 driver
+  --enable-exos205        enable EXOS205 driver
+  --enable-ni5210         enable Racal-Interlan NI5210 driver
+  --enable-lance          enable Lance PCI PCNet/32 driver
+  --enable-ne2100         enable Novell NE2100 driver
+  --enable-ni6510         enable Racal-Interlan NI6510 driver
+  --enable-natsemi        enable NatSemi DP8381x driver
+  --enable-ni5010         enable Racal-Interlan NI5010 driver
+  --enable-3c503          enable 3Com503 driver
+  --enable-ne             enable NE1000/2000 ISA driver
+  --enable-ns8390         enable NE2000 PCI driver
+  --enable-wd             enable WD8003/8013, SMC8216/8416 driver
+  --enable-otulip         enable old Tulip driver
+  --enable-rtl8139        enable Realtek 8139 driver
+  --enable-sis900         enable SIS 900 and SIS 7016 driver
+  --enable-sk-g16         enable Schneider and Koch G16 driver
+  --enable-smc9000        enable SMC9000 driver
+  --enable-tiara          enable Tiara driver
+  --enable-tulip          enable Tulip driver
+  --enable-via-rhine      enable Rhine-I/II driver
+  --enable-w89c840        enable Winbond W89c840, Compex RL100-ATX driver
+  --enable-3c503-shmem    use 3c503 shared memory mode
+  --enable-3c503-aui      use AUI by default on 3c503 cards
+  --enable-compex-rl2000-fix
+                          specify this if you have a Compex RL2000 PCI
+  --enable-smc9000-scan=LIST
+                          probe for SMC9000 I/O addresses using LIST
+  --enable-ne-scan=LIST   probe for NE base address using LIST
+  --enable-wd-default-mem=MEM
+                          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-hercules      disable hercules terminal support
+  --disable-serial        disable serial terminal support
+  --enable-serial-speed-simulation
+                          simulate the slowness of a serial device
+  --enable-preset-menu=FILE
+                          preset a menu file FILE in Stage 2
+  --enable-example-kernel
+                          build the example Multiboot kernel
+  --disable-auto-linux-mem-opt
+                          don't pass Linux mem= option automatically
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-binutils=DIR     search the directory DIR to find binutils
+  --without-curses        do not use curses
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <bug-grub@gnu.org>.
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+	   test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+GRUB configure 0.97
+generated by GNU Autoconf 2.59
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by GRUB $as_me 0.97, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+	"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=$`echo $ac_var`
+	echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+	       sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+	ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+          ac_config_headers="$ac_config_headers config.h"
+
+am__api_version="1.9"
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	    break 3
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo "$as_me:$LINENO: checking whether build environment is sane" >&5
+echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
+   if test "$*" = "X"; then
+      # -L didn't work.
+      set X `ls -t $srcdir/configure conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$*" != "X $srcdir/configure conftest.file" \
+      && test "$*" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      { { echo "$as_me:$LINENO: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" >&5
+echo "$as_me: error: ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" >&2;}
+   { (exit 1); exit 1; }; }
+   fi
+
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   { { echo "$as_me:$LINENO: error: newly created file is older than distributed files!
+Check your system clock" >&5
+echo "$as_me: error: newly created file is older than distributed files!
+Check your system clock" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+test "$program_prefix" != NONE &&
+  program_transform_name="s,^,$program_prefix,;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s,\$,$program_suffix,;$program_transform_name"
+# Double any \ or $.  echo might interpret backslashes.
+# By default was `s,x,x', remove it if useless.
+cat <<\_ACEOF >conftest.sed
+s/[\\$]/&&/g;s/;s,x,x,$//
+_ACEOF
+program_transform_name=`echo $program_transform_name | sed -f conftest.sed`
+rm conftest.sed
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5
+echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+  # We used to keeping the `.' as first argument, in order to
+  # allow $(mkdir_p) to be used without argument.  As in
+  #   $(mkdir_p) $(somedir)
+  # where $(somedir) is conditionally defined.  However this is wrong
+  # for two reasons:
+  #  1. if the package is installed by a user who cannot write `.'
+  #     make install will fail,
+  #  2. the above comment should most certainly read
+  #     $(mkdir_p) $(DESTDIR)$(somedir)
+  #     so it does not work when $(somedir) is undefined and
+  #     $(DESTDIR) is not.
+  #  To support the latter case, we have to write
+  #     test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir),
+  #  so the `.' trick is pointless.
+  mkdir_p='mkdir -p --'
+else
+  # On NextStep and OpenStep, the `mkdir' command does not
+  # recognize any option.  It will interpret all options as
+  # directories to create, and then abort because `.' already
+  # exists.
+  for d in ./-p ./--version;
+  do
+    test -d $d && rmdir $d
+  done
+  # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
+  if test -f "$ac_aux_dir/mkinstalldirs"; then
+    mkdir_p='$(mkinstalldirs)'
+  else
+    mkdir_p='$(install_sh) -d'
+  fi
+fi
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AWK+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AWK="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  echo "$as_me:$LINENO: result: $AWK" >&5
+echo "${ECHO_T}$AWK" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$AWK" && break
+done
+
+echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'`
+if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.make <<\_ACEOF
+all:
+	@echo 'ac_maketemp="$(MAKE)"'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftest.make
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+  SET_MAKE=
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+# test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" &&
+   test -f $srcdir/config.status; then
+  { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5
+echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='grub'
+ VERSION='0.97'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+install_sh=${install_sh-"$am_aux_dir/install-sh"}
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  echo "$as_me:$LINENO: result: $STRIP" >&5
+echo "${ECHO_T}$STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":"
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5
+echo "${ECHO_T}$ac_ct_STRIP" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  STRIP=$ac_ct_STRIP
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+
+# Make sure we can run config.sub.
+$ac_config_sub sun4 >/dev/null 2>&1 ||
+  { { echo "$as_me:$LINENO: error: cannot run $ac_config_sub" >&5
+echo "$as_me: error: cannot run $ac_config_sub" >&2;}
+   { (exit 1); exit 1; }; }
+
+echo "$as_me:$LINENO: checking build system type" >&5
+echo $ECHO_N "checking build system type... $ECHO_C" >&6
+if test "${ac_cv_build+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_build_alias=$build_alias
+test -z "$ac_cv_build_alias" &&
+  ac_cv_build_alias=`$ac_config_guess`
+test -z "$ac_cv_build_alias" &&
+  { { echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5
+echo "$as_me: error: cannot guess build type; you must specify one" >&2;}
+   { (exit 1); exit 1; }; }
+ac_cv_build=`$ac_config_sub $ac_cv_build_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_build_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_build_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_build" >&5
+echo "${ECHO_T}$ac_cv_build" >&6
+build=$ac_cv_build
+build_cpu=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $ac_cv_build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+echo "$as_me:$LINENO: checking host system type" >&5
+echo $ECHO_N "checking host system type... $ECHO_C" >&6
+if test "${ac_cv_host+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_host_alias=$host_alias
+test -z "$ac_cv_host_alias" &&
+  ac_cv_host_alias=$ac_cv_build_alias
+ac_cv_host=`$ac_config_sub $ac_cv_host_alias` ||
+  { { echo "$as_me:$LINENO: error: $ac_config_sub $ac_cv_host_alias failed" >&5
+echo "$as_me: error: $ac_config_sub $ac_cv_host_alias failed" >&2;}
+   { (exit 1); exit 1; }; }
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_host" >&5
+echo "${ECHO_T}$ac_cv_host" >&6
+host=$ac_cv_host
+host_cpu=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $ac_cv_host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+
+
+case "$host_cpu" in
+i[3456]86) host_cpu=i386 ;;
+x86_64) host_cpu=x86_64 ;;
+*) { { echo "$as_me:$LINENO: error: unsupported CPU type" >&5
+echo "$as_me: error: unsupported CPU type" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+
+
+
+#
+# Options
+#
+
+echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6
+    # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+  enableval="$enable_maintainer_mode"
+  USE_MAINTAINER_MODE=$enableval
+else
+  USE_MAINTAINER_MODE=no
+fi;
+  echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5
+echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6
+
+
+if test $USE_MAINTAINER_MODE = yes; then
+  MAINTAINER_MODE_TRUE=
+  MAINTAINER_MODE_FALSE='#'
+else
+  MAINTAINER_MODE_TRUE='#'
+  MAINTAINER_MODE_FALSE=
+fi
+
+  MAINT=$MAINTAINER_MODE_TRUE
+
+
+if test "x$enable_maintainer_mode" = xyes; then
+  # Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_PERL+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $PERL in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PERL="$PERL" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+PERL=$ac_cv_path_PERL
+
+if test -n "$PERL"; then
+  echo "$as_me:$LINENO: result: $PERL" >&5
+echo "${ECHO_T}$PERL" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  if test -z "$PERL"; then
+    { { echo "$as_me:$LINENO: error: perl not found" >&5
+echo "$as_me: error: perl not found" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+fi
+
+# This should be checked before AC_PROG_CC
+if test "x$CFLAGS" = x; then
+  default_CFLAGS=yes
+fi
+
+if test "x$host_cpu" = xx86_64; then
+  CFLAGS="-m32 $CFLAGS"
+fi
+
+#
+# Programs
+#
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+	;;
+    conftest.$ac_ext )
+	# This is the source file.
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	# FIXME: I believe we export ac_cv_exeext for Libtool,
+	# but it would be cool to find out if it's true.  Does anybody
+	# maintain Libtool? --akim.
+	export ac_cv_exeext
+	break;;
+    * )
+	break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  export ac_cv_exeext
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX 10.20 and later	-Ae
+# HP-UX older versions	-Aa -D_HPUX_SOURCE
+# SVR4			-Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+DEPDIR="${am__leading_dot}deps"
+
+          ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo done
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5
+echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# We grep out `Entering directory' and `Leaving directory'
+# messages which can occur if `w' ends up in MAKEFLAGS.
+# In particular we don't look at `^make:' because GNU make might
+# be invoked under some other name (usually "gmake"), in which
+# case it prints its new name instead of `make'.
+if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
+   am__include=include
+   am__quote=
+   _am_result=GNU
+fi
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
+      am__include=.include
+      am__quote="\""
+      _am_result=BSD
+   fi
+fi
+
+
+echo "$as_me:$LINENO: result: $_am_result" >&5
+echo "${ECHO_T}$_am_result" >&6
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then
+  enableval="$enable_dependency_tracking"
+
+fi;
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+
+
+if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+
+
+depcc="$CC"   am_compiler_list=
+
+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    case $depmode in
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    none) break ;;
+    esac
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.
+    if depmode=$depmode \
+       source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+
+
+if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+# We need this for older versions of Autoconf.
+
+depcc="$CC"   am_compiler_list=
+
+echo "$as_me:$LINENO: checking dependency style of $depcc" >&5
+echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    case $depmode in
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    none) break ;;
+    esac
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.
+    if depmode=$depmode \
+       source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5
+echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+
+
+if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+
+CCAS="$CC"
+
+
+
+# Check whether --with-binutils or --without-binutils was given.
+if test "${with_binutils+set}" = set; then
+  withval="$with_binutils"
+
+fi;
+
+if test "x$with_binutils" != x; then
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $RANLIB in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_RANLIB="$RANLIB" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_dummy=""$with_binutils:$PATH""
+for as_dir in $as_dummy
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_RANLIB="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_path_RANLIB" && ac_cv_path_RANLIB=":"
+  ;;
+esac
+fi
+RANLIB=$ac_cv_path_RANLIB
+
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+else
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+fi
+
+# optimization flags
+if test "x$ac_cv_c_compiler_gnu" = xyes; then
+  if test "x$default_CFLAGS" = xyes; then
+    # Autoconf may set CFLAGS to -O2 and/or -g. So eliminate them.
+    CFLAGS="`echo $CFLAGS | sed -e 's/-g//g' -e 's/-O[0-9]//g'` -g"
+    # If the user specify the directory for binutils, add the option `-B'.
+    if test "x$with_binutils" != x; then
+      CFLAGS="-B$with_binutils/ $CFLAGS"
+    fi
+    STAGE1_CFLAGS="-O2"
+    GRUB_CFLAGS="-O2"
+
+echo "$as_me:$LINENO: checking whether optimization for size works" >&5
+echo $ECHO_N "checking whether optimization for size works... $ECHO_C" >&6
+if test "${size_flag+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+      saved_CFLAGS=$CFLAGS
+      CFLAGS="-Os -g"
+      cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  size_flag=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+size_flag=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+      CFLAGS=$saved_CFLAGS
+
+fi
+echo "$as_me:$LINENO: result: $size_flag" >&5
+echo "${ECHO_T}$size_flag" >&6
+    if test "x$size_flag" = xyes; then
+      STAGE2_CFLAGS="-Os"
+    else
+      STAGE2_CFLAGS="-O2 -fno-strength-reduce -fno-unroll-loops"
+    fi
+    # OpenBSD has a GCC extension for protecting applications from
+    # stack smashing attacks, but GRUB doesn't want this feature.
+    echo "$as_me:$LINENO: checking whether gcc has -fno-stack-protector" >&5
+echo $ECHO_N "checking whether gcc has -fno-stack-protector... $ECHO_C" >&6
+if test "${no_stack_protector_flag+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+      saved_CFLAGS=$CFLAGS
+      CFLAGS="-fno-stack-protector"
+      cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  no_stack_protector_flag=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+no_stack_protector_flag=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+      CFLAGS=$saved_CFLAGS
+
+fi
+echo "$as_me:$LINENO: result: $no_stack_protector_flag" >&5
+echo "${ECHO_T}$no_stack_protector_flag" >&6
+    if test "x$no_stack_protector_flag" = xyes; then
+      STAGE2_CFLAGS="$STAGE2_CFLAGS -fno-stack-protector"
+    fi
+  fi
+fi
+
+
+
+
+
+# Enforce coding standards.
+CPPFLAGS="$CPPFLAGS -Wall -Wmissing-prototypes -Wunused -Wshadow"
+CPPFLAGS="$CPPFLAGS -Wpointer-arith"
+
+echo "$as_me:$LINENO: checking whether -Wundef works" >&5
+echo $ECHO_N "checking whether -Wundef works... $ECHO_C" >&6
+if test "${undef_flag+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+  saved_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="-Wundef"
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  undef_flag=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+undef_flag=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  CPPFLAGS="$saved_CPPFLAGS"
+
+fi
+echo "$as_me:$LINENO: result: $undef_flag" >&5
+echo "${ECHO_T}$undef_flag" >&6
+
+# The options `-falign-*' are supported by gcc 3.0 or later.
+# Probably it is sufficient to only check for -falign-loops.
+echo "$as_me:$LINENO: checking whether -falign-loops works" >&5
+echo $ECHO_N "checking whether -falign-loops works... $ECHO_C" >&6
+if test "${falign_loop_flag+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+  saved_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="-falign-loops=1"
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  falign_loop_flag=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+falign_loop_flag=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  CPPFLAGS="$saved_CPPFLAGS"
+
+fi
+echo "$as_me:$LINENO: result: $falign_loop_flag" >&5
+echo "${ECHO_T}$falign_loop_flag" >&6
+
+# Force no alignment to save space.
+if test "x$falign_loop_flag" = xyes; then
+  CPPFLAGS="$CPPFLAGS -falign-jumps=1 -falign-loops=1 -falign-functions=1"
+else
+  CPPFLAGS="$CPPFLAGS -malign-jumps=1 -malign-loops=1 -malign-functions=1"
+fi
+
+if test "x$undef_flag" = xyes; then
+  CPPFLAGS="$CPPFLAGS -Wundef"
+fi
+
+if test "x$with_binutils" != x; then
+  # Extract the first word of "objcopy", so it can be a program name with args.
+set dummy objcopy; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_path_OBJCOPY+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $OBJCOPY in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_OBJCOPY="$OBJCOPY" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_dummy=""$with_binutils:$PATH""
+for as_dir in $as_dummy
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_path_OBJCOPY="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  ;;
+esac
+fi
+OBJCOPY=$ac_cv_path_OBJCOPY
+
+if test -n "$OBJCOPY"; then
+  echo "$as_me:$LINENO: result: $OBJCOPY" >&5
+echo "${ECHO_T}$OBJCOPY" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+else
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objcopy", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objcopy; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_OBJCOPY+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$OBJCOPY"; then
+  ac_cv_prog_OBJCOPY="$OBJCOPY" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_OBJCOPY="${ac_tool_prefix}objcopy"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+OBJCOPY=$ac_cv_prog_OBJCOPY
+if test -n "$OBJCOPY"; then
+  echo "$as_me:$LINENO: result: $OBJCOPY" >&5
+echo "${ECHO_T}$OBJCOPY" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_OBJCOPY"; then
+  ac_ct_OBJCOPY=$OBJCOPY
+  # Extract the first word of "objcopy", so it can be a program name with args.
+set dummy objcopy; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_OBJCOPY+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_OBJCOPY"; then
+  ac_cv_prog_ac_ct_OBJCOPY="$ac_ct_OBJCOPY" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_OBJCOPY="objcopy"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_OBJCOPY=$ac_cv_prog_ac_ct_OBJCOPY
+if test -n "$ac_ct_OBJCOPY"; then
+  echo "$as_me:$LINENO: result: $ac_ct_OBJCOPY" >&5
+echo "${ECHO_T}$ac_ct_OBJCOPY" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  OBJCOPY=$ac_ct_OBJCOPY
+else
+  OBJCOPY="$ac_cv_prog_OBJCOPY"
+fi
+
+fi
+
+# Defined in acinclude.m4.
+
+echo "$as_me:$LINENO: checking if C symbols get an underscore after compilation" >&5
+echo $ECHO_N "checking if C symbols get an underscore after compilation... $ECHO_C" >&6
+if test "${grub_cv_asm_uscore+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat > conftest.c <<\EOF
+int
+func (int *list)
+{
+  *list = 0;
+  return *list;
+}
+EOF
+
+if { ac_try='${CC-cc} ${CFLAGS} -S conftest.c'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } && test -s conftest.s; then
+  true
+else
+  { { echo "$as_me:$LINENO: error: ${CC-cc} failed to produce assembly code" >&5
+echo "$as_me: error: ${CC-cc} failed to produce assembly code" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+if grep _func conftest.s >/dev/null 2>&1; then
+  grub_cv_asm_uscore=yes
+else
+  grub_cv_asm_uscore=no
+fi
+
+rm -f conftest*
+fi
+
+
+if test "x$grub_cv_asm_uscore" = xyes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_ASM_USCORE $grub_cv_asm_uscore
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: result: $grub_cv_asm_uscore" >&5
+echo "${ECHO_T}$grub_cv_asm_uscore" >&6
+
+echo "$as_me:$LINENO: checking whether ${OBJCOPY} works for absolute addresses" >&5
+echo $ECHO_N "checking whether ${OBJCOPY} works for absolute addresses... $ECHO_C" >&6
+if test "${grub_cv_prog_objcopy_absolute+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat > conftest.c <<\EOF
+void
+cmain (void)
+{
+   *((int *) 0x1000) = 2;
+}
+EOF
+
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && test -s conftest.o; then :
+else
+  { { echo "$as_me:$LINENO: error: ${CC-cc} cannot compile C source code" >&5
+echo "$as_me: error: ${CC-cc} cannot compile C source code" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+grub_cv_prog_objcopy_absolute=yes
+for link_addr in 2000 8000 7C00; do
+  if { ac_try='${CC-cc} ${CFLAGS} -nostdlib -Wl,-N -Wl,-Ttext -Wl,$link_addr conftest.o -o conftest.exec'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then :
+  else
+    { { echo "$as_me:$LINENO: error: ${CC-cc} cannot link at address $link_addr" >&5
+echo "$as_me: error: ${CC-cc} cannot link at address $link_addr" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  if { ac_try='${OBJCOPY-objcopy} -O binary conftest.exec conftest'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then :
+  else
+    { { echo "$as_me:$LINENO: error: ${OBJCOPY-objcopy} cannot create binary files" >&5
+echo "$as_me: error: ${OBJCOPY-objcopy} cannot create binary files" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  if test ! -f conftest.old || { ac_try='cmp -s conftest.old conftest'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    mv -f conftest conftest.old
+  else
+    grub_cv_prog_objcopy_absolute=no
+    break
+  fi
+done
+rm -f conftest*
+fi
+
+echo "$as_me:$LINENO: result: $grub_cv_prog_objcopy_absolute" >&5
+echo "${ECHO_T}$grub_cv_prog_objcopy_absolute" >&6
+if test "x$grub_cv_prog_objcopy_absolute" != xyes; then
+  { { echo "$as_me:$LINENO: error: GRUB requires a working absolute objcopy; upgrade your binutils" >&5
+echo "$as_me: error: GRUB requires a working absolute objcopy; upgrade your binutils" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+echo "$as_me:$LINENO: checking whether addr32 must be in the same line as the instruction" >&5
+echo $ECHO_N "checking whether addr32 must be in the same line as the instruction... $ECHO_C" >&6
+if test "${grub_cv_asm_prefix_requirement+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat > conftest.s <<\EOF
+	.code16
+l1:	addr32	movb	%al, l1
+EOF
+
+if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } && test -s conftest.o; then
+  grub_cv_asm_prefix_requirement=yes
+else
+  grub_cv_asm_prefix_requirement=no
+fi
+
+rm -f conftest*
+fi
+
+
+if test "x$grub_cv_asm_prefix_requirement" = xyes; then
+  grub_tmp_addr32="addr32"
+  grub_tmp_data32="data32"
+else
+  grub_tmp_addr32="addr32;"
+  grub_tmp_data32="data32;"
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define ADDR32 $grub_tmp_addr32
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define DATA32 $grub_tmp_data32
+_ACEOF
+
+
+echo "$as_me:$LINENO: result: $grub_cv_asm_prefix_requirement" >&5
+echo "${ECHO_T}$grub_cv_asm_prefix_requirement" >&6
+
+
+
+echo "$as_me:$LINENO: checking for .code16 addr32 assembler support" >&5
+echo $ECHO_N "checking for .code16 addr32 assembler support... $ECHO_C" >&6
+if test "${grub_cv_asm_addr32+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat > conftest.s.in <<\EOF
+	.code16
+l1:	@ADDR32@	movb	%al, l1
+EOF
+
+if test "x$grub_cv_asm_prefix_requirement" = xyes; then
+  sed -e s/@ADDR32@/addr32/ < conftest.s.in > conftest.s
+else
+  sed -e s/@ADDR32@/addr32\;/ < conftest.s.in > conftest.s
+fi
+
+if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } && test -s conftest.o; then
+  grub_cv_asm_addr32=yes
+else
+  grub_cv_asm_addr32=no
+fi
+
+rm -f conftest*
+fi
+
+
+echo "$as_me:$LINENO: result: $grub_cv_asm_addr32" >&5
+echo "${ECHO_T}$grub_cv_asm_addr32" >&6
+if test "x$grub_cv_asm_addr32" != xyes; then
+  { { echo "$as_me:$LINENO: error: GRUB requires GAS .code16 addr32 support; upgrade your binutils" >&5
+echo "$as_me: error: GRUB requires GAS .code16 addr32 support; upgrade your binutils" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+echo "$as_me:$LINENO: checking whether an absolute indirect call/jump must not be prefixed with an asterisk" >&5
+echo $ECHO_N "checking whether an absolute indirect call/jump must not be prefixed with an asterisk... $ECHO_C" >&6
+if test "${grub_cv_asm_absolute_without_asterisk+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat > conftest.s <<\EOF
+	lcall	*(offset)
+offset:
+	.long	0
+	.word	0
+EOF
+
+if { ac_try='${CC-cc} ${CFLAGS} -c conftest.s'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } && test -s conftest.o; then
+  grub_cv_asm_absolute_without_asterisk=no
+else
+  grub_cv_asm_absolute_without_asterisk=yes
+fi
+
+rm -f conftest*
+fi
+
+
+if test "x$grub_cv_asm_absolute_without_asterisk" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define ABSOLUTE_WITHOUT_ASTERISK 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: result: $grub_cv_asm_absolute_without_asterisk" >&5
+echo "${ECHO_T}$grub_cv_asm_absolute_without_asterisk" >&6
+
+
+echo "$as_me:$LINENO: checking if start is defined by the compiler" >&5
+echo $ECHO_N "checking if start is defined by the compiler... $ECHO_C" >&6
+if test "${grub_cv_check_start_symbol+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+asm ("incl start")
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  grub_cv_check_start_symbol=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+grub_cv_check_start_symbol=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+
+
+if test "x$grub_cv_check_start_symbol" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_START_SYMBOL 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: result: $grub_cv_check_start_symbol" >&5
+echo "${ECHO_T}$grub_cv_check_start_symbol" >&6
+
+
+echo "$as_me:$LINENO: checking if _start is defined by the compiler" >&5
+echo $ECHO_N "checking if _start is defined by the compiler... $ECHO_C" >&6
+if test "${grub_cv_check_uscore_start_symbol+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+asm ("incl _start")
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  grub_cv_check_uscore_start_symbol=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+grub_cv_check_uscore_start_symbol=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+
+
+if test "x$grub_cv_check_uscore_start_symbol" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_USCORE_START_SYMBOL 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: result: $grub_cv_check_uscore_start_symbol" >&5
+echo "${ECHO_T}$grub_cv_check_uscore_start_symbol" >&6
+
+if test "x$grub_cv_check_start_symbol" != "xyes" \
+	-a "x$grub_cv_check_uscore_start_symbol" != "xyes"; then
+  { { echo "$as_me:$LINENO: error: Neither start nor _start is defined" >&5
+echo "$as_me: error: Neither start nor _start is defined" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+echo "$as_me:$LINENO: checking if __bss_start is defined by the compiler" >&5
+echo $ECHO_N "checking if __bss_start is defined by the compiler... $ECHO_C" >&6
+if test "${grub_cv_check_uscore_uscore_bss_start_symbol+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+asm ("incl __bss_start")
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  grub_cv_check_uscore_uscore_bss_start_symbol=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+grub_cv_check_uscore_uscore_bss_start_symbol=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+
+
+if test "x$grub_cv_check_uscore_uscore_bss_start_symbol" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_USCORE_USCORE_BSS_START_SYMBOL 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: result: $grub_cv_check_uscore_uscore_bss_start_symbol" >&5
+echo "${ECHO_T}$grub_cv_check_uscore_uscore_bss_start_symbol" >&6
+
+
+echo "$as_me:$LINENO: checking if _edata is defined by the compiler" >&5
+echo $ECHO_N "checking if _edata is defined by the compiler... $ECHO_C" >&6
+if test "${grub_cv_check_uscore_edata_symbol+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+asm ("incl _edata")
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  grub_cv_check_uscore_edata_symbol=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+grub_cv_check_uscore_edata_symbol=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+
+
+if test "x$grub_cv_check_uscore_edata_symbol" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_USCORE_EDATA_SYMBOL 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: result: $grub_cv_check_uscore_edata_symbol" >&5
+echo "${ECHO_T}$grub_cv_check_uscore_edata_symbol" >&6
+
+
+echo "$as_me:$LINENO: checking if edata is defined by the compiler" >&5
+echo $ECHO_N "checking if edata is defined by the compiler... $ECHO_C" >&6
+if test "${grub_cv_check_edata_symbol+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+asm ("incl edata")
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  grub_cv_check_edata_symbol=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+grub_cv_check_edata_symbol=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+
+
+if test "x$grub_cv_check_edata_symbol" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_EDATA_SYMBOL 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: result: $grub_cv_check_edata_symbol" >&5
+echo "${ECHO_T}$grub_cv_check_edata_symbol" >&6
+
+if test "x$grub_cv_check_uscore_uscore_bss_start_symbol" != "xyes" \
+	-a "x$grub_cv_check_uscore_edata_symbol" != "xyes" \
+	-a "x$grub_cv_check_edata_symbol" != "xyes"; then
+  { { echo "$as_me:$LINENO: error: None of __bss_start, _edata, edata defined" >&5
+echo "$as_me: error: None of __bss_start, _edata, edata defined" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+echo "$as_me:$LINENO: checking if end is defined by the compiler" >&5
+echo $ECHO_N "checking if end is defined by the compiler... $ECHO_C" >&6
+if test "${grub_cv_check_end_symbol+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+asm ("incl end")
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  grub_cv_check_end_symbol=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+grub_cv_check_end_symbol=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+
+
+if test "x$grub_cv_check_end_symbol" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_END_SYMBOL 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: result: $grub_cv_check_end_symbol" >&5
+echo "${ECHO_T}$grub_cv_check_end_symbol" >&6
+
+
+echo "$as_me:$LINENO: checking if _end is defined by the compiler" >&5
+echo $ECHO_N "checking if _end is defined by the compiler... $ECHO_C" >&6
+if test "${grub_cv_check_uscore_end_symbol+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+asm ("incl _end")
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  grub_cv_check_uscore_end_symbol=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+grub_cv_check_uscore_end_symbol=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+
+
+if test "x$grub_cv_check_uscore_end_symbol" = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_USCORE_END_SYMBOL 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: result: $grub_cv_check_uscore_end_symbol" >&5
+echo "${ECHO_T}$grub_cv_check_uscore_end_symbol" >&6
+
+if test "x$grub_cv_check_end_symbol" != "xyes" \
+	-a "x$grub_cv_check_uscore_end_symbol" != "xyes"; then
+  { { echo "$as_me:$LINENO: error: Neither end nor _end is defined" >&5
+echo "$as_me: error: Neither end nor _end is defined" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+# Check for curses libraries.
+
+# Check whether --with-curses or --without-curses was given.
+if test "${with_curses+set}" = set; then
+  withval="$with_curses"
+
+fi;
+
+# Get the filename or the whole disk and open it.
+# Known to work on NetBSD.
+echo "$as_me:$LINENO: checking for opendisk in -lutil" >&5
+echo $ECHO_N "checking for opendisk in -lutil... $ECHO_C" >&6
+if test "${ac_cv_lib_util_opendisk+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lutil  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char opendisk ();
+int
+main ()
+{
+opendisk ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_util_opendisk=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_util_opendisk=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_util_opendisk" >&5
+echo "${ECHO_T}$ac_cv_lib_util_opendisk" >&6
+if test $ac_cv_lib_util_opendisk = yes; then
+  GRUB_LIBS="$GRUB_LIBS -lutil"
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_OPENDISK 1
+_ACEOF
+
+fi
+
+
+# Unless the user specify --without-curses, check for curses.
+if test "x$with_curses" != "xno"; then
+  echo "$as_me:$LINENO: checking for wgetch in -lncurses" >&5
+echo $ECHO_N "checking for wgetch in -lncurses... $ECHO_C" >&6
+if test "${ac_cv_lib_ncurses_wgetch+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lncurses  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char wgetch ();
+int
+main ()
+{
+wgetch ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_ncurses_wgetch=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_ncurses_wgetch=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_ncurses_wgetch" >&5
+echo "${ECHO_T}$ac_cv_lib_ncurses_wgetch" >&6
+if test $ac_cv_lib_ncurses_wgetch = yes; then
+  GRUB_LIBS="$GRUB_LIBS -lncurses"
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBCURSES 1
+_ACEOF
+
+else
+  echo "$as_me:$LINENO: checking for wgetch in -lcurses" >&5
+echo $ECHO_N "checking for wgetch in -lcurses... $ECHO_C" >&6
+if test "${ac_cv_lib_curses_wgetch+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcurses  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char wgetch ();
+int
+main ()
+{
+wgetch ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_curses_wgetch=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_curses_wgetch=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_curses_wgetch" >&5
+echo "${ECHO_T}$ac_cv_lib_curses_wgetch" >&6
+if test $ac_cv_lib_curses_wgetch = yes; then
+  GRUB_LIBS="$GRUB_LIBS -lcurses"
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBCURSES 1
+_ACEOF
+
+fi
+
+fi
+
+fi
+
+
+
+# Check for headers.
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+
+
+for ac_header in string.h strings.h ncurses/curses.h ncurses.h curses.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to bug-grub@gnu.org ##
+## ------------------------------- ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+# Check for user options.
+
+# filesystems support.
+# Check whether --enable-ext2fs or --disable-ext2fs was given.
+if test "${enable_ext2fs+set}" = set; then
+  enableval="$enable_ext2fs"
+
+fi;
+
+if test x"$enable_ext2fs" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_EXT2FS=1"
+fi
+
+# Check whether --enable-fat or --disable-fat was given.
+if test "${enable_fat+set}" = set; then
+  enableval="$enable_fat"
+
+fi;
+
+if test x"$enable_fat" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_FAT=1"
+fi
+
+# Check whether --enable-ffs or --disable-ffs was given.
+if test "${enable_ffs+set}" = set; then
+  enableval="$enable_ffs"
+
+fi;
+
+if test x"$enable_ffs" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_FFS=1"
+fi
+
+# Check whether --enable-ufs2 or --disable-ufs2 was given.
+if test "${enable_ufs2+set}" = set; then
+  enableval="$enable_ufs2"
+
+fi;
+
+if test x"$enable_ufs2" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_UFS2=1"
+fi
+
+# Check whether --enable-minix or --disable-minix was given.
+if test "${enable_minix+set}" = set; then
+  enableval="$enable_minix"
+
+fi;
+
+if test x"$enable_minix" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_MINIX=1"
+fi
+
+# Check whether --enable-reiserfs or --disable-reiserfs was given.
+if test "${enable_reiserfs+set}" = set; then
+  enableval="$enable_reiserfs"
+
+fi;
+
+if test x"$enable_reiserfs" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_REISERFS=1"
+fi
+
+# Check whether --enable-vstafs or --disable-vstafs was given.
+if test "${enable_vstafs+set}" = set; then
+  enableval="$enable_vstafs"
+
+fi;
+
+if test x"$enable_vstafs" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_VSTAFS=1"
+fi
+
+# Check whether --enable-jfs or --disable-jfs was given.
+if test "${enable_jfs+set}" = set; then
+  enableval="$enable_jfs"
+
+fi;
+
+if test x"$enable_jfs" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_JFS=1"
+fi
+
+# Check whether --enable-xfs or --disable-xfs was given.
+if test "${enable_xfs+set}" = set; then
+  enableval="$enable_xfs"
+
+fi;
+
+if test x"$enable_xfs" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_XFS=1"
+fi
+
+# Check whether --enable-iso9660 or --disable-iso9660 was given.
+if test "${enable_iso9660+set}" = set; then
+  enableval="$enable_iso9660"
+
+fi;
+
+if test x"$enable_iso9660" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_ISO9660=1"
+fi
+
+
+# Check whether --enable-gunzip or --disable-gunzip was given.
+if test "${enable_gunzip+set}" = set; then
+  enableval="$enable_gunzip"
+
+fi;
+
+if test x"$enable_gunzip" = xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DNO_DECOMPRESSION=1"
+fi
+
+# Check whether --enable-md5-password or --disable-md5-password was given.
+if test "${enable_md5_password+set}" = set; then
+  enableval="$enable_md5_password"
+
+fi;
+if test "x$enable_md5_password" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DUSE_MD5_PASSWORDS=1"
+fi
+
+# Check whether --enable-packet-retransmission or --disable-packet-retransmission was given.
+if test "${enable_packet_retransmission+set}" = set; then
+  enableval="$enable_packet_retransmission"
+
+fi;
+if test "x$enable_packet_retransmission" != xno; then
+  NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCONGESTED=1"
+fi
+
+# Check whether --enable-pci-direct or --disable-pci-direct was given.
+if test "${enable_pci_direct+set}" = set; then
+  enableval="$enable_pci_direct"
+
+fi;
+if test "x$enable_pci_direct" = xyes; then
+  NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCONFIG_PCI_DIRECT=1"
+fi
+
+# Check whether --enable-3c509 or --disable-3c509 was given.
+if test "${enable_3c509+set}" = set; then
+  enableval="$enable_3c509"
+
+fi;
+if test "x$enable_3c509" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C509"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c509.o"
+fi
+
+# Check whether --enable-3c529 or --disable-3c529 was given.
+if test "${enable_3c529+set}" = set; then
+  enableval="$enable_3c529"
+
+fi;
+if test "x$enable_3c529" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C529=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c529.o"
+fi
+
+# Check whether --enable-3c595 or --disable-3c595 was given.
+if test "${enable_3c595+set}" = set; then
+  enableval="$enable_3c595"
+
+fi;
+if test "x$enable_3c595" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C595=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c595.o"
+fi
+
+# Check whether --enable-3c90x or --disable-3c90x was given.
+if test "${enable_3c90x+set}" = set; then
+  enableval="$enable_3c90x"
+
+fi;
+if test "x$enable_3c90x" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C90X=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c90x.o"
+fi
+
+# Check whether --enable-cs89x0 or --disable-cs89x0 was given.
+if test "${enable_cs89x0+set}" = set; then
+  enableval="$enable_cs89x0"
+
+fi;
+if test "x$enable_cs89x0" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_CS89X0=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS cs89x0.o"
+fi
+
+# Check whether --enable-davicom or --disable-davicom was given.
+if test "${enable_davicom+set}" = set; then
+  enableval="$enable_davicom"
+
+fi;
+if test "x$enable_davicom" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_DAVICOM=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS davicom.o"
+fi
+
+# Check whether --enable-depca or --disable-depca was given.
+if test "${enable_depca+set}" = set; then
+  enableval="$enable_depca"
+
+fi;
+if test "x$enable_depca" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_DEPCA=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS depca.o"
+fi
+
+# Check whether --enable-eepro or --disable-eepro was given.
+if test "${enable_eepro+set}" = set; then
+  enableval="$enable_eepro"
+
+fi;
+if test "x$enable_eepro" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_EEPRO=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS eepro.o"
+fi
+
+# Check whether --enable-eepro100 or --disable-eepro100 was given.
+if test "${enable_eepro100+set}" = set; then
+  enableval="$enable_eepro100"
+
+fi;
+if test "x$enable_eepro100" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_EEPRO100=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS eepro100.o"
+fi
+
+# Check whether --enable-epic100 or --disable-epic100 was given.
+if test "${enable_epic100+set}" = set; then
+  enableval="$enable_epic100"
+
+fi;
+if test "x$enable_epic100" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_EPIC100=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS epic100.o"
+fi
+
+# Check whether --enable-3c507 or --disable-3c507 was given.
+if test "${enable_3c507+set}" = set; then
+  enableval="$enable_3c507"
+
+fi;
+if test "x$enable_3c507" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C507=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c507.o"
+fi
+
+# Check whether --enable-exos205 or --disable-exos205 was given.
+if test "${enable_exos205+set}" = set; then
+  enableval="$enable_exos205"
+
+fi;
+if test "x$enable_exos205" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_EXOS205=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS exos205.o"
+fi
+
+# Check whether --enable-ni5210 or --disable-ni5210 was given.
+if test "${enable_ni5210+set}" = set; then
+  enableval="$enable_ni5210"
+
+fi;
+if test "x$enable_ni5210" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NI5210=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS ni5210.o"
+fi
+
+# Check whether --enable-lance or --disable-lance was given.
+if test "${enable_lance+set}" = set; then
+  enableval="$enable_lance"
+
+fi;
+if test "x$enable_lance" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_LANCE=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS lance.o"
+fi
+
+# Check whether --enable-ne2100 or --disable-ne2100 was given.
+if test "${enable_ne2100+set}" = set; then
+  enableval="$enable_ne2100"
+
+fi;
+if test "x$enable_ne2100" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NE2100=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS ne2100.o"
+fi
+
+# Check whether --enable-ni6510 or --disable-ni6510 was given.
+if test "${enable_ni6510+set}" = set; then
+  enableval="$enable_ni6510"
+
+fi;
+if test "x$enable_ni6510" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NI6510=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS ni6510.o"
+fi
+
+# Check whether --enable-natsemi or --disable-natsemi was given.
+if test "${enable_natsemi+set}" = set; then
+  enableval="$enable_natsemi"
+
+fi;
+if test "x$enable_natsemi" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NATSEMI=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS natsemi.o"
+fi
+
+# Check whether --enable-ni5010 or --disable-ni5010 was given.
+if test "${enable_ni5010+set}" = set; then
+  enableval="$enable_ni5010"
+
+fi;
+if test "x$enable_ni5010" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NI5010=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS ni5010.o"
+fi
+
+# Check whether --enable-3c503 or --disable-3c503 was given.
+if test "${enable_3c503+set}" = set; then
+  enableval="$enable_3c503"
+
+fi;
+if test "x$enable_3c503" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C503=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c503.o"
+fi
+
+# Check whether --enable-ne or --disable-ne was given.
+if test "${enable_ne+set}" = set; then
+  enableval="$enable_ne"
+
+fi;
+if test "x$enable_ne" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NE=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS ne.o"
+fi
+
+# Check whether --enable-ns8390 or --disable-ns8390 was given.
+if test "${enable_ns8390+set}" = set; then
+  enableval="$enable_ns8390"
+
+fi;
+if test "x$enable_ns8390" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NS8390=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS ns8390.o"
+fi
+
+# Check whether --enable-wd or --disable-wd was given.
+if test "${enable_wd+set}" = set; then
+  enableval="$enable_wd"
+
+fi;
+if test "x$enable_wd" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_WD=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS wd.o"
+fi
+
+# Check whether --enable-otulip or --disable-otulip was given.
+if test "${enable_otulip+set}" = set; then
+  enableval="$enable_otulip"
+
+fi;
+if test "x$enable_otulip" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_OTULIP=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS otulip.o"
+fi
+
+# Check whether --enable-rtl8139 or --disable-rtl8139 was given.
+if test "${enable_rtl8139+set}" = set; then
+  enableval="$enable_rtl8139"
+
+fi;
+if test "x$enable_rtl8139" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_RTL8139=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS rtl8139.o"
+fi
+
+# Check whether --enable-sis900 or --disable-sis900 was given.
+if test "${enable_sis900+set}" = set; then
+  enableval="$enable_sis900"
+
+fi;
+if test "x$enable_sis900" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_SIS900=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS sis900.o"
+fi
+
+# Check whether --enable-sk-g16 or --disable-sk-g16 was given.
+if test "${enable_sk_g16+set}" = set; then
+  enableval="$enable_sk_g16"
+
+fi;
+if test "x$enable_sk_g16" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_SK_G16=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS sk_g16.o"
+fi
+
+# Check whether --enable-smc9000 or --disable-smc9000 was given.
+if test "${enable_smc9000+set}" = set; then
+  enableval="$enable_smc9000"
+
+fi;
+if test "x$enable_smc9000" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_SMC9000=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS smc9000.o"
+fi
+
+# Check whether --enable-tiara or --disable-tiara was given.
+if test "${enable_tiara+set}" = set; then
+  enableval="$enable_tiara"
+
+fi;
+if test "x$enable_tiara" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_TIARA=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS tiara.o"
+fi
+
+# Check whether --enable-tulip or --disable-tulip was given.
+if test "${enable_tulip+set}" = set; then
+  enableval="$enable_tulip"
+
+fi;
+if test "x$enable_tulip" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_TULIP=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS tulip.o"
+fi
+
+# Check whether --enable-via-rhine or --disable-via-rhine was given.
+if test "${enable_via_rhine+set}" = set; then
+  enableval="$enable_via_rhine"
+
+fi;
+if test "x$enable_via_rhine" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_VIA_RHINE=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS via_rhine.o"
+fi
+
+# Check whether --enable-w89c840 or --disable-w89c840 was given.
+if test "${enable_w89c840+set}" = set; then
+  enableval="$enable_w89c840"
+
+fi;
+if test "x$enable_w89c840" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_W89C840=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS w89c840.o"
+fi
+
+
+
+if test "x$NET_CFLAGS" != x; then
+  NETBOOT_SUPPORT_TRUE=
+  NETBOOT_SUPPORT_FALSE='#'
+else
+  NETBOOT_SUPPORT_TRUE='#'
+  NETBOOT_SUPPORT_FALSE=
+fi
+
+if test "x$NET_CFLAGS" != x; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_TFTP=1"
+fi
+
+# Check whether --enable-3c503-shmem or --disable-3c503-shmem was given.
+if test "${enable_3c503_shmem+set}" = set; then
+  enableval="$enable_3c503_shmem"
+
+fi;
+if test "x$enable_3c503_shmem" = xyes; then
+  NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DT503_SHMEM=1"
+fi
+
+# Check whether --enable-3c503-aui or --disable-3c503-aui was given.
+if test "${enable_3c503_aui+set}" = set; then
+  enableval="$enable_3c503_aui"
+
+fi;
+if test "x$enable_3c503_aui" = xyes; then
+  NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DT503_AUI=1"
+fi
+
+# Check whether --enable-compex-rl2000-fix or --disable-compex-rl2000-fix was given.
+if test "${enable_compex_rl2000_fix+set}" = set; then
+  enableval="$enable_compex_rl2000_fix"
+
+fi;
+if test "x$enable_compex_rl2000_fix" = xyes; then
+  NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCOMPEX_RL2000_FIX=1"
+fi
+
+# Check whether --enable-smc9000-scan or --disable-smc9000-scan was given.
+if test "${enable_smc9000_scan+set}" = set; then
+  enableval="$enable_smc9000_scan"
+  NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DSMC9000_SCAN=$enable_smc9000_scan"
+fi;
+
+# Check whether --enable-ne-scan or --disable-ne-scan was given.
+if test "${enable_ne_scan+set}" = set; then
+  enableval="$enable_ne_scan"
+  NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DNE_SCAN=$enable_ne_scan"
+else
+  NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DNE_SCAN=0x280,0x300,0x320,0x340"
+fi;
+
+# Check whether --enable-wd-default-mem or --disable-wd-default-mem was given.
+if test "${enable_wd_default_mem+set}" = set; then
+  enableval="$enable_wd_default_mem"
+  NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DWD_DEFAULT_MEM=$enable_wd_default_mem"
+else
+  NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DWD_DEFAULT_MEM=0xCC000"
+fi;
+
+# Check whether --enable-cs-scan or --disable-cs-scan was given.
+if test "${enable_cs_scan+set}" = set; then
+  enableval="$enable_cs_scan"
+  NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCS_SCAN=$enable_cs_scan"
+fi;
+
+# Check whether --enable-diskless or --disable-diskless was given.
+if test "${enable_diskless+set}" = set; then
+  enableval="$enable_diskless"
+
+fi;
+
+
+if test "x$enable_diskless" = xyes; then
+  DISKLESS_SUPPORT_TRUE=
+  DISKLESS_SUPPORT_FALSE='#'
+else
+  DISKLESS_SUPPORT_TRUE='#'
+  DISKLESS_SUPPORT_FALSE=
+fi
+
+
+# Check whether --enable-hercules or --disable-hercules was given.
+if test "${enable_hercules+set}" = set; then
+  enableval="$enable_hercules"
+
+fi;
+
+
+if test "x$enable_hercules" != xno; then
+  HERCULES_SUPPORT_TRUE=
+  HERCULES_SUPPORT_FALSE='#'
+else
+  HERCULES_SUPPORT_TRUE='#'
+  HERCULES_SUPPORT_FALSE=
+fi
+
+
+# Check whether --enable-serial or --disable-serial was given.
+if test "${enable_serial+set}" = set; then
+  enableval="$enable_serial"
+
+fi;
+
+
+if test "x$enable_serial" != xno; then
+  SERIAL_SUPPORT_TRUE=
+  SERIAL_SUPPORT_FALSE='#'
+else
+  SERIAL_SUPPORT_TRUE='#'
+  SERIAL_SUPPORT_FALSE=
+fi
+
+
+# Check whether --enable-serial-speed-simulation or --disable-serial-speed-simulation was given.
+if test "${enable_serial_speed_simulation+set}" = set; then
+  enableval="$enable_serial_speed_simulation"
+
+fi;
+
+
+if test "x$enable_serial_speed_simulation" = xyes; then
+  SERIAL_SPEED_SIMULATION_TRUE=
+  SERIAL_SPEED_SIMULATION_FALSE='#'
+else
+  SERIAL_SPEED_SIMULATION_TRUE='#'
+  SERIAL_SPEED_SIMULATION_FALSE=
+fi
+
+
+# Sanity check.
+if test "x$enable_diskless" = xyes; then
+  if test "x$NET_CFLAGS" = x; then
+    { { echo "$as_me:$LINENO: error: You must enable at least one network driver" >&5
+echo "$as_me: error: You must enable at least one network driver" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+fi
+
+# Check whether --enable-preset-menu or --disable-preset-menu was given.
+if test "${enable_preset_menu+set}" = set; then
+  enableval="$enable_preset_menu"
+
+fi;
+if test "x$enable_preset_menu" = x; then
+  :
+else
+  if test -r $enable_preset_menu; then
+
+# Because early versions of GNU sed 3.x are too buggy, use a C program
+# instead of shell commands. *sigh*
+cat >conftest.c <<\EOF
+#include <stdio.h>
+
+int
+main (void)
+{
+  int c;
+
+  while ((c = getchar ()) != EOF)
+    {
+      switch (c)
+        {
+	case '\n':
+	  fputs ("\\n", stdout);
+	  break;
+	case '\r':
+	  fputs ("\\r", stdout);
+	  break;
+	case '\\':
+	  fputs ("\\\\", stdout);
+	  break;
+	case '"':
+	  fputs ("\\\"", stdout);
+	  break;
+	default:
+	  putchar (c);
+	}
+    }
+
+  return 0;
+}
+EOF
+
+if { ac_try='${CC-cc} ${CFLAGS} conftest.c -o conftest'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } && test -s conftest; then
+  grub_tmp_value=`./conftest < "$enable_preset_menu"`
+else
+  { { echo "$as_me:$LINENO: error: ${CC-cc} failed to produce an executable file" >&5
+echo "$as_me: error: ${CC-cc} failed to produce an executable file" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+cat >>confdefs.h <<_ACEOF
+#define PRESET_MENU_STRING "$grub_tmp_value"
+_ACEOF
+
+rm -f conftest*
+
+  else
+    { { echo "$as_me:$LINENO: error: Cannot read the preset menu file $enable_preset_menu" >&5
+echo "$as_me: error: Cannot read the preset menu file $enable_preset_menu" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+fi
+
+# Check whether --enable-example-kernel or --disable-example-kernel was given.
+if test "${enable_example_kernel+set}" = set; then
+  enableval="$enable_example_kernel"
+
+fi;
+
+
+if test "x$enable_example_kernel" = xyes; then
+  BUILD_EXAMPLE_KERNEL_TRUE=
+  BUILD_EXAMPLE_KERNEL_FALSE='#'
+else
+  BUILD_EXAMPLE_KERNEL_TRUE='#'
+  BUILD_EXAMPLE_KERNEL_FALSE=
+fi
+
+
+# Check whether --enable-auto-linux-mem-opt or --disable-auto-linux-mem-opt was given.
+if test "${enable_auto_linux_mem_opt+set}" = set; then
+  enableval="$enable_auto_linux_mem_opt"
+
+fi;
+if test "x$enable_auto_linux_mem_opt" = xno; then
+  :
+else
+
+cat >>confdefs.h <<\_ACEOF
+#define AUTO_LINUX_MEM_OPT 1
+_ACEOF
+
+fi
+
+
+
+
+
+
+CCASFLAGS='$(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)'
+
+
+
+                                                                                                                                  ac_config_files="$ac_config_files Makefile stage1/Makefile stage2/Makefile docs/Makefile lib/Makefile util/Makefile grub/Makefile netboot/Makefile util/grub-image util/grub-install util/grub-md5-crypt util/grub-terminfo util/grub-set-default"
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[	 ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[	 ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+	 sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${NETBOOT_SUPPORT_TRUE}" && test -z "${NETBOOT_SUPPORT_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"NETBOOT_SUPPORT\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"NETBOOT_SUPPORT\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${DISKLESS_SUPPORT_TRUE}" && test -z "${DISKLESS_SUPPORT_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"DISKLESS_SUPPORT\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"DISKLESS_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
+echo "$as_me: error: conditional \"HERCULES_SUPPORT\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${SERIAL_SUPPORT_TRUE}" && test -z "${SERIAL_SUPPORT_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"SERIAL_SUPPORT\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"SERIAL_SUPPORT\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${SERIAL_SPEED_SIMULATION_TRUE}" && test -z "${SERIAL_SPEED_SIMULATION_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"SERIAL_SPEED_SIMULATION\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"SERIAL_SPEED_SIMULATION\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${BUILD_EXAMPLE_KERNEL_TRUE}" && test -z "${BUILD_EXAMPLE_KERNEL_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"BUILD_EXAMPLE_KERNEL\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"BUILD_EXAMPLE_KERNEL\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by GRUB $as_me 0.97, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+		   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+		   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+GRUB config.status 0.97
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+#
+# INIT-COMMANDS section.
+#
+
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+_ACEOF
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "stage1/Makefile" ) CONFIG_FILES="$CONFIG_FILES stage1/Makefile" ;;
+  "stage2/Makefile" ) CONFIG_FILES="$CONFIG_FILES stage2/Makefile" ;;
+  "docs/Makefile" ) CONFIG_FILES="$CONFIG_FILES docs/Makefile" ;;
+  "lib/Makefile" ) CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;;
+  "util/Makefile" ) CONFIG_FILES="$CONFIG_FILES util/Makefile" ;;
+  "grub/Makefile" ) CONFIG_FILES="$CONFIG_FILES grub/Makefile" ;;
+  "netboot/Makefile" ) CONFIG_FILES="$CONFIG_FILES netboot/Makefile" ;;
+  "util/grub-image" ) CONFIG_FILES="$CONFIG_FILES util/grub-image" ;;
+  "util/grub-install" ) CONFIG_FILES="$CONFIG_FILES util/grub-install" ;;
+  "util/grub-md5-crypt" ) CONFIG_FILES="$CONFIG_FILES util/grub-md5-crypt" ;;
+  "util/grub-terminfo" ) CONFIG_FILES="$CONFIG_FILES util/grub-terminfo" ;;
+  "util/grub-set-default" ) CONFIG_FILES="$CONFIG_FILES util/grub-set-default" ;;
+  "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+  "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@CYGPATH_W@,$CYGPATH_W,;t t
+s,@PACKAGE@,$PACKAGE,;t t
+s,@VERSION@,$VERSION,;t t
+s,@ACLOCAL@,$ACLOCAL,;t t
+s,@AUTOCONF@,$AUTOCONF,;t t
+s,@AUTOMAKE@,$AUTOMAKE,;t t
+s,@AUTOHEADER@,$AUTOHEADER,;t t
+s,@MAKEINFO@,$MAKEINFO,;t t
+s,@install_sh@,$install_sh,;t t
+s,@STRIP@,$STRIP,;t t
+s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t
+s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t
+s,@mkdir_p@,$mkdir_p,;t t
+s,@AWK@,$AWK,;t t
+s,@SET_MAKE@,$SET_MAKE,;t t
+s,@am__leading_dot@,$am__leading_dot,;t t
+s,@AMTAR@,$AMTAR,;t t
+s,@am__tar@,$am__tar,;t t
+s,@am__untar@,$am__untar,;t t
+s,@build@,$build,;t t
+s,@build_cpu@,$build_cpu,;t t
+s,@build_vendor@,$build_vendor,;t t
+s,@build_os@,$build_os,;t t
+s,@host@,$host,;t t
+s,@host_cpu@,$host_cpu,;t t
+s,@host_vendor@,$host_vendor,;t t
+s,@host_os@,$host_os,;t t
+s,@MAINTAINER_MODE_TRUE@,$MAINTAINER_MODE_TRUE,;t t
+s,@MAINTAINER_MODE_FALSE@,$MAINTAINER_MODE_FALSE,;t t
+s,@MAINT@,$MAINT,;t t
+s,@PERL@,$PERL,;t t
+s,@CC@,$CC,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@DEPDIR@,$DEPDIR,;t t
+s,@am__include@,$am__include,;t t
+s,@am__quote@,$am__quote,;t t
+s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t
+s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t
+s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t
+s,@CCDEPMODE@,$CCDEPMODE,;t t
+s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t
+s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t
+s,@CCAS@,$CCAS,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@STAGE1_CFLAGS@,$STAGE1_CFLAGS,;t t
+s,@STAGE2_CFLAGS@,$STAGE2_CFLAGS,;t t
+s,@GRUB_CFLAGS@,$GRUB_CFLAGS,;t t
+s,@OBJCOPY@,$OBJCOPY,;t t
+s,@ac_ct_OBJCOPY@,$ac_ct_OBJCOPY,;t t
+s,@GRUB_LIBS@,$GRUB_LIBS,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@NETBOOT_SUPPORT_TRUE@,$NETBOOT_SUPPORT_TRUE,;t t
+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,@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
+s,@SERIAL_SUPPORT_FALSE@,$SERIAL_SUPPORT_FALSE,;t t
+s,@SERIAL_SPEED_SIMULATION_TRUE@,$SERIAL_SPEED_SIMULATION_TRUE,;t t
+s,@SERIAL_SPEED_SIMULATION_FALSE@,$SERIAL_SPEED_SIMULATION_FALSE,;t t
+s,@BUILD_EXAMPLE_KERNEL_TRUE@,$BUILD_EXAMPLE_KERNEL_TRUE,;t t
+s,@BUILD_EXAMPLE_KERNEL_FALSE@,$BUILD_EXAMPLE_KERNEL_FALSE,;t t
+s,@FSYS_CFLAGS@,$FSYS_CFLAGS,;t t
+s,@NET_CFLAGS@,$NET_CFLAGS,;t t
+s,@NET_EXTRAFLAGS@,$NET_EXTRAFLAGS,;t t
+s,@NETBOOT_DRIVERS@,$NETBOOT_DRIVERS,;t t
+s,@CCASFLAGS@,$CCASFLAGS,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+				     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([	 ]*\)#\([	 ]*define[	 ][	 ]*\)'
+ac_dB='[	 ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([	 ]*\)#\([	 ]*\)undef\([	 ][	 ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 # Do quote $f, to prevent DOS paths from being IFS'd.
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[	 ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*\)\(([^)]*)\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[	 ]*#[	 ]*undef[	 ][	 ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[	 ]*#[	 ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[	 ]*#[	 ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[	 ]*#[	 ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+# Compute $ac_file's index in $config_headers.
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $ac_file | $ac_file:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null ||
+$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X$ac_file : 'X\(//\)[^/]' \| \
+	 X$ac_file : 'X\(//\)$' \| \
+	 X$ac_file : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X$ac_file |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`/stamp-h$_am_stamp_count
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_COMMANDS section.
+#
+for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
+  ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
+  ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
+  ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
+$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_dest" : 'X\(//\)[^/]' \| \
+	 X"$ac_dest" : 'X\(//\)$' \| \
+	 X"$ac_dest" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_dest" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
+echo "$as_me: executing $ac_dest commands" >&6;}
+  case $ac_dest in
+    depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
+  # Strip MF so we end up with the name of the file.
+  mf=`echo "$mf" | sed -e 's/:.*$//'`
+  # Check whether this is an Automake generated Makefile or not.
+  # We used to match only the files named `Makefile.in', but
+  # some people rename them; so instead we look at the file content.
+  # Grep'ing the first line is not enough: some people post-process
+  # each Makefile.in and add a new line on top of each file to say so.
+  # So let's grep whole file.
+  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
+    dirpart=`(dirname "$mf") 2>/dev/null ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$mf" : 'X\(//\)[^/]' \| \
+	 X"$mf" : 'X\(//\)$' \| \
+	 X"$mf" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  else
+    continue
+  fi
+  # Extract the definition of DEPDIR, am__include, and am__quote
+  # from the Makefile without running `make'.
+  DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+  test -z "$DEPDIR" && continue
+  am__include=`sed -n 's/^am__include = //p' < "$mf"`
+  test -z "am__include" && continue
+  am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+  # When using ansi2knr, U may be empty or an underscore; expand it
+  U=`sed -n 's/^U = //p' < "$mf"`
+  # Find all dependency output files, they are included files with
+  # $(DEPDIR) in their names.  We invoke sed twice because it is the
+  # simplest approach to changing $(DEPDIR) to its actual value in the
+  # expansion.
+  for file in `sed -n "
+    s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+       sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+    # Make sure the directory exists.
+    test -f "$dirpart/$file" && continue
+    fdir=`(dirname "$file") 2>/dev/null ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$file" : 'X\(//\)[^/]' \| \
+	 X"$file" : 'X\(//\)$' \| \
+	 X"$file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    { if $as_mkdir_p; then
+    mkdir -p $dirpart/$fdir
+  else
+    as_dir=$dirpart/$fdir
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5
+echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+    # echo "creating $dirpart/$file"
+    echo '# dummy' > "$dirpart/$file"
+  done
+done
+ ;;
+  esac
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..bb9e1d9
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,670 @@
+dnl Configure script for GRUB.
+dnl Copyright 1999,2000,2001,2002,2003,2004,2005 Free Software Foundation, Inc.
+
+dnl Permission to use, copy, modify and distribute this software and its
+dnl documentation is hereby granted, provided that both the copyright
+dnl notice and this permission notice appear in all copies of the
+dnl software, derivative works or modified versions, and any portions
+dnl thereof, and that both notices appear in supporting documentation.
+dnl
+dnl THE FREE SOFTWARE FOUNDATION ALLOWS FREE USE OF THIS SOFTWARE IN ITS
+dnl "AS IS" CONDITION.  THE FREE SOFTWARE FOUNDATION DISCLAIMS ANY
+dnl LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE
+dnl USE OF THIS SOFTWARE.
+
+AC_PREREQ(2.57)
+AC_INIT([GRUB], [0.97], [bug-grub@gnu.org])
+AC_CONFIG_SRCDIR([stage2/stage2.c])
+AC_CONFIG_HEADER([config.h])
+AM_INIT_AUTOMAKE
+
+AC_CANONICAL_HOST
+
+case "$host_cpu" in
+i[[3456]]86) host_cpu=i386 ;;
+x86_64) host_cpu=x86_64 ;;
+*) AC_MSG_ERROR([unsupported CPU type]) ;;
+esac
+
+AC_SUBST(host_cpu)
+AC_SUBST(host_vendor)
+
+#
+# Options
+#
+
+AM_MAINTAINER_MODE
+if test "x$enable_maintainer_mode" = xyes; then
+  AC_PATH_PROG(PERL,perl)
+  if test -z "$PERL"; then
+    AC_MSG_ERROR([perl not found])
+  fi
+fi
+
+# This should be checked before AC_PROG_CC
+if test "x$CFLAGS" = x; then
+  default_CFLAGS=yes
+fi
+
+if test "x$host_cpu" = xx86_64; then
+  CFLAGS="-m32 $CFLAGS"
+fi
+
+#
+# Programs
+#
+
+AC_CHECK_TOOL(CC, gcc)
+AC_PROG_CC
+# We need this for older versions of Autoconf.
+_AM_DEPENDENCIES(CC)
+
+dnl Because recent automake complains about AS, set it here.
+CCAS="$CC"
+AC_SUBST(CCAS)
+
+AC_ARG_WITH(binutils,
+  [  --with-binutils=DIR     search the directory DIR to find binutils])
+
+if test "x$with_binutils" != x; then
+dnl AC_PATH_TOOL is not seen in autoconf 2.13, so use AC_PATH_PROG
+dnl instead for now. It is preferable when you cross-compile GRUB.
+dnl  AC_PATH_TOOL(RANLIB, ranlib, :, "$with_binutils:$PATH")
+  AC_PATH_PROG(RANLIB, ranlib, :, "$with_binutils:$PATH")
+else
+  AC_PROG_RANLIB
+fi
+
+# optimization flags
+if test "x$ac_cv_prog_gcc" = xyes; then
+  if test "x$default_CFLAGS" = xyes; then
+    # Autoconf may set CFLAGS to -O2 and/or -g. So eliminate them.
+    CFLAGS="`echo $CFLAGS | sed -e 's/-g//g' -e 's/-O[[0-9]]//g'` -g"
+    # If the user specify the directory for binutils, add the option `-B'.
+    if test "x$with_binutils" != x; then
+      CFLAGS="-B$with_binutils/ $CFLAGS"
+    fi
+    STAGE1_CFLAGS="-O2"
+    GRUB_CFLAGS="-O2"
+    AC_CACHE_CHECK([whether optimization for size works], size_flag, [
+      saved_CFLAGS=$CFLAGS
+      CFLAGS="-Os -g"
+      AC_TRY_COMPILE(, , size_flag=yes, size_flag=no)
+      CFLAGS=$saved_CFLAGS
+    ])
+    if test "x$size_flag" = xyes; then
+      STAGE2_CFLAGS="-Os"
+    else
+      STAGE2_CFLAGS="-O2 -fno-strength-reduce -fno-unroll-loops"
+    fi
+    # OpenBSD has a GCC extension for protecting applications from
+    # stack smashing attacks, but GRUB doesn't want this feature.
+    AC_CACHE_CHECK([whether gcc has -fno-stack-protector],
+		   no_stack_protector_flag, [
+      saved_CFLAGS=$CFLAGS
+      CFLAGS="-fno-stack-protector"
+      AC_TRY_COMPILE(,
+		     ,
+		     no_stack_protector_flag=yes,
+		     no_stack_protector_flag=no)
+      CFLAGS=$saved_CFLAGS
+    ])
+    if test "x$no_stack_protector_flag" = xyes; then
+      STAGE2_CFLAGS="$STAGE2_CFLAGS -fno-stack-protector"
+    fi
+  fi
+fi
+
+AC_SUBST(STAGE1_CFLAGS)
+AC_SUBST(STAGE2_CFLAGS)
+AC_SUBST(GRUB_CFLAGS)
+
+# Enforce coding standards.
+CPPFLAGS="$CPPFLAGS -Wall -Wmissing-prototypes -Wunused -Wshadow"
+CPPFLAGS="$CPPFLAGS -Wpointer-arith"
+
+AC_CACHE_CHECK([whether -Wundef works], undef_flag, [
+  saved_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="-Wundef"
+  AC_TRY_COMPILE(, , undef_flag=yes, undef_flag=no)
+  CPPFLAGS="$saved_CPPFLAGS"
+])
+
+# The options `-falign-*' are supported by gcc 3.0 or later.
+# Probably it is sufficient to only check for -falign-loops.
+AC_CACHE_CHECK([whether -falign-loops works], [falign_loop_flag], [
+  saved_CPPFLAGS="$CPPFLAGS"
+  CPPFLAGS="-falign-loops=1"
+  AC_TRY_COMPILE(, , [falign_loop_flag=yes], [falign_loop_flag=no])
+  CPPFLAGS="$saved_CPPFLAGS"
+])
+
+# Force no alignment to save space.
+if test "x$falign_loop_flag" = xyes; then
+  CPPFLAGS="$CPPFLAGS -falign-jumps=1 -falign-loops=1 -falign-functions=1"
+else
+  CPPFLAGS="$CPPFLAGS -malign-jumps=1 -malign-loops=1 -malign-functions=1"
+fi
+
+if test "x$undef_flag" = xyes; then
+  CPPFLAGS="$CPPFLAGS -Wundef"
+fi
+
+if test "x$with_binutils" != x; then
+dnl  AC_PATH_TOOL(OBJCOPY, objcopy, , "$with_binutils:$PATH")
+  AC_PATH_PROG(OBJCOPY, objcopy, , "$with_binutils:$PATH")
+else
+  AC_CHECK_TOOL(OBJCOPY, objcopy)
+fi
+
+# Defined in acinclude.m4.
+grub_ASM_USCORE
+grub_PROG_OBJCOPY_ABSOLUTE
+if test "x$grub_cv_prog_objcopy_absolute" != xyes; then
+  AC_MSG_ERROR([GRUB requires a working absolute objcopy; upgrade your binutils])
+fi
+
+grub_ASM_PREFIX_REQUIREMENT
+
+grub_ASM_ADDR32
+if test "x$grub_cv_asm_addr32" != xyes; then
+  AC_MSG_ERROR([GRUB requires GAS .code16 addr32 support; upgrade your binutils])
+fi
+
+grub_ASM_ABSOLUTE_WITHOUT_ASTERISK
+
+grub_CHECK_START_SYMBOL
+grub_CHECK_USCORE_START_SYMBOL
+if test "x$grub_cv_check_start_symbol" != "xyes" \
+	-a "x$grub_cv_check_uscore_start_symbol" != "xyes"; then
+  AC_MSG_ERROR([Neither start nor _start is defined])
+fi
+
+grub_CHECK_USCORE_USCORE_BSS_START_SYMBOL
+grub_CHECK_USCORE_EDATA_SYMBOL
+grub_CHECK_EDATA_SYMBOL
+if test "x$grub_cv_check_uscore_uscore_bss_start_symbol" != "xyes" \
+	-a "x$grub_cv_check_uscore_edata_symbol" != "xyes" \
+	-a "x$grub_cv_check_edata_symbol" != "xyes"; then
+  AC_MSG_ERROR([None of __bss_start, _edata, edata defined])
+fi
+
+grub_CHECK_END_SYMBOL
+grub_CHECK_USCORE_END_SYMBOL
+if test "x$grub_cv_check_end_symbol" != "xyes" \
+	-a "x$grub_cv_check_uscore_end_symbol" != "xyes"; then
+  AC_MSG_ERROR([Neither end nor _end is defined])
+fi
+
+# Check for curses libraries.
+AC_ARG_WITH(curses,
+  [  --without-curses        do not use curses])
+
+# Get the filename or the whole disk and open it.
+# Known to work on NetBSD.
+AC_CHECK_LIB(util, opendisk, [GRUB_LIBS="$GRUB_LIBS -lutil"
+  AC_DEFINE(HAVE_OPENDISK, 1, [Define if opendisk() in -lutil can be used])])
+
+# Unless the user specify --without-curses, check for curses.
+if test "x$with_curses" != "xno"; then
+  AC_CHECK_LIB(ncurses, wgetch, [GRUB_LIBS="$GRUB_LIBS -lncurses"
+  AC_DEFINE(HAVE_LIBCURSES, 1, [Define if you have a curses library])],
+    [AC_CHECK_LIB(curses, wgetch, [GRUB_LIBS="$GRUB_LIBS -lcurses"
+       AC_DEFINE(HAVE_LIBCURSES, 1, [Define if you have a curses library])])])
+fi
+
+AC_SUBST(GRUB_LIBS)
+
+# Check for headers.
+AC_CHECK_HEADERS(string.h strings.h ncurses/curses.h ncurses.h curses.h)
+
+# Check for user options.
+
+# filesystems support.
+AC_ARG_ENABLE(ext2fs,
+  [  --disable-ext2fs        disable ext2fs support in Stage 2])
+
+if test x"$enable_ext2fs" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_EXT2FS=1"
+fi
+
+AC_ARG_ENABLE(fat,
+  [  --disable-fat           disable FAT support in Stage 2])
+
+if test x"$enable_fat" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_FAT=1"
+fi
+
+AC_ARG_ENABLE(ffs,
+  [  --disable-ffs           disable FFS support in Stage 2])
+
+if test x"$enable_ffs" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_FFS=1"
+fi
+
+AC_ARG_ENABLE(ufs2,
+  [  --disable-ufs2          disable UFS2 support in Stage 2])
+
+if test x"$enable_ufs2" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_UFS2=1"
+fi
+
+AC_ARG_ENABLE(minix,
+  [  --disable-minix         disable Minix fs support in Stage 2])
+
+if test x"$enable_minix" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_MINIX=1"
+fi
+
+AC_ARG_ENABLE(reiserfs,
+  [  --disable-reiserfs      disable ReiserFS support in Stage 2])
+
+if test x"$enable_reiserfs" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_REISERFS=1"
+fi
+
+AC_ARG_ENABLE(vstafs,
+  [  --disable-vstafs        disable VSTa FS support in Stage 2])
+
+if test x"$enable_vstafs" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_VSTAFS=1"
+fi
+
+AC_ARG_ENABLE(jfs,
+  [  --disable-jfs           disable IBM JFS support in Stage 2])
+
+if test x"$enable_jfs" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_JFS=1"
+fi
+
+AC_ARG_ENABLE(xfs,
+  [  --disable-xfs           disable SGI XFS support in Stage 2])
+
+if test x"$enable_xfs" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_XFS=1"
+fi
+
+AC_ARG_ENABLE(iso9660,
+  [  --disable-iso9660       disable ISO9660 support in Stage 2])
+
+if test x"$enable_iso9660" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_ISO9660=1"
+fi
+
+dnl AC_ARG_ENABLE(tftp,
+dnl [  --enable-tftp           enable TFTP support in Stage 2])
+dnl 
+dnl #if test x"$enable_tftp" = xyes; then
+dnl FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_TFTP=1"
+dnl fi
+
+AC_ARG_ENABLE(gunzip,
+  [  --disable-gunzip        disable decompression in Stage 2])
+
+if test x"$enable_gunzip" = xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DNO_DECOMPRESSION=1"
+fi
+
+AC_ARG_ENABLE(md5-password,
+  [  --disable-md5-password  disable MD5 password support in Stage 2])
+if test "x$enable_md5_password" != xno; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DUSE_MD5_PASSWORDS=1"
+fi
+
+dnl The netboot support.
+dnl General options.
+AC_ARG_ENABLE(packet-retransmission,
+  [  --disable-packet-retransmission
+                          turn off packet retransmission])
+if test "x$enable_packet_retransmission" != xno; then
+  NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCONGESTED=1"
+fi
+
+AC_ARG_ENABLE(pci-direct,
+  [  --enable-pci-direct     access PCI directly instead of using BIOS])
+if test "x$enable_pci_direct" = xyes; then
+  NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCONFIG_PCI_DIRECT=1"
+fi
+
+dnl Device drivers.
+AC_ARG_ENABLE(3c509,
+  [  --enable-3c509          enable 3Com509 driver])
+if test "x$enable_3c509" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C509"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c509.o"
+fi
+
+AC_ARG_ENABLE(3c529,
+  [  --enable-3c529          enable 3Com529 driver])
+if test "x$enable_3c529" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C529=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c529.o"
+fi
+
+AC_ARG_ENABLE(3c595,
+  [  --enable-3c595          enable 3Com595 driver])
+if test "x$enable_3c595" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C595=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c595.o"
+fi
+
+AC_ARG_ENABLE(3c90x,
+  [  --enable-3c90x          enable 3Com90x driver])
+if test "x$enable_3c90x" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C90X=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c90x.o"
+fi
+
+AC_ARG_ENABLE(cs89x0,
+  [  --enable-cs89x0         enable CS89x0 driver])
+if test "x$enable_cs89x0" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_CS89X0=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS cs89x0.o"
+fi
+
+AC_ARG_ENABLE(davicom,
+  [  --enable-davicom        enable Davicom driver])
+if test "x$enable_davicom" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_DAVICOM=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS davicom.o"
+fi
+
+AC_ARG_ENABLE(depca,
+  [  --enable-depca          enable DEPCA and EtherWORKS driver])
+if test "x$enable_depca" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_DEPCA=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS depca.o"
+fi
+
+AC_ARG_ENABLE(eepro,
+  [  --enable-eepro          enable Etherexpress Pro/10 driver])
+if test "x$enable_eepro" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_EEPRO=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS eepro.o"
+fi
+
+AC_ARG_ENABLE(eepro100,
+  [  --enable-eepro100       enable Etherexpress Pro/100 driver])
+if test "x$enable_eepro100" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_EEPRO100=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS eepro100.o"
+fi
+
+AC_ARG_ENABLE(epic100,
+  [  --enable-epic100        enable SMC 83c170 EPIC/100 driver])
+if test "x$enable_epic100" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_EPIC100=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS epic100.o"
+fi
+
+AC_ARG_ENABLE(3c507,
+  [  --enable-3c507          enable 3Com507 driver])
+if test "x$enable_3c507" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C507=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c507.o"
+fi
+
+AC_ARG_ENABLE(exos205,
+  [  --enable-exos205        enable EXOS205 driver])
+if test "x$enable_exos205" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_EXOS205=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS exos205.o"
+fi
+
+AC_ARG_ENABLE(ni5210,
+  [  --enable-ni5210         enable Racal-Interlan NI5210 driver])
+if test "x$enable_ni5210" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NI5210=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS ni5210.o"
+fi
+
+AC_ARG_ENABLE(lance,
+  [  --enable-lance          enable Lance PCI PCNet/32 driver])
+if test "x$enable_lance" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_LANCE=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS lance.o"
+fi
+
+AC_ARG_ENABLE(ne2100,
+  [  --enable-ne2100         enable Novell NE2100 driver])
+if test "x$enable_ne2100" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NE2100=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS ne2100.o"
+fi
+
+AC_ARG_ENABLE(ni6510,
+  [  --enable-ni6510         enable Racal-Interlan NI6510 driver])
+if test "x$enable_ni6510" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NI6510=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS ni6510.o"
+fi
+
+AC_ARG_ENABLE(natsemi,
+  [  --enable-natsemi        enable NatSemi DP8381x driver])
+if test "x$enable_natsemi" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NATSEMI=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS natsemi.o"
+fi
+
+AC_ARG_ENABLE(ni5010,
+  [  --enable-ni5010         enable Racal-Interlan NI5010 driver])
+if test "x$enable_ni5010" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NI5010=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS ni5010.o"
+fi
+
+AC_ARG_ENABLE(3c503,
+  [  --enable-3c503          enable 3Com503 driver])
+if test "x$enable_3c503" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_3C503=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS 3c503.o"
+fi
+
+AC_ARG_ENABLE(ne,
+  [  --enable-ne             enable NE1000/2000 ISA driver])
+if test "x$enable_ne" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NE=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS ne.o"
+fi
+
+AC_ARG_ENABLE(ns8390,
+  [  --enable-ns8390         enable NE2000 PCI driver])
+if test "x$enable_ns8390" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_NS8390=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS ns8390.o"
+fi
+
+AC_ARG_ENABLE(wd,
+  [  --enable-wd             enable WD8003/8013, SMC8216/8416 driver])
+if test "x$enable_wd" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_WD=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS wd.o"
+fi
+
+AC_ARG_ENABLE(otulip,
+  [  --enable-otulip         enable old Tulip driver])
+if test "x$enable_otulip" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_OTULIP=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS otulip.o"
+fi
+
+AC_ARG_ENABLE(rtl8139,
+  [  --enable-rtl8139        enable Realtek 8139 driver])
+if test "x$enable_rtl8139" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_RTL8139=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS rtl8139.o"
+fi
+
+AC_ARG_ENABLE(sis900,
+  [  --enable-sis900         enable SIS 900 and SIS 7016 driver])
+if test "x$enable_sis900" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_SIS900=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS sis900.o"
+fi
+
+AC_ARG_ENABLE(sk-g16,
+  [  --enable-sk-g16         enable Schneider and Koch G16 driver])
+if test "x$enable_sk_g16" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_SK_G16=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS sk_g16.o"
+fi
+
+AC_ARG_ENABLE(smc9000,
+  [  --enable-smc9000        enable SMC9000 driver])
+if test "x$enable_smc9000" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_SMC9000=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS smc9000.o"
+fi
+
+AC_ARG_ENABLE(tiara,
+  [  --enable-tiara          enable Tiara driver])
+if test "x$enable_tiara" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_TIARA=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS tiara.o"
+fi
+
+AC_ARG_ENABLE(tulip,
+  [  --enable-tulip          enable Tulip driver])
+if test "x$enable_tulip" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_TULIP=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS tulip.o"
+fi
+
+AC_ARG_ENABLE(via-rhine,
+  [  --enable-via-rhine      enable Rhine-I/II driver])
+if test "x$enable_via_rhine" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_VIA_RHINE=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS via_rhine.o"
+fi
+
+AC_ARG_ENABLE(w89c840,
+  [  --enable-w89c840        enable Winbond W89c840, Compex RL100-ATX driver])
+if test "x$enable_w89c840" = xyes; then
+  NET_CFLAGS="$NET_CFLAGS -DINCLUDE_W89C840=1"
+  NETBOOT_DRIVERS="$NETBOOT_DRIVERS w89c840.o"
+fi
+
+dnl Check if the netboot support is turned on.
+AM_CONDITIONAL(NETBOOT_SUPPORT, test "x$NET_CFLAGS" != x)
+if test "x$NET_CFLAGS" != x; then
+  FSYS_CFLAGS="$FSYS_CFLAGS -DFSYS_TFTP=1"
+fi
+
+dnl Extra options.
+AC_ARG_ENABLE(3c503-shmem,
+  [  --enable-3c503-shmem    use 3c503 shared memory mode])
+if test "x$enable_3c503_shmem" = xyes; then
+  NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DT503_SHMEM=1"
+fi
+
+AC_ARG_ENABLE(3c503-aui,
+  [  --enable-3c503-aui      use AUI by default on 3c503 cards])
+if test "x$enable_3c503_aui" = xyes; then
+  NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DT503_AUI=1"
+fi
+
+AC_ARG_ENABLE(compex-rl2000-fix,
+  [  --enable-compex-rl2000-fix
+                          specify this if you have a Compex RL2000 PCI])
+if test "x$enable_compex_rl2000_fix" = xyes; then
+  NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCOMPEX_RL2000_FIX=1"
+fi
+
+AC_ARG_ENABLE(smc9000-scan,
+  [  --enable-smc9000-scan=LIST
+                          probe for SMC9000 I/O addresses using LIST],
+  [NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DSMC9000_SCAN=$enable_smc9000_scan"])
+
+AC_ARG_ENABLE(ne-scan,
+  [  --enable-ne-scan=LIST   probe for NE base address using LIST],
+  [NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DNE_SCAN=$enable_ne_scan"],
+  [NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DNE_SCAN=0x280,0x300,0x320,0x340"])
+
+AC_ARG_ENABLE(wd-default-mem,
+  [  --enable-wd-default-mem=MEM
+                          set the default memory location for WD/SMC],
+  [NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DWD_DEFAULT_MEM=$enable_wd_default_mem"],
+  [NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DWD_DEFAULT_MEM=0xCC000"])
+
+AC_ARG_ENABLE(cs-scan,
+  [  --enable-cs-scan=LIST   probe for CS89x0 base address using LIST],
+  [NET_EXTRAFLAGS="$NET_EXTRAFLAGS -DCS_SCAN=$enable_cs_scan"])
+
+dnl Diskless
+AC_ARG_ENABLE(diskless,
+  [  --enable-diskless       enable diskless support])
+AM_CONDITIONAL(DISKLESS_SUPPORT, test "x$enable_diskless" = xyes)
+
+dnl Hercules terminal
+AC_ARG_ENABLE(hercules,
+  [  --disable-hercules      disable hercules terminal support])
+AM_CONDITIONAL(HERCULES_SUPPORT, test "x$enable_hercules" != xno)
+
+dnl Serial terminal
+AC_ARG_ENABLE(serial,
+  [  --disable-serial        disable serial terminal support])
+AM_CONDITIONAL(SERIAL_SUPPORT, test "x$enable_serial" != xno)
+
+dnl Simulation of the slowness of a serial device.
+AC_ARG_ENABLE(serial-speed-simulation,
+  [  --enable-serial-speed-simulation
+                          simulate the slowness of a serial device])
+AM_CONDITIONAL(SERIAL_SPEED_SIMULATION,
+  test "x$enable_serial_speed_simulation" = xyes)
+
+# Sanity check.
+if test "x$enable_diskless" = xyes; then
+  if test "x$NET_CFLAGS" = x; then
+    AC_MSG_ERROR([You must enable at least one network driver])
+  fi
+fi
+
+dnl Embed a menu string in GRUB itself.
+AC_ARG_ENABLE(preset-menu,
+  [  --enable-preset-menu=FILE
+                          preset a menu file FILE in Stage 2])
+if test "x$enable_preset_menu" = x; then
+  :
+else
+  if test -r $enable_preset_menu; then
+    grub_DEFINE_FILE(PRESET_MENU_STRING, [$enable_preset_menu],
+    		     [Define if there is user specified preset menu string])
+  else
+    AC_MSG_ERROR([Cannot read the preset menu file $enable_preset_menu])
+  fi
+fi
+
+dnl Build the example Multiboot kernel.
+AC_ARG_ENABLE(example-kernel,
+  [  --enable-example-kernel
+                          build the example Multiboot kernel])
+AM_CONDITIONAL(BUILD_EXAMPLE_KERNEL, test "x$enable_example_kernel" = xyes)
+
+dnl Automatic Linux mem= option.
+AC_ARG_ENABLE(auto-linux-mem-opt,
+  [  --disable-auto-linux-mem-opt
+                          don't pass Linux mem= option automatically])
+if test "x$enable_auto_linux_mem_opt" = xno; then
+  :
+else
+  AC_DEFINE(AUTO_LINUX_MEM_OPT, 1, [Define if you don't want to pass the mem= option to Linux])
+fi
+
+dnl Now substitute the variables.
+AC_SUBST(FSYS_CFLAGS)
+AC_SUBST(NET_CFLAGS)
+AC_SUBST(NET_EXTRAFLAGS)
+AC_SUBST(NETBOOT_DRIVERS)
+
+dnl Because recent automake complains about CCASFLAGS, set it here.
+CCASFLAGS='$(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)'
+AC_SUBST(CCASFLAGS)
+
+
+dnl Output.
+AC_CONFIG_FILES([Makefile stage1/Makefile stage2/Makefile \
+		 docs/Makefile lib/Makefile util/Makefile \
+		 grub/Makefile netboot/Makefile util/grub-image \
+		 util/grub-install util/grub-md5-crypt \
+		 util/grub-terminfo util/grub-set-default])
+AC_OUTPUT
diff --git a/depcomp b/depcomp
new file mode 100755
index 0000000..11e2d3b
--- /dev/null
+++ b/depcomp
@@ -0,0 +1,522 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2004-05-31.23
+
+# Copyright (C) 1999, 2000, 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.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by `PROGRAMS ARGS'.
+  object      Object file output by `PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputing dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit 0
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit 0
+    ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+  "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> $depfile
+    echo >> $depfile
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> $depfile
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
+  tmpdepfile="$stripped.u"
+  if test "$libtool" = yes; then
+    "$@" -Wc,-M
+  else
+    "$@" -M
+  fi
+  stat=$?
+
+  if test -f "$tmpdepfile"; then :
+  else
+    stripped=`echo "$stripped" | sed 's,^.*/,,'`
+    tmpdepfile="$stripped.u"
+  fi
+
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+
+  if test -f "$tmpdepfile"; then
+    outname="$stripped.o"
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+    sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Intel's C compiler understands `-MD -MF file'.  However on
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using \ :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+    sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      # Dependencies are output in .lo.d with libtool 1.4.
+      # With libtool 1.5 they are output both in $dir.libs/$base.o.d
+      # and in $dir.libs/$base.o.d and $dir$base.o.d.  We process the
+      # latter, because the former will be cleaned when $dir.libs is
+      # erased.
+      tmpdepfile1="$dir.libs/$base.lo.d"
+      tmpdepfile2="$dir$base.o.d"
+      tmpdepfile3="$dir.libs/$base.d"
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1="$dir$base.o.d"
+      tmpdepfile2="$dir$base.d"
+      tmpdepfile3="$dir$base.d"
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+      exit $stat
+   fi
+
+   if test -f "$tmpdepfile1"; then
+      tmpdepfile="$tmpdepfile1"
+   elif test -f "$tmpdepfile2"; then
+      tmpdepfile="$tmpdepfile2"
+   else
+      tmpdepfile="$tmpdepfile3"
+   fi
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a tab and a space in the [].
+      sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for `:'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  "$@" $dashmflag |
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no
+  for arg in "$@"; do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix="`echo $object | sed 's/^.*\././'`"
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o,
+  # because we must use -o when running libtool.
+  "$@" || exit $?
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+	set fnord "$@"
+	shift
+	shift
+	;;
+    *)
+	set fnord "$@" "$arg"
+	shift
+	shift
+	;;
+    esac
+  done
+  "$@" -E |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::	\1 \\:p' >> "$depfile"
+  echo "	" >> "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/docs/Makefile.am b/docs/Makefile.am
new file mode 100644
index 0000000..db99e2d
--- /dev/null
+++ b/docs/Makefile.am
@@ -0,0 +1,65 @@
+info_TEXINFOS = grub.texi multiboot.texi
+grub_TEXINFOS = internals.texi
+EXAMPLES = boot.S kernel.c multiboot.h
+multiboot_TEXINFOS = boot.S.texi kernel.c.texi multiboot.h.texi
+man_MANS = grub.8 mbchk.1 grub-install.8 grub-md5-crypt.8 grub-terminfo.8
+HELP2MAN = help2man
+SRC2TEXI = src2texi
+noinst_SCRIPTS = $(HELP2MAN) $(SRC2TEXI)
+EXTRA_PROGRAMS = kernel
+
+# The example kernel is built if you specify --enable-example-kernel.
+if BUILD_EXAMPLE_KERNEL
+noinst_PROGRAMS = kernel
+kernel_SOURCES = $(EXAMPLES)
+kernel_CFLAGS = -fno-builtin -nostdinc -O -g -Wall \
+	-imacros $(top_builddir)/config.h
+kernel_LDFLAGS = -nostdlib -Wl,-N -Wl,-Ttext -Wl,100000
+
+boot.o: multiboot.h
+endif
+
+EXTRA_DIST = menu.lst $(man_MANS) $(noinst_SCRIPTS) \
+	$(EXAMPLES) $(multiboot_TEXINFOS)
+CLEANFILES = $(noinst_PROGRAMS)
+
+# Cancel the rule %.texi -> %. This rule may confuse make to determine
+# the dependecies.
+.texi:
+
+%.c.texi: %.c $(srcdir)/$(SRC2TEXI)
+	$(SHELL) $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
+
+%.h.texi: %.h $(srcdir)/$(SRC2TEXI)
+	$(SHELL) $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
+
+%.S.texi: %.S $(srcdir)/$(SRC2TEXI)
+	$(SHELL) $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
+
+if MAINTAINER_MODE
+$(srcdir)/grub.8: ../grub/grub $(srcdir)/$(HELP2MAN)
+	$(PERL) $(srcdir)/$(HELP2MAN) --name="the grub shell" \
+		--section=8 --output=$@ $<
+
+$(srcdir)/grub-install.8: ../util/grub-install $(srcdir)/$(HELP2MAN)
+	chmod 755 $<
+	$(PERL) $(srcdir)/$(HELP2MAN) --name="install GRUB on your drive" \
+		--section=8 --output=$@ $<
+
+$(srcdir)/mbchk.1: ../util/mbchk $(srcdir)/$(HELP2MAN)
+	$(PERL) $(srcdir)/$(HELP2MAN) \
+		--name="check the format of a Multiboot kernel" \
+		--section=1 --output=$@ $<
+
+$(srcdir)/grub-md5-crypt.8: ../util/grub-md5-crypt $(srcdir)/$(HELP2MAN)
+	chmod 755 $<
+	$(PERL) $(srcdir)/$(HELP2MAN) \
+		--name="Encrypt a password in MD5 format" \
+		--section=8 --output=$@ $<
+
+$(srcdir)/grub-terminfo.8: ../util/grub-terminfo $(srcdir)/$(HELP2MAN)
+	chmod 755 $<
+	$(PERL) $(srcdir)/$(HELP2MAN) \
+		--name="Generate a terminfo command from a terminfo name" \
+		--section=8 --output=$@ $<
+endif
diff --git a/docs/Makefile.in b/docs/Makefile.in
new file mode 100644
index 0000000..3e2de4b
--- /dev/null
+++ b/docs/Makefile.in
@@ -0,0 +1,770 @@
+# Makefile.in generated by automake 1.9.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  Free Software Foundation, Inc.
+# This Makefile.in 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 distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+SOURCES = $(kernel_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+EXTRA_PROGRAMS = kernel$(EXEEXT)
+@BUILD_EXAMPLE_KERNEL_TRUE@noinst_PROGRAMS = kernel$(EXEEXT)
+subdir = docs
+DIST_COMMON = $(grub_TEXINFOS) $(multiboot_TEXINFOS) \
+	$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+	$(srcdir)/stamp-vti $(srcdir)/version.texi mdate-sh \
+	texinfo.tex
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+PROGRAMS = $(noinst_PROGRAMS)
+am__kernel_SOURCES_DIST = boot.S kernel.c multiboot.h
+am__objects_1 = boot.$(OBJEXT) kernel-kernel.$(OBJEXT)
+@BUILD_EXAMPLE_KERNEL_TRUE@am_kernel_OBJECTS = $(am__objects_1)
+kernel_OBJECTS = $(am_kernel_OBJECTS)
+kernel_LDADD = $(LDADD)
+SCRIPTS = $(noinst_SCRIPTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+CCASCOMPILE = $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS)
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(kernel_SOURCES)
+DIST_SOURCES = $(am__kernel_SOURCES_DIST)
+INFO_DEPS = $(srcdir)/grub.info $(srcdir)/multiboot.info
+am__TEXINFO_TEX_DIR = $(srcdir)
+DVIS = grub.dvi multiboot.dvi
+PDFS = grub.pdf multiboot.pdf
+PSS = grub.ps multiboot.ps
+HTMLS = grub.html multiboot.html
+TEXINFOS = grub.texi multiboot.texi
+TEXI2DVI = texi2dvi
+TEXI2PDF = $(TEXI2DVI) --pdf --batch
+MAKEINFOHTML = $(MAKEINFO) --html
+AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
+DVIPS = dvips
+am__installdirs = "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)" \
+	"$(DESTDIR)$(man8dir)"
+man1dir = $(mandir)/man1
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(man_MANS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_EXAMPLE_KERNEL_FALSE = @BUILD_EXAMPLE_KERNEL_FALSE@
+BUILD_EXAMPLE_KERNEL_TRUE = @BUILD_EXAMPLE_KERNEL_TRUE@
+CC = @CC@
+CCAS = @CCAS@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISKLESS_SUPPORT_FALSE = @DISKLESS_SUPPORT_FALSE@
+DISKLESS_SUPPORT_TRUE = @DISKLESS_SUPPORT_TRUE@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FSYS_CFLAGS = @FSYS_CFLAGS@
+GRUB_CFLAGS = @GRUB_CFLAGS@
+GRUB_LIBS = @GRUB_LIBS@
+HERCULES_SUPPORT_FALSE = @HERCULES_SUPPORT_FALSE@
+HERCULES_SUPPORT_TRUE = @HERCULES_SUPPORT_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
+NETBOOT_SUPPORT_FALSE = @NETBOOT_SUPPORT_FALSE@
+NETBOOT_SUPPORT_TRUE = @NETBOOT_SUPPORT_TRUE@
+NET_CFLAGS = @NET_CFLAGS@
+NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
+OBJCOPY = @OBJCOPY@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+RANLIB = @RANLIB@
+SERIAL_SPEED_SIMULATION_FALSE = @SERIAL_SPEED_SIMULATION_FALSE@
+SERIAL_SPEED_SIMULATION_TRUE = @SERIAL_SPEED_SIMULATION_TRUE@
+SERIAL_SUPPORT_FALSE = @SERIAL_SUPPORT_FALSE@
+SERIAL_SUPPORT_TRUE = @SERIAL_SUPPORT_TRUE@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STAGE1_CFLAGS = @STAGE1_CFLAGS@
+STAGE2_CFLAGS = @STAGE2_CFLAGS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_OBJCOPY = @ac_ct_OBJCOPY@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+info_TEXINFOS = grub.texi multiboot.texi
+grub_TEXINFOS = internals.texi
+EXAMPLES = boot.S kernel.c multiboot.h
+multiboot_TEXINFOS = boot.S.texi kernel.c.texi multiboot.h.texi
+man_MANS = grub.8 mbchk.1 grub-install.8 grub-md5-crypt.8 grub-terminfo.8
+HELP2MAN = help2man
+SRC2TEXI = src2texi
+noinst_SCRIPTS = $(HELP2MAN) $(SRC2TEXI)
+@BUILD_EXAMPLE_KERNEL_TRUE@kernel_SOURCES = $(EXAMPLES)
+@BUILD_EXAMPLE_KERNEL_TRUE@kernel_CFLAGS = -fno-builtin -nostdinc -O -g -Wall \
+@BUILD_EXAMPLE_KERNEL_TRUE@	-imacros $(top_builddir)/config.h
+
+@BUILD_EXAMPLE_KERNEL_TRUE@kernel_LDFLAGS = -nostdlib -Wl,-N -Wl,-Ttext -Wl,100000
+EXTRA_DIST = menu.lst $(man_MANS) $(noinst_SCRIPTS) \
+	$(EXAMPLES) $(multiboot_TEXINFOS)
+
+CLEANFILES = $(noinst_PROGRAMS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .S .c .dvi .html .info .o .obj .pdf .ps .texi
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  docs/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu  docs/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstPROGRAMS:
+	-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+kernel$(EXEEXT): $(kernel_OBJECTS) $(kernel_DEPENDENCIES) 
+	@rm -f kernel$(EXEEXT)
+	$(LINK) $(kernel_LDFLAGS) $(kernel_OBJECTS) $(kernel_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kernel-kernel.Po@am__quote@
+
+.S.o:
+	$(CCASCOMPILE) -c $<
+
+.S.obj:
+	$(CCASCOMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.o:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+kernel-kernel.o: kernel.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kernel_CFLAGS) $(CFLAGS) -MT kernel-kernel.o -MD -MP -MF "$(DEPDIR)/kernel-kernel.Tpo" -c -o kernel-kernel.o `test -f 'kernel.c' || echo '$(srcdir)/'`kernel.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/kernel-kernel.Tpo" "$(DEPDIR)/kernel-kernel.Po"; else rm -f "$(DEPDIR)/kernel-kernel.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='kernel.c' object='kernel-kernel.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kernel_CFLAGS) $(CFLAGS) -c -o kernel-kernel.o `test -f 'kernel.c' || echo '$(srcdir)/'`kernel.c
+
+kernel-kernel.obj: kernel.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kernel_CFLAGS) $(CFLAGS) -MT kernel-kernel.obj -MD -MP -MF "$(DEPDIR)/kernel-kernel.Tpo" -c -o kernel-kernel.obj `if test -f 'kernel.c'; then $(CYGPATH_W) 'kernel.c'; else $(CYGPATH_W) '$(srcdir)/kernel.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/kernel-kernel.Tpo" "$(DEPDIR)/kernel-kernel.Po"; else rm -f "$(DEPDIR)/kernel-kernel.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='kernel.c' object='kernel-kernel.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(kernel_CFLAGS) $(CFLAGS) -c -o kernel-kernel.obj `if test -f 'kernel.c'; then $(CYGPATH_W) 'kernel.c'; else $(CYGPATH_W) '$(srcdir)/kernel.c'; fi`
+
+.texi.info:
+	restore=: && backupdir="$(am__leading_dot)am$$$$" && \
+	am__cwd=`pwd` && cd $(srcdir) && \
+	rm -rf $$backupdir && mkdir $$backupdir && \
+	for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \
+	  if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \
+	done; \
+	cd "$$am__cwd"; \
+	if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+	 -o $@ $<; \
+	then \
+	  rc=0; \
+	  cd $(srcdir); \
+	else \
+	  rc=$$?; \
+	  cd $(srcdir) && \
+	  $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \
+	fi; \
+	rm -rf $$backupdir; exit $$rc
+
+.texi.dvi:
+	TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+	MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+	$(TEXI2DVI) $<
+
+.texi.pdf:
+	TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \
+	MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \
+	$(TEXI2PDF) $<
+
+.texi.html:
+	rm -rf $(@:.html=.htp)
+	if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \
+	 -o $(@:.html=.htp) $<; \
+	then \
+	  rm -rf $@; \
+	  if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+	    mv $(@:.html=) $@; else mv $(@:.html=.htp) $@; fi; \
+	else \
+	  if test ! -d $(@:.html=.htp) && test -d $(@:.html=); then \
+	    rm -rf $(@:.html=); else rm -Rf $(@:.html=.htp) $@; fi; \
+	  exit 1; \
+	fi
+$(srcdir)/grub.info: grub.texi $(srcdir)/version.texi $(grub_TEXINFOS)
+grub.dvi: grub.texi $(srcdir)/version.texi $(grub_TEXINFOS)
+grub.pdf: grub.texi $(srcdir)/version.texi $(grub_TEXINFOS)
+grub.html: grub.texi $(srcdir)/version.texi $(grub_TEXINFOS)
+$(srcdir)/version.texi: @MAINTAINER_MODE_TRUE@ $(srcdir)/stamp-vti
+$(srcdir)/stamp-vti: grub.texi $(top_srcdir)/configure
+	@(dir=.; test -f ./grub.texi || dir=$(srcdir); \
+	set `$(SHELL) $(srcdir)/mdate-sh $$dir/grub.texi`; \
+	echo "@set UPDATED $$1 $$2 $$3"; \
+	echo "@set UPDATED-MONTH $$2 $$3"; \
+	echo "@set EDITION $(VERSION)"; \
+	echo "@set VERSION $(VERSION)") > vti.tmp
+	@cmp -s vti.tmp $(srcdir)/version.texi \
+	  || (echo "Updating $(srcdir)/version.texi"; \
+	      cp vti.tmp $(srcdir)/version.texi)
+	-@rm -f vti.tmp
+	@cp $(srcdir)/version.texi $@
+
+mostlyclean-vti:
+	-rm -f vti.tmp
+
+maintainer-clean-vti:
+@MAINTAINER_MODE_TRUE@	-rm -f $(srcdir)/stamp-vti $(srcdir)/version.texi
+$(srcdir)/multiboot.info: multiboot.texi $(multiboot_TEXINFOS)
+multiboot.dvi: multiboot.texi $(multiboot_TEXINFOS)
+multiboot.pdf: multiboot.texi $(multiboot_TEXINFOS)
+multiboot.html: multiboot.texi $(multiboot_TEXINFOS)
+.dvi.ps:
+	$(DVIPS) -o $@ $<
+
+uninstall-info-am:
+	$(PRE_UNINSTALL)
+	@if (install-info --version && \
+	     install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+	  list='$(INFO_DEPS)'; \
+	  for file in $$list; do \
+	    relfile=`echo "$$file" | sed 's|^.*/||'`; \
+	    echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \
+	    install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \
+	  done; \
+	else :; fi
+	@$(NORMAL_UNINSTALL)
+	@list='$(INFO_DEPS)'; \
+	for file in $$list; do \
+	  relfile=`echo "$$file" | sed 's|^.*/||'`; \
+	  relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \
+	  (if cd "$(DESTDIR)$(infodir)"; then \
+	     echo " rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9])"; \
+	     rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \
+	   else :; fi); \
+	done
+
+dist-info: $(INFO_DEPS)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	list='$(INFO_DEPS)'; \
+	for base in $$list; do \
+	  case $$base in \
+	    $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \
+	  esac; \
+	  if test -f $$base; then d=.; else d=$(srcdir); fi; \
+	  for file in $$d/$$base*; do \
+	    relfile=`expr "$$file" : "$$d/\(.*\)"`; \
+	    test -f $(distdir)/$$relfile || \
+	      cp -p $$file $(distdir)/$$relfile; \
+	  done; \
+	done
+
+mostlyclean-aminfo:
+	-rm -rf grub.aux grub.cp grub.cps grub.fn grub.ky grub.log grub.pg grub.tmp \
+	  grub.toc grub.tp grub.vr grub.dvi grub.pdf grub.ps grub.html \
+	  multiboot.aux multiboot.cp multiboot.cps multiboot.fn \
+	  multiboot.ky multiboot.log multiboot.pg multiboot.tmp \
+	  multiboot.toc multiboot.tp multiboot.vr multiboot.dvi \
+	  multiboot.pdf multiboot.ps multiboot.html
+
+maintainer-clean-aminfo:
+	@list='$(INFO_DEPS)'; for i in $$list; do \
+	  i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \
+	  echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \
+	  rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \
+	done
+install-man1: $(man1_MANS) $(man_MANS)
+	@$(NORMAL_INSTALL)
+	test -z "$(man1dir)" || $(mkdir_p) "$(DESTDIR)$(man1dir)"
+	@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
+	l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+	for i in $$l2; do \
+	  case "$$i" in \
+	    *.1*) list="$$list $$i" ;; \
+	  esac; \
+	done; \
+	for i in $$list; do \
+	  if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+	  else file=$$i; fi; \
+	  ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+	  case "$$ext" in \
+	    1*) ;; \
+	    *) ext='1' ;; \
+	  esac; \
+	  inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+	  inst=`echo $$inst | sed -e 's/^.*\///'`; \
+	  inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+	  echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+	  $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \
+	done
+uninstall-man1:
+	@$(NORMAL_UNINSTALL)
+	@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
+	l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+	for i in $$l2; do \
+	  case "$$i" in \
+	    *.1*) list="$$list $$i" ;; \
+	  esac; \
+	done; \
+	for i in $$list; do \
+	  ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+	  case "$$ext" in \
+	    1*) ;; \
+	    *) ext='1' ;; \
+	  esac; \
+	  inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+	  inst=`echo $$inst | sed -e 's/^.*\///'`; \
+	  inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+	  echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \
+	  rm -f "$(DESTDIR)$(man1dir)/$$inst"; \
+	done
+install-man8: $(man8_MANS) $(man_MANS)
+	@$(NORMAL_INSTALL)
+	test -z "$(man8dir)" || $(mkdir_p) "$(DESTDIR)$(man8dir)"
+	@list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
+	l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+	for i in $$l2; do \
+	  case "$$i" in \
+	    *.8*) list="$$list $$i" ;; \
+	  esac; \
+	done; \
+	for i in $$list; do \
+	  if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+	  else file=$$i; fi; \
+	  ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+	  case "$$ext" in \
+	    8*) ;; \
+	    *) ext='8' ;; \
+	  esac; \
+	  inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+	  inst=`echo $$inst | sed -e 's/^.*\///'`; \
+	  inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+	  echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+	  $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst"; \
+	done
+uninstall-man8:
+	@$(NORMAL_UNINSTALL)
+	@list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
+	l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+	for i in $$l2; do \
+	  case "$$i" in \
+	    *.8*) list="$$list $$i" ;; \
+	  esac; \
+	done; \
+	for i in $$list; do \
+	  ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+	  case "$$ext" in \
+	    8*) ;; \
+	    *) ext='8' ;; \
+	  esac; \
+	  inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+	  inst=`echo $$inst | sed -e 's/^.*\///'`; \
+	  inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+	  echo " rm -f '$(DESTDIR)$(man8dir)/$$inst'"; \
+	  rm -f "$(DESTDIR)$(man8dir)/$$inst"; \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	    $$tags $$unique; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$tags $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+	list='$(DISTFILES)'; for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+	  esac; \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+	    dir="/$$dir"; \
+	    $(mkdir_p) "$(distdir)$$dir"; \
+	  else \
+	    dir=''; \
+	  fi; \
+	  if test -d $$d/$$file; then \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+	$(MAKE) $(AM_MAKEFLAGS) \
+	  top_distdir="$(top_distdir)" distdir="$(distdir)" \
+	  dist-info
+check-am: all-am
+check: check-am
+all-am: Makefile $(INFO_DEPS) $(PROGRAMS) $(SCRIPTS) $(MANS)
+installdirs:
+	for dir in "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)"; do \
+	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am: $(DVIS)
+
+html: html-am
+
+html-am: $(HTMLS)
+
+info: info-am
+
+info-am: $(INFO_DEPS)
+
+install-data-am: install-info-am install-man
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-info-am: $(INFO_DEPS)
+	@$(NORMAL_INSTALL)
+	test -z "$(infodir)" || $(mkdir_p) "$(DESTDIR)$(infodir)"
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	list='$(INFO_DEPS)'; \
+	for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	  esac; \
+	  if test -f $$file; then d=.; else d=$(srcdir); fi; \
+	  file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \
+	  for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \
+                       $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \
+	    if test -f $$ifile; then \
+	      relfile=`echo "$$ifile" | sed 's|^.*/||'`; \
+	      echo " $(INSTALL_DATA) '$$ifile' '$(DESTDIR)$(infodir)/$$relfile'"; \
+	      $(INSTALL_DATA) "$$ifile" "$(DESTDIR)$(infodir)/$$relfile"; \
+	    else : ; fi; \
+	  done; \
+	done
+	@$(POST_INSTALL)
+	@if (install-info --version && \
+	     install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+	  list='$(INFO_DEPS)'; \
+	  for file in $$list; do \
+	    relfile=`echo "$$file" | sed 's|^.*/||'`; \
+	    echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\
+	    install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\
+	  done; \
+	else : ; fi
+install-man: install-man1 install-man8
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-aminfo \
+	maintainer-clean-generic maintainer-clean-vti
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-aminfo mostlyclean-compile \
+	mostlyclean-generic mostlyclean-vti
+
+pdf: pdf-am
+
+pdf-am: $(PDFS)
+
+ps: ps-am
+
+ps-am: $(PSS)
+
+uninstall-am: uninstall-info-am uninstall-man
+
+uninstall-man: uninstall-man1 uninstall-man8
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+	clean-noinstPROGRAMS ctags dist-info distclean \
+	distclean-compile distclean-generic distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-exec install-exec-am \
+	install-info install-info-am install-man install-man1 \
+	install-man8 install-strip installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-aminfo \
+	maintainer-clean-generic maintainer-clean-vti mostlyclean \
+	mostlyclean-aminfo mostlyclean-compile mostlyclean-generic \
+	mostlyclean-vti pdf pdf-am ps ps-am tags uninstall \
+	uninstall-am uninstall-info-am uninstall-man uninstall-man1 \
+	uninstall-man8
+
+
+@BUILD_EXAMPLE_KERNEL_TRUE@boot.o: multiboot.h
+
+# Cancel the rule %.texi -> %. This rule may confuse make to determine
+# the dependecies.
+.texi:
+
+%.c.texi: %.c $(srcdir)/$(SRC2TEXI)
+	$(SHELL) $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
+
+%.h.texi: %.h $(srcdir)/$(SRC2TEXI)
+	$(SHELL) $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
+
+%.S.texi: %.S $(srcdir)/$(SRC2TEXI)
+	$(SHELL) $(srcdir)/$(SRC2TEXI) $(srcdir) $< $@
+
+@MAINTAINER_MODE_TRUE@$(srcdir)/grub.8: ../grub/grub $(srcdir)/$(HELP2MAN)
+@MAINTAINER_MODE_TRUE@	$(PERL) $(srcdir)/$(HELP2MAN) --name="the grub shell" \
+@MAINTAINER_MODE_TRUE@		--section=8 --output=$@ $<
+
+@MAINTAINER_MODE_TRUE@$(srcdir)/grub-install.8: ../util/grub-install $(srcdir)/$(HELP2MAN)
+@MAINTAINER_MODE_TRUE@	chmod 755 $<
+@MAINTAINER_MODE_TRUE@	$(PERL) $(srcdir)/$(HELP2MAN) --name="install GRUB on your drive" \
+@MAINTAINER_MODE_TRUE@		--section=8 --output=$@ $<
+
+@MAINTAINER_MODE_TRUE@$(srcdir)/mbchk.1: ../util/mbchk $(srcdir)/$(HELP2MAN)
+@MAINTAINER_MODE_TRUE@	$(PERL) $(srcdir)/$(HELP2MAN) \
+@MAINTAINER_MODE_TRUE@		--name="check the format of a Multiboot kernel" \
+@MAINTAINER_MODE_TRUE@		--section=1 --output=$@ $<
+
+@MAINTAINER_MODE_TRUE@$(srcdir)/grub-md5-crypt.8: ../util/grub-md5-crypt $(srcdir)/$(HELP2MAN)
+@MAINTAINER_MODE_TRUE@	chmod 755 $<
+@MAINTAINER_MODE_TRUE@	$(PERL) $(srcdir)/$(HELP2MAN) \
+@MAINTAINER_MODE_TRUE@		--name="Encrypt a password in MD5 format" \
+@MAINTAINER_MODE_TRUE@		--section=8 --output=$@ $<
+
+@MAINTAINER_MODE_TRUE@$(srcdir)/grub-terminfo.8: ../util/grub-terminfo $(srcdir)/$(HELP2MAN)
+@MAINTAINER_MODE_TRUE@	chmod 755 $<
+@MAINTAINER_MODE_TRUE@	$(PERL) $(srcdir)/$(HELP2MAN) \
+@MAINTAINER_MODE_TRUE@		--name="Generate a terminfo command from a terminfo name" \
+@MAINTAINER_MODE_TRUE@		--section=8 --output=$@ $<
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/docs/boot.S b/docs/boot.S
new file mode 100644
index 0000000..b0e167f
--- /dev/null
+++ b/docs/boot.S
@@ -0,0 +1,80 @@
+/* boot.S - bootstrap the kernel */
+/* Copyright (C) 1999, 2001  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.  */
+
+#define ASM	1
+#include <multiboot.h>
+	
+	.text
+
+	.globl	start, _start
+start:
+_start:
+	jmp	multiboot_entry
+
+	/* Align 32 bits boundary.  */
+	.align	4
+	
+	/* Multiboot header.  */
+multiboot_header:
+	/* magic */
+	.long	MULTIBOOT_HEADER_MAGIC
+	/* flags */
+	.long	MULTIBOOT_HEADER_FLAGS
+	/* checksum */
+	.long	-(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
+#ifndef __ELF__
+	/* header_addr */
+	.long	multiboot_header
+	/* load_addr */
+	.long	_start
+	/* load_end_addr */
+	.long	_edata
+	/* bss_end_addr */
+	.long	_end
+	/* entry_addr */
+	.long	multiboot_entry
+#endif /* ! __ELF__ */
+
+multiboot_entry:
+	/* Initialize the stack pointer.  */
+	movl	$(stack + STACK_SIZE), %esp
+
+	/* Reset EFLAGS.  */
+	pushl	$0
+	popf
+
+	/* Push the pointer to the Multiboot information structure.  */
+	pushl	%ebx
+	/* Push the magic value.  */
+	pushl	%eax
+
+	/* Now enter the C main function...  */
+	call	EXT_C(cmain)
+
+	/* Halt.  */
+	pushl	$halt_message
+	call	EXT_C(printf)
+	
+loop:	hlt
+	jmp	loop
+
+halt_message:
+	.asciz	"Halted."
+
+	/* Our stack area.  */
+	.comm	stack, STACK_SIZE
+	
\ No newline at end of file
diff --git a/docs/boot.S.texi b/docs/boot.S.texi
new file mode 100644
index 0000000..afca9f7
--- /dev/null
+++ b/docs/boot.S.texi
@@ -0,0 +1,80 @@
+/* @r{boot.S - bootstrap the kernel} */
+/* @r{Copyright (C) 1999, 2001  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.} */
+
+#define ASM     1
+#include <multiboot.h>
+        
+        .text
+
+        .globl  start, _start
+start:
+_start:
+        jmp     multiboot_entry
+
+        /* @r{Align 32 bits boundary.} */
+        .align  4
+        
+        /* @r{Multiboot header.} */
+multiboot_header:
+        /* @r{magic} */
+        .long   MULTIBOOT_HEADER_MAGIC
+        /* @r{flags} */
+        .long   MULTIBOOT_HEADER_FLAGS
+        /* @r{checksum} */
+        .long   -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
+#ifndef __ELF__
+        /* @r{header_addr} */
+        .long   multiboot_header
+        /* @r{load_addr} */
+        .long   _start
+        /* @r{load_end_addr} */
+        .long   _edata
+        /* @r{bss_end_addr} */
+        .long   _end
+        /* @r{entry_addr} */
+        .long   multiboot_entry
+#endif /* @r{! __ELF__} */
+
+multiboot_entry:
+        /* @r{Initialize the stack pointer.} */
+        movl    $(stack + STACK_SIZE), %esp
+
+        /* @r{Reset EFLAGS.} */
+        pushl   $0
+        popf
+
+        /* @r{Push the pointer to the Multiboot information structure.} */
+        pushl   %ebx
+        /* @r{Push the magic value.} */
+        pushl   %eax
+
+        /* @r{Now enter the C main function...} */
+        call    EXT_C(cmain)
+
+        /* @r{Halt.} */
+        pushl   $halt_message
+        call    EXT_C(printf)
+        
+loop:   hlt
+        jmp     loop
+
+halt_message:
+        .asciz  "Halted."
+
+        /* @r{Our stack area.} */
+        .comm   stack, STACK_SIZE
+        
\ No newline at end of file
diff --git a/docs/grub-install.8 b/docs/grub-install.8
new file mode 100644
index 0000000..ac588a3
--- /dev/null
+++ b/docs/grub-install.8
@@ -0,0 +1,52 @@
+.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.23.
+.TH GRUB-INSTALL "8" "May 2005" "grub-install (GNU GRUB 0.97)" FSF
+.SH NAME
+grub-install \- install GRUB on your drive
+.SH SYNOPSIS
+.B grub-install
+[\fIOPTION\fR] \fIinstall_device\fR
+.SH DESCRIPTION
+Install GRUB on your drive.
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+print this message and exit
+.TP
+\fB\-v\fR, \fB\-\-version\fR
+print the version information and exit
+.TP
+\fB\-\-root\-directory\fR=\fIDIR\fR
+install GRUB images under the directory DIR
+instead of the root directory
+.TP
+\fB\-\-grub\-shell\fR=\fIFILE\fR
+use FILE as the grub shell
+.TP
+\fB\-\-no\-floppy\fR
+do not probe any floppy drive
+.TP
+\fB\-\-force\-lba\fR
+force GRUB to use LBA mode even for a buggy
+BIOS
+.TP
+\fB\-\-recheck\fR
+probe a device map even if it already exists
+.PP
+INSTALL_DEVICE can be a GRUB device name or a system device filename.
+.PP
+grub-install copies GRUB images into the DIR/boot directory specfied by
+\fB\-\-root\-directory\fR, and uses the grub shell to install grub into the boot
+sector.
+.SH "REPORTING BUGS"
+Report bugs to <bug-grub@gnu.org>.
+.SH "SEE ALSO"
+The full documentation for
+.B grub-install
+is maintained as a Texinfo manual.  If the
+.B info
+and
+.B grub-install
+programs are properly installed at your site, the command
+.IP
+.B info grub-install
+.PP
+should give you access to the complete manual.
diff --git a/docs/grub-md5-crypt.8 b/docs/grub-md5-crypt.8
new file mode 100644
index 0000000..07db531
--- /dev/null
+++ b/docs/grub-md5-crypt.8
@@ -0,0 +1,32 @@
+.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.23.
+.TH GRUB-MD5-CRYPT "8" "May 2005" "grub-md5-crypt (GNU GRUB )" FSF
+.SH NAME
+grub-md5-crypt \- Encrypt a password in MD5 format
+.SH SYNOPSIS
+.B grub-md5-crypt
+[\fIOPTION\fR]
+.SH DESCRIPTION
+Encrypt a password in MD5 format.
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+print this message and exit
+.TP
+\fB\-v\fR, \fB\-\-version\fR
+print the version information and exit
+.TP
+\fB\-\-grub\-shell\fR=\fIFILE\fR
+use FILE as the grub shell
+.SH "REPORTING BUGS"
+Report bugs to <bug-grub@gnu.org>.
+.SH "SEE ALSO"
+The full documentation for
+.B grub-md5-crypt
+is maintained as a Texinfo manual.  If the
+.B info
+and
+.B grub-md5-crypt
+programs are properly installed at your site, the command
+.IP
+.B info grub-md5-crypt
+.PP
+should give you access to the complete manual.
diff --git a/docs/grub-terminfo.8 b/docs/grub-terminfo.8
new file mode 100644
index 0000000..ac9f19c
--- /dev/null
+++ b/docs/grub-terminfo.8
@@ -0,0 +1,29 @@
+.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.23.
+.TH GRUB-TERMINFO "8" "May 2005" "grub-terminfo (GNU GRUB 0.97)" FSF
+.SH NAME
+grub-terminfo \- Generate a terminfo command from a terminfo name
+.SH SYNOPSIS
+.B grub-terminfo
+\fITERMNAME\fR
+.SH DESCRIPTION
+Generate a terminfo command from a terminfo name.
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+print this message and exit
+.TP
+\fB\-v\fR, \fB\-\-version\fR
+print the version information and exit
+.SH "REPORTING BUGS"
+Report bugs to <bug-grub@gnu.org>.
+.SH "SEE ALSO"
+The full documentation for
+.B grub-terminfo
+is maintained as a Texinfo manual.  If the
+.B info
+and
+.B grub-terminfo
+programs are properly installed at your site, the command
+.IP
+.B info grub-terminfo
+.PP
+should give you access to the complete manual.
diff --git a/docs/grub.8 b/docs/grub.8
new file mode 100644
index 0000000..92149f7
--- /dev/null
+++ b/docs/grub.8
@@ -0,0 +1,71 @@
+.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.23.
+.TH GRUB "8" "May 2005" "grub (GNU GRUB 0.97)" FSF
+.SH NAME
+grub \- the grub shell
+.SH SYNOPSIS
+.B grub
+[\fIOPTION\fR]...
+.SH DESCRIPTION
+Enter the GRand Unified Bootloader command shell.
+.TP
+\fB\-\-batch\fR
+turn on batch mode for non-interactive use
+.TP
+\fB\-\-boot\-drive\fR=\fIDRIVE\fR
+specify stage2 boot_drive [default=0x0]
+.TP
+\fB\-\-config\-file\fR=\fIFILE\fR
+specify stage2 config_file [default=/boot/grub/menu.lst]
+.TP
+\fB\-\-device\-map\fR=\fIFILE\fR
+use the device map file FILE
+.TP
+\fB\-\-help\fR
+display this message and exit
+.TP
+\fB\-\-hold\fR
+wait until a debugger will attach
+.TP
+\fB\-\-install\-partition\fR=\fIPAR\fR
+specify stage2 install_partition [default=0x20000]
+.TP
+\fB\-\-no\-config\-file\fR
+do not use the config file
+.TP
+\fB\-\-no\-curses\fR
+do not use curses
+.TP
+\fB\-\-no\-floppy\fR
+do not probe any floppy drive
+.TP
+\fB\-\-no\-pager\fR
+do not use internal pager
+.TP
+\fB\-\-preset\-menu\fR
+use the preset menu
+.TP
+\fB\-\-probe\-second\-floppy\fR
+probe the second floppy drive
+.TP
+\fB\-\-read\-only\fR
+do not write anything to devices
+.TP
+\fB\-\-verbose\fR
+print verbose messages
+.TP
+\fB\-\-version\fR
+print version information and exit
+.SH "REPORTING BUGS"
+Report bugs to <bug-grub@gnu.org>.
+.SH "SEE ALSO"
+The full documentation for
+.B grub
+is maintained as a Texinfo manual.  If the
+.B info
+and
+.B grub
+programs are properly installed at your site, the command
+.IP
+.B info grub
+.PP
+should give you access to the complete manual.
diff --git a/docs/grub.info b/docs/grub.info
new file mode 100644
index 0000000..f48783c
--- /dev/null
+++ b/docs/grub.info
Binary files differ
diff --git a/docs/grub.texi b/docs/grub.texi
new file mode 100644
index 0000000..51d330a
--- /dev/null
+++ b/docs/grub.texi
@@ -0,0 +1,3984 @@
+\input texinfo
+@c -*-texinfo-*-
+@c %**start of header
+@setfilename grub.info
+@settitle GRUB Manual
+@c %**end of header
+
+@include version.texi
+
+@c Unify all our little indices for now.
+@syncodeindex fn cp
+@syncodeindex vr cp
+@syncodeindex ky cp
+@syncodeindex pg cp
+@syncodeindex tp cp
+
+@footnotestyle separate
+@paragraphindent 3
+@finalout
+
+@dircategory Kernel
+@direntry
+* GRUB: (grub).                 The GRand Unified Bootloader
+* grub-install: (grub)Invoking grub-install.    Install GRUB on your drive
+* grub-md5-crypt: (grub)Invoking grub-md5-crypt.        Encrypt a password
+                                                        in MD5 format
+* grub-terminfo: (grub)Invoking grub-terminfo.  Generate a terminfo
+                                                command from a
+                                                terminfo name
+* grub-set-default: (grub)Invoking grub-set-default.    Set a default boot
+                                                        entry
+* mbchk: (grub)Invoking mbchk.  Check for the format of a Multiboot kernel
+@end direntry
+
+@setchapternewpage odd
+
+@ifinfo
+Copyright @copyright{} 1999,2000,2001,2002,2004 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries a copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end ifinfo
+
+@titlepage
+@sp 10
+@title the GRUB manual
+@subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}.
+@author Gordon Matzigkeit
+@author Yoshinori K. Okuji
+@c The following two commands start the copyright page.
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1999,2000,2001,2002,2004 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by Free Software Foundation.
+@end titlepage
+
+@c Output the table of contents at the beginning.
+@contents
+
+@finalout
+@headings double
+
+@ifnottex
+@node Top
+@top GRUB manual
+
+This is the documentation of GNU GRUB, the GRand Unified Bootloader,
+a flexible and powerful boot loader program for @sc{pc}s.
+
+This edition documents version @value{VERSION}.
+@end ifnottex
+
+@menu
+* Introduction::                Capturing the spirit of GRUB
+* Naming convention::           Names of your drives in GRUB
+* Installation::                Installing GRUB on your drive
+* Booting::                     How to boot different operating systems
+* Configuration::               Writing your own configuration file
+* Network::                     Downloading OS images from a network
+* Serial terminal::             Using GRUB via a serial line
+* Preset Menu::                 Embedding a configuration file into GRUB
+* Security::                    Improving the security
+* Images::                      GRUB image files
+* Filesystem::                  Filesystem syntax and semantics
+* Interface::                   The menu and the command-line
+* Commands::                    The list of available builtin commands
+* Troubleshooting::             Error messages produced by GRUB
+* Invoking the grub shell::     How to use the grub shell
+* Invoking grub-install::       How to use the GRUB installer
+* Invoking grub-md5-crypt::     How to generate a cryptic password
+* Invoking grub-terminfo::      How to generate a terminfo command
+* Invoking grub-set-default::   How to set a default boot entry
+* Invoking mbchk::              How to use the Multiboot checker
+* Obtaining and Building GRUB:: How to obtain and build GRUB
+* Reporting bugs::              Where you should send a bug report
+* Future::                      Some future plans on GRUB
+* Internals::                   Hacking GRUB
+* Index::
+@end menu
+
+
+@node Introduction
+@chapter Introduction to GRUB
+
+@menu
+* Overview::                    What exactly GRUB is and how to use it
+* History::                     From maggot to house fly
+* Features::                    GRUB features
+* Role of a boot loader::       The role of a boot loader
+@end menu
+
+
+@node Overview
+@section Overview
+
+Briefly, a @dfn{boot loader} is the first software program that runs when
+a computer starts.  It is responsible for loading and transferring
+control to an operating system @dfn{kernel} software (such as Linux or
+GNU Mach).  The kernel, in turn, initializes the rest of the operating
+system (e.g. a GNU system).
+
+GNU GRUB is a very powerful boot loader, which can load a wide variety
+of free operating systems, as well as proprietary operating systems with
+chain-loading@footnote{@dfn{chain-load} is the mechanism for loading
+unsupported operating systems by loading another boot loader. It is
+typically used for loading DOS or Windows.}. GRUB is designed to
+address the complexity of booting a personal computer; both the
+program and this manual are tightly bound to that computer platform,
+although porting to other platforms may be addressed in the future.
+
+One of the important features in GRUB is flexibility; GRUB understands
+filesystems and kernel executable formats, so you can load an arbitrary
+operating system the way you like, without recording the physical
+position of your kernel on the disk. Thus you can load the kernel
+just by specifying its file name and the drive and partition where the
+kernel resides.
+
+When booting with GRUB, you can use either a command-line interface
+(@pxref{Command-line interface}), or a menu interface (@pxref{Menu
+interface}). Using the command-line interface, you type the drive
+specification and file name of the kernel manually. In the menu
+interface, you just select an OS using the arrow keys. The menu is
+based on a configuration file which you prepare beforehand
+(@pxref{Configuration}). While in the menu, you can switch to the
+command-line mode, and vice-versa. You can even edit menu entries
+before using them.
+
+In the following chapters, you will learn how to specify a drive, a
+partition, and a file name (@pxref{Naming convention}) to GRUB, how to
+install GRUB on your drive (@pxref{Installation}), and how to boot your
+OSes (@pxref{Booting}), step by step.
+
+Besides the GRUB boot loader itself, there is a @dfn{grub shell}
+@command{grub} (@pxref{Invoking the grub shell}) which can be run when
+you are in your operating system. It emulates the boot loader and can
+be used for installing the boot loader.
+
+
+@node History
+@section History of GRUB
+
+GRUB originated in 1995 when Erich Boleyn was trying to boot the GNU
+Hurd with the University of Utah's Mach 4 microkernel (now known as GNU
+Mach).  Erich and Brian Ford designed the Multiboot Specification
+(@pxref{Top, Multiboot Specification, Motivation, multiboot, The Multiboot
+Specification}), because they were determined not to add to the large
+number of mutually-incompatible PC boot methods.
+
+Erich then began modifying the FreeBSD boot loader so that it would
+understand Multiboot. He soon realized that it would be a lot easier
+to write his own boot loader from scratch than to keep working on the
+FreeBSD boot loader, and so GRUB was born.
+
+Erich added many features to GRUB, but other priorities prevented him
+from keeping up with the demands of its quickly-expanding user base. In
+1999, Gordon Matzigkeit and Yoshinori K. Okuji adopted GRUB as an
+official GNU package, and opened its development by making the latest
+sources available via anonymous CVS. @xref{Obtaining and Building
+GRUB}, for more information.
+
+
+@node Features
+@section GRUB features
+
+The primary requirement for GRUB is that it be compliant with the
+@dfn{Multiboot Specification}, which is described in @ref{Top, Multiboot
+Specification, Motivation, multiboot, The Multiboot Specification}.
+
+The other goals, listed in approximate order of importance, are:
+
+@itemize @bullet{}
+@item
+Basic functions must be straightforward for end-users.
+
+@item
+Rich functionality to support kernel experts and designers.
+
+@item
+Backward compatibility for booting FreeBSD, NetBSD, OpenBSD, and
+Linux. Proprietary kernels (such as DOS, Windows NT, and OS/2) are
+supported via a chain-loading function.
+@end itemize
+
+Except for specific compatibility modes (chain-loading and the Linux
+@dfn{piggyback} format), all kernels will be started in much the same
+state as in the Multiboot Specification. Only kernels loaded at 1 megabyte
+or above are presently supported. Any attempt to load below that
+boundary will simply result in immediate failure and an error message
+reporting the problem.
+
+In addition to the requirements above, GRUB has the following features
+(note that the Multiboot Specification doesn't require all the features
+that GRUB supports):
+
+@table @asis
+@item Recognize multiple executable formats
+Support many of the @dfn{a.out} variants plus @dfn{ELF}. Symbol
+tables are also loaded.
+
+@item Support non-Multiboot kernels
+Support many of the various free 32-bit kernels that lack Multiboot
+compliance (primarily FreeBSD, NetBSD, OpenBSD, and
+Linux). Chain-loading of other boot loaders is also supported.
+
+@item Load multiples modules
+Fully support the Multiboot feature of loading multiple modules.
+
+@item Load a configuration file
+Support a human-readable text configuration file with preset boot
+commands. You can also load another configuration file dynamically and
+embed a preset configuration file in a GRUB image file. The list of
+commands (@pxref{Commands}) are a superset of those supported on the
+command-line. An example configuration file is provided in
+@ref{Configuration}.
+
+@item Provide a menu interface
+A menu interface listing preset boot commands, with a programmable
+timeout, is available. There is no fixed limit on the number of boot
+entries, and the current implementation has space for several hundred.
+
+@item Have a flexible command-line interface
+A fairly flexible command-line interface, accessible from the menu,
+is available to edit any preset commands, or write a new boot command
+set from scratch. If no configuration file is present, GRUB drops to
+the command-line.
+
+The list of commands (@pxref{Commands}) are a subset of those supported
+for configuration files. Editing commands closely resembles the Bash
+command-line (@pxref{Command Line Editing, Bash, Command Line Editing,
+features, Bash Features}), with @key{TAB}-completion of commands,
+devices, partitions, and files in a directory depending on context.
+
+@item Support multiple filesystem types
+Support multiple filesystem types transparently, plus a useful explicit
+blocklist notation. The currently supported filesystem types are
+@dfn{BSD FFS}, @dfn{DOS FAT16 and FAT32}, @dfn{Minix fs}, @dfn{Linux
+ext2fs}, @dfn{ReiserFS}, @dfn{JFS}, @dfn{XFS}, and @dfn{VSTa
+fs}. @xref{Filesystem}, for more information.
+
+@item Support automatic decompression
+Can decompress files which were compressed by @command{gzip}. This
+function is both automatic and transparent to the user (i.e. all
+functions operate upon the uncompressed contents of the specified
+files). This greatly reduces a file size and loading time, a
+particularly great benefit for floppies.@footnote{There are a few
+pathological cases where loading a very badly organized ELF kernel might
+take longer, but in practice this never happen.}
+
+It is conceivable that some kernel modules should be loaded in a
+compressed state, so a different module-loading command can be specified
+to avoid uncompressing the modules.
+
+@item Access data on any installed device
+Support reading data from any or all floppies or hard disk(s) recognized
+by the BIOS, independent of the setting of the root device.
+
+@item Be independent of drive geometry translations
+Unlike many other boot loaders, GRUB makes the particular drive
+translation irrelevant. A drive installed and running with one
+translation may be converted to another translation without any adverse
+effects or changes in GRUB's configuration.
+
+@item Detect all installed @sc{ram}
+GRUB can generally find all the installed @sc{ram} on a PC-compatible
+machine. It uses an advanced BIOS query technique for finding all
+memory regions. As described on the Multiboot Specification (@pxref{Top,
+Multiboot Specification, Motivation, multiboot, The Multiboot
+Specification}), not all kernels make use of this information, but GRUB
+provides it for those who do.
+
+@item Support Logical Block Address mode
+In traditional disk calls (called @dfn{CHS mode}), there is a geometry
+translation problem, that is, the BIOS cannot access over 1024
+cylinders, so the accessible space is limited to at least 508 MB and to
+at most 8GB. GRUB can't universally solve this problem, as there is no
+standard interface used in all machines. However, several newer machines
+have the new interface, Logical Block Address (@dfn{LBA}) mode. GRUB
+automatically detects if LBA mode is available and uses it if
+available. In LBA mode, GRUB can access the entire disk.
+
+@item Support network booting
+GRUB is basically a disk-based boot loader but also has network
+support. You can load OS images from a network by using the @dfn{TFTP}
+protocol.
+
+@item Support remote terminals
+To support computers with no console, GRUB provides remote terminal
+support, so that you can control GRUB from a remote host. Only serial
+terminal support is implemented at the moment.
+@end table
+
+
+@node Role of a boot loader
+@section The role of a boot loader
+
+The following is a quotation from Gordon Matzigkeit, a GRUB fanatic:
+
+@quotation
+Some people like to acknowledge both the operating system and kernel when
+they talk about their computers, so they might say they use
+``GNU/Linux'' or ``GNU/Hurd''.  Other people seem to think that the
+kernel is the most important part of the system, so they like to call
+their GNU operating systems ``Linux systems.''
+
+I, personally, believe that this is a grave injustice, because the
+@emph{boot loader} is the most important software of all. I used to
+refer to the above systems as either ``LILO''@footnote{The LInux LOader,
+a boot loader that everybody uses, but nobody likes.} or ``GRUB''
+systems.
+
+Unfortunately, nobody ever understood what I was talking about; now I
+just use the word ``GNU'' as a pseudonym for GRUB.
+
+So, if you ever hear people talking about their alleged ``GNU'' systems,
+remember that they are actually paying homage to the best boot loader
+around@dots{} GRUB!
+@end quotation
+
+We, the GRUB maintainers, do not (usually) encourage Gordon's level of
+fanaticism, but it helps to remember that boot loaders deserve
+recognition.  We hope that you enjoy using GNU GRUB as much as we did
+writing it.
+
+
+@node Naming convention
+@chapter Naming convention
+
+The device syntax used in GRUB is a wee bit different from what you may
+have seen before in your operating system(s), and you need to know it so
+that you can specify a drive/partition.
+
+Look at the following examples and explanations:
+
+@example
+(fd0)
+@end example
+
+First of all, GRUB requires that the device name be enclosed with
+@samp{(} and @samp{)}. The @samp{fd} part means that it is a floppy
+disk. The number @samp{0} is the drive number, which is counted from
+@emph{zero}. This expression means that GRUB will use the whole floppy
+disk.
+
+@example
+(hd0,1)
+@end example
+
+Here, @samp{hd} means it is a hard disk drive. The first integer
+@samp{0} indicates the drive number, that is, the first hard disk, while
+the second integer, @samp{1}, indicates the partition number (or the
+@sc{pc} slice number in the BSD terminology). Once again, please note
+that the partition numbers are counted from @emph{zero}, not from
+one. This expression means the second partition of the first hard disk
+drive. In this case, GRUB uses one partition of the disk, instead of the
+whole disk.
+
+@example
+(hd0,4)
+@end example
+
+This specifies the first @dfn{extended partition} of the first hard disk
+drive. Note that the partition numbers for extended partitions are
+counted from @samp{4}, regardless of the actual number of primary
+partitions on your hard disk.
+
+@example
+(hd1,a)
+@end example
+
+This means the BSD @samp{a} partition of the second hard disk. If you
+need to specify which @sc{pc} slice number should be used, use something
+like this: @samp{(hd1,0,a)}. If the @sc{pc} slice number is omitted,
+GRUB searches for the first @sc{pc} slice which has a BSD @samp{a}
+partition.
+
+Of course, to actually access the disks or partitions with GRUB, you
+need to use the device specification in a command, like @samp{root
+(fd0)} or @samp{unhide (hd0,2)}. To help you find out which number
+specifies a partition you want, the GRUB command-line
+(@pxref{Command-line interface}) options have argument
+completion. This means that, for example, you only need to type
+
+@example
+root (
+@end example
+
+followed by a @key{TAB}, and GRUB will display the list of drives,
+partitions, or file names. So it should be quite easy to determine the
+name of your target partition, even with minimal knowledge of the
+syntax.
+
+Note that GRUB does @emph{not} distinguish IDE from SCSI - it simply
+counts the drive numbers from zero, regardless of their type. Normally,
+any IDE drive number is less than any SCSI drive number, although that
+is not true if you change the boot sequence by swapping IDE and SCSI
+drives in your BIOS.
+
+Now the question is, how to specify a file? Again, consider an
+example:
+
+@example
+(hd0,0)/vmlinuz
+@end example
+
+This specifies the file named @samp{vmlinuz}, found on the first
+partition of the first hard disk drive. Note that the argument
+completion works with file names, too.
+
+That was easy, admit it. Now read the next chapter, to find out how to
+actually install GRUB on your drive.
+
+
+@node Installation
+@chapter Installation
+
+In order to install GRUB as your boot loader, you need to first
+install the GRUB system and utilities under your UNIX-like operating
+system (@pxref{Obtaining and Building GRUB}). You can do this either
+from the source tarball, or as a package for your OS.
+
+After you have done that, you need to install the boot loader on a
+drive (floppy or hard disk). There are two ways of doing that - either
+using the utility @command{grub-install} (@pxref{Invoking
+grub-install}) on a UNIX-like OS, or by running GRUB itself from a
+floppy. These are quite similar, however the utility might probe a
+wrong BIOS drive, so you should be careful.
+
+Also, if you install GRUB on a UNIX-like OS, please make sure that you
+have an emergency boot disk ready, so that you can rescue your computer
+if, by any chance, your hard drive becomes unusable (unbootable).
+
+GRUB comes with boot images, which are normally put in the directory
+@file{/usr/lib/grub/i386-pc}. If you do not use grub-install, then
+you need to copy the files @file{stage1}, @file{stage2}, and
+@file{*stage1_5} to the directory @file{/boot/grub}, and run the
+@command{grub-set-default} (@pxref{Invoking grub-set-default}) if you
+intend to use @samp{default saved} (@pxref{default}) in your
+configuration file. Hereafter, the directory where GRUB images are
+initially placed (normally @file{/usr/lib/grub/i386-pc}) will be
+called the @dfn{image directory}, and the directory where the boot
+loader needs to find them (usually @file{/boot/grub}) will be called
+the @dfn{boot directory}.
+
+@menu
+* Creating a GRUB boot floppy::
+* Installing GRUB natively::
+* Installing GRUB using grub-install::
+* Making a GRUB bootable CD-ROM::
+@end menu
+
+
+@node Creating a GRUB boot floppy
+@section Creating a GRUB boot floppy
+
+To create a GRUB boot floppy, you need to take the files @file{stage1}
+and @file{stage2} from the image directory, and write them to the first
+and the second block of the floppy disk, respectively.
+
+@strong{Caution:} This procedure will destroy any data currently stored
+on the floppy.
+
+On a UNIX-like operating system, that is done with the following
+commands:
+
+@example
+@group
+# @kbd{cd /usr/lib/grub/i386-pc}
+# @kbd{dd if=stage1 of=/dev/fd0 bs=512 count=1}
+1+0 records in
+1+0 records out
+# @kbd{dd if=stage2 of=/dev/fd0 bs=512 seek=1}
+153+1 records in
+153+1 records out
+#
+@end group
+@end example
+
+The device file name may be different. Consult the manual for your OS.
+
+
+@node Installing GRUB natively
+@section Installing GRUB natively
+
+@strong{Caution:} Installing GRUB's stage1 in this manner will erase the
+normal boot-sector used by an OS.
+
+GRUB can currently boot GNU Mach, Linux, FreeBSD, NetBSD, and OpenBSD
+directly, so using it on a boot sector (the first sector of a
+partition) should be okay. But generally, it would be a good idea to
+back up the first sector of the partition on which you are installing
+GRUB's stage1. This isn't as important if you are installing GRUB on
+the first sector of a hard disk, since it's easy to reinitialize it
+(e.g. by running @samp{FDISK /MBR} from DOS).
+
+If you decide to install GRUB in the native environment, which is
+definitely desirable, you'll need to create a GRUB boot disk, and
+reboot your computer with it. Otherwise, see @ref{Installing GRUB using
+grub-install}.
+
+Once started, GRUB will show the command-line interface
+(@pxref{Command-line interface}). First, set the GRUB's @dfn{root
+device}@footnote{Note that GRUB's root device doesn't necessarily mean
+your OS's root partition; if you need to specify a root partition for
+your OS, add the argument into the command @command{kernel}.} to the
+partition containing the boot directory, like this:
+
+@example
+grub> @kbd{root (hd0,0)}
+@end example
+
+If you are not sure which partition actually holds this directory, use the
+command @command{find} (@pxref{find}), like this:
+
+@example
+grub> @kbd{find /boot/grub/stage1}
+@end example
+
+This will search for the file name @file{/boot/grub/stage1} and show the
+devices which contain the file.
+
+Once you've set the root device correctly, run the command
+@command{setup} (@pxref{setup}):
+
+@example
+grub> @kbd{setup (hd0)}
+@end example
+
+This command will install the GRUB boot loader on the Master Boot
+Record (MBR) of the first drive. If you want to put GRUB into the boot
+sector of a partition instead of putting it in the MBR, specify the
+partition into which you want to install GRUB:
+
+@example
+grub> @kbd{setup (hd0,0)}
+@end example
+
+If you install GRUB into a partition or a drive other than the first
+one, you must chain-load GRUB from another boot loader. Refer to the
+manual for the boot loader to know how to chain-load GRUB.
+
+After using the setup command, you will boot into GRUB without the
+GRUB floppy. See the chapter @ref{Booting} to find out how to boot
+your operating systems from GRUB.
+
+
+@node Installing GRUB using grub-install
+@section Installing GRUB using grub-install
+
+@strong{Caution:} This procedure is definitely less safe, because
+there are several ways in which your computer can become
+unbootable. For example, most operating systems don't tell GRUB how to
+map BIOS drives to OS devices correctly---GRUB merely @dfn{guesses}
+the mapping. This will succeed in most cases, but not
+always. Therefore, GRUB provides you with a map file called the
+@dfn{device map}, which you must fix if it is wrong. @xref{Device
+map}, for more details.
+
+If you still do want to install GRUB under a UNIX-like OS (such
+as @sc{gnu}), invoke the program @command{grub-install} (@pxref{Invoking
+grub-install}) as the superuser (@dfn{root}).
+
+The usage is basically very simple. You only need to specify one
+argument to the program, namely, where to install the boot loader. The
+argument can be either a device file (like @samp{/dev/hda}) or a
+partition specified in GRUB's notation. For example, under Linux the
+following will install GRUB into the MBR of the first IDE disk:
+
+@example
+# @kbd{grub-install /dev/hda}
+@end example
+
+Likewise, under GNU/Hurd, this has the same effect:
+
+@example
+# @kbd{grub-install /dev/hd0}
+@end example
+
+If it is the first BIOS drive, this is the same as well:
+
+@example
+# @kbd{grub-install '(hd0)'}
+@end example
+
+Or you can omit the parentheses:
+
+@example
+# @kbd{grub-install hd0}
+@end example
+
+But all the above examples assume that GRUB should use images under
+the root directory. If you want GRUB to use images under a directory
+other than the root directory, you need to specify the option
+@option{--root-directory}. The typical usage is that you create a GRUB
+boot floppy with a filesystem. Here is an example:
+
+@example
+@group
+# @kbd{mke2fs /dev/fd0}
+# @kbd{mount -t ext2 /dev/fd0 /mnt}
+# @kbd{grub-install --root-directory=/mnt fd0}
+# @kbd{umount /mnt}
+@end group
+@end example
+
+Another example is when you have a separate boot partition
+which is mounted at @file{/boot}. Since GRUB is a boot loader, it
+doesn't know anything about mountpoints at all. Thus, you need to run
+@command{grub-install} like this:
+
+@example
+# @kbd{grub-install --root-directory=/boot /dev/hda}
+@end example
+
+By the way, as noted above, it is quite difficult to guess BIOS drives
+correctly under a UNIX-like OS. Thus, @command{grub-install} will prompt
+you to check if it could really guess the correct mappings, after the
+installation. The format is defined in @ref{Device map}. Please be
+quite careful. If the output is wrong, it is unlikely that your
+computer will be able to boot with no problem.
+
+Note that @command{grub-install} is actually just a shell script and the
+real task is done by the grub shell @command{grub} (@pxref{Invoking the
+grub shell}). Therefore, you may run @command{grub} directly to install
+GRUB, without using @command{grub-install}. Don't do that, however,
+unless you are very familiar with the internals of GRUB. Installing a
+boot loader on a running OS may be extremely dangerous.
+
+
+@node Making a GRUB bootable CD-ROM
+@section Making a GRUB bootable CD-ROM
+
+GRUB supports the @dfn{no emulation mode} in the El Torito
+specification@footnote{El Torito is a specification for bootable CD
+using BIOS functions.}. This means that you can use the whole CD-ROM
+from GRUB and you don't have to make a floppy or hard disk image file,
+which can cause compatibility problems.
+
+For booting from a CD-ROM, GRUB uses a special Stage 2 called
+@file{stage2_eltorito}. The only GRUB files you need to have in your 
+bootable CD-ROM are this @file{stage2_eltorito} and optionally a config file
+@file{menu.lst}. You don't need to use @file{stage1} or @file{stage2},
+because El Torito is quite different from the standard boot process.
+
+Here is an example of procedures to make a bootable CD-ROM
+image. First, make a top directory for the bootable image, say,
+@samp{iso}:
+
+@example
+$ @kbd{mkdir iso}
+@end example
+
+Make a directory for GRUB:
+
+@example
+$ @kbd{mkdir -p iso/boot/grub}
+@end example
+
+Copy the file @file{stage2_eltorito}:
+
+@example
+$ @kbd{cp /usr/lib/grub/i386-pc/stage2_eltorito iso/boot/grub}
+@end example
+
+If desired, make the config file @file{menu.lst} under @file{iso/boot/grub}
+(@pxref{Configuration}), and copy any files and directories for the disc to the
+directory @file{iso/}.
+
+Finally, make a ISO9660 image file like this:
+
+@example
+$ @kbd{mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot \
+    -boot-load-size 4 -boot-info-table -o grub.iso iso}
+@end example
+
+This produces a file named @file{grub.iso}, which then can be burned
+into a CD (or a DVD).  @kbd{mkisofs} has already set up the disc to boot
+from the @kbd{boot/grub/stage2_eltorito} file, so there is no need to 
+setup GRUB on the disc.  (Note that the @kbd{-boot-load-size 4} bit is
+required for compatibility with the BIOS on many older machines.)
+
+You can use the device @samp{(cd)} to access a CD-ROM in your
+config file. This is not required; GRUB automatically sets the root device 
+to @samp{(cd)} when booted from a CD-ROM. It is only necessary to refer to 
+@samp{(cd)} if you want to access other drives as well.
+
+
+@node Booting
+@chapter Booting
+
+GRUB can load Multiboot-compliant kernels in a consistent way,
+but for some free operating systems you need to use some OS-specific
+magic.
+
+@menu
+* General boot methods::        How to boot OSes with GRUB generally
+* OS-specific notes::           Notes on some operating systems
+* Making your system robust::   How to make your system robust
+@end menu
+
+
+@node General boot methods
+@section How to boot operating systems
+
+GRUB has two distinct boot methods. One of the two is to load an
+operating system directly, and the other is to chain-load another boot
+loader which then will load an operating system actually. Generally
+speaking, the former is more desirable, because you don't need to
+install or maintain other boot loaders and GRUB is flexible enough to
+load an operating system from an arbitrary disk/partition. However,
+the latter is sometimes required, since GRUB doesn't support all the
+existing operating systems natively.
+
+@menu
+* Loading an operating system directly::
+* Chain-loading::
+@end menu
+
+
+@node Loading an operating system directly
+@subsection How to boot an OS directly with GRUB
+
+Multiboot (@pxref{Top, Multiboot Specification, Motivation, multiboot,
+The Multiboot Specification}) is the native format supported by GRUB.
+For the sake of convenience, there is also support for Linux, FreeBSD,
+NetBSD and OpenBSD. If you want to boot other operating systems, you
+will have to chain-load them (@pxref{Chain-loading}).
+
+Generally, GRUB can boot any Multiboot-compliant OS in the following
+steps:
+
+@enumerate
+@item
+Set GRUB's root device to the drive where the OS images are stored with
+the command @command{root} (@pxref{root}).
+
+@item
+Load the kernel image with the command @command{kernel} (@pxref{kernel}).
+
+@item
+If you need modules, load them with the command @command{module}
+(@pxref{module}) or @command{modulenounzip} (@pxref{modulenounzip}).
+
+@item
+Run the command @command{boot} (@pxref{boot}).
+@end enumerate
+
+Linux, FreeBSD, NetBSD and OpenBSD can be booted in a similar
+manner. You load a kernel image with the command @command{kernel} and
+then run the command @command{boot}. If the kernel requires some
+parameters, just append the parameters to @command{kernel}, after the
+file name of the kernel. Also, please refer to @ref{OS-specific notes},
+for information on your OS-specific issues.
+
+
+@node Chain-loading
+@subsection Load another boot loader to boot unsupported operating systems
+
+If you want to boot an unsupported operating system (e.g. Windows 95),
+chain-load a boot loader for the operating system. Normally, the boot
+loader is embedded in the @dfn{boot sector} of the partition on which
+the operating system is installed.
+
+@enumerate
+@item
+Set GRUB's root device to the partition by the command
+@command{rootnoverify} (@pxref{rootnoverify}):
+
+@example
+grub> @kbd{rootnoverify (hd0,0)}
+@end example
+
+@item
+Set the @dfn{active} flag in the partition using the command
+@command{makeactive}@footnote{This is not necessary for most of the
+modern operating systems.} (@pxref{makeactive}):
+
+@example
+grub> @kbd{makeactive}
+@end example
+
+@item
+Load the boot loader with the command @command{chainloader}
+(@pxref{chainloader}):
+
+@example
+grub> @kbd{chainloader +1}
+@end example
+
+@samp{+1} indicates that GRUB should read one sector from the start of
+the partition. The complete description about this syntax can be found
+in @ref{Block list syntax}.
+
+@item
+Run the command @command{boot} (@pxref{boot}).
+@end enumerate
+
+However, DOS and Windows have some deficiencies, so you might have to
+use more complicated instructions. @xref{DOS/Windows}, for more
+information.
+
+
+@node OS-specific notes
+@section Some caveats on OS-specific issues
+
+Here, we describe some caveats on several operating systems.
+
+@menu
+* GNU/Hurd::
+* GNU/Linux::
+* FreeBSD::
+* NetBSD::
+* OpenBSD::
+* DOS/Windows::
+* SCO UnixWare::
+* QNX::
+@end menu
+
+
+@node GNU/Hurd
+@subsection GNU/Hurd
+
+Since GNU/Hurd is Multiboot-compliant, it is easy to boot it; there is
+nothing special about it. But do not forget that you have to specify a
+root partition to the kernel.
+
+@enumerate
+@item
+Set GRUB's root device to the same drive as GNU/Hurd's. Probably the
+command @code{find /boot/gnumach} or similar can help you
+(@pxref{find}).
+
+@item
+Load the kernel and the module, like this:
+
+@example
+@group
+grub> @kbd{kernel /boot/gnumach root=hd0s1}
+grub> @kbd{module /boot/serverboot}
+@end group
+@end example
+
+@item
+Run the command @command{boot} (@pxref{boot}).
+@end enumerate
+
+
+@node GNU/Linux
+@subsection GNU/Linux
+
+It is relatively easy to boot GNU/Linux from GRUB, because it somewhat
+resembles to boot a Multiboot-compliant OS.
+
+@enumerate
+@item
+Set GRUB's root device to the same drive as GNU/Linux's. Probably the
+command @code{find /vmlinuz} or similar can help you (@pxref{find}).
+
+@item
+Load the kernel:
+
+@example
+grub> @kbd{kernel /vmlinuz root=/dev/hda1}
+@end example
+
+If you need to specify some kernel parameters, just append them to the
+command. For example, to set @option{vga} to @samp{ext}, do this:
+
+@example
+grub> @kbd{kernel /vmlinuz root=/dev/hda1 vga=ext}
+@end example
+
+See the documentation in the Linux source tree for complete
+information on the available options.
+
+@item
+If you use an initrd, execute the command @command{initrd}
+(@pxref{initrd}) after @command{kernel}:
+
+@example
+grub> @kbd{initrd /initrd}
+@end example
+
+@item
+Finally, run the command @command{boot} (@pxref{boot}).
+@end enumerate
+
+@strong{Caution:} If you use an initrd and specify the @samp{mem=}
+option to the kernel to let it use less than actual memory size, you
+will also have to specify the same memory size to GRUB. To let GRUB know
+the size, run the command @command{uppermem} @emph{before} loading the
+kernel. @xref{uppermem}, for more information.
+
+
+@node FreeBSD
+@subsection FreeBSD
+
+GRUB can load the kernel directly, either in ELF or a.out format. But
+this is not recommended, since FreeBSD's bootstrap interface sometimes
+changes heavily, so GRUB can't guarantee to pass kernel parameters
+correctly.
+
+Thus, we'd recommend loading the very flexible loader
+@file{/boot/loader} instead. See this example:
+
+@example
+@group
+grub> @kbd{root (hd0,a)}
+grub> @kbd{kernel /boot/loader}
+grub> @kbd{boot}
+@end group
+@end example
+
+
+@node NetBSD
+@subsection NetBSD
+
+GRUB can load NetBSD a.out and ELF directly, follow these steps:
+
+@enumerate
+@item
+Set GRUB's root device with @command{root} (@pxref{root}).
+
+@item
+Load the kernel with @command{kernel} (@pxref{kernel}). You should
+append the ugly option @option{--type=netbsd}, if you want to load an
+ELF kernel, like this:
+
+@example
+grub> @kbd{kernel --type=netbsd /netbsd-elf}
+@end example
+
+@item
+Run @command{boot} (@pxref{boot}).
+@end enumerate
+
+For now, however, GRUB doesn't allow you to pass kernel parameters, so
+it may be better to chain-load it instead. For more information, please
+see @ref{Chain-loading}.
+
+
+@node OpenBSD
+@subsection OpenBSD
+
+The booting instruction is exactly the same as for NetBSD
+(@pxref{NetBSD}).
+
+
+@node DOS/Windows
+@subsection DOS/Windows
+
+GRUB cannot boot DOS or Windows directly, so you must chain-load them
+(@pxref{Chain-loading}). However, their boot loaders have some critical
+deficiencies, so it may not work to just chain-load them. To overcome
+the problems, GRUB provides you with two helper functions.
+
+If you have installed DOS (or Windows) on a non-first hard disk, you
+have to use the disk swapping technique, because that OS cannot boot
+from any disks but the first one. The workaround used in GRUB is the
+command @command{map} (@pxref{map}), like this:
+
+@example
+@group
+grub> @kbd{map (hd0) (hd1)}
+grub> @kbd{map (hd1) (hd0)}
+@end group
+@end example
+
+This performs a @dfn{virtual} swap between your first and second hard
+drive.
+
+@strong{Caution:} This is effective only if DOS (or Windows) uses BIOS
+to access the swapped disks. If that OS uses a special driver for the
+disks, this probably won't work.
+
+Another problem arises if you installed more than one set of DOS/Windows
+onto one disk, because they could be confused if there are more than one
+primary partitions for DOS/Windows. Certainly you should avoid doing
+this, but there is a solution if you do want to do so. Use the partition
+hiding/unhiding technique.
+
+If GRUB @dfn{hide}s a DOS (or Windows) partition (@pxref{hide}), DOS (or
+Windows) will ignore the partition. If GRUB @dfn{unhide}s a DOS (or
+Windows) partition (@pxref{unhide}), DOS (or Windows) will detect the
+partition. Thus, if you have installed DOS (or Windows) on the first
+and the second partition of the first hard disk, and you want to boot
+the copy on the first partition, do the following:
+
+@example
+@group
+grub> @kbd{unhide (hd0,0)}
+grub> @kbd{hide (hd0,1)}
+grub> @kbd{rootnoverify (hd0,0)}
+grub> @kbd{chainloader +1}
+grub> @kbd{makeactive}
+grub> @kbd{boot}
+@end group
+@end example
+
+
+@node SCO UnixWare
+@subsection SCO UnixWare
+
+It is known that the signature in the boot loader for SCO UnixWare is
+wrong, so you will have to specify the option @option{--force} to
+@command{chainloader} (@pxref{chainloader}), like this:
+
+@example
+@group
+grub> @kbd{rootnoverify (hd1,0)}
+grub> @kbd{chainloader --force +1}
+grub> @kbd{makeactive}
+grub> @kbd{boot}
+@end group
+@end example
+
+
+@node QNX
+@subsection QNX
+
+QNX seems to use a bigger boot loader, so you need to boot it up, like
+this:
+
+@example
+@group
+grub> @kbd{rootnoverify (hd1,1)}
+grub> @kbd{chainloader +4}
+grub> @kbd{boot}
+@end group
+@end example
+
+
+@node Making your system robust
+@section How to make your system robust
+
+When you test a new kernel or a new OS, it is important to make sure
+that your computer can boot even if the new system is unbootable. This
+is crucial especially if you maintain servers or remote systems. To
+accomplish this goal, you need to set up two things:
+
+@enumerate
+@item
+You must maintain a system which is always bootable. For instance, if
+you test a new kernel, you need to keep a working kernel in a
+different place. And, it would sometimes be very nice to even have a
+complete copy of a working system in a different partition or disk.
+
+@item
+You must direct GRUB to boot a working system when the new system
+fails. This is possible with the @dfn{fallback} system in GRUB.
+@end enumerate
+
+The former requirement is very specific to each OS, so this
+documentation does not cover that topic. It is better to consult some
+backup tools.
+
+So let's see the GRUB part. There are two possibilities: one of them
+is quite simple but not very robust, and the other is a bit complex to
+set up but probably the best solution to make sure that your system
+can start as long as GRUB itself is bootable.
+
+@menu
+* Booting once-only::
+* Booting fallback systems::
+@end menu
+
+
+@node Booting once-only
+@subsection Booting once-only
+
+You can teach GRUB to boot an entry only at next boot time. Suppose
+that your have an old kernel @file{old_kernel} and a new kernel
+@file{new_kernel}. You know that @file{old_kernel} can boot
+your system correctly, and you want to test @file{new_kernel}.
+
+To ensure that your system will go back to the old kernel even if the
+new kernel fails (e.g. it panics), you can specify that GRUB should
+try the new kernel only once and boot the old kernel after that.
+
+First, modify your configuration file. Here is an example:
+
+@example
+@group
+default saved        # This is important!!!
+timeout 10
+
+title the old kernel
+root (hd0,0)
+kernel /old_kernel
+savedefault
+
+title the new kernel
+root (hd0,0)
+kernel /new_kernel
+savedefault 0         # This is important!!!
+@end group
+@end example
+
+Note that this configuration file uses @samp{default saved}
+(@pxref{default}) at the head and @samp{savedefault 0}
+(@pxref{savedefault}) in the entry for the new kernel. This means
+that GRUB boots a saved entry by default, and booting the entry for the
+new kernel saves @samp{0} as the saved entry.
+
+With this configuration file, after all, GRUB always tries to boot the
+old kernel after it booted the new one, because @samp{0} is the entry
+of @code{the old kernel}.
+
+The next step is to tell GRUB to boot the new kernel at next boot
+time. For this, execute @command{grub-set-default} (@pxref{Invoking
+grub-set-default}):
+
+@example
+# @kbd{grub-set-default 1}
+@end example
+
+This command sets the saved entry to @samp{1}, that is, to the new
+kernel.
+
+This method is useful, but still not very robust, because GRUB stops
+booting, if there is any error in the boot entry, such that the new
+kernel has an invalid executable format. Thus, it it even better to
+use the @dfn{fallback} mechanism of GRUB. Look at next subsection for
+this feature.
+
+
+@node Booting fallback systems
+@subsection Booting fallback systems
+
+GRUB supports a fallback mechanism of booting one or more other
+entries if a default boot entry fails. You can specify multiple
+fallback entries if you wish.
+
+Suppose that you have three systems, @samp{A}, @samp{B} and
+@samp{C}. @samp{A} is a system which you want to boot by
+default. @samp{B} is a backup system which is supposed to boot
+safely. @samp{C} is another backup system which is used in case where
+@samp{B} is broken.
+
+Then you may want GRUB to boot the first system which is bootable
+among @samp{A}, @samp{B} and @samp{C}. A configuration file can be
+written in this way:
+
+@example
+@group
+default saved        # This is important!!!
+timeout 10
+fallback 1 2         # This is important!!!
+
+title A
+root (hd0,0)
+kernel /kernel
+savedefault fallback # This is important!!!
+
+title B
+root (hd1,0)
+kernel /kernel
+savedefault fallback # This is important!!!
+
+title C
+root (hd2,0)
+kernel /kernel
+savedefault
+@end group
+@end example
+
+Note that @samp{default saved} (@pxref{default}), @samp{fallback 1 2}
+and @samp{savedefault fallback} are used. GRUB will boot a saved entry
+by default and save a fallback entry as next boot entry with this
+configuration.
+
+When GRUB tries to boot @samp{A}, GRUB saves @samp{1} as next boot
+entry, because the command @command{fallback} specifies that @samp{1}
+is the first fallback entry. The entry @samp{1} is @samp{B}, so GRUB
+will try to boot @samp{B} at next boot time.
+
+Likewise, when GRUB tries to boot @samp{B}, GRUB saves @samp{2} as
+next boot entry, because @command{fallback} specifies @samp{2} as next
+fallback entry. This makes sure that GRUB will boot @samp{C} after
+booting @samp{B}.
+
+It is noteworthy that GRUB uses fallback entries both when GRUB
+itself fails in booting an entry and when @samp{A} or @samp{B} fails
+in starting up your system. So this solution ensures that your system
+is started even if GRUB cannot find your kernel or if your kernel
+panics.
+
+However, you need to run @command{grub-set-default} (@pxref{Invoking
+grub-set-default}) when @samp{A} starts correctly or you fix @samp{A}
+after it crashes, since GRUB always sets next boot entry to a fallback
+entry. You should run this command in a startup script such as
+@file{rc.local} to boot @samp{A} by default:
+
+@example
+# @kbd{grub-set-default 0}
+@end example
+
+where @samp{0} is the number of the boot entry for the system
+@samp{A}.
+
+If you want to see what is current default entry, you can look at the
+file @file{/boot/grub/default} (or @file{/grub/default} in
+some systems). Because this file is plain-text, you can just
+@command{cat} this file. But it is strongly recommended @strong{not to
+modify this file directly}, because GRUB may fail in saving a default
+entry in this file, if you change this file in an unintended
+manner. Therefore, you should use @command{grub-set-default} when you
+need to change the default entry.
+
+
+@node Configuration
+@chapter Configuration
+
+You've probably noticed that you need to type several commands to boot your
+OS. There's a solution to that - GRUB provides a menu interface
+(@pxref{Menu interface}) from which you can select an item (using arrow
+keys) that will do everything to boot an OS.
+
+To enable the menu, you need a configuration file,
+@file{menu.lst} under the boot directory. We'll analyze an example
+file.
+
+The file first contains some general settings, the menu interface
+related options. You can put these commands (@pxref{Menu-specific
+commands}) before any of the items (starting with @command{title}
+(@pxref{title})).
+
+@example
+@group
+#
+# Sample boot menu configuration file
+#
+@end group
+@end example
+
+As you may have guessed, these lines are comments. Lines starting with a
+hash character (@samp{#}), and blank lines, are ignored by GRUB.
+
+@example
+@group
+# By default, boot the first entry.
+default 0
+@end group
+@end example
+
+The first entry (here, counting starts with number zero, not one!) will
+be the default choice.
+
+@example
+@group
+# Boot automatically after 30 secs.
+timeout 30
+@end group
+@end example
+
+As the comment says, GRUB will boot automatically in 30 seconds, unless
+interrupted with a keypress.
+
+@example
+@group
+# Fallback to the second entry.
+fallback 1
+@end group
+@end example
+
+If, for any reason, the default entry doesn't work, fall back to the
+second one (this is rarely used, for obvious reasons).
+
+Note that the complete descriptions of these commands, which are menu
+interface specific, can be found in @ref{Menu-specific
+commands}. Other descriptions can be found in @ref{Commands}.
+
+Now, on to the actual OS definitions. You will see that each entry
+begins with a special command, @command{title} (@pxref{title}), and the
+action is described after it. Note that there is no command
+@command{boot} (@pxref{boot}) at the  end of each item. That is because
+GRUB automatically executes @command{boot} if it loads other commands
+successfully.
+
+The argument for the command @command{title} is used to display a short
+title/description of the entry in the menu. Since @command{title}
+displays the argument as is, you can write basically anything there.
+
+@example
+@group
+# For booting GNU/Hurd
+title  GNU/Hurd
+root   (hd0,0)
+kernel /boot/gnumach.gz root=hd0s1
+module /boot/serverboot.gz
+@end group
+@end example
+
+This boots GNU/Hurd from the first hard disk.
+
+@example
+@group
+# For booting GNU/Linux
+title  GNU/Linux
+kernel (hd1,0)/vmlinuz root=/dev/hdb1
+@end group
+@end example
+
+This boots GNU/Linux, but from the second hard disk.
+
+@example
+@group
+# For booting Mach (getting kernel from floppy)
+title  Utah Mach4 multiboot
+root   (hd0,2)
+pause  Insert the diskette now^G!!
+kernel (fd0)/boot/kernel root=hd0s3
+module (fd0)/boot/bootstrap
+@end group
+@end example
+
+This boots Mach with a kernel on a floppy, but the root filesystem at
+hd0s3. It also contains a @command{pause} line (@pxref{pause}), which
+will cause GRUB to display a prompt and delay, before actually executing
+the rest of the commands and booting.
+
+@example
+@group
+# For booting FreeBSD
+title  FreeBSD
+root   (hd0,2,a)
+kernel /boot/loader
+@end group
+@end example
+
+This item will boot FreeBSD kernel loaded from the @samp{a} partition of
+the third @sc{pc} slice of the first hard disk.
+
+@example
+@group
+# For booting OS/2
+title OS/2
+root  (hd0,1)
+makeactive
+# chainload OS/2 bootloader from the first sector
+chainloader +1
+# This is similar to "chainload", but loads a specific file
+#chainloader /boot/chain.os2
+@end group
+@end example
+
+This will boot OS/2, using a chain-loader (@pxref{Chain-loading}).
+
+@example
+@group
+# For booting Windows NT or Windows95
+title Windows NT / Windows 95 boot menu
+root        (hd0,0)
+makeactive
+chainloader +1
+# For loading DOS if Windows NT is installed
+# chainload /bootsect.dos
+@end group
+@end example
+
+The same as the above, but for Windows.
+
+@example
+@group
+# For installing GRUB into the hard disk
+title Install GRUB into the hard disk
+root    (hd0,0)
+setup   (hd0)
+@end group
+@end example
+
+This will just (re)install GRUB onto the hard disk.
+
+@example
+# Change the colors.
+title Change the colors
+color light-green/brown blink-red/blue
+@end example
+
+In the last entry, the command @command{color} is used (@pxref{color}),
+to change the menu colors (try it!). This command is somewhat special,
+because it can be used both in the command-line and in the menu. GRUB
+has several such commands, see @ref{General commands}.
+
+We hope that you now understand how to use the basic features of
+GRUB. To learn more about GRUB, see the following chapters.
+
+
+@node Network
+@chapter Downloading OS images from a network
+
+Although GRUB is a disk-based boot loader, it does provide network
+support. To use the network support, you need to enable at least one
+network driver in the GRUB build process. For more information please
+see @file{netboot/README.netboot} in the source distribution.
+
+@menu
+* General usage of network support::
+* Diskless::
+@end menu
+
+
+@node General usage of network support
+@section How to set up your network
+
+GRUB requires a file server and optionally a server that will assign an
+IP address to the machine on which GRUB is running. For the former, only
+TFTP is supported at the moment. The latter is either BOOTP, DHCP or a
+RARP server@footnote{RARP is not advised, since it cannot serve much
+information}. It is not necessary to run both the servers on one
+computer. How to configure these servers is beyond the scope of this
+document, so please refer to the manuals specific to those
+protocols/servers.
+
+If you decided to use a server to assign an IP address, set up the
+server and run @command{bootp} (@pxref{bootp}), @command{dhcp}
+(@pxref{dhcp}) or @command{rarp} (@pxref{rarp}) for BOOTP, DHCP or RARP,
+respectively. Each command will show an assigned IP address, a netmask,
+an IP address for your TFTP server and a gateway. If any of the
+addresses is wrong or it causes an error, probably the configuration of
+your servers isn't set up properly.
+
+Otherwise, run @command{ifconfig}, like this:
+
+@example
+grub> @kbd{ifconfig --address=192.168.110.23 --server=192.168.110.14}
+@end example
+
+You can also use @command{ifconfig} in conjuction with @command{bootp},
+@command{dhcp} or @command{rarp} (e.g. to reassign the server address
+manually). @xref{ifconfig}, for more details.
+
+Finally, download your OS images from your network. The network can be
+accessed using the network drive @samp{(nd)}. Everything else is very
+similar to the normal instructions (@pxref{Booting}).
+
+Here is an example:
+
+@example
+@group
+grub> @kbd{bootp}
+Probing... [NE*000]
+NE2000 base ...
+Address: 192.168.110.23    Netmask: 255.255.255.0
+Server: 192.168.110.14     Gateway: 192.168.110.1
+
+grub> @kbd{root (nd)}
+grub> @kbd{kernel /tftproot/gnumach.gz root=sd0s1}
+grub> @kbd{module /tftproot/serverboot.gz}
+grub> @kbd{boot}
+@end group
+@end example
+
+
+@node Diskless
+@section Booting from a network
+
+It is sometimes very useful to boot from a network, especially when you
+use a machine which has no local disk. In this case, you need to obtain
+a kind of Net Boot @sc{rom}, such as a PXE @sc{rom} or a free software
+package like Etherboot. Such a Boot @sc{rom} first boots the machine,
+sets up the network card installed into the machine, and downloads a
+second stage boot image from the network. Then, the second image will
+try to boot an operating system actually from the network.
+
+GRUB provides two second stage images, @file{nbgrub} and
+@file{pxegrub} (@pxref{Images}). These images are the same as the
+normal Stage 2, except that they set up a network automatically, and try
+to load a configuration file from the network, if specified. The usage
+is very simple: If the machine has a PXE @sc{rom}, use
+@file{pxegrub}. If the machine has an NBI loader such as Etherboot, use
+@file{nbgrub}. There is no difference between them except their
+formats. Since the way to load a second stage image you want to use
+should be described in the manual on your Net Boot @sc{rom}, please
+refer to the manual, for more information.
+
+However, there is one thing specific to GRUB. Namely, how to specify a
+configuration file in a BOOTP/DHCP server. For now, GRUB uses the tag
+@samp{150}, to get the name of a configuration file. The following is an
+example with a BOOTP configuration:
+
+@example
+@group
+.allhost:hd=/tmp:bf=null:\
+        :ds=145.71.35.1 145.71.32.1:\
+        :sm=255.255.254.0:\
+        :gw=145.71.35.1:\
+        :sa=145.71.35.5:
+
+foo:ht=1:ha=63655d0334a7:ip=145.71.35.127:\
+        :bf=/nbgrub:\
+        :tc=.allhost:\
+        :T150="(nd)/tftpboot/menu.lst.foo":
+@end group
+@end example
+
+Note that you should specify the drive name @code{(nd)} in the name of
+the configuration file. This is because you might change the root drive
+before downloading the configuration from the TFTP server when the
+preset menu feature is used (@pxref{Preset Menu}).
+
+See the manual of your BOOTP/DHCP server for more information. The
+exact syntax should differ a little from the example.
+
+
+@node Serial terminal
+@chapter Using GRUB via a serial line
+
+This chapter describes how to use the serial terminal support in GRUB.
+
+If you have many computers or computers with no display/keyboard, it
+could be very useful to control the computers through serial
+communications. To connect one computer with another via a serial line,
+you need to prepare a null-modem (cross) serial cable, and you may need
+to have multiport serial boards, if your computer doesn't have extra
+serial ports. In addition, a terminal emulator is also required, such as
+minicom. Refer to a manual of your operating system, for more
+information.
+
+As for GRUB, the instruction to set up a serial terminal is quite
+simple. First of all, make sure that you haven't specified the option
+@option{--disable-serial} to the configure script when you built your
+GRUB images. If you get them in binary form, probably they have serial
+terminal support already.
+
+Then, initialize your serial terminal after GRUB starts up. Here is an
+example:
+
+@example
+@group
+grub> @kbd{serial --unit=0 --speed=9600}
+grub> @kbd{terminal serial}
+@end group
+@end example
+
+The command @command{serial} initializes the serial unit 0 with the
+speed 9600bps. The serial unit 0 is usually called @samp{COM1}, so, if
+you want to use COM2, you must specify @samp{--unit=1} instead. This
+command accepts many other options, so please refer to @ref{serial},
+for more details.
+
+The command @command{terminal} (@pxref{terminal}) chooses which type of
+terminal you want to use. In the case above, the terminal will be a
+serial terminal, but you can also pass @code{console} to the command,
+as @samp{terminal serial console}. In this case, a terminal in which
+you press any key will be selected as a GRUB terminal.
+
+However, note that GRUB assumes that your terminal emulator is
+compatible with VT100 by default. This is true for most terminal
+emulators nowadays, but you should pass the option @option{--dumb} to
+the command if your terminal emulator is not VT100-compatible or
+implements few VT100 escape sequences. If you specify this option then
+GRUB provides you with an alternative menu interface, because the normal
+menu requires several fancy features of your terminal.
+
+
+@node Preset Menu
+@chapter Embedding a configuration file into GRUB
+
+GRUB supports a @dfn{preset menu} which is to be always loaded before
+starting. The preset menu feature is useful, for example, when your
+computer has no console but a serial cable. In this case, it is
+critical to set up the serial terminal as soon as possible, since you
+cannot see any message until the serial terminal begins to work. So it
+is good to run the commands @command{serial} (@pxref{serial}) and
+@command{terminal} (@pxref{terminal}) before anything else at the
+start-up time.
+
+How the preset menu works is slightly complicated:
+
+@enumerate
+@item
+GRUB checks if the preset menu feature is used, and loads the preset
+menu, if available. This includes running commands and reading boot
+entries, like an ordinary configuration file.
+
+@item
+GRUB checks if the configuration file is available. Note that this check
+is performed @strong{regardless of the existence of the preset
+menu}. The configuration file is loaded even if the preset menu was
+loaded.
+
+@item
+If the preset menu includes any boot entries, they are cleared when
+the configuration file is loaded. It doesn't matter whether the
+configuration file has any entries or no entry. The boot entries in the
+preset menu are used only when GRUB fails in loading the configuration
+file.
+@end enumerate
+
+To enable the preset menu feature, you must rebuild GRUB specifying a
+file to the configure script with the option
+@option{--enable-preset-menu}. The file has the same semantics as
+normal configuration files (@pxref{Configuration}).
+
+Another point you should take care is that the diskless support
+(@pxref{Diskless}) diverts the preset menu. Diskless images embed a
+preset menu to execute the command @command{bootp} (@pxref{bootp})
+automatically, unless you specify your own preset menu to the configure
+script. This means that you must put commands to initialize a network in
+the preset menu yourself, because diskless images don't set it up
+implicitly, when you use the preset menu explicitly.
+
+Therefore, a typical preset menu used with diskless support would be
+like this:
+
+@example
+@group
+# Set up the serial terminal, first of all.
+serial --unit=0 --speed=19200
+terminal --timeout=0 serial
+
+# Initialize the network.
+dhcp
+@end group
+@end example
+
+
+@node Security
+@chapter Protecting your computer from cracking
+
+You may be interested in how to prevent ordinary users from doing
+whatever they like, if you share your computer with other people. So
+this chapter describes how to improve the security of GRUB.
+
+One thing which could be a security hole is that the user can do too
+many things with GRUB, because GRUB allows one to modify its configuration
+and run arbitrary commands at run-time. For example, the user can even
+read @file{/etc/passwd} in the command-line interface by the command
+@command{cat} (@pxref{cat}). So it is necessary to disable all the
+interactive operations.
+
+Thus, GRUB provides a @dfn{password} feature, so that only administrators
+can start the interactive operations (i.e. editing menu entries and
+entering the command-line interface). To use this feature, you need to
+run the command @command{password} in your configuration file
+(@pxref{password}), like this:
+
+@example
+password --md5 PASSWORD
+@end example
+
+If this is specified, GRUB disallows any interactive control, until you
+press the key @key{p} and enter a correct password.  The option
+@option{--md5} tells GRUB that @samp{PASSWORD} is in MD5 format.  If it
+is omitted, GRUB assumes the @samp{PASSWORD} is in clear text.
+
+You can encrypt your password with the command @command{md5crypt}
+(@pxref{md5crypt}). For example, run the grub shell (@pxref{Invoking the
+grub shell}), and enter your password:
+
+@example
+@group
+grub> md5crypt
+Password: **********
+Encrypted: $1$U$JK7xFegdxWH6VuppCUSIb.
+@end group
+@end example
+
+Then, cut and paste the encrypted password to your configuration file.
+
+Also, you can specify an optional argument to @command{password}. See
+this example:
+
+@example
+password PASSWORD /boot/grub/menu-admin.lst
+@end example
+
+In this case, GRUB will load @file{/boot/grub/menu-admin.lst} as a
+configuration file when you enter the valid password.
+
+Another thing which may be dangerous is that any user can choose any
+menu entry. Usually, this wouldn't be problematic, but you might want to
+permit only administrators to run some of your menu entries, such as an
+entry for booting an insecure OS like DOS.
+
+GRUB provides the command @command{lock} (@pxref{lock}). This command
+always fails until you enter the valid password, so you can use it, like
+this:
+
+@example
+@group
+title Boot DOS
+lock
+rootnoverify (hd0,1)
+makeactive
+chainload +1
+@end group
+@end example
+
+You should insert @command{lock} right after @command{title}, because
+any user can execute commands in an entry until GRUB encounters
+@command{lock}.
+
+You can also use the command @command{password} instead of
+@command{lock}. In this case the boot process will ask for the password
+and stop if it was entered incorrectly.  Since the @command{password}
+takes its own @var{PASSWORD} argument this is useful if you want
+different passwords for different entries.
+
+
+@node Images
+@chapter GRUB image files
+
+GRUB consists of several images: two essential stages, optional stages
+called @dfn{Stage 1.5}, one image for bootable CD-ROM, and two network
+boot images. Here is a short overview of them. @xref{Internals}, for
+more details.
+
+@table @file
+@item stage1
+This is an essential image used for booting up GRUB. Usually, this is
+embedded in an MBR or the boot sector of a partition. Because a PC boot
+sector is 512 bytes, the size of this image is exactly 512 bytes.
+
+All @file{stage1} must do is to load Stage 2 or Stage 1.5 from a local
+disk. Because of the size restriction, @file{stage1} encodes the
+location of Stage 2 (or Stage 1.5) in a block list format, so it never
+understand any filesystem structure.
+
+@item stage2
+This is the core image of GRUB. It does everything but booting up
+itself. Usually, this is put in a filesystem, but that is not required.
+
+@item e2fs_stage1_5
+@itemx fat_stage1_5
+@itemx ffs_stage1_5
+@itemx jfs_stage1_5
+@itemx minix_stage1_5
+@itemx reiserfs_stage1_5
+@itemx vstafs_stage1_5
+@itemx xfs_stage1_5
+
+These are called @dfn{Stage 1.5}, because they serve as a bridge
+between @file{stage1} and @file{stage2}, that is to say, Stage 1.5 is
+loaded by Stage 1 and Stage 1.5 loads Stage 2. The difference between
+@file{stage1} and @file{*_stage1_5} is that the former doesn't
+understand any filesystem while the latter understands one filesystem
+(e.g. @file{e2fs_stage1_5} understands ext2fs). So you can move the
+Stage 2 image to another location safely, even after GRUB has been
+installed.
+
+While Stage 2 cannot generally be embedded in a fixed area as the size
+is so large, Stage 1.5 can be installed into the area right after an MBR,
+or the boot loader area of a ReiserFS or a FFS.
+
+@item stage2_eltorito
+This is a boot image for CD-ROMs using the @dfn{no emulation mode} in
+El Torito specification. This is identical to Stage 2, except that
+this boots up without Stage 1 and sets up a special drive @samp{(cd)}.
+
+@item nbgrub
+This is a network boot image for the Network Image Proposal used by some
+network boot loaders, such as Etherboot. This is mostly the same as
+Stage 2, but it also sets up a network and loads a configuration file
+from the network.
+
+@item pxegrub
+This is another network boot image for the Preboot Execution Environment
+used by several Netboot ROMs. This is identical to @file{nbgrub}, except
+for the format.
+@end table
+
+
+@node Filesystem
+@chapter Filesystem syntax and semantics
+
+GRUB uses a special syntax for specifying disk drives which can be
+accessed by BIOS. Because of BIOS limitations, GRUB cannot distinguish
+between IDE, ESDI, SCSI, or others. You must know yourself which BIOS
+device is equivalent to which OS device. Normally, that will be clear if
+you see the files in a device or use the command @command{find}
+(@pxref{find}).
+
+@menu
+* Device syntax::               How to specify devices
+* File name syntax::            How to specify files
+* Block list syntax::           How to specify block lists
+@end menu
+
+
+@node Device syntax
+@section How to specify devices
+
+The device syntax is like this:
+
+@example
+@code{(@var{device}[,@var{part-num}][,@var{bsd-subpart-letter}])}
+@end example
+
+@samp{[]} means the parameter is optional. @var{device} should be
+either @samp{fd} or @samp{hd} followed by a digit, like @samp{fd0}.
+But you can also set @var{device} to a hexadecimal or a decimal number
+which is a BIOS drive number, so the following are equivalent:
+
+@example
+(hd0)
+(0x80)
+(128)
+@end example
+
+@var{part-num} represents the partition number of @var{device}, starting
+from zero for primary partitions and from four for extended partitions,
+and @var{bsd-subpart-letter} represents the BSD disklabel subpartition,
+such as @samp{a} or @samp{e}.
+
+A shortcut for specifying BSD subpartitions is
+@code{(@var{device},@var{bsd-subpart-letter})}, in this case, GRUB
+searches for the first PC partition containing a BSD disklabel, then
+finds the subpartition @var{bsd-subpart-letter}. Here is an example:
+
+@example
+(hd0,a)
+@end example
+
+The syntax @samp{(hd0)} represents using the entire disk (or the
+MBR when installing GRUB), while the syntax @samp{(hd0,0)}
+represents using the first partition of the disk (or the boot sector
+of the partition when installing GRUB).
+
+If you enabled the network support, the special drive, @samp{(nd)}, is
+also available. Before using the network drive, you must initialize the
+network. @xref{Network}, for more information.
+
+If you boot GRUB from a CD-ROM, @samp{(cd)} is available. @xref{Making
+a GRUB bootable CD-ROM}, for details.
+
+
+@node File name syntax
+@section How to specify files
+
+There are two ways to specify files, by @dfn{absolute file name} and by
+@dfn{block list}.
+
+An absolute file name resembles a Unix absolute file name, using
+@samp{/} for the directory separator (not @samp{\} as in DOS). One
+example is @samp{(hd0,0)/boot/grub/menu.lst}. This means the file
+@file{/boot/grub/menu.lst} in the first partition of the first hard
+disk. If you omit the device name in an absolute file name, GRUB uses
+GRUB's @dfn{root device} implicitly. So if you set the root device to,
+say, @samp{(hd1,0)} by the command @command{root} (@pxref{root}), then
+@code{/boot/kernel} is the same as @code{(hd1,0)/boot/kernel}.
+
+
+@node Block list syntax
+@section How to specify block lists
+
+A block list is used for specifying a file that doesn't appear in the
+filesystem, like a chainloader. The syntax is
+@code{[@var{offset}]+@var{length}[,[@var{offset}]+@var{length}]@dots{}}.
+Here is an example:
+
+@example
+@code{0+100,200+1,300+300}
+@end example
+
+This represents that GRUB should read blocks 0 through 99, block 200,
+and blocks 300 through 599. If you omit an offset, then GRUB assumes
+the offset is zero.
+
+Like the file name syntax (@pxref{File name syntax}), if a blocklist
+does not contain a device name, then GRUB uses GRUB's @dfn{root
+device}. So @code{(hd0,1)+1} is the same as @code{+1} when the root
+device is @samp{(hd0,1)}.
+
+
+@node Interface
+@chapter GRUB's user interface
+
+GRUB has both a simple menu interface for choosing preset entries from a
+configuration file, and a highly flexible command-line for performing
+any desired combination of boot commands.
+
+GRUB looks for its configuration file as soon as it is loaded. If one
+is found, then the full menu interface is activated using whatever
+entries were found in the file. If you choose the @dfn{command-line} menu
+option, or if the configuration file was not found, then GRUB drops to
+the command-line interface.
+
+@menu
+* Command-line interface::      The flexible command-line interface
+* Menu interface::              The simple menu interface
+* Menu entry editor::           Editing a menu entry
+* Hidden menu interface::       The hidden menu interface
+@end menu
+
+
+@node Command-line interface
+@section The flexible command-line interface
+
+The command-line interface provides a prompt and after it an editable
+text area much like a command-line in Unix or DOS. Each command is
+immediately executed after it is entered@footnote{However, this
+behavior will be changed in the future version, in a user-invisible
+way.}. The commands (@pxref{Command-line and menu entry commands}) are a
+subset of those available in the configuration file, used with exactly
+the same syntax.
+
+Cursor movement and editing of the text on the line can be done via a
+subset of the functions available in the Bash shell:
+
+@table @key
+@item C-f
+@itemx PC right key
+Move forward one character.
+
+@item C-b
+@itemx PC left key
+Move back one character.
+
+@item C-a
+@itemx HOME
+Move to the start of the line.
+
+@item C-e
+@itemx END
+Move the the end of the line.
+
+@item C-d
+@itemx DEL
+Delete the character underneath the cursor.
+
+@item C-h
+@itemx BS
+Delete the character to the left of the cursor.
+
+@item C-k
+Kill the text from the current cursor position to the end of the line.
+
+@item C-u
+Kill backward from the cursor to the beginning of the line.
+
+@item C-y
+Yank the killed text back into the buffer at the cursor.
+
+@item C-p
+@itemx PC up key
+Move up through the history list.
+
+@item C-n
+@itemx PC down key
+Move down through the history list.
+@end table
+
+When typing commands interactively, if the cursor is within or before
+the first word in the command-line, pressing the @key{TAB} key (or
+@key{C-i}) will display a listing of the available commands, and if the
+cursor is after the first word, the @kbd{@key{TAB}} will provide a
+completion listing of disks, partitions, and file names depending on the
+context. Note that to obtain a list of drives, one must open a
+parenthesis, as @command{root (}.
+
+Note that you cannot use the completion functionality in the TFTP
+filesystem. This is because TFTP doesn't support file name listing for
+the security.
+
+
+@node Menu interface
+@section The simple menu interface
+
+The menu interface is quite easy to use. Its commands are both
+reasonably intuitive and described on screen.
+
+Basically, the menu interface provides a list of @dfn{boot entries} to
+the user to choose from. Use the arrow keys to select the entry of
+choice, then press @key{RET} to run it.  An optional timeout is
+available to boot the default entry (the first one if not set), which is
+aborted by pressing any key.
+
+Commands are available to enter a bare command-line by pressing @key{c}
+(which operates exactly like the non-config-file version of GRUB, but
+allows one to return to the menu if desired by pressing @key{ESC}) or to
+edit any of the @dfn{boot entries} by pressing @key{e}.
+
+If you protect the menu interface with a password (@pxref{Security}),
+all you can do is choose an entry by pressing @key{RET}, or press
+@key{p} to enter the password.
+
+
+@node Menu entry editor
+@section Editing a menu entry
+
+The menu entry editor looks much like the main menu interface, but the
+lines in the menu are individual commands in the selected entry instead
+of entry names.
+
+If an @key{ESC} is pressed in the editor, it aborts all the changes made
+to the configuration entry and returns to the main menu interface.
+
+When a particular line is selected, the editor places the user in a
+special version of the GRUB command-line to edit that line.  When the
+user hits @key{RET}, GRUB replaces the line in question in the boot
+entry with the changes (unless it was aborted via @key{ESC},
+in which case the changes are thrown away).
+
+If you want to add a new line to the menu entry, press @key{o} if adding
+a line after the current line or press @key{O} if before the current
+line.
+
+To delete a line, hit the key @key{d}. Although GRUB unfortunately
+does not support @dfn{undo}, you can do almost the same thing by just
+returning to the main menu.
+
+
+@node Hidden menu interface
+@section The hidden menu interface
+
+When your terminal is dumb or you request GRUB to hide the menu
+interface explicitly with the command @command{hiddenmenu}
+(@pxref{hiddenmenu}), GRUB doesn't show the menu interface (@pxref{Menu
+interface}) and automatically boots the default entry, unless
+interrupted by pressing @key{ESC}.
+
+When you interrupt the timeout and your terminal is dumb, GRUB falls
+back to the command-line interface (@pxref{Command-line interface}).
+
+
+@node Commands
+@chapter The list of available commands
+
+In this chapter, we list all commands that are available in GRUB.
+
+Commands belong to different groups. A few can only be used in
+the global section of the configuration file (or ``menu''); most
+of them can be entered on the command-line and can be used either
+anywhere in the menu or specifically in the menu entries.
+
+@menu
+* Menu-specific commands::
+* General commands::
+* Command-line and menu entry commands::
+@end menu
+
+
+@node Menu-specific commands
+@section The list of commands for the menu only
+
+The semantics used in parsing the configuration file are the following:
+
+@itemize @bullet
+@item
+The menu-specific commands have to be used before any others.
+
+@item
+The files @emph{must} be in plain-text format.
+
+@item
+@samp{#} at the beginning of a line in a configuration file means it is
+only a comment.
+
+@item
+Options are separated by spaces.
+
+@item
+All numbers can be either decimal or hexadecimal. A hexadecimal number
+must be preceded by @samp{0x}, and is case-insensitive.
+
+@item
+Extra options or text at the end of the line are ignored unless otherwise
+specified.
+
+@item
+Unrecognized commands are added to the current entry, except before entries
+start, where they are ignored.
+@end itemize
+
+These commands can only be used in the menu:
+
+@menu
+* default::                     Set the default entry
+* fallback::                    Set the fallback entry
+* hiddenmenu::                  Hide the menu interface
+* timeout::                     Set the timeout
+* title::                       Start a menu entry
+@end menu
+
+
+@node default
+@subsection default
+
+@deffn Command default num
+Set the default entry to the entry number @var{num}. Numbering starts
+from 0, and the entry number 0 is the default if the command is not
+used.
+
+You can specify @samp{saved} instead of a number. In this case, the
+default entry is the entry saved with the command
+@command{savedefault}. @xref{savedefault}, for more information.
+@end deffn
+
+
+@node fallback
+@subsection fallback
+
+@deffn Command fallback num...
+Go into unattended boot mode: if the default boot entry has any errors,
+instead of waiting for the user to do something, immediately start
+over using the @var{num} entry (same numbering as the @code{default}
+command (@pxref{default})). This obviously won't help if the machine was
+rebooted by a kernel that GRUB loaded. You can specify multiple
+fallback entry numbers.
+@end deffn
+
+
+@node hiddenmenu
+@subsection hiddenmenu
+
+@deffn Command hiddenmenu
+Don't display the menu. If the command is used, no menu will be
+displayed on the control terminal, and the default entry will be
+booted after the timeout expired. The user can still request the
+menu to be displayed by pressing @key{ESC} before the timeout
+expires. See also @ref{Hidden menu interface}.
+@end deffn
+
+
+@node timeout
+@subsection timeout
+
+@deffn Command timeout sec
+Set a timeout, in @var{sec} seconds, before automatically booting the
+default entry (normally the first entry defined).
+@end deffn
+
+
+@node title
+@subsection title
+
+@deffn Command title name @dots{}
+Start a new boot entry, and set its name to the contents of the rest of
+the line, starting with the first non-space character.
+@end deffn
+
+
+@node General commands
+@section The list of general commands
+
+Commands usable anywhere in the menu and in the command-line.
+
+@menu
+* bootp::                       Initialize a network device via BOOTP
+* color::                       Color the menu interface
+* device::                      Specify a file as a drive
+* dhcp::                        Initialize a network device via DHCP
+* hide::                        Hide a partition
+* ifconfig::                    Configure a network device manually
+* pager::                       Change the state of the internal pager
+* partnew::                     Make a primary partition
+* parttype::                    Change the type of a partition
+* password::                    Set a password for the menu interface
+* rarp::                        Initialize a network device via RARP
+* serial::                      Set up a serial device
+* setkey::                      Configure the key map
+* terminal::                    Choose a terminal
+* terminfo::                    Define escape sequences for a terminal
+* tftpserver::                  Specify a TFTP server
+* unhide::                      Unhide a partition
+@end menu
+
+
+@node bootp
+@subsection bootp
+
+@deffn Command bootp [@option{--with-configfile}]
+Initialize a network device via the @dfn{BOOTP} protocol. This command
+is only available if GRUB is compiled with netboot support. See also
+@ref{Network}.
+
+If you specify @option{--with-configfile} to this command, GRUB will
+fetch and load a configuration file specified by your BOOTP server
+with the vendor tag @samp{150}.
+@end deffn
+
+
+@node color
+@subsection color
+
+@deffn Command color normal [highlight]
+Change the menu colors. The color @var{normal} is used for most
+lines in the menu (@pxref{Menu interface}), and the color
+@var{highlight} is used to highlight the line where the cursor
+points. If you omit @var{highlight}, then the inverted color of
+@var{normal} is used for the highlighted line. The format of a color is
+@code{@var{foreground}/@var{background}}. @var{foreground} and
+@var{background} are symbolic color names. A symbolic color name must be
+one of these:
+
+@itemize @bullet
+@item
+black
+
+@item
+blue
+
+@item
+green
+
+@item
+cyan
+
+@item
+red
+
+@item
+magenta
+
+@item
+brown
+
+@item
+light-gray
+
+@strong{These below can be specified only for the foreground.}
+
+@item
+dark-gray
+
+@item
+light-blue
+
+@item
+light-green
+
+@item
+light-cyan
+
+@item
+light-red
+
+@item
+light-magenta
+
+@item
+yellow
+
+@item
+white
+@end itemize
+
+But only the first eight names can be used for @var{background}. You can
+prefix @code{blink-} to @var{foreground} if you want a blinking
+foreground color.
+
+This command can be used in the configuration file and on the command
+line, so you may write something like this in your configuration file:
+
+@example
+@group
+# Set default colors.
+color light-gray/blue black/light-gray
+
+# Change the colors.
+title OS-BS like
+color magenta/blue black/magenta
+@end group
+@end example
+@end deffn
+
+
+@node device
+@subsection device
+
+@deffn Command device drive file
+In the grub shell, specify the file @var{file} as the actual drive for a
+@sc{bios} drive @var{drive}. You can use this command to create a disk
+image, and/or to fix the drives guessed by GRUB when GRUB fails to
+determine them correctly, like this:
+
+@example
+@group
+grub> @kbd{device (fd0) /floppy-image}
+grub> @kbd{device (hd0) /dev/sd0}
+@end group
+@end example
+
+This command can be used only in the grub shell (@pxref{Invoking the
+grub shell}).
+@end deffn
+
+
+@node dhcp
+@subsection dhcp
+
+@deffn Command dhcp [--with-configfile]
+Initialize a network device via the @dfn{DHCP} protocol. Currently,
+this command is just an alias for @command{bootp}, since the two
+protocols are very similar. This command is only available if GRUB is
+compiled with netboot support. See also @ref{Network}.
+
+If you specify @option{--with-configfile} to this command, GRUB will
+fetch and load a configuration file specified by your DHCP server
+with the vendor tag @samp{150}.
+@end deffn
+
+
+@node hide
+@subsection hide
+
+@deffn Command hide partition
+Hide the partition @var{partition} by setting the @dfn{hidden} bit in
+its partition type code. This is useful only when booting DOS or Windows
+and multiple primary FAT partitions exist in one disk. See also
+@ref{DOS/Windows}.
+@end deffn
+
+
+@node ifconfig
+@subsection ifconfig
+
+@deffn Command ifconfig [@option{--server=server}] [@option{--gateway=gateway}] [@option{--mask=mask}] [@option{--address=address}]
+Configure the IP address, the netmask, the gateway, and the server
+address of a network device manually. The values must be in dotted
+decimal format, like @samp{192.168.11.178}. The order of the options is
+not important. This command shows current network configuration, if no
+option is specified. See also @ref{Network}.
+@end deffn
+
+
+@node pager
+@subsection pager
+
+@deffn Command pager [flag]
+Toggle or set the state of the internal pager. If @var{flag} is
+@samp{on}, the internal pager is enabled. If @var{flag} is @samp{off},
+it is disabled. If no argument is given, the state is toggled.
+@end deffn
+
+
+@node partnew
+@subsection partnew
+
+@deffn Command partnew part type from len
+Create a new primary partition. @var{part} is a partition specification
+in GRUB syntax (@pxref{Naming convention}); @var{type} is the partition
+type and must be a number in the range @code{0-0xff}; @var{from} is
+the starting address and @var{len} is the length, both in sector units.
+@end deffn
+
+
+@node parttype
+@subsection parttype
+
+@deffn Command parttype part type
+Change the type of an existing partition.  @var{part} is a partition
+specification in GRUB syntax (@pxref{Naming convention}); @var{type}
+is the new partition type and must be a number in the range 0-0xff.
+@end deffn
+
+
+@node password
+@subsection password
+
+@deffn Command password [@option{--md5}] passwd [new-config-file]
+If used in the first section of a menu file, disable all interactive
+editing control (menu entry editor and command-line) and entries
+protected by the command @command{lock}. If the password @var{passwd} is
+entered, it loads the @var{new-config-file} as a new config file and
+restarts the GRUB Stage 2, if @var{new-config-file} is
+specified. Otherwise, GRUB will just unlock the privileged instructions.
+You can also use this command in the script section, in which case it
+will ask for the password, before continuing.  The option
+@option{--md5} tells GRUB that @var{passwd} is encrypted with
+@command{md5crypt} (@pxref{md5crypt}).
+@end deffn
+
+
+@node rarp
+@subsection rarp
+
+@deffn Command rarp
+Initialize a network device via the @dfn{RARP} protocol.  This command
+is only available if GRUB is compiled with netboot support. See also
+@ref{Network}.
+@end deffn
+
+
+@node serial
+@subsection serial
+
+@deffn Command serial [@option{--unit=unit}] [@option{--port=port}] [@option{--speed=speed}] [@option{--word=word}] [@option{--parity=parity}] [@option{--stop=stop}] [@option{--device=dev}]
+Initialize a serial device. @var{unit} is a number in the range 0-3
+specifying which serial port to use; default is 0, which corresponds to
+the port often called COM1. @var{port} is the I/O port where the UART
+is to be found; if specified it takes precedence over @var{unit}.
+@var{speed} is the transmission speed; default is 9600. @var{word} and
+@var{stop} are the number of data bits and stop bits. Data bits must
+be in the range 5-8 and stop bits must be 1 or 2. Default is 8 data
+bits and one stop bit. @var{parity} is one of @samp{no}, @samp{odd},
+@samp{even} and defaults to @samp{no}. The option @option{--device}
+can only be used in the grub shell and is used to specify the 
+tty device to be used in the host operating system (@pxref{Invoking the
+grub shell}).
+
+The serial port is not used as a communication channel unless the
+@command{terminal} command is used (@pxref{terminal}).
+
+This command is only available if GRUB is compiled with serial
+support. See also @ref{Serial terminal}.
+@end deffn
+
+
+@node setkey
+@subsection setkey
+
+@deffn Command setkey [to_key from_key]
+Change the keyboard map. The key @var{from_key} is mapped to the key
+@var{to_key}. If no argument is specified, reset key mappings. Note that 
+this command @emph{does not} exchange the keys. If you want to exchange 
+the keys, run this command again with the arguments exchanged, like this:
+
+@example
+grub> @kbd{setkey capslock control}
+grub> @kbd{setkey control capslock}
+@end example
+
+A key must be an alphabet letter, a digit, or one of these symbols:
+@samp{escape}, @samp{exclam}, @samp{at}, @samp{numbersign},
+@samp{dollar}, @samp{percent}, @samp{caret}, @samp{ampersand},
+@samp{asterisk}, @samp{parenleft}, @samp{parenright}, @samp{minus},
+@samp{underscore}, @samp{equal}, @samp{plus}, @samp{backspace},
+@samp{tab}, @samp{bracketleft}, @samp{braceleft}, @samp{bracketright},
+@samp{braceright}, @samp{enter}, @samp{control}, @samp{semicolon},
+@samp{colon}, @samp{quote}, @samp{doublequote}, @samp{backquote},
+@samp{tilde}, @samp{shift}, @samp{backslash}, @samp{bar}, @samp{comma},
+@samp{less}, @samp{period}, @samp{greater}, @samp{slash},
+@samp{question}, @samp{alt}, @samp{space}, @samp{capslock}, @samp{FX}
+(@samp{X} is a digit), and @samp{delete}. This table describes to which
+character each of the symbols corresponds:
+
+@table @samp
+@item exclam
+@samp{!}
+
+@item at
+@samp{@@}
+
+@item numbersign
+@samp{#}
+
+@item dollar
+@samp{$}
+
+@item percent
+@samp{%}
+
+@item caret
+@samp{^}
+
+@item ampersand
+@samp{&}
+
+@item asterisk
+@samp{*}
+
+@item parenleft
+@samp{(}
+
+@item parenright
+@samp{)}
+
+@item minus
+@samp{-}
+
+@item underscore
+@samp{_}
+
+@item equal
+@samp{=}
+
+@item plus
+@samp{+}
+
+@item bracketleft
+@samp{[}
+
+@item braceleft
+@samp{@{}
+
+@item bracketright
+@samp{]}
+
+@item braceright
+@samp{@}}
+
+@item semicolon
+@samp{;}
+
+@item colon
+@samp{:}
+
+@item quote
+@samp{'}
+
+@item doublequote
+@samp{"}
+
+@item backquote
+@samp{`}
+
+@item tilde
+@samp{~}
+
+@item backslash
+@samp{\}
+
+@item bar
+@samp{|}
+
+@item comma
+@samp{,}
+
+@item less
+@samp{<}
+
+@item period
+@samp{.}
+
+@item greater
+@samp{>}
+
+@item slash
+@samp{/}
+
+@item question
+@samp{?}
+
+@item space
+@samp{ }
+@end table
+@end deffn
+
+
+@node terminal
+@subsection terminal
+
+@deffn Command terminal [@option{--dumb}] [@option{--no-echo}] [@option{--no-edit}] [@option{--timeout=secs}] [@option{--lines=lines}] [@option{--silent}] [@option{console}] [@option{serial}] [@option{hercules}]
+Select a terminal for user interaction. The terminal is assumed to be
+VT100-compatible unless @option{--dumb} is specified. If both
+@option{console} and @option{serial} are specified, then GRUB will use
+the one where a key is entered first or the first when the timeout
+expires. If neither are specified, the current setting is
+reported. This command is only available if GRUB is compiled with serial
+support. See also @ref{Serial terminal}.
+
+This may not make sense for most users, but GRUB supports Hercules
+console as well. Hercules console is usable like the ordinary console,
+and the usage is quite similar to that for serial terminals: specify
+@option{hercules} as the argument.
+
+The option @option{--lines} defines the number of lines in your
+terminal, and it is used for the internal pager function. If you don't
+specify this option, the number is assumed as 24.
+
+The option @option{--silent} suppresses the message to prompt you to
+hit any key. This might be useful if your system has no terminal
+device.
+
+The option @option{--no-echo} has GRUB not to echo back input
+characters. This implies the option @option{--no-edit}.
+
+The option @option{--no-edit} disables the BASH-like editing feature.
+@end deffn
+
+
+@node terminfo
+@subsection terminfo
+
+@deffn Command terminfo @option{--name=name} @option{--cursor-address=seq} [@option{--clear-screen=seq}] [@option{--enter-standout-mode=seq}] [@option{--exit-standout-mode=seq}]
+Define the capabilities of your terminal. Use this command to define
+escape sequences, if it is not vt100-compatible. You may use @samp{\e}
+for @key{ESC} and @samp{^X} for a control character.
+
+You can use the utility @command{grub-terminfo} to generate
+appropriate arguments to this command. @xref{Invoking grub-terminfo}.
+
+If no option is specified, the current settings are printed.
+@end deffn
+
+
+@node tftpserver
+@subsection tftpserver
+
+@deffn Command tftpserver ipaddr
+@strong{Caution:} This command exists only for backward
+compatibility. Use @command{ifconfig} (@pxref{ifconfig}) instead.
+
+Override a TFTP server address returned by a BOOTP/DHCP/RARP server. The
+argument @var{ipaddr} must be in dotted decimal format, like
+@samp{192.168.0.15}.  This command is only available if GRUB is compiled
+with netboot support. See also @ref{Network}.
+@end deffn
+
+
+@node unhide
+@subsection unhide
+
+@deffn Command unhide partition
+Unhide the partition @var{partition} by clearing the @dfn{hidden} bit in
+its partition type code. This is useful only when booting DOS or Windows
+and multiple primary partitions exist on one disk. See also
+@ref{DOS/Windows}.
+@end deffn
+
+
+@node Command-line and menu entry commands
+@section The list of command-line and menu entry commands
+
+These commands are usable in the command-line and in menu entries.  If
+you forget a command, you can run the command @command{help}
+(@pxref{help}).
+
+@menu
+* blocklist::                   Get the block list notation of a file
+* boot::                        Start up your operating system
+* cat::                         Show the contents of a file
+* chainloader::                 Chain-load another boot loader
+* cmp::                         Compare two files
+* configfile::                  Load a configuration file
+* debug::                       Toggle the debug flag
+* displayapm::                  Display APM information
+* displaymem::                  Display memory configuration
+* embed::                       Embed Stage 1.5
+* find::                        Find a file
+* fstest::                      Test a filesystem
+* geometry::                    Manipulate the geometry of a drive
+* halt::                        Shut down your computer
+* help::                        Show help messages
+* impsprobe::                   Probe SMP
+* initrd::                      Load an initrd
+* install::                     Install GRUB
+* ioprobe::                     Probe I/O ports used for a drive
+* kernel::                      Load a kernel
+* lock::                        Lock a menu entry
+* makeactive::                  Make a partition active
+* map::                         Map a drive to another
+* md5crypt::                    Encrypt a password in MD5 format
+* module::                      Load a module
+* modulenounzip::               Load a module without decompression
+* pause::                       Wait for a key press
+* quit::                        Exit from the grub shell
+* reboot::                      Reboot your computer
+* read::                        Read data from memory
+* root::                        Set GRUB's root device
+* rootnoverify::                Set GRUB's root device without mounting
+* savedefault::                 Save current entry as the default entry
+* setup::                       Set up GRUB's installation automatically
+* testload::                    Load a file for testing a filesystem
+* testvbe::                     Test VESA BIOS EXTENSION
+* uppermem::                    Set the upper memory size
+* vbeprobe::                    Probe VESA BIOS EXTENSION
+@end menu
+
+
+@node blocklist
+@subsection blocklist
+
+@deffn Command blocklist file
+Print the block list notation of the file @var{file}. @xref{Block list
+syntax}.
+@end deffn
+
+
+@node boot
+@subsection boot
+
+@deffn Command boot
+Boot the OS or chain-loader which has been loaded. Only necessary if
+running the fully interactive command-line (it is implicit at the end of
+a menu entry).
+@end deffn
+
+
+@node cat
+@subsection cat
+
+@deffn Command cat file
+Display the contents of the file @var{file}. This command may be useful
+to remind you of your OS's root partition:
+
+@example
+grub> @kbd{cat /etc/fstab}
+@end example
+@end deffn
+
+
+@node chainloader
+@subsection chainloader
+
+@deffn Command chainloader [@option{--force}] file
+Load @var{file} as a chain-loader. Like any other file loaded by the
+filesystem code, it can use the blocklist notation to grab the first
+sector of the current partition with @samp{+1}. If you specify the
+option @option{--force}, then load @var{file} forcibly, whether it has a
+correct signature or not. This is required when you want to load a
+defective boot loader, such as SCO UnixWare 7.1 (@pxref{SCO UnixWare}).
+@end deffn
+
+
+@node cmp
+@subsection cmp
+
+@deffn Command cmp file1 file2
+Compare the file @var{file1} with the file @var{file2}. If they differ
+in size, print the sizes like this:
+
+@example
+Differ in size: 0x1234 [foo], 0x4321 [bar]
+@end example
+
+If the sizes are equal but the bytes at an offset differ, then print the
+bytes like this:
+
+@example
+Differ at the offset 777: 0xbe [foo], 0xef [bar]
+@end example
+
+If they are completely identical, nothing will be printed.
+@end deffn
+
+
+@node configfile
+@subsection configfile
+
+@deffn Command configfile file
+Load @var{file} as a configuration file.
+@end deffn
+
+
+@node debug
+@subsection debug
+
+@deffn Command debug
+Toggle debug mode (by default it is off). When debug mode is on, some
+extra messages are printed to show disk activity. This global debug flag
+is mainly useful for GRUB developers when testing new code.
+@end deffn
+
+
+@node displayapm
+@subsection displayapm
+
+@deffn Command displayapm
+Display APM BIOS information.
+@end deffn
+
+
+@node displaymem
+@subsection displaymem
+
+@deffn Command displaymem
+Display what GRUB thinks the system address space map of the machine is,
+including all regions of physical @sc{ram} installed. GRUB's
+@dfn{upper/lower memory} display uses the standard BIOS interface for
+the available memory in the first megabyte, or @dfn{lower memory}, and a
+synthesized number from various BIOS interfaces of the memory starting
+at 1MB and going up to the first chipset hole for @dfn{upper memory}
+(the standard PC @dfn{upper memory} interface is limited to reporting a
+maximum of 64MB).
+@end deffn
+
+
+@node embed
+@subsection embed
+
+@deffn Command embed stage1_5 device
+Embed the Stage 1.5 @var{stage1_5} in the sectors after the MBR if
+@var{device} is a drive, or in the @dfn{boot loader} area if @var{device}
+is a FFS partition or a ReiserFS partition.@footnote{The latter feature
+has not been implemented yet.} Print the number of sectors which
+@var{stage1_5} occupies, if successful.
+
+Usually, you don't need to run this command directly. @xref{setup}.
+@end deffn
+
+
+@node find
+@subsection find
+
+@deffn Command find filename
+Search for the file name @var{filename} in all mountable partitions
+and print the list of the devices which contain the file. The file
+name @var{filename} should be an absolute file name like
+@code{/boot/grub/stage1}.
+@end deffn
+
+
+@node fstest
+@subsection fstest
+
+@deffn Command fstest
+Toggle filesystem test mode.
+Filesystem test mode, when turned on, prints out data corresponding to
+all the device reads and what values are being sent to the low-level
+routines. The format is @samp{<@var{partition-offset-sector},
+@var{byte-offset}, @var{byte-length}>} for high-level reads inside a
+partition, and @samp{[@var{disk-offset-sector}]} for low-level sector
+requests from the disk.
+Filesystem test mode is turned off by any use of the @command{install}
+(@pxref{install}) or @command{testload} (@pxref{testload}) commands.
+@end deffn
+
+
+@node geometry
+@subsection geometry
+
+@deffn Command geometry drive [cylinder head sector [total_sector]]
+Print the information for the drive @var{drive}. In the grub shell, you
+can set the geometry of the drive arbitrarily. The number of
+cylinders, the number of heads, the number of sectors and the number of
+total sectors are set to CYLINDER, HEAD, SECTOR and TOTAL_SECTOR,
+respectively. If you omit TOTAL_SECTOR, then it will be calculated
+based on the C/H/S values automatically.
+@end deffn
+
+
+@node halt
+@subsection halt
+
+@deffn Command halt @option{--no-apm}
+The command halts the computer. If the @option{--no-apm} option
+is specified, no APM BIOS call is performed. Otherwise, the computer
+is shut down using APM.
+@end deffn
+
+
+@node help
+@subsection help
+
+@deffn Command help @option{--all} [pattern @dots{}]
+Display helpful information about builtin commands. If you do not
+specify @var{pattern}, this command shows short descriptions of most of
+available commands. If you specify the option @option{--all} to this
+command, short descriptions of rarely used commands (such as
+@ref{testload}) are displayed as well.
+
+If you specify any @var{patterns}, it displays longer information
+about each of the commands which match those @var{patterns}.
+@end deffn
+
+
+@node impsprobe
+@subsection impsprobe
+
+@deffn Command impsprobe
+Probe the Intel Multiprocessor Specification 1.1 or 1.4 configuration
+table and boot the various CPUs which are found into a tight loop. This
+command can be used only in the Stage 2, but not in the grub shell.
+@end deffn
+
+
+@node initrd
+@subsection initrd
+
+@deffn Command initrd file @dots{}
+Load an initial ramdisk for a Linux format boot image and set the
+appropriate parameters in the Linux setup area in memory. See also
+@ref{GNU/Linux}.
+@end deffn
+
+
+@node install
+@subsection install
+
+@deffn Command install [@option{--force-lba}] [@option{--stage2=os_stage2_file}] stage1_file [@option{d}] dest_dev stage2_file [addr] [@option{p}] [config_file] [real_config_file]
+This command is fairly complex, and you should not use this command
+unless you are familiar with GRUB. Use @command{setup} (@pxref{setup})
+instead.
+
+In short, it will perform a full install presuming the Stage 2 or Stage
+1.5@footnote{They're loaded the same way, so we will refer to the Stage
+1.5 as a Stage 2 from now on.} is in its final install location.
+
+In slightly more detail, it will load @var{stage1_file}, validate that
+it is a GRUB Stage 1 of the right version number, install in it a
+blocklist for loading @var{stage2_file} as a Stage 2. If the option
+@option{d} is present, the Stage 1 will always look for the actual
+disk @var{stage2_file} was installed on, rather than using the booting
+drive. The Stage 2 will be loaded at address @var{addr}, which must be
+@samp{0x8000} for a true Stage 2, and @samp{0x2000} for a Stage 1.5. If
+@var{addr} is not present, GRUB will determine the address
+automatically. It then writes the completed Stage 1 to the first block
+of the device @var{dest_dev}. If the options @option{p} or
+@var{config_file} are present, then it reads the first block of stage2,
+modifies it with the values of the partition @var{stage2_file} was found
+on (for @option{p}) or places the string @var{config_file} into the area
+telling the stage2 where to look for a configuration file at boot
+time. Likewise, if @var{real_config_file} is present and
+@var{stage2_file} is a Stage 1.5, then the Stage 2 @var{config_file} is
+patched with the configuration file name @var{real_config_file}. This
+command preserves the DOS BPB (and for hard disks, the partition table)
+of the sector the Stage 1 is to be installed into.
+
+@strong{Caution:} Several buggy BIOSes don't pass a booting drive
+properly when booting from a hard disk drive. Therefore, you will
+unfortunately have to specify the option @option{d}, whether your
+Stage2 resides at the booting drive or not, if you have such a
+BIOS. We know these are defective in this way:
+
+@table @asis
+@item
+Fujitsu LifeBook 400 BIOS version 31J0103A
+
+@item
+HP Vectra XU 6/200 BIOS version GG.06.11
+@end table
+
+@strong{Caution2:} A number of BIOSes don't return a correct LBA support
+bitmap even if they do have the support. So GRUB provides a solution to
+ignore the wrong bitmap, that is, the option @option{--force-lba}. Don't
+use this option if you know that your BIOS doesn't have LBA support.
+
+@strong{Caution3:} You must specify the option @option{--stage2} in the
+grub shell, if you cannot unmount the filesystem where your stage2 file
+resides. The argument should be the file name in your operating system.
+@end deffn
+
+
+@node ioprobe
+@subsection ioprobe
+
+@deffn Command ioprobe drive
+Probe I/O ports used for the drive @var{drive}. This command will list
+the I/O ports on the screen. For technical information,
+@xref{Internals}.
+@end deffn
+
+
+@node kernel
+@subsection kernel
+
+@deffn Command kernel [@option{--type=type}] [@option{--no-mem-option}] file @dots{}
+Attempt to load the primary boot image (Multiboot a.out or @sc{elf},
+Linux zImage or bzImage, FreeBSD a.out, NetBSD a.out, etc.) from
+@var{file}. The rest of the line is passed verbatim as the @dfn{kernel
+command-line}. Any modules must be reloaded after using this command.
+
+This command also accepts the option @option{--type} so that you can
+specify the kernel type of @var{file} explicitly. The argument
+@var{type} must be one of these: @samp{netbsd}, @samp{freebsd},
+@samp{openbsd}, @samp{linux}, @samp{biglinux}, and
+@samp{multiboot}. However, you need to specify it only if you want to
+load a NetBSD @sc{elf} kernel, because GRUB can automatically determine
+a kernel type in the other cases, quite safely.
+
+The option @option{--no-mem-option} is effective only for Linux. If the
+option is specified, GRUB doesn't pass the option @option{mem=} to the
+kernel.  This option is implied for Linux kernels 2.4.18 and newer.
+@end deffn
+
+
+@node lock
+@subsection lock
+
+@deffn Command lock
+Prevent normal users from executing arbitrary menu entries. You must use
+the command @command{password} if you really want this command to be
+useful (@pxref{password}).
+
+This command is used in a menu, as shown in this example:
+
+@example
+@group
+title This entry is too dangerous to be executed by normal users
+lock
+root (hd0,a)
+kernel /no-security-os
+@end group
+@end example
+
+See also @ref{Security}.
+@end deffn
+
+
+@node makeactive
+@subsection makeactive
+
+@deffn Command makeactive
+Set the active partition on the root disk to GRUB's root device.
+This command is limited to @emph{primary} PC partitions on a hard disk.
+@end deffn
+
+
+@node map
+@subsection map
+
+@deffn Command map to_drive from_drive
+Map the drive @var{from_drive} to the drive @var{to_drive}. This is
+necessary when you chain-load some operating systems, such as DOS, if
+such an OS resides at a non-first drive. Here is an example:
+
+@example
+@group
+grub> @kbd{map (hd0) (hd1)}
+grub> @kbd{map (hd1) (hd0)}
+@end group
+@end example
+
+The example exchanges the order between the first hard disk and the
+second hard disk. See also @ref{DOS/Windows}.
+@end deffn
+
+
+@node md5crypt
+@subsection md5crypt
+
+@deffn Command md5crypt
+Prompt to enter a password, and encrypt it in MD5 format. The encrypted
+password can be used with the command @command{password}
+(@pxref{password}). See also @ref{Security}.
+@end deffn
+
+
+@node module
+@subsection module
+
+@deffn Command module file @dots{}
+Load a boot module @var{file} for a Multiboot format boot image (no
+interpretation of the file contents are made, so the user of this
+command must know what the kernel in question expects). The rest of the
+line is passed as the @dfn{module command-line}, like the
+@command{kernel} command. You must load a Multiboot kernel image before
+loading any module. See also @ref{modulenounzip}.
+@end deffn
+
+
+@node modulenounzip
+@subsection modulenounzip
+
+@deffn Command modulenounzip file @dots{}
+The same as @command{module} (@pxref{module}), except that automatic
+decompression is disabled.
+@end deffn
+
+
+@node pause
+@subsection pause
+
+@deffn Command pause message @dots{}
+Print the @var{message}, then wait until a key is pressed. Note that
+placing @key{^G} (ASCII code 7) in the message will cause the speaker to
+emit the standard beep sound, which is useful when prompting the user to
+change floppies.
+@end deffn
+
+
+@node quit
+@subsection quit
+
+@deffn Command quit
+Exit from the grub shell @command{grub} (@pxref{Invoking the grub
+shell}). This command can be used only in the grub shell.
+@end deffn
+
+
+@node reboot
+@subsection reboot
+
+@deffn Command reboot
+Reboot the computer.
+@end deffn
+
+
+@node read
+@subsection read
+
+@deffn Command read addr
+Read a 32-bit value from memory at address @var{addr} and display it in
+hex format.
+@end deffn
+
+
+@node root
+@subsection root
+
+@deffn Command root device [hdbias]
+Set the current @dfn{root device} to the device @var{device}, then
+attempt to mount it to get the partition size (for passing the partition
+descriptor in @code{ES:ESI}, used by some chain-loaded boot loaders), the
+BSD drive-type (for booting BSD kernels using their native boot format),
+and correctly determine the PC partition where a BSD sub-partition is
+located. The optional @var{hdbias} parameter is a number to tell a BSD
+kernel how many BIOS drive numbers are on controllers before the current
+one. For example, if there is an IDE disk and a SCSI disk, and your
+FreeBSD root partition is on the SCSI disk, then use a @samp{1} for
+@var{hdbias}.
+
+See also @ref{rootnoverify}.
+@end deffn
+
+
+@node rootnoverify
+@subsection rootnoverify
+
+@deffn Command rootnoverify device [hdbias]
+Similar to @command{root} (@pxref{root}), but don't attempt to mount the
+partition. This is useful for when an OS is outside of the area of the
+disk that GRUB can read, but setting the correct root device is still
+desired. Note that the items mentioned in @command{root} above which
+derived from attempting the mount will @emph{not} work correctly.
+@end deffn
+
+
+@node savedefault
+@subsection savedefault
+
+@deffn Command savedefault num
+Save the current menu entry or @var{num} if specified as a default
+entry. Here is an example:
+
+@example
+@group
+default saved
+timeout 10
+
+title GNU/Linux
+root (hd0,0)
+kernel /boot/vmlinuz root=/dev/sda1 vga=ext
+initrd /boot/initrd
+savedefault
+
+title FreeBSD
+root (hd0,a)
+kernel /boot/loader
+savedefault
+@end group
+@end example
+
+With this configuration, GRUB will choose the entry booted previously as
+the default entry.
+
+You can specify @samp{fallback} instead of a number. Then, next
+fallback entry is saved. Next fallback entry is chosen from fallback
+entries. Normally, this will be the first entry in fallback ones.
+
+See also @ref{default} and @ref{Invoking grub-set-default}.
+@end deffn
+
+
+@node setup
+@subsection setup
+
+@deffn Command setup [@option{--force-lba}] [@option{--stage2=os_stage2_file}] [@option{--prefix=dir}] install_device [image_device]
+Set up the installation of GRUB automatically. This command uses the
+more flexible command @command{install} (@pxref{install}) in the backend
+and installs GRUB into the device @var{install_device}. If
+@var{image_device} is specified, then find the GRUB images
+(@pxref{Images}) in the device @var{image_device}, otherwise use the
+current @dfn{root device}, which can be set by the command
+@command{root}. If @var{install_device} is a hard disk, then embed a
+Stage 1.5 in the disk if possible.
+
+The option @option{--prefix} specifies the directory under which GRUB
+images are put. If it is not specified, GRUB automatically searches them
+in @file{/boot/grub} and @file{/grub}.
+
+The options @option{--force-lba} and @option{--stage2} are just passed
+to @command{install} if specified. @xref{install}, for more
+information.
+@end deffn
+
+
+@node testload
+@subsection testload
+
+@deffn Command testload file
+Read the entire contents of @var{file} in several different ways and
+compare them, to test the filesystem code. The output is somewhat
+cryptic, but if no errors are reported and the final @samp{i=@var{X},
+filepos=@var{Y}} reading has @var{X} and @var{Y} equal, then it is
+definitely consistent, and very likely works correctly subject to a
+consistent offset error. If this test succeeds, then a good next step is
+to try loading a kernel.
+@end deffn
+
+
+@node testvbe
+@subsection testvbe
+
+@deffn Command testvbe mode
+Test the VESA BIOS EXTENSION mode @var{mode}. This command will switch
+your video card to the graphics mode, and show an endless animation. Hit
+any key to return. See also @ref{vbeprobe}.
+@end deffn
+
+
+@node uppermem
+@subsection uppermem
+
+@deffn Command uppermem kbytes
+Force GRUB to assume that only @var{kbytes} kilobytes of upper memory
+are installed. Any system address range maps are discarded.
+
+@strong{Caution:} This should be used with great caution, and should
+only be necessary on some old machines. GRUB's BIOS probe can pick up
+all @sc{ram} on all new machines the author has ever heard of. It can
+also be used for debugging purposes to lie to an OS.
+@end deffn
+
+
+@node vbeprobe
+@subsection vbeprobe
+
+@deffn Command vbeprobe [mode]
+Probe VESA BIOS EXTENSION information. If the mode @var{mode} is
+specified, show only the information about @var{mode}. Otherwise, this
+command lists up available VBE modes on the screen. See also
+@ref{testvbe}.
+@end deffn
+
+
+@node Troubleshooting
+@chapter Error messages reported by GRUB
+
+This chapter describes error messages reported by GRUB when you
+encounter trouble. @xref{Invoking the grub shell}, if your problem is
+specific to the grub shell.
+
+@menu
+* Stage1 errors::               Errors reported by the Stage 1
+* Stage1.5 errors::             Errors reported by the Stage 1.5
+* Stage2 errors::               Errors reported by the Stage 2
+@end menu
+
+
+@node Stage1 errors
+@section Errors reported by the Stage 1
+
+The general way that the Stage 1 handles errors is to print an error
+string and then halt. Pressing @kbd{@key{CTRL}-@key{ALT}-@key{DEL}} will
+reboot.
+
+The following is a comprehensive list of error messages for the Stage 1:
+
+@table @asis
+@item Hard Disk Error
+The stage2 or stage1.5 is being read from a hard disk, and the attempt
+to determine the size and geometry of the hard disk failed.
+
+@item Floppy Error
+The stage2 or stage1.5 is being read from a floppy disk, and the attempt
+to determine the size and geometry of the floppy disk failed. It's listed
+as a separate error since the probe sequence is different than for hard
+disks.
+
+@item Read Error
+A disk read error happened while trying to read the stage2 or stage1.5.
+
+@item Geom Error
+The location of the stage2 or stage1.5 is not in the portion of the disk
+supported directly by the BIOS read calls.  This could occur because the
+BIOS translated geometry has been changed by the user or the disk is
+moved to another machine or controller after installation, or GRUB was
+not installed using itself (if it was, the Stage 2 version of this error
+would have been seen during that process and it would not have completed
+the install).
+@end table
+
+
+@node Stage1.5 errors
+@section Errors reported by the Stage 1.5
+
+The general way that the Stage 1.5 handles errors is to print an error
+number in the form @code{Error @var{num}} and then halt. Pressing
+@kbd{@key{CTRL}-@key{ALT}-@key{DEL}} will reboot.
+
+The error numbers correspond to the errors reported by Stage
+2. @xref{Stage2 errors}.
+
+
+@node Stage2 errors
+@section Errors reported by the Stage 2
+
+The general way that the Stage 2 handles errors is to abort the
+operation in question, print an error string, then (if possible) either
+continue based on the fact that an error occurred or wait for the user to
+deal with the error.
+
+The following is a comprehensive list of error messages for the Stage 2
+(error numbers for the Stage 1.5 are listed before the colon in each
+description):
+
+@table @asis
+@item 1 : Filename must be either an absolute filename or blocklist
+This error is returned if a file name is requested which doesn't fit the
+syntax/rules listed in the @ref{Filesystem}.
+
+@item 2 : Bad file or directory type
+This error is returned if a file requested is not a regular file, but
+something like a symbolic link, directory, or FIFO.
+
+@item 3 : Bad or corrupt data while decompressing file
+This error is returned if the run-length decompression code gets an
+internal error. This is usually from a corrupt file.
+
+@item 4 : Bad or incompatible header in compressed file
+This error is returned if the file header for a supposedly compressed
+file is bad.
+
+@item 5 : Partition table invalid or corrupt
+This error is returned if the sanity checks on the integrity of the
+partition table fail. This is a bad sign.
+
+@item 6 : Mismatched or corrupt version of stage1/stage2
+This error is returned if the install command points to incompatible
+or corrupt versions of the stage1 or stage2. It can't detect corruption
+in general, but this is a sanity check on the version numbers, which
+should be correct.
+
+@item 7 : Loading below 1MB is not supported
+This error is returned if the lowest address in a kernel is below the
+1MB boundary. The Linux zImage format is a special case and can be
+handled since it has a fixed loading address and maximum size.
+
+@item 8 : Kernel must be loaded before booting
+This error is returned if GRUB is told to execute the boot sequence
+without having a kernel to start.
+
+@item 9 : Unknown boot failure
+This error is returned if the boot attempt did not succeed for reasons
+which are unknown.
+
+@item 10 : Unsupported Multiboot features requested
+This error is returned when the Multiboot features word in the Multiboot
+header requires a feature that is not recognized. The point of this is
+that the kernel requires special handling which GRUB is probably
+unable to provide.
+
+@item 11 : Unrecognized device string
+This error is returned if a device string was expected, and the string
+encountered didn't fit the syntax/rules listed in the @ref{Filesystem}.
+
+@item 12 : Invalid device requested
+This error is returned if a device string is recognizable but does not
+fall under the other device errors.
+
+@item 13 : Invalid or unsupported executable format
+This error is returned if the kernel image being loaded is not
+recognized as Multiboot or one of the supported native formats (Linux
+zImage or bzImage, FreeBSD, or NetBSD).
+
+@item 14 : Filesystem compatibility error, cannot read whole file
+Some of the filesystem reading code in GRUB has limits on the length of
+the files it can read. This error is returned when the user runs into
+such a limit.
+
+@item 15 : File not found
+This error is returned if the specified file name cannot be found, but
+everything else (like the disk/partition info) is OK.
+
+@item 16 : Inconsistent filesystem structure
+This error is returned by the filesystem code to denote an internal
+error caused by the sanity checks of the filesystem structure on disk
+not matching what it expects. This is usually caused by a corrupt
+filesystem or bugs in the code handling it in GRUB.
+
+@item 17 : Cannot mount selected partition
+This error is returned if the partition requested exists, but the
+filesystem type cannot be recognized by GRUB.
+
+@item 18 : Selected cylinder exceeds maximum supported by BIOS
+This error is returned when a read is attempted at a linear block
+address beyond the end of the BIOS translated area. This generally
+happens if your disk is larger than the BIOS can handle (512MB for
+(E)IDE disks on older machines or larger than 8GB in general).
+
+@item 19 : Linux kernel must be loaded before initrd
+This error is returned if the initrd command is used before loading a
+Linux kernel.
+
+@item 20 : Multiboot kernel must be loaded before modules
+This error is returned if the module load command is used before loading
+a Multiboot kernel. It only makes sense in this case anyway, as GRUB has
+no idea how to communicate the presence of such modules to a
+non-Multiboot-aware kernel.
+
+@item 21 : Selected disk does not exist
+This error is returned if the device part of a device- or full file name
+refers to a disk or BIOS device that is not present or not recognized by
+the BIOS in the system.
+
+@item 22 : No such partition
+This error is returned if a partition is requested in the device part of
+a device- or full file name which isn't on the selected disk.
+
+@item 23 : Error while parsing number
+This error is returned if GRUB was expecting to read a number and
+encountered bad data.
+
+@item 24 : Attempt to access block outside partition
+This error is returned if a linear block address is outside of the disk
+partition. This generally happens because of a corrupt filesystem on the
+disk or a bug in the code handling it in GRUB (it's a great debugging
+tool).
+
+@item 25 : Disk read error
+This error is returned if there is a disk read error when trying to
+probe or read data from a particular disk.
+
+@item 26 : Too many symbolic links
+This error is returned if the link count is beyond the maximum
+(currently 5), possibly the symbolic links are looped.
+
+@item 27 : Unrecognized command
+This error is returned if an unrecognized command is entered on the
+command-line or in a boot sequence section of a configuration file and
+that entry is selected.
+
+@item 28 : Selected item cannot fit into memory
+This error is returned if a kernel, module, or raw file load command is
+either trying to load its data such that it won't fit into memory or it
+is simply too big.
+
+@item 29 : Disk write error
+This error is returned if there is a disk write error when trying to
+write to a particular disk. This would generally only occur during an
+install of set active partition command.
+
+@item 30 : Invalid argument
+This error is returned if an argument specified to a command is invalid.
+
+@item 31 : File is not sector aligned
+This error may occur only when you access a ReiserFS partition by
+block-lists (e.g. the command @command{install}). In this case, you
+should mount the partition with the @samp{-o notail} option.
+
+@item 32 : Must be authenticated
+This error is returned if you try to run a locked entry. You should
+enter a correct password before running such an entry.
+
+@item 33 : Serial device not configured
+This error is returned if you try to change your terminal to a serial
+one before initializing any serial device.
+
+@item 34 : No spare sectors on the disk
+This error is returned if a disk doesn't have enough spare space. This
+happens when you try to embed Stage 1.5 into the unused sectors after
+the MBR, but the first partition starts right after the MBR or they are
+used by EZ-BIOS.
+@end table
+
+
+@node Invoking the grub shell
+@chapter Invoking the grub shell
+
+This chapter documents the grub shell @command{grub}. Note that the grub
+shell is an emulator; it doesn't run under the native environment, so it
+sometimes does something wrong. Therefore, you shouldn't trust it too
+much. If there is anything wrong with it, don't hesitate to try the
+native GRUB environment, especially when it guesses a wrong map between
+BIOS drives and OS devices.
+
+@menu
+* Basic usage::                 How to use the grub shell
+* Installation under UNIX::     How to install GRUB via @command{grub}
+* Device map::                  The map between BIOS drives and OS devices
+@end menu
+
+
+@node Basic usage
+@section Introduction into the grub shell
+
+You can use the command @command{grub} for installing GRUB under your
+operating systems and for a testbed when you add a new feature into GRUB
+or when fixing a bug. @command{grub} is almost the same as the Stage 2,
+and, in fact, it shares the source code with the Stage 2 and you can use
+the same commands (@pxref{Commands}) in @command{grub}. It is emulated by
+replacing BIOS calls with UNIX system calls and libc functions.
+
+The command @command{grub} accepts the following options:
+
+@table @option
+@item --help
+Print a summary of the command-line options and exit.
+
+@item --version
+Print the version number of GRUB and exit.
+
+@item --verbose
+Print some verbose messages for debugging purpose.
+
+@item --device-map=@var{file}
+Use the device map file @var{file}. The format is described in
+@ref{Device map}.
+
+@item --no-floppy
+Do not probe any floppy drive. This option has no effect if the option
+@option{--device-map} is specified (@pxref{Device map}).
+
+@item --probe-second-floppy
+Probe the second floppy drive. If this option is not specified, the grub
+shell does not probe it, as that sometimes takes a long time. If you
+specify the device map file (@pxref{Device map}), the grub shell just
+ignores this option.
+
+@item --config-file=@var{file}
+Read the configuration file @var{file} instead of
+@file{/boot/grub/menu.lst}. The format is the same as the normal GRUB
+syntax. See @ref{Filesystem}, for more information.
+
+@item --boot-drive=@var{drive}
+Set the stage2 @var{boot_drive} to @var{drive}. This argument should be
+an integer (decimal, octal or hexadecimal).
+
+@item --install-partition=@var{par}
+Set the stage2 @var{install_partition} to @var{par}. This argument
+should be an integer (decimal, octal or hexadecimal).
+
+@item --no-config-file
+Do not use the configuration file even if it can be read.
+
+@item --no-curses
+Do not use the screen handling interface by the curses even if it is
+available.
+
+@item --batch
+This option has the same meaning as @samp{--no-config-file --no-curses}.
+
+@item --read-only
+Disable writing to any disk.
+
+@item --hold
+Wait until a debugger will attach. This option is useful when you want
+to debug the startup code.
+@end table
+
+
+@node Installation under UNIX
+@section How to install GRUB via @command{grub}
+
+The installation procedure is the same as under the @dfn{native} Stage
+2. @xref{Installation}, for more information. The command
+@command{grub}-specific information is described here.
+
+What you should be careful about is @dfn{buffer cache}. @command{grub}
+makes use of raw devices instead of filesystems that your operating
+systems serve, so there exists a potential problem that some cache
+inconsistency may corrupt your filesystems. What we recommend is:
+
+@itemize @bullet
+@item
+If you can unmount drives to which GRUB may write any amount of data,
+unmount them before running @command{grub}.
+
+@item
+If a drive cannot be unmounted but can be mounted with the read-only
+flag, mount it in read-only mode. That should be secure.
+
+@item
+If a drive must be mounted with the read-write flag, make sure that no
+activity is being done on it while the command @command{grub} is
+running.
+
+@item
+Reboot your operating system as soon as possible. This is probably not
+required if you follow the rules above, but reboot is the most secure
+way.
+@end itemize
+
+In addition, enter the command @command{quit} when you finish the
+installation. That is @emph{very important} because @command{quit} makes
+the buffer cache consistent. Do not push @key{C-c}.
+
+If you want to install GRUB non-interactively, specify @samp{--batch}
+option in the command-line. This is a simple example:
+
+@example
+@group
+#!/bin/sh
+
+# Use /usr/sbin/grub if you are on an older system.
+/sbin/grub --batch <<EOT 1>/dev/null 2>/dev/null
+root (hd0,0)
+setup (hd0)
+quit
+EOT
+@end group
+@end example
+
+
+@node Device map
+@section The map between BIOS drives and OS devices
+
+When you specify the option @option{--device-map} (@pxref{Basic usage}),
+the grub shell creates the @dfn{device map file} automatically unless it
+already exists. The file name @file{/boot/grub/device.map} is preferred.
+
+If the device map file exists, the grub shell reads it to map BIOS
+drives to OS devices. This file consists of lines like this:
+
+@example
+@var{device} @var{file}
+@end example
+
+@var{device} is a drive specified in the GRUB syntax (@pxref{Device
+syntax}), and @var{file} is an OS file, which is normally a device
+file.
+
+The reason why the grub shell gives you the device map file is that it
+cannot guess the map between BIOS drives and OS devices correctly in
+some environments. For example, if you exchange the boot sequence
+between IDE and SCSI in your BIOS, it gets the order wrong.
+
+Thus, edit the file if the grub shell makes a mistake. You can put any
+comments in the file if needed, as the grub shell assumes that a line is
+just a comment if the first character is @samp{#}.
+
+
+@node Invoking grub-install
+@chapter Invoking grub-install
+
+The program @command{grub-install} installs GRUB on your drive using the
+grub shell (@pxref{Invoking the grub shell}). You must specify the
+device name on which you want to install GRUB, like this:
+
+@example
+grub-install @var{install_device}
+@end example
+
+The device name @var{install_device} is an OS device name or a GRUB
+device name.
+
+@command{grub-install} accepts the following options:
+
+@table @option
+@item --help
+Print a summary of the command-line options and exit.
+
+@item --version
+Print the version number of GRUB and exit.
+
+@item --force-lba
+Force GRUB to use LBA mode even for a buggy BIOS. Use this option only
+if your BIOS doesn't work properly in LBA mode even though it supports
+LBA mode.
+
+@item --root-directory=@var{dir}
+Install GRUB images under the directory @var{dir} instead of the root
+directory. This option is useful when you want to install GRUB into a
+separate partition or a removable disk. Here is an example in which
+you have a separate @dfn{boot} partition which is mounted on
+@file{/boot}:
+
+@example
+@kbd{grub-install --root-directory=/boot hd0}
+@end example
+
+@item --grub-shell=@var{file}
+Use @var{file} as the grub shell. You can append arbitrary options to
+@var{file} after the file name, like this:
+
+@example
+@kbd{grub-install --grub-shell="grub --read-only" /dev/fd0}
+@end example
+
+@item --recheck
+Recheck the device map, even if @file{/boot/grub/device.map} already
+exists. You should use this option whenever you add/remove a disk
+into/from your computer.
+@end table
+
+
+@node Invoking grub-md5-crypt
+@chapter Invoking grub-md5-crypt
+
+The program @command{grub-md5-crypt} encrypts a password in MD5 format.
+This is just a frontend of the grub shell (@pxref{Invoking the grub
+shell}). Passwords encrypted by this program can be used with the
+command @command{password} (@pxref{password}).
+
+@command{grub-md5-crypt} accepts the following options:
+
+@table @option
+@item --help
+Print a summary of the command-line options and exit.
+
+@item --version
+Print the version information and exit.
+
+@item --grub-shell=@var{file}
+Use @var{file} as the grub shell.
+@end table
+
+
+@node Invoking grub-terminfo
+@chapter Invoking grub-terminfo
+
+The program @command{grub-terminfo} generates a terminfo command from
+a terminfo name (@pxref{terminfo}). The result can be used in the
+configuration file, to define escape sequences. Because GRUB assumes
+that your terminal is vt100-compatible by default, this would be
+useful only if your terminal is uncommon (such as vt52).
+
+@command{grub-terminfo} accepts the following options:
+
+@table @option
+@item --help
+Print a summary of the command-line options and exit.
+
+@item --version
+Print the version information and exit.
+@end table
+
+You must specify one argument to this command. For example:
+
+@example
+@kbd{grub-terminfo vt52}
+@end example
+
+
+@node Invoking grub-set-default
+@chapter Invoking grub-set-default
+
+The program @command{grub-set-default} sets the default boot entry for
+GRUB. This automatically creates a file named @file{default} under
+your GRUB directory (i.e. @file{/boot/grub}), if it is not
+present. This file is used to determine the default boot entry when
+GRUB boots up your system when you use @samp{default saved} in your
+configuration file (@pxref{default}), and to save next default boot
+entry when you use @samp{savedefault} in a boot entry
+(@pxref{savedefault}).
+
+@command{grub-set-default} accepts the following options:
+
+@table @option
+@item --help
+Print a summary of the command-line options and exit.
+
+@item --version
+Print the version information and exit.
+
+@item --root-directory=@var{dir}
+Use the directory @var{dir} instead of the root directory
+(i.e. @file{/}) to define the location of the default file. This
+is useful when you mount a disk which is used for another system.
+@end table
+
+You must specify a single argument to @command{grub-set-default}. This
+argument is normally the number of a default boot entry. For example,
+if you have this configuration file:
+
+@example
+@group
+default saved
+timeout 10
+
+title GNU/Hurd
+root (hd0,0)
+...
+
+title GNU/Linux
+root (hd0,1)
+...
+@end group
+@end example
+
+and if you want to set the next default boot entry to GNU/Linux, you
+may execute this command:
+
+@example
+@kbd{grub-set-default 1}
+@end example
+
+Because the entry for GNU/Linux is @samp{1}. Note that entries are
+counted from zero. So, if you want to specify GNU/Hurd here, then you
+should specify @samp{0}.
+
+This feature is very useful if you want to test a new kernel or to
+make your system quite robust. @xref{Making your system robust}, for
+more hints about how to set up a robust system.
+
+
+@node Invoking mbchk
+@chapter Invoking mbchk
+
+The program @command{mbchk} checks for the format of a Multiboot
+kernel. We recommend using this program before booting your own kernel
+by GRUB.
+
+@command{mbchk} accepts the following options:
+
+@table @option
+@item --help
+Print a summary of the command-line options and exit.
+
+@item --version
+Print the version number of GRUB and exit.
+
+@item --quiet
+Suppress all normal output.
+@end table
+
+
+@node Obtaining and Building GRUB
+@appendix How to obtain and build GRUB
+
+@quotation
+@strong{Caution:} GRUB requires binutils-2.9.1.0.23 or later because the
+GNU assembler has been changed so that it can produce real 16bits
+machine code between 2.9.1 and 2.9.1.0.x. See
+@uref{http://sources.redhat.com/binutils/}, to obtain information on
+how to get the latest version.
+@end quotation
+
+GRUB is available from the GNU alpha archive site
+@uref{ftp://alpha.gnu.org/gnu/grub} or any of its mirrors. The file
+will be named grub-version.tar.gz. The current version is
+@value{VERSION}, so the file you should grab is:
+
+@uref{ftp://alpha.gnu.org/gnu/grub/grub-@value{VERSION}.tar.gz}
+
+To unbundle GRUB use the instruction:
+
+@example
+@kbd{zcat grub-@value{VERSION}.tar.gz | tar xvf -}
+@end example
+
+which will create a directory called @file{grub-@value{VERSION}} with
+all the sources. You can look at the file @file{INSTALL} for detailed
+instructions on how to build and install GRUB, but you should be able to
+just do:
+
+@example
+@group
+@kbd{cd grub-@value{VERSION}}
+@kbd{./configure}
+@kbd{make install}
+@end group
+@end example
+
+This will install the grub shell @file{grub} (@pxref{Invoking the grub
+shell}), the Multiboot checker @file{mbchk} (@pxref{Invoking mbchk}),
+and the GRUB images. This will also install the GRUB manual.
+
+Also, the latest version is available from the CVS. See
+@uref{http://savannah.gnu.org/cvs/?group=grub} for more information.
+
+
+@node Reporting bugs
+@appendix Reporting bugs
+
+These are the guideline for how to report bugs. Take a look at this
+list below before you submit bugs:
+
+@enumerate
+@item
+Before getting unsettled, read this manual through and through. Also,
+see the @uref{http://www.gnu.org/software/grub/grub-faq.html, GNU GRUB FAQ}.
+
+@item
+Always mention the information on your GRUB. The version number and the
+configuration are quite important. If you build it yourself, write the
+options specified to the configure script and your operating system,
+including the versions of gcc and binutils.
+
+@item
+If you have trouble with the installation, inform us of how you
+installed GRUB. Don't omit error messages, if any. Just @samp{GRUB hangs
+up when it boots} is not enough.
+
+The information on your hardware is also essential. These are especially
+important: the geometries and the partition tables of your hard disk
+drives and your BIOS.
+
+@item
+If GRUB cannot boot your operating system, write down
+@emph{everything} you see on the screen. Don't paraphrase them, like
+@samp{The foo OS crashes with GRUB, even though it can boot with the
+bar boot loader just fine}. Mention the commands you executed, the
+messages printed by them, and information on your operating system
+including the version number.
+
+@item
+Explain what you wanted to do. It is very useful to know your purpose
+and your wish, and how GRUB didn't satisfy you.
+
+@item
+If you can investigate the problem yourself, please do. That will give
+you and us much more information on the problem. Attaching a patch is
+even better.
+
+When you attach a patch, make the patch in unified diff format, and
+write ChangeLog entries. But, even when you make a patch, don't forget
+to explain the problem, so that we can understand what your patch is
+for.
+
+@item
+Write down anything that you think might be related. Please understand
+that we often need to reproduce the same problem you encounterred in our
+environment. So your information should be sufficient for us to do the
+same thing---Don't forget that we cannot see your computer directly. If
+you are not sure whether to state a fact or leave it out, state it!
+Reporting too many things is much better than omitting something
+important.
+@end enumerate
+
+If you follow the guideline above, submit a report to the
+@uref{http://savannah.gnu.org/bugs/?group=grub, Bug Tracking System}.
+Alternatively, you can submit a report via electronic mail to
+@email{bug-grub@@gnu.org}, but we strongly recommend that you use the
+Bug Tracking System, because e-mail can be passed over easily.
+
+Once we get your report, we will try to fix the bugs.
+
+
+@node Future
+@appendix Where GRUB will go
+
+We started the next generation of GRUB, GRUB 2. This will include
+internationalization, dynamic module loading, real memory management,
+multiple architecture support, a scripting language, and many other
+nice feature. If you are interested in the development of GRUB 2, take
+a look at @uref{http://www.gnu.org/software/grub/grub.html, the
+homepage}.
+
+
+@c Separate the programming guide.
+@include internals.texi
+
+
+@node Index
+@unnumbered Index
+
+@c Currently, we use only the Concept Index.
+@printindex cp
+
+
+@bye
+
+Some notes:
+
+  This is the second attempt to rewrite the manual. The status is
+mostly complete, but I need to check the spelling by ispell, and add
+more indices. Perhaps I also have to let some English native speakers
+proofread this manual through. My English is syntactically almost
+perfect, but sometimes (often?) awful in the nuance. Hehe, I can't be an
+English poet for now.
diff --git a/docs/help2man b/docs/help2man
new file mode 100755
index 0000000..506fcb8
--- /dev/null
+++ b/docs/help2man
@@ -0,0 +1,517 @@
+#!/usr/bin/perl -w
+
+# Generate a short man page from --help and --version output.
+# Copyright © 1997, 1998, 1999, 2000 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.
+
+# Written by Brendan O'Dea <bod@compusol.com.au>
+# Available from ftp://ftp.gnu.org/gnu/help2man/
+
+use 5.004;
+use strict;
+use Getopt::Long;
+use Text::Tabs qw(expand);
+use POSIX qw(strftime setlocale LC_TIME);
+
+my $this_program = 'help2man';
+my $this_version = '1.23';
+my $version_info = <<EOT;
+GNU $this_program $this_version
+
+Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+Written by Brendan O'Dea <bod\@compusol.com.au>
+EOT
+
+my $help_info = <<EOT;
+`$this_program' generates a man page out of `--help' and `--version' output.
+
+Usage: $this_program [OPTION]... EXECUTABLE
+
+ -n, --name=STRING       use `STRING' as the description for the NAME paragraph
+ -s, --section=SECTION   use `SECTION' as the section for the man page
+ -i, --include=FILE      include material from `FILE'
+ -I, --opt-include=FILE  include material from `FILE' if it exists
+ -o, --output=FILE       send output to `FILE'
+ -N, --no-info           suppress pointer to Texinfo manual
+     --help              print this help, then exit
+     --version           print version number, then exit
+
+EXECUTABLE should accept `--help' and `--version' options.
+
+Report bugs to <bug-help2man\@gnu.org>.
+EOT
+
+my $section = 1;
+my ($opt_name, @opt_include, $opt_output, $opt_no_info);
+
+# Parse options.
+Getopt::Long::config('bundling');
+GetOptions (
+    'n|name=s'		=> \$opt_name,
+    's|section=s'	=> \$section,
+    'i|include=s'	=> sub { push @opt_include, [ pop, 1 ] },
+    'I|opt-include=s'	=> sub { push @opt_include, [ pop, 0 ] },
+    'o|output=s'	=> \$opt_output,
+    'N|no-info'		=> \$opt_no_info,
+    help		=> sub { print $help_info; exit },
+    version		=> sub { print $version_info; exit },
+) or die $help_info;
+
+die $help_info unless @ARGV == 1;
+
+my %include = ();
+my %append = ();
+my @include = (); # retain order given in include file
+
+# Provide replacement `quote-regex' operator for pre-5.005.
+BEGIN { eval q(sub qr { '' =~ $_[0]; $_[0] }) if $] < 5.005 }
+
+# Process include file (if given).  Format is:
+#
+#   [section name]
+#   verbatim text
+#
+# or
+#
+#   /pattern/
+#   verbatim text
+#
+
+for (@opt_include)
+{
+    my ($inc, $required) = @$_;
+
+    next unless -f $inc or $required;
+    die "$this_program: can't open `$inc' ($!)\n"
+	unless open INC, $inc;
+
+    my $key;
+    my $hash = \%include;
+
+    while (<INC>)
+    {
+	# [section]
+	if (/^\[([^]]+)\]/)
+	{
+	    $key = uc $1;
+	    $key =~ s/^\s+//;
+	    $key =~ s/\s+$//;
+	    $hash = \%include;
+	    push @include, $key unless $include{$key};
+	    next;
+	}
+
+	# /pattern/
+	if (m!^/(.*)/([ims]*)!)
+	{
+	    my $pat = $2 ? "(?$2)$1" : $1;
+
+	    # Check pattern.
+	    eval { $key = qr($pat) };
+	    if ($@)
+	    {
+		$@ =~ s/ at .*? line \d.*//;
+		die "$inc:$.:$@";
+	    }
+
+	    $hash = \%append;
+	    next;
+	}
+
+	# Silently ignore anything before the first
+	# section--allows for comments and revision info.
+	next unless $key;
+
+	$hash->{$key} ||= '';
+	$hash->{$key} .= $_;
+    }
+
+    close INC;
+
+    die "$this_program: no valid information found in `$inc'\n"
+	unless $key;
+}
+
+# Compress trailing blank lines.
+for my $hash (\(%include, %append))
+{
+    for (keys %$hash) { $hash->{$_} =~ s/\n+$/\n/ }
+}
+
+# Turn off localisation of executable's ouput.
+@ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3;
+
+# Turn off localisation of date (for strftime).
+setlocale LC_TIME, 'C';
+
+# Grab help and version info from executable.
+my ($help_text, $version_text) = map {
+    join '', map { s/ +$//; expand $_ } `$ARGV[0] --$_ 2>/dev/null`
+	or die "$this_program: can't get `--$_' info from $ARGV[0]\n"
+} qw(help version);
+
+my $date = strftime "%B %Y", localtime;
+(my $program = $ARGV[0]) =~ s!.*/!!;
+my $package = $program;
+my $version;
+
+if ($opt_output)
+{
+    unlink $opt_output
+	or die "$this_program: can't unlink $opt_output ($!)\n"
+	if -e $opt_output;
+
+    open STDOUT, ">$opt_output"
+	or die "$this_program: can't create $opt_output ($!)\n";
+}
+
+# The first line of the --version information is assumed to be in one
+# of the following formats:
+#
+#   <version>
+#   <program> <version>
+#   {GNU,Free} <program> <version>
+#   <program> ({GNU,Free} <package>) <version>
+#   <program> - {GNU,Free} <package> <version>
+#
+# and seperated from any copyright/author details by a blank line.
+
+($_, $version_text) = split /\n+/, $version_text, 2;
+
+if (/^(\S+) +\(((?:GNU|Free) +[^)]+)\) +(.*)/ or
+    /^(\S+) +- *((?:GNU|Free) +\S+) +(.*)/)
+{
+    $program = $1;
+    $package = $2;
+    $version = $3;
+}
+elsif (/^((?:GNU|Free) +)?(\S+) +(.*)/)
+{
+    $program = $2;
+    $package = $1 ? "$1$2" : $2;
+    $version = $3;
+}
+else
+{
+    $version = $_;
+}
+
+$program =~ s!.*/!!;
+
+# No info for `info' itself.
+$opt_no_info = 1 if $program eq 'info';
+
+# --name overrides --include contents.
+$include{NAME} = "$program \\- $opt_name\n" if $opt_name;
+
+# Default (useless) NAME paragraph.
+$include{NAME} ||= "$program \\- manual page for $program $version\n";
+
+# Man pages traditionally have the page title in caps.
+my $PROGRAM = uc $program;
+
+# Extract usage clause(s) [if any] for SYNOPSIS.
+if ($help_text =~ s/^Usage:( +(\S+))(.*)((?:\n(?: {6}\1| *or: +\S).*)*)//m)
+{
+    my @syn = $2 . $3;
+
+    if ($_ = $4)
+    {
+	s/^\n//;
+	for (split /\n/) { s/^ *(or: +)?//; push @syn, $_ }
+    }
+
+    my $synopsis = '';
+    for (@syn)
+    {
+	$synopsis .= ".br\n" if $synopsis;
+	s!^\S*/!!;
+	s/^(\S+) *//;
+	$synopsis .= ".B $1\n";
+	s/\s+$//;
+	s/(([][]|\.\.+)+)/\\fR$1\\fI/g;
+	s/^/\\fI/ unless s/^\\fR//;
+	$_ .= '\fR';
+	s/(\\fI)( *)/$2$1/g;
+	s/\\fI\\fR//g;
+	s/^\\fR//;
+	s/\\fI$//;
+	s/^\./\\&./;
+
+	$synopsis .= "$_\n";
+    }
+
+    $include{SYNOPSIS} ||= $synopsis;
+}
+
+# Process text, initial section is DESCRIPTION.
+my $sect = 'DESCRIPTION';
+$_ = "$help_text\n\n$version_text";
+
+# Normalise paragraph breaks.
+s/^\n+//;
+s/\n*$/\n/;
+s/\n\n+/\n\n/g;
+
+# Temporarily exchange leading dots, apostrophes and backslashes for
+# tokens.
+s/^\./\x80/mg;
+s/^'/\x81/mg;
+s/\\/\x82/g;
+
+# Start a new paragraph (if required) for these.
+s/([^\n])\n(Report +bugs|Email +bug +reports +to|Written +by)/$1\n\n$2/g;
+
+sub convert_option;
+
+while (length)
+{
+    # Convert some standard paragraph names.
+    if (s/^(Options|Examples): *\n//)
+    {
+	$sect = uc $1;
+	next;
+    }
+
+    # Copyright section
+    if (/^Copyright +[(\xa9]/)
+    {
+	$sect = 'COPYRIGHT';
+	$include{$sect} ||= '';
+	$include{$sect} .= ".PP\n" if $include{$sect};
+
+	my $copy;
+	($copy, $_) = split /\n\n/, $_, 2;
+
+	for ($copy)
+	{
+	    # Add back newline
+	    s/\n*$/\n/;
+
+	    # Convert iso9959-1 copyright symbol or (c) to nroff
+	    # character.
+	    s/^Copyright +(?:\xa9|\([Cc]\))/Copyright \\(co/mg;
+
+	    # Insert line breaks before additional copyright messages
+	    # and the disclaimer.
+	    s/(.)\n(Copyright |This +is +free +software)/$1\n.br\n$2/g;
+
+	    # Join hyphenated lines.
+	    s/([A-Za-z])-\n */$1/g;
+	}
+
+	$include{$sect} .= $copy;
+	$_ ||= '';
+	next;
+    }
+
+    # Catch bug report text.
+    if (/^(Report +bugs|Email +bug +reports +to) /)
+    {
+	$sect = 'REPORTING BUGS';
+    }
+
+    # Author section.
+    elsif (/^Written +by/)
+    {
+	$sect = 'AUTHOR';
+    }
+
+    # Examples, indicated by an indented leading $, % or > are
+    # rendered in a constant width font.
+    if (/^( +)([\$\%>] )\S/)
+    {
+	my $indent = $1;
+	my $prefix = $2;
+	my $break = '.IP';
+	$include{$sect} ||= '';
+	while (s/^$indent\Q$prefix\E(\S.*)\n*//)
+	{
+	    $include{$sect} .= "$break\n\\f(CW$prefix$1\\fR\n";
+	    $break = '.br';
+	}
+
+	next;
+    }
+
+    my $matched = '';
+    $include{$sect} ||= '';
+
+    # Sub-sections have a trailing colon and the second line indented.
+    if (s/^(\S.*:) *\n / /)
+    {
+	$matched .= $& if %append;
+	$include{$sect} .= qq(.SS "$1"\n);
+    }
+
+    my $indent = 0;
+    my $content = '';
+
+    # Option with description.
+    if (s/^( {1,10}([+-]\S.*?))(?:(  +)|\n( {20,}))(\S.*)\n//)
+    {
+	$matched .= $& if %append;
+	$indent = length ($4 || "$1$3");
+	$content = ".TP\n\x83$2\n\x83$5\n";
+	unless ($4)
+	{
+	    # Indent may be different on second line.
+	    $indent = length $& if /^ {20,}/;
+	}
+    }
+
+    # Option without description.
+    elsif (s/^ {1,10}([+-]\S.*)\n//)
+    {
+	$matched .= $& if %append;
+	$content = ".HP\n\x83$1\n";
+	$indent = 80; # not continued
+    }
+
+    # Indented paragraph with tag.
+    elsif (s/^( +(\S.*?)  +)(\S.*)\n//)
+    {
+	$matched .= $& if %append;
+	$indent = length $1;
+	$content = ".TP\n\x83$2\n\x83$3\n";
+    }
+
+    # Indented paragraph.
+    elsif (s/^( +)(\S.*)\n//)
+    {
+	$matched .= $& if %append;
+	$indent = length $1;
+	$content = ".IP\n\x83$2\n";
+    }
+
+    # Left justified paragraph.
+    else
+    {
+	s/(.*)\n//;
+	$matched .= $& if %append;
+	$content = ".PP\n" if $include{$sect};
+	$content .= "$1\n";
+    }
+
+    # Append continuations.
+    while (s/^ {$indent}(\S.*)\n//)
+    {
+	$matched .= $& if %append;
+	$content .= "\x83$1\n"
+    }
+
+    # Move to next paragraph.
+    s/^\n+//;
+
+    for ($content)
+    {
+	# Leading dot and apostrophe protection.
+	s/\x83\./\x80/g;
+	s/\x83'/\x81/g;
+	s/\x83//g;
+
+	# Convert options.
+	s/(^| )(-[][\w=-]+)/$1 . convert_option $2/mge;
+    }
+
+    # Check if matched paragraph contains /pat/.
+    if (%append)
+    {
+	for my $pat (keys %append)
+	{
+	    if ($matched =~ $pat)
+	    {
+		$content .= ".PP\n" unless $append{$pat} =~ /^\./;
+		$content .= $append{$pat};
+	    }
+	}
+    }
+
+    $include{$sect} .= $content;
+}
+
+# Refer to the real documentation.
+unless ($opt_no_info)
+{
+    $sect = 'SEE ALSO';
+    $include{$sect} ||= '';
+    $include{$sect} .= ".PP\n" if $include{$sect};
+    $include{$sect} .= <<EOT;
+The full documentation for
+.B $program
+is maintained as a Texinfo manual.  If the
+.B info
+and
+.B $program
+programs are properly installed at your site, the command
+.IP
+.B info $program
+.PP
+should give you access to the complete manual.
+EOT
+}
+
+# Output header.
+print <<EOT;
+.\\" DO NOT MODIFY THIS FILE!  It was generated by $this_program $this_version.
+.TH $PROGRAM "$section" "$date" "$package $version" FSF
+EOT
+
+# Section ordering.
+my @pre = qw(NAME SYNOPSIS DESCRIPTION OPTIONS EXAMPLES);
+my @post = ('AUTHOR', 'REPORTING BUGS', 'COPYRIGHT', 'SEE ALSO');
+my $filter = join '|', @pre, @post;
+
+# Output content.
+for (@pre, (grep ! /^($filter)$/o, @include), @post)
+{
+    if ($include{$_})
+    {
+	my $quote = /\W/ ? '"' : '';
+	print ".SH $quote$_$quote\n";
+	
+	for ($include{$_})
+	{
+	    # Replace leading dot, apostrophe and backslash tokens.
+	    s/\x80/\\&./g;
+	    s/\x81/\\&'/g;
+	    s/\x82/\\e/g;
+	    print;
+	}
+    }
+}
+
+exit;
+
+# Convert option dashes to \- to stop nroff from hyphenating 'em, and
+# embolden.  Option arguments get italicised.
+sub convert_option
+{
+    local $_ = '\fB' . shift;
+
+    s/-/\\-/g;
+    unless (s/\[=(.*)\]$/\\fR[=\\fI$1\\fR]/)
+    {
+	s/=(.)/\\fR=\\fI$1/;
+	s/ (.)/ \\fI$1/;
+	$_ .= '\fR';
+    }
+
+    $_;
+}
diff --git a/docs/internals.texi b/docs/internals.texi
new file mode 100644
index 0000000..5eb6406
--- /dev/null
+++ b/docs/internals.texi
@@ -0,0 +1,427 @@
+@node Internals
+@appendix Hacking GRUB
+
+This chapter documents the user-invisible aspect of GRUB.
+
+As a general rule of software development, it is impossible to keep the
+descriptions of the internals up-to-date, and it is quite hard to
+document everything. So refer to the source code, whenever you are not
+satisfied with this documentation.  Please assume that this gives just
+hints to you.
+
+@menu
+* Memory map::                  The memory map of various components
+* Embedded data::               Embedded variables in GRUB
+* Filesystem interface::        The generic interface for filesystems
+* Command interface::           The generic interface for built-ins
+* Bootstrap tricks::            The bootstrap mechanism used in GRUB
+* I/O ports detection::         How to probe I/O ports used by INT 13H
+* Memory detection::            How to detect all installed RAM
+* Low-level disk I/O::          INT 13H disk I/O interrupts
+* MBR::                         The structure of Master Boot Record
+* Partition table::             The format of partition tables
+* Submitting patches::          Where and how you should send patches
+@end menu
+
+
+@node Memory map
+@section The memory map of various components
+
+GRUB consists of two distinct components, called @dfn{stages}, which are
+loaded at different times in the boot process. Because they run
+mutual-exclusively, sometimes a memory area overlaps with another
+memory area. And, even in one stage, a single memory area can be used
+for various purposes, because their usages are mutually exclusive.
+
+Here is the memory map of the various components:
+
+@table @asis
+@item 0 to 4K-1
+BIOS and real mode interrupts
+
+@item 0x07BE to 0x07FF
+Partition table passed to another boot loader
+
+@item down from 8K-1
+Real mode stack
+
+@item 0x2000 to ?
+The optional Stage 1.5 is loaded here
+
+@item 0x2000 to 0x7FFF
+Command-line buffer for Multiboot kernels and modules
+
+@item 0x7C00 to 0x7DFF
+Stage 1 is loaded here by BIOS or another boot loader
+
+@item 0x7F00 to 0x7F42
+LBA drive parameters
+
+@item 0x8000 to ?
+Stage2 is loaded here
+
+@item The end of Stage 2 to 416K-1
+Heap, in particular used for the menu
+
+@item down from 416K-1
+Protected mode stack
+
+@item 416K to 448K-1
+Filesystem buffer
+
+@item 448K to 479.5K-1
+Raw device buffer
+
+@item 479.5K to 480K-1
+512-byte scratch area
+
+@item 480K to 512K-1
+Buffers for various functions, such as password, command-line, cut and
+paste, and completion.
+
+@item The last 1K of lower memory
+Disk swapping code and data
+@end table
+
+See the file @file{stage2/shared.h}, for more information.
+
+
+@node Embedded data
+@section Embedded variables in GRUB
+
+Stage 1 and Stage 2 have embedded variables whose locations are
+well-defined, so that the installation can patch the binary file
+directly without recompilation of the stages.
+
+In Stage 1, these are defined:
+
+@table @code
+@item 0x3E
+The version number (not GRUB's, but the installation mechanism's).
+
+@item 0x40
+The boot drive. If it is 0xFF, use a drive passed by BIOS.
+
+@item 0x41
+The flag for if forcing LBA.
+
+@item 0x42
+The starting address of Stage 2.
+
+@item 0x44
+The first sector of Stage 2.
+
+@item 0x48
+The starting segment of Stage 2.
+
+@item 0x1FE
+The signature (@code{0xAA55}).
+@end table
+
+See the file @file{stage1/stage1.S}, for more information.
+
+In the first sector of Stage 1.5 and Stage 2, the block lists are
+recorded between @code{firstlist} and @code{lastlist}. The address of
+@code{lastlist} is determined when assembling the file
+@file{stage2/start.S}.
+
+The trick here is that it is actually read backward, and the first
+8-byte block list is not read here, but after the pointer is decremented
+8 bytes, then after reading it, it decrements again, reads, and so on,
+until it is finished. The terminating condition is when the number of
+sectors to be read in the next block list is zero.
+
+The format of a block list can be seen from the example in the code just
+before the @code{firstlist} label. Note that it is always from the
+beginning of the disk, but @emph{not} relative to the partition 
+boundaries.
+
+In the second sector of Stage 1.5 and Stage 2, these are defined:
+
+@table @asis
+@item @code{0x6}
+The version number (likewise, the installation mechanism's).
+
+@item @code{0x8}
+The installed partition.
+
+@item @code{0xC}
+The saved entry number.
+
+@item @code{0x10}
+The identifier.
+
+@item @code{0x11}
+The flag for if forcing LBA.
+
+@item @code{0x12}
+The version string (GRUB's).
+
+@item @code{0x12} + @dfn{the length of the version string}
+The name of a configuration file.
+@end table
+
+See the file @file{stage2/asm.S}, for more information.
+
+
+@node Filesystem interface
+@section The generic interface for filesystems
+
+For any particular partition, it is presumed that only one of the
+@dfn{normal} filesystems such as FAT, FFS, or ext2fs can be used, so
+there is a switch table managed by the functions in
+@file{disk_io.c}. The notation is that you can only @dfn{mount} one at a
+time.
+
+The block list filesystem has a special place in the system. In addition
+to the @dfn{normal} filesystem (or even without one mounted), you can
+access disk blocks directly (in the indicated partition) via the block
+list notation. Using the block list filesystem doesn't effect any other
+filesystem mounts.
+
+The variables which can be read by the filesystem backend are:
+
+@vtable @code
+@item current_drive
+The current BIOS drive number (numbered from 0, if a floppy, and
+numbered from 0x80, if a hard disk).
+
+@item current_partition
+The current partition number.
+
+@item current_slice
+The current partition type.
+
+@item saved_drive
+The @dfn{drive} part of the root device.
+
+@item saved_partition
+The @dfn{partition} part of the root device.
+
+@item part_start
+The current partition starting address, in sectors.
+
+@item part_length
+The current partition length, in sectors.
+
+@item print_possibilities
+True when the @code{dir} function should print the possible completions
+of a file, and false when it should try to actually open a file of that
+name.
+
+@item FSYS_BUF
+Filesystem buffer which is 32K in size, to use in any way which the
+filesystem backend desires.
+@end vtable
+
+The variables which need to be written by a filesystem backend are:
+
+@vtable @code
+@item filepos
+The current position in the file, in sectors.
+
+@strong{Caution:} the value of @var{filepos} can be changed out from
+under the filesystem code in the current implementation. Don't depend on
+it being the same for later calls into the backend code!
+
+@item filemax
+The length of the file.
+
+@item disk_read_func
+The value of @var{disk_read_hook} @emph{only} during reading of data
+for the file, not any other fs data, inodes, FAT tables, whatever, then
+set to @code{NULL} at all other times (it will be @code{NULL} by
+default). If this isn't done correctly, then the @command{testload} and
+@command{install} commands won't work correctly.
+@end vtable
+
+The functions expected to be used by the filesystem backend are:
+
+@ftable @code
+@item devread
+Only read sectors from within a partition. Sector 0 is the first sector
+in the partition.
+
+@item grub_read
+If the backend uses the block list code, then @code{grub_read} can be
+used, after setting @var{block_file} to 1.
+
+@item print_a_completion
+If @var{print_possibilities} is true, call @code{print_a_completion} for
+each possible file name. Otherwise, the file name completion won't work.
+@end ftable
+
+The functions expected to be defined by the filesystem backend are
+described at least moderately in the file @file{filesys.h}. Their usage
+is fairly evident from their use in the functions in @file{disk_io.c},
+look for the use of the @var{fsys_table} array.
+
+@strong{Caution:} The semantics are such that then @samp{mount}ing the
+filesystem, presume the filesystem buffer @code{FSYS_BUF} is corrupted,
+and (re-)load all important contents. When opening and reading a file,
+presume that the data from the @samp{mount} is available, and doesn't
+get corrupted by the open/read (i.e. multiple opens and/or reads will be
+done with only one mount if in the same filesystem).
+
+
+@node Command interface
+@section The generic interface for built-ins
+
+GRUB built-in commands are defined in a uniformal interface, whether
+they are menu-specific or can be used anywhere. The definition of a
+builtin command consists of two parts: the code itself and the table of
+the information.
+
+The code must be a function which takes two arguments, a command-line
+string and flags, and returns an @samp{int} value. The @dfn{flags}
+argument specifies how the function is called, using a bit mask. The
+return value must be zero if successful, otherwise non-zero. So it is
+normally enough to return @var{errnum}.
+
+The table of the information is represented by the structure
+@code{struct builtin}, which contains the name of the command, a pointer
+to the function, flags, a short description of the command and a long
+description of the command. Since the descriptions are used only for
+help messages interactively, you don't have to define them, if the
+command may not be called interactively (such as @command{title}).
+
+The table is finally registered in the table @var{builtin_table}, so
+that @code{run_script} and @code{enter_cmdline} can find the
+command. See the files @file{cmdline.c} and @file{builtins.c}, for more
+details.
+
+
+@node Bootstrap tricks
+@section The bootstrap mechanism used in GRUB
+
+The disk space can be used in a boot loader is very restricted because
+a MBR (@pxref{MBR}) is only 512 bytes but it also contains a partition
+table (@pxref{Partition table}) and a BPB. So the question is how to
+make a boot loader code enough small to be fit in a MBR.
+
+However, GRUB is a very large program, so we break GRUB into 2 (or 3)
+distinct components, @dfn{Stage 1} and @dfn{Stage 2} (and optionally
+@dfn{Stage 1.5}). @xref{Memory map}, for more information.
+
+We embed Stage 1 in a MBR or in the boot sector of a partition, and
+place Stage 2 in a filesystem. The optional Stage 1.5 can be installed
+in a filesystem, in the @dfn{boot loader} area in a FFS or a ReiserFS,
+and in the sectors right after a MBR, because Stage 1.5 is enough small
+and the sectors right after a MBR is normally an unused region. The size
+of this region is the number of sectors per head minus 1.
+
+Thus, all Stage1 must do is just load Stage2 or Stage1.5. But even if
+Stage 1 needs not to support the user interface or the filesystem
+interface, it is impossible to make Stage 1 less than 400 bytes, because
+GRUB should support both the CHS mode and the LBA mode (@pxref{Low-level
+disk I/O}).
+
+The solution used by GRUB is that Stage 1 loads only the first sector of
+Stage 2 (or Stage 1.5) and Stage 2 itself loads the rest. The flow of
+Stage 1 is:
+
+@enumerate
+@item
+Initialize the system briefly.
+
+@item
+Detect the geometry and the accessing mode of the @dfn{loading drive}.
+
+@item
+Load the first sector of Stage 2.
+
+@item
+Jump to the starting address of the Stage 2.
+@end enumerate
+
+The flow of Stage 2 (and Stage 1.5) is:
+
+@enumerate
+@item
+Load the rest of itself to the real starting address, that is, the
+starting address plus 512 bytes. The block lists are stored in the last
+part of the first sector.
+
+@item
+Long jump to the real starting address.
+@end enumerate
+
+Note that Stage 2 (or Stage 1.5) does not probe the geometry
+or the accessing mode of the @dfn{loading drive}, since Stage 1 has
+already probed them.
+
+
+@node I/O ports detection
+@section How to probe I/O ports used by INT 13H
+
+FIXME: I will write this chapter after implementing the new technique.
+
+
+
+@node Memory detection
+@section How to detect all installed RAM
+
+FIXME: I doubt if Erich didn't write this chapter only himself wholly,
+so I will rewrite this chapter.
+
+
+@node Low-level disk I/O
+@section INT 13H disk I/O interrupts
+
+FIXME: I'm not sure where some part of the original chapter is derived,
+so I will rewrite this chapter.
+
+
+@node MBR
+@section The structure of Master Boot Record
+
+FIXME: Likewise.
+
+
+@node Partition table
+@section The format of partition tables
+
+FIXME: Probably the original chapter is derived from "How It Works", so
+I will rewrite this chapter.
+
+
+@node Submitting patches
+@section Where and how you should send patches
+
+When you write patches for GRUB, please send them to the mailing list
+@email{bug-grub@@gnu.org}. Here is the list of items of which you
+should take care:
+
+@itemize @bullet
+@item
+Please make your patch as small as possible. Generally, it is not a good
+thing to make one big patch which changes many things. Instead,
+segregate features and produce many patches.
+
+@item
+Use as late code as possible, for the original code. The CVS repository
+always has the current version (@pxref{Obtaining and Building GRUB}).
+
+@item
+Write ChangeLog entries. @xref{Change Logs, , Change Logs, standards,
+GNU Coding Standards}, if you don't know how to write ChangeLog.
+
+@item
+Make patches in unified diff format. @samp{diff -urN} is appropriate in
+most cases.
+
+@item
+Don't make patches reversely. Reverse patches are difficult to read and
+use.
+
+@item
+Be careful enough of the license term and the copyright. Because GRUB
+is under GNU General Public License, you may not steal code from
+software whose license is incompatible against GPL. And, if you copy
+code written by others, you must not ignore their copyrights. Feel free
+to ask GRUB maintainers, whenever you are not sure what you should do.
+
+@item
+If your patch is too large to send in e-mail, put it at somewhere we can
+see. Usually, you shouldn't send e-mail over 20K.
+@end itemize
diff --git a/docs/kernel.c b/docs/kernel.c
new file mode 100644
index 0000000..af0def9
--- /dev/null
+++ b/docs/kernel.c
@@ -0,0 +1,284 @@
+/* kernel.c - the C part of the kernel */
+/* Copyright (C) 1999  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.  */
+
+#include <multiboot.h>
+
+/* Macros.  */
+
+/* Check if the bit BIT in FLAGS is set.  */
+#define CHECK_FLAG(flags,bit)	((flags) & (1 << (bit)))
+
+/* Some screen stuff.  */
+/* The number of columns.  */
+#define COLUMNS			80
+/* The number of lines.  */
+#define LINES			24
+/* The attribute of an character.  */
+#define ATTRIBUTE		7
+/* The video memory address.  */
+#define VIDEO			0xB8000
+
+/* Variables.  */
+/* Save the X position.  */
+static int xpos;
+/* Save the Y position.  */
+static int ypos;
+/* Point to the video memory.  */
+static volatile unsigned char *video;
+
+/* Forward declarations.  */
+void cmain (unsigned long magic, unsigned long addr);
+static void cls (void);
+static void itoa (char *buf, int base, int d);
+static void putchar (int c);
+void printf (const char *format, ...);
+
+/* Check if MAGIC is valid and print the Multiboot information structure
+   pointed by ADDR.  */
+void
+cmain (unsigned long magic, unsigned long addr)
+{
+  multiboot_info_t *mbi;
+  
+  /* Clear the screen.  */
+  cls ();
+
+  /* Am I booted by a Multiboot-compliant boot loader?  */
+  if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
+    {
+      printf ("Invalid magic number: 0x%x\n", (unsigned) magic);
+      return;
+    }
+
+  /* Set MBI to the address of the Multiboot information structure.  */
+  mbi = (multiboot_info_t *) addr;
+
+  /* Print out the flags.  */
+  printf ("flags = 0x%x\n", (unsigned) mbi->flags);
+
+  /* Are mem_* valid?  */
+  if (CHECK_FLAG (mbi->flags, 0))
+    printf ("mem_lower = %uKB, mem_upper = %uKB\n",
+	    (unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper);
+
+  /* Is boot_device valid?  */
+  if (CHECK_FLAG (mbi->flags, 1))
+    printf ("boot_device = 0x%x\n", (unsigned) mbi->boot_device);
+  
+  /* Is the command line passed?  */
+  if (CHECK_FLAG (mbi->flags, 2))
+    printf ("cmdline = %s\n", (char *) mbi->cmdline);
+
+  /* Are mods_* valid?  */
+  if (CHECK_FLAG (mbi->flags, 3))
+    {
+      module_t *mod;
+      int i;
+      
+      printf ("mods_count = %d, mods_addr = 0x%x\n",
+	      (int) mbi->mods_count, (int) mbi->mods_addr);
+      for (i = 0, mod = (module_t *) mbi->mods_addr;
+	   i < mbi->mods_count;
+	   i++, mod++)
+	printf (" mod_start = 0x%x, mod_end = 0x%x, string = %s\n",
+		(unsigned) mod->mod_start,
+		(unsigned) mod->mod_end,
+		(char *) mod->string);
+    }
+
+  /* Bits 4 and 5 are mutually exclusive!  */
+  if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5))
+    {
+      printf ("Both bits 4 and 5 are set.\n");
+      return;
+    }
+
+  /* Is the symbol table of a.out valid?  */
+  if (CHECK_FLAG (mbi->flags, 4))
+    {
+      aout_symbol_table_t *aout_sym = &(mbi->u.aout_sym);
+      
+      printf ("aout_symbol_table: tabsize = 0x%0x, "
+	      "strsize = 0x%x, addr = 0x%x\n",
+	      (unsigned) aout_sym->tabsize,
+	      (unsigned) aout_sym->strsize,
+	      (unsigned) aout_sym->addr);
+    }
+
+  /* Is the section header table of ELF valid?  */
+  if (CHECK_FLAG (mbi->flags, 5))
+    {
+      elf_section_header_table_t *elf_sec = &(mbi->u.elf_sec);
+
+      printf ("elf_sec: num = %u, size = 0x%x,"
+	      " addr = 0x%x, shndx = 0x%x\n",
+	      (unsigned) elf_sec->num, (unsigned) elf_sec->size,
+	      (unsigned) elf_sec->addr, (unsigned) elf_sec->shndx);
+    }
+
+  /* Are mmap_* valid?  */
+  if (CHECK_FLAG (mbi->flags, 6))
+    {
+      memory_map_t *mmap;
+      
+      printf ("mmap_addr = 0x%x, mmap_length = 0x%x\n",
+	      (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length);
+      for (mmap = (memory_map_t *) mbi->mmap_addr;
+	   (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
+	   mmap = (memory_map_t *) ((unsigned long) mmap
+				    + mmap->size + sizeof (mmap->size)))
+	printf (" size = 0x%x, base_addr = 0x%x%x,"
+		" length = 0x%x%x, type = 0x%x\n",
+		(unsigned) mmap->size,
+		(unsigned) mmap->base_addr_high,
+		(unsigned) mmap->base_addr_low,
+		(unsigned) mmap->length_high,
+		(unsigned) mmap->length_low,
+		(unsigned) mmap->type);
+    }
+}    
+
+/* Clear the screen and initialize VIDEO, XPOS and YPOS.  */
+static void
+cls (void)
+{
+  int i;
+
+  video = (unsigned char *) VIDEO;
+  
+  for (i = 0; i < COLUMNS * LINES * 2; i++)
+    *(video + i) = 0;
+
+  xpos = 0;
+  ypos = 0;
+}
+
+/* Convert the integer D to a string and save the string in BUF. If
+   BASE is equal to 'd', interpret that D is decimal, and if BASE is
+   equal to 'x', interpret that D is hexadecimal.  */
+static void
+itoa (char *buf, int base, int d)
+{
+  char *p = buf;
+  char *p1, *p2;
+  unsigned long ud = d;
+  int divisor = 10;
+  
+  /* If %d is specified and D is minus, put `-' in the head.  */
+  if (base == 'd' && d < 0)
+    {
+      *p++ = '-';
+      buf++;
+      ud = -d;
+    }
+  else if (base == 'x')
+    divisor = 16;
+
+  /* Divide UD by DIVISOR until UD == 0.  */
+  do
+    {
+      int remainder = ud % divisor;
+      
+      *p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10;
+    }
+  while (ud /= divisor);
+
+  /* Terminate BUF.  */
+  *p = 0;
+  
+  /* Reverse BUF.  */
+  p1 = buf;
+  p2 = p - 1;
+  while (p1 < p2)
+    {
+      char tmp = *p1;
+      *p1 = *p2;
+      *p2 = tmp;
+      p1++;
+      p2--;
+    }
+}
+
+/* Put the character C on the screen.  */
+static void
+putchar (int c)
+{
+  if (c == '\n' || c == '\r')
+    {
+    newline:
+      xpos = 0;
+      ypos++;
+      if (ypos >= LINES)
+	ypos = 0;
+      return;
+    }
+
+  *(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF;
+  *(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE;
+
+  xpos++;
+  if (xpos >= COLUMNS)
+    goto newline;
+}
+
+/* Format a string and print it on the screen, just like the libc
+   function printf.  */
+void
+printf (const char *format, ...)
+{
+  char **arg = (char **) &format;
+  int c;
+  char buf[20];
+
+  arg++;
+  
+  while ((c = *format++) != 0)
+    {
+      if (c != '%')
+	putchar (c);
+      else
+	{
+	  char *p;
+	  
+	  c = *format++;
+	  switch (c)
+	    {
+	    case 'd':
+	    case 'u':
+	    case 'x':
+	      itoa (buf, c, *((int *) arg++));
+	      p = buf;
+	      goto string;
+	      break;
+
+	    case 's':
+	      p = *arg++;
+	      if (! p)
+		p = "(null)";
+
+	    string:
+	      while (*p)
+		putchar (*p++);
+	      break;
+
+	    default:
+	      putchar (*((int *) arg++));
+	      break;
+	    }
+	}
+    }
+}
diff --git a/docs/kernel.c.texi b/docs/kernel.c.texi
new file mode 100644
index 0000000..bd61bd5
--- /dev/null
+++ b/docs/kernel.c.texi
@@ -0,0 +1,284 @@
+/* @r{kernel.c - the C part of the kernel} */
+/* @r{Copyright (C) 1999  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.} */
+
+#include <multiboot.h>
+
+/* @r{Macros.} */
+
+/* @r{Check if the bit BIT in FLAGS is set.} */
+#define CHECK_FLAG(flags,bit)   ((flags) & (1 << (bit)))
+
+/* @r{Some screen stuff.} */
+/* @r{The number of columns.} */
+#define COLUMNS                 80
+/* @r{The number of lines.} */
+#define LINES                   24
+/* @r{The attribute of an character.} */
+#define ATTRIBUTE               7
+/* @r{The video memory address.} */
+#define VIDEO                   0xB8000
+
+/* @r{Variables.} */
+/* @r{Save the X position.} */
+static int xpos;
+/* @r{Save the Y position.} */
+static int ypos;
+/* @r{Point to the video memory.} */
+static volatile unsigned char *video;
+
+/* @r{Forward declarations.} */
+void cmain (unsigned long magic, unsigned long addr);
+static void cls (void);
+static void itoa (char *buf, int base, int d);
+static void putchar (int c);
+void printf (const char *format, ...);
+
+/* @r{Check if MAGIC is valid and print the Multiboot information structure
+   pointed by ADDR.} */
+void
+cmain (unsigned long magic, unsigned long addr)
+@{
+  multiboot_info_t *mbi;
+  
+  /* @r{Clear the screen.} */
+  cls ();
+
+  /* @r{Am I booted by a Multiboot-compliant boot loader?} */
+  if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
+    @{
+      printf ("Invalid magic number: 0x%x\n", (unsigned) magic);
+      return;
+    @}
+
+  /* @r{Set MBI to the address of the Multiboot information structure.} */
+  mbi = (multiboot_info_t *) addr;
+
+  /* @r{Print out the flags.} */
+  printf ("flags = 0x%x\n", (unsigned) mbi->flags);
+
+  /* @r{Are mem_* valid?} */
+  if (CHECK_FLAG (mbi->flags, 0))
+    printf ("mem_lower = %uKB, mem_upper = %uKB\n",
+            (unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper);
+
+  /* @r{Is boot_device valid?} */
+  if (CHECK_FLAG (mbi->flags, 1))
+    printf ("boot_device = 0x%x\n", (unsigned) mbi->boot_device);
+  
+  /* @r{Is the command line passed?} */
+  if (CHECK_FLAG (mbi->flags, 2))
+    printf ("cmdline = %s\n", (char *) mbi->cmdline);
+
+  /* @r{Are mods_* valid?} */
+  if (CHECK_FLAG (mbi->flags, 3))
+    @{
+      module_t *mod;
+      int i;
+      
+      printf ("mods_count = %d, mods_addr = 0x%x\n",
+              (int) mbi->mods_count, (int) mbi->mods_addr);
+      for (i = 0, mod = (module_t *) mbi->mods_addr;
+           i < mbi->mods_count;
+           i++, mod++)
+        printf (" mod_start = 0x%x, mod_end = 0x%x, string = %s\n",
+                (unsigned) mod->mod_start,
+                (unsigned) mod->mod_end,
+                (char *) mod->string);
+    @}
+
+  /* @r{Bits 4 and 5 are mutually exclusive!} */
+  if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5))
+    @{
+      printf ("Both bits 4 and 5 are set.\n");
+      return;
+    @}
+
+  /* @r{Is the symbol table of a.out valid?} */
+  if (CHECK_FLAG (mbi->flags, 4))
+    @{
+      aout_symbol_table_t *aout_sym = &(mbi->u.aout_sym);
+      
+      printf ("aout_symbol_table: tabsize = 0x%0x, "
+              "strsize = 0x%x, addr = 0x%x\n",
+              (unsigned) aout_sym->tabsize,
+              (unsigned) aout_sym->strsize,
+              (unsigned) aout_sym->addr);
+    @}
+
+  /* @r{Is the section header table of ELF valid?} */
+  if (CHECK_FLAG (mbi->flags, 5))
+    @{
+      elf_section_header_table_t *elf_sec = &(mbi->u.elf_sec);
+
+      printf ("elf_sec: num = %u, size = 0x%x,"
+              " addr = 0x%x, shndx = 0x%x\n",
+              (unsigned) elf_sec->num, (unsigned) elf_sec->size,
+              (unsigned) elf_sec->addr, (unsigned) elf_sec->shndx);
+    @}
+
+  /* @r{Are mmap_* valid?} */
+  if (CHECK_FLAG (mbi->flags, 6))
+    @{
+      memory_map_t *mmap;
+      
+      printf ("mmap_addr = 0x%x, mmap_length = 0x%x\n",
+              (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length);
+      for (mmap = (memory_map_t *) mbi->mmap_addr;
+           (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
+           mmap = (memory_map_t *) ((unsigned long) mmap
+                                    + mmap->size + sizeof (mmap->size)))
+        printf (" size = 0x%x, base_addr = 0x%x%x,"
+                " length = 0x%x%x, type = 0x%x\n",
+                (unsigned) mmap->size,
+                (unsigned) mmap->base_addr_high,
+                (unsigned) mmap->base_addr_low,
+                (unsigned) mmap->length_high,
+                (unsigned) mmap->length_low,
+                (unsigned) mmap->type);
+    @}
+@}    
+
+/* @r{Clear the screen and initialize VIDEO, XPOS and YPOS.} */
+static void
+cls (void)
+@{
+  int i;
+
+  video = (unsigned char *) VIDEO;
+  
+  for (i = 0; i < COLUMNS * LINES * 2; i++)
+    *(video + i) = 0;
+
+  xpos = 0;
+  ypos = 0;
+@}
+
+/* @r{Convert the integer D to a string and save the string in BUF. If
+   BASE is equal to 'd', interpret that D is decimal, and if BASE is
+   equal to 'x', interpret that D is hexadecimal.} */
+static void
+itoa (char *buf, int base, int d)
+@{
+  char *p = buf;
+  char *p1, *p2;
+  unsigned long ud = d;
+  int divisor = 10;
+  
+  /* @r{If %d is specified and D is minus, put `-' in the head.} */
+  if (base == 'd' && d < 0)
+    @{
+      *p++ = '-';
+      buf++;
+      ud = -d;
+    @}
+  else if (base == 'x')
+    divisor = 16;
+
+  /* @r{Divide UD by DIVISOR until UD == 0.} */
+  do
+    @{
+      int remainder = ud % divisor;
+      
+      *p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10;
+    @}
+  while (ud /= divisor);
+
+  /* @r{Terminate BUF.} */
+  *p = 0;
+  
+  /* @r{Reverse BUF.} */
+  p1 = buf;
+  p2 = p - 1;
+  while (p1 < p2)
+    @{
+      char tmp = *p1;
+      *p1 = *p2;
+      *p2 = tmp;
+      p1++;
+      p2--;
+    @}
+@}
+
+/* @r{Put the character C on the screen.} */
+static void
+putchar (int c)
+@{
+  if (c == '\n' || c == '\r')
+    @{
+    newline:
+      xpos = 0;
+      ypos++;
+      if (ypos >= LINES)
+        ypos = 0;
+      return;
+    @}
+
+  *(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF;
+  *(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE;
+
+  xpos++;
+  if (xpos >= COLUMNS)
+    goto newline;
+@}
+
+/* @r{Format a string and print it on the screen, just like the libc
+   function printf.} */
+void
+printf (const char *format, ...)
+@{
+  char **arg = (char **) &format;
+  int c;
+  char buf[20];
+
+  arg++;
+  
+  while ((c = *format++) != 0)
+    @{
+      if (c != '%')
+        putchar (c);
+      else
+        @{
+          char *p;
+          
+          c = *format++;
+          switch (c)
+            @{
+            case 'd':
+            case 'u':
+            case 'x':
+              itoa (buf, c, *((int *) arg++));
+              p = buf;
+              goto string;
+              break;
+
+            case 's':
+              p = *arg++;
+              if (! p)
+                p = "(null)";
+
+            string:
+              while (*p)
+                putchar (*p++);
+              break;
+
+            default:
+              putchar (*((int *) arg++));
+              break;
+            @}
+        @}
+    @}
+@}
diff --git a/docs/mbchk.1 b/docs/mbchk.1
new file mode 100644
index 0000000..3ff3fbd
--- /dev/null
+++ b/docs/mbchk.1
@@ -0,0 +1,27 @@
+.\" DO NOT MODIFY THIS FILE!  It was generated by help2man 1.23.
+.TH MBCHK "1" "May 2005" "mbchk (GNU GRUB 0.97)" FSF
+.SH NAME
+mbchk \- check the format of a Multiboot kernel
+.SH SYNOPSIS
+.B mbchk
+[\fIOPTION\fR]... [\fIFILE\fR]...
+.SH DESCRIPTION
+Check if the format of FILE complies with the Multiboot Specification.
+.PP
+\fB\-q\fR, \fB\-\-quiet\fR                suppress all normal output
+\fB\-h\fR, \fB\-\-help\fR                 display this help and exit
+\fB\-v\fR, \fB\-\-version\fR              output version information and exit.
+.SH "REPORTING BUGS"
+Report bugs to <bug-grub@gnu.org>.
+.SH "SEE ALSO"
+The full documentation for
+.B mbchk
+is maintained as a Texinfo manual.  If the
+.B info
+and
+.B mbchk
+programs are properly installed at your site, the command
+.IP
+.B info mbchk
+.PP
+should give you access to the complete manual.
diff --git a/docs/mdate-sh b/docs/mdate-sh
new file mode 100755
index 0000000..881782e
--- /dev/null
+++ b/docs/mdate-sh
@@ -0,0 +1,170 @@
+#!/bin/sh
+# Get modification time of a file or directory and pretty-print it.
+
+scriptversion=2004-12-08.12
+
+# Copyright (C) 1995, 1996, 1997, 2003, 2004 Free Software Foundation, Inc.
+# written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
+#
+# 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.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+case $1 in
+  '')
+     echo "$0: No file.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: mdate-sh [--help] [--version] FILE
+
+Pretty-print the modification time of FILE.
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit 0
+    ;;
+  -v | --v*)
+    echo "mdate-sh $scriptversion"
+    exit 0
+    ;;
+esac
+
+# Prevent date giving response in another language.
+LANG=C
+export LANG
+LC_ALL=C
+export LC_ALL
+LC_TIME=C
+export LC_TIME
+
+save_arg1="$1"
+
+# Find out how to get the extended ls output of a file or directory.
+if ls -L /dev/null 1>/dev/null 2>&1; then
+  ls_command='ls -L -l -d'
+else
+  ls_command='ls -l -d'
+fi
+
+# A `ls -l' line looks as follows on OS/2.
+#  drwxrwx---        0 Aug 11  2001 foo
+# This differs from Unix, which adds ownership information.
+#  drwxrwx---   2 root  root      4096 Aug 11  2001 foo
+#
+# To find the date, we split the line on spaces and iterate on words
+# until we find a month.  This cannot work with files whose owner is a
+# user named `Jan', or `Feb', etc.  However, it's unlikely that `/'
+# will be owned by a user whose name is a month.  So we first look at
+# the extended ls output of the root directory to decide how many
+# words should be skipped to get the date.
+
+# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below.
+set x`ls -l -d /`
+
+# Find which argument is the month.
+month=
+command=
+until test $month
+do
+  shift
+  # Add another shift to the command.
+  command="$command shift;"
+  case $1 in
+    Jan) month=January; nummonth=1;;
+    Feb) month=February; nummonth=2;;
+    Mar) month=March; nummonth=3;;
+    Apr) month=April; nummonth=4;;
+    May) month=May; nummonth=5;;
+    Jun) month=June; nummonth=6;;
+    Jul) month=July; nummonth=7;;
+    Aug) month=August; nummonth=8;;
+    Sep) month=September; nummonth=9;;
+    Oct) month=October; nummonth=10;;
+    Nov) month=November; nummonth=11;;
+    Dec) month=December; nummonth=12;;
+  esac
+done
+
+# Get the extended ls output of the file or directory.
+set x`eval "$ls_command \"\$save_arg1\""`
+
+# Remove all preceding arguments
+eval $command
+
+# Get the month.  Next argument is day, followed by the year or time.
+case $1 in
+  Jan) month=January; nummonth=1;;
+  Feb) month=February; nummonth=2;;
+  Mar) month=March; nummonth=3;;
+  Apr) month=April; nummonth=4;;
+  May) month=May; nummonth=5;;
+  Jun) month=June; nummonth=6;;
+  Jul) month=July; nummonth=7;;
+  Aug) month=August; nummonth=8;;
+  Sep) month=September; nummonth=9;;
+  Oct) month=October; nummonth=10;;
+  Nov) month=November; nummonth=11;;
+  Dec) month=December; nummonth=12;;
+esac
+
+day=$2
+
+# Here we have to deal with the problem that the ls output gives either
+# the time of day or the year.
+case $3 in
+  *:*) set `date`; eval year=\$$#
+       case $2 in
+	 Jan) nummonthtod=1;;
+	 Feb) nummonthtod=2;;
+	 Mar) nummonthtod=3;;
+	 Apr) nummonthtod=4;;
+	 May) nummonthtod=5;;
+	 Jun) nummonthtod=6;;
+	 Jul) nummonthtod=7;;
+	 Aug) nummonthtod=8;;
+	 Sep) nummonthtod=9;;
+	 Oct) nummonthtod=10;;
+	 Nov) nummonthtod=11;;
+	 Dec) nummonthtod=12;;
+       esac
+       # For the first six month of the year the time notation can also
+       # be used for files modified in the last year.
+       if (expr $nummonth \> $nummonthtod) > /dev/null;
+       then
+	 year=`expr $year - 1`
+       fi;;
+  *) year=$3;;
+esac
+
+# The result.
+echo $day $month $year
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/docs/menu.lst b/docs/menu.lst
new file mode 100644
index 0000000..ae58aee
--- /dev/null
+++ b/docs/menu.lst
@@ -0,0 +1,82 @@
+#
+# Sample boot menu configuration file
+#
+
+# Boot automatically after 30 secs.
+timeout 30
+
+# By default, boot the first entry.
+default 0
+
+# Fallback to the second entry.
+fallback 1
+
+# For booting GNU/Hurd
+title  GNU/Hurd
+root   (hd0,0)
+kernel /boot/gnumach.gz root=hd0s1
+module /boot/serverboot.gz
+
+# For booting GNU/Linux
+title  GNU/Linux
+root (hd1,0)
+kernel /vmlinuz root=/dev/hdb1
+#initrd /initrd.img
+
+# For booting GNU/kFreeBSD
+title  GNU/kFreeBSD
+root   (hd0,2,a)
+kernel /boot/loader.gz
+
+# For booting GNU/kNetBSD
+title  GNU/kNetBSD
+root   (hd0,2,a)
+kernel --type=netbsd /boot/knetbsd.gz
+
+# For booting Mach (getting kernel from floppy)
+title  Utah Mach4 multiboot
+root   (hd0,2)
+pause  Insert the diskette now!!
+kernel (fd0)/boot/kernel root=hd0s3
+module (fd0)/boot/bootstrap
+
+# For booting FreeBSD
+title  FreeBSD
+root   (hd0,2,a)
+kernel /boot/loader
+
+# For booting NetBSD
+title  NetBSD
+root   (hd0,2,a)
+kernel --type=netbsd /netbsd
+
+# For booting OpenBSD
+title  OpenBSD
+root   (hd0,2,a)
+kernel --type=netbsd /bsd
+
+# For booting OS/2
+title OS/2
+root  (hd0,1)
+makeactive
+# chainload OS/2 bootloader from the first sector
+chainloader +1
+# This is similar to "chainload", but loads a specific file
+#chainloader /boot/chain.os2
+
+# For booting Windows NT or Windows95
+title Windows NT / Windows 95 boot menu
+rootnoverify (hd0,0)
+makeactive
+chainloader  +1
+# For loading DOS if Windows NT is installed
+# chainload /bootsect.dos
+
+# For installing GRUB into the hard disk
+title Install GRUB into the hard disk
+root    (hd0,0)
+setup   (hd0)
+
+# Change the colors.
+title Change the colors
+color light-green/brown blink-red/blue
diff --git a/docs/multiboot.h b/docs/multiboot.h
new file mode 100644
index 0000000..df79225
--- /dev/null
+++ b/docs/multiboot.h
@@ -0,0 +1,119 @@
+/* multiboot.h - the header for Multiboot */
+/* Copyright (C) 1999, 2001  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.  */
+
+/* Macros.  */
+
+/* The magic number for the Multiboot header.  */
+#define MULTIBOOT_HEADER_MAGIC		0x1BADB002
+
+/* The flags for the Multiboot header.  */
+#ifdef __ELF__
+# define MULTIBOOT_HEADER_FLAGS		0x00000003
+#else
+# define MULTIBOOT_HEADER_FLAGS		0x00010003
+#endif
+
+/* The magic number passed by a Multiboot-compliant boot loader.  */
+#define MULTIBOOT_BOOTLOADER_MAGIC	0x2BADB002
+
+/* The size of our stack (16KB).  */
+#define STACK_SIZE			0x4000
+
+/* C symbol format. HAVE_ASM_USCORE is defined by configure.  */
+#ifdef HAVE_ASM_USCORE
+# define EXT_C(sym)			_ ## sym
+#else
+# define EXT_C(sym)			sym
+#endif
+
+#ifndef ASM
+/* Do not include here in boot.S.  */
+
+/* Types.  */
+
+/* The Multiboot header.  */
+typedef struct multiboot_header
+{
+  unsigned long magic;
+  unsigned long flags;
+  unsigned long checksum;
+  unsigned long header_addr;
+  unsigned long load_addr;
+  unsigned long load_end_addr;
+  unsigned long bss_end_addr;
+  unsigned long entry_addr;
+} multiboot_header_t;
+
+/* The symbol table for a.out.  */
+typedef struct aout_symbol_table
+{
+  unsigned long tabsize;
+  unsigned long strsize;
+  unsigned long addr;
+  unsigned long reserved;
+} aout_symbol_table_t;
+
+/* The section header table for ELF.  */
+typedef struct elf_section_header_table
+{
+  unsigned long num;
+  unsigned long size;
+  unsigned long addr;
+  unsigned long shndx;
+} elf_section_header_table_t;
+
+/* The Multiboot information.  */
+typedef struct multiboot_info
+{
+  unsigned long flags;
+  unsigned long mem_lower;
+  unsigned long mem_upper;
+  unsigned long boot_device;
+  unsigned long cmdline;
+  unsigned long mods_count;
+  unsigned long mods_addr;
+  union
+  {
+    aout_symbol_table_t aout_sym;
+    elf_section_header_table_t elf_sec;
+  } u;
+  unsigned long mmap_length;
+  unsigned long mmap_addr;
+} multiboot_info_t;
+
+/* The module structure.  */
+typedef struct module
+{
+  unsigned long mod_start;
+  unsigned long mod_end;
+  unsigned long string;
+  unsigned long reserved;
+} module_t;
+
+/* The memory map. Be careful that the offset 0 is base_addr_low
+   but no size.  */
+typedef struct memory_map
+{
+  unsigned long size;
+  unsigned long base_addr_low;
+  unsigned long base_addr_high;
+  unsigned long length_low;
+  unsigned long length_high;
+  unsigned long type;
+} memory_map_t;
+
+#endif /* ! ASM */
diff --git a/docs/multiboot.h.texi b/docs/multiboot.h.texi
new file mode 100644
index 0000000..3fa8c0b
--- /dev/null
+++ b/docs/multiboot.h.texi
@@ -0,0 +1,119 @@
+/* @r{multiboot.h - the header for Multiboot} */
+/* @r{Copyright (C) 1999, 2001  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.} */
+
+/* @r{Macros.} */
+
+/* @r{The magic number for the Multiboot header.} */
+#define MULTIBOOT_HEADER_MAGIC          0x1BADB002
+
+/* @r{The flags for the Multiboot header.} */
+#ifdef __ELF__
+# define MULTIBOOT_HEADER_FLAGS         0x00000003
+#else
+# define MULTIBOOT_HEADER_FLAGS         0x00010003
+#endif
+
+/* @r{The magic number passed by a Multiboot-compliant boot loader.} */
+#define MULTIBOOT_BOOTLOADER_MAGIC      0x2BADB002
+
+/* @r{The size of our stack (16KB).} */
+#define STACK_SIZE                      0x4000
+
+/* @r{C symbol format. HAVE_ASM_USCORE is defined by configure.} */
+#ifdef HAVE_ASM_USCORE
+# define EXT_C(sym)                     _ ## sym
+#else
+# define EXT_C(sym)                     sym
+#endif
+
+#ifndef ASM
+/* @r{Do not include here in boot.S.} */
+
+/* @r{Types.} */
+
+/* @r{The Multiboot header.} */
+typedef struct multiboot_header
+@{
+  unsigned long magic;
+  unsigned long flags;
+  unsigned long checksum;
+  unsigned long header_addr;
+  unsigned long load_addr;
+  unsigned long load_end_addr;
+  unsigned long bss_end_addr;
+  unsigned long entry_addr;
+@} multiboot_header_t;
+
+/* @r{The symbol table for a.out.} */
+typedef struct aout_symbol_table
+@{
+  unsigned long tabsize;
+  unsigned long strsize;
+  unsigned long addr;
+  unsigned long reserved;
+@} aout_symbol_table_t;
+
+/* @r{The section header table for ELF.} */
+typedef struct elf_section_header_table
+@{
+  unsigned long num;
+  unsigned long size;
+  unsigned long addr;
+  unsigned long shndx;
+@} elf_section_header_table_t;
+
+/* @r{The Multiboot information.} */
+typedef struct multiboot_info
+@{
+  unsigned long flags;
+  unsigned long mem_lower;
+  unsigned long mem_upper;
+  unsigned long boot_device;
+  unsigned long cmdline;
+  unsigned long mods_count;
+  unsigned long mods_addr;
+  union
+  @{
+    aout_symbol_table_t aout_sym;
+    elf_section_header_table_t elf_sec;
+  @} u;
+  unsigned long mmap_length;
+  unsigned long mmap_addr;
+@} multiboot_info_t;
+
+/* @r{The module structure.} */
+typedef struct module
+@{
+  unsigned long mod_start;
+  unsigned long mod_end;
+  unsigned long string;
+  unsigned long reserved;
+@} module_t;
+
+/* @r{The memory map. Be careful that the offset 0 is base_addr_low
+   but no size.} */
+typedef struct memory_map
+@{
+  unsigned long size;
+  unsigned long base_addr_low;
+  unsigned long base_addr_high;
+  unsigned long length_low;
+  unsigned long length_high;
+  unsigned long type;
+@} memory_map_t;
+
+#endif /* @r{! ASM} */
diff --git a/docs/multiboot.info b/docs/multiboot.info
new file mode 100644
index 0000000..bcd1e9d
--- /dev/null
+++ b/docs/multiboot.info
Binary files differ
diff --git a/docs/multiboot.texi b/docs/multiboot.texi
new file mode 100644
index 0000000..eded05c
--- /dev/null
+++ b/docs/multiboot.texi
@@ -0,0 +1,1234 @@
+\input texinfo @c -*-texinfo-*-
+@c -*-texinfo-*-
+@c %**start of header
+@setfilename multiboot.info
+@settitle Multiboot Specification
+@c %**end of header
+
+@c Unify all our little indices for now.
+@syncodeindex fn cp
+@syncodeindex vr cp
+@syncodeindex ky cp
+@syncodeindex pg cp
+@syncodeindex tp cp
+
+@footnotestyle separate
+@paragraphindent 3
+@finalout
+
+
+@dircategory Kernel
+@direntry
+* Multiboot Specification: (multiboot).		Multiboot Specification.
+@end direntry
+
+@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.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries a copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end ifinfo
+
+@titlepage
+@sp 10
+@title The Multiboot Specification
+@author Yoshinori K. Okuji, Bryan Ford, Erich Stefan Boleyn, Kunihiro Ishiguro
+@page
+
+@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.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided also that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions.
+@end titlepage
+
+@finalout
+@headings double
+
+@ifnottex
+@node Top
+@top Multiboot Specification
+
+This file documents Multiboot Specification, the proposal for the boot
+sequence standard. This edition documents version 0.6.93.
+@end ifnottex
+
+@menu
+* Overview::                    
+* Terminology::                 
+* Specification::               
+* Examples::                    
+* History::                     
+* Index::                       
+@end menu
+
+
+@node Overview
+@chapter Introduction to Multiboot Specification
+
+This chapter describes some rough information on the Multiboot
+Specification. Note that this is not a part of the specification itself.
+
+@menu
+* Motivation::                  
+* Architecture::                
+* Operating systems::           
+* Boot sources::                
+* Boot-time configuration::     
+* Convenience to operating systems::  
+* Boot modules::                
+@end menu
+
+
+@node Motivation
+@section The background of Multiboot Specification
+
+Every operating system ever created tends to have its own boot loader.
+Installing a new operating system on a machine generally involves
+installing a whole new set of boot mechanisms, each with completely
+different install-time and boot-time user interfaces. Getting multiple
+operating systems to coexist reliably on one machine through typical
+@dfn{chaining} mechanisms can be a nightmare. There is little or no
+choice of boot loaders for a particular operating system --- if the one
+that comes with the operating system doesn't do exactly what you want,
+or doesn't work on your machine, you're screwed.
+
+While we may not be able to fix this problem in existing commercial
+operating systems, it shouldn't be too difficult for a few people in the
+free operating system communities to put their heads together and solve
+this problem for the popular free operating systems. That's what this
+specification aims for. Basically, it specifies an interface between a
+boot loader and a operating system, such that any complying boot loader
+should be able to load any complying operating system. This
+specification does @emph{not} specify how boot loaders should work ---
+only how they must interface with the operating system being loaded.
+
+
+@node Architecture
+@section The target architecture
+
+This specification is primarily targeted at @sc{pc}, since they are the
+most common and have the largest variety of operating systems and boot
+loaders. However, to the extent that certain other architectures may
+need a boot specification and do not have one already, a variation of
+this specification, stripped of the x86-specific details, could be
+adopted for them as well.
+
+
+@node Operating systems
+@section The target operating systems
+
+This specification is targeted toward free 32-bit operating systems
+that can be fairly easily modified to support the specification without
+going through lots of bureaucratic rigmarole. The particular free
+operating systems that this specification is being primarily designed
+for are Linux, FreeBSD, NetBSD, Mach, and VSTa. It is hoped that other
+emerging free operating systems will adopt it from the start, and thus
+immediately be able to take advantage of existing boot loaders. It would
+be nice if commercial operating system vendors eventually adopted this
+specification as well, but that's probably a pipe dream.
+
+
+@node Boot sources
+@section Boot sources
+
+It should be possible to write compliant boot loaders that load the OS
+image from a variety of sources, including floppy disk, hard disk, and
+across a network.
+
+Disk-based boot loaders may use a variety of techniques to find the
+relevant OS image and boot module data on disk, such as by
+interpretation of specific file systems (e.g. the BSD/Mach boot loader),
+using precalculated @dfn{block lists} (e.g. LILO), loading from a
+special @dfn{boot partition} (e.g. OS/2), or even loading from within
+another operating system (e.g. the VSTa boot code, which loads from
+DOS). Similarly, network-based boot loaders could use a variety of
+network hardware and protocols.
+
+It is hoped that boot loaders will be created that support multiple
+loading mechanisms, increasing their portability, robustness, and
+user-friendliness.
+
+
+@node Boot-time configuration
+@section Configure an operating system at boot-time
+
+It is often necessary for one reason or another for the user to be able
+to provide some configuration information to an operating system
+dynamically at boot time. While this specification should not dictate
+how this configuration information is obtained by the boot loader, it
+should provide a standard means for the boot loader to pass such
+information to the operating system.
+
+
+@node Convenience to operating systems
+@section How to make OS development easier
+
+OS images should be easy to generate. Ideally, an OS image should simply
+be an ordinary 32-bit executable file in whatever file format the
+operating system normally uses. It should be possible to @code{nm} or
+disassemble OS images just like normal executables. Specialized tools
+should not be required to create OS images in a @emph{special} file
+format. If this means shifting some work from the operating system to
+a boot loader, that is probably appropriate, because all the memory
+consumed by the boot loader will typically be made available again after
+the boot process is created, whereas every bit of code in the OS image
+typically has to remain in memory forever. The operating system should
+not have to worry about getting into 32-bit mode initially, because mode
+switching code generally needs to be in the boot loader anyway in order
+to load operating system data above the 1MB boundary, and forcing the
+operating system to do this makes creation of OS images much more
+difficult.
+
+Unfortunately, there is a horrendous variety of executable file formats
+even among free Unix-like @sc{pc}-based operating systems --- generally
+a different format for each operating system. Most of the relevant free
+operating systems use some variant of a.out format, but some are moving
+to @sc{elf}. It is highly desirable for boot loaders not to have to be
+able to interpret all the different types of executable file formats in
+existence in order to load the OS image --- otherwise the boot loader
+effectively becomes operating system specific again.
+
+This specification adopts a compromise solution to this
+problem. Multiboot-compliant OS images always contain a magic
+@dfn{Multiboot header} (@pxref{OS image format}), which allows the boot
+loader to load the image without having to understand numerous a.out
+variants or other executable formats. This magic header does not need to
+be at the very beginning of the executable file, so kernel images can
+still conform to the local a.out format variant in addition to being
+Multiboot-compliant.
+
+
+@node Boot modules
+@section Boot modules
+
+Many modern operating system kernels, such as those of VSTa and Mach, do
+not by themselves contain enough mechanism to get the system fully
+operational: they require the presence of additional software modules at
+boot time in order to access devices, mount file systems, etc. While
+these additional modules could be embedded in the main OS image along
+with the kernel itself, and the resulting image be split apart manually
+by the operating system when it receives control, it is often more
+flexible, more space-efficient, and more convenient to the operating
+system and user if the boot loader can load these additional modules
+independently in the first place.
+
+Thus, this specification should provide a standard method for a boot
+loader to indicate to the operating system what auxiliary boot modules
+were loaded, and where they can be found. Boot loaders don't have to
+support multiple boot modules, but they are strongly encouraged to,
+because some operating systems will be unable to boot without them.
+
+
+@node Terminology
+@chapter The definitions of terms used through the specification
+
+@table @dfn
+@item must
+We use the term @dfn{must}, when any boot loader or OS image needs to
+follow a rule --- otherwise, the boot loader or OS image is @emph{not}
+Multiboot-compliant.
+
+@item should
+We use the term @dfn{should}, when any boot loader or OS image is
+recommended to follow a rule, but it doesn't need to follow the rule.
+
+@item may
+We use the term @dfn{may}, when any boot loader or OS image is allowed
+to follow a rule.
+
+@item boot loader
+Whatever program or set of programs loads the image of the final
+operating system to be run on the machine. The boot loader may itself
+consist of several stages, but that is an implementation detail not
+relevant to this specification. Only the @emph{final} stage of the boot
+loader --- the stage that eventually transfers control to an operating
+system --- must follow the rules specified in this document in order
+to be @dfn{Multiboot-compliant}; earlier boot loader stages may be
+designed in whatever way is most convenient.
+
+@item OS image
+The initial binary image that a boot loader loads into memory and
+transfers control to start an operating system. The OS image is
+typically an executable containing the operating system kernel.
+
+@item boot module
+Other auxiliary files that a boot loader loads into memory along with
+an OS image, but does not interpret in any way other than passing their
+locations to the operating system when it is invoked.
+
+@item Multiboot-compliant
+A boot loader or an OS image which follows the rules defined as
+@dfn{must} is Multiboot-compliant. When this specification specifies a
+rule as @dfn{should} or @dfn{may}, a Multiboot-complaint boot loader/OS
+image doesn't need to follow the rule.
+
+@item u8
+The type of unsigned 8-bit data.
+
+@item u16
+The type of unsigned 16-bit data. Because the target architecture is
+little-endian, u16 is coded in little-endian.
+
+@item u32
+The type of unsigned 32-bit data. Because the target architecture is
+little-endian, u32 is coded in little-endian.
+
+@item u64
+The type of unsigned 64-bit data. Because the target architecture is
+little-endian, u64 is coded in little-endian.
+@end table
+
+
+@node Specification
+@chapter The exact definitions of Multiboot Specification
+
+There are three main aspects of a boot loader/OS image interface:
+
+@enumerate
+@item
+The format of an OS image as seen by a boot loader.
+
+@item
+The state of a machine when a boot loader starts an operating
+system.
+
+@item
+The format of information passed by a boot loader to an operating
+system.
+@end enumerate
+
+@menu
+* OS image format::             
+* Machine state::               
+* Boot information format::     
+@end menu
+
+
+@node OS image format
+@section OS image format
+
+An OS image may be an ordinary 32-bit executable file in the standard
+format for that particular operating system, except that it may be
+linked at a non-default load address to avoid loading on top of the
+@sc{pc}'s I/O region or other reserved areas, and of course it should
+not use shared libraries or other fancy features.
+
+An OS image must contain an additional header called @dfn{Multiboot
+header}, besides the headers of the format used by the OS image. The
+Multiboot header must be contained completely within the first 8192
+bytes of the OS image, and must be longword (32-bit) aligned. In
+general, it should come @emph{as early as possible}, and may be
+embedded in the beginning of the text segment after the @emph{real}
+executable header.
+
+@menu
+* Header layout::               The layout of Multiboot header
+* Header magic fields::         The magic fields of Multiboot header
+* Header address fields::       
+* Header graphics fields::      
+@end menu
+
+
+@node Header layout
+@subsection The layout of Multiboot header
+
+The layout of the Multiboot header must be as follows:
+
+@multitable @columnfractions .1 .1 .2 .5
+@item Offset @tab Type  @tab Field Name    @tab Note
+@item 0      @tab u32 @tab magic         @tab required
+@item 4      @tab u32 @tab flags         @tab required
+@item 8      @tab u32 @tab checksum      @tab required
+@item 12     @tab u32 @tab header_addr   @tab if flags[16] is set
+@item 16     @tab u32 @tab load_addr     @tab if flags[16] is set
+@item 20     @tab u32 @tab load_end_addr @tab if flags[16] is set
+@item 24     @tab u32 @tab bss_end_addr  @tab if flags[16] is set
+@item 28     @tab u32 @tab entry_addr    @tab if flags[16] is set
+@item 32     @tab u32 @tab mode_type     @tab if flags[2] is set
+@item 36     @tab u32 @tab width         @tab if flags[2] is set
+@item 40     @tab u32 @tab height        @tab if flags[2] is set
+@item 44     @tab u32 @tab depth         @tab if flags[2] is set
+@end multitable
+
+The fields @samp{magic}, @samp{flags} and @samp{checksum} are defined in
+@ref{Header magic fields}, the fields @samp{header_addr},
+@samp{load_addr}, @samp{load_end_addr}, @samp{bss_end_addr} and
+@samp{entry_addr} are defined in @ref{Header address fields}, and the
+fields @samp{mode_type}, @samp{width}, @samp{height} and @samp{depth} are
+defind in @ref{Header graphics fields}.
+
+
+@node Header magic fields
+@subsection The magic fields of Multiboot header
+
+@table @samp
+@item magic
+The field @samp{magic} is the magic number identifying the header,
+which must be the hexadecimal value @code{0x1BADB002}.
+
+@item flags
+The field @samp{flags} specifies features that the OS image requests or
+requires of an boot loader. Bits 0-15 indicate requirements; if the
+boot loader sees any of these bits set but doesn't understand the flag
+or can't fulfill the requirements it indicates for some reason, it must
+notify the user and fail to load the OS image. Bits 16-31 indicate
+optional features; if any bits in this range are set but the boot loader
+doesn't understand them, it may simply ignore them and proceed as
+usual. Naturally, all as-yet-undefined bits in the @samp{flags} word
+must be set to zero in OS images. This way, the @samp{flags} fields
+serves for version control as well as simple feature selection.
+
+If bit 0 in the @samp{flags} word is set, then all boot modules loaded
+along with the operating system must be aligned on page (4KB)
+boundaries. Some operating systems expect to be able to map the pages
+containing boot modules directly into a paged address space during
+startup, and thus need the boot modules to be page-aligned.
+
+If bit 1 in the @samp{flags} word is set, then information on available
+memory via at least the @samp{mem_*} fields of the Multiboot information
+structure (@pxref{Boot information format}) must be included. If the
+boot loader is capable of passing a memory map (the @samp{mmap_*} fields)
+and one exists, then it may be included as well.
+
+If bit 2 in the @samp{flags} word is set, information about the video
+mode table (@pxref{Boot information format}) must be available to the
+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
+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}
+be provided if the images is in a.out format or in some other
+format. Compliant boot loaders must be able to load images that either
+are in @sc{elf} format or contain the load address information embedded
+in the Multiboot header; they may also directly support other executable
+formats, such as particular a.out variants, but are not required to.
+
+@item checksum
+The field @samp{checksum} is a 32-bit unsigned value which, when added
+to the other magic fields (i.e. @samp{magic} and @samp{flags}), must
+have a 32-bit unsigned sum of zero.
+@end table
+
+
+@node Header address fields
+@subsection The address fields of Multiboot header
+
+All of the address fields enabled by flag bit 16 are physical addresses.
+The meaning of each is as follows:
+
+@table @code
+@item header_addr
+Contains the address corresponding to the beginning of the Multiboot
+header --- the physical memory location at which the magic value is
+supposed to be loaded. This field serves to @dfn{synchronize} the
+mapping between OS image offsets and physical memory addresses.
+
+@item load_addr
+Contains the physical address of the beginning of the text segment. The
+offset in the OS image file at which to start loading is defined by the
+offset at which the header was found, minus (header_addr -
+load_addr). load_addr must be less than or equal to header_addr.
+
+@item load_end_addr
+Contains the physical address of the end of the data
+segment. (load_end_addr - load_addr) specifies how much data to load.
+This implies that the text and data segments must be consecutive in the
+OS image; this is true for existing a.out executable formats.
+If this field is zero, the boot loader assumes that the text and data
+segments occupy the whole OS image file.
+
+@item bss_end_addr
+Contains the physical address of the end of the bss segment. The boot
+loader initializes this area to zero, and reserves the memory it
+occupies to avoid placing boot modules and other data relevant to the
+operating system in that area. If this field is zero, the boot loader
+assumes that no bss segment is present.
+
+@item entry_addr
+The physical address to which the boot loader should jump in order to
+start running the operating system.
+@end table
+
+
+@node Header graphics fields
+@subsection The graphics fields of Multiboot header
+
+All of the graphics fields are enabled by flag bit 2. They specify the
+preferred graphics mode. Note that that is only a @emph{recommended}
+mode by the OS image. If the mode exists, the boot loader should set
+it, when the user doesn't specify a mode explicitly. Otherwise, the
+boot loader should fall back to a similar mode, if available.
+
+The meaning of each is as follows:
+
+@table @code
+@item mode_type
+Contains @samp{0} for linear graphics mode or @samp{1} for
+EGA-standard text mode. Everything else is reserved for future
+expansion. Note that the boot loader may set a text mode, even if this
+field contains @samp{0}.
+
+@item width
+Contains the number of the columns. This is specified in pixels in a
+graphics mode, and in characters in a text mode. The value zero
+indicates that the OS image has no preference.
+
+@item height
+Contains the number of the lines. This is specified in pixels in a
+graphics mode, and in characters in a text mode. The value zero
+indicates that the OS image has no preference.
+
+@item depth
+Contains the number of bits per pixel in a graphics mode, and zero in
+a text mode. The value zero indicates that the OS image has no
+preference.
+@end table
+
+
+@node Machine state
+@section Machine state
+
+When the boot loader invokes the 32-bit operating system, the machine
+must have the following state:
+
+@table @samp
+@item EAX
+Must contain the magic value @samp{0x2BADB002}; the presence of this
+value indicates to the operating system that it was loaded by a
+Multiboot-compliant boot loader (e.g. as opposed to another type of
+boot loader that the operating system can also be loaded from).
+
+@item EBX
+Must contain the 32-bit physical address of the Multiboot
+information structure provided by the boot loader (@pxref{Boot
+information format}).
+
+@item CS
+Must be a 32-bit read/execute code segment with an offset of @samp{0}
+and a limit of @samp{0xFFFFFFFF}. The exact value is undefined.
+
+@item DS
+@itemx ES
+@itemx FS
+@itemx GS
+@itemx SS
+Must be a 32-bit read/write data segment with an offset of @samp{0}
+and a limit of @samp{0xFFFFFFFF}. The exact values are all undefined.
+
+@item A20 gate
+Must be enabled.
+
+@item CR0
+Bit 31 (PG) must be cleared. Bit 0 (PE) must be set. Other bits are
+all undefined.
+
+@item EFLAGS
+Bit 17 (VM) must be cleared. Bit 9 (IF) must be cleared. Other bits
+are all undefined.
+@end table
+
+All other processor registers and flag bits are undefined. This
+includes, in particular:
+
+@table @samp
+@item ESP
+The OS image must create its own stack as soon as it needs one.
+
+@item GDTR
+Even though the segment registers are set up as described above, the
+@samp{GDTR} may be invalid, so the OS image must not load any segment
+registers (even just reloading the same values!) until it sets up its
+own @samp{GDT}.
+
+@item IDTR
+The OS image must leave interrupts disabled until it sets up its own
+@code{IDT}.
+@end table
+
+However, other machine state should be left by the boot loader in
+@dfn{normal working order}, i.e. as initialized by the @sc{bios} (or
+DOS, if that's what the boot loader runs from). In other words, the
+operating system should be able to make @sc{bios} calls and such after
+being loaded, as long as it does not overwrite the @sc{bios} data
+structures before doing so. Also, the boot loader must leave the
+@sc{pic} programmed with the normal @sc{bios}/DOS values, even if it
+changed them during the switch to 32-bit mode.
+
+
+@node Boot information format
+@section Boot information format
+
+FIXME: Split this chapter like the chapter ``OS image format''.
+
+Upon entry to the operating system, the @code{EBX} register contains the
+physical address of a @dfn{Multiboot information} data structure,
+through which the boot loader communicates vital information to the
+operating system. The operating system can use or ignore any parts of
+the structure as it chooses; all information passed by the boot loader
+is advisory only.
+
+The Multiboot information structure and its related substructures may be
+placed anywhere in memory by the boot loader (with the exception of the
+memory reserved for the kernel and boot modules, of course). It is the
+operating system's responsibility to avoid overwriting this memory until
+it is done using it.
+
+The format of the Multiboot information structure (as defined so far)
+follows:
+
+@example
+@group
+        +-------------------+
+0       | flags             |    (required)
+        +-------------------+
+4       | mem_lower         |    (present if flags[0] is set)
+8       | mem_upper         |    (present if flags[0] is set)
+        +-------------------+
+12      | boot_device       |    (present if flags[1] is set)
+        +-------------------+
+16      | cmdline           |    (present if flags[2] is set)
+        +-------------------+
+20      | mods_count        |    (present if flags[3] is set)
+24      | mods_addr         |    (present if flags[3] is set)
+        +-------------------+
+28 - 40 | syms              |    (present if flags[4] or
+        |                   |                flags[5] is set)
+        +-------------------+
+44      | mmap_length       |    (present if flags[6] is set)
+48      | mmap_addr         |    (present if flags[6] is set)
+        +-------------------+
+52      | drives_length     |    (present if flags[7] is set)
+56      | drives_addr       |    (present if flags[7] is set)
+        +-------------------+
+60      | config_table      |    (present if flags[8] is set)
+        +-------------------+
+64      | boot_loader_name  |    (present if flags[9] is set)
+        +-------------------+
+68      | apm_table         |    (present if flags[10] is set)
+        +-------------------+
+72      | vbe_control_info  |    (present if flags[11] is set)
+76      | vbe_mode_info     |
+80      | vbe_mode          |
+82      | vbe_interface_seg |
+84      | vbe_interface_off |
+86      | vbe_interface_len |
+        +-------------------+
+@end group
+@end example
+
+The first longword indicates the presence and validity of other fields
+in the Multiboot information structure. All as-yet-undefined bits must
+be set to zero by the boot loader. Any set bits that the operating
+system does not understand should be ignored. Thus, the @samp{flags}
+field also functions as a version indicator, allowing the Multiboot
+information structure to be expanded in the future without breaking
+anything.
+
+If bit 0 in the @samp{flags} word is set, then the @samp{mem_*} fields
+are valid. @samp{mem_lower} and @samp{mem_upper} indicate the amount of
+lower and upper memory, respectively, in kilobytes. Lower memory starts
+at address 0, and upper memory starts at address 1 megabyte. The maximum
+possible value for lower memory is 640 kilobytes. The value returned for
+upper memory is maximally the address of the first upper memory hole
+minus 1 megabyte. It is not guaranteed to be this value.
+
+If bit 1 in the @samp{flags} word is set, then the @samp{boot_device}
+field is valid, and indicates which @sc{bios} disk device the boot
+loader loaded the OS image from. If the OS image was not loaded from a
+@sc{bios} disk, then this field must not be present (bit 3 must be
+clear). The operating system may use this field as a hint for
+determining its own @dfn{root} device, but is not required to. The
+@samp{boot_device} field is laid out in four one-byte subfields as
+follows:
+
+@example
+@group
++-------+-------+-------+-------+
+| drive | part1 | part2 | part3 |
++-------+-------+-------+-------+
+@end group
+@end example
+
+The first byte contains the @sc{bios} drive number as understood by the
+@sc{bios} INT 0x13 low-level disk interface: e.g. 0x00 for the first
+floppy disk or 0x80 for the first hard disk.
+
+The three remaining bytes specify the boot partition. @samp{part1}
+specifies the @dfn{top-level} partition number, @samp{part2} specifies a
+@dfn{sub-partition} in the top-level partition, etc. Partition numbers
+always start from zero. Unused partition bytes must be set to 0xFF. For
+example, if the disk is partitioned using a simple one-level DOS
+partitioning scheme, then @samp{part1} contains the DOS partition
+number, and @samp{part2} and @samp{part3} are both 0xFF. As another
+example, if a disk is partitioned first into DOS partitions, and then
+one of those DOS partitions is subdivided into several BSD partitions
+using BSD's @dfn{disklabel} strategy, then @samp{part1} contains the DOS
+partition number, @samp{part2} contains the BSD sub-partition within
+that DOS partition, and @samp{part3} is 0xFF.
+
+DOS extended partitions are indicated as partition numbers starting from
+4 and increasing, rather than as nested sub-partitions, even though the
+underlying disk layout of extended partitions is hierarchical in
+nature. For example, if the boot loader boots from the second extended
+partition on a disk partitioned in conventional DOS style, then
+@samp{part1} will be 5, and @samp{part2} and @samp{part3} will both be
+0xFF.
+
+If bit 2 of the @samp{flags} longword is set, the @samp{cmdline} field
+is valid, and contains the physical address of the command line to
+be passed to the kernel. The command line is a normal C-style
+zero-terminated string.
+
+If bit 3 of the @samp{flags} is set, then the @samp{mods} fields
+indicate to the kernel what boot modules were loaded along with the
+kernel image, and where they can be found. @samp{mods_count} contains
+the number of modules loaded; @samp{mods_addr} contains the physical
+address of the first module structure. @samp{mods_count} may be zero,
+indicating no boot modules were loaded, even if bit 1 of @samp{flags} is
+set. Each module structure is formatted as follows:
+
+@example
+@group
+        +-------------------+
+0       | mod_start         |
+4       | mod_end           |
+        +-------------------+
+8       | string            |
+        +-------------------+
+12      | reserved (0)      |
+        +-------------------+
+@end group
+@end example
+
+The first two fields contain the start and end addresses of the boot
+module itself. The @samp{string} field provides an arbitrary string to
+be associated with that particular boot module; it is a zero-terminated
+ASCII string, just like the kernel command line. The @samp{string} field
+may be 0 if there is no string associated with the module. Typically the
+string might be a command line (e.g. if the operating system treats boot
+modules as executable programs), or a pathname (e.g. if the operating
+system treats boot modules as files in a file system), but its exact use
+is specific to the operating system. The @samp{reserved} field must be
+set to 0 by the boot loader and ignored by the operating system.
+
+@strong{Caution:} Bits 4 & 5 are mutually exclusive.
+
+If bit 4 in the @samp{flags} word is set, then the following fields in
+the Multiboot information structure starting at byte 28 are valid:
+
+@example
+@group
+        +-------------------+
+28      | tabsize           |
+32      | strsize           |
+36      | addr              |
+40      | reserved (0)      |
+        +-------------------+
+@end group
+@end example
+
+These indicate where the symbol table from an a.out kernel image can be
+found. @samp{addr} is the physical address of the size (4-byte unsigned
+long) of an array of a.out format @dfn{nlist} structures, followed
+immediately by the array itself, then the size (4-byte unsigned long) of
+a set of zero-terminated @sc{ascii} strings (plus sizeof(unsigned long) in
+this case), and finally the set of strings itself. @samp{tabsize} is
+equal to its size parameter (found at the beginning of the symbol
+section), and @samp{strsize} is equal to its size parameter (found at
+the beginning of the string section) of the following string table to
+which the symbol table refers. Note that @samp{tabsize} may be 0,
+indicating no symbols, even if bit 4 in the @samp{flags} word is set.
+
+If bit 5 in the @samp{flags} word is set, then the following fields in
+the Multiboot information structure starting at byte 28 are valid:
+
+@example
+@group
+        +-------------------+
+28      | num               |
+32      | size              |
+36      | addr              |
+40      | shndx             |
+        +-------------------+
+@end group
+@end example
+
+These indicate where the section header table from an ELF kernel is, the
+size of each entry, number of entries, and the string table used as the
+index of names. They correspond to the @samp{shdr_*} entries
+(@samp{shdr_num}, etc.) in the Executable and Linkable Format (@sc{elf})
+specification in the program header. All sections are loaded, and the
+physical address fields of the @sc{elf} section header then refer to where
+the sections are in memory (refer to the i386 @sc{elf} documentation for
+details as to how to read the section header(s)). Note that
+@samp{shdr_num} may be 0, indicating no symbols, even if bit 5 in the
+@samp{flags} word is set.
+
+If bit 6 in the @samp{flags} word is set, then the @samp{mmap_*} fields
+are valid, and indicate the address and length of a buffer containing a
+memory map of the machine provided by the @sc{bios}. @samp{mmap_addr} is
+the address, and @samp{mmap_length} is the total size of the buffer. The
+buffer consists of one or more of the following size/structure pairs
+(@samp{size} is really used for skipping to the next pair):
+
+@example
+@group
+        +-------------------+
+-4      | size              |
+        +-------------------+
+0       | base_addr_low     |
+4       | base_addr_high    |
+8       | length_low        |
+12      | length_high       |
+16      | type              |
+        +-------------------+
+@end group
+@end example
+
+where @samp{size} is the size of the associated structure in bytes, which
+can be greater than the minimum of 20 bytes. @samp{base_addr_low} is the
+lower 32 bits of the starting address, and @samp{base_addr_high} is the
+upper 32 bits, for a total of a 64-bit starting address. @samp{length_low}
+is the lower 32 bits of the size of the memory region in bytes, and
+@samp{length_high} is the upper 32 bits, for a total of a 64-bit
+length. @samp{type} is the variety of address range represented, where a
+value of 1 indicates available @sc{ram}, and all other values currently
+indicated a reserved area.
+
+The map provided is guaranteed to list all standard @sc{ram} that should
+be available for normal use.
+
+If bit 7 in the @samp{flags} is set, then the @samp{drives_*} fields
+are valid, and indicate the address of the physical address of the first
+drive structure and the size of drive structures. @samp{drives_addr}
+is the address, and @samp{drives_length} is the total size of drive
+structures. Note that @samp{drives_length} may be zero. Each drive
+structure is formatted as follows:
+
+@example
+@group
+        +-------------------+
+0       | size              |
+        +-------------------+
+4       | drive_number      |
+        +-------------------+
+5       | drive_mode        |
+        +-------------------+
+6       | drive_cylinders   |
+8       | drive_heads       |
+9       | drive_sectors     |
+        +-------------------+
+10 - xx | drive_ports       |
+        +-------------------+
+@end group
+@end example
+
+The @samp{size} field specifies the size of this structure. The size
+varies, depending on the number of ports. Note that the size may not be
+equal to (10 + 2 * the number of ports), because of an alignment.
+
+The @samp{drive_number} field contains the BIOS drive number. The
+@samp{drive_mode} field represents the access mode used by the boot
+loader. Currently, the following modes are defined:
+
+@table @samp
+@item 0
+CHS mode (traditional cylinder/head/sector addressing mode).
+
+@item 1
+LBA mode (Logical Block Addressing mode).
+@end table
+
+The three fields, @samp{drive_cylinders}, @samp{drive_heads} and
+@samp{drive_sectors}, indicate the geometry of the drive detected by the
+@sc{bios}. @samp{drive_cylinders} contains the number of the
+cylinders. @samp{drive_heads} contains the number of the
+heads. @samp{drive_sectors} contains the number of the sectors per
+track.
+
+The @samp{drive_ports} field contains the array of the I/O ports used
+for the drive in the @sc{bios} code. The array consists of zero or more
+unsigned two-bytes integers, and is terminated with zero. Note that the
+array may contain any number of I/O ports that are not related to the
+drive actually (such as @sc{dma} controller's ports).
+
+If bit 8 in the @samp{flags} is set, then the @samp{config_table} field
+is valid, and indicates the address of the @sc{rom} configuration table
+returned by the @dfn{GET CONFIGURATION} @sc{bios} call. If the @sc{bios}
+call fails, then the size of the table must be @emph{zero}.
+
+If bit 9 in the @samp{flags} is set, the @samp{boot_loader_name} field
+is valid, and contains the physical address of the name of a boot
+loader booting the kernel. The name is a normal C-style zero-terminated
+string.
+
+If bit 10 in the @samp{flags} is set, the @samp{apm_table} field is
+valid, and contains the physical address of an @sc{apm} table defined as
+below:
+
+@example
+@group
+        +----------------------+
+0       | version              |
+2       | cseg                 |
+4       | offset               |
+8       | cseg_16              |
+10      | dseg                 |
+12      | flags                |
+14      | cseg_len             |
+16      | cseg_16_len          |
+18      | dseg_len             |
+        +----------------------+
+@end group
+@end example
+
+The fields @samp{version}, @samp{cseg}, @samp{offset}, @samp{cseg_16},
+@samp{dseg}, @samp{flags}, @samp{cseg_len}, @samp{cseg_16_len},
+@samp{dseg_len} indicate the version number, the protected mode 32-bit
+code segment, the offset of the entry point, the protected mode 16-bit
+code segment, the protected mode 16-bit data segment, the flags, the
+length of the protected mode 32-bit code segment, the length of the
+protected mode 16-bit code segment, and the length of the protected mode
+16-bit data segment, respectively. Only the field @samp{offset} is 4
+bytes, and the others are 2 bytes. See
+@uref{http://www.microsoft.com/hwdev/busbios/amp_12.htm, Advanced Power
+Management (APM) BIOS Interface Specification}, for more information.
+
+If bit 11 in the @samp{flags} is set, the graphics table is available.
+This must only be done if the kernel has indicated in the
+@samp{Multiboot Header} that it accepts a graphics mode.
+
+The fields @samp{vbe_control_info} and @samp{vbe_mode_info} contain
+the physical addresses of @sc{vbe} control information returned by the
+@sc{vbe} Function 00h and @sc{vbe} mode information returned by the
+@sc{vbe} Function 01h, respectively.
+
+The field @samp{vbe_mode} indicates current video mode in the format
+specified in @sc{vbe} 3.0.
+
+The rest fields @samp{vbe_interface_seg}, @samp{vbe_interface_off}, and
+@samp{vbe_interface_len} contain the table of a protected mode interface
+defined in @sc{vbe} 2.0+. If this information is not available, those
+fields contain zero. Note that @sc{vbe} 3.0 defines another protected
+mode interface which is incompatible with the old one. If you want to
+use the new protected mode interface, you will have to find the table
+yourself.
+
+The fields for the graphics table are designed for @sc{vbe}, but
+Multiboot boot loaders may simulate @sc{vbe} on non-@sc{vbe} modes, as
+if they were @sc{vbe} modes.
+
+
+@node Examples
+@chapter Examples
+
+@strong{Caution:} The following items are not part of the specification
+document, but are included for prospective operating system and boot
+loader writers.
+
+@menu
+* Notes on PC::                 
+* BIOS device mapping techniques::  
+* Example OS code::             
+* Example boot loader code::    
+@end menu
+
+
+@node Notes on PC
+@section Notes on PC
+
+In reference to bit 0 of the @samp{flags} parameter in the Multiboot
+information structure, if the bootloader in question uses older
+@sc{bios} interfaces, or the newest ones are not available (see
+description about bit 6), then a maximum of either 15 or 63 megabytes of
+memory may be reported. It is @emph{highly} recommended that boot
+loaders perform a thorough memory probe.
+
+In reference to bit 1 of the @samp{flags} parameter in the Multiboot
+information structure, it is recognized that determination of which
+@sc{bios} drive maps to which device driver in an operating system is
+non-trivial, at best. Many kludges have been made to various operating
+systems instead of solving this problem, most of them breaking under
+many conditions. To encourage the use of general-purpose solutions to
+this problem, there are 2 @sc{bios} device mapping techniques
+(@pxref{BIOS device mapping techniques}). 
+
+In reference to bit 6 of the @samp{flags} parameter in the Multiboot
+information structure, it is important to note that the data structure
+used there (starting with @samp{BaseAddrLow}) is the data returned by
+the INT 15h, AX=E820h --- Query System Address Map call. See @xref{Query
+System Address Map, , Query System Address Map, grub.info, The GRUB
+Manual}, for more information. The interface here is meant to allow a
+boot loader to work unmodified with any reasonable extensions of the
+@sc{bios} interface, passing along any extra data to be interpreted by
+the operating system as desired.
+
+
+@node BIOS device mapping techniques
+@section BIOS device mapping techniques
+
+Both of these techniques should be usable from any PC operating system,
+and neither require any special support in the drivers themselves. This
+section will be flushed out into detailed explanations, particularly for
+the I/O restriction technique.
+
+The general rule is that the data comparison technique is the quick and
+dirty solution. It works most of the time, but doesn't cover all the
+bases, and is relatively simple.
+
+The I/O restriction technique is much more complex, but it has potential
+to solve the problem under all conditions, plus allow access of the
+remaining @sc{bios} devices when not all of them have operating system
+drivers.
+
+@menu
+* Data comparison technique::   
+* I/O restriction technique::   
+@end menu
+
+
+@node Data comparison technique
+@subsection Data comparison technique
+
+Before activating @emph{any} of the device drivers, gather enough data
+from similar sectors on each of the disks such that each one can be
+uniquely identified.
+
+After activating the device drivers, compare data from the drives using
+the operating system drivers. This should hopefully be sufficient to
+provide such a mapping.
+
+Problems:
+
+@enumerate
+@item
+The data on some @sc{bios} devices might be identical (so the part
+reading the drives from the @sc{bios} should have some mechanism to give
+up).
+
+@item
+There might be extra drives not accessible from the @sc{bios} which are
+identical to some drive used by the @sc{bios} (so it should be capable
+of giving up there as well).
+@end enumerate
+
+
+@node I/O restriction technique
+@subsection I/O restriction technique
+
+This first step may be unnecessary, but first create copy-on-write
+mappings for the device drivers writing into @sc{pc} @sc{ram}. Keep the
+original copies for the @dfn{clean @sc{bios} virtual machine} to be
+created later.
+
+For each device driver brought online, determine which @sc{bios} devices
+become inaccessible by:
+
+@enumerate
+@item
+Create a @dfn{clean @sc{bios} virtual machine}.
+
+@item
+Set the I/O permission map for the I/O area claimed by the device driver
+to no permissions (neither read nor write).
+
+@item
+Access each device.
+
+@item
+Record which devices succeed, and those which try to access the
+@dfn{restricted} I/O areas (hopefully, this will be an @dfn{xor}
+situation).
+@end enumerate
+
+For each device driver, given how many of the @sc{bios} devices were
+subsumed by it (there should be no gaps in this list), it should be easy
+to determine which devices on the controller these are.
+
+In general, you have at most 2 disks from each controller given
+@sc{bios} numbers, but they pretty much always count from the lowest
+logically numbered devices on the controller.
+
+
+@node Example OS code
+@section Example OS code
+
+In this distribution, the example Multiboot kernel @file{kernel} is
+included. The kernel just prints out the Multiboot information structure
+on the screen, so you can make use of the kernel to test a
+Multiboot-compliant boot loader and for reference to how to implement a
+Multiboot kernel. The source files can be found under the directory
+@file{docs} in the GRUB distribution.
+
+The kernel @file{kernel} consists of only three files: @file{boot.S},
+@file{kernel.c} and @file{multiboot.h}. The assembly source
+@file{boot.S} is written in GAS (@pxref{Top, , GNU assembler, as.info,
+The GNU assembler}), and contains the Multiboot information structure to
+comply with the specification. When a Multiboot-compliant boot loader
+loads and execute it, it initialize the stack pointer and @code{EFLAGS},
+and then call the function @code{cmain} defined in @file{kernel.c}. If
+@code{cmain} returns to the callee, then it shows a message to inform
+the user of the halt state and stops forever until you push the reset
+key. The file @file{kernel.c} contains the function @code{cmain},
+which checks if the magic number passed by the boot loader is valid and
+so on, and some functions to print messages on the screen. The file
+@file{multiboot.h} defines some macros, such as the magic number for the
+Multiboot header, the Multiboot header structure and the Multiboot
+information structure.
+
+@menu
+* multiboot.h::                 
+* boot.S::                      
+* kernel.c::                    
+* Other Multiboot kernels::     
+@end menu
+
+
+@node multiboot.h
+@subsection multiboot.h
+
+This is the source code in the file @file{multiboot.h}:
+
+@example
+@include multiboot.h.texi
+@end example
+
+
+@node boot.S
+@subsection boot.S
+
+In the file @file{boot.S}:
+
+@example
+@include boot.S.texi
+@end example
+
+
+@node kernel.c
+@subsection kernel.c
+
+And, in the file @file{kernel.c}:
+
+@example
+@include kernel.c.texi
+@end example
+
+
+@node Other Multiboot kernels
+@subsection Other Multiboot kernels
+
+Other useful information should be available in Multiboot kernels, such
+as GNU Mach and Fiasco @url{http://os.inf.tu-dresden.de/fiasco/}. And,
+it is worth mentioning the OSKit
+@url{http://www.cs.utah.edu/projects/flux/oskit/}, which provides a
+library supporting the specification.
+
+
+@node Example boot loader code
+@section Example boot loader code
+
+The GNU GRUB (@pxref{Top, , GRUB, grub.info, The GRUB manual}) project
+is a full Multiboot-compliant boot loader, supporting all required and
+optional features present in this specification. A public release has
+not been made, but the test release is available from:
+
+@url{ftp://alpha.gnu.org/gnu/grub}
+
+See the webpage @url{http://www.gnu.org/software/grub/grub.html}, for
+more information.
+
+
+@node History
+@chapter The change log of this specification
+
+@table @asis
+@item 0.7
+@itemize @bullet
+@item
+@dfn{Multiboot Standard} is renamed to @dfn{Multiboot Specification}.
+
+@item
+Graphics fields are added to Multiboot header.
+
+@item
+BIOS drive information, BIOS configuration table, the name of a boot
+loader, APM information, and graphics information are added to Multiboot
+information.
+
+@item
+Rewritten in Texinfo format.
+
+@item
+Rewritten, using more strict words.
+
+@item
+The maintainer changes to the GNU GRUB maintainer team
+@email{bug-grub@@gnu.org}, from Bryan Ford and Erich Stefan Boleyn.
+@end itemize
+
+@item 0.6
+@itemize @bullet
+@item
+A few wording changes.
+
+@item
+Header checksum.
+
+@item
+Clasification of machine state passed to an operating system.
+@end itemize
+
+@item 0.5
+@itemize @bullet
+@item
+Name change.
+@end itemize
+
+@item 0.4
+@itemize @bullet
+@item
+Major changes plus HTMLification.
+@end itemize
+@end table
+
+
+@node Index
+@unnumbered Index
+
+@printindex cp
+
+@contents
+@bye
diff --git a/docs/src2texi b/docs/src2texi
new file mode 100644
index 0000000..10786d9
--- /dev/null
+++ b/docs/src2texi
@@ -0,0 +1,16 @@
+#! /bin/sh
+#
+# Convert a source file to a TeXinfo file. Stolen from glibc.
+#
+# Usage: src2texi SRCDIR SRC TEXI
+
+dir=$1
+src=`basename $2`
+texi=`basename $3`
+
+sed -e 's,[{}],@&,g'					\
+    -e 's,/\*\(@.*\)\*/,\1,g'				\
+    -e 's,/\*  *,/* @r{,g' -e 's,  *\*/,} */,'		\
+    -e 's/\(@[a-z][a-z]*\)@{\([^}]*\)@}/\1{\2}/g'	\
+    ${dir}/${src} | expand > ${texi}.new
+mv -f ${texi}.new ${dir}/${texi}
diff --git a/docs/stamp-vti b/docs/stamp-vti
new file mode 100644
index 0000000..b97de24
--- /dev/null
+++ b/docs/stamp-vti
@@ -0,0 +1,4 @@
+@set UPDATED 8 May 2005
+@set UPDATED-MONTH May 2005
+@set EDITION 0.97
+@set VERSION 0.97
diff --git a/docs/texinfo.tex b/docs/texinfo.tex
new file mode 100644
index 0000000..c93912a
--- /dev/null
+++ b/docs/texinfo.tex
@@ -0,0 +1,7086 @@
+% texinfo.tex -- TeX macros to handle Texinfo files.
+%
+% Load plain if necessary, i.e., if running under initex.
+\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi
+%
+\def\texinfoversion{2004-11-25.16}
+%
+% Copyright (C) 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995,
+% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
+% Foundation, Inc.
+%
+% This texinfo.tex file 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 texinfo.tex file 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 texinfo.tex file; see the file COPYING.  If not, write
+% to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+% Boston, MA 02111-1307, USA.
+%
+% As a special exception, when this file is read by TeX when processing
+% a Texinfo source document, you may use the result without
+% restriction.  (This has been our intent since Texinfo was invented.)
+%
+% Please try the latest version of texinfo.tex before submitting bug
+% reports; you can get the latest version from:
+%   http://www.gnu.org/software/texinfo/ (the Texinfo home page), or
+%   ftp://tug.org/tex/texinfo.tex
+%     (and all CTAN mirrors, see http://www.ctan.org).
+% The texinfo.tex in any given distribution could well be out
+% of date, so if that's what you're using, please check.
+%
+% Send bug reports to bug-texinfo@gnu.org.  Please include including a
+% complete document in each bug report with which we can reproduce the
+% problem.  Patches are, of course, greatly appreciated.
+%
+% To process a Texinfo manual with TeX, it's most reliable to use the
+% texi2dvi shell script that comes with the distribution.  For a simple
+% manual foo.texi, however, you can get away with this:
+%   tex foo.texi
+%   texindex foo.??
+%   tex foo.texi
+%   tex foo.texi
+%   dvips foo.dvi -o  # or whatever; this makes foo.ps.
+% The extra TeX runs get the cross-reference information correct.
+% Sometimes one run after texindex suffices, and sometimes you need more
+% than two; texi2dvi does it as many times as necessary.
+%
+% It is possible to adapt texinfo.tex for other languages, to some
+% extent.  You can get the existing language-specific files from the
+% full Texinfo distribution.
+%
+% The GNU Texinfo home page is http://www.gnu.org/software/texinfo.
+
+
+\message{Loading texinfo [version \texinfoversion]:}
+
+% If in a .fmt file, print the version number
+% and turn on active characters that we couldn't do earlier because
+% they might have appeared in the input file name.
+\everyjob{\message{[Texinfo version \texinfoversion]}%
+  \catcode`+=\active \catcode`\_=\active}
+
+\message{Basics,}
+\chardef\other=12
+
+% We never want plain's \outer definition of \+ in Texinfo.
+% For @tex, we can use \tabalign.
+\let\+ = \relax
+
+% Save some plain tex macros whose names we will redefine.
+\let\ptexb=\b
+\let\ptexbullet=\bullet
+\let\ptexc=\c
+\let\ptexcomma=\,
+\let\ptexdot=\.
+\let\ptexdots=\dots
+\let\ptexend=\end
+\let\ptexequiv=\equiv
+\let\ptexexclam=\!
+\let\ptexfootnote=\footnote
+\let\ptexgtr=>
+\let\ptexhat=^
+\let\ptexi=\i
+\let\ptexindent=\indent
+\let\ptexinsert=\insert
+\let\ptexlbrace=\{
+\let\ptexless=<
+\let\ptexnewwrite\newwrite
+\let\ptexnoindent=\noindent
+\let\ptexplus=+
+\let\ptexrbrace=\}
+\let\ptexslash=\/
+\let\ptexstar=\*
+\let\ptext=\t
+
+% If this character appears in an error message or help string, it
+% starts a new line in the output.
+\newlinechar = `^^J
+
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+  \let\linenumber = \empty % Pre-3.0.
+\else
+  \def\linenumber{l.\the\inputlineno:\space}
+\fi
+
+% Set up fixed words for English if not already set.
+\ifx\putwordAppendix\undefined  \gdef\putwordAppendix{Appendix}\fi
+\ifx\putwordChapter\undefined   \gdef\putwordChapter{Chapter}\fi
+\ifx\putwordfile\undefined      \gdef\putwordfile{file}\fi
+\ifx\putwordin\undefined        \gdef\putwordin{in}\fi
+\ifx\putwordIndexIsEmpty\undefined     \gdef\putwordIndexIsEmpty{(Index is empty)}\fi
+\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi
+\ifx\putwordInfo\undefined      \gdef\putwordInfo{Info}\fi
+\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi
+\ifx\putwordMethodon\undefined  \gdef\putwordMethodon{Method on}\fi
+\ifx\putwordNoTitle\undefined   \gdef\putwordNoTitle{No Title}\fi
+\ifx\putwordof\undefined        \gdef\putwordof{of}\fi
+\ifx\putwordon\undefined        \gdef\putwordon{on}\fi
+\ifx\putwordpage\undefined      \gdef\putwordpage{page}\fi
+\ifx\putwordsection\undefined   \gdef\putwordsection{section}\fi
+\ifx\putwordSection\undefined   \gdef\putwordSection{Section}\fi
+\ifx\putwordsee\undefined       \gdef\putwordsee{see}\fi
+\ifx\putwordSee\undefined       \gdef\putwordSee{See}\fi
+\ifx\putwordShortTOC\undefined  \gdef\putwordShortTOC{Short Contents}\fi
+\ifx\putwordTOC\undefined       \gdef\putwordTOC{Table of Contents}\fi
+%
+\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi
+\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi
+\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi
+\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi
+\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi
+\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi
+\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi
+\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi
+\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi
+\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi
+\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi
+\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi
+%
+\ifx\putwordDefmac\undefined    \gdef\putwordDefmac{Macro}\fi
+\ifx\putwordDefspec\undefined   \gdef\putwordDefspec{Special Form}\fi
+\ifx\putwordDefvar\undefined    \gdef\putwordDefvar{Variable}\fi
+\ifx\putwordDefopt\undefined    \gdef\putwordDefopt{User Option}\fi
+\ifx\putwordDeffunc\undefined   \gdef\putwordDeffunc{Function}\fi
+
+% In some macros, we cannot use the `\? notation---the left quote is
+% in some cases the escape char.
+\chardef\colonChar = `\:
+\chardef\commaChar = `\,
+\chardef\dotChar   = `\.
+\chardef\exclamChar= `\!
+\chardef\questChar = `\?
+\chardef\semiChar  = `\;
+\chardef\underChar = `\_
+
+\chardef\spaceChar = `\ %
+\chardef\spacecat = 10
+\def\spaceisspace{\catcode\spaceChar=\spacecat}
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+% The following is used inside several \edef's.
+\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname}
+
+% Hyphenation fixes.
+\hyphenation{
+  Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script
+  ap-pen-dix bit-map bit-maps
+  data-base data-bases eshell fall-ing half-way long-est man-u-script
+  man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm
+  par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces
+  spell-ing spell-ings
+  stand-alone strong-est time-stamp time-stamps which-ever white-space
+  wide-spread wrap-around
+}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen\bindingoffset
+\newdimen\normaloffset
+\newdimen\pagewidth \newdimen\pageheight
+
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt}
+
+% @| inserts a changebar to the left of the current line.  It should
+% surround any changed text.  This approach does *not* work if the
+% change spans more than two lines of output.  To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change).
+%
+\def\|{%
+  % \vadjust can only be used in horizontal mode.
+  \leavevmode
+  %
+  % Append this vertical mode material after the current line in the output.
+  \vadjust{%
+    % We want to insert a rule with the height and depth of the current
+    % leading; that is exactly what \strutbox is supposed to record.
+    \vskip-\baselineskip
+    %
+    % \vadjust-items are inserted at the left edge of the type.  So
+    % the \llap here moves out into the left-hand margin.
+    \llap{%
+      %
+      % For a thicker or thinner bar, change the `1pt'.
+      \vrule height\baselineskip width1pt
+      %
+      % This is the space between the bar and the text.
+      \hskip 12pt
+    }%
+  }%
+}
+
+% Sometimes it is convenient to have everything in the transcript file
+% and nothing on the terminal.  We don't just call \tracingall here,
+% since that produces some useless output on the terminal.  We also make
+% some effort to order the tracing commands to reduce output in the log
+% file; cf. trace.sty in LaTeX.
+%
+\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+\def\loggingall{%
+  \tracingstats2
+  \tracingpages1
+  \tracinglostchars2  % 2 gives us more in etex
+  \tracingparagraphs1
+  \tracingoutput1
+  \tracingmacros2
+  \tracingrestores1
+  \showboxbreadth\maxdimen \showboxdepth\maxdimen
+  \ifx\eTeXversion\undefined\else % etex gives us more logging
+    \tracingscantokens1
+    \tracingifs1
+    \tracinggroups1
+    \tracingnesting2
+    \tracingassigns1
+  \fi
+  \tracingcommands3  % 3 gives us more in etex
+  \errorcontextlines16
+}%
+
+% add check for \lastpenalty to plain's definitions.  If the last thing
+% we did was a \nobreak, we don't want to insert more space.
+%
+\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount
+  \removelastskip\penalty-50\smallskip\fi\fi}
+\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount
+  \removelastskip\penalty-100\medskip\fi\fi}
+\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount
+  \removelastskip\penalty-200\bigskip\fi\fi}
+
+% For @cropmarks command.
+% Do @cropmarks to get crop marks.
+%
+\newif\ifcropmarks
+\let\cropmarks = \cropmarkstrue
+%
+% Dimensions to add cropmarks at corners.
+% Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines
+\newdimen\cornerlong  \cornerlong=1pc
+\newdimen\cornerthick \cornerthick=.3pt
+\newdimen\topandbottommargin \topandbottommargin=.75in
+
+% Main output routine.
+\chardef\PAGE = 255
+\output = {\onepageout{\pagecontents\PAGE}}
+
+\newbox\headlinebox
+\newbox\footlinebox
+
+% \onepageout takes a vbox as an argument.  Note that \pagecontents
+% does insertions, but you have to call it yourself.
+\def\onepageout#1{%
+  \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi
+  %
+  \ifodd\pageno  \advance\hoffset by \bindingoffset
+  \else \advance\hoffset by -\bindingoffset\fi
+  %
+  % Do this outside of the \shipout so @code etc. will be expanded in
+  % the headline as they should be, not taken literally (outputting ''code).
+  \setbox\headlinebox = \vbox{\let\hsize=\pagewidth \makeheadline}%
+  \setbox\footlinebox = \vbox{\let\hsize=\pagewidth \makefootline}%
+  %
+  {%
+    % Have to do this stuff outside the \shipout because we want it to
+    % take effect in \write's, yet the group defined by the \vbox ends
+    % before the \shipout runs.
+    %
+    \escapechar = `\\     % use backslash in output files.
+    \indexdummies         % don't expand commands in the output.
+    \normalturnoffactive  % \ in index entries must not stay \, e.g., if
+                   % the page break happens to be in the middle of an example.
+    \shipout\vbox{%
+      % Do this early so pdf references go to the beginning of the page.
+      \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi
+      %
+      \ifcropmarks \vbox to \outervsize\bgroup
+        \hsize = \outerhsize
+        \vskip-\topandbottommargin
+        \vtop to0pt{%
+          \line{\ewtop\hfil\ewtop}%
+          \nointerlineskip
+          \line{%
+            \vbox{\moveleft\cornerthick\nstop}%
+            \hfill
+            \vbox{\moveright\cornerthick\nstop}%
+          }%
+          \vss}%
+        \vskip\topandbottommargin
+        \line\bgroup
+          \hfil % center the page within the outer (page) hsize.
+          \ifodd\pageno\hskip\bindingoffset\fi
+          \vbox\bgroup
+      \fi
+      %
+      \unvbox\headlinebox
+      \pagebody{#1}%
+      \ifdim\ht\footlinebox > 0pt
+        % Only leave this space if the footline is nonempty.
+        % (We lessened \vsize for it in \oddfootingxxx.)
+        % The \baselineskip=24pt in plain's \makefootline has no effect.
+        \vskip 2\baselineskip
+        \unvbox\footlinebox
+      \fi
+      %
+      \ifcropmarks
+          \egroup % end of \vbox\bgroup
+        \hfil\egroup % end of (centering) \line\bgroup
+        \vskip\topandbottommargin plus1fill minus1fill
+        \boxmaxdepth = \cornerthick
+        \vbox to0pt{\vss
+          \line{%
+            \vbox{\moveleft\cornerthick\nsbot}%
+            \hfill
+            \vbox{\moveright\cornerthick\nsbot}%
+          }%
+          \nointerlineskip
+          \line{\ewbot\hfil\ewbot}%
+        }%
+      \egroup % \vbox from first cropmarks clause
+      \fi
+    }% end of \shipout\vbox
+  }% end of group with \normalturnoffactive
+  \advancepageno
+  \ifnum\outputpenalty>-20000 \else\dosupereject\fi
+}
+
+\newinsert\margin \dimen\margin=\maxdimen
+
+\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+{\catcode`\@ =11
+\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+% marginal hacks, juha@viisa.uucp (Juha Takala)
+\ifvoid\margin\else % marginal info is present
+  \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi
+\dimen@=\dp#1 \unvbox#1
+\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
+}
+
+% Here are the rules for the cropmarks.  Note that they are
+% offset so that the space between them is truly \outerhsize or \outervsize
+% (P. A. MacKay, 12 November, 1986)
+%
+\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+\def\nstop{\vbox
+  {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+\def\nsbot{\vbox
+  {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+
+% Parse an argument, then pass it to #1.  The argument is the rest of
+% the input line (except we remove a trailing comment).  #1 should be a
+% macro which expects an ordinary undelimited TeX argument.
+%
+\def\parsearg{\parseargusing{}}
+\def\parseargusing#1#2{%
+  \def\next{#2}%
+  \begingroup
+    \obeylines
+    \spaceisspace
+    #1%
+    \parseargline\empty% Insert the \empty token, see \finishparsearg below.
+}
+
+{\obeylines %
+  \gdef\parseargline#1^^M{%
+    \endgroup % End of the group started in \parsearg.
+    \argremovecomment #1\comment\ArgTerm%
+  }%
+}
+
+% First remove any @comment, then any @c comment.
+\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm}
+\def\argremovec#1\c#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm}
+
+% Each occurence of `\^^M' or `<space>\^^M' is replaced by a single space.
+%
+% \argremovec might leave us with trailing space, e.g.,
+%    @end itemize  @c foo
+% This space token undergoes the same procedure and is eventually removed
+% by \finishparsearg.
+%
+\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M}
+\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M}
+\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{%
+  \def\temp{#3}%
+  \ifx\temp\empty
+    % We cannot use \next here, as it holds the macro to run;
+    % thus we reuse \temp.
+    \let\temp\finishparsearg
+  \else
+    \let\temp\argcheckspaces
+  \fi
+  % Put the space token in:
+  \temp#1 #3\ArgTerm
+}
+
+% If a _delimited_ argument is enclosed in braces, they get stripped; so
+% to get _exactly_ the rest of the line, we had to prevent such situation.
+% We prepended an \empty token at the very beginning and we expand it now,
+% just before passing the control to \next.
+% (Similarily, we have to think about #3 of \argcheckspacesY above: it is
+% either the null string, or it ends with \^^M---thus there is no danger
+% that a pair of braces would be stripped.
+%
+% But first, we have to remove the trailing space token.
+%
+\def\finishparsearg#1 \ArgTerm{\expandafter\next\expandafter{#1}}
+
+% \parseargdef\foo{...}
+%	is roughly equivalent to
+% \def\foo{\parsearg\Xfoo}
+% \def\Xfoo#1{...}
+%
+% Actually, I use \csname\string\foo\endcsname, ie. \\foo, as it is my
+% favourite TeX trick.  --kasal, 16nov03
+
+\def\parseargdef#1{%
+  \expandafter \doparseargdef \csname\string#1\endcsname #1%
+}
+\def\doparseargdef#1#2{%
+  \def#2{\parsearg#1}%
+  \def#1##1%
+}
+
+% Several utility definitions with active space:
+{
+  \obeyspaces
+  \gdef\obeyedspace{ }
+
+  % Make each space character in the input produce a normal interword
+  % space in the output.  Don't allow a line break at this space, as this
+  % is used only in environments like @example, where each line of input
+  % should produce a line of output anyway.
+  %
+  \gdef\sepspaces{\obeyspaces\let =\tie}
+
+  % If an index command is used in an @example environment, any spaces
+  % therein should become regular spaces in the raw index file, not the
+  % expansion of \tie (\leavevmode \penalty \@M \ ).
+  \gdef\unsepspaces{\let =\space}
+}
+
+
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+% Define the framework for environments in texinfo.tex.  It's used like this:
+%
+%   \envdef\foo{...}
+%   \def\Efoo{...}
+%
+% It's the responsibility of \envdef to insert \begingroup before the
+% actual body; @end closes the group after calling \Efoo.  \envdef also
+% defines \thisenv, so the current environment is known; @end checks
+% whether the environment name matches.  The \checkenv macro can also be
+% used to check whether the current environment is the one expected.
+%
+% Non-false conditionals (@iftex, @ifset) don't fit into this, so they
+% are not treated as enviroments; they don't open a group.  (The
+% implementation of @end takes care not to call \endgroup in this
+% special case.)
+
+
+% At runtime, environments start with this:
+\def\startenvironment#1{\begingroup\def\thisenv{#1}}
+% initialize
+\let\thisenv\empty
+
+% ... but they get defined via ``\envdef\foo{...}'':
+\long\def\envdef#1#2{\def#1{\startenvironment#1#2}}
+\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}}
+
+% Check whether we're in the right environment:
+\def\checkenv#1{%
+  \def\temp{#1}%
+  \ifx\thisenv\temp
+  \else
+    \badenverr
+  \fi
+}
+
+% Evironment mismatch, #1 expected:
+\def\badenverr{%
+  \errhelp = \EMsimple
+  \errmessage{This command can appear only \inenvironment\temp,
+    not \inenvironment\thisenv}%
+}
+\def\inenvironment#1{%
+  \ifx#1\empty
+    out of any environment%
+  \else
+    in environment \expandafter\string#1%
+  \fi
+}
+
+% @end foo executes the definition of \Efoo.
+% But first, it executes a specialized version of \checkenv
+%
+\parseargdef\end{%
+  \if 1\csname iscond.#1\endcsname
+  \else
+    % The general wording of \badenverr may not be ideal, but... --kasal, 06nov03
+    \expandafter\checkenv\csname#1\endcsname
+    \csname E#1\endcsname
+    \endgroup
+  \fi
+}
+
+\newhelp\EMsimple{Press RETURN to continue.}
+
+
+%% Simple single-character @ commands
+
+% @@ prints an @
+% Kludge this until the fonts are right (grr).
+\def\@{{\tt\char64}}
+
+% This is turned off because it was never documented
+% and you can use @w{...} around a quote to suppress ligatures.
+%% Define @` and @' to be the same as ` and '
+%% but suppressing ligatures.
+%\def\`{{`}}
+%\def\'{{'}}
+
+% Used to generate quoted braces.
+\def\mylbrace {{\tt\char123}}
+\def\myrbrace {{\tt\char125}}
+\let\{=\mylbrace
+\let\}=\myrbrace
+\begingroup
+  % Definitions to produce \{ and \} commands for indices,
+  % and @{ and @} for the aux file.
+  \catcode`\{ = \other \catcode`\} = \other
+  \catcode`\[ = 1 \catcode`\] = 2
+  \catcode`\! = 0 \catcode`\\ = \other
+  !gdef!lbracecmd[\{]%
+  !gdef!rbracecmd[\}]%
+  !gdef!lbraceatcmd[@{]%
+  !gdef!rbraceatcmd[@}]%
+!endgroup
+
+% @comma{} to avoid , parsing problems.
+\let\comma = ,
+
+% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent
+% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H.
+\let\, = \c
+\let\dotaccent = \.
+\def\ringaccent#1{{\accent23 #1}}
+\let\tieaccent = \t
+\let\ubaraccent = \b
+\let\udotaccent = \d
+
+% Other special characters: @questiondown @exclamdown @ordf @ordm
+% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss.
+\def\questiondown{?`}
+\def\exclamdown{!`}
+\def\ordf{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{a}}}
+\def\ordm{\leavevmode\raise1ex\hbox{\selectfonts\lllsize \underbar{o}}}
+
+% Dotless i and dotless j, used for accents.
+\def\imacro{i}
+\def\jmacro{j}
+\def\dotless#1{%
+  \def\temp{#1}%
+  \ifx\temp\imacro \ptexi
+  \else\ifx\temp\jmacro \j
+  \else \errmessage{@dotless can be used only with i or j}%
+  \fi\fi
+}
+
+% The \TeX{} logo, as in plain, but resetting the spacing so that a
+% period following counts as ending a sentence.  (Idea found in latex.)
+%
+\edef\TeX{\TeX \spacefactor=1000 }
+
+% @LaTeX{} logo.  Not quite the same results as the definition in
+% latex.ltx, since we use a different font for the raised A; it's most
+% convenient for us to use an explicitly smaller font, rather than using
+% the \scriptstyle font (since we don't reset \scriptstyle and
+% \scriptscriptstyle).
+%
+\def\LaTeX{%
+  L\kern-.36em
+  {\setbox0=\hbox{T}%
+   \vbox to \ht0{\hbox{\selectfonts\lllsize A}\vss}}%
+  \kern-.15em
+  \TeX
+}
+
+% Be sure we're in horizontal mode when doing a tie, since we make space
+% equivalent to this in @example-like environments. Otherwise, a space
+% at the beginning of a line will start with \penalty -- and
+% since \penalty is valid in vertical mode, we'd end up putting the
+% penalty on the vertical list instead of in the new paragraph.
+{\catcode`@ = 11
+ % Avoid using \@M directly, because that causes trouble
+ % if the definition is written into an index file.
+ \global\let\tiepenalty = \@M
+ \gdef\tie{\leavevmode\penalty\tiepenalty\ }
+}
+
+% @: forces normal size whitespace following.
+\def\:{\spacefactor=1000 }
+
+% @* forces a line break.
+\def\*{\hfil\break\hbox{}\ignorespaces}
+
+% @/ allows a line break.
+\let\/=\allowbreak
+
+% @. is an end-of-sentence period.
+\def\.{.\spacefactor=3000 }
+
+% @! is an end-of-sentence bang.
+\def\!{!\spacefactor=3000 }
+
+% @? is an end-of-sentence query.
+\def\?{?\spacefactor=3000 }
+
+% @w prevents a word break.  Without the \leavevmode, @w at the
+% beginning of a paragraph, when TeX is still in vertical mode, would
+% produce a whole line of output instead of starting the paragraph.
+\def\w#1{\leavevmode\hbox{#1}}
+
+% @group ... @end group forces ... to be all on one page, by enclosing
+% it in a TeX vbox.  We use \vtop instead of \vbox to construct the box
+% to keep its height that of a normal line.  According to the rules for
+% \topskip (p.114 of the TeXbook), the glue inserted is
+% max (\topskip - \ht (first item), 0).  If that height is large,
+% therefore, no glue is inserted, and the space between the headline and
+% the text is small, which looks bad.
+%
+% Another complication is that the group might be very large.  This can
+% cause the glue on the previous page to be unduly stretched, because it
+% does not have much material.  In this case, it's better to add an
+% explicit \vfill so that the extra space is at the bottom.  The
+% threshold for doing this is if the group is more than \vfilllimit
+% percent of a page (\vfilllimit can be changed inside of @tex).
+%
+\newbox\groupbox
+\def\vfilllimit{0.7}
+%
+\envdef\group{%
+  \ifnum\catcode`\^^M=\active \else
+    \errhelp = \groupinvalidhelp
+    \errmessage{@group invalid in context where filling is enabled}%
+  \fi
+  \startsavinginserts
+  %
+  \setbox\groupbox = \vtop\bgroup
+    % Do @comment since we are called inside an environment such as
+    % @example, where each end-of-line in the input causes an
+    % end-of-line in the output.  We don't want the end-of-line after
+    % the `@group' to put extra space in the output.  Since @group
+    % should appear on a line by itself (according to the Texinfo
+    % manual), we don't worry about eating any user text.
+    \comment
+}
+%
+% The \vtop produces a box with normal height and large depth; thus, TeX puts
+% \baselineskip glue before it, and (when the next line of text is done)
+% \lineskip glue after it.  Thus, space below is not quite equal to space
+% above.  But it's pretty close.
+\def\Egroup{%
+    % To get correct interline space between the last line of the group
+    % and the first line afterwards, we have to propagate \prevdepth.
+    \endgraf % Not \par, as it may have been set to \lisppar.
+    \global\dimen1 = \prevdepth
+  \egroup           % End the \vtop.
+  % \dimen0 is the vertical size of the group's box.
+  \dimen0 = \ht\groupbox  \advance\dimen0 by \dp\groupbox
+  % \dimen2 is how much space is left on the page (more or less).
+  \dimen2 = \pageheight   \advance\dimen2 by -\pagetotal
+  % if the group doesn't fit on the current page, and it's a big big
+  % group, force a page break.
+  \ifdim \dimen0 > \dimen2
+    \ifdim \pagetotal < \vfilllimit\pageheight
+      \page
+    \fi
+  \fi
+  \box\groupbox
+  \prevdepth = \dimen1
+  \checkinserts
+}
+%
+% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+% message, so this ends up printing `@group can only ...'.
+%
+\newhelp\groupinvalidhelp{%
+group can only be used in environments such as @example,^^J%
+where each line of input produces a line of output.}
+
+% @need space-in-mils
+% forces a page break if there is not space-in-mils remaining.
+
+\newdimen\mil  \mil=0.001in
+
+% Old definition--didn't work.
+%\parseargdef\need{\par %
+%% This method tries to make TeX break the page naturally
+%% if the depth of the box does not fit.
+%{\baselineskip=0pt%
+%\vtop to #1\mil{\vfil}\kern -#1\mil\nobreak
+%\prevdepth=-1000pt
+%}}
+
+\parseargdef\need{%
+  % Ensure vertical mode, so we don't make a big box in the middle of a
+  % paragraph.
+  \par
+  %
+  % If the @need value is less than one line space, it's useless.
+  \dimen0 = #1\mil
+  \dimen2 = \ht\strutbox
+  \advance\dimen2 by \dp\strutbox
+  \ifdim\dimen0 > \dimen2
+    %
+    % Do a \strut just to make the height of this box be normal, so the
+    % normal leading is inserted relative to the preceding line.
+    % And a page break here is fine.
+    \vtop to #1\mil{\strut\vfil}%
+    %
+    % TeX does not even consider page breaks if a penalty added to the
+    % main vertical list is 10000 or more.  But in order to see if the
+    % empty box we just added fits on the page, we must make it consider
+    % page breaks.  On the other hand, we don't want to actually break the
+    % page after the empty box.  So we use a penalty of 9999.
+    %
+    % There is an extremely small chance that TeX will actually break the
+    % page at this \penalty, if there are no other feasible breakpoints in
+    % sight.  (If the user is using lots of big @group commands, which
+    % almost-but-not-quite fill up a page, TeX will have a hard time doing
+    % good page breaking, for example.)  However, I could not construct an
+    % example where a page broke at this \penalty; if it happens in a real
+    % document, then we can reconsider our strategy.
+    \penalty9999
+    %
+    % Back up by the size of the box, whether we did a page break or not.
+    \kern -#1\mil
+    %
+    % Do not allow a page break right after this kern.
+    \nobreak
+  \fi
+}
+
+% @br   forces paragraph break (and is undocumented).
+
+\let\br = \par
+
+% @page forces the start of a new page.
+%
+\def\page{\par\vfill\supereject}
+
+% @exdent text....
+% outputs text on separate line in roman font, starting at standard page margin
+
+% This records the amount of indent in the innermost environment.
+% That's how much \exdent should take out.
+\newskip\exdentamount
+
+% This defn is used inside fill environments such as @defun.
+\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}
+
+% This defn is used inside nofill environments such as @example.
+\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount
+  \leftline{\hskip\leftskip{\rm#1}}}}
+
+% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current
+% paragraph.  For more general purposes, use the \margin insertion
+% class.  WHICH is `l' or `r'.
+%
+\newskip\inmarginspacing \inmarginspacing=1cm
+\def\strutdepth{\dp\strutbox}
+%
+\def\doinmargin#1#2{\strut\vadjust{%
+  \nobreak
+  \kern-\strutdepth
+  \vtop to \strutdepth{%
+    \baselineskip=\strutdepth
+    \vss
+    % if you have multiple lines of stuff to put here, you'll need to
+    % make the vbox yourself of the appropriate size.
+    \ifx#1l%
+      \llap{\ignorespaces #2\hskip\inmarginspacing}%
+    \else
+      \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}%
+    \fi
+    \null
+  }%
+}}
+\def\inleftmargin{\doinmargin l}
+\def\inrightmargin{\doinmargin r}
+%
+% @inmargin{TEXT [, RIGHT-TEXT]}
+% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right;
+% else use TEXT for both).
+%
+\def\inmargin#1{\parseinmargin #1,,\finish}
+\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing.
+  \setbox0 = \hbox{\ignorespaces #2}%
+  \ifdim\wd0 > 0pt
+    \def\lefttext{#1}%  have both texts
+    \def\righttext{#2}%
+  \else
+    \def\lefttext{#1}%  have only one text
+    \def\righttext{#1}%
+  \fi
+  %
+  \ifodd\pageno
+    \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin
+  \else
+    \def\temp{\inleftmargin\lefttext}%
+  \fi
+  \temp
+}
+
+% @include file    insert text of that file as input.
+%
+\def\include{\parseargusing\filenamecatcodes\includezzz}
+\def\includezzz#1{%
+  \pushthisfilestack
+  \def\thisfile{#1}%
+  {%
+    \makevalueexpandable
+    \def\temp{\input #1 }%
+    \expandafter
+  }\temp
+  \popthisfilestack
+}
+\def\filenamecatcodes{%
+  \catcode`\\=\other
+  \catcode`~=\other
+  \catcode`^=\other
+  \catcode`_=\other
+  \catcode`|=\other
+  \catcode`<=\other
+  \catcode`>=\other
+  \catcode`+=\other
+  \catcode`-=\other
+}
+
+\def\pushthisfilestack{%
+  \expandafter\pushthisfilestackX\popthisfilestack\StackTerm
+}
+\def\pushthisfilestackX{%
+  \expandafter\pushthisfilestackY\thisfile\StackTerm
+}
+\def\pushthisfilestackY #1\StackTerm #2\StackTerm {%
+  \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}%
+}
+
+\def\popthisfilestack{\errthisfilestackempty}
+\def\errthisfilestackempty{\errmessage{Internal error:
+  the stack of filenames is empty.}}
+
+\def\thisfile{}
+
+% @center line
+% outputs that line, centered.
+%
+\parseargdef\center{%
+  \ifhmode
+    \let\next\centerH
+  \else
+    \let\next\centerV
+  \fi
+  \next{\hfil \ignorespaces#1\unskip \hfil}%
+}
+\def\centerH#1{%
+  {%
+    \hfil\break
+    \advance\hsize by -\leftskip
+    \advance\hsize by -\rightskip
+    \line{#1}%
+    \break
+  }%
+}
+\def\centerV#1{\line{\kern\leftskip #1\kern\rightskip}}
+
+% @sp n   outputs n lines of vertical space
+
+\parseargdef\sp{\vskip #1\baselineskip}
+
+% @comment ...line which is ignored...
+% @c is the same as @comment
+% @ignore ... @end ignore  is another way to write a comment
+
+\def\comment{\begingroup \catcode`\^^M=\other%
+\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other%
+\commentxxx}
+{\catcode`\^^M=\other \gdef\commentxxx#1^^M{\endgroup}}
+
+\let\c=\comment
+
+% @paragraphindent NCHARS
+% We'll use ems for NCHARS, close enough.
+% NCHARS can also be the word `asis' or `none'.
+% We cannot feasibly implement @paragraphindent asis, though.
+%
+\def\asisword{asis} % no translation, these are keywords
+\def\noneword{none}
+%
+\parseargdef\paragraphindent{%
+  \def\temp{#1}%
+  \ifx\temp\asisword
+  \else
+    \ifx\temp\noneword
+      \defaultparindent = 0pt
+    \else
+      \defaultparindent = #1em
+    \fi
+  \fi
+  \parindent = \defaultparindent
+}
+
+% @exampleindent NCHARS
+% We'll use ems for NCHARS like @paragraphindent.
+% It seems @exampleindent asis isn't necessary, but
+% I preserve it to make it similar to @paragraphindent.
+\parseargdef\exampleindent{%
+  \def\temp{#1}%
+  \ifx\temp\asisword
+  \else
+    \ifx\temp\noneword
+      \lispnarrowing = 0pt
+    \else
+      \lispnarrowing = #1em
+    \fi
+  \fi
+}
+
+% @firstparagraphindent WORD
+% If WORD is `none', then suppress indentation of the first paragraph
+% after a section heading.  If WORD is `insert', then do indent at such
+% paragraphs.
+%
+% The paragraph indentation is suppressed or not by calling
+% \suppressfirstparagraphindent, which the sectioning commands do.
+% We switch the definition of this back and forth according to WORD.
+% By default, we suppress indentation.
+%
+\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent}
+\def\insertword{insert}
+%
+\parseargdef\firstparagraphindent{%
+  \def\temp{#1}%
+  \ifx\temp\noneword
+    \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent
+  \else\ifx\temp\insertword
+    \let\suppressfirstparagraphindent = \relax
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @firstparagraphindent option `\temp'}%
+  \fi\fi
+}
+
+% Here is how we actually suppress indentation.  Redefine \everypar to
+% \kern backwards by \parindent, and then reset itself to empty.
+%
+% We also make \indent itself not actually do anything until the next
+% paragraph.
+%
+\gdef\dosuppressfirstparagraphindent{%
+  \gdef\indent{%
+    \restorefirstparagraphindent
+    \indent
+  }%
+  \gdef\noindent{%
+    \restorefirstparagraphindent
+    \noindent
+  }%
+  \global\everypar = {%
+    \kern -\parindent
+    \restorefirstparagraphindent
+  }%
+}
+
+\gdef\restorefirstparagraphindent{%
+  \global \let \indent = \ptexindent
+  \global \let \noindent = \ptexnoindent
+  \global \everypar = {}%
+}
+
+
+% @asis just yields its argument.  Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math outputs its argument in math mode.
+%
+% One complication: _ usually means subscripts, but it could also mean
+% an actual _ character, as in @math{@var{some_variable} + 1}.  So make
+% _ active, and distinguish by seeing if the current family is \slfam,
+% which is what @var uses.
+{
+  \catcode\underChar = \active
+  \gdef\mathunderscore{%
+    \catcode\underChar=\active
+    \def_{\ifnum\fam=\slfam \_\else\sb\fi}%
+  }
+}
+% Another complication: we want \\ (and @\) to output a \ character.
+% FYI, plain.tex uses \\ as a temporary control sequence (why?), but
+% this is not advertised and we don't care.  Texinfo does not
+% otherwise define @\.
+%
+% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\.
+\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi}
+%
+\def\math{%
+  \tex
+  \mathunderscore
+  \let\\ = \mathbackslash
+  \mathactive
+  $\finishmath
+}
+\def\finishmath#1{#1$\endgroup}  % Close the group opened by \tex.
+
+% Some active characters (such as <) are spaced differently in math.
+% We have to reset their definitions in case the @math was an argument
+% to a command which sets the catcodes (such as @item or @section).
+%
+{
+  \catcode`^ = \active
+  \catcode`< = \active
+  \catcode`> = \active
+  \catcode`+ = \active
+  \gdef\mathactive{%
+    \let^ = \ptexhat
+    \let< = \ptexless
+    \let> = \ptexgtr
+    \let+ = \ptexplus
+  }
+}
+
+% @bullet and @minus need the same treatment as @math, just above.
+\def\bullet{$\ptexbullet$}
+\def\minus{$-$}
+
+% @dots{} outputs an ellipsis using the current font.
+% We do .5em per period so that it has the same spacing in a typewriter
+% font as three actual period characters.
+%
+\def\dots{%
+  \leavevmode
+  \hbox to 1.5em{%
+    \hskip 0pt plus 0.25fil
+    .\hfil.\hfil.%
+    \hskip 0pt plus 0.5fil
+  }%
+}
+
+% @enddots{} is an end-of-sentence ellipsis.
+%
+\def\enddots{%
+  \dots
+  \spacefactor=3000
+}
+
+% @comma{} is so commas can be inserted into text without messing up
+% Texinfo's parsing.
+%
+\let\comma = ,
+
+% @refill is a no-op.
+\let\refill=\relax
+
+% If working on a large document in chapters, it is convenient to
+% be able to disable indexing, cross-referencing, and contents, for test runs.
+% This is done with @novalidate (before @setfilename).
+%
+\newif\iflinks \linkstrue % by default we want the aux files.
+\let\novalidate = \linksfalse
+
+% @setfilename is done at the beginning of every texinfo file.
+% So open here the files we need to have open while reading the input.
+% This makes it possible to make a .fmt file for texinfo.
+\def\setfilename{%
+   \fixbackslash  % Turn off hack to swallow `\input texinfo'.
+   \iflinks
+     \tryauxfile
+     % Open the new aux file.  TeX will close it automatically at exit.
+     \immediate\openout\auxfile=\jobname.aux
+   \fi % \openindices needs to do some work in any case.
+   \openindices
+   \let\setfilename=\comment % Ignore extra @setfilename cmds.
+   %
+   % If texinfo.cnf is present on the system, read it.
+   % Useful for site-wide @afourpaper, etc.
+   \openin 1 texinfo.cnf
+   \ifeof 1 \else \input texinfo.cnf \fi
+   \closein 1
+   %
+   \comment % Ignore the actual filename.
+}
+
+% Called from \setfilename.
+%
+\def\openindices{%
+  \newindex{cp}%
+  \newcodeindex{fn}%
+  \newcodeindex{vr}%
+  \newcodeindex{tp}%
+  \newcodeindex{ky}%
+  \newcodeindex{pg}%
+}
+
+% @bye.
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+
+\message{pdf,}
+% adobe `portable' document format
+\newcount\tempnum
+\newcount\lnkcount
+\newtoks\filename
+\newcount\filenamelength
+\newcount\pgn
+\newtoks\toksA
+\newtoks\toksB
+\newtoks\toksC
+\newtoks\toksD
+\newbox\boxA
+\newcount\countA
+\newif\ifpdf
+\newif\ifpdfmakepagedest
+
+% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1
+% can be set).  So we test for \relax and 0 as well as \undefined,
+% borrowed from ifpdf.sty.
+\ifx\pdfoutput\undefined
+\else
+  \ifx\pdfoutput\relax
+  \else
+    \ifcase\pdfoutput
+    \else
+      \pdftrue
+    \fi
+  \fi
+\fi
+%
+\ifpdf
+  \input pdfcolor
+  \pdfcatalog{/PageMode /UseOutlines}%
+  \def\dopdfimage#1#2#3{%
+    \def\imagewidth{#2}%
+    \def\imageheight{#3}%
+    % without \immediate, pdftex seg faults when the same image is
+    % included twice.  (Version 3.14159-pre-1.0-unofficial-20010704.)
+    \ifnum\pdftexversion < 14
+      \immediate\pdfimage
+    \else
+      \immediate\pdfximage
+    \fi
+      \ifx\empty\imagewidth\else width \imagewidth \fi
+      \ifx\empty\imageheight\else height \imageheight \fi
+      \ifnum\pdftexversion<13
+         #1.pdf%
+       \else
+         {#1.pdf}%
+       \fi
+    \ifnum\pdftexversion < 14 \else
+      \pdfrefximage \pdflastximage
+    \fi}
+  \def\pdfmkdest#1{{%
+    % We have to set dummies so commands such as @code in a section title
+    % aren't expanded.
+    \atdummies
+    \normalturnoffactive
+    \pdfdest name{#1} xyz%
+  }}
+  \def\pdfmkpgn#1{#1}
+  \let\linkcolor = \Blue  % was Cyan, but that seems light?
+  \def\endlink{\Black\pdfendlink}
+  % Adding outlines to PDF; macros for calculating structure of outlines
+  % come from Petr Olsak
+  \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0%
+    \else \csname#1\endcsname \fi}
+  \def\advancenumber#1{\tempnum=\expnumber{#1}\relax
+    \advance\tempnum by 1
+    \expandafter\xdef\csname#1\endcsname{\the\tempnum}}
+  %
+  % #1 is the section text.  #2 is the pdf expression for the number
+  % of subentries (or empty, for subsubsections).  #3 is the node
+  % text, which might be empty if this toc entry had no
+  % corresponding node.  #4 is the page number.
+  %
+  \def\dopdfoutline#1#2#3#4{%
+    % Generate a link to the node text if that exists; else, use the
+    % page number.  We could generate a destination for the section
+    % text in the case where a section has no node, but it doesn't
+    % seem worthwhile, since most documents are normally structured.
+    \def\pdfoutlinedest{#3}%
+    \ifx\pdfoutlinedest\empty \def\pdfoutlinedest{#4}\fi
+    %
+    \pdfoutline goto name{\pdfmkpgn{\pdfoutlinedest}}#2{#1}%
+  }
+  %
+  \def\pdfmakeoutlines{%
+    \begingroup
+      % Thanh's hack / proper braces in bookmarks
+      \edef\mylbrace{\iftrue \string{\else}\fi}\let\{=\mylbrace
+      \edef\myrbrace{\iffalse{\else\string}\fi}\let\}=\myrbrace
+      %
+      % Read toc silently, to get counts of subentries for \pdfoutline.
+      \def\numchapentry##1##2##3##4{%
+	\def\thischapnum{##2}%
+	\def\thissecnum{0}%
+	\def\thissubsecnum{0}%
+      }%
+      \def\numsecentry##1##2##3##4{%
+	\advancenumber{chap\thischapnum}%
+	\def\thissecnum{##2}%
+	\def\thissubsecnum{0}%
+      }%
+      \def\numsubsecentry##1##2##3##4{%
+	\advancenumber{sec\thissecnum}%
+	\def\thissubsecnum{##2}%
+      }%
+      \def\numsubsubsecentry##1##2##3##4{%
+	\advancenumber{subsec\thissubsecnum}%
+      }%
+      \def\thischapnum{0}%
+      \def\thissecnum{0}%
+      \def\thissubsecnum{0}%
+      %
+      % use \def rather than \let here because we redefine \chapentry et
+      % al. a second time, below.
+      \def\appentry{\numchapentry}%
+      \def\appsecentry{\numsecentry}%
+      \def\appsubsecentry{\numsubsecentry}%
+      \def\appsubsubsecentry{\numsubsubsecentry}%
+      \def\unnchapentry{\numchapentry}%
+      \def\unnsecentry{\numsecentry}%
+      \def\unnsubsecentry{\numsubsecentry}%
+      \def\unnsubsubsecentry{\numsubsubsecentry}%
+      \input \jobname.toc
+      %
+      % Read toc second time, this time actually producing the outlines.
+      % The `-' means take the \expnumber as the absolute number of
+      % subentries, which we calculated on our first read of the .toc above.
+      %
+      % We use the node names as the destinations.
+      \def\numchapentry##1##2##3##4{%
+        \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}%
+      \def\numsecentry##1##2##3##4{%
+        \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}%
+      \def\numsubsecentry##1##2##3##4{%
+        \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}%
+      \def\numsubsubsecentry##1##2##3##4{% count is always zero
+        \dopdfoutline{##1}{}{##3}{##4}}%
+      %
+      % PDF outlines are displayed using system fonts, instead of
+      % document fonts.  Therefore we cannot use special characters,
+      % since the encoding is unknown.  For example, the eogonek from
+      % Latin 2 (0xea) gets translated to a | character.  Info from
+      % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100.
+      %
+      % xx to do this right, we have to translate 8-bit characters to
+      % their "best" equivalent, based on the @documentencoding.  Right
+      % now, I guess we'll just let the pdf reader have its way.
+      \indexnofonts
+      \turnoffactive
+      \input \jobname.toc
+    \endgroup
+  }
+  %
+  \def\makelinks #1,{%
+    \def\params{#1}\def\E{END}%
+    \ifx\params\E
+      \let\nextmakelinks=\relax
+    \else
+      \let\nextmakelinks=\makelinks
+      \ifnum\lnkcount>0,\fi
+      \picknum{#1}%
+      \startlink attr{/Border [0 0 0]}
+        goto name{\pdfmkpgn{\the\pgn}}%
+      \linkcolor #1%
+      \advance\lnkcount by 1%
+      \endlink
+    \fi
+    \nextmakelinks
+  }
+  \def\picknum#1{\expandafter\pn#1}
+  \def\pn#1{%
+    \def\p{#1}%
+    \ifx\p\lbrace
+      \let\nextpn=\ppn
+    \else
+      \let\nextpn=\ppnn
+      \def\first{#1}
+    \fi
+    \nextpn
+  }
+  \def\ppn#1{\pgn=#1\gobble}
+  \def\ppnn{\pgn=\first}
+  \def\pdfmklnk#1{\lnkcount=0\makelinks #1,END,}
+  \def\skipspaces#1{\def\PP{#1}\def\D{|}%
+    \ifx\PP\D\let\nextsp\relax
+    \else\let\nextsp\skipspaces
+      \ifx\p\space\else\addtokens{\filename}{\PP}%
+        \advance\filenamelength by 1
+      \fi
+    \fi
+    \nextsp}
+  \def\getfilename#1{\filenamelength=0\expandafter\skipspaces#1|\relax}
+  \ifnum\pdftexversion < 14
+    \let \startlink \pdfannotlink
+  \else
+    \let \startlink \pdfstartlink
+  \fi
+  \def\pdfurl#1{%
+    \begingroup
+      \normalturnoffactive\def\@{@}%
+      \makevalueexpandable
+      \leavevmode\Red
+      \startlink attr{/Border [0 0 0]}%
+        user{/Subtype /Link /A << /S /URI /URI (#1) >>}%
+    \endgroup}
+  \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}}
+  \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks}
+  \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks}
+  \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}}
+  \def\maketoks{%
+    \expandafter\poptoks\the\toksA|ENDTOKS|\relax
+    \ifx\first0\adn0
+    \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3
+    \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6
+    \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9
+    \else
+      \ifnum0=\countA\else\makelink\fi
+      \ifx\first.\let\next=\done\else
+        \let\next=\maketoks
+        \addtokens{\toksB}{\the\toksD}
+        \ifx\first,\addtokens{\toksB}{\space}\fi
+      \fi
+    \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+    \next}
+  \def\makelink{\addtokens{\toksB}%
+    {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0}
+  \def\pdflink#1{%
+    \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}}
+    \linkcolor #1\endlink}
+  \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st}
+\else
+  \let\pdfmkdest = \gobble
+  \let\pdfurl = \gobble
+  \let\endlink = \relax
+  \let\linkcolor = \relax
+  \let\pdfmakeoutlines = \relax
+\fi  % \ifx\pdfoutput
+
+
+\message{fonts,}
+
+% Change the current font style to #1, remembering it in \curfontstyle.
+% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in
+% italics, not bold italics.
+%
+\def\setfontstyle#1{%
+  \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd.
+  \csname ten#1\endcsname  % change the current font
+}
+
+% Select #1 fonts with the current style.
+%
+\def\selectfonts#1{\csname #1fonts\endcsname \csname\curfontstyle\endcsname}
+
+\def\rm{\fam=0 \setfontstyle{rm}}
+\def\it{\fam=\itfam \setfontstyle{it}}
+\def\sl{\fam=\slfam \setfontstyle{sl}}
+\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf}
+\def\tt{\fam=\ttfam \setfontstyle{tt}}
+
+% Texinfo sort of supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf.
+\newfam\sffam
+\def\sf{\fam=\sffam \setfontstyle{sf}}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+% We don't need math for this font style.
+\def\ttsl{\setfontstyle{ttsl}}
+
+% Default leading.
+\newdimen\textleading  \textleading = 13.2pt
+
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly.  There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}
+\def\strutheightpercent{.70833}
+\def\strutdepthpercent {.29167}
+%
+\def\setleading#1{%
+  \normalbaselineskip = #1\relax
+  \normallineskip = \lineskipfactor\normalbaselineskip
+  \normalbaselines
+  \setbox\strutbox =\hbox{%
+    \vrule width0pt height\strutheightpercent\baselineskip
+                    depth \strutdepthpercent \baselineskip
+  }%
+}
+
+% Set the font macro #1 to the font named #2, adding on the
+% specified font prefix (normally `cm').
+% #3 is the font's design size, #4 is a scale factor
+\def\setfont#1#2#3#4{\font#1=\fontprefix#2#3 scaled #4}
+
+% Use cm as the default font prefix.
+% To specify the font prefix, you must define \fontprefix
+% before you read in texinfo.tex.
+\ifx\fontprefix\undefined
+\def\fontprefix{cm}
+\fi
+% Support font families that don't use the same naming scheme as CM.
+\def\rmshape{r}
+\def\rmbshape{bx}               %where the normal face is bold
+\def\bfshape{b}
+\def\bxshape{bx}
+\def\ttshape{tt}
+\def\ttbshape{tt}
+\def\ttslshape{sltt}
+\def\itshape{ti}
+\def\itbshape{bxti}
+\def\slshape{sl}
+\def\slbshape{bxsl}
+\def\sfshape{ss}
+\def\sfbshape{ss}
+\def\scshape{csc}
+\def\scbshape{csc}
+
+% Text fonts (11.2pt, magstep1).
+\def\textnominalsize{11pt}
+\edef\mainmagstep{\magstephalf}
+\setfont\textrm\rmshape{10}{\mainmagstep}
+\setfont\texttt\ttshape{10}{\mainmagstep}
+\setfont\textbf\bfshape{10}{\mainmagstep}
+\setfont\textit\itshape{10}{\mainmagstep}
+\setfont\textsl\slshape{10}{\mainmagstep}
+\setfont\textsf\sfshape{10}{\mainmagstep}
+\setfont\textsc\scshape{10}{\mainmagstep}
+\setfont\textttsl\ttslshape{10}{\mainmagstep}
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+
+% A few fonts for @defun names and args.
+\setfont\defbf\bfshape{10}{\magstep1}
+\setfont\deftt\ttshape{10}{\magstep1}
+\setfont\defttsl\ttslshape{10}{\magstep1}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \let\tenttsl=\defttsl \bf}
+
+% Fonts for indices, footnotes, small examples (9pt).
+\def\smallnominalsize{9pt}
+\setfont\smallrm\rmshape{9}{1000}
+\setfont\smalltt\ttshape{9}{1000}
+\setfont\smallbf\bfshape{10}{900}
+\setfont\smallit\itshape{9}{1000}
+\setfont\smallsl\slshape{9}{1000}
+\setfont\smallsf\sfshape{9}{1000}
+\setfont\smallsc\scshape{10}{900}
+\setfont\smallttsl\ttslshape{10}{900}
+\font\smalli=cmmi9
+\font\smallsy=cmsy9
+
+% Fonts for small examples (8pt).
+\def\smallernominalsize{8pt}
+\setfont\smallerrm\rmshape{8}{1000}
+\setfont\smallertt\ttshape{8}{1000}
+\setfont\smallerbf\bfshape{10}{800}
+\setfont\smallerit\itshape{8}{1000}
+\setfont\smallersl\slshape{8}{1000}
+\setfont\smallersf\sfshape{8}{1000}
+\setfont\smallersc\scshape{10}{800}
+\setfont\smallerttsl\ttslshape{10}{800}
+\font\smalleri=cmmi8
+\font\smallersy=cmsy8
+
+% Fonts for title page (20.4pt):
+\def\titlenominalsize{20pt}
+\setfont\titlerm\rmbshape{12}{\magstep3}
+\setfont\titleit\itbshape{10}{\magstep4}
+\setfont\titlesl\slbshape{10}{\magstep4}
+\setfont\titlett\ttbshape{12}{\magstep3}
+\setfont\titlettsl\ttslshape{10}{\magstep4}
+\setfont\titlesf\sfbshape{17}{\magstep1}
+\let\titlebf=\titlerm
+\setfont\titlesc\scbshape{10}{\magstep4}
+\font\titlei=cmmi12 scaled \magstep3
+\font\titlesy=cmsy10 scaled \magstep4
+\def\authorrm{\secrm}
+\def\authortt{\sectt}
+
+% Chapter (and unnumbered) fonts (17.28pt).
+\def\chapnominalsize{17pt}
+\setfont\chaprm\rmbshape{12}{\magstep2}
+\setfont\chapit\itbshape{10}{\magstep3}
+\setfont\chapsl\slbshape{10}{\magstep3}
+\setfont\chaptt\ttbshape{12}{\magstep2}
+\setfont\chapttsl\ttslshape{10}{\magstep3}
+\setfont\chapsf\sfbshape{17}{1000}
+\let\chapbf=\chaprm
+\setfont\chapsc\scbshape{10}{\magstep3}
+\font\chapi=cmmi12 scaled \magstep2
+\font\chapsy=cmsy10 scaled \magstep3
+
+% Section fonts (14.4pt).
+\def\secnominalsize{14pt}
+\setfont\secrm\rmbshape{12}{\magstep1}
+\setfont\secit\itbshape{10}{\magstep2}
+\setfont\secsl\slbshape{10}{\magstep2}
+\setfont\sectt\ttbshape{12}{\magstep1}
+\setfont\secttsl\ttslshape{10}{\magstep2}
+\setfont\secsf\sfbshape{12}{\magstep1}
+\let\secbf\secrm
+\setfont\secsc\scbshape{10}{\magstep2}
+\font\seci=cmmi12 scaled \magstep1
+\font\secsy=cmsy10 scaled \magstep2
+
+% Subsection fonts (13.15pt).
+\def\ssecnominalsize{13pt}
+\setfont\ssecrm\rmbshape{12}{\magstephalf}
+\setfont\ssecit\itbshape{10}{1315}
+\setfont\ssecsl\slbshape{10}{1315}
+\setfont\ssectt\ttbshape{12}{\magstephalf}
+\setfont\ssecttsl\ttslshape{10}{1315}
+\setfont\ssecsf\sfbshape{12}{\magstephalf}
+\let\ssecbf\ssecrm
+\setfont\ssecsc\scbshape{10}{1315}
+\font\sseci=cmmi12 scaled \magstephalf
+\font\ssecsy=cmsy10 scaled 1315
+
+% Reduced fonts for @acro in text (10pt).
+\def\reducednominalsize{10pt}
+\setfont\reducedrm\rmshape{10}{1000}
+\setfont\reducedtt\ttshape{10}{1000}
+\setfont\reducedbf\bfshape{10}{1000}
+\setfont\reducedit\itshape{10}{1000}
+\setfont\reducedsl\slshape{10}{1000}
+\setfont\reducedsf\sfshape{10}{1000}
+\setfont\reducedsc\scshape{10}{1000}
+\setfont\reducedttsl\ttslshape{10}{1000}
+\font\reducedi=cmmi10
+\font\reducedsy=cmsy10
+
+% In order for the font changes to affect most math symbols and letters,
+% we have to define the \textfont of the standard families.  Since
+% texinfo doesn't allow for producing subscripts and superscripts except
+% in the main text, we don't bother to reset \scriptfont and
+% \scriptscriptfont (which would also require loading a lot more fonts).
+%
+\def\resetmathfonts{%
+  \textfont0=\tenrm \textfont1=\teni \textfont2=\tensy
+  \textfont\itfam=\tenit \textfont\slfam=\tensl \textfont\bffam=\tenbf
+  \textfont\ttfam=\tentt \textfont\sffam=\tensf
+}
+
+% The font-changing commands redefine the meanings of \tenSTYLE, instead
+% of just \STYLE.  We do this because \STYLE needs to also set the
+% current \fam for math mode.  Our \STYLE (e.g., \rm) commands hardwire
+% \tenSTYLE to set the current font.
+%
+% Each font-changing command also sets the names \lsize (one size lower)
+% and \lllsize (three sizes lower).  These relative commands are used in
+% the LaTeX logo and acronyms.
+%
+% This all needs generalizing, badly.
+%
+\def\textfonts{%
+  \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+  \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+  \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
+  \let\tenttsl=\textttsl
+  \def\curfontsize{text}%
+  \def\lsize{reduced}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{\textleading}}
+\def\titlefonts{%
+  \let\tenrm=\titlerm \let\tenit=\titleit \let\tensl=\titlesl
+  \let\tenbf=\titlebf \let\tentt=\titlett \let\smallcaps=\titlesc
+  \let\tensf=\titlesf \let\teni=\titlei \let\tensy=\titlesy
+  \let\tenttsl=\titlettsl
+  \def\curfontsize{title}%
+  \def\lsize{chap}\def\lllsize{subsec}%
+  \resetmathfonts \setleading{25pt}}
+\def\titlefont#1{{\titlefonts\rm #1}}
+\def\chapfonts{%
+  \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+  \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+  \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
+  \let\tenttsl=\chapttsl
+  \def\curfontsize{chap}%
+  \def\lsize{sec}\def\lllsize{text}%
+  \resetmathfonts \setleading{19pt}}
+\def\secfonts{%
+  \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+  \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+  \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
+  \let\tenttsl=\secttsl
+  \def\curfontsize{sec}%
+  \def\lsize{subsec}\def\lllsize{reduced}%
+  \resetmathfonts \setleading{16pt}}
+\def\subsecfonts{%
+  \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+  \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+  \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
+  \let\tenttsl=\ssecttsl
+  \def\curfontsize{ssec}%
+  \def\lsize{text}\def\lllsize{small}%
+  \resetmathfonts \setleading{15pt}}
+\let\subsubsecfonts = \subsecfonts
+\def\reducedfonts{%
+  \let\tenrm=\reducedrm \let\tenit=\reducedit \let\tensl=\reducedsl
+  \let\tenbf=\reducedbf \let\tentt=\reducedtt \let\reducedcaps=\reducedsc
+  \let\tensf=\reducedsf \let\teni=\reducedi \let\tensy=\reducedsy
+  \let\tenttsl=\reducedttsl
+  \def\curfontsize{reduced}%
+  \def\lsize{small}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{10.5pt}}
+\def\smallfonts{%
+  \let\tenrm=\smallrm \let\tenit=\smallit \let\tensl=\smallsl
+  \let\tenbf=\smallbf \let\tentt=\smalltt \let\smallcaps=\smallsc
+  \let\tensf=\smallsf \let\teni=\smalli \let\tensy=\smallsy
+  \let\tenttsl=\smallttsl
+  \def\curfontsize{small}%
+  \def\lsize{smaller}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{10.5pt}}
+\def\smallerfonts{%
+  \let\tenrm=\smallerrm \let\tenit=\smallerit \let\tensl=\smallersl
+  \let\tenbf=\smallerbf \let\tentt=\smallertt \let\smallcaps=\smallersc
+  \let\tensf=\smallersf \let\teni=\smalleri \let\tensy=\smallersy
+  \let\tenttsl=\smallerttsl
+  \def\curfontsize{smaller}%
+  \def\lsize{smaller}\def\lllsize{smaller}%
+  \resetmathfonts \setleading{9.5pt}}
+
+% Set the fonts to use with the @small... environments.
+\let\smallexamplefonts = \smallfonts
+
+% About \smallexamplefonts.  If we use \smallfonts (9pt), @smallexample
+% can fit this many characters:
+%   8.5x11=86   smallbook=72  a4=90  a5=69
+% If we use \scriptfonts (8pt), then we can fit this many characters:
+%   8.5x11=90+  smallbook=80  a4=90+  a5=77
+% For me, subjectively, the few extra characters that fit aren't worth
+% the additional smallness of 8pt.  So I'm making the default 9pt.
+%
+% By the way, for comparison, here's what fits with @example (10pt):
+%   8.5x11=71  smallbook=60  a4=75  a5=58
+%
+% I wish the USA used A4 paper.
+% --karl, 24jan03.
+
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\textfonts \rm
+
+% Define these so they can be easily changed for other fonts.
+\def\angleleft{$\langle$}
+\def\angleright{$\rangle$}
+
+% Count depth in font-changes, for error checks
+\newcount\fontdepth \fontdepth=0
+
+% Fonts for short table of contents.
+\setfont\shortcontrm\rmshape{12}{1000}
+\setfont\shortcontbf\bfshape{10}{\magstep1}  % no cmb12
+\setfont\shortcontsl\slshape{12}{1000}
+\setfont\shortconttt\ttshape{12}{1000}
+
+%% Add scribe-like font environments, plus @l for inline lisp (usually sans
+%% serif) and @ii for TeX italic
+
+% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
+% unless the following character is such as not to need one.
+\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else
+                    \ptexslash\fi\fi\fi}
+\def\smartslanted#1{{\ifusingtt\ttsl\sl #1}\futurelet\next\smartitalicx}
+\def\smartitalic#1{{\ifusingtt\ttsl\it #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally uses \ttsl.
+% @var is set to this for defun arguments.
+\def\ttslanted#1{{\ttsl #1}\futurelet\next\smartitalicx}
+
+% like \smartslanted except unconditionally use \sl.  We never want
+% ttsl for book titles, do we?
+\def\cite#1{{\sl #1}\futurelet\next\smartitalicx}
+
+\let\i=\smartitalic
+\let\slanted=\smartslanted
+\let\var=\smartslanted
+\let\dfn=\smartslanted
+\let\emph=\smartitalic
+
+% @b, explicit bold.
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% @sansserif, explicit sans.
+\def\sansserif#1{{\sf #1}}
+
+% We can't just use \exhyphenpenalty, because that only has effect at
+% the end of a paragraph.  Restore normal hyphenation at the end of the
+% group within which \nohyphenation is presumably called.
+%
+\def\nohyphenation{\hyphenchar\font = -1  \aftergroup\restorehyphenation}
+\def\restorehyphenation{\hyphenchar\font = `- }
+
+% Set sfcode to normal for the chars that usually have another value.
+% Can't use plain's \frenchspacing because it uses the `\x notation, and
+% sometimes \x has an active definition that messes things up.
+%
+\catcode`@=11
+  \def\frenchspacing{%
+    \sfcode\dotChar  =\@m \sfcode\questChar=\@m \sfcode\exclamChar=\@m
+    \sfcode\colonChar=\@m \sfcode\semiChar =\@m \sfcode\commaChar =\@m
+  }
+\catcode`@=\other
+
+\def\t#1{%
+  {\tt \rawbackslash \frenchspacing #1}%
+  \null
+}
+\def\samp#1{`\tclose{#1}'\null}
+\setfont\keyrm\rmshape{8}{1000}
+\font\keysy=cmsy9
+\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{%
+  \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{%
+    \vbox{\hrule\kern-0.4pt
+     \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}%
+    \kern-0.4pt\hrule}%
+  \kern-.06em\raise0.4pt\hbox{\angleright}}}}
+% The old definition, with no lozenge:
+%\def\key #1{{\ttsl \nohyphenation \uppercase{#1}}\null}
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+% @file, @option are the same as @samp.
+\let\file=\samp
+\let\option=\samp
+
+% @code is a modification of @t,
+% which makes spaces the same size as normal in the surrounding text.
+\def\tclose#1{%
+  {%
+    % Change normal interword space to be same as for the current font.
+    \spaceskip = \fontdimen2\font
+    %
+    % Switch to typewriter.
+    \tt
+    %
+    % But `\ ' produces the large typewriter interword space.
+    \def\ {{\spaceskip = 0pt{} }}%
+    %
+    % Turn off hyphenation.
+    \nohyphenation
+    %
+    \rawbackslash
+    \frenchspacing
+    #1%
+  }%
+  \null
+}
+
+% We *must* turn on hyphenation at `-' and `_' in @code.
+% Otherwise, it is too hard to avoid overfull hboxes
+% in the Emacs manual, the Library manual, etc.
+
+% Unfortunately, TeX uses one parameter (\hyphenchar) to control
+% both hyphenation at - and hyphenation within words.
+% We must therefore turn them both off (\tclose does that)
+% and arrange explicitly to hyphenate at a dash.
+%  -- rms.
+{
+  \catcode`\-=\active
+  \catcode`\_=\active
+  %
+  \global\def\code{\begingroup
+    \catcode`\-=\active \let-\codedash
+    \catcode`\_=\active \let_\codeunder
+    \codex
+  }
+}
+
+\def\realdash{-}
+\def\codedash{-\discretionary{}{}{}}
+\def\codeunder{%
+  % this is all so @math{@code{var_name}+1} can work.  In math mode, _
+  % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.)
+  % will therefore expand the active definition of _, which is us
+  % (inside @code that is), therefore an endless loop.
+  \ifusingtt{\ifmmode
+               \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_.
+             \else\normalunderscore \fi
+             \discretionary{}{}{}}%
+            {\_}%
+}
+\def\codex #1{\tclose{#1}\endgroup}
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+
+% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always),
+%   `example' (@kbd uses ttsl only inside of @example and friends),
+%   or `code' (@kbd uses normal tty font always).
+\parseargdef\kbdinputstyle{%
+  \def\arg{#1}%
+  \ifx\arg\worddistinct
+    \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}%
+  \else\ifx\arg\wordexample
+    \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}%
+  \else\ifx\arg\wordcode
+    \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}%
+  \else
+    \errhelp = \EMsimple
+    \errmessage{Unknown @kbdinputstyle option `\arg'}%
+  \fi\fi\fi
+}
+\def\worddistinct{distinct}
+\def\wordexample{example}
+\def\wordcode{code}
+
+% Default is `distinct.'
+\kbdinputstyle distinct
+
+\def\xkey{\key}
+\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
+\ifx\one\xkey\ifx\threex\three \key{#2}%
+\else{\tclose{\kbdfont\look}}\fi
+\else{\tclose{\kbdfont\look}}\fi}
+
+% For @indicateurl, @env, @command quotes seem unnecessary, so use \code.
+\let\indicateurl=\code
+\let\env=\code
+\let\command=\code
+
+% @uref (abbreviation for `urlref') takes an optional (comma-separated)
+% second argument specifying the text to display and an optional third
+% arg as text to display instead of (rather than in addition to) the url
+% itself.  First (mandatory) arg is the url.  Perhaps eventually put in
+% a hypertex \special here.
+%
+\def\uref#1{\douref #1,,,\finish}
+\def\douref#1,#2,#3,#4\finish{\begingroup
+  \unsepspaces
+  \pdfurl{#1}%
+  \setbox0 = \hbox{\ignorespaces #3}%
+  \ifdim\wd0 > 0pt
+    \unhbox0 % third arg given, show only that
+  \else
+    \setbox0 = \hbox{\ignorespaces #2}%
+    \ifdim\wd0 > 0pt
+      \ifpdf
+        \unhbox0             % PDF: 2nd arg given, show only it
+      \else
+        \unhbox0\ (\code{#1})% DVI: 2nd arg given, show both it and url
+      \fi
+    \else
+      \code{#1}% only url given, so show it
+    \fi
+  \fi
+  \endlink
+\endgroup}
+
+% @url synonym for @uref, since that's how everyone uses it.
+%
+\let\url=\uref
+
+% rms does not like angle brackets --karl, 17may97.
+% So now @email is just like @uref, unless we are pdf.
+%
+%\def\email#1{\angleleft{\tt #1}\angleright}
+\ifpdf
+  \def\email#1{\doemail#1,,\finish}
+  \def\doemail#1,#2,#3\finish{\begingroup
+    \unsepspaces
+    \pdfurl{mailto:#1}%
+    \setbox0 = \hbox{\ignorespaces #2}%
+    \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi
+    \endlink
+  \endgroup}
+\else
+  \let\email=\uref
+\fi
+
+% Check if we are currently using a typewriter font.  Since all the
+% Computer Modern typewriter fonts have zero interword stretch (and
+% shrink), and it is reasonable to expect all typewriter fonts to have
+% this property, we can check that font parameter.
+%
+\def\ifmonospace{\ifdim\fontdimen3\font=0pt }
+
+% Typeset a dimension, e.g., `in' or `pt'.  The only reason for the
+% argument is to make the input look right: @dmn{pt} instead of @dmn{}pt.
+%
+\def\dmn#1{\thinspace #1}
+
+\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
+
+% @l was never documented to mean ``switch to the Lisp font'',
+% and it is not used as such in any manual I can find.  We need it for
+% Polish suppressed-l.  --karl, 22sep96.
+%\def\l#1{{\li #1}\null}
+
+% Explicit font changes: @r, @sc, undocumented @ii.
+\def\r#1{{\rm #1}}              % roman font
+\def\sc#1{{\smallcaps#1}}       % smallcaps font
+\def\ii#1{{\it #1}}             % italic font
+
+% @acronym for "FBI", "NATO", and the like.
+% We print this one point size smaller, since it's intended for
+% all-uppercase.
+% 
+\def\acronym#1{\doacronym #1,,\finish}
+\def\doacronym#1,#2,#3\finish{%
+  {\selectfonts\lsize #1}%
+  \def\temp{#2}%
+  \ifx\temp\empty \else
+    \space ({\unsepspaces \ignorespaces \temp \unskip})%
+  \fi
+}
+
+% @abbr for "Comput. J." and the like.
+% No font change, but don't do end-of-sentence spacing.
+% 
+\def\abbr#1{\doabbr #1,,\finish}
+\def\doabbr#1,#2,#3\finish{%
+  {\frenchspacing #1}%
+  \def\temp{#2}%
+  \ifx\temp\empty \else
+    \space ({\unsepspaces \ignorespaces \temp \unskip})%
+  \fi
+}
+
+% @pounds{} is a sterling sign, which Knuth put in the CM italic font.
+%
+\def\pounds{{\it\$}}
+
+% @euro{} comes from a separate font, depending on the current style.
+% We use the free feym* fonts from the eurosym package by Henrik
+% Theiling, which support regular, slanted, bold and bold slanted (and
+% "outlined" (blackboard board, sort of) versions, which we don't need).
+% It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
+% 
+% Although only regular is the truly official Euro symbol, we ignore
+% that.  The Euro is designed to be slightly taller than the regular
+% font height.
+% 
+% feymr - regular
+% feymo - slanted
+% feybr - bold
+% feybo - bold slanted
+% 
+% There is no good (free) typewriter version, to my knowledge.
+% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
+% Hmm.
+% 
+% Also doesn't work in math.  Do we need to do math with euro symbols?
+% Hope not.
+% 
+% 
+\def\euro{{\eurofont e}}
+\def\eurofont{%
+  % We set the font at each command, rather than predefining it in
+  % \textfonts and the other font-switching commands, so that
+  % installations which never need the symbold don't have to have the
+  % font installed.
+  % 
+  % There is only one designed size (nominal 10pt), so we always scale
+  % that to the current nominal size.
+  % 
+  % By the way, simply using "at 1em" works for cmr10 and the like, but
+  % does not work for cmbx10 and other extended/shrunken fonts.
+  % 
+  \def\eurosize{\csname\curfontsize nominalsize\endcsname}%
+  %
+  \ifx\curfontstyle\bfstylename 
+    % bold:
+    \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
+  \else 
+    % regular:
+    \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
+  \fi
+  \thiseurofont
+}
+
+% @registeredsymbol - R in a circle.  The font for the R should really
+% be smaller yet, but lllsize is the best we can do for now.
+% Adapted from the plain.tex definition of \copyright.
+%
+\def\registeredsymbol{%
+  $^{{\ooalign{\hfil\raise.07ex\hbox{\selectfonts\lllsize R}%
+               \hfil\crcr\Orb}}%
+    }$%
+}
+
+% Laurent Siebenmann reports \Orb undefined with:
+%  Textures 1.7.7 (preloaded format=plain 93.10.14)  (68K)  16 APR 2004 02:38
+% so we'll define it if necessary.
+% 
+\ifx\Orb\undefined
+\def\Orb{\mathhexbox20D}
+\fi
+
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page.  Must do @settitle before @titlepage.
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+% Do an implicit @contents or @shortcontents after @end titlepage if the
+% user says @setcontentsaftertitlepage or @setshortcontentsaftertitlepage.
+%
+\newif\ifsetcontentsaftertitlepage
+ \let\setcontentsaftertitlepage = \setcontentsaftertitlepagetrue
+\newif\ifsetshortcontentsaftertitlepage
+ \let\setshortcontentsaftertitlepage = \setshortcontentsaftertitlepagetrue
+
+\parseargdef\shorttitlepage{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+        \endgroup\page\hbox{}\page}
+
+\envdef\titlepage{%
+  % Open one extra group, as we want to close it in the middle of \Etitlepage.
+  \begingroup
+    \parindent=0pt \textfonts
+    % Leave some space at the very top of the page.
+    \vglue\titlepagetopglue
+    % No rule at page bottom unless we print one at the top with @title.
+    \finishedtitlepagetrue
+    %
+    % Most title ``pages'' are actually two pages long, with space
+    % at the top of the second.  We don't want the ragged left on the second.
+    \let\oldpage = \page
+    \def\page{%
+      \iffinishedtitlepage\else
+	 \finishtitlepage
+      \fi
+      \let\page = \oldpage
+      \page
+      \null
+    }%
+}
+
+\def\Etitlepage{%
+    \iffinishedtitlepage\else
+	\finishtitlepage
+    \fi
+    % It is important to do the page break before ending the group,
+    % because the headline and footline are only empty inside the group.
+    % If we use the new definition of \page, we always get a blank page
+    % after the title page, which we certainly don't want.
+    \oldpage
+  \endgroup
+  %
+  % Need this before the \...aftertitlepage checks so that if they are
+  % in effect the toc pages will come out with page numbers.
+  \HEADINGSon
+  %
+  % If they want short, they certainly want long too.
+  \ifsetshortcontentsaftertitlepage
+    \shortcontents
+    \contents
+    \global\let\shortcontents = \relax
+    \global\let\contents = \relax
+  \fi
+  %
+  \ifsetcontentsaftertitlepage
+    \contents
+    \global\let\contents = \relax
+    \global\let\shortcontents = \relax
+  \fi
+}
+
+\def\finishtitlepage{%
+  \vskip4pt \hrule height 2pt width \hsize
+  \vskip\titlepagebottomglue
+  \finishedtitlepagetrue
+}
+
+%%% Macros to be used within @titlepage:
+
+\let\subtitlerm=\tenrm
+\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}
+
+\def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines
+		\let\tt=\authortt}
+
+\parseargdef\title{%
+  \checkenv\titlepage
+  \leftline{\titlefonts\rm #1}
+  % print a rule at the page bottom also.
+  \finishedtitlepagefalse
+  \vskip4pt \hrule height 4pt width \hsize \vskip4pt
+}
+
+\parseargdef\subtitle{%
+  \checkenv\titlepage
+  {\subtitlefont \rightline{#1}}%
+}
+
+% @author should come last, but may come many times.
+% It can also be used inside @quotation.
+%
+\parseargdef\author{%
+  \def\temp{\quotation}%
+  \ifx\thisenv\temp
+    \def\quotationauthor{#1}% printed in \Equotation.
+  \else
+    \checkenv\titlepage
+    \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi
+    {\authorfont \leftline{#1}}%
+  \fi
+}
+
+
+%%% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks\evenheadline    % headline on even pages
+\newtoks\oddheadline     % headline on odd pages
+\newtoks\evenfootline    % footline on even pages
+\newtoks\oddfootline     % footline on odd pages
+
+% Now make TeX use those variables
+\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+                            \else \the\evenheadline \fi}}
+\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+                            \else \the\evenfootline \fi}\HEADINGShook}
+\let\HEADINGShook=\relax
+
+% Commands to set those variables.
+% For example, this is what  @headings on  does
+% @evenheading @thistitle|@thispage|@thischapter
+% @oddheading @thischapter|@thispage|@thistitle
+% @evenfooting @thisfile||
+% @oddfooting ||@thisfile
+
+
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish}
+\def\evenheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish}
+\def\oddheadingyyy #1\|#2\|#3\|#4\finish{%
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}%
+
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish}
+\def\evenfootingyyy #1\|#2\|#3\|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish}
+\def\oddfootingyyy #1\|#2\|#3\|#4\finish{%
+  \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}%
+  %
+  % Leave some space for the footline.  Hopefully ok to assume
+  % @evenfooting will not be used by itself.
+  \global\advance\pageheight by -\baselineskip
+  \global\advance\vsize by -\baselineskip
+}
+
+\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}}
+
+
+% @headings double      turns headings on for double-sided printing.
+% @headings single      turns headings on for single-sided printing.
+% @headings off         turns them off.
+% @headings on          same as @headings double, retained for compatibility.
+% @headings after       turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
+% @headings singleafter turns on single-sided headings after this page.
+% By default, they are off at the start of a document,
+% and turned `on' after @end titlepage.
+
+\def\headings #1 {\csname HEADINGS#1\endcsname}
+
+\def\HEADINGSoff{%
+\global\evenheadline={\hfil} \global\evenfootline={\hfil}
+\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
+\HEADINGSoff
+% When we turn headings on, set the page number to 1.
+% For double-sided printing, put current file name in lower left corner,
+% chapter name on inside top of right hand pages, document
+% title on inside top of left hand pages, and page numbers on outside top
+% edge of all pages.
+\def\HEADINGSdouble{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+\let\contentsalignmacro = \chappager
+
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{%
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+\def\HEADINGSon{\HEADINGSdouble}
+
+\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+\let\HEADINGSdoubleafter=\HEADINGSafter
+\def\HEADINGSdoublex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chapoddpage
+}
+
+\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+\def\HEADINGSsinglex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+\global\let\contentsalignmacro = \chappager
+}
+
+% Subroutines used in generating headings
+% This produces Day Month Year style of output.
+% Only define if not already defined, in case a txi-??.tex file has set
+% up a different format (e.g., txi-cs.tex does this).
+\ifx\today\undefined
+\def\today{%
+  \number\day\space
+  \ifcase\month
+  \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr
+  \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug
+  \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec
+  \fi
+  \space\number\year}
+\fi
+
+% @settitle line...  specifies the title of the document, for headings.
+% It generates no output of its own.
+\def\thistitle{\putwordNoTitle}
+\def\settitle{\parsearg{\gdef\thistitle}}
+
+
+\message{tables,}
+% Tables -- @table, @ftable, @vtable, @item(x).
+
+% default indentation of table text
+\newdimen\tableindent \tableindent=.8in
+% default indentation of @itemize and @enumerate text
+\newdimen\itemindent  \itemindent=.3in
+% margin between end of table item and start of table text.
+\newdimen\itemmargin  \itemmargin=.1in
+
+% used internally for \itemindent minus \itemmargin
+\newdimen\itemmax
+
+% Note @table, @ftable, and @vtable define @item, @itemx, etc., with
+% these defs.
+% They also define \itemindex
+% to index the item name in whatever manner is desired (perhaps none).
+
+\newif\ifitemxneedsnegativevskip
+
+\def\itemxpar{\par\ifitemxneedsnegativevskip\nobreak\vskip-\parskip\nobreak\fi}
+
+\def\internalBitem{\smallbreak \parsearg\itemzzz}
+\def\internalBitemx{\itemxpar \parsearg\itemzzz}
+
+\def\itemzzz #1{\begingroup %
+  \advance\hsize by -\rightskip
+  \advance\hsize by -\tableindent
+  \setbox0=\hbox{\itemindicate{#1}}%
+  \itemindex{#1}%
+  \nobreak % This prevents a break before @itemx.
+  %
+  % If the item text does not fit in the space we have, put it on a line
+  % by itself, and do not allow a page break either before or after that
+  % line.  We do not start a paragraph here because then if the next
+  % command is, e.g., @kindex, the whatsit would get put into the
+  % horizontal list on a line by itself, resulting in extra blank space.
+  \ifdim \wd0>\itemmax
+    %
+    % Make this a paragraph so we get the \parskip glue and wrapping,
+    % but leave it ragged-right.
+    \begingroup
+      \advance\leftskip by-\tableindent
+      \advance\hsize by\tableindent
+      \advance\rightskip by0pt plus1fil
+      \leavevmode\unhbox0\par
+    \endgroup
+    %
+    % We're going to be starting a paragraph, but we don't want the
+    % \parskip glue -- logically it's part of the @item we just started.
+    \nobreak \vskip-\parskip
+    %
+    % Stop a page break at the \parskip glue coming up.  However, if
+    % what follows is an environment such as @example, there will be no
+    % \parskip glue; then the negative vskip we just inserted would
+    % cause the example and the item to crash together.  So we use this
+    % bizarre value of 10001 as a signal to \aboveenvbreak to insert
+    % \parskip glue after all.  Section titles are handled this way also.
+    % 
+    \penalty 10001
+    \endgroup
+    \itemxneedsnegativevskipfalse
+  \else
+    % The item text fits into the space.  Start a paragraph, so that the
+    % following text (if any) will end up on the same line.
+    \noindent
+    % Do this with kerns and \unhbox so that if there is a footnote in
+    % the item text, it can migrate to the main vertical list and
+    % eventually be printed.
+    \nobreak\kern-\tableindent
+    \dimen0 = \itemmax  \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0
+    \unhbox0
+    \nobreak\kern\dimen0
+    \endgroup
+    \itemxneedsnegativevskiptrue
+  \fi
+}
+
+\def\item{\errmessage{@item while not in a list environment}}
+\def\itemx{\errmessage{@itemx while not in a list environment}}
+
+% @table, @ftable, @vtable.
+\envdef\table{%
+  \let\itemindex\gobble
+  \tablecheck{table}%
+}
+\envdef\ftable{%
+  \def\itemindex ##1{\doind {fn}{\code{##1}}}%
+  \tablecheck{ftable}%
+}
+\envdef\vtable{%
+  \def\itemindex ##1{\doind {vr}{\code{##1}}}%
+  \tablecheck{vtable}%
+}
+\def\tablecheck#1{%
+  \ifnum \the\catcode`\^^M=\active
+    \endgroup
+    \errmessage{This command won't work in this context; perhaps the problem is
+      that we are \inenvironment\thisenv}%
+    \def\next{\doignore{#1}}%
+  \else
+    \let\next\tablex
+  \fi
+  \next
+}
+\def\tablex#1{%
+  \def\itemindicate{#1}%
+  \parsearg\tabley
+}
+\def\tabley#1{%
+  {%
+    \makevalueexpandable
+    \edef\temp{\noexpand\tablez #1\space\space\space}%
+    \expandafter
+  }\temp \endtablez
+}
+\def\tablez #1 #2 #3 #4\endtablez{%
+  \aboveenvbreak
+  \ifnum 0#1>0 \advance \leftskip by #1\mil \fi
+  \ifnum 0#2>0 \tableindent=#2\mil \fi
+  \ifnum 0#3>0 \advance \rightskip by #3\mil \fi
+  \itemmax=\tableindent
+  \advance \itemmax by -\itemmargin
+  \advance \leftskip by \tableindent
+  \exdentamount=\tableindent
+  \parindent = 0pt
+  \parskip = \smallskipamount
+  \ifdim \parskip=0pt \parskip=2pt \fi
+  \let\item = \internalBitem
+  \let\itemx = \internalBitemx
+}
+\def\Etable{\endgraf\afterenvbreak}
+\let\Eftable\Etable
+\let\Evtable\Etable
+\let\Eitemize\Etable
+\let\Eenumerate\Etable
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\envdef\itemize{\parsearg\doitemize}
+
+\def\doitemize#1{%
+  \aboveenvbreak
+  \itemmax=\itemindent
+  \advance\itemmax by -\itemmargin
+  \advance\leftskip by \itemindent
+  \exdentamount=\itemindent
+  \parindent=0pt
+  \parskip=\smallskipamount
+  \ifdim\parskip=0pt \parskip=2pt \fi
+  \def\itemcontents{#1}%
+  % @itemize with no arg is equivalent to @itemize @bullet.
+  \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi
+  \let\item=\itemizeitem
+}
+
+% Definition of @item while inside @itemize and @enumerate.
+%
+\def\itemizeitem{%
+  \advance\itemno by 1  % for enumerations
+  {\let\par=\endgraf \smallbreak}% reasonable place to break
+  {%
+   % If the document has an @itemize directly after a section title, a
+   % \nobreak will be last on the list, and \sectionheading will have
+   % done a \vskip-\parskip.  In that case, we don't want to zero
+   % parskip, or the item text will crash with the heading.  On the
+   % other hand, when there is normal text preceding the item (as there
+   % usually is), we do want to zero parskip, or there would be too much
+   % space.  In that case, we won't have a \nobreak before.  At least
+   % that's the theory.
+   \ifnum\lastpenalty<10000 \parskip=0in \fi
+   \noindent
+   \hbox to 0pt{\hss \itemcontents \kern\itemmargin}%
+   \vadjust{\penalty 1200}}% not good to break after first line of item.
+  \flushcr
+}
+
+% \splitoff TOKENS\endmark defines \first to be the first token in
+% TOKENS, and \rest to be the remainder.
+%
+\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+
+% Allow an optional argument of an uppercase letter, lowercase letter,
+% or number, to specify the first label in the enumerated list.  No
+% argument is the same as `1'.
+%
+\envparseargdef\enumerate{\enumeratey #1  \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+  % If we were given no argument, pretend we were given `1'.
+  \def\thearg{#1}%
+  \ifx\thearg\empty \def\thearg{1}\fi
+  %
+  % Detect if the argument is a single token.  If so, it might be a
+  % letter.  Otherwise, the only valid thing it can be is a number.
+  % (We will always have one token, because of the test we just made.
+  % This is a good thing, since \splitoff doesn't work given nothing at
+  % all -- the first parameter is undelimited.)
+  \expandafter\splitoff\thearg\endmark
+  \ifx\rest\empty
+    % Only one token in the argument.  It could still be anything.
+    % A ``lowercase letter'' is one whose \lccode is nonzero.
+    % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+    %   not equal to itself.
+    % Otherwise, we assume it's a number.
+    %
+    % We need the \relax at the end of the \ifnum lines to stop TeX from
+    % continuing to look for a <number>.
+    %
+    \ifnum\lccode\expandafter`\thearg=0\relax
+      \numericenumerate % a number (we hope)
+    \else
+      % It's a letter.
+      \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+        \lowercaseenumerate % lowercase letter
+      \else
+        \uppercaseenumerate % uppercase letter
+      \fi
+    \fi
+  \else
+    % Multiple tokens in the argument.  We hope it's a number.
+    \numericenumerate
+  \fi
+}
+
+% An @enumerate whose labels are integers.  The starting integer is
+% given in \thearg.
+%
+\def\numericenumerate{%
+  \itemno = \thearg
+  \startenumeration{\the\itemno}%
+}
+
+% The starting (lowercase) letter is in \thearg.
+\def\lowercaseenumerate{%
+  \itemno = \expandafter`\thearg
+  \startenumeration{%
+    % Be sure we're not beyond the end of the alphabet.
+    \ifnum\itemno=0
+      \errmessage{No more lowercase letters in @enumerate; get a bigger
+                  alphabet}%
+    \fi
+    \char\lccode\itemno
+  }%
+}
+
+% The starting (uppercase) letter is in \thearg.
+\def\uppercaseenumerate{%
+  \itemno = \expandafter`\thearg
+  \startenumeration{%
+    % Be sure we're not beyond the end of the alphabet.
+    \ifnum\itemno=0
+      \errmessage{No more uppercase letters in @enumerate; get a bigger
+                  alphabet}
+    \fi
+    \char\uccode\itemno
+  }%
+}
+
+% Call \doitemize, adding a period to the first argument and supplying the
+% common last two arguments.  Also subtract one from the initial value in
+% \itemno, since @item increments \itemno.
+%
+\def\startenumeration#1{%
+  \advance\itemno by -1
+  \doitemize{#1.}\flushcr
+}
+
+% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+% to @enumerate.
+%
+\def\alphaenumerate{\enumerate{a}}
+\def\capsenumerate{\enumerate{A}}
+\def\Ealphaenumerate{\Eenumerate}
+\def\Ecapsenumerate{\Eenumerate}
+
+
+% @multitable macros
+% Amy Hendrickson, 8/18/94, 3/6/96
+%
+% @multitable ... @end multitable will make as many columns as desired.
+% Contents of each column will wrap at width given in preamble.  Width
+% can be specified either with sample text given in a template line,
+% or in percent of \hsize, the current width of text on page.
+
+% Table can continue over pages but will only break between lines.
+
+% To make preamble:
+%
+% Either define widths of columns in terms of percent of \hsize:
+%   @multitable @columnfractions .25 .3 .45
+%   @item ...
+%
+%   Numbers following @columnfractions are the percent of the total
+%   current hsize to be used for each column. You may use as many
+%   columns as desired.
+
+
+% Or use a template:
+%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+%   @item ...
+%   using the widest term desired in each column.
+
+% Each new table line starts with @item, each subsequent new column
+% starts with @tab. Empty columns may be produced by supplying @tab's
+% with nothing between them for as many times as empty columns are needed,
+% ie, @tab@tab@tab will produce two empty columns.
+
+% @item, @tab do not need to be on their own lines, but it will not hurt
+% if they are.
+
+% Sample multitable:
+
+%   @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+%   @item first col stuff @tab second col stuff @tab third col
+%   @item
+%   first col stuff
+%   @tab
+%   second col stuff
+%   @tab
+%   third col
+%   @item first col stuff @tab second col stuff
+%   @tab Many paragraphs of text may be used in any column.
+%
+%         They will wrap at the width determined by the template.
+%   @item@tab@tab This will be in third column.
+%   @end multitable
+
+% Default dimensions may be reset by user.
+% @multitableparskip is vertical space between paragraphs in table.
+% @multitableparindent is paragraph indent in table.
+% @multitablecolmargin is horizontal space to be left between columns.
+% @multitablelinespace is space to leave between table items, baseline
+%                                                            to baseline.
+%   0pt means it depends on current normal line spacing.
+%
+\newskip\multitableparskip
+\newskip\multitableparindent
+\newdimen\multitablecolspace
+\newskip\multitablelinespace
+\multitableparskip=0pt
+\multitableparindent=6pt
+\multitablecolspace=12pt
+\multitablelinespace=0pt
+
+% Macros used to set up halign preamble:
+%
+\let\endsetuptable\relax
+\def\xendsetuptable{\endsetuptable}
+\let\columnfractions\relax
+\def\xcolumnfractions{\columnfractions}
+\newif\ifsetpercent
+
+% #1 is the @columnfraction, usually a decimal number like .5, but might
+% be just 1.  We just use it, whatever it is.
+%
+\def\pickupwholefraction#1 {%
+  \global\advance\colcount by 1
+  \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}%
+  \setuptable
+}
+
+\newcount\colcount
+\def\setuptable#1{%
+  \def\firstarg{#1}%
+  \ifx\firstarg\xendsetuptable
+    \let\go = \relax
+  \else
+    \ifx\firstarg\xcolumnfractions
+      \global\setpercenttrue
+    \else
+      \ifsetpercent
+         \let\go\pickupwholefraction
+      \else
+         \global\advance\colcount by 1
+         \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a
+                   % separator; typically that is always in the input, anyway.
+         \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+      \fi
+    \fi
+    \ifx\go\pickupwholefraction
+      % Put the argument back for the \pickupwholefraction call, so
+      % we'll always have a period there to be parsed.
+      \def\go{\pickupwholefraction#1}%
+    \else
+      \let\go = \setuptable
+    \fi%
+  \fi
+  \go
+}
+
+% multitable-only commands.
+%
+% @headitem starts a heading row, which we typeset in bold.
+% Assignments have to be global since we are inside the implicit group
+% of an alignment entry.  Note that \everycr resets \everytab.
+\def\headitem{\checkenv\multitable \crcr \global\everytab={\bf}\the\everytab}%
+%
+% A \tab used to include \hskip1sp.  But then the space in a template
+% line is not enough.  That is bad.  So let's go back to just `&' until
+% we encounter the problem it was intended to solve again.
+%					--karl, nathan@acm.org, 20apr99.
+\def\tab{\checkenv\multitable &\the\everytab}%
+
+% @multitable ... @end multitable definitions:
+%
+\newtoks\everytab  % insert after every tab.
+%
+\envdef\multitable{%
+  \vskip\parskip
+  \startsavinginserts
+  %
+  % @item within a multitable starts a normal row.
+  % We use \def instead of \let so that if one of the multitable entries
+  % contains an @itemize, we don't choke on the \item (seen as \crcr aka
+  % \endtemplate) expanding \doitemize.
+  \def\item{\crcr}%
+  %
+  \tolerance=9500
+  \hbadness=9500
+  \setmultitablespacing
+  \parskip=\multitableparskip
+  \parindent=\multitableparindent
+  \overfullrule=0pt
+  \global\colcount=0
+  %
+  \everycr = {%
+    \noalign{%
+      \global\everytab={}%
+      \global\colcount=0 % Reset the column counter.
+      % Check for saved footnotes, etc.
+      \checkinserts
+      % Keeps underfull box messages off when table breaks over pages.
+      %\filbreak
+	% Maybe so, but it also creates really weird page breaks when the
+	% table breaks over pages. Wouldn't \vfil be better?  Wait until the
+	% problem manifests itself, so it can be fixed for real --karl.
+    }%
+  }%
+  %
+  \parsearg\domultitable
+}
+\def\domultitable#1{%
+  % To parse everything between @multitable and @item:
+  \setuptable#1 \endsetuptable
+  %
+  % This preamble sets up a generic column definition, which will
+  % be used as many times as user calls for columns.
+  % \vtop will set a single line and will also let text wrap and
+  % continue for many paragraphs if desired.
+  \halign\bgroup &%
+    \global\advance\colcount by 1
+    \multistrut
+    \vtop{%
+      % Use the current \colcount to find the correct column width:
+      \hsize=\expandafter\csname col\the\colcount\endcsname
+      %
+      % In order to keep entries from bumping into each other
+      % we will add a \leftskip of \multitablecolspace to all columns after
+      % the first one.
+      %
+      % If a template has been used, we will add \multitablecolspace
+      % to the width of each template entry.
+      %
+      % If the user has set preamble in terms of percent of \hsize we will
+      % use that dimension as the width of the column, and the \leftskip
+      % will keep entries from bumping into each other.  Table will start at
+      % left margin and final column will justify at right margin.
+      %
+      % Make sure we don't inherit \rightskip from the outer environment.
+      \rightskip=0pt
+      \ifnum\colcount=1
+	% The first column will be indented with the surrounding text.
+	\advance\hsize by\leftskip
+      \else
+	\ifsetpercent \else
+	  % If user has not set preamble in terms of percent of \hsize
+	  % we will advance \hsize by \multitablecolspace.
+	  \advance\hsize by \multitablecolspace
+	\fi
+       % In either case we will make \leftskip=\multitablecolspace:
+      \leftskip=\multitablecolspace
+      \fi
+      % Ignoring space at the beginning and end avoids an occasional spurious
+      % blank line, when TeX decides to break the line at the space before the
+      % box from the multistrut, so the strut ends up on a line by itself.
+      % For example:
+      % @multitable @columnfractions .11 .89
+      % @item @code{#}
+      % @tab Legal holiday which is valid in major parts of the whole country.
+      % Is automatically provided with highlighting sequences respectively
+      % marking characters.
+      \noindent\ignorespaces##\unskip\multistrut
+    }\cr
+}
+\def\Emultitable{%
+  \crcr
+  \egroup % end the \halign
+  \global\setpercentfalse
+}
+
+\def\setmultitablespacing{%
+  \def\multistrut{\strut}% just use the standard line spacing
+  %
+  % Compute \multitablelinespace (if not defined by user) for use in
+  % \multitableparskip calculation.  We used define \multistrut based on
+  % this, but (ironically) that caused the spacing to be off.
+  % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100.
+\ifdim\multitablelinespace=0pt
+\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip
+\global\advance\multitablelinespace by-\ht0
+\fi
+%% Test to see if parskip is larger than space between lines of
+%% table. If not, do nothing.
+%%        If so, set to same dimension as multitablelinespace.
+\ifdim\multitableparskip>\multitablelinespace
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+                                      %% than skip between lines in the table.
+\fi%
+\ifdim\multitableparskip=0pt
+\global\multitableparskip=\multitablelinespace
+\global\advance\multitableparskip-7pt %% to keep parskip somewhat smaller
+                                      %% than skip between lines in the table.
+\fi}
+
+
+\message{conditionals,}
+
+% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext,
+% @ifnotxml always succeed.  They currently do nothing; we don't
+% attempt to check whether the conditionals are properly nested.  But we
+% have to remember that they are conditionals, so that @end doesn't
+% attempt to close an environment group.
+%
+\def\makecond#1{%
+  \expandafter\let\csname #1\endcsname = \relax
+  \expandafter\let\csname iscond.#1\endcsname = 1
+}
+\makecond{iftex}
+\makecond{ifnotdocbook}
+\makecond{ifnothtml}
+\makecond{ifnotinfo}
+\makecond{ifnotplaintext}
+\makecond{ifnotxml}
+
+% Ignore @ignore, @ifhtml, @ifinfo, and the like.
+%
+\def\direntry{\doignore{direntry}}
+\def\documentdescription{\doignore{documentdescription}}
+\def\docbook{\doignore{docbook}}
+\def\html{\doignore{html}}
+\def\ifdocbook{\doignore{ifdocbook}}
+\def\ifhtml{\doignore{ifhtml}}
+\def\ifinfo{\doignore{ifinfo}}
+\def\ifnottex{\doignore{ifnottex}}
+\def\ifplaintext{\doignore{ifplaintext}}
+\def\ifxml{\doignore{ifxml}}
+\def\ignore{\doignore{ignore}}
+\def\menu{\doignore{menu}}
+\def\xml{\doignore{xml}}
+
+% Ignore text until a line `@end #1', keeping track of nested conditionals.
+%
+% A count to remember the depth of nesting.
+\newcount\doignorecount
+
+\def\doignore#1{\begingroup
+  % Scan in ``verbatim'' mode:
+  \catcode`\@ = \other
+  \catcode`\{ = \other
+  \catcode`\} = \other
+  %
+  % Make sure that spaces turn into tokens that match what \doignoretext wants.
+  \spaceisspace
+  %
+  % Count number of #1's that we've seen.
+  \doignorecount = 0
+  %
+  % Swallow text until we reach the matching `@end #1'.
+  \dodoignore{#1}%
+}
+
+{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source.
+  \obeylines %
+  %
+  \gdef\dodoignore#1{%
+    % #1 contains the command name as a string, e.g., `ifinfo'.
+    %
+    % Define a command to find the next `@end #1', which must be on a line
+    % by itself.
+    \long\def\doignoretext##1^^M@end #1{\doignoretextyyy##1^^M@#1\_STOP_}%
+    % And this command to find another #1 command, at the beginning of a
+    % line.  (Otherwise, we would consider a line `@c @ifset', for
+    % example, to count as an @ifset for nesting.)
+    \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}%
+    %
+    % And now expand that command.
+    \obeylines %
+    \doignoretext ^^M%
+  }%
+}
+
+\def\doignoreyyy#1{%
+  \def\temp{#1}%
+  \ifx\temp\empty			% Nothing found.
+    \let\next\doignoretextzzz
+  \else					% Found a nested condition, ...
+    \advance\doignorecount by 1
+    \let\next\doignoretextyyy		% ..., look for another.
+    % If we're here, #1 ends with ^^M\ifinfo (for example).
+  \fi
+  \next #1% the token \_STOP_ is present just after this macro.
+}
+
+% We have to swallow the remaining "\_STOP_".
+%
+\def\doignoretextzzz#1{%
+  \ifnum\doignorecount = 0	% We have just found the outermost @end.
+    \let\next\enddoignore
+  \else				% Still inside a nested condition.
+    \advance\doignorecount by -1
+    \let\next\doignoretext      % Look for the next @end.
+  \fi
+  \next
+}
+
+% Finish off ignored text.
+\def\enddoignore{\endgroup\ignorespaces}
+
+
+% @set VAR sets the variable VAR to an empty value.
+% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+%
+% Since we want to separate VAR from REST-OF-LINE (which might be
+% empty), we can't just use \parsearg; we have to insert a space of our
+% own to delimit the rest of the line, and then take it out again if we
+% didn't need it.
+% We rely on the fact that \parsearg sets \catcode`\ =10.
+%
+\parseargdef\set{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+  {%
+    \makevalueexpandable
+    \def\temp{#2}%
+    \edef\next{\gdef\makecsname{SET#1}}%
+    \ifx\temp\empty
+      \next{}%
+    \else
+      \setzzz#2\endsetzzz
+    \fi
+  }%
+}
+% Remove the trailing space \setxxx inserted.
+\def\setzzz#1 \endsetzzz{\next{#1}}
+
+% @clear VAR clears (i.e., unsets) the variable VAR.
+%
+\parseargdef\clear{%
+  {%
+    \makevalueexpandable
+    \global\expandafter\let\csname SET#1\endcsname=\relax
+  }%
+}
+
+% @value{foo} gets the text saved in variable foo.
+\def\value{\begingroup\makevalueexpandable\valuexxx}
+\def\valuexxx#1{\expandablevalue{#1}\endgroup}
+{
+  \catcode`\- = \active \catcode`\_ = \active
+  %
+  \gdef\makevalueexpandable{%
+    \let\value = \expandablevalue
+    % We don't want these characters active, ...
+    \catcode`\-=\other \catcode`\_=\other
+    % ..., but we might end up with active ones in the argument if
+    % we're called from @code, as @code{@value{foo-bar_}}, though.
+    % So \let them to their normal equivalents.
+    \let-\realdash \let_\normalunderscore
+  }
+}
+
+% We have this subroutine so that we can handle at least some @value's
+% properly in indexes (we call \makevalueexpandable in \indexdummies).
+% The command has to be fully expandable (if the variable is set), since
+% the result winds up in the index file.  This means that if the
+% variable's value contains other Texinfo commands, it's almost certain
+% it will fail (although perhaps we could fix that with sufficient work
+% to do a one-level expansion on the result, instead of complete).
+%
+\def\expandablevalue#1{%
+  \expandafter\ifx\csname SET#1\endcsname\relax
+    {[No value for ``#1'']}%
+    \message{Variable `#1', used in @value, is not set.}%
+  \else
+    \csname SET#1\endcsname
+  \fi
+}
+
+% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+% with @set.
+%
+% To get special treatment of `@end ifset,' call \makeond and the redefine.
+%
+\makecond{ifset}
+\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}}
+\def\doifset#1#2{%
+  {%
+    \makevalueexpandable
+    \let\next=\empty
+    \expandafter\ifx\csname SET#2\endcsname\relax
+      #1% If not set, redefine \next.
+    \fi
+    \expandafter
+  }\next
+}
+\def\ifsetfail{\doignore{ifset}}
+
+% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+% The `\else' inside the `\doifset' parameter is a trick to reuse the
+% above code: if the variable is not set, do nothing, if it is set,
+% then redefine \next to \ifclearfail.
+%
+\makecond{ifclear}
+\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}}
+\def\ifclearfail{\doignore{ifclear}}
+
+% @dircategory CATEGORY  -- specify a category of the dir file
+% which this file should belong to.  Ignore this in TeX.
+\let\dircategory=\comment
+
+% @defininfoenclose.
+\let\definfoenclose=\comment
+
+
+\message{indexing,}
+% Index generation facilities
+
+% Define \newwrite to be identical to plain tex's \newwrite
+% except not \outer, so it can be used within macros and \if's.
+\edef\newwrite{\makecsname{ptexnewwrite}}
+
+% \newindex {foo} defines an index named foo.
+% It automatically defines \fooindex such that
+% \fooindex ...rest of line... puts an entry in the index foo.
+% It also defines \fooindfile to be the number of the output channel for
+% the file that accumulates this index.  The file's extension is foo.
+% The name of an index should be no more than 2 characters long
+% for the sake of vms.
+%
+\def\newindex#1{%
+  \iflinks
+    \expandafter\newwrite \csname#1indfile\endcsname
+    \openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+  \fi
+  \expandafter\xdef\csname#1index\endcsname{%     % Define @#1index
+    \noexpand\doindex{#1}}
+}
+
+% @defindex foo  ==  \newindex{foo}
+%
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+%
+\def\defcodeindex{\parsearg\newcodeindex}
+%
+\def\newcodeindex#1{%
+  \iflinks
+    \expandafter\newwrite \csname#1indfile\endcsname
+    \openout \csname#1indfile\endcsname \jobname.#1
+  \fi
+  \expandafter\xdef\csname#1index\endcsname{%
+    \noexpand\docodeindex{#1}}%
+}
+
+
+% @synindex foo bar    makes index foo feed into index bar.
+% Do this instead of @defindex foo if you don't want it as a separate index.
+%
+% @syncodeindex foo bar   similar, but put all entries made for index foo
+% inside @code.
+%
+\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}}
+\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}}
+
+% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo),
+% #3 the target index (bar).
+\def\dosynindex#1#2#3{%
+  % Only do \closeout if we haven't already done it, else we'll end up
+  % closing the target index.
+  \expandafter \ifx\csname donesynindex#2\endcsname \undefined
+    % The \closeout helps reduce unnecessary open files; the limit on the
+    % Acorn RISC OS is a mere 16 files.
+    \expandafter\closeout\csname#2indfile\endcsname
+    \expandafter\let\csname\donesynindex#2\endcsname = 1
+  \fi
+  % redefine \fooindfile:
+  \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname
+  \expandafter\let\csname#2indfile\endcsname=\temp
+  % redefine \fooindex:
+  \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}%
+}
+
+% Define \doindex, the driver for all \fooindex macros.
+% Argument #1 is generated by the calling \fooindex macro,
+%  and it is "foo", the name of the index.
+
+% \doindex just uses \parsearg; it calls \doind for the actual work.
+% This is because \doind is more useful to call from other macros.
+
+% There is also \dosubind {index}{topic}{subtopic}
+% which makes an entry in a two-level index such as the operation index.
+
+\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+\def\singleindexer #1{\doind{\indexname}{#1}}
+
+% like the previous two, but they put @code around the argument.
+\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+
+% Take care of Texinfo commands that can appear in an index entry.
+% Since there are some commands we want to expand, and others we don't,
+% we have to laboriously prevent expansion for those that we don't.
+%
+\def\indexdummies{%
+  \def\@{@}% change to @@ when we switch to @ as escape char in index files.
+  \def\ {\realbackslash\space }%
+  % Need these in case \tex is in effect and \{ is a \delimiter again.
+  % But can't use \lbracecmd and \rbracecmd because texindex assumes
+  % braces and backslashes are used only as delimiters.
+  \let\{ = \mylbrace
+  \let\} = \myrbrace
+  %
+  % \definedummyword defines \#1 as \realbackslash #1\space, thus
+  % effectively preventing its expansion.  This is used only for control
+  % words, not control letters, because the \space would be incorrect
+  % for control characters, but is needed to separate the control word
+  % from whatever follows.
+  %
+  % For control letters, we have \definedummyletter, which omits the
+  % space.
+  %
+  % These can be used both for control words that take an argument and
+  % those that do not.  If it is followed by {arg} in the input, then
+  % that will dutifully get written to the index (or wherever).
+  %
+  \def\definedummyword##1{%
+    \expandafter\def\csname ##1\endcsname{\realbackslash ##1\space}%
+  }%
+  \def\definedummyletter##1{%
+    \expandafter\def\csname ##1\endcsname{\realbackslash ##1}%
+  }%
+  \let\definedummyaccent\definedummyletter
+  %
+  % Do the redefinitions.
+  \commondummies
+}
+
+% For the aux file, @ is the escape character.  So we want to redefine
+% everything using @ instead of \realbackslash.  When everything uses
+% @, this will be simpler.
+%
+\def\atdummies{%
+  \def\@{@@}%
+  \def\ {@ }%
+  \let\{ = \lbraceatcmd
+  \let\} = \rbraceatcmd
+  %
+  % (See comments in \indexdummies.)
+  \def\definedummyword##1{%
+    \expandafter\def\csname ##1\endcsname{@##1\space}%
+  }%
+  \def\definedummyletter##1{%
+    \expandafter\def\csname ##1\endcsname{@##1}%
+  }%
+  \let\definedummyaccent\definedummyletter
+  %
+  % Do the redefinitions.
+  \commondummies
+}
+
+% Called from \indexdummies and \atdummies.  \definedummyword and
+% \definedummyletter must be defined first.
+%
+\def\commondummies{%
+  %
+  \normalturnoffactive
+  %
+  \commondummiesnofonts
+  %
+  \definedummyletter{_}%
+  %
+  % Non-English letters.
+  \definedummyword{AA}%
+  \definedummyword{AE}%
+  \definedummyword{L}%
+  \definedummyword{OE}%
+  \definedummyword{O}%
+  \definedummyword{aa}%
+  \definedummyword{ae}%
+  \definedummyword{l}%
+  \definedummyword{oe}%
+  \definedummyword{o}%
+  \definedummyword{ss}%
+  \definedummyword{exclamdown}%
+  \definedummyword{questiondown}%
+  \definedummyword{ordf}%
+  \definedummyword{ordm}%
+  %
+  % Although these internal commands shouldn't show up, sometimes they do.
+  \definedummyword{bf}%
+  \definedummyword{gtr}%
+  \definedummyword{hat}%
+  \definedummyword{less}%
+  \definedummyword{sf}%
+  \definedummyword{sl}%
+  \definedummyword{tclose}%
+  \definedummyword{tt}%
+  %
+  \definedummyword{LaTeX}%
+  \definedummyword{TeX}%
+  %
+  % Assorted special characters.
+  \definedummyword{bullet}%
+  \definedummyword{comma}%
+  \definedummyword{copyright}%
+  \definedummyword{registeredsymbol}%
+  \definedummyword{dots}%
+  \definedummyword{enddots}%
+  \definedummyword{equiv}%
+  \definedummyword{error}%
+  \definedummyword{euro}%
+  \definedummyword{expansion}%
+  \definedummyword{minus}%
+  \definedummyword{pounds}%
+  \definedummyword{point}%
+  \definedummyword{print}%
+  \definedummyword{result}%
+  %
+  % Handle some cases of @value -- where it does not contain any
+  % (non-fully-expandable) commands.
+  \makevalueexpandable
+  %
+  % Normal spaces, not active ones.
+  \unsepspaces
+  %
+  % No macro expansion.
+  \turnoffmacros
+}
+
+% \commondummiesnofonts: common to \commondummies and \indexnofonts.
+%
+% Better have this without active chars.
+{
+  \catcode`\~=\other
+  \gdef\commondummiesnofonts{%
+    % Control letters and accents.
+    \definedummyletter{!}%
+    \definedummyaccent{"}%
+    \definedummyaccent{'}%
+    \definedummyletter{*}%
+    \definedummyaccent{,}%
+    \definedummyletter{.}%
+    \definedummyletter{/}%
+    \definedummyletter{:}%
+    \definedummyaccent{=}%
+    \definedummyletter{?}%
+    \definedummyaccent{^}%
+    \definedummyaccent{`}%
+    \definedummyaccent{~}%
+    \definedummyword{u}%
+    \definedummyword{v}%
+    \definedummyword{H}%
+    \definedummyword{dotaccent}%
+    \definedummyword{ringaccent}%
+    \definedummyword{tieaccent}%
+    \definedummyword{ubaraccent}%
+    \definedummyword{udotaccent}%
+    \definedummyword{dotless}%
+    %
+    % Texinfo font commands.
+    \definedummyword{b}%
+    \definedummyword{i}%
+    \definedummyword{r}%
+    \definedummyword{sc}%
+    \definedummyword{t}%
+    %
+    % Commands that take arguments.
+    \definedummyword{acronym}%
+    \definedummyword{cite}%
+    \definedummyword{code}%
+    \definedummyword{command}%
+    \definedummyword{dfn}%
+    \definedummyword{emph}%
+    \definedummyword{env}%
+    \definedummyword{file}%
+    \definedummyword{kbd}%
+    \definedummyword{key}%
+    \definedummyword{math}%
+    \definedummyword{option}%
+    \definedummyword{samp}%
+    \definedummyword{strong}%
+    \definedummyword{tie}%
+    \definedummyword{uref}%
+    \definedummyword{url}%
+    \definedummyword{var}%
+    \definedummyword{verb}%
+    \definedummyword{w}%
+  }
+}
+
+% \indexnofonts is used when outputting the strings to sort the index
+% by, and when constructing control sequence names.  It eliminates all
+% control sequences and just writes whatever the best ASCII sort string
+% would be for a given command (usually its argument).
+%
+\def\indexnofonts{%
+  % Accent commands should become @asis.
+  \def\definedummyaccent##1{%
+    \expandafter\let\csname ##1\endcsname\asis
+  }%
+  % We can just ignore other control letters.
+  \def\definedummyletter##1{%
+    \expandafter\def\csname ##1\endcsname{}%
+  }%
+  % Hopefully, all control words can become @asis.
+  \let\definedummyword\definedummyaccent
+  %
+  \commondummiesnofonts
+  %
+  % Don't no-op \tt, since it isn't a user-level command
+  % and is used in the definitions of the active chars like <, >, |, etc.
+  % Likewise with the other plain tex font commands.
+  %\let\tt=\asis
+  %
+  \def\ { }%
+  \def\@{@}%
+  % how to handle braces?
+  \def\_{\normalunderscore}%
+  %
+  % Non-English letters.
+  \def\AA{AA}%
+  \def\AE{AE}%
+  \def\L{L}%
+  \def\OE{OE}%
+  \def\O{O}%
+  \def\aa{aa}%
+  \def\ae{ae}%
+  \def\l{l}%
+  \def\oe{oe}%
+  \def\o{o}%
+  \def\ss{ss}%
+  \def\exclamdown{!}%
+  \def\questiondown{?}%
+  \def\ordf{a}%
+  \def\ordm{o}%
+  %
+  \def\LaTeX{LaTeX}%
+  \def\TeX{TeX}%
+  %
+  % Assorted special characters.
+  % (The following {} will end up in the sort string, but that's ok.)
+  \def\bullet{bullet}%
+  \def\comma{,}%
+  \def\copyright{copyright}%
+  \def\registeredsymbol{R}%
+  \def\dots{...}%
+  \def\enddots{...}%
+  \def\equiv{==}%
+  \def\error{error}%
+  \def\euro{euro}%
+  \def\expansion{==>}%
+  \def\minus{-}%
+  \def\pounds{pounds}%
+  \def\point{.}%
+  \def\print{-|}%
+  \def\result{=>}%
+  %
+  % Don't write macro names.
+  \emptyusermacros
+}
+
+\let\indexbackslash=0  %overridden during \printindex.
+\let\SETmarginindex=\relax % put index entries in margin (undocumented)?
+
+% Most index entries go through here, but \dosubind is the general case.
+% #1 is the index name, #2 is the entry text.
+\def\doind#1#2{\dosubind{#1}{#2}{}}
+
+% Workhorse for all \fooindexes.
+% #1 is name of index, #2 is stuff to put there, #3 is subentry --
+% empty if called from \doind, as we usually are (the main exception
+% is with most defuns, which call us directly).
+%
+\def\dosubind#1#2#3{%
+  \iflinks
+  {%
+    % Store the main index entry text (including the third arg).
+    \toks0 = {#2}%
+    % If third arg is present, precede it with a space.
+    \def\thirdarg{#3}%
+    \ifx\thirdarg\empty \else
+      \toks0 = \expandafter{\the\toks0 \space #3}%
+    \fi
+    %
+    \edef\writeto{\csname#1indfile\endcsname}%
+    %
+    \ifvmode
+      \dosubindsanitize
+    \else
+      \dosubindwrite
+    \fi
+  }%
+  \fi
+}
+
+% Write the entry in \toks0 to the index file:
+%
+\def\dosubindwrite{%
+  % Put the index entry in the margin if desired.
+  \ifx\SETmarginindex\relax\else
+    \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}%
+  \fi
+  %
+  % Remember, we are within a group.
+  \indexdummies % Must do this here, since \bf, etc expand at this stage
+  \escapechar=`\\
+  \def\backslashcurfont{\indexbackslash}% \indexbackslash isn't defined now
+      % so it will be output as is; and it will print as backslash.
+  %
+  % Process the index entry with all font commands turned off, to
+  % get the string to sort by.
+  {\indexnofonts
+   \edef\temp{\the\toks0}% need full expansion
+   \xdef\indexsorttmp{\temp}%
+  }%
+  %
+  % Set up the complete index entry, with both the sort key and
+  % the original text, including any font commands.  We write
+  % three arguments to \entry to the .?? file (four in the
+  % subentry case), texindex reduces to two when writing the .??s
+  % sorted result.
+  \edef\temp{%
+    \write\writeto{%
+      \string\entry{\indexsorttmp}{\noexpand\folio}{\the\toks0}}%
+  }%
+  \temp
+}
+
+% Take care of unwanted page breaks:
+%
+% If a skip is the last thing on the list now, preserve it
+% by backing up by \lastskip, doing the \write, then inserting
+% the skip again.  Otherwise, the whatsit generated by the
+% \write will make \lastskip zero.  The result is that sequences
+% like this:
+% @end defun
+% @tindex whatever
+% @defun ...
+% will have extra space inserted, because the \medbreak in the
+% start of the @defun won't see the skip inserted by the @end of
+% the previous defun.
+%
+% But don't do any of this if we're not in vertical mode.  We
+% don't want to do a \vskip and prematurely end a paragraph.
+%
+% Avoid page breaks due to these extra skips, too.
+%
+% But wait, there is a catch there:
+% We'll have to check whether \lastskip is zero skip.  \ifdim is not
+% sufficient for this purpose, as it ignores stretch and shrink parts
+% of the skip.  The only way seems to be to check the textual
+% representation of the skip.
+%
+% The following is almost like \def\zeroskipmacro{0.0pt} except that
+% the ``p'' and ``t'' characters have catcode \other, not 11 (letter).
+%
+\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname}
+%
+% ..., ready, GO:
+%
+\def\dosubindsanitize{%
+  % \lastskip and \lastpenalty cannot both be nonzero simultaneously.
+  \skip0 = \lastskip
+  \edef\lastskipmacro{\the\lastskip}%
+  \count255 = \lastpenalty
+  %
+  % If \lastskip is nonzero, that means the last item was a
+  % skip.  And since a skip is discardable, that means this
+  % -\skip0 glue we're inserting is preceded by a
+  % non-discardable item, therefore it is not a potential
+  % breakpoint, therefore no \nobreak needed.
+  \ifx\lastskipmacro\zeroskipmacro
+  \else
+    \vskip-\skip0
+  \fi
+  %
+  \dosubindwrite
+  %
+  \ifx\lastskipmacro\zeroskipmacro
+    % If \lastskip was zero, perhaps the last item was a penalty, and
+    % perhaps it was >=10000, e.g., a \nobreak.  In that case, we want
+    % to re-insert the same penalty (values >10000 are used for various
+    % signals); since we just inserted a non-discardable item, any
+    % following glue (such as a \parskip) would be a breakpoint.  For example:
+    % 
+    %   @deffn deffn-whatever
+    %   @vindex index-whatever
+    %   Description.
+    % would allow a break between the index-whatever whatsit
+    % and the "Description." paragraph.
+    \ifnum\count255>9999 \penalty\count255 \fi
+  \else
+    % On the other hand, if we had a nonzero \lastskip,
+    % this make-up glue would be preceded by a non-discardable item
+    % (the whatsit from the \write), so we must insert a \nobreak.
+    \nobreak\vskip\skip0
+  \fi
+}
+
+% The index entry written in the file actually looks like
+%  \entry {sortstring}{page}{topic}
+% or
+%  \entry {sortstring}{page}{topic}{subtopic}
+% The texindex program reads in these files and writes files
+% containing these kinds of lines:
+%  \initial {c}
+%     before the first topic whose initial is c
+%  \entry {topic}{pagelist}
+%     for a topic that is used without subtopics
+%  \primary {topic}
+%     for the beginning of a topic that is used with subtopics
+%  \secondary {subtopic}{pagelist}
+%     for each subtopic.
+
+% Define the user-accessible indexing commands
+% @findex, @vindex, @kindex, @cindex.
+
+\def\findex {\fnindex}
+\def\kindex {\kyindex}
+\def\cindex {\cpindex}
+\def\vindex {\vrindex}
+\def\tindex {\tpindex}
+\def\pindex {\pgindex}
+
+\def\cindexsub {\begingroup\obeylines\cindexsub}
+{\obeylines %
+\gdef\cindexsub "#1" #2^^M{\endgroup %
+\dosubind{cp}{#2}{#1}}}
+
+% Define the macros used in formatting output of the sorted index material.
+
+% @printindex causes a particular index (the ??s file) to get printed.
+% It does not print any chapter heading (usually an @unnumbered).
+%
+\parseargdef\printindex{\begingroup
+  \dobreak \chapheadingskip{10000}%
+  %
+  \smallfonts \rm
+  \tolerance = 9500
+  \everypar = {}% don't want the \kern\-parindent from indentation suppression.
+  %
+  % See if the index file exists and is nonempty.
+  % Change catcode of @ here so that if the index file contains
+  % \initial {@}
+  % as its first line, TeX doesn't complain about mismatched braces
+  % (because it thinks @} is a control sequence).
+  \catcode`\@ = 11
+  \openin 1 \jobname.#1s
+  \ifeof 1
+    % \enddoublecolumns gets confused if there is no text in the index,
+    % and it loses the chapter title and the aux file entries for the
+    % index.  The easiest way to prevent this problem is to make sure
+    % there is some text.
+    \putwordIndexNonexistent
+  \else
+    %
+    % If the index file exists but is empty, then \openin leaves \ifeof
+    % false.  We have to make TeX try to read something from the file, so
+    % it can discover if there is anything in it.
+    \read 1 to \temp
+    \ifeof 1
+      \putwordIndexIsEmpty
+    \else
+      % Index files are almost Texinfo source, but we use \ as the escape
+      % character.  It would be better to use @, but that's too big a change
+      % to make right now.
+      \def\indexbackslash{\backslashcurfont}%
+      \catcode`\\ = 0
+      \escapechar = `\\
+      \begindoublecolumns
+      \input \jobname.#1s
+      \enddoublecolumns
+    \fi
+  \fi
+  \closein 1
+\endgroup}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+\def\initial#1{{%
+  % Some minor font changes for the special characters.
+  \let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+  %
+  % Remove any glue we may have, we'll be inserting our own.
+  \removelastskip
+  %
+  % We like breaks before the index initials, so insert a bonus.
+  \nobreak
+  \vskip 0pt plus 3\baselineskip
+  \penalty 0
+  \vskip 0pt plus -3\baselineskip
+  %
+  % Typeset the initial.  Making this add up to a whole number of
+  % baselineskips increases the chance of the dots lining up from column
+  % to column.  It still won't often be perfect, because of the stretch
+  % we need before each entry, but it's better.
+  %
+  % No shrink because it confuses \balancecolumns.
+  \vskip 1.67\baselineskip plus .5\baselineskip
+  \leftline{\secbf #1}%
+  % Do our best not to break after the initial.
+  \nobreak
+  \vskip .33\baselineskip plus .1\baselineskip
+}}
+
+% \entry typesets a paragraph consisting of the text (#1), dot leaders, and
+% then page number (#2) flushed to the right margin.  It is used for index
+% and table of contents entries.  The paragraph is indented by \leftskip.
+%
+% A straightforward implementation would start like this:
+%	\def\entry#1#2{...
+% But this frozes the catcodes in the argument, and can cause problems to
+% @code, which sets - active.  This problem was fixed by a kludge---
+% ``-'' was active throughout whole index, but this isn't really right.
+%
+% The right solution is to prevent \entry from swallowing the whole text.
+%                                 --kasal, 21nov03
+\def\entry{%
+  \begingroup
+    %
+    % Start a new paragraph if necessary, so our assignments below can't
+    % affect previous text.
+    \par
+    %
+    % Do not fill out the last line with white space.
+    \parfillskip = 0in
+    %
+    % No extra space above this paragraph.
+    \parskip = 0in
+    %
+    % Do not prefer a separate line ending with a hyphen to fewer lines.
+    \finalhyphendemerits = 0
+    %
+    % \hangindent is only relevant when the entry text and page number
+    % don't both fit on one line.  In that case, bob suggests starting the
+    % dots pretty far over on the line.  Unfortunately, a large
+    % indentation looks wrong when the entry text itself is broken across
+    % lines.  So we use a small indentation and put up with long leaders.
+    %
+    % \hangafter is reset to 1 (which is the value we want) at the start
+    % of each paragraph, so we need not do anything with that.
+    \hangindent = 2em
+    %
+    % When the entry text needs to be broken, just fill out the first line
+    % with blank space.
+    \rightskip = 0pt plus1fil
+    %
+    % A bit of stretch before each entry for the benefit of balancing
+    % columns.
+    \vskip 0pt plus1pt
+    %
+    % Swallow the left brace of the text (first parameter):
+    \afterassignment\doentry
+    \let\temp =
+}
+\def\doentry{%
+    \bgroup % Instead of the swallowed brace.
+      \noindent
+      \aftergroup\finishentry
+      % And now comes the text of the entry.
+}
+\def\finishentry#1{%
+    % #1 is the page number.
+    %
+    % The following is kludged to not output a line of dots in the index if
+    % there are no page numbers.  The next person who breaks this will be
+    % cursed by a Unix daemon.
+    \def\tempa{{\rm }}%
+    \def\tempb{#1}%
+    \edef\tempc{\tempa}%
+    \edef\tempd{\tempb}%
+    \ifx\tempc\tempd
+      \ %
+    \else
+      %
+      % If we must, put the page number on a line of its own, and fill out
+      % this line with blank space.  (The \hfil is overwhelmed with the
+      % fill leaders glue in \indexdotfill if the page number does fit.)
+      \hfil\penalty50
+      \null\nobreak\indexdotfill % Have leaders before the page number.
+      %
+      % The `\ ' here is removed by the implicit \unskip that TeX does as
+      % part of (the primitive) \par.  Without it, a spurious underfull
+      % \hbox ensues.
+      \ifpdf
+	\pdfgettoks#1.%
+	\ \the\toksA
+      \else
+	\ #1%
+      \fi
+    \fi
+    \par
+  \endgroup
+}
+
+% Like \dotfill except takes at least 1 em.
+\def\indexdotfill{\cleaders
+  \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill}
+
+\def\primary #1{\line{#1\hfil}}
+
+\newskip\secondaryindent \secondaryindent=0.5cm
+\def\secondary#1#2{{%
+  \parfillskip=0in
+  \parskip=0in
+  \hangindent=1in
+  \hangafter=1
+  \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill
+  \ifpdf
+    \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph.
+  \else
+    #2
+  \fi
+  \par
+}}
+
+% Define two-column mode, which we use to typeset indexes.
+% Adapted from the TeXbook, page 416, which is to say,
+% the manmac.tex format used to print the TeXbook itself.
+\catcode`\@=11
+
+\newbox\partialpage
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns
+  % Grab any single-column material above us.
+  \output = {%
+    %
+    % Here is a possibility not foreseen in manmac: if we accumulate a
+    % whole lot of material, we might end up calling this \output
+    % routine twice in a row (see the doublecol-lose test, which is
+    % essentially a couple of indexes with @setchapternewpage off).  In
+    % that case we just ship out what is in \partialpage with the normal
+    % output routine.  Generally, \partialpage will be empty when this
+    % runs and this will be a no-op.  See the indexspread.tex test case.
+    \ifvoid\partialpage \else
+      \onepageout{\pagecontents\partialpage}%
+    \fi
+    %
+    \global\setbox\partialpage = \vbox{%
+      % Unvbox the main output page.
+      \unvbox\PAGE
+      \kern-\topskip \kern\baselineskip
+    }%
+  }%
+  \eject % run that output routine to set \partialpage
+  %
+  % Use the double-column output routine for subsequent pages.
+  \output = {\doublecolumnout}%
+  %
+  % Change the page size parameters.  We could do this once outside this
+  % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+  % format, but then we repeat the same computation.  Repeating a couple
+  % of assignments once per index is clearly meaningless for the
+  % execution time, so we may as well do it in one place.
+  %
+  % First we halve the line length, less a little for the gutter between
+  % the columns.  We compute the gutter based on the line length, so it
+  % changes automatically with the paper format.  The magic constant
+  % below is chosen so that the gutter has the same value (well, +-<1pt)
+  % as it did when we hard-coded it.
+  %
+  % We put the result in a separate register, \doublecolumhsize, so we
+  % can restore it in \pagesofar, after \hsize itself has (potentially)
+  % been clobbered.
+  %
+  \doublecolumnhsize = \hsize
+    \advance\doublecolumnhsize by -.04154\hsize
+    \divide\doublecolumnhsize by 2
+  \hsize = \doublecolumnhsize
+  %
+  % Double the \vsize as well.  (We don't need a separate register here,
+  % since nobody clobbers \vsize.)
+  \vsize = 2\vsize
+}
+
+% The double-column output routine for all double-column pages except
+% the last.
+%
+\def\doublecolumnout{%
+  \splittopskip=\topskip \splitmaxdepth=\maxdepth
+  % Get the available space for the double columns -- the normal
+  % (undoubled) page height minus any material left over from the
+  % previous page.
+  \dimen@ = \vsize
+  \divide\dimen@ by 2
+  \advance\dimen@ by -\ht\partialpage
+  %
+  % box0 will be the left-hand column, box2 the right.
+  \setbox0=\vsplit255 to\dimen@ \setbox2=\vsplit255 to\dimen@
+  \onepageout\pagesofar
+  \unvbox255
+  \penalty\outputpenalty
+}
+%
+% Re-output the contents of the output page -- any previous material,
+% followed by the two boxes we just split, in box0 and box2.
+\def\pagesofar{%
+  \unvbox\partialpage
+  %
+  \hsize = \doublecolumnhsize
+  \wd0=\hsize \wd2=\hsize
+  \hbox to\pagewidth{\box0\hfil\box2}%
+}
+%
+% All done with double columns.
+\def\enddoublecolumns{%
+  \output = {%
+    % Split the last of the double-column material.  Leave it on the
+    % current page, no automatic page break.
+    \balancecolumns
+    %
+    % If we end up splitting too much material for the current page,
+    % though, there will be another page break right after this \output
+    % invocation ends.  Having called \balancecolumns once, we do not
+    % want to call it again.  Therefore, reset \output to its normal
+    % definition right away.  (We hope \balancecolumns will never be
+    % called on to balance too much material, but if it is, this makes
+    % the output somewhat more palatable.)
+    \global\output = {\onepageout{\pagecontents\PAGE}}%
+  }%
+  \eject
+  \endgroup % started in \begindoublecolumns
+  %
+  % \pagegoal was set to the doubled \vsize above, since we restarted
+  % the current page.  We're now back to normal single-column
+  % typesetting, so reset \pagegoal to the normal \vsize (after the
+  % \endgroup where \vsize got restored).
+  \pagegoal = \vsize
+}
+%
+% Called at the end of the double column material.
+\def\balancecolumns{%
+  \setbox0 = \vbox{\unvbox255}% like \box255 but more efficient, see p.120.
+  \dimen@ = \ht0
+  \advance\dimen@ by \topskip
+  \advance\dimen@ by-\baselineskip
+  \divide\dimen@ by 2 % target to split to
+  %debug\message{final 2-column material height=\the\ht0, target=\the\dimen@.}%
+  \splittopskip = \topskip
+  % Loop until we get a decent breakpoint.
+  {%
+    \vbadness = 10000
+    \loop
+      \global\setbox3 = \copy0
+      \global\setbox1 = \vsplit3 to \dimen@
+    \ifdim\ht3>\dimen@
+      \global\advance\dimen@ by 1pt
+    \repeat
+  }%
+  %debug\message{split to \the\dimen@, column heights: \the\ht1, \the\ht3.}%
+  \setbox0=\vbox to\dimen@{\unvbox1}%
+  \setbox2=\vbox to\dimen@{\unvbox3}%
+  %
+  \pagesofar
+}
+\catcode`\@ = \other
+
+
+\message{sectioning,}
+% Chapters, sections, etc.
+
+% \unnumberedno is an oxymoron, of course.  But we count the unnumbered
+% sections so that we can refer to them unambiguously in the pdf
+% outlines by their "section number".  We avoid collisions with chapter
+% numbers by starting them at 10000.  (If a document ever has 10000
+% chapters, we're in trouble anyway, I'm sure.)
+\newcount\unnumberedno \unnumberedno = 10000
+\newcount\chapno
+\newcount\secno        \secno=0
+\newcount\subsecno     \subsecno=0
+\newcount\subsubsecno  \subsubsecno=0
+
+% This counter is funny since it counts through charcodes of letters A, B, ...
+\newcount\appendixno  \appendixno = `\@
+%
+% \def\appendixletter{\char\the\appendixno}
+% We do the following ugly conditional instead of the above simple
+% construct for the sake of pdftex, which needs the actual
+% letter in the expansion, not just typeset.
+%
+\def\appendixletter{%
+  \ifnum\appendixno=`A A%
+  \else\ifnum\appendixno=`B B%
+  \else\ifnum\appendixno=`C C%
+  \else\ifnum\appendixno=`D D%
+  \else\ifnum\appendixno=`E E%
+  \else\ifnum\appendixno=`F F%
+  \else\ifnum\appendixno=`G G%
+  \else\ifnum\appendixno=`H H%
+  \else\ifnum\appendixno=`I I%
+  \else\ifnum\appendixno=`J J%
+  \else\ifnum\appendixno=`K K%
+  \else\ifnum\appendixno=`L L%
+  \else\ifnum\appendixno=`M M%
+  \else\ifnum\appendixno=`N N%
+  \else\ifnum\appendixno=`O O%
+  \else\ifnum\appendixno=`P P%
+  \else\ifnum\appendixno=`Q Q%
+  \else\ifnum\appendixno=`R R%
+  \else\ifnum\appendixno=`S S%
+  \else\ifnum\appendixno=`T T%
+  \else\ifnum\appendixno=`U U%
+  \else\ifnum\appendixno=`V V%
+  \else\ifnum\appendixno=`W W%
+  \else\ifnum\appendixno=`X X%
+  \else\ifnum\appendixno=`Y Y%
+  \else\ifnum\appendixno=`Z Z%
+  % The \the is necessary, despite appearances, because \appendixletter is
+  % expanded while writing the .toc file.  \char\appendixno is not
+  % expandable, thus it is written literally, thus all appendixes come out
+  % with the same letter (or @) in the toc without it.
+  \else\char\the\appendixno
+  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi
+  \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
+
+% Each @chapter defines this as the name of the chapter.
+% page headings and footings can use it.  @section does likewise.
+% However, they are not reliable, because we don't use marks.
+\def\thischapter{}
+\def\thissection{}
+
+\newcount\absseclevel % used to calculate proper heading level
+\newcount\secbase\secbase=0 % @raisesections/@lowersections modify this count
+
+% @raisesections: treat @section as chapter, @subsection as section, etc.
+\def\raisesections{\global\advance\secbase by -1}
+\let\up=\raisesections % original BFox name
+
+% @lowersections: treat @chapter as section, @section as subsection, etc.
+\def\lowersections{\global\advance\secbase by 1}
+\let\down=\lowersections % original BFox name
+
+% we only have subsub.
+\chardef\maxseclevel = 3
+%
+% A numbered section within an unnumbered changes to unnumbered too.
+% To achive this, remember the "biggest" unnum. sec. we are currently in:
+\chardef\unmlevel = \maxseclevel
+%
+% Trace whether the current chapter is an appendix or not:
+% \chapheadtype is "N" or "A", unnumbered chapters are ignored.
+\def\chapheadtype{N}
+
+% Choose a heading macro
+% #1 is heading type
+% #2 is heading level
+% #3 is text for heading
+\def\genhead#1#2#3{%
+  % Compute the abs. sec. level:
+  \absseclevel=#2
+  \advance\absseclevel by \secbase
+  % Make sure \absseclevel doesn't fall outside the range:
+  \ifnum \absseclevel < 0
+    \absseclevel = 0
+  \else
+    \ifnum \absseclevel > 3
+      \absseclevel = 3
+    \fi
+  \fi
+  % The heading type:
+  \def\headtype{#1}%
+  \if \headtype U%
+    \ifnum \absseclevel < \unmlevel
+      \chardef\unmlevel = \absseclevel
+    \fi
+  \else
+    % Check for appendix sections:
+    \ifnum \absseclevel = 0
+      \edef\chapheadtype{\headtype}%
+    \else
+      \if \headtype A\if \chapheadtype N%
+	\errmessage{@appendix... within a non-appendix chapter}%
+      \fi\fi
+    \fi
+    % Check for numbered within unnumbered:
+    \ifnum \absseclevel > \unmlevel
+      \def\headtype{U}%
+    \else
+      \chardef\unmlevel = 3
+    \fi
+  \fi
+  % Now print the heading:
+  \if \headtype U%
+    \ifcase\absseclevel
+	\unnumberedzzz{#3}%
+    \or \unnumberedseczzz{#3}%
+    \or \unnumberedsubseczzz{#3}%
+    \or \unnumberedsubsubseczzz{#3}%
+    \fi
+  \else
+    \if \headtype A%
+      \ifcase\absseclevel
+	  \appendixzzz{#3}%
+      \or \appendixsectionzzz{#3}%
+      \or \appendixsubseczzz{#3}%
+      \or \appendixsubsubseczzz{#3}%
+      \fi
+    \else
+      \ifcase\absseclevel
+	  \chapterzzz{#3}%
+      \or \seczzz{#3}%
+      \or \numberedsubseczzz{#3}%
+      \or \numberedsubsubseczzz{#3}%
+      \fi
+    \fi
+  \fi
+  \suppressfirstparagraphindent
+}
+
+% an interface:
+\def\numhead{\genhead N}
+\def\apphead{\genhead A}
+\def\unnmhead{\genhead U}
+
+% @chapter, @appendix, @unnumbered.  Increment top-level counter, reset
+% all lower-level sectioning counters to zero.
+%
+% Also set \chaplevelprefix, which we prepend to @float sequence numbers
+% (e.g., figures), q.v.  By default (before any chapter), that is empty.
+\let\chaplevelprefix = \empty
+%
+\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz#1{%
+  % section resetting is \global in case the chapter is in a group, such
+  % as an @include file.
+  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+    \global\advance\chapno by 1
+  %
+  % Used for \float.
+  \gdef\chaplevelprefix{\the\chapno.}%
+  \resetallfloatnos
+  %
+  \message{\putwordChapter\space \the\chapno}%
+  %
+  % Write the actual heading.
+  \chapmacro{#1}{Ynumbered}{\the\chapno}%
+  %
+  % So @section and the like are numbered underneath this chapter.
+  \global\let\section = \numberedsec
+  \global\let\subsection = \numberedsubsec
+  \global\let\subsubsection = \numberedsubsubsec
+}
+
+\outer\parseargdef\appendix{\apphead0{#1}} % normally apphead0 calls appendixzzz
+\def\appendixzzz#1{%
+  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+    \global\advance\appendixno by 1
+  \gdef\chaplevelprefix{\appendixletter.}%
+  \resetallfloatnos
+  %
+  \def\appendixnum{\putwordAppendix\space \appendixletter}%
+  \message{\appendixnum}%
+  %
+  \chapmacro{#1}{Yappendix}{\appendixletter}%
+  %
+  \global\let\section = \appendixsec
+  \global\let\subsection = \appendixsubsec
+  \global\let\subsubsection = \appendixsubsubsec
+}
+
+\outer\parseargdef\unnumbered{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+\def\unnumberedzzz#1{%
+  \global\secno=0 \global\subsecno=0 \global\subsubsecno=0
+    \global\advance\unnumberedno by 1
+  %
+  % Since an unnumbered has no number, no prefix for figures.
+  \global\let\chaplevelprefix = \empty
+  \resetallfloatnos
+  %
+  % This used to be simply \message{#1}, but TeX fully expands the
+  % argument to \message.  Therefore, if #1 contained @-commands, TeX
+  % expanded them.  For example, in `@unnumbered The @cite{Book}', TeX
+  % expanded @cite (which turns out to cause errors because \cite is meant
+  % to be executed, not expanded).
+  %
+  % Anyway, we don't want the fully-expanded definition of @cite to appear
+  % as a result of the \message, we just want `@cite' itself.  We use
+  % \the<toks register> to achieve this: TeX expands \the<toks> only once,
+  % simply yielding the contents of <toks register>.  (We also do this for
+  % the toc entries.)
+  \toks0 = {#1}%
+  \message{(\the\toks0)}%
+  %
+  \chapmacro{#1}{Ynothing}{\the\unnumberedno}%
+  %
+  \global\let\section = \unnumberedsec
+  \global\let\subsection = \unnumberedsubsec
+  \global\let\subsubsection = \unnumberedsubsubsec
+}
+
+% @centerchap is like @unnumbered, but the heading is centered.
+\outer\parseargdef\centerchap{%
+  % Well, we could do the following in a group, but that would break
+  % an assumption that \chapmacro is called at the outermost level.
+  % Thus we are safer this way:		--kasal, 24feb04
+  \let\centerparametersmaybe = \centerparameters
+  \unnmhead0{#1}%
+  \let\centerparametersmaybe = \relax
+}
+
+% @top is like @unnumbered.
+\let\top\unnumbered
+
+% Sections.
+\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz
+\def\seczzz#1{%
+  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
+  \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}%
+}
+
+\outer\parseargdef\appendixsection{\apphead1{#1}} % normally calls appendixsectionzzz
+\def\appendixsectionzzz#1{%
+  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
+  \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}%
+}
+\let\appendixsec\appendixsection
+
+\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} % normally calls unnumberedseczzz
+\def\unnumberedseczzz#1{%
+  \global\subsecno=0 \global\subsubsecno=0  \global\advance\secno by 1
+  \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}%
+}
+
+% Subsections.
+\outer\parseargdef\numberedsubsec{\numhead2{#1}} % normally calls numberedsubseczzz
+\def\numberedsubseczzz#1{%
+  \global\subsubsecno=0  \global\advance\subsecno by 1
+  \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}%
+}
+
+\outer\parseargdef\appendixsubsec{\apphead2{#1}} % normally calls appendixsubseczzz
+\def\appendixsubseczzz#1{%
+  \global\subsubsecno=0  \global\advance\subsecno by 1
+  \sectionheading{#1}{subsec}{Yappendix}%
+                 {\appendixletter.\the\secno.\the\subsecno}%
+}
+
+\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+\def\unnumberedsubseczzz#1{%
+  \global\subsubsecno=0  \global\advance\subsecno by 1
+  \sectionheading{#1}{subsec}{Ynothing}%
+                 {\the\unnumberedno.\the\secno.\the\subsecno}%
+}
+
+% Subsubsections.
+\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} % normally numberedsubsubseczzz
+\def\numberedsubsubseczzz#1{%
+  \global\advance\subsubsecno by 1
+  \sectionheading{#1}{subsubsec}{Ynumbered}%
+                 {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} % normally appendixsubsubseczzz
+\def\appendixsubsubseczzz#1{%
+  \global\advance\subsubsecno by 1
+  \sectionheading{#1}{subsubsec}{Yappendix}%
+                 {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+\def\unnumberedsubsubseczzz#1{%
+  \global\advance\subsubsecno by 1
+  \sectionheading{#1}{subsubsec}{Ynothing}%
+                 {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}%
+}
+
+% These macros control what the section commands do, according
+% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+% Define them by default for a numbered chapter.
+\let\section = \numberedsec
+\let\subsection = \numberedsubsec
+\let\subsubsection = \numberedsubsubsec
+
+% Define @majorheading, @heading and @subheading
+
+% NOTE on use of \vbox for chapter headings, section headings, and such:
+%       1) We use \vbox rather than the earlier \line to permit
+%          overlong headings to fold.
+%       2) \hyphenpenalty is set to 10000 because hyphenation in a
+%          heading is obnoxious; this forbids it.
+%       3) Likewise, headings look best if no \parindent is used, and
+%          if justification is not attempted.  Hence \raggedright.
+
+
+\def\majorheading{%
+  {\advance\chapheadingskip by 10pt \chapbreak }%
+  \parsearg\chapheadingzzz
+}
+
+\def\chapheading{\chapbreak \parsearg\chapheadingzzz}
+\def\chapheadingzzz#1{%
+  {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                    \parindent=0pt\raggedright
+                    \rm #1\hfill}}%
+  \bigskip \par\penalty 200\relax
+  \suppressfirstparagraphindent
+}
+
+% @heading, @subheading, @subsubheading.
+\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{}
+  \suppressfirstparagraphindent}
+\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{}
+  \suppressfirstparagraphindent}
+\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{}
+  \suppressfirstparagraphindent}
+
+% These macros generate a chapter, section, etc. heading only
+% (including whitespace, linebreaking, etc. around it),
+% given all the information in convenient, parsed form.
+
+%%% Args are the skip and penalty (usually negative)
+\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+
+%%% Define plain chapter starts, and page on/off switching for it
+% Parameter controlling skip before chapter headings (if needed)
+
+\newskip\chapheadingskip
+
+\def\chapbreak{\dobreak \chapheadingskip {-4000}}
+\def\chappager{\par\vfill\supereject}
+\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi}
+
+\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+
+\def\CHAPPAGoff{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{%
+\global\let\contentsalignmacro = \chappager
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{%
+\global\let\contentsalignmacro = \chapoddpage
+\global\let\pchapsepmacro=\chapoddpage
+\global\let\pagealignmacro=\chapoddpage
+\global\def\HEADINGSon{\HEADINGSdouble}}
+
+\CHAPPAGon
+
+% Chapter opening.
+%
+% #1 is the text, #2 is the section type (Ynumbered, Ynothing,
+% Yappendix, Yomitfromtoc), #3 the chapter number.
+%
+% To test against our argument.
+\def\Ynothingkeyword{Ynothing}
+\def\Yomitfromtockeyword{Yomitfromtoc}
+\def\Yappendixkeyword{Yappendix}
+%
+\def\chapmacro#1#2#3{%
+  \pchapsepmacro
+  {%
+    \chapfonts \rm
+    %
+    % Have to define \thissection before calling \donoderef, because the
+    % xref code eventually uses it.  On the other hand, it has to be called
+    % after \pchapsepmacro, or the headline will change too soon.
+    \gdef\thissection{#1}%
+    \gdef\thischaptername{#1}%
+    %
+    % Only insert the separating space if we have a chapter/appendix
+    % number, and don't print the unnumbered ``number''.
+    \def\temptype{#2}%
+    \ifx\temptype\Ynothingkeyword
+      \setbox0 = \hbox{}%
+      \def\toctype{unnchap}%
+      \def\thischapter{#1}%
+    \else\ifx\temptype\Yomitfromtockeyword
+      \setbox0 = \hbox{}% contents like unnumbered, but no toc entry
+      \def\toctype{omit}%
+      \xdef\thischapter{}%
+    \else\ifx\temptype\Yappendixkeyword
+      \setbox0 = \hbox{\putwordAppendix{} #3\enspace}%
+      \def\toctype{app}%
+      % We don't substitute the actual chapter name into \thischapter
+      % because we don't want its macros evaluated now.  And we don't
+      % use \thissection because that changes with each section.
+      %
+      \xdef\thischapter{\putwordAppendix{} \appendixletter:
+                        \noexpand\thischaptername}%
+    \else
+      \setbox0 = \hbox{#3\enspace}%
+      \def\toctype{numchap}%
+      \xdef\thischapter{\putwordChapter{} \the\chapno:
+                        \noexpand\thischaptername}%
+    \fi\fi\fi
+    %
+    % Write the toc entry for this chapter.  Must come before the
+    % \donoderef, because we include the current node name in the toc
+    % entry, and \donoderef resets it to empty.
+    \writetocentry{\toctype}{#1}{#3}%
+    %
+    % For pdftex, we have to write out the node definition (aka, make
+    % the pdfdest) after any page break, but before the actual text has
+    % been typeset.  If the destination for the pdf outline is after the
+    % text, then jumping from the outline may wind up with the text not
+    % being visible, for instance under high magnification.
+    \donoderef{#2}%
+    %
+    % Typeset the actual heading.
+    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+          \hangindent=\wd0 \centerparametersmaybe
+          \unhbox0 #1\par}%
+  }%
+  \nobreak\bigskip % no page break after a chapter title
+  \nobreak
+}
+
+% @centerchap -- centered and unnumbered.
+\let\centerparametersmaybe = \relax
+\def\centerparameters{%
+  \advance\rightskip by 3\rightskip
+  \leftskip = \rightskip
+  \parfillskip = 0pt
+}
+
+
+% I don't think this chapter style is supported any more, so I'm not
+% updating it with the new noderef stuff.  We'll see.  --karl, 11aug03.
+%
+\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+%
+\def\unnchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                       \parindent=0pt\raggedright
+                       \rm #1\hfill}}\bigskip \par\nobreak
+}
+\def\chfopen #1#2{\chapoddpage {\chapfonts
+\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+\par\penalty 5000 %
+}
+\def\centerchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+                       \parindent=0pt
+                       \hfill {\rm #1}\hfill}}\bigskip \par\nobreak
+}
+\def\CHAPFopen{%
+  \global\let\chapmacro=\chfopen
+  \global\let\centerchapmacro=\centerchfopen}
+
+
+% Section titles.  These macros combine the section number parts and
+% call the generic \sectionheading to do the printing.
+%
+\newskip\secheadingskip
+\def\secheadingbreak{\dobreak \secheadingskip{-1000}}
+
+% Subsection titles.
+\newskip\subsecheadingskip
+\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}}
+
+% Subsubsection titles.
+\def\subsubsecheadingskip{\subsecheadingskip}
+\def\subsubsecheadingbreak{\subsecheadingbreak}
+
+
+% Print any size, any type, section title.
+%
+% #1 is the text, #2 is the section level (sec/subsec/subsubsec), #3 is
+% the section type for xrefs (Ynumbered, Ynothing, Yappendix), #4 is the
+% section number.
+%
+\def\sectionheading#1#2#3#4{%
+  {%
+    % Switch to the right set of fonts.
+    \csname #2fonts\endcsname \rm
+    %
+    % Insert space above the heading.
+    \csname #2headingbreak\endcsname
+    %
+    % Only insert the space after the number if we have a section number.
+    \def\sectionlevel{#2}%
+    \def\temptype{#3}%
+    %
+    \ifx\temptype\Ynothingkeyword
+      \setbox0 = \hbox{}%
+      \def\toctype{unn}%
+      \gdef\thissection{#1}%
+    \else\ifx\temptype\Yomitfromtockeyword
+      % for @headings -- no section number, don't include in toc,
+      % and don't redefine \thissection.
+      \setbox0 = \hbox{}%
+      \def\toctype{omit}%
+      \let\sectionlevel=\empty
+    \else\ifx\temptype\Yappendixkeyword
+      \setbox0 = \hbox{#4\enspace}%
+      \def\toctype{app}%
+      \gdef\thissection{#1}%
+    \else
+      \setbox0 = \hbox{#4\enspace}%
+      \def\toctype{num}%
+      \gdef\thissection{#1}%
+    \fi\fi\fi
+    %
+    % Write the toc entry (before \donoderef).  See comments in \chfplain.
+    \writetocentry{\toctype\sectionlevel}{#1}{#4}%
+    %
+    % Write the node reference (= pdf destination for pdftex).
+    % Again, see comments in \chfplain.
+    \donoderef{#3}%
+    %
+    % Output the actual section heading.
+    \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \raggedright
+          \hangindent=\wd0  % zero if no section number
+          \unhbox0 #1}%
+  }%
+  % Add extra space after the heading -- half of whatever came above it.
+  % Don't allow stretch, though.
+  \kern .5 \csname #2headingskip\endcsname
+  %
+  % Do not let the kern be a potential breakpoint, as it would be if it
+  % was followed by glue.
+  \nobreak
+  %
+  % We'll almost certainly start a paragraph next, so don't let that
+  % glue accumulate.  (Not a breakpoint because it's preceded by a
+  % discardable item.)
+  \vskip-\parskip
+  % 
+  % This is purely so the last item on the list is a known \penalty >
+  % 10000.  This is so \startdefun can avoid allowing breakpoints after
+  % section headings.  Otherwise, it would insert a valid breakpoint between:
+  % 
+  %   @section sec-whatever
+  %   @deffn def-whatever
+  \penalty 10001
+}
+
+
+\message{toc,}
+% Table of contents.
+\newwrite\tocfile
+
+% Write an entry to the toc file, opening it if necessary.
+% Called from @chapter, etc.
+%
+% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno}
+% We append the current node name (if any) and page number as additional
+% arguments for the \{chap,sec,...}entry macros which will eventually
+% read this.  The node name is used in the pdf outlines as the
+% destination to jump to.
+%
+% We open the .toc file for writing here instead of at @setfilename (or
+% any other fixed time) so that @contents can be anywhere in the document.
+% But if #1 is `omit', then we don't do anything.  This is used for the
+% table of contents chapter openings themselves.
+%
+\newif\iftocfileopened
+\def\omitkeyword{omit}%
+%
+\def\writetocentry#1#2#3{%
+  \edef\writetoctype{#1}%
+  \ifx\writetoctype\omitkeyword \else
+    \iftocfileopened\else
+      \immediate\openout\tocfile = \jobname.toc
+      \global\tocfileopenedtrue
+    \fi
+    %
+    \iflinks
+      \toks0 = {#2}%
+      \toks2 = \expandafter{\lastnode}%
+      \edef\temp{\write\tocfile{\realbackslash #1entry{\the\toks0}{#3}%
+                               {\the\toks2}{\noexpand\folio}}}%
+      \temp
+    \fi
+  \fi
+  %
+  % Tell \shipout to create a pdf destination on each page, if we're
+  % writing pdf.  These are used in the table of contents.  We can't
+  % just write one on every page because the title pages are numbered
+  % 1 and 2 (the page numbers aren't printed), and so are the first
+  % two pages of the document.  Thus, we'd have two destinations named
+  % `1', and two named `2'.
+  \ifpdf \global\pdfmakepagedesttrue \fi
+}
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\newcount\savepageno
+\newcount\lastnegativepageno \lastnegativepageno = -1
+
+% Prepare to read what we've written to \tocfile.
+%
+\def\startcontents#1{%
+  % If @setchapternewpage on, and @headings double, the contents should
+  % start on an odd page, unlike chapters.  Thus, we maintain
+  % \contentsalignmacro in parallel with \pagealignmacro.
+  % From: Torbjorn Granlund <tege@matematik.su.se>
+  \contentsalignmacro
+  \immediate\closeout\tocfile
+  %
+  % Don't need to put `Contents' or `Short Contents' in the headline.
+  % It is abundantly clear what they are.
+  \def\thischapter{}%
+  \chapmacro{#1}{Yomitfromtoc}{}%
+  %
+  \savepageno = \pageno
+  \begingroup                  % Set up to handle contents files properly.
+    \catcode`\\=0  \catcode`\{=1  \catcode`\}=2  \catcode`\@=11
+    % We can't do this, because then an actual ^ in a section
+    % title fails, e.g., @chapter ^ -- exponentiation.  --karl, 9jul97.
+    %\catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi
+    \raggedbottom             % Worry more about breakpoints than the bottom.
+    \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+    %
+    % Roman numerals for page numbers.
+    \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi
+}
+
+
+% Normal (long) toc.
+\def\contents{%
+  \startcontents{\putwordTOC}%
+    \openin 1 \jobname.toc
+    \ifeof 1 \else
+      \input \jobname.toc
+    \fi
+    \vfill \eject
+    \contentsalignmacro % in case @setchapternewpage odd is in effect
+    \ifeof 1 \else
+      \pdfmakeoutlines
+    \fi
+    \closein 1
+  \endgroup
+  \lastnegativepageno = \pageno
+  \global\pageno = \savepageno
+}
+
+% And just the chapters.
+\def\summarycontents{%
+  \startcontents{\putwordShortTOC}%
+    %
+    \let\numchapentry = \shortchapentry
+    \let\appentry = \shortchapentry
+    \let\unnchapentry = \shortunnchapentry
+    % We want a true roman here for the page numbers.
+    \secfonts
+    \let\rm=\shortcontrm \let\bf=\shortcontbf
+    \let\sl=\shortcontsl \let\tt=\shortconttt
+    \rm
+    \hyphenpenalty = 10000
+    \advance\baselineskip by 1pt % Open it up a little.
+    \def\numsecentry##1##2##3##4{}
+    \let\appsecentry = \numsecentry
+    \let\unnsecentry = \numsecentry
+    \let\numsubsecentry = \numsecentry
+    \let\appsubsecentry = \numsecentry
+    \let\unnsubsecentry = \numsecentry
+    \let\numsubsubsecentry = \numsecentry
+    \let\appsubsubsecentry = \numsecentry
+    \let\unnsubsubsecentry = \numsecentry
+    \openin 1 \jobname.toc
+    \ifeof 1 \else
+      \input \jobname.toc
+    \fi
+    \closein 1
+    \vfill \eject
+    \contentsalignmacro % in case @setchapternewpage odd is in effect
+  \endgroup
+  \lastnegativepageno = \pageno
+  \global\pageno = \savepageno
+}
+\let\shortcontents = \summarycontents
+
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g., `A' for an appendix, or `3' for a chapter.
+%
+\def\shortchaplabel#1{%
+  % This space should be enough, since a single number is .5em, and the
+  % widest letter (M) is 1em, at least in the Computer Modern fonts.
+  % But use \hss just in case.
+  % (This space doesn't include the extra space that gets added after
+  % the label; that gets put in by \shortchapentry above.)
+  %
+  % We'd like to right-justify chapter numbers, but that looks strange
+  % with appendix letters.  And right-justifying numbers and
+  % left-justifying letters looks strange when there is less than 10
+  % chapters.  Have to read the whole toc once to know how many chapters
+  % there are before deciding ...
+  \hbox to 1em{#1\hss}%
+}
+
+% These macros generate individual entries in the table of contents.
+% The first argument is the chapter or section name.
+% The last argument is the page number.
+% The arguments in between are the chapter number, section number, ...
+
+% Chapters, in the main contents.
+\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}}
+%
+% Chapters, in the short toc.
+% See comments in \dochapentry re vbox and related settings.
+\def\shortchapentry#1#2#3#4{%
+  \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}%
+}
+
+% Appendices, in the main contents.
+% Need the word Appendix, and a fixed-size box.
+%
+\def\appendixbox#1{%
+  % We use M since it's probably the widest letter.
+  \setbox0 = \hbox{\putwordAppendix{} M}%
+  \hbox to \wd0{\putwordAppendix{} #1\hss}}
+%
+\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\labelspace#1}{#4}}
+
+% Unnumbered chapters.
+\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}}
+\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}}
+
+% Sections.
+\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}}
+\let\appsecentry=\numsecentry
+\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}}
+
+% Subsections.
+\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsecentry=\numsubsecentry
+\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}}
+
+% And subsubsections.
+\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}}
+\let\appsubsubsecentry=\numsubsubsecentry
+\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}}
+
+% This parameter controls the indentation of the various levels.
+% Same as \defaultparindent.
+\newdimen\tocindent \tocindent = 15pt
+
+% Now for the actual typesetting. In all these, #1 is the text and #2 is the
+% page number.
+%
+% If the toc has to be broken over pages, we want it to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+   \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip
+   \begingroup
+     \chapentryfonts
+     \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+   \endgroup
+   \nobreak\vskip .25\baselineskip plus.1\baselineskip
+}
+
+\def\dosecentry#1#2{\begingroup
+  \secentryfonts \leftskip=\tocindent
+  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsecentry#1#2{\begingroup
+  \subsecentryfonts \leftskip=2\tocindent
+  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+\def\dosubsubsecentry#1#2{\begingroup
+  \subsubsecentryfonts \leftskip=3\tocindent
+  \tocentry{#1}{\dopageno\bgroup#2\egroup}%
+\endgroup}
+
+% We use the same \entry macro as for the index entries.
+\let\tocentry = \entry
+
+% Space between chapter (or whatever) number and the title.
+\def\labelspace{\hskip1em \relax}
+
+\def\dopageno#1{{\rm #1}}
+\def\doshortpageno#1{{\rm #1}}
+
+\def\chapentryfonts{\secfonts \rm}
+\def\secentryfonts{\textfonts}
+\def\subsecentryfonts{\textfonts}
+\def\subsubsecentryfonts{\textfonts}
+
+
+\message{environments,}
+% @foo ... @end foo.
+
+% @point{}, @result{}, @expansion{}, @print{}, @equiv{}.
+%
+% Since these characters are used in examples, it should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+%
+\def\point{$\star$}
+\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% The @error{} command.
+% Adapted from the TeXbook's \boxit.
+%
+\newbox\errorbox
+%
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt}
+%
+\setbox\errorbox=\hbox to \dimen0{\hfil
+   \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+   \advance\hsize by -2\dimen2 % Rules.
+   \vbox{%
+      \hrule height\dimen2
+      \hbox{\vrule width\dimen2 \kern3pt          % Space to left of text.
+         \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+         \kern3pt\vrule width\dimen2}% Space to right.
+      \hrule height\dimen2}
+    \hfil}
+%
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
+% @tex ... @end tex    escapes into raw Tex temporarily.
+% One exception: @ is still an escape character, so that @end tex works.
+% But \@ or @@ will get a plain tex @ character.
+
+\envdef\tex{%
+  \catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+  \catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+  \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie
+  \catcode `\%=14
+  \catcode `\+=\other
+  \catcode `\"=\other
+  \catcode `\|=\other
+  \catcode `\<=\other
+  \catcode `\>=\other
+  \escapechar=`\\
+  %
+  \let\b=\ptexb
+  \let\bullet=\ptexbullet
+  \let\c=\ptexc
+  \let\,=\ptexcomma
+  \let\.=\ptexdot
+  \let\dots=\ptexdots
+  \let\equiv=\ptexequiv
+  \let\!=\ptexexclam
+  \let\i=\ptexi
+  \let\indent=\ptexindent
+  \let\noindent=\ptexnoindent
+  \let\{=\ptexlbrace
+  \let\+=\tabalign
+  \let\}=\ptexrbrace
+  \let\/=\ptexslash
+  \let\*=\ptexstar
+  \let\t=\ptext
+  %
+  \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}%
+  \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}%
+  \def\@{@}%
+}
+% There is no need to define \Etex.
+
+% Define @lisp ... @end lisp.
+% @lisp environment forms a group so it can rebind things,
+% including the definition of @end lisp (which normally is erroneous).
+
+% Amount to narrow the margins by for @lisp.
+\newskip\lispnarrowing \lispnarrowing=0.4in
+
+% This is the definition that ^^M gets inside @lisp, @example, and other
+% such environments.  \null is better than a space, since it doesn't
+% have any width.
+\def\lisppar{\null\endgraf}
+
+% This space is always present above and below environments.
+\newskip\envskipamount \envskipamount = 0pt
+
+% Make spacing and below environment symmetrical.  We use \parskip here
+% to help in doing that, since in @example-like environments \parskip
+% is reset to zero; thus the \afterenvbreak inserts no space -- but the
+% start of the next paragraph will insert \parskip.
+%
+\def\aboveenvbreak{{%
+  % =10000 instead of <10000 because of a special case in \itemzzz and
+  % \sectionheading, q.v.
+  \ifnum \lastpenalty=10000 \else
+    \advance\envskipamount by \parskip
+    \endgraf
+    \ifdim\lastskip<\envskipamount
+      \removelastskip
+      % it's not a good place to break if the last penalty was \nobreak
+      % or better ...
+      \ifnum\lastpenalty<10000 \penalty-50 \fi
+      \vskip\envskipamount
+    \fi
+  \fi
+}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag.  If "set", @lisp etc don't narrow margins.
+\let\nonarrowing=\relax
+
+% @cartouche ... @end cartouche: draw rectangle w/rounded corners around
+% environment contents.
+\font\circle=lcircle10
+\newdimen\circthick
+\newdimen\cartouter\newdimen\cartinner
+\newskip\normbskip\newskip\normpskip\newskip\normlskip
+\circthick=\fontdimen8\circle
+%
+\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+\def\ctr{{\hskip 6pt\circle\char'010}}
+\def\cbl{{\circle\char'012\hskip -6pt}}
+\def\cbr{{\hskip 6pt\circle\char'011}}
+\def\carttop{\hbox to \cartouter{\hskip\lskip
+        \ctl\leaders\hrule height\circthick\hfil\ctr
+        \hskip\rskip}}
+\def\cartbot{\hbox to \cartouter{\hskip\lskip
+        \cbl\leaders\hrule height\circthick\hfil\cbr
+        \hskip\rskip}}
+%
+\newskip\lskip\newskip\rskip
+
+\envdef\cartouche{%
+  \ifhmode\par\fi  % can't be in the midst of a paragraph.
+  \startsavinginserts
+  \lskip=\leftskip \rskip=\rightskip
+  \leftskip=0pt\rightskip=0pt % we want these *outside*.
+  \cartinner=\hsize \advance\cartinner by-\lskip
+  \advance\cartinner by-\rskip
+  \cartouter=\hsize
+  \advance\cartouter by 18.4pt	% allow for 3pt kerns on either
+				% side, and for 6pt waste from
+				% each corner char, and rule thickness
+  \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+  % Flag to tell @lisp, etc., not to narrow margin.
+  \let\nonarrowing=\comment
+  \vbox\bgroup
+      \baselineskip=0pt\parskip=0pt\lineskip=0pt
+      \carttop
+      \hbox\bgroup
+	  \hskip\lskip
+	  \vrule\kern3pt
+	  \vbox\bgroup
+	      \kern3pt
+	      \hsize=\cartinner
+	      \baselineskip=\normbskip
+	      \lineskip=\normlskip
+	      \parskip=\normpskip
+	      \vskip -\parskip
+	      \comment % For explanation, see the end of \def\group.
+}
+\def\Ecartouche{%
+              \ifhmode\par\fi
+	      \kern3pt
+	  \egroup
+	  \kern3pt\vrule
+	  \hskip\rskip
+      \egroup
+      \cartbot
+  \egroup
+  \checkinserts
+}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\def\nonfillstart{%
+  \aboveenvbreak
+  \hfuzz = 12pt % Don't be fussy
+  \sepspaces % Make spaces be word-separators rather than space tokens.
+  \let\par = \lisppar % don't ignore blank lines
+  \obeylines % each line of input is a line of output
+  \parskip = 0pt
+  \parindent = 0pt
+  \emergencystretch = 0pt % don't try to avoid overfull boxes
+  % @cartouche defines \nonarrowing to inhibit narrowing
+  % at next level down.
+  \ifx\nonarrowing\relax
+    \advance \leftskip by \lispnarrowing
+    \exdentamount=\lispnarrowing
+  \fi
+  \let\exdent=\nofillexdent
+}
+
+% If you want all examples etc. small: @set dispenvsize small.
+% If you want even small examples the full size: @set dispenvsize nosmall.
+% This affects the following displayed environments:
+%    @example, @display, @format, @lisp
+%
+\def\smallword{small}
+\def\nosmallword{nosmall}
+\let\SETdispenvsize\relax
+\def\setnormaldispenv{%
+  \ifx\SETdispenvsize\smallword
+    \smallexamplefonts \rm
+  \fi
+}
+\def\setsmalldispenv{%
+  \ifx\SETdispenvsize\nosmallword
+  \else
+    \smallexamplefonts \rm
+  \fi
+}
+
+% We often define two environments, @foo and @smallfoo.
+% Let's do it by one command:
+\def\makedispenv #1#2{
+  \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}
+  \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}
+  \expandafter\let\csname E#1\endcsname \afterenvbreak
+  \expandafter\let\csname Esmall#1\endcsname \afterenvbreak
+}
+
+% Define two synonyms:
+\def\maketwodispenvs #1#2#3{
+  \makedispenv{#1}{#3}
+  \makedispenv{#2}{#3}
+}
+
+% @lisp: indented, narrowed, typewriter font; @example: same as @lisp.
+%
+% @smallexample and @smalllisp: use smaller fonts.
+% Originally contributed by Pavel@xerox.
+%
+\maketwodispenvs {lisp}{example}{%
+  \nonfillstart
+  \tt
+  \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special.
+  \gobble       % eat return
+}
+
+% @display/@smalldisplay: same as @lisp except keep current font.
+%
+\makedispenv {display}{%
+  \nonfillstart
+  \gobble
+}
+
+% @format/@smallformat: same as @display except don't narrow margins.
+%
+\makedispenv{format}{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  \gobble
+}
+
+% @flushleft: same as @format, but doesn't obey \SETdispenvsize.
+\envdef\flushleft{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  \gobble
+}
+\let\Eflushleft = \afterenvbreak
+
+% @flushright.
+%
+\envdef\flushright{%
+  \let\nonarrowing = t%
+  \nonfillstart
+  \advance\leftskip by 0pt plus 1fill
+  \gobble
+}
+\let\Eflushright = \afterenvbreak
+
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins.  We keep \parskip nonzero in general, since
+% we're doing normal filling.  So, when using \aboveenvbreak and
+% \afterenvbreak, temporarily make \parskip 0.
+%
+\envdef\quotation{%
+  {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+  \parindent=0pt
+  %
+  % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+  \ifx\nonarrowing\relax
+    \advance\leftskip by \lispnarrowing
+    \advance\rightskip by \lispnarrowing
+    \exdentamount = \lispnarrowing
+    \let\nonarrowing = \relax
+  \fi
+  \parsearg\quotationlabel
+}
+
+% We have retained a nonzero parskip for the environment, since we're
+% doing normal filling.
+%
+\def\Equotation{%
+  \par
+  \ifx\quotationauthor\undefined\else
+    % indent a bit.
+    \leftline{\kern 2\leftskip \sl ---\quotationauthor}%
+  \fi
+  {\parskip=0pt \afterenvbreak}%
+}
+
+% If we're given an argument, typeset it in bold with a colon after.
+\def\quotationlabel#1{%
+  \def\temp{#1}%
+  \ifx\temp\empty \else
+    {\bf #1: }%
+  \fi
+}
+
+
+% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>}
+% If we want to allow any <char> as delimiter,
+% we need the curly braces so that makeinfo sees the @verb command, eg:
+% `@verbx...x' would look like the '@verbx' command.  --janneke@gnu.org
+%
+% [Knuth]: Donald Ervin Knuth, 1996.  The TeXbook.
+%
+% [Knuth] p.344; only we need to do the other characters Texinfo sets
+% active too.  Otherwise, they get lost as the first character on a
+% verbatim line.
+\def\dospecials{%
+  \do\ \do\\\do\{\do\}\do\$\do\&%
+  \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~%
+  \do\<\do\>\do\|\do\@\do+\do\"%
+}
+%
+% [Knuth] p. 380
+\def\uncatcodespecials{%
+  \def\do##1{\catcode`##1=\other}\dospecials}
+%
+% [Knuth] pp. 380,381,391
+% Disable Spanish ligatures ?` and !` of \tt font
+\begingroup
+  \catcode`\`=\active\gdef`{\relax\lq}
+\endgroup
+%
+% Setup for the @verb command.
+%
+% Eight spaces for a tab
+\begingroup
+  \catcode`\^^I=\active
+  \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }}
+\endgroup
+%
+\def\setupverb{%
+  \tt  % easiest (and conventionally used) font for verbatim
+  \def\par{\leavevmode\endgraf}%
+  \catcode`\`=\active
+  \tabeightspaces
+  % Respect line breaks,
+  % print special symbols as themselves, and
+  % make each space count
+  % must do in this order:
+  \obeylines \uncatcodespecials \sepspaces
+}
+
+% Setup for the @verbatim environment
+%
+% Real tab expansion
+\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount
+%
+\def\starttabbox{\setbox0=\hbox\bgroup}
+\begingroup
+  \catcode`\^^I=\active
+  \gdef\tabexpand{%
+    \catcode`\^^I=\active
+    \def^^I{\leavevmode\egroup
+      \dimen0=\wd0 % the width so far, or since the previous tab
+      \divide\dimen0 by\tabw
+      \multiply\dimen0 by\tabw % compute previous multiple of \tabw
+      \advance\dimen0 by\tabw  % advance to next multiple of \tabw
+      \wd0=\dimen0 \box0 \starttabbox
+    }%
+  }
+\endgroup
+\def\setupverbatim{%
+  \nonfillstart
+  \advance\leftskip by -\defbodyindent
+  % Easiest (and conventionally used) font for verbatim
+  \tt
+  \def\par{\leavevmode\egroup\box0\endgraf}%
+  \catcode`\`=\active
+  \tabexpand
+  % Respect line breaks,
+  % print special symbols as themselves, and
+  % make each space count
+  % must do in this order:
+  \obeylines \uncatcodespecials \sepspaces
+  \everypar{\starttabbox}%
+}
+
+% Do the @verb magic: verbatim text is quoted by unique
+% delimiter characters.  Before first delimiter expect a
+% right brace, after last delimiter expect closing brace:
+%
+%    \def\doverb'{'<char>#1<char>'}'{#1}
+%
+% [Knuth] p. 382; only eat outer {}
+\begingroup
+  \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other
+  \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next]
+\endgroup
+%
+\def\verb{\begingroup\setupverb\doverb}
+%
+%
+% Do the @verbatim magic: define the macro \doverbatim so that
+% the (first) argument ends when '@end verbatim' is reached, ie:
+%
+%     \def\doverbatim#1@end verbatim{#1}
+%
+% For Texinfo it's a lot easier than for LaTeX,
+% because texinfo's \verbatim doesn't stop at '\end{verbatim}':
+% we need not redefine '\', '{' and '}'.
+%
+% Inspired by LaTeX's verbatim command set [latex.ltx]
+%
+\begingroup
+  \catcode`\ =\active
+  \obeylines %
+  % ignore everything up to the first ^^M, that's the newline at the end
+  % of the @verbatim input line itself.  Otherwise we get an extra blank
+  % line in the output.
+  \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}%
+  % We really want {...\end verbatim} in the body of the macro, but
+  % without the active space; thus we have to use \xdef and \gobble.
+\endgroup
+%
+\envdef\verbatim{%
+    \setupverbatim\doverbatim
+}
+\let\Everbatim = \afterenvbreak
+
+
+% @verbatiminclude FILE - insert text of file in verbatim environment.
+%
+\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude}
+%
+\def\doverbatiminclude#1{%
+  {%
+    \makevalueexpandable
+    \setupverbatim
+    \input #1
+    \afterenvbreak
+  }%
+}
+
+% @copying ... @end copying.
+% Save the text away for @insertcopying later.
+%
+% We save the uninterpreted tokens, rather than creating a box.
+% Saving the text in a box would be much easier, but then all the
+% typesetting commands (@smallbook, font changes, etc.) have to be done
+% beforehand -- and a) we want @copying to be done first in the source
+% file; b) letting users define the frontmatter in as flexible order as
+% possible is very desirable.
+%
+\def\copying{\checkenv{}\begingroup\scanargctxt\docopying}
+\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}}
+%
+\def\insertcopying{%
+  \begingroup
+    \parindent = 0pt  % paragraph indentation looks wrong on title page
+    \scanexp\copyingtext
+  \endgroup
+}
+
+\message{defuns,}
+% @defun etc.
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+
+% Start the processing of @deffn:
+\def\startdefun{%
+  \ifnum\lastpenalty<10000
+    \medbreak
+  \else
+    % If there are two @def commands in a row, we'll have a \nobreak,
+    % which is there to keep the function description together with its
+    % header.  But if there's nothing but headers, we need to allow a
+    % break somewhere.  Check specifically for penalty 10002, inserted
+    % by \defargscommonending, instead of 10000, since the sectioning
+    % commands also insert a nobreak penalty, and we don't want to allow
+    % a break between a section heading and a defun.
+    % 
+    \ifnum\lastpenalty=10002 \penalty2000 \fi
+    %
+    % Similarly, after a section heading, do not allow a break.
+    % But do insert the glue.
+    \medskip  % preceded by discardable penalty, so not a breakpoint
+  \fi
+  %
+  \parindent=0in
+  \advance\leftskip by \defbodyindent
+  \exdentamount=\defbodyindent
+}
+
+\def\dodefunx#1{%
+  % First, check whether we are in the right environment:
+  \checkenv#1%
+  %
+  % As above, allow line break if we have multiple x headers in a row.
+  % It's not a great place, though.
+  \ifnum\lastpenalty=10002 \penalty3000 \fi
+  %
+  % And now, it's time to reuse the body of the original defun:
+  \expandafter\gobbledefun#1%
+}
+\def\gobbledefun#1\startdefun{}
+
+% \printdefunline \deffnheader{text}
+%
+\def\printdefunline#1#2{%
+  \begingroup
+    % call \deffnheader:
+    #1#2 \endheader
+    % common ending:
+    \interlinepenalty = 10000
+    \advance\rightskip by 0pt plus 1fil
+    \endgraf
+    \nobreak\vskip -\parskip
+    \penalty 10002  % signal to \startdefun and \dodefunx
+    % Some of the @defun-type tags do not enable magic parentheses,
+    % rendering the following check redundant.  But we don't optimize.
+    \checkparencounts
+  \endgroup
+}
+
+\def\Edefun{\endgraf\medbreak}
+
+% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn;
+% the only thing remainnig is to define \deffnheader.
+%
+\def\makedefun#1{%
+  \expandafter\let\csname E#1\endcsname = \Edefun
+  \edef\temp{\noexpand\domakedefun
+    \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}%
+  \temp
+}
+
+% \domakedefun \deffn \deffnx \deffnheader
+%
+% Define \deffn and \deffnx, without parameters.
+% \deffnheader has to be defined explicitly.
+%
+\def\domakedefun#1#2#3{%
+  \envdef#1{%
+    \startdefun
+    \parseargusing\activeparens{\printdefunline#3}%
+  }%
+  \def#2{\dodefunx#1}%
+  \def#3%
+}
+
+%%% Untyped functions:
+
+% @deffn category name args
+\makedefun{deffn}{\deffngeneral{}}
+
+% @deffn category class name args
+\makedefun{defop}#1 {\defopon{#1\ \putwordon}}
+
+% \defopon {category on}class name args
+\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deffngeneral {subind}category name args
+%
+\def\deffngeneral#1#2 #3 #4\endheader{%
+  % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}.
+  \dosubind{fn}{\code{#3}}{#1}%
+  \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}%
+}
+
+%%% Typed functions:
+
+% @deftypefn category type name args
+\makedefun{deftypefn}{\deftypefngeneral{}}
+
+% @deftypeop category class type name args
+\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}}
+
+% \deftypeopon {category on}class type name args
+\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypefngeneral {subind}category type name args
+%
+\def\deftypefngeneral#1#2 #3 #4 #5\endheader{%
+  \dosubind{fn}{\code{#4}}{#1}%
+  \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+%%% Typed variables:
+
+% @deftypevr category type var args
+\makedefun{deftypevr}{\deftypecvgeneral{}}
+
+% @deftypecv category class type var args
+\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}}
+
+% \deftypecvof {category of}class type var args
+\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} }
+
+% \deftypecvgeneral {subind}category type var args
+%
+\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{%
+  \dosubind{vr}{\code{#4}}{#1}%
+  \defname{#2}{#3}{#4}\defunargs{#5\unskip}%
+}
+
+%%% Untyped variables:
+
+% @defvr category var args
+\makedefun{defvr}#1 {\deftypevrheader{#1} {} }
+
+% @defcv category class var args
+\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}}
+
+% \defcvof {category of}class var args
+\def\defcvof#1#2 {\deftypecvof{#1}#2 {} }
+
+%%% Type:
+% @deftp category name args
+\makedefun{deftp}#1 #2 #3\endheader{%
+  \doind{tp}{\code{#2}}%
+  \defname{#1}{}{#2}\defunargs{#3\unskip}%
+}
+
+% Remaining @defun-like shortcuts:
+\makedefun{defun}{\deffnheader{\putwordDeffunc} }
+\makedefun{defmac}{\deffnheader{\putwordDefmac} }
+\makedefun{defspec}{\deffnheader{\putwordDefspec} }
+\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} }
+\makedefun{defvar}{\defvrheader{\putwordDefvar} }
+\makedefun{defopt}{\defvrheader{\putwordDefopt} }
+\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} }
+\makedefun{defmethod}{\defopon\putwordMethodon}
+\makedefun{deftypemethod}{\deftypeopon\putwordMethodon}
+\makedefun{defivar}{\defcvof\putwordInstanceVariableof}
+\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof}
+
+% \defname, which formats the name of the @def (not the args).
+% #1 is the category, such as "Function".
+% #2 is the return type, if any.
+% #3 is the function name.
+%
+% We are followed by (but not passed) the arguments, if any.
+%
+\def\defname#1#2#3{%
+  % Get the values of \leftskip and \rightskip as they were outside the @def...
+  \advance\leftskip by -\defbodyindent
+  %
+  % How we'll format the type name.  Putting it in brackets helps
+  % distinguish it from the body text that may end up on the next line
+  % just below it.
+  \def\temp{#1}%
+  \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi}
+  %
+  % Figure out line sizes for the paragraph shape.
+  % The first line needs space for \box0; but if \rightskip is nonzero,
+  % we need only space for the part of \box0 which exceeds it:
+  \dimen0=\hsize  \advance\dimen0 by -\wd0  \advance\dimen0 by \rightskip
+  % The continuations:
+  \dimen2=\hsize  \advance\dimen2 by -\defargsindent
+  % (plain.tex says that \dimen1 should be used only as global.)
+  \parshape 2 0in \dimen0 \defargsindent \dimen2
+  %
+  % Put the type name to the right margin.
+  \noindent
+  \hbox to 0pt{%
+    \hfil\box0 \kern-\hsize
+    % \hsize has to be shortened this way:
+    \kern\leftskip
+    % Intentionally do not respect \rightskip, since we need the space.
+  }%
+  %
+  % Allow all lines to be underfull without complaint:
+  \tolerance=10000 \hbadness=10000
+  \exdentamount=\defbodyindent
+  {%
+    % defun fonts. We use typewriter by default (used to be bold) because:
+    % . we're printing identifiers, they should be in tt in principle.
+    % . in languages with many accents, such as Czech or French, it's
+    %   common to leave accents off identifiers.  The result looks ok in
+    %   tt, but exceedingly strange in rm.
+    % . we don't want -- and --- to be treated as ligatures.
+    % . this still does not fix the ?` and !` ligatures, but so far no
+    %   one has made identifiers using them :).
+    \df \tt
+    \def\temp{#2}% return value type
+    \ifx\temp\empty\else \tclose{\temp} \fi
+    #3% output function name
+  }%
+  {\rm\enskip}% hskip 0.5 em of \tenrm
+  %
+  \boldbrax
+  % arguments will be output next, if any.
+}
+
+% Print arguments in slanted roman (not ttsl), inconsistently with using
+% tt for the name.  This is because literal text is sometimes needed in
+% the argument list (groff manual), and ttsl and tt are not very
+% distinguishable.  Prevent hyphenation at `-' chars.
+%
+\def\defunargs#1{%
+  % use sl by default (not ttsl),
+  % tt for the names.
+  \df \sl \hyphenchar\font=0
+  %
+  % On the other hand, if an argument has two dashes (for instance), we
+  % want a way to get ttsl.  Let's try @var for that.
+  \let\var=\ttslanted
+  #1%
+  \sl\hyphenchar\font=45
+}
+
+% We want ()&[] to print specially on the defun line.
+%
+\def\activeparens{%
+  \catcode`\(=\active \catcode`\)=\active
+  \catcode`\[=\active \catcode`\]=\active
+  \catcode`\&=\active
+}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+% Be sure that we always have a definition for `(', etc.  For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+{
+  \activeparens
+  \global\let(=\lparen \global\let)=\rparen
+  \global\let[=\lbrack \global\let]=\rbrack
+  \global\let& = \&
+
+  \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+  \gdef\magicamp{\let&=\amprm}
+}
+
+\newcount\parencount
+
+% If we encounter &foo, then turn on ()-hacking afterwards
+\newif\ifampseen
+\def\amprm#1 {\ampseentrue{\bf\&#1 }}
+
+\def\parenfont{%
+  \ifampseen
+    % At the first level, print parens in roman,
+    % otherwise use the default font.
+    \ifnum \parencount=1 \rm \fi
+  \else
+    % The \sf parens (in \boldbrax) actually are a little bolder than
+    % the contained text.  This is especially needed for [ and ] .
+    \sf
+  \fi
+}
+\def\infirstlevel#1{%
+  \ifampseen
+    \ifnum\parencount=1
+      #1%
+    \fi
+  \fi
+}
+\def\bfafterword#1 {#1 \bf}
+
+\def\opnr{%
+  \global\advance\parencount by 1
+  {\parenfont(}%
+  \infirstlevel \bfafterword
+}
+\def\clnr{%
+  {\parenfont)}%
+  \infirstlevel \sl
+  \global\advance\parencount by -1
+}
+
+\newcount\brackcount
+\def\lbrb{%
+  \global\advance\brackcount by 1
+  {\bf[}%
+}
+\def\rbrb{%
+  {\bf]}%
+  \global\advance\brackcount by -1
+}
+
+\def\checkparencounts{%
+  \ifnum\parencount=0 \else \badparencount \fi
+  \ifnum\brackcount=0 \else \badbrackcount \fi
+}
+\def\badparencount{%
+  \errmessage{Unbalanced parentheses in @def}%
+  \global\parencount=0
+}
+\def\badbrackcount{%
+  \errmessage{Unbalanced square braces in @def}%
+  \global\brackcount=0
+}
+
+
+\message{macros,}
+% @macro.
+
+% To do this right we need a feature of e-TeX, \scantokens,
+% which we arrange to emulate with a temporary file in ordinary TeX.
+\ifx\eTeXversion\undefined
+  \newwrite\macscribble
+  \def\scantokens#1{%
+    \toks0={#1}%
+    \immediate\openout\macscribble=\jobname.tmp
+    \immediate\write\macscribble{\the\toks0}%
+    \immediate\closeout\macscribble
+    \input \jobname.tmp
+  }
+\fi
+
+\def\scanmacro#1{%
+  \begingroup
+    \newlinechar`\^^M
+    \let\xeatspaces\eatspaces
+    % Undo catcode changes of \startcontents and \doprintindex
+    % When called from @insertcopying or (short)caption, we need active
+    % backslash to get it printed correctly.  Previously, we had
+    % \catcode`\\=\other instead.  We'll see whether a problem appears
+    % with macro expansion.				--kasal, 19aug04
+    \catcode`\@=0 \catcode`\\=\active \escapechar=`\@
+    % ... and \example
+    \spaceisspace
+    %
+    % Append \endinput to make sure that TeX does not see the ending newline.
+    %
+    % I've verified that it is necessary both for e-TeX and for ordinary TeX
+    %							--kasal, 29nov03
+    \scantokens{#1\endinput}%
+  \endgroup
+}
+
+\def\scanexp#1{%
+  \edef\temp{\noexpand\scanmacro{#1}}%
+  \temp
+}
+
+\newcount\paramno   % Count of parameters
+\newtoks\macname    % Macro name
+\newif\ifrecursive  % Is it recursive?
+\def\macrolist{}    % List of all defined macros in the form
+                    % \do\macro1\do\macro2...
+
+% Utility routines.
+% This does \let #1 = #2, with \csnames; that is,
+%   \let \csname#1\endcsname = \csname#2\endcsname
+% (except of course we have to play expansion games).
+% 
+\def\cslet#1#2{%
+  \expandafter\let
+  \csname#1\expandafter\endcsname
+  \csname#2\endcsname
+}
+
+% Trim leading and trailing spaces off a string.
+% Concepts from aro-bend problem 15 (see CTAN).
+{\catcode`\@=11
+\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }}
+\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@}
+\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @}
+\def\unbrace#1{#1}
+\unbrace{\gdef\trim@@@ #1 } #2@{#1}
+}
+
+% Trim a single trailing ^^M off a string.
+{\catcode`\^^M=\other \catcode`\Q=3%
+\gdef\eatcr #1{\eatcra #1Q^^MQ}%
+\gdef\eatcra#1^^MQ{\eatcrb#1Q}%
+\gdef\eatcrb#1Q#2Q{#1}%
+}
+
+% Macro bodies are absorbed as an argument in a context where
+% all characters are catcode 10, 11 or 12, except \ which is active
+% (as in normal texinfo). It is necessary to change the definition of \.
+
+% It's necessary to have hard CRs when the macro is executed. This is
+% done by  making ^^M (\endlinechar) catcode 12 when reading the macro
+% body, and then making it the \newlinechar in \scanmacro.
+
+\def\scanctxt{%
+  \catcode`\"=\other
+  \catcode`\+=\other
+  \catcode`\<=\other
+  \catcode`\>=\other
+  \catcode`\@=\other
+  \catcode`\^=\other
+  \catcode`\_=\other
+  \catcode`\|=\other
+  \catcode`\~=\other
+}
+
+\def\scanargctxt{%
+  \scanctxt
+  \catcode`\\=\other
+  \catcode`\^^M=\other
+}
+
+\def\macrobodyctxt{%
+  \scanctxt
+  \catcode`\{=\other
+  \catcode`\}=\other
+  \catcode`\^^M=\other
+  \usembodybackslash
+}
+
+\def\macroargctxt{%
+  \scanctxt
+  \catcode`\\=\other
+}
+
+% \mbodybackslash is the definition of \ in @macro bodies.
+% It maps \foo\ => \csname macarg.foo\endcsname => #N
+% where N is the macro parameter number.
+% We define \csname macarg.\endcsname to be \realbackslash, so
+% \\ in macro replacement text gets you a backslash.
+
+{\catcode`@=0 @catcode`@\=@active
+ @gdef@usembodybackslash{@let\=@mbodybackslash}
+ @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname}
+}
+\expandafter\def\csname macarg.\endcsname{\realbackslash}
+
+\def\macro{\recursivefalse\parsearg\macroxxx}
+\def\rmacro{\recursivetrue\parsearg\macroxxx}
+
+\def\macroxxx#1{%
+  \getargs{#1}%           now \macname is the macname and \argl the arglist
+  \ifx\argl\empty       % no arguments
+     \paramno=0%
+  \else
+     \expandafter\parsemargdef \argl;%
+  \fi
+  \if1\csname ismacro.\the\macname\endcsname
+     \message{Warning: redefining \the\macname}%
+  \else
+     \expandafter\ifx\csname \the\macname\endcsname \relax
+     \else \errmessage{Macro name \the\macname\space already defined}\fi
+     \global\cslet{macsave.\the\macname}{\the\macname}%
+     \global\expandafter\let\csname ismacro.\the\macname\endcsname=1%
+     % Add the macroname to \macrolist
+     \toks0 = \expandafter{\macrolist\do}%
+     \xdef\macrolist{\the\toks0
+       \expandafter\noexpand\csname\the\macname\endcsname}%
+  \fi
+  \begingroup \macrobodyctxt
+  \ifrecursive \expandafter\parsermacbody
+  \else \expandafter\parsemacbody
+  \fi}
+
+\parseargdef\unmacro{%
+  \if1\csname ismacro.#1\endcsname
+    \global\cslet{#1}{macsave.#1}%
+    \global\expandafter\let \csname ismacro.#1\endcsname=0%
+    % Remove the macro name from \macrolist:
+    \begingroup
+      \expandafter\let\csname#1\endcsname \relax
+      \let\do\unmacrodo
+      \xdef\macrolist{\macrolist}%
+    \endgroup
+  \else
+    \errmessage{Macro #1 not defined}%
+  \fi
+}
+
+% Called by \do from \dounmacro on each macro.  The idea is to omit any
+% macro definitions that have been changed to \relax.
+%
+\def\unmacrodo#1{%
+  \ifx#1\relax
+    % remove this
+  \else
+    \noexpand\do \noexpand #1%
+  \fi
+}
+
+% This makes use of the obscure feature that if the last token of a
+% <parameter list> is #, then the preceding argument is delimited by
+% an opening brace, and that opening brace is not consumed.
+\def\getargs#1{\getargsxxx#1{}}
+\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs}
+\def\getmacname #1 #2\relax{\macname={#1}}
+\def\getmacargs#1{\def\argl{#1}}
+
+% Parse the optional {params} list.  Set up \paramno and \paramlist
+% so \defmacro knows what to do.  Define \macarg.blah for each blah
+% in the params list, to be ##N where N is the position in that list.
+% That gets used by \mbodybackslash (above).
+
+% We need to get `macro parameter char #' into several definitions.
+% The technique used is stolen from LaTeX:  let \hash be something
+% unexpandable, insert that wherever you need a #, and then redefine
+% it to # just before using the token list produced.
+%
+% The same technique is used to protect \eatspaces till just before
+% the macro is used.
+
+\def\parsemargdef#1;{\paramno=0\def\paramlist{}%
+        \let\hash\relax\let\xeatspaces\relax\parsemargdefxxx#1,;,}
+\def\parsemargdefxxx#1,{%
+  \if#1;\let\next=\relax
+  \else \let\next=\parsemargdefxxx
+    \advance\paramno by 1%
+    \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname
+        {\xeatspaces{\hash\the\paramno}}%
+    \edef\paramlist{\paramlist\hash\the\paramno,}%
+  \fi\next}
+
+% These two commands read recursive and nonrecursive macro bodies.
+% (They're different since rec and nonrec macros end differently.)
+
+\long\def\parsemacbody#1@end macro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+\long\def\parsermacbody#1@end rmacro%
+{\xdef\temp{\eatcr{#1}}\endgroup\defmacro}%
+
+% This defines the macro itself. There are six cases: recursive and
+% nonrecursive macros of zero, one, and many arguments.
+% Much magic with \expandafter here.
+% \xdef is used so that macro definitions will survive the file
+% they're defined in; @include reads the file inside a group.
+\def\defmacro{%
+  \let\hash=##% convert placeholders to macro parameter chars
+  \ifrecursive
+    \ifcase\paramno
+    % 0
+      \expandafter\xdef\csname\the\macname\endcsname{%
+        \noexpand\scanmacro{\temp}}%
+    \or % 1
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \noexpand\braceorline
+         \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+      \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+         \egroup\noexpand\scanmacro{\temp}}%
+    \else % many
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \noexpand\csname\the\macname xx\endcsname}%
+      \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+          \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+      \expandafter\expandafter
+      \expandafter\xdef
+      \expandafter\expandafter
+        \csname\the\macname xxx\endcsname
+          \paramlist{\egroup\noexpand\scanmacro{\temp}}%
+    \fi
+  \else
+    \ifcase\paramno
+    % 0
+      \expandafter\xdef\csname\the\macname\endcsname{%
+        \noexpand\norecurse{\the\macname}%
+        \noexpand\scanmacro{\temp}\egroup}%
+    \or % 1
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \noexpand\braceorline
+         \expandafter\noexpand\csname\the\macname xxx\endcsname}%
+      \expandafter\xdef\csname\the\macname xxx\endcsname##1{%
+        \egroup
+        \noexpand\norecurse{\the\macname}%
+        \noexpand\scanmacro{\temp}\egroup}%
+    \else % many
+      \expandafter\xdef\csname\the\macname\endcsname{%
+         \bgroup\noexpand\macroargctxt
+         \expandafter\noexpand\csname\the\macname xx\endcsname}%
+      \expandafter\xdef\csname\the\macname xx\endcsname##1{%
+          \expandafter\noexpand\csname\the\macname xxx\endcsname ##1,}%
+      \expandafter\expandafter
+      \expandafter\xdef
+      \expandafter\expandafter
+      \csname\the\macname xxx\endcsname
+      \paramlist{%
+          \egroup
+          \noexpand\norecurse{\the\macname}%
+          \noexpand\scanmacro{\temp}\egroup}%
+    \fi
+  \fi}
+
+\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}}
+
+% \braceorline decides whether the next nonwhitespace character is a
+% {.  If so it reads up to the closing }, if not, it reads the whole
+% line.  Whatever was read is then fed to the next control sequence
+% as an argument (by \parsebrace or \parsearg)
+\def\braceorline#1{\let\next=#1\futurelet\nchar\braceorlinexxx}
+\def\braceorlinexxx{%
+  \ifx\nchar\bgroup\else
+    \expandafter\parsearg
+  \fi \next}
+
+% We want to disable all macros during \shipout so that they are not
+% expanded by \write.
+\def\turnoffmacros{\begingroup \def\do##1{\let\noexpand##1=\relax}%
+  \edef\next{\macrolist}\expandafter\endgroup\next}
+
+% For \indexnofonts, we need to get rid of all macros, leaving only the
+% arguments (if present).  Of course this is not nearly correct, but it
+% is the best we can do for now.  makeinfo does not expand macros in the
+% argument to @deffn, which ends up writing an index entry, and texindex
+% isn't prepared for an index sort entry that starts with \.
+% 
+% Since macro invocations are followed by braces, we can just redefine them
+% to take a single TeX argument.  The case of a macro invocation that
+% goes to end-of-line is not handled.
+% 
+\def\emptyusermacros{\begingroup
+  \def\do##1{\let\noexpand##1=\noexpand\asis}%
+  \edef\next{\macrolist}\expandafter\endgroup\next}
+
+
+% @alias.
+% We need some trickery to remove the optional spaces around the equal
+% sign.  Just make them active and then expand them all to nothing.
+\def\alias{\parseargusing\obeyspaces\aliasxxx}
+\def\aliasxxx #1{\aliasyyy#1\relax}
+\def\aliasyyy #1=#2\relax{%
+  {%
+    \expandafter\let\obeyedspace=\empty
+    \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}%
+  }%
+  \next
+}
+
+
+\message{cross references,}
+
+\newwrite\auxfile
+
+\newif\ifhavexrefs    % True if xref values are known.
+\newif\ifwarnedxrefs  % True if we warned once that they aren't known.
+
+% @inforef is relatively simple.
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+  node \samp{\ignorespaces#1{}}}
+
+% @node's only job in TeX is to define \lastnode, which is used in
+% cross-references.  The @node line might or might not have commas, and
+% might or might not have spaces before the first comma, like:
+% @node foo , bar , ...
+% We don't want such trailing spaces in the node name.
+%
+\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse}
+%
+% also remove a trailing comma, in case of something like this:
+% @node Help-Cross,  ,  , Cross-refs
+\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse}
+\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}}
+
+\let\nwnode=\node
+\let\lastnode=\empty
+
+% Write a cross-reference definition for the current node.  #1 is the
+% type (Ynumbered, Yappendix, Ynothing).
+%
+\def\donoderef#1{%
+  \ifx\lastnode\empty\else
+    \setref{\lastnode}{#1}%
+    \global\let\lastnode=\empty
+  \fi
+}
+
+% @anchor{NAME} -- define xref target at arbitrary point.
+%
+\newcount\savesfregister
+%
+\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi}
+\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi}
+\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces}
+
+% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an
+% anchor), which consists of three parts:
+% 1) NAME-title - the current sectioning name taken from \thissection,
+%                 or the anchor name.
+% 2) NAME-snt   - section number and type, passed as the SNT arg, or
+%                 empty for anchors.
+% 3) NAME-pg    - the page number.
+%
+% This is called from \donoderef, \anchor, and \dofloat.  In the case of
+% floats, there is an additional part, which is not written here:
+% 4) NAME-lof   - the text as it should appear in a @listoffloats.
+%
+\def\setref#1#2{%
+  \pdfmkdest{#1}%
+  \iflinks
+    {%
+      \atdummies  % preserve commands, but don't expand them
+      \turnoffactive
+      \otherbackslash
+      \edef\writexrdef##1##2{%
+	\write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef
+	  ##1}{##2}}% these are parameters of \writexrdef
+      }%
+      \toks0 = \expandafter{\thissection}%
+      \immediate \writexrdef{title}{\the\toks0 }%
+      \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc.
+      \writexrdef{pg}{\folio}% will be written later, during \shipout
+    }%
+  \fi
+}
+
+% @xref, @pxref, and @ref generate cross-references.  For \xrefX, #1 is
+% the node name, #2 the name of the Info cross-reference, #3 the printed
+% node name, #4 the name of the Info file, #5 the name of the printed
+% manual.  All but the node name can be omitted.
+%
+\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+\def\ref#1{\xrefX[#1,,,,,,,]}
+\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+  \unsepspaces
+  \def\printedmanual{\ignorespaces #5}%
+  \def\printedrefname{\ignorespaces #3}%
+  \setbox1=\hbox{\printedmanual\unskip}%
+  \setbox0=\hbox{\printedrefname\unskip}%
+  \ifdim \wd0 = 0pt
+    % No printed node name was explicitly given.
+    \expandafter\ifx\csname SETxref-automatic-section-title\endcsname\relax
+      % Use the node name inside the square brackets.
+      \def\printedrefname{\ignorespaces #1}%
+    \else
+      % Use the actual chapter/section title appear inside
+      % the square brackets.  Use the real section title if we have it.
+      \ifdim \wd1 > 0pt
+        % It is in another manual, so we don't have it.
+        \def\printedrefname{\ignorespaces #1}%
+      \else
+        \ifhavexrefs
+          % We know the real title if we have the xref values.
+          \def\printedrefname{\refx{#1-title}{}}%
+        \else
+          % Otherwise just copy the Info node name.
+          \def\printedrefname{\ignorespaces #1}%
+        \fi%
+      \fi
+    \fi
+  \fi
+  %
+  % Make link in pdf output.
+  \ifpdf
+    \leavevmode
+    \getfilename{#4}%
+    {\turnoffactive \otherbackslash
+     \ifnum\filenamelength>0
+       \startlink attr{/Border [0 0 0]}%
+         goto file{\the\filename.pdf} name{#1}%
+     \else
+       \startlink attr{/Border [0 0 0]}%
+         goto name{\pdfmkpgn{#1}}%
+     \fi
+    }%
+    \linkcolor
+  \fi
+  %
+  % Float references are printed completely differently: "Figure 1.2"
+  % instead of "[somenode], p.3".  We distinguish them by the
+  % LABEL-title being set to a magic string.
+  {%
+    % Have to otherify everything special to allow the \csname to
+    % include an _ in the xref name, etc.
+    \indexnofonts
+    \turnoffactive
+    \otherbackslash
+    \expandafter\global\expandafter\let\expandafter\Xthisreftitle
+      \csname XR#1-title\endcsname
+  }%
+  \iffloat\Xthisreftitle
+    % If the user specified the print name (third arg) to the ref,
+    % print it instead of our usual "Figure 1.2".
+    \ifdim\wd0 = 0pt
+      \refx{#1-snt}%
+    \else
+      \printedrefname
+    \fi
+    %
+    % if the user also gave the printed manual name (fifth arg), append
+    % "in MANUALNAME".
+    \ifdim \wd1 > 0pt
+      \space \putwordin{} \cite{\printedmanual}%
+    \fi
+  \else
+    % node/anchor (non-float) references.
+    %
+    % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
+    % insert empty discretionaries after hyphens, which means that it will
+    % not find a line break at a hyphen in a node names.  Since some manuals
+    % are best written with fairly long node names, containing hyphens, this
+    % is a loss.  Therefore, we give the text of the node name again, so it
+    % is as if TeX is seeing it for the first time.
+    \ifdim \wd1 > 0pt
+      \putwordsection{} ``\printedrefname'' \putwordin{} \cite{\printedmanual}%
+    \else
+      % _ (for example) has to be the character _ for the purposes of the
+      % control sequence corresponding to the node, but it has to expand
+      % into the usual \leavevmode...\vrule stuff for purposes of
+      % printing. So we \turnoffactive for the \refx-snt, back on for the
+      % printing, back off for the \refx-pg.
+      {\turnoffactive \otherbackslash
+       % Only output a following space if the -snt ref is nonempty; for
+       % @unnumbered and @anchor, it won't be.
+       \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}%
+       \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi
+      }%
+      % output the `[mynode]' via a macro so it can be overridden.
+      \xrefprintnodename\printedrefname
+      %
+      % But we always want a comma and a space:
+      ,\space
+      %
+      % output the `page 3'.
+      \turnoffactive \otherbackslash \putwordpage\tie\refx{#1-pg}{}%
+    \fi
+  \fi
+  \endlink
+\endgroup}
+
+% This macro is called from \xrefX for the `[nodename]' part of xref
+% output.  It's a separate macro only so it can be changed more easily,
+% since square brackets don't work well in some documents.  Particularly
+% one that Bob is working on :).
+%
+\def\xrefprintnodename#1{[#1]}
+
+% Things referred to by \setref.
+%
+\def\Ynothing{}
+\def\Yomitfromtoc{}
+\def\Ynumbered{%
+  \ifnum\secno=0
+    \putwordChapter@tie \the\chapno
+  \else \ifnum\subsecno=0
+    \putwordSection@tie \the\chapno.\the\secno
+  \else \ifnum\subsubsecno=0
+    \putwordSection@tie \the\chapno.\the\secno.\the\subsecno
+  \else
+    \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno
+  \fi\fi\fi
+}
+\def\Yappendix{%
+  \ifnum\secno=0
+     \putwordAppendix@tie @char\the\appendixno{}%
+  \else \ifnum\subsecno=0
+     \putwordSection@tie @char\the\appendixno.\the\secno
+  \else \ifnum\subsubsecno=0
+    \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno
+  \else
+    \putwordSection@tie
+      @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno
+  \fi\fi\fi
+}
+
+% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+% If its value is nonempty, SUFFIX is output afterward.
+%
+\def\refx#1#2{%
+  {%
+    \indexnofonts
+    \otherbackslash
+    \expandafter\global\expandafter\let\expandafter\thisrefX
+      \csname XR#1\endcsname
+  }%
+  \ifx\thisrefX\relax
+    % If not defined, say something at least.
+    \angleleft un\-de\-fined\angleright
+    \iflinks
+      \ifhavexrefs
+        \message{\linenumber Undefined cross reference `#1'.}%
+      \else
+        \ifwarnedxrefs\else
+          \global\warnedxrefstrue
+          \message{Cross reference values unknown; you must run TeX again.}%
+        \fi
+      \fi
+    \fi
+  \else
+    % It's defined, so just use it.
+    \thisrefX
+  \fi
+  #2% Output the suffix in any case.
+}
+
+% This is the macro invoked by entries in the aux file.  Usually it's
+% just a \def (we prepend XR to the control sequence name to avoid
+% collisions).  But if this is a float type, we have more work to do.
+%
+\def\xrdef#1#2{%
+  \expandafter\gdef\csname XR#1\endcsname{#2}% remember this xref value.
+  %
+  % Was that xref control sequence that we just defined for a float?
+  \expandafter\iffloat\csname XR#1\endcsname
+    % it was a float, and we have the (safe) float type in \iffloattype.
+    \expandafter\let\expandafter\floatlist
+      \csname floatlist\iffloattype\endcsname
+    %
+    % Is this the first time we've seen this float type?
+    \expandafter\ifx\floatlist\relax
+      \toks0 = {\do}% yes, so just \do
+    \else
+      % had it before, so preserve previous elements in list.
+      \toks0 = \expandafter{\floatlist\do}%
+    \fi
+    %
+    % Remember this xref in the control sequence \floatlistFLOATTYPE,
+    % for later use in \listoffloats.
+    \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0{#1}}%
+  \fi
+}
+
+% Read the last existing aux file, if any.  No error if none exists.
+%
+\def\tryauxfile{%
+  \openin 1 \jobname.aux
+  \ifeof 1 \else
+    \readauxfile
+    \global\havexrefstrue
+  \fi
+  \closein 1
+}
+
+\def\readauxfile{\begingroup
+  \catcode`\^^@=\other
+  \catcode`\^^A=\other
+  \catcode`\^^B=\other
+  \catcode`\^^C=\other
+  \catcode`\^^D=\other
+  \catcode`\^^E=\other
+  \catcode`\^^F=\other
+  \catcode`\^^G=\other
+  \catcode`\^^H=\other
+  \catcode`\^^K=\other
+  \catcode`\^^L=\other
+  \catcode`\^^N=\other
+  \catcode`\^^P=\other
+  \catcode`\^^Q=\other
+  \catcode`\^^R=\other
+  \catcode`\^^S=\other
+  \catcode`\^^T=\other
+  \catcode`\^^U=\other
+  \catcode`\^^V=\other
+  \catcode`\^^W=\other
+  \catcode`\^^X=\other
+  \catcode`\^^Z=\other
+  \catcode`\^^[=\other
+  \catcode`\^^\=\other
+  \catcode`\^^]=\other
+  \catcode`\^^^=\other
+  \catcode`\^^_=\other
+  % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc.
+  % in xref tags, i.e., node names.  But since ^^e4 notation isn't
+  % supported in the main text, it doesn't seem desirable.  Furthermore,
+  % that is not enough: for node names that actually contain a ^
+  % character, we would end up writing a line like this: 'xrdef {'hat
+  % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first
+  % argument, and \hat is not an expandable control sequence.  It could
+  % all be worked out, but why?  Either we support ^^ or we don't.
+  %
+  % The other change necessary for this was to define \auxhat:
+  % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter
+  % and then to call \auxhat in \setq.
+  %
+  \catcode`\^=\other
+  %
+  % Special characters.  Should be turned off anyway, but...
+  \catcode`\~=\other
+  \catcode`\[=\other
+  \catcode`\]=\other
+  \catcode`\"=\other
+  \catcode`\_=\other
+  \catcode`\|=\other
+  \catcode`\<=\other
+  \catcode`\>=\other
+  \catcode`\$=\other
+  \catcode`\#=\other
+  \catcode`\&=\other
+  \catcode`\%=\other
+  \catcode`+=\other % avoid \+ for paranoia even though we've turned it off
+  %
+  % This is to support \ in node names and titles, since the \
+  % characters end up in a \csname.  It's easier than
+  % leaving it active and making its active definition an actual \
+  % character.  What I don't understand is why it works in the *value*
+  % of the xrdef.  Seems like it should be a catcode12 \, and that
+  % should not typeset properly.  But it works, so I'm moving on for
+  % now.  --karl, 15jan04.
+  \catcode`\\=\other
+  %
+  % Make the characters 128-255 be printing characters.
+  {%
+    \count 1=128
+    \def\loop{%
+      \catcode\count 1=\other
+      \advance\count 1 by 1
+      \ifnum \count 1<256 \loop \fi
+    }%
+  }%
+  %
+  % @ is our escape character in .aux files, and we need braces.
+  \catcode`\{=1
+  \catcode`\}=2
+  \catcode`\@=0
+  %
+  \input \jobname.aux
+\endgroup}
+
+
+\message{insertions,}
+% including footnotes.
+
+\newcount \footnoteno
+
+% The trailing space in the following definition for supereject is
+% vital for proper filling; pages come out unaligned when you do a
+% pagealignmacro call if that space before the closing brace is
+% removed. (Generally, numeric constants should always be followed by a
+% space to prevent strange expansion errors.)
+\def\supereject{\par\penalty -20000\footnoteno =0 }
+
+% @footnotestyle is meaningful for info output only.
+\let\footnotestyle=\comment
+
+{\catcode `\@=11
+%
+% Auto-number footnotes.  Otherwise like plain.
+\gdef\footnote{%
+  \let\indent=\ptexindent
+  \let\noindent=\ptexnoindent
+  \global\advance\footnoteno by \@ne
+  \edef\thisfootno{$^{\the\footnoteno}$}%
+  %
+  % In case the footnote comes at the end of a sentence, preserve the
+  % extra spacing after we do the footnote number.
+  \let\@sf\empty
+  \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\ptexslash\fi
+  %
+  % Remove inadvertent blank space before typesetting the footnote number.
+  \unskip
+  \thisfootno\@sf
+  \dofootnote
+}%
+
+% Don't bother with the trickery in plain.tex to not require the
+% footnote text as a parameter.  Our footnotes don't need to be so general.
+%
+% Oh yes, they do; otherwise, @ifset (and anything else that uses
+% \parseargline) fails inside footnotes because the tokens are fixed when
+% the footnote is read.  --karl, 16nov96.
+%
+\gdef\dofootnote{%
+  \insert\footins\bgroup
+  % We want to typeset this text as a normal paragraph, even if the
+  % footnote reference occurs in (for example) a display environment.
+  % So reset some parameters.
+  \hsize=\pagewidth
+  \interlinepenalty\interfootnotelinepenalty
+  \splittopskip\ht\strutbox % top baseline for broken footnotes
+  \splitmaxdepth\dp\strutbox
+  \floatingpenalty\@MM
+  \leftskip\z@skip
+  \rightskip\z@skip
+  \spaceskip\z@skip
+  \xspaceskip\z@skip
+  \parindent\defaultparindent
+  %
+  \smallfonts \rm
+  %
+  % Because we use hanging indentation in footnotes, a @noindent appears
+  % to exdent this text, so make it be a no-op.  makeinfo does not use
+  % hanging indentation so @noindent can still be needed within footnote
+  % text after an @example or the like (not that this is good style).
+  \let\noindent = \relax
+  %
+  % Hang the footnote text off the number.  Use \everypar in case the
+  % footnote extends for more than one paragraph.
+  \everypar = {\hang}%
+  \textindent{\thisfootno}%
+  %
+  % Don't crash into the line above the footnote text.  Since this
+  % expands into a box, it must come within the paragraph, lest it
+  % provide a place where TeX can split the footnote.
+  \footstrut
+  \futurelet\next\fo@t
+}
+}%end \catcode `\@=11
+
+% In case a @footnote appears in a vbox, save the footnote text and create
+% the real \insert just after the vbox finished.  Otherwise, the insertion
+% would be lost.
+% Similarily, if a @footnote appears inside an alignment, save the footnote
+% text to a box and make the \insert when a row of the table is finished.
+% And the same can be done for other insert classes.  --kasal, 16nov03.
+
+% Replace the \insert primitive by a cheating macro.
+% Deeper inside, just make sure that the saved insertions are not spilled
+% out prematurely.
+%
+\def\startsavinginserts{%
+  \ifx \insert\ptexinsert
+    \let\insert\saveinsert
+  \else
+    \let\checkinserts\relax
+  \fi
+}
+
+% This \insert replacement works for both \insert\footins{foo} and
+% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}.
+%
+\def\saveinsert#1{%
+  \edef\next{\noexpand\savetobox \makeSAVEname#1}%
+  \afterassignment\next
+  % swallow the left brace
+  \let\temp =
+}
+\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}}
+\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1}
+
+\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi}
+
+\def\placesaveins#1{%
+  \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname
+    {\box#1}%
+}
+
+% eat @SAVE -- beware, all of them have catcode \other:
+{
+  \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials  %  ;-)
+  \gdef\gobblesave @SAVE{}
+}
+
+% initialization:
+\def\newsaveins #1{%
+  \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}%
+  \next
+}
+\def\newsaveinsX #1{%
+  \csname newbox\endcsname #1%
+  \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts
+    \checksaveins #1}%
+}
+
+% initialize:
+\let\checkinserts\empty
+\newsaveins\footins
+\newsaveins\margin
+
+
+% @image.  We use the macros from epsf.tex to support this.
+% If epsf.tex is not installed and @image is used, we complain.
+%
+% Check for and read epsf.tex up front.  If we read it only at @image
+% time, we might be inside a group, and then its definitions would get
+% undone and the next image would fail.
+\openin 1 = epsf.tex
+\ifeof 1 \else
+  % Do not bother showing banner with epsf.tex v2.7k (available in
+  % doc/epsf.tex and on ctan).
+  \def\epsfannounce{\toks0 = }%
+  \input epsf.tex
+\fi
+\closein 1
+%
+% We will only complain once about lack of epsf.tex.
+\newif\ifwarnednoepsf
+\newhelp\noepsfhelp{epsf.tex must be installed for images to
+  work.  It is also included in the Texinfo distribution, or you can get
+  it from ftp://tug.org/tex/epsf.tex.}
+%
+\def\image#1{%
+  \ifx\epsfbox\undefined
+    \ifwarnednoepsf \else
+      \errhelp = \noepsfhelp
+      \errmessage{epsf.tex not found, images will be ignored}%
+      \global\warnednoepsftrue
+    \fi
+  \else
+    \imagexxx #1,,,,,\finish
+  \fi
+}
+%
+% Arguments to @image:
+% #1 is (mandatory) image filename; we tack on .eps extension.
+% #2 is (optional) width, #3 is (optional) height.
+% #4 is (ignored optional) html alt text.
+% #5 is (ignored optional) extension.
+% #6 is just the usual extra ignored arg for parsing this stuff.
+\newif\ifimagevmode
+\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup
+  \catcode`\^^M = 5     % in case we're inside an example
+  \normalturnoffactive  % allow _ et al. in names
+  % If the image is by itself, center it.
+  \ifvmode
+    \imagevmodetrue
+    \nobreak\bigskip
+    % Usually we'll have text after the image which will insert
+    % \parskip glue, so insert it here too to equalize the space
+    % above and below.
+    \nobreak\vskip\parskip
+    \nobreak
+    \line\bgroup\hss
+  \fi
+  %
+  % Output the image.
+  \ifpdf
+    \dopdfimage{#1}{#2}{#3}%
+  \else
+    % \epsfbox itself resets \epsf?size at each figure.
+    \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi
+    \setbox0 = \hbox{\ignorespaces #3}\ifdim\wd0 > 0pt \epsfysize=#3\relax \fi
+    \epsfbox{#1.eps}%
+  \fi
+  %
+  \ifimagevmode \hss \egroup \bigbreak \fi  % space after the image
+\endgroup}
+
+
+% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables,
+% etc.  We don't actually implement floating yet, we always include the
+% float "here".  But it seemed the best name for the future.
+%
+\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish}
+
+% There may be a space before second and/or third parameter; delete it.
+\def\eatcommaspace#1, {#1,}
+
+% #1 is the optional FLOATTYPE, the text label for this float, typically
+% "Figure", "Table", "Example", etc.  Can't contain commas.  If omitted,
+% this float will not be numbered and cannot be referred to.
+%
+% #2 is the optional xref label.  Also must be present for the float to
+% be referable.
+%
+% #3 is the optional positioning argument; for now, it is ignored.  It
+% will somehow specify the positions allowed to float to (here, top, bottom).
+%
+% We keep a separate counter for each FLOATTYPE, which we reset at each
+% chapter-level command.
+\let\resetallfloatnos=\empty
+%
+\def\dofloat#1,#2,#3,#4\finish{%
+  \let\thiscaption=\empty
+  \let\thisshortcaption=\empty
+  %
+  % don't lose footnotes inside @float.
+  %
+  % BEWARE: when the floats start float, we have to issue warning whenever an
+  % insert appears inside a float which could possibly float. --kasal, 26may04
+  %
+  \startsavinginserts
+  %
+  % We can't be used inside a paragraph.
+  \par
+  %
+  \vtop\bgroup
+    \def\floattype{#1}%
+    \def\floatlabel{#2}%
+    \def\floatloc{#3}% we do nothing with this yet.
+    %
+    \ifx\floattype\empty
+      \let\safefloattype=\empty
+    \else
+      {%
+        % the floattype might have accents or other special characters,
+        % but we need to use it in a control sequence name.
+        \indexnofonts
+        \turnoffactive
+        \xdef\safefloattype{\floattype}%
+      }%
+    \fi
+    %
+    % If label is given but no type, we handle that as the empty type.
+    \ifx\floatlabel\empty \else
+      % We want each FLOATTYPE to be numbered separately (Figure 1,
+      % Table 1, Figure 2, ...).  (And if no label, no number.)
+      %
+      \expandafter\getfloatno\csname\safefloattype floatno\endcsname
+      \global\advance\floatno by 1
+      %
+      {%
+        % This magic value for \thissection is output by \setref as the
+        % XREFLABEL-title value.  \xrefX uses it to distinguish float
+        % labels (which have a completely different output format) from
+        % node and anchor labels.  And \xrdef uses it to construct the
+        % lists of floats.
+        %
+        \edef\thissection{\floatmagic=\safefloattype}%
+        \setref{\floatlabel}{Yfloat}%
+      }%
+    \fi
+    %
+    % start with \parskip glue, I guess.
+    \vskip\parskip
+    %
+    % Don't suppress indentation if a float happens to start a section.
+    \restorefirstparagraphindent
+}
+
+% we have these possibilities:
+% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap
+% @float Foo,lbl & no caption:    Foo 1.1
+% @float Foo & @caption{Cap}:     Foo: Cap
+% @float Foo & no caption:        Foo
+% @float ,lbl & Caption{Cap}:     1.1: Cap
+% @float ,lbl & no caption:       1.1
+% @float & @caption{Cap}:         Cap
+% @float & no caption:
+%
+\def\Efloat{%
+    \let\floatident = \empty
+    %
+    % In all cases, if we have a float type, it comes first.
+    \ifx\floattype\empty \else \def\floatident{\floattype}\fi
+    %
+    % If we have an xref label, the number comes next.
+    \ifx\floatlabel\empty \else
+      \ifx\floattype\empty \else % if also had float type, need tie first.
+        \appendtomacro\floatident{\tie}%
+      \fi
+      % the number.
+      \appendtomacro\floatident{\chaplevelprefix\the\floatno}%
+    \fi
+    %
+    % Start the printed caption with what we've constructed in
+    % \floatident, but keep it separate; we need \floatident again.
+    \let\captionline = \floatident
+    %
+    \ifx\thiscaption\empty \else
+      \ifx\floatident\empty \else
+	\appendtomacro\captionline{: }% had ident, so need a colon between
+      \fi
+      %
+      % caption text.
+      \appendtomacro\captionline{\scanexp\thiscaption}%
+    \fi
+    %
+    % If we have anything to print, print it, with space before.
+    % Eventually this needs to become an \insert.
+    \ifx\captionline\empty \else
+      \vskip.5\parskip
+      \captionline
+      %
+      % Space below caption.
+      \vskip\parskip
+    \fi
+    %
+    % If have an xref label, write the list of floats info.  Do this
+    % after the caption, to avoid chance of it being a breakpoint.
+    \ifx\floatlabel\empty \else
+      % Write the text that goes in the lof to the aux file as
+      % \floatlabel-lof.  Besides \floatident, we include the short
+      % caption if specified, else the full caption if specified, else nothing.
+      {%
+        \atdummies \turnoffactive \otherbackslash
+        % since we read the caption text in the macro world, where ^^M
+        % is turned into a normal character, we have to scan it back, so
+        % we don't write the literal three characters "^^M" into the aux file.
+	\scanexp{%
+	  \xdef\noexpand\gtemp{%
+	    \ifx\thisshortcaption\empty
+	      \thiscaption
+	    \else
+	      \thisshortcaption
+	    \fi
+	  }%
+	}%
+        \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident
+	  \ifx\gtemp\empty \else : \gtemp \fi}}%
+      }%
+    \fi
+  \egroup  % end of \vtop
+  %
+  % place the captured inserts
+  %
+  % BEWARE: when the floats start float, we have to issue warning whenever an
+  % insert appears inside a float which could possibly float. --kasal, 26may04
+  %
+  \checkinserts
+}
+
+% Append the tokens #2 to the definition of macro #1, not expanding either.
+%
+\def\appendtomacro#1#2{%
+  \expandafter\def\expandafter#1\expandafter{#1#2}%
+}
+
+% @caption, @shortcaption
+%
+\def\caption{\docaption\thiscaption}
+\def\shortcaption{\docaption\thisshortcaption}
+\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption}
+\def\defcaption#1#2{\egroup \def#1{#2}}
+
+% The parameter is the control sequence identifying the counter we are
+% going to use.  Create it if it doesn't exist and assign it to \floatno.
+\def\getfloatno#1{%
+  \ifx#1\relax
+      % Haven't seen this figure type before.
+      \csname newcount\endcsname #1%
+      %
+      % Remember to reset this floatno at the next chap.
+      \expandafter\gdef\expandafter\resetallfloatnos
+        \expandafter{\resetallfloatnos #1=0 }%
+  \fi
+  \let\floatno#1%
+}
+
+% \setref calls this to get the XREFLABEL-snt value.  We want an @xref
+% to the FLOATLABEL to expand to "Figure 3.1".  We call \setref when we
+% first read the @float command.
+%
+\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}%
+
+% Magic string used for the XREFLABEL-title value, so \xrefX can
+% distinguish floats from other xref types.
+\def\floatmagic{!!float!!}
+
+% #1 is the control sequence we are passed; we expand into a conditional
+% which is true if #1 represents a float ref.  That is, the magic
+% \thissection value which we \setref above.
+%
+\def\iffloat#1{\expandafter\doiffloat#1==\finish}
+%
+% #1 is (maybe) the \floatmagic string.  If so, #2 will be the
+% (safe) float type for this float.  We set \iffloattype to #2.
+%
+\def\doiffloat#1=#2=#3\finish{%
+  \def\temp{#1}%
+  \def\iffloattype{#2}%
+  \ifx\temp\floatmagic
+}
+
+% @listoffloats FLOATTYPE - print a list of floats like a table of contents.
+%
+\parseargdef\listoffloats{%
+  \def\floattype{#1}% floattype
+  {%
+    % the floattype might have accents or other special characters,
+    % but we need to use it in a control sequence name.
+    \indexnofonts
+    \turnoffactive
+    \xdef\safefloattype{\floattype}%
+  }%
+  %
+  % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE.
+  \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax
+    \ifhavexrefs
+      % if the user said @listoffloats foo but never @float foo.
+      \message{\linenumber No `\safefloattype' floats to list.}%
+    \fi
+  \else
+    \begingroup
+      \leftskip=\tocindent  % indent these entries like a toc
+      \let\do=\listoffloatsdo
+      \csname floatlist\safefloattype\endcsname
+    \endgroup
+  \fi
+}
+
+% This is called on each entry in a list of floats.  We're passed the
+% xref label, in the form LABEL-title, which is how we save it in the
+% aux file.  We strip off the -title and look up \XRLABEL-lof, which
+% has the text we're supposed to typeset here.
+%
+% Figures without xref labels will not be included in the list (since
+% they won't appear in the aux file).
+%
+\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish}
+\def\listoffloatsdoentry#1-title\finish{{%
+  % Can't fully expand XR#1-lof because it can contain anything.  Just
+  % pass the control sequence.  On the other hand, XR#1-pg is just the
+  % page number, and we want to fully expand that so we can get a link
+  % in pdf output.
+  \toksA = \expandafter{\csname XR#1-lof\endcsname}%
+  %
+  % use the same \entry macro we use to generate the TOC and index.
+  \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}%
+  \writeentry
+}}
+
+\message{localization,}
+% and i18n.
+
+% @documentlanguage is usually given very early, just after
+% @setfilename.  If done too late, it may not override everything
+% properly.  Single argument is the language abbreviation.
+% It would be nice if we could set up a hyphenation file here.
+%
+\parseargdef\documentlanguage{%
+  \tex % read txi-??.tex file in plain TeX.
+    % Read the file if it exists.
+    \openin 1 txi-#1.tex
+    \ifeof 1
+      \errhelp = \nolanghelp
+      \errmessage{Cannot read language file txi-#1.tex}%
+    \else
+      \input txi-#1.tex
+    \fi
+    \closein 1
+  \endgroup
+}
+\newhelp\nolanghelp{The given language definition file cannot be found or
+is empty.  Maybe you need to install it?  In the current directory
+should work if nowhere else does.}
+
+
+% @documentencoding should change something in TeX eventually, most
+% likely, but for now just recognize it.
+\let\documentencoding = \comment
+
+
+% Page size parameters.
+%
+\newdimen\defaultparindent \defaultparindent = 15pt
+
+\chapheadingskip = 15pt plus 4pt minus 2pt
+\secheadingskip = 12pt plus 3pt minus 2pt
+\subsecheadingskip = 9pt plus 2pt minus 2pt
+
+% Prevent underfull vbox error messages.
+\vbadness = 10000
+
+% Don't be so finicky about underfull hboxes, either.
+\hbadness = 2000
+
+% Following George Bush, just get rid of widows and orphans.
+\widowpenalty=10000
+\clubpenalty=10000
+
+% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+% using an old version of TeX, don't do anything.  We want the amount of
+% stretch added to depend on the line length, hence the dependence on
+% \hsize.  We call this whenever the paper size is set.
+%
+\def\setemergencystretch{%
+  \ifx\emergencystretch\thisisundefined
+    % Allow us to assign to \emergencystretch anyway.
+    \def\emergencystretch{\dimen0}%
+  \else
+    \emergencystretch = .15\hsize
+  \fi
+}
+
+% Parameters in order: 1) textheight; 2) textwidth; 3) voffset;
+% 4) hoffset; 5) binding offset; 6) topskip; 7) physical page height; 8)
+% physical page width.
+%
+% We also call \setleading{\textleading}, so the caller should define
+% \textleading.  The caller should also set \parskip.
+%
+\def\internalpagesizes#1#2#3#4#5#6#7#8{%
+  \voffset = #3\relax
+  \topskip = #6\relax
+  \splittopskip = \topskip
+  %
+  \vsize = #1\relax
+  \advance\vsize by \topskip
+  \outervsize = \vsize
+  \advance\outervsize by 2\topandbottommargin
+  \pageheight = \vsize
+  %
+  \hsize = #2\relax
+  \outerhsize = \hsize
+  \advance\outerhsize by 0.5in
+  \pagewidth = \hsize
+  %
+  \normaloffset = #4\relax
+  \bindingoffset = #5\relax
+  %
+  \ifpdf
+    \pdfpageheight #7\relax
+    \pdfpagewidth #8\relax
+  \fi
+  %
+  \setleading{\textleading}
+  %
+  \parindent = \defaultparindent
+  \setemergencystretch
+}
+
+% @letterpaper (the default).
+\def\letterpaper{{\globaldefs = 1
+  \parskip = 3pt plus 2pt minus 1pt
+  \textleading = 13.2pt
+  %
+  % If page is nothing but text, make it come out even.
+  \internalpagesizes{46\baselineskip}{6in}%
+                    {\voffset}{.25in}%
+                    {\bindingoffset}{36pt}%
+                    {11in}{8.5in}%
+}}
+
+% Use @smallbook to reset parameters for 7x9.5 (or so) format.
+\def\smallbook{{\globaldefs = 1
+  \parskip = 2pt plus 1pt
+  \textleading = 12pt
+  %
+  \internalpagesizes{7.5in}{5in}%
+                    {\voffset}{.25in}%
+                    {\bindingoffset}{16pt}%
+                    {9.25in}{7in}%
+  %
+  \lispnarrowing = 0.3in
+  \tolerance = 700
+  \hfuzz = 1pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = .5cm
+}}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{{\globaldefs = 1
+  \parskip = 3pt plus 2pt minus 1pt
+  \textleading = 13.2pt
+  %
+  % Double-side printing via postscript on Laserjet 4050
+  % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm.
+  % To change the settings for a different printer or situation, adjust
+  % \normaloffset until the front-side and back-side texts align.  Then
+  % do the same for \bindingoffset.  You can set these for testing in
+  % your texinfo source file like this:
+  % @tex
+  % \global\normaloffset = -6mm
+  % \global\bindingoffset = 10mm
+  % @end tex
+  \internalpagesizes{51\baselineskip}{160mm}
+                    {\voffset}{\hoffset}%
+                    {\bindingoffset}{44pt}%
+                    {297mm}{210mm}%
+  %
+  \tolerance = 700
+  \hfuzz = 1pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = 5mm
+}}
+
+% Use @afivepaper to print on European A5 paper.
+% From romildo@urano.iceb.ufop.br, 2 July 2000.
+% He also recommends making @example and @lisp be small.
+\def\afivepaper{{\globaldefs = 1
+  \parskip = 2pt plus 1pt minus 0.1pt
+  \textleading = 12.5pt
+  %
+  \internalpagesizes{160mm}{120mm}%
+                    {\voffset}{\hoffset}%
+                    {\bindingoffset}{8pt}%
+                    {210mm}{148mm}%
+  %
+  \lispnarrowing = 0.2in
+  \tolerance = 800
+  \hfuzz = 1.2pt
+  \contentsrightmargin = 0pt
+  \defbodyindent = 2mm
+  \tableindent = 12mm
+}}
+
+% A specific text layout, 24x15cm overall, intended for A4 paper.
+\def\afourlatex{{\globaldefs = 1
+  \afourpaper
+  \internalpagesizes{237mm}{150mm}%
+                    {\voffset}{4.6mm}%
+                    {\bindingoffset}{7mm}%
+                    {297mm}{210mm}%
+  %
+  % Must explicitly reset to 0 because we call \afourpaper.
+  \globaldefs = 0
+}}
+
+% Use @afourwide to print on A4 paper in landscape format.
+\def\afourwide{{\globaldefs = 1
+  \afourpaper
+  \internalpagesizes{241mm}{165mm}%
+                    {\voffset}{-2.95mm}%
+                    {\bindingoffset}{7mm}%
+                    {297mm}{210mm}%
+  \globaldefs = 0
+}}
+
+% @pagesizes TEXTHEIGHT[,TEXTWIDTH]
+% Perhaps we should allow setting the margins, \topskip, \parskip,
+% and/or leading, also. Or perhaps we should compute them somehow.
+%
+\parseargdef\pagesizes{\pagesizesyyy #1,,\finish}
+\def\pagesizesyyy#1,#2,#3\finish{{%
+  \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi
+  \globaldefs = 1
+  %
+  \parskip = 3pt plus 2pt minus 1pt
+  \setleading{\textleading}%
+  %
+  \dimen0 = #1
+  \advance\dimen0 by \voffset
+  %
+  \dimen2 = \hsize
+  \advance\dimen2 by \normaloffset
+  %
+  \internalpagesizes{#1}{\hsize}%
+                    {\voffset}{\normaloffset}%
+                    {\bindingoffset}{44pt}%
+                    {\dimen0}{\dimen2}%
+}}
+
+% Set default to letter.
+%
+\letterpaper
+
+
+\message{and turning on texinfo input format.}
+
+% Define macros to output various characters with catcode for normal text.
+\catcode`\"=\other
+\catcode`\~=\other
+\catcode`\^=\other
+\catcode`\_=\other
+\catcode`\|=\other
+\catcode`\<=\other
+\catcode`\>=\other
+\catcode`\+=\other
+\catcode`\$=\other
+\def\normaldoublequote{"}
+\def\normaltilde{~}
+\def\normalcaret{^}
+\def\normalunderscore{_}
+\def\normalverticalbar{|}
+\def\normalless{<}
+\def\normalgreater{>}
+\def\normalplus{+}
+\def\normaldollar{$}%$ font-lock fix
+
+% This macro is used to make a character print one way in \tt
+% (where it can probably be output as-is), and another way in other fonts,
+% where something hairier probably needs to be done.
+%
+% #1 is what to print if we are indeed using \tt; #2 is what to print
+% otherwise.  Since all the Computer Modern typewriter fonts have zero
+% interword stretch (and shrink), and it is reasonable to expect all
+% typewriter fonts to have this, we can check that font parameter.
+%
+\def\ifusingtt#1#2{\ifdim \fontdimen3\font=0pt #1\else #2\fi}
+
+% Same as above, but check for italic font.  Actually this also catches
+% non-italic slanted fonts since it is impossible to distinguish them from
+% italic fonts.  But since this is only used by $ and it uses \sl anyway
+% this is not a problem.
+\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi}
+
+% Turn off all special characters except @
+% (and those which the user can use as if they were ordinary).
+% Most of these we simply print from the \tt font, but for some, we can
+% use math or other variants that look better in normal text.
+
+\catcode`\"=\active
+\def\activedoublequote{{\tt\char34}}
+\let"=\activedoublequote
+\catcode`\~=\active
+\def~{{\tt\char126}}
+\chardef\hat=`\^
+\catcode`\^=\active
+\def^{{\tt \hat}}
+
+\catcode`\_=\active
+\def_{\ifusingtt\normalunderscore\_}
+% Subroutine for the previous macro.
+\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }
+
+\catcode`\|=\active
+\def|{{\tt\char124}}
+\chardef \less=`\<
+\catcode`\<=\active
+\def<{{\tt \less}}
+\chardef \gtr=`\>
+\catcode`\>=\active
+\def>{{\tt \gtr}}
+\catcode`\+=\active
+\def+{{\tt \char 43}}
+\catcode`\$=\active
+\def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix
+
+% If a .fmt file is being used, characters that might appear in a file
+% name cannot be active until we have parsed the command line.
+% So turn them off again, and have \everyjob (or @setfilename) turn them on.
+% \otherifyactive is called near the end of this file.
+\def\otherifyactive{\catcode`+=\other \catcode`\_=\other}
+
+\catcode`\@=0
+
+% \backslashcurfont outputs one backslash character in current font,
+% as in \char`\\.
+\global\chardef\backslashcurfont=`\\
+\global\let\rawbackslashxx=\backslashcurfont  % let existing .??s files work
+
+% \rawbackslash defines an active \ to do \backslashcurfont.
+% \otherbackslash defines an active \ to be a literal `\' character with
+% catcode other.
+{\catcode`\\=\active
+ @gdef@rawbackslash{@let\=@backslashcurfont}
+ @gdef@otherbackslash{@let\=@realbackslash}
+}
+
+% \realbackslash is an actual character `\' with catcode other.
+{\catcode`\\=\other @gdef@realbackslash{\}}
+
+% \normalbackslash outputs one backslash in fixed width font.
+\def\normalbackslash{{\tt\backslashcurfont}}
+
+\catcode`\\=\active
+
+% Used sometimes to turn off (effectively) the active characters
+% even after parsing them.
+@def@turnoffactive{%
+  @let"=@normaldoublequote
+  @let\=@realbackslash
+  @let~=@normaltilde
+  @let^=@normalcaret
+  @let_=@normalunderscore
+  @let|=@normalverticalbar
+  @let<=@normalless
+  @let>=@normalgreater
+  @let+=@normalplus
+  @let$=@normaldollar %$ font-lock fix
+  @unsepspaces
+}
+
+% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
+% the literal character `\'.  (Thus, \ is not expandable when this is in
+% effect.)
+%
+@def@normalturnoffactive{@turnoffactive @let\=@normalbackslash}
+
+% Make _ and + \other characters, temporarily.
+% This is canceled by @fixbackslash.
+@otherifyactive
+
+% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+% That is what \eatinput is for; after that, the `\' should revert to printing
+% a backslash.
+%
+@gdef@eatinput input texinfo{@fixbackslash}
+@global@let\ = @eatinput
+
+% On the other hand, perhaps the file did not have a `\input texinfo'. Then
+% the first `\{ in the file would cause an error. This macro tries to fix
+% that, assuming it is called before the first `\' could plausibly occur.
+% Also back turn on active characters that might appear in the input
+% file name, in case not using a pre-dumped format.
+%
+@gdef@fixbackslash{%
+  @ifx\@eatinput @let\ = @normalbackslash @fi
+  @catcode`+=@active
+  @catcode`@_=@active
+}
+
+% Say @foo, not \foo, in error messages.
+@escapechar = `@@
+
+% These look ok in all fonts, so just make them not special.
+@catcode`@& = @other
+@catcode`@# = @other
+@catcode`@% = @other
+
+
+@c Local variables:
+@c eval: (add-hook 'write-file-hooks 'time-stamp)
+@c page-delimiter: "^\\\\message"
+@c time-stamp-start: "def\\\\texinfoversion{"
+@c time-stamp-format: "%:y-%02m-%02d.%02H"
+@c time-stamp-end: "}"
+@c End:
+
+@c vim:sw=2:
+
+@ignore
+   arch-tag: e1b36e32-c96e-4135-a41a-0b2efa2ea115
+@end ignore
diff --git a/docs/version.texi b/docs/version.texi
new file mode 100644
index 0000000..b97de24
--- /dev/null
+++ b/docs/version.texi
@@ -0,0 +1,4 @@
+@set UPDATED 8 May 2005
+@set UPDATED-MONTH May 2005
+@set EDITION 0.97
+@set VERSION 0.97
diff --git a/grub/Makefile.am b/grub/Makefile.am
new file mode 100644
index 0000000..7eb2eaa
--- /dev/null
+++ b/grub/Makefile.am
@@ -0,0 +1,19 @@
+sbin_PROGRAMS = grub
+
+if SERIAL_SPEED_SIMULATION
+SERIAL_FLAGS = -DSUPPORT_SERIAL=1 -DSIMULATE_SLOWNESS_OF_SERIAL=1
+else
+SERIAL_FLAGS = -DSUPPORT_SERIAL=1 
+endif
+
+AM_CPPFLAGS = -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
+	-DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
+	-DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \
+	-DUSE_MD5_PASSWORDS=1 -DSUPPORT_HERCULES=1 \
+	$(SERIAL_FLAGS) -I$(top_srcdir)/stage2 \
+	-I$(top_srcdir)/stage1 -I$(top_srcdir)/lib
+
+AM_CFLAGS = $(GRUB_CFLAGS)
+
+grub_SOURCES = main.c asmstub.c
+grub_LDADD = ../stage2/libgrub.a  ../lib/libcommon.a $(GRUB_LIBS)
diff --git a/grub/Makefile.in b/grub/Makefile.in
new file mode 100644
index 0000000..136c38f
--- /dev/null
+++ b/grub/Makefile.in
@@ -0,0 +1,445 @@
+# Makefile.in generated by automake 1.9.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  Free Software Foundation, Inc.
+# This Makefile.in 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 distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+SOURCES = $(grub_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+sbin_PROGRAMS = grub$(EXEEXT)
+subdir = grub
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(sbindir)"
+sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(sbin_PROGRAMS)
+am_grub_OBJECTS = main.$(OBJEXT) asmstub.$(OBJEXT)
+grub_OBJECTS = $(am_grub_OBJECTS)
+am__DEPENDENCIES_1 =
+grub_DEPENDENCIES = ../stage2/libgrub.a ../lib/libcommon.a \
+	$(am__DEPENDENCIES_1)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(grub_SOURCES)
+DIST_SOURCES = $(grub_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_EXAMPLE_KERNEL_FALSE = @BUILD_EXAMPLE_KERNEL_FALSE@
+BUILD_EXAMPLE_KERNEL_TRUE = @BUILD_EXAMPLE_KERNEL_TRUE@
+CC = @CC@
+CCAS = @CCAS@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISKLESS_SUPPORT_FALSE = @DISKLESS_SUPPORT_FALSE@
+DISKLESS_SUPPORT_TRUE = @DISKLESS_SUPPORT_TRUE@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FSYS_CFLAGS = @FSYS_CFLAGS@
+GRUB_CFLAGS = @GRUB_CFLAGS@
+GRUB_LIBS = @GRUB_LIBS@
+HERCULES_SUPPORT_FALSE = @HERCULES_SUPPORT_FALSE@
+HERCULES_SUPPORT_TRUE = @HERCULES_SUPPORT_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
+NETBOOT_SUPPORT_FALSE = @NETBOOT_SUPPORT_FALSE@
+NETBOOT_SUPPORT_TRUE = @NETBOOT_SUPPORT_TRUE@
+NET_CFLAGS = @NET_CFLAGS@
+NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
+OBJCOPY = @OBJCOPY@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+RANLIB = @RANLIB@
+SERIAL_SPEED_SIMULATION_FALSE = @SERIAL_SPEED_SIMULATION_FALSE@
+SERIAL_SPEED_SIMULATION_TRUE = @SERIAL_SPEED_SIMULATION_TRUE@
+SERIAL_SUPPORT_FALSE = @SERIAL_SUPPORT_FALSE@
+SERIAL_SUPPORT_TRUE = @SERIAL_SUPPORT_TRUE@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STAGE1_CFLAGS = @STAGE1_CFLAGS@
+STAGE2_CFLAGS = @STAGE2_CFLAGS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_OBJCOPY = @ac_ct_OBJCOPY@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+@SERIAL_SPEED_SIMULATION_FALSE@SERIAL_FLAGS = -DSUPPORT_SERIAL=1 
+@SERIAL_SPEED_SIMULATION_TRUE@SERIAL_FLAGS = -DSUPPORT_SERIAL=1 -DSIMULATE_SLOWNESS_OF_SERIAL=1
+AM_CPPFLAGS = -DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
+	-DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
+	-DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \
+	-DUSE_MD5_PASSWORDS=1 -DSUPPORT_HERCULES=1 \
+	$(SERIAL_FLAGS) -I$(top_srcdir)/stage2 \
+	-I$(top_srcdir)/stage1 -I$(top_srcdir)/lib
+
+AM_CFLAGS = $(GRUB_CFLAGS)
+grub_SOURCES = main.c asmstub.c
+grub_LDADD = ../stage2/libgrub.a  ../lib/libcommon.a $(GRUB_LIBS)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  grub/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu  grub/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	test -z "$(sbindir)" || $(mkdir_p) "$(DESTDIR)$(sbindir)"
+	@list='$(sbin_PROGRAMS)'; for p in $$list; do \
+	  p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+	  if test -f $$p \
+	  ; then \
+	    f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+	   echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+	   $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \
+	  else :; fi; \
+	done
+
+uninstall-sbinPROGRAMS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(sbin_PROGRAMS)'; for p in $$list; do \
+	  f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+	  echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(sbindir)/$$f"; \
+	done
+
+clean-sbinPROGRAMS:
+	-test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS)
+grub$(EXEEXT): $(grub_OBJECTS) $(grub_DEPENDENCIES) 
+	@rm -f grub$(EXEEXT)
+	$(LINK) $(grub_LDFLAGS) $(grub_OBJECTS) $(grub_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asmstub.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	    $$tags $$unique; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$tags $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+	list='$(DISTFILES)'; for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+	  esac; \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+	    dir="/$$dir"; \
+	    $(mkdir_p) "$(distdir)$$dir"; \
+	  else \
+	    dir=''; \
+	  fi; \
+	  if test -d $$d/$$file; then \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS)
+installdirs:
+	for dir in "$(DESTDIR)$(sbindir)"; do \
+	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-sbinPROGRAMS
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-sbinPROGRAMS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+	clean-sbinPROGRAMS ctags distclean distclean-compile \
+	distclean-generic distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-exec install-exec-am install-info \
+	install-info-am install-man install-sbinPROGRAMS install-strip \
+	installcheck installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+	uninstall-am uninstall-info-am uninstall-sbinPROGRAMS
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/grub/asmstub.c b/grub/asmstub.c
new file mode 100644
index 0000000..ab95b4b
--- /dev/null
+++ b/grub/asmstub.c
@@ -0,0 +1,1275 @@
+/* asmstub.c - a version of shared_src/asm.S that works under Unix */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,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 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.
+ */
+
+/* Try to use glibc's transparant LFS support. */
+#define _LARGEFILE_SOURCE	1
+/* lseek becomes synonymous with lseek64.  */
+#define _FILE_OFFSET_BITS	64
+
+/* Simulator entry point. */
+int grub_stage2 (void);
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <setjmp.h>
+#include <sys/time.h>
+#include <termios.h>
+#include <signal.h>
+
+#ifdef __linux__
+# include <sys/ioctl.h>		/* ioctl */
+# if !defined(__GLIBC__) || \
+	((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))
+/* Maybe libc doesn't have large file support.  */
+#  include <linux/unistd.h>	/* _llseek */
+# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */
+# ifndef BLKFLSBUF
+#  define BLKFLSBUF	_IO (0x12,97)	/* flush buffer cache */
+# endif /* ! BLKFLSBUF */
+#endif /* __linux__ */
+
+/* We want to prevent any circularararity in our stubs, as well as
+   libc name clashes. */
+#define WITHOUT_LIBC_STUBS 1
+#include <shared.h>
+#include <device.h>
+#include <serial.h>
+#include <term.h>
+
+/* Simulated memory sizes. */
+#define EXTENDED_MEMSIZE (3 * 1024 * 1024)	/* 3MB */
+#define CONVENTIONAL_MEMSIZE (640 * 1024)	/* 640kB */
+
+unsigned long install_partition = 0x20000;
+unsigned long boot_drive = 0;
+int saved_entryno = 0;
+char version_string[] = VERSION;
+char config_file[128] = "/boot/grub/menu.lst"; /* FIXME: arbitrary */
+unsigned long linux_text_len = 0;
+char *linux_data_tmp_addr = 0;
+char *linux_data_real_addr = 0;
+unsigned short io_map[IO_MAP_SIZE];
+struct apm_info apm_bios_info;
+
+/* Emulation requirements. */
+char *grub_scratch_mem = 0;
+
+struct geometry *disks = 0;
+
+/* The map between BIOS drives and UNIX device file names.  */
+char **device_map = 0;
+
+/* The jump buffer for exiting correctly.  */
+static jmp_buf env_for_exit;
+
+/* The current color for console.  */
+int console_current_color = A_NORMAL;
+
+/* The file descriptor for a serial device.  */
+static int serial_fd = -1;
+
+/* The file name of a serial device.  */
+static char *serial_device = 0;
+
+#ifdef SIMULATE_SLOWNESS_OF_SERIAL
+/* The speed of a serial device.  */
+static unsigned int serial_speed;
+#endif /* SIMULATE_SLOWNESS_OF_SERIAL */
+
+/* The main entry point into this mess. */
+int
+grub_stage2 (void)
+{
+  /* These need to be static, because they survive our stack transitions. */
+  static int status = 0;
+  static char *realstack;
+  char *scratch, *simstack;
+  int i;
+
+  auto void doit (void);
+  
+  /* We need a nested function so that we get a clean stack frame,
+     regardless of how the code is optimized. */
+  void doit (void)
+    {
+      /* Make sure our stack lives in the simulated memory area. */
+      asm volatile ("movl %%esp, %0\n\tmovl %1, %%esp\n"
+		    : "=&r" (realstack) : "r" (simstack));
+      
+      /* Do a setjmp here for the stop command.  */
+      if (! setjmp (env_for_exit))
+	{
+	  /* Actually enter the generic stage2 code.  */
+	  status = 0;
+	  init_bios_info ();
+	}
+      else
+	{
+	  /* If ERRNUM is non-zero, then set STATUS to non-zero.  */
+	  if (errnum)
+	    status = 1;
+	}
+      
+      /* Replace our stack before we use any local variables. */
+      asm volatile ("movl %0, %%esp\n" : : "r" (realstack));
+    }
+
+  assert (grub_scratch_mem == 0);
+  scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15);
+  assert (scratch);
+  grub_scratch_mem = (char *) ((((int) scratch) >> 4) << 4);
+
+  /* FIXME: simulate the memory holes using mprot, if available. */
+
+  assert (disks == 0);
+  disks = malloc (NUM_DISKS * sizeof (*disks));
+  assert (disks);
+  /* Initialize DISKS.  */
+  for (i = 0; i < NUM_DISKS; i++)
+    disks[i].flags = -1;
+
+  if (! init_device_map (&device_map, device_map_file, floppy_disks))
+    return 1;
+  
+  /* Check some invariants. */
+  assert ((SCRATCHSEG << 4) == SCRATCHADDR);
+  assert ((BUFFERSEG << 4) == BUFFERADDR);
+  assert (BUFFERADDR + BUFFERLEN == SCRATCHADDR);
+  assert (FSYS_BUF % 16 == 0);
+  assert (FSYS_BUF + FSYS_BUFLEN == BUFFERADDR);
+
+#ifdef HAVE_LIBCURSES
+  /* Get into char-at-a-time mode. */
+  if (use_curses)
+    {
+      initscr ();
+      cbreak ();
+      noecho ();
+      nonl ();
+      scrollok (stdscr, TRUE);
+      keypad (stdscr, TRUE);
+      wtimeout (stdscr, 100);
+      signal (SIGWINCH, SIG_IGN);
+    }
+#endif
+
+  /* Make sure that actual writing is done.  */
+  sync ();
+
+  /* Set our stack, and go for it. */
+  simstack = (char *) PROTSTACKINIT;
+  doit ();
+
+  /* I don't know if this is necessary really.  */
+  sync ();
+
+#ifdef HAVE_LIBCURSES
+  if (use_curses)
+    endwin ();
+#endif
+
+  /* Close off the file descriptors we used. */
+  for (i = 0; i < NUM_DISKS; i ++)
+    if (disks[i].flags != -1)
+      {
+#ifdef __linux__
+	/* In Linux, invalidate the buffer cache. In other OSes, reboot
+	   is one of the solutions...  */
+	ioctl (disks[i].flags, BLKFLSBUF, 0);
+#else
+# warning "In your operating system, the buffer cache will not be flushed."
+#endif
+	close (disks[i].flags);
+      }
+
+  if (serial_fd >= 0)
+    close (serial_fd);
+  
+  /* Release memory. */
+  restore_device_map (device_map);
+  device_map = 0;
+  free (disks);
+  disks = 0;
+  free (scratch);
+  grub_scratch_mem = 0;
+
+  if (serial_device)
+    free (serial_device);
+  serial_device = 0;
+  
+  /* Ahh... at last we're ready to return to caller. */
+  return status;
+}
+
+/* Assign DRIVE to a device name DEVICE.  */
+void
+assign_device_name (int drive, const char *device)
+{
+  /* If DRIVE is already assigned, free it.  */
+  if (device_map[drive])
+    free (device_map[drive]);
+
+  /* If the old one is already opened, close it.  */
+  if (disks[drive].flags != -1)
+    {
+      close (disks[drive].flags);
+      disks[drive].flags = -1;
+    }
+
+  /* Assign DRIVE to DEVICE.  */
+  if (! device)
+    device_map[drive] = 0;
+  else
+    device_map[drive] = strdup (device);
+}
+
+void
+stop (void)
+{
+#ifdef HAVE_LIBCURSES
+  if (use_curses)
+    endwin ();
+#endif
+
+  /* Jump to doit.  */
+  longjmp (env_for_exit, 1);
+}
+
+void
+grub_reboot (void)
+{
+  stop ();
+}
+
+void
+grub_halt (int no_apm)
+{
+  stop ();
+}
+
+/* calls for direct boot-loader chaining */
+void
+chain_stage1 (unsigned long segment, unsigned long offset,
+	      unsigned long part_table_addr)
+{
+  stop ();
+}
+
+
+void
+chain_stage2 (unsigned long segment, unsigned long offset, int second_sector)
+{
+  stop ();
+}
+
+
+/* do some funky stuff, then boot linux */
+void
+linux_boot (void)
+{
+  stop ();
+}
+
+
+/* For bzImage kernels. */
+void
+big_linux_boot (void)
+{
+  stop ();
+}
+
+
+/* booting a multiboot executable */
+void
+multi_boot (int start, int mb_info)
+{
+  stop ();
+}
+
+/* sets it to linear or wired A20 operation */
+void
+gateA20 (int linear)
+{
+  /* Nothing to do in the simulator. */
+}
+
+/* Set up the int15 handler.  */
+void
+set_int15_handler (void)
+{
+  /* Nothing to do in the simulator.  */
+}
+
+/* Restore the original int15 handler.  */
+void
+unset_int15_handler (void)
+{
+  /* Nothing to do in the simulator.  */
+}
+
+/* The key map.  */
+unsigned short bios_key_map[KEY_MAP_SIZE + 1];
+unsigned short ascii_key_map[KEY_MAP_SIZE + 1];
+
+/* Copy MAP to the drive map and set up the int13 handler.  */
+void
+set_int13_handler (unsigned short *map)
+{
+  /* Nothing to do in the simulator.  */
+}
+
+int
+get_code_end (void)
+{
+  /* Just return a little area for simulation. */
+  return BOOTSEC_LOCATION + (60 * 1024);
+}
+
+
+/* memory probe routines */
+int
+get_memsize (int type)
+{
+  if (! type)
+    return CONVENTIONAL_MEMSIZE >> 10;
+  else
+    return EXTENDED_MEMSIZE >> 10;
+}
+
+
+/* get_eisamemsize() :  return packed EISA memory map, lower 16 bits is
+ *		memory between 1M and 16M in 1K parts, upper 16 bits is
+ *		memory above 16M in 64K parts.  If error, return -1.
+ */
+int
+get_eisamemsize (void)
+{
+  return (EXTENDED_MEMSIZE >> 10);
+}
+
+
+#define MMAR_DESC_TYPE_AVAILABLE 1 /* available to OS */
+#define MMAR_DESC_TYPE_RESERVED 2 /* not available */
+#define MMAR_DESC_TYPE_ACPI_RECLAIM 3 /* usable by OS after reading ACPI */
+#define MMAR_DESC_TYPE_ACPI_NVS 4 /* required to save between NVS sessions */
+
+#define MMAR_DESC_LENGTH	20
+
+/* Fetch the next entry in the memory map and return the continuation
+   value.  DESC is a pointer to the descriptor buffer, and CONT is the
+   previous continuation value (0 to get the first entry in the
+   map).  */
+int
+get_mmap_entry (struct mmar_desc *desc, int cont)
+{
+  /* Record the memory map statically.  */
+  static struct mmar_desc desc_table[] =
+  {
+    /* The conventional memory.  */
+    {
+      MMAR_DESC_LENGTH,
+      0,
+      CONVENTIONAL_MEMSIZE,
+      MMAR_DESC_TYPE_AVAILABLE
+    },
+    /* BIOS RAM and ROM (such as video memory).  */
+    {
+      MMAR_DESC_LENGTH,
+      CONVENTIONAL_MEMSIZE,
+      0x100000 - CONVENTIONAL_MEMSIZE,
+      MMAR_DESC_TYPE_RESERVED
+    },
+    /* The extended memory.  */
+    {
+      MMAR_DESC_LENGTH,
+      0x100000,
+      EXTENDED_MEMSIZE,
+      MMAR_DESC_TYPE_AVAILABLE
+    }
+  };
+  
+  int num = sizeof (desc_table) / sizeof (*desc_table);
+
+  if (cont < 0 || cont >= num)
+    {
+      /* Should not happen.  */
+      desc->desc_len = 0;
+    }
+  else
+    {
+      /* Copy the entry.  */
+      *desc = desc_table[cont++];
+
+      /* If the next entry exists, return the index.  */
+      if (cont < num)
+	return cont;
+    }
+  
+  return 0;
+}
+
+/* Track the int13 handler.  */
+void
+track_int13 (int drive)
+{
+  /* Nothing to do in the simulator.  */
+}
+
+/* Get the ROM configuration table.  */
+unsigned long
+get_rom_config_table (void)
+{
+  return 0;
+}
+
+/* Get APM BIOS information.  */
+void
+get_apm_info (void)
+{
+  /* Nothing to do in the simulator.  */
+}
+
+/* Get VBE controller information.  */
+int
+get_vbe_controller_info (struct vbe_controller *controller)
+{
+  /* Always fails.  */
+  return 0;
+}
+
+/* Get VBE mode information.  */
+int
+get_vbe_mode_info (int mode_number, struct vbe_mode *mode)
+{
+  /* Always fails.  */
+  return 0;
+}
+
+/* Set VBE mode.  */
+int
+set_vbe_mode (int mode_number)
+{
+  /* Always fails.  */
+  return 0;
+}
+
+/* low-level timing info */
+int
+getrtsecs (void)
+{
+  /* FIXME: exact value is not important, so just return time_t for now. */
+  return time (0);
+}
+
+int
+currticks (void)
+{
+  struct timeval tv;
+  long csecs;
+  int ticks_per_csec, ticks_per_usec;
+
+  /* Note: 18.2 ticks/sec.  */
+
+  /* Get current time.  */
+  gettimeofday (&tv, 0);
+
+  /* Compute centiseconds.  */
+  csecs = tv.tv_sec / 10;
+
+  /* Ticks per centisecond.  */
+  ticks_per_csec = csecs * 182;
+
+  /* Ticks per microsecond.  */
+  ticks_per_usec = (((tv.tv_sec - csecs * 10) * 1000000 + tv.tv_usec)
+		    * 182 / 10000000);
+
+  /* Sum them.  */
+  return ticks_per_csec + ticks_per_usec;
+}
+
+/* displays an ASCII character.  IBM displays will translate some
+   characters to special graphical ones */
+void
+console_putchar (int c)
+{
+  /* Curses doesn't have VGA fonts.  */
+  switch (c)
+    {
+    case DISP_UL:
+      c = ACS_ULCORNER;
+      break;
+    case DISP_UR:
+      c = ACS_URCORNER;
+      break;
+    case DISP_LL:
+      c = ACS_LLCORNER;
+      break;
+    case DISP_LR:
+      c = ACS_LRCORNER;
+      break;
+    case DISP_HORIZ:
+      c = ACS_HLINE;
+      break;
+    case DISP_VERT:
+      c = ACS_VLINE;
+      break;
+    case DISP_LEFT:
+      c = ACS_LARROW;
+      break;
+    case DISP_RIGHT:
+      c = ACS_RARROW;
+      break;
+    case DISP_UP:
+      c = ACS_UARROW;
+      break;
+    case DISP_DOWN:
+      c = ACS_DARROW;
+      break;
+    default:
+      break;
+    }
+
+#ifdef HAVE_LIBCURSES
+  if (use_curses)
+    {
+      /* In ncurses, a newline is treated badly, so we emulate it in our
+	 own way.  */
+      if (c == '\n')
+	{
+	  int x, y;
+
+	  getyx (stdscr, y, x);
+	  if (y + 1 == LINES)
+	    scroll (stdscr);
+	  else
+	    move (y + 1, x);
+	}
+      else if (isprint (c))
+	{
+	  int x, y;
+
+	  getyx (stdscr, y, x);
+	  if (x + 1 == COLS)
+	    {
+	      console_putchar ('\r');
+	      console_putchar ('\n');
+	    }
+	  addch (c | console_current_color);
+	}
+      else
+	{
+	  addch (c);
+	}
+      
+#ifdef REFRESH_IMMEDIATELY
+      refresh ();
+#endif
+    }
+  else
+#endif
+    {
+      /* CR is not used in Unix.  */
+      if (c != '\r')
+	putchar (c);
+    }
+}
+
+/* The store for ungetch simulation. This is necessary, because
+   ncurses-1.9.9g is still used in the world and its ungetch is
+   completely broken.  */
+#ifdef HAVE_LIBCURSES
+static int save_char = ERR;
+#endif
+
+static int
+console_translate_key (int c)
+{
+  switch (c)
+    {
+    case KEY_LEFT:
+      return 2;
+    case KEY_RIGHT:
+      return 6;
+    case KEY_UP:
+      return 16;
+    case KEY_DOWN:
+      return 14;
+    case KEY_DC:
+      return 4;
+    case KEY_BACKSPACE:
+      return 8;
+    case KEY_HOME:
+      return 1;
+    case KEY_END:
+      return 5;
+    case KEY_PPAGE:
+      return 7;
+    case KEY_NPAGE:
+      return 3;
+    default:
+      break;
+    }
+
+  return c;
+}
+
+/* like 'getkey', but doesn't wait, returns -1 if nothing available */
+int
+console_checkkey (void)
+{
+#ifdef HAVE_LIBCURSES
+  if (use_curses)
+    {
+      int c;
+
+      /* Check for SAVE_CHAR. This should not be true, because this
+	 means checkkey is called twice continuously.  */
+      if (save_char != ERR)
+	return save_char;
+
+      c = getch ();
+      /* If C is not ERR, then put it back in the input queue.  */
+      if (c != ERR)
+	save_char = c;
+      return console_translate_key (c);
+    }
+#endif
+
+  /* Just pretend they hit the space bar, then read the real key when
+     they call getkey. */
+  return ' ';
+}
+
+/* returns packed BIOS/ASCII code */
+int
+console_getkey (void)
+{
+  int c;
+
+#ifdef HAVE_LIBCURSES
+  if (use_curses)
+    {
+      /* If checkkey has already got a character, then return it.  */
+      if (save_char != ERR)
+	{
+	  c = save_char;
+	  save_char = ERR;
+	  return console_translate_key (c);
+	}
+
+      wtimeout (stdscr, -1);
+      c = getch ();
+      wtimeout (stdscr, 100);
+    }
+  else
+#endif
+    c = getchar ();
+
+  /* Quit if we get EOF. */
+  if (c == -1)
+    stop ();
+  
+  return console_translate_key (c);
+}
+
+/* returns packed values, LSB+1 is x, LSB is y */
+int
+console_getxy (void)
+{
+  int y, x;
+#ifdef HAVE_LIBCURSES
+  if (use_curses)
+    getyx (stdscr, y, x);
+  else
+#endif
+  y = x = 0;
+  return (x << 8) | (y & 0xff);
+}
+
+void
+console_gotoxy (int x, int y)
+{
+#ifdef HAVE_LIBCURSES
+  if (use_curses)
+    move (y, x);
+#endif
+}
+
+/* low-level character I/O */
+void
+console_cls (void)
+{
+#ifdef HAVE_LIBCURSES
+  if (use_curses)
+    clear ();
+#endif
+}
+
+void
+console_setcolorstate (color_state state)
+{
+  console_current_color = 
+    (state == COLOR_STATE_HIGHLIGHT) ? A_REVERSE : A_NORMAL;
+}
+
+void
+console_setcolor (int normal_color, int highlight_color)
+{
+  /* Nothing to do.  */
+}
+
+int
+console_setcursor (int on)
+{
+  return 1;
+}
+
+/* Low-level disk I/O.  Our stubbed version just returns a file
+   descriptor, not the actual geometry. */
+int
+get_diskinfo (int drive, struct geometry *geometry)
+{
+  /* FIXME: this function is truly horrid.  We try opening the device,
+     then severely abuse the GEOMETRY->flags field to pass a file
+     descriptor to biosdisk.  Thank God nobody's looking at this comment,
+     or my reputation would be ruined. --Gord */
+
+  /* See if we have a cached device. */
+  if (disks[drive].flags == -1)
+    {
+      /* The unpartitioned device name: /dev/XdX */
+      char *devname = device_map[drive];
+      char buf[512];
+
+      if (! devname)
+	return -1;
+
+      if (verbose)
+	grub_printf ("Attempt to open drive 0x%x (%s)\n",
+		     drive, devname);
+
+      /* Open read/write, or read-only if that failed. */
+      if (! read_only)
+	disks[drive].flags = open (devname, O_RDWR);
+
+      if (disks[drive].flags == -1)
+	{
+	  if (read_only || errno == EACCES || errno == EROFS || errno == EPERM)
+	    {
+	      disks[drive].flags = open (devname, O_RDONLY);
+	      if (disks[drive].flags == -1)
+		{
+		  assign_device_name (drive, 0);
+		  return -1;
+		}
+	    }
+	  else
+	    {
+	      assign_device_name (drive, 0);
+	      return -1;
+	    }
+	}
+
+      /* Attempt to read the first sector.  */
+      if (read (disks[drive].flags, buf, 512) != 512)
+	{
+	  close (disks[drive].flags);
+	  disks[drive].flags = -1;
+	  assign_device_name (drive, 0);
+	  return -1;
+	}
+
+      if (disks[drive].flags != -1)
+	get_drive_geometry (&disks[drive], device_map, drive);
+    }
+
+  if (disks[drive].flags == -1)
+    return -1;
+
+#ifdef __linux__
+  /* In Linux, invalidate the buffer cache, so that left overs
+     from other program in the cache are flushed and seen by us */
+  ioctl (disks[drive].flags, BLKFLSBUF, 0);
+#endif
+
+  *geometry = disks[drive];
+  return 0;
+}
+
+/* Read LEN bytes from FD in BUF. Return less than or equal to zero if an
+   error occurs, otherwise return LEN.  */
+static int
+nread (int fd, char *buf, size_t len)
+{
+  int size = len;
+
+  while (len)
+    {
+      int ret = read (fd, buf, len);
+
+      if (ret <= 0)
+	{
+	  if (errno == EINTR)
+	    continue;
+	  else
+	    return ret;
+	}
+
+      len -= ret;
+      buf += ret;
+    }
+
+  return size;
+}
+
+/* Write LEN bytes from BUF to FD. Return less than or equal to zero if an
+   error occurs, otherwise return LEN.  */
+static int
+nwrite (int fd, char *buf, size_t len)
+{
+  int size = len;
+
+  while (len)
+    {
+      int ret = write (fd, buf, len);
+
+      if (ret <= 0)
+	{
+	  if (errno == EINTR)
+	    continue;
+	  else
+	    return ret;
+	}
+
+      len -= ret;
+      buf += ret;
+    }
+
+  return size;
+}
+
+/* Dump BUF in the format of hexadecimal numbers.  */
+static void
+hex_dump (void *buf, size_t size)
+{
+  /* FIXME: How to determine which length is readable?  */
+#define MAX_COLUMN	70
+
+  /* use unsigned char for numerical computations */
+  unsigned char *ptr = buf;
+  /* count the width of the line */
+  int column = 0;
+  /* how many bytes written */
+  int count = 0;
+
+  while (size > 0)
+    {
+      /* high 4 bits */
+      int hi = *ptr >> 4;
+      /* low 4 bits */
+      int low = *ptr & 0xf;
+
+      /* grub_printf does not handle prefix number, such as %2x, so
+	 format the number by hand...  */
+      grub_printf ("%x%x", hi, low);
+      column += 2;
+      count++;
+      ptr++;
+      size--;
+
+      /* Insert space or newline with the interval 4 bytes.  */
+      if (size != 0 && (count % 4) == 0)
+	{
+	  if (column < MAX_COLUMN)
+	    {
+	      grub_printf (" ");
+	      column++;
+	    }
+	  else
+	    {
+	      grub_printf ("\n");
+	      column = 0;
+	    }
+	}
+    }
+
+  /* Add a newline at the end for readability.  */
+  grub_printf ("\n");
+}
+
+int
+biosdisk (int subfunc, int drive, struct geometry *geometry,
+	  int sector, int nsec, int segment)
+{
+  char *buf;
+  int fd = geometry->flags;
+
+  /* Get the file pointer from the geometry, and make sure it matches. */
+  if (fd == -1 || fd != disks[drive].flags)
+    return BIOSDISK_ERROR_GEOMETRY;
+
+  /* Seek to the specified location. */
+#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))
+      return -1;
+  }
+#else
+  {
+    off_t offset = (off_t) sector * (off_t) SECTOR_SIZE;
+
+    if (lseek (fd, offset, SEEK_SET) != offset)
+      return -1;
+  }
+#endif
+
+  buf = (char *) (segment << 4);
+
+  switch (subfunc)
+    {
+    case BIOSDISK_READ:
+#ifdef __linux__
+      if (sector == 0 && nsec > 1)
+	{
+	  /* Work around a bug in linux's ez remapping.  Linux remaps all
+	     sectors that are read together with the MBR in one read.  It
+	     should only remap the MBR, so we split the read in two 
+	     parts. -jochen  */
+	  if (nread (fd, buf, SECTOR_SIZE) != SECTOR_SIZE)
+	    return -1;
+	  buf += SECTOR_SIZE;
+	  nsec--;
+	}
+#endif
+      if (nread (fd, buf, nsec * SECTOR_SIZE) != nsec * SECTOR_SIZE)
+	return -1;
+      break;
+
+    case BIOSDISK_WRITE:
+      if (verbose)
+	{
+	  grub_printf ("Write %d sectors starting from %d sector"
+		       " to drive 0x%x (%s)\n",
+		       nsec, sector, drive, device_map[drive]);
+	  hex_dump (buf, nsec * SECTOR_SIZE);
+	}
+      if (! read_only)
+	if (nwrite (fd, buf, nsec * SECTOR_SIZE) != nsec * SECTOR_SIZE)
+	  return -1;
+      break;
+
+    default:
+      grub_printf ("unknown subfunc %d\n", subfunc);
+      break;
+    }
+
+  return 0;
+}
+
+
+void
+stop_floppy (void)
+{
+  /* NOTUSED */
+}
+
+/* Fetch a key from a serial device.  */
+int
+serial_hw_fetch (void)
+{
+  fd_set fds;
+  struct timeval to;
+  char c;
+
+  /* Wait only for the serial device.  */
+  FD_ZERO (&fds);
+  FD_SET (serial_fd, &fds);
+
+  to.tv_sec = 0;
+  to.tv_usec = 0;
+  
+  if (select (serial_fd + 1, &fds, 0, 0, &to) > 0)
+    {
+      if (nread (serial_fd, &c, 1) != 1)
+	stop ();
+
+      return c;
+    }
+  
+  return -1;
+}
+
+/* Put a character to a serial device.  */
+void
+serial_hw_put (int c)
+{
+  char ch = (char) c;
+  
+  if (nwrite (serial_fd, &ch, 1) != 1)
+    stop ();
+}
+
+void
+serial_hw_delay (void)
+{
+#ifdef SIMULATE_SLOWNESS_OF_SERIAL
+  struct timeval otv, tv;
+
+  gettimeofday (&otv, 0);
+
+  while (1)
+    {
+      long delta;
+      
+      gettimeofday (&tv, 0);
+      delta = tv.tv_usec - otv.tv_usec;
+      if (delta < 0)
+	delta += 1000000;
+      
+      if (delta >= 1000000 / (serial_speed >> 3))
+	break;
+    }
+#endif /* SIMULATE_SLOWNESS_OF_SERIAL */
+}
+
+static speed_t
+get_termios_speed (int speed)
+{
+  switch (speed)
+    {
+    case 2400: return B2400;
+    case 4800: return B4800;
+    case 9600: return B9600;
+    case 19200: return B19200;
+    case 38400: return B38400;
+#ifdef B57600
+    case 57600: return B57600;
+#endif
+#ifdef B115200      
+    case 115200: return B115200;
+#endif
+    }
+
+  return B0;
+}
+
+/* Get the port number of the unit UNIT. In the grub shell, this doesn't
+   make sense.  */
+unsigned short
+serial_hw_get_port (int unit)
+{
+  return 0;
+}
+
+/* Initialize a serial device. In the grub shell, PORT is unused.  */
+int
+serial_hw_init (unsigned short port, unsigned int speed,
+		int word_len, int parity, int stop_bit_len)
+{
+  struct termios termios;
+  speed_t termios_speed;
+  int i;
+  
+  /* Check if the file name is specified.  */
+  if (! serial_device)
+    return 0;
+
+  /* If a serial device is already opened, close it first.  */
+  if (serial_fd >= 0)
+    close (serial_fd);
+  
+  /* Open the device file.  */
+  serial_fd = open (serial_device,
+		    O_RDWR | O_NOCTTY
+#if defined(O_SYNC)
+		    /* O_SYNC is used in Linux (and some others?).  */
+		    | O_SYNC
+#elif defined(O_FSYNC)
+		    /* O_FSYNC is used in FreeBSD.  */
+		    | O_FSYNC
+#endif
+		    );
+  if (serial_fd < 0)
+    return 0;
+
+  /* Get the termios parameters.  */
+  if (tcgetattr (serial_fd, &termios))
+    goto fail;
+
+  /* Raw mode.  */
+  cfmakeraw (&termios);
+
+  /* Set the speed.  */
+  termios_speed = get_termios_speed (speed);
+  if (termios_speed == B0)
+    goto fail;
+  
+  cfsetispeed (&termios, termios_speed);
+  cfsetospeed (&termios, termios_speed);
+
+  /* Set the word length.  */
+  termios.c_cflag &= ~CSIZE;
+  switch (word_len)
+    {
+    case UART_5BITS_WORD:
+      termios.c_cflag |= CS5;
+      break;
+    case UART_6BITS_WORD:
+      termios.c_cflag |= CS6;
+      break;
+    case UART_7BITS_WORD:
+      termios.c_cflag |= CS7;
+      break;
+    case UART_8BITS_WORD:
+      termios.c_cflag |= CS8;
+      break;
+    default:
+      goto fail;
+    }
+
+  /* Set the parity.  */
+  switch (parity)
+    {
+    case UART_NO_PARITY:
+      termios.c_cflag &= ~PARENB;
+      break;
+    case UART_ODD_PARITY:
+      termios.c_cflag |= PARENB;
+      termios.c_cflag |= PARODD;
+      break;
+    case UART_EVEN_PARITY:
+      termios.c_cflag |= PARENB;
+      termios.c_cflag &= ~PARODD;
+      break;
+    default:
+      goto fail;
+    }
+
+  /* Set the length of stop bit.  */
+  switch (stop_bit_len)
+    {
+    case UART_1_STOP_BIT:
+      termios.c_cflag &= ~CSTOPB;
+      break;
+    case UART_2_STOP_BITS:
+      termios.c_cflag |= CSTOPB;
+      break;
+    default:
+      goto fail;
+    }
+
+  /* Set the parameters.  */
+  if (tcsetattr (serial_fd, TCSANOW, &termios))
+    goto fail;
+
+#ifdef SIMULATE_SLOWNESS_OF_SERIAL
+  serial_speed = speed;
+#endif /* SIMUATE_SLOWNESS_OF_SERIAL */
+
+  /* Get rid of the flag TERM_NEED_INIT from the serial terminal.  */
+  for (i = 0; term_table[i].name; i++)
+    {
+      if (strcmp (term_table[i].name, "serial") == 0)
+	{
+	  term_table[i].flags &= ~(TERM_NEED_INIT);
+	  break;
+	}
+    }
+  
+  return 1;
+
+ fail:
+  close (serial_fd);
+  serial_fd = -1;
+  return 0;
+}
+
+/* Set the file name of a serial device (or a pty device). This is a
+   function specific to the grub shell.  */
+void
+serial_set_device (const char *device)
+{
+  if (serial_device)
+    free (serial_device);
+  
+  serial_device = strdup (device);
+}
+
+/* There is no difference between console and hercules in the grub shell.  */
+void
+hercules_putchar (int c)
+{
+  console_putchar (c);
+}
+
+int
+hercules_getxy (void)
+{
+  return console_getxy ();
+}
+
+void
+hercules_gotoxy (int x, int y)
+{
+  console_gotoxy (x, y);
+}
+
+void
+hercules_cls (void)
+{
+  console_cls ();
+}
+
+void
+hercules_setcolorstate (color_state state)
+{
+  console_setcolorstate (state);
+}
+
+void
+hercules_setcolor (int normal_color, int highlight_color)
+{
+  console_setcolor (normal_color, highlight_color);
+}
+
+int
+hercules_setcursor (int on)
+{
+  return 1;
+}
diff --git a/grub/main.c b/grub/main.c
new file mode 100644
index 0000000..dfe847e
--- /dev/null
+++ b/grub/main.c
@@ -0,0 +1,265 @@
+/* main.c - experimental GRUB stage2 that runs under Unix */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,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.
+ */
+
+/* Simulator entry point. */
+int grub_stage2 (void);
+
+#include <stdio.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <setjmp.h>
+
+#define WITHOUT_LIBC_STUBS 1
+#include <shared.h>
+#include <term.h>
+
+char *program_name = 0;
+int use_config_file = 1;
+int use_preset_menu = 0;
+#ifdef HAVE_LIBCURSES
+int use_curses = 1;
+#else
+int use_curses = 0;
+#endif
+int verbose = 0;
+int read_only = 0;
+int floppy_disks = 1;
+char *device_map_file = 0;
+static int default_boot_drive;
+static int default_install_partition;
+static char *default_config_file;
+
+#define OPT_HELP		-2
+#define OPT_VERSION		-3
+#define OPT_HOLD		-4
+#define OPT_CONFIG_FILE		-5
+#define OPT_INSTALL_PARTITION	-6
+#define OPT_BOOT_DRIVE		-7
+#define OPT_NO_CONFIG_FILE	-8
+#define OPT_NO_CURSES		-9
+#define OPT_BATCH		-10
+#define OPT_VERBOSE		-11
+#define OPT_READ_ONLY		-12
+#define OPT_PROBE_SECOND_FLOPPY	-13
+#define OPT_NO_FLOPPY		-14
+#define OPT_DEVICE_MAP		-15
+#define OPT_PRESET_MENU		-16
+#define OPT_NO_PAGER		-17
+#define OPTSTRING ""
+
+static struct option longopts[] =
+{
+  {"batch", no_argument, 0, OPT_BATCH},
+  {"boot-drive", required_argument, 0, OPT_BOOT_DRIVE},
+  {"config-file", required_argument, 0, OPT_CONFIG_FILE},
+  {"device-map", required_argument, 0, OPT_DEVICE_MAP},
+  {"help", no_argument, 0, OPT_HELP},
+  {"hold", optional_argument, 0, OPT_HOLD},
+  {"install-partition", required_argument, 0, OPT_INSTALL_PARTITION},
+  {"no-config-file", no_argument, 0, OPT_NO_CONFIG_FILE},
+  {"no-curses", no_argument, 0, OPT_NO_CURSES},
+  {"no-floppy", no_argument, 0, OPT_NO_FLOPPY},
+  {"no-pager", no_argument, 0, OPT_NO_PAGER},
+  {"preset-menu", no_argument, 0, OPT_PRESET_MENU},
+  {"probe-second-floppy", no_argument, 0, OPT_PROBE_SECOND_FLOPPY},
+  {"read-only", no_argument, 0, OPT_READ_ONLY},
+  {"verbose", no_argument, 0, OPT_VERBOSE},
+  {"version", no_argument, 0, OPT_VERSION},
+  {0},
+};
+
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr, "Try ``grub --help'' for more information.\n");
+  else
+    printf ("\
+Usage: grub [OPTION]...\n\
+\n\
+Enter the GRand Unified Bootloader command shell.\n\
+\n\
+    --batch                  turn on batch mode for non-interactive use\n\
+    --boot-drive=DRIVE       specify stage2 boot_drive [default=0x%x]\n\
+    --config-file=FILE       specify stage2 config_file [default=%s]\n\
+    --device-map=FILE        use the device map file FILE\n\
+    --help                   display this message and exit\n\
+    --hold                   wait until a debugger will attach\n\
+    --install-partition=PAR  specify stage2 install_partition [default=0x%x]\n\
+    --no-config-file         do not use the config file\n\
+    --no-curses              do not use curses\n\
+    --no-floppy              do not probe any floppy drive\n\
+    --no-pager               do not use internal pager\n\
+    --preset-menu            use the preset menu\n\
+    --probe-second-floppy    probe the second floppy drive\n\
+    --read-only              do not write anything to devices\n\
+    --verbose                print verbose messages\n\
+    --version                print version information and exit\n\
+\n\
+Report bugs to <bug-grub@gnu.org>.\n\
+",
+	    default_boot_drive, default_config_file,
+	    default_install_partition);
+
+  exit (status);
+}
+
+
+int
+main (int argc, char **argv)
+{
+  int c;
+  int hold = 0;
+
+  /* First of all, call sync so that all in-core data is scheduled to be
+     actually written to disks. This is very important because GRUB does
+     not use ordinary stdio interface but raw devices.  */
+  sync ();
+  
+  program_name = argv[0];
+  default_boot_drive = boot_drive;
+  default_install_partition = install_partition;
+  if (config_file)
+    default_config_file = config_file;
+  else
+    default_config_file = "NONE";
+  
+  /* Parse command-line options. */
+  do
+    {
+      c = getopt_long (argc, argv, OPTSTRING, longopts, 0);
+      switch (c)
+	{
+	case EOF:
+	  /* Fall through the bottom of the loop. */
+	  break;
+
+	case OPT_HELP:
+	  usage (0);
+	  break;
+
+	case OPT_VERSION:
+	  printf ("grub (GNU GRUB " VERSION ")\n");
+	  exit (0);
+	  break;
+
+	case OPT_HOLD:
+	  if (! optarg)
+	    hold = -1;
+	  else
+	    hold = atoi (optarg);
+	  break;
+
+	case OPT_CONFIG_FILE:
+	  strncpy (config_file, optarg, 127); /* FIXME: arbitrary */
+	  config_file[127] = '\0';
+	  break;
+
+	case OPT_INSTALL_PARTITION:
+	  install_partition = strtoul (optarg, 0, 0);
+	  if (install_partition == ULONG_MAX)
+	    {
+	      perror ("strtoul");
+	      exit (1);
+	    }
+	  break;
+
+	case OPT_BOOT_DRIVE:
+	  boot_drive = strtoul (optarg, 0, 0);
+	  if (boot_drive == ULONG_MAX)
+	    {
+	      perror ("strtoul");
+	      exit (1);
+	    }
+	  break;
+
+	case OPT_NO_CONFIG_FILE:
+	  use_config_file = 0;
+	  break;
+
+	case OPT_NO_CURSES:
+	  use_curses = 0;
+	  break;
+
+	case OPT_NO_PAGER:
+	  use_pager = 0;
+	  break;
+
+	case OPT_BATCH:
+	  /* This is the same as "--no-config-file --no-curses --no-pager".  */
+	  use_config_file = 0;
+	  use_curses = 0;
+	  use_pager = 0;
+	  break;
+
+	case OPT_READ_ONLY:
+	  read_only = 1;
+	  break;
+
+	case OPT_VERBOSE:
+	  verbose = 1;
+	  break;
+
+	case OPT_NO_FLOPPY:
+	  floppy_disks = 0;
+	  break;
+
+	case OPT_PROBE_SECOND_FLOPPY:
+	  floppy_disks = 2;
+	  break;
+
+	case OPT_DEVICE_MAP:
+	  device_map_file = strdup (optarg);
+	  break;
+
+	case OPT_PRESET_MENU:
+	  use_preset_menu = 1;
+	  break;
+	  
+	default:
+	  usage (1);
+	}
+    }
+  while (c != EOF);
+
+  /* Wait until the HOLD variable is cleared by an attached debugger. */
+  if (hold && verbose)
+    printf ("Run \"gdb %s %d\", and set HOLD to zero.\n",
+	    program_name, (int) getpid ());
+  while (hold)
+    {
+      if (hold > 0)
+	hold--;
+      
+      sleep (1);
+    }
+
+  /* If we don't have curses (!HAVE_LIBCURSES or --no-curses or
+     --batch) put terminal to dumb for better handling of line i/o */
+  if (! use_curses)
+    current_term->flags = TERM_NO_EDIT | TERM_DUMB;
+
+  /* Transfer control to the stage2 simulator. */
+  exit (grub_stage2 ());
+}
diff --git a/install-sh b/install-sh
new file mode 100755
index 0000000..6ebe46d
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,323 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2004-12-17.09
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+chmodcmd="$chmodprog 0755"
+chowncmd=
+chgrpcmd=
+stripcmd=
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=
+dst=
+dir_arg=
+dstarg=
+no_target_directory=
+
+usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+-c         (ignored)
+-d         create directories instead of installing files.
+-g GROUP   $chgrpprog installed files to GROUP.
+-m MODE    $chmodprog installed files to MODE.
+-o USER    $chownprog installed files to USER.
+-s         $stripprog installed files.
+-t DIRECTORY  install into DIRECTORY.
+-T         report an error if DSTFILE is a directory.
+--help     display this help and exit.
+--version  display version info and exit.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
+
+while test -n "$1"; do
+  case $1 in
+    -c) shift
+        continue;;
+
+    -d) dir_arg=true
+        shift
+        continue;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+        shift
+        shift
+        continue;;
+
+    --help) echo "$usage"; exit 0;;
+
+    -m) chmodcmd="$chmodprog $2"
+        shift
+        shift
+        continue;;
+
+    -o) chowncmd="$chownprog $2"
+        shift
+        shift
+        continue;;
+
+    -s) stripcmd=$stripprog
+        shift
+        continue;;
+
+    -t) dstarg=$2
+	shift
+	shift
+	continue;;
+
+    -T) no_target_directory=true
+	shift
+	continue;;
+
+    --version) echo "$0 $scriptversion"; exit 0;;
+
+    *)  # When -d is used, all remaining arguments are directories to create.
+	# When -t is used, the destination is already specified.
+	test -n "$dir_arg$dstarg" && break
+        # Otherwise, the last argument is the destination.  Remove it from $@.
+	for arg
+	do
+          if test -n "$dstarg"; then
+	    # $@ is not empty: it contains at least $arg.
+	    set fnord "$@" "$dstarg"
+	    shift # fnord
+	  fi
+	  shift # arg
+	  dstarg=$arg
+	done
+	break;;
+  esac
+done
+
+if test -z "$1"; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src ;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    src=
+
+    if test -d "$dst"; then
+      mkdircmd=:
+      chmodcmd=
+    else
+      mkdircmd=$mkdirprog
+    fi
+  else
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dstarg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dstarg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst ;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dstarg: Is a directory" >&2
+	exit 1
+      fi
+      dst=$dst/`basename "$src"`
+    fi
+  fi
+
+  # This sed command emulates the dirname command.
+  dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
+
+  # Make sure that the destination directory exists.
+
+  # Skip lots of stat calls in the usual case.
+  if test ! -d "$dstdir"; then
+    defaultIFS='
+	 '
+    IFS="${IFS-$defaultIFS}"
+
+    oIFS=$IFS
+    # Some sh's can't handle IFS=/ for some reason.
+    IFS='%'
+    set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+    shift
+    IFS=$oIFS
+
+    pathcomp=
+
+    while test $# -ne 0 ; do
+      pathcomp=$pathcomp$1
+      shift
+      if test ! -d "$pathcomp"; then
+        $mkdirprog "$pathcomp"
+	# mkdir can fail with a `File exist' error in case several
+	# install-sh are creating the directory concurrently.  This
+	# is OK.
+	test -d "$pathcomp" || exit
+      fi
+      pathcomp=$pathcomp/
+    done
+  fi
+
+  if test -n "$dir_arg"; then
+    $doit $mkdircmd "$dst" \
+      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
+
+  else
+    dstfile=`basename "$dst"`
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+    trap '(exit $?); exit' 1 2 13 15
+
+    # Copy the file name to the temp name.
+    $doit $cpprog "$src" "$dsttmp" &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
+
+    # Now rename the file to the real destination.
+    { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
+      || {
+	   # The rename failed, perhaps because mv can't rename something else
+	   # to itself, or perhaps because mv is so ancient that it does not
+	   # support -f.
+
+	   # Now remove or move aside any old file at destination location.
+	   # We try this two ways since rm can't unlink itself on some
+	   # systems and the destination file might be busy for other
+	   # reasons.  In this case, the final cleanup might fail but the new
+	   # file should still install successfully.
+	   {
+	     if test -f "$dstdir/$dstfile"; then
+	       $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
+	       || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
+	       || {
+		 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+		 (exit 1); exit 1
+	       }
+	     else
+	       :
+	     fi
+	   } &&
+
+	   # Now rename the file to the real destination.
+	   $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+	 }
+    }
+  fi || { (exit 1); exit 1; }
+done
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+{
+  (exit 0); exit 0
+}
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/lib/Makefile.am b/lib/Makefile.am
new file mode 100644
index 0000000..645a03f
--- /dev/null
+++ b/lib/Makefile.am
@@ -0,0 +1,6 @@
+noinst_LIBRARIES = libcommon.a
+
+AM_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/stage2 \
+	-I$(top_srcdir)/stage1
+
+libcommon_a_SOURCES = getopt.c getopt1.c getopt.h device.c device.h
diff --git a/lib/Makefile.in b/lib/Makefile.in
new file mode 100644
index 0000000..3dae206
--- /dev/null
+++ b/lib/Makefile.in
@@ -0,0 +1,416 @@
+# Makefile.in generated by automake 1.9.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  Free Software Foundation, Inc.
+# This Makefile.in 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 distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+SOURCES = $(libcommon_a_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = lib
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+AR = ar
+ARFLAGS = cru
+libcommon_a_AR = $(AR) $(ARFLAGS)
+libcommon_a_LIBADD =
+am_libcommon_a_OBJECTS = getopt.$(OBJEXT) getopt1.$(OBJEXT) \
+	device.$(OBJEXT)
+libcommon_a_OBJECTS = $(am_libcommon_a_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libcommon_a_SOURCES)
+DIST_SOURCES = $(libcommon_a_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_EXAMPLE_KERNEL_FALSE = @BUILD_EXAMPLE_KERNEL_FALSE@
+BUILD_EXAMPLE_KERNEL_TRUE = @BUILD_EXAMPLE_KERNEL_TRUE@
+CC = @CC@
+CCAS = @CCAS@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISKLESS_SUPPORT_FALSE = @DISKLESS_SUPPORT_FALSE@
+DISKLESS_SUPPORT_TRUE = @DISKLESS_SUPPORT_TRUE@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FSYS_CFLAGS = @FSYS_CFLAGS@
+GRUB_CFLAGS = @GRUB_CFLAGS@
+GRUB_LIBS = @GRUB_LIBS@
+HERCULES_SUPPORT_FALSE = @HERCULES_SUPPORT_FALSE@
+HERCULES_SUPPORT_TRUE = @HERCULES_SUPPORT_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
+NETBOOT_SUPPORT_FALSE = @NETBOOT_SUPPORT_FALSE@
+NETBOOT_SUPPORT_TRUE = @NETBOOT_SUPPORT_TRUE@
+NET_CFLAGS = @NET_CFLAGS@
+NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
+OBJCOPY = @OBJCOPY@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+RANLIB = @RANLIB@
+SERIAL_SPEED_SIMULATION_FALSE = @SERIAL_SPEED_SIMULATION_FALSE@
+SERIAL_SPEED_SIMULATION_TRUE = @SERIAL_SPEED_SIMULATION_TRUE@
+SERIAL_SUPPORT_FALSE = @SERIAL_SUPPORT_FALSE@
+SERIAL_SUPPORT_TRUE = @SERIAL_SUPPORT_TRUE@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STAGE1_CFLAGS = @STAGE1_CFLAGS@
+STAGE2_CFLAGS = @STAGE2_CFLAGS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_OBJCOPY = @ac_ct_OBJCOPY@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+noinst_LIBRARIES = libcommon.a
+AM_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/stage2 \
+	-I$(top_srcdir)/stage1
+
+libcommon_a_SOURCES = getopt.c getopt1.c getopt.h device.c device.h
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  lib/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu  lib/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libcommon.a: $(libcommon_a_OBJECTS) $(libcommon_a_DEPENDENCIES) 
+	-rm -f libcommon.a
+	$(libcommon_a_AR) libcommon.a $(libcommon_a_OBJECTS) $(libcommon_a_LIBADD)
+	$(RANLIB) libcommon.a
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/device.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/getopt1.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	    $$tags $$unique; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$tags $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+	list='$(DISTFILES)'; for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+	  esac; \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+	    dir="/$$dir"; \
+	    $(mkdir_p) "$(distdir)$$dir"; \
+	  else \
+	    dir=''; \
+	  fi; \
+	  if test -d $$d/$$file; then \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+	clean-noinstLIBRARIES ctags distclean distclean-compile \
+	distclean-generic distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-exec install-exec-am install-info \
+	install-info-am install-man install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+	uninstall-am uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/lib/device.c b/lib/device.c
new file mode 100644
index 0000000..d0663b3
--- /dev/null
+++ b/lib/device.c
@@ -0,0 +1,915 @@
+/* device.c - Some helper functions for OS devices and BIOS drives */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  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
+ *  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.
+ */
+
+/* Try to use glibc's transparant LFS support. */
+#define _LARGEFILE_SOURCE       1
+/* lseek becomes synonymous with lseek64.  */
+#define _FILE_OFFSET_BITS       64
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdarg.h>
+
+#ifdef __linux__
+# if !defined(__GLIBC__) || \
+        ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1)))
+/* Maybe libc doesn't have large file support.  */
+#  include <linux/unistd.h>     /* _llseek */
+# endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */
+# include <sys/ioctl.h>		/* ioctl */
+# ifndef HDIO_GETGEO
+#  define HDIO_GETGEO	0x0301	/* get device geometry */
+/* If HDIO_GETGEO is not defined, it is unlikely that hd_geometry is
+   defined.  */
+struct hd_geometry
+{
+  unsigned char heads;
+  unsigned char sectors;
+  unsigned short cylinders;
+  unsigned long start;
+};
+# endif /* ! HDIO_GETGEO */
+# ifndef FLOPPY_MAJOR
+#  define FLOPPY_MAJOR	2	/* the major number for floppy */
+# endif /* ! FLOPPY_MAJOR */
+# ifndef MAJOR
+#  define MAJOR(dev)	\
+  ({ \
+     unsigned long long __dev = (dev); \
+     (unsigned) ((__dev >> 8) & 0xfff) \
+                 | ((unsigned int) (__dev >> 32) & ~0xfff); \
+  })
+# endif /* ! MAJOR */
+# ifndef CDROM_GET_CAPABILITY
+#  define CDROM_GET_CAPABILITY	0x5331	/* get capabilities */
+# endif /* ! CDROM_GET_CAPABILITY */
+# ifndef BLKGETSIZE
+#  define BLKGETSIZE	_IO(0x12,96)	/* return device size */
+# endif /* ! BLKGETSIZE */
+#endif /* __linux__ */
+
+/* Use __FreeBSD_kernel__ instead of __FreeBSD__ for compatibility with
+   kFreeBSD-based non-FreeBSD systems (e.g. GNU/kFreeBSD) */
+#if defined(__FreeBSD__) && ! defined(__FreeBSD_kernel__)
+# define __FreeBSD_kernel__
+#endif
+#ifdef __FreeBSD_kernel__
+  /* Obtain version of kFreeBSD headers */
+# include <osreldate.h>
+# ifndef __FreeBSD_kernel_version
+#  define __FreeBSD_kernel_version __FreeBSD_version
+# endif
+
+  /* Runtime detection of kernel */
+# include <sys/utsname.h>
+int
+get_kfreebsd_version ()
+{
+  struct utsname uts;
+  int major; int minor, v[2];
+
+  uname (&uts);
+  sscanf (uts.release, "%d.%d", &major, &minor);
+
+  if (major >= 9)
+    major = 9;
+  if (major >= 5)
+    {
+      v[0] = minor/10; v[1] = minor%10;
+    }
+  else
+    {
+      v[0] = minor%10; v[1] = minor/10;
+    }
+  return major*100000+v[0]*10000+v[1]*1000;
+}
+#endif /* __FreeBSD_kernel__ */
+
+#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
+# include <sys/ioctl.h>		/* ioctl */
+# include <sys/disklabel.h>
+# include <sys/cdio.h>		/* CDIOCCLRDEBUG */
+# if defined(__FreeBSD_kernel__)
+#  include <sys/param.h>
+#  if __FreeBSD_kernel_version >= 500040
+#   include <sys/disk.h>
+#  endif
+# endif /* __FreeBSD_kernel__ */
+#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */
+
+#ifdef HAVE_OPENDISK
+# include <util.h>
+#endif /* HAVE_OPENDISK */
+
+#define WITHOUT_LIBC_STUBS	1
+#include <shared.h>
+#include <device.h>
+
+/* Get the geometry of a drive DRIVE.  */
+void
+get_drive_geometry (struct geometry *geom, char **map, int drive)
+{
+  int fd;
+
+  if (geom->flags == -1)
+    {
+      fd = open (map[drive], O_RDONLY);
+      assert (fd >= 0);
+    }
+  else
+    fd = geom->flags;
+
+  /* XXX This is the default size.  */
+  geom->sector_size = SECTOR_SIZE;
+  
+#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;
+    
+    goto success;
+  }
+
+#elif defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
+# if defined(__FreeBSD_kernel__) && __FreeBSD_kernel_version >= 500040
+  /* kFreeBSD version 5 or later */
+  if (get_kfreebsd_version () >= 500040)
+  {
+    unsigned int sector_size;
+    off_t media_size;
+    unsigned int tmp;
+    
+    if(ioctl (fd, DIOCGSECTORSIZE, &sector_size) != 0)
+      sector_size = 512;
+    
+    if (ioctl (fd, DIOCGMEDIASIZE, &media_size) != 0)
+      goto fail;
+
+    geom->total_sectors = media_size / sector_size;
+    
+    if (ioctl (fd, DIOCGFWSECTORS, &tmp) == 0)
+      geom->sectors = tmp;
+    else
+      geom->sectors = 63;
+    if (ioctl (fd, DIOCGFWHEADS, &tmp) == 0)
+      geom->heads = tmp;
+    else if (geom->total_sectors <= 63 * 1 * 1024)
+      geom->heads = 1;
+    else if (geom->total_sectors <= 63 * 16 * 1024)
+      geom->heads = 16;
+    else
+      geom->heads = 255;
+
+    geom->cylinders = (geom->total_sectors
+			   / geom->heads
+			   / geom->sectors);
+    
+    goto success;
+  }
+  else
+#endif /* defined(__FreeBSD_kernel__) && __FreeBSD_kernel_version >= 500040 */
+
+  /* kFreeBSD < 5, NetBSD or OpenBSD */
+  {
+    struct disklabel hdg;
+    if (ioctl (fd, DIOCGDINFO, &hdg))
+      goto fail;
+    
+    geom->cylinders = hdg.d_ncylinders;
+    geom->heads = hdg.d_ntracks;
+    geom->sectors = hdg.d_nsectors;
+    geom->total_sectors = hdg.d_secperunit;
+
+    goto success;
+  }
+  
+#else
+  /* Notably, defined(__GNU__) */
+# warning "Automatic detection of geometries will be performed only \
+partially. This is not fatal."
+#endif
+
+ fail:
+  {
+    struct stat st;
+
+    /* FIXME: It would be nice to somehow compute fake C/H/S settings,
+       given a proper st_blocks size. */
+    if (drive & 0x80)
+      {
+	geom->cylinders = DEFAULT_HD_CYLINDERS;
+	geom->heads = DEFAULT_HD_HEADS;
+	geom->sectors = DEFAULT_HD_SECTORS;
+      }
+    else
+      {
+	geom->cylinders = DEFAULT_FD_CYLINDERS;
+	geom->heads = DEFAULT_FD_HEADS;
+	geom->sectors = DEFAULT_FD_SECTORS;
+      }
+
+    /* Set the total sectors properly, if we can. */
+    if (! fstat (fd, &st) && st.st_size)
+      geom->total_sectors = st.st_size >> SECTOR_BITS;
+    else
+      geom->total_sectors = geom->cylinders * geom->heads * geom->sectors;
+  }
+
+ success:
+  if (geom->flags == -1)
+    close (fd);
+}
+
+#ifdef __linux__
+/* Check if we have devfs support.  */
+static int
+have_devfs (void)
+{
+  static int dev_devfsd_exists = -1;
+  
+  if (dev_devfsd_exists < 0)
+    {
+      struct stat st;
+      
+      dev_devfsd_exists = stat ("/dev/.devfsd", &st) == 0;
+    }
+  
+  return dev_devfsd_exists;
+}
+#endif /* __linux__ */
+
+/* These three functions are quite different among OSes.  */
+static void
+get_floppy_disk_name (char *name, int unit)
+{
+#if defined(__linux__)
+  /* GNU/Linux */
+  if (have_devfs ())
+    sprintf (name, "/dev/floppy/%d", unit);
+  else
+    sprintf (name, "/dev/fd%d", unit);
+#elif defined(__GNU__)
+  /* GNU/Hurd */
+  sprintf (name, "/dev/fd%d", unit);
+#elif defined(__FreeBSD_kernel__)
+  /* kFreeBSD */
+  if (get_kfreebsd_version () >= 400000)
+    sprintf (name, "/dev/fd%d", unit);
+  else
+    sprintf (name, "/dev/rfd%d", unit);
+#elif defined(__NetBSD__)
+  /* NetBSD */
+  /* opendisk() doesn't work for floppies.  */
+  sprintf (name, "/dev/rfd%da", unit);
+#elif defined(__OpenBSD__)
+  /* OpenBSD */
+  sprintf (name, "/dev/rfd%dc", unit);
+#elif defined(__QNXNTO__)
+  /* QNX RTP */
+  sprintf (name, "/dev/fd%d", unit);
+#else
+# warning "BIOS floppy drives cannot be guessed in your operating system."
+  /* Set NAME to a bogus string.  */
+  *name = 0;
+#endif
+}
+
+static void
+get_ide_disk_name (char *name, int unit)
+{
+#if defined(__linux__)
+  /* GNU/Linux */
+  sprintf (name, "/dev/hd%c", unit + 'a');
+#elif defined(__GNU__)
+  /* GNU/Hurd */
+  sprintf (name, "/dev/hd%d", unit);
+#elif defined(__FreeBSD_kernel__)
+  /* kFreeBSD */
+  if (get_kfreebsd_version () >= 400000)
+    sprintf (name, "/dev/ad%d", unit);
+  else
+    sprintf (name, "/dev/rwd%d", unit);
+#elif defined(__NetBSD__) && defined(HAVE_OPENDISK)
+  /* NetBSD */
+  char shortname[16];
+  int fd;
+  
+  sprintf (shortname, "wd%d", unit);
+  fd = opendisk (shortname, O_RDONLY, name,
+		 16,	/* length of NAME */
+		 0	/* char device */
+		 );
+  close (fd);
+#elif defined(__OpenBSD__)
+  /* OpenBSD */
+  sprintf (name, "/dev/rwd%dc", unit);
+#elif defined(__QNXNTO__)
+  /* QNX RTP */
+  /* Actually, QNX RTP doesn't distinguish IDE from SCSI, so this could
+     contain SCSI disks.  */
+  sprintf (name, "/dev/hd%d", unit);
+#else
+# warning "BIOS IDE drives cannot be guessed in your operating system."
+  /* Set NAME to a bogus string.  */
+  *name = 0;
+#endif
+}
+
+static void
+get_scsi_disk_name (char *name, int unit)
+{
+#if defined(__linux__)
+  /* GNU/Linux */
+  sprintf (name, "/dev/sd%c", unit + 'a');
+#elif defined(__GNU__)
+  /* GNU/Hurd */
+  sprintf (name, "/dev/sd%d", unit);
+#elif defined(__FreeBSD_kernel__)
+  /* kFreeBSD */
+  if (get_kfreebsd_version () >= 400000)
+    sprintf (name, "/dev/da%d", unit);
+  else
+    sprintf (name, "/dev/rda%d", unit);
+#elif defined(__NetBSD__) && defined(HAVE_OPENDISK)
+  /* NetBSD */
+  char shortname[16];
+  int fd;
+  
+  sprintf (shortname, "sd%d", unit);
+  fd = opendisk (shortname, O_RDONLY, name,
+		 16,	/* length of NAME */
+		 0	/* char device */
+		 );
+  close (fd);
+#elif defined(__OpenBSD__)
+  /* OpenBSD */
+  sprintf (name, "/dev/rsd%dc", unit);
+#elif defined(__QNXNTO__)
+  /* QNX RTP */
+  /* QNX RTP doesn't distinguish SCSI from IDE, so it is better to
+     disable the detection of SCSI disks here.  */
+  *name = 0;
+#else
+# warning "BIOS SCSI drives cannot be guessed in your operating system."
+  /* Set NAME to a bogus string.  */
+  *name = 0;
+#endif
+}
+
+#ifdef __linux__
+static void
+get_dac960_disk_name (char *name, int controller, int drive)
+{
+  sprintf (name, "/dev/rd/c%dd%d", controller, drive);
+}
+
+static void
+get_ataraid_disk_name (char *name, int unit)
+{
+  sprintf (name, "/dev/ataraid/d%c", unit + '0');
+}
+#endif
+
+/* Check if DEVICE can be read. If an error occurs, return zero,
+   otherwise return non-zero.  */
+int
+check_device (const char *device)
+{
+  char buf[512];
+  FILE *fp;
+
+  /* If DEVICE is empty, just return 1.  */
+  if (*device == 0)
+    return 1;
+  
+  fp = fopen (device, "r");
+  if (! fp)
+    {
+      switch (errno)
+	{
+#ifdef ENOMEDIUM
+	case ENOMEDIUM:
+# if 0
+	  /* At the moment, this finds only CDROMs, which can't be
+	     read anyway, so leave it out. Code should be
+	     reactivated if `removable disks' and CDROMs are
+	     supported.  */
+	  /* Accept it, it may be inserted.  */
+	  return 1;
+# endif
+	  break;
+#endif /* ENOMEDIUM */
+	default:
+	  /* Break case and leave.  */
+	  break;
+	}
+      /* Error opening the device.  */
+      return 0;
+    }
+  
+  /* Make sure CD-ROMs don't get assigned a BIOS disk number 
+     before SCSI disks!  */
+#ifdef __linux__
+# ifdef CDROM_GET_CAPABILITY
+  if (ioctl (fileno (fp), CDROM_GET_CAPABILITY, 0) >= 0)
+    return 0;
+# else /* ! CDROM_GET_CAPABILITY */
+  /* Check if DEVICE is a CD-ROM drive by the HDIO_GETGEO ioctl.  */
+  {
+    struct hd_geometry hdg;
+    struct stat st;
+
+    if (fstat (fileno (fp), &st))
+      return 0;
+
+    /* If it is a block device and isn't a floppy, check if HDIO_GETGEO
+       succeeds.  */
+    if (S_ISBLK (st.st_mode)
+	&& MAJOR (st.st_rdev) != FLOPPY_MAJOR
+	&& ioctl (fileno (fp), HDIO_GETGEO, &hdg))
+      return 0;
+  }
+# endif /* ! CDROM_GET_CAPABILITY */
+#endif /* __linux__ */
+
+#if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
+# ifdef CDIOCCLRDEBUG
+  if (ioctl (fileno (fp), CDIOCCLRDEBUG, 0) >= 0)
+    return 0;
+# endif /* CDIOCCLRDEBUG */
+#endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */
+  
+  /* Attempt to read the first sector.  */
+  if (fread (buf, 1, 512, fp) != 512)
+    {
+      fclose (fp);
+      return 0;
+    }
+  
+  fclose (fp);
+  return 1;
+}
+
+/* Read mapping information from FP, and write it to MAP.  */
+static int
+read_device_map (FILE *fp, char **map, const char *map_file)
+{
+  auto void show_error (int no, const char *msg);
+  auto void show_warning (int no, const char *msg, ...);
+  
+  auto void show_error (int no, const char *msg)
+    {
+      fprintf (stderr, "%s:%d: error: %s\n", map_file, no, msg);
+    }
+  
+  auto void show_warning (int no, const char *msg, ...)
+    {
+      va_list ap;
+      
+      va_start (ap, msg);
+      fprintf (stderr, "%s:%d: warning: ", map_file, no);
+      vfprintf (stderr, msg, ap);
+      va_end (ap);
+    }
+  
+  /* If there is the device map file, use the data in it instead of
+     probing devices.  */
+  char buf[1024];		/* XXX */
+  int line_number = 0;
+  
+  while (fgets (buf, sizeof (buf), fp))
+    {
+      char *ptr, *eptr;
+      int drive;
+      int is_floppy = 0;
+      
+      /* Increase the number of lines.  */
+      line_number++;
+      
+      /* If the first character is '#', skip it.  */
+      if (buf[0] == '#')
+	continue;
+      
+      ptr = buf;
+      /* Skip leading spaces.  */
+      while (*ptr && isspace (*ptr))
+	ptr++;
+
+      /* Skip empty lines.  */
+      if (! *ptr)
+	continue;
+      
+      if (*ptr != '(')
+	{
+	  show_error (line_number, "No open parenthesis found");
+	  return 0;
+	}
+      
+      ptr++;
+      if ((*ptr != 'f' && *ptr != 'h') || *(ptr + 1) != 'd')
+	{
+	  show_error (line_number, "Bad drive name");
+	  return 0;
+	}
+      
+      if (*ptr == 'f')
+	is_floppy = 1;
+      
+      ptr += 2;
+      drive = strtoul (ptr, &ptr, 10);
+      if (drive < 0)
+	{
+	  show_error (line_number, "Bad device number");
+	  return 0;
+	}
+      else if (drive > 127)
+	{
+	  show_warning (line_number,
+			"Ignoring %cd%d due to a BIOS limitation",
+			is_floppy ? 'f' : 'h', drive);
+	  continue;
+	}
+      
+      if (! is_floppy)
+	drive += 0x80;
+      
+      if (*ptr != ')')
+	{
+	  show_error (line_number, "No close parenthesis found");
+	  return 0;
+	}
+      
+      ptr++;
+      /* Skip spaces.  */
+      while (*ptr && isspace (*ptr))
+	ptr++;
+      
+      if (! *ptr)
+	{
+	  show_error (line_number, "No filename found");
+	  return 0;
+	}
+      
+      /* Terminate the filename.  */
+      eptr = ptr;
+      while (*eptr && ! isspace (*eptr))
+	eptr++;
+      *eptr = 0;
+
+      /* Multiple entries for a given drive is not allowed.  */
+      if (map[drive])
+	{
+	  show_error (line_number, "Duplicated entry found");
+	  return 0;
+	}
+      
+      map[drive] = strdup (ptr);
+      assert (map[drive]);
+    }
+  
+  return 1;
+}
+
+/* Initialize the device map MAP. *MAP will be allocated from the heap
+   space. If MAP_FILE is not NULL, then read mappings from the file
+   MAP_FILE if it exists, otherwise, write guessed mappings to the file.
+   FLOPPY_DISKS is the number of floppy disk drives which will be probed.
+   If it is zero, don't probe any floppy at all. If it is one, probe one
+   floppy. If it is two, probe two floppies. And so on.  */
+int
+init_device_map (char ***map, const char *map_file, int floppy_disks)
+{
+  int i;
+  int num_hd = 0;
+  FILE *fp = 0;
+
+  assert (map);
+  assert (*map == 0);
+  *map = malloc (NUM_DISKS * sizeof (char *));
+  assert (*map);
+  
+  /* Probe devices for creating the device map.  */
+  
+  /* Initialize DEVICE_MAP.  */
+  for (i = 0; i < NUM_DISKS; i++)
+    (*map)[i] = 0;
+  
+  if (map_file)
+    {
+      /* Open the device map file.  */
+      fp = fopen (map_file, "r");
+      if (fp)
+	{
+	  int ret;
+
+	  ret = read_device_map (fp, *map, map_file);
+	  fclose (fp);
+	  return ret;
+	}
+    }
+  
+  /* Print something so that the user does not think GRUB has been
+     crashed.  */
+  fprintf (stderr,
+	   "Probing devices to guess BIOS drives. "
+	   "This may take a long time.\n");
+  
+  if (map_file)
+    /* Try to open the device map file to write the probed data.  */
+    fp = fopen (map_file, "w");
+  
+  /* Floppies.  */
+  for (i = 0; i < floppy_disks; i++)
+    {
+      char name[16];
+      
+      get_floppy_disk_name (name, i);
+      /* In floppies, write the map, whether check_device succeeds
+	 or not, because the user just does not insert floppies.  */
+      if (fp)
+	fprintf (fp, "(fd%d)\t%s\n", i, name);
+      
+      if (check_device (name))
+	{
+	  (*map)[i] = strdup (name);
+	  assert ((*map)[i]);
+	}
+    }
+  
+#ifdef __linux__
+  if (have_devfs ())
+    {
+      while (1)
+	{
+	  char discn[32];
+	  char name[PATH_MAX];
+	  struct stat st;
+
+	  /* Linux creates symlinks "/dev/discs/discN" for convenience.
+	     The way to number disks is the same as GRUB's.  */
+	  sprintf (discn, "/dev/discs/disc%d", num_hd);
+	  if (stat (discn, &st) < 0)
+	    break;
+	  
+	  if (realpath (discn, name))
+	    {
+	      strcat (name, "/disc");
+	      (*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++;
+	}
+      
+      /* OK, close the device map file if opened.  */
+      if (fp)
+	fclose (fp);
+      
+      return 1;
+    }
+#endif /* __linux__ */
+    
+  /* IDE disks.  */
+  for (i = 0; i < 8; i++)
+    {
+      char name[16];
+      
+      get_ide_disk_name (name, i);
+      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++;
+	}
+    }
+  
+#ifdef __linux__
+  /* ATARAID disks.  */
+  for (i = 0; i < 8; i++)
+    {
+      char name[20];
+
+      get_ataraid_disk_name (name, i);
+      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__ */
+
+  /* The rest is SCSI disks.  */
+  for (i = 0; i < 16; i++)
+    {
+      char name[16];
+      
+      get_scsi_disk_name (name, i);
+      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++;
+	}
+    }
+  
+#ifdef __linux__
+  /* This is for DAC960 - we have
+     /dev/rd/c<controller>d<logical drive>p<partition>.
+     
+     DAC960 driver currently supports up to 8 controllers, 32 logical
+     drives, and 7 partitions.  */
+  {
+    int controller, drive;
+    
+    for (controller = 0; controller < 8; controller++)
+      {
+	for (drive = 0; drive < 15; drive++)
+	  {
+	    char name[24];
+	    
+	    get_dac960_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.  */
+  if (fp)
+    fclose (fp);
+
+  return 1;
+}
+
+/* Restore the memory consumed for MAP.  */
+void
+restore_device_map (char **map)
+{
+  int i;
+
+  for (i = 0; i < NUM_DISKS; i++)
+    if (map[i])
+      free (map[i]);
+
+  free (map);
+}
+
+#ifdef __linux__
+/* Linux-only functions, because Linux has a bug that the disk cache for
+   a whole disk is not consistent with the one for a partition of the
+   disk.  */
+int
+is_disk_device (char **map, int drive)
+{
+  struct stat st;
+  
+  assert (map[drive] != 0);
+  assert (stat (map[drive], &st) == 0);
+  /* For now, disk devices under Linux are all block devices.  */
+  return S_ISBLK (st.st_mode);
+}
+
+int
+write_to_partition (char **map, int drive, int partition,
+		    int sector, int size, const char *buf)
+{
+  char dev[PATH_MAX];	/* XXX */
+  int fd;
+  
+  if ((partition & 0x00FF00) != 0x00FF00)
+    {
+      /* If the partition is a BSD partition, it is difficult to
+	 obtain the representation in Linux. So don't support that.  */
+      errnum = ERR_DEV_VALUES;
+      return 1;
+    }
+  
+  assert (map[drive] != 0);
+  
+  strcpy (dev, map[drive]);
+  if (have_devfs ())
+    {
+      if (strcmp (dev + strlen(dev) - 5, "/disc") == 0)
+	strcpy (dev + strlen(dev) - 5, "/part");
+    }
+  sprintf (dev + strlen(dev), "%d", ((partition >> 16) & 0xFF) + 1);
+  
+  /* Open the partition.  */
+  fd = open (dev, O_RDWR);
+  if (fd < 0)
+    {
+      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 (write (fd, buf, size * SECTOR_SIZE) != (size * SECTOR_SIZE))
+    {
+      close (fd);
+      errnum = ERR_WRITE;
+      return 0;
+    }
+  
+  sync ();	/* Paranoia.  */
+  close (fd);
+  
+  return 1;
+}
+#endif /* __linux__ */
diff --git a/lib/device.h b/lib/device.h
new file mode 100644
index 0000000..02ffce8
--- /dev/null
+++ b/lib/device.h
@@ -0,0 +1,48 @@
+/* device.h - Define macros and declare prototypes for device.c */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,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 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 DEVICE_MAP_HEADER
+#define DEVICE_MAP_HEADER	1
+
+/* The maximum number of BIOS disks.  */
+#define NUM_DISKS	256
+
+/* Simulated disk sizes. */
+#define DEFAULT_FD_CYLINDERS	80
+#define DEFAULT_FD_HEADS	2
+#define DEFAULT_FD_SECTORS	18
+#define DEFAULT_HD_CYLINDERS	620
+#define DEFAULT_HD_HEADS	128
+#define DEFAULT_HD_SECTORS	63
+
+/* Function prototypes.  */
+extern void get_drive_geometry (struct geometry *geom, char **map, int drive);
+extern int check_device (const char *device);
+extern int init_device_map (char ***map, const char *map_file,
+			    int no_floppies);
+extern void restore_device_map (char **map);
+
+#ifdef __linux__
+extern int is_disk_device (char **map, int drive);
+extern int write_to_partition (char **map, int drive, int partition,
+			       int offset, int size, const char *buf);
+#endif /* __linux__ */
+			       
+#endif /* DEVICE_MAP_HEADER */
diff --git a/lib/getopt.c b/lib/getopt.c
new file mode 100644
index 0000000..04905fd
--- /dev/null
+++ b/lib/getopt.c
@@ -0,0 +1,1053 @@
+/* Getopt for GNU.
+   NOTE: getopt is now part of the C library, so if you don't know what
+   "Keep this file name-space clean" means, talk to drepper@gnu.org
+   before changing it!
+
+   Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98
+   	Free Software Foundation, Inc.
+
+   NOTE: The canonical source of this file is maintained with the GNU C Library.
+   Bugs can be reported to bug-glibc@gnu.org.
+
+   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.  */
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+   Ditto for AIX 3.2 and <stdlib.h>.  */
+#ifndef _NO_PROTO
+# define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+   reject `defined (const)'.  */
+# ifndef const
+#  define const
+# endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+# include <gnu-versions.h>
+# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#  define ELIDE_CODE
+# endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef	__GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+   contain conflicting prototypes for getopt.  */
+# include <stdlib.h>
+# include <unistd.h>
+#endif	/* GNU C library.  */
+
+#ifdef VMS
+# include <unixlib.h>
+# if HAVE_STRING_H - 0
+#  include <string.h>
+# endif
+#endif
+
+#ifndef _
+/* This is for other GNU distributions with internationalized messages.
+   When compiling libc, the _ macro is predefined.  */
+# ifdef HAVE_LIBINTL_H
+#  include <libintl.h>
+#  define _(msgid)	gettext (msgid)
+# else
+#  define _(msgid)	(msgid)
+# endif
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+   but it behaves differently for the user, since it allows the user
+   to intersperse the options with the other arguments.
+
+   As `getopt' works, it permutes the elements of ARGV so that,
+   when it is done, all the options precede everything else.  Thus
+   all application programs are extended to handle flexible argument order.
+
+   Setting the environment variable POSIXLY_CORRECT disables permutation.
+   Then the behavior is completely standard.
+
+   GNU application programs can use a third alternative mode in which
+   they can distinguish the relative order of options and other arguments.  */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+char *optarg = NULL;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns -1, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+/* 1003.2 says this must be 1 before any call.  */
+int optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+   causes problems with re-calling getopt as programs generally don't
+   know that. */
+
+int __getopt_initialized = 0;
+
+/* The next char to be scanned in the option-element
+   in which the last option character we returned was found.
+   This allows us to pick up the scan where we left off.
+
+   If this is zero, or a null string, it means resume the scan
+   by advancing to the next ARGV-element.  */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+   for unrecognized options.  */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+   This must be initialized on some systems to avoid linking in the
+   system's own getopt implementation.  */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+   If the caller did not specify anything,
+   the default is REQUIRE_ORDER if the environment variable
+   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+   REQUIRE_ORDER means don't recognize them as options;
+   stop option processing when the first non-option is seen.
+   This is what Unix does.
+   This mode of operation is selected by either setting the environment
+   variable POSIXLY_CORRECT, or using `+' as the first character
+   of the list of option characters.
+
+   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+   so that eventually all the non-options are at the end.  This allows options
+   to be given in any order, even with programs that were not written to
+   expect this.
+
+   RETURN_IN_ORDER is an option available to programs that were written
+   to expect options and other ARGV-elements in any order and that care about
+   the ordering of the two.  We describe each non-option ARGV-element
+   as if it were the argument of an option with character code 1.
+   Using `-' as the first character of the list of option characters
+   selects this mode of operation.
+
+   The special argument `--' forces an end of option-scanning regardless
+   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+   `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
+
+static enum
+{
+  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable.  */
+static char *posixly_correct;
+
+#ifdef	__GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+   because there are many ways it can cause trouble.
+   On some systems, it contains special magic macros that don't work
+   in GCC.  */
+# include <string.h>
+# define my_index	strchr
+#else
+
+# if HAVE_STRING_H
+#  include <string.h>
+# else
+#  include <strings.h>
+# endif
+
+/* Avoid depending on library functions or files
+   whose names are inconsistent.  */
+
+#ifndef getenv
+extern char *getenv ();
+#endif
+
+static char *
+my_index (str, chr)
+     const char *str;
+     int chr;
+{
+  while (*str)
+    {
+      if (*str == chr)
+	return (char *) str;
+      str++;
+    }
+  return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+   If not using GCC, it is ok not to declare it.  */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+   That was relevant to code that was here before.  */
+# if (!defined __STDC__ || !__STDC__) && !defined strlen
+/* gcc with -traditional declares the built-in strlen to return int,
+   and has done so at least since version 2.4.5. -- rms.  */
+extern int strlen (const char *);
+# endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+
+/* Handle permutation of arguments.  */
+
+/* Describe the part of ARGV that contains non-options that have
+   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+   `last_nonopt' is the index after the last of them.  */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Bash 2.0 gives us an environment variable containing flags
+   indicating ARGV elements that should not be considered arguments.  */
+
+/* Defined in getopt_init.c  */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+
+static int original_argc;
+static char *const *original_argv;
+
+/* Make sure the environment variable bash 2.0 puts in the environment
+   is valid for the getopt call we must make sure that the ARGV passed
+   to getopt is that one passed to the process.  */
+static void
+__attribute__ ((unused))
+store_args_and_env (int argc, char *const *argv)
+{
+  /* XXX This is no good solution.  We should rather copy the args so
+     that we can compare them later.  But we must not use malloc(3).  */
+  original_argc = argc;
+  original_argv = argv;
+}
+# ifdef text_set_element
+text_set_element (__libc_subinit, store_args_and_env);
+# endif /* text_set_element */
+
+# define SWAP_FLAGS(ch1, ch2) \
+  if (nonoption_flags_len > 0)						      \
+    {									      \
+      char __tmp = __getopt_nonoption_flags[ch1];			      \
+      __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];	      \
+      __getopt_nonoption_flags[ch2] = __tmp;				      \
+    }
+#else	/* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif	/* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+   One subsequence is elements [first_nonopt,last_nonopt)
+   which contains all the non-options that have been skipped so far.
+   The other is elements [last_nonopt,optind), which contains all
+   the options processed since those non-options were skipped.
+
+   `first_nonopt' and `last_nonopt' are relocated so that they describe
+   the new indices of the non-options in ARGV after they are moved.  */
+
+#if defined __STDC__ && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (argv)
+     char **argv;
+{
+  int bottom = first_nonopt;
+  int middle = last_nonopt;
+  int top = optind;
+  char *tem;
+
+  /* Exchange the shorter segment with the far end of the longer segment.
+     That puts the shorter segment into the right place.
+     It leaves the longer segment in the right place overall,
+     but it consists of two parts that need to be swapped next.  */
+
+#ifdef _LIBC
+  /* First make sure the handling of the `__getopt_nonoption_flags'
+     string can work normally.  Our top argument must be in the range
+     of the string.  */
+  if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+    {
+      /* We must extend the array.  The user plays games with us and
+	 presents new arguments.  */
+      char *new_str = malloc (top + 1);
+      if (new_str == NULL)
+	nonoption_flags_len = nonoption_flags_max_len = 0;
+      else
+	{
+	  memset (__mempcpy (new_str, __getopt_nonoption_flags,
+			     nonoption_flags_max_len),
+		  '\0', top + 1 - nonoption_flags_max_len);
+	  nonoption_flags_max_len = top + 1;
+	  __getopt_nonoption_flags = new_str;
+	}
+    }
+#endif
+
+  while (top > middle && middle > bottom)
+    {
+      if (top - middle > middle - bottom)
+	{
+	  /* Bottom segment is the short one.  */
+	  int len = middle - bottom;
+	  register int i;
+
+	  /* Swap it with the top part of the top segment.  */
+	  for (i = 0; i < len; i++)
+	    {
+	      tem = argv[bottom + i];
+	      argv[bottom + i] = argv[top - (middle - bottom) + i];
+	      argv[top - (middle - bottom) + i] = tem;
+	      SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+	    }
+	  /* Exclude the moved bottom segment from further swapping.  */
+	  top -= len;
+	}
+      else
+	{
+	  /* Top segment is the short one.  */
+	  int len = top - middle;
+	  register int i;
+
+	  /* Swap it with the bottom part of the bottom segment.  */
+	  for (i = 0; i < len; i++)
+	    {
+	      tem = argv[bottom + i];
+	      argv[bottom + i] = argv[middle + i];
+	      argv[middle + i] = tem;
+	      SWAP_FLAGS (bottom + i, middle + i);
+	    }
+	  /* Exclude the moved top segment from further swapping.  */
+	  bottom += len;
+	}
+    }
+
+  /* Update records for the slots the non-options now occupy.  */
+
+  first_nonopt += (optind - last_nonopt);
+  last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made.  */
+
+#if defined __STDC__ && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  /* Start processing options with ARGV-element 1 (since ARGV-element 0
+     is the program name); the sequence of previously skipped
+     non-option ARGV-elements is empty.  */
+
+  first_nonopt = last_nonopt = optind;
+
+  nextchar = NULL;
+
+  posixly_correct = getenv ("POSIXLY_CORRECT");
+
+  /* Determine how to handle the ordering of options and nonoptions.  */
+
+  if (optstring[0] == '-')
+    {
+      ordering = RETURN_IN_ORDER;
+      ++optstring;
+    }
+  else if (optstring[0] == '+')
+    {
+      ordering = REQUIRE_ORDER;
+      ++optstring;
+    }
+  else if (posixly_correct != NULL)
+    ordering = REQUIRE_ORDER;
+  else
+    ordering = PERMUTE;
+
+#ifdef _LIBC
+  if (posixly_correct == NULL
+      && argc == original_argc && argv == original_argv)
+    {
+      if (nonoption_flags_max_len == 0)
+	{
+	  if (__getopt_nonoption_flags == NULL
+	      || __getopt_nonoption_flags[0] == '\0')
+	    nonoption_flags_max_len = -1;
+	  else
+	    {
+	      const char *orig_str = __getopt_nonoption_flags;
+	      int len = nonoption_flags_max_len = strlen (orig_str);
+	      if (nonoption_flags_max_len < argc)
+		nonoption_flags_max_len = argc;
+	      __getopt_nonoption_flags =
+		(char *) malloc (nonoption_flags_max_len);
+	      if (__getopt_nonoption_flags == NULL)
+		nonoption_flags_max_len = -1;
+	      else
+		memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+			'\0', nonoption_flags_max_len - len);
+	    }
+	}
+      nonoption_flags_len = nonoption_flags_max_len;
+    }
+  else
+    nonoption_flags_len = 0;
+#endif
+
+  return optstring;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of the option characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns -1.
+   Then `optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   If an option character is seen that is not listed in OPTSTRING,
+   return '?' after printing an error message.  If you set `opterr' to
+   zero, the error message is suppressed but we still return '?'.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `optarg'.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `optarg', otherwise `optarg' is set to zero.
+
+   If OPTSTRING starts with `-' or `+', it requests different methods of
+   handling the non-option ARGV-elements.
+   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+   Long-named options begin with `--' instead of `-'.
+   Their names may be abbreviated as long as the abbreviation is unique
+   or is an exact match for some defined option.  If they have an
+   argument, it follows the option name in the same ARGV-element, separated
+   from the option name by a `=', or else the in next ARGV-element.
+   When `getopt' finds a long-named option, it returns 0 if that option's
+   `flag' field is nonzero, the value of the option's `val' field
+   if the `flag' field is zero.
+
+   The elements of ARGV aren't really const, because we permute them.
+   But we pretend they're const in the prototype to be compatible
+   with other systems.
+
+   LONGOPTS is a vector of `struct option' terminated by an
+   element containing a name which is zero.
+
+   LONGIND returns the index in LONGOPT of the long-named option found.
+   It is only valid when a long-named option has been found by the most
+   recent call.
+
+   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+   long-named options.  */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+     const struct option *longopts;
+     int *longind;
+     int long_only;
+{
+  optarg = NULL;
+
+  if (optind == 0 || !__getopt_initialized)
+    {
+      if (optind == 0)
+	optind = 1;	/* Don't scan ARGV[0], the program name.  */
+      optstring = _getopt_initialize (argc, argv, optstring);
+      __getopt_initialized = 1;
+    }
+
+  /* Test whether ARGV[optind] points to a non-option argument.
+     Either it does not have option syntax, or there is an environment flag
+     from the shell indicating it is not an option.  The later information
+     is only used when the used in the GNU libc.  */
+#ifdef _LIBC
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'	      \
+		      || (optind < nonoption_flags_len			      \
+			  && __getopt_nonoption_flags[optind] == '1'))
+#else
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#endif
+
+  if (nextchar == NULL || *nextchar == '\0')
+    {
+      /* Advance to the next ARGV-element.  */
+
+      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+	 moved back by the user (who may also have changed the arguments).  */
+      if (last_nonopt > optind)
+	last_nonopt = optind;
+      if (first_nonopt > optind)
+	first_nonopt = optind;
+
+      if (ordering == PERMUTE)
+	{
+	  /* If we have just processed some options following some non-options,
+	     exchange them so that the options come first.  */
+
+	  if (first_nonopt != last_nonopt && last_nonopt != optind)
+	    exchange ((char **) argv);
+	  else if (last_nonopt != optind)
+	    first_nonopt = optind;
+
+	  /* Skip any additional non-options
+	     and extend the range of non-options previously skipped.  */
+
+	  while (optind < argc && NONOPTION_P)
+	    optind++;
+	  last_nonopt = optind;
+	}
+
+      /* The special ARGV-element `--' means premature end of options.
+	 Skip it like a null option,
+	 then exchange with previous non-options as if it were an option,
+	 then skip everything else like a non-option.  */
+
+      if (optind != argc && !strcmp (argv[optind], "--"))
+	{
+	  optind++;
+
+	  if (first_nonopt != last_nonopt && last_nonopt != optind)
+	    exchange ((char **) argv);
+	  else if (first_nonopt == last_nonopt)
+	    first_nonopt = optind;
+	  last_nonopt = argc;
+
+	  optind = argc;
+	}
+
+      /* If we have done all the ARGV-elements, stop the scan
+	 and back over any non-options that we skipped and permuted.  */
+
+      if (optind == argc)
+	{
+	  /* Set the next-arg-index to point at the non-options
+	     that we previously skipped, so the caller will digest them.  */
+	  if (first_nonopt != last_nonopt)
+	    optind = first_nonopt;
+	  return -1;
+	}
+
+      /* If we have come to a non-option and did not permute it,
+	 either stop the scan or describe it to the caller and pass it by.  */
+
+      if (NONOPTION_P)
+	{
+	  if (ordering == REQUIRE_ORDER)
+	    return -1;
+	  optarg = argv[optind++];
+	  return 1;
+	}
+
+      /* We have found another option-ARGV-element.
+	 Skip the initial punctuation.  */
+
+      nextchar = (argv[optind] + 1
+		  + (longopts != NULL && argv[optind][1] == '-'));
+    }
+
+  /* Decode the current option-ARGV-element.  */
+
+  /* Check whether the ARGV-element is a long option.
+
+     If long_only and the ARGV-element has the form "-f", where f is
+     a valid short option, don't consider it an abbreviated form of
+     a long option that starts with f.  Otherwise there would be no
+     way to give the -f short option.
+
+     On the other hand, if there's a long option "fubar" and
+     the ARGV-element is "-fu", do consider that an abbreviation of
+     the long option, just like "--fu", and not "-f" with arg "u".
+
+     This distinction seems to be the most useful approach.  */
+
+  if (longopts != NULL
+      && (argv[optind][1] == '-'
+	  || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+    {
+      char *nameend;
+      const struct option *p;
+      const struct option *pfound = NULL;
+      int exact = 0;
+      int ambig = 0;
+      int indfound = -1;
+      int option_index;
+
+      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+	/* Do nothing.  */ ;
+
+      /* Test all long options for either exact match
+	 or abbreviated matches.  */
+      for (p = longopts, option_index = 0; p->name; p++, option_index++)
+	if (!strncmp (p->name, nextchar, nameend - nextchar))
+	  {
+	    if ((unsigned int) (nameend - nextchar)
+		== (unsigned int) strlen (p->name))
+	      {
+		/* Exact match found.  */
+		pfound = p;
+		indfound = option_index;
+		exact = 1;
+		break;
+	      }
+	    else if (pfound == NULL)
+	      {
+		/* First nonexact match found.  */
+		pfound = p;
+		indfound = option_index;
+	      }
+	    else
+	      /* Second or later nonexact match found.  */
+	      ambig = 1;
+	  }
+
+      if (ambig && !exact)
+	{
+	  if (opterr)
+	    fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+		     argv[0], argv[optind]);
+	  nextchar += strlen (nextchar);
+	  optind++;
+	  optopt = 0;
+	  return '?';
+	}
+
+      if (pfound != NULL)
+	{
+	  option_index = indfound;
+	  optind++;
+	  if (*nameend)
+	    {
+	      /* Don't test has_arg with >, because some C compilers don't
+		 allow it to be used on enums.  */
+	      if (pfound->has_arg)
+		optarg = nameend + 1;
+	      else
+		{
+		  if (opterr)
+		    {
+		      if (argv[optind - 1][1] == '-')
+			/* --option */
+			fprintf (stderr,
+				 _("%s: option `--%s' doesn't allow an argument\n"),
+				 argv[0], pfound->name);
+		      else
+			/* +option or -option */
+			fprintf (stderr,
+				 _("%s: option `%c%s' doesn't allow an argument\n"),
+				 argv[0], argv[optind - 1][0], pfound->name);
+		    }
+		  nextchar += strlen (nextchar);
+
+		  optopt = pfound->val;
+		  return '?';
+		}
+	    }
+	  else if (pfound->has_arg == 1)
+	    {
+	      if (optind < argc)
+		optarg = argv[optind++];
+	      else
+		{
+		  if (opterr)
+		    fprintf (stderr,
+			   _("%s: option `%s' requires an argument\n"),
+			   argv[0], argv[optind - 1]);
+		  nextchar += strlen (nextchar);
+		  optopt = pfound->val;
+		  return optstring[0] == ':' ? ':' : '?';
+		}
+	    }
+	  nextchar += strlen (nextchar);
+	  if (longind != NULL)
+	    *longind = option_index;
+	  if (pfound->flag)
+	    {
+	      *(pfound->flag) = pfound->val;
+	      return 0;
+	    }
+	  return pfound->val;
+	}
+
+      /* Can't find it as a long option.  If this is not getopt_long_only,
+	 or the option starts with '--' or is not a valid short
+	 option, then it's an error.
+	 Otherwise interpret it as a short option.  */
+      if (!long_only || argv[optind][1] == '-'
+	  || my_index (optstring, *nextchar) == NULL)
+	{
+	  if (opterr)
+	    {
+	      if (argv[optind][1] == '-')
+		/* --option */
+		fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+			 argv[0], nextchar);
+	      else
+		/* +option or -option */
+		fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+			 argv[0], argv[optind][0], nextchar);
+	    }
+	  nextchar = (char *) "";
+	  optind++;
+	  optopt = 0;
+	  return '?';
+	}
+    }
+
+  /* Look at and handle the next short option-character.  */
+
+  {
+    char c = *nextchar++;
+    char *temp = my_index (optstring, c);
+
+    /* Increment `optind' when we start to process its last character.  */
+    if (*nextchar == '\0')
+      ++optind;
+
+    if (temp == NULL || c == ':')
+      {
+	if (opterr)
+	  {
+	    if (posixly_correct)
+	      /* 1003.2 specifies the format of this message.  */
+	      fprintf (stderr, _("%s: illegal option -- %c\n"),
+		       argv[0], c);
+	    else
+	      fprintf (stderr, _("%s: invalid option -- %c\n"),
+		       argv[0], c);
+	  }
+	optopt = c;
+	return '?';
+      }
+    /* Convenience. Treat POSIX -W foo same as long option --foo */
+    if (temp[0] == 'W' && temp[1] == ';')
+      {
+	char *nameend;
+	const struct option *p;
+	const struct option *pfound = NULL;
+	int exact = 0;
+	int ambig = 0;
+	int indfound = 0;
+	int option_index;
+
+	/* This is an option that requires an argument.  */
+	if (*nextchar != '\0')
+	  {
+	    optarg = nextchar;
+	    /* If we end this ARGV-element by taking the rest as an arg,
+	       we must advance to the next element now.  */
+	    optind++;
+	  }
+	else if (optind == argc)
+	  {
+	    if (opterr)
+	      {
+		/* 1003.2 specifies the format of this message.  */
+		fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+			 argv[0], c);
+	      }
+	    optopt = c;
+	    if (optstring[0] == ':')
+	      c = ':';
+	    else
+	      c = '?';
+	    return c;
+	  }
+	else
+	  /* We already incremented `optind' once;
+	     increment it again when taking next ARGV-elt as argument.  */
+	  optarg = argv[optind++];
+
+	/* optarg is now the argument, see if it's in the
+	   table of longopts.  */
+
+	for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+	  /* Do nothing.  */ ;
+
+	/* Test all long options for either exact match
+	   or abbreviated matches.  */
+	for (p = longopts, option_index = 0; p->name; p++, option_index++)
+	  if (!strncmp (p->name, nextchar, nameend - nextchar))
+	    {
+	      if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+		{
+		  /* Exact match found.  */
+		  pfound = p;
+		  indfound = option_index;
+		  exact = 1;
+		  break;
+		}
+	      else if (pfound == NULL)
+		{
+		  /* First nonexact match found.  */
+		  pfound = p;
+		  indfound = option_index;
+		}
+	      else
+		/* Second or later nonexact match found.  */
+		ambig = 1;
+	    }
+	if (ambig && !exact)
+	  {
+	    if (opterr)
+	      fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+		       argv[0], argv[optind]);
+	    nextchar += strlen (nextchar);
+	    optind++;
+	    return '?';
+	  }
+	if (pfound != NULL)
+	  {
+	    option_index = indfound;
+	    if (*nameend)
+	      {
+		/* Don't test has_arg with >, because some C compilers don't
+		   allow it to be used on enums.  */
+		if (pfound->has_arg)
+		  optarg = nameend + 1;
+		else
+		  {
+		    if (opterr)
+		      fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+			       argv[0], pfound->name);
+
+		    nextchar += strlen (nextchar);
+		    return '?';
+		  }
+	      }
+	    else if (pfound->has_arg == 1)
+	      {
+		if (optind < argc)
+		  optarg = argv[optind++];
+		else
+		  {
+		    if (opterr)
+		      fprintf (stderr,
+			       _("%s: option `%s' requires an argument\n"),
+			       argv[0], argv[optind - 1]);
+		    nextchar += strlen (nextchar);
+		    return optstring[0] == ':' ? ':' : '?';
+		  }
+	      }
+	    nextchar += strlen (nextchar);
+	    if (longind != NULL)
+	      *longind = option_index;
+	    if (pfound->flag)
+	      {
+		*(pfound->flag) = pfound->val;
+		return 0;
+	      }
+	    return pfound->val;
+	  }
+	  nextchar = NULL;
+	  return 'W';	/* Let the application handle it.   */
+      }
+    if (temp[1] == ':')
+      {
+	if (temp[2] == ':')
+	  {
+	    /* This is an option that accepts an argument optionally.  */
+	    if (*nextchar != '\0')
+	      {
+		optarg = nextchar;
+		optind++;
+	      }
+	    else
+	      optarg = NULL;
+	    nextchar = NULL;
+	  }
+	else
+	  {
+	    /* This is an option that requires an argument.  */
+	    if (*nextchar != '\0')
+	      {
+		optarg = nextchar;
+		/* If we end this ARGV-element by taking the rest as an arg,
+		   we must advance to the next element now.  */
+		optind++;
+	      }
+	    else if (optind == argc)
+	      {
+		if (opterr)
+		  {
+		    /* 1003.2 specifies the format of this message.  */
+		    fprintf (stderr,
+			   _("%s: option requires an argument -- %c\n"),
+			   argv[0], c);
+		  }
+		optopt = c;
+		if (optstring[0] == ':')
+		  c = ':';
+		else
+		  c = '?';
+	      }
+	    else
+	      /* We already incremented `optind' once;
+		 increment it again when taking next ARGV-elt as argument.  */
+	      optarg = argv[optind++];
+	    nextchar = NULL;
+	  }
+      }
+    return c;
+  }
+}
+
+int
+getopt (argc, argv, optstring)
+     int argc;
+     char *const *argv;
+     const char *optstring;
+{
+  return _getopt_internal (argc, argv, optstring,
+			   (const struct option *) 0,
+			   (int *) 0,
+			   0);
+}
+
+#endif	/* Not ELIDE_CODE.  */
+
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+   the above definition of `getopt'.  */
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+
+      c = getopt (argc, argv, "abc:d:0123456789");
+      if (c == -1)
+	break;
+
+      switch (c)
+	{
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+	  if (digit_optind != 0 && digit_optind != this_option_optind)
+	    printf ("digits occur in two different argv-elements.\n");
+	  digit_optind = this_option_optind;
+	  printf ("option %c\n", c);
+	  break;
+
+	case 'a':
+	  printf ("option a\n");
+	  break;
+
+	case 'b':
+	  printf ("option b\n");
+	  break;
+
+	case 'c':
+	  printf ("option c with value `%s'\n", optarg);
+	  break;
+
+	case '?':
+	  break;
+
+	default:
+	  printf ("?? getopt returned character code 0%o ??\n", c);
+	}
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+	printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/lib/getopt.h b/lib/getopt.h
new file mode 100644
index 0000000..fb30719
--- /dev/null
+++ b/lib/getopt.h
@@ -0,0 +1,133 @@
+/* Declarations for getopt.
+   Copyright (C) 1989,90,91,92,93,94,96,97 Free Software Foundation, Inc.
+
+   NOTE: The canonical source of this file is maintained with the GNU C Library.
+   Bugs can be reported to bug-glibc@gnu.org.
+
+   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.  */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+   When `getopt' finds an option that takes an argument,
+   the argument value is returned here.
+   Also, when `ordering' is RETURN_IN_ORDER,
+   each non-option ARGV-element is returned here.  */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+   This is used for communication to and from the caller
+   and for communication between successive calls to `getopt'.
+
+   On entry to `getopt', zero means this is the first call; initialize.
+
+   When `getopt' returns -1, this is the index of the first of the
+   non-option elements that the caller should itself scan.
+
+   Otherwise, `optind' communicates from one call to the next
+   how much of ARGV has been scanned so far.  */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+   for unrecognized options.  */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized.  */
+
+extern int optopt;
+
+/* Describe the long-named options requested by the application.
+   The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+   of `struct option' terminated by an element containing a name which is
+   zero.
+
+   The field `has_arg' is:
+   no_argument		(or 0) if the option does not take an argument,
+   required_argument	(or 1) if the option requires an argument,
+   optional_argument 	(or 2) if the option takes an optional argument.
+
+   If the field `flag' is not NULL, it points to a variable that is set
+   to the value given in the field `val' when the option is found, but
+   left unchanged if the option is not found.
+
+   To have a long-named option do something other than set an `int' to
+   a compiled-in constant, such as set a value from `optarg', set the
+   option's `flag' field to zero and its `val' field to a nonzero
+   value (the equivalent single-letter option character, if there is
+   one).  For long options that have a zero `flag' field, `getopt'
+   returns the contents of the `val' field.  */
+
+struct option
+{
+#if defined (__STDC__) && __STDC__
+  const char *name;
+#else
+  char *name;
+#endif
+  /* has_arg can't be an enum because some compilers complain about
+     type mismatches in all the code that assumes it is an int.  */
+  int has_arg;
+  int *flag;
+  int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'.  */
+
+#define	no_argument		0
+#define required_argument	1
+#define optional_argument	2
+
+#if defined (__STDC__) && __STDC__
+#ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+   differences in the consts, in stdlib.h.  To avoid compilation
+   errors, only prototype getopt for the GNU C library.  */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+#else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+#endif /* __GNU_LIBRARY__ */
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+		        const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+			     const char *shortopts,
+		             const struct option *longopts, int *longind);
+
+/* Internal only.  Users should not call this directly.  */
+extern int _getopt_internal (int argc, char *const *argv,
+			     const char *shortopts,
+		             const struct option *longopts, int *longind,
+			     int long_only);
+#else /* not __STDC__ */
+extern int getopt ();
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* __STDC__ */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif /* getopt.h */
diff --git a/lib/getopt1.c b/lib/getopt1.c
new file mode 100644
index 0000000..ff25737
--- /dev/null
+++ b/lib/getopt1.c
@@ -0,0 +1,190 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+   Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
+     Free Software Foundation, Inc.
+
+   NOTE: The canonical source of this file is maintained with the GNU C Library.
+   Bugs can be reported to bug-glibc@gnu.org.
+
+   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.  */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "getopt.h"
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+   reject `defined (const)'.  */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+   actually compiling the library itself.  This code is part of the GNU C
+   Library, but also included in many other GNU distributions.  Compiling
+   and linking in this code is a waste when using the GNU C library
+   (especially if it is a shared library).  Rather than having every GNU
+   program understand `configure --with-gnu-libc' and omit the object files,
+   it is simpler to just do this in the source for each such file.  */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+   to get __GNU_LIBRARY__ defined.  */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#endif
+
+#ifndef	NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+   If an option that starts with '-' (not '--') doesn't match a long option,
+   but does match a short option, it is parsed as a short option
+   instead.  */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+     int argc;
+     char *const *argv;
+     const char *options;
+     const struct option *long_options;
+     int *opt_index;
+{
+  return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif	/* Not ELIDE_CODE.  */
+
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  int c;
+  int digit_optind = 0;
+
+  while (1)
+    {
+      int this_option_optind = optind ? optind : 1;
+      int option_index = 0;
+      static struct option long_options[] =
+      {
+	{"add", 1, 0, 0},
+	{"append", 0, 0, 0},
+	{"delete", 1, 0, 0},
+	{"verbose", 0, 0, 0},
+	{"create", 0, 0, 0},
+	{"file", 1, 0, 0},
+	{0, 0, 0, 0}
+      };
+
+      c = getopt_long (argc, argv, "abc:d:0123456789",
+		       long_options, &option_index);
+      if (c == -1)
+	break;
+
+      switch (c)
+	{
+	case 0:
+	  printf ("option %s", long_options[option_index].name);
+	  if (optarg)
+	    printf (" with arg %s", optarg);
+	  printf ("\n");
+	  break;
+
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+	  if (digit_optind != 0 && digit_optind != this_option_optind)
+	    printf ("digits occur in two different argv-elements.\n");
+	  digit_optind = this_option_optind;
+	  printf ("option %c\n", c);
+	  break;
+
+	case 'a':
+	  printf ("option a\n");
+	  break;
+
+	case 'b':
+	  printf ("option b\n");
+	  break;
+
+	case 'c':
+	  printf ("option c with value `%s'\n", optarg);
+	  break;
+
+	case 'd':
+	  printf ("option d with value `%s'\n", optarg);
+	  break;
+
+	case '?':
+	  break;
+
+	default:
+	  printf ("?? getopt returned character code 0%o ??\n", c);
+	}
+    }
+
+  if (optind < argc)
+    {
+      printf ("non-option ARGV-elements: ");
+      while (optind < argc)
+	printf ("%s ", argv[optind++]);
+      printf ("\n");
+    }
+
+  exit (0);
+}
+
+#endif /* TEST */
diff --git a/missing b/missing
new file mode 100755
index 0000000..64b5f90
--- /dev/null
+++ b/missing
@@ -0,0 +1,353 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2004-09-07.08
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004
+#   Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# 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.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case "$1" in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Send bug reports to <bug-automake@gnu.org>."
+    exit 0
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit 0
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# Now exit if we have it, but it failed.  Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).
+case "$1" in
+  lex|yacc)
+    # Not GNU programs, they don't have --version.
+    ;;
+
+  tar)
+    if test -n "$run"; then
+       echo 1>&2 "ERROR: \`tar' requires --run"
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       exit 1
+    fi
+    ;;
+
+  *)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       # Could not run --version or --help.  This is probably someone
+       # running `$TOOL --version' or `$TOOL --help' to check whether
+       # $TOOL exists and not knowing $TOOL uses missing.
+       exit 1
+    fi
+    ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+  aclocal*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case "$f" in
+      *:*) touch_files="$touch_files "`echo "$f" |
+				       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+	   sed 's/\.am$/.in/' |
+	   while read f; do touch "$f"; done
+    ;;
+
+  autom4te)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+    test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo "#! /bin/sh"
+	echo "# Created by GNU Automake missing as a replacement of"
+	echo "#  $ $@"
+	echo "exit 0"
+	chmod +x $file
+	exit 1
+    fi
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' $msg.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+	case "$LASTARG" in
+	*.y)
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" y.tab.c
+	    fi
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" y.tab.h
+	    fi
+	  ;;
+	esac
+    fi
+    if [ ! -f y.tab.h ]; then
+	echo >y.tab.h
+    fi
+    if [ ! -f y.tab.c ]; then
+	echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex|flex)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+	case "$LASTARG" in
+	*.l)
+	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" lex.yy.c
+	    fi
+	  ;;
+	esac
+    fi
+    if [ ! -f lex.yy.c ]; then
+	echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+	 you modified a dependency of a manual page.  You may need the
+	 \`Help2man' package in order for those modifications to take
+	 effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+	file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+    fi
+    if [ -f "$file" ]; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo ".ab help2man is required to generate this page"
+	exit 1
+    fi
+    ;;
+
+  makeinfo)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+    fi
+    touch $file
+    ;;
+
+  tar)
+    shift
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+	case "$firstarg" in
+	*o*)
+	    firstarg=`echo "$firstarg" | sed s/o//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+	case "$firstarg" in
+	*h*)
+	    firstarg=`echo "$firstarg" | sed s/h//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/mkinstalldirs b/mkinstalldirs
new file mode 100755
index 0000000..6fbe5e1
--- /dev/null
+++ b/mkinstalldirs
@@ -0,0 +1,150 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+
+scriptversion=2004-02-15.20
+
+# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain.
+#
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
+
+Create each directory DIR (with mode MODE, if specified), including all
+leading file name components.
+
+Report bugs to <bug-automake@gnu.org>."
+
+# process command line arguments
+while test $# -gt 0 ; do
+  case $1 in
+    -h | --help | --h*)         # -h for help
+      echo "$usage"
+      exit 0
+      ;;
+    -m)                         # -m PERM arg
+      shift
+      test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+      dirmode=$1
+      shift
+      ;;
+    --version)
+      echo "$0 $scriptversion"
+      exit 0
+      ;;
+    --)                         # stop option processing
+      shift
+      break
+      ;;
+    -*)                         # unknown option
+      echo "$usage" 1>&2
+      exit 1
+      ;;
+    *)                          # first non-opt arg
+      break
+      ;;
+  esac
+done
+
+for file
+do
+  if test -d "$file"; then
+    shift
+  else
+    break
+  fi
+done
+
+case $# in
+  0) exit 0 ;;
+esac
+
+# Solaris 8's mkdir -p isn't thread-safe.  If you mkdir -p a/b and
+# mkdir -p a/c at the same time, both will detect that a is missing,
+# one will create a, then the other will try to create a and die with
+# a "File exists" error.  This is a problem when calling mkinstalldirs
+# from a parallel make.  We use --version in the probe to restrict
+# ourselves to GNU mkdir, which is thread-safe.
+case $dirmode in
+  '')
+    if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+      echo "mkdir -p -- $*"
+      exec mkdir -p -- "$@"
+    else
+      # On NextStep and OpenStep, the `mkdir' command does not
+      # recognize any option.  It will interpret all options as
+      # directories to create, and then abort because `.' already
+      # exists.
+      test -d ./-p && rmdir ./-p
+      test -d ./--version && rmdir ./--version
+    fi
+    ;;
+  *)
+    if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
+       test ! -d ./--version; then
+      echo "mkdir -m $dirmode -p -- $*"
+      exec mkdir -m "$dirmode" -p -- "$@"
+    else
+      # Clean up after NextStep and OpenStep mkdir.
+      for d in ./-m ./-p ./--version "./$dirmode";
+      do
+        test -d $d && rmdir $d
+      done
+    fi
+    ;;
+esac
+
+for file
+do
+  set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+  shift
+
+  pathcomp=
+  for d
+  do
+    pathcomp="$pathcomp$d"
+    case $pathcomp in
+      -*) pathcomp=./$pathcomp ;;
+    esac
+
+    if test ! -d "$pathcomp"; then
+      echo "mkdir $pathcomp"
+
+      mkdir "$pathcomp" || lasterr=$?
+
+      if test ! -d "$pathcomp"; then
+	errstatus=$lasterr
+      else
+	if test ! -z "$dirmode"; then
+	  echo "chmod $dirmode $pathcomp"
+	  lasterr=""
+	  chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+	  if test ! -z "$lasterr"; then
+	    errstatus=$lasterr
+	  fi
+	fi
+      fi
+    fi
+
+    pathcomp="$pathcomp/"
+  done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
diff --git a/netboot/3c509.c b/netboot/3c509.c
new file mode 100644
index 0000000..8882b9a
--- /dev/null
+++ b/netboot/3c509.c
@@ -0,0 +1,620 @@
+/**************************************************************************
+ETHERBOOT -  BOOTP/TFTP Bootstrap Program
+
+Author: Martin Renters.
+  Date: Mar 22 1995
+
+ This code is based heavily on David Greenman's if_ed.c driver and
+  Andres Vega Garcia's if_ep.c driver.
+
+ Copyright (C) 1993-1994, David Greenman, Martin Renters.
+ Copyright (C) 1993-1995, Andres Vega Garcia.
+ Copyright (C) 1995, Serge Babkin.
+  This software may be used, modified, copied, distributed, and sold, in
+  both source and binary form provided that the above copyright and these
+  terms are retained. Under no circumstances are the authors responsible for
+  the proper functioning of this software, nor do the authors assume any
+  responsibility for damages incurred with its use.
+
+3c509 support added by Serge Babkin (babkin@hq.icb.chel.su)
+
+$Id: 3c509.c,v 1.4 2002/01/02 21:56:40 okuji Exp $
+
+***************************************************************************/
+
+/* #define EDEBUG */
+
+#include "etherboot.h"
+#include "nic.h"
+#include "cards.h"
+#include "timer.h"
+#include "3c509.h"
+
+#define	udelay(n)	waiton_timer2(((n)*TICKS_PER_MS)/1000)
+
+static unsigned short	eth_nic_base;
+static enum { none, bnc, utp } connector = none;	/* for 3C509 */
+
+#ifdef	INCLUDE_3C529
+/*
+ * This table and several other pieces of the MCA support
+ * code were shamelessly borrowed from the Linux kernel source.
+ *
+ * MCA support added by Adam Fritzler (mid@auk.cx)
+ *
+ */
+struct el3_mca_adapters_struct {
+        const char *name;
+        int id;
+};
+static struct el3_mca_adapters_struct el3_mca_adapters[] = {
+        { "3Com 3c529 EtherLink III (10base2)", 0x627c },
+        { "3Com 3c529 EtherLink III (10baseT)", 0x627d },
+        { "3Com 3c529 EtherLink III (test mode)", 0x62db },
+        { "3Com 3c529 EtherLink III (TP or coax)", 0x62f6 },
+        { "3Com 3c529 EtherLink III (TP)", 0x62f7 },
+        { NULL, 0 },
+};
+#endif
+
+/**************************************************************************
+ETH_RESET - Reset adapter
+***************************************************************************/
+static void t509_reset(struct nic *nic)
+{
+	int i;
+
+	/***********************************************************
+			Reset 3Com 509 card
+	*************************************************************/
+
+	/* stop card */
+	outw(RX_DISABLE, BASE + EP_COMMAND);
+	outw(RX_DISCARD_TOP_PACK, BASE + EP_COMMAND);
+	while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)
+		;
+	outw(TX_DISABLE, BASE + EP_COMMAND);
+	outw(STOP_TRANSCEIVER, BASE + EP_COMMAND);
+	udelay(1000);
+	outw(RX_RESET, BASE + EP_COMMAND);
+	outw(TX_RESET, BASE + EP_COMMAND);
+	outw(C_INTR_LATCH, BASE + EP_COMMAND);
+	outw(SET_RD_0_MASK, BASE + EP_COMMAND);
+	outw(SET_INTR_MASK, BASE + EP_COMMAND);
+	outw(SET_RX_FILTER, BASE + EP_COMMAND);
+
+	/*
+	* initialize card
+	*/
+	while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)
+		;
+
+	GO_WINDOW(0);
+
+	/* Disable the card */
+	outw(0, BASE + EP_W0_CONFIG_CTRL);
+
+	/* Configure IRQ to none */
+	outw(SET_IRQ(0), BASE + EP_W0_RESOURCE_CFG);
+
+	/* Enable the card */
+	outw(ENABLE_DRQ_IRQ, BASE + EP_W0_CONFIG_CTRL);
+
+	GO_WINDOW(2);
+
+	/* Reload the ether_addr. */
+	for (i = 0; i < ETH_ALEN; i++)
+		outb(nic->node_addr[i], BASE + EP_W2_ADDR_0 + i);
+
+	outw(RX_RESET, BASE + EP_COMMAND);
+	outw(TX_RESET, BASE + EP_COMMAND);
+
+	/* Window 1 is operating window */
+	GO_WINDOW(1);
+	for (i = 0; i < 31; i++)
+		inb(BASE + EP_W1_TX_STATUS);
+
+	/* get rid of stray intr's */
+	outw(ACK_INTR | 0xff, BASE + EP_COMMAND);
+
+	outw(SET_RD_0_MASK | S_5_INTS, BASE + EP_COMMAND);
+
+	outw(SET_INTR_MASK, BASE + EP_COMMAND);
+
+	outw(SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST, BASE + EP_COMMAND);
+
+	/* configure BNC */
+	if (connector == bnc) {
+		outw(START_TRANSCEIVER, BASE + EP_COMMAND);
+		udelay(1000);
+	}
+	/* configure UTP */
+	else if (connector == utp) {
+		GO_WINDOW(4);
+		outw(ENABLE_UTP, BASE + EP_W4_MEDIA_TYPE);
+		sleep(2);	/* Give time for media to negotiate */
+		GO_WINDOW(1);
+	}
+
+	/* start transceiver and receiver */
+	outw(RX_ENABLE, BASE + EP_COMMAND);
+	outw(TX_ENABLE, BASE + EP_COMMAND);
+
+	/* set early threshold for minimal packet length */
+	outw(SET_RX_EARLY_THRESH | ETH_ZLEN, BASE + EP_COMMAND);
+	outw(SET_TX_START_THRESH | 16, BASE + EP_COMMAND);
+}
+
+/**************************************************************************
+ETH_TRANSMIT - Transmit a frame
+***************************************************************************/
+static char padmap[] = {
+	0, 3, 2, 1};
+
+static void t509_transmit(
+struct nic *nic,
+const char *d,			/* Destination */
+unsigned int t,			/* Type */
+unsigned int s,			/* size */
+const char *p)			/* Packet */
+{
+	register unsigned int len;
+	int pad;
+	int status;
+
+#ifdef	EDEBUG
+	printf("{l=%d,t=%hX}",s+ETH_HLEN,t);
+#endif
+
+	/* swap bytes of type */
+	t= htons(t);
+
+	len=s+ETH_HLEN; /* actual length of packet */
+	pad = padmap[len & 3];
+
+	/*
+	* The 3c509 automatically pads short packets to minimum ethernet length,
+	* but we drop packets that are too large. Perhaps we should truncate
+	* them instead?
+	*/
+	if (len + pad > ETH_FRAME_LEN) {
+		return;
+	}
+
+	/* drop acknowledgements */
+	while ((status=inb(BASE + EP_W1_TX_STATUS)) & TXS_COMPLETE ) {
+		if (status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {
+			outw(TX_RESET, BASE + EP_COMMAND);
+			outw(TX_ENABLE, BASE + EP_COMMAND);
+		}
+		outb(0x0, BASE + EP_W1_TX_STATUS);
+	}
+
+	while (inw(BASE + EP_W1_FREE_TX) < (unsigned short)len + pad + 4)
+		; /* no room in FIFO */
+
+	outw(len, BASE + EP_W1_TX_PIO_WR_1);
+	outw(0x0, BASE + EP_W1_TX_PIO_WR_1);	/* Second dword meaningless */
+
+	/* write packet */
+	outsw(BASE + EP_W1_TX_PIO_WR_1, d, ETH_ALEN/2);
+	outsw(BASE + EP_W1_TX_PIO_WR_1, nic->node_addr, ETH_ALEN/2);
+	outw(t, BASE + EP_W1_TX_PIO_WR_1);
+	outsw(BASE + EP_W1_TX_PIO_WR_1, p, s / 2);
+	if (s & 1)
+		outb(*(p+s - 1), BASE + EP_W1_TX_PIO_WR_1);
+
+	while (pad--)
+		outb(0, BASE + EP_W1_TX_PIO_WR_1);	/* Padding */
+
+	/* wait for Tx complete */
+	while((inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS) != 0)
+		;
+}
+
+/**************************************************************************
+ETH_POLL - Wait for a frame
+***************************************************************************/
+static int t509_poll(struct nic *nic)
+{
+	/* common variables */
+	unsigned short type = 0;	/* used by EDEBUG */
+	/* variables for 3C509 */
+	short status, cst;
+	register short rx_fifo;
+
+	cst=inw(BASE + EP_STATUS);
+
+#ifdef	EDEBUG
+	if(cst & 0x1FFF)
+		printf("-%hX-",cst);
+#endif
+
+	if( (cst & S_RX_COMPLETE)==0 ) {
+		/* acknowledge  everything */
+		outw(ACK_INTR| (cst & S_5_INTS), BASE + EP_COMMAND);
+		outw(C_INTR_LATCH, BASE + EP_COMMAND);
+
+		return 0;
+	}
+
+	status = inw(BASE + EP_W1_RX_STATUS);
+#ifdef	EDEBUG
+	printf("*%hX*",status);
+#endif
+
+	if (status & ERR_RX) {
+		outw(RX_DISCARD_TOP_PACK, BASE + EP_COMMAND);
+		return 0;
+	}
+
+	rx_fifo = status & RX_BYTES_MASK;
+	if (rx_fifo==0)
+		return 0;
+
+		/* read packet */
+#ifdef	EDEBUG
+	printf("[l=%d",rx_fifo);
+#endif
+	insw(BASE + EP_W1_RX_PIO_RD_1, nic->packet, rx_fifo / 2);
+	if(rx_fifo & 1)
+		nic->packet[rx_fifo-1]=inb(BASE + EP_W1_RX_PIO_RD_1);
+	nic->packetlen=rx_fifo;
+
+	while(1) {
+		status = inw(BASE + EP_W1_RX_STATUS);
+#ifdef	EDEBUG
+		printf("*%hX*",status);
+#endif
+		rx_fifo = status & RX_BYTES_MASK;
+		if(rx_fifo>0) {
+			insw(BASE + EP_W1_RX_PIO_RD_1, nic->packet+nic->packetlen, rx_fifo / 2);
+			if(rx_fifo & 1)
+				nic->packet[nic->packetlen+rx_fifo-1]=inb(BASE + EP_W1_RX_PIO_RD_1);
+			nic->packetlen+=rx_fifo;
+#ifdef	EDEBUG
+			printf("+%d",rx_fifo);
+#endif
+		}
+		if(( status & RX_INCOMPLETE )==0) {
+#ifdef	EDEBUG
+			printf("=%d",nic->packetlen);
+#endif
+			break;
+		}
+		udelay(1000);	/* if incomplete wait 1 ms */
+	}
+	/* acknowledge reception of packet */
+	outw(RX_DISCARD_TOP_PACK, BASE + EP_COMMAND);
+	while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS)
+		;
+#ifdef	EDEBUG
+	type = (nic->packet[12]<<8) | nic->packet[13];
+	if(nic->packet[0]+nic->packet[1]+nic->packet[2]+nic->packet[3]+nic->packet[4]+
+	    nic->packet[5] == 0xFF*ETH_ALEN)
+		printf(",t=%hX,b]",type);
+	else
+		printf(",t=%hX]",type);
+#endif
+	return (1);
+}
+
+/*************************************************************************
+	3Com 509 - specific routines
+**************************************************************************/
+
+static int
+eeprom_rdy(void)
+{
+	int i;
+
+	for (i = 0; is_eeprom_busy(IS_BASE) && i < MAX_EEPROMBUSY; i++);
+	if (i >= MAX_EEPROMBUSY) {
+		/* printf("3c509: eeprom failed to come ready.\n"); */
+		printf("3c509: eeprom busy.\n"); /* memory in EPROM is tight */
+		return (0);
+	}
+	return (1);
+}
+
+/*
+ * get_e: gets a 16 bits word from the EEPROM. we must have set the window
+ * before
+ */
+static int
+get_e(int offset)
+{
+	if (!eeprom_rdy())
+		return (0xffff);
+	outw(EEPROM_CMD_RD | offset, IS_BASE + EP_W0_EEPROM_COMMAND);
+	if (!eeprom_rdy())
+		return (0xffff);
+	return (inw(IS_BASE + EP_W0_EEPROM_DATA));
+}
+
+static int
+send_ID_sequence(int port)
+{
+	int cx, al;
+
+	for (al = 0xff, cx = 0; cx < 255; cx++) {
+		outb(al, port);
+		al <<= 1;
+		if (al & 0x100)
+			al ^= 0xcf;
+	}
+	return (1);
+}
+
+
+/*
+ * We get eeprom data from the id_port given an offset into the eeprom.
+ * Basically; after the ID_sequence is sent to all of the cards; they enter
+ * the ID_CMD state where they will accept command requests. 0x80-0xbf loads
+ * the eeprom data.  We then read the port 16 times and with every read; the
+ * cards check for contention (ie: if one card writes a 0 bit and another
+ * writes a 1 bit then the host sees a 0. At the end of the cycle; each card
+ * compares the data on the bus; if there is a difference then that card goes
+ * into ID_WAIT state again). In the meantime; one bit of data is returned in
+ * the AX register which is conveniently returned to us by inb().  Hence; we
+ * read 16 times getting one bit of data with each read.
+ */
+static int
+get_eeprom_data(int id_port, int offset)
+{
+	int i, data = 0;
+	outb(0x80 + offset, id_port);
+	/* Do we really need this wait? Won't be noticeable anyway */
+	udelay(10000);
+	for (i = 0; i < 16; i++)
+		data = (data << 1) | (inw(id_port) & 1);
+	return (data);
+}
+
+static void t509_disable(struct nic *nic)
+{
+	outb(0xc0, EP_ID_PORT);
+}
+
+/**************************************************************************
+ETH_PROBE - Look for an adapter
+***************************************************************************/
+#ifdef	INCLUDE_3C529
+struct nic *t529_probe(struct nic *nic, unsigned short *probe_addrs)
+#else
+struct nic *t509_probe(struct nic *nic, unsigned short *probe_addrs)
+#endif
+{
+	/* common variables */
+	int i;
+	int failcount;
+
+#ifdef	INCLUDE_3C529
+	struct el3_mca_adapters_struct *mcafound = NULL;
+	int mca_pos4 = 0, mca_pos5 = 0, mca_irq = 0;
+#endif
+
+	t509_disable(nic);		/* in case board was active */
+					/* note that nic is not used */
+	for (failcount = 0; failcount < 4000; failcount++) {
+		int data, j, io_base, id_port;
+		unsigned short k;
+		int ep_current_tag;
+		short *p;
+#ifdef	INCLUDE_3C529
+		int curboard;
+#endif
+
+		id_port = EP_ID_PORT;
+		ep_current_tag = EP_LAST_TAG + 1;
+
+	/*********************************************************
+			Search for 3Com 509 card
+	***********************************************************/
+#ifdef	INCLUDE_3C529
+		/*
+		 * XXX: We should really check to make sure we have an MCA
+		 * bus controller before going ahead with this...
+		 *
+		 * For now, we avoid any hassle by making it a compile
+		 * time option.
+		 *
+		 */
+		printf("\nWarning: Assuming presence of MCA bus\n");
+
+                /* Make sure motherboard setup is off */
+                outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);
+
+		/* Cycle through slots */
+		for(curboard=0; curboard<MCA_MAX_SLOT_NR; curboard++) {
+			int boardid;
+			int curcard;
+
+			outb_p(0x8|(curboard&0xf), MCA_ADAPTER_SETUP_REG);
+
+			boardid = inb_p(MCA_POS_REG(0));
+			boardid += inb_p(MCA_POS_REG(1)) << 8;
+
+			curcard = 0;
+			while (el3_mca_adapters[curcard].name) {
+				if (el3_mca_adapters[curcard].id == boardid) {
+					mcafound = &el3_mca_adapters[curcard];
+
+					mca_pos4 = inb_p(MCA_POS_REG(4));
+					mca_pos5 = inb_p(MCA_POS_REG(5));
+
+					goto donewithdetect;
+				}
+				else
+					curcard++;
+			}
+
+		}
+	donewithdetect:
+		/* Kill all setup modes */
+		outb_p(0, MCA_ADAPTER_SETUP_REG);
+
+		if (mcafound) {
+			eth_nic_base = ((short)((mca_pos4&0xfc)|0x02)) << 8;
+			mca_irq = mca_pos5 & 0x0f;
+			ep_current_tag--;
+		}
+		else
+			printf("MCA Card not found\n");
+#endif
+	/* Look for the EISA boards, leave them activated */
+	/* search for the first card, ignore all others */
+	for(j = 1; j < 16; j++) {
+		io_base = (j * EP_EISA_START) | EP_EISA_W0;
+		if (inw(io_base + EP_W0_MFG_ID) != MFG_ID)
+			continue;
+
+		/* we must have found 0x1f if the board is EISA configurated */
+		if ((inw(io_base + EP_W0_ADDRESS_CFG) & 0x1f) != 0x1f)
+			continue;
+
+		/* Reset and Enable the card */
+		outb(W0_P4_CMD_RESET_ADAPTER, io_base + EP_W0_CONFIG_CTRL);
+		udelay(1000); /* Must wait 800 µs, be conservative */
+		outb(W0_P4_CMD_ENABLE_ADAPTER, io_base + EP_W0_CONFIG_CTRL);
+
+		/*
+		 * Once activated, all the registers are mapped in the range
+		 * x000 - x00F, where x is the slot number.
+		 */
+		eth_nic_base = j * EP_EISA_START;
+		break;
+	}
+	ep_current_tag--;
+
+	/* Look for the ISA boards. Init and leave them actived */
+	/* search for the first card, ignore all others */
+	outb(0xc0, id_port);	/* Global reset */
+	udelay(1000);		/* wait 1 ms */
+	for (i = 0; i < EP_MAX_BOARDS; i++) {
+		outb(0, id_port);
+		outb(0, id_port);
+		send_ID_sequence(id_port);
+
+		data = get_eeprom_data(id_port, EEPROM_MFG_ID);
+		if (data != MFG_ID)
+			break;
+
+		/* resolve contention using the Ethernet address */
+		for (j = 0; j < 3; j++)
+			data = get_eeprom_data(id_port, j);
+
+		eth_nic_base =
+		    (get_eeprom_data(id_port, EEPROM_ADDR_CFG) & 0x1f) * 0x10 + 0x200;
+		outb(ep_current_tag, id_port);	/* tags board */
+		outb(ACTIVATE_ADAPTER_TO_CONFIG, id_port);
+		ep_current_tag--;
+		break;
+	}
+
+	if (i >= EP_MAX_BOARDS)
+		goto no3c509;
+
+	/*
+	* The iobase was found and MFG_ID was 0x6d50. PROD_ID should be
+	* 0x9[0-f]50
+	*/
+	GO_WINDOW(0);
+	k = get_e(EEPROM_PROD_ID);
+#ifdef	INCLUDE_3C529
+	/*
+	 * On MCA, the PROD_ID matches the MCA card ID (POS0+POS1)
+	 */
+	if (mcafound) {
+		if (mcafound->id != k) {
+			printf("MCA: PROD_ID in EEPROM does not match MCA card ID! (%hX != %hX)\n", k, mcafound->id);
+			goto no3c509;
+		}
+	} else { /* for ISA/EISA */
+		if ((k & 0xf0ff) != (PROD_ID & 0xf0ff))
+			goto no3c509;
+	}
+#else
+	if ((k & 0xf0ff) != (PROD_ID & 0xf0ff))
+		goto no3c509;
+#endif
+
+#ifdef	INCLUDE_3C529
+	if (mcafound) {
+		printf("%s board found on MCA at %#hx IRQ %d -",
+		       mcafound->name, eth_nic_base, mca_irq);
+	} else {
+#endif
+		if(eth_nic_base >= EP_EISA_START)
+			printf("3C5x9 board on EISA at %#hx - ",eth_nic_base);
+		else
+			printf("3C5x9 board on ISA at %#hx - ",eth_nic_base);
+#ifdef	INCLUDE_3C529
+	}
+#endif
+
+	/* test for presence of connectors */
+	i = inw(IS_BASE + EP_W0_CONFIG_CTRL);
+	j = (inw(IS_BASE + EP_W0_ADDRESS_CFG) >> 14) & 0x3;
+
+	switch(j) {
+		case 0:
+			if (i & IS_UTP) {
+				printf("10baseT\n");
+				connector = utp;
+				}
+			else {
+				printf("10baseT not present\n");
+				goto no3c509;
+				}
+			break;
+		case 1:
+			if (i & IS_AUI)
+				printf("10base5\n");
+			else {
+				printf("10base5 not present\n");
+				goto no3c509;
+				}
+			break;
+		case 3:
+			if (i & IS_BNC) {
+				printf("10base2\n");
+				connector = bnc;
+				}
+			else {
+				printf("10base2 not present\n");
+				goto no3c509;
+				}
+			break;
+		default:
+			printf("unknown connector\n");
+			goto no3c509;
+		}
+	/*
+	* Read the station address from the eeprom
+	*/
+	p = (unsigned short *) nic->node_addr;
+	for (i = 0; i < ETH_ALEN / 2; i++) {
+		GO_WINDOW(0);
+		p[i] = htons(get_e(i));
+		GO_WINDOW(2);
+		outw(ntohs(p[i]), BASE + EP_W2_ADDR_0 + (i * 2));
+	}
+	printf("Ethernet address: %!\n", nic->node_addr);
+	t509_reset(nic);
+	nic->reset = t509_reset;
+	nic->poll = t509_poll;
+	nic->transmit = t509_transmit;
+	nic->disable = t509_disable;
+	return nic;
+no3c509:
+	printf("(probe fail)");
+	}
+	return 0;
+}
+
+/*
+ * Local variables:
+ *  c-basic-offset: 8
+ * End:
+ */
diff --git a/netboot/3c509.h b/netboot/3c509.h
new file mode 100644
index 0000000..7214932
--- /dev/null
+++ b/netboot/3c509.h
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 1993 Herb Peyerl (hpeyerl@novatel.ca) All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer. 2. The name
+ * of the author may not be used to endorse or promote products derived from
+ * this software withough specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * if_epreg.h,v 1.4 1994/11/13 10:12:37 gibbs Exp Modified by:
+ *
+ October 2, 1994
+
+ Modified by: Andres Vega Garcia
+
+ INRIA - Sophia Antipolis, France
+ e-mail: avega@sophia.inria.fr
+ finger: avega@pax.inria.fr
+
+ */
+
+/*
+ * Ethernet software status per interface.
+ */
+/*
+ * Some global constants
+ */
+
+#define TX_INIT_RATE		16
+#define TX_INIT_MAX_RATE	64
+#define RX_INIT_LATENCY		64
+#define RX_INIT_EARLY_THRESH	64
+#define MIN_RX_EARLY_THRESHF	16	/* not less than ether_header */
+#define MIN_RX_EARLY_THRESHL	4
+
+#define EEPROMSIZE	0x40
+#define MAX_EEPROMBUSY	1000
+#define EP_LAST_TAG	0xd7
+#define EP_MAX_BOARDS	16
+#define EP_ID_PORT	0x100
+
+/*
+ * some macros to acces long named fields
+ */
+#define IS_BASE (eth_nic_base)
+#define BASE	(eth_nic_base)
+
+/*
+ * Commands to read/write EEPROM trough EEPROM command register (Window 0,
+ * Offset 0xa)
+ */
+#define EEPROM_CMD_RD	0x0080	/* Read:  Address required (5 bits) */
+#define EEPROM_CMD_WR	0x0040	/* Write: Address required (5 bits) */
+#define EEPROM_CMD_ERASE 0x00c0	/* Erase: Address required (5 bits) */
+#define EEPROM_CMD_EWEN	0x0030	/* Erase/Write Enable: No data required */
+
+#define EEPROM_BUSY		(1<<15)
+#define EEPROM_TST_MODE		(1<<14)
+
+/*
+ * Some short functions, worth to let them be a macro
+ */
+#define is_eeprom_busy(b) (inw((b)+EP_W0_EEPROM_COMMAND)&EEPROM_BUSY)
+#define GO_WINDOW(x)	outw(WINDOW_SELECT|(x), BASE+EP_COMMAND)
+
+/**************************************************************************
+ *
+ * These define the EEPROM data structure.  They are used in the probe
+ * function to verify the existance of the adapter after having sent
+ * the ID_Sequence.
+ *
+ * There are others but only the ones we use are defined here.
+ *
+ **************************************************************************/
+
+#define EEPROM_NODE_ADDR_0	0x0	/* Word */
+#define EEPROM_NODE_ADDR_1	0x1	/* Word */
+#define EEPROM_NODE_ADDR_2	0x2	/* Word */
+#define EEPROM_PROD_ID		0x3	/* 0x9[0-f]50 */
+#define EEPROM_MFG_ID		0x7	/* 0x6d50 */
+#define EEPROM_ADDR_CFG		0x8	/* Base addr */
+#define EEPROM_RESOURCE_CFG	0x9	/* IRQ. Bits 12-15 */
+
+/**************************************************************************
+ *
+ * These are the registers for the 3Com 3c509 and their bit patterns when
+ * applicable.  They have been taken out the the "EtherLink III Parallel
+ * Tasking EISA and ISA Technical Reference" "Beta Draft 10/30/92" manual
+ * from 3com.
+ *
+ **************************************************************************/
+
+#define EP_COMMAND		0x0e	/* Write. BASE+0x0e is always a
+					 * command reg. */
+#define EP_STATUS		0x0e	/* Read. BASE+0x0e is always status
+					 * reg. */
+#define EP_WINDOW		0x0f	/* Read. BASE+0x0f is always window
+					 * reg. */
+/*
+ * Window 0 registers. Setup.
+ */
+/* Write */
+#define EP_W0_EEPROM_DATA	0x0c
+#define EP_W0_EEPROM_COMMAND	0x0a
+#define EP_W0_RESOURCE_CFG	0x08
+#define EP_W0_ADDRESS_CFG	0x06
+#define EP_W0_CONFIG_CTRL	0x04
+/* Read */
+#define EP_W0_PRODUCT_ID	0x02
+#define EP_W0_MFG_ID		0x00
+
+/*
+ * Window 1 registers. Operating Set.
+ */
+/* Write */
+#define EP_W1_TX_PIO_WR_2	0x02
+#define EP_W1_TX_PIO_WR_1	0x00
+/* Read */
+#define EP_W1_FREE_TX		0x0c
+#define EP_W1_TX_STATUS		0x0b	/* byte */
+#define EP_W1_TIMER		0x0a	/* byte */
+#define EP_W1_RX_STATUS		0x08
+#define EP_W1_RX_PIO_RD_2	0x02
+#define EP_W1_RX_PIO_RD_1	0x00
+
+/*
+ * Window 2 registers. Station Address Setup/Read
+ */
+/* Read/Write */
+#define EP_W2_ADDR_5		0x05
+#define EP_W2_ADDR_4		0x04
+#define EP_W2_ADDR_3		0x03
+#define EP_W2_ADDR_2		0x02
+#define EP_W2_ADDR_1		0x01
+#define EP_W2_ADDR_0		0x00
+
+/*
+ * Window 3 registers.  FIFO Management.
+ */
+/* Read */
+#define EP_W3_FREE_TX		0x0c
+#define EP_W3_FREE_RX		0x0a
+
+/*
+ * Window 4 registers. Diagnostics.
+ */
+/* Read/Write */
+#define EP_W4_MEDIA_TYPE	0x0a
+#define EP_W4_CTRLR_STATUS	0x08
+#define EP_W4_NET_DIAG		0x06
+#define EP_W4_FIFO_DIAG		0x04
+#define EP_W4_HOST_DIAG		0x02
+#define EP_W4_TX_DIAG		0x00
+
+/*
+ * Window 5 Registers.  Results and Internal status.
+ */
+/* Read */
+#define EP_W5_READ_0_MASK	0x0c
+#define EP_W5_INTR_MASK		0x0a
+#define EP_W5_RX_FILTER		0x08
+#define EP_W5_RX_EARLY_THRESH	0x06
+#define EP_W5_TX_AVAIL_THRESH	0x02
+#define EP_W5_TX_START_THRESH	0x00
+
+/*
+ * Window 6 registers. Statistics.
+ */
+/* Read/Write */
+#define TX_TOTAL_OK		0x0c
+#define RX_TOTAL_OK		0x0a
+#define TX_DEFERRALS		0x08
+#define RX_FRAMES_OK		0x07
+#define TX_FRAMES_OK		0x06
+#define RX_OVERRUNS		0x05
+#define TX_COLLISIONS		0x04
+#define TX_AFTER_1_COLLISION	0x03
+#define TX_AFTER_X_COLLISIONS	0x02
+#define TX_NO_SQE		0x01
+#define TX_CD_LOST		0x00
+
+/****************************************
+ *
+ * Register definitions.
+ *
+ ****************************************/
+
+/*
+ * Command register. All windows.
+ *
+ * 16 bit register.
+ *     15-11:  5-bit code for command to be executed.
+ *     10-0:   11-bit arg if any. For commands with no args;
+ *	      this can be set to anything.
+ */
+#define GLOBAL_RESET		(unsigned short) 0x0000	/* Wait at least 1ms
+							 * after issuing */
+#define WINDOW_SELECT		(unsigned short) (0x1<<11)
+#define START_TRANSCEIVER	(unsigned short) (0x2<<11)	/* Read ADDR_CFG reg to
+							 * determine whether
+							 * this is needed. If
+							 * so; wait 800 uSec
+							 * before using trans-
+							 * ceiver. */
+#define RX_DISABLE		(unsigned short) (0x3<<11)	/* state disabled on
+							 * power-up */
+#define RX_ENABLE		(unsigned short) (0x4<<11)
+#define RX_RESET		(unsigned short) (0x5<<11)
+#define RX_DISCARD_TOP_PACK	(unsigned short) (0x8<<11)
+#define TX_ENABLE		(unsigned short) (0x9<<11)
+#define TX_DISABLE		(unsigned short) (0xa<<11)
+#define TX_RESET		(unsigned short) (0xb<<11)
+#define REQ_INTR		(unsigned short) (0xc<<11)
+#define SET_INTR_MASK		(unsigned short) (0xe<<11)
+#define SET_RD_0_MASK		(unsigned short) (0xf<<11)
+#define SET_RX_FILTER		(unsigned short) (0x10<<11)
+#define FIL_INDIVIDUAL	(unsigned short) (0x1)
+#define FIL_GROUP		(unsigned short) (0x2)
+#define FIL_BRDCST	(unsigned short) (0x4)
+#define FIL_ALL		(unsigned short) (0x8)
+#define SET_RX_EARLY_THRESH	(unsigned short) (0x11<<11)
+#define SET_TX_AVAIL_THRESH	(unsigned short) (0x12<<11)
+#define SET_TX_START_THRESH	(unsigned short) (0x13<<11)
+#define STATS_ENABLE		(unsigned short) (0x15<<11)
+#define STATS_DISABLE		(unsigned short) (0x16<<11)
+#define STOP_TRANSCEIVER	(unsigned short) (0x17<<11)
+/*
+ * The following C_* acknowledge the various interrupts. Some of them don't
+ * do anything.  See the manual.
+ */
+#define ACK_INTR		(unsigned short) (0x6800)
+#define C_INTR_LATCH	(unsigned short) (ACK_INTR|0x1)
+#define C_CARD_FAILURE	(unsigned short) (ACK_INTR|0x2)
+#define C_TX_COMPLETE	(unsigned short) (ACK_INTR|0x4)
+#define C_TX_AVAIL	(unsigned short) (ACK_INTR|0x8)
+#define C_RX_COMPLETE	(unsigned short) (ACK_INTR|0x10)
+#define C_RX_EARLY	(unsigned short) (ACK_INTR|0x20)
+#define C_INT_RQD		(unsigned short) (ACK_INTR|0x40)
+#define C_UPD_STATS	(unsigned short) (ACK_INTR|0x80)
+
+/*
+ * Status register. All windows.
+ *
+ *     15-13:  Window number(0-7).
+ *     12:     Command_in_progress.
+ *     11:     reserved.
+ *     10:     reserved.
+ *     9:      reserved.
+ *     8:      reserved.
+ *     7:      Update Statistics.
+ *     6:      Interrupt Requested.
+ *     5:      RX Early.
+ *     4:      RX Complete.
+ *     3:      TX Available.
+ *     2:      TX Complete.
+ *     1:      Adapter Failure.
+ *     0:      Interrupt Latch.
+ */
+#define S_INTR_LATCH		(unsigned short) (0x1)
+#define S_CARD_FAILURE		(unsigned short) (0x2)
+#define S_TX_COMPLETE		(unsigned short) (0x4)
+#define S_TX_AVAIL		(unsigned short) (0x8)
+#define S_RX_COMPLETE		(unsigned short) (0x10)
+#define S_RX_EARLY		(unsigned short) (0x20)
+#define S_INT_RQD		(unsigned short) (0x40)
+#define S_UPD_STATS		(unsigned short) (0x80)
+#define S_5_INTS		(S_CARD_FAILURE|S_TX_COMPLETE|\
+				 S_TX_AVAIL|S_RX_COMPLETE|S_RX_EARLY)
+#define S_COMMAND_IN_PROGRESS	(unsigned short) (0x1000)
+
+/*
+ * FIFO Registers.
+ * RX Status. Window 1/Port 08
+ *
+ *     15:     Incomplete or FIFO empty.
+ *     14:     1: Error in RX Packet   0: Incomplete or no error.
+ *     13-11:  Type of error.
+ *	      1000 = Overrun.
+ *	      1011 = Run Packet Error.
+ *	      1100 = Alignment Error.
+ *	      1101 = CRC Error.
+ *	      1001 = Oversize Packet Error (>1514 bytes)
+ *	      0010 = Dribble Bits.
+ *	      (all other error codes, no errors.)
+ *
+ *     10-0:   RX Bytes (0-1514)
+ */
+#define ERR_RX_INCOMPLETE	(unsigned short) (0x1<<15)
+#define ERR_RX			(unsigned short) (0x1<<14)
+#define ERR_RX_OVERRUN		(unsigned short) (0x8<<11)
+#define ERR_RX_RUN_PKT		(unsigned short) (0xb<<11)
+#define ERR_RX_ALIGN		(unsigned short) (0xc<<11)
+#define ERR_RX_CRC		(unsigned short) (0xd<<11)
+#define ERR_RX_OVERSIZE		(unsigned short) (0x9<<11)
+#define ERR_RX_DRIBBLE		(unsigned short) (0x2<<11)
+
+/*
+ * FIFO Registers.
+ * TX Status. Window 1/Port 0B
+ *
+ *   Reports the transmit status of a completed transmission. Writing this
+ *   register pops the transmit completion stack.
+ *
+ *   Window 1/Port 0x0b.
+ *
+ *     7:      Complete
+ *     6:      Interrupt on successful transmission requested.
+ *     5:      Jabber Error (TP Only, TX Reset required. )
+ *     4:      Underrun (TX Reset required. )
+ *     3:      Maximum Collisions.
+ *     2:      TX Status Overflow.
+ *     1-0:    Undefined.
+ *
+ */
+#define TXS_COMPLETE		0x80
+#define TXS_SUCCES_INTR_REQ		0x40
+#define TXS_JABBER		0x20
+#define TXS_UNDERRUN		0x10
+#define TXS_MAX_COLLISION	0x8
+#define TXS_STATUS_OVERFLOW	0x4
+
+/*
+ * Configuration control register.
+ * Window 0/Port 04
+ */
+/* Read */
+#define IS_AUI				(1<<13)
+#define IS_BNC				(1<<12)
+#define IS_UTP				(1<<9)
+/* Write */
+#define ENABLE_DRQ_IRQ			0x0001
+#define W0_P4_CMD_RESET_ADAPTER		0x4
+#define W0_P4_CMD_ENABLE_ADAPTER	0x1
+/*
+ * Media type and status.
+ * Window 4/Port 0A
+ */
+#define ENABLE_UTP			0xc0
+#define DISABLE_UTP			0x0
+
+/*
+ * Resource control register
+ */
+
+#define SET_IRQ(i)	( ((i)<<12) | 0xF00) /* set IRQ i */
+
+/*
+ * Receive status register
+ */
+
+#define RX_BYTES_MASK			(unsigned short) (0x07ff)
+#define RX_ERROR	0x4000
+#define RX_INCOMPLETE	0x8000
+
+
+/*
+ * Misc defines for various things.
+ */
+#define ACTIVATE_ADAPTER_TO_CONFIG	0xff /* to the id_port */
+#define MFG_ID				0x6d50 /* in EEPROM and W0 ADDR_CONFIG */
+#define PROD_ID				0x9150
+
+#define AUI				0x1
+#define BNC				0x2
+#define UTP				0x4
+
+#define RX_BYTES_MASK			(unsigned short) (0x07ff)
+
+ /* EISA support */
+#define EP_EISA_START			0x1000
+#define EP_EISA_W0			0x0c80
+
+#ifdef	INCLUDE_3C529
+ /* MCA support */
+#define MCA_MOTHERBOARD_SETUP_REG	0x94
+#define MCA_ADAPTER_SETUP_REG		0x96
+#define MCA_MAX_SLOT_NR			8
+#define MCA_POS_REG(n)			(0x100+(n))
+#endif
+
+/*
+ * Local variables:
+ *  c-basic-offset: 8
+ * End:
+ */
diff --git a/netboot/3c595.c b/netboot/3c595.c
new file mode 100644
index 0000000..5a04e25
--- /dev/null
+++ b/netboot/3c595.c
@@ -0,0 +1,503 @@
+/*
+* 3c595.c -- 3COM 3C595 Fast Etherlink III PCI driver for etherboot
+*
+* Copyright (C) 2000 Shusuke Nisiyama <shu@athena.qe.eng.hokudai.ac.jp>
+* All rights reserved.
+* Mar. 14, 2000
+*
+*  This software may be used, modified, copied, distributed, and sold, in
+*  both source and binary form provided that the above copyright and these
+*  terms are retained. Under no circumstances are the authors responsible for
+*  the proper functioning of this software, nor do the authors assume any
+*  responsibility for damages incurred with its use.
+*
+* This code is based on Martin Renters' etherboot-4.4.3 3c509.c and 
+* Herb Peyerl's FreeBSD 3.4-RELEASE if_vx.c driver.
+*
+*  Copyright (C) 1993-1994, David Greenman, Martin Renters.
+*  Copyright (C) 1993-1995, Andres Vega Garcia.
+*  Copyright (C) 1995, Serge Babkin.
+*
+*  Copyright (c) 1994 Herb Peyerl <hpeyerl@novatel.ca>
+*
+*/
+
+/* #define EDEBUG */
+
+#include "etherboot.h"
+#include "nic.h"
+#include "pci.h"
+#include "3c595.h"
+#include "timer.h"
+
+static unsigned short	eth_nic_base, eth_asic_base;
+static unsigned short	vx_connector, vx_connectors;
+
+static struct connector_entry {
+  int bit;
+  char *name;
+} conn_tab[VX_CONNECTORS] = {
+#define CONNECTOR_UTP   0
+  { 0x08, "utp"},
+#define CONNECTOR_AUI   1
+  { 0x20, "aui"},
+/* dummy */
+  { 0, "???"},
+#define CONNECTOR_BNC   3
+  { 0x10, "bnc"},
+#define CONNECTOR_TX    4
+  { 0x02, "tx"},
+#define CONNECTOR_FX    5
+  { 0x04, "fx"},
+#define CONNECTOR_MII   6
+  { 0x40, "mii"},
+  { 0, "???"}
+};
+
+static void vxgetlink(void);
+static void vxsetlink(void);
+
+#define	udelay(n)	waiton_timer2(((n)*TICKS_PER_MS)/1000)
+
+/**************************************************************************
+ETH_RESET - Reset adapter
+***************************************************************************/
+static void t595_reset(struct nic *nic)
+{
+	int i, j;
+
+	/***********************************************************
+			Reset 3Com 595 card
+	*************************************************************/
+
+	/* stop card */
+	outw(RX_DISABLE, BASE + VX_COMMAND);
+	outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
+	VX_BUSY_WAIT;
+	outw(TX_DISABLE, BASE + VX_COMMAND);
+	outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
+	udelay(8000);
+	outw(RX_RESET, BASE + VX_COMMAND);
+	VX_BUSY_WAIT;
+	outw(TX_RESET, BASE + VX_COMMAND);
+	VX_BUSY_WAIT;
+	outw(C_INTR_LATCH, BASE + VX_COMMAND);
+	outw(SET_RD_0_MASK, BASE + VX_COMMAND);
+	outw(SET_INTR_MASK, BASE + VX_COMMAND);
+	outw(SET_RX_FILTER, BASE + VX_COMMAND);
+
+	/*
+	* initialize card
+	*/
+	VX_BUSY_WAIT;
+
+	GO_WINDOW(0);
+
+	/* Disable the card */
+/*	outw(0, BASE + VX_W0_CONFIG_CTRL); */
+
+	/* Configure IRQ to none */
+/*	outw(SET_IRQ(0), BASE + VX_W0_RESOURCE_CFG); */
+
+	/* Enable the card */
+/*	outw(ENABLE_DRQ_IRQ, BASE + VX_W0_CONFIG_CTRL); */
+
+	GO_WINDOW(2);
+
+	/* Reload the ether_addr. */
+	for (i = 0; i < ETH_ALEN; i++)
+		outb(nic->node_addr[i], BASE + VX_W2_ADDR_0 + i);
+
+	outw(RX_RESET, BASE + VX_COMMAND);
+	VX_BUSY_WAIT;
+	outw(TX_RESET, BASE + VX_COMMAND);
+	VX_BUSY_WAIT;
+
+	/* Window 1 is operating window */
+	GO_WINDOW(1);
+	for (i = 0; i < 31; i++)
+		inb(BASE + VX_W1_TX_STATUS);
+
+	outw(SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
+		S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
+	outw(SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
+		S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
+
+/*
+ * Attempt to get rid of any stray interrupts that occured during
+ * configuration.  On the i386 this isn't possible because one may
+ * already be queued.  However, a single stray interrupt is
+ * unimportant.
+ */
+
+	outw(ACK_INTR | 0xff, BASE + VX_COMMAND);
+
+	outw(SET_RX_FILTER | FIL_INDIVIDUAL |
+	    FIL_BRDCST, BASE + VX_COMMAND);
+
+	vxsetlink();
+/*{
+	int i,j;
+	i = CONNECTOR_TX;
+	GO_WINDOW(3);
+	j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK;
+	outl(BASE + VX_W3_INTERNAL_CFG, j | (i <<INTERNAL_CONNECTOR_BITS));
+        GO_WINDOW(4);
+        outw(LINKBEAT_ENABLE, BASE + VX_W4_MEDIA_TYPE);
+        GO_WINDOW(1);
+}*/
+
+	/* start tranciever and receiver */
+	outw(RX_ENABLE, BASE + VX_COMMAND);
+	outw(TX_ENABLE, BASE + VX_COMMAND);
+
+}
+
+/**************************************************************************
+ETH_TRANSMIT - Transmit a frame
+***************************************************************************/
+static char padmap[] = {
+	0, 3, 2, 1};
+
+static void t595_transmit(
+struct nic *nic,
+const char *d,			/* Destination */
+unsigned int t,			/* Type */
+unsigned int s,			/* size */
+const char *p)			/* Packet */
+{
+	register int len;
+	int pad;
+	int status;
+
+#ifdef EDEBUG
+	printf("{l=%d,t=%hX}",s+ETH_HLEN,t);
+#endif
+
+	/* swap bytes of type */
+	t= htons(t);
+
+	len=s+ETH_HLEN; /* actual length of packet */
+	pad = padmap[len & 3];
+
+	/*
+	* The 3c595 automatically pads short packets to minimum ethernet length,
+	* but we drop packets that are too large. Perhaps we should truncate
+	* them instead?
+	*/
+	if (len + pad > ETH_FRAME_LEN) {
+		return;
+	}
+
+	/* drop acknowledgements */
+	while(( status=inb(BASE + VX_W1_TX_STATUS) )& TXS_COMPLETE ) {
+		if(status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {
+			outw(TX_RESET, BASE + VX_COMMAND);
+			outw(TX_ENABLE, BASE + VX_COMMAND);
+		}
+
+		outb(0x0, BASE + VX_W1_TX_STATUS);
+	}
+
+	while (inw(BASE + VX_W1_FREE_TX) < len + pad + 4) {
+		/* no room in FIFO */
+	}
+
+	outw(len, BASE + VX_W1_TX_PIO_WR_1);
+	outw(0x0, BASE + VX_W1_TX_PIO_WR_1);	/* Second dword meaningless */
+
+	/* write packet */
+	outsw(BASE + VX_W1_TX_PIO_WR_1, d, ETH_ALEN/2);
+	outsw(BASE + VX_W1_TX_PIO_WR_1, nic->node_addr, ETH_ALEN/2);
+	outw(t, BASE + VX_W1_TX_PIO_WR_1);
+	outsw(BASE + VX_W1_TX_PIO_WR_1, p, s / 2);
+	if (s & 1)
+		outb(*(p+s - 1), BASE + VX_W1_TX_PIO_WR_1);
+
+	while (pad--)
+		outb(0, BASE + VX_W1_TX_PIO_WR_1);	/* Padding */
+
+        /* wait for Tx complete */
+        while((inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS) != 0)
+                ;
+}
+
+/**************************************************************************
+ETH_POLL - Wait for a frame
+***************************************************************************/
+static int t595_poll(struct nic *nic)
+{
+	/* common variables */
+	unsigned short type = 0;	/* used by EDEBUG */
+	/* variables for 3C595 */
+	short status, cst;
+	register short rx_fifo;
+
+	cst=inw(BASE + VX_STATUS);
+
+#ifdef EDEBUG
+	if(cst & 0x1FFF)
+		printf("-%hX-",cst);
+#endif
+
+	if( (cst & S_RX_COMPLETE)==0 ) {
+		/* acknowledge  everything */
+		outw(ACK_INTR | cst, BASE + VX_COMMAND);
+		outw(C_INTR_LATCH, BASE + VX_COMMAND);
+
+		return 0;
+	}
+
+	status = inw(BASE + VX_W1_RX_STATUS);
+#ifdef EDEBUG
+	printf("*%hX*",status);
+#endif
+
+	if (status & ERR_RX) {
+		outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
+		return 0;
+	}
+
+	rx_fifo = status & RX_BYTES_MASK;
+	if (rx_fifo==0)
+		return 0;
+
+		/* read packet */
+#ifdef EDEBUG
+	printf("[l=%d",rx_fifo);
+#endif
+	insw(BASE + VX_W1_RX_PIO_RD_1, nic->packet, rx_fifo / 2);
+	if(rx_fifo & 1)
+		nic->packet[rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1);
+	nic->packetlen=rx_fifo;
+
+	while(1) {
+		status = inw(BASE + VX_W1_RX_STATUS);
+#ifdef EDEBUG
+		printf("*%hX*",status);
+#endif
+		rx_fifo = status & RX_BYTES_MASK;
+
+		if(rx_fifo>0) {
+			insw(BASE + VX_W1_RX_PIO_RD_1, nic->packet+nic->packetlen, rx_fifo / 2);
+			if(rx_fifo & 1)
+				nic->packet[nic->packetlen+rx_fifo-1]=inb(BASE + VX_W1_RX_PIO_RD_1);
+			nic->packetlen+=rx_fifo;
+#ifdef EDEBUG
+			printf("+%d",rx_fifo);
+#endif
+		}
+		if(( status & RX_INCOMPLETE )==0) {
+#ifdef EDEBUG
+			printf("=%d",nic->packetlen);
+#endif
+			break;
+		}
+		udelay(1000);
+	}
+
+	/* acknowledge reception of packet */
+	outw(RX_DISCARD_TOP_PACK, BASE + VX_COMMAND);
+	while (inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS);
+#ifdef EDEBUG
+	type = (nic->packet[12]<<8) | nic->packet[13];
+	if(nic->packet[0]+nic->packet[1]+nic->packet[2]+nic->packet[3]+nic->packet[4]+
+	    nic->packet[5] == 0xFF*ETH_ALEN)
+		printf(",t=%hX,b]",type);
+	else
+		printf(",t=%hX]",type);
+#endif
+	return 1;
+}
+
+
+/*************************************************************************
+	3Com 595 - specific routines
+**************************************************************************/
+
+static int
+eeprom_rdy()
+{
+	int i;
+
+	for (i = 0; is_eeprom_busy(BASE) && i < MAX_EEPROMBUSY; i++)
+		udelay(1000);
+	if (i >= MAX_EEPROMBUSY) {
+	        /* printf("3c595: eeprom failed to come ready.\n"); */
+		printf("3c595: eeprom is busy.\n"); /* memory in EPROM is tight */
+		return (0);
+	}
+	return (1);
+}
+
+/*
+ * get_e: gets a 16 bits word from the EEPROM. we must have set the window
+ * before
+ */
+static int
+get_e(offset)
+int offset;
+{
+	if (!eeprom_rdy())
+		return (0xffff);
+	outw(EEPROM_CMD_RD | offset, BASE + VX_W0_EEPROM_COMMAND);
+	if (!eeprom_rdy())
+		return (0xffff);
+	return (inw(BASE + VX_W0_EEPROM_DATA));
+}
+
+static void            
+vxgetlink(void)
+{
+    int n, k;
+
+    GO_WINDOW(3);
+    vx_connectors = inw(BASE + VX_W3_RESET_OPT) & 0x7f;
+    for (n = 0, k = 0; k < VX_CONNECTORS; k++) {
+      if (vx_connectors & conn_tab[k].bit) {
+        if (n > 0) {
+          printf("/");
+	}
+        printf(conn_tab[k].name);
+        n++;
+      }
+    }
+    if (vx_connectors == 0) {
+        printf("no connectors!");
+        return;
+    }
+    GO_WINDOW(3);
+    vx_connector = (inl(BASE + VX_W3_INTERNAL_CFG) 
+                        & INTERNAL_CONNECTOR_MASK) 
+                        >> INTERNAL_CONNECTOR_BITS;
+    if (vx_connector & 0x10) {
+        vx_connector &= 0x0f;
+        printf("[*%s*]", conn_tab[vx_connector].name);
+        printf(": disable 'auto select' with DOS util!");
+    } else {
+        printf("[*%s*]", conn_tab[vx_connector].name);
+    }
+}
+
+static void            
+vxsetlink(void)
+{       
+    int i, j, k;
+    char *reason, *warning;
+    static short prev_flags;
+    static char prev_conn = -1;
+
+    if (prev_conn == -1) {
+        prev_conn = vx_connector;
+    }
+
+    i = vx_connector;       /* default in EEPROM */
+    reason = "default";
+    warning = 0;
+
+    if ((vx_connectors & conn_tab[vx_connector].bit) == 0) {
+        warning = "strange connector type in EEPROM.";
+        reason = "forced";
+        i = CONNECTOR_UTP;
+    }
+
+        if (warning != 0) {
+            printf("warning: %s\n", warning);
+        }
+        printf("selected %s. (%s)\n", conn_tab[i].name, reason);
+
+    /* Set the selected connector. */
+    GO_WINDOW(3);
+    j = inl(BASE + VX_W3_INTERNAL_CFG) & ~INTERNAL_CONNECTOR_MASK;
+    outl(j | (i <<INTERNAL_CONNECTOR_BITS), BASE + VX_W3_INTERNAL_CFG);
+
+    /* First, disable all. */
+    outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
+    udelay(8000);
+    GO_WINDOW(4);
+    outw(0, BASE + VX_W4_MEDIA_TYPE);
+
+    /* Second, enable the selected one. */
+    switch(i) {
+      case CONNECTOR_UTP:
+        GO_WINDOW(4);
+        outw(ENABLE_UTP, BASE + VX_W4_MEDIA_TYPE);
+        break;
+      case CONNECTOR_BNC:
+        outw(START_TRANSCEIVER,BASE + VX_COMMAND);
+        udelay(8000);
+        break;
+      case CONNECTOR_TX:
+      case CONNECTOR_FX:
+        GO_WINDOW(4);
+        outw(LINKBEAT_ENABLE, BASE + VX_W4_MEDIA_TYPE);
+        break;
+      default:  /* AUI and MII fall here */
+        break;
+    }
+    GO_WINDOW(1); 
+}
+
+static void t595_disable(struct nic *nic)
+{
+    outw(STOP_TRANSCEIVER, BASE + VX_COMMAND);
+    udelay(8000);
+    GO_WINDOW(4);
+    outw(0, BASE + VX_W4_MEDIA_TYPE);
+    GO_WINDOW(1);
+}
+
+/**************************************************************************
+ETH_PROBE - Look for an adapter
+***************************************************************************/
+struct nic *t595_probe(struct nic *nic, unsigned short *probeaddrs, struct pci_device *pci)
+{
+	int i;
+	unsigned short *p;
+
+	if (probeaddrs == 0 || probeaddrs[0] == 0)
+		return 0;
+/*	eth_nic_base = probeaddrs[0] & ~3; */
+	eth_nic_base = pci->ioaddr;
+
+	GO_WINDOW(0);
+	outw(GLOBAL_RESET, BASE + VX_COMMAND);
+	VX_BUSY_WAIT;
+
+	vxgetlink();
+
+/*
+	printf("\nEEPROM:");
+	for (i = 0; i < (EEPROMSIZE/2); i++) {
+	  printf("%hX:", get_e(i));
+	}
+	printf("\n");
+*/
+	/*
+	* Read the station address from the eeprom
+	*/
+	p = (unsigned short *) nic->node_addr;
+	for (i = 0; i < 3; i++) {
+		GO_WINDOW(0);
+		p[i] = htons(get_e(EEPROM_OEM_ADDR_0 + i));
+		GO_WINDOW(2);
+		outw(ntohs(p[i]), BASE + VX_W2_ADDR_0 + (i * 2));
+	}
+
+	printf("Ethernet address: %!\n", nic->node_addr);
+
+	t595_reset(nic);
+	nic->reset = t595_reset;
+	nic->poll = t595_poll;
+	nic->transmit = t595_transmit;
+	nic->disable = t595_disable;
+	return nic;
+
+}
+
+/*
+ * Local variables:
+ *  c-basic-offset: 8
+ * End:
+ */
+
diff --git a/netboot/3c595.h b/netboot/3c595.h
new file mode 100644
index 0000000..49d8d9b
--- /dev/null
+++ b/netboot/3c595.h
@@ -0,0 +1,435 @@
+/*
+ * Copyright (c) 1993 Herb Peyerl (hpeyerl@novatel.ca) All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer. 2. The name
+ * of the author may not be used to endorse or promote products derived from
+ * this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ October 2, 1994
+
+ Modified by: Andres Vega Garcia
+
+ INRIA - Sophia Antipolis, France
+ e-mail: avega@sophia.inria.fr
+ finger: avega@pax.inria.fr
+
+ */
+
+/*
+ * Created from if_epreg.h by Fred Gray (fgray@rice.edu) to support the
+ * 3c590 family.
+ */
+
+/*
+ * Modified by Shusuke Nisiyama <shu@athena.qe.eng.hokudai.ac.jp>
+ * for etherboot
+ * Mar. 14, 2000
+*/
+
+/*
+ * Ethernet software status per interface.
+ */
+
+/*
+ * Some global constants
+ */
+
+#define TX_INIT_RATE         16
+#define TX_INIT_MAX_RATE     64
+#define RX_INIT_LATENCY      64
+#define RX_INIT_EARLY_THRESH 64
+#define MIN_RX_EARLY_THRESHF   16 /* not less than ether_header */
+#define MIN_RX_EARLY_THRESHL   4
+
+#define EEPROMSIZE      0x40
+#define MAX_EEPROMBUSY  1000
+#define VX_LAST_TAG     0xd7
+#define VX_MAX_BOARDS   16
+#define VX_ID_PORT      0x100
+
+/*
+ * some macros to acces long named fields
+ */
+#define BASE 	(eth_nic_base)
+
+/*
+ * Commands to read/write EEPROM trough EEPROM command register (Window 0,
+ * Offset 0xa)
+ */
+#define EEPROM_CMD_RD    0x0080	/* Read:  Address required (5 bits) */
+#define EEPROM_CMD_WR    0x0040	/* Write: Address required (5 bits) */
+#define EEPROM_CMD_ERASE 0x00c0	/* Erase: Address required (5 bits) */
+#define EEPROM_CMD_EWEN  0x0030	/* Erase/Write Enable: No data required */
+
+#define EEPROM_BUSY		(1<<15)
+
+/*
+ * Some short functions, worth to let them be a macro
+ */
+
+/**************************************************************************
+ *									  *
+ * These define the EEPROM data structure.  They are used in the probe
+ * function to verify the existence of the adapter after having sent
+ * the ID_Sequence.
+ *
+ * There are others but only the ones we use are defined here.
+ *
+ **************************************************************************/
+
+#define EEPROM_NODE_ADDR_0	0x0	/* Word */
+#define EEPROM_NODE_ADDR_1	0x1	/* Word */
+#define EEPROM_NODE_ADDR_2	0x2	/* Word */
+#define EEPROM_PROD_ID		0x3	/* 0x9[0-f]50 */
+#define EEPROM_MFG_ID		0x7	/* 0x6d50 */
+#define EEPROM_ADDR_CFG		0x8	/* Base addr */
+#define EEPROM_RESOURCE_CFG	0x9	/* IRQ. Bits 12-15 */
+#define EEPROM_OEM_ADDR_0	0xa	/* Word */
+#define EEPROM_OEM_ADDR_1	0xb	/* Word */
+#define EEPROM_OEM_ADDR_2	0xc	/* Word */
+#define EEPROM_SOFT_INFO_2	0xf     /* Software information 2 */
+
+#define NO_RX_OVN_ANOMALY       (1<<5)
+
+/**************************************************************************
+ *										  *
+ * These are the registers for the 3Com 3c509 and their bit patterns when *
+ * applicable.  They have been taken out the the "EtherLink III Parallel  *
+ * Tasking EISA and ISA Technical Reference" "Beta Draft 10/30/92" manual *
+ * from 3com.								  *
+ *										  *
+ **************************************************************************/
+
+#define VX_COMMAND		0x0e	/* Write. BASE+0x0e is always a
+					 * command reg. */
+#define VX_STATUS		0x0e	/* Read. BASE+0x0e is always status
+					 * reg. */
+#define VX_WINDOW		0x0f	/* Read. BASE+0x0f is always window
+					 * reg. */
+/*
+ * Window 0 registers. Setup.
+ */
+/* Write */
+#define VX_W0_EEPROM_DATA	0x0c
+#define VX_W0_EEPROM_COMMAND	0x0a
+#define VX_W0_RESOURCE_CFG	0x08
+#define VX_W0_ADDRESS_CFG	0x06 
+#define VX_W0_CONFIG_CTRL	0x04
+        /* Read */
+#define VX_W0_PRODUCT_ID	0x02
+#define VX_W0_MFG_ID		0x00
+
+
+/*
+ * Window 1 registers. Operating Set.
+ */
+/* Write */
+#define VX_W1_TX_PIO_WR_2	0x02
+#define VX_W1_TX_PIO_WR_1	0x00
+/* Read */
+#define VX_W1_FREE_TX		0x0c
+#define VX_W1_TX_STATUS		0x0b	/* byte */
+#define VX_W1_TIMER		0x0a	/* byte */
+#define VX_W1_RX_STATUS		0x08
+#define VX_W1_RX_PIO_RD_2	0x02
+#define VX_W1_RX_PIO_RD_1	0x00
+
+/*
+ * Window 2 registers. Station Address Setup/Read
+ */
+/* Read/Write */
+#define VX_W2_ADDR_5		0x05
+#define VX_W2_ADDR_4		0x04
+#define VX_W2_ADDR_3		0x03
+#define VX_W2_ADDR_2		0x02
+#define VX_W2_ADDR_1		0x01
+#define VX_W2_ADDR_0		0x00
+
+/*
+ * Window 3 registers. FIFO Management.
+ */
+/* Read */
+#define VX_W3_INTERNAL_CFG	0x00
+#define VX_W3_RESET_OPT		0x08
+#define VX_W3_FREE_TX		0x0c
+#define VX_W3_FREE_RX		0x0a
+
+/*
+ * Window 4 registers. Diagnostics.
+ */
+/* Read/Write */
+#define VX_W4_MEDIA_TYPE	0x0a
+#define VX_W4_CTRLR_STATUS	0x08
+#define VX_W4_NET_DIAG		0x06
+#define VX_W4_FIFO_DIAG		0x04
+#define VX_W4_HOST_DIAG		0x02
+#define VX_W4_TX_DIAG		0x00
+
+/*
+ * Window 5 Registers.  Results and Internal status.
+ */
+/* Read */
+#define VX_W5_READ_0_MASK	0x0c
+#define VX_W5_INTR_MASK		0x0a
+#define VX_W5_RX_FILTER		0x08
+#define VX_W5_RX_EARLY_THRESH	0x06
+#define VX_W5_TX_AVAIL_THRESH	0x02
+#define VX_W5_TX_START_THRESH	0x00
+
+/*
+ * Window 6 registers. Statistics.
+ */
+/* Read/Write */
+#define TX_TOTAL_OK		0x0c
+#define RX_TOTAL_OK		0x0a
+#define TX_DEFERRALS		0x08
+#define RX_FRAMES_OK		0x07
+#define TX_FRAMES_OK		0x06
+#define RX_OVERRUNS		0x05
+#define TX_COLLISIONS		0x04
+#define TX_AFTER_1_COLLISION	0x03
+#define TX_AFTER_X_COLLISIONS	0x02
+#define TX_NO_SQE		0x01
+#define TX_CD_LOST		0x00
+
+/****************************************
+ *
+ * Register definitions.
+ *
+ ****************************************/
+
+/*
+ * Command register. All windows.
+ *
+ * 16 bit register.
+ *     15-11:  5-bit code for command to be executed.
+ *     10-0:   11-bit arg if any. For commands with no args;
+ *	      this can be set to anything.
+ */
+#define GLOBAL_RESET		(unsigned short) 0x0000	/* Wait at least 1ms
+							 * after issuing */
+#define WINDOW_SELECT		(unsigned short) (0x1<<11)
+#define START_TRANSCEIVER	(unsigned short) (0x2<<11)	/* Read ADDR_CFG reg to
+							 * determine whether
+							 * this is needed. If
+							 * so; wait 800 uSec
+							 * before using trans-
+							 * ceiver. */
+#define RX_DISABLE		(unsigned short) (0x3<<11)	/* state disabled on
+							 * power-up */
+#define RX_ENABLE		(unsigned short) (0x4<<11)
+#define RX_RESET		(unsigned short) (0x5<<11)
+#define RX_DISCARD_TOP_PACK	(unsigned short) (0x8<<11)
+#define TX_ENABLE		(unsigned short) (0x9<<11)
+#define TX_DISABLE		(unsigned short) (0xa<<11)
+#define TX_RESET		(unsigned short) (0xb<<11)
+#define REQ_INTR		(unsigned short) (0xc<<11)
+/*
+ * The following C_* acknowledge the various interrupts. Some of them don't
+ * do anything.  See the manual.
+ */
+#define ACK_INTR		(unsigned short) (0x6800)
+#	define C_INTR_LATCH	(unsigned short) (ACK_INTR|0x1)
+#	define C_CARD_FAILURE	(unsigned short) (ACK_INTR|0x2)
+#	define C_TX_COMPLETE	(unsigned short) (ACK_INTR|0x4)
+#	define C_TX_AVAIL	(unsigned short) (ACK_INTR|0x8)
+#	define C_RX_COMPLETE	(unsigned short) (ACK_INTR|0x10)
+#	define C_RX_EARLY	(unsigned short) (ACK_INTR|0x20)
+#	define C_INT_RQD		(unsigned short) (ACK_INTR|0x40)
+#	define C_UPD_STATS	(unsigned short) (ACK_INTR|0x80)
+#define SET_INTR_MASK		(unsigned short) (0xe<<11)
+#define SET_RD_0_MASK		(unsigned short) (0xf<<11)
+#define SET_RX_FILTER		(unsigned short) (0x10<<11)
+#	define FIL_INDIVIDUAL	(unsigned short) (0x1)
+#	define FIL_MULTICAST     (unsigned short) (0x02)
+#	define FIL_BRDCST        (unsigned short) (0x04)
+#	define FIL_PROMISC       (unsigned short) (0x08)
+#define SET_RX_EARLY_THRESH	(unsigned short) (0x11<<11)
+#define SET_TX_AVAIL_THRESH	(unsigned short) (0x12<<11)
+#define SET_TX_START_THRESH	(unsigned short) (0x13<<11)
+#define STATS_ENABLE		(unsigned short) (0x15<<11)
+#define STATS_DISABLE		(unsigned short) (0x16<<11)
+#define STOP_TRANSCEIVER	(unsigned short) (0x17<<11)
+
+/*
+ * Status register. All windows.
+ *
+ *     15-13:  Window number(0-7).
+ *     12:     Command_in_progress.
+ *     11:     reserved.
+ *     10:     reserved.
+ *     9:      reserved.
+ *     8:      reserved.
+ *     7:      Update Statistics.
+ *     6:      Interrupt Requested.
+ *     5:      RX Early.
+ *     4:      RX Complete.
+ *     3:      TX Available.
+ *     2:      TX Complete.
+ *     1:      Adapter Failure.
+ *     0:      Interrupt Latch.
+ */
+#define S_INTR_LATCH		(unsigned short) (0x1)
+#define S_CARD_FAILURE		(unsigned short) (0x2)
+#define S_TX_COMPLETE		(unsigned short) (0x4)
+#define S_TX_AVAIL		(unsigned short) (0x8)
+#define S_RX_COMPLETE		(unsigned short) (0x10)
+#define S_RX_EARLY		(unsigned short) (0x20)
+#define S_INT_RQD		(unsigned short) (0x40)
+#define S_UPD_STATS		(unsigned short) (0x80)
+#define S_COMMAND_IN_PROGRESS	(unsigned short) (0x1000)
+
+#define VX_BUSY_WAIT while (inw(BASE + VX_STATUS) & S_COMMAND_IN_PROGRESS)
+
+/* Address Config. Register.    
+ * Window 0/Port 06
+ */
+
+#define ACF_CONNECTOR_BITS	14  
+#define ACF_CONNECTOR_UTP	0
+#define ACF_CONNECTOR_AUI	1
+#define ACF_CONNECTOR_BNC	3
+   
+#define INTERNAL_CONNECTOR_BITS 20
+#define INTERNAL_CONNECTOR_MASK 0x01700000
+
+/*
+ * FIFO Registers. RX Status.
+ *
+ *     15:     Incomplete or FIFO empty.
+ *     14:     1: Error in RX Packet   0: Incomplete or no error.
+ *     13-11:  Type of error.
+ *	      1000 = Overrun.
+ *	      1011 = Run Packet Error.
+ *	      1100 = Alignment Error.
+ *	      1101 = CRC Error.
+ *	      1001 = Oversize Packet Error (>1514 bytes)
+ *	      0010 = Dribble Bits.
+ *	      (all other error codes, no errors.)
+ *
+ *     10-0:   RX Bytes (0-1514)
+ */
+#define ERR_INCOMPLETE  (unsigned short) (0x8000)
+#define ERR_RX          (unsigned short) (0x4000)
+#define ERR_MASK        (unsigned short) (0x7800)
+#define ERR_OVERRUN     (unsigned short) (0x4000)
+#define ERR_RUNT        (unsigned short) (0x5800)
+#define ERR_ALIGNMENT   (unsigned short) (0x6000)
+#define ERR_CRC         (unsigned short) (0x6800)
+#define ERR_OVERSIZE    (unsigned short) (0x4800)
+#define ERR_DRIBBLE     (unsigned short) (0x1000)
+
+/*
+ * TX Status. 
+ *
+ *   Reports the transmit status of a completed transmission. Writing this
+ *   register pops the transmit completion stack.
+ *
+ *   Window 1/Port 0x0b.
+ *
+ *     7:      Complete
+ *     6:      Interrupt on successful transmission requested.
+ *     5:      Jabber Error (TP Only, TX Reset required. )
+ *     4:      Underrun (TX Reset required. )
+ *     3:      Maximum Collisions.
+ *     2:      TX Status Overflow.
+ *     1-0:    Undefined.
+ *
+ */
+#define TXS_COMPLETE		0x80
+#define TXS_INTR_REQ		0x40
+#define TXS_JABBER		0x20
+#define TXS_UNDERRUN		0x10
+#define TXS_MAX_COLLISION	0x8
+#define TXS_STATUS_OVERFLOW	0x4
+
+#define RS_AUI			(1<<5)
+#define RS_BNC			(1<<4)
+#define RS_UTP			(1<<3)
+#define	RS_T4			(1<<0)
+#define	RS_TX			(1<<1)
+#define	RS_FX			(1<<2)
+#define	RS_MII			(1<<6)
+
+
+/*
+ * FIFO Status (Window 4)
+ *
+ *   Supports FIFO diagnostics
+ *
+ *   Window 4/Port 0x04.1
+ *
+ *     15:	1=RX receiving (RO). Set when a packet is being received
+ *		into the RX FIFO.
+ *     14:	Reserved
+ *     13:	1=RX underrun (RO). Generates Adapter Failure interrupt.
+ *		Requires RX Reset or Global Reset command to recover.
+ *		It is generated when you read past the end of a packet -
+ *		reading past what has been received so far will give bad
+ *		data.
+ *     12:	1=RX status overrun (RO). Set when there are already 8
+ *		packets in the RX FIFO. While this bit is set, no additional
+ *		packets are received. Requires no action on the part of
+ *		the host. The condition is cleared once a packet has been
+ *		read out of the RX FIFO.
+ *     11:	1=RX overrun (RO). Set when the RX FIFO is full (there
+ *		may not be an overrun packet yet). While this bit is set,
+ *		no additional packets will be received (some additional
+ *		bytes can still be pending between the wire and the RX
+ *		FIFO). Requires no action on the part of the host. The
+ *		condition is cleared once a few bytes have been read out
+ *		from the RX FIFO.
+ *     10:	1=TX overrun (RO). Generates adapter failure interrupt.
+ *		Requires TX Reset or Global Reset command to recover.
+ *		Disables Transmitter.
+ *     9-8:	Unassigned.
+ *     7-0:	Built in self test bits for the RX and TX FIFO's.
+ */
+#define FIFOS_RX_RECEIVING	(unsigned short) 0x8000
+#define FIFOS_RX_UNDERRUN	(unsigned short) 0x2000
+#define FIFOS_RX_STATUS_OVERRUN	(unsigned short) 0x1000
+#define FIFOS_RX_OVERRUN	(unsigned short) 0x0800
+#define FIFOS_TX_OVERRUN	(unsigned short) 0x0400
+
+/*
+ * Misc defines for various things.
+ */
+#define TAG_ADAPTER                     0xd0
+#define ACTIVATE_ADAPTER_TO_CONFIG      0xff
+#define ENABLE_DRQ_IRQ                  0x0001
+#define MFG_ID                          0x506d  /* `TCM' */
+#define PROD_ID                         0x5090
+#define GO_WINDOW(x)		outw(WINDOW_SELECT|(x),BASE+VX_COMMAND)
+#define JABBER_GUARD_ENABLE	0x40
+#define LINKBEAT_ENABLE		0x80
+#define	ENABLE_UTP		(JABBER_GUARD_ENABLE | LINKBEAT_ENABLE)
+#define DISABLE_UTP		0x0
+#define RX_BYTES_MASK		(unsigned short) (0x07ff)
+#define RX_ERROR        0x4000
+#define RX_INCOMPLETE   0x8000
+#define TX_INDICATE		1<<15
+#define is_eeprom_busy(b)	(inw((b)+VX_W0_EEPROM_COMMAND)&EEPROM_BUSY)
+
+#define	VX_IOSIZE	0x20
+
+#define VX_CONNECTORS 8
+
+/*
+ * Local variables:
+ *  c-basic-offset: 8
+ * End:
+ */
diff --git a/netboot/3c90x.c b/netboot/3c90x.c
new file mode 100644
index 0000000..93996e0
--- /dev/null
+++ b/netboot/3c90x.c
@@ -0,0 +1,929 @@
+/*
+ * 3c90x.c -- This file implements the 3c90x driver for etherboot.  Written
+ * by Greg Beeley, Greg.Beeley@LightSys.org.  Modified by Steve Smith,
+ * Steve.Smith@Juno.Com
+ *
+ * This program Copyright (C) 1999 LightSys Technology Services, Inc.
+ * Portions Copyright (C) 1999 Steve Smith
+ *
+ * This program may be re-distributed in source or binary form, modified,
+ * sold, or copied for any purpose, provided that the above copyright message
+ * and this text are included with all source copies or derivative works, and
+ * provided that the above copyright message and this text are included in the
+ * documentation of any binary-only distributions.  This program is distributed
+ * WITHOUT ANY WARRANTY, without even the warranty of FITNESS FOR A PARTICULAR
+ * PURPOSE or MERCHANTABILITY.  Please read the associated documentation
+ * "3c90x.txt" before compiling and using this driver.
+ *
+ * --------
+ *
+ * Program written with the assistance of the 3com documentation for
+ * the 3c905B-TX card, as well as with some assistance from the 3c59x
+ * driver Donald Becker wrote for the Linux kernel, and with some assistance
+ * from the remainder of the Etherboot distribution.
+ *
+ * REVISION HISTORY:
+ *
+ * v0.10	1-26-1998	GRB	Initial implementation.
+ * v0.90	1-27-1998	GRB	System works.
+ * v1.00pre1	2-11-1998	GRB	Got prom boot issue fixed.
+ * v2.0		9-24-1999	SCS	Modified for 3c905 (from 3c905b code)
+ *					Re-wrote poll and transmit for
+ *					better error recovery and heavy
+ *					network traffic operation
+ *
+ */
+
+#include "etherboot.h"
+#include "nic.h"
+#include "pci.h"
+#include "cards.h"
+#include "timer.h"
+
+#define	XCVR_MAGIC	(0x5A00)
+/** any single transmission fails after 16 collisions or other errors
+ ** this is the number of times to retry the transmission -- this should
+ ** be plenty
+ **/
+#define	XMIT_RETRIES	250
+
+#undef	virt_to_bus
+#define	virt_to_bus(x)	((unsigned long)x)
+
+/*** Register definitions for the 3c905 ***/
+enum Registers
+    {
+    regPowerMgmtCtrl_w = 0x7c,        /** 905B Revision Only                 **/
+    regUpMaxBurst_w = 0x7a,           /** 905B Revision Only                 **/
+    regDnMaxBurst_w = 0x78,           /** 905B Revision Only                 **/
+    regDebugControl_w = 0x74,         /** 905B Revision Only                 **/
+    regDebugData_l = 0x70,            /** 905B Revision Only                 **/
+    regRealTimeCnt_l = 0x40,          /** Universal                          **/
+    regUpBurstThresh_b = 0x3e,        /** 905B Revision Only                 **/
+    regUpPoll_b = 0x3d,               /** 905B Revision Only                 **/
+    regUpPriorityThresh_b = 0x3c,     /** 905B Revision Only                 **/
+    regUpListPtr_l = 0x38,            /** Universal                          **/
+    regCountdown_w = 0x36,            /** Universal                          **/
+    regFreeTimer_w = 0x34,            /** Universal                          **/
+    regUpPktStatus_l = 0x30,          /** Universal with Exception, pg 130   **/
+    regTxFreeThresh_b = 0x2f,         /** 90X Revision Only                  **/
+    regDnPoll_b = 0x2d,               /** 905B Revision Only                 **/
+    regDnPriorityThresh_b = 0x2c,     /** 905B Revision Only                 **/
+    regDnBurstThresh_b = 0x2a,        /** 905B Revision Only                 **/
+    regDnListPtr_l = 0x24,            /** Universal with Exception, pg 107   **/
+    regDmaCtrl_l = 0x20,              /** Universal with Exception, pg 106   **/
+                                      /**                                    **/
+    regIntStatusAuto_w = 0x1e,        /** 905B Revision Only                 **/
+    regTxStatus_b = 0x1b,             /** Universal with Exception, pg 113   **/
+    regTimer_b = 0x1a,                /** Universal                          **/
+    regTxPktId_b = 0x18,              /** 905B Revision Only                 **/
+    regCommandIntStatus_w = 0x0e,     /** Universal (Command Variations)     **/
+    };
+
+/** following are windowed registers **/
+enum Registers7
+    {
+    regPowerMgmtEvent_7_w = 0x0c,     /** 905B Revision Only                 **/
+    regVlanEtherType_7_w = 0x04,      /** 905B Revision Only                 **/
+    regVlanMask_7_w = 0x00,           /** 905B Revision Only                 **/
+    };
+
+enum Registers6
+    {
+    regBytesXmittedOk_6_w = 0x0c,     /** Universal                          **/
+    regBytesRcvdOk_6_w = 0x0a,        /** Universal                          **/
+    regUpperFramesOk_6_b = 0x09,      /** Universal                          **/
+    regFramesDeferred_6_b = 0x08,     /** Universal                          **/
+    regFramesRecdOk_6_b = 0x07,       /** Universal with Exceptions, pg 142  **/
+    regFramesXmittedOk_6_b = 0x06,    /** Universal                          **/
+    regRxOverruns_6_b = 0x05,         /** Universal                          **/
+    regLateCollisions_6_b = 0x04,     /** Universal                          **/
+    regSingleCollisions_6_b = 0x03,   /** Universal                          **/
+    regMultipleCollisions_6_b = 0x02, /** Universal                          **/
+    regSqeErrors_6_b = 0x01,          /** Universal                          **/
+    regCarrierLost_6_b = 0x00,        /** Universal                          **/
+    };
+
+enum Registers5
+    {
+    regIndicationEnable_5_w = 0x0c,   /** Universal                          **/
+    regInterruptEnable_5_w = 0x0a,    /** Universal                          **/
+    regTxReclaimThresh_5_b = 0x09,    /** 905B Revision Only                 **/
+    regRxFilter_5_b = 0x08,           /** Universal                          **/
+    regRxEarlyThresh_5_w = 0x06,      /** Universal                          **/
+    regTxStartThresh_5_w = 0x00,      /** Universal                          **/
+    };
+
+enum Registers4
+    {
+    regUpperBytesOk_4_b = 0x0d,       /** Universal                          **/
+    regBadSSD_4_b = 0x0c,             /** Universal                          **/
+    regMediaStatus_4_w = 0x0a,        /** Universal with Exceptions, pg 201  **/
+    regPhysicalMgmt_4_w = 0x08,       /** Universal                          **/
+    regNetworkDiagnostic_4_w = 0x06,  /** Universal with Exceptions, pg 203  **/
+    regFifoDiagnostic_4_w = 0x04,     /** Universal with Exceptions, pg 196  **/
+    regVcoDiagnostic_4_w = 0x02,      /** Undocumented?                      **/
+    };
+
+enum Registers3
+    {
+    regTxFree_3_w = 0x0c,             /** Universal                          **/
+    regRxFree_3_w = 0x0a,             /** Universal with Exceptions, pg 125  **/
+    regResetMediaOptions_3_w = 0x08,  /** Media Options on B Revision,       **/
+                                      /** Reset Options on Non-B Revision    **/
+    regMacControl_3_w = 0x06,         /** Universal with Exceptions, pg 199  **/
+    regMaxPktSize_3_w = 0x04,         /** 905B Revision Only                 **/
+    regInternalConfig_3_l = 0x00,     /** Universal, different bit           **/
+                                      /** definitions, pg 59                 **/
+    };
+
+enum Registers2
+    {
+    regResetOptions_2_w = 0x0c,       /** 905B Revision Only                 **/
+    regStationMask_2_3w = 0x06,       /** Universal with Exceptions, pg 127  **/
+    regStationAddress_2_3w = 0x00,    /** Universal with Exceptions, pg 127  **/
+    };
+
+enum Registers1
+    {
+    regRxStatus_1_w = 0x0a,           /** 90X Revision Only, Pg 126          **/
+    };
+
+enum Registers0
+    {
+    regEepromData_0_w = 0x0c,         /** Universal                          **/
+    regEepromCommand_0_w = 0x0a,      /** Universal                          **/
+    regBiosRomData_0_b = 0x08,        /** 905B Revision Only                 **/
+    regBiosRomAddr_0_l = 0x04,        /** 905B Revision Only                 **/
+    };
+
+
+/*** The names for the eight register windows ***/
+enum Windows
+    {
+    winPowerVlan7 = 0x07,
+    winStatistics6 = 0x06,
+    winTxRxControl5 = 0x05,
+    winDiagnostics4 = 0x04,
+    winTxRxOptions3 = 0x03,
+    winAddressing2 = 0x02,
+    winUnused1 = 0x01,
+    winEepromBios0 = 0x00,
+    };
+
+
+/*** Command definitions for the 3c90X ***/
+enum Commands
+    {
+    cmdGlobalReset = 0x00,             /** Universal with Exceptions, pg 151 **/
+    cmdSelectRegisterWindow = 0x01,    /** Universal                         **/
+    cmdEnableDcConverter = 0x02,       /**                                   **/
+    cmdRxDisable = 0x03,               /**                                   **/
+    cmdRxEnable = 0x04,                /** Universal                         **/
+    cmdRxReset = 0x05,                 /** Universal                         **/
+    cmdStallCtl = 0x06,                /** Universal                         **/
+    cmdTxEnable = 0x09,                /** Universal                         **/
+    cmdTxDisable = 0x0A,               /**                                   **/
+    cmdTxReset = 0x0B,                 /** Universal                         **/
+    cmdRequestInterrupt = 0x0C,        /**                                   **/
+    cmdAcknowledgeInterrupt = 0x0D,    /** Universal                         **/
+    cmdSetInterruptEnable = 0x0E,      /** Universal                         **/
+    cmdSetIndicationEnable = 0x0F,     /** Universal                         **/
+    cmdSetRxFilter = 0x10,             /** Universal                         **/
+    cmdSetRxEarlyThresh = 0x11,        /**                                   **/
+    cmdSetTxStartThresh = 0x13,        /**                                   **/
+    cmdStatisticsEnable = 0x15,        /**                                   **/
+    cmdStatisticsDisable = 0x16,       /**                                   **/
+    cmdDisableDcConverter = 0x17,      /**                                   **/
+    cmdSetTxReclaimThresh = 0x18,      /**                                   **/
+    cmdSetHashFilterBit = 0x19,        /**                                   **/
+    };
+
+
+/*** Values for int status register bitmask **/
+#define	INT_INTERRUPTLATCH	(1<<0)
+#define INT_HOSTERROR		(1<<1)
+#define INT_TXCOMPLETE		(1<<2)
+#define INT_RXCOMPLETE		(1<<4)
+#define INT_RXEARLY		(1<<5)
+#define INT_INTREQUESTED	(1<<6)
+#define INT_UPDATESTATS		(1<<7)
+#define INT_LINKEVENT		(1<<8)
+#define INT_DNCOMPLETE		(1<<9)
+#define INT_UPCOMPLETE		(1<<10)
+#define INT_CMDINPROGRESS	(1<<12)
+#define INT_WINDOWNUMBER	(7<<13)
+
+
+/*** TX descriptor ***/
+typedef struct
+    {
+    unsigned int	DnNextPtr;
+    unsigned int	FrameStartHeader;
+    unsigned int	HdrAddr;
+    unsigned int	HdrLength;
+    unsigned int	DataAddr;
+    unsigned int	DataLength;
+    }
+    TXD;
+
+/*** RX descriptor ***/
+typedef struct
+    {
+    unsigned int	UpNextPtr;
+    unsigned int	UpPktStatus;
+    unsigned int	DataAddr;
+    unsigned int	DataLength;
+    }
+    RXD;
+
+/*** Global variables ***/
+static struct
+    {
+    unsigned char	isBrev;
+    unsigned char	CurrentWindow;
+    unsigned int	IOAddr;
+    unsigned char	HWAddr[ETH_ALEN];
+    TXD			TransmitDPD;
+    RXD			ReceiveUPD;
+    }
+    INF_3C90X;
+
+
+/*** a3c90x_internal_IssueCommand: sends a command to the 3c90x card
+ ***/
+static int
+a3c90x_internal_IssueCommand(int ioaddr, int cmd, int param)
+    {
+    unsigned int val;
+
+	/** Build the cmd. **/
+	val = cmd;
+	val <<= 11;
+	val |= param;
+
+	/** Send the cmd to the cmd register **/
+	outw(val, ioaddr + regCommandIntStatus_w);
+
+	/** Wait for the cmd to complete, if necessary **/
+	while (inw(ioaddr + regCommandIntStatus_w) & INT_CMDINPROGRESS);
+
+    return 0;
+    }
+
+
+/*** a3c90x_internal_SetWindow: selects a register window set.
+ ***/
+static int
+a3c90x_internal_SetWindow(int ioaddr, int window)
+    {
+
+	/** Window already as set? **/
+	if (INF_3C90X.CurrentWindow == window) return 0;
+
+	/** Issue the window command. **/
+	a3c90x_internal_IssueCommand(ioaddr, cmdSelectRegisterWindow, window);
+	INF_3C90X.CurrentWindow = window;
+
+    return 0;
+    }
+
+
+/*** a3c90x_internal_ReadEeprom - read data from the serial eeprom.
+ ***/
+static unsigned short
+a3c90x_internal_ReadEeprom(int ioaddr, int address)
+    {
+    unsigned short val;
+
+	/** Select correct window **/
+        a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winEepromBios0);
+
+	/** Make sure the eeprom isn't busy **/
+	while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
+
+	/** Read the value. **/
+	outw(address + ((0x02)<<6), ioaddr + regEepromCommand_0_w);
+	while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
+	val = inw(ioaddr + regEepromData_0_w);
+
+    return val;
+    }
+
+
+/*** a3c90x_internal_WriteEepromWord - write a physical word of
+ *** data to the onboard serial eeprom (not the BIOS prom, but the
+ *** nvram in the card that stores, among other things, the MAC
+ *** address).
+ ***/
+static int
+a3c90x_internal_WriteEepromWord(int ioaddr, int address, unsigned short value)
+    {
+	/** Select register window **/
+        a3c90x_internal_SetWindow(ioaddr, winEepromBios0);
+
+	/** Verify Eeprom not busy **/
+	while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
+
+	/** Issue WriteEnable, and wait for completion. **/
+	outw(0x30, ioaddr + regEepromCommand_0_w);
+	while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
+
+	/** Issue EraseRegister, and wait for completion. **/
+	outw(address + ((0x03)<<6), ioaddr + regEepromCommand_0_w);
+	while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
+
+	/** Send the new data to the eeprom, and wait for completion. **/
+	outw(value, ioaddr + regEepromData_0_w);
+	outw(0x30, ioaddr + regEepromCommand_0_w);
+	while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
+
+	/** Burn the new data into the eeprom, and wait for completion. **/
+	outw(address + ((0x01)<<6), ioaddr + regEepromCommand_0_w);
+	while((1<<15) & inw(ioaddr + regEepromCommand_0_w));
+
+    return 0;
+    }
+
+
+/*** a3c90x_internal_WriteEeprom - write data to the serial eeprom,
+ *** and re-compute the eeprom checksum.
+ ***/
+static int
+a3c90x_internal_WriteEeprom(int ioaddr, int address, unsigned short value)
+    {
+    int cksum = 0,v;
+    int i;
+    int maxAddress, cksumAddress;
+
+	if (INF_3C90X.isBrev)
+	    {
+	    maxAddress=0x1f;
+	    cksumAddress=0x20;
+	    }
+	else
+	    {
+	    maxAddress=0x16;
+	    cksumAddress=0x17;
+	    }
+
+	/** Write the value. **/
+	if (a3c90x_internal_WriteEepromWord(ioaddr, address, value) == -1)
+	    return -1;
+
+	/** Recompute the checksum. **/
+	for(i=0;i<=maxAddress;i++)
+	    {
+	    v = a3c90x_internal_ReadEeprom(ioaddr, i);
+	    cksum ^= (v & 0xFF);
+	    cksum ^= ((v>>8) & 0xFF);
+	    }
+	/** Write the checksum to the location in the eeprom **/
+	if (a3c90x_internal_WriteEepromWord(ioaddr, cksumAddress, cksum) == -1)
+	    return -1;
+
+    return 0;
+    }
+
+
+
+/*** a3c90x_reset: exported function that resets the card to its default
+ *** state.  This is so the Linux driver can re-set the card up the way
+ *** it wants to.  If CFG_3C90X_PRESERVE_XCVR is defined, then the reset will
+ *** not alter the selected transceiver that we used to download the boot
+ *** image.
+ ***/
+static void
+a3c90x_reset(struct nic *nic)
+    {
+    int cfg;
+
+#ifdef	CFG_3C90X_PRESERVE_XCVR
+    /** Read the current InternalConfig value. **/
+    a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winTxRxOptions3);
+    cfg = inl(INF_3C90X.IOAddr + regInternalConfig_3_l);
+#endif
+
+    /** Send the reset command to the card **/
+    printf("Issuing RESET:\n");
+    a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdGlobalReset, 0);
+
+    /** wait for reset command to complete **/
+    while (inw(INF_3C90X.IOAddr + regCommandIntStatus_w) & INT_CMDINPROGRESS);
+
+    /** global reset command resets station mask, non-B revision cards
+     ** require explicit reset of values
+     **/
+    a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winAddressing2);
+    outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+0);
+    outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+2);
+    outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+4);
+
+#ifdef	CFG_3C90X_PRESERVE_XCVR
+    /** Re-set the original InternalConfig value from before reset **/
+    a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winTxRxOptions3);
+    outl(cfg, INF_3C90X.IOAddr + regInternalConfig_3_l);
+
+    /** enable DC converter for 10-Base-T **/
+    if ((cfg&0x0300) == 0x0300)
+	{
+	a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdEnableDcConverter, 0);
+	}
+#endif
+
+    /** Issue transmit reset, wait for command completion **/
+    a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdTxReset, 0);
+    while (inw(INF_3C90X.IOAddr + regCommandIntStatus_w) & INT_CMDINPROGRESS)
+	;
+    if (! INF_3C90X.isBrev)
+	outb(0x01, INF_3C90X.IOAddr + regTxFreeThresh_b);
+    a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdTxEnable, 0);
+
+    /**
+     ** reset of the receiver on B-revision cards re-negotiates the link
+     ** takes several seconds (a computer eternity)
+     **/
+    if (INF_3C90X.isBrev)
+	a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxReset, 0x04);
+    else
+	a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxReset, 0x00);
+    while (inw(INF_3C90X.IOAddr + regCommandIntStatus_w) & INT_CMDINPROGRESS);
+	;
+    a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxEnable, 0);
+
+    a3c90x_internal_IssueCommand(INF_3C90X.IOAddr,
+                                 cmdSetInterruptEnable, 0);
+    /** enable rxComplete and txComplete **/
+    a3c90x_internal_IssueCommand(INF_3C90X.IOAddr,
+                                 cmdSetIndicationEnable, 0x0014);
+    /** acknowledge any pending status flags **/
+    a3c90x_internal_IssueCommand(INF_3C90X.IOAddr,
+                                 cmdAcknowledgeInterrupt, 0x661);
+
+    return;
+    }
+
+
+
+/*** a3c90x_transmit: exported function that transmits a packet.  Does not
+ *** return any particular status.  Parameters are:
+ *** d[6] - destination address, ethernet;
+ *** t - protocol type (ARP, IP, etc);
+ *** s - size of the non-header part of the packet that needs transmitted;
+ *** p - the pointer to the packet data itself.
+ ***/
+static void
+a3c90x_transmit(struct nic *nic, const char *d, unsigned int t,
+                unsigned int s, const char *p)
+    {
+
+    struct eth_hdr
+	{
+	unsigned char dst_addr[ETH_ALEN];
+	unsigned char src_addr[ETH_ALEN];
+	unsigned short type;
+	} hdr;
+
+    unsigned char status;
+    unsigned i, retries;
+
+    for (retries=0; retries < XMIT_RETRIES ; retries++)
+	{
+	/** Stall the download engine **/
+	a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdStallCtl, 2);
+
+	/** Make sure the card is not waiting on us **/
+	inw(INF_3C90X.IOAddr + regCommandIntStatus_w);
+	inw(INF_3C90X.IOAddr + regCommandIntStatus_w);
+
+	while (inw(INF_3C90X.IOAddr+regCommandIntStatus_w) &
+	       INT_CMDINPROGRESS)
+	    ;
+
+	/** Set the ethernet packet type **/
+	hdr.type = htons(t);
+
+	/** Copy the destination address **/
+	memcpy(hdr.dst_addr, d, ETH_ALEN);
+
+	/** Copy our MAC address **/
+	memcpy(hdr.src_addr, INF_3C90X.HWAddr, ETH_ALEN);
+
+	/** Setup the DPD (download descriptor) **/
+	INF_3C90X.TransmitDPD.DnNextPtr = 0;
+	/** set notification for transmission completion (bit 15) **/
+	INF_3C90X.TransmitDPD.FrameStartHeader = (s + sizeof(hdr)) | 0x8000;
+	INF_3C90X.TransmitDPD.HdrAddr = virt_to_bus(&hdr);
+	INF_3C90X.TransmitDPD.HdrLength = sizeof(hdr);
+	INF_3C90X.TransmitDPD.DataAddr = virt_to_bus(p);
+	INF_3C90X.TransmitDPD.DataLength = s + (1<<31);
+
+	/** Send the packet **/
+	outl(virt_to_bus(&(INF_3C90X.TransmitDPD)),
+	     INF_3C90X.IOAddr + regDnListPtr_l);
+
+	/** End Stall and Wait for upload to complete. **/
+	a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdStallCtl, 3);
+	while(inl(INF_3C90X.IOAddr + regDnListPtr_l) != 0)
+	    ;
+
+	/** Wait for NIC Transmit to Complete **/
+	load_timer2(10*TICKS_PER_MS);	/* Give it 10 ms */
+	while (!(inw(INF_3C90X.IOAddr + regCommandIntStatus_w)&0x0004) &&
+		timer2_running())
+		;
+
+	if (!(inw(INF_3C90X.IOAddr + regCommandIntStatus_w)&0x0004))
+	    {
+	    printf("3C90X: Tx Timeout\n");
+	    continue;
+	    }
+
+	status = inb(INF_3C90X.IOAddr + regTxStatus_b);
+
+	/** acknowledge transmit interrupt by writing status **/
+	outb(0x00, INF_3C90X.IOAddr + regTxStatus_b);
+
+	/** successful completion (sans "interrupt Requested" bit) **/
+	if ((status & 0xbf) == 0x80)
+	    return;
+
+	   printf("3C90X: Status (%hhX)\n", status);
+	/** check error codes **/
+	if (status & 0x02)
+	    {
+	    printf("3C90X: Tx Reclaim Error (%hhX)\n", status);
+	    a3c90x_reset(NULL);
+	    }
+	else if (status & 0x04)
+	    {
+	    printf("3C90X: Tx Status Overflow (%hhX)\n", status);
+	    for (i=0; i<32; i++)
+		outb(0x00, INF_3C90X.IOAddr + regTxStatus_b);
+	    /** must re-enable after max collisions before re-issuing tx **/
+	    a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdTxEnable, 0);
+	    }
+	else if (status & 0x08)
+	    {
+	    printf("3C90X: Tx Max Collisions (%hhX)\n", status);
+	    /** must re-enable after max collisions before re-issuing tx **/
+	    a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdTxEnable, 0);
+	    }
+	else if (status & 0x10)
+	    {
+	    printf("3C90X: Tx Underrun (%hhX)\n", status);
+	    a3c90x_reset(NULL);
+	    }
+	else if (status & 0x20)
+	    {
+	    printf("3C90X: Tx Jabber (%hhX)\n", status);
+	    a3c90x_reset(NULL);
+	    }
+	else if ((status & 0x80) != 0x80)
+	    {
+	    printf("3C90X: Internal Error - Incomplete Transmission (%hhX)\n",
+	           status);
+	    a3c90x_reset(NULL);
+	    }
+	}
+
+    /** failed after RETRY attempts **/
+    printf("Failed to send after %d retries\n", retries);
+    return;
+
+    }
+
+
+
+/*** a3c90x_poll: exported routine that waits for a certain length of time
+ *** for a packet, and if it sees none, returns 0.  This routine should
+ *** copy the packet to nic->packet if it gets a packet and set the size
+ *** in nic->packetlen.  Return 1 if a packet was found.
+ ***/
+static int
+a3c90x_poll(struct nic *nic)
+    {
+    int i, errcode;
+
+    if (!(inw(INF_3C90X.IOAddr + regCommandIntStatus_w)&0x0010))
+	{
+	return 0;
+	}
+
+    /** we don't need to acknowledge rxComplete -- the upload engine
+     ** does it for us.
+     **/
+
+    /** Build the up-load descriptor **/
+    INF_3C90X.ReceiveUPD.UpNextPtr = 0;
+    INF_3C90X.ReceiveUPD.UpPktStatus = 0;
+    INF_3C90X.ReceiveUPD.DataAddr = virt_to_bus(nic->packet);
+    INF_3C90X.ReceiveUPD.DataLength = 1536 + (1<<31);
+
+    /** Submit the upload descriptor to the NIC **/
+    outl(virt_to_bus(&(INF_3C90X.ReceiveUPD)),
+         INF_3C90X.IOAddr + regUpListPtr_l);
+
+    /** Wait for upload completion (upComplete(15) or upError (14)) **/
+    for(i=0;i<40000;i++);
+    while((INF_3C90X.ReceiveUPD.UpPktStatus & ((1<<14) | (1<<15))) == 0)
+	for(i=0;i<40000;i++);
+
+    /** Check for Error (else we have good packet) **/
+    if (INF_3C90X.ReceiveUPD.UpPktStatus & (1<<14))
+	{
+	errcode = INF_3C90X.ReceiveUPD.UpPktStatus;
+	if (errcode & (1<<16))
+	    printf("3C90X: Rx Overrun (%hX)\n",errcode>>16);
+	else if (errcode & (1<<17))
+	    printf("3C90X: Runt Frame (%hX)\n",errcode>>16);
+	else if (errcode & (1<<18))
+	    printf("3C90X: Alignment Error (%hX)\n",errcode>>16);
+	else if (errcode & (1<<19))
+	    printf("3C90X: CRC Error (%hX)\n",errcode>>16);
+	else if (errcode & (1<<20))
+	    printf("3C90X: Oversized Frame (%hX)\n",errcode>>16);
+	else
+	    printf("3C90X: Packet error (%hX)\n",errcode>>16);
+	return 0;
+	}
+
+    /** Ok, got packet.  Set length in nic->packetlen. **/
+    nic->packetlen = (INF_3C90X.ReceiveUPD.UpPktStatus & 0x1FFF);
+
+    return 1;
+    }
+
+
+
+/*** a3c90x_disable: exported routine to disable the card.  What's this for?
+ *** the eepro100.c driver didn't have one, so I just left this one empty too.
+ *** Ideas anyone?
+ *** Must turn off receiver at least so stray packets will not corrupt memory
+ *** [Ken]
+ ***/
+static void
+a3c90x_disable(struct nic *nic)
+    {
+	/* Disable the receiver and transmitter. */
+	outw(cmdRxDisable, INF_3C90X.IOAddr + regCommandIntStatus_w);
+	outw(cmdTxDisable, INF_3C90X.IOAddr + regCommandIntStatus_w);
+    }
+
+
+
+/*** a3c90x_probe: exported routine to probe for the 3c905 card and perform
+ *** initialization.  If this routine is called, the pci functions did find the
+ *** card.  We just have to init it here.
+ ***/
+struct nic*
+a3c90x_probe(struct nic *nic, unsigned short *probeaddrs, struct pci_device *pci)
+    {
+    int i, c;
+    unsigned short eeprom[0x21];
+    unsigned int cfg;
+    unsigned int mopt;
+    unsigned short linktype;
+
+    if (probeaddrs == 0 || probeaddrs[0] == 0)
+          return 0;
+
+    adjust_pci_device(pci);
+
+    INF_3C90X.IOAddr = probeaddrs[0] & ~3;
+    INF_3C90X.CurrentWindow = 255;
+    switch (a3c90x_internal_ReadEeprom(INF_3C90X.IOAddr, 0x03))
+	{
+	case 0x9000: /** 10 Base TPO             **/
+	case 0x9001: /** 10/100 T4               **/
+	case 0x9050: /** 10/100 TPO              **/
+	case 0x9051: /** 10 Base Combo           **/
+		INF_3C90X.isBrev = 0;
+		break;
+
+	case 0x9004: /** 10 Base TPO             **/
+	case 0x9005: /** 10 Base Combo           **/
+	case 0x9006: /** 10 Base TPO and Base2   **/
+	case 0x900A: /** 10 Base FL              **/
+	case 0x9055: /** 10/100 TPO              **/
+	case 0x9056: /** 10/100 T4               **/
+	case 0x905A: /** 10 Base FX              **/
+	default:
+		INF_3C90X.isBrev = 1;
+		break;
+	}
+
+    /** Load the EEPROM contents **/
+    if (INF_3C90X.isBrev)
+	{
+	for(i=0;i<=0x20;i++)
+	    {
+	    eeprom[i] = a3c90x_internal_ReadEeprom(INF_3C90X.IOAddr, i);
+	    }
+
+#ifdef	CFG_3C90X_BOOTROM_FIX
+	/** Set xcvrSelect in InternalConfig in eeprom. **/
+	/* only necessary for 3c905b revision cards with boot PROM bug!!! */
+	a3c90x_internal_WriteEeprom(INF_3C90X.IOAddr, 0x13, 0x0160);
+#endif
+
+#ifdef	CFG_3C90X_XCVR
+	if (CFG_3C90X_XCVR == 255)
+	    {
+	    /** Clear the LanWorks register **/
+	    a3c90x_internal_WriteEeprom(INF_3C90X.IOAddr, 0x16, 0);
+	    }
+	else
+	    {
+	    /** Set the selected permanent-xcvrSelect in the
+	     ** LanWorks register
+	     **/
+	    a3c90x_internal_WriteEeprom(INF_3C90X.IOAddr, 0x16,
+	                    XCVR_MAGIC + ((CFG_3C90X_XCVR) & 0x000F));
+	    }
+#endif
+	}
+    else
+	{
+	for(i=0;i<=0x17;i++)
+	    {
+	    eeprom[i] = a3c90x_internal_ReadEeprom(INF_3C90X.IOAddr, i);
+	    }
+	}
+
+    /** Print identification message **/
+    printf("\n\n3C90X Driver 2.00 "
+           "Copyright 1999 LightSys Technology Services, Inc.\n"
+           "Portions Copyright 1999 Steve Smith\n");
+    printf("Provided with ABSOLUTELY NO WARRANTY.\n");
+    printf("-------------------------------------------------------"
+           "------------------------\n");
+
+    /** Retrieve the Hardware address and print it on the screen. **/
+    INF_3C90X.HWAddr[0] = eeprom[0]>>8;
+    INF_3C90X.HWAddr[1] = eeprom[0]&0xFF;
+    INF_3C90X.HWAddr[2] = eeprom[1]>>8;
+    INF_3C90X.HWAddr[3] = eeprom[1]&0xFF;
+    INF_3C90X.HWAddr[4] = eeprom[2]>>8;
+    INF_3C90X.HWAddr[5] = eeprom[2]&0xFF;
+    printf("MAC Address = %!\n", INF_3C90X.HWAddr);
+
+    /** Program the MAC address into the station address registers **/
+    a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winAddressing2);
+    outw(htons(eeprom[0]), INF_3C90X.IOAddr + regStationAddress_2_3w);
+    outw(htons(eeprom[1]), INF_3C90X.IOAddr + regStationAddress_2_3w+2);
+    outw(htons(eeprom[2]), INF_3C90X.IOAddr + regStationAddress_2_3w+4);
+    outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+0);
+    outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+2);
+    outw(0, INF_3C90X.IOAddr + regStationMask_2_3w+4);
+
+    /** Fill in our entry in the etherboot arp table **/
+    for(i=0;i<ETH_ALEN;i++)
+	nic->node_addr[i] = (eeprom[i/2] >> (8*((i&1)^1))) & 0xff;
+
+    /** Read the media options register, print a message and set default
+     ** xcvr.
+     **
+     ** Uses Media Option command on B revision, Reset Option on non-B
+     ** revision cards -- same register address
+     **/
+    a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winTxRxOptions3);
+    mopt = inw(INF_3C90X.IOAddr + regResetMediaOptions_3_w);
+
+    /** mask out VCO bit that is defined as 10baseFL bit on B-rev cards **/
+    if (! INF_3C90X.isBrev)
+	{
+	mopt &= 0x7F;
+	}
+
+    printf("Connectors present: ");
+    c = 0;
+    linktype = 0x0008;
+    if (mopt & 0x01)
+	{
+	printf("%s100Base-T4",(c++)?", ":"");
+	linktype = 0x0006;
+	}
+    if (mopt & 0x04)
+	{
+	printf("%s100Base-FX",(c++)?", ":"");
+	linktype = 0x0005;
+	}
+    if (mopt & 0x10)
+	{
+	printf("%s10Base-2",(c++)?", ":"");
+	linktype = 0x0003;
+	}
+    if (mopt & 0x20)
+	{
+	printf("%sAUI",(c++)?", ":"");
+	linktype = 0x0001;
+	}
+    if (mopt & 0x40)
+	{
+	printf("%sMII",(c++)?", ":"");
+	linktype = 0x0006;
+	}
+    if ((mopt & 0xA) == 0xA)
+	{
+	printf("%s10Base-T / 100Base-TX",(c++)?", ":"");
+	linktype = 0x0008;
+	}
+    else if ((mopt & 0xA) == 0x2)
+	{
+	printf("%s100Base-TX",(c++)?", ":"");
+	linktype = 0x0008;
+	}
+    else if ((mopt & 0xA) == 0x8)
+	{
+	printf("%s10Base-T",(c++)?", ":"");
+	linktype = 0x0008;
+	}
+    printf(".\n");
+
+    /** Determine transceiver type to use, depending on value stored in
+     ** eeprom 0x16
+     **/
+    if (INF_3C90X.isBrev)
+	{
+	if ((eeprom[0x16] & 0xFF00) == XCVR_MAGIC)
+	    {
+	    /** User-defined **/
+	    linktype = eeprom[0x16] & 0x000F;
+	    }
+	}
+    else
+	{
+#ifdef	CFG_3C90X_XCVR
+	    if (CFG_3C90X_XCVR != 255)
+		linktype = CFG_3C90X_XCVR;
+#endif	/* CFG_3C90X_XCVR */
+
+	    /** I don't know what MII MAC only mode is!!! **/
+	    if (linktype == 0x0009)
+		{
+		if (INF_3C90X.isBrev)
+			printf("WARNING: MII External MAC Mode only supported on B-revision "
+			       "cards!!!!\nFalling Back to MII Mode\n");
+		linktype = 0x0006;
+		}
+	}
+
+    /** enable DC converter for 10-Base-T **/
+    if (linktype == 0x0003)
+	{
+	a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdEnableDcConverter, 0);
+	}
+
+    /** Set the link to the type we just determined. **/
+    a3c90x_internal_SetWindow(INF_3C90X.IOAddr, winTxRxOptions3);
+    cfg = inl(INF_3C90X.IOAddr + regInternalConfig_3_l);
+    cfg &= ~(0xF<<20);
+    cfg |= (linktype<<20);
+    outl(cfg, INF_3C90X.IOAddr + regInternalConfig_3_l);
+
+    /** Now that we set the xcvr type, reset the Tx and Rx, re-enable. **/
+    a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdTxReset, 0x00);
+    while (inw(INF_3C90X.IOAddr + regCommandIntStatus_w) & INT_CMDINPROGRESS)
+	;
+
+    if (!INF_3C90X.isBrev)
+	outb(0x01, INF_3C90X.IOAddr + regTxFreeThresh_b);
+
+    a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdTxEnable, 0);
+
+    /**
+     ** reset of the receiver on B-revision cards re-negotiates the link
+     ** takes several seconds (a computer eternity)
+     **/
+    if (INF_3C90X.isBrev)
+	a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxReset, 0x04);
+    else
+	a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxReset, 0x00);
+    while (inw(INF_3C90X.IOAddr + regCommandIntStatus_w) & INT_CMDINPROGRESS)
+	;
+
+    /** Set the RX filter = receive only individual pkts & bcast. **/
+    a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdSetRxFilter, 0x01 + 0x04);
+    a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdRxEnable, 0);
+
+
+    /**
+     ** set Indication and Interrupt flags , acknowledge any IRQ's
+     **/
+    a3c90x_internal_IssueCommand(INF_3C90X.IOAddr, cmdSetInterruptEnable, 0);
+    a3c90x_internal_IssueCommand(INF_3C90X.IOAddr,
+                                 cmdSetIndicationEnable, 0x0014);
+    a3c90x_internal_IssueCommand(INF_3C90X.IOAddr,
+                                 cmdAcknowledgeInterrupt, 0x661);
+
+    /** Set our exported functions **/
+    nic->reset    = a3c90x_reset;
+    nic->poll     = a3c90x_poll;
+    nic->transmit = a3c90x_transmit;
+    nic->disable  = a3c90x_disable;
+
+    return nic;
+    }
+
+
diff --git a/netboot/3c90x.txt b/netboot/3c90x.txt
new file mode 100644
index 0000000..3d6746c
--- /dev/null
+++ b/netboot/3c90x.txt
@@ -0,0 +1,307 @@
+
+	Instructions for use of the 3C90X driver for EtherBoot
+
+		Original 3C905B support by:
+			Greg Beeley (Greg.Beeley@LightSys.org),
+			LightSys Technology Services, Inc.
+			February 11, 1999
+
+		Updates for 3C90X family by:
+			Steve Smith (steve.smith@juno.com)
+			October 1, 1999
+
+		Minor documentation updates by
+			Greg Beeley (Greg.Beeley@LightSys.org)
+			March 29, 2000
+
+-------------------------------------------------------------------------------
+
+I   OVERVIEW
+
+    The 3c90X series ethernet cards are a group of high-performance busmaster
+    DMA cards from 3Com.  This particular driver supports both the 3c90x and
+    the 3c90xB revision cards.  3C90xC family support has been tested to some
+    degree but not extensively.
+
+    Here's the licensing information:
+
+    This program Copyright (C) 1999 LightSys Technology Services, Inc.
+    Portions Copyright (C) 1999 Steve Smith.
+
+    This program may be re-distributed in source or binary form, modified,
+    sold, or copied for any purpose, provided that the above copyright message
+    and this text are included with all source copies or derivative works, and
+    provided that the above copyright message and this text are included in the
+    documentation of any binary-only distributions.  This program is
+    distributed WITHOUT ANY WARRANTY, without even the warranty of FITNESS FOR
+    A PARTICULAR PURPOSE or MERCHANTABILITY.  Please read the associated
+    documentation "3c90x.txt" before compiling and using this driver.
+
+
+II  FLASH PROMS
+
+    The 3c90xB cards, according to the 3Com documentation, only accept the
+    following flash memory chips:
+
+	Atmel AT29C512 (64 kilobyte)
+	Atmel AT29C010 (128 kilobyte)
+
+    The 3c90x cards, according to the 3Com documentation, accept the
+    following flash memory chips capacities:
+
+	64  kb (8 kB)
+	128 kb (16 kB)
+	256 kb (32 kB) and
+	512 kb (64 kB)
+
+    Atmel AT29C512 (64 kilobyte) chips are specifically listed for both
+    adapters, but flashing on the 3c905b cards would only be supported
+    through the Atmel parts.  Any device, of the supported size, should
+    be supported when programmed by a dedicated PROM programmer (e.g.
+    not the card).
+
+    To use this driver in such a PROM, visit Atmel's web site and download
+    their .PDF file containing a list of their distributors.  Contact the
+    distributors for pricing information.  The prices are quite reasonable
+    (about $3 US each for the 64 kB part), and are comparable to what one would
+    expect for similarly sized standard EPROMs.  And, the flash chips are much
+    easier to work with, as they don't need to be UV-erased to be reprogrammed.
+    The 3C905B card actually provides a method to program the flash memory
+    while it is resident on board the card itself; if someone would like to
+    write a small DOS program to do the programming, I can provide the
+    information about the registers and so forth.
+
+    A utility program, 3c90xutil, is provided with Etherboot in the 'contrib'
+    directory that allows for the on-board flashing of the ROM while Linux
+    is running.  The program has been successfully used under Linux, but I
+    have heard problem reports of its use under FreeBSD.  Anyone willing to
+    make it work under FreeBSD is more than welcome to do so!
+
+    You also have the option of using EPROM chips - the 3C905B-TX-NM has been
+    successfully tested with 27C256 (32kB) and 27C512 (64kB) chips with a
+    specified access time of 100ns and faster.
+
+
+III GENERAL USE
+
+    Normally, the basic procedure for using this driver is as follows:
+
+	1.  Run the 3c90xcfg program on the driver diskette to enable the
+	boot PROM and set it to 64k or 128k, as appropriate.
+	2.  Build the appropriate 3c90x.fd0 or 3c90x.fd0 floppy image with
+	possibly the value CFG_3C90X_XCVR defined to the transceiver type that
+	you want to use (i.e., 10/100 rj45, AUI, coax, MII).
+	3.  Run the floppy image on the PC to be network booted, to get
+	it configured, and to verify that it will boot properly.
+	4.  Build the 3c90x.rom or 3c90x.lzrom PROM image and program
+	it into the flash or EPROM memory chip.
+	5.  Put the PROM in the ethernet card, boot and enable 'boot from
+	network first' in the system BIOS, save and reboot.
+
+    Here are some issues to be aware of:
+
+	1.  If you experience crashes or different behaviour when using the
+	boot PROM, add the setting CFG_3C90X_BOOTROM_FIX and go through the
+	steps 2-5 above.  This works around a bug in some 3c905B cards (see
+	below), but has some side-effects which may not be desirable.
+        Please note that you have to boot off a floppy (not PROM!) once for
+        this fix to take effect.
+	2.  The possible need to manually set the CFG_3C90X_XCVR value to
+	configure the transceiver type.  Values are listed below.
+	3.  The possible need to define CFG_3C90X_PRESERVE_XCVR for use in
+	operating systems that don't intelligently determine the
+	transceiver type.
+
+    Some things that are on the 'To-Do' list, perhaps for me, but perhaps
+    for any other volunteers out there:
+
+	1.  Extend the driver to fully implement the auto-select
+	algorithm if the card has multiple media ports.
+	2.  Fix any bugs in the code <grin>....
+	3.  Extend the driver to support the 3c905c revision cards
+	"officially".  Right now, the support has been primarily empirical
+	and not based on 3c905C documentation.
+
+    Now for the details....
+
+    This driver has been tested on roughly 300 systems.  The main two
+    configuration issues to contend with are:
+
+	1.  Ensure that PCI Busmastering is enabled for the adapter (configured
+	in the CMOS setup)
+	2.  Some systems don't work properly with the adapter when plug and
+	play OS is enabled; I always set it to "No" or "Disabled" -- this makes
+	it easier and really doesn't adversely affect anything.
+
+    Roughly 95% of the systems worked when configured properly.  A few
+    have issues with booting locally once the boot PROM has been installed
+    (this number has been less than 2%).  Other configuration issues that
+    to check:
+
+	1.  Newer BIOS's actually work correctly with the network boot order.
+	Set the network adapter first.  Most older BIOS's automatically go to
+	the network boot PROM first.
+	2.  For systems where the adapter was already installed and is just
+	having the PROM installed, try setting the "reset configuration data"
+	to yes in the CMOS setup if the BIOS isn't seen at first.  If your BIOS
+	doesn't have this option, remove the card, start the system, shut down,
+	install the card and restart (or switch to a different PCI slot).
+	3.  Make sure the CMOS security settings aren't preventing a boot.
+
+    The 3c905B cards have a significant 'bug' that relates to the flash prom:
+    unless the card is set internally to the MII transceiver, it will only
+    read the first 8k of the PROM image.  Don't ask why -- it seems really
+    obscure, but it has to do with the way they mux'd the address lines
+    from the PCI bus to the ROM.  Unfortunately, most of us are not using
+    MII transceivers, and even the .lzrom image ends up being just a little
+    bit larger than 8k.  Note that the workaround for this is disabled by
+    default, because the Windows NT 4.0 driver does not like it (no packets
+    are transmitted).
+
+    So, the solution that I've used is to internally set the card's nvram
+    configuration to use MII when it boots.  The 3c905b driver does this
+    automatically.  This way, the 16k prom image can be loaded into memory,
+    and then the 3c905b driver can set the temporary configuration of the
+    card to an appropriate value, either configurable by the user or chosen
+    by the driver.
+
+    To enable the 3c905B bugfix, which is necessary for these cards when 
+    booting from the Flash ROM, define -DCFG_3C90X_BOOTROM_FIX when building,
+    create a floppy image and boot it once.
+    Thereafter, the card should accept the larger prom image.
+
+    The driver should choose an appropriate transceiver on the card.  However,
+    if it doesn't on your card or if you need to, for instance, set your
+    card to 10mbps when connected to an unmanaged 10/100 hub, you can specify
+    which transceiver you want to use.  To do this, build the 3c905b.fd0
+    image with -DCFG_3C90X_XCVR=x, where 'x' is one of the following
+    values:
+
+	0	10Base-T
+	1	10mbps AUI
+	3	10Base-2 (thinnet/coax)
+	4	100Base-TX
+	5	100Base-FX
+	6	MII
+	8	Auto-negotiation 10Base-T / 100Base-TX (usually the default)
+	9	MII External MAC Mode
+	255	Allow driver to choose an 'appropriate' media port.
+
+    Then proceed from step 2 in the above 'general use' instructions.  The
+    .rom image can be built with CFG_3C90X_XCVR set to a value, but you
+    normally don't want to do this, since it is easier to change the
+    transceiver type by rebuilding a new floppy, changing the BIOS to floppy
+    boot, booting, and then changing the BIOS back to network boot.  If
+    CFG_3C90X_XCVR is not set in a particular build, it just uses the
+    current configuration (either its 'best guess' or whatever the stored
+    CFG_3C90X_XCVR value was from the last time it was set).
+
+    [[ Note for the more technically inclined:  The CFG_3C90X_XCVR value is
+    programmed into a register in the card's NVRAM that was reserved for
+    LanWorks PROM images to use.  When the driver boots, the card comes
+    up in MII mode, and the driver checks the LanWorks register to find
+    out if the user specified a transceiver type.  If it finds that
+    information, it uses that, otherwise it picks a transceiver that the
+    card has based on the 3c905b's MediaOptions register.  This driver isn't
+    quite smart enough to always determine which media port is actually
+    _connected_; maybe someone else would like to take on that task (it
+    actually involves sending a self-directed packet and seeing if it
+    comes back.  IF it does, that port is connected). ]]
+
+    Another issue to keep in mind is that it is possible that some OS'es
+    might not be happy with the way I've handled the PROM-image hack with
+    setting MII mode on bootup.  Linux 2.0.35 does not have this problem.
+    Behavior of other systems may vary.  The 3com documentation specifically
+    says that, at least with the card that I have, the device driver in the
+    OS should auto-select the media port, so other drivers should work fine
+    with this 'hack'.  However, if yours doesn't seem to, you can try defining
+    CFG_3C90X_PRESERVE_XCVR when building to cause Etherboot to keep the
+    working setting (that allowed the bootp/tftp process) across the eth_reset
+    operation.
+
+
+IV  FOR DEVELOPERS....
+
+    If you would like to fix/extend/etc. this driver, feel free to do so; just
+    be sure you can test the modified version on the 3c905B-TX cards that the
+    driver was originally designed for.  This section of this document gives
+    some information that might be relevant to a programmer.
+
+    A.  Main Entry Point
+
+	a3c90x_probe is the main entry point for this driver.  It is referred
+	to in an array in 'config.c'.
+
+    B.  Other Important Functions
+
+	The functions a3c90x_transmit, a3c90x_poll, a3c90x_reset, and
+	a3c90x_disable are static functions that EtherBoot finds out about
+	as a  result of a3c90x_probe setting entries in the nic structure
+	for them.  The EtherBoot framework does not use interrupts.  It is
+	polled.  All transmit and receive operations are initiated by the
+	etherboot framework, not by an interrupt or by the driver.
+
+    C.  Internal Functions
+
+	The following functions are internal to the driver:
+
+	a3c90x_internal_IssueCommand - sends a command to the 3c905b card.
+	a3c90x_internal_SetWindow - shifts between one of eight register
+	windows onboard the 3c90x.  The bottom 16 bytes of the card's
+	I/O space are multiplexed among 128 bytes, only 16 of which are
+	visible at any one time.  This SetWindow function selects one of
+	the eight sets.
+	a3c90x_internal_ReadEeprom - reads a word (16 bits) from the
+	card's onboard nvram.  This is NOT the BIOS boot rom.  This is
+	where the card stores such things as its hardware address.
+	a3c90x_internal_WriteEeprom - writes a word (16 bits) to the
+	card's nvram, and recomputes the eeprom checksum.
+	a3c90x_internal_WriteEepromWord - writes a word (16 bits) to the
+	card's nvram.  Used by the above routine.
+	a3c90x_internal_WriteEepromWord - writes a word (16 bits) to the
+	card's nvram.  Used by the above routine.
+
+    D.  Globals
+
+	All global variables are inside a global structure named INF_3C90X.
+	So, wherever you see that structure referenced, you know the variable
+	is a global.  Just keeps things a little neater.
+
+    E.  Enumerations
+
+	There are quite a few enumerated type definitions for registers and
+	so forth, many for registers that I didn't even touch in the driver.
+	Register types start with 'reg', window numbers (for SetWindow)
+	start with 'win', and commands (for IssueCommand) start with 'cmd'.
+	Register offsets also include an indication in the name as to the
+	size of the register (_b = byte, _w = word, _l = long), and which
+	window the register is in, if it is windowed (0-7).
+
+    F.  Why the 'a3c90x' name?
+
+	I had to come up with a letter at the beginning of all of the
+	identifiers, since 3com so conveniently had their name start with a
+	number.  Another driver used 't' (for 'three'?); I chose 'a' for
+	no reason at all.
+
+Addendum by Jorge L. deLyra <delyra@latt.if.usp.br>, 22Nov2000 re
+working around the 3C905 hardware bug mentioned above:
+
+Use this floppy to fix any 3COM model 3C905B PCI 10/100 Ethernet cards
+that fail to load and run the boot program the first time around. If
+they have a "Lucent" rather than a "Broadcom" chipset these cards have
+a configuration bug that causes a hang when trying to load the boot
+program from the PROM, if you try to use them right out of the box.
+
+The boot program in this floppy is the file named 3c905b-tpo100.rom
+from Etherboot version 4.6.10, compiled with the bugfix parameter
+
+			CFG_3C90X_BOOTROM_FIX
+
+You have to take the chip off the card and boot the system once using
+this floppy. Once loaded from the floppy, the boot program will access
+the card and change some setting in it, correcting the problem. After
+that you may use either this boot program or the normal one, compiled
+without this bugfix parameter, to boot the machine from the PROM chip.
+
+[Any recent Etherboot version should do, not just 4.6.10 - Ed.]
diff --git a/netboot/Makefile.am b/netboot/Makefile.am
new file mode 100644
index 0000000..0855bb4
--- /dev/null
+++ b/netboot/Makefile.am
@@ -0,0 +1,219 @@
+# For <shared.h> and <stage1.h>.
+INCLUDES = -I$(top_srcdir)/stage2 -I$(top_srcdir)/stage1
+
+# Don't build the netboot support by default.
+if NETBOOT_SUPPORT
+LIBDRIVERS = libdrivers.a
+else
+LIBDRIVERS =
+endif
+
+noinst_LIBRARIES = $(LIBDRIVERS)
+
+libdrivers_a_SOURCES = cards.h config.c etherboot.h \
+	fsys_tftp.c linux-asm-io.h linux-asm-string.h \
+	main.c misc.c nic.h osdep.h pci.c pci.h timer.c timer.h
+EXTRA_libdrivers_a_SOURCES = 3c509.c 3c509.h 3c595.c 3c595.h 3c90x.c \
+	cs89x0.c cs89x0.h davicom.c depca.c eepro.c eepro100.c \
+	epic100.c epic100.h fa311.c i82586.c lance.c natsemi.c \
+	ni5010.c ns8390.c ns8390.h otulip.c otulip.h rtl8139.c \
+	sis900.c sis900.h sk_g16.c sk_g16.h smc9000.c smc9000.h \
+	tiara.c tlan.c tulip.c via-rhine.c w89c840.c
+libdrivers_a_CFLAGS = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	-DFSYS_TFTP=1 $(NET_CFLAGS) $(NET_EXTRAFLAGS)
+# Filled by configure.
+libdrivers_a_LIBADD = @NETBOOT_DRIVERS@
+libdrivers_a_DEPENDENCIES = $(libdrivers_a_LIBADD)
+
+EXTRA_DIST = README.netboot 3c90x.txt cs89x0.txt sis900.txt tulip.txt
+
+# These below are several special rules for the device drivers.
+# We cannot use a simple rule for them...
+
+# What objects are derived from a driver?
+3c509_drivers = 3c509.o 3c529.o
+3c595_drivers = 3c595.o
+3c90x_drivers = 3c90x.o
+cs89x0_drivers = cs89x0.o
+davicom_drivers = davicom.o
+depca_drivers = depca.o
+eepro_drivers = eepro.o
+eepro100_drivers = eepro100.o
+epic100_drivers = epic100.o
+#fa311_drivers = fa311.o
+i82586_drivers = 3c507.o exos205.o ni5210.o
+lance_drivers = lance.o ne2100.o ni6510.o
+natsemi_drivers = natsemi.o
+ni5010_drivers = ni5010.o
+ns8390_drivers = 3c503.o ne.o ns8390.o wd.o
+otulip_drivers = otulip.o
+rtl8139_drivers = rtl8139.o
+sis900_drivers = sis900.o
+sk_g16_drivers = sk_g16.o
+smc9000_drivers = smc9000.o
+tiara_drivers = tiara.o
+#tlan_drivers = tlan.o
+tulip_drivers = tulip.o
+via_rhine_drivers = via_rhine.o
+w89c840_drivers = w89c840.o
+
+# Is it really necessary to specify dependecies explicitly?
+$(3c509_drivers): 3c509.c 3c509.h
+$(3c509_drivers): %.o: 3c509.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(3c595_drivers): 3c595.c 3c595.h
+$(3c595_drivers): %.o: 3c595.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(3c90x_drivers): 3c90x.c
+$(3c90x_drivers): %.o: 3c90x.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(cs89x0_drivers): cs89x0.c cs89x0.h
+$(cs89x0_drivers): %.o: cs89x0.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(davicom_drivers): davicom.c
+$(davicom_drivers): %.o: davicom.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(depca_drivers): depca.c
+$(depca_drivers): %.o: depca.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(eepro_drivers): eepro.c
+$(eepro_drivers): %.o: eepro.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(eepro100_drivers): eepro100.c
+$(eepro100_drivers): %.o: eepro100.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(epic100_drivers): epic100.c epic100.h
+$(epic100_drivers): %.o: epic100.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+#$(fa311_drivers): fa311.c
+#$(fa311_drivers): %.o: fa311.c
+#	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+#	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(i82586_drivers): i82586.c
+$(i82586_drivers): %.o: i82586.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(lance_drivers): lance.c
+$(lance_drivers): %.o: lance.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(natsemi_drivers): natsemi.c
+$(natsemi_drivers): %.o: natsemi.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(ni5010_drivers): ni5010.c
+$(ni5010_drivers): %.o: ni5010.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(ns8390_drivers): ns8390.c ns8390.h
+$(ns8390_drivers): %.o: ns8390.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(otulip_drivers): otulip.c otulip.h
+$(otulip_drivers): %.o: otulip.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(rtl8139_drivers): rtl8139.c
+$(rtl8139_drivers): %.o: rtl8139.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(sis900_drivers): sis900.c
+$(sis900_drivers): %.o: sis900.c sis900.h
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(sk_g16_drivers): sk_g16.c sk_g16.h
+$(sk_g16_drivers): %.o: sk_g16.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(smc9000_drivers): smc9000.c smc9000.h
+$(smc9000_drivers): %.o: smc9000.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(tiara_drivers): tiara.c
+$(tiara_drivers): %.o: tiara.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+#$(tlan_drivers): tlan.c
+#$(tlan_drivers): %.o: tlan.c
+#	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+#	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(tulip_drivers): tulip.c
+$(tulip_drivers): %.o: tulip.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(via_rhine_drivers): via-rhine.c
+$(via_rhine_drivers): %.o: via-rhine.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(w89c840_drivers): w89c840.c
+$(w89c840_drivers): %.o: w89c840.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+# Per-object flags.
+3c509_o_CFLAGS = -DINCLUDE_3C509=1
+3c529_o_CFLAGS = -DINCLUDE_3C529=1
+3c595_o_CFLAGS = -DINCLUDE_3C595=1
+3c90x_o_CFLAGS = -DINCLUDE_3C90X=1
+cs89x0_o_CFLAGS = -DINCLUDE_CS89X0=1
+davicom_o_CFLAGS = -DINCLUDE_DAVICOM=1
+depca_o_CFLAGS = -DINCLUDE_DEPCA=1
+eepro_o_CFLAGS = -DINCLUDE_EEPRO=1
+eepro100_o_CFLAGS = -DINCLUDE_EEPRO100=1
+epic100_o_CFLAGS = -DINCLUDE_EPIC100=1
+#fa311_o_CFLAGS = -DINCLUDE_FA311=1
+3c507_o_CFLAGS = -DINCLUDE_3C507=1
+exos205_o_CFLAGS = -DINCLUDE_EXOS205=1
+ni5210_o_CFLAGS = -DINCLUDE_NI5210=1
+lance_o_CFLAGS = -DINCLUDE_LANCE=1
+ne2100_o_CFLAGS = -DINCLUDE_NE2100=1
+ni6510_o_CFLAGS = -DINCLUDE_NI6510=1
+natsemi_o_CFLAGS = -DINCLUDE_NATSEMI=1
+ni5010_o_CFLAGS = -DINCLUDE_NI5010=1
+3c503_o_CFLAGS = -DINCLUDE_3C503=1
+ne_o_CFLAGS = -DINCLUDE_NE=1
+ns8390_o_CFLAGS = -DINCLUDE_NS8390=1
+wd_o_CFLAGS = -DINCLUDE_WD=1
+otulip_o_CFLAGS = -DINCLUDE_OTULIP=1
+rtl8139_o_CFLAGS = -DINCLUDE_RTL8139=1
+sis900_o_CFLAGS = -DINCLUDE_SIS900=1
+sk_g16_o_CFLAGS = -DINCLUDE_SK_G16=1
+smc9000_o_CFLAGS = -DINCLUDE_SMC9000=1
+tiara_o_CFLAGS = -DINCLUDE_TIARA=1
+#tlan_o_CFLAGS = -DINCLUDE_TLAN=1
+tulip_o_CFLAGS = -DINCLUDE_TULIP=1
+via_rhine_o_CFLAGS = -DINCLUDE_VIA_RHINE=1
+w89c840_o_CFLAGS = -DINCLUDE_W89C840=1
diff --git a/netboot/Makefile.in b/netboot/Makefile.in
new file mode 100644
index 0000000..75ac299
--- /dev/null
+++ b/netboot/Makefile.in
@@ -0,0 +1,1091 @@
+# Makefile.in generated by automake 1.9.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  Free Software Foundation, Inc.
+# This Makefile.in 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 distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+SOURCES = $(libdrivers_a_SOURCES) $(EXTRA_libdrivers_a_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = netboot
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+AR = ar
+ARFLAGS = cru
+libdrivers_a_AR = $(AR) $(ARFLAGS)
+am_libdrivers_a_OBJECTS = libdrivers_a-config.$(OBJEXT) \
+	libdrivers_a-fsys_tftp.$(OBJEXT) libdrivers_a-main.$(OBJEXT) \
+	libdrivers_a-misc.$(OBJEXT) libdrivers_a-pci.$(OBJEXT) \
+	libdrivers_a-timer.$(OBJEXT)
+libdrivers_a_OBJECTS = $(am_libdrivers_a_OBJECTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libdrivers_a_SOURCES) $(EXTRA_libdrivers_a_SOURCES)
+DIST_SOURCES = $(libdrivers_a_SOURCES) $(EXTRA_libdrivers_a_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_EXAMPLE_KERNEL_FALSE = @BUILD_EXAMPLE_KERNEL_FALSE@
+BUILD_EXAMPLE_KERNEL_TRUE = @BUILD_EXAMPLE_KERNEL_TRUE@
+CC = @CC@
+CCAS = @CCAS@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISKLESS_SUPPORT_FALSE = @DISKLESS_SUPPORT_FALSE@
+DISKLESS_SUPPORT_TRUE = @DISKLESS_SUPPORT_TRUE@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FSYS_CFLAGS = @FSYS_CFLAGS@
+GRUB_CFLAGS = @GRUB_CFLAGS@
+GRUB_LIBS = @GRUB_LIBS@
+HERCULES_SUPPORT_FALSE = @HERCULES_SUPPORT_FALSE@
+HERCULES_SUPPORT_TRUE = @HERCULES_SUPPORT_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
+NETBOOT_SUPPORT_FALSE = @NETBOOT_SUPPORT_FALSE@
+NETBOOT_SUPPORT_TRUE = @NETBOOT_SUPPORT_TRUE@
+NET_CFLAGS = @NET_CFLAGS@
+NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
+OBJCOPY = @OBJCOPY@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+RANLIB = @RANLIB@
+SERIAL_SPEED_SIMULATION_FALSE = @SERIAL_SPEED_SIMULATION_FALSE@
+SERIAL_SPEED_SIMULATION_TRUE = @SERIAL_SPEED_SIMULATION_TRUE@
+SERIAL_SUPPORT_FALSE = @SERIAL_SUPPORT_FALSE@
+SERIAL_SUPPORT_TRUE = @SERIAL_SUPPORT_TRUE@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STAGE1_CFLAGS = @STAGE1_CFLAGS@
+STAGE2_CFLAGS = @STAGE2_CFLAGS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_OBJCOPY = @ac_ct_OBJCOPY@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+
+# For <shared.h> and <stage1.h>.
+INCLUDES = -I$(top_srcdir)/stage2 -I$(top_srcdir)/stage1
+@NETBOOT_SUPPORT_FALSE@LIBDRIVERS = 
+
+# Don't build the netboot support by default.
+@NETBOOT_SUPPORT_TRUE@LIBDRIVERS = libdrivers.a
+noinst_LIBRARIES = $(LIBDRIVERS)
+libdrivers_a_SOURCES = cards.h config.c etherboot.h \
+	fsys_tftp.c linux-asm-io.h linux-asm-string.h \
+	main.c misc.c nic.h osdep.h pci.c pci.h timer.c timer.h
+
+EXTRA_libdrivers_a_SOURCES = 3c509.c 3c509.h 3c595.c 3c595.h 3c90x.c \
+	cs89x0.c cs89x0.h davicom.c depca.c eepro.c eepro100.c \
+	epic100.c epic100.h fa311.c i82586.c lance.c natsemi.c \
+	ni5010.c ns8390.c ns8390.h otulip.c otulip.h rtl8139.c \
+	sis900.c sis900.h sk_g16.c sk_g16.h smc9000.c smc9000.h \
+	tiara.c tlan.c tulip.c via-rhine.c w89c840.c
+
+libdrivers_a_CFLAGS = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	-DFSYS_TFTP=1 $(NET_CFLAGS) $(NET_EXTRAFLAGS)
+
+# Filled by configure.
+libdrivers_a_LIBADD = @NETBOOT_DRIVERS@
+libdrivers_a_DEPENDENCIES = $(libdrivers_a_LIBADD)
+EXTRA_DIST = README.netboot 3c90x.txt cs89x0.txt sis900.txt tulip.txt
+
+# These below are several special rules for the device drivers.
+# We cannot use a simple rule for them...
+
+# What objects are derived from a driver?
+3c509_drivers = 3c509.o 3c529.o
+3c595_drivers = 3c595.o
+3c90x_drivers = 3c90x.o
+cs89x0_drivers = cs89x0.o
+davicom_drivers = davicom.o
+depca_drivers = depca.o
+eepro_drivers = eepro.o
+eepro100_drivers = eepro100.o
+epic100_drivers = epic100.o
+#fa311_drivers = fa311.o
+i82586_drivers = 3c507.o exos205.o ni5210.o
+lance_drivers = lance.o ne2100.o ni6510.o
+natsemi_drivers = natsemi.o
+ni5010_drivers = ni5010.o
+ns8390_drivers = 3c503.o ne.o ns8390.o wd.o
+otulip_drivers = otulip.o
+rtl8139_drivers = rtl8139.o
+sis900_drivers = sis900.o
+sk_g16_drivers = sk_g16.o
+smc9000_drivers = smc9000.o
+tiara_drivers = tiara.o
+#tlan_drivers = tlan.o
+tulip_drivers = tulip.o
+via_rhine_drivers = via_rhine.o
+w89c840_drivers = w89c840.o
+
+# Per-object flags.
+3c509_o_CFLAGS = -DINCLUDE_3C509=1
+3c529_o_CFLAGS = -DINCLUDE_3C529=1
+3c595_o_CFLAGS = -DINCLUDE_3C595=1
+3c90x_o_CFLAGS = -DINCLUDE_3C90X=1
+cs89x0_o_CFLAGS = -DINCLUDE_CS89X0=1
+davicom_o_CFLAGS = -DINCLUDE_DAVICOM=1
+depca_o_CFLAGS = -DINCLUDE_DEPCA=1
+eepro_o_CFLAGS = -DINCLUDE_EEPRO=1
+eepro100_o_CFLAGS = -DINCLUDE_EEPRO100=1
+epic100_o_CFLAGS = -DINCLUDE_EPIC100=1
+#fa311_o_CFLAGS = -DINCLUDE_FA311=1
+3c507_o_CFLAGS = -DINCLUDE_3C507=1
+exos205_o_CFLAGS = -DINCLUDE_EXOS205=1
+ni5210_o_CFLAGS = -DINCLUDE_NI5210=1
+lance_o_CFLAGS = -DINCLUDE_LANCE=1
+ne2100_o_CFLAGS = -DINCLUDE_NE2100=1
+ni6510_o_CFLAGS = -DINCLUDE_NI6510=1
+natsemi_o_CFLAGS = -DINCLUDE_NATSEMI=1
+ni5010_o_CFLAGS = -DINCLUDE_NI5010=1
+3c503_o_CFLAGS = -DINCLUDE_3C503=1
+ne_o_CFLAGS = -DINCLUDE_NE=1
+ns8390_o_CFLAGS = -DINCLUDE_NS8390=1
+wd_o_CFLAGS = -DINCLUDE_WD=1
+otulip_o_CFLAGS = -DINCLUDE_OTULIP=1
+rtl8139_o_CFLAGS = -DINCLUDE_RTL8139=1
+sis900_o_CFLAGS = -DINCLUDE_SIS900=1
+sk_g16_o_CFLAGS = -DINCLUDE_SK_G16=1
+smc9000_o_CFLAGS = -DINCLUDE_SMC9000=1
+tiara_o_CFLAGS = -DINCLUDE_TIARA=1
+#tlan_o_CFLAGS = -DINCLUDE_TLAN=1
+tulip_o_CFLAGS = -DINCLUDE_TULIP=1
+via_rhine_o_CFLAGS = -DINCLUDE_VIA_RHINE=1
+w89c840_o_CFLAGS = -DINCLUDE_W89C840=1
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  netboot/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu  netboot/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libdrivers.a: $(libdrivers_a_OBJECTS) $(libdrivers_a_DEPENDENCIES) 
+	-rm -f libdrivers.a
+	$(libdrivers_a_AR) libdrivers.a $(libdrivers_a_OBJECTS) $(libdrivers_a_LIBADD)
+	$(RANLIB) libdrivers.a
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-3c509.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-3c595.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-3c90x.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-config.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-cs89x0.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-davicom.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-depca.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-eepro.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-eepro100.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-epic100.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-fa311.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-fsys_tftp.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-i82586.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-lance.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-misc.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-natsemi.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-ni5010.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-ns8390.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-otulip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-pci.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-rtl8139.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-sis900.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-sk_g16.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-smc9000.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-tiara.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-timer.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-tlan.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-tulip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-via-rhine.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libdrivers_a-w89c840.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+libdrivers_a-config.o: config.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-config.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-config.Tpo" -c -o libdrivers_a-config.o `test -f 'config.c' || echo '$(srcdir)/'`config.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-config.Tpo" "$(DEPDIR)/libdrivers_a-config.Po"; else rm -f "$(DEPDIR)/libdrivers_a-config.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='config.c' object='libdrivers_a-config.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-config.o `test -f 'config.c' || echo '$(srcdir)/'`config.c
+
+libdrivers_a-config.obj: config.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-config.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-config.Tpo" -c -o libdrivers_a-config.obj `if test -f 'config.c'; then $(CYGPATH_W) 'config.c'; else $(CYGPATH_W) '$(srcdir)/config.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-config.Tpo" "$(DEPDIR)/libdrivers_a-config.Po"; else rm -f "$(DEPDIR)/libdrivers_a-config.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='config.c' object='libdrivers_a-config.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-config.obj `if test -f 'config.c'; then $(CYGPATH_W) 'config.c'; else $(CYGPATH_W) '$(srcdir)/config.c'; fi`
+
+libdrivers_a-fsys_tftp.o: fsys_tftp.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-fsys_tftp.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-fsys_tftp.Tpo" -c -o libdrivers_a-fsys_tftp.o `test -f 'fsys_tftp.c' || echo '$(srcdir)/'`fsys_tftp.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-fsys_tftp.Tpo" "$(DEPDIR)/libdrivers_a-fsys_tftp.Po"; else rm -f "$(DEPDIR)/libdrivers_a-fsys_tftp.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_tftp.c' object='libdrivers_a-fsys_tftp.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-fsys_tftp.o `test -f 'fsys_tftp.c' || echo '$(srcdir)/'`fsys_tftp.c
+
+libdrivers_a-fsys_tftp.obj: fsys_tftp.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-fsys_tftp.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-fsys_tftp.Tpo" -c -o libdrivers_a-fsys_tftp.obj `if test -f 'fsys_tftp.c'; then $(CYGPATH_W) 'fsys_tftp.c'; else $(CYGPATH_W) '$(srcdir)/fsys_tftp.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-fsys_tftp.Tpo" "$(DEPDIR)/libdrivers_a-fsys_tftp.Po"; else rm -f "$(DEPDIR)/libdrivers_a-fsys_tftp.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_tftp.c' object='libdrivers_a-fsys_tftp.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-fsys_tftp.obj `if test -f 'fsys_tftp.c'; then $(CYGPATH_W) 'fsys_tftp.c'; else $(CYGPATH_W) '$(srcdir)/fsys_tftp.c'; fi`
+
+libdrivers_a-main.o: main.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-main.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-main.Tpo" -c -o libdrivers_a-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-main.Tpo" "$(DEPDIR)/libdrivers_a-main.Po"; else rm -f "$(DEPDIR)/libdrivers_a-main.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='main.c' object='libdrivers_a-main.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-main.o `test -f 'main.c' || echo '$(srcdir)/'`main.c
+
+libdrivers_a-main.obj: main.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-main.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-main.Tpo" -c -o libdrivers_a-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-main.Tpo" "$(DEPDIR)/libdrivers_a-main.Po"; else rm -f "$(DEPDIR)/libdrivers_a-main.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='main.c' object='libdrivers_a-main.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-main.obj `if test -f 'main.c'; then $(CYGPATH_W) 'main.c'; else $(CYGPATH_W) '$(srcdir)/main.c'; fi`
+
+libdrivers_a-misc.o: misc.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-misc.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-misc.Tpo" -c -o libdrivers_a-misc.o `test -f 'misc.c' || echo '$(srcdir)/'`misc.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-misc.Tpo" "$(DEPDIR)/libdrivers_a-misc.Po"; else rm -f "$(DEPDIR)/libdrivers_a-misc.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='misc.c' object='libdrivers_a-misc.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-misc.o `test -f 'misc.c' || echo '$(srcdir)/'`misc.c
+
+libdrivers_a-misc.obj: misc.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-misc.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-misc.Tpo" -c -o libdrivers_a-misc.obj `if test -f 'misc.c'; then $(CYGPATH_W) 'misc.c'; else $(CYGPATH_W) '$(srcdir)/misc.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-misc.Tpo" "$(DEPDIR)/libdrivers_a-misc.Po"; else rm -f "$(DEPDIR)/libdrivers_a-misc.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='misc.c' object='libdrivers_a-misc.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-misc.obj `if test -f 'misc.c'; then $(CYGPATH_W) 'misc.c'; else $(CYGPATH_W) '$(srcdir)/misc.c'; fi`
+
+libdrivers_a-pci.o: pci.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-pci.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-pci.Tpo" -c -o libdrivers_a-pci.o `test -f 'pci.c' || echo '$(srcdir)/'`pci.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-pci.Tpo" "$(DEPDIR)/libdrivers_a-pci.Po"; else rm -f "$(DEPDIR)/libdrivers_a-pci.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='pci.c' object='libdrivers_a-pci.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-pci.o `test -f 'pci.c' || echo '$(srcdir)/'`pci.c
+
+libdrivers_a-pci.obj: pci.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-pci.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-pci.Tpo" -c -o libdrivers_a-pci.obj `if test -f 'pci.c'; then $(CYGPATH_W) 'pci.c'; else $(CYGPATH_W) '$(srcdir)/pci.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-pci.Tpo" "$(DEPDIR)/libdrivers_a-pci.Po"; else rm -f "$(DEPDIR)/libdrivers_a-pci.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='pci.c' object='libdrivers_a-pci.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-pci.obj `if test -f 'pci.c'; then $(CYGPATH_W) 'pci.c'; else $(CYGPATH_W) '$(srcdir)/pci.c'; fi`
+
+libdrivers_a-timer.o: timer.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-timer.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-timer.Tpo" -c -o libdrivers_a-timer.o `test -f 'timer.c' || echo '$(srcdir)/'`timer.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-timer.Tpo" "$(DEPDIR)/libdrivers_a-timer.Po"; else rm -f "$(DEPDIR)/libdrivers_a-timer.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='timer.c' object='libdrivers_a-timer.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-timer.o `test -f 'timer.c' || echo '$(srcdir)/'`timer.c
+
+libdrivers_a-timer.obj: timer.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-timer.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-timer.Tpo" -c -o libdrivers_a-timer.obj `if test -f 'timer.c'; then $(CYGPATH_W) 'timer.c'; else $(CYGPATH_W) '$(srcdir)/timer.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-timer.Tpo" "$(DEPDIR)/libdrivers_a-timer.Po"; else rm -f "$(DEPDIR)/libdrivers_a-timer.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='timer.c' object='libdrivers_a-timer.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-timer.obj `if test -f 'timer.c'; then $(CYGPATH_W) 'timer.c'; else $(CYGPATH_W) '$(srcdir)/timer.c'; fi`
+
+libdrivers_a-3c509.o: 3c509.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-3c509.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-3c509.Tpo" -c -o libdrivers_a-3c509.o `test -f '3c509.c' || echo '$(srcdir)/'`3c509.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-3c509.Tpo" "$(DEPDIR)/libdrivers_a-3c509.Po"; else rm -f "$(DEPDIR)/libdrivers_a-3c509.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='3c509.c' object='libdrivers_a-3c509.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-3c509.o `test -f '3c509.c' || echo '$(srcdir)/'`3c509.c
+
+libdrivers_a-3c509.obj: 3c509.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-3c509.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-3c509.Tpo" -c -o libdrivers_a-3c509.obj `if test -f '3c509.c'; then $(CYGPATH_W) '3c509.c'; else $(CYGPATH_W) '$(srcdir)/3c509.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-3c509.Tpo" "$(DEPDIR)/libdrivers_a-3c509.Po"; else rm -f "$(DEPDIR)/libdrivers_a-3c509.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='3c509.c' object='libdrivers_a-3c509.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-3c509.obj `if test -f '3c509.c'; then $(CYGPATH_W) '3c509.c'; else $(CYGPATH_W) '$(srcdir)/3c509.c'; fi`
+
+libdrivers_a-3c595.o: 3c595.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-3c595.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-3c595.Tpo" -c -o libdrivers_a-3c595.o `test -f '3c595.c' || echo '$(srcdir)/'`3c595.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-3c595.Tpo" "$(DEPDIR)/libdrivers_a-3c595.Po"; else rm -f "$(DEPDIR)/libdrivers_a-3c595.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='3c595.c' object='libdrivers_a-3c595.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-3c595.o `test -f '3c595.c' || echo '$(srcdir)/'`3c595.c
+
+libdrivers_a-3c595.obj: 3c595.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-3c595.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-3c595.Tpo" -c -o libdrivers_a-3c595.obj `if test -f '3c595.c'; then $(CYGPATH_W) '3c595.c'; else $(CYGPATH_W) '$(srcdir)/3c595.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-3c595.Tpo" "$(DEPDIR)/libdrivers_a-3c595.Po"; else rm -f "$(DEPDIR)/libdrivers_a-3c595.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='3c595.c' object='libdrivers_a-3c595.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-3c595.obj `if test -f '3c595.c'; then $(CYGPATH_W) '3c595.c'; else $(CYGPATH_W) '$(srcdir)/3c595.c'; fi`
+
+libdrivers_a-3c90x.o: 3c90x.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-3c90x.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-3c90x.Tpo" -c -o libdrivers_a-3c90x.o `test -f '3c90x.c' || echo '$(srcdir)/'`3c90x.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-3c90x.Tpo" "$(DEPDIR)/libdrivers_a-3c90x.Po"; else rm -f "$(DEPDIR)/libdrivers_a-3c90x.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='3c90x.c' object='libdrivers_a-3c90x.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-3c90x.o `test -f '3c90x.c' || echo '$(srcdir)/'`3c90x.c
+
+libdrivers_a-3c90x.obj: 3c90x.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-3c90x.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-3c90x.Tpo" -c -o libdrivers_a-3c90x.obj `if test -f '3c90x.c'; then $(CYGPATH_W) '3c90x.c'; else $(CYGPATH_W) '$(srcdir)/3c90x.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-3c90x.Tpo" "$(DEPDIR)/libdrivers_a-3c90x.Po"; else rm -f "$(DEPDIR)/libdrivers_a-3c90x.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='3c90x.c' object='libdrivers_a-3c90x.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-3c90x.obj `if test -f '3c90x.c'; then $(CYGPATH_W) '3c90x.c'; else $(CYGPATH_W) '$(srcdir)/3c90x.c'; fi`
+
+libdrivers_a-cs89x0.o: cs89x0.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-cs89x0.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-cs89x0.Tpo" -c -o libdrivers_a-cs89x0.o `test -f 'cs89x0.c' || echo '$(srcdir)/'`cs89x0.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-cs89x0.Tpo" "$(DEPDIR)/libdrivers_a-cs89x0.Po"; else rm -f "$(DEPDIR)/libdrivers_a-cs89x0.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='cs89x0.c' object='libdrivers_a-cs89x0.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-cs89x0.o `test -f 'cs89x0.c' || echo '$(srcdir)/'`cs89x0.c
+
+libdrivers_a-cs89x0.obj: cs89x0.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-cs89x0.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-cs89x0.Tpo" -c -o libdrivers_a-cs89x0.obj `if test -f 'cs89x0.c'; then $(CYGPATH_W) 'cs89x0.c'; else $(CYGPATH_W) '$(srcdir)/cs89x0.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-cs89x0.Tpo" "$(DEPDIR)/libdrivers_a-cs89x0.Po"; else rm -f "$(DEPDIR)/libdrivers_a-cs89x0.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='cs89x0.c' object='libdrivers_a-cs89x0.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-cs89x0.obj `if test -f 'cs89x0.c'; then $(CYGPATH_W) 'cs89x0.c'; else $(CYGPATH_W) '$(srcdir)/cs89x0.c'; fi`
+
+libdrivers_a-davicom.o: davicom.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-davicom.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-davicom.Tpo" -c -o libdrivers_a-davicom.o `test -f 'davicom.c' || echo '$(srcdir)/'`davicom.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-davicom.Tpo" "$(DEPDIR)/libdrivers_a-davicom.Po"; else rm -f "$(DEPDIR)/libdrivers_a-davicom.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='davicom.c' object='libdrivers_a-davicom.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-davicom.o `test -f 'davicom.c' || echo '$(srcdir)/'`davicom.c
+
+libdrivers_a-davicom.obj: davicom.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-davicom.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-davicom.Tpo" -c -o libdrivers_a-davicom.obj `if test -f 'davicom.c'; then $(CYGPATH_W) 'davicom.c'; else $(CYGPATH_W) '$(srcdir)/davicom.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-davicom.Tpo" "$(DEPDIR)/libdrivers_a-davicom.Po"; else rm -f "$(DEPDIR)/libdrivers_a-davicom.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='davicom.c' object='libdrivers_a-davicom.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-davicom.obj `if test -f 'davicom.c'; then $(CYGPATH_W) 'davicom.c'; else $(CYGPATH_W) '$(srcdir)/davicom.c'; fi`
+
+libdrivers_a-depca.o: depca.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-depca.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-depca.Tpo" -c -o libdrivers_a-depca.o `test -f 'depca.c' || echo '$(srcdir)/'`depca.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-depca.Tpo" "$(DEPDIR)/libdrivers_a-depca.Po"; else rm -f "$(DEPDIR)/libdrivers_a-depca.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='depca.c' object='libdrivers_a-depca.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-depca.o `test -f 'depca.c' || echo '$(srcdir)/'`depca.c
+
+libdrivers_a-depca.obj: depca.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-depca.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-depca.Tpo" -c -o libdrivers_a-depca.obj `if test -f 'depca.c'; then $(CYGPATH_W) 'depca.c'; else $(CYGPATH_W) '$(srcdir)/depca.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-depca.Tpo" "$(DEPDIR)/libdrivers_a-depca.Po"; else rm -f "$(DEPDIR)/libdrivers_a-depca.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='depca.c' object='libdrivers_a-depca.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-depca.obj `if test -f 'depca.c'; then $(CYGPATH_W) 'depca.c'; else $(CYGPATH_W) '$(srcdir)/depca.c'; fi`
+
+libdrivers_a-eepro.o: eepro.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-eepro.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-eepro.Tpo" -c -o libdrivers_a-eepro.o `test -f 'eepro.c' || echo '$(srcdir)/'`eepro.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-eepro.Tpo" "$(DEPDIR)/libdrivers_a-eepro.Po"; else rm -f "$(DEPDIR)/libdrivers_a-eepro.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='eepro.c' object='libdrivers_a-eepro.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-eepro.o `test -f 'eepro.c' || echo '$(srcdir)/'`eepro.c
+
+libdrivers_a-eepro.obj: eepro.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-eepro.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-eepro.Tpo" -c -o libdrivers_a-eepro.obj `if test -f 'eepro.c'; then $(CYGPATH_W) 'eepro.c'; else $(CYGPATH_W) '$(srcdir)/eepro.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-eepro.Tpo" "$(DEPDIR)/libdrivers_a-eepro.Po"; else rm -f "$(DEPDIR)/libdrivers_a-eepro.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='eepro.c' object='libdrivers_a-eepro.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-eepro.obj `if test -f 'eepro.c'; then $(CYGPATH_W) 'eepro.c'; else $(CYGPATH_W) '$(srcdir)/eepro.c'; fi`
+
+libdrivers_a-eepro100.o: eepro100.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-eepro100.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-eepro100.Tpo" -c -o libdrivers_a-eepro100.o `test -f 'eepro100.c' || echo '$(srcdir)/'`eepro100.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-eepro100.Tpo" "$(DEPDIR)/libdrivers_a-eepro100.Po"; else rm -f "$(DEPDIR)/libdrivers_a-eepro100.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='eepro100.c' object='libdrivers_a-eepro100.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-eepro100.o `test -f 'eepro100.c' || echo '$(srcdir)/'`eepro100.c
+
+libdrivers_a-eepro100.obj: eepro100.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-eepro100.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-eepro100.Tpo" -c -o libdrivers_a-eepro100.obj `if test -f 'eepro100.c'; then $(CYGPATH_W) 'eepro100.c'; else $(CYGPATH_W) '$(srcdir)/eepro100.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-eepro100.Tpo" "$(DEPDIR)/libdrivers_a-eepro100.Po"; else rm -f "$(DEPDIR)/libdrivers_a-eepro100.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='eepro100.c' object='libdrivers_a-eepro100.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-eepro100.obj `if test -f 'eepro100.c'; then $(CYGPATH_W) 'eepro100.c'; else $(CYGPATH_W) '$(srcdir)/eepro100.c'; fi`
+
+libdrivers_a-epic100.o: epic100.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-epic100.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-epic100.Tpo" -c -o libdrivers_a-epic100.o `test -f 'epic100.c' || echo '$(srcdir)/'`epic100.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-epic100.Tpo" "$(DEPDIR)/libdrivers_a-epic100.Po"; else rm -f "$(DEPDIR)/libdrivers_a-epic100.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='epic100.c' object='libdrivers_a-epic100.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-epic100.o `test -f 'epic100.c' || echo '$(srcdir)/'`epic100.c
+
+libdrivers_a-epic100.obj: epic100.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-epic100.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-epic100.Tpo" -c -o libdrivers_a-epic100.obj `if test -f 'epic100.c'; then $(CYGPATH_W) 'epic100.c'; else $(CYGPATH_W) '$(srcdir)/epic100.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-epic100.Tpo" "$(DEPDIR)/libdrivers_a-epic100.Po"; else rm -f "$(DEPDIR)/libdrivers_a-epic100.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='epic100.c' object='libdrivers_a-epic100.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-epic100.obj `if test -f 'epic100.c'; then $(CYGPATH_W) 'epic100.c'; else $(CYGPATH_W) '$(srcdir)/epic100.c'; fi`
+
+libdrivers_a-fa311.o: fa311.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-fa311.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-fa311.Tpo" -c -o libdrivers_a-fa311.o `test -f 'fa311.c' || echo '$(srcdir)/'`fa311.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-fa311.Tpo" "$(DEPDIR)/libdrivers_a-fa311.Po"; else rm -f "$(DEPDIR)/libdrivers_a-fa311.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fa311.c' object='libdrivers_a-fa311.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-fa311.o `test -f 'fa311.c' || echo '$(srcdir)/'`fa311.c
+
+libdrivers_a-fa311.obj: fa311.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-fa311.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-fa311.Tpo" -c -o libdrivers_a-fa311.obj `if test -f 'fa311.c'; then $(CYGPATH_W) 'fa311.c'; else $(CYGPATH_W) '$(srcdir)/fa311.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-fa311.Tpo" "$(DEPDIR)/libdrivers_a-fa311.Po"; else rm -f "$(DEPDIR)/libdrivers_a-fa311.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fa311.c' object='libdrivers_a-fa311.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-fa311.obj `if test -f 'fa311.c'; then $(CYGPATH_W) 'fa311.c'; else $(CYGPATH_W) '$(srcdir)/fa311.c'; fi`
+
+libdrivers_a-i82586.o: i82586.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-i82586.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-i82586.Tpo" -c -o libdrivers_a-i82586.o `test -f 'i82586.c' || echo '$(srcdir)/'`i82586.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-i82586.Tpo" "$(DEPDIR)/libdrivers_a-i82586.Po"; else rm -f "$(DEPDIR)/libdrivers_a-i82586.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='i82586.c' object='libdrivers_a-i82586.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-i82586.o `test -f 'i82586.c' || echo '$(srcdir)/'`i82586.c
+
+libdrivers_a-i82586.obj: i82586.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-i82586.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-i82586.Tpo" -c -o libdrivers_a-i82586.obj `if test -f 'i82586.c'; then $(CYGPATH_W) 'i82586.c'; else $(CYGPATH_W) '$(srcdir)/i82586.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-i82586.Tpo" "$(DEPDIR)/libdrivers_a-i82586.Po"; else rm -f "$(DEPDIR)/libdrivers_a-i82586.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='i82586.c' object='libdrivers_a-i82586.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-i82586.obj `if test -f 'i82586.c'; then $(CYGPATH_W) 'i82586.c'; else $(CYGPATH_W) '$(srcdir)/i82586.c'; fi`
+
+libdrivers_a-lance.o: lance.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-lance.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-lance.Tpo" -c -o libdrivers_a-lance.o `test -f 'lance.c' || echo '$(srcdir)/'`lance.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-lance.Tpo" "$(DEPDIR)/libdrivers_a-lance.Po"; else rm -f "$(DEPDIR)/libdrivers_a-lance.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='lance.c' object='libdrivers_a-lance.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-lance.o `test -f 'lance.c' || echo '$(srcdir)/'`lance.c
+
+libdrivers_a-lance.obj: lance.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-lance.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-lance.Tpo" -c -o libdrivers_a-lance.obj `if test -f 'lance.c'; then $(CYGPATH_W) 'lance.c'; else $(CYGPATH_W) '$(srcdir)/lance.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-lance.Tpo" "$(DEPDIR)/libdrivers_a-lance.Po"; else rm -f "$(DEPDIR)/libdrivers_a-lance.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='lance.c' object='libdrivers_a-lance.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-lance.obj `if test -f 'lance.c'; then $(CYGPATH_W) 'lance.c'; else $(CYGPATH_W) '$(srcdir)/lance.c'; fi`
+
+libdrivers_a-natsemi.o: natsemi.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-natsemi.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-natsemi.Tpo" -c -o libdrivers_a-natsemi.o `test -f 'natsemi.c' || echo '$(srcdir)/'`natsemi.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-natsemi.Tpo" "$(DEPDIR)/libdrivers_a-natsemi.Po"; else rm -f "$(DEPDIR)/libdrivers_a-natsemi.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='natsemi.c' object='libdrivers_a-natsemi.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-natsemi.o `test -f 'natsemi.c' || echo '$(srcdir)/'`natsemi.c
+
+libdrivers_a-natsemi.obj: natsemi.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-natsemi.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-natsemi.Tpo" -c -o libdrivers_a-natsemi.obj `if test -f 'natsemi.c'; then $(CYGPATH_W) 'natsemi.c'; else $(CYGPATH_W) '$(srcdir)/natsemi.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-natsemi.Tpo" "$(DEPDIR)/libdrivers_a-natsemi.Po"; else rm -f "$(DEPDIR)/libdrivers_a-natsemi.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='natsemi.c' object='libdrivers_a-natsemi.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-natsemi.obj `if test -f 'natsemi.c'; then $(CYGPATH_W) 'natsemi.c'; else $(CYGPATH_W) '$(srcdir)/natsemi.c'; fi`
+
+libdrivers_a-ni5010.o: ni5010.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-ni5010.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-ni5010.Tpo" -c -o libdrivers_a-ni5010.o `test -f 'ni5010.c' || echo '$(srcdir)/'`ni5010.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-ni5010.Tpo" "$(DEPDIR)/libdrivers_a-ni5010.Po"; else rm -f "$(DEPDIR)/libdrivers_a-ni5010.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ni5010.c' object='libdrivers_a-ni5010.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-ni5010.o `test -f 'ni5010.c' || echo '$(srcdir)/'`ni5010.c
+
+libdrivers_a-ni5010.obj: ni5010.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-ni5010.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-ni5010.Tpo" -c -o libdrivers_a-ni5010.obj `if test -f 'ni5010.c'; then $(CYGPATH_W) 'ni5010.c'; else $(CYGPATH_W) '$(srcdir)/ni5010.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-ni5010.Tpo" "$(DEPDIR)/libdrivers_a-ni5010.Po"; else rm -f "$(DEPDIR)/libdrivers_a-ni5010.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ni5010.c' object='libdrivers_a-ni5010.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-ni5010.obj `if test -f 'ni5010.c'; then $(CYGPATH_W) 'ni5010.c'; else $(CYGPATH_W) '$(srcdir)/ni5010.c'; fi`
+
+libdrivers_a-ns8390.o: ns8390.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-ns8390.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-ns8390.Tpo" -c -o libdrivers_a-ns8390.o `test -f 'ns8390.c' || echo '$(srcdir)/'`ns8390.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-ns8390.Tpo" "$(DEPDIR)/libdrivers_a-ns8390.Po"; else rm -f "$(DEPDIR)/libdrivers_a-ns8390.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ns8390.c' object='libdrivers_a-ns8390.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-ns8390.o `test -f 'ns8390.c' || echo '$(srcdir)/'`ns8390.c
+
+libdrivers_a-ns8390.obj: ns8390.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-ns8390.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-ns8390.Tpo" -c -o libdrivers_a-ns8390.obj `if test -f 'ns8390.c'; then $(CYGPATH_W) 'ns8390.c'; else $(CYGPATH_W) '$(srcdir)/ns8390.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-ns8390.Tpo" "$(DEPDIR)/libdrivers_a-ns8390.Po"; else rm -f "$(DEPDIR)/libdrivers_a-ns8390.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ns8390.c' object='libdrivers_a-ns8390.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-ns8390.obj `if test -f 'ns8390.c'; then $(CYGPATH_W) 'ns8390.c'; else $(CYGPATH_W) '$(srcdir)/ns8390.c'; fi`
+
+libdrivers_a-otulip.o: otulip.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-otulip.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-otulip.Tpo" -c -o libdrivers_a-otulip.o `test -f 'otulip.c' || echo '$(srcdir)/'`otulip.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-otulip.Tpo" "$(DEPDIR)/libdrivers_a-otulip.Po"; else rm -f "$(DEPDIR)/libdrivers_a-otulip.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='otulip.c' object='libdrivers_a-otulip.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-otulip.o `test -f 'otulip.c' || echo '$(srcdir)/'`otulip.c
+
+libdrivers_a-otulip.obj: otulip.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-otulip.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-otulip.Tpo" -c -o libdrivers_a-otulip.obj `if test -f 'otulip.c'; then $(CYGPATH_W) 'otulip.c'; else $(CYGPATH_W) '$(srcdir)/otulip.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-otulip.Tpo" "$(DEPDIR)/libdrivers_a-otulip.Po"; else rm -f "$(DEPDIR)/libdrivers_a-otulip.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='otulip.c' object='libdrivers_a-otulip.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-otulip.obj `if test -f 'otulip.c'; then $(CYGPATH_W) 'otulip.c'; else $(CYGPATH_W) '$(srcdir)/otulip.c'; fi`
+
+libdrivers_a-rtl8139.o: rtl8139.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-rtl8139.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-rtl8139.Tpo" -c -o libdrivers_a-rtl8139.o `test -f 'rtl8139.c' || echo '$(srcdir)/'`rtl8139.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-rtl8139.Tpo" "$(DEPDIR)/libdrivers_a-rtl8139.Po"; else rm -f "$(DEPDIR)/libdrivers_a-rtl8139.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='rtl8139.c' object='libdrivers_a-rtl8139.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-rtl8139.o `test -f 'rtl8139.c' || echo '$(srcdir)/'`rtl8139.c
+
+libdrivers_a-rtl8139.obj: rtl8139.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-rtl8139.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-rtl8139.Tpo" -c -o libdrivers_a-rtl8139.obj `if test -f 'rtl8139.c'; then $(CYGPATH_W) 'rtl8139.c'; else $(CYGPATH_W) '$(srcdir)/rtl8139.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-rtl8139.Tpo" "$(DEPDIR)/libdrivers_a-rtl8139.Po"; else rm -f "$(DEPDIR)/libdrivers_a-rtl8139.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='rtl8139.c' object='libdrivers_a-rtl8139.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-rtl8139.obj `if test -f 'rtl8139.c'; then $(CYGPATH_W) 'rtl8139.c'; else $(CYGPATH_W) '$(srcdir)/rtl8139.c'; fi`
+
+libdrivers_a-sis900.o: sis900.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-sis900.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-sis900.Tpo" -c -o libdrivers_a-sis900.o `test -f 'sis900.c' || echo '$(srcdir)/'`sis900.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-sis900.Tpo" "$(DEPDIR)/libdrivers_a-sis900.Po"; else rm -f "$(DEPDIR)/libdrivers_a-sis900.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='sis900.c' object='libdrivers_a-sis900.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-sis900.o `test -f 'sis900.c' || echo '$(srcdir)/'`sis900.c
+
+libdrivers_a-sis900.obj: sis900.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-sis900.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-sis900.Tpo" -c -o libdrivers_a-sis900.obj `if test -f 'sis900.c'; then $(CYGPATH_W) 'sis900.c'; else $(CYGPATH_W) '$(srcdir)/sis900.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-sis900.Tpo" "$(DEPDIR)/libdrivers_a-sis900.Po"; else rm -f "$(DEPDIR)/libdrivers_a-sis900.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='sis900.c' object='libdrivers_a-sis900.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-sis900.obj `if test -f 'sis900.c'; then $(CYGPATH_W) 'sis900.c'; else $(CYGPATH_W) '$(srcdir)/sis900.c'; fi`
+
+libdrivers_a-sk_g16.o: sk_g16.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-sk_g16.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-sk_g16.Tpo" -c -o libdrivers_a-sk_g16.o `test -f 'sk_g16.c' || echo '$(srcdir)/'`sk_g16.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-sk_g16.Tpo" "$(DEPDIR)/libdrivers_a-sk_g16.Po"; else rm -f "$(DEPDIR)/libdrivers_a-sk_g16.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='sk_g16.c' object='libdrivers_a-sk_g16.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-sk_g16.o `test -f 'sk_g16.c' || echo '$(srcdir)/'`sk_g16.c
+
+libdrivers_a-sk_g16.obj: sk_g16.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-sk_g16.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-sk_g16.Tpo" -c -o libdrivers_a-sk_g16.obj `if test -f 'sk_g16.c'; then $(CYGPATH_W) 'sk_g16.c'; else $(CYGPATH_W) '$(srcdir)/sk_g16.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-sk_g16.Tpo" "$(DEPDIR)/libdrivers_a-sk_g16.Po"; else rm -f "$(DEPDIR)/libdrivers_a-sk_g16.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='sk_g16.c' object='libdrivers_a-sk_g16.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-sk_g16.obj `if test -f 'sk_g16.c'; then $(CYGPATH_W) 'sk_g16.c'; else $(CYGPATH_W) '$(srcdir)/sk_g16.c'; fi`
+
+libdrivers_a-smc9000.o: smc9000.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-smc9000.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-smc9000.Tpo" -c -o libdrivers_a-smc9000.o `test -f 'smc9000.c' || echo '$(srcdir)/'`smc9000.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-smc9000.Tpo" "$(DEPDIR)/libdrivers_a-smc9000.Po"; else rm -f "$(DEPDIR)/libdrivers_a-smc9000.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='smc9000.c' object='libdrivers_a-smc9000.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-smc9000.o `test -f 'smc9000.c' || echo '$(srcdir)/'`smc9000.c
+
+libdrivers_a-smc9000.obj: smc9000.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-smc9000.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-smc9000.Tpo" -c -o libdrivers_a-smc9000.obj `if test -f 'smc9000.c'; then $(CYGPATH_W) 'smc9000.c'; else $(CYGPATH_W) '$(srcdir)/smc9000.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-smc9000.Tpo" "$(DEPDIR)/libdrivers_a-smc9000.Po"; else rm -f "$(DEPDIR)/libdrivers_a-smc9000.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='smc9000.c' object='libdrivers_a-smc9000.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-smc9000.obj `if test -f 'smc9000.c'; then $(CYGPATH_W) 'smc9000.c'; else $(CYGPATH_W) '$(srcdir)/smc9000.c'; fi`
+
+libdrivers_a-tiara.o: tiara.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-tiara.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-tiara.Tpo" -c -o libdrivers_a-tiara.o `test -f 'tiara.c' || echo '$(srcdir)/'`tiara.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-tiara.Tpo" "$(DEPDIR)/libdrivers_a-tiara.Po"; else rm -f "$(DEPDIR)/libdrivers_a-tiara.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='tiara.c' object='libdrivers_a-tiara.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-tiara.o `test -f 'tiara.c' || echo '$(srcdir)/'`tiara.c
+
+libdrivers_a-tiara.obj: tiara.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-tiara.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-tiara.Tpo" -c -o libdrivers_a-tiara.obj `if test -f 'tiara.c'; then $(CYGPATH_W) 'tiara.c'; else $(CYGPATH_W) '$(srcdir)/tiara.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-tiara.Tpo" "$(DEPDIR)/libdrivers_a-tiara.Po"; else rm -f "$(DEPDIR)/libdrivers_a-tiara.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='tiara.c' object='libdrivers_a-tiara.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-tiara.obj `if test -f 'tiara.c'; then $(CYGPATH_W) 'tiara.c'; else $(CYGPATH_W) '$(srcdir)/tiara.c'; fi`
+
+libdrivers_a-tlan.o: tlan.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-tlan.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-tlan.Tpo" -c -o libdrivers_a-tlan.o `test -f 'tlan.c' || echo '$(srcdir)/'`tlan.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-tlan.Tpo" "$(DEPDIR)/libdrivers_a-tlan.Po"; else rm -f "$(DEPDIR)/libdrivers_a-tlan.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='tlan.c' object='libdrivers_a-tlan.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-tlan.o `test -f 'tlan.c' || echo '$(srcdir)/'`tlan.c
+
+libdrivers_a-tlan.obj: tlan.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-tlan.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-tlan.Tpo" -c -o libdrivers_a-tlan.obj `if test -f 'tlan.c'; then $(CYGPATH_W) 'tlan.c'; else $(CYGPATH_W) '$(srcdir)/tlan.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-tlan.Tpo" "$(DEPDIR)/libdrivers_a-tlan.Po"; else rm -f "$(DEPDIR)/libdrivers_a-tlan.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='tlan.c' object='libdrivers_a-tlan.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-tlan.obj `if test -f 'tlan.c'; then $(CYGPATH_W) 'tlan.c'; else $(CYGPATH_W) '$(srcdir)/tlan.c'; fi`
+
+libdrivers_a-tulip.o: tulip.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-tulip.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-tulip.Tpo" -c -o libdrivers_a-tulip.o `test -f 'tulip.c' || echo '$(srcdir)/'`tulip.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-tulip.Tpo" "$(DEPDIR)/libdrivers_a-tulip.Po"; else rm -f "$(DEPDIR)/libdrivers_a-tulip.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='tulip.c' object='libdrivers_a-tulip.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-tulip.o `test -f 'tulip.c' || echo '$(srcdir)/'`tulip.c
+
+libdrivers_a-tulip.obj: tulip.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-tulip.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-tulip.Tpo" -c -o libdrivers_a-tulip.obj `if test -f 'tulip.c'; then $(CYGPATH_W) 'tulip.c'; else $(CYGPATH_W) '$(srcdir)/tulip.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-tulip.Tpo" "$(DEPDIR)/libdrivers_a-tulip.Po"; else rm -f "$(DEPDIR)/libdrivers_a-tulip.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='tulip.c' object='libdrivers_a-tulip.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-tulip.obj `if test -f 'tulip.c'; then $(CYGPATH_W) 'tulip.c'; else $(CYGPATH_W) '$(srcdir)/tulip.c'; fi`
+
+libdrivers_a-via-rhine.o: via-rhine.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-via-rhine.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-via-rhine.Tpo" -c -o libdrivers_a-via-rhine.o `test -f 'via-rhine.c' || echo '$(srcdir)/'`via-rhine.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-via-rhine.Tpo" "$(DEPDIR)/libdrivers_a-via-rhine.Po"; else rm -f "$(DEPDIR)/libdrivers_a-via-rhine.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='via-rhine.c' object='libdrivers_a-via-rhine.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-via-rhine.o `test -f 'via-rhine.c' || echo '$(srcdir)/'`via-rhine.c
+
+libdrivers_a-via-rhine.obj: via-rhine.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-via-rhine.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-via-rhine.Tpo" -c -o libdrivers_a-via-rhine.obj `if test -f 'via-rhine.c'; then $(CYGPATH_W) 'via-rhine.c'; else $(CYGPATH_W) '$(srcdir)/via-rhine.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-via-rhine.Tpo" "$(DEPDIR)/libdrivers_a-via-rhine.Po"; else rm -f "$(DEPDIR)/libdrivers_a-via-rhine.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='via-rhine.c' object='libdrivers_a-via-rhine.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-via-rhine.obj `if test -f 'via-rhine.c'; then $(CYGPATH_W) 'via-rhine.c'; else $(CYGPATH_W) '$(srcdir)/via-rhine.c'; fi`
+
+libdrivers_a-w89c840.o: w89c840.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-w89c840.o -MD -MP -MF "$(DEPDIR)/libdrivers_a-w89c840.Tpo" -c -o libdrivers_a-w89c840.o `test -f 'w89c840.c' || echo '$(srcdir)/'`w89c840.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-w89c840.Tpo" "$(DEPDIR)/libdrivers_a-w89c840.Po"; else rm -f "$(DEPDIR)/libdrivers_a-w89c840.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='w89c840.c' object='libdrivers_a-w89c840.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-w89c840.o `test -f 'w89c840.c' || echo '$(srcdir)/'`w89c840.c
+
+libdrivers_a-w89c840.obj: w89c840.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -MT libdrivers_a-w89c840.obj -MD -MP -MF "$(DEPDIR)/libdrivers_a-w89c840.Tpo" -c -o libdrivers_a-w89c840.obj `if test -f 'w89c840.c'; then $(CYGPATH_W) 'w89c840.c'; else $(CYGPATH_W) '$(srcdir)/w89c840.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libdrivers_a-w89c840.Tpo" "$(DEPDIR)/libdrivers_a-w89c840.Po"; else rm -f "$(DEPDIR)/libdrivers_a-w89c840.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='w89c840.c' object='libdrivers_a-w89c840.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libdrivers_a_CFLAGS) $(CFLAGS) -c -o libdrivers_a-w89c840.obj `if test -f 'w89c840.c'; then $(CYGPATH_W) 'w89c840.c'; else $(CYGPATH_W) '$(srcdir)/w89c840.c'; fi`
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	    $$tags $$unique; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$tags $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+	list='$(DISTFILES)'; for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+	  esac; \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+	    dir="/$$dir"; \
+	    $(mkdir_p) "$(distdir)$$dir"; \
+	  else \
+	    dir=''; \
+	  fi; \
+	  if test -d $$d/$$file; then \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(LIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+	clean-noinstLIBRARIES ctags distclean distclean-compile \
+	distclean-generic distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-exec install-exec-am install-info \
+	install-info-am install-man install-strip installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
+	uninstall-am uninstall-info-am
+
+
+# Is it really necessary to specify dependecies explicitly?
+$(3c509_drivers): 3c509.c 3c509.h
+$(3c509_drivers): %.o: 3c509.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(3c595_drivers): 3c595.c 3c595.h
+$(3c595_drivers): %.o: 3c595.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(3c90x_drivers): 3c90x.c
+$(3c90x_drivers): %.o: 3c90x.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(cs89x0_drivers): cs89x0.c cs89x0.h
+$(cs89x0_drivers): %.o: cs89x0.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(davicom_drivers): davicom.c
+$(davicom_drivers): %.o: davicom.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(depca_drivers): depca.c
+$(depca_drivers): %.o: depca.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(eepro_drivers): eepro.c
+$(eepro_drivers): %.o: eepro.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(eepro100_drivers): eepro100.c
+$(eepro100_drivers): %.o: eepro100.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(epic100_drivers): epic100.c epic100.h
+$(epic100_drivers): %.o: epic100.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+#$(fa311_drivers): fa311.c
+#$(fa311_drivers): %.o: fa311.c
+#	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+#	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(i82586_drivers): i82586.c
+$(i82586_drivers): %.o: i82586.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(lance_drivers): lance.c
+$(lance_drivers): %.o: lance.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(natsemi_drivers): natsemi.c
+$(natsemi_drivers): %.o: natsemi.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(ni5010_drivers): ni5010.c
+$(ni5010_drivers): %.o: ni5010.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(ns8390_drivers): ns8390.c ns8390.h
+$(ns8390_drivers): %.o: ns8390.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(otulip_drivers): otulip.c otulip.h
+$(otulip_drivers): %.o: otulip.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(rtl8139_drivers): rtl8139.c
+$(rtl8139_drivers): %.o: rtl8139.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(sis900_drivers): sis900.c
+$(sis900_drivers): %.o: sis900.c sis900.h
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(sk_g16_drivers): sk_g16.c sk_g16.h
+$(sk_g16_drivers): %.o: sk_g16.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(smc9000_drivers): smc9000.c smc9000.h
+$(smc9000_drivers): %.o: smc9000.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(tiara_drivers): tiara.c
+$(tiara_drivers): %.o: tiara.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+#$(tlan_drivers): tlan.c
+#$(tlan_drivers): %.o: tlan.c
+#	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+#	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(tulip_drivers): tulip.c
+$(tulip_drivers): %.o: tulip.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(via_rhine_drivers): via-rhine.c
+$(via_rhine_drivers): %.o: via-rhine.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+
+$(w89c840_drivers): w89c840.c
+$(w89c840_drivers): %.o: w89c840.c
+	$(COMPILE) $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	  $(NET_EXTRAFLAGS) $($(basename $@)_o_CFLAGS) -o $@ -c $<
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/netboot/README.netboot b/netboot/README.netboot
new file mode 100644
index 0000000..7edfaf0
--- /dev/null
+++ b/netboot/README.netboot
@@ -0,0 +1,168 @@
+You can use the netboot support to download OS images from a network.
+Nearly all the device drivers are coming from the network-based boot
+loader, Etherboot. Please visit its web page. They have rich
+documentations so you will be able to get useful information from there.
+The URL is <http://etherboot.sourceforge.net/>.
+
+These below are common options for configure. Perhaps you may not need
+to specify them.
+
+--disable-packet-retransmission
+  Turns off packet retransmission. Use it on an empty network, where
+  no packet collision can happen.
+
+--enable-pci-direct
+  Define this for PCI BIOSes that do not implement BIOS32 or not
+  correctly.
+
+--enable-diskless
+  Enable the diskless support. If specified, you will get two optional
+  images, called "nbgrub" and "pxegrub". The former is the ``Net Boot
+  Image Proposal'' format, which is used by Etherboot and Netboot, while
+  the latter is the ``Preboot Execution Environment" format, which is
+  used by a PXE ROM. You may buy a PXE ROM from some companies.
+
+Here is the information about the device drivers. They are all disabled
+by default, so you must specify configure options to enable drivers you
+want to use. Some drivers have extra per-driver options, so the extra
+options are also described below.
+
+Caution: You should enable them as you need. Don't enable any
+unnecessary driver, because GRUB might crash if you include too many
+drivers at the same time.
+
+3Com509, ISA/EISA
+  --enable-3c509
+
+3Com529 == MCA 3c509
+  --enable-3c529
+
+3Com59x and 3Com900
+  --enable-3c595
+
+3Com90x
+  --enable-3c90x
+
+Crystal Semiconductor CS89x0
+  --enable-cs89x0
+  --enable-cs-scan=LIST
+    Probe for CS89x0 base address using LIST of comma separated hex
+    addresses; increasing the address by one (0x300 -> 0x301) will force
+    a more aggressive probing algorithm. This might be neccessary after
+    a soft-reset of the NIC.
+
+Davicom DM9102 and 9009
+  --enable-davicom
+
+Digital DE100 and DE200
+  --enable-depca
+
+Intel Etherexpress Pro/10 (ISA card)
+  --enable-eepro
+
+Intel Etherexpress Pro/100
+  --enable-eepro100
+
+SMC 83c170 EPIC/100
+  --enable-epic100
+
+3Com507
+  --enable-3c507
+
+EXOS205
+  --enable-exos205
+
+Racal-Interlan NI5210
+  --enable-ni5210
+
+Lance PCI PCNet/32
+AMD HomePNA
+  --enable-lance
+
+Novell NE2100 and NE1500
+  --enable-ne2100
+
+Racal-Interlan NI6510
+  --enable-ni6510
+
+National Semiconductor DP8381x (Netgear FA311 and FA312)
+  --enable-natsemi
+
+Racal-Interlan NI5010
+  --enable-ni5010
+
+3Com503, aka Etherlink II, also /16 model
+  --enable-3c503
+  --enable-3c503-shmem
+    Use 3c503 shared memory mode.
+  --enable-3c503-aui
+    Use AUI by default on 3c503 cards.
+
+NE1000/2000 and clones (ISA)
+  --enable-ne
+  --enable-ne-scan=LIST (0x280,0x300,0x320,0x340)
+    Probe for NE base address using LIST of comma separated hex
+    addresses.
+
+NE2000 PCI clone (RTL8029)
+Winbond 86C940
+Compex RL2000
+KTI ET32P2
+NetVin 5000SC
+Holtek 80232
+  --enable-ns8390
+  --enable-compex-rl2000-fix
+    If you have a Compex RL2000 PCI 32-bit (11F6:1401), and the probe
+    hangs in "Probing...[NE*000/PCI]", try enabling this fix... it
+    worked for me :).
+
+WD8003/8013, SMC8216/8416
+  --enable-wd
+  --enable-wd-default-mem=MEM (0xCC000)
+    Default memory location for WD/SMC cards.
+
+Old base driver for Tulip clones
+  --enable-otulip
+
+Realtek 8139
+SMC 1211
+D-Link DFE530TX+ and DFE538TX
+  --enable-rtl8139
+
+SIS 900 and SIS 7016
+  --enable-sis900
+
+Schneider and Koch G16
+  --enable-sk-g16
+
+SMC9000
+  --enable-smc9000
+  --enable-smc9000-scan=LIST
+    List of I/O addresses to probe.
+
+Tiara, Fujitsu Lancard
+  --enable-tiara
+
+Linksys LNE100TX and other NICs using this Tulip clone chip
+Netgear FA310TX and other NICs using this Tulip clone chip
+Tulip clones based on the ADMtek Centaur-P
+Tulip clones based on the Macronix 987x5
+Tulip-Fast
+Tulip+
+Tulip 21142
+ASIX AX88140
+Intel Tulip
+Compex RL100-TX
+  --enable-tulip
+
+Rhine-I, e.g. D-Link DFE-530TX
+Rhine-II
+  --enable-via-rhine
+
+Winbond W89c840
+Compex RL100-ATX
+  --enable-w89c840
+
+
+The description about how to use the support can be found in the GRUB
+manual. Run "info grub" in the shell prompt.
diff --git a/netboot/cards.h b/netboot/cards.h
new file mode 100644
index 0000000..cf37050
--- /dev/null
+++ b/netboot/cards.h
@@ -0,0 +1,183 @@
+#ifndef	CARDS_H
+#define CARDS_H
+
+/*
+ * 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.
+ */
+
+#include "nic.h"
+
+/* OK, this is how the PCI support hack works:  if pci.h is included before
+ * this file is included, assume that the driver supports PCI.  This means that
+ * this file is usually included last.  */
+
+#ifdef	PCI_H
+#define PCI_ARG(x) ,x
+#else
+#define PCI_ARG(x)
+#endif
+
+#ifdef	INCLUDE_WD
+extern struct nic	*wd_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_3C503
+extern struct nic	*t503_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_VIA_RHINE
+extern struct nic	*rhine_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_NE
+extern struct nic	*ne_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_NS8390
+extern struct nic	*nepci_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_3C509
+extern struct nic	*t509_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_3C529
+extern struct nic	*t529_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_3C595
+extern struct nic	*t595_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_3C90X
+extern struct nic	*a3c90x_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_EEPRO
+extern struct nic	*eepro_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_EEPRO100
+extern struct nic	*eepro100_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_EPIC100
+extern struct nic	*epic100_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_OTULIP
+extern struct nic	*otulip_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_TULIP
+extern struct nic	*tulip_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_DAVICOM
+extern struct nic	*davicom_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_CS89X0
+extern struct nic	*cs89x0_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_LANCE
+extern struct nic	*lancepci_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_NE2100
+extern struct nic	*ne2100_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_NI6510
+extern struct nic	*ni6510_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_SK_G16
+extern struct nic	*SK_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_3C507
+extern struct nic	*t507_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_NI5010
+extern struct nic	*ni5010_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_NI5210
+extern struct nic	*ni5210_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_EXOS205
+extern struct nic	*exos205_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_SMC9000
+extern struct nic	*smc9000_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_TIARA
+extern struct nic	*tiara_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_DEPCA
+extern struct nic	*depca_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_RTL8139
+extern struct nic	*rtl8139_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_W89C840
+extern struct nic	*w89c840_probe(struct nic *, unsigned short *
+	PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_SIS900
+extern struct nic	*sis900_probe(struct nic *, unsigned short *
+        PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_NATSEMI
+extern struct nic	*natsemi_probe(struct nic *, unsigned short *
+        PCI_ARG(struct pci_device *));
+#endif
+
+#ifdef	INCLUDE_TLAN
+extern struct nic	*tlan_probe(struct nic *, unsigned short *
+        PCI_ARG(struct pci_device *));
+#endif
+
+#endif	/* CARDS_H */
diff --git a/netboot/config.c b/netboot/config.c
new file mode 100644
index 0000000..3949a67
--- /dev/null
+++ b/netboot/config.c
@@ -0,0 +1,598 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2001,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.
+ */
+
+/* Based on "src/config.c" in etherboot-5.0.5.  */
+
+/*
+ * 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.
+ */
+
+#define GRUB	1
+#include <etherboot.h>
+#include <nic.h>
+
+#undef	INCLUDE_PCI
+#if	defined(INCLUDE_NS8390) || defined(INCLUDE_EEPRO100) || defined(INCLUDE_LANCE) || defined(INCLUDE_EPIC100) || defined(INCLUDE_TULIP) || defined(INCLUDE_OTULIP) || defined(INCLUDE_3C90X) ||  defined(INCLUDE_3C595) || defined(INCLUDE_RTL8139) || defined(INCLUDE_VIA_RHINE) || defined(INCLUDE_W89C840) || defined(INCLUDE_DAVICOM) || defined(INCLUDE_SIS900) || defined(INCLUDE_NATSEMI) || defined(INCLUDE_TLAN)
+	/* || others later */
+# define INCLUDE_PCI
+# include <pci.h>
+static unsigned short pci_ioaddrs[16];
+
+static struct pci_device pci_nic_list[] =
+{
+#ifdef	INCLUDE_NS8390
+  { PCI_VENDOR_ID_REALTEK,	PCI_DEVICE_ID_REALTEK_8029,
+    "Realtek 8029", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_WINBOND2,	PCI_DEVICE_ID_WINBOND2_89C940,
+    "Winbond NE2000-PCI", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_COMPEX,	PCI_DEVICE_ID_COMPEX_RL2000,
+    "Compex ReadyLink 2000", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_KTI,		PCI_DEVICE_ID_KTI_ET32P2,
+    "KTI ET32P2", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_NETVIN,	PCI_DEVICE_ID_NETVIN_NV5000SC,
+    "NetVin NV5000SC", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_HOLTEK,	PCI_DEVICE_ID_HOLTEK_HT80232,
+    "Holtek HT80232", 0, 0, 0, 0},
+#endif
+#ifdef	INCLUDE_3C90X
+  { PCI_VENDOR_ID_3COM,		PCI_DEVICE_ID_3COM_3C900TPO,
+    "3Com900-TPO", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		PCI_DEVICE_ID_3COM_3C900COMBO,
+    "3Com900-Combo", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		PCI_DEVICE_ID_3COM_3C905TX,
+    "3Com905-TX", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		PCI_DEVICE_ID_3COM_3C905T4,
+    "3Com905-T4", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		0x9004,
+    "3Com900B-TPO", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		0x9005,
+    "3Com900B-Combo", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		0x9006,
+    "3Com900B-2/T", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		0x900A,
+    "3Com900B-FL", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		PCI_DEVICE_ID_3COM_3C905B_TX,
+    "3Com905B-TX", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		0x9056,
+    "3Com905B-T4", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		0x905A,
+    "3Com905B-FL", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		PCI_DEVICE_ID_3COM_3C905C_TXM,
+    "3Com905C-TXM", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		0x9800,
+    "3Com980-Cyclone", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		0x9805,
+    "3Com9805", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		0x7646,
+    "3CSOHO100-TX", 0, 0, 0, 0},
+#endif
+#ifdef	INCLUDE_3C595
+  { PCI_VENDOR_ID_3COM,		PCI_DEVICE_ID_3COM_3C590,
+    "3Com590", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		PCI_DEVICE_ID_3COM_3C595,
+    "3Com595", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		PCI_DEVICE_ID_3COM_3C595_1,
+    "3Com595", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		PCI_DEVICE_ID_3COM_3C595_2,
+    "3Com595", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		PCI_DEVICE_ID_3COM_3C900TPO,
+    "3Com900-TPO", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		PCI_DEVICE_ID_3COM_3C900COMBO,
+    "3Com900-Combo", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		0x9004,
+    "3Com900B-TPO", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		0x9005,
+    "3Com900B-Combo", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		0x9006,
+    "3Com900B-2/T", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		0x900A,
+    "3Com900B-FL", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		0x9800,
+    "3Com980-Cyclone", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		0x9805,
+    "3Com9805", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_3COM,		0x7646,
+    "3CSOHO100-TX", 0, 0, 0, 0},
+#endif
+#ifdef	INCLUDE_EEPRO100
+  { PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82557,
+    "Intel EtherExpressPro100", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82559ER,
+    "Intel EtherExpressPro100 82559ER", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ID1029,
+    "Intel EtherExpressPro100 ID1029", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_ID1030,
+    "Intel Corporation 82559 InBusiness 10/100", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_INTEL,	PCI_DEVICE_ID_INTEL_82562,
+    "Intel EtherExpressPro100 82562EM", 0, 0, 0, 0},
+#endif
+#ifdef	INCLUDE_EPIC100
+  { PCI_VENDOR_ID_SMC,		PCI_DEVICE_ID_SMC_EPIC100,
+    "SMC EtherPowerII", 0, 0, 0, 0},
+#endif
+#ifdef	INCLUDE_LANCE
+  { PCI_VENDOR_ID_AMD,		PCI_DEVICE_ID_AMD_LANCE,
+    "AMD Lance/PCI", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_AMD_HOMEPNA,	PCI_DEVICE_ID_AMD_HOMEPNA,
+    "AMD Lance/HomePNA", 0, 0, 0, 0},
+#endif
+#ifdef	INCLUDE_RTL8139
+  { PCI_VENDOR_ID_REALTEK,	PCI_DEVICE_ID_REALTEK_8139,
+    "Realtek 8139", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_DLINK,	PCI_DEVICE_ID_DFE530TXP,
+    "DFE530TX+/DFE538TX", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_SMC_1211,	PCI_DEVICE_ID_SMC_1211,
+    "SMC EZ10/100", 0, 0, 0, 0},
+#endif
+#ifdef	INCLUDE_OTULIP
+  { PCI_VENDOR_ID_DEC,		PCI_DEVICE_ID_DEC_TULIP,
+    "Digital Tulip", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_DEC,		PCI_DEVICE_ID_DEC_TULIP_FAST,
+    "Digital Tulip Fast", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_DEC,		PCI_DEVICE_ID_DEC_TULIP_PLUS,
+    "Digital Tulip+", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_DEC,		PCI_DEVICE_ID_DEC_21142,
+    "Digital Tulip 21142", 0, 0, 0, 0},
+#endif
+#ifdef	INCLUDE_TULIP
+  { PCI_VENDOR_ID_DEC,		PCI_DEVICE_ID_DEC_TULIP,
+    "Digital Tulip", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_DEC,		PCI_DEVICE_ID_DEC_TULIP_FAST,
+    "Digital Tulip Fast", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_DEC,		PCI_DEVICE_ID_DEC_TULIP_PLUS,
+    "Digital Tulip+", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_DEC,		PCI_DEVICE_ID_DEC_21142,
+    "Digital Tulip 21142", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_MACRONIX,	PCI_DEVICE_ID_MX987x5,
+    "Macronix MX987x5", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_LINKSYS,	PCI_DEVICE_ID_LC82C115,
+    "LinkSys LNE100TX", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_LINKSYS,	PCI_DEVICE_ID_DEC_TULIP,
+    "Netgear FA310TX", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_DAVICOM,	PCI_DEVICE_ID_DM9102,
+    "Davicom 9102", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_DAVICOM,	PCI_DEVICE_ID_DM9009,
+    "Davicom 9009", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_ADMTEK,	PCI_DEVICE_ID_ADMTEK_0985,
+    "ADMtek Centaur-P", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_ADMTEK,	0x0981,
+    "ADMtek AN981 Comet", 0, 0, 0, 0},
+  { 0x125B,			0x1400,
+    "ASIX AX88140", 0, 0, 0, 0 },
+  { 0x11F6,			0x9881,
+    "Compex RL100-TX", 0, 0, 0, 0 },
+#endif
+#ifdef	INCLUDE_DAVICOM
+  { PCI_VENDOR_ID_DAVICOM,	PCI_DEVICE_ID_DM9102,
+    "Davicom 9102", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_DAVICOM,	PCI_DEVICE_ID_DM9009,
+    "Davicom 9009", 0, 0, 0, 0},
+#endif
+#ifdef	INCLUDE_VIA_RHINE
+  { PCI_VENDOR_ID_VIATEC,	PCI_DEVICE_ID_VIA_VT6102,
+    "VIA 6102", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_VIATEC,	PCI_DEVICE_ID_VIA_RHINE_I,
+    "VIA 3043", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_VIATEC,	PCI_DEVICE_ID_VIA_86C100A,
+    "VIA 86C100A", 0, 0, 0, 0},
+#endif
+#ifdef	INCLUDE_W89C840
+  { PCI_VENDOR_ID_WINBOND2,	PCI_DEVICE_ID_WINBOND2_89C840,
+    "Winbond W89C840F", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_COMPEX,	PCI_DEVICE_ID_COMPEX_RL100ATX,
+    "Compex RL100ATX", 0, 0, 0, 0},
+#endif
+#ifdef INCLUDE_SIS900
+  { PCI_VENDOR_ID_SIS,     	PCI_DEVICE_ID_SIS900,
+    "SIS900", 0, 0, 0, 0},
+  { PCI_VENDOR_ID_SIS,     	PCI_DEVICE_ID_SIS7016,
+    "SIS7016", 0, 0, 0, 0},
+#endif
+  
+#ifdef INCLUDE_NATSEMI
+  { PCI_VENDOR_ID_NS,	     	PCI_DEVICE_ID_DP83815,
+    "DP83815", 0, 0, 0, 0},
+#endif
+  
+#ifdef INCLUDE_TLAN
+  { PCI_VENDOR_ID_OLICOM,	PCI_DEVICE_ID_OLICOM_OC2326,
+    "OC2326", 0, 0, 0, 0},
+#endif
+
+  /* other PCI NICs go here */
+  {0, 0, NULL, 0, 0, 0, 0}
+};
+#endif	/* INCLUDE_*PCI */
+
+#include <cards.h>
+
+#ifdef INCLUDE_PCI
+struct pci_dispatch_table
+{
+  unsigned short vendor;
+  unsigned short dev_id;
+  struct nic *(*eth_probe) (struct nic *, unsigned short *,
+			    struct pci_device *);
+};
+
+static struct pci_dispatch_table PCI_NIC[] =
+{
+# ifdef INCLUDE_NS8390
+  { PCI_VENDOR_ID_REALTEK,  PCI_DEVICE_ID_REALTEK_8029,    nepci_probe },
+  { PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940, nepci_probe },
+  { PCI_VENDOR_ID_COMPEX,   PCI_DEVICE_ID_COMPEX_RL2000,   nepci_probe },
+  { PCI_VENDOR_ID_KTI,      PCI_DEVICE_ID_KTI_ET32P2,      nepci_probe },
+  { PCI_VENDOR_ID_NETVIN,   PCI_DEVICE_ID_NETVIN_NV5000SC, nepci_probe },
+  { PCI_VENDOR_ID_HOLTEK,   PCI_DEVICE_ID_HOLTEK_HT80232,  nepci_probe },
+# endif /* INCLUDE_NS8390 */
+# ifdef INCLUDE_3C90X
+  { PCI_VENDOR_ID_3COM,	    PCI_DEVICE_ID_3COM_3C900TPO,   a3c90x_probe },
+  { PCI_VENDOR_ID_3COM,     PCI_DEVICE_ID_3COM_3C900COMBO, a3c90x_probe },
+  { PCI_VENDOR_ID_3COM,     PCI_DEVICE_ID_3COM_3C905TX,    a3c90x_probe },
+  { PCI_VENDOR_ID_3COM,     PCI_DEVICE_ID_3COM_3C905T4,    a3c90x_probe },
+  { PCI_VENDOR_ID_3COM,     0x9004,                        a3c90x_probe },
+  { PCI_VENDOR_ID_3COM,     0x9005,                        a3c90x_probe },
+  { PCI_VENDOR_ID_3COM,     0x9006,                        a3c90x_probe },
+  { PCI_VENDOR_ID_3COM,     0x900A,                        a3c90x_probe },
+  { PCI_VENDOR_ID_3COM,     PCI_DEVICE_ID_3COM_3C905B_TX,  a3c90x_probe },
+  { PCI_VENDOR_ID_3COM,     0x9056,                        a3c90x_probe },
+  { PCI_VENDOR_ID_3COM,     0x905A,                        a3c90x_probe },
+  { PCI_VENDOR_ID_3COM,     PCI_DEVICE_ID_3COM_3C905C_TXM, a3c90x_probe },
+  { PCI_VENDOR_ID_3COM,     0x9800,                        a3c90x_probe },
+  { PCI_VENDOR_ID_3COM,     0x9805,                        a3c90x_probe },
+  { PCI_VENDOR_ID_3COM,     0x7646,                        a3c90x_probe },
+# endif /* INCLUDE_3C90X */
+# ifdef	INCLUDE_3C595
+  { PCI_VENDOR_ID_3COM,     PCI_DEVICE_ID_3COM_3C590,      t595_probe },
+  { PCI_VENDOR_ID_3COM,     PCI_DEVICE_ID_3COM_3C595,      t595_probe },
+  { PCI_VENDOR_ID_3COM,     PCI_DEVICE_ID_3COM_3C595_1,    t595_probe },
+  { PCI_VENDOR_ID_3COM,     PCI_DEVICE_ID_3COM_3C595_2,    t595_probe },
+  { PCI_VENDOR_ID_3COM,     PCI_DEVICE_ID_3COM_3C900TPO,   t595_probe },
+  { PCI_VENDOR_ID_3COM,     PCI_DEVICE_ID_3COM_3C900COMBO, t595_probe },
+  { PCI_VENDOR_ID_3COM,     0x9004,                        t595_probe },
+  { PCI_VENDOR_ID_3COM,     0x9005,                        t595_probe },
+  { PCI_VENDOR_ID_3COM,     0x9006,                        t595_probe },
+  { PCI_VENDOR_ID_3COM,     0x900A,                        t595_probe },
+  { PCI_VENDOR_ID_3COM,     0x9800,                        t595_probe },
+  { PCI_VENDOR_ID_3COM,     0x9805,                        t595_probe },
+  { PCI_VENDOR_ID_3COM,     0x7646,                        t595_probe },
+# endif /* INCLUDE_3C595 */
+# ifdef	INCLUDE_EEPRO100
+  { PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82557,     eepro100_probe },
+  { PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82559ER,   eepro100_probe },
+  { PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_ID1029,    eepro100_probe },
+  { PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_ID1030,    eepro100_probe },
+  { PCI_VENDOR_ID_INTEL,    PCI_DEVICE_ID_INTEL_82562,     eepro100_probe },
+# endif /* INCLUDE_EEPRO100 */
+# ifdef	INCLUDE_EPIC100
+  { PCI_VENDOR_ID_SMC,      PCI_DEVICE_ID_SMC_EPIC100,     epic100_probe },
+# endif /* INCLUDE_EPIC100 */
+# ifdef	INCLUDE_LANCE
+  { PCI_VENDOR_ID_AMD,      PCI_DEVICE_ID_AMD_LANCE,       lancepci_probe },
+  { PCI_VENDOR_ID_AMD_HOMEPNA, PCI_DEVICE_ID_AMD_HOMEPNA,  lancepci_probe },
+# endif /* INCLUDE_LANCE */
+# ifdef	INCLUDE_RTL8139
+  { PCI_VENDOR_ID_REALTEK,  PCI_DEVICE_ID_REALTEK_8139,    rtl8139_probe },
+  { PCI_VENDOR_ID_DLINK,    PCI_DEVICE_ID_DFE530TXP,       rtl8139_probe },
+  { PCI_VENDOR_ID_SMC_1211, PCI_DEVICE_ID_SMC_1211,        rtl8139_probe },
+# endif /* INCLUDE_RTL8139 */
+# ifdef	INCLUDE_OTULIP
+  { PCI_VENDOR_ID_DEC,      PCI_DEVICE_ID_DEC_TULIP,       otulip_probe },
+  { PCI_VENDOR_ID_DEC,      PCI_DEVICE_ID_DEC_TULIP_FAST,  otulip_probe },
+  { PCI_VENDOR_ID_DEC,      PCI_DEVICE_ID_DEC_TULIP_PLUS,  otulip_probe },
+  { PCI_VENDOR_ID_DEC,      PCI_DEVICE_ID_DEC_21142,       otulip_probe },
+# endif /* INCLUDE_OTULIP */
+# ifdef	INCLUDE_TULIP
+  { PCI_VENDOR_ID_DEC,      PCI_DEVICE_ID_DEC_TULIP,       tulip_probe },
+  { PCI_VENDOR_ID_DEC,      PCI_DEVICE_ID_DEC_TULIP_FAST,  tulip_probe },
+  { PCI_VENDOR_ID_DEC,      PCI_DEVICE_ID_DEC_TULIP_PLUS,  tulip_probe },
+  { PCI_VENDOR_ID_DEC,      PCI_DEVICE_ID_DEC_21142,       tulip_probe },
+  { PCI_VENDOR_ID_MACRONIX, PCI_DEVICE_ID_MX987x5,         tulip_probe },
+  { PCI_VENDOR_ID_LINKSYS,  PCI_DEVICE_ID_LC82C115,        tulip_probe },
+  { PCI_VENDOR_ID_LINKSYS,  PCI_DEVICE_ID_DEC_TULIP,       tulip_probe },
+  { PCI_VENDOR_ID_DAVICOM,  PCI_DEVICE_ID_DM9102,          tulip_probe },
+  { PCI_VENDOR_ID_DAVICOM,  PCI_DEVICE_ID_DM9009,          tulip_probe },
+  { PCI_VENDOR_ID_ADMTEK,   PCI_DEVICE_ID_ADMTEK_0985,     tulip_probe },
+  { PCI_VENDOR_ID_ADMTEK,   0x0981,                        tulip_probe },
+  { 0x125B,                 0x1400,                        tulip_probe },
+  { 0x11F6,                 0x9881,                        tulip_probe },
+# endif /* INCLUDE_TULIP */
+# ifdef INCLUDE_DAVICOM
+  { PCI_VENDOR_ID_DAVICOM,   PCI_DEVICE_ID_DM9102,           davicom_probe },
+  { PCI_VENDOR_ID_DAVICOM,   PCI_DEVICE_ID_DM9009,           davicom_probe },
+# endif /* INCLUDE_DAVICOM */
+# ifdef	INCLUDE_VIA_RHINE
+  { PCI_VENDOR_ID_VIATEC,   PCI_DEVICE_ID_VIA_VT6102,      rhine_probe },
+  { PCI_VENDOR_ID_VIATEC,   PCI_DEVICE_ID_VIA_RHINE_I,     rhine_probe },
+  { PCI_VENDOR_ID_VIATEC,   PCI_DEVICE_ID_VIA_86C100A,     rhine_probe },
+# endif /* INCLUDE_VIA_RHINE */
+# ifdef INCLUDE_W89C840
+  { PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C840, w89c840_probe },
+  { PCI_VENDOR_ID_COMPEX,   PCI_DEVICE_ID_COMPEX_RL100ATX, w89c840_probe },
+# endif /* INCLUDE_W89C840 */
+# ifdef INCLUDE_SIS900
+  { PCI_VENDOR_ID_SIS,      PCI_DEVICE_ID_SIS900,          sis900_probe },
+  { PCI_VENDOR_ID_SIS,      PCI_DEVICE_ID_SIS7016,         sis900_probe },
+# endif /* INCLUDE_SIS900 */
+# ifdef INCLUDE_NATSEMI
+  { PCI_VENDOR_ID_NS,       PCI_DEVICE_ID_DP83815,         natsemi_probe },
+# endif /* INCLUDE_NATSEMI */
+# ifdef INCLUDE_TLAN
+  { PCI_VENDOR_ID_OLICOM,   PCI_DEVICE_ID_OLICOM_OC2326,   tlan_probe },
+# endif /* INCLUDE_TLAN */
+  { 0,                      0,                             0 }
+};
+#endif /* GRUB && INCLUDE_PCI */
+
+struct dispatch_table
+{
+  const char	*nic_name;
+#ifdef	INCLUDE_PCI
+  struct nic	*(*eth_probe) (struct nic *, unsigned short *,
+			       struct pci_device *);
+#else
+  struct nic	*(*eth_probe) (struct nic *, unsigned short *);
+#endif	/* INCLUDE_PCI */
+  unsigned short	*probe_ioaddrs;		/* for probe overrides */
+};
+
+/*
+ *	NIC probing is in order of appearance in this table.
+ *	If for some reason you want to change the order,
+ *	just rearrange the entries (bracketed by the #ifdef/#endif)
+ */
+static struct dispatch_table	NIC[] =
+{
+#ifdef	INCLUDE_RTL8139
+  { "RTL8139", rtl8139_probe, pci_ioaddrs },
+#endif
+#ifdef INCLUDE_SIS900
+  { "SIS900", sis900_probe, pci_ioaddrs },	
+#endif
+#ifdef INCLUDE_NATSEMI
+  { "NATSEMI", natsemi_probe, pci_ioaddrs },	
+#endif
+#ifdef	INCLUDE_WD
+  { "WD", wd_probe, 0 },
+#endif
+#ifdef	INCLUDE_3C503
+  { "3C503", t503_probe, 0 },
+#endif
+#ifdef	INCLUDE_NE
+  { "NE*000", ne_probe, 0 },
+#endif
+#ifdef	INCLUDE_3C509
+  { "3C5x9", t509_probe, 0 },
+#endif
+#ifdef	INCLUDE_3C529
+  { "3C5x9", t529_probe, 0 },
+#endif
+#ifdef	INCLUDE_3C595
+  { "3C595", t595_probe, pci_ioaddrs },
+#endif
+#ifdef	INCLUDE_3C90X
+  { "3C90X", a3c90x_probe, pci_ioaddrs },
+#endif
+#ifdef	INCLUDE_EEPRO
+  { "EEPRO", eepro_probe, 0 },
+#endif
+#ifdef	INCLUDE_EEPRO100
+  { "EEPRO100", eepro100_probe, pci_ioaddrs },
+#endif
+#ifdef	INCLUDE_EPIC100
+  { "EPIC100", epic100_probe, pci_ioaddrs },
+#endif
+#ifdef	INCLUDE_OTULIP
+  { "OTulip", otulip_probe, pci_ioaddrs },
+#endif
+#ifdef	INCLUDE_TULIP
+  { "Tulip", tulip_probe, pci_ioaddrs },
+#endif
+#ifdef	INCLUDE_DAVICOM
+  { "DAVICOM", davicom_probe, pci_ioaddrs },
+#endif
+#ifdef	INCLUDE_CS89X0
+  { "CS89x0", cs89x0_probe, 0 },
+#endif
+#ifdef	INCLUDE_NE2100
+  { "NE2100", ne2100_probe, 0 },
+#endif
+#ifdef	INCLUDE_NI6510
+  { "NI6510", ni6510_probe, 0 },
+#endif
+#ifdef	INCLUDE_SK_G16
+  { "SK_G16", SK_probe, 0 },
+#endif
+#ifdef	INCLUDE_3C507
+  { "3C507", t507_probe, 0 },
+#endif
+#ifdef	INCLUDE_NI5010
+  { "NI5010", ni5010_probe, 0 },
+#endif
+#ifdef	INCLUDE_NI5210
+  { "NI5210", ni5210_probe, 0 },
+#endif
+#ifdef	INCLUDE_EXOS205
+  { "EXOS205", exos205_probe, 0 },
+#endif
+#ifdef	INCLUDE_SMC9000
+  { "SMC9000", smc9000_probe, 0 },
+#endif
+#ifdef	INCLUDE_TIARA
+  { "TIARA", tiara_probe, 0 },
+#endif
+#ifdef	INCLUDE_DEPCA
+  { "DEPCA", depca_probe, 0 },
+#endif
+#ifdef	INCLUDE_NS8390
+  { "NE2000/PCI", nepci_probe, pci_ioaddrs },
+#endif
+#ifdef	INCLUDE_LANCE
+  { "LANCE/PCI", lancepci_probe, pci_ioaddrs },
+#endif
+#ifdef	INCLUDE_VIA_RHINE
+  { "VIA 86C100", rhine_probe, pci_ioaddrs },
+#endif
+#ifdef	INCLUDE_W89C840
+  { "W89C840F", w89c840_probe, pci_ioaddrs },
+#endif
+#ifdef	INCLUDE_TLAN
+  { "Olicom 2326", tlan_probe, pci_ioaddrs },
+#endif
+  /* this entry must always be last to mark the end of list */
+  { 0, 0, 0 }
+};
+
+#define	NIC_TABLE_SIZE	(sizeof (NIC) / sizeof (NIC[0]))
+
+static int
+eth_dummy (struct nic *dummy)
+{
+  return 0;
+}
+
+static char	packet[ETH_FRAME_LEN];
+
+struct nic	nic =
+{
+  (void (*) (struct nic *)) eth_dummy,	/* reset */
+  eth_dummy,				/* poll */
+  (void (*) (struct nic *, const char *,
+	     unsigned int, unsigned int,
+	     const char *)) eth_dummy,	/* transmit */
+  (void (*) (struct nic *)) eth_dummy,	/* disable */
+#ifdef	T503_AUI
+  1,					/* aui */
+#else
+  0,					/* no aui */
+#endif
+  &rom,					/* rom_info */
+  arptable[ARP_CLIENT].node,		/* node_addr */
+  packet,				/* packet */
+  0,				/* packetlen */
+  0,				/* priv_data */
+};
+
+void
+eth_reset (void)
+{
+  (*nic.reset) (&nic);
+}
+
+int
+eth_probe (void)
+{
+  struct pci_device	*p;
+  const struct dispatch_table	*t;
+  static int probed = 0;
+
+  /* If already probed, don't try to probe it any longer.  */
+  if (probed)
+    return 1;
+  
+  /* Clear the ready flag.  */
+  network_ready = 0;
+  /* Clear the ARP table.  */
+  grub_memset ((char *) arptable, 0,
+	       MAX_ARP * sizeof (struct arptable_t));
+  
+  p = 0;
+  
+#ifdef	INCLUDE_PCI
+  /* In GRUB, the ROM info is initialized here.  */
+  rom = *((struct rom_info *) ROM_INFO_LOCATION);
+  
+  eth_pci_init(pci_nic_list);
+  pci_ioaddrs[0] = 0;
+  pci_ioaddrs[1] = 0;
+  /* at this point we have a list of possible PCI candidates
+     we just pick the first one with a non-zero ioaddr */
+  for (p = pci_nic_list; p->vendor != 0; ++p)
+    {
+      if (p->ioaddr != 0)
+	{
+	  pci_ioaddrs[0] = p->ioaddr;
+	  break;
+	}
+    }
+#endif
+  
+  etherboot_printf("Probing...");
+	
+#ifdef INCLUDE_PCI
+  if (p->vendor)
+    {
+      struct pci_dispatch_table *pt;
+      
+      for (pt = PCI_NIC; pt->eth_probe != 0; pt++)
+	if (p->vendor == pt->vendor && p->dev_id == pt->dev_id)
+	  {
+	    etherboot_printf ("[%s]", p->name);
+	    if ((pt->eth_probe) (&nic, pci_ioaddrs, p))
+	      {
+		probed = 1;
+		return 1;
+	      }
+	  }
+    }
+#endif /* INCLUDE_PCI */
+	
+  for (t = NIC; t->nic_name != 0; ++t)
+    {
+      etherboot_printf("[%s]", t->nic_name);
+#ifdef	INCLUDE_PCI
+      if ((*t->eth_probe) (&nic, t->probe_ioaddrs, p))
+	{
+	  probed = 1;
+	  return 1;
+	}
+#else
+      if ((*t->eth_probe) (&nic, t->probe_ioaddrs))
+	{
+	  probed = 1;
+	  return 1;
+	}
+#endif	/* INCLUDE_PCI */
+    }
+  
+  return 0;
+}
+
+int
+eth_poll (void)
+{
+  return ((*nic.poll) (&nic));
+}
+
+void
+eth_transmit (const char *d, unsigned int t, unsigned int s, const void *p)
+{
+  (*nic.transmit) (&nic, d, t, s, p);
+  if (t == IP)
+    twiddle ();
+}
+
+void
+eth_disable (void)
+{
+  (*nic.disable) (&nic);
+}
diff --git a/netboot/cs89x0.c b/netboot/cs89x0.c
new file mode 100644
index 0000000..9f96481
--- /dev/null
+++ b/netboot/cs89x0.c
@@ -0,0 +1,659 @@
+/* cs89x0.c: A Crystal Semiconductor CS89[02]0 driver for etherboot. */
+/*
+  Permission is granted to distribute the enclosed cs89x0.[ch] driver
+  only in conjunction with the Etherboot package.  The code is
+  ordinarily distributed under the GPL.
+  
+  Russ Nelson, January 2000
+
+  ChangeLog:
+
+  Thu Dec 6 22:40:00 1996  Markus Gutschke  <gutschk@math.uni-muenster.de>
+
+  * disabled all "advanced" features; this should make the code more reliable
+
+  * reorganized the reset function
+
+  * always reset the address port, so that autoprobing will continue working
+
+  * some cosmetic changes
+
+  * 2.5
+
+  Thu Dec 5 21:00:00 1996  Markus Gutschke  <gutschk@math.uni-muenster.de>
+
+  * tested the code against a CS8900 card
+
+  * lots of minor bug fixes and adjustments
+
+  * this is the first release, that actually works! it still requires some
+    changes in order to be more tolerant to different environments
+
+  * 4
+
+  Fri Nov 22 23:00:00 1996  Markus Gutschke  <gutschk@math.uni-muenster.de>
+
+  * read the manuals for the CS89x0 chipsets and took note of all the
+    changes that will be neccessary in order to adapt Russel Nelson's code
+    to the requirements of a BOOT-Prom
+
+  * 6
+
+  Thu Nov 19 22:00:00 1996  Markus Gutschke  <gutschk@math.uni-muenster.de>
+
+  * Synched with Russel Nelson's current code (v1.00)
+
+  * 2
+
+  Thu Nov 12 18:00:00 1996  Markus Gutschke  <gutschk@math.uni-muenster.de>
+
+  * Cleaned up some of the code and tried to optimize the code size.
+
+  * 1.5
+
+  Sun Nov 10 16:30:00 1996  Markus Gutschke  <gutschk@math.uni-muenster.de>
+
+  * First experimental release. This code compiles fine, but I
+  have no way of testing whether it actually works.
+
+  * I did not (yet) bother to make the code 16bit aware, so for
+  the time being, it will only work for Etherboot/32.
+
+  * 12
+
+  */
+
+#include "etherboot.h"
+#include "nic.h"
+#include "cards.h"
+#include "cs89x0.h"
+
+static unsigned short	eth_nic_base;
+static unsigned long    eth_mem_start;
+static unsigned short   eth_irq;
+static unsigned short   eth_cs_type;	/* one of: CS8900, CS8920, CS8920M  */
+static unsigned short   eth_auto_neg_cnf;
+static unsigned short   eth_adapter_cnf;
+static unsigned short	eth_linectl;
+
+/*************************************************************************
+	CS89x0 - specific routines
+**************************************************************************/
+
+static inline int readreg(int portno)
+{
+	outw(portno, eth_nic_base + ADD_PORT);
+	return inw(eth_nic_base + DATA_PORT);
+}
+
+static inline void writereg(int portno, int value)
+{
+	outw(portno, eth_nic_base + ADD_PORT);
+	outw(value, eth_nic_base + DATA_PORT);
+	return;
+}
+
+/*************************************************************************
+EEPROM access
+**************************************************************************/
+
+static int wait_eeprom_ready(void)
+{
+	unsigned long tmo = currticks() + 4*TICKS_PER_SEC;
+
+	/* check to see if the EEPROM is ready, a timeout is used -
+	   just in case EEPROM is ready when SI_BUSY in the
+	   PP_SelfST is clear */
+	while(readreg(PP_SelfST) & SI_BUSY) {
+		if (currticks() >= tmo)
+			return -1; }
+	return 0;
+}
+
+static int get_eeprom_data(int off, int len, unsigned short *buffer)
+{
+	int i;
+
+#ifdef	EDEBUG
+	printf("\ncs: EEPROM data from %hX for %hX:",off,len);
+#endif
+	for (i = 0; i < len; i++) {
+		if (wait_eeprom_ready() < 0)
+			return -1;
+		/* Now send the EEPROM read command and EEPROM location
+		   to read */
+		writereg(PP_EECMD, (off + i) | EEPROM_READ_CMD);
+		if (wait_eeprom_ready() < 0)
+			return -1;
+		buffer[i] = readreg(PP_EEData);
+#ifdef	EDEBUG
+		if (!(i%10))
+			printf("\ncs: ");
+		printf("%hX ", buffer[i]);
+#endif
+	}
+#ifdef	EDEBUG
+	putchar('\n');
+#endif
+
+	return(0);
+}
+
+static int get_eeprom_chksum(int off, int len, unsigned short *buffer)
+{
+	int  i, cksum;
+
+	cksum = 0;
+	for (i = 0; i < len; i++)
+		cksum += buffer[i];
+	cksum &= 0xffff;
+	if (cksum == 0)
+		return 0;
+	return -1;
+}
+
+/*************************************************************************
+Activate all of the available media and probe for network
+**************************************************************************/
+
+static void clrline(void)
+{
+	int i;
+
+	putchar('\r');
+	for (i = 79; i--; ) putchar(' ');
+	printf("\rcs: ");
+	return;
+}
+
+static void control_dc_dc(int on_not_off)
+{
+	unsigned int selfcontrol;
+	unsigned long tmo = currticks() + TICKS_PER_SEC;
+
+	/* control the DC to DC convertor in the SelfControl register.  */
+	selfcontrol = HCB1_ENBL; /* Enable the HCB1 bit as an output */
+	if (((eth_adapter_cnf & A_CNF_DC_DC_POLARITY) != 0) ^ on_not_off)
+		selfcontrol |= HCB1;
+	else
+		selfcontrol &= ~HCB1;
+	writereg(PP_SelfCTL, selfcontrol);
+
+	/* Wait for the DC/DC converter to power up - 1000ms */
+	while (currticks() < tmo);
+
+	return;
+}
+
+static int detect_tp(void)
+{
+	unsigned long tmo;
+
+	/* Turn on the chip auto detection of 10BT/ AUI */
+
+	clrline(); printf("attempting %s:","TP");
+
+        /* If connected to another full duplex capable 10-Base-T card
+	   the link pulses seem to be lost when the auto detect bit in
+	   the LineCTL is set.  To overcome this the auto detect bit
+	   will be cleared whilst testing the 10-Base-T interface.
+	   This would not be necessary for the sparrow chip but is
+	   simpler to do it anyway. */
+	writereg(PP_LineCTL, eth_linectl &~ AUI_ONLY);
+	control_dc_dc(0);
+
+        /* Delay for the hardware to work out if the TP cable is
+	   present - 150ms */
+	for (tmo = currticks() + 4; currticks() < tmo; );
+
+	if ((readreg(PP_LineST) & LINK_OK) == 0)
+		return 0;
+
+	if (eth_cs_type != CS8900) {
+
+		writereg(PP_AutoNegCTL, eth_auto_neg_cnf & AUTO_NEG_MASK);
+
+		if ((eth_auto_neg_cnf & AUTO_NEG_BITS) == AUTO_NEG_ENABLE) {
+			printf(" negotiating duplex... ");
+			while (readreg(PP_AutoNegST) & AUTO_NEG_BUSY) {
+				if (currticks() - tmo > 40*TICKS_PER_SEC) {
+					printf("time out ");
+					break;
+				}
+			}
+		}
+		if (readreg(PP_AutoNegST) & FDX_ACTIVE)
+			printf("using full duplex");
+		else
+			printf("using half duplex");
+	}
+
+	return A_CNF_MEDIA_10B_T;
+}
+
+/* send a test packet - return true if carrier bits are ok */
+static int send_test_pkt(struct nic *nic)
+{
+	static unsigned char testpacket[] = { 0,0,0,0,0,0, 0,0,0,0,0,0,
+				     0, 46, /*A 46 in network order       */
+				     0, 0,  /*DSAP=0 & SSAP=0 fields      */
+				     0xf3,0 /*Control (Test Req+P bit set)*/ };
+	unsigned long tmo;
+
+	writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_TX_ON);
+
+	memcpy(testpacket, nic->node_addr, ETH_ALEN);
+	memcpy(testpacket+ETH_ALEN, nic->node_addr, ETH_ALEN);
+
+	outw(TX_AFTER_ALL, eth_nic_base + TX_CMD_PORT);
+	outw(ETH_ZLEN, eth_nic_base + TX_LEN_PORT);
+
+	/* Test to see if the chip has allocated memory for the packet */
+	for (tmo = currticks() + 2;
+	     (readreg(PP_BusST) & READY_FOR_TX_NOW) == 0; )
+		if (currticks() >= tmo)
+			return(0);
+
+	/* Write the contents of the packet */
+	outsw(eth_nic_base + TX_FRAME_PORT, testpacket,
+	      (ETH_ZLEN+1)>>1);
+
+	printf(" sending test packet ");
+	/* wait a couple of timer ticks for packet to be received */
+	for (tmo = currticks() + 2; currticks() < tmo; );
+
+	if ((readreg(PP_TxEvent) & TX_SEND_OK_BITS) == TX_OK) {
+			printf("succeeded");
+			return 1;
+	}
+	printf("failed");
+	return 0;
+}
+
+
+static int detect_aui(struct nic *nic)
+{
+	clrline(); printf("attempting %s:","AUI");
+	control_dc_dc(0);
+
+	writereg(PP_LineCTL, (eth_linectl & ~AUTO_AUI_10BASET) | AUI_ONLY);
+
+	if (send_test_pkt(nic)) {
+		return A_CNF_MEDIA_AUI; }
+	else
+		return 0;
+}
+
+static int detect_bnc(struct nic *nic)
+{
+	clrline(); printf("attempting %s:","BNC");
+	control_dc_dc(1);
+
+	writereg(PP_LineCTL, (eth_linectl & ~AUTO_AUI_10BASET) | AUI_ONLY);
+
+	if (send_test_pkt(nic)) {
+		return A_CNF_MEDIA_10B_2; }
+	else
+		return 0;
+}
+
+/**************************************************************************
+ETH_RESET - Reset adapter
+***************************************************************************/
+
+static void cs89x0_reset(struct nic *nic)
+{
+	int  i;
+	unsigned long reset_tmo;
+
+	writereg(PP_SelfCTL, readreg(PP_SelfCTL) | POWER_ON_RESET);
+
+	/* wait for two ticks; that is 2*55ms */
+	for (reset_tmo = currticks() + 2; currticks() < reset_tmo; );
+
+	if (eth_cs_type != CS8900) {
+		/* Hardware problem requires PNP registers to be reconfigured
+		   after a reset */
+		if (eth_irq != 0xFFFF) {
+			outw(PP_CS8920_ISAINT, eth_nic_base + ADD_PORT);
+			outb(eth_irq, eth_nic_base + DATA_PORT);
+			outb(0, eth_nic_base + DATA_PORT + 1); }
+
+		if (eth_mem_start) {
+			outw(PP_CS8920_ISAMemB, eth_nic_base + ADD_PORT);
+			outb((eth_mem_start >> 8) & 0xff, eth_nic_base + DATA_PORT);
+			outb((eth_mem_start >> 24) & 0xff, eth_nic_base + DATA_PORT + 1); } }
+
+	/* Wait until the chip is reset */
+	for (reset_tmo = currticks() + 2;
+	     (readreg(PP_SelfST) & INIT_DONE) == 0 &&
+		     currticks() < reset_tmo; );
+
+	/* disable interrupts and memory accesses */
+	writereg(PP_BusCTL, 0);
+
+	/* set the ethernet address */
+	for (i=0; i < ETH_ALEN/2; i++)
+		writereg(PP_IA+i*2,
+			 nic->node_addr[i*2] |
+			 (nic->node_addr[i*2+1] << 8));
+
+	/* receive only error free packets addressed to this card */
+	writereg(PP_RxCTL, DEF_RX_ACCEPT);
+
+	/* do not generate any interrupts on receive operations */
+	writereg(PP_RxCFG, 0);
+
+	/* do not generate any interrupts on transmit operations */
+	writereg(PP_TxCFG, 0);
+
+	/* do not generate any interrupts on buffer operations */
+	writereg(PP_BufCFG, 0);
+
+	/* reset address port, so that autoprobing will keep working */
+	outw(PP_ChipID, eth_nic_base + ADD_PORT);
+
+	return;
+}
+
+/**************************************************************************
+ETH_TRANSMIT - Transmit a frame
+***************************************************************************/
+
+static void cs89x0_transmit(
+	struct nic *nic,
+	const char *d,			/* Destination */
+	unsigned int t,			/* Type */
+	unsigned int s,			/* size */
+	const char *p)			/* Packet */
+{
+	unsigned long tmo;
+	int           sr;
+
+	/* does this size have to be rounded??? please,
+	   somebody have a look in the specs */
+	if ((sr = ((s + ETH_HLEN + 1)&~1)) < ETH_ZLEN)
+		sr = ETH_ZLEN;
+
+retry:
+	/* initiate a transmit sequence */
+	outw(TX_AFTER_ALL, eth_nic_base + TX_CMD_PORT);
+	outw(sr, eth_nic_base + TX_LEN_PORT);
+
+	/* Test to see if the chip has allocated memory for the packet */
+	if ((readreg(PP_BusST) & READY_FOR_TX_NOW) == 0) {
+		/* Oops... this should not happen! */
+		printf("cs: unable to send packet; retrying...\n");
+		for (tmo = currticks() + 5*TICKS_PER_SEC; currticks() < tmo; );
+		cs89x0_reset(nic);
+		goto retry; }
+
+	/* Write the contents of the packet */
+	outsw(eth_nic_base + TX_FRAME_PORT, d, ETH_ALEN/2);
+	outsw(eth_nic_base + TX_FRAME_PORT, nic->node_addr,
+	      ETH_ALEN/2);
+	outw(((t >> 8)&0xFF)|(t << 8), eth_nic_base + TX_FRAME_PORT);
+	outsw(eth_nic_base + TX_FRAME_PORT, p, (s+1)/2);
+	for (sr = sr/2 - (s+1)/2 - ETH_ALEN - 1; sr-- > 0;
+	     outw(0, eth_nic_base + TX_FRAME_PORT));
+
+	/* wait for transfer to succeed */
+	for (tmo = currticks()+5*TICKS_PER_SEC;
+	     (s = readreg(PP_TxEvent)&~0x1F) == 0 && currticks() < tmo;)
+		/* nothing */ ;
+	if ((s & TX_SEND_OK_BITS) != TX_OK) {
+		printf("\ntransmission error %#hX\n", s);
+	}
+
+	return;
+}
+
+/**************************************************************************
+ETH_POLL - Wait for a frame
+***************************************************************************/
+
+static int cs89x0_poll(struct nic *nic)
+{
+	int status;
+
+	status = readreg(PP_RxEvent);
+
+	if ((status & RX_OK) == 0)
+		return(0);
+
+	status = inw(eth_nic_base + RX_FRAME_PORT);
+	nic->packetlen = inw(eth_nic_base + RX_FRAME_PORT);
+	insw(eth_nic_base + RX_FRAME_PORT, nic->packet, nic->packetlen >> 1);
+	if (nic->packetlen & 1)
+		nic->packet[nic->packetlen-1] = inw(eth_nic_base + RX_FRAME_PORT);
+	return 1;
+}
+
+static void cs89x0_disable(struct nic *nic)
+{
+	cs89x0_reset(nic);
+}
+
+/**************************************************************************
+ETH_PROBE - Look for an adapter
+***************************************************************************/
+
+struct nic *cs89x0_probe(struct nic *nic, unsigned short *probe_addrs)
+{
+	static const unsigned int netcard_portlist[] = {
+#ifdef	CS_SCAN
+		CS_SCAN,
+#else	/* use "conservative" default values for autoprobing */
+		0x300,0x320,0x340,0x200,0x220,0x240,
+		0x260,0x280,0x2a0,0x2c0,0x2e0,
+	/* if that did not work, then be more aggressive */
+		0x301,0x321,0x341,0x201,0x221,0x241,
+		0x261,0x281,0x2a1,0x2c1,0x2e1,
+#endif
+		0};
+
+	int      i, result = -1;
+	unsigned rev_type = 0, ioaddr, ioidx, isa_cnf, cs_revision;
+	unsigned short eeprom_buff[CHKSUM_LEN];
+
+
+	for (ioidx = 0; (ioaddr=netcard_portlist[ioidx++]) != 0; ) {
+		/* if they give us an odd I/O address, then do ONE write to
+		   the address port, to get it back to address zero, where we
+		   expect to find the EISA signature word. */
+		if (ioaddr & 1) {
+			ioaddr &= ~1;
+			if ((inw(ioaddr + ADD_PORT) & ADD_MASK) != ADD_SIG)
+				continue;
+			outw(PP_ChipID, ioaddr + ADD_PORT);
+		}
+
+		if (inw(ioaddr + DATA_PORT) != CHIP_EISA_ID_SIG)
+			continue;
+		eth_nic_base = ioaddr;
+
+		/* get the chip type */
+		rev_type = readreg(PRODUCT_ID_ADD);
+		eth_cs_type = rev_type &~ REVISON_BITS;
+		cs_revision = ((rev_type & REVISON_BITS) >> 8) + 'A';
+
+		printf("\ncs: cs89%c0%s rev %c, base %#hX",
+		       eth_cs_type==CS8900?'0':'2',
+		       eth_cs_type==CS8920M?"M":"",
+		       cs_revision,
+		       eth_nic_base);
+
+		/* First check to see if an EEPROM is attached*/
+		if ((readreg(PP_SelfST) & EEPROM_PRESENT) == 0) {
+			printf("\ncs: no EEPROM...\n");
+			outw(PP_ChipID, eth_nic_base + ADD_PORT);
+			continue; }
+		else if (get_eeprom_data(START_EEPROM_DATA,CHKSUM_LEN,
+					 eeprom_buff) < 0) {
+			printf("\ncs: EEPROM read failed...\n");
+			outw(PP_ChipID, eth_nic_base + ADD_PORT);
+			continue; }
+		else if (get_eeprom_chksum(START_EEPROM_DATA,CHKSUM_LEN,
+					   eeprom_buff) < 0) {
+			printf("\ncs: EEPROM checksum bad...\n");
+			outw(PP_ChipID, eth_nic_base + ADD_PORT);
+			continue; }
+
+		/* get transmission control word but keep the
+		   autonegotiation bits */
+		eth_auto_neg_cnf = eeprom_buff[AUTO_NEG_CNF_OFFSET/2];
+		/* Store adapter configuration */
+		eth_adapter_cnf = eeprom_buff[ADAPTER_CNF_OFFSET/2];
+		/* Store ISA configuration */
+		isa_cnf = eeprom_buff[ISA_CNF_OFFSET/2];
+
+		/* store the initial memory base address */
+		eth_mem_start = eeprom_buff[PACKET_PAGE_OFFSET/2] << 8;
+
+		printf("%s%s%s, addr ",
+		       (eth_adapter_cnf & A_CNF_10B_T)?", RJ-45":"",
+		       (eth_adapter_cnf & A_CNF_AUI)?", AUI":"",
+		       (eth_adapter_cnf & A_CNF_10B_2)?", BNC":"");
+
+		/* If this is a CS8900 then no pnp soft */
+		if (eth_cs_type != CS8900 &&
+		    /* Check if the ISA IRQ has been set  */
+		    (i = readreg(PP_CS8920_ISAINT) & 0xff,
+		     (i != 0 && i < CS8920_NO_INTS)))
+			eth_irq = i;
+		else {
+			i = isa_cnf & INT_NO_MASK;
+			if (eth_cs_type == CS8900) {
+				/* the table that follows is dependent
+				   upon how you wired up your cs8900
+				   in your system.  The table is the
+				   same as the cs8900 engineering demo
+				   board.  irq_map also depends on the
+				   contents of the table.  Also see
+				   write_irq, which is the reverse
+				   mapping of the table below. */
+				if (i < 4) i = "\012\013\014\005"[i];
+				else printf("\ncs: BUG: isa_config is %d\n", i); }
+			eth_irq = i; }
+
+		/* Retrieve and print the ethernet address. */
+		for (i=0; i<ETH_ALEN; i++) {
+			nic->node_addr[i] = ((unsigned char *)eeprom_buff)[i];
+		}
+		printf("%!\n", nic->node_addr);
+
+		/* Set the LineCTL quintuplet based on adapter
+		   configuration read from EEPROM */
+		if ((eth_adapter_cnf & A_CNF_EXTND_10B_2) &&
+		    (eth_adapter_cnf & A_CNF_LOW_RX_SQUELCH))
+			eth_linectl = LOW_RX_SQUELCH;
+		else
+			eth_linectl = 0;
+
+		/* check to make sure that they have the "right"
+		   hardware available */
+		switch(eth_adapter_cnf & A_CNF_MEDIA_TYPE) {
+		case A_CNF_MEDIA_10B_T: result = eth_adapter_cnf & A_CNF_10B_T;
+			break;
+		case A_CNF_MEDIA_AUI:   result = eth_adapter_cnf & A_CNF_AUI;
+			break;
+		case A_CNF_MEDIA_10B_2: result = eth_adapter_cnf & A_CNF_10B_2;
+			break;
+		default: result = eth_adapter_cnf & (A_CNF_10B_T | A_CNF_AUI |
+						     A_CNF_10B_2);
+		}
+		if (!result) {
+			printf("cs: EEPROM is configured for unavailable media\n");
+		error:
+			writereg(PP_LineCTL, readreg(PP_LineCTL) &
+				 ~(SERIAL_TX_ON | SERIAL_RX_ON));
+			outw(PP_ChipID, eth_nic_base + ADD_PORT);
+			continue;
+		}
+
+		/* Initialize the card for probing of the attached media */
+		cs89x0_reset(nic);
+
+		/* set the hardware to the configured choice */
+		switch(eth_adapter_cnf & A_CNF_MEDIA_TYPE) {
+		case A_CNF_MEDIA_10B_T:
+			result = detect_tp();
+			if (!result) {
+				clrline();
+				printf("10Base-T (RJ-45%s",
+				       ") has no cable\n"); }
+			/* check "ignore missing media" bit */
+			if (eth_auto_neg_cnf & IMM_BIT)
+				/* Yes! I don't care if I see a link pulse */
+				result = A_CNF_MEDIA_10B_T;
+			break;
+		case A_CNF_MEDIA_AUI:
+			result = detect_aui(nic);
+			if (!result) {
+				clrline();
+				printf("10Base-5 (AUI%s",
+				       ") has no cable\n"); }
+			/* check "ignore missing media" bit */
+			if (eth_auto_neg_cnf & IMM_BIT)
+				/* Yes! I don't care if I see a carrrier */
+				result = A_CNF_MEDIA_AUI;
+			break;
+		case A_CNF_MEDIA_10B_2:
+			result = detect_bnc(nic);
+			if (!result) {
+				clrline();
+				printf("10Base-2 (BNC%s",
+				       ") has no cable\n"); }
+			/* check "ignore missing media" bit */
+			if (eth_auto_neg_cnf & IMM_BIT)
+				/* Yes! I don't care if I can xmit a packet */
+				result = A_CNF_MEDIA_10B_2;
+			break;
+		case A_CNF_MEDIA_AUTO:
+			writereg(PP_LineCTL, eth_linectl | AUTO_AUI_10BASET);
+			if (eth_adapter_cnf & A_CNF_10B_T)
+				if ((result = detect_tp()) != 0)
+					break;
+			if (eth_adapter_cnf & A_CNF_AUI)
+				if ((result = detect_aui(nic)) != 0)
+					break;
+			if (eth_adapter_cnf & A_CNF_10B_2)
+				if ((result = detect_bnc(nic)) != 0)
+					break;
+			clrline(); printf("no media detected\n");
+			goto error;
+		}
+		clrline();
+		switch(result) {
+		case 0:                 printf("no network cable attached to configured media\n");
+			goto error;
+		case A_CNF_MEDIA_10B_T: printf("using 10Base-T (RJ-45)\n");
+			break;
+		case A_CNF_MEDIA_AUI:   printf("using 10Base-5 (AUI)\n");
+			break;
+		case A_CNF_MEDIA_10B_2: printf("using 10Base-2 (BNC)\n");
+			break;
+		}
+
+		/* Turn on both receive and transmit operations */
+		writereg(PP_LineCTL, readreg(PP_LineCTL) | SERIAL_RX_ON |
+			 SERIAL_TX_ON);
+
+		break;
+	}
+
+	if (ioaddr == 0)
+		return (0);
+	nic->reset = cs89x0_reset;
+	nic->poll = cs89x0_poll;
+	nic->transmit = cs89x0_transmit;
+	nic->disable = cs89x0_disable;
+	return (nic);
+}
+
+/*
+ * Local variables:
+ *  c-basic-offset: 8
+ * End:
+ */
+
diff --git a/netboot/cs89x0.h b/netboot/cs89x0.h
new file mode 100644
index 0000000..b1806f4
--- /dev/null
+++ b/netboot/cs89x0.h
@@ -0,0 +1,461 @@
+/*  Copyright, 1988-1992, Russell Nelson, Crynwr Software
+
+   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, version 1.
+
+   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.  */
+
+#define PP_ChipID 0x0000	/* offset   0h -> Corp -ID              */
+				/* offset   2h -> Model/Product Number  */
+				/* offset   3h -> Chip Revision Number  */
+
+#define PP_ISAIOB 0x0020	/*  IO base address */
+#define PP_CS8900_ISAINT 0x0022	/*  ISA interrupt select */
+#define PP_CS8920_ISAINT 0x0370	/*  ISA interrupt select */
+#define PP_CS8900_ISADMA 0x0024	/*  ISA Rec DMA channel */
+#define PP_CS8920_ISADMA 0x0374	/*  ISA Rec DMA channel */
+#define PP_ISASOF 0x0026	/*  ISA DMA offset */
+#define PP_DmaFrameCnt 0x0028	/*  ISA DMA Frame count */
+#define PP_DmaByteCnt 0x002A	/*  ISA DMA Byte count */
+#define PP_CS8900_ISAMemB 0x002C	/*  Memory base */
+#define PP_CS8920_ISAMemB 0x0348 /*  */
+
+#define PP_ISABootBase 0x0030	/*  Boot Prom base  */
+#define PP_ISABootMask 0x0034	/*  Boot Prom Mask */
+
+/* EEPROM data and command registers */
+#define PP_EECMD 0x0040		/*  NVR Interface Command register */
+#define PP_EEData 0x0042	/*  NVR Interface Data Register */
+#define PP_DebugReg 0x0044	/*  Debug Register */
+
+#define PP_RxCFG 0x0102		/*  Rx Bus config */
+#define PP_RxCTL 0x0104		/*  Receive Control Register */
+#define PP_TxCFG 0x0106		/*  Transmit Config Register */
+#define PP_TxCMD 0x0108		/*  Transmit Command Register */
+#define PP_BufCFG 0x010A	/*  Bus configuration Register */
+#define PP_LineCTL 0x0112	/*  Line Config Register */
+#define PP_SelfCTL 0x0114	/*  Self Command Register */
+#define PP_BusCTL 0x0116	/*  ISA bus control Register */
+#define PP_TestCTL 0x0118	/*  Test Register */
+#define PP_AutoNegCTL 0x011C	/*  Auto Negotiation Ctrl */
+
+#define PP_ISQ 0x0120		/*  Interrupt Status */
+#define PP_RxEvent 0x0124	/*  Rx Event Register */
+#define PP_TxEvent 0x0128	/*  Tx Event Register */
+#define PP_BufEvent 0x012C	/*  Bus Event Register */
+#define PP_RxMiss 0x0130	/*  Receive Miss Count */
+#define PP_TxCol 0x0132		/*  Transmit Collision Count */
+#define PP_LineST 0x0134	/*  Line State Register */
+#define PP_SelfST 0x0136	/*  Self State register */
+#define PP_BusST 0x0138		/*  Bus Status */
+#define PP_TDR 0x013C		/*  Time Domain Reflectometry */
+#define PP_AutoNegST 0x013E	/*  Auto Neg Status */
+#define PP_TxCommand 0x0144	/*  Tx Command */
+#define PP_TxLength 0x0146	/*  Tx Length */
+#define PP_LAF 0x0150		/*  Hash Table */
+#define PP_IA 0x0158		/*  Physical Address Register */
+
+#define PP_RxStatus 0x0400	/*  Receive start of frame */
+#define PP_RxLength 0x0402	/*  Receive Length of frame */
+#define PP_RxFrame 0x0404	/*  Receive frame pointer */
+#define PP_TxFrame 0x0A00	/*  Transmit frame pointer */
+
+/*  Primary I/O Base Address. If no I/O base is supplied by the user, then this */
+/*  can be used as the default I/O base to access the PacketPage Area. */
+#define DEFAULTIOBASE 0x0300
+#define FIRST_IO 0x020C		/*  First I/O port to check */
+#define LAST_IO 0x037C		/*  Last I/O port to check (+10h) */
+#define ADD_MASK 0x3000		/*  Mask it use of the ADD_PORT register */
+#define ADD_SIG 0x3000		/*  Expected ID signature */
+
+#define CHIP_EISA_ID_SIG 0x630E   /*  Product ID Code for Crystal Chip (CS8900 spec 4.3) */
+
+#ifdef	IBMEIPKT
+#define EISA_ID_SIG 0x4D24	/*  IBM */
+#define PART_NO_SIG 0x1010	/*  IBM */
+#define MONGOOSE_BIT 0x0000	/*  IBM */
+#else
+#define EISA_ID_SIG 0x630E	/*  PnP Vendor ID (same as chip id for Crystal board) */
+#define PART_NO_SIG 0x4000	/*  ID code CS8920 board (PnP Vendor Product code) */
+#define MONGOOSE_BIT 0x2000	/*  PART_NO_SIG + MONGOOSE_BUT => ID of mongoose */
+#endif
+
+#define PRODUCT_ID_ADD 0x0002   /*  Address of product ID */
+
+/*  Mask to find out the types of  registers */
+#define REG_TYPE_MASK 0x001F
+
+/*  Eeprom Commands */
+#define ERSE_WR_ENBL 0x00F0
+#define ERSE_WR_DISABLE 0x0000
+
+/*  Defines Control/Config register quintuplet numbers */
+#define RX_BUF_CFG 0x0003
+#define RX_CONTROL 0x0005
+#define TX_CFG 0x0007
+#define TX_COMMAND 0x0009
+#define BUF_CFG 0x000B
+#define LINE_CONTROL 0x0013
+#define SELF_CONTROL 0x0015
+#define BUS_CONTROL 0x0017
+#define TEST_CONTROL 0x0019
+
+/*  Defines Status/Count registers quintuplet numbers */
+#define RX_EVENT 0x0004
+#define TX_EVENT 0x0008
+#define BUF_EVENT 0x000C
+#define RX_MISS_COUNT 0x0010
+#define TX_COL_COUNT 0x0012
+#define LINE_STATUS 0x0014
+#define SELF_STATUS 0x0016
+#define BUS_STATUS 0x0018
+#define TDR 0x001C
+
+/* PP_RxCFG - Receive  Configuration and Interrupt Mask bit definition -  Read/write */
+#define SKIP_1 0x0040
+#define RX_STREAM_ENBL 0x0080
+#define RX_OK_ENBL 0x0100
+#define RX_DMA_ONLY 0x0200
+#define AUTO_RX_DMA 0x0400
+#define BUFFER_CRC 0x0800
+#define RX_CRC_ERROR_ENBL 0x1000
+#define RX_RUNT_ENBL 0x2000
+#define RX_EXTRA_DATA_ENBL 0x4000
+
+/* PP_RxCTL - Receive Control bit definition - Read/write */
+#define RX_IA_HASH_ACCEPT 0x0040
+#define RX_PROM_ACCEPT 0x0080
+#define RX_OK_ACCEPT 0x0100
+#define RX_MULTCAST_ACCEPT 0x0200
+#define RX_IA_ACCEPT 0x0400
+#define RX_BROADCAST_ACCEPT 0x0800
+#define RX_BAD_CRC_ACCEPT 0x1000
+#define RX_RUNT_ACCEPT 0x2000
+#define RX_EXTRA_DATA_ACCEPT 0x4000
+#define RX_ALL_ACCEPT (RX_PROM_ACCEPT|RX_BAD_CRC_ACCEPT|RX_RUNT_ACCEPT|RX_EXTRA_DATA_ACCEPT)
+/*  Default receive mode - individually addressed, broadcast, and error free */
+#define DEF_RX_ACCEPT (RX_IA_ACCEPT | RX_BROADCAST_ACCEPT | RX_OK_ACCEPT)
+
+/* PP_TxCFG - Transmit Configuration Interrupt Mask bit definition - Read/write */
+#define TX_LOST_CRS_ENBL 0x0040
+#define TX_SQE_ERROR_ENBL 0x0080
+#define TX_OK_ENBL 0x0100
+#define TX_LATE_COL_ENBL 0x0200
+#define TX_JBR_ENBL 0x0400
+#define TX_ANY_COL_ENBL 0x0800
+#define TX_16_COL_ENBL 0x8000
+
+/* PP_TxCMD - Transmit Command bit definition - Read-only */
+#define TX_START_4_BYTES 0x0000
+#define TX_START_64_BYTES 0x0040
+#define TX_START_128_BYTES 0x0080
+#define TX_START_ALL_BYTES 0x00C0
+#define TX_FORCE 0x0100
+#define TX_ONE_COL 0x0200
+#define TX_TWO_PART_DEFF_DISABLE 0x0400
+#define TX_NO_CRC 0x1000
+#define TX_RUNT 0x2000
+
+/* PP_BufCFG - Buffer Configuration Interrupt Mask bit definition - Read/write */
+#define GENERATE_SW_INTERRUPT 0x0040
+#define RX_DMA_ENBL 0x0080
+#define READY_FOR_TX_ENBL 0x0100
+#define TX_UNDERRUN_ENBL 0x0200
+#define RX_MISS_ENBL 0x0400
+#define RX_128_BYTE_ENBL 0x0800
+#define TX_COL_COUNT_OVRFLOW_ENBL 0x1000
+#define RX_MISS_COUNT_OVRFLOW_ENBL 0x2000
+#define RX_DEST_MATCH_ENBL 0x8000
+
+/* PP_LineCTL - Line Control bit definition - Read/write */
+#define SERIAL_RX_ON 0x0040
+#define SERIAL_TX_ON 0x0080
+#define AUI_ONLY 0x0100
+#define AUTO_AUI_10BASET 0x0200
+#define MODIFIED_BACKOFF 0x0800
+#define NO_AUTO_POLARITY 0x1000
+#define TWO_PART_DEFDIS 0x2000
+#define LOW_RX_SQUELCH 0x4000
+
+/* PP_SelfCTL - Software Self Control bit definition - Read/write */
+#define POWER_ON_RESET 0x0040
+#define SW_STOP 0x0100
+#define SLEEP_ON 0x0200
+#define AUTO_WAKEUP 0x0400
+#define HCB0_ENBL 0x1000
+#define HCB1_ENBL 0x2000
+#define HCB0 0x4000
+#define HCB1 0x8000
+
+/* PP_BusCTL - ISA Bus Control bit definition - Read/write */
+#define RESET_RX_DMA 0x0040
+#define MEMORY_ON 0x0400
+#define DMA_BURST_MODE 0x0800
+#define IO_CHANNEL_READY_ON 0x1000
+#define RX_DMA_SIZE_64K 0x2000
+#define ENABLE_IRQ 0x8000
+
+/* PP_TestCTL - Test Control bit definition - Read/write */
+#define LINK_OFF 0x0080
+#define ENDEC_LOOPBACK 0x0200
+#define AUI_LOOPBACK 0x0400
+#define BACKOFF_OFF 0x0800
+#define FAST_TEST 0x8000
+
+/* PP_RxEvent - Receive Event Bit definition - Read-only */
+#define RX_IA_HASHED 0x0040
+#define RX_DRIBBLE 0x0080
+#define RX_OK 0x0100
+#define RX_HASHED 0x0200
+#define RX_IA 0x0400
+#define RX_BROADCAST 0x0800
+#define RX_CRC_ERROR 0x1000
+#define RX_RUNT 0x2000
+#define RX_EXTRA_DATA 0x4000
+
+#define HASH_INDEX_MASK 0x0FC00
+
+/* PP_TxEvent - Transmit Event Bit definition - Read-only */
+#define TX_LOST_CRS 0x0040
+#define TX_SQE_ERROR 0x0080
+#define TX_OK 0x0100
+#define TX_LATE_COL 0x0200
+#define TX_JBR 0x0400
+#define TX_16_COL 0x8000
+#define TX_SEND_OK_BITS (TX_OK|TX_LOST_CRS)
+#define TX_COL_COUNT_MASK 0x7800
+
+/* PP_BufEvent - Buffer Event Bit definition - Read-only */
+#define SW_INTERRUPT 0x0040
+#define RX_DMA 0x0080
+#define READY_FOR_TX 0x0100
+#define TX_UNDERRUN 0x0200
+#define RX_MISS 0x0400
+#define RX_128_BYTE 0x0800
+#define TX_COL_OVRFLW 0x1000
+#define RX_MISS_OVRFLW 0x2000
+#define RX_DEST_MATCH 0x8000
+
+/* PP_LineST - Ethernet Line Status bit definition - Read-only */
+#define LINK_OK 0x0080
+#define AUI_ON 0x0100
+#define TENBASET_ON 0x0200
+#define POLARITY_OK 0x1000
+#define CRS_OK 0x4000
+
+/* PP_SelfST - Chip Software Status bit definition */
+#define ACTIVE_33V 0x0040
+#define INIT_DONE 0x0080
+#define SI_BUSY 0x0100
+#define EEPROM_PRESENT 0x0200
+#define EEPROM_OK 0x0400
+#define EL_PRESENT 0x0800
+#define EE_SIZE_64 0x1000
+
+/* PP_BusST - ISA Bus Status bit definition */
+#define TX_BID_ERROR 0x0080
+#define READY_FOR_TX_NOW 0x0100
+
+/* PP_AutoNegCTL - Auto Negotiation Control bit definition */
+#define RE_NEG_NOW 0x0040
+#define ALLOW_FDX 0x0080
+#define AUTO_NEG_ENABLE 0x0100
+#define NLP_ENABLE 0x0200
+#define FORCE_FDX 0x8000
+#define AUTO_NEG_BITS (FORCE_FDX|NLP_ENABLE|AUTO_NEG_ENABLE)
+#define AUTO_NEG_MASK (FORCE_FDX|NLP_ENABLE|AUTO_NEG_ENABLE|ALLOW_FDX|RE_NEG_NOW)
+
+/* PP_AutoNegST - Auto Negotiation Status bit definition */
+#define AUTO_NEG_BUSY 0x0080
+#define FLP_LINK 0x0100
+#define FLP_LINK_GOOD 0x0800
+#define LINK_FAULT 0x1000
+#define HDX_ACTIVE 0x4000
+#define FDX_ACTIVE 0x8000
+
+/*  The following block defines the ISQ event types */
+#define ISQ_RECEIVER_EVENT 0x04
+#define ISQ_TRANSMITTER_EVENT 0x08
+#define ISQ_BUFFER_EVENT 0x0c
+#define ISQ_RX_MISS_EVENT 0x10
+#define ISQ_TX_COL_EVENT 0x12
+
+#define ISQ_EVENT_MASK 0x003F   /*  ISQ mask to find out type of event */
+#define ISQ_HIST 16		/*  small history buffer */
+#define AUTOINCREMENT 0x8000	/*  Bit mask to set bit-15 for autoincrement */
+
+#define TXRXBUFSIZE 0x0600
+#define RXDMABUFSIZE 0x8000
+#define RXDMASIZE 0x4000
+#define TXRX_LENGTH_MASK 0x07FF
+
+/*  rx options bits */
+#define RCV_WITH_RXON	1       /*  Set SerRx ON */
+#define RCV_COUNTS	2       /*  Use Framecnt1 */
+#define RCV_PONG	4       /*  Pong respondent */
+#define RCV_DONG	8       /*  Dong operation */
+#define RCV_POLLING	0x10	/*  Poll RxEvent */
+#define RCV_ISQ		0x20	/*  Use ISQ, int */
+#define RCV_AUTO_DMA	0x100	/*  Set AutoRxDMAE */
+#define RCV_DMA		0x200	/*  Set RxDMA only */
+#define RCV_DMA_ALL	0x400	/*  Copy all DMA'ed */
+#define RCV_FIXED_DATA	0x800	/*  Every frame same */
+#define RCV_IO		0x1000	/*  Use ISA IO only */
+#define RCV_MEMORY	0x2000	/*  Use ISA Memory */
+
+#define RAM_SIZE	0x1000       /*  The card has 4k bytes or RAM */
+#define PKT_START PP_TxFrame  /*  Start of packet RAM */
+
+#define RX_FRAME_PORT	0x0000
+#define TX_FRAME_PORT RX_FRAME_PORT
+#define TX_CMD_PORT	0x0004
+#define TX_NOW		0x0000       /*  Tx packet after   5 bytes copied */
+#define TX_AFTER_381	0x0020       /*  Tx packet after 381 bytes copied */
+#define TX_AFTER_ALL	0x0060       /*  Tx packet after all bytes copied */
+#define TX_LEN_PORT	0x0006
+#define ISQ_PORT	0x0008
+#define ADD_PORT	0x000A
+#define DATA_PORT	0x000C
+
+#define EEPROM_WRITE_EN		0x00F0
+#define EEPROM_WRITE_DIS	0x0000
+#define EEPROM_WRITE_CMD	0x0100
+#define EEPROM_READ_CMD		0x0200
+
+/*  Receive Header */
+/*  Description of header of each packet in receive area of memory */
+#define RBUF_EVENT_LOW	0   /*  Low byte of RxEvent - status of received frame */
+#define RBUF_EVENT_HIGH	1   /*  High byte of RxEvent - status of received frame */
+#define RBUF_LEN_LOW	2   /*  Length of received data - low byte */
+#define RBUF_LEN_HI	3   /*  Length of received data - high byte */
+#define RBUF_HEAD_LEN	4   /*  Length of this header */
+
+#define CHIP_READ 0x1   /*  Used to mark state of the repins code (chip or dma) */
+#define DMA_READ 0x2   /*  Used to mark state of the repins code (chip or dma) */
+
+/*  for bios scan */
+/*  */
+#ifdef	CSDEBUG
+/*  use these values for debugging bios scan */
+#define BIOS_START_SEG 0x00000
+#define BIOS_OFFSET_INC 0x0010
+#else
+#define BIOS_START_SEG 0x0c000
+#define BIOS_OFFSET_INC 0x0200
+#endif
+
+#define BIOS_LAST_OFFSET 0x0fc00
+
+/*  Byte offsets into the EEPROM configuration buffer */
+#define ISA_CNF_OFFSET 0x6
+#define TX_CTL_OFFSET (ISA_CNF_OFFSET + 8)			/*  8900 eeprom */
+#define AUTO_NEG_CNF_OFFSET (ISA_CNF_OFFSET + 8)		/*  8920 eeprom */
+
+  /*  the assumption here is that the bits in the eeprom are generally  */
+  /*  in the same position as those in the autonegctl register. */
+  /*  Of course the IMM bit is not in that register so it must be  */
+  /*  masked out */
+#define EE_FORCE_FDX  0x8000
+#define EE_NLP_ENABLE 0x0200
+#define EE_AUTO_NEG_ENABLE 0x0100
+#define EE_ALLOW_FDX 0x0080
+#define EE_AUTO_NEG_CNF_MASK (EE_FORCE_FDX|EE_NLP_ENABLE|EE_AUTO_NEG_ENABLE|EE_ALLOW_FDX)
+
+#define IMM_BIT 0x0040		/*  ignore missing media */
+
+#define ADAPTER_CNF_OFFSET (AUTO_NEG_CNF_OFFSET + 2)
+#define A_CNF_10B_T 0x0001
+#define A_CNF_AUI 0x0002
+#define A_CNF_10B_2 0x0004
+#define A_CNF_MEDIA_TYPE 0x0060
+#define A_CNF_MEDIA_AUTO 0x0000
+#define A_CNF_MEDIA_10B_T 0x0020
+#define A_CNF_MEDIA_AUI 0x0040
+#define A_CNF_MEDIA_10B_2 0x0060
+#define A_CNF_DC_DC_POLARITY 0x0080
+#define A_CNF_NO_AUTO_POLARITY 0x2000
+#define A_CNF_LOW_RX_SQUELCH 0x4000
+#define A_CNF_EXTND_10B_2 0x8000
+
+#define PACKET_PAGE_OFFSET 0x8
+
+/*  Bit definitions for the ISA configuration word from the EEPROM */
+#define INT_NO_MASK 0x000F
+#define DMA_NO_MASK 0x0070
+#define ISA_DMA_SIZE 0x0200
+#define ISA_AUTO_RxDMA 0x0400
+#define ISA_RxDMA 0x0800
+#define DMA_BURST 0x1000
+#define STREAM_TRANSFER 0x2000
+#define ANY_ISA_DMA (ISA_AUTO_RxDMA | ISA_RxDMA)
+
+/*  DMA controller registers */
+#define DMA_BASE 0x00     /*  DMA controller base */
+#define DMA_BASE_2 0x0C0    /*  DMA controller base */
+
+#define DMA_STAT 0x0D0    /*  DMA controller status register */
+#define DMA_MASK 0x0D4    /*  DMA controller mask register */
+#define DMA_MODE 0x0D6    /*  DMA controller mode register */
+#define DMA_RESETFF 0x0D8    /*  DMA controller first/last flip flop */
+
+/*  DMA data */
+#define DMA_DISABLE 0x04     /*  Disable channel n */
+#define DMA_ENABLE 0x00     /*  Enable channel n */
+/*  Demand transfers, incr. address, auto init, writes, ch. n */
+#define DMA_RX_MODE 0x14
+/*  Demand transfers, incr. address, auto init, reads, ch. n */
+#define DMA_TX_MODE 0x18
+
+#define DMA_SIZE (16*1024) /*  Size of dma buffer - 16k */
+
+#define CS8900 0x0000
+#define CS8920 0x4000
+#define CS8920M 0x6000
+#define REVISON_BITS 0x1F00
+#define EEVER_NUMBER 0x12
+#define CHKSUM_LEN 0x14
+#define CHKSUM_VAL 0x0000
+#define START_EEPROM_DATA 0x001c /*  Offset into eeprom for start of data */
+#define IRQ_MAP_EEPROM_DATA 0x0046 /*  Offset into eeprom for the IRQ map */
+#define IRQ_MAP_LEN 0x0004 /*  No of bytes to read for the IRQ map */
+#define PNP_IRQ_FRMT 0x0022 /*  PNP small item IRQ format */
+#define CS8900_IRQ_MAP 0x1c20 /*  This IRQ map is fixed */
+
+#define CS8920_NO_INTS 0x0F   /*  Max CS8920 interrupt select # */
+
+#define PNP_ADD_PORT 0x0279
+#define PNP_WRITE_PORT 0x0A79
+
+#define GET_PNP_ISA_STRUCT 0x40
+#define PNP_ISA_STRUCT_LEN 0x06
+#define PNP_CSN_CNT_OFF 0x01
+#define PNP_RD_PORT_OFF 0x02
+#define PNP_FUNCTION_OK 0x00
+#define PNP_WAKE 0x03
+#define PNP_RSRC_DATA 0x04
+#define PNP_RSRC_READY 0x01
+#define PNP_STATUS 0x05
+#define PNP_ACTIVATE 0x30
+#define PNP_CNF_IO_H 0x60
+#define PNP_CNF_IO_L 0x61
+#define PNP_CNF_INT 0x70
+#define PNP_CNF_DMA 0x74
+#define PNP_CNF_MEM 0x48
+
+#define BIT0 1
+#define BIT15 0x8000
+
+/*
+ * Local variables:
+ *  c-basic-offset: 8
+ * End:
+ */
+
diff --git a/netboot/cs89x0.txt b/netboot/cs89x0.txt
new file mode 100644
index 0000000..4927641
--- /dev/null
+++ b/netboot/cs89x0.txt
@@ -0,0 +1,26 @@
+Permission is granted to distribute the enclosed cs89x0.[ch] driver
+only in conjunction with the Etherboot package.  The code is
+ordinarily distributed under the GPL.
+
+Russ Nelson, January 2000
+
+CREDITS
+
+I want to thank
+
+  Mike Cruse <mcruse@cti-ltd.com>
+     for providing an evaluation NIC and for sponsoring the
+     development of this driver.
+
+  Randall Sears <sears@crystal.cirrus.com>
+  Deva Bodas <bodas@crystal.cirrus.com>
+  Andreas Kraemer <akraemer@crystal.cirrus.com>
+  Wolfgang Krause <100303.2673@compuserve.com>
+     for excellent technical support and for providing the required
+     programming information. I appreciate Crystal Semiconductor's
+     commitment towards free software.
+
+  Russell Nelson <nelson@crynwr.com>
+     for writing the Linux device driver for the CS89x0
+     chipset. Russel's code is very well designed and simplified my
+     job a lot.
diff --git a/netboot/davicom.c b/netboot/davicom.c
new file mode 100644
index 0000000..5a98656
--- /dev/null
+++ b/netboot/davicom.c
@@ -0,0 +1,692 @@
+/*  
+    DAVICOM DM9009/DM9102/DM9102A Etherboot Driver	V1.00
+
+    This driver was ported from Marty Conner's Tulip Etherboot driver. 
+    Thanks Marty Connor (mdc@thinguin.org) 
+    You can get Tulip driver source file from this URL:
+
+    "http://etherboot.sourceforge..net/#Distribution"
+    
+    This davicom etherboot driver supports DM9009/DM9102/DM9102A/
+    DM9102A+DM9801/DM9102A+DM9802 NICs.
+
+    This software may be used and distributed according to the terms
+    of the GNU Public License, incorporated herein by reference.
+
+*/
+
+/*********************************************************************/
+/* Revision History                                                  */
+/*********************************************************************/
+
+/*
+  19 OCT 2000  Sten     1.00
+			Different half and full duplex mode
+			Do the different programming for DM9801/DM9802
+
+  12 OCT 2000  Sten     0.90
+			This driver was ported from tulip driver and it 
+			has the following difference.
+			Changed symbol tulip/TULIP to davicom/DAVICOM
+			Deleted some code that did not use in this driver.
+			Used chain-strcture to replace ring structure
+			for both TX/RX descriptor.
+			Allocated two tx descriptor.
+			According current media mode to set operating 
+			register(CR6)
+*/
+
+
+/*********************************************************************/
+/* Declarations                                                      */
+/*********************************************************************/
+
+#include "etherboot.h"
+#include "nic.h"
+#include "pci.h"
+#include "cards.h"
+
+#undef DAVICOM_DEBUG
+#undef DAVICOM_DEBUG_WHERE
+
+#define TX_TIME_OUT       2*TICKS_PER_SEC
+
+typedef unsigned char  u8;
+typedef   signed char  s8;
+typedef unsigned short u16;
+typedef   signed short s16;
+typedef unsigned int   u32;
+typedef   signed int   s32;
+
+/* Register offsets for davicom device */
+enum davicom_offsets {
+   CSR0=0,     CSR1=0x08,  CSR2=0x10,  CSR3=0x18,  CSR4=0x20,  CSR5=0x28,
+   CSR6=0x30,  CSR7=0x38,  CSR8=0x40,  CSR9=0x48, CSR10=0x50, CSR11=0x58,
+  CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x80, CSR20=0xA0
+};
+
+/* EEPROM Address width definitions */
+#define EEPROM_ADDRLEN 6
+#define EEPROM_SIZE    32              /* 1 << EEPROM_ADDRLEN */
+/* Used to be 128, but we only need to read enough to get the MAC
+   address at bytes 20..25 */
+
+/* Data Read from the EEPROM */
+static unsigned char ee_data[EEPROM_SIZE];
+
+/* The EEPROM commands include the alway-set leading bit. */
+#define EE_WRITE_CMD    (5 << addr_len)
+#define EE_READ_CMD     (6 << addr_len)
+#define EE_ERASE_CMD    (7 << addr_len)
+
+/* EEPROM_Ctrl bits. */
+#define EE_SHIFT_CLK    0x02    /* EEPROM shift clock. */
+#define EE_CS           0x01    /* EEPROM chip select. */
+#define EE_DATA_WRITE   0x04    /* EEPROM chip data in. */
+#define EE_WRITE_0      0x01
+#define EE_WRITE_1      0x05
+#define EE_DATA_READ    0x08    /* EEPROM chip data out. */
+#define EE_ENB          (0x4800 | EE_CS)
+
+/* Sten 10/11 for phyxcer */
+#define PHY_DATA_0	0x0
+#define PHY_DATA_1	0x20000
+#define MDCLKH		0x10000
+
+/* Delay between EEPROM clock transitions.  Even at 33Mhz current PCI
+   implementations don't overrun the EEPROM clock.  We add a bus
+   turn-around to insure that this remains true.  */
+#define eeprom_delay()  inl(ee_addr)
+
+/* helpful macro if on a big_endian machine for changing byte order.
+   not strictly needed on Intel */
+#define le16_to_cpu(val) (val)
+
+/* transmit and receive descriptor format */
+struct txdesc {
+  volatile unsigned long   status;         /* owner, status */
+  unsigned long   buf1sz:11,      /* size of buffer 1 */
+    buf2sz:11,                    /* size of buffer 2 */
+    control:10;                   /* control bits */
+  const unsigned char *buf1addr;  /* buffer 1 address */
+  const unsigned char *buf2addr;  /* buffer 2 address */
+};
+
+struct rxdesc {
+  volatile unsigned long   status;         /* owner, status */
+  unsigned long   buf1sz:11,      /* size of buffer 1 */
+    buf2sz:11,                    /* size of buffer 2 */
+    control:10;                   /* control bits */
+  unsigned char   *buf1addr;      /* buffer 1 address */
+  unsigned char   *buf2addr;      /* buffer 2 address */
+};
+
+/* Size of transmit and receive buffers */
+#define BUFLEN 1536
+
+/*********************************************************************/
+/* Global Storage                                                    */
+/*********************************************************************/
+
+/* PCI Bus parameters */
+static unsigned short vendor, dev_id;
+static unsigned long ioaddr;
+
+/* Note: transmit and receive buffers must be longword aligned and
+   longword divisable */
+
+/* transmit descriptor and buffer */
+#define NTXD 2
+static struct txdesc txd[NTXD] __attribute__ ((aligned(4)));
+#ifdef	USE_LOWMEM_BUFFER
+#define txb ((char *)0x10000 - BUFLEN)
+#else
+static unsigned char txb[BUFLEN] __attribute__ ((aligned(4)));
+#endif
+
+/* receive descriptor(s) and buffer(s) */
+#define NRXD 4
+static struct rxdesc rxd[NRXD] __attribute__ ((aligned(4)));
+#ifdef	USE_LOWMEM_BUFFER
+#define rxb ((char *)0x10000 - NRXD * BUFLEN - BUFLEN)
+#else
+static unsigned char rxb[NRXD * BUFLEN] __attribute__ ((aligned(4)));
+#endif
+static int rxd_tail;
+static int TxPtr;
+
+
+/*********************************************************************/
+/* Function Prototypes                                               */
+/*********************************************************************/
+static void whereami(const char *str);
+static int read_eeprom(unsigned long ioaddr, int location, int addr_len);
+struct nic *davicom_probe(struct nic *nic, unsigned short *io_addrs,
+			struct pci_device *pci);
+static void davicom_init_chain(struct nic *nic);	/* Sten 10/9 */
+static void davicom_reset(struct nic *nic);
+static void davicom_transmit(struct nic *nic, const char *d, unsigned int t,
+			   unsigned int s, const char *p);
+static int davicom_poll(struct nic *nic);
+static void davicom_disable(struct nic *nic);
+static void whereami (const char *str);
+#ifdef	DAVICOM_DEBUG
+static void davicom_more(void);
+#endif /* DAVICOM_DEBUG */
+static void davicom_wait(unsigned int nticks);
+static int phy_read(int);
+static void phy_write(int, u16);
+static void phy_write_1bit(u32, u32);
+static int phy_read_1bit(u32);
+static void davicom_media_chk(struct nic *);
+
+
+/*********************************************************************/
+/* Utility Routines                                                  */
+/*********************************************************************/
+
+static inline void whereami (const char *str)
+{
+#ifdef	DAVICOM_DEBUG_WHERE
+  printf("%s\n", str);
+  /* sleep(2); */
+#endif
+}
+
+#ifdef	DAVICOM_DEBUG
+static void davicom_more()
+{
+  printf("\n\n-- more --");
+  while (!iskey())
+    /* wait */;
+  getchar();
+  printf("\n\n");
+}
+#endif /* DAVICOM_DEBUG */
+
+static void davicom_wait(unsigned int nticks)
+{
+  unsigned int to = currticks() + nticks;
+  while (currticks() < to)
+    /* wait */ ;
+}
+
+
+/*********************************************************************/
+/* For DAVICOM phyxcer register by MII interface		     */
+/*********************************************************************/
+/*
+  Read a word data from phy register
+*/
+static int phy_read(int location)
+{
+ int i, phy_addr=1;
+ u16 phy_data;
+ u32 io_dcr9;
+
+ whereami("phy_read\n");
+
+ io_dcr9 = ioaddr + CSR9;
+
+ /* Send 33 synchronization clock to Phy controller */
+ for (i=0; i<34; i++)
+     phy_write_1bit(io_dcr9, PHY_DATA_1);
+
+ /* Send start command(01) to Phy */
+ phy_write_1bit(io_dcr9, PHY_DATA_0);
+ phy_write_1bit(io_dcr9, PHY_DATA_1);
+
+ /* Send read command(10) to Phy */
+ phy_write_1bit(io_dcr9, PHY_DATA_1);
+ phy_write_1bit(io_dcr9, PHY_DATA_0);
+
+ /* Send Phy addres */
+ for (i=0x10; i>0; i=i>>1)
+     phy_write_1bit(io_dcr9, phy_addr&i ? PHY_DATA_1: PHY_DATA_0);
+   
+ /* Send register addres */
+ for (i=0x10; i>0; i=i>>1)
+     phy_write_1bit(io_dcr9, location&i ? PHY_DATA_1: PHY_DATA_0);
+
+ /* Skip transition state */
+ phy_read_1bit(io_dcr9);
+
+ /* read 16bit data */
+ for (phy_data=0, i=0; i<16; i++) {
+   phy_data<<=1;
+   phy_data|=phy_read_1bit(io_dcr9);
+ }
+
+ return phy_data;
+}
+
+/*
+  Write a word to Phy register
+*/
+static void phy_write(int location, u16 phy_data)
+{
+ u16 i, phy_addr=1;
+ u32 io_dcr9; 
+
+ whereami("phy_write\n");
+
+ io_dcr9 = ioaddr + CSR9;
+
+ /* Send 33 synchronization clock to Phy controller */
+ for (i=0; i<34; i++)
+   phy_write_1bit(io_dcr9, PHY_DATA_1);
+
+ /* Send start command(01) to Phy */
+ phy_write_1bit(io_dcr9, PHY_DATA_0);
+ phy_write_1bit(io_dcr9, PHY_DATA_1);
+
+ /* Send write command(01) to Phy */
+ phy_write_1bit(io_dcr9, PHY_DATA_0);
+ phy_write_1bit(io_dcr9, PHY_DATA_1);
+
+ /* Send Phy addres */
+ for (i=0x10; i>0; i=i>>1)
+   phy_write_1bit(io_dcr9, phy_addr&i ? PHY_DATA_1: PHY_DATA_0);
+
+ /* Send register addres */
+ for (i=0x10; i>0; i=i>>1)
+   phy_write_1bit(io_dcr9, location&i ? PHY_DATA_1: PHY_DATA_0);
+
+ /* written trasnition */
+ phy_write_1bit(io_dcr9, PHY_DATA_1);
+ phy_write_1bit(io_dcr9, PHY_DATA_0);
+
+ /* Write a word data to PHY controller */
+ for (i=0x8000; i>0; i>>=1)
+   phy_write_1bit(io_dcr9, phy_data&i ? PHY_DATA_1: PHY_DATA_0);
+}
+
+/*
+  Write one bit data to Phy Controller
+*/
+static void phy_write_1bit(u32 ee_addr, u32 phy_data)
+{
+ whereami("phy_write_1bit\n");
+ outl(phy_data, ee_addr);                        /* MII Clock Low */
+ eeprom_delay();
+ outl(phy_data|MDCLKH, ee_addr);                 /* MII Clock High */
+ eeprom_delay();
+ outl(phy_data, ee_addr);                        /* MII Clock Low */
+ eeprom_delay();
+}
+
+/*
+  Read one bit phy data from PHY controller
+*/
+static int phy_read_1bit(u32 ee_addr)
+{
+ int phy_data;
+
+ whereami("phy_read_1bit\n");
+
+ outl(0x50000, ee_addr);
+ eeprom_delay();
+
+ phy_data=(inl(ee_addr)>>19) & 0x1;
+
+ outl(0x40000, ee_addr);
+ eeprom_delay();
+
+ return phy_data;
+}
+
+/*
+  DM9801/DM9802 present check and program 
+*/
+static void HPNA_process(void)
+{
+
+ if ( (phy_read(3) & 0xfff0) == 0xb900 ) {
+   if ( phy_read(31) == 0x4404 ) {
+     /* DM9801 present */
+     if (phy_read(3) == 0xb901)
+       phy_write(16, 0x5);	/* DM9801 E4 */
+     else
+       phy_write(16, 0x1005); /* DM9801 E3 and others */
+     phy_write(25, ((phy_read(24) + 3) & 0xff) | 0xf000);
+   } else {
+     /* DM9802 present */
+     phy_write(16, 0x5);
+     phy_write(25, (phy_read(25) & 0xff00) + 2);
+   }
+ }
+}
+
+/*
+  Sense media mode and set CR6
+*/
+static void davicom_media_chk(struct nic * nic)
+{
+  unsigned long to, csr6;
+
+  csr6 = 0x00200000;	/* SF */
+  outl(csr6, ioaddr + CSR6);
+
+  if (vendor == PCI_VENDOR_ID_DAVICOM && dev_id == PCI_DEVICE_ID_DM9009) {
+    /* Set to 10BaseT mode for DM9009 */
+    phy_write(0, 0);
+  } else {
+    /* For DM9102/DM9102A */
+    to = currticks() + 2 * TICKS_PER_SEC;
+    while ( ((phy_read(1) & 0x24)!=0x24) && (currticks() < to))
+      /* wait */ ;
+
+    if ( (phy_read(1) & 0x24) == 0x24 ) {
+      if (phy_read(17) & 0xa000)  
+        csr6 |= 0x00000200;	/* Full Duplex mode */
+    } else
+      csr6 |= 0x00040000; /* Select DM9801/DM9802 when Ethernet link failed */
+  }
+
+  /* set the chip's operating mode */
+  outl(csr6, ioaddr + CSR6);
+
+  /* DM9801/DM9802 present check & program */
+  if (csr6 & 0x40000)
+    HPNA_process();
+}
+
+
+/*********************************************************************/
+/* EEPROM Reading Code                                               */
+/*********************************************************************/
+/* EEPROM routines adapted from the Linux Tulip Code */
+/* Reading a serial EEPROM is a "bit" grungy, but we work our way
+   through:->.
+*/
+static int read_eeprom(unsigned long ioaddr, int location, int addr_len)
+{
+  int i;
+  unsigned short retval = 0;
+  long ee_addr = ioaddr + CSR9;
+  int read_cmd = location | EE_READ_CMD;
+
+  whereami("read_eeprom\n");
+
+  outl(EE_ENB & ~EE_CS, ee_addr);
+  outl(EE_ENB, ee_addr);
+
+  /* Shift the read command bits out. */
+  for (i = 4 + addr_len; i >= 0; i--) {
+    short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+    outl(EE_ENB | dataval, ee_addr);
+    eeprom_delay();
+    outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+    eeprom_delay();
+  }
+  outl(EE_ENB, ee_addr);
+
+  for (i = 16; i > 0; i--) {
+    outl(EE_ENB | EE_SHIFT_CLK, ee_addr);
+    eeprom_delay();
+    retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
+    outl(EE_ENB, ee_addr);
+    eeprom_delay();
+  }
+
+  /* Terminate the EEPROM access. */
+  outl(EE_ENB & ~EE_CS, ee_addr);
+  return retval;
+}
+
+/*********************************************************************/
+/* davicom_init_chain - setup the tx and rx descriptors                */
+/* Sten 10/9							     */
+/*********************************************************************/
+static void davicom_init_chain(struct nic *nic)
+{
+  int i;
+
+  /* setup the transmit descriptor */
+  /* Sten: Set 2 TX descriptor but use one TX buffer because
+	   it transmit a packet and wait complete every time. */
+  for (i=0; i<NTXD; i++) {
+    txd[i].buf1addr = &txb[0];		/* Used same TX buffer */
+    txd[i].buf2addr = (unsigned char *)&txd[i+1]; /*  Point to Next TX desc */
+    txd[i].buf1sz   = 0;
+    txd[i].buf2sz   = 0;
+    txd[i].control  = 0x184;           /* Begin/End/Chain */
+    txd[i].status   = 0x00000000;      /* give ownership to Host */
+  }
+
+  /* construct perfect filter frame with mac address as first match
+     and broadcast address for all others */
+  for (i=0; i<192; i++) txb[i] = 0xFF;
+  txb[0] = nic->node_addr[0];
+  txb[1] = nic->node_addr[1];
+  txb[4] = nic->node_addr[2];
+  txb[5] = nic->node_addr[3];
+  txb[8] = nic->node_addr[4];
+  txb[9] = nic->node_addr[5];
+
+  /* setup receive descriptor */
+  for (i=0; i<NRXD; i++) {
+    rxd[i].buf1addr = &rxb[i * BUFLEN];
+    rxd[i].buf2addr = (unsigned char *)&rxd[i+1]; /* Point to Next RX desc */
+    rxd[i].buf1sz   = BUFLEN;
+    rxd[i].buf2sz   = 0;        /* not used */
+    rxd[i].control  = 0x4;		/* Chain Structure */
+    rxd[i].status   = 0x80000000;   /* give ownership to device */
+  }
+
+  /* Chain the last descriptor to first */
+  txd[NTXD - 1].buf2addr = (unsigned char *)&txd[0];
+  rxd[NRXD - 1].buf2addr = (unsigned char *)&rxd[0];
+  TxPtr = 0;
+  rxd_tail = 0;
+}
+
+
+/*********************************************************************/
+/* davicom_reset - Reset adapter                                         */
+/*********************************************************************/
+static void davicom_reset(struct nic *nic)
+{
+  unsigned long to;
+  u32 addr_low, addr_high;
+
+  whereami("davicom_reset\n");
+
+  /* Stop Tx and RX */
+  outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
+
+  /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
+  outl(0x00000001, ioaddr + CSR0);
+
+  davicom_wait(TICKS_PER_SEC);
+
+  /* TX/RX descriptor burst */
+  outl(0x0C00000, ioaddr + CSR0);	/* Sten 10/9 */
+
+  /* set up transmit and receive descriptors */
+  davicom_init_chain(nic);	/* Sten 10/9 */
+
+  /* Point to receive descriptor */
+  outl((unsigned long)&rxd[0], ioaddr + CSR3);
+  outl((unsigned long)&txd[0], ioaddr + CSR4);	/* Sten 10/9 */
+
+  /* According phyxcer media mode to set CR6,
+     DM9102/A phyxcer can auto-detect media mode */
+  davicom_media_chk(nic);
+
+  /* Prepare Setup Frame Sten 10/9 */
+  txd[TxPtr].buf1sz = 192;
+  txd[TxPtr].control = 0x024;		/* SF/CE */
+  txd[TxPtr].status = 0x80000000;	/* Give ownership to device */
+
+  /* Start Tx */
+  outl(inl(ioaddr + CSR6) | 0x00002000, ioaddr + CSR6);
+  /* immediate transmit demand */
+  outl(0, ioaddr + CSR1);
+
+  to = currticks() + TX_TIME_OUT;
+  while ((txd[TxPtr].status & 0x80000000) && (currticks() < to)) /* Sten 10/9 */
+    /* wait */ ;
+
+  if (currticks() >= to) {
+    printf ("TX Setup Timeout!\n");
+  }
+  /* Point to next TX descriptor */
+ TxPtr = (++TxPtr >= NTXD) ? 0:TxPtr;	/* Sten 10/9 */
+
+#ifdef DAVICOM_DEBUG
+  printf("txd.status = %X\n", txd.status);
+  printf("ticks = %d\n", currticks() - (to - TX_TIME_OUT));
+  davicom_more();
+#endif
+
+  /* enable RX */
+  outl(inl(ioaddr + CSR6) | 0x00000002, ioaddr + CSR6);
+  /* immediate poll demand */
+  outl(0, ioaddr + CSR2);
+}
+
+
+/*********************************************************************/
+/* eth_transmit - Transmit a frame                                   */
+/*********************************************************************/
+static void davicom_transmit(struct nic *nic, const char *d, unsigned int t,
+                           unsigned int s, const char *p)
+{
+  unsigned long to;
+
+  whereami("davicom_transmit\n");
+
+  /* Stop Tx */
+  /* outl(inl(ioaddr + CSR6) & ~0x00002000, ioaddr + CSR6); */
+
+  /* setup ethernet header */
+  memcpy(&txb[0], d, ETH_ALEN);	/* DA 6byte */
+  memcpy(&txb[ETH_ALEN], nic->node_addr, ETH_ALEN); /* SA 6byte*/
+  txb[ETH_ALEN*2] = (t >> 8) & 0xFF; /* Frame type: 2byte */
+  txb[ETH_ALEN*2+1] = t & 0xFF;
+  memcpy(&txb[ETH_HLEN], p, s); /* Frame data */
+
+  /* setup the transmit descriptor */
+  txd[TxPtr].buf1sz   = ETH_HLEN+s;
+  txd[TxPtr].control  = 0x00000184;      /* LS+FS+CE */
+  txd[TxPtr].status   = 0x80000000;      /* give ownership to device */
+
+  /* immediate transmit demand */
+  outl(0, ioaddr + CSR1);
+
+  to = currticks() + TX_TIME_OUT;
+  while ((txd[TxPtr].status & 0x80000000) && (currticks() < to))
+    /* wait */ ;
+
+  if (currticks() >= to) {
+    printf ("TX Timeout!\n");
+  }
+ 
+  /* Point to next TX descriptor */
+  TxPtr = (++TxPtr >= NTXD) ? 0:TxPtr;	/* Sten 10/9 */
+
+}
+
+/*********************************************************************/
+/* eth_poll - Wait for a frame                                       */
+/*********************************************************************/
+static int davicom_poll(struct nic *nic)
+{
+  whereami("davicom_poll\n");
+
+  if (rxd[rxd_tail].status & 0x80000000)
+    return 0;
+
+  whereami("davicom_poll got one\n");
+
+  nic->packetlen = (rxd[rxd_tail].status & 0x3FFF0000) >> 16;
+
+  if( rxd[rxd_tail].status & 0x00008000){
+      rxd[rxd_tail].status = 0x80000000;
+      rxd_tail++;
+      if (rxd_tail == NRXD) rxd_tail = 0;
+      return 0;
+  }
+
+  /* copy packet to working buffer */
+  /* XXX - this copy could be avoided with a little more work
+     but for now we are content with it because the optimised
+     memcpy is quite fast */
+
+  memcpy(nic->packet, rxb + rxd_tail * BUFLEN, nic->packetlen);
+
+  /* return the descriptor and buffer to receive ring */
+  rxd[rxd_tail].status = 0x80000000;
+  rxd_tail++;
+  if (rxd_tail == NRXD) rxd_tail = 0;
+
+  return 1;
+}
+
+/*********************************************************************/
+/* eth_disable - Disable the interface                               */
+/*********************************************************************/
+static void davicom_disable(struct nic *nic)
+{
+  whereami("davicom_disable\n");
+
+  /* disable interrupts */
+  outl(0x00000000, ioaddr + CSR7);
+
+  /* Stop the chip's Tx and Rx processes. */
+  outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
+
+  /* Clear the missed-packet counter. */
+  (volatile unsigned long)inl(ioaddr + CSR8);
+}
+
+/*********************************************************************/
+/* eth_probe - Look for an adapter                                   */
+/*********************************************************************/
+struct nic *davicom_probe(struct nic *nic, unsigned short *io_addrs,
+                          struct pci_device *pci)
+{
+  unsigned int i;
+  u32 l1, l2;
+
+  whereami("davicom_probe\n");
+
+  if (io_addrs == 0 || *io_addrs == 0)
+    return 0;
+
+  vendor  = pci->vendor;
+  dev_id  = pci->dev_id;
+  ioaddr  = *io_addrs;
+
+  /* wakeup chip */
+  pcibios_write_config_dword(pci->bus, pci->devfn, 0x40, 0x00000000);
+
+  /* Stop the chip's Tx and Rx processes. */
+  outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
+
+  /* Clear the missed-packet counter. */
+  (volatile unsigned long)inl(ioaddr + CSR8);
+
+  /* Get MAC Address */
+  /* read EEPROM data */
+  for (i = 0; i < sizeof(ee_data)/2; i++)
+    ((unsigned short *)ee_data)[i] =
+        le16_to_cpu(read_eeprom(ioaddr, i, EEPROM_ADDRLEN));
+
+  /* extract MAC address from EEPROM buffer */
+  for (i=0; i<ETH_ALEN; i++)
+    nic->node_addr[i] = ee_data[20+i];
+
+  printf("Davicom %! at ioaddr %#hX\n", nic->node_addr, ioaddr);
+
+  /* initialize device */
+  davicom_reset(nic);
+
+  nic->reset    = davicom_reset;
+  nic->poll     = davicom_poll;
+  nic->transmit = davicom_transmit;
+  nic->disable  = davicom_disable;
+
+  return nic;
+}
diff --git a/netboot/depca.c b/netboot/depca.c
new file mode 100644
index 0000000..120520b
--- /dev/null
+++ b/netboot/depca.c
@@ -0,0 +1,752 @@
+/* Etherboot: depca.h merged, comments from Linux driver retained */
+/*  depca.c: A DIGITAL DEPCA  & EtherWORKS ethernet driver for linux.
+
+    Written 1994, 1995 by David C. Davies.
+
+
+                      Copyright 1994 David C. Davies
+		                   and 
+			 United States Government
+	 (as represented by the Director, National Security Agency).  
+
+               Copyright 1995  Digital Equipment Corporation.
+
+
+    This software may be used and distributed according to the terms of
+    the GNU Public License, incorporated herein by reference.
+
+    This driver is written for the Digital Equipment Corporation series
+    of DEPCA and EtherWORKS ethernet cards:
+
+        DEPCA       (the original)
+    	DE100
+    	DE101
+	DE200 Turbo
+	DE201 Turbo
+	DE202 Turbo (TP BNC)
+	DE210
+	DE422       (EISA)
+
+    The  driver has been tested on DE100, DE200 and DE202 cards  in  a
+    relatively busy network. The DE422 has been tested a little.
+
+    This  driver will NOT work   for the DE203,  DE204  and DE205 series  of
+    cards,  since they have  a  new custom ASIC in   place of the AMD  LANCE
+    chip.  See the 'ewrk3.c'   driver in the  Linux  source tree for running
+    those cards.
+
+    I have benchmarked the driver with a  DE100 at 595kB/s to (542kB/s from)
+    a DECstation 5000/200.
+
+    The author may be reached at davies@maniac.ultranet.com
+
+    =========================================================================
+
+    The  driver was originally based  on   the 'lance.c' driver from  Donald
+    Becker   which  is included with  the  standard  driver distribution for
+    linux.  V0.4  is  a complete  re-write  with only  the kernel  interface
+    remaining from the original code.
+
+    1) Lance.c code in /linux/drivers/net/
+    2) "Ethernet/IEEE 802.3 Family. 1992 World Network Data Book/Handbook",
+       AMD, 1992 [(800) 222-9323].
+    3) "Am79C90 CMOS Local Area Network Controller for Ethernet (C-LANCE)",
+       AMD, Pub. #17881, May 1993.
+    4) "Am79C960 PCnet-ISA(tm), Single-Chip Ethernet Controller for ISA",
+       AMD, Pub. #16907, May 1992
+    5) "DEC EtherWORKS LC Ethernet Controller Owners Manual",
+       Digital Equipment corporation, 1990, Pub. #EK-DE100-OM.003
+    6) "DEC EtherWORKS Turbo Ethernet Controller Owners Manual",
+       Digital Equipment corporation, 1990, Pub. #EK-DE200-OM.003
+    7) "DEPCA Hardware Reference Manual", Pub. #EK-DEPCA-PR
+       Digital Equipment Corporation, 1989
+    8) "DEC EtherWORKS Turbo_(TP BNC) Ethernet Controller Owners Manual",
+       Digital Equipment corporation, 1991, Pub. #EK-DE202-OM.001
+    
+
+    Peter Bauer's depca.c (V0.5) was referred to when debugging V0.1 of this
+    driver.
+
+    The original DEPCA  card requires that the  ethernet ROM address counter
+    be enabled to count and has an 8 bit NICSR.  The ROM counter enabling is
+    only  done when a  0x08 is read as the  first address octet (to minimise
+    the chances  of writing over some  other hardware's  I/O register).  The
+    NICSR accesses   have been changed  to  byte accesses  for all the cards
+    supported by this driver, since there is only one  useful bit in the MSB
+    (remote boot timeout) and it  is not used.  Also, there  is a maximum of
+    only 48kB network  RAM for this  card.  My thanks  to Torbjorn Lindh for
+    help debugging all this (and holding my feet to  the fire until I got it
+    right).
+
+    The DE200  series  boards have  on-board 64kB  RAM for  use  as a shared
+    memory network  buffer. Only the DE100  cards make use  of a  2kB buffer
+    mode which has not  been implemented in  this driver (only the 32kB  and
+    64kB modes are supported [16kB/48kB for the original DEPCA]).
+
+    At the most only 2 DEPCA cards can  be supported on  the ISA bus because
+    there is only provision  for two I/O base addresses  on each card (0x300
+    and 0x200). The I/O address is detected by searching for a byte sequence
+    in the Ethernet station address PROM at the expected I/O address for the
+    Ethernet  PROM.   The shared memory  base   address  is 'autoprobed'  by
+    looking  for the self  test PROM  and detecting the  card name.   When a
+    second  DEPCA is  detected,  information  is   placed in the   base_addr
+    variable of the  next device structure (which  is created if necessary),
+    thus  enabling ethif_probe  initialization  for the device.  More than 2
+    EISA cards can  be  supported, but  care will  be  needed assigning  the
+    shared memory to ensure that each slot has the  correct IRQ, I/O address
+    and shared memory address assigned.
+
+    ************************************************************************
+
+    NOTE: If you are using two  ISA DEPCAs, it is  important that you assign
+    the base memory addresses correctly.   The  driver autoprobes I/O  0x300
+    then 0x200.  The  base memory address for  the first device must be less
+    than that of the second so that the auto probe will correctly assign the
+    I/O and memory addresses on the same card.  I can't think of a way to do
+    this unambiguously at the moment, since there is nothing on the cards to
+    tie I/O and memory information together.
+
+    I am unable  to  test  2 cards   together for now,    so this  code   is
+    unchecked. All reports, good or bad, are welcome.
+
+    ************************************************************************
+
+    The board IRQ   setting must be  at an  unused IRQ which  is auto-probed
+    using Donald Becker's autoprobe routines. DEPCA and DE100 board IRQs are
+    {2,3,4,5,7}, whereas the  DE200 is at {5,9,10,11,15}.  Note that IRQ2 is
+    really IRQ9 in machines with 16 IRQ lines.
+
+    No 16MB memory  limitation should exist with this  driver as DMA is  not
+    used and the common memory area is in low memory on the network card (my
+    current system has 20MB and I've not had problems yet).
+
+    The ability to load this driver as a loadable module has been added. To
+    utilise this ability, you have to do <8 things:
+
+    0) have a copy of the loadable modules code installed on your system.
+    1) copy depca.c from the  /linux/drivers/net directory to your favourite
+    temporary directory.
+    2) if you wish, edit the  source code near  line 1530 to reflect the I/O
+    address and IRQ you're using (see also 5).
+    3) compile  depca.c, but include -DMODULE in  the command line to ensure
+    that the correct bits are compiled (see end of source code).
+    4) if you are wanting to add a new  card, goto 5. Otherwise, recompile a
+    kernel with the depca configuration turned off and reboot.
+    5) insmod depca.o [irq=7] [io=0x200] [mem=0xd0000] [adapter_name=DE100]
+       [Alan Cox: Changed the code to allow command line irq/io assignments]
+       [Dave Davies: Changed the code to allow command line mem/name
+                                                                assignments]
+    6) run the net startup bits for your eth?? interface manually 
+    (usually /etc/rc.inet[12] at boot time). 
+    7) enjoy!
+
+    Note that autoprobing is not allowed in loadable modules - the system is
+    already up and running and you're messing with interrupts.
+
+    To unload a module, turn off the associated interface 
+    'ifconfig eth?? down' then 'rmmod depca'.
+
+    To assign a base memory address for the shared memory  when running as a
+    loadable module, see 5 above.  To include the adapter  name (if you have
+    no PROM  but know the card name)  also see 5  above. Note that this last
+    option  will not work  with kernel  built-in  depca's. 
+
+    The shared memory assignment for a loadable module  makes sense to avoid
+    the 'memory autoprobe' picking the wrong shared memory  (for the case of
+    2 depca's in a PC).
+
+    ************************************************************************
+    Support for MCA EtherWORKS cards added 11-3-98.
+    Verified to work with up to 2 DE212 cards in a system (although not
+      fully stress-tested).  
+
+    Currently known bugs/limitations:
+
+    Note:  with the MCA stuff as a module, it trusts the MCA configuration,
+           not the command line for IRQ and memory address.  You can
+           specify them if you want, but it will throw your values out.
+           You still have to pass the IO address it was configured as
+           though.
+
+    ************************************************************************
+    TO DO:
+    ------
+
+
+    Revision History
+    ----------------
+
+    Version   Date        Description
+  
+      0.1     25-jan-94   Initial writing.
+      0.2     27-jan-94   Added LANCE TX hardware buffer chaining.
+      0.3      1-feb-94   Added multiple DEPCA support.
+      0.31     4-feb-94   Added DE202 recognition.
+      0.32    19-feb-94   Tidy up. Improve multi-DEPCA support.
+      0.33    25-feb-94   Fix DEPCA ethernet ROM counter enable.
+                          Add jabber packet fix from murf@perftech.com
+			  and becker@super.org
+      0.34     7-mar-94   Fix DEPCA max network memory RAM & NICSR access.
+      0.35     8-mar-94   Added DE201 recognition. Tidied up.
+      0.351   30-apr-94   Added EISA support. Added DE422 recognition.
+      0.36    16-may-94   DE422 fix released.
+      0.37    22-jul-94   Added MODULE support
+      0.38    15-aug-94   Added DBR ROM switch in depca_close(). 
+                          Multi DEPCA bug fix.
+      0.38axp 15-sep-94   Special version for Alpha AXP Linux V1.0.
+      0.381   12-dec-94   Added DE101 recognition, fix multicast bug.
+      0.382    9-feb-95   Fix recognition bug reported by <bkm@star.rl.ac.uk>.
+      0.383   22-feb-95   Fix for conflict with VESA SCSI reported by
+                          <stromain@alf.dec.com>
+      0.384   17-mar-95   Fix a ring full bug reported by <bkm@star.rl.ac.uk>
+      0.385    3-apr-95   Fix a recognition bug reported by 
+                                                <ryan.niemi@lastfrontier.com>
+      0.386   21-apr-95   Fix the last fix...sorry, must be galloping senility
+      0.40    25-May-95   Rewrite for portability & updated.
+                          ALPHA support from <jestabro@amt.tay1.dec.com>
+      0.41    26-Jun-95   Added verify_area() calls in depca_ioctl() from
+                          suggestion by <heiko@colossus.escape.de>
+      0.42    27-Dec-95   Add 'mem' shared memory assignment for loadable 
+                          modules.
+                          Add 'adapter_name' for loadable modules when no PROM.
+			  Both above from a suggestion by 
+			  <pchen@woodruffs121.residence.gatech.edu>.
+			  Add new multicasting code.
+      0.421   22-Apr-96	  Fix alloc_device() bug <jari@markkus2.fimr.fi>
+      0.422   29-Apr-96	  Fix depca_hw_init() bug <jari@markkus2.fimr.fi>
+      0.423    7-Jun-96   Fix module load bug <kmg@barco.be>
+      0.43    16-Aug-96   Update alloc_device() to conform to de4x5.c
+      0.44     1-Sep-97   Fix *_probe() to test check_region() first - bug
+                           reported by <mmogilvi@elbert.uccs.edu>
+      0.45     3-Nov-98   Added support for MCA EtherWORKS (DE210/DE212) cards
+                           by <tymm@computer.org> 
+      0.451    5-Nov-98   Fixed mca stuff cuz I'm a dummy. <tymm@computer.org>
+      0.5     14-Nov-98   Re-spin for 2.1.x kernels.
+      0.51    27-Jun-99   Correct received packet length for CRC from
+                           report by <worm@dkik.dk>
+
+    =========================================================================
+*/
+
+#include "etherboot.h"
+#include "nic.h"
+#include "cards.h"
+
+/*
+** I/O addresses. Note that the 2k buffer option is not supported in
+** this driver.
+*/
+#define DEPCA_NICSR ioaddr+0x00   /* Network interface CSR */
+#define DEPCA_RBI   ioaddr+0x02   /* RAM buffer index (2k buffer mode) */
+#define DEPCA_DATA  ioaddr+0x04   /* LANCE registers' data port */
+#define DEPCA_ADDR  ioaddr+0x06   /* LANCE registers' address port */
+#define DEPCA_HBASE ioaddr+0x08   /* EISA high memory base address reg. */
+#define DEPCA_PROM  ioaddr+0x0c   /* Ethernet address ROM data port */
+#define DEPCA_CNFG  ioaddr+0x0c   /* EISA Configuration port */
+#define DEPCA_RBSA  ioaddr+0x0e   /* RAM buffer starting address (2k buff.) */
+
+/*
+** These are LANCE registers addressable through DEPCA_ADDR 
+*/
+#define CSR0       0
+#define CSR1       1
+#define CSR2       2
+#define CSR3       3
+
+/* 
+** NETWORK INTERFACE CSR (NI_CSR) bit definitions 
+*/
+ 
+#define TO       	0x0100	/* Time Out for remote boot */
+#define SHE      	0x0080  /* SHadow memory Enable */
+#define BS       	0x0040  /* Bank Select */
+#define BUF      	0x0020	/* BUFfer size (1->32k, 0->64k) */
+#define RBE      	0x0010	/* Remote Boot Enable (1->net boot) */
+#define AAC      	0x0008  /* Address ROM Address Counter (1->enable) */
+#define _128KB      	0x0008  /* 128kB Network RAM (1->enable) */
+#define IM       	0x0004	/* Interrupt Mask (1->mask) */
+#define IEN      	0x0002	/* Interrupt tristate ENable (1->enable) */
+#define LED      	0x0001	/* LED control */
+
+/* 
+** Control and Status Register 0 (CSR0) bit definitions 
+*/
+
+#define ERR     	0x8000 	/* Error summary */
+#define BABL    	0x4000 	/* Babble transmitter timeout error  */
+#define CERR    	0x2000 	/* Collision Error */
+#define MISS    	0x1000 	/* Missed packet */
+#define MERR    	0x0800 	/* Memory Error */
+#define RINT    	0x0400 	/* Receiver Interrupt */
+#define TINT    	0x0200 	/* Transmit Interrupt */
+#define IDON    	0x0100 	/* Initialization Done */
+#define INTR    	0x0080 	/* Interrupt Flag */
+#define INEA    	0x0040 	/* Interrupt Enable */
+#define RXON    	0x0020 	/* Receiver on */
+#define TXON    	0x0010 	/* Transmitter on */
+#define TDMD    	0x0008 	/* Transmit Demand */
+#define STOP    	0x0004 	/* Stop */
+#define STRT    	0x0002 	/* Start */
+#define INIT    	0x0001 	/* Initialize */
+#define INTM            0xff00  /* Interrupt Mask */
+#define INTE            0xfff0  /* Interrupt Enable */
+
+/*
+** CONTROL AND STATUS REGISTER 3 (CSR3)
+*/
+
+#define BSWP    	0x0004	/* Byte SWaP */
+#define ACON    	0x0002	/* ALE control */
+#define BCON    	0x0001	/* Byte CONtrol */
+
+/*
+** Initialization Block Mode Register 
+*/
+
+#define PROM       	0x8000 	/* Promiscuous Mode */
+#define EMBA       	0x0080	/* Enable Modified Back-off Algorithm */
+#define INTL       	0x0040 	/* Internal Loopback */
+#define DRTY       	0x0020 	/* Disable Retry */
+#define COLL       	0x0010 	/* Force Collision */
+#define DTCR       	0x0008 	/* Disable Transmit CRC */
+#define LOOP       	0x0004 	/* Loopback */
+#define DTX        	0x0002 	/* Disable the Transmitter */
+#define DRX        	0x0001 	/* Disable the Receiver */
+
+/*
+** Receive Message Descriptor 1 (RMD1) bit definitions. 
+*/
+
+#define R_OWN       0x80000000 	/* Owner bit 0 = host, 1 = lance */
+#define R_ERR     	0x4000 	/* Error Summary */
+#define R_FRAM    	0x2000 	/* Framing Error */
+#define R_OFLO    	0x1000 	/* Overflow Error */
+#define R_CRC     	0x0800 	/* CRC Error */
+#define R_BUFF    	0x0400 	/* Buffer Error */
+#define R_STP     	0x0200 	/* Start of Packet */
+#define R_ENP     	0x0100 	/* End of Packet */
+
+/*
+** Transmit Message Descriptor 1 (TMD1) bit definitions. 
+*/
+
+#define T_OWN       0x80000000 	/* Owner bit 0 = host, 1 = lance */
+#define T_ERR     	0x4000 	/* Error Summary */
+#define T_ADD_FCS 	0x2000 	/* More the 1 retry needed to Xmit */
+#define T_MORE    	0x1000	/* >1 retry to transmit packet */
+#define T_ONE     	0x0800 	/* 1 try needed to transmit the packet */
+#define T_DEF     	0x0400 	/* Deferred */
+#define T_STP       0x02000000 	/* Start of Packet */
+#define T_ENP       0x01000000	/* End of Packet */
+#define T_FLAGS     0xff000000  /* TX Flags Field */
+
+/*
+** Transmit Message Descriptor 3 (TMD3) bit definitions.
+*/
+
+#define TMD3_BUFF    0x8000	/* BUFFer error */
+#define TMD3_UFLO    0x4000	/* UnderFLOw error */
+#define TMD3_RES     0x2000	/* REServed */
+#define TMD3_LCOL    0x1000	/* Late COLlision */
+#define TMD3_LCAR    0x0800	/* Loss of CARrier */
+#define TMD3_RTRY    0x0400	/* ReTRY error */
+
+/*
+** Ethernet PROM defines
+*/
+#define PROBE_LENGTH    32
+
+/*
+** Set the number of Tx and Rx buffers. Ensure that the memory requested
+** here is <= to the amount of shared memory set up by the board switches.
+** The number of descriptors MUST BE A POWER OF 2.
+**
+** total_memory = NUM_RX_DESC*(8+RX_BUFF_SZ) + NUM_TX_DESC*(8+TX_BUFF_SZ)
+*/
+#define NUM_RX_DESC     2               /* Number of RX descriptors */
+#define NUM_TX_DESC     2               /* Number of TX descriptors */
+#define RX_BUFF_SZ	1536            /* Buffer size for each Rx buffer */
+#define TX_BUFF_SZ	1536            /* Buffer size for each Tx buffer */
+
+/*
+** ISA Bus defines
+*/
+#define DEPCA_IO_PORTS	{0x300, 0x200, 0}
+
+#ifndef	DEPCA_MODEL
+#define	DEPCA_MODEL	DEPCA
+#endif
+
+static enum {
+	DEPCA, DE100, DE101, DE200, DE201, DE202, DE210, DE212, DE422, unknown
+} adapter = DEPCA_MODEL;
+
+/*
+** Name <-> Adapter mapping
+*/
+
+static char *adapter_name[] = {
+	"DEPCA",
+	"DE100","DE101",
+	"DE200","DE201","DE202",
+	"DE210","DE212",
+	"DE422",
+	""
+};
+
+#ifndef	DEPCA_RAM_BASE
+#define DEPCA_RAM_BASE	0xd0000
+#endif
+
+/*
+** Memory Alignment. Each descriptor is 4 longwords long. To force a
+** particular alignment on the TX descriptor, adjust DESC_SKIP_LEN and
+** DESC_ALIGN. ALIGN aligns the start address of the private memory area
+** and hence the RX descriptor ring's first entry. 
+*/
+#define ALIGN4      ((u32)4 - 1)       /* 1 longword align */
+#define ALIGN8      ((u32)8 - 1)       /* 2 longword (quadword) align */
+#define ALIGN         ALIGN8              /* Keep the LANCE happy... */
+
+typedef	long		s32;
+typedef	unsigned long	u32;
+typedef	short		s16;
+typedef	unsigned short	u16;
+typedef	char		s8;
+typedef	unsigned char	u8;
+
+/*
+** The DEPCA Rx and Tx ring descriptors. 
+*/
+struct depca_rx_desc {
+    volatile s32 base;
+    s16 buf_length;		/* This length is negative 2's complement! */
+    s16 msg_length;		/* This length is "normal". */
+};
+
+struct depca_tx_desc {
+    volatile s32 base;
+    s16 length;		        /* This length is negative 2's complement! */
+    s16 misc;                   /* Errors and TDR info */
+};
+
+#define LA_MASK 0x0000ffff      /* LANCE address mask for mapping network RAM
+				   to LANCE memory address space */
+
+/*
+** The Lance initialization block, described in databook, in common memory.
+*/
+struct depca_init {
+    u16 mode;	                /* Mode register */
+    u8  phys_addr[ETH_ALEN];	/* Physical ethernet address */
+    u8  mcast_table[8];	        /* Multicast Hash Table. */
+    u32 rx_ring;     	        /* Rx ring base pointer & ring length */
+    u32 tx_ring;	        /* Tx ring base pointer & ring length */
+};
+
+struct depca_private {
+	struct depca_rx_desc	*rx_ring;
+	struct depca_tx_desc	*tx_ring;
+	struct depca_init	init_block;	/* Shadow init block */
+	char			*rx_memcpy[NUM_RX_DESC];
+	char			*tx_memcpy[NUM_TX_DESC];
+	u32			bus_offset;	/* ISA bus address offset */
+	u32			sh_mem;		/* address of shared mem */
+	u32			dma_buffs;	/* Rx & Tx buffer start */
+	int			rx_cur, tx_cur;	/* Next free ring entry */
+	int			txRingMask, rxRingMask;
+	s32			rx_rlen, tx_rlen;
+	/* log2([rt]xRingMask+1) for the descriptors */
+};
+
+static Address		mem_start = DEPCA_RAM_BASE;
+static Address		mem_len, offset;
+static unsigned short	ioaddr = 0;
+static struct depca_private	lp;
+
+/*
+** Miscellaneous defines...
+*/
+#define STOP_DEPCA \
+    outw(CSR0, DEPCA_ADDR);\
+    outw(STOP, DEPCA_DATA)
+
+/* Initialize the lance Rx and Tx descriptor rings. */
+static void depca_init_ring(struct nic *nic)
+{
+	int	i;
+	u32	p;
+
+	lp.rx_cur = lp.tx_cur = 0;
+	/* Initialize the base addresses and length of each buffer in the ring */
+	for (i = 0; i <= lp.rxRingMask; i++) {
+		writel((p = lp.dma_buffs + i * RX_BUFF_SZ) | R_OWN, &lp.rx_ring[i].base);
+		writew(-RX_BUFF_SZ, &lp.rx_ring[i].buf_length);
+		lp.rx_memcpy[i] = (char *) (p + lp.bus_offset);
+	}
+	for (i = 0; i <= lp.txRingMask; i++) {
+		writel((p = lp.dma_buffs + (i + lp.txRingMask + 1) * TX_BUFF_SZ) & 0x00ffffff, &lp.tx_ring[i].base);
+		lp.tx_memcpy[i] = (char *) (p + lp.bus_offset);
+	}
+
+	/* Set up the initialization block */
+	lp.init_block.rx_ring = ((u32) ((u32) lp.rx_ring) & LA_MASK) | lp.rx_rlen;
+	lp.init_block.tx_ring = ((u32) ((u32) lp.tx_ring) & LA_MASK) | lp.tx_rlen;
+	for (i = 0; i < ETH_ALEN; i++)
+		lp.init_block.phys_addr[i] = nic->node_addr[i];
+	lp.init_block.mode = 0x0000;	/* Enable the Tx and Rx */
+	memset(lp.init_block.mcast_table, 0, sizeof(lp.init_block.mcast_table));
+}
+
+static void LoadCSRs(void)
+{
+	outw(CSR1, DEPCA_ADDR);	/* initialisation block address LSW */
+	outw((u16) (lp.sh_mem & LA_MASK), DEPCA_DATA);
+	outw(CSR2, DEPCA_ADDR);	/* initialisation block address MSW */
+	outw((u16) ((lp.sh_mem & LA_MASK) >> 16), DEPCA_DATA);
+	outw(CSR3, DEPCA_ADDR);	/* ALE control */
+	outw(ACON, DEPCA_DATA);
+	outw(CSR0, DEPCA_ADDR);	/* Point back to CSR0 */
+}
+
+static int InitRestartDepca(void)
+{
+	int		i;
+
+	/* Copy the shadow init_block to shared memory */
+	memcpy_toio((char *)lp.sh_mem, &lp.init_block, sizeof(struct depca_init));
+	outw(CSR0, DEPCA_ADDR);		/* point back to CSR0 */
+	outw(INIT, DEPCA_DATA);		/* initialise DEPCA */
+
+	for (i = 0; i < 100 && !(inw(DEPCA_DATA) & IDON); i++)
+		;
+	if (i < 100) {
+		/* clear IDON by writing a 1, and start LANCE */
+		outw(IDON | STRT, DEPCA_DATA);
+	} else {
+		printf("DEPCA not initialised\n");
+		return (1);
+	}
+	return (0);
+}
+
+/**************************************************************************
+RESET - Reset adapter
+***************************************************************************/
+static void depca_reset(struct nic *nic)
+{
+	s16	nicsr;
+	int	i, j;
+
+	STOP_DEPCA;
+	nicsr = inb(DEPCA_NICSR);
+	nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | IM);
+	outb(nicsr, DEPCA_NICSR);
+	if (inw(DEPCA_DATA) != STOP)
+	{
+		printf("depca: Cannot stop NIC\n");
+		return;
+	}
+
+	/* Initialisation block */
+	lp.sh_mem = mem_start;
+	mem_start += sizeof(struct depca_init);
+	/* Tx & Rx descriptors (aligned to a quadword boundary) */
+	mem_start = (mem_start + ALIGN) & ~ALIGN;
+	lp.rx_ring = (struct depca_rx_desc *) mem_start;
+	mem_start += (sizeof(struct depca_rx_desc) * NUM_RX_DESC);
+	lp.tx_ring = (struct depca_tx_desc *) mem_start;
+	mem_start += (sizeof(struct depca_tx_desc) * NUM_TX_DESC);
+
+	lp.bus_offset = mem_start & 0x00ff0000;
+	/* LANCE re-mapped start address */
+	lp.dma_buffs = mem_start & LA_MASK;
+
+	/* Finish initialising the ring information. */
+	lp.rxRingMask = NUM_RX_DESC - 1;
+	lp.txRingMask = NUM_TX_DESC - 1;
+
+	/* Calculate Tx/Rx RLEN size for the descriptors. */
+	for (i = 0, j = lp.rxRingMask; j > 0; i++) {
+		j >>= 1;
+	}
+	lp.rx_rlen = (s32) (i << 29);
+	for (i = 0, j = lp.txRingMask; j > 0; i++) {
+		j >>= 1;
+	}
+	lp.tx_rlen = (s32) (i << 29);
+
+	/* Load the initialisation block */
+	depca_init_ring(nic);
+	LoadCSRs();
+	InitRestartDepca();
+}
+
+/**************************************************************************
+POLL - Wait for a frame
+***************************************************************************/
+static int depca_poll(struct nic *nic)
+{
+	int		entry;
+	u32		status;
+
+	entry = lp.rx_cur;
+	if ((status = readl(&lp.rx_ring[entry].base) & R_OWN))
+		return (0);
+	memcpy(nic->packet, lp.rx_memcpy[entry], nic->packetlen = lp.rx_ring[entry].msg_length);
+	lp.rx_ring[entry].base |= R_OWN;
+	lp.rx_cur = (++lp.rx_cur) & lp.rxRingMask;
+	return (1);
+}
+
+/**************************************************************************
+TRANSMIT - Transmit a frame
+***************************************************************************/
+static void depca_transmit(
+	struct nic *nic,
+	const char *d,			/* Destination */
+	unsigned int t,			/* Type */
+	unsigned int s,			/* size */
+	const char *p)			/* Packet */
+{
+	int		entry, len;
+	char		*mem;
+
+	/* send the packet to destination */
+	/*
+	** Caution: the right order is important here... dont
+	** setup the ownership rights until all the other
+	** information is in place
+	*/
+	mem = lp.tx_memcpy[entry = lp.tx_cur];
+	memcpy_toio(mem, d, ETH_ALEN);
+	memcpy_toio(mem + ETH_ALEN, nic->node_addr, ETH_ALEN);
+	mem[ETH_ALEN * 2] = t >> 8;
+	mem[ETH_ALEN * 2 + 1] = t;
+	memcpy_toio(mem + ETH_HLEN, p, s);
+	s += ETH_HLEN;
+	len = (s < ETH_ZLEN ? ETH_ZLEN : s);
+	/* clean out flags */
+	writel(readl(&lp.tx_ring[entry].base) & ~T_FLAGS, &lp.tx_ring[entry].base);
+	/* clears other error flags */
+	writew(0x0000, &lp.tx_ring[entry].misc);
+	/* packet length in buffer */
+	writew(-len, &lp.tx_ring[entry].length);
+	/* start and end of packet, ownership */
+	writel(readl(&lp.tx_ring[entry].base) | (T_STP|T_ENP|T_OWN), &lp.tx_ring[entry].base);
+	/* update current pointers */
+	lp.tx_cur = (++lp.tx_cur) & lp.txRingMask;
+}
+
+/**************************************************************************
+DISABLE - Turn off ethernet interface
+***************************************************************************/
+static void depca_disable(struct nic *nic)
+{
+	STOP_DEPCA;
+}
+
+/*
+** Look for a special sequence in the Ethernet station address PROM that
+** is common across all DEPCA products. Note that the original DEPCA needs
+** its ROM address counter to be initialized and enabled. Only enable
+** if the first address octet is a 0x08 - this minimises the chances of
+** messing around with some other hardware, but it assumes that this DEPCA
+** card initialized itself correctly.
+**
+** Search the Ethernet address ROM for the signature. Since the ROM address
+** counter can start at an arbitrary point, the search must include the entire
+** probe sequence length plus the (length_of_the_signature - 1).
+** Stop the search IMMEDIATELY after the signature is found so that the
+** PROM address counter is correctly positioned at the start of the
+** ethernet address for later read out.
+*/
+static int depca_probe1(struct nic *nic)
+{
+	u8	data, nicsr;
+	/* This is only correct for little endian machines, but then
+	   Etherboot doesn't work on anything but a PC */
+	u8	sig[] = { 0xFF, 0x00, 0x55, 0xAA, 0xFF, 0x00, 0x55, 0xAA };
+	int	i, j;
+	long	sum, chksum;
+
+	data = inb(DEPCA_PROM);		/* clear counter on DEPCA */
+	data = inb(DEPCA_PROM);		/* read data */
+	if (data == 0x8) {
+		nicsr = inb(DEPCA_NICSR);
+		nicsr |= AAC;
+		outb(nicsr, DEPCA_NICSR);
+	}
+	for (i = 0, j = 0; j < (int)sizeof(sig) && i < PROBE_LENGTH+((int)sizeof(sig))-1; ++i) {
+		data = inb(DEPCA_PROM);
+		if (data == sig[j])		/* track signature */
+			++j;
+		else
+			j = (data == sig[0]) ? 1 : 0;
+	}
+	if (j != sizeof(sig))
+		return (0);
+	/* put the card in its initial state */
+	STOP_DEPCA;
+	nicsr = ((inb(DEPCA_NICSR) & ~SHE & ~RBE & ~IEN) | IM);
+	outb(nicsr, DEPCA_NICSR);
+	if (inw(DEPCA_DATA) != STOP)
+		return (0);
+	memcpy((char *)mem_start, sig, sizeof(sig));
+	if (memcmp((char *)mem_start, sig, sizeof(sig)) != 0)
+		return (0);
+	for (i = 0, j = 0, sum = 0; j < 3; j++) {
+		sum <<= 1;
+		if (sum > 0xFFFF)
+			sum -= 0xFFFF;
+		sum += (u8)(nic->node_addr[i++] = inb(DEPCA_PROM));
+		sum += (u16)((nic->node_addr[i++] = inb(DEPCA_PROM)) << 8);
+		if (sum > 0xFFFF)
+			sum -= 0xFFFF;
+	}
+	if (sum == 0xFFFF)
+		sum = 0;
+	chksum = (u8)inb(DEPCA_PROM);
+	chksum |= (u16)(inb(DEPCA_PROM) << 8);
+	mem_len = (adapter == DEPCA) ? (48 << 10) : (64 << 10);
+	offset = 0;
+	if (nicsr & BUF) {
+		offset = 0x8000;
+		nicsr &= ~BS;
+		mem_len -= (32 << 10);
+	}
+	if (adapter != DEPCA)	/* enable shadow RAM */
+		outb(nicsr |= SHE, DEPCA_NICSR);
+	printf("%s base %#hX, memory [%#hX-%#hX], addr %!",
+		adapter_name[adapter], ioaddr, mem_start, mem_start + mem_len,
+		nic->node_addr);
+	if (sum != chksum)
+		printf(" (bad checksum)");
+	putchar('\n');
+	return (1);
+}
+
+/**************************************************************************
+PROBE - Look for an adapter, this routine's visible to the outside
+***************************************************************************/
+struct nic *depca_probe(struct nic *nic, unsigned short *probe_addrs)
+{
+	static unsigned short	base[] = DEPCA_IO_PORTS;
+	int			i;
+
+	if (probe_addrs == 0 || probe_addrs[0] == 0)
+		probe_addrs = base;	/* Use defaults */
+	for (i = 0; (ioaddr = base[i]) != 0; ++i) {
+		if (depca_probe1(nic))
+			break;
+	}
+	if (ioaddr == 0)
+		return (0);
+	depca_reset(nic);
+	/* point to NIC specific routines */
+	nic->reset = depca_reset;
+	nic->poll = depca_poll;
+	nic->transmit = depca_transmit;
+	nic->disable = depca_disable;
+	return (nic);
+}
diff --git a/netboot/eepro.c b/netboot/eepro.c
new file mode 100644
index 0000000..4e3f07b
--- /dev/null
+++ b/netboot/eepro.c
@@ -0,0 +1,586 @@
+/**************************************************************************
+Etherboot -  BOOTP/TFTP Bootstrap Program
+Intel EEPRO/10 NIC driver for Etherboot
+Adapted from Linux eepro.c from kernel 2.2.17
+
+This board accepts a 32 pin EEPROM (29C256), however a test with a
+27C010 shows that this EPROM also works in the socket, but it's not clear
+how repeatably. The two top address pins appear to be held low, thus
+the bottom 32kB of the 27C010 is visible in the CPU's address space.
+To be sure you could put 4 copies of the code in the 27C010, then
+it doesn't matter whether the extra lines are held low or high, just
+hopefully not floating as CMOS chips don't like floating inputs.
+
+Be careful with seating the EPROM as the socket on my board actually
+has 34 pins, the top row of 2 are not used.
+***************************************************************************/
+
+/*
+ * 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.
+ */
+
+/* to get some global routines like printf */
+#include "etherboot.h"
+/* to get the interface to the body of the program */
+#include "nic.h"
+/* to get our own prototype */
+#include "cards.h"
+/* we use timer2 for microsecond waits */
+#include "timer.h"
+
+#undef	DEBUG		/* only after include files */
+
+/* Different 82595 chips */
+#define LAN595		0
+#define LAN595TX	1
+#define LAN595FX	2
+#define LAN595FX_10ISA	3
+
+#define	SLOW_DOWN	inb(0x80);
+
+/* The station (ethernet) address prefix, used for IDing the board. */
+#define SA_ADDR0 0x00	/* Etherexpress Pro/10 */
+#define SA_ADDR1 0xaa
+#define SA_ADDR2 0x00
+
+#define GetBit(x,y) ((x & (1<<y))>>y)
+
+/* EEPROM Word 0: */
+#define ee_PnP       0  /* Plug 'n Play enable bit */
+#define ee_Word1     1  /* Word 1? */
+#define ee_BusWidth  2  /* 8/16 bit */
+#define ee_FlashAddr 3  /* Flash Address */
+#define ee_FlashMask 0x7   /* Mask */
+#define ee_AutoIO    6  /* */
+#define ee_reserved0 7  /* =0! */
+#define ee_Flash     8  /* Flash there? */
+#define ee_AutoNeg   9  /* Auto Negotiation enabled? */
+#define ee_IO0       10 /* IO Address LSB */
+#define ee_IO0Mask   0x /*...*/
+#define ee_IO1       15 /* IO MSB */
+
+/* EEPROM Word 1: */
+#define ee_IntSel    0   /* Interrupt */
+#define ee_IntMask   0x7
+#define ee_LI        3   /* Link Integrity 0= enabled */
+#define ee_PC        4   /* Polarity Correction 0= enabled */
+#define ee_TPE_AUI   5   /* PortSelection 1=TPE */
+#define ee_Jabber    6   /* Jabber prevention 0= enabled */
+#define ee_AutoPort  7   /* Auto Port Selection 1= Disabled */
+#define ee_SMOUT     8   /* SMout Pin Control 0= Input */
+#define ee_PROM      9   /* Flash EPROM / PROM 0=Flash */
+#define ee_reserved1 10  /* .. 12 =0! */
+#define ee_AltReady  13  /* Alternate Ready, 0=normal */
+#define ee_reserved2 14  /* =0! */
+#define ee_Duplex    15
+
+/* Word2,3,4: */
+#define ee_IA5       0 /*bit start for individual Addr Byte 5 */
+#define ee_IA4       8 /*bit start for individual Addr Byte 5 */
+#define ee_IA3       0 /*bit start for individual Addr Byte 5 */
+#define ee_IA2       8 /*bit start for individual Addr Byte 5 */
+#define ee_IA1       0 /*bit start for individual Addr Byte 5 */
+#define ee_IA0       8 /*bit start for individual Addr Byte 5 */
+
+/* Word 5: */
+#define ee_BNC_TPE   0 /* 0=TPE */
+#define ee_BootType  1 /* 00=None, 01=IPX, 10=ODI, 11=NDIS */
+#define ee_BootTypeMask 0x3 
+#define ee_NumConn   3  /* Number of Connections 0= One or Two */
+#define ee_FlashSock 4  /* Presence of Flash Socket 0= Present */
+#define ee_PortTPE   5
+#define ee_PortBNC   6
+#define ee_PortAUI   7
+#define ee_PowerMgt  10 /* 0= disabled */
+#define ee_CP        13 /* Concurrent Processing */
+#define ee_CPMask    0x7
+
+/* Word 6: */
+#define ee_Stepping  0 /* Stepping info */
+#define ee_StepMask  0x0F
+#define ee_BoardID   4 /* Manucaturer Board ID, reserved */
+#define ee_BoardMask 0x0FFF
+
+/* Word 7: */
+#define ee_INT_TO_IRQ 0 /* int to IRQ Mapping  = 0x1EB8 for Pro/10+ */
+#define ee_FX_INT2IRQ 0x1EB8 /* the _only_ mapping allowed for FX chips */
+
+/*..*/
+#define ee_SIZE 0x40 /* total EEprom Size */
+#define ee_Checksum 0xBABA /* initial and final value for adding checksum */
+
+
+/* Card identification via EEprom:   */
+#define ee_addr_vendor 0x10  /* Word offset for EISA Vendor ID */
+#define ee_addr_id 0x11      /* Word offset for Card ID */
+#define ee_addr_SN 0x12      /* Serial Number */
+#define ee_addr_CRC_8 0x14   /* CRC over last thee Bytes */
+
+
+#define ee_vendor_intel0 0x25  /* Vendor ID Intel */
+#define ee_vendor_intel1 0xD4
+#define ee_id_eepro10p0 0x10   /* ID for eepro/10+ */
+#define ee_id_eepro10p1 0x31
+
+/* now this section could be used by both boards: the oldies and the ee10:
+ * ee10 uses tx buffer before of rx buffer and the oldies the inverse.
+ * (aris)
+ */
+#define	RAM_SIZE	0x8000
+
+#define	RCV_HEADER	8
+#define RCV_DEFAULT_RAM	0x6000
+#define RCV_RAM 	rcv_ram
+
+static unsigned rcv_ram = RCV_DEFAULT_RAM;
+
+#define XMT_HEADER	8
+#define XMT_RAM		(RAM_SIZE - RCV_RAM)
+
+#define XMT_START	((rcv_start + RCV_RAM) % RAM_SIZE)
+
+#define RCV_LOWER_LIMIT	(rcv_start >> 8)
+#define RCV_UPPER_LIMIT	(((rcv_start + RCV_RAM) - 2) >> 8)
+#define XMT_LOWER_LIMIT	(XMT_START >> 8)
+#define XMT_UPPER_LIMIT	(((XMT_START + XMT_RAM) - 2) >> 8)
+
+#define RCV_START_PRO	0x00
+#define RCV_START_10	XMT_RAM
+					/* by default the old driver */
+static unsigned rcv_start = RCV_START_PRO;
+
+#define	RCV_DONE	0x0008
+#define	RX_OK		0x2000
+#define	RX_ERROR	0x0d81
+
+#define	TX_DONE_BIT	0x0080
+#define	CHAIN_BIT	0x8000
+#define	XMT_STATUS	0x02
+#define	XMT_CHAIN	0x04
+#define	XMT_COUNT	0x06
+
+#define	BANK0_SELECT	0x00		
+#define	BANK1_SELECT	0x40		
+#define	BANK2_SELECT	0x80		
+
+/* Bank 0 registers */
+#define	COMMAND_REG	0x00	/* Register 0 */
+#define	MC_SETUP	0x03
+#define	XMT_CMD		0x04
+#define	DIAGNOSE_CMD	0x07
+#define	RCV_ENABLE_CMD	0x08
+#define	RCV_DISABLE_CMD	0x0a
+#define	STOP_RCV_CMD	0x0b
+#define	RESET_CMD	0x0e
+#define	POWER_DOWN_CMD	0x18
+#define	RESUME_XMT_CMD	0x1c
+#define	SEL_RESET_CMD	0x1e
+#define	STATUS_REG	0x01	/* Register 1 */
+#define	RX_INT		0x02
+#define	TX_INT		0x04
+#define	EXEC_STATUS	0x30
+#define	ID_REG		0x02	/* Register 2	*/
+#define	R_ROBIN_BITS	0xc0	/* round robin counter */
+#define	ID_REG_MASK	0x2c
+#define	ID_REG_SIG	0x24
+#define	AUTO_ENABLE	0x10
+#define	INT_MASK_REG	0x03	/* Register 3	*/
+#define	RX_STOP_MASK	0x01
+#define	RX_MASK		0x02
+#define	TX_MASK		0x04
+#define	EXEC_MASK	0x08
+#define	ALL_MASK	0x0f
+#define	IO_32_BIT	0x10
+#define	RCV_BAR		0x04	/* The following are word (16-bit) registers */
+#define	RCV_STOP	0x06
+
+#define	XMT_BAR_PRO	0x0a
+#define	XMT_BAR_10	0x0b
+static unsigned xmt_bar = XMT_BAR_PRO;
+
+#define	HOST_ADDRESS_REG	0x0c
+#define	IO_PORT		0x0e
+#define	IO_PORT_32_BIT	0x0c
+
+/* Bank 1 registers */
+#define	REG1	0x01
+#define	WORD_WIDTH	0x02
+#define	INT_ENABLE	0x80
+#define INT_NO_REG	0x02
+#define	RCV_LOWER_LIMIT_REG	0x08
+#define	RCV_UPPER_LIMIT_REG	0x09
+
+#define	XMT_LOWER_LIMIT_REG_PRO	0x0a
+#define	XMT_UPPER_LIMIT_REG_PRO	0x0b
+#define	XMT_LOWER_LIMIT_REG_10	0x0b
+#define	XMT_UPPER_LIMIT_REG_10	0x0a
+static unsigned xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_PRO;
+static unsigned xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_PRO;
+
+/* Bank 2 registers */
+#define	XMT_Chain_Int	0x20	/* Interrupt at the end of the transmit chain */
+#define	XMT_Chain_ErrStop	0x40 /* Interrupt at the end of the chain even if there are errors */
+#define	RCV_Discard_BadFrame	0x80 /* Throw bad frames away, and continue to receive others */
+#define	REG2		0x02
+#define	PRMSC_Mode	0x01
+#define	Multi_IA	0x20
+#define	REG3		0x03
+#define	TPE_BIT		0x04
+#define	BNC_BIT		0x20
+#define	REG13		0x0d
+#define	FDX		0x00
+#define	A_N_ENABLE	0x02
+	
+#define	I_ADD_REG0	0x04
+#define	I_ADD_REG1	0x05
+#define	I_ADD_REG2	0x06
+#define	I_ADD_REG3	0x07
+#define	I_ADD_REG4	0x08
+#define	I_ADD_REG5	0x09
+
+#define EEPROM_REG_PRO	0x0a
+#define EEPROM_REG_10	0x0b
+static unsigned eeprom_reg = EEPROM_REG_PRO;
+
+#define EESK 0x01
+#define EECS 0x02
+#define EEDI 0x04
+#define EEDO 0x08
+
+/* The horrible routine to read a word from the serial EEPROM. */
+/* IMPORTANT - the 82595 will be set to Bank 0 after the eeprom is read */
+
+/* The delay between EEPROM clock transitions. */
+#define eeprom_delay() { udelay(40); }
+#define EE_READ_CMD (6 << 6)
+
+/* do a full reset */
+#define eepro_full_reset(ioaddr)	outb(RESET_CMD, ioaddr); udelay(40);
+
+/* do a nice reset */
+#define eepro_sel_reset(ioaddr) 	{ \
+					outb(SEL_RESET_CMD, ioaddr); \
+					SLOW_DOWN; \
+					SLOW_DOWN; \
+					}
+
+/* clear all interrupts */
+#define	eepro_clear_int(ioaddr)	outb(ALL_MASK, ioaddr + STATUS_REG)
+
+/* enable rx */
+#define	eepro_en_rx(ioaddr)	outb(RCV_ENABLE_CMD, ioaddr)
+
+/* disable rx */
+#define	eepro_dis_rx(ioaddr)	outb(RCV_DISABLE_CMD, ioaddr)
+
+/* switch bank */
+#define eepro_sw2bank0(ioaddr) outb(BANK0_SELECT, ioaddr)
+#define eepro_sw2bank1(ioaddr) outb(BANK1_SELECT, ioaddr)
+#define eepro_sw2bank2(ioaddr) outb(BANK2_SELECT, ioaddr)
+
+static unsigned int	rx_start, tx_start;
+static int		tx_last;
+static unsigned		tx_end;
+static int		eepro = 0;
+static unsigned short	ioaddr = 0;
+static unsigned int	mem_start, mem_end = RCV_DEFAULT_RAM / 1024;
+
+#define	udelay(n)	waiton_timer2(((n)*TICKS_PER_MS)/1000)
+
+/**************************************************************************
+RESET - Reset adapter
+***************************************************************************/
+static void eepro_reset(struct nic *nic)
+{
+	int		temp_reg, i;
+
+	/* put the card in its initial state */
+	eepro_sw2bank2(ioaddr);	/* be careful, bank2 now */
+	temp_reg = inb(ioaddr + eeprom_reg);
+#ifdef	DEBUG
+	printf("Stepping %d\n", temp_reg >> 5);
+#endif
+	if (temp_reg & 0x10)	/* check the TurnOff Enable bit */
+		outb(temp_reg & 0xEF, ioaddr + eeprom_reg);
+	for (i = 0; i < ETH_ALEN; i++)	/* fill the MAC address */
+		outb(nic->node_addr[i], ioaddr + I_ADD_REG0 + i);
+	temp_reg = inb(ioaddr + REG1);
+	/* setup Transmit Chaining and discard bad RCV frames */
+	outb(temp_reg | XMT_Chain_Int | XMT_Chain_ErrStop
+		| RCV_Discard_BadFrame, ioaddr + REG1);
+	temp_reg = inb(ioaddr + REG2);		/* match broadcast */
+	outb(temp_reg | 0x14, ioaddr + REG2);
+	temp_reg = inb(ioaddr + REG3);
+	outb(temp_reg & 0x3F, ioaddr + REG3);	/* clear test mode */
+	/* set the receiving mode */
+	eepro_sw2bank1(ioaddr);	/* be careful, bank1 now */
+	/* initialise the RCV and XMT upper and lower limits */
+	outb(RCV_LOWER_LIMIT, ioaddr + RCV_LOWER_LIMIT_REG);
+	outb(RCV_UPPER_LIMIT, ioaddr + RCV_UPPER_LIMIT_REG);
+	outb(XMT_LOWER_LIMIT, ioaddr + xmt_lower_limit_reg);
+	outb(XMT_UPPER_LIMIT, ioaddr + xmt_upper_limit_reg);
+	eepro_sw2bank0(ioaddr);	/* Switch back to bank 0 */
+	eepro_clear_int(ioaddr);
+	/* Initialise RCV */
+	outw(rx_start = (RCV_LOWER_LIMIT << 8), ioaddr + RCV_BAR);
+	outw(((RCV_UPPER_LIMIT << 8) | 0xFE), ioaddr + RCV_STOP);
+	/* Intialise XMT */
+	outw((XMT_LOWER_LIMIT << 8), ioaddr + xmt_bar);
+	eepro_sel_reset(ioaddr);
+	tx_start = tx_end = (XMT_LOWER_LIMIT << 8);
+	tx_last = 0;
+	eepro_en_rx(ioaddr);
+}
+
+/**************************************************************************
+POLL - Wait for a frame
+***************************************************************************/
+static int eepro_poll(struct nic *nic)
+{
+	int		i;
+	unsigned int	rcv_car = rx_start;
+	unsigned int	rcv_event, rcv_status, rcv_next_frame, rcv_size;
+
+	/* return true if there's an ethernet packet ready to read */
+	/* nic->packet should contain data on return */
+	/* nic->packetlen should contain length of data */
+#if	0
+	if ((inb(ioaddr + STATUS_REG) & 0x40) == 0)
+		return (0);
+	outb(0x40, ioaddr + STATUS_REG);
+#endif
+	outw(rcv_car, ioaddr + HOST_ADDRESS_REG);
+	rcv_event = inw(ioaddr + IO_PORT);
+	if (rcv_event != RCV_DONE)
+		return (0);
+	rcv_status = inw(ioaddr + IO_PORT);
+	rcv_next_frame = inw(ioaddr + IO_PORT);
+	rcv_size = inw(ioaddr + IO_PORT);
+#if	0
+	printf("%hX %hX %d %hhX\n", rcv_status, rcv_next_frame, rcv_size,
+		inb(ioaddr + STATUS_REG));
+#endif
+	if ((rcv_status & (RX_OK|RX_ERROR)) != RX_OK) {
+		printf("Receive error %hX\n", rcv_status);
+		return (0);
+	}
+	rcv_size &= 0x3FFF;
+	insw(ioaddr + IO_PORT, nic->packet, ((rcv_size + 3) >> 1));
+#if	0
+	for (i = 0; i < 48; i++) {
+		printf("%hhX", nic->packet[i]);
+		putchar(i % 16 == 15 ? '\n' : ' ');
+	}
+#endif
+	nic->packetlen = rcv_size;
+	rcv_car = rx_start + RCV_HEADER + rcv_size;
+	rx_start = rcv_next_frame;
+	if (rcv_car == 0)
+		rcv_car = ((RCV_UPPER_LIMIT << 8) | 0xff);
+	outw(rcv_car - 1, ioaddr + RCV_STOP);
+	return (1);
+}
+
+/**************************************************************************
+TRANSMIT - Transmit a frame
+***************************************************************************/
+static void eepro_transmit(
+	struct nic *nic,
+	const char *d,			/* Destination */
+	unsigned int t,			/* Type */
+	unsigned int s,			/* size */
+	const char *p)			/* Packet */
+{
+	unsigned int	status, tx_available, last, end, length;
+	unsigned short	type;
+	int		boguscount = 20;
+
+	length = s + ETH_HLEN;
+	if (tx_end > tx_start)
+		tx_available = XMT_RAM - (tx_end - tx_start);
+	else if (tx_end < tx_start)
+		tx_available = tx_start - tx_end;
+	else
+		tx_available = XMT_RAM;
+	last = tx_end;
+	end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
+	if (end >= (XMT_UPPER_LIMIT << 8)) {
+		last = (XMT_LOWER_LIMIT << 8);
+		end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
+	}
+	outw(last, ioaddr + HOST_ADDRESS_REG);
+	outw(XMT_CMD, ioaddr + IO_PORT);
+	outw(0, ioaddr + IO_PORT);
+	outw(end, ioaddr + IO_PORT);
+	outw(length, ioaddr + IO_PORT);
+	outsw(ioaddr + IO_PORT, d, ETH_ALEN / 2);
+	outsw(ioaddr + IO_PORT, nic->node_addr, ETH_ALEN / 2);
+	type = htons(t);
+	outsw(ioaddr + IO_PORT, &type, sizeof(type) / 2);
+	outsw(ioaddr + IO_PORT, p, (s + 3) >> 1);
+	/* A dummy read to flush the DRAM write pipeline */
+	status = inw(ioaddr + IO_PORT);
+	outw(last, ioaddr + xmt_bar);
+	outb(XMT_CMD, ioaddr);
+	tx_start = last;
+	tx_last = last;
+	tx_end = end;
+#if	0
+	printf("%d %d\n", tx_start, tx_end);
+#endif
+	while (boguscount > 0) {
+		if (((status = inw(ioaddr + IO_PORT)) & TX_DONE_BIT) == 0) {
+			udelay(40);
+			boguscount--;
+			continue;
+		}
+#if	DEBUG
+		if ((status & 0x2000) == 0)
+			printf("Transmit status %hX\n", status);
+#endif
+	}
+}
+
+/**************************************************************************
+DISABLE - Turn off ethernet interface
+***************************************************************************/
+static void eepro_disable(struct nic *nic)
+{
+	eepro_sw2bank0(ioaddr);	/* Switch to bank 0 */
+	/* Flush the Tx and disable Rx */
+	outb(STOP_RCV_CMD, ioaddr);
+	tx_start = tx_end = (XMT_LOWER_LIMIT << 8);
+	tx_last = 0;
+	/* Reset the 82595 */
+	eepro_full_reset(ioaddr);
+}
+
+static int read_eeprom(int location)
+{
+	int		i;
+	unsigned short	retval = 0;
+	int		ee_addr = ioaddr + eeprom_reg;
+	int		read_cmd = location | EE_READ_CMD;
+	int		ctrl_val = EECS;
+
+	if (eepro == LAN595FX_10ISA) {
+		eepro_sw2bank1(ioaddr);
+		outb(0x00, ioaddr + STATUS_REG);
+	}
+	eepro_sw2bank2(ioaddr);
+	outb(ctrl_val, ee_addr);
+	/* shift the read command bits out */
+	for (i = 8; i >= 0; i--) {
+		short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : ctrl_val;
+		outb(outval, ee_addr);
+		outb(outval | EESK, ee_addr);	/* EEPROM clock tick */
+		eeprom_delay();
+		outb(outval, ee_addr);		/* finish EEPROM clock tick */
+		eeprom_delay();
+	}
+	outb(ctrl_val, ee_addr);
+	for (i = 16; i > 0; i--) {
+		outb(ctrl_val | EESK, ee_addr);
+		eeprom_delay();
+		retval = (retval << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0);
+		outb(ctrl_val, ee_addr);
+		eeprom_delay();
+	}
+	/* terminate the EEPROM access */
+	ctrl_val &= ~EECS;
+	outb(ctrl_val | EESK, ee_addr);
+	eeprom_delay();
+	outb(ctrl_val, ee_addr);
+	eeprom_delay();
+	eepro_sw2bank0(ioaddr);
+	return (retval);
+}
+
+static int eepro_probe1(struct nic *nic)
+{
+	int		i, id, counter, l_eepro = 0;
+	union {
+		unsigned char	caddr[ETH_ALEN];
+		unsigned short	saddr[ETH_ALEN/2];
+	} station_addr;
+	char		*name;
+
+	id = inb(ioaddr + ID_REG);
+	if ((id & ID_REG_MASK) != ID_REG_SIG)
+		return (0);
+	counter = id & R_ROBIN_BITS;
+	if (((id = inb(ioaddr + ID_REG)) & R_ROBIN_BITS) != (counter + 0x40))
+		return (0);
+	/* yes the 82595 has been found */
+	station_addr.saddr[2] = read_eeprom(2);
+	if (station_addr.saddr[2] == 0x0000 || station_addr.saddr[2] == 0xFFFF) {
+		l_eepro = 3;
+		eepro = LAN595FX_10ISA;
+		eeprom_reg= EEPROM_REG_10;
+		rcv_start = RCV_START_10;
+		xmt_lower_limit_reg = XMT_LOWER_LIMIT_REG_10;
+		xmt_upper_limit_reg = XMT_UPPER_LIMIT_REG_10;
+		station_addr.saddr[2] = read_eeprom(2);
+	}
+	station_addr.saddr[1] = read_eeprom(3);
+	station_addr.saddr[0] = read_eeprom(4);
+	if (l_eepro)
+		name = "Intel EtherExpress 10 ISA";
+	else if (read_eeprom(7) == ee_FX_INT2IRQ) {
+		name = "Intel EtherExpress Pro/10+ ISA";
+		l_eepro = 2;
+	} else if (station_addr.saddr[0] == SA_ADDR1) {
+		name = "Intel EtherExpress Pro/10 ISA";
+		l_eepro = 1;
+	} else {
+		l_eepro = 0;
+		name = "Intel 82595-based LAN card";
+	}
+	station_addr.saddr[0] = swap16(station_addr.saddr[0]);
+	station_addr.saddr[1] = swap16(station_addr.saddr[1]);
+	station_addr.saddr[2] = swap16(station_addr.saddr[2]);
+	for (i = 0; i < ETH_ALEN; i++) {
+		nic->node_addr[i] = station_addr.caddr[i];
+	}
+	printf("\n%s ioaddr %#hX, addr %!", name, ioaddr, nic->node_addr);
+	mem_start = RCV_LOWER_LIMIT << 8;
+	if ((mem_end & 0x3F) < 3 || (mem_end & 0x3F) > 29)
+		mem_end = RCV_UPPER_LIMIT << 8;
+	else {
+		mem_end = mem_end * 1024 + (RCV_LOWER_LIMIT << 8);
+		rcv_ram = mem_end - (RCV_LOWER_LIMIT << 8);
+	}
+	printf(", Rx mem %dK, if %s\n", (mem_end - mem_start) >> 10,
+		GetBit(read_eeprom(5), ee_BNC_TPE) ? "BNC" : "TP");
+	return (1);
+}
+
+/**************************************************************************
+PROBE - Look for an adapter, this routine's visible to the outside
+***************************************************************************/
+struct nic *eepro_probe(struct nic *nic, unsigned short *probe_addrs)
+{
+	unsigned short		*p;
+	/* same probe list as the Linux driver */
+	static unsigned short	ioaddrs[] = {
+		0x300, 0x210, 0x240, 0x280, 0x2C0, 0x200, 0x320, 0x340, 0x360, 0};
+
+	if (probe_addrs == 0 || probe_addrs[0] == 0)
+		probe_addrs = ioaddrs;
+	for (p = probe_addrs; (ioaddr = *p) != 0; p++) {
+		if (eepro_probe1(nic))
+			break;
+	}
+	if (*p == 0)
+		return (0);
+	eepro_reset(nic);
+	/* point to NIC specific routines */
+	nic->reset = eepro_reset;
+	nic->poll = eepro_poll;
+	nic->transmit = eepro_transmit;
+	nic->disable = eepro_disable;
+	return (nic);
+}
diff --git a/netboot/eepro100.c b/netboot/eepro100.c
new file mode 100644
index 0000000..b6510a7
--- /dev/null
+++ b/netboot/eepro100.c
@@ -0,0 +1,654 @@
+/*
+ * eepro100.c -- This file implements the eepro100 driver for etherboot.
+ *
+ *
+ * Copyright (C) AW Computer Systems.
+ * written by R.E.Wolff -- R.E.Wolff@BitWizard.nl
+ *
+ *
+ * AW Computer Systems is contributing to the free software community
+ * by paying for this driver and then putting the result under GPL.
+ *
+ * If you need a Linux device driver, please contact BitWizard for a
+ * quote.
+ *
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ *              date       version  by   what
+ *  Written:    May 29 1997  V0.10  REW  Initial revision.
+ * changes:     May 31 1997  V0.90  REW  Works!
+ *              Jun 1  1997  V0.91  REW  Cleanup
+ *              Jun 2  1997  V0.92  REW  Add some code documentation
+ *              Jul 25 1997  V1.00  REW  Tested by AW to work in a PROM
+ *                                       Cleanup for publication
+ *
+ * This is the etherboot intel etherexpress Pro/100B driver.
+ *
+ * It was written from scratch, with Donald Beckers eepro100.c kernel
+ * driver as a guideline. Mostly the 82557 related definitions and the
+ * lower level routines have been cut-and-pasted into this source.
+ *
+ * The driver was finished before Intel got the NDA out of the closet.
+ * I still don't have the docs.
+ * */
+
+/* Philosophy of this driver.
+ *
+ * Probing:
+ *
+ * Using the pci.c functions of the Etherboot code, the 82557 chip is detected.
+ * It is verified that the BIOS initialized everything properly and if
+ * something is missing it is done now.
+ *
+ *
+ * Initialization:
+ *
+ *
+ * The chip is then initialized to "know" its ethernet address, and to
+ * start recieving packets. The Linux driver has a whole transmit and
+ * recieve ring of buffers. This is neat if you need high performance:
+ * you can write the buffers asynchronously to the chip reading the
+ * buffers and transmitting them over the network.  Performance is NOT
+ * an issue here. We can boot a 400k kernel in about two
+ * seconds. (Theory: 0.4 seconds). Booting a system is going to take
+ * about half a minute anyway, so getting 10 times closer to the
+ * theoretical limit is going to make a difference of a few percent.
+ *
+ *
+ * Transmitting and recieving.
+ *
+ * We have only one transmit descriptor. It has two buffer descriptors:
+ * one for the header, and the other for the data.
+ * We have only one receive buffer. The chip is told to recieve packets,
+ * and suspend itself once it got one. The recieve (poll) routine simply
+ * looks at the recieve buffer to see if there is already a packet there.
+ * if there is, the buffer is copied, and the reciever is restarted.
+ *
+ * Caveats:
+ *
+ * The etherboot framework moves the code to the 32k segment from
+ * 0x98000 to 0xa0000. There is just a little room between the end of
+ * this driver and the 0xa0000 address. If you compile in too many
+ * features, this will overflow.
+ * The number under "hex" in the output of size that scrolls by while
+ * compiling should be less than 8000. Maybe even the stack is up there,
+ * so that you need even more headroom.
+ */
+
+/* The etherboot authors seem to dislike the argument ordering in
+ * outb macros that Linux uses. I disklike the confusion that this
+ * has caused even more.... This file uses the Linux argument ordering.  */
+/* Sorry not us. It's inherted code from FreeBSD. [The authors] */
+
+#include "etherboot.h"
+#include "nic.h"
+#include "pci.h"
+#include "cards.h"
+#include "timer.h"
+
+#undef	virt_to_bus
+#define	virt_to_bus(x)	((unsigned long)x)
+
+static int ioaddr;
+
+typedef unsigned char  u8;
+typedef   signed char  s8;
+typedef unsigned short u16;
+typedef   signed short s16;
+typedef unsigned int   u32;
+typedef   signed int   s32;
+
+enum speedo_offsets {
+  SCBStatus = 0, SCBCmd = 2,      /* Rx/Command Unit command and status. */
+  SCBPointer = 4,                 /* General purpose pointer. */
+  SCBPort = 8,                    /* Misc. commands and operands.  */
+  SCBflash = 12, SCBeeprom = 14,  /* EEPROM and flash memory control. */
+  SCBCtrlMDI = 16,                /* MDI interface control. */
+  SCBEarlyRx = 20,                /* Early receive byte count. */
+};
+
+static int do_eeprom_cmd(int cmd, int cmd_len);
+void hd(void *where, int n);
+
+/***********************************************************************/
+/*                       I82557 related defines                        */
+/***********************************************************************/
+
+/* Serial EEPROM section.
+   A "bit" grungy, but we work our way through bit-by-bit :->. */
+/*  EEPROM_Ctrl bits. */
+#define EE_SHIFT_CLK    0x01    /* EEPROM shift clock. */
+#define EE_CS           0x02    /* EEPROM chip select. */
+#define EE_DATA_WRITE   0x04    /* EEPROM chip data in. */
+#define EE_DATA_READ    0x08    /* EEPROM chip data out. */
+#define EE_WRITE_0      0x4802
+#define EE_WRITE_1      0x4806
+#define EE_ENB          (0x4800 | EE_CS)
+
+#define udelay(n)       waiton_timer2(((n)*TICKS_PER_MS)/1000)
+
+/* The EEPROM commands include the alway-set leading bit. */
+#define EE_READ_CMD     6
+
+/* The SCB accepts the following controls for the Tx and Rx units: */
+#define  CU_START       0x0010
+#define  CU_RESUME      0x0020
+#define  CU_STATSADDR   0x0040
+#define  CU_SHOWSTATS   0x0050  /* Dump statistics counters. */
+#define  CU_CMD_BASE    0x0060  /* Base address to add to add CU commands. */
+#define  CU_DUMPSTATS   0x0070  /* Dump then reset stats counters. */
+
+#define  RX_START       0x0001
+#define  RX_RESUME      0x0002
+#define  RX_ABORT       0x0004
+#define  RX_ADDR_LOAD   0x0006
+#define  RX_RESUMENR    0x0007
+#define INT_MASK        0x0100
+#define DRVR_INT        0x0200          /* Driver generated interrupt. */
+
+enum phy_chips { NonSuchPhy=0, I82553AB, I82553C, I82503, DP83840, S80C240,
+                                         S80C24, PhyUndefined, DP83840A=10, };
+
+/* Commands that can be put in a command list entry. */
+enum commands {
+  CmdNOp = 0,
+  CmdIASetup = 1,
+  CmdConfigure = 2,
+  CmdMulticastList = 3,
+  CmdTx = 4,
+  CmdTDR = 5,
+  CmdDump = 6,
+  CmdDiagnose = 7,
+
+  /* And some extra flags: */
+  CmdSuspend = 0x4000,      /* Suspend after completion. */
+  CmdIntr = 0x2000,         /* Interrupt after completion. */
+  CmdTxFlex = 0x0008,       /* Use "Flexible mode" for CmdTx command. */
+};
+
+/* How to wait for the command unit to accept a command.
+   Typically this takes 0 ticks. */
+static inline void wait_for_cmd_done(int cmd_ioaddr)
+{
+  short wait = 100;
+  do   ;
+  while(inb(cmd_ioaddr) && --wait >= 0);
+}
+
+/* Elements of the dump_statistics block. This block must be lword aligned. */
+static struct speedo_stats {
+        u32 tx_good_frames;
+        u32 tx_coll16_errs;
+        u32 tx_late_colls;
+        u32 tx_underruns;
+        u32 tx_lost_carrier;
+        u32 tx_deferred;
+        u32 tx_one_colls;
+        u32 tx_multi_colls;
+        u32 tx_total_colls;
+        u32 rx_good_frames;
+        u32 rx_crc_errs;
+        u32 rx_align_errs;
+        u32 rx_resource_errs;
+        u32 rx_overrun_errs;
+        u32 rx_colls_errs;
+        u32 rx_runt_errs;
+        u32 done_marker;
+} lstats;
+
+/* A speedo3 TX buffer descriptor with two buffers... */
+static struct TxFD {
+  volatile s16 status;
+  s16 command;
+  u32 link;          /* void * */
+  u32 tx_desc_addr;  /* (almost) Always points to the tx_buf_addr element. */
+  s32 count;         /* # of TBD (=2), Tx start thresh., etc. */
+                     /* This constitutes two "TBD" entries: hdr and data */
+  u32 tx_buf_addr0;  /* void *, header of frame to be transmitted.  */
+  s32 tx_buf_size0;  /* Length of Tx hdr. */
+  u32 tx_buf_addr1;  /* void *, data to be transmitted.  */
+  s32 tx_buf_size1;  /* Length of Tx data. */
+} txfd;
+
+struct RxFD {               /* Receive frame descriptor. */
+  volatile s16 status;
+  s16 command;
+  u32 link;                 /* struct RxFD * */
+  u32 rx_buf_addr;          /* void * */
+  u16 count;
+  u16 size;
+  char packet[1518];
+};
+
+#ifdef	USE_LOWMEM_BUFFER
+#define rxfd ((struct RxFD *)(0x10000 - sizeof(struct RxFD)))
+#define ACCESS(x) x->
+#else
+static struct RxFD rxfd;
+#define ACCESS(x) x.
+#endif
+
+static int congenb = 0;         /* Enable congestion control in the DP83840. */
+static int txfifo = 8;          /* Tx FIFO threshold in 4 byte units, 0-15 */
+static int rxfifo = 8;          /* Rx FIFO threshold, default 32 bytes. */
+static int txdmacount = 0;      /* Tx DMA burst length, 0-127, default 0. */
+static int rxdmacount = 0;      /* Rx DMA length, 0 means no preemption. */
+
+/* I don't understand a byte in this structure. It was copied from the
+ * Linux kernel initialization for the eepro100. -- REW */
+static struct ConfCmd {
+  s16 status;
+  s16 command;
+  u32 link;
+  unsigned char data[22];
+} confcmd = {
+  0, CmdConfigure,
+  (u32) & txfd,
+  {22, 0x08, 0, 0,  0, 0x80, 0x32, 0x03,  1, /* 1=Use MII  0=Use AUI */
+   0, 0x2E, 0,  0x60, 0,
+   0xf2, 0x48,   0, 0x40, 0xf2, 0x80,        /* 0x40=Force full-duplex */
+   0x3f, 0x05, }
+};
+
+/***********************************************************************/
+/*                       Locally used functions                        */
+/***********************************************************************/
+
+/* Support function: mdio_write
+ *
+ * This probably writes to the "physical media interface chip".
+ * -- REW
+ */
+
+static int mdio_write(int phy_id, int location, int value)
+{
+  int val, boguscnt = 64*4;         /* <64 usec. to complete, typ 27 ticks */
+
+  outl(0x04000000 | (location<<16) | (phy_id<<21) | value,
+       ioaddr + SCBCtrlMDI);
+  do {
+    udelay(16);
+
+    val = inl(ioaddr + SCBCtrlMDI);
+    if (--boguscnt < 0) {
+      printf(" mdio_write() timed out with val = %X.\n", val);
+    }
+  } while (! (val & 0x10000000));
+  return val & 0xffff;
+}
+
+/* Support function: mdio_read
+ *
+ * This probably reads a register in the "physical media interface chip".
+ * -- REW
+ */
+static int mdio_read(int phy_id, int location)
+{
+  int val, boguscnt = 64*4;               /* <64 usec. to complete, typ 27 ticks */
+  outl(0x08000000 | (location<<16) | (phy_id<<21), ioaddr + SCBCtrlMDI);
+  do {
+    udelay(16);
+
+    val = inl(ioaddr + SCBCtrlMDI);
+    if (--boguscnt < 0) {
+      printf( " mdio_read() timed out with val = %X.\n", val);
+    }
+  } while (! (val & 0x10000000));
+  return val & 0xffff;
+}
+
+/* The fixes for the code were kindly provided by Dragan Stancevic
+   <visitor@valinux.com> to strictly follow Intel specifications of EEPROM
+   access timing.
+   The publicly available sheet 64486302 (sec. 3.1) specifies 1us access
+   interval for serial EEPROM.  However, it looks like that there is an
+   additional requirement dictating larger udelay's in the code below.
+   2000/05/24  SAW */
+static int do_eeprom_cmd(int cmd, int cmd_len)
+{
+	unsigned retval = 0;
+	long ee_addr = ioaddr + SCBeeprom;
+
+	outw(EE_ENB, ee_addr); udelay(2);
+	outw(EE_ENB | EE_SHIFT_CLK, ee_addr); udelay(2);
+
+	/* Shift the command bits out. */
+	do {
+		short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0;
+		outw(dataval, ee_addr); udelay(2);
+		outw(dataval | EE_SHIFT_CLK, ee_addr); udelay(2);
+		retval = (retval << 1) | ((inw(ee_addr) & EE_DATA_READ) ? 1 : 0);
+	} while (--cmd_len >= 0);
+	outw(EE_ENB, ee_addr); udelay(2);
+
+	/* Terminate the EEPROM access. */
+	outw(EE_ENB & ~EE_CS, ee_addr);
+	return retval;
+}
+
+static inline void whereami (const char *str)
+{
+#if	0
+  printf ("%s\n", str);
+  sleep (2);
+#endif
+}
+
+/* function: eepro100_reset
+ * resets the card. This is used to allow Etherboot to probe the card again
+ * from a "virginal" state....
+ * Arguments: none
+ *
+ * returns:   void.
+ */
+
+static void eepro100_reset(struct nic *nic)
+{
+  outl(0, ioaddr + SCBPort);
+}
+
+/* function: eepro100_transmit
+ * This transmits a packet.
+ *
+ * Arguments: char d[6]:          destination ethernet address.
+ *            unsigned short t:   ethernet protocol type.
+ *            unsigned short s:   size of the data-part of the packet.
+ *            char *p:            the data for the packet.
+ * returns:   void.
+ */
+
+static void eepro100_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
+{
+  struct eth_hdr {
+    unsigned char dst_addr[ETH_ALEN];
+    unsigned char src_addr[ETH_ALEN];
+    unsigned short type;
+  } hdr;
+  unsigned short status;
+  int to;
+  int s1, s2;
+
+  status = inw(ioaddr + SCBStatus);
+  /* Acknowledge all of the current interrupt sources ASAP. */
+  outw(status & 0xfc00, ioaddr + SCBStatus);
+
+#ifdef	DEBUG
+  printf ("transmitting type %hX packet (%d bytes). status = %hX, cmd=%hX\n",
+	  t, s, status, inw (ioaddr + SCBCmd));
+#endif
+
+  memcpy (&hdr.dst_addr, d, ETH_ALEN);
+  memcpy (&hdr.src_addr, nic->node_addr, ETH_ALEN);
+
+  hdr.type = htons (t);
+
+  txfd.status = 0;
+  txfd.command = CmdSuspend | CmdTx | CmdTxFlex;
+  txfd.link   = virt_to_bus (&txfd);
+  txfd.count   = 0x02208000;
+  txfd.tx_desc_addr = (u32)&txfd.tx_buf_addr0;
+
+  txfd.tx_buf_addr0 = virt_to_bus (&hdr);
+  txfd.tx_buf_size0 = sizeof (hdr);
+
+  txfd.tx_buf_addr1 = virt_to_bus (p);
+  txfd.tx_buf_size1 = s;
+
+#ifdef	DEBUG
+  printf ("txfd: \n");
+  hd (&txfd, sizeof (txfd));
+#endif
+
+  outl(virt_to_bus(&txfd), ioaddr + SCBPointer);
+  outw(INT_MASK | CU_START, ioaddr + SCBCmd);
+  wait_for_cmd_done(ioaddr + SCBCmd);
+
+  s1 = inw (ioaddr + SCBStatus);
+  load_timer2(10*TICKS_PER_MS);		/* timeout 10 ms for transmit */
+  while (!txfd.status && timer2_running())
+    /* Wait */;
+  s2 = inw (ioaddr + SCBStatus);
+
+#ifdef	DEBUG
+  printf ("s1 = %hX, s2 = %hX.\n", s1, s2);
+#endif
+}
+
+/* function: eepro100_poll / eth_poll
+ * This recieves a packet from the network.
+ *
+ * Arguments: none
+ *
+ * returns:   1 if a packet was recieved.
+ *            0 if no pacet was recieved.
+ * side effects:
+ *            returns the packet in the array nic->packet.
+ *            returns the length of the packet in nic->packetlen.
+ */
+
+static int eepro100_poll(struct nic *nic)
+{
+  if (!ACCESS(rxfd)status)
+    return 0;
+
+  /* Ok. We got a packet. Now restart the reciever.... */
+  ACCESS(rxfd)status = 0;
+  ACCESS(rxfd)command = 0xc000;
+  outl(virt_to_bus(&(ACCESS(rxfd)status)), ioaddr + SCBPointer);
+  outw(INT_MASK | RX_START, ioaddr + SCBCmd);
+  wait_for_cmd_done(ioaddr + SCBCmd);
+
+#ifdef	DEBUG
+  printf ("Got a packet: Len = %d.\n", ACCESS(rxfd)count & 0x3fff);
+#endif
+  nic->packetlen =  ACCESS(rxfd)count & 0x3fff;
+  memcpy (nic->packet, ACCESS(rxfd)packet, nic->packetlen);
+#ifdef	DEBUG
+  hd (nic->packet, 0x30);
+#endif
+  return 1;
+}
+
+static void eepro100_disable(struct nic *nic)
+{
+    /* See if this PartialReset solves the problem with interfering with
+       kernel operation after Etherboot hands over. - Ken 20001102 */
+    outl(2, ioaddr + SCBPort);
+}
+
+/* exported function: eepro100_probe / eth_probe
+ * initializes a card
+ *
+ * side effects:
+ *            leaves the ioaddress of the 82557 chip in the variable ioaddr.
+ *            leaves the 82557 initialized, and ready to recieve packets.
+ */
+
+struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs, struct pci_device *p)
+{
+	unsigned short sum = 0;
+	int i;
+	int read_cmd, ee_size;
+	unsigned short value;
+	int options;
+	int promisc;
+
+	/* we cache only the first few words of the EEPROM data
+	   be careful not to access beyond this array */
+	unsigned short eeprom[16];
+
+	if (probeaddrs == 0 || probeaddrs[0] == 0)
+		return 0;
+	ioaddr = probeaddrs[0] & ~3; /* Mask the bit that says "this is an io addr" */
+
+	adjust_pci_device(p);
+
+	if ((do_eeprom_cmd(EE_READ_CMD << 24, 27) & 0xffe0000)
+		== 0xffe0000) {
+		ee_size = 0x100;
+		read_cmd = EE_READ_CMD << 24;
+	} else {
+		ee_size = 0x40;
+		read_cmd = EE_READ_CMD << 22;
+	}
+
+	for (i = 0, sum = 0; i < ee_size; i++) {
+		unsigned short value = do_eeprom_cmd(read_cmd | (i << 16), 27);
+		if (i < (int)(sizeof(eeprom)/sizeof(eeprom[0])))
+			eeprom[i] = value;
+		sum += value;
+	}
+
+  for (i=0;i<ETH_ALEN;i++) {
+	nic->node_addr[i] =  (eeprom[i/2] >> (8*(i&1))) & 0xff;
+  }
+  printf ("Ethernet addr: %!\n", nic->node_addr);
+
+  if (sum != 0xBABA)
+	printf("eepro100: Invalid EEPROM checksum %#hX, "
+	       "check settings before activating this device!\n", sum);
+  outl(0, ioaddr + SCBPort);
+  udelay (10000);
+
+  whereami ("Got eeprom.");
+
+  outl(virt_to_bus(&lstats), ioaddr + SCBPointer);
+  outw(INT_MASK | CU_STATSADDR, ioaddr + SCBCmd);
+  wait_for_cmd_done(ioaddr + SCBCmd);
+
+  whereami ("set stats addr.");
+  /* INIT RX stuff. */
+
+  /* Base = 0 */
+  outl(0, ioaddr + SCBPointer);
+  outw(INT_MASK | RX_ADDR_LOAD, ioaddr + SCBCmd);
+  wait_for_cmd_done(ioaddr + SCBCmd);
+
+  whereami ("set rx base addr.");
+
+  ACCESS(rxfd)status  = 0x0001;
+  ACCESS(rxfd)command = 0x0000;
+  ACCESS(rxfd)link    = virt_to_bus(&(ACCESS(rxfd)status));
+  ACCESS(rxfd)rx_buf_addr = (int) &nic->packet;
+  ACCESS(rxfd)count   = 0;
+  ACCESS(rxfd)size    = 1528;
+
+  outl(virt_to_bus(&(ACCESS(rxfd)status)), ioaddr + SCBPointer);
+  outw(INT_MASK | RX_START, ioaddr + SCBCmd);
+  wait_for_cmd_done(ioaddr + SCBCmd);
+
+  whereami ("started RX process.");
+
+  /* Start the reciever.... */
+  ACCESS(rxfd)status = 0;
+  ACCESS(rxfd)command = 0xc000;
+  outl(virt_to_bus(&(ACCESS(rxfd)status)), ioaddr + SCBPointer);
+  outw(INT_MASK | RX_START, ioaddr + SCBCmd);
+
+  /* INIT TX stuff. */
+
+  /* Base = 0 */
+  outl(0, ioaddr + SCBPointer);
+  outw(INT_MASK | CU_CMD_BASE, ioaddr + SCBCmd);
+  wait_for_cmd_done(ioaddr + SCBCmd);
+
+  whereami ("set TX base addr.");
+
+  txfd.command      = (CmdIASetup);
+  txfd.status       = 0x0000;
+  txfd.link         = virt_to_bus (&confcmd);
+
+  {
+	char *t = (char *)&txfd.tx_desc_addr;
+
+	for (i=0;i<ETH_ALEN;i++)
+		t[i] = nic->node_addr[i];
+  }
+
+#ifdef	DEBUG
+  printf ("Setup_eaddr:\n");
+  hd (&txfd, 0x20);
+#endif
+  /*      options = 0x40; */ /* 10mbps half duplex... */
+  options = 0x00;            /* Autosense */
+
+  promisc = 0;
+
+  if (   ((eeprom[6]>>8) & 0x3f) == DP83840
+	  || ((eeprom[6]>>8) & 0x3f) == DP83840A) {
+	int mdi_reg23 = mdio_read(eeprom[6] & 0x1f, 23) | 0x0422;
+	if (congenb)
+	  mdi_reg23 |= 0x0100;
+	printf("  DP83840 specific setup, setting register 23 to %hX.\n",
+	       mdi_reg23);
+	mdio_write(eeprom[6] & 0x1f, 23, mdi_reg23);
+  }
+  whereami ("Done DP8340 special setup.");
+  if (options != 0) {
+	mdio_write(eeprom[6] & 0x1f, 0,
+		   ((options & 0x20) ? 0x2000 : 0) |    /* 100mbps? */
+		   ((options & 0x10) ? 0x0100 : 0)); /* Full duplex? */
+	whereami ("set mdio_register.");
+  }
+
+  confcmd.command  = CmdSuspend | CmdConfigure;
+  confcmd.status   = 0x0000;
+  confcmd.link     = virt_to_bus (&txfd);
+  confcmd.data[1]  = (txfifo << 4) | rxfifo;
+  confcmd.data[4]  = rxdmacount;
+  confcmd.data[5]  = txdmacount + 0x80;
+  confcmd.data[15] = promisc ? 0x49: 0x48;
+  confcmd.data[19] = (options & 0x10) ? 0xC0 : 0x80;
+  confcmd.data[21] = promisc ? 0x0D: 0x05;
+
+  outl(virt_to_bus(&txfd), ioaddr + SCBPointer);
+  outw(INT_MASK | CU_START, ioaddr + SCBCmd);
+  wait_for_cmd_done(ioaddr + SCBCmd);
+
+  whereami ("started TX thingy (config, iasetup).");
+
+  load_timer2(10*TICKS_PER_MS);
+  while (!txfd.status && timer2_running())
+	/* Wait */;
+
+  nic->reset = eepro100_reset;
+  nic->poll = eepro100_poll;
+  nic->transmit = eepro100_transmit;
+  nic->disable = eepro100_disable;
+  return nic;
+}
+
+/*********************************************************************/
+
+#ifdef	DEBUG
+
+/* Hexdump a number of bytes from memory... */
+void hd (void *where, int n)
+{
+  int i;
+
+  while (n > 0) {
+    printf ("%X ", where);
+    for (i=0;i < ( (n>16)?16:n);i++)
+      printf (" %hhX", ((char *)where)[i]);
+    printf ("\n");
+    n -= 16;
+    where += 16;
+  }
+}
+#endif
+
diff --git a/netboot/epic100.c b/netboot/epic100.c
new file mode 100644
index 0000000..c5c3fd2
--- /dev/null
+++ b/netboot/epic100.c
@@ -0,0 +1,481 @@
+/* epic100.c: A SMC 83c170 EPIC/100 fast ethernet driver for Etherboot */
+
+#define LINUX_OUT_MACROS
+
+#include "etherboot.h"
+#include "nic.h"
+#include "cards.h"
+#include "timer.h"
+#include "epic100.h"
+
+#undef	virt_to_bus
+#define	virt_to_bus(x)	((unsigned long)x)
+
+#define TX_RING_SIZE	2	/* use at least 2 buffers for TX */
+#define RX_RING_SIZE	2
+
+#define PKT_BUF_SZ	1536	/* Size of each temporary Tx/Rx buffer.*/
+
+/*
+#define DEBUG_RX
+#define DEBUG_TX
+#define DEBUG_EEPROM
+*/
+
+#define EPIC_DEBUG 0	/* debug level */
+
+/* The EPIC100 Rx and Tx buffer descriptors. */
+struct epic_rx_desc {
+    unsigned short status;
+    unsigned short rxlength;
+    unsigned long  bufaddr;
+    unsigned short buflength;
+    unsigned short control;
+    unsigned long  next;
+};
+
+/* description of the tx descriptors control bits commonly used */
+#define TD_STDFLAGS	TD_LASTDESC
+
+struct epic_tx_desc {
+    unsigned short status;
+    unsigned short txlength;
+    unsigned long  bufaddr;
+    unsigned short buflength;
+    unsigned short control;
+    unsigned long  next;
+};
+
+#define delay(nanosec)   do { int _i = 3; while (--_i > 0) \
+                                     { __SLOW_DOWN_IO; }} while (0)
+
+static void	epic100_open(void);
+static void	epic100_init_ring(void);
+static void	epic100_disable(struct nic *nic);
+static int	epic100_poll(struct nic *nic);
+static void	epic100_transmit(struct nic *nic, const char *destaddr,
+				 unsigned int type, unsigned int len, const char *data);
+static int	read_eeprom(int location);
+static int	mii_read(int phy_id, int location);
+
+static int	ioaddr;
+
+static int	command;
+static int	intstat;
+static int	intmask;
+static int	genctl ;
+static int	eectl  ;
+static int	test   ;
+static int	mmctl  ;
+static int	mmdata ;
+static int	lan0   ;
+static int	rxcon  ;
+static int	txcon  ;
+static int	prcdar ;
+static int	ptcdar ;
+static int	eththr ;
+
+static unsigned int	cur_rx, cur_tx;		/* The next free ring entry */
+#ifdef	DEBUG_EEPROM
+static unsigned short	eeprom[64];
+#endif
+static signed char	phys[4];		/* MII device addresses. */
+static struct epic_rx_desc	rx_ring[RX_RING_SIZE];
+static struct epic_tx_desc	tx_ring[TX_RING_SIZE];
+#ifdef	USE_LOWMEM_BUFFER
+#define rx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE)
+#define tx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE - PKT_BUF_SZ * TX_RING_SIZE)
+#else
+static char		rx_packet[PKT_BUF_SZ * RX_RING_SIZE];
+static char		tx_packet[PKT_BUF_SZ * TX_RING_SIZE];
+#endif
+
+/***********************************************************************/
+/*                    Externally visible functions                     */
+/***********************************************************************/
+
+    static void
+epic100_reset(struct nic *nic)
+{
+    /* Soft reset the chip. */
+    outl(GC_SOFT_RESET, genctl);
+}
+
+    struct nic*
+epic100_probe(struct nic *nic, unsigned short *probeaddrs)
+{
+    unsigned short sum = 0;
+    unsigned short value;
+    int i;
+    unsigned short* ap;
+    unsigned int phy, phy_idx;
+
+    if (probeaddrs == 0 || probeaddrs[0] == 0)
+	return 0;
+
+    /* Ideally we would detect all network cards in slot order.  That would
+       be best done a central PCI probe dispatch, which wouldn't work
+       well with the current structure.  So instead we detect just the
+       Epic cards in slot order. */
+
+    ioaddr = probeaddrs[0] & ~3; /* Mask the bit that says "this is an io addr" */
+
+    /* compute all used static epic100 registers address */
+    command = ioaddr + COMMAND;		/* Control Register */
+    intstat = ioaddr + INTSTAT;		/* Interrupt Status */
+    intmask = ioaddr + INTMASK;		/* Interrupt Mask */
+    genctl  = ioaddr + GENCTL;		/* General Control */
+    eectl   = ioaddr + EECTL;		/* EEPROM Control  */
+    test    = ioaddr + TEST;		/* Test register (clocks) */
+    mmctl   = ioaddr + MMCTL;		/* MII Management Interface Control */
+    mmdata  = ioaddr + MMDATA;		/* MII Management Interface Data */
+    lan0    = ioaddr + LAN0;		/* MAC address. (0x40-0x48) */
+    rxcon   = ioaddr + RXCON;		/* Receive Control */
+    txcon   = ioaddr + TXCON;		/* Transmit Control */
+    prcdar  = ioaddr + PRCDAR;		/* PCI Receive Current Descr Address */
+    ptcdar  = ioaddr + PTCDAR;		/* PCI Transmit Current Descr Address */
+    eththr  = ioaddr + ETHTHR;		/* Early Transmit Threshold */
+
+    /* Reset the chip & bring it out of low-power mode. */
+    outl(GC_SOFT_RESET, genctl);
+
+    /* Disable ALL interrupts by setting the interrupt mask. */
+    outl(INTR_DISABLE, intmask);
+
+    /*
+     * set the internal clocks:
+     * Application Note 7.15 says:
+     *    In order to set the CLOCK TEST bit in the TEST register,
+     *	  perform the following:
+     *
+     *        Write 0x0008 to the test register at least sixteen
+     *        consecutive times.
+     *
+     * The CLOCK TEST bit is Write-Only. Writing it several times
+     * consecutively insures a successful write to the bit...
+     */
+
+    for (i = 0; i < 16; i++) {
+	outl(0x00000008, test);
+    }
+
+#ifdef	DEBUG_EEPROM
+    for (i = 0; i < 64; i++) {
+	value = read_eeprom(i);
+	eeprom[i] = value;
+	sum += value;
+    }
+
+#if	(EPIC_DEBUG > 1)
+    printf("EEPROM contents\n");
+    for (i = 0; i < 64; i++) {
+	printf(" %hhX%s", eeprom[i], i % 16 == 15 ? "\n" : "");
+    }
+#endif
+#endif
+
+    /* This could also be read from the EEPROM. */
+    ap = (unsigned short*)nic->node_addr;
+    for (i = 0; i < 3; i++)
+	*ap++ = inw(lan0 + i*4);
+
+    printf(" I/O %#hX %! ", ioaddr, nic->node_addr);
+
+    /* Find the connected MII xcvrs. */
+    for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(phys); phy++) {
+	int mii_status = mii_read(phy, 0);
+
+	if (mii_status != 0xffff  && mii_status != 0x0000) {
+	    phys[phy_idx++] = phy;
+#if	(EPIC_DEBUG > 1)
+	    printf("MII transceiver found at address %d.\n", phy);
+#endif
+	}
+    }
+    if (phy_idx == 0) {
+#if	(EPIC_DEBUG > 1)
+	printf("***WARNING***: No MII transceiver found!\n");
+#endif
+	/* Use the known PHY address of the EPII. */
+	phys[0] = 3;
+    }
+
+    epic100_open();
+
+    nic->reset    = epic100_reset;
+    nic->poll     = epic100_poll;
+    nic->transmit = epic100_transmit;
+    nic->disable  = epic100_disable;
+
+    return nic;
+}
+
+    static void
+epic100_open(void)
+{
+    int mii_reg5;
+    int full_duplex = 0;
+    unsigned long tmp;
+
+    epic100_init_ring();
+
+    /* Pull the chip out of low-power mode, and set for PCI read multiple. */
+    outl(GC_RX_FIFO_THR_64 | GC_MRC_READ_MULT | GC_ONE_COPY, genctl);
+
+    outl(TX_FIFO_THRESH, eththr);
+
+    tmp = TC_EARLY_TX_ENABLE | TX_SLOT_TIME;
+
+    mii_reg5 = mii_read(phys[0], 5);
+    if (mii_reg5 != 0xffff && (mii_reg5 & 0x0100)) {
+	full_duplex = 1;
+	printf(" full-duplex mode");
+	tmp |= TC_LM_FULL_DPX;
+    } else
+	tmp |= TC_LM_NORMAL;
+
+    outl(tmp, txcon);
+
+    /* Give adress of RX and TX ring to the chip */
+    outl(virt_to_bus(&rx_ring), prcdar);
+    outl(virt_to_bus(&tx_ring), ptcdar);
+
+    /* Start the chip's Rx process: receive unicast and broadcast */
+    outl(0x04, rxcon);
+    outl(CR_START_RX | CR_QUEUE_RX, command);
+
+    putchar('\n');
+}
+
+/* Initialize the Rx and Tx rings. */
+    static void
+epic100_init_ring(void)
+{
+    int i;
+    char* p;
+
+    cur_rx = cur_tx = 0;
+
+    p = &rx_packet[0];
+    for (i = 0; i < RX_RING_SIZE; i++) {
+	rx_ring[i].status    = RRING_OWN;	/* Owned by Epic chip */
+	rx_ring[i].buflength = PKT_BUF_SZ;
+	rx_ring[i].bufaddr   = virt_to_bus(p + (PKT_BUF_SZ * i));
+	rx_ring[i].control   = 0;
+	rx_ring[i].next      = virt_to_bus(&(rx_ring[i + 1]) );
+    }
+    /* Mark the last entry as wrapping the ring. */
+    rx_ring[i-1].next = virt_to_bus(&rx_ring[0]);
+
+    /*
+     *The Tx buffer descriptor is filled in as needed,
+     * but we do need to clear the ownership bit.
+     */
+    p = &tx_packet[0];
+
+    for (i = 0; i < TX_RING_SIZE; i++) {
+	tx_ring[i].status  = 0;			/* Owned by CPU */
+	tx_ring[i].bufaddr = virt_to_bus(p + (PKT_BUF_SZ * i));
+	tx_ring[i].control = TD_STDFLAGS;
+	tx_ring[i].next    = virt_to_bus(&(tx_ring[i + 1]) );
+    }
+    tx_ring[i-1].next = virt_to_bus(&tx_ring[0]);
+}
+
+/* function: epic100_transmit
+ * This transmits a packet.
+ *
+ * Arguments: char d[6]:          destination ethernet address.
+ *            unsigned short t:   ethernet protocol type.
+ *            unsigned short s:   size of the data-part of the packet.
+ *            char *p:            the data for the packet.
+ * returns:   void.
+ */
+    static void
+epic100_transmit(struct nic *nic, const char *destaddr, unsigned int type,
+		 unsigned int len, const char *data)
+{
+    unsigned short nstype;
+    char* txp;
+    int entry;
+
+    /* Calculate the next Tx descriptor entry. */
+    entry = cur_tx % TX_RING_SIZE;
+
+    if ((tx_ring[entry].status & TRING_OWN) == TRING_OWN) {
+	printf("eth_transmit: Unable to transmit. status=%hX. Resetting...\n",
+	       tx_ring[entry].status);
+
+	epic100_open();
+	return;
+    }
+
+    txp = (char*)tx_ring[entry].bufaddr;
+
+    memcpy(txp, destaddr, ETH_ALEN);
+    memcpy(txp + ETH_ALEN, nic->node_addr, ETH_ALEN);
+    nstype = htons(type);
+    memcpy(txp + 12, (char*)&nstype, 2);
+    memcpy(txp + ETH_HLEN, data, len);
+
+    len += ETH_HLEN;
+
+    /*
+     * Caution: the write order is important here,
+     * set the base address with the "ownership"
+     * bits last.
+     */
+    tx_ring[entry].txlength  = (len >= 60 ? len : 60);
+    tx_ring[entry].buflength = len;
+    tx_ring[entry].status    = TRING_OWN;	/* Pass ownership to the chip. */
+
+    cur_tx++;
+
+    /* Trigger an immediate transmit demand. */
+    outl(CR_QUEUE_TX, command);
+
+    load_timer2(10*TICKS_PER_MS);         /* timeout 10 ms for transmit */
+    while ((tx_ring[entry].status & TRING_OWN) && timer2_running())
+	/* Wait */;
+
+    if ((tx_ring[entry].status & TRING_OWN) != 0)
+	printf("Oops, transmitter timeout, status=%hX\n",
+	    tx_ring[entry].status);
+}
+
+/* function: epic100_poll / eth_poll
+ * This receives a packet from the network.
+ *
+ * Arguments: none
+ *
+ * returns:   1 if a packet was received.
+ *            0 if no pacet was received.
+ * side effects:
+ *            returns the packet in the array nic->packet.
+ *            returns the length of the packet in nic->packetlen.
+ */
+
+    static int
+epic100_poll(struct nic *nic)
+{
+    int entry;
+    int status;
+    int retcode;
+
+    entry = cur_rx % RX_RING_SIZE;
+
+    if ((status = rx_ring[entry].status & RRING_OWN) == RRING_OWN)
+	return (0);
+
+    /* We own the next entry, it's a new packet. Send it up. */
+
+#if	(EPIC_DEBUG > 4)
+    printf("epic_poll: entry %d status %hX\n", entry, status);
+#endif
+
+    cur_rx++;
+    if (status & 0x2000) {
+	printf("epic_poll: Giant packet\n");
+	retcode = 0;
+    } else if (status & 0x0006) {
+	/* Rx Frame errors are counted in hardware. */
+	printf("epic_poll: Frame received with errors\n");
+	retcode = 0;
+    } else {
+	/* Omit the four octet CRC from the length. */
+	nic->packetlen = rx_ring[entry].rxlength - 4;
+	memcpy(nic->packet, (char*)rx_ring[entry].bufaddr, nic->packetlen);
+	retcode = 1;
+    }
+
+    /* Clear all error sources. */
+    outl(status & INTR_CLEARERRS, intstat);
+
+    /* Give the descriptor back to the chip */
+    rx_ring[entry].status = RRING_OWN;
+
+    /* Restart Receiver */
+    outl(CR_START_RX | CR_QUEUE_RX, command);
+
+    return retcode;
+}
+
+
+    static void
+epic100_disable(struct nic *nic)
+{
+}
+
+
+#ifdef	DEBUG_EEPROM
+/* Serial EEPROM section. */
+
+/*  EEPROM_Ctrl bits. */
+#define EE_SHIFT_CLK	0x04	/* EEPROM shift clock. */
+#define EE_CS		0x02	/* EEPROM chip select. */
+#define EE_DATA_WRITE	0x08	/* EEPROM chip data in. */
+#define EE_WRITE_0	0x01
+#define EE_WRITE_1	0x09
+#define EE_DATA_READ	0x10	/* EEPROM chip data out. */
+#define EE_ENB		(0x0001 | EE_CS)
+
+/* The EEPROM commands include the alway-set leading bit. */
+#define EE_WRITE_CMD	(5 << 6)
+#define EE_READ_CMD	(6 << 6)
+#define EE_ERASE_CMD	(7 << 6)
+
+#define eeprom_delay(n)	delay(n)
+
+    static int
+read_eeprom(int location)
+{
+    int i;
+    int retval = 0;
+    int read_cmd = location | EE_READ_CMD;
+
+    outl(EE_ENB & ~EE_CS, eectl);
+    outl(EE_ENB, eectl);
+
+    /* Shift the read command bits out. */
+    for (i = 10; i >= 0; i--) {
+	short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+	outl(EE_ENB | dataval, eectl);
+	eeprom_delay(100);
+	outl(EE_ENB | dataval | EE_SHIFT_CLK, eectl);
+	eeprom_delay(150);
+	outl(EE_ENB | dataval, eectl);	/* Finish EEPROM a clock tick. */
+	eeprom_delay(250);
+    }
+    outl(EE_ENB, eectl);
+
+    for (i = 16; i > 0; i--) {
+	outl(EE_ENB | EE_SHIFT_CLK, eectl);
+	eeprom_delay(100);
+	retval = (retval << 1) | ((inl(eectl) & EE_DATA_READ) ? 1 : 0);
+	outl(EE_ENB, eectl);
+	eeprom_delay(100);
+    }
+
+    /* Terminate the EEPROM access. */
+    outl(EE_ENB & ~EE_CS, eectl);
+    return retval;
+}
+#endif
+
+
+#define MII_READOP	1
+#define MII_WRITEOP	2
+
+    static int
+mii_read(int phy_id, int location)
+{
+    int i;
+
+    outl((phy_id << 9) | (location << 4) | MII_READOP, mmctl);
+    /* Typical operation takes < 50 ticks. */
+
+    for (i = 4000; i > 0; i--)
+	if ((inl(mmctl) & MII_READOP) == 0)
+	    break;
+    return inw(mmdata);
+}
diff --git a/netboot/epic100.h b/netboot/epic100.h
new file mode 100644
index 0000000..61bd1d9
--- /dev/null
+++ b/netboot/epic100.h
@@ -0,0 +1,188 @@
+#ifndef	_EPIC100_H_
+# define _EPIC100_H_
+
+#ifndef	PCI_VENDOR_SMC
+# define PCI_VENDOR_SMC		0x10B8
+#endif
+
+#ifndef	PCI_DEVICE_SMC_EPIC100
+# define PCI_DEVICE_SMC_EPIC100	0x0005
+#endif
+
+#define PCI_DEVICE_ID_NONE	0xFFFF
+
+/* Offsets to registers (using SMC names). */
+enum epic100_registers {
+    COMMAND= 0,		/* Control Register */
+    INTSTAT= 4,		/* Interrupt Status */
+    INTMASK= 8,		/* Interrupt Mask */
+    GENCTL = 0x0C,	/* General Control */
+    NVCTL  = 0x10,	/* Non Volatile Control */
+    EECTL  = 0x14,	/* EEPROM Control  */
+    TEST   = 0x1C,	/* Test register: marked as reserved (see in source code) */
+    CRCCNT = 0x20,	/* CRC Error Counter */
+    ALICNT = 0x24,	/* Frame Alignment Error Counter */
+    MPCNT  = 0x28,	/* Missed Packet Counter */
+    MMCTL  = 0x30,	/* MII Management Interface Control */
+    MMDATA = 0x34,	/* MII Management Interface Data */
+    MIICFG = 0x38,	/* MII Configuration */
+    IPG    = 0x3C,	/* InterPacket Gap */
+    LAN0   = 0x40,	/* MAC address. (0x40-0x48) */
+    IDCHK  = 0x4C,	/* BoardID/ Checksum */
+    MC0    = 0x50,	/* Multicast filter table. (0x50-0x5c) */
+    RXCON  = 0x60,	/* Receive Control */
+    TXCON  = 0x70,	/* Transmit Control */
+    TXSTAT = 0x74,	/* Transmit Status */
+    PRCDAR = 0x84,	/* PCI Receive Current Descriptor Address */
+    PRSTAT = 0xA4,	/* PCI Receive DMA Status */
+    PRCPTHR= 0xB0,	/* PCI Receive Copy Threshold */
+    PTCDAR = 0xC4,	/* PCI Transmit Current Descriptor Address */
+    ETHTHR = 0xDC	/* Early Transmit Threshold */
+};
+
+/* Command register (CR_) bits */
+#define CR_STOP_RX		(0x00000001)
+#define CR_START_RX		(0x00000002)
+#define CR_QUEUE_TX		(0x00000004)
+#define CR_QUEUE_RX		(0x00000008)
+#define CR_NEXTFRAME		(0x00000010)
+#define CR_STOP_TX_DMA		(0x00000020)
+#define CR_STOP_RX_DMA		(0x00000040)
+#define CR_TX_UGO		(0x00000080)
+
+/* Interrupt register bits. NI means No Interrupt generated */
+
+#define	INTR_RX_THR_STA		(0x00400000)	/* rx copy threshold status NI */
+#define	INTR_RX_BUFF_EMPTY	(0x00200000)	/* rx buffers empty. NI */
+#define	INTR_TX_IN_PROG		(0x00100000)	/* tx copy in progess. NI */
+#define	INTR_RX_IN_PROG		(0x00080000)	/* rx copy in progress. NI */
+#define	INTR_TXIDLE		(0x00040000)	/* tx idle. NI */
+#define INTR_RXIDLE		(0x00020000)	/* rx idle. NI */
+#define INTR_INTR_ACTIVE	(0x00010000)	/* Interrupt active. NI */
+#define INTR_RX_STATUS_OK	(0x00008000)	/* rx status valid. NI */
+#define INTR_PCI_TGT_ABT	(0x00004000)	/* PCI Target abort */
+#define INTR_PCI_MASTER_ABT	(0x00002000)	/* PCI Master abort */
+#define INTR_PCI_PARITY_ERR	(0x00001000)	/* PCI adress parity error */
+#define INTR_PCI_DATA_ERR	(0x00000800)	/* PCI data parity error */
+#define INTR_RX_THR_CROSSED	(0x00000400)	/* rx copy threshold crossed */
+#define INTR_CNTFULL		(0x00000200)	/* Counter overflow */
+#define INTR_TXUNDERRUN		(0x00000100)	/* tx underrun. */
+#define INTR_TXEMPTY		(0x00000080)	/* tx queue empty */
+#define INTR_TX_CH_COMPLETE	(0x00000040)	/* tx chain complete */
+#define INTR_TXDONE		(0x00000020)	/* tx complete (w or w/o err) */
+#define INTR_RXERROR		(0x00000010)	/* rx error (CRC) */
+#define INTR_RXOVERFLOW		(0x00000008)	/* rx buffer overflow */
+#define INTR_RX_QUEUE_EMPTY	(0x00000004)	/* rx queue empty. */
+#define INTR_RXHEADER		(0x00000002)	/* header copy complete */
+#define INTR_RXDONE		(0x00000001)	/* Receive copy complete */
+
+#define INTR_CLEARINTR		(0x00007FFF)
+#define INTR_VALIDBITS		(0x007FFFFF)
+#define INTR_DISABLE		(0x00000000)
+#define INTR_CLEARERRS		(0x00007F18)
+#define INTR_ABNINTR		(INTR_CNTFULL | INTR_TXUNDERRUN | INTR_RXOVERFLOW)
+
+/* General Control (GC_) bits */
+
+#define GC_SOFT_RESET		(0x00000001)
+#define GC_INTR_ENABLE		(0x00000002)
+#define GC_SOFT_INTR		(0x00000004)
+#define GC_POWER_DOWN		(0x00000008)
+#define GC_ONE_COPY		(0x00000010)
+#define GC_BIG_ENDIAN		(0x00000020)
+#define GC_RX_PREEMPT_TX	(0x00000040)
+#define GC_TX_PREEMPT_RX	(0x00000080)
+
+/*
+ * Receive FIFO Threshold values
+ * Control the level at which the  PCI burst state machine
+ * begins to empty the receive FIFO. Possible values: 0-3
+ *
+ * 0 => 32, 1 => 64, 2 => 96 3 => 128 bytes.
+ */
+#define GC_RX_FIFO_THR_32	(0x00000000)
+#define GC_RX_FIFO_THR_64	(0x00000100)
+#define GC_RX_FIFO_THR_96	(0x00000200)
+#define GC_RX_FIFO_THR_128	(0x00000300)
+
+/* Memory Read Control (MRC_) values */
+#define GC_MRC_MEM_READ		(0x00000000)
+#define GC_MRC_READ_MULT	(0x00000400)
+#define GC_MRC_READ_LINE	(0x00000800)
+
+#define GC_SOFTBIT0		(0x00001000)
+#define GC_SOFTBIT1		(0x00002000)
+#define GC_RESET_PHY		(0x00004000)
+
+/* Definitions of the Receive Control (RC_) register bits */
+
+#define RC_SAVE_ERRORED_PKT	(0x00000001)
+#define RC_SAVE_RUNT_FRAMES	(0x00000002)
+#define RC_RCV_BROADCAST	(0x00000004)
+#define RC_RCV_MULTICAST	(0x00000008)
+#define RC_RCV_INVERSE_PKT	(0x00000010)
+#define RC_PROMISCUOUS_MODE	(0x00000020)
+#define RC_MONITOR_MODE		(0x00000040)
+#define RC_EARLY_RCV_ENABLE	(0x00000080)
+
+/* description of the rx descriptors control bits */
+#define RD_FRAGLIST		(0x0001)	/* Desc points to a fragment list */
+#define RD_LLFORM		(0x0002)	/* Frag list format */
+#define RD_HDR_CPY		(0x0004)	/* Desc used for header copy */
+
+/* Definition of the Transmit CONTROL (TC) register bits */
+
+#define TC_EARLY_TX_ENABLE	(0x00000001)
+
+/* Loopback Mode (LM_) Select valuesbits */
+#define TC_LM_NORMAL		(0x00000000)
+#define TC_LM_INTERNAL		(0x00000002)
+#define TC_LM_EXTERNAL		(0x00000004)
+#define TC_LM_FULL_DPX		(0x00000006)
+
+#define TX_SLOT_TIME		(0x00000078)
+
+/* Bytes transferred to chip before transmission starts. */
+#define TX_FIFO_THRESH		128	/* Rounded down to 4 byte units. */
+
+/* description of rx descriptors status bits */
+#define RRING_PKT_INTACT	(0x0001)
+#define RRING_ALIGN_ERR		(0x0002)
+#define RRING_CRC_ERR		(0x0004)
+#define RRING_MISSED_PKT	(0x0008)
+#define RRING_MULTICAST		(0x0010)
+#define RRING_BROADCAST		(0x0020)
+#define RRING_RECEIVER_DISABLE	(0x0040)
+#define RRING_STATUS_VALID	(0x1000)
+#define RRING_FRAGLIST_ERR	(0x2000)
+#define RRING_HDR_COPIED	(0x4000)
+#define RRING_OWN		(0x8000)
+
+/* error summary */
+#define RRING_ERROR		(RRING_ALIGN_ERR|RRING_CRC_ERR)
+
+/* description of tx descriptors status bits */
+#define TRING_PKT_INTACT	(0x0001)	/* pkt transmitted. */
+#define TRING_PKT_NONDEFER	(0x0002)	/* pkt xmitted w/o deferring */
+#define TRING_COLL		(0x0004)	/* pkt xmitted w collisions */
+#define TRING_CARR		(0x0008)	/* carrier sense lost */
+#define TRING_UNDERRUN		(0x0010)	/* DMA underrun */
+#define TRING_HB_COLL		(0x0020)	/* Collision detect Heartbeat */
+#define TRING_WIN_COLL		(0x0040)	/* out of window collision */
+#define TRING_DEFERRED		(0x0080)	/* Deferring */
+#define TRING_COLL_COUNT	(0x0F00)	/* collision counter (mask) */
+#define TRING_COLL_EXCESS	(0x1000)	/* tx aborted: excessive colls */
+#define TRING_OWN		(0x8000)	/* desc ownership bit */
+
+/* error summary */
+#define TRING_ABORT	(TRING_COLL_EXCESS|TRING_WIN_COLL|TRING_UNDERRUN)
+#define TRING_ERROR	(TRING_DEFERRED|TRING_WIN_COLL|TRING_UNDERRUN|TRING_CARR/*|TRING_COLL*/ )
+
+/* description of the tx descriptors control bits */
+#define TD_FRAGLIST		(0x0001)	/* Desc points to a fragment list */
+#define TD_LLFORM		(0x0002)	/* Frag list format */
+#define TD_IAF			(0x0004)	/* Generate Interrupt after tx */
+#define TD_NOCRC		(0x0008)	/* No CRC generated */
+#define TD_LASTDESC		(0x0010)	/* Last desc for this frame */
+
+#endif	/* _EPIC100_H_ */
diff --git a/netboot/etherboot.h b/netboot/etherboot.h
new file mode 100644
index 0000000..74ca16f
--- /dev/null
+++ b/netboot/etherboot.h
@@ -0,0 +1,547 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,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.
+ */
+
+/* RULE: You must define the macro ``GRUB'' when including this header
+   file in GRUB code.  */
+
+/* Based on "src/etherboot.h" in etherboot-5.0.5.  */
+
+/**************************************************************************
+ETHERBOOT -  BOOTP/TFTP Bootstrap Program
+
+Author: Martin Renters
+  Date: Dec/93
+
+**************************************************************************/
+
+/* Include GRUB-specific macros and prototypes here.  */
+#include <shared.h>
+
+/* FIXME: For now, enable the DHCP support. Perhaps I should segregate
+   the DHCP support from the BOOTP support, and permit both to
+   co-exist.  */
+#undef NO_DHCP_SUPPORT
+
+/* In GRUB, the relocated address in Etherboot doesn't have any sense.
+   Just define it as a bogus value.  */
+#define RELOC	0
+
+/* FIXME: Should be an option.  */
+#define BACKOFF_LIMIT	7
+
+#include <osdep.h>
+
+#define CTRL_C		3
+
+#ifndef	MAX_TFTP_RETRIES
+# define MAX_TFTP_RETRIES	20
+#endif
+
+#ifndef	MAX_BOOTP_RETRIES
+# define MAX_BOOTP_RETRIES	20
+#endif
+
+#define MAX_BOOTP_EXTLEN	(ETH_FRAME_LEN - ETH_HLEN - \
+				 sizeof (struct bootp_t))
+
+#ifndef	MAX_ARP_RETRIES
+# define MAX_ARP_RETRIES	20
+#endif
+
+#ifndef	MAX_RPC_RETRIES
+# define MAX_RPC_RETRIES	20
+#endif
+
+#define	TICKS_PER_SEC		18
+
+/* Inter-packet retry in ticks */
+#define TIMEOUT			(10 * TICKS_PER_SEC)
+
+/* These settings have sense only if compiled with -DCONGESTED */
+/* total retransmission timeout in ticks */
+#define TFTP_TIMEOUT		(30 * TICKS_PER_SEC)
+/* packet retransmission timeout in ticks */
+#define TFTP_REXMT		(3 * TICKS_PER_SEC)
+
+#ifndef	NULL
+# define NULL			((void *) 0)
+#endif
+
+/*
+   I'm moving towards the defined names in linux/if_ether.h for clarity.
+   The confusion between 60/64 and 1514/1518 arose because the NS8390
+   counts the 4 byte frame checksum in the incoming packet, but not
+   in the outgoing packet. 60/1514 are the correct numbers for most
+   if not all of the other NIC controllers. I will be retiring the
+   64/1518 defines in the lead-up to 5.0.
+*/
+
+#define ETH_ALEN		6	/* Size of Ethernet address */
+#define ETH_HLEN		14	/* Size of ethernet header */
+#define	ETH_ZLEN		60	/* Minimum packet */
+/*#define ETH_MIN_PACKET		64*/
+#define	ETH_FRAME_LEN		1514	/* Maximum packet */
+/*#define ETH_MAX_PACKET		1518*/
+/* Because some DHCP/BOOTP servers don't treat the maximum length the same
+   as Etherboot, subtract the size of an IP header and that of an UDP
+   header.  */
+#define	ETH_MAX_MTU		(ETH_FRAME_LEN - ETH_HLEN \
+				- sizeof (struct iphdr) \
+				- sizeof (struct udphdr))
+
+#define ARP_CLIENT	0
+#define ARP_SERVER	1
+#define ARP_GATEWAY	2
+#define ARP_ROOTSERVER	3
+#define ARP_SWAPSERVER	4
+#define MAX_ARP		ARP_SWAPSERVER+1
+
+#define	RARP_REQUEST	3
+#define	RARP_REPLY	4
+
+#define IP		0x0800
+#define ARP		0x0806
+#define	RARP		0x8035
+
+#define BOOTP_SERVER	67
+#define BOOTP_CLIENT	68
+#define TFTP_PORT	69
+#define SUNRPC_PORT	111
+
+#define IP_UDP		17
+/* Same after going through htonl */
+#define IP_BROADCAST	0xFFFFFFFF
+
+#define ARP_REQUEST	1
+#define ARP_REPLY	2
+
+#define BOOTP_REQUEST	1
+#define BOOTP_REPLY	2
+
+#define TAG_LEN(p)		(*((p) + 1))
+#define RFC1533_COOKIE		99, 130, 83, 99
+#define RFC1533_PAD		0
+#define RFC1533_NETMASK		1
+#define RFC1533_TIMEOFFSET	2
+#define RFC1533_GATEWAY		3
+#define RFC1533_TIMESERVER	4
+#define RFC1533_IEN116NS	5
+#define RFC1533_DNS		6
+#define RFC1533_LOGSERVER	7
+#define RFC1533_COOKIESERVER	8
+#define RFC1533_LPRSERVER	9
+#define RFC1533_IMPRESSSERVER	10
+#define RFC1533_RESOURCESERVER	11
+#define RFC1533_HOSTNAME	12
+#define RFC1533_BOOTFILESIZE	13
+#define RFC1533_MERITDUMPFILE	14
+#define RFC1533_DOMAINNAME	15
+#define RFC1533_SWAPSERVER	16
+#define RFC1533_ROOTPATH	17
+#define RFC1533_EXTENSIONPATH	18
+#define RFC1533_IPFORWARDING	19
+#define RFC1533_IPSOURCEROUTING	20
+#define RFC1533_IPPOLICYFILTER	21
+#define RFC1533_IPMAXREASSEMBLY	22
+#define RFC1533_IPTTL		23
+#define RFC1533_IPMTU		24
+#define RFC1533_IPMTUPLATEAU	25
+#define RFC1533_INTMTU		26
+#define RFC1533_INTLOCALSUBNETS	27
+#define RFC1533_INTBROADCAST	28
+#define RFC1533_INTICMPDISCOVER	29
+#define RFC1533_INTICMPRESPOND	30
+#define RFC1533_INTROUTEDISCOVER 31
+#define RFC1533_INTROUTESOLICIT	32
+#define RFC1533_INTSTATICROUTES	33
+#define RFC1533_LLTRAILERENCAP	34
+#define RFC1533_LLARPCACHETMO	35
+#define RFC1533_LLETHERNETENCAP	36
+#define RFC1533_TCPTTL		37
+#define RFC1533_TCPKEEPALIVETMO	38
+#define RFC1533_TCPKEEPALIVEGB	39
+#define RFC1533_NISDOMAIN	40
+#define RFC1533_NISSERVER	41
+#define RFC1533_NTPSERVER	42
+#define RFC1533_VENDOR		43
+#define RFC1533_NBNS		44
+#define RFC1533_NBDD		45
+#define RFC1533_NBNT		46
+#define RFC1533_NBSCOPE		47
+#define RFC1533_XFS		48
+#define RFC1533_XDM		49
+#ifndef	NO_DHCP_SUPPORT
+#define RFC2132_REQ_ADDR	50
+#define RFC2132_MSG_TYPE	53
+#define RFC2132_SRV_ID		54
+#define RFC2132_PARAM_LIST	55
+#define RFC2132_MAX_SIZE	57
+#define RFC2132_VENDOR_CLASS_ID	60
+
+#define DHCPDISCOVER		1
+#define DHCPOFFER		2
+#define DHCPREQUEST		3
+#define DHCPACK			5
+#endif	/* NO_DHCP_SUPPORT */
+
+#define RFC1533_VENDOR_MAJOR	0
+#define RFC1533_VENDOR_MINOR	0
+
+#define RFC1533_VENDOR_MAGIC	128
+#define RFC1533_VENDOR_ADDPARM	129
+#define RFC1533_VENDOR_MNUOPTS	160
+#define RFC1533_VENDOR_SELECTION 176
+#define RFC1533_VENDOR_MOTD	184
+#define RFC1533_VENDOR_NUMOFMOTD 8
+#define RFC1533_VENDOR_IMG	192
+#define RFC1533_VENDOR_NUMOFIMG	16
+
+#define RFC1533_VENDOR_CONFIGFILE	150
+
+#define RFC1533_END		255
+
+#define BOOTP_VENDOR_LEN	64
+#ifndef	NO_DHCP_SUPPORT
+#define DHCP_OPT_LEN		312
+#endif	/* NO_DHCP_SUPPORT */
+
+#define	TFTP_DEFAULTSIZE_PACKET	512
+#define	TFTP_MAX_PACKET		1432 /* 512 */
+
+#define TFTP_RRQ	1
+#define TFTP_WRQ	2
+#define TFTP_DATA	3
+#define TFTP_ACK	4
+#define TFTP_ERROR	5
+#define TFTP_OACK	6
+
+#define TFTP_CODE_EOF	1
+#define TFTP_CODE_MORE	2
+#define TFTP_CODE_ERROR	3
+#define TFTP_CODE_BOOT	4
+#define TFTP_CODE_CFG	5
+
+#define AWAIT_ARP	0
+#define AWAIT_BOOTP	1
+#define AWAIT_TFTP	2
+#define AWAIT_RARP	3
+#define AWAIT_RPC	4
+#define AWAIT_QDRAIN	5	/* drain queue, process ARP requests */
+
+typedef struct
+{
+  unsigned long	s_addr;
+}
+in_addr;
+
+struct arptable_t
+{
+  in_addr ipaddr;
+  unsigned char node[6];
+};
+
+/*
+ * A pity sipaddr and tipaddr are not longword aligned or we could use
+ * in_addr. No, I don't want to use #pragma packed.
+ */
+struct arprequest
+{
+  unsigned short hwtype;
+  unsigned short protocol;
+  char hwlen;
+  char protolen;
+  unsigned short opcode;
+  char shwaddr[6];
+  char sipaddr[4];
+  char thwaddr[6];
+  char tipaddr[4];
+};
+
+struct iphdr
+{
+  char verhdrlen;
+  char service;
+  unsigned short len;
+  unsigned short ident;
+  unsigned short frags;
+  char ttl;
+  char protocol;
+  unsigned short chksum;
+  in_addr src;
+  in_addr dest;
+};
+
+struct udphdr
+{
+  unsigned short src;
+  unsigned short dest;
+  unsigned short len;
+  unsigned short chksum;
+};
+
+/* Format of a bootp packet.  */
+struct bootp_t
+{
+  char bp_op;
+  char bp_htype;
+  char bp_hlen;
+  char bp_hops;
+  unsigned long bp_xid;
+  unsigned short bp_secs;
+  unsigned short unused;
+  in_addr bp_ciaddr;
+  in_addr bp_yiaddr;
+  in_addr bp_siaddr;
+  in_addr bp_giaddr;
+  char bp_hwaddr[16];
+  char bp_sname[64];
+  char bp_file[128];
+#ifdef	NO_DHCP_SUPPORT
+  char bp_vend[BOOTP_VENDOR_LEN];
+#else
+  char bp_vend[DHCP_OPT_LEN];
+#endif	/* NO_DHCP_SUPPORT */
+};
+
+/* Format of a bootp IP packet.  */
+struct bootpip_t
+{
+  struct iphdr ip;
+  struct udphdr udp;
+  struct bootp_t bp;
+};
+
+/* Format of bootp packet with extensions.  */
+struct bootpd_t
+{
+  struct bootp_t bootp_reply;
+  unsigned char  bootp_extension[MAX_BOOTP_EXTLEN];
+};
+
+struct tftp_t
+{
+  struct iphdr ip;
+  struct udphdr udp;
+  unsigned short opcode;
+  union
+  {
+    char rrq[TFTP_DEFAULTSIZE_PACKET];
+    
+    struct
+    {
+      unsigned short block;
+      char download[TFTP_MAX_PACKET];
+    }
+    data;
+    
+    struct
+    {
+      unsigned short block;
+    }
+    ack;
+    
+    struct
+    {
+      unsigned short errcode;
+      char errmsg[TFTP_DEFAULTSIZE_PACKET];
+    }
+    err;
+    
+    struct
+    {
+      char data[TFTP_DEFAULTSIZE_PACKET+2];
+    }
+    oack;
+  }
+  u;
+};
+
+/* Define a smaller tftp packet solely for making requests to conserve stack
+   512 bytes should be enough.  */
+struct tftpreq_t
+{
+  struct iphdr ip;
+  struct udphdr udp;
+  unsigned short opcode;
+  union
+  {
+    char rrq[512];
+    
+    struct
+    {
+      unsigned short block;
+    }
+    ack;
+    
+    struct
+    {
+      unsigned short errcode;
+      char errmsg[512-2];
+    }
+    err;
+  }
+  u;
+};
+
+#define TFTP_MIN_PACKET	(sizeof(struct iphdr) + sizeof(struct udphdr) + 4)
+
+struct rpc_t
+{
+  struct iphdr ip;
+  struct udphdr udp;
+  union
+  {
+    char data[300];		/* longest RPC call must fit!!!! */
+    
+    struct
+    {
+      long id;
+      long type;
+      long rpcvers;
+      long prog;
+      long vers;
+      long proc;
+      long data[1];
+    }
+    call;
+    
+    struct
+    {
+      long id;
+      long type;
+      long rstatus;
+      long verifier;
+      long v2;
+      long astatus;
+      long data[1];
+    }
+    reply;
+  }
+  u;
+};
+
+#define PROG_PORTMAP	100000
+#define PROG_NFS	100003
+#define PROG_MOUNT	100005
+
+#define MSG_CALL	0
+#define MSG_REPLY	1
+
+#define PORTMAP_GETPORT	3
+
+#define MOUNT_ADDENTRY	1
+#define MOUNT_UMOUNTALL	4
+
+#define NFS_LOOKUP	4
+#define NFS_READ	6
+
+#define NFS_FHSIZE	32
+
+#define NFSERR_PERM	1
+#define NFSERR_NOENT	2
+#define NFSERR_ACCES	13
+
+/* Block size used for NFS read accesses.  A RPC reply packet (including  all
+ * headers) must fit within a single Ethernet frame to avoid fragmentation.
+ * Chosen to be a power of two, as most NFS servers are optimized for this.  */
+#define NFS_READ_SIZE	1024
+
+#define	FLOPPY_BOOT_LOCATION	0x7c00
+/* Must match offsets in loader.S */
+#define ROM_SEGMENT		0x1fa
+#define ROM_LENGTH		0x1fc
+
+#define	ROM_INFO_LOCATION	(FLOPPY_BOOT_LOCATION + ROM_SEGMENT)
+/* at end of floppy boot block */
+
+struct rom_info
+{
+  unsigned short	rom_segment;
+  unsigned short	rom_length;
+};
+
+static inline int
+rom_address_ok (struct rom_info *rom, int assigned_rom_segment)
+{
+  return (assigned_rom_segment < 0xC000
+	  || assigned_rom_segment == rom->rom_segment);
+}
+
+/* Define a type for passing info to a loaded program.  */
+struct ebinfo
+{
+  unsigned char	major, minor;	/* Version */
+  unsigned short	flags;		/* Bit flags */
+};
+
+/***************************************************************************
+External prototypes
+***************************************************************************/
+/* main.c */
+extern void print_network_configuration (void);
+extern int ifconfig (char *ip, char *sm, char *gw, char *svr);
+extern int udp_transmit (unsigned long destip, unsigned int srcsock,
+			 unsigned int destsock, int len, const void *buf);
+extern int await_reply (int type, int ival, void *ptr, int timeout);
+extern int decode_rfc1533 (unsigned char *, int, int, int);
+extern long rfc2131_sleep_interval (int base, int exp);
+extern void cleanup (void);
+extern int rarp (void);
+extern int bootp (void);
+extern void cleanup_net (void);
+
+/* config.c */
+extern void print_config (void);
+extern void eth_reset (void);
+extern int eth_probe (void);
+extern int eth_poll (void);
+extern void eth_transmit (const char *d, unsigned int t,
+			  unsigned int s, const void *p);
+extern void eth_disable (void);
+
+/* misc.c */
+extern void twiddle (void);
+extern void sleep (int secs);
+extern int getdec (char **s);
+extern void etherboot_printf (const char *, ...);
+extern int etherboot_sprintf (char *, const char *, ...);
+extern int inet_aton (char *p, in_addr *i);
+
+/***************************************************************************
+External variables
+***************************************************************************/
+/* main.c */
+extern int ip_abort;
+extern int network_ready;
+extern struct rom_info rom;
+extern struct arptable_t arptable[MAX_ARP];
+extern struct bootpd_t bootp_data;
+#define	BOOTP_DATA_ADDR	(&bootp_data)
+extern unsigned char *end_of_rfc1533;
+
+/* config.c */
+extern struct nic nic;
+
+/* Local hack - define some macros to use etherboot source files "as is".  */
+#ifndef GRUB
+# undef printf
+# define printf	etherboot_printf
+# undef sprintf
+# define sprintf etherboot_sprintf
+#endif /* GRUB */
diff --git a/netboot/fa311.c b/netboot/fa311.c
new file mode 100644
index 0000000..df92a68
--- /dev/null
+++ b/netboot/fa311.c
@@ -0,0 +1,421 @@
+/*
+        Driver for the National Semiconductor DP83810 Ethernet controller.
+        
+        Portions Copyright (C) 2001 Inprimis Technologies, Inc.
+        http://www.inprimis.com/
+        
+        This driver is based (heavily) on the Linux driver for this chip 
+        which is copyright 1999-2001 by Donald Becker.
+
+        This software has no warranties expressed or implied for any
+        purpose.
+
+        This software may be used and distributed according to the terms of
+        the GNU General Public License (GPL), incorporated herein by reference.
+        Drivers based on or derived from this code fall under the GPL and must
+        retain the authorship, copyright and license notice.  This file is not
+        a complete program and may only be used when the entire operating
+        system is licensed under the GPL.  License for under other terms may be
+        available.  Contact the original author for details.
+
+        The original author may be reached as becker@scyld.com, or at
+        Scyld Computing Corporation
+        410 Severn Ave., Suite 210
+        Annapolis MD 21403
+*/
+
+
+typedef unsigned char  u8;
+typedef   signed char  s8;
+typedef unsigned short u16;
+typedef   signed short s16;
+typedef unsigned int   u32;
+typedef   signed int   s32;
+
+#include "etherboot.h"
+#include "nic.h"
+#include "pci.h"
+
+#undef	virt_to_bus
+#define	virt_to_bus(x)          ((unsigned long)x)
+#define cpu_to_le32(val)        (val)
+#define le32_to_cpu(val)        (val)
+#define virt_to_le32desc(addr)  cpu_to_le32(virt_to_bus(addr))
+#define le32desc_to_virt(addr)  bus_to_virt(le32_to_cpu(addr))
+
+#define TX_RING_SIZE 1
+#define RX_RING_SIZE 4
+#define TIME_OUT     1000000
+#define PKT_BUF_SZ   1536
+
+/* Offsets to the device registers. */
+enum register_offsets {
+    ChipCmd=0x00, ChipConfig=0x04, EECtrl=0x08, PCIBusCfg=0x0C,
+    IntrStatus=0x10, IntrMask=0x14, IntrEnable=0x18,
+    TxRingPtr=0x20, TxConfig=0x24,
+    RxRingPtr=0x30, RxConfig=0x34,
+    WOLCmd=0x40, PauseCmd=0x44, RxFilterAddr=0x48, RxFilterData=0x4C,
+    BootRomAddr=0x50, BootRomData=0x54, StatsCtrl=0x5C, StatsData=0x60,
+    RxPktErrs=0x60, RxMissed=0x68, RxCRCErrs=0x64,
+};
+
+/* Bit in ChipCmd. */
+enum ChipCmdBits {
+    ChipReset=0x100, RxReset=0x20, TxReset=0x10, RxOff=0x08, RxOn=0x04,
+    TxOff=0x02, TxOn=0x01,
+};
+
+/* Bits in the interrupt status/mask registers. */
+enum intr_status_bits {
+    IntrRxDone=0x0001, IntrRxIntr=0x0002, IntrRxErr=0x0004, IntrRxEarly=0x0008,
+    IntrRxIdle=0x0010, IntrRxOverrun=0x0020,
+    IntrTxDone=0x0040, IntrTxIntr=0x0080, IntrTxErr=0x0100,
+    IntrTxIdle=0x0200, IntrTxUnderrun=0x0400,
+    StatsMax=0x0800, LinkChange=0x4000,	WOLPkt=0x2000,
+    RxResetDone=0x1000000, TxResetDone=0x2000000,
+    IntrPCIErr=0x00f00000, IntrNormalSummary=0x0251, IntrAbnormalSummary=0xED20,
+};
+
+/* Bits in the RxMode register. */
+enum rx_mode_bits {
+    AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0xC0000000,
+    AcceptMulticast=0x00200000, AcceptAllMulticast=0x20000000,
+    AcceptAllPhys=0x10000000, AcceptMyPhys=0x08000000,
+};
+
+/* Bits in network_desc.status */
+enum desc_status_bits {
+    DescOwn=0x80000000, DescMore=0x40000000, DescIntr=0x20000000,
+    DescNoCRC=0x10000000,
+    DescPktOK=0x08000000, RxTooLong=0x00400000,
+};
+
+/* The Rx and Tx buffer descriptors. */
+struct netdev_desc {
+    u32 next_desc;
+    s32 cmd_status;
+    u32 addr;
+};
+
+static struct FA311_DEV {
+    unsigned int    ioaddr;
+    unsigned short  vendor;
+    unsigned short  device;
+    unsigned int    cur_rx;
+    unsigned int    cur_tx;
+    unsigned int    rx_buf_sz;
+    volatile struct netdev_desc *rx_head_desc;
+    volatile struct netdev_desc rx_ring[RX_RING_SIZE] __attribute__ ((aligned (4)));
+    volatile struct netdev_desc tx_ring[TX_RING_SIZE] __attribute__ ((aligned (4)));
+} fa311_dev;
+
+static int  eeprom_read(long ioaddr, int location);
+static void init_ring(struct FA311_DEV *dev);
+static void fa311_reset(struct nic *nic);
+static int  fa311_poll(struct nic *nic);
+static void fa311_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p);
+static void fa311_disable(struct nic *nic);
+
+static char rx_packet[PKT_BUF_SZ * RX_RING_SIZE] __attribute__ ((aligned (4)));
+static char tx_packet[PKT_BUF_SZ * TX_RING_SIZE] __attribute__ ((aligned (4)));
+
+struct nic * fa311_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci)
+{
+int            prev_eedata;
+int            i;
+int            duplex;
+int            tx_config;
+int            rx_config;
+unsigned char  macaddr[6];
+unsigned char  mactest;
+unsigned char  pci_bus = 0;
+struct FA311_DEV* dev = &fa311_dev;
+	
+    if (io_addrs == 0 || *io_addrs == 0)
+        return (0);
+    memset(dev, 0, sizeof(*dev));
+    dev->vendor = pci->vendor;
+    dev->device = pci->dev_id;
+    dev->ioaddr = pci->membase;
+
+    /* Work around the dropped serial bit. */
+    prev_eedata = eeprom_read(dev->ioaddr, 6);
+    for (i = 0; i < 3; i++) {
+        int eedata = eeprom_read(dev->ioaddr, i + 7);
+        macaddr[i*2] = (eedata << 1) + (prev_eedata >> 15);
+        macaddr[i*2+1] = eedata >> 7;
+        prev_eedata = eedata;
+    }
+    mactest = 0;
+    for (i = 0; i < 6; i++)
+        mactest |= macaddr[i];
+    if (mactest == 0)
+        return (0);
+    for (i = 0; i < 6; i++)
+        nic->node_addr[i] = macaddr[i];
+    printf("%! ", nic->node_addr);
+
+    adjust_pci_device(pci);
+
+    fa311_reset(nic);
+
+    nic->reset = fa311_reset;
+    nic->disable = fa311_disable;
+    nic->poll = fa311_poll;
+    nic->transmit = fa311_transmit;
+
+    init_ring(dev);
+
+    writel(virt_to_bus(dev->rx_ring), dev->ioaddr + RxRingPtr);
+    writel(virt_to_bus(dev->tx_ring), dev->ioaddr + TxRingPtr);
+
+    for (i = 0; i < 6; i += 2)
+    {
+        writel(i, dev->ioaddr + RxFilterAddr);
+        writew(macaddr[i] + (macaddr[i+1] << 8),
+               dev->ioaddr + RxFilterData);
+    }
+
+    /* Initialize other registers. */
+    /* Configure for standard, in-spec Ethernet. */
+    if (readl(dev->ioaddr + ChipConfig) & 0x20000000)
+    {    /* Full duplex */
+        tx_config = 0xD0801002;
+        rx_config = 0x10000020;
+    }
+    else
+    {
+        tx_config = 0x10801002;
+        rx_config = 0x0020;
+    }
+    writel(tx_config, dev->ioaddr + TxConfig);
+    writel(rx_config, dev->ioaddr + RxConfig);
+
+    duplex = readl(dev->ioaddr + ChipConfig) & 0x20000000 ? 1 : 0;
+    if (duplex) {
+        rx_config |= 0x10000000;
+        tx_config |= 0xC0000000;
+    } else {
+        rx_config &= ~0x10000000;
+        tx_config &= ~0xC0000000;
+    }
+    writew(tx_config, dev->ioaddr + TxConfig);
+    writew(rx_config, dev->ioaddr + RxConfig);
+
+    writel(AcceptBroadcast | AcceptAllMulticast | AcceptMyPhys, 
+           dev->ioaddr + RxFilterAddr);
+
+    writel(RxOn | TxOn, dev->ioaddr + ChipCmd);
+    writel(4, dev->ioaddr + StatsCtrl);              /* Clear Stats */
+    return nic;	
+
+}
+
+static void fa311_reset(struct nic *nic)
+{
+u32 chip_config;
+struct FA311_DEV* dev = &fa311_dev;
+
+    /* Reset the chip to erase previous misconfiguration. */
+    outl(ChipReset, dev->ioaddr + ChipCmd);
+
+    if ((readl(dev->ioaddr + ChipConfig) & 0xe000) != 0xe000)
+    {
+        chip_config = readl(dev->ioaddr + ChipConfig);
+    }
+}
+
+static int fa311_poll(struct nic *nic)
+{
+s32 desc_status;
+int to;
+int entry;
+int retcode;
+struct FA311_DEV* dev = &fa311_dev;
+
+    retcode = 0;
+    entry = dev->cur_rx;
+    to = TIME_OUT;
+    while (to != 0)
+    {
+        desc_status = dev->rx_ring[entry].cmd_status;
+        if ((desc_status & DescOwn) != 0)
+            break;
+        else
+            --to;
+    }
+    if (to != 0)
+    {
+        readl(dev->ioaddr + IntrStatus);         /* clear interrrupt bits */
+        /* driver owns the next entry it's a new packet. Send it up. */
+        if ((desc_status & (DescMore|DescPktOK|RxTooLong)) == DescPktOK)
+        {
+            nic->packetlen = (desc_status & 0x0fff) - 4;    /* Omit CRC size. */
+            memcpy(nic->packet, (char*)(dev->rx_ring[entry].addr), nic->packetlen);
+            retcode = 1;
+        }
+        /* Give the descriptor back to the chip */
+        dev->rx_ring[entry].cmd_status = cpu_to_le32(dev->rx_buf_sz);
+        dev->cur_rx++;
+        if (dev->cur_rx >= RX_RING_SIZE)
+            dev->cur_rx = 0;
+        dev->rx_head_desc = &dev->rx_ring[dev->cur_rx];
+    }
+    /* Restart Rx engine if stopped. */
+    writel(RxOn, dev->ioaddr + ChipCmd);
+    return retcode;
+}
+
+static void fa311_transmit(struct nic *nic, const char *destaddr, unsigned int type, unsigned int len, const char *data)
+{
+unsigned short nstype;
+s32            desc_status;
+int            to;
+int            entry;
+char*          txp;
+unsigned char* s;
+struct FA311_DEV* dev = &fa311_dev;
+
+    /* Calculate the next Tx descriptor entry. */
+    entry = dev->cur_tx;
+    txp = (char*)(dev->tx_ring[entry].addr);
+
+    memcpy(txp, destaddr, ETH_ALEN);
+    memcpy(txp + ETH_ALEN, nic->node_addr, ETH_ALEN);
+    nstype = htons(type);
+    memcpy(txp + 12, (char*)&nstype, 2);
+    memcpy(txp + ETH_HLEN, data, len);
+    len += ETH_HLEN;
+    /* pad frame */
+    if (len <  ETH_ZLEN)
+    {
+        s = (unsigned char*)(txp+len);
+        while (s < (unsigned char*)(txp+ETH_ZLEN))
+            *s++ = 0;
+        len = ETH_ZLEN;
+    }
+    dev->tx_ring[entry].cmd_status = cpu_to_le32(DescOwn | len);
+    dev->cur_tx++;
+    if (dev->cur_tx >= TX_RING_SIZE)
+        dev->cur_tx = 0;
+
+    /* Wake the potentially-idle transmit channel. */
+    writel(TxOn, dev->ioaddr + ChipCmd);
+
+    /* wait for tranmission to complete */
+    to = TIME_OUT;
+    while (to != 0)
+    {
+        desc_status = dev->tx_ring[entry].cmd_status;
+        if ((desc_status & DescOwn) == 0)
+            break;
+        else
+            --to;
+    }
+
+    readl(dev->ioaddr + IntrStatus);         /* clear interrrupt bits */
+    return;
+}
+
+static void fa311_disable(struct nic *nic)
+{
+struct FA311_DEV* dev = &fa311_dev;
+
+    /* Stop the chip's Tx and Rx processes. */
+    writel(RxOff | TxOff, dev->ioaddr + ChipCmd);
+}
+
+
+/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
+   The EEPROM code is for the common 93c06/46 EEPROMs with 6 bit addresses. */
+
+/* Delay between EEPROM clock transitions.
+   No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
+   a delay.  Note that pre-2.0.34 kernels had a cache-alignment bug that
+   made udelay() unreliable.
+   The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
+   depricated.
+*/
+#define eeprom_delay(ee_addr)	inl(ee_addr)
+
+enum EEPROM_Ctrl_Bits {
+	EE_ShiftClk=0x04, EE_DataIn=0x01, EE_ChipSelect=0x08, EE_DataOut=0x02,
+};
+#define EE_Write0 (EE_ChipSelect)
+#define EE_Write1 (EE_ChipSelect | EE_DataIn)
+
+/* The EEPROM commands include the alway-set leading bit. */
+enum EEPROM_Cmds {
+	EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
+};
+
+
+static int eeprom_read(long addr, int location)
+{
+	int i;
+	int retval = 0;
+	int ee_addr = addr + EECtrl;
+	int read_cmd = location | EE_ReadCmd;
+	writel(EE_Write0, ee_addr);
+
+	/* Shift the read command bits out. */
+	for (i = 10; i >= 0; i--) {
+		short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
+		writel(dataval, ee_addr);
+		eeprom_delay(ee_addr);
+		writel(dataval | EE_ShiftClk, ee_addr);
+		eeprom_delay(ee_addr);
+	}
+	writel(EE_ChipSelect, ee_addr);
+	eeprom_delay(ee_addr);
+
+	for (i = 0; i < 16; i++) {
+		writel(EE_ChipSelect | EE_ShiftClk, ee_addr);
+		eeprom_delay(ee_addr);
+		retval |= (readl(ee_addr) & EE_DataOut) ? 1 << i : 0;
+		writel(EE_ChipSelect, ee_addr);
+		eeprom_delay(ee_addr);
+	}
+
+	/* Terminate the EEPROM access. */
+	writel(EE_Write0, ee_addr);
+	writel(0, ee_addr);
+	return retval;
+}
+
+/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
+static void init_ring(struct FA311_DEV *dev)
+{
+	int i;
+
+	dev->cur_rx = 0;
+    dev->cur_tx = 0;
+
+	dev->rx_buf_sz = PKT_BUF_SZ;
+	dev->rx_head_desc = &dev->rx_ring[0];
+
+	/* Initialize all Rx descriptors. */
+	for (i = 0; i < RX_RING_SIZE; i++) {
+		dev->rx_ring[i].next_desc = virt_to_le32desc(&dev->rx_ring[i+1]);
+		dev->rx_ring[i].cmd_status = DescOwn;
+	}
+	/* Mark the last entry as wrapping the ring. */
+	dev->rx_ring[i-1].next_desc = virt_to_le32desc(&dev->rx_ring[0]);
+
+	/* Fill in the Rx buffers.  Handle allocation failure gracefully. */
+	for (i = 0; i < RX_RING_SIZE; i++) {
+		dev->rx_ring[i].addr = (u32)(&rx_packet[PKT_BUF_SZ * i]);
+	    dev->rx_ring[i].cmd_status = cpu_to_le32(dev->rx_buf_sz);
+	}
+
+	for (i = 0; i < TX_RING_SIZE; i++) {
+		dev->tx_ring[i].next_desc = virt_to_le32desc(&dev->tx_ring[i+1]);
+		dev->tx_ring[i].cmd_status = 0;
+	}
+	dev->tx_ring[i-1].next_desc = virt_to_le32desc(&dev->tx_ring[0]);
+
+	for (i = 0; i < TX_RING_SIZE; i++)
+		dev->tx_ring[i].addr = (u32)(&tx_packet[PKT_BUF_SZ * i]);
+	return;
+}
+
diff --git a/netboot/fsys_tftp.c b/netboot/fsys_tftp.c
new file mode 100644
index 0000000..b0233e8
--- /dev/null
+++ b/netboot/fsys_tftp.c
@@ -0,0 +1,497 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,2002,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 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.
+ */
+
+/* Based on "src/main.c" in etherboot-4.5.8.  */
+/**************************************************************************
+ETHERBOOT -  BOOTP/TFTP Bootstrap Program
+
+Author: Martin Renters
+  Date: Dec/93
+
+**************************************************************************/
+
+/* #define TFTP_DEBUG	1 */
+
+#include <filesys.h>
+
+#define GRUB	1
+#include <etherboot.h>
+#include <nic.h>
+
+static int retry;
+static unsigned short iport = 2000;
+static unsigned short oport;
+static unsigned short block, prevblock;
+static int bcounter;
+static struct tftp_t tp, saved_tp;
+static int packetsize;
+static int buf_eof, buf_read;
+static int saved_filepos;
+static unsigned short len, saved_len;
+static char *buf;
+
+/* Fill the buffer by receiving the data via the TFTP protocol.  */
+static int
+buf_fill (int abort)
+{
+#ifdef TFTP_DEBUG
+  grub_printf ("buf_fill (%d)\n", abort);
+#endif
+  
+  while (! buf_eof && (buf_read + packetsize <= FSYS_BUFLEN))
+    {
+      struct tftp_t *tr;
+      long timeout;
+
+#ifdef CONGESTED
+      timeout = rfc2131_sleep_interval (block ? TFTP_REXMT : TIMEOUT, retry);
+#else
+      timeout = rfc2131_sleep_interval (TIMEOUT, retry);
+#endif
+  
+      if (! await_reply (AWAIT_TFTP, iport, NULL, timeout))
+	{
+	  if (ip_abort)
+	    return 0;
+
+	  if (! block && retry++ < MAX_TFTP_RETRIES)
+	    {
+	      /* Maybe initial request was lost.  */
+#ifdef TFTP_DEBUG
+	      grub_printf ("Maybe initial request was lost.\n");
+#endif
+	      if (! udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
+				  ++iport, TFTP_PORT, len, &tp))
+		return 0;
+	      
+	      continue;
+	    }
+	  
+#ifdef CONGESTED
+	  if (block && ((retry += TFTP_REXMT) < TFTP_TIMEOUT))
+	    {
+	      /* We resend our last ack.  */
+# ifdef TFTP_DEBUG
+	      grub_printf ("<REXMT>\n");
+# endif
+	      udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
+			    iport, oport,
+			    TFTP_MIN_PACKET, &tp);
+	      continue;
+	    }
+#endif
+	  /* Timeout.  */
+	  return 0;
+	}
+
+      tr = (struct tftp_t *) &nic.packet[ETH_HLEN];
+      if (tr->opcode == ntohs (TFTP_ERROR))
+	{
+	  grub_printf ("TFTP error %d (%s)\n",
+		       ntohs (tr->u.err.errcode),
+		       tr->u.err.errmsg);
+	  return 0;
+	}
+      
+      if (tr->opcode == ntohs (TFTP_OACK))
+	{
+	  char *p = tr->u.oack.data, *e;
+
+#ifdef TFTP_DEBUG
+	  grub_printf ("OACK ");
+#endif
+	  /* Shouldn't happen.  */
+	  if (prevblock)
+	    {
+	      /* Ignore it.  */
+	      grub_printf ("%s:%d: warning: PREVBLOCK != 0 (0x%x)\n",
+			   __FILE__, __LINE__, prevblock);
+	      continue;
+	    }
+	  
+	  len = ntohs (tr->udp.len) - sizeof (struct udphdr) - 2;
+	  if (len > TFTP_MAX_PACKET)
+	    goto noak;
+	  
+	  e = p + len;
+	  while (*p != '\000' && p < e)
+	    {
+	      if (! grub_strcmp ("blksize", p))
+		{
+		  p += 8;
+		  if ((packetsize = getdec (&p)) < TFTP_DEFAULTSIZE_PACKET)
+		    goto noak;
+#ifdef TFTP_DEBUG
+		  grub_printf ("blksize = %d\n", packetsize);
+#endif
+		}
+	      else if (! grub_strcmp ("tsize", p))
+		{
+		  p += 6;
+		  if ((filemax = getdec (&p)) < 0)
+		    {
+		      filemax = -1;
+		      goto noak;
+		    }
+#ifdef TFTP_DEBUG
+		  grub_printf ("tsize = %d\n", filemax);
+#endif
+		}
+	      else
+		{
+		noak:
+#ifdef TFTP_DEBUG
+		  grub_printf ("NOAK\n");
+#endif
+		  tp.opcode = htons (TFTP_ERROR);
+		  tp.u.err.errcode = 8;
+		  len = (grub_sprintf ((char *) tp.u.err.errmsg,
+				       "RFC1782 error")
+			 + sizeof (tp.ip) + sizeof (tp.udp)
+			 + sizeof (tp.opcode) + sizeof (tp.u.err.errcode)
+			 + 1);
+		  udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
+				iport, ntohs (tr->udp.src),
+				len, &tp);
+		  return 0;
+		}
+	      
+	      while (p < e && *p)
+		p++;
+	      
+	      if (p < e)
+		p++;
+	    }
+	  
+	  if (p > e)
+	    goto noak;
+	  
+	  /* This ensures that the packet does not get processed as
+	     data!  */
+	  block = tp.u.ack.block = 0;
+	}
+      else if (tr->opcode == ntohs (TFTP_DATA))
+	{
+#ifdef TFTP_DEBUG
+	  grub_printf ("DATA ");
+#endif
+	  len = ntohs (tr->udp.len) - sizeof (struct udphdr) - 4;
+	  
+	  /* Shouldn't happen.  */
+	  if (len > packetsize)
+	    {
+	      /* Ignore it.  */
+	      grub_printf ("%s:%d: warning: LEN > PACKETSIZE (0x%x > 0x%x)\n",
+			   __FILE__, __LINE__, len, packetsize);
+	      continue;
+	    }
+	  
+	  block = ntohs (tp.u.ack.block = tr->u.data.block);
+	}
+      else
+	/* Neither TFTP_OACK nor TFTP_DATA.  */
+	break;
+
+      if ((block || bcounter) && (block != prevblock + (unsigned short) 1))
+	/* Block order should be continuous */
+	tp.u.ack.block = htons (block = prevblock);
+      
+      /* Should be continuous.  */
+      tp.opcode = abort ? htons (TFTP_ERROR) : htons (TFTP_ACK);
+      oport = ntohs (tr->udp.src);
+
+#ifdef TFTP_DEBUG
+      grub_printf ("ACK\n");
+#endif
+      /* Ack.  */
+      udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, iport,
+		    oport, TFTP_MIN_PACKET, &tp);
+      
+      if (abort)
+	{
+	  buf_eof = 1;
+	  break;
+	}
+
+      /* Retransmission or OACK.  */
+      if ((unsigned short) (block - prevblock) != 1)
+	/* Don't process.  */
+	continue;
+      
+      prevblock = block;
+      /* Is it the right place to zero the timer?  */
+      retry = 0;
+
+      /* In GRUB, this variable doesn't play any important role at all,
+	 but use it for consistency with Etherboot.  */
+      bcounter++;
+      
+      /* Copy the downloaded data to the buffer.  */
+      grub_memmove (buf + buf_read, tr->u.data.download, len);
+      buf_read += len;
+
+      /* End of data.  */
+      if (len < packetsize)		
+	buf_eof = 1;
+    }
+  
+  return 1;
+}
+
+/* Send the RRQ whose length is LEN.  */
+static int
+send_rrq (void)
+{
+  /* Initialize some variables.  */
+  retry = 0;
+  block = 0;
+  prevblock = 0;
+  packetsize = TFTP_DEFAULTSIZE_PACKET;
+  bcounter = 0;
+
+  buf = (char *) FSYS_BUF;
+  buf_eof = 0;
+  buf_read = 0;
+  saved_filepos = 0;
+
+  /* Clear out the Rx queue first.  It contains nothing of interest,
+   * except possibly ARP requests from the DHCP/TFTP server.  We use
+   * polling throughout Etherboot, so some time may have passed since we
+   * last polled the receive queue, which may now be filled with
+   * broadcast packets.  This will cause the reply to the packets we are
+   * about to send to be lost immediately.  Not very clever.  */
+  await_reply (AWAIT_QDRAIN, 0, NULL, 0);
+  
+#ifdef TFTP_DEBUG
+  grub_printf ("send_rrq ()\n");
+  {
+    int i;
+    char *p;
+
+    for (i = 0, p = (char *) &tp; i < len; i++)
+      if (p[i] >= ' ' && p[i] <= '~')
+	grub_putchar (p[i]);
+      else
+	grub_printf ("\\%x", (unsigned) p[i]);
+
+    grub_putchar ('\n');
+  }
+#endif
+  /* Send the packet.  */
+  return udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, ++iport,
+		       TFTP_PORT, len, &tp);
+}
+
+/* Mount the network drive. If the drive is ready, return one, otherwise
+   return zero.  */
+int
+tftp_mount (void)
+{
+  /* Check if the current drive is the network drive.  */
+  if (current_drive != NETWORK_DRIVE)
+    return 0;
+
+  /* If the drive is not initialized yet, abort.  */
+  if (! network_ready)
+    return 0;
+
+  return 1;
+}
+
+/* Read up to SIZE bytes, returned in ADDR.  */
+int
+tftp_read (char *addr, int size)
+{
+  /* How many bytes is read?  */
+  int ret = 0;
+
+#ifdef TFTP_DEBUG
+  grub_printf ("tftp_read (0x%x, %d)\n", (int) addr, size);
+#endif
+  
+  if (filepos < saved_filepos)
+    {
+      /* Uggh.. FILEPOS has been moved backwards. So reopen the file.  */
+      buf_read = 0;
+      buf_fill (1);
+      grub_memmove ((char *) &tp, (char *) &saved_tp, saved_len);
+      len = saved_len;
+#ifdef TFTP_DEBUG
+      {
+	int i;
+	grub_printf ("opcode = 0x%x, rrq = ", (unsigned long) tp.opcode);
+	for (i = 0; i < TFTP_DEFAULTSIZE_PACKET; i++)
+	  {
+	    if (tp.u.rrq[i] >= ' ' && tp.u.rrq[i] <= '~')
+	      grub_putchar (tp.u.rrq[i]);
+	    else
+	      grub_putchar ('*');
+	  }
+	grub_putchar ('\n');
+      }
+#endif
+      
+      if (! send_rrq ())
+	{
+	  errnum = ERR_WRITE;
+	  return 0;
+	}
+    }
+  
+  while (size > 0)
+    {
+      int amt = buf_read + saved_filepos - filepos;
+
+      /* If the length that can be copied from the buffer is over the
+	 requested size, cut it down.  */
+      if (amt > size)
+	amt = size;
+
+      if (amt > 0)
+	{
+	  /* Copy the buffer to the supplied memory space.  */
+	  grub_memmove (addr, buf + filepos - saved_filepos, amt);
+	  size -= amt;
+	  addr += amt;
+	  filepos += amt;
+	  ret += amt;
+
+	  /* If the size of the empty space becomes small, move the unused
+	     data forwards.  */
+	  if (filepos - saved_filepos > FSYS_BUFLEN / 2)
+	    {
+	      grub_memmove (buf, buf + FSYS_BUFLEN / 2, FSYS_BUFLEN / 2);
+	      buf_read -= FSYS_BUFLEN / 2;
+	      saved_filepos += FSYS_BUFLEN / 2;
+	    }
+	}
+      else
+	{
+	  /* Skip the whole buffer.  */
+	  saved_filepos += buf_read;
+	  buf_read = 0;
+	}
+
+      /* Read the data.  */
+      if (size > 0 && ! buf_fill (0))
+	{
+	  errnum = ERR_READ;
+	  return 0;
+	}
+
+      /* Sanity check.  */
+      if (size > 0 && buf_read == 0)
+	{
+	  errnum = ERR_READ;
+	  return 0;
+	}
+    }
+
+  return ret;
+}
+
+/* Check if the file DIRNAME really exists. Get the size and save it in
+   FILEMAX.  */
+int
+tftp_dir (char *dirname)
+{
+  int ch;
+
+#ifdef TFTP_DEBUG
+  grub_printf ("tftp_dir (%s)\n", dirname);
+#endif
+  
+  /* In TFTP, there is no way to know what files exist.  */
+  if (print_possibilities)
+    return 1;
+
+  /* Don't know the size yet.  */
+  filemax = -1;
+  
+ reopen:
+  /* Construct the TFTP request packet.  */
+  tp.opcode = htons (TFTP_RRQ);
+  /* Terminate the filename.  */
+  ch = nul_terminate (dirname);
+  /* Make the request string (octet, blksize and tsize).  */
+  len = (grub_sprintf ((char *) tp.u.rrq,
+		       "%s%coctet%cblksize%c%d%ctsize%c0",
+		       dirname, 0, 0, 0, TFTP_MAX_PACKET, 0, 0)
+	 + sizeof (tp.ip) + sizeof (tp.udp) + sizeof (tp.opcode) + 1);
+  /* Restore the original DIRNAME.  */
+  dirname[grub_strlen (dirname)] = ch;
+  /* Save the TFTP packet so that we can reopen the file later.  */
+  grub_memmove ((char *) &saved_tp, (char *) &tp, len);
+  saved_len = len;
+  if (! send_rrq ())
+    {
+      errnum = ERR_WRITE;
+      return 0;
+    }
+  
+  /* Read the data.  */
+  if (! buf_fill (0))
+    {
+      errnum = ERR_FILE_NOT_FOUND;
+      return 0;
+    }
+
+  if (filemax == -1)
+    {
+      /* The server doesn't support the "tsize" option, so we must read
+	 the file twice...  */
+
+      /* Zero the size of the file.  */
+      filemax = 0;
+      do
+	{
+	  /* Add the length of the downloaded data.  */
+	  filemax += buf_read;
+	  /* Reset the offset. Just discard the contents of the buffer.  */
+	  buf_read = 0;
+	  /* Read the data.  */
+	  if (! buf_fill (0))
+	    {
+	      errnum = ERR_READ;
+	      return 0;
+	    }
+	}
+      while (! buf_eof);
+
+      /* Maybe a few amounts of data remains.  */
+      filemax += buf_read;
+      
+      /* Retry the open instruction.  */
+      goto reopen;
+    }
+
+  return 1;
+}
+
+/* Close the file.  */
+void
+tftp_close (void)
+{
+#ifdef TFTP_DEBUG
+  grub_printf ("tftp_close ()\n");
+#endif
+  
+  buf_read = 0;
+  buf_fill (1);
+}
diff --git a/netboot/i82586.c b/netboot/i82586.c
new file mode 100644
index 0000000..15540c2
--- /dev/null
+++ b/netboot/i82586.c
@@ -0,0 +1,825 @@
+/**************************************************************************
+Etherboot -  BOOTP/TFTP Bootstrap Program
+i82586 NIC driver for Etherboot
+Ken Yap, January 1998
+***************************************************************************/
+
+/*
+ * 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.
+ */
+
+#include "etherboot.h"
+#include "nic.h"
+#include "cards.h"
+#include "timer.h"
+
+#define	udelay(n)	waiton_timer2(((n)*TICKS_PER_MS)/1000)
+
+/* Sources of information:
+
+   Donald Becker's excellent 3c507 driver in Linux
+   Intel 82596 data sheet (yes, 82596; it has a 586 compatibility mode)
+*/
+
+/* Code below mostly stolen wholesale from 3c507.c driver in Linux */
+
+/*
+		Details of the i82586.
+
+   You'll really need the databook to understand the details of this part,
+   but the outline is that the i82586 has two separate processing units.
+   Both are started from a list of three configuration tables, of which only
+   the last, the System Control Block (SCB), is used after reset-time.  The SCB
+   has the following fields:
+		Status word
+		Command word
+		Tx/Command block addr.
+		Rx block addr.
+   The command word accepts the following controls for the Tx and Rx units:
+  */
+
+#define	CUC_START	0x0100
+#define	CUC_RESUME	0x0200
+#define	CUC_SUSPEND	0x0300
+#define	RX_START	0x0010
+#define	RX_RESUME	0x0020
+#define	RX_SUSPEND	0x0030
+
+/* The Rx unit uses a list of frame descriptors and a list of data buffer
+   descriptors.  We use full-sized (1518 byte) data buffers, so there is
+   a one-to-one pairing of frame descriptors to buffer descriptors.
+
+   The Tx ("command") unit executes a list of commands that look like:
+	Status word	Written by the 82586 when the command is done.
+	Command word	Command in lower 3 bits, post-command action in upper 3
+	Link word	The address of the next command.
+	Parameters	(as needed).
+
+	Some definitions related to the Command Word are:
+ */
+#define CMD_EOL		0x8000		/* The last command of the list, stop. */
+#define CMD_SUSP	0x4000		/* Suspend after doing cmd. */
+#define CMD_INTR	0x2000		/* Interrupt after doing cmd. */
+
+enum commands {
+	CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
+	CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7};
+
+/*
+		Details of the EtherLink16 Implementation
+
+  The 3c507 and NI5210 are generic shared-memory i82586 implementations.
+  3c507: The host can map 16K, 32K, 48K, or 64K of the 64K memory into
+  0x0[CD][08]0000, or all 64K into 0xF[02468]0000.
+  NI5210: The host can map 8k or 16k at 0x[CDE][048C]000 but we
+  assume 8k because to have 16k you cannot put a ROM on the NIC.
+  */
+
+/* Offsets from the base I/O address. */
+
+#ifdef	INCLUDE_3C507
+
+#define	SA_DATA		0	/* Station address data, or 3Com signature. */
+#define MISC_CTRL	6	/* Switch the SA_DATA banks, and bus config bits. */
+#define RESET_IRQ	10	/* Reset the latched IRQ line. */
+#define I82586_ATTN	11	/* Frob the 82586 Channel Attention line. */
+#define ROM_CONFIG	13
+#define MEM_CONFIG	14
+#define IRQ_CONFIG	15
+#define EL16_IO_EXTENT	16
+
+/* The ID port is used at boot-time to locate the ethercard. */
+#define ID_PORT		0x100
+
+#endif
+
+#ifdef	INCLUDE_NI5210
+
+#define	NI52_RESET	0  /* writing to this address, resets the i82586 */
+#define	I82586_ATTN	1  /* channel attention, kick the 586 */
+
+#endif
+
+#ifdef	INCLUDE_EXOS205
+
+#define	EXOS205_RESET	0  /* writing to this address, resets the i82586 */
+#define	I82586_ATTN	1  /* channel attention, kick the 586 */
+
+#endif
+
+/* Offsets to registers in the mailbox (SCB). */
+#define iSCB_STATUS	0x8
+#define iSCB_CMD	0xA
+#define iSCB_CBL	0xC	/* Command BLock offset. */
+#define iSCB_RFA	0xE	/* Rx Frame Area offset. */
+
+/*  Since the 3c507 maps the shared memory window so that the last byte is
+at 82586 address FFFF, the first byte is at 82586 address 0, 16K, 32K, or
+48K corresponding to window sizes of 64K, 48K, 32K and 16K respectively.
+We can account for this be setting the 'SBC Base' entry in the ISCP table
+below for all the 16 bit offset addresses, and also adding the 'SCB Base'
+value to all 24 bit physical addresses (in the SCP table and the TX and RX
+Buffer Descriptors).
+				-Mark
+*/
+
+/*
+  What follows in 'init_words[]' is the "program" that is downloaded to the
+  82586 memory.  It's mostly tables and command blocks, and starts at the
+  reset address 0xfffff6.  This is designed to be similar to the EtherExpress,
+  thus the unusual location of the SCB at 0x0008.
+
+  Even with the additional "don't care" values, doing it this way takes less
+  program space than initializing the individual tables, and I feel it's much
+  cleaner.
+
+  The databook is particularly useless for the first two structures, I had
+  to use the Crynwr driver as an example.
+
+  The memory setup is as follows:
+*/
+
+#define CONFIG_CMD	0x18
+#define SET_SA_CMD	0x24
+#define SA_OFFSET	0x2A
+#define IDLELOOP	0x30
+#define TDR_CMD		0x38
+#define TDR_TIME	0x3C
+#define DUMP_CMD	0x40
+#define DIAG_CMD	0x48
+#define SET_MC_CMD	0x4E
+#define DUMP_DATA	0x56	/* A 170 byte buffer for dump and Set-MC into. */
+
+#define TX_BUF_START	0x0100
+#define TX_BUF_SIZE	(1518+14+20+16) /* packet+header+TBD */
+
+#define RX_BUF_START	0x1000
+#define RX_BUF_SIZE	(1518+14+18)	/* packet+header+RBD */
+#define RX_BUF_END	(mem_end - mem_start - 20)
+
+/*
+  That's it: only 86 bytes to set up the beast, including every extra
+  command available.  The 170 byte buffer at DUMP_DATA is shared between the
+  Dump command (called only by the diagnostic program) and the SetMulticastList
+  command.
+
+  To complete the memory setup you only have to write the station address at
+  SA_OFFSET and create the Tx & Rx buffer lists.
+
+  The Tx command chain and buffer list is setup as follows:
+  A Tx command table, with the data buffer pointing to...
+  A Tx data buffer descriptor.  The packet is in a single buffer, rather than
+	chaining together several smaller buffers.
+  A NoOp command, which initially points to itself,
+  And the packet data.
+
+  A transmit is done by filling in the Tx command table and data buffer,
+  re-writing the NoOp command, and finally changing the offset of the last
+  command to point to the current Tx command.  When the Tx command is finished,
+  it jumps to the NoOp, when it loops until the next Tx command changes the
+  "link offset" in the NoOp.  This way the 82586 never has to go through the
+  slow restart sequence.
+
+  The Rx buffer list is set up in the obvious ring structure.  We have enough
+  memory (and low enough interrupt latency) that we can avoid the complicated
+  Rx buffer linked lists by alway associating a full-size Rx data buffer with
+  each Rx data frame.
+
+  I currently use one transmit buffer starting at TX_BUF_START (0x0100), and
+  use the rest of memory, from RX_BUF_START to RX_BUF_END, for Rx buffers.
+
+  */
+
+static unsigned short init_words[] = {
+	/*	System Configuration Pointer (SCP). */
+#if	defined(INCLUDE_3C507)
+	0x0000,					/* Set bus size to 16 bits. */
+#else
+	0x0001,					/* Set bus size to 8 bits */
+#endif
+	0,0,					/* pad words. */
+	0x0000,0x0000,				/* ISCP phys addr, set in init_82586_mem(). */
+
+	/*	Intermediate System Configuration Pointer (ISCP). */
+	0x0001,					/* Status word that's cleared when init is done. */
+	0x0008,0,0,				/* SCB offset, (skip, skip) */
+
+	/* System Control Block (SCB). */
+	0,0xf000|RX_START|CUC_START,		/* SCB status and cmd. */
+	CONFIG_CMD,				/* Command list pointer, points to Configure. */
+	RX_BUF_START,				/* Rx block list. */
+	0,0,0,0,				/* Error count: CRC, align, buffer, overrun. */
+
+	/* 0x0018: Configure command.  Change to put MAC data with packet. */
+	0, CmdConfigure,			/* Status, command. */
+	SET_SA_CMD,				/* Next command is Set Station Addr. */
+	0x0804,					/* "4" bytes of config data, 8 byte FIFO. */
+	0x2e40,					/* Magic values, including MAC data location. */
+	0,					/* Unused pad word. */
+
+	/* 0x0024: Setup station address command. */
+	0, CmdSASetup,
+	SET_MC_CMD,				/* Next command. */
+	0xaa00,0xb000,0x0bad,	/* Station address (to be filled in) */
+
+	/* 0x0030: NOP, looping back to itself.  Point to first Tx buffer to Tx. */
+	0, CmdNOp, IDLELOOP, 0 /* pad */,
+
+	/* 0x0038: A unused Time-Domain Reflectometer command. */
+	0, CmdTDR, IDLELOOP, 0,
+
+	/* 0x0040: An unused Dump State command. */
+	0, CmdDump, IDLELOOP, DUMP_DATA,
+
+	/* 0x0048: An unused Diagnose command. */
+	0, CmdDiagnose, IDLELOOP,
+
+	/* 0x004E: An empty set-multicast-list command. */
+	0, CmdMulticastList, IDLELOOP, 0,
+};
+
+/* NIC specific static variables go here */
+
+static unsigned short		ioaddr, irq, scb_base;
+static Address			mem_start, mem_end;
+static unsigned short		rx_head, rx_tail;
+
+#define	read_mem(m,s)	fmemcpy((char *)s, m, sizeof(s))
+
+static void setup_rx_buffers(struct nic *nic)
+{
+	Address			write_ptr;
+	unsigned short		cur_rx_buf;
+	static unsigned short	rx_cmd[16] = {
+		0x0000,			/* Rx status */
+		0x0000,			/* Rx command, only and last */
+		RX_BUF_START,		/* Link (will be adjusted) */
+		RX_BUF_START + 22,	/* Buffer offset (will be adjusted) */
+		0x0000, 0x0000, 0x0000,	/* Pad for dest addr */
+		0x0000, 0x0000, 0x0000,	/* Pad for source addr */
+		0x0000,			/* Pad for protocol */
+		0x0000,			/* Buffer: Actual count */
+		-1,			/* Buffer: Next (none) */
+		RX_BUF_START + 0x20,	/* Buffer: Address low (+ scb_base) (will be adjusted) */
+		0x0000,			/* Buffer: Address high */
+		0x8000 | (RX_BUF_SIZE - 0x20)
+	};
+
+	cur_rx_buf = rx_head = RX_BUF_START;
+	do {		/* While there is room for one more buffer */
+		write_ptr = mem_start + cur_rx_buf;
+		/* adjust some contents */
+		rx_cmd[1] = 0x0000;
+		rx_cmd[2] = cur_rx_buf + RX_BUF_SIZE;
+		rx_cmd[3] = cur_rx_buf + 22;
+		rx_cmd[13] = cur_rx_buf + 0x20 + scb_base;
+		memcpy((char *)write_ptr, (char *)rx_cmd, sizeof(rx_cmd));
+		rx_tail = cur_rx_buf;
+		cur_rx_buf += RX_BUF_SIZE;
+	} while (cur_rx_buf <= RX_BUF_END - RX_BUF_SIZE);
+	/* Terminate the list by setting the EOL bit and wrap ther pointer
+	   to make the list a ring. */
+	write_ptr = mem_start + rx_tail;
+	rx_cmd[1] = 0xC000;
+	rx_cmd[2] = rx_head;
+	memcpy((char *)write_ptr, (char *)rx_cmd, sizeof(unsigned short) * 3);
+}
+
+static void ack_status(void)
+{
+	unsigned short	cmd, status;
+	unsigned short	*shmem = (short *)mem_start;
+
+	cmd = (status = shmem[iSCB_STATUS>>1]) & 0xf000;
+	if (status & 0x100)		/* CU suspended? */
+		cmd |= CUC_RESUME;
+	if ((status & 0x200) == 0)	/* CU not active? */
+		cmd |= CUC_START;
+	if (status & 0x010)		/* RU suspended? */
+		cmd |= RX_RESUME;
+	else if ((status & 0x040) == 0)	/* RU not active? */
+		cmd |= RX_START;
+	if (cmd == 0)			/* Nothing to do */
+		return;
+	shmem[iSCB_CMD>>1] = cmd;
+#if	defined(DEBUG)
+	printf("Status %hX Command %hX\n", status, cmd);
+#endif
+	outb(0, ioaddr + I82586_ATTN);
+}
+
+/**************************************************************************
+RESET - Reset adapter
+***************************************************************************/
+
+static void i82586_reset(struct nic *nic)
+{
+	unsigned long	time;
+	unsigned short	*shmem = (short *)mem_start;
+
+	/* put the card in its initial state */
+
+#ifdef	INCLUDE_3C507
+	/* Enable loopback to protect the wire while starting up,
+	   and hold the 586 in reset during the memory initialisation. */
+	outb(0x20, ioaddr + MISC_CTRL);
+#endif
+
+	/* Fix the ISCP address and base. */
+	init_words[3] = scb_base;
+	init_words[7] = scb_base;
+
+	/* Write the words at 0xfff6. */
+	/* Write the words at 0x0000. */
+	/* Fill in the station address. */
+	memcpy((char *)(mem_end - 10), (char *)init_words, 10);
+	memcpy((char *)mem_start, (char *)&init_words[5], sizeof(init_words) - 10);
+	memcpy((char *)mem_start + SA_OFFSET, nic->node_addr, ETH_ALEN);
+	setup_rx_buffers(nic);
+
+#ifdef	INCLUDE_3C507
+	/* Start the 586 by releasing the reset line, but leave loopback. */
+	outb(0xA0, ioaddr + MISC_CTRL);
+#endif
+
+	/* This was time consuming to track down; you need to give two channel
+	   attention signals to reliably start up the i82586. */
+	outb(0, ioaddr + I82586_ATTN);
+	time = currticks() + TICKS_PER_SEC;	/* allow 1 second to init */
+	while (
+			shmem[iSCB_STATUS>>1] == 0)
+	{
+		if (currticks() > time)
+		{
+			printf("i82586 initialisation timed out with status %hX, cmd %hX\n",
+					shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
+			break;
+		}
+	}
+	/* Issue channel-attn -- the 82586 won't start. */
+	outb(0, ioaddr + I82586_ATTN);
+
+#ifdef	INCLUDE_3C507
+	/* Disable loopback. */
+	outb(0x80, ioaddr + MISC_CTRL);
+#endif
+#if	defined(DEBUG)
+	printf("i82586 status %hX, cmd %hX\n",
+			shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
+#endif
+}
+
+/**************************************************************************
+  POLL - Wait for a frame
+ ***************************************************************************/
+static int i82586_poll(struct nic *nic)
+{
+	int		status;
+	unsigned short	rfd_cmd, next_rx_frame, data_buffer_addr,
+	frame_status, pkt_len;
+	unsigned short	*shmem = (short *)mem_start + rx_head;
+
+	/* return true if there's an ethernet packet ready to read */
+	if (
+			((frame_status = shmem[0]) & 0x8000) == 0)
+		return (0);		/* nope */
+	rfd_cmd = shmem[1];
+	next_rx_frame = shmem[2];
+	data_buffer_addr = shmem[3];
+	pkt_len = shmem[11];
+	status = 0;
+	if (rfd_cmd != 0 || data_buffer_addr != rx_head + 22
+			|| (pkt_len & 0xC000) != 0xC000)
+		printf("\nRx frame corrupt, discarded");
+	else if ((frame_status & 0x2000) == 0)
+		printf("\nRx frame had error");
+	else
+	{
+		/* We have a frame, copy it to our buffer */
+		pkt_len &= 0x3FFF;
+		memcpy(nic->packet, (char *)mem_start + rx_head + 0x20, pkt_len);
+		/* Only packets not from ourself */
+		if (memcmp(nic->packet + ETH_ALEN, nic->node_addr, ETH_ALEN) != 0)
+		{
+			nic->packetlen = pkt_len;
+			status = 1;
+		}
+	}
+	/* Clear the status word and set EOL on Rx frame */
+	shmem[0] = 0;
+	shmem[1] = 0xC000;
+	*(short *)(mem_start + rx_tail + 2) = 0;
+	rx_tail = rx_head;
+	rx_head = next_rx_frame;
+	ack_status();
+	return (status);
+}
+
+/**************************************************************************
+  TRANSMIT - Transmit a frame
+ ***************************************************************************/
+static void i82586_transmit(
+		struct nic *nic,
+		const char *d,			/* Destination */
+		unsigned int t,			/* Type */
+		unsigned int s,			/* size */
+		const char *p)			/* Packet */
+{
+	Address			bptr;
+	unsigned short		type, z;
+	static unsigned short	tx_cmd[11] = {
+		0x0,			/* Tx status */
+		CmdTx,			/* Tx command */
+		TX_BUF_START+16,	/* Next command is a NoOp */
+		TX_BUF_START+8,		/* Data Buffer offset */
+		0x8000,			/* | with size */
+		0xffff,			/* No next data buffer */
+		TX_BUF_START+22,	/* + scb_base */
+		0x0,			/* Buffer address high bits (always zero) */
+		0x0,			/* Nop status */
+		CmdNOp,			/* Nop command */
+		TX_BUF_START+16		/* Next is myself */
+	};
+	unsigned short	*shmem = (short *)mem_start + TX_BUF_START;
+
+	/* send the packet to destination */
+	/* adjust some contents */
+	type = htons(t);
+	if (s < ETH_ZLEN)
+		s = ETH_ZLEN;
+	tx_cmd[4] = (s + ETH_HLEN) | 0x8000;
+	tx_cmd[6] = TX_BUF_START + 22 + scb_base;
+	bptr = mem_start + TX_BUF_START;
+	memcpy((char *)bptr, (char *)tx_cmd, sizeof(tx_cmd));
+	bptr += sizeof(tx_cmd);
+	memcpy((char *)bptr, d, ETH_ALEN);
+	bptr += ETH_ALEN;
+	memcpy((char *)bptr, nic->node_addr, ETH_ALEN);
+	bptr += ETH_ALEN;
+	memcpy((char *)bptr, (char *)&type, sizeof(type));
+	bptr += sizeof(type);
+	memcpy((char *)bptr, p, s);
+	/* Change the offset in the IDLELOOP */
+	*(unsigned short *)(mem_start + IDLELOOP + 4) = TX_BUF_START;
+	/* Wait for transmit completion */
+	while (
+			(shmem[0] & 0x2000) == 0)
+		;
+	/* Change the offset in the IDLELOOP back and
+	   change the final loop to point here */
+	*(unsigned short *)(mem_start + IDLELOOP + 4) = IDLELOOP;
+	*(unsigned short *)(mem_start + TX_BUF_START + 20) = IDLELOOP;
+	ack_status();
+}
+
+/**************************************************************************
+  DISABLE - Turn off ethernet interface
+ ***************************************************************************/
+static void i82586_disable(struct nic *nic)
+{
+	unsigned short	*shmem = (short *)mem_start;
+
+#if	0
+	/* Flush the Tx and disable Rx. */
+	shmem[iSCB_CMD>>1] = RX_SUSPEND | CUC_SUSPEND;
+	outb(0, ioaddr + I82586_ATTN);
+#ifdef	INCLUDE_NI5210
+	outb(0, ioaddr + NI52_RESET);
+#endif
+#endif	/* 0 */
+}
+
+#ifdef	INCLUDE_3C507
+
+static int t507_probe1(struct nic *nic, unsigned short ioaddr)
+{
+	int			i;
+	Address			size;
+	char			mem_config;
+	char			if_port;
+
+	if (inb(ioaddr) != '*' || inb(ioaddr+1) != '3'
+		|| inb(ioaddr+2) != 'C' || inb(ioaddr+3) != 'O')
+		return (0);
+	irq = inb(ioaddr + IRQ_CONFIG) & 0x0f;
+	mem_config = inb(ioaddr + MEM_CONFIG);
+	if (mem_config & 0x20)
+	{
+		size = 65536L;
+		mem_start = 0xf00000L + (mem_config & 0x08 ? 0x080000L
+			: (((Address)mem_config & 0x3) << 17));
+	}
+	else
+	{
+		size = ((((Address)mem_config & 0x3) + 1) << 14);
+		mem_start = 0x0c0000L + (((Address)mem_config & 0x18) << 12);
+	}
+	mem_end = mem_start + size;
+	scb_base = 65536L - size;
+	if_port = inb(ioaddr + ROM_CONFIG) & 0x80;
+	/* Get station address */
+	outb(0x01, ioaddr + MISC_CTRL);
+	for (i = 0; i < ETH_ALEN; ++i)
+	{
+		nic->node_addr[i] = inb(ioaddr+i);
+	}
+	printf("\n3c507 ioaddr %#hX, IRQ %d, mem [%#X-%#X], %sternal xcvr, addr %!\n",
+		ioaddr, irq, mem_start, mem_end, if_port ? "in" : "ex", nic->node_addr);
+	return (1);
+}
+
+/**************************************************************************
+PROBE - Look for an adapter, this routine's visible to the outside
+***************************************************************************/
+
+struct nic *t507_probe(struct nic *nic, unsigned short *probe_addrs)
+{
+	static unsigned char	init_ID_done = 0;
+	unsigned short		lrs_state = 0xff;
+	static unsigned short	io_addrs[] = { 0x300, 0x320, 0x340, 0x280, 0 };
+	unsigned short		*p;
+	int			i;
+
+	if (init_ID_done == 0)
+	{
+		/* Send the ID sequence to the ID_PORT to enable the board */
+		outb(0x00, ID_PORT);
+		for (i = 0; i < 255; ++i)
+		{
+			outb(lrs_state, ID_PORT);
+			lrs_state <<= 1;
+			if (lrs_state & 0x100)
+				lrs_state ^= 0xe7;
+		}
+		outb(0x00, ID_PORT);
+		init_ID_done = 1;
+	}
+	/* if probe_addrs is 0, then routine can use a hardwired default */
+	if (probe_addrs == 0)
+		probe_addrs = io_addrs;
+	for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
+		if (t507_probe1(nic, ioaddr))
+			break;
+	if (ioaddr != 0)
+	{
+		/* point to NIC specific routines */
+		i82586_reset(nic);
+		nic->reset = i82586_reset;
+		nic->poll = i82586_poll;
+		nic->transmit = i82586_transmit;
+		nic->disable = i82586_disable;
+		return nic;
+	}
+	/* else */
+	{
+		return 0;
+	}
+}
+
+#endif
+
+#ifdef	INCLUDE_NI5210
+
+static int ni5210_probe2(void)
+{
+	unsigned short		i;
+	unsigned short		shmem[10];
+
+	/* Fix the ISCP address and base. */
+	init_words[3] = scb_base;
+	init_words[7] = scb_base;
+
+	/* Write the words at 0xfff6. */
+	/* Write the words at 0x0000. */
+	memcpy((char *)(mem_end - 10), (char *)init_words, 10);
+	memcpy((char *)mem_start, (char *)&init_words[5], sizeof(init_words) - 10);
+	if (*(unsigned short *)mem_start != 1)
+		return (0);
+	outb(0, ioaddr + NI52_RESET);
+	outb(0, ioaddr + I82586_ATTN);
+	udelay(32);
+	i = 50;
+	while (
+		shmem[iSCB_STATUS>>1] == 0)
+	{
+		if (--i == 0)
+		{
+			printf("i82586 initialisation timed out with status %hX, cmd %hX\n",
+				shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
+			break;
+		}
+	}
+	/* Issue channel-attn -- the 82586 won't start. */
+	outb(0, ioaddr + I82586_ATTN);
+	if (*(unsigned short *)mem_start != 0)
+		return (0);
+	return (1);
+}
+
+static int ni5210_probe1(struct nic *nic)
+{
+	int			i;
+	static Address		mem_addrs[] = {
+		0xc0000, 0xc4000, 0xc8000, 0xcc000,
+		0xd0000, 0xd4000, 0xd8000, 0xdc000,
+		0xe0000, 0xe4000, 0xe8000, 0xec000,
+		0 };
+	Address			*p;
+
+	if (inb(ioaddr + 6) != 0x0 || inb(ioaddr + 7) != 0x55)
+		return (0);
+	scb_base = -8192;		/* assume 8k memory */
+	for (p = mem_addrs; (mem_start = *p) != 0; ++p)
+		if (mem_end = mem_start + 8192, ni5210_probe2())
+			break;
+	if (mem_start == 0)
+		return (0);
+	/* Get station address */
+	for (i = 0; i < ETH_ALEN; ++i)
+	{
+		nic->node_addr[i] = inb(ioaddr+i);
+	}
+	printf("\nNI5210 ioaddr %#hX, mem [%#X-%#X], addr %!\n",
+		ioaddr, mem_start, mem_end, nic->node_addr);
+	return (1);
+}
+
+struct nic *ni5210_probe(struct nic *nic, unsigned short *probe_addrs)
+{
+	/* missing entries are addresses usually already used */
+	static unsigned short	io_addrs[] = {
+		0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230, 0x238,
+		0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, /*Par*/
+		0x280, 0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8,
+		0x2C0, 0x2C8, 0x2D0, 0x2D8, 0x2E0, 0x2E8, 0x2F0, /*Ser*/
+		0x300, 0x308, 0x310, 0x318, 0x320, 0x328, 0x330, 0x338,
+		0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370, /*Par*/
+		0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, /*Vid,Par*/
+		0x3C0, 0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, /*Ser*/
+		0x0
+	};
+	unsigned short		*p;
+	int			i;
+
+	/* if probe_addrs is 0, then routine can use a hardwired default */
+	if (probe_addrs == 0)
+		probe_addrs = io_addrs;
+	for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
+		if (ni5210_probe1(nic))
+			break;
+	if (ioaddr != 0)
+	{
+		/* point to NIC specific routines */
+		i82586_reset(nic);
+		nic->reset = i82586_reset;
+		nic->poll = i82586_poll;
+		nic->transmit = i82586_transmit;
+		nic->disable = i82586_disable;
+		return nic;
+	}
+	/* else */
+	{
+		return 0;
+	}
+}
+#endif
+
+#ifdef	INCLUDE_EXOS205
+
+/*
+ * Code to download to I186 in EXOS205
+ */
+
+static unsigned char exos_i186_init[] =
+{
+0x08,0x00,0x14,0x00,0x00,0x00,0xaa,0xfa,0x33,0xc0,0xba,0xfe,0xff,0xef,0xb8,0xf8,
+0xff,0xe7,0xa0,0xb8,0x7c,0x00,0xe7,0xa4,0xb8,0xbc,0x80,0xe7,0xa8,0x8c,0xc8,0x8e,
+0xd8,0xbb,0x2f,0x0e,0xc6,0x07,0xa5,0x33,0xc9,0xeb,0x00,0xeb,0x00,0xeb,0x00,0xe2,
+0xf8,0xbe,0x2c,0x0e,0xba,0x02,0x05,0x33,0xdb,0xb9,0x03,0x00,0xec,0x24,0x0f,0x8a,
+0xe0,0x02,0xd8,0x42,0x42,0xec,0x02,0xd8,0xd0,0xe0,0xd0,0xe0,0xd0,0xe0,0xd0,0xe0,
+0x0a,0xc4,0x88,0x04,0x42,0x42,0x46,0xe2,0xe3,0x8a,0xe3,0xd0,0xec,0xd0,0xec,0xd0,
+0xec,0xd0,0xec,0x80,0xe3,0x0f,0x02,0xe3,0x80,0xf4,0x05,0xec,0x3a,0xe0,0x74,0x05,
+0xc6,0x04,0x5a,0xeb,0xfe,0xc6,0x04,0x55,0x33,0xc0,0x8e,0xd8,0xbe,0x38,0x00,0xc7,
+0x04,0xce,0x0e,0x46,0x46,0xc7,0x04,0x00,0xff,0xfb,0xba,0x3c,0x00,0xb8,0x03,0x00,
+0xef,0x33,0xdb,0x33,0xc9,0xbd,0x04,0x0f,0x90,0x90,0x90,0x90,0xe2,0xfa,0x43,0x2e,
+0x89,0x5e,0x00,0xeb,0xf3,0x52,0xba,0x00,0x06,0xef,0x50,0x53,0x55,0xbd,0xf8,0x0e,
+0x2e,0x8b,0x5e,0x00,0x43,0x2e,0x89,0x5e,0x00,0xba,0x22,0x00,0xb8,0x00,0x80,0xef,
+0x5d,0x5b,0x58,0x5a,0xcf,0x49,0x4e,0x54,0x52,0x20,0x63,0x6e,0x74,0x2d,0x3e,0x00,
+0x00,0x4c,0x4f,0x4f,0x50,0x20,0x63,0x6e,0x74,0x2d,0x3e,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xea,0x30,0x0e,0x00,0xff,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,00
+};
+
+/* These offsets are from the end of the i186 download code */
+
+#define	OFFSET_SEMA		0x1D1
+#define	OFFSET_ADDR		0x1D7
+
+static int exos205_probe2(void)
+{
+	unsigned short		i;
+	unsigned short		shmem[10];
+
+	/* Fix the ISCP address and base. */
+	init_words[3] = scb_base;
+	init_words[7] = scb_base;
+
+	/* Write the words at 0xfff6. */
+	/* Write the words at 0x0000. */
+	memcpy((char *)(mem_end - 10), (char *)init_words, 10);
+	memcpy((char *)mem_start, (char *)&init_words[5], sizeof(init_words) - 10);
+	if (*(unsigned short *)mem_start != 1)
+		return (0);
+	outb(0, ioaddr + EXOS205_RESET);
+	outb(0, ioaddr + I82586_ATTN);
+	i = 50;
+	while (
+		shmem[iSCB_STATUS>>1] == 0)
+	{
+		if (--i == 0)
+		{
+			printf("i82586 initialisation timed out with status %hX, cmd %hX\n",
+				shmem[iSCB_STATUS>>1], shmem[iSCB_CMD>>1]);
+			break;
+		}
+	}
+	/* Issue channel-attn -- the 82586 won't start. */
+	outb(0, ioaddr + I82586_ATTN);
+	if (*(unsigned short *)mem_start != 0)
+		return (0);
+	return (1);
+}
+
+static int exos205_probe1(struct nic *nic)
+{
+	int			i;
+	/* If you know the other addresses please let me know */
+	static Address		mem_addrs[] = {
+		0xcc000, 0 };
+	Address			*p;
+
+	scb_base = -16384;		/* assume 8k memory */
+	for (p = mem_addrs; (mem_start = *p) != 0; ++p)
+		if (mem_end = mem_start + 16384, exos205_probe2())
+			break;
+	if (mem_start == 0)
+		return (0);
+	/* Get station address */
+	for (i = 0; i < ETH_ALEN; ++i)
+	{
+		nic->node_addr[i] = inb(ioaddr+i);
+	}
+	printf("\nEXOS205 ioaddr %#hX, mem [%#X-%#X], addr %!\n",
+		ioaddr, mem_start, mem_end, nic->node_addr);
+	return (1);
+}
+
+struct nic *exos205_probe(struct nic *nic, unsigned short *probe_addrs)
+{
+	/* If you know the other addresses, please let me know */
+	static unsigned short	io_addrs[] = {
+		0x310, 0x0
+	};
+	unsigned short		*p;
+	int			i;
+
+	/* if probe_addrs is 0, then routine can use a hardwired default */
+	if (probe_addrs == 0)
+		probe_addrs = io_addrs;
+	for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
+		if (exos205_probe1(nic))
+			break;
+	if (ioaddr != 0)
+	{
+		/* point to NIC specific routines */
+		i82586_reset(nic);
+		nic->reset = i82586_reset;
+		nic->poll = i82586_poll;
+		nic->transmit = i82586_transmit;
+		nic->disable = i82586_disable;
+		return nic;
+	}
+	/* else */
+	{
+		return 0;
+	}
+}
+
+#endif
diff --git a/netboot/lance.c b/netboot/lance.c
new file mode 100644
index 0000000..9db1119
--- /dev/null
+++ b/netboot/lance.c
@@ -0,0 +1,564 @@
+/**************************************************************************
+Etherboot -  BOOTP/TFTP Bootstrap Program
+LANCE NIC driver for Etherboot
+Large portions borrowed from the Linux LANCE driver by Donald Becker
+Ken Yap, July 1997
+***************************************************************************/
+
+/*
+ * 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.
+ */
+
+/* to get some global routines like printf */
+#include "etherboot.h"
+/* to get the interface to the body of the program */
+#include "nic.h"
+#ifdef	INCLUDE_LANCE
+#include "pci.h"
+#endif
+#include "cards.h"
+
+/* Offsets from base I/O address */
+#if	defined(INCLUDE_NE2100) || defined(INCLUDE_LANCE)
+#define	LANCE_ETH_ADDR	0x0
+#define	LANCE_DATA	0x10
+#define	LANCE_ADDR	0x12
+#define	LANCE_RESET	0x14
+#define	LANCE_BUS_IF	0x16
+#define	LANCE_TOTAL_SIZE	0x18
+#endif
+#ifdef	INCLUDE_NI6510
+#define	LANCE_ETH_ADDR	0x8
+#define	LANCE_DATA	0x0
+#define	LANCE_ADDR	0x2
+#define	LANCE_RESET	0x4
+#define	LANCE_BUS_IF	0x6
+#define	LANCE_TOTAL_SIZE	0x10
+#endif
+
+/* lance_poll() now can use multiple Rx buffers to prevent packet loss. Set
+ * Set LANCE_LOG_RX_BUFFERS to 0..7 for 1, 2, 4, 8, 16, 32, 64 or 128 Rx
+ * buffers. Usually 4 (=16 Rx buffers) is a good value. (Andreas Neuhaus)
+ * Decreased to 2 (=4 Rx buffers) (Ken Yap, 20010305) */
+
+#define LANCE_LOG_RX_BUFFERS	2		/* Use 2^2=4 Rx buffers */
+
+#define RX_RING_SIZE		(1 << (LANCE_LOG_RX_BUFFERS))
+#define RX_RING_MOD_MASK	(RX_RING_SIZE - 1)
+#define RX_RING_LEN_BITS	((LANCE_LOG_RX_BUFFERS) << 29)
+
+struct lance_init_block
+{
+	unsigned short	mode;
+	unsigned char	phys_addr[ETH_ALEN];
+	unsigned long	filter[2];
+	Address		rx_ring;
+	Address		tx_ring;
+};
+
+struct lance_rx_head
+{
+	union {
+		Address		base;
+		unsigned char	addr[4];
+	} u;
+	short		buf_length;	/* 2s complement */
+	short		msg_length;
+};
+
+struct lance_tx_head
+{
+	union {
+		Address		base;
+		unsigned char	addr[4];
+	} u;
+	short		buf_length;	/* 2s complement */
+	short		misc;
+};
+
+struct lance_interface
+{
+	struct lance_init_block	init_block;
+	struct lance_rx_head	rx_ring[RX_RING_SIZE];
+	struct lance_tx_head	tx_ring;
+	unsigned char		rbuf[RX_RING_SIZE][ETH_FRAME_LEN+4];
+	unsigned char		tbuf[ETH_FRAME_LEN];
+	/*
+	 * Do not alter the order of the struct members above;
+	 * the hardware depends on the correct alignment.
+	 */
+	int			rx_idx;
+};
+
+#define	LANCE_MUST_PAD		0x00000001
+#define	LANCE_ENABLE_AUTOSELECT	0x00000002
+#define	LANCE_SELECT_PHONELINE	0x00000004
+#define	LANCE_MUST_UNRESET	0x00000008
+
+/* A mapping from the chip ID number to the part number and features.
+   These are from the datasheets -- in real life the '970 version
+   reportedly has the same ID as the '965. */
+static const struct lance_chip_type
+{
+	int	id_number;
+	const char	*name;
+	int	flags;
+} chip_table[] = {
+	{0x0000, "LANCE 7990",			/* Ancient lance chip.  */
+		LANCE_MUST_PAD + LANCE_MUST_UNRESET},
+	{0x0003, "PCnet/ISA 79C960",		/* 79C960 PCnet/ISA.  */
+		LANCE_ENABLE_AUTOSELECT},
+	{0x2260, "PCnet/ISA+ 79C961",		/* 79C961 PCnet/ISA+, Plug-n-Play.  */
+		LANCE_ENABLE_AUTOSELECT},
+	{0x2420, "PCnet/PCI 79C970",		/* 79C970 or 79C974 PCnet-SCSI, PCI. */
+		LANCE_ENABLE_AUTOSELECT},
+	/* Bug: the PCnet/PCI actually uses the PCnet/VLB ID number, so just call
+		it the PCnet32. */
+	{0x2430, "PCnet32",			/* 79C965 PCnet for VL bus. */
+		LANCE_ENABLE_AUTOSELECT},
+        {0x2621, "PCnet/PCI-II 79C970A",        /* 79C970A PCInetPCI II. */
+                LANCE_ENABLE_AUTOSELECT},
+	{0x2625, "PCnet-FAST III 79C973",	/* 79C973 PCInet-FAST III. */
+		LANCE_ENABLE_AUTOSELECT},
+        {0x2626, "PCnet/HomePNA 79C978",        
+                LANCE_ENABLE_AUTOSELECT|LANCE_SELECT_PHONELINE},
+	{0x0, "PCnet (unknown)",
+		LANCE_ENABLE_AUTOSELECT},
+};
+
+/* Define a macro for converting program addresses to real addresses */
+#undef	virt_to_bus
+#define	virt_to_bus(x)		((unsigned long)x)
+
+static int			chip_version;
+static int			lance_version;
+static unsigned short		ioaddr;
+#ifndef	INCLUDE_LANCE
+static int			dma;
+#endif
+static struct lance_interface	*lp;
+
+/* additional 8 bytes for 8-byte alignment space */
+#ifdef	USE_LOWMEM_BUFFER
+#define lance ((char *)0x10000 - (sizeof(struct lance_interface)+8))
+#else
+static char			lance[sizeof(struct lance_interface)+8];
+#endif
+
+#ifndef	INCLUDE_LANCE
+/* DMA defines and helper routines */
+
+/* DMA controller registers */
+#define DMA1_CMD_REG		0x08	/* command register (w) */
+#define DMA1_STAT_REG		0x08	/* status register (r) */
+#define DMA1_REQ_REG            0x09    /* request register (w) */
+#define DMA1_MASK_REG		0x0A	/* single-channel mask (w) */
+#define DMA1_MODE_REG		0x0B	/* mode register (w) */
+#define DMA1_CLEAR_FF_REG	0x0C	/* clear pointer flip-flop (w) */
+#define DMA1_TEMP_REG           0x0D    /* Temporary Register (r) */
+#define DMA1_RESET_REG		0x0D	/* Master Clear (w) */
+#define DMA1_CLR_MASK_REG       0x0E    /* Clear Mask */
+#define DMA1_MASK_ALL_REG       0x0F    /* all-channels mask (w) */
+
+#define DMA2_CMD_REG		0xD0	/* command register (w) */
+#define DMA2_STAT_REG		0xD0	/* status register (r) */
+#define DMA2_REQ_REG            0xD2    /* request register (w) */
+#define DMA2_MASK_REG		0xD4	/* single-channel mask (w) */
+#define DMA2_MODE_REG		0xD6	/* mode register (w) */
+#define DMA2_CLEAR_FF_REG	0xD8	/* clear pointer flip-flop (w) */
+#define DMA2_TEMP_REG           0xDA    /* Temporary Register (r) */
+#define DMA2_RESET_REG		0xDA	/* Master Clear (w) */
+#define DMA2_CLR_MASK_REG       0xDC    /* Clear Mask */
+#define DMA2_MASK_ALL_REG       0xDE    /* all-channels mask (w) */
+
+
+#define DMA_MODE_READ	0x44	/* I/O to memory, no autoinit, increment, single mode */
+#define DMA_MODE_WRITE	0x48	/* memory to I/O, no autoinit, increment, single mode */
+#define DMA_MODE_CASCADE 0xC0   /* pass thru DREQ->HRQ, DACK<-HLDA only */
+
+/* enable/disable a specific DMA channel */
+static void enable_dma(unsigned int dmanr)
+{
+	if (dmanr <= 3)
+		outb_p(dmanr, DMA1_MASK_REG);
+	else
+		outb_p(dmanr & 3, DMA2_MASK_REG);
+}
+
+static void disable_dma(unsigned int dmanr)
+{
+	if (dmanr <= 3)
+		outb_p(dmanr | 4, DMA1_MASK_REG);
+	else
+		outb_p((dmanr & 3) | 4, DMA2_MASK_REG);
+}
+
+/* set mode (above) for a specific DMA channel */
+static void set_dma_mode(unsigned int dmanr, char mode)
+{
+	if (dmanr <= 3)
+		outb_p(mode | dmanr, DMA1_MODE_REG);
+	else
+		outb_p(mode | (dmanr&3), DMA2_MODE_REG);
+}
+#endif	/* !INCLUDE_LANCE */
+
+/**************************************************************************
+RESET - Reset adapter
+***************************************************************************/
+static void lance_reset(struct nic *nic)
+{
+	int		i;
+	Address		l;
+
+	/* Reset the LANCE */
+	(void)inw(ioaddr+LANCE_RESET);
+	/* Un-Reset the LANCE, needed only for the NE2100 */
+	if (chip_table[lance_version].flags & LANCE_MUST_UNRESET)
+		outw(0, ioaddr+LANCE_RESET);
+	if (chip_table[lance_version].flags & LANCE_ENABLE_AUTOSELECT)
+	{
+		/* This is 79C960 specific; Turn on auto-select of media
+		   (AUI, BNC). */
+		outw(0x2, ioaddr+LANCE_ADDR);
+		/* Don't touch 10base2 power bit. */
+		outw(inw(ioaddr+LANCE_BUS_IF) | 0x2, ioaddr+LANCE_BUS_IF);
+	}
+	/* HomePNA cards need to explicitly pick the phoneline interface.
+	 * Some of these cards have ethernet interfaces as well, this
+	 * code might require some modification for those.
+  	 */
+        if (chip_table[lance_version].flags & LANCE_SELECT_PHONELINE) {
+                short media, check ;
+                /* this is specific to HomePNA cards... */
+                outw(49, ioaddr+0x12) ;
+                media = inw(ioaddr+0x16) ;
+#ifdef DEBUG
+                printf("media was %d\n", media) ;
+#endif
+                media &= ~3 ;
+                media |= 1 ;
+#ifdef DEBUG
+                printf("media changed to %d\n", media) ;
+#endif
+                media &= ~3 ;
+                media |= 1 ;
+                outw(49, ioaddr+0x12) ;
+                outw(media, ioaddr+0x16) ;
+                outw(49, ioaddr+0x12) ;
+                check = inw(ioaddr+0x16) ;
+#ifdef DEBUG
+                printf("check %s, media was set properly\n", 
+			check ==  media ? "passed" : "FAILED" ) ; 
+#endif
+	}
+ 
+	/* Re-initialise the LANCE, and start it when done. */
+	/* Set station address */
+	for (i = 0; i < ETH_ALEN; ++i)
+		lp->init_block.phys_addr[i] = nic->node_addr[i];
+	/* Preset the receive ring headers */
+	for (i=0; i<RX_RING_SIZE; i++) {
+		lp->rx_ring[i].buf_length = -ETH_FRAME_LEN-4;
+		/* OWN */
+		lp->rx_ring[i].u.base = virt_to_bus(lp->rbuf[i]) & 0xffffff;
+		/* we set the top byte as the very last thing */
+		lp->rx_ring[i].u.addr[3] = 0x80;
+	}
+	lp->rx_idx = 0;
+	lp->init_block.mode = 0x0;	/* enable Rx and Tx */
+	l = (Address)virt_to_bus(&lp->init_block);
+	outw(0x1, ioaddr+LANCE_ADDR);
+	(void)inw(ioaddr+LANCE_ADDR);
+	outw((short)l, ioaddr+LANCE_DATA);
+	outw(0x2, ioaddr+LANCE_ADDR);
+	(void)inw(ioaddr+LANCE_ADDR);
+	outw((short)(l >> 16), ioaddr+LANCE_DATA);
+	outw(0x4, ioaddr+LANCE_ADDR);
+	(void)inw(ioaddr+LANCE_ADDR);
+	outw(0x915, ioaddr+LANCE_DATA);
+	outw(0x0, ioaddr+LANCE_ADDR);
+	(void)inw(ioaddr+LANCE_ADDR);
+	outw(0x4, ioaddr+LANCE_DATA);		/* stop */
+	outw(0x1, ioaddr+LANCE_DATA);		/* init */
+	for (i = 10000; i > 0; --i)
+		if (inw(ioaddr+LANCE_DATA) & 0x100)
+			break;
+#ifdef	DEBUG
+	if (i <= 0)
+		printf("Init timed out\n");
+#endif
+	/* Apparently clearing the InitDone bit here triggers a bug
+	   in the '974. (Mark Stockton) */
+	outw(0x2, ioaddr+LANCE_DATA);		/* start */
+}
+
+/**************************************************************************
+POLL - Wait for a frame
+***************************************************************************/
+static int lance_poll(struct nic *nic)
+{
+	int		status;
+
+	status = lp->rx_ring[lp->rx_idx].u.base >> 24;
+	if (status & 0x80)
+		return (0);
+#ifdef	DEBUG
+	printf("LANCE packet received rx_ring.u.base %X mcnt %hX csr0 %hX\n",
+		lp->rx_ring[lp->rx_idx].u.base, lp->rx_ring[lp->rx_idx].msg_length,
+		inw(ioaddr+LANCE_DATA));
+#endif
+	if (status == 0x3)
+		memcpy(nic->packet, lp->rbuf[lp->rx_idx], nic->packetlen = lp->rx_ring[lp->rx_idx].msg_length);
+	/* Andrew Boyd of QNX reports that some revs of the 79C765
+	   clear the buffer length */
+	lp->rx_ring[lp->rx_idx].buf_length = -ETH_FRAME_LEN-4;
+	lp->rx_ring[lp->rx_idx].u.addr[3] |= 0x80;	/* prime for next receive */
+
+	/* I'm not sure if the following is still ok with multiple Rx buffers, but it works */
+	outw(0x0, ioaddr+LANCE_ADDR);
+	(void)inw(ioaddr+LANCE_ADDR);
+	outw(0x500, ioaddr+LANCE_DATA);		/* clear receive + InitDone */
+
+	/* Switch to the next Rx ring buffer */
+	lp->rx_idx = (lp->rx_idx + 1) & RX_RING_MOD_MASK;
+
+	return (status == 0x3);
+}
+
+/**************************************************************************
+TRANSMIT - Transmit a frame
+***************************************************************************/
+static void lance_transmit(
+	struct nic *nic,
+	const char *d,			/* Destination */
+	unsigned int t,			/* Type */
+	unsigned int s,			/* size */
+	const char *p)			/* Packet */
+{
+	unsigned long		time;
+
+	/* copy the packet to ring buffer */
+	memcpy(lp->tbuf, d, ETH_ALEN);	/* dst */
+	memcpy(&lp->tbuf[ETH_ALEN], nic->node_addr, ETH_ALEN); /* src */
+	lp->tbuf[ETH_ALEN+ETH_ALEN] = t >> 8;	/* type */
+	lp->tbuf[ETH_ALEN+ETH_ALEN+1] = t;	/* type */
+	memcpy(&lp->tbuf[ETH_HLEN], p, s);
+	s += ETH_HLEN;
+	if (chip_table[chip_version].flags & LANCE_MUST_PAD)
+		while (s < ETH_ZLEN)	/* pad to min length */
+			lp->tbuf[s++] = 0;
+	lp->tx_ring.buf_length = -s;
+	lp->tx_ring.misc = 0x0;
+	/* OWN, STP, ENP */
+	lp->tx_ring.u.base = virt_to_bus(lp->tbuf) & 0xffffff;
+	/* we set the top byte as the very last thing */
+	lp->tx_ring.u.addr[3] = 0x83;
+	/* Trigger an immediate send poll */
+	outw(0x0, ioaddr+LANCE_ADDR);
+	(void)inw(ioaddr+LANCE_ADDR);	/* as in the datasheets... */
+	/* Klaus Espenlaub: the value below was 0x48, but that enabled the
+	 * interrupt line, causing a hang if for some reasone the interrupt
+	 * controller had the LANCE interrupt enabled.  I have no idea why
+	 * nobody ran into this before...  */
+	outw(0x08, ioaddr+LANCE_DATA);
+	/* wait for transmit complete */
+	time = currticks() + TICKS_PER_SEC;		/* wait one second */
+	while (currticks() < time && (lp->tx_ring.u.base & 0x80000000) != 0)
+		;
+	if ((lp->tx_ring.u.base & 0x80000000) != 0)
+		printf("LANCE timed out on transmit\n");
+	(void)inw(ioaddr+LANCE_ADDR);
+	outw(0x200, ioaddr+LANCE_DATA);		/* clear transmit + InitDone */
+#ifdef	DEBUG
+	printf("tx_ring.u.base %X tx_ring.buf_length %hX tx_ring.misc %hX csr0 %hX\n",
+		lp->tx_ring.u.base, lp->tx_ring.buf_length, lp->tx_ring.misc,
+		inw(ioaddr+LANCE_DATA));
+#endif
+}
+
+static void lance_disable(struct nic *nic)
+{
+	(void)inw(ioaddr+LANCE_RESET);
+	if (chip_table[lance_version].flags & LANCE_MUST_UNRESET)
+		outw(0, ioaddr+LANCE_RESET);
+
+	outw(0, ioaddr+LANCE_ADDR);
+	outw(0x0004, ioaddr+LANCE_DATA);	/* stop the LANCE */
+
+#ifndef	INCLUDE_LANCE
+	disable_dma(dma);
+#endif
+}
+
+#ifdef	INCLUDE_LANCE
+static int lance_probe1(struct nic *nic, struct pci_device *pci)
+#else
+static int lance_probe1(struct nic *nic)
+#endif
+{
+	int			reset_val ;
+	unsigned int		i;
+	Address			l;
+	short			dma_channels;
+#ifndef	INCLUDE_LANCE
+	static const char	dmas[] = { 5, 6, 7, 3 };
+#endif
+
+	reset_val = inw(ioaddr+LANCE_RESET);
+	outw(reset_val, ioaddr+LANCE_RESET);
+#if	1  /* Klaus Espenlaub -- was #ifdef	INCLUDE_NE2100*/
+	outw(0x0, ioaddr+LANCE_ADDR);	/* Switch to window 0 */
+	if (inw(ioaddr+LANCE_DATA) != 0x4)
+		return (-1);
+#endif
+	outw(88, ioaddr+LANCE_ADDR);	/* Get the version of the chip */
+	if (inw(ioaddr+LANCE_ADDR) != 88)
+		lance_version = 0;
+	else
+	{
+		chip_version = inw(ioaddr+LANCE_DATA);
+		outw(89, ioaddr+LANCE_ADDR);
+		chip_version |= inw(ioaddr+LANCE_DATA) << 16;
+		if ((chip_version & 0xfff) != 0x3)
+			return (-1);
+		chip_version = (chip_version >> 12) & 0xffff;
+		for (lance_version = 1; chip_table[lance_version].id_number != 0; ++lance_version)
+			if (chip_table[lance_version].id_number == chip_version)
+				break;
+	}
+	/* make sure data structure is 8-byte aligned */
+	l = ((Address)lance + 7) & ~7;
+	lp = (struct lance_interface *)l;
+	lp->init_block.mode = 0x3;	/* disable Rx and Tx */
+	lp->init_block.filter[0] = lp->init_block.filter[1] = 0x0;
+	/* using multiple Rx buffer and a single Tx buffer */
+	lp->init_block.rx_ring = (virt_to_bus(&lp->rx_ring) & 0xffffff) | RX_RING_LEN_BITS;
+	lp->init_block.tx_ring = virt_to_bus(&lp->tx_ring) & 0xffffff;
+	l = virt_to_bus(&lp->init_block);
+	outw(0x1, ioaddr+LANCE_ADDR);
+	(void)inw(ioaddr+LANCE_ADDR);
+	outw((unsigned short)l, ioaddr+LANCE_DATA);
+	outw(0x2, ioaddr+LANCE_ADDR);
+	(void)inw(ioaddr+LANCE_ADDR);
+	outw((unsigned short)(l >> 16), ioaddr+LANCE_DATA);
+	outw(0x4, ioaddr+LANCE_ADDR);
+	(void)inw(ioaddr+LANCE_ADDR);
+	outw(0x915, ioaddr+LANCE_DATA);
+	outw(0x0, ioaddr+LANCE_ADDR);
+	(void)inw(ioaddr+LANCE_ADDR);
+	/* Get station address */
+	for (i = 0; i < ETH_ALEN; ++i) {
+		nic->node_addr[i] = inb(ioaddr+LANCE_ETH_ADDR+i);
+	}
+#ifndef	INCLUDE_LANCE
+	/* now probe for DMA channel */
+	dma_channels = ((inb(DMA1_STAT_REG) >> 4) & 0xf) |
+		(inb(DMA2_STAT_REG) & 0xf0);
+	/* need to fix when PCI provides DMA info */
+	for (i = 0; i < (sizeof(dmas)/sizeof(dmas[0])); ++i)
+	{
+		int		j;
+
+		dma = dmas[i];
+		/* Don't enable a permanently busy DMA channel,
+		   or the machine will hang */
+		if (dma_channels & (1 << dma))
+			continue;
+		outw(0x7f04, ioaddr+LANCE_DATA);	/* clear memory error bits */
+		set_dma_mode(dma, DMA_MODE_CASCADE);
+		enable_dma(dma);
+		outw(0x1, ioaddr+LANCE_DATA);		/* init */
+		for (j = 100; j > 0; --j)
+			if (inw(ioaddr+LANCE_DATA) & 0x900)
+				break;
+		if (inw(ioaddr+LANCE_DATA) & 0x100)
+			break;
+		else
+			disable_dma(dma);
+	}
+	if (i >= (sizeof(dmas)/sizeof(dmas[0])))
+		dma = 0;
+	printf("\n%s base %#X, DMA %d, addr %!\n",
+		chip_table[lance_version].name, ioaddr, dma, nic->node_addr);
+#else
+	printf(" %s base %#hX, addr %!\n", chip_table[lance_version].name, ioaddr, nic->node_addr);
+#endif
+	if (chip_table[chip_version].flags & LANCE_ENABLE_AUTOSELECT) {
+		/* Turn on auto-select of media (10baseT or BNC) so that the
+		 * user watch the LEDs. */
+		outw(0x0002, ioaddr+LANCE_ADDR);
+		/* Don't touch 10base2 power bit. */
+		outw(inw(ioaddr+LANCE_BUS_IF) | 0x0002, ioaddr+LANCE_BUS_IF);
+	}
+	return (lance_version);
+}
+
+/**************************************************************************
+PROBE - Look for an adapter, this routine's visible to the outside
+***************************************************************************/
+
+#ifdef	INCLUDE_LANCE
+struct nic *lancepci_probe(struct nic *nic, unsigned short *probe_addrs, struct pci_device *pci)
+#endif
+#ifdef	INCLUDE_NE2100
+struct nic *ne2100_probe(struct nic *nic, unsigned short *probe_addrs)
+#endif
+#ifdef	INCLUDE_NI6510
+struct nic *ni6510_probe(struct nic *nic, unsigned short *probe_addrs)
+#endif
+{
+	unsigned short		*p;
+#ifndef	INCLUDE_LANCE
+	static unsigned short	io_addrs[] = { 0x300, 0x320, 0x340, 0x360, 0 };
+#endif
+
+	/* if probe_addrs is 0, then routine can use a hardwired default */
+	if (probe_addrs == 0) {
+#ifdef	INCLUDE_LANCE
+		return 0;
+#else
+		probe_addrs = io_addrs;
+#endif
+	}
+	for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
+	{
+		char	offset15, offset14 = inb(ioaddr + 14);
+		unsigned short	pci_cmd;
+
+#ifdef	INCLUDE_NE2100
+		if ((offset14 == 0x52 || offset14 == 0x57) &&
+		 ((offset15 = inb(ioaddr + 15)) == 0x57 || offset15 == 0x44))
+			if (lance_probe1(nic) >= 0)
+				break;
+#endif
+#ifdef	INCLUDE_NI6510
+		if ((offset14 == 0x00 || offset14 == 0x52) &&
+		 ((offset15 = inb(ioaddr + 15)) == 0x55 || offset15 == 0x44))
+			if (lance_probe1(nic) >= 0)
+				break;
+#endif
+#ifdef	INCLUDE_LANCE
+		adjust_pci_device(pci);
+		if (lance_probe1(nic, pci) >= 0)
+			break;
+#endif
+	}
+	/* if board found */
+	if (ioaddr != 0)
+	{
+		/* point to NIC specific routines */
+		lance_reset(nic);
+		nic->reset = lance_reset;
+		nic->poll = lance_poll;
+		nic->transmit = lance_transmit;
+		nic->disable = lance_disable;
+		return nic;
+	}
+
+	/* no board found */
+	return 0;
+}
diff --git a/netboot/linux-asm-io.h b/netboot/linux-asm-io.h
new file mode 100644
index 0000000..4fe91fb
--- /dev/null
+++ b/netboot/linux-asm-io.h
@@ -0,0 +1,187 @@
+#ifndef	_ASM_IO_H
+#define _ASM_IO_H
+
+/*
+ * This file contains the definitions for the x86 IO instructions
+ * inb/inw/inl/outb/outw/outl and the "string versions" of the same
+ * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
+ * versions of the single-IO instructions (inb_p/inw_p/..).
+ *
+ * This file is not meant to be obfuscating: it's just complicated
+ * to (a) handle it all in a way that makes gcc able to optimize it
+ * as well as possible and (b) trying to avoid writing the same thing
+ * over and over again with slight variations and possibly making a
+ * mistake somewhere.
+ */
+
+/*
+ * Thanks to James van Artsdalen for a better timing-fix than
+ * the two short jumps: using outb's to a nonexistent port seems
+ * to guarantee better timings even on fast machines.
+ *
+ * On the other hand, I'd like to be sure of a non-existent port:
+ * I feel a bit unsafe about using 0x80 (should be safe, though)
+ *
+ *		Linus
+ */
+
+#ifdef	SLOW_IO_BY_JUMPING
+#define __SLOW_DOWN_IO __asm__ __volatile__("jmp 1f\n1:\tjmp 1f\n1:")
+#else
+#define __SLOW_DOWN_IO __asm__ __volatile__("outb %al,$0x80")
+#endif
+
+#ifdef	REALLY_SLOW_IO
+#define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
+#else
+#define SLOW_DOWN_IO __SLOW_DOWN_IO
+#endif
+
+/*
+ * readX/writeX() are used to access memory mapped devices. On some
+ * architectures the memory mapped IO stuff needs to be accessed
+ * differently. On the x86 architecture, we just read/write the
+ * memory location directly.
+ */
+#define readb(addr) (*(volatile unsigned char *) (addr))
+#define readw(addr) (*(volatile unsigned short *) (addr))
+#define readl(addr) (*(volatile unsigned int *) (addr))
+
+#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+
+#define memset_io(a,b,c)	memset((void *)(a),(b),(c))
+#define memcpy_fromio(a,b,c)	memcpy((a),(void *)(b),(c))
+#define memcpy_toio(a,b,c)	memcpy((void *)(a),(b),(c))
+
+/*
+ * Again, i386 does not require mem IO specific function.
+ */
+
+#define eth_io_copy_and_sum(a,b,c,d)	eth_copy_and_sum((a),(void *)(b),(c),(d))
+
+/*
+ * Talk about misusing macros..
+ */
+
+#define __OUT1(s,x) \
+extern void __out##s(unsigned x value, unsigned short port); \
+extern inline void __out##s(unsigned x value, unsigned short port) {
+
+#define __OUT2(s,s1,s2) \
+__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
+
+#define __OUT(s,s1,x) \
+__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); } \
+__OUT1(s##c,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); } \
+__OUT1(s##_p,x) __OUT2(s,s1,"w") : : "a" (value), "d" (port)); SLOW_DOWN_IO; } \
+__OUT1(s##c_p,x) __OUT2(s,s1,"") : : "a" (value), "id" (port)); SLOW_DOWN_IO; }
+
+#define __IN1(s,x) \
+extern unsigned x __in##s(unsigned short port); \
+extern inline unsigned x __in##s(unsigned short port) { unsigned x _v;
+
+#define __IN2(s,s1,s2) \
+__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
+
+#define __IN(s,s1,x,i...) \
+__IN1(s,x) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); return _v; } \
+__IN1(s##c,x) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); return _v; } \
+__IN1(s##_p,x) __IN2(s,s1,"w") : "=a" (_v) : "d" (port) ,##i ); SLOW_DOWN_IO; return _v; } \
+__IN1(s##c_p,x) __IN2(s,s1,"") : "=a" (_v) : "id" (port) ,##i ); SLOW_DOWN_IO; return _v; }
+
+#define __INS(s) \
+extern void ins##s(unsigned short port, void * addr, unsigned long count); \
+extern inline void ins##s(unsigned short port, void * addr, unsigned long count) \
+{ __asm__ __volatile__ ("cld ; rep ; ins" #s \
+: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
+
+#define __OUTS(s) \
+extern void outs##s(unsigned short port, const void * addr, unsigned long  count); \
+extern inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
+{ __asm__ __volatile__ ("cld ; rep ; outs" #s \
+: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
+
+__IN(b,"", char)
+__IN(w,"",short)
+__IN(l,"", long)
+
+__OUT(b,"b",char)
+__OUT(w,"w",short)
+__OUT(l,,int)
+
+__INS(b)
+__INS(w)
+__INS(l)
+
+__OUTS(b)
+__OUTS(w)
+__OUTS(l)
+
+/*
+ * Note that due to the way __builtin_constant_p() works, you
+ *  - can't use it inside a inline function (it will never be true)
+ *  - you don't have to worry about side effects within the __builtin..
+ */
+#define outb(val,port) \
+((__builtin_constant_p((port)) && (port) < 256) ? \
+	__outbc((val),(port)) : \
+	__outb((val),(port)))
+
+#define inb(port) \
+((__builtin_constant_p((port)) && (port) < 256) ? \
+	__inbc(port) : \
+	__inb(port))
+
+#define outb_p(val,port) \
+((__builtin_constant_p((port)) && (port) < 256) ? \
+	__outbc_p((val),(port)) : \
+	__outb_p((val),(port)))
+
+#define inb_p(port) \
+((__builtin_constant_p((port)) && (port) < 256) ? \
+	__inbc_p(port) : \
+	__inb_p(port))
+
+#define outw(val,port) \
+((__builtin_constant_p((port)) && (port) < 256) ? \
+	__outwc((val),(port)) : \
+	__outw((val),(port)))
+
+#define inw(port) \
+((__builtin_constant_p((port)) && (port) < 256) ? \
+	__inwc(port) : \
+	__inw(port))
+
+#define outw_p(val,port) \
+((__builtin_constant_p((port)) && (port) < 256) ? \
+	__outwc_p((val),(port)) : \
+	__outw_p((val),(port)))
+
+#define inw_p(port) \
+((__builtin_constant_p((port)) && (port) < 256) ? \
+	__inwc_p(port) : \
+	__inw_p(port))
+
+#define outl(val,port) \
+((__builtin_constant_p((port)) && (port) < 256) ? \
+	__outlc((val),(port)) : \
+	__outl((val),(port)))
+
+#define inl(port) \
+((__builtin_constant_p((port)) && (port) < 256) ? \
+	__inlc(port) : \
+	__inl(port))
+
+#define outl_p(val,port) \
+((__builtin_constant_p((port)) && (port) < 256) ? \
+	__outlc_p((val),(port)) : \
+	__outl_p((val),(port)))
+
+#define inl_p(port) \
+((__builtin_constant_p((port)) && (port) < 256) ? \
+	__inlc_p(port) : \
+	__inl_p(port))
+
+#endif
diff --git a/netboot/linux-asm-string.h b/netboot/linux-asm-string.h
new file mode 100644
index 0000000..d5bec08
--- /dev/null
+++ b/netboot/linux-asm-string.h
@@ -0,0 +1,291 @@
+/*
+ * Taken from Linux /usr/include/asm/string.h
+ * All except memcpy, memmove, memset and memcmp removed.
+ */
+
+#ifndef	_I386_STRING_H_
+#define _I386_STRING_H_
+
+/*
+ * This string-include defines all string functions as inline
+ * functions. Use gcc. It also assumes ds=es=data space, this should be
+ * normal. Most of the string-functions are rather heavily hand-optimized,
+ * see especially strtok,strstr,str[c]spn. They should work, but are not
+ * very easy to understand. Everything is done entirely within the register
+ * set, making the functions fast and clean. String instructions have been
+ * used through-out, making for "slightly" unclear code :-)
+ *
+ *		NO Copyright (C) 1991, 1992 Linus Torvalds,
+ *		consider these trivial functions to be PD.
+ */
+
+typedef int	size_t;
+
+extern void *__memcpy(void * to, const void * from, size_t n);
+extern void *__constant_memcpy(void * to, const void * from, size_t n);
+extern void *memmove(void * dest,const void * src, size_t n);
+extern void *__memset_generic(void * s, char c,size_t count);
+extern void *__constant_c_memset(void * s, unsigned long c, size_t count);
+extern void *__constant_c_and_count_memset(void * s, unsigned long pattern, size_t count);
+
+
+extern inline void * __memcpy(void * to, const void * from, size_t n)
+{
+int d0, d1, d2;
+__asm__ __volatile__(
+	"cld\n\t"
+	"rep ; movsl\n\t"
+	"testb $2,%b4\n\t"
+	"je 1f\n\t"
+	"movsw\n"
+	"1:\ttestb $1,%b4\n\t"
+	"je 2f\n\t"
+	"movsb\n"
+	"2:"
+	: "=&c" (d0), "=&D" (d1), "=&S" (d2)
+	:"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+	: "memory");
+return (to);
+}
+
+/*
+ * This looks horribly ugly, but the compiler can optimize it totally,
+ * as the count is constant.
+ */
+extern inline void * __constant_memcpy(void * to, const void * from, size_t n)
+{
+	switch (n) {
+		case 0:
+			return to;
+		case 1:
+			*(unsigned char *)to = *(const unsigned char *)from;
+			return to;
+		case 2:
+			*(unsigned short *)to = *(const unsigned short *)from;
+			return to;
+		case 3:
+			*(unsigned short *)to = *(const unsigned short *)from;
+			*(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
+			return to;
+		case 4:
+			*(unsigned long *)to = *(const unsigned long *)from;
+			return to;
+		case 6:	/* for Ethernet addresses */
+			*(unsigned long *)to = *(const unsigned long *)from;
+			*(2+(unsigned short *)to) = *(2+(const unsigned short *)from);
+			return to;
+		case 8:
+			*(unsigned long *)to = *(const unsigned long *)from;
+			*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+			return to;
+		case 12:
+			*(unsigned long *)to = *(const unsigned long *)from;
+			*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+			*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
+			return to;
+		case 16:
+			*(unsigned long *)to = *(const unsigned long *)from;
+			*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+			*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
+			*(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
+			return to;
+		case 20:
+			*(unsigned long *)to = *(const unsigned long *)from;
+			*(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
+			*(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
+			*(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
+			*(4+(unsigned long *)to) = *(4+(const unsigned long *)from);
+			return to;
+	}
+#define COMMON(x) \
+__asm__ __volatile__( \
+	"cld\n\t" \
+	"rep ; movsl" \
+	x \
+	: "=&c" (d0), "=&D" (d1), "=&S" (d2) \
+	: "0" (n/4),"1" ((long) to),"2" ((long) from) \
+	: "memory");
+{
+	int d0, d1, d2;
+	switch (n % 4) {
+		case 0: COMMON(""); return to;
+		case 1: COMMON("\n\tmovsb"); return to;
+		case 2: COMMON("\n\tmovsw"); return to;
+		default: COMMON("\n\tmovsw\n\tmovsb"); return to;
+	}
+}
+
+#undef COMMON
+}
+
+#define __HAVE_ARCH_MEMCPY
+#define memcpy(t, f, n) \
+(__builtin_constant_p(n) ? \
+ __constant_memcpy((t),(f),(n)) : \
+ __memcpy((t),(f),(n)))
+
+#define __HAVE_ARCH_MEMMOVE
+extern inline void * memmove(void * dest,const void * src, size_t n)
+{
+int d0, d1, d2;
+if (dest<src)
+__asm__ __volatile__(
+	"cld\n\t"
+	"rep\n\t"
+	"movsb"
+	: "=&c" (d0), "=&S" (d1), "=&D" (d2)
+	:"0" (n),"1" (src),"2" (dest)
+	: "memory");
+else
+__asm__ __volatile__(
+	"std\n\t"
+	"rep\n\t"
+	"movsb\n\t"
+	"cld"
+	: "=&c" (d0), "=&S" (d1), "=&D" (d2)
+	:"0" (n),
+	 "1" (n-1+(const char *)src),
+	 "2" (n-1+(char *)dest)
+	:"memory");
+return dest;
+}
+
+#define memcmp __builtin_memcmp
+
+extern inline void * __memset_generic(void * s, char c,size_t count)
+{
+int d0, d1;
+__asm__ __volatile__(
+	"cld\n\t"
+	"rep\n\t"
+	"stosb"
+	: "=&c" (d0), "=&D" (d1)
+	:"a" (c),"1" (s),"0" (count)
+	:"memory");
+return s;
+}
+
+/* we might want to write optimized versions of these later */
+#define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
+
+/*
+ * memset(x,0,y) is a reasonably common thing to do, so we want to fill
+ * things 32 bits at a time even when we don't know the size of the
+ * area at compile-time..
+ */
+extern inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
+{
+int d0, d1;
+__asm__ __volatile__(
+	"cld\n\t"
+	"rep ; stosl\n\t"
+	"testb $2,%b3\n\t"
+	"je 1f\n\t"
+	"stosw\n"
+	"1:\ttestb $1,%b3\n\t"
+	"je 2f\n\t"
+	"stosb\n"
+	"2:"
+	: "=&c" (d0), "=&D" (d1)
+	:"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
+	:"memory");
+return (s);
+}
+
+/*
+ * This looks horribly ugly, but the compiler can optimize it totally,
+ * as we by now know that both pattern and count is constant..
+ */
+extern inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
+{
+	switch (count) {
+		case 0:
+			return s;
+		case 1:
+			*(unsigned char *)s = pattern;
+			return s;
+		case 2:
+			*(unsigned short *)s = pattern;
+			return s;
+		case 3:
+			*(unsigned short *)s = pattern;
+			*(2+(unsigned char *)s) = pattern;
+			return s;
+		case 4:
+			*(unsigned long *)s = pattern;
+			return s;
+	}
+#define COMMON(x) \
+__asm__  __volatile__("cld\n\t" \
+	"rep ; stosl" \
+	x \
+	: "=&c" (d0), "=&D" (d1) \
+	: "a" (pattern),"0" (count/4),"1" ((long) s) \
+	: "memory")
+{
+	int d0, d1;
+	switch (count % 4) {
+		case 0: COMMON(""); return s;
+		case 1: COMMON("\n\tstosb"); return s;
+		case 2: COMMON("\n\tstosw"); return s;
+		default: COMMON("\n\tstosw\n\tstosb"); return s;
+	}
+}
+
+#undef COMMON
+}
+
+#define __constant_c_x_memset(s, c, count) \
+(__builtin_constant_p(count) ? \
+ __constant_c_and_count_memset((s),(c),(count)) : \
+ __constant_c_memset((s),(c),(count)))
+
+#define __memset(s, c, count) \
+(__builtin_constant_p(count) ? \
+ __constant_count_memset((s),(c),(count)) : \
+ __memset_generic((s),(c),(count)))
+
+#define __HAVE_ARCH_MEMSET
+#define memset(s, c, count) \
+(__builtin_constant_p(c) ? \
+ __constant_c_x_memset((s),(c),(count)) : \
+ __memset((s),(c),(count)))
+
+#define __HAVE_ARCH_STRNCMP
+static inline int strncmp(const char * cs,const char * ct,size_t count)
+{
+register int __res;
+int d0, d1, d2;
+__asm__ __volatile__(
+	"1:\tdecl %3\n\t"
+	"js 2f\n\t"
+	"lodsb\n\t"
+	"scasb\n\t"
+	"jne 3f\n\t"
+	"testb %%al,%%al\n\t"
+	"jne 1b\n"
+	"2:\txorl %%eax,%%eax\n\t"
+	"jmp 4f\n"
+	"3:\tsbbl %%eax,%%eax\n\t"
+	"orb $1,%%al\n"
+	"4:"
+		     :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
+		     :"1" (cs),"2" (ct),"3" (count));
+return __res;
+}
+
+#define __HAVE_ARCH_STRLEN
+static inline size_t strlen(const char * s)
+{
+int d0;
+register int __res;
+__asm__ __volatile__(
+	"repne\n\t"
+	"scasb\n\t"
+	"notl %0\n\t"
+	"decl %0"
+	:"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffff));
+return __res;
+}
+
+#endif
diff --git a/netboot/main.c b/netboot/main.c
new file mode 100644
index 0000000..82759b6
--- /dev/null
+++ b/netboot/main.c
@@ -0,0 +1,1171 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,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.
+ */
+
+/* Based on "src/main.c" in etherboot-5.0.5.  */
+
+/**************************************************************************
+ETHERBOOT -  BOOTP/TFTP Bootstrap Program
+
+Author: Martin Renters
+  Date: Dec/93
+  
+Literature dealing with the network protocols:
+       ARP - RFC826
+       RARP - RFC903
+       UDP - RFC768
+       BOOTP - RFC951, RFC2132 (vendor extensions)
+       DHCP - RFC2131, RFC2132 (options)
+       TFTP - RFC1350, RFC2347 (options), RFC2348 (blocksize), RFC2349 (tsize)
+       RPC - RFC1831, RFC1832 (XDR), RFC1833 (rpcbind/portmapper)
+       NFS - RFC1094, RFC1813 (v3, useful for clarifications, not implemented)
+
+**************************************************************************/
+
+#define GRUB	1
+#include <etherboot.h>
+#include <nic.h>
+
+/* #define DEBUG	1 */
+
+struct arptable_t arptable[MAX_ARP];
+
+/* Set if the user pushes Control-C.  */
+int ip_abort = 0;
+/* Set if an ethernet card is probed and IP addresses are set.  */
+int network_ready = 0;
+
+struct rom_info rom;
+
+static int vendorext_isvalid;
+static unsigned long netmask;
+static struct bootpd_t bootp_data;
+static unsigned long xid;
+static unsigned char *end_of_rfc1533 = NULL;
+
+#ifndef	NO_DHCP_SUPPORT
+#endif /* NO_DHCP_SUPPORT */
+
+/* äEth */
+static unsigned char vendorext_magic[] = {0xE4, 0x45, 0x74, 0x68};
+static const unsigned char broadcast[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+#ifdef	NO_DHCP_SUPPORT
+
+static unsigned char rfc1533_cookie[5] = {RFC1533_COOKIE, RFC1533_END};
+
+#else /* ! NO_DHCP_SUPPORT */
+
+static int dhcp_reply;
+static in_addr dhcp_server = {0L};
+static in_addr dhcp_addr = {0L};
+static unsigned char rfc1533_cookie[] = {RFC1533_COOKIE};
+static unsigned char rfc1533_end[] = {RFC1533_END};
+
+static const unsigned char dhcpdiscover[] =
+{
+  RFC2132_MSG_TYPE, 1, DHCPDISCOVER,	
+  RFC2132_MAX_SIZE,2,	/* request as much as we can */
+  ETH_MAX_MTU / 256, ETH_MAX_MTU % 256,
+  RFC2132_PARAM_LIST, 4, RFC1533_NETMASK, RFC1533_GATEWAY,
+  RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH
+};
+
+static const unsigned char dhcprequest[] =
+{
+  RFC2132_MSG_TYPE, 1, DHCPREQUEST,
+  RFC2132_SRV_ID, 4, 0, 0, 0, 0,
+  RFC2132_REQ_ADDR, 4, 0, 0, 0, 0,
+  RFC2132_MAX_SIZE, 2,	/* request as much as we can */
+  ETH_MAX_MTU / 256, ETH_MAX_MTU % 256,
+  /* request parameters */
+  RFC2132_PARAM_LIST,
+  /* 4 standard + 2 vendortags */
+  4 + 2,
+  /* Standard parameters */
+  RFC1533_NETMASK, RFC1533_GATEWAY,
+  RFC1533_HOSTNAME, RFC1533_EXTENSIONPATH,
+  /* Etherboot vendortags */
+  RFC1533_VENDOR_MAGIC,
+  RFC1533_VENDOR_CONFIGFILE,
+};
+
+#endif /* ! NO_DHCP_SUPPORT */
+
+static unsigned short ipchksum (unsigned short *ip, int len);
+static unsigned short udpchksum (struct iphdr *packet);
+
+void
+print_network_configuration (void)
+{
+  if (! eth_probe ())
+    grub_printf ("No ethernet card found.\n");
+  else if (! network_ready)
+    grub_printf ("Not initialized yet.\n");
+  else
+    {
+      etherboot_printf ("Address: %@\n", arptable[ARP_CLIENT].ipaddr.s_addr);
+      etherboot_printf ("Netmask: %@\n", netmask);
+      etherboot_printf ("Server: %@\n", arptable[ARP_SERVER].ipaddr.s_addr);
+      etherboot_printf ("Gateway: %@\n", arptable[ARP_GATEWAY].ipaddr.s_addr);
+    }
+}
+
+
+/**************************************************************************
+DEFAULT_NETMASK - Return default netmask for IP address
+**************************************************************************/
+static inline unsigned long 
+default_netmask (void)
+{
+  int net = ntohl (arptable[ARP_CLIENT].ipaddr.s_addr) >> 24;
+  if (net <= 127)
+    return (htonl (0xff000000));
+  else if (net < 192)
+    return (htonl (0xffff0000));
+  else
+    return (htonl (0xffffff00));
+}
+
+/* ifconfig - configure network interface.  */
+int
+ifconfig (char *ip, char *sm, char *gw, char *svr)
+{
+  in_addr tmp;
+  
+  if (sm) 
+    {
+      if (! inet_aton (sm, &tmp))
+	return 0;
+      
+      netmask = tmp.s_addr;
+    }
+  
+  if (ip) 
+    {
+      if (! inet_aton (ip, &arptable[ARP_CLIENT].ipaddr)) 
+	return 0;
+      
+      if (! netmask && ! sm) 
+	netmask = default_netmask ();
+    }
+  
+  if (gw && ! inet_aton (gw, &arptable[ARP_GATEWAY].ipaddr)) 
+    return 0;
+
+  /* Clear out the ARP entry.  */
+  grub_memset (arptable[ARP_GATEWAY].node, 0, ETH_ALEN);
+  
+  if (svr && ! inet_aton (svr, &arptable[ARP_SERVER].ipaddr)) 
+    return 0;
+
+  /* Likewise.  */
+  grub_memset (arptable[ARP_SERVER].node, 0, ETH_ALEN);
+  
+  if (ip || sm)
+    {
+      if (IP_BROADCAST == (netmask | arptable[ARP_CLIENT].ipaddr.s_addr)
+	  || netmask == (netmask | arptable[ARP_CLIENT].ipaddr.s_addr)
+	  || ! netmask)
+	network_ready = 0;
+      else
+	network_ready = 1;
+    }
+  
+  return 1;
+}
+
+
+/**************************************************************************
+UDP_TRANSMIT - Send a UDP datagram
+**************************************************************************/
+int 
+udp_transmit (unsigned long destip, unsigned int srcsock,
+	      unsigned int destsock, int len, const void *buf)
+{
+  struct iphdr *ip;
+  struct udphdr *udp;
+  struct arprequest arpreq;
+  int arpentry, i;
+  int retry;
+
+  ip = (struct iphdr *) buf;
+  udp = (struct udphdr *) ((unsigned long) buf + sizeof (struct iphdr));
+  ip->verhdrlen = 0x45;
+  ip->service = 0;
+  ip->len = htons (len);
+  ip->ident = 0;
+  ip->frags = 0;
+  ip->ttl = 60;
+  ip->protocol = IP_UDP;
+  ip->chksum = 0;
+  ip->src.s_addr = arptable[ARP_CLIENT].ipaddr.s_addr;
+  ip->dest.s_addr = destip;
+  ip->chksum = ipchksum ((unsigned short *) buf, sizeof (struct iphdr));
+  udp->src = htons (srcsock);
+  udp->dest = htons (destsock);
+  udp->len = htons (len - sizeof (struct iphdr));
+  udp->chksum = 0;
+  udp->chksum = htons (udpchksum (ip));
+
+  if (udp->chksum == 0)
+    udp->chksum = 0xffff;
+  
+  if (destip == IP_BROADCAST)
+    {
+      eth_transmit (broadcast, IP, len, buf);
+    }
+  else
+    {
+      if (((destip & netmask)
+	   != (arptable[ARP_CLIENT].ipaddr.s_addr & netmask))
+	  && arptable[ARP_GATEWAY].ipaddr.s_addr)
+	destip = arptable[ARP_GATEWAY].ipaddr.s_addr;
+      
+      for (arpentry = 0; arpentry < MAX_ARP; arpentry++)
+	if (arptable[arpentry].ipaddr.s_addr == destip)
+	  break;
+      
+      if (arpentry == MAX_ARP)
+	{
+	  etherboot_printf ("%@ is not in my arp table!\n", destip);
+	  return 0;
+	}
+      
+      for (i = 0; i < ETH_ALEN; i++)
+	if (arptable[arpentry].node[i])
+	  break;
+      
+      if (i == ETH_ALEN)
+	{
+	  /* Need to do arp request.  */
+#ifdef DEBUG
+	  grub_printf ("arp request.\n");
+#endif
+	  arpreq.hwtype = htons (1);
+	  arpreq.protocol = htons (IP);
+	  arpreq.hwlen = ETH_ALEN;
+	  arpreq.protolen = 4;
+	  arpreq.opcode = htons (ARP_REQUEST);
+	  grub_memmove (arpreq.shwaddr, arptable[ARP_CLIENT].node,
+			ETH_ALEN);
+	  grub_memmove (arpreq.sipaddr, (char *) &arptable[ARP_CLIENT].ipaddr,
+			sizeof (in_addr));
+	  grub_memset (arpreq.thwaddr, 0, ETH_ALEN);
+	  grub_memmove (arpreq.tipaddr, (char *) &destip, sizeof (in_addr));
+	  
+	  for (retry = 1; retry <= MAX_ARP_RETRIES; retry++)
+	    {
+	      long timeout;
+	      
+	      eth_transmit (broadcast, ARP, sizeof (arpreq), &arpreq);
+	      timeout = rfc2131_sleep_interval (TIMEOUT, retry);
+	      
+	      if (await_reply (AWAIT_ARP, arpentry, arpreq.tipaddr, timeout))
+		goto xmit;
+
+	      if (ip_abort)
+		return 0;
+	    }
+	  
+	  return 0;
+	}
+      
+    xmit:
+      eth_transmit (arptable[arpentry].node, IP, len, buf);
+    }
+  
+  return 1;
+}
+
+/**************************************************************************
+TFTP - Download extended BOOTP data, or kernel image
+**************************************************************************/
+static int
+tftp (const char *name, int (*fnc) (unsigned char *, int, int, int))
+{
+  int retry = 0;
+  static unsigned short iport = 2000;
+  unsigned short oport = 0;
+  unsigned short len, block = 0, prevblock = 0;
+  int bcounter = 0;
+  struct tftp_t *tr;
+  struct tftpreq_t tp;
+  int rc;
+  int packetsize = TFTP_DEFAULTSIZE_PACKET;
+  
+  /* Clear out the Rx queue first.  It contains nothing of interest,
+   * except possibly ARP requests from the DHCP/TFTP server.  We use
+   * polling throughout Etherboot, so some time may have passed since we
+   * last polled the receive queue, which may now be filled with
+   * broadcast packets.  This will cause the reply to the packets we are
+   * about to send to be lost immediately.  Not very clever.  */
+  await_reply (AWAIT_QDRAIN, 0, NULL, 0);
+  
+  tp.opcode = htons (TFTP_RRQ);
+  len = (grub_sprintf ((char *) tp.u.rrq, "%s%coctet%cblksize%c%d",
+		       name, 0, 0, 0, TFTP_MAX_PACKET)
+	 + sizeof (tp.ip) + sizeof (tp.udp) + sizeof (tp.opcode) + 1);
+  if (! udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, ++iport,
+		      TFTP_PORT, len, &tp))
+    return 0;
+  
+  for (;;)
+    {
+      long timeout;
+      
+#ifdef CONGESTED
+      timeout = rfc2131_sleep_interval (block ? TFTP_REXMT : TIMEOUT, retry);
+#else
+      timeout = rfc2131_sleep_interval (TIMEOUT, retry);
+#endif
+
+      if (! await_reply (AWAIT_TFTP, iport, NULL, timeout))
+	{
+	  if (! block && retry++ < MAX_TFTP_RETRIES)
+	    {
+	      /* Maybe initial request was lost.  */
+	      if (! udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
+				  ++iport, TFTP_PORT, len, &tp))
+		return 0;
+	      
+	      continue;
+	    }
+	  
+#ifdef CONGESTED
+	  if (block && ((retry += TFTP_REXMT) < TFTP_TIMEOUT))
+	    {
+	      /* We resend our last ack.  */
+#ifdef MDEBUG
+	      grub_printf ("<REXMT>\n");
+#endif
+	      udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
+			    iport, oport,
+			    TFTP_MIN_PACKET, &tp);
+	      continue;
+	    }
+#endif
+	  /* Timeout.  */
+	  break;
+	}
+      
+      tr = (struct tftp_t *) &nic.packet[ETH_HLEN];
+      if (tr->opcode == ntohs (TFTP_ERROR))
+	{
+	  grub_printf ("TFTP error %d (%s)\n",
+		       ntohs (tr->u.err.errcode),
+		       tr->u.err.errmsg);
+	  break;
+	}
+      
+      if (tr->opcode == ntohs (TFTP_OACK))
+	{
+	  char *p = tr->u.oack.data, *e;
+	  
+	  /* Shouldn't happen.  */
+	  if (prevblock)
+	    /* Ignore it.  */
+	    continue;
+	  
+	  len = ntohs (tr->udp.len) - sizeof (struct udphdr) - 2;
+	  if (len > TFTP_MAX_PACKET)
+	    goto noak;
+	  
+	  e = p + len;
+	  while (*p != '\000' && p < e)
+	    {
+	      if (! grub_strcmp ("blksize", p))
+		{
+		  p += 8;
+		  if ((packetsize = getdec (&p)) < TFTP_DEFAULTSIZE_PACKET)
+		    goto noak;
+		  
+		  while (p < e && *p)
+		    p++;
+		  
+		  if (p < e)
+		    p++;
+		}
+	      else
+		{
+		noak:
+		  tp.opcode = htons (TFTP_ERROR);
+		  tp.u.err.errcode = 8;
+		  len = (grub_sprintf ((char *) tp.u.err.errmsg,
+				       "RFC1782 error")
+			 + sizeof (tp.ip) + sizeof (tp.udp)
+			 + sizeof (tp.opcode) + sizeof (tp.u.err.errcode)
+			 + 1);
+		  udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr,
+				iport, ntohs (tr->udp.src),
+				len, &tp);
+		  return 0;
+		}
+	    }
+	  
+	  if (p > e)
+	    goto noak;
+	  
+	  /* This ensures that the packet does not get processed as data!  */
+	  block = tp.u.ack.block = 0; 
+	}
+      else if (tr->opcode == ntohs (TFTP_DATA))
+	{
+	  len = ntohs (tr->udp.len) - sizeof (struct udphdr) - 4;
+	  /* Shouldn't happen.  */
+	  if (len > packetsize)
+	    /* Ignore it.  */
+	    continue;
+	  
+	  block = ntohs (tp.u.ack.block = tr->u.data.block);
+	}
+      else
+	/* Neither TFTP_OACK nor TFTP_DATA.  */
+	break;
+      
+      if ((block || bcounter) && (block != prevblock + 1))
+	/* Block order should be continuous */
+	tp.u.ack.block = htons (block = prevblock);
+      
+      /* Should be continuous.  */
+      tp.opcode = htons (TFTP_ACK);
+      oport = ntohs (tr->udp.src);
+      /* Ack.  */
+      udp_transmit (arptable[ARP_SERVER].ipaddr.s_addr, iport,
+		    oport, TFTP_MIN_PACKET, &tp);
+      
+      if ((unsigned short) (block - prevblock) != 1)
+	/* Retransmission or OACK, don't process via callback
+	 * and don't change the value of prevblock.  */
+	continue;
+      
+      prevblock = block;
+      /* Is it the right place to zero the timer?  */
+      retry = 0;
+      
+      if ((rc = fnc (tr->u.data.download,
+		     ++bcounter, len, len < packetsize)) >= 0)
+	return rc;
+
+      /* End of data.  */
+      if (len < packetsize)           
+	return 1;
+    }
+  
+  return 0;
+}
+
+/**************************************************************************
+RARP - Get my IP address and load information
+**************************************************************************/
+int 
+rarp (void)
+{
+  int retry;
+
+  /* arp and rarp requests share the same packet structure.  */
+  struct arprequest rarpreq;
+
+  /* Make sure that an ethernet is probed.  */
+  if (! eth_probe ())
+    return 0;
+
+  /* Clear the ready flag.  */
+  network_ready = 0;
+  
+  grub_memset (&rarpreq, 0, sizeof (rarpreq));
+
+  rarpreq.hwtype = htons (1);
+  rarpreq.protocol = htons (IP);
+  rarpreq.hwlen = ETH_ALEN;
+  rarpreq.protolen = 4;
+  rarpreq.opcode = htons (RARP_REQUEST);
+  grub_memmove ((char *) &rarpreq.shwaddr, arptable[ARP_CLIENT].node,
+		ETH_ALEN);
+  /* sipaddr is already zeroed out */
+  grub_memmove ((char *) &rarpreq.thwaddr, arptable[ARP_CLIENT].node,
+		ETH_ALEN);
+  /* tipaddr is already zeroed out */
+
+  for (retry = 0; retry < MAX_ARP_RETRIES; ++retry)
+    {
+      long timeout;
+      
+      eth_transmit (broadcast, RARP, sizeof (rarpreq), &rarpreq);
+
+      timeout = rfc2131_sleep_interval (TIMEOUT, retry);
+      if (await_reply (AWAIT_RARP, 0, rarpreq.shwaddr, timeout))
+	break;
+
+      if (ip_abort)
+	return 0;
+    }
+
+  if (retry < MAX_ARP_RETRIES)
+    {
+      network_ready = 1;
+      return 1;
+    }
+
+  return 0;
+}
+
+/**************************************************************************
+BOOTP - Get my IP address and load information
+**************************************************************************/
+int 
+bootp (void)
+{
+  int retry;
+#ifndef	NO_DHCP_SUPPORT
+  int reqretry;
+#endif /* ! NO_DHCP_SUPPORT */
+  struct bootpip_t ip;
+  unsigned long starttime;
+
+  /* Make sure that an ethernet is probed.  */
+  if (! eth_probe ())
+    return 0;
+
+  /* Clear the ready flag.  */
+  network_ready = 0;
+
+#ifdef DEBUG
+  grub_printf ("network is ready.\n");
+#endif
+  
+  grub_memset (&ip, 0, sizeof (struct bootpip_t));
+  ip.bp.bp_op = BOOTP_REQUEST;
+  ip.bp.bp_htype = 1;
+  ip.bp.bp_hlen = ETH_ALEN;
+  starttime = currticks ();
+  /* Use lower 32 bits of node address, more likely to be
+     distinct than the time since booting */
+  grub_memmove (&xid, &arptable[ARP_CLIENT].node[2], sizeof(xid));
+  ip.bp.bp_xid = xid += htonl (starttime);
+  grub_memmove (ip.bp.bp_hwaddr, arptable[ARP_CLIENT].node, ETH_ALEN);
+#ifdef DEBUG
+  etherboot_printf ("bp_op = %d\n", ip.bp.bp_op);
+  etherboot_printf ("bp_htype = %d\n", ip.bp.bp_htype);
+  etherboot_printf ("bp_hlen = %d\n", ip.bp.bp_hlen);
+  etherboot_printf ("bp_xid = %d\n", ip.bp.bp_xid);
+  etherboot_printf ("bp_hwaddr = %!\n", ip.bp.bp_hwaddr);
+  etherboot_printf ("bp_hops = %d\n", (int) ip.bp.bp_hops);
+  etherboot_printf ("bp_secs = %d\n", (int) ip.bp.bp_hwaddr);
+#endif
+  
+#ifdef	NO_DHCP_SUPPORT
+  /* Request RFC-style options.  */
+  grub_memmove (ip.bp.bp_vend, rfc1533_cookie, 5);
+#else
+  /* Request RFC-style options.  */
+  grub_memmove (ip.bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
+  grub_memmove (ip.bp.bp_vend + sizeof rfc1533_cookie, dhcpdiscover,
+		sizeof dhcpdiscover);
+  grub_memmove (ip.bp.bp_vend + sizeof rfc1533_cookie + sizeof dhcpdiscover,
+		rfc1533_end, sizeof rfc1533_end);
+#endif /* ! NO_DHCP_SUPPORT */
+
+  for (retry = 0; retry < MAX_BOOTP_RETRIES;)
+    {
+      long timeout;
+
+#ifdef DEBUG
+      grub_printf ("retry = %d\n", retry);
+#endif
+      
+      /* Clear out the Rx queue first.  It contains nothing of
+       * interest, except possibly ARP requests from the DHCP/TFTP
+       * server.  We use polling throughout Etherboot, so some time
+       * may have passed since we last polled the receive queue,
+       * which may now be filled with broadcast packets.  This will
+       * cause the reply to the packets we are about to send to be
+       * lost immediately.  Not very clever.  */
+      await_reply (AWAIT_QDRAIN, 0, NULL, 0);
+
+      udp_transmit (IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
+		    sizeof (struct bootpip_t), &ip);
+      timeout = rfc2131_sleep_interval (TIMEOUT, retry++);
+#ifdef NO_DHCP_SUPPORT
+      if (await_reply (AWAIT_BOOTP, 0, NULL, timeout))
+	{
+	  network_ready = 1;
+	  return 1;
+	}
+#else /* ! NO_DHCP_SUPPORT */
+      if (await_reply (AWAIT_BOOTP, 0, NULL, timeout))
+	{
+	  if (dhcp_reply != DHCPOFFER)
+	    {
+	      network_ready = 1;
+	      return 1;
+	    }
+
+	  dhcp_reply = 0;
+#ifdef DEBUG
+  etherboot_printf ("bp_op = %d\n", (int) ip.bp.bp_op);
+  etherboot_printf ("bp_htype = %d\n", (int) ip.bp.bp_htype);
+  etherboot_printf ("bp_hlen = %d\n", (int) ip.bp.bp_hlen);
+  etherboot_printf ("bp_xid = %d\n", (int) ip.bp.bp_xid);
+  etherboot_printf ("bp_hwaddr = %!\n", ip.bp.bp_hwaddr);
+  etherboot_printf ("bp_hops = %d\n", (int) ip.bp.bp_hops);
+  etherboot_printf ("bp_secs = %d\n", (int) ip.bp.bp_hwaddr);
+#endif
+	  grub_memmove (ip.bp.bp_vend, rfc1533_cookie, sizeof rfc1533_cookie);
+	  grub_memmove (ip.bp.bp_vend + sizeof rfc1533_cookie,
+			dhcprequest, sizeof dhcprequest);
+	  grub_memmove (ip.bp.bp_vend + sizeof rfc1533_cookie
+			+ sizeof dhcprequest,
+			rfc1533_end, sizeof rfc1533_end);
+	  grub_memmove (ip.bp.bp_vend + 9, (char *) &dhcp_server,
+			sizeof (in_addr));
+	  grub_memmove (ip.bp.bp_vend + 15, (char *) &dhcp_addr,
+			sizeof (in_addr));
+#ifdef DEBUG
+	  grub_printf ("errnum = %d\n", errnum);
+#endif
+	  for (reqretry = 0; reqretry < MAX_BOOTP_RETRIES;)
+	    {
+	      int ret;
+#ifdef DEBUG
+	      grub_printf ("reqretry = %d\n", reqretry);
+#endif
+	      
+	      ret = udp_transmit (IP_BROADCAST, BOOTP_CLIENT, BOOTP_SERVER,
+				  sizeof (struct bootpip_t), &ip);
+	      if (! ret)
+		grub_printf ("udp_transmit failed.\n");
+	      
+	      dhcp_reply = 0;
+	      timeout = rfc2131_sleep_interval (TIMEOUT, reqretry++);
+	      if (await_reply (AWAIT_BOOTP, 0, NULL, timeout))
+		if (dhcp_reply == DHCPACK)
+		  {
+		    network_ready = 1;
+		    return 1;
+		  }
+
+#ifdef DEBUG
+	      grub_printf ("dhcp_reply = %d\n", dhcp_reply);
+#endif
+	      
+	      if (ip_abort)
+		return 0;
+	    }
+	}
+#endif /* ! NO_DHCP_SUPPORT */
+      
+      if (ip_abort)
+	return 0;
+      
+      ip.bp.bp_secs = htons ((currticks () - starttime) / TICKS_PER_SEC);
+    }
+
+  /* Timeout.  */
+  return 0;
+}
+
+/**************************************************************************
+UDPCHKSUM - Checksum UDP Packet (one of the rare cases when assembly is
+            actually simpler...)
+ RETURNS: checksum, 0 on checksum error. This
+          allows for using the same routine for RX and TX summing:
+          RX  if (packet->udp.chksum && udpchksum(packet))
+                  error("checksum error");
+          TX  packet->udp.chksum=0;
+              if (0==(packet->udp.chksum=udpchksum(packet)))
+                  packet->upd.chksum=0xffff;
+**************************************************************************/
+static inline void
+dosum (unsigned short *start, unsigned int len, unsigned short *sum)
+{
+  __asm__ __volatile__
+    ("clc\n"
+     "1:\tlodsw\n\t"
+     "xchg %%al,%%ah\n\t"	/* convert to host byte order */
+     "adcw %%ax,%0\n\t"		/* add carry of previous iteration */
+     "loop 1b\n\t"
+     "adcw $0,%0"		/* add carry of last iteration */
+     : "=b" (*sum), "=S"(start), "=c"(len)
+     : "0"(*sum), "1"(start), "2"(len)
+     : "ax", "cc"
+     );
+}
+
+/* UDP sum:
+ * proto, src_ip, dst_ip, udp_dport, udp_sport, 2*udp_len, payload
+ */
+static unsigned short
+udpchksum (struct iphdr *packet)
+{
+  int len = ntohs (packet->len);
+  unsigned short rval;
+  
+  /* add udplength + protocol number */
+  rval = (len - sizeof (struct iphdr)) + IP_UDP;
+  
+  /* pad to an even number of bytes */
+  if (len % 2) {
+    ((char *) packet)[len++] = 0;
+  }
+  
+  /* sum over src/dst ipaddr + udp packet */
+  len -= (char *) &packet->src - (char *) packet;
+  dosum ((unsigned short *) &packet->src, len >> 1, &rval);
+  
+  /* take one's complement */
+  return ~rval;
+}
+
+/**************************************************************************
+AWAIT_REPLY - Wait until we get a response for our request
+**************************************************************************/
+int 
+await_reply (int type, int ival, void *ptr, int timeout)
+{
+  unsigned long time;
+  struct iphdr *ip;
+  struct udphdr *udp;
+  struct arprequest *arpreply;
+  struct bootp_t *bootpreply;
+  unsigned short ptype;
+  unsigned int protohdrlen = (ETH_HLEN + sizeof (struct iphdr)
+			      + sizeof (struct udphdr));
+
+  /* Clear the abort flag.  */
+  ip_abort = 0;
+  
+  time = timeout + currticks ();
+  /* The timeout check is done below.  The timeout is only checked if
+   * there is no packet in the Rx queue.  This assumes that eth_poll()
+   * needs a negligible amount of time.  */
+  for (;;)
+    {
+      if (eth_poll ())
+	{
+	  /* We have something!  */
+	  
+	  /* Check for ARP - No IP hdr.  */
+	  if (nic.packetlen >= ETH_HLEN)
+	    {
+	      ptype = (((unsigned short) nic.packet[12]) << 8
+		       | ((unsigned short) nic.packet[13]));
+	    }
+	  else
+	    /* What else could we do with it?  */
+	    continue;
+	  
+	  if (nic.packetlen >= ETH_HLEN + sizeof (struct arprequest)
+	      && ptype == ARP)
+	    {
+	      unsigned long tmp;
+
+	      arpreply = (struct arprequest *) &nic.packet[ETH_HLEN];
+	      
+	      if (arpreply->opcode == htons (ARP_REPLY)
+		  && ! grub_memcmp (arpreply->sipaddr, ptr, sizeof (in_addr))
+		  && type == AWAIT_ARP)
+		{
+		  grub_memmove ((char *) arptable[ival].node,
+				arpreply->shwaddr,
+				ETH_ALEN);
+		  return 1;
+		}
+	      
+	      grub_memmove ((char *) &tmp, arpreply->tipaddr,
+			    sizeof (in_addr));
+	      
+	      if (arpreply->opcode == htons (ARP_REQUEST)
+		  && tmp == arptable[ARP_CLIENT].ipaddr.s_addr)
+		{
+		  arpreply->opcode = htons (ARP_REPLY);
+		  grub_memmove (arpreply->tipaddr, arpreply->sipaddr,
+				sizeof (in_addr));
+		  grub_memmove (arpreply->thwaddr, (char *) arpreply->shwaddr,
+				ETH_ALEN);
+		  grub_memmove (arpreply->sipaddr,
+				(char *) &arptable[ARP_CLIENT].ipaddr,
+				sizeof (in_addr));
+		  grub_memmove (arpreply->shwaddr,
+				arptable[ARP_CLIENT].node,
+				ETH_ALEN);
+		  eth_transmit (arpreply->thwaddr, ARP,
+				sizeof (struct arprequest),
+				arpreply);
+#ifdef MDEBUG
+		  grub_memmove (&tmp, arpreply->tipaddr, sizeof (in_addr));
+		  etherboot_printf ("Sent ARP reply to: %@\n", tmp);
+#endif	/* MDEBUG */
+		}
+	      
+	      continue;
+	    }
+
+	  if (type == AWAIT_QDRAIN)
+	    continue;
+	  
+	  /* Check for RARP - No IP hdr.  */
+	  if (type == AWAIT_RARP
+	      && nic.packetlen >= ETH_HLEN + sizeof (struct arprequest)
+	      && ptype == RARP)
+	    {
+	      arpreply = (struct arprequest *) &nic.packet[ETH_HLEN];
+	      
+	      if (arpreply->opcode == htons (RARP_REPLY)
+		  && ! grub_memcmp (arpreply->thwaddr, ptr, ETH_ALEN))
+		{
+		  grub_memmove ((char *) arptable[ARP_SERVER].node,
+				arpreply->shwaddr, ETH_ALEN);
+		  grub_memmove ((char *) &arptable[ARP_SERVER].ipaddr,
+				arpreply->sipaddr, sizeof (in_addr));
+		  grub_memmove ((char *) &arptable[ARP_CLIENT].ipaddr,
+				arpreply->tipaddr, sizeof (in_addr));
+		  return 1;
+		}
+	      
+	      continue;
+	    }
+
+	  /* Anything else has IP header.  */
+	  if (nic.packetlen < protohdrlen || ptype != IP)
+	    continue;
+	  
+	  ip = (struct iphdr *) &nic.packet[ETH_HLEN];
+	  if (ip->verhdrlen != 0x45
+	      || ipchksum ((unsigned short *) ip, sizeof (struct iphdr))
+	      || ip->protocol != IP_UDP)
+	    continue;
+	  
+	  /*
+	    - Till Straumann <Till.Straumann@TU-Berlin.de>
+	    added udp checksum (safer on a wireless link)
+	    added fragmentation check: I had a corrupted image
+	    in memory due to fragmented TFTP packets - took me
+	    3 days to find the cause for this :-(
+	  */
+	  
+	  /* If More Fragments bit and Fragment Offset field
+	     are non-zero then packet is fragmented */
+	  if (ip->frags & htons(0x3FFF))
+	    {
+	      grub_printf ("ALERT: got a fragmented packet - reconfigure your server\n");
+	      continue;
+	    }
+	  
+	  udp = (struct udphdr *) &nic.packet[(ETH_HLEN
+					       + sizeof (struct iphdr))];
+	  if (udp->chksum && udpchksum (ip))
+	    {
+	      grub_printf ("UDP checksum error\n");
+	      continue;
+	    }
+	  
+	  /* BOOTP ?  */
+	  bootpreply = (struct bootp_t *)
+	    &nic.packet[(ETH_HLEN + sizeof (struct iphdr)
+			 + sizeof (struct udphdr))];
+	  if (type == AWAIT_BOOTP
+#ifdef NO_DHCP_SUPPORT
+	      && (nic.packetlen
+		  >= (ETH_HLEN + sizeof (struct bootp_t) - BOOTP_VENDOR_LEN))
+#else
+	      && (nic.packetlen
+		  >= (ETH_HLEN + sizeof (struct bootp_t) - DHCP_OPT_LEN))
+#endif /* ! NO_DHCP_SUPPORT */
+	      && udp->dest == htons (BOOTP_CLIENT)
+	      && bootpreply->bp_op == BOOTP_REPLY
+	      && bootpreply->bp_xid == xid
+	      && (! grub_memcmp (broadcast, bootpreply->bp_hwaddr, ETH_ALEN)
+		  || ! grub_memcmp (arptable[ARP_CLIENT].node,
+				    bootpreply->bp_hwaddr, ETH_ALEN)))
+	    {
+#ifdef DEBUG
+	      grub_printf ("BOOTP packet was received.\n");
+#endif
+	      arptable[ARP_CLIENT].ipaddr.s_addr
+		= bootpreply->bp_yiaddr.s_addr;
+#ifndef	NO_DHCP_SUPPORT
+	      dhcp_addr.s_addr = bootpreply->bp_yiaddr.s_addr;
+#ifdef DEBUG
+	      etherboot_printf ("dhcp_addr = %@\n", dhcp_addr.s_addr);
+#endif
+#endif /* ! NO_DHCP_SUPPORT */
+	      netmask = default_netmask ();
+	      arptable[ARP_SERVER].ipaddr.s_addr
+		= bootpreply->bp_siaddr.s_addr;
+	      /* Kill arp.  */
+	      grub_memset (arptable[ARP_SERVER].node, 0, ETH_ALEN);
+	      arptable[ARP_GATEWAY].ipaddr.s_addr
+		= bootpreply->bp_giaddr.s_addr;
+	      /* Kill arp.  */
+	      grub_memset (arptable[ARP_GATEWAY].node, 0, ETH_ALEN);
+
+	      grub_memmove ((char *) BOOTP_DATA_ADDR, (char *) bootpreply,
+			    sizeof (struct bootpd_t));
+#ifdef NO_DHCP_SUPPORT
+	      decode_rfc1533 (BOOTP_DATA_ADDR->bootp_reply.bp_vend,
+			      0, BOOTP_VENDOR_LEN + MAX_BOOTP_EXTLEN, 1);
+#else
+	      decode_rfc1533 (BOOTP_DATA_ADDR->bootp_reply.bp_vend,
+			      0, DHCP_OPT_LEN + MAX_BOOTP_EXTLEN, 1);
+#endif /* ! NO_DHCP_SUPPORT */
+	      
+	      return 1;
+	    }
+	  
+	  /* TFTP ? */
+	  if (type == AWAIT_TFTP && ntohs (udp->dest) == ival)
+	    return 1;
+	}
+      else
+	{
+	  /* Check for abort key only if the Rx queue is empty -
+	   * as long as we have something to process, don't
+	   * assume that something failed.  It is unlikely that
+	   * we have no processing time left between packets.  */
+	  if (checkkey () != -1 && ASCII_CHAR (getkey ()) == CTRL_C)
+	    {
+	      ip_abort = 1;
+	      return 0;
+	    }
+	  
+	  /* Do the timeout after at least a full queue walk.  */
+	  if ((timeout == 0) || (currticks() > time))
+	    {
+	      break;
+	    }
+	}
+    }
+  
+  return 0;
+}
+
+/**************************************************************************
+DECODE_RFC1533 - Decodes RFC1533 header
+**************************************************************************/
+int
+decode_rfc1533 (unsigned char *p, int block, int len, int eof)
+{
+  static unsigned char *extdata = NULL, *extend = NULL;
+  unsigned char *extpath = NULL;
+  unsigned char *endp;
+  
+  if (block == 0)
+    {
+      end_of_rfc1533 = NULL;
+      vendorext_isvalid = 0;
+      
+      if (grub_memcmp (p, rfc1533_cookie, 4))
+	/* no RFC 1533 header found */
+	return 0;
+      
+      p += 4;
+      endp = p + len;
+    }
+  else
+    {
+      if (block == 1)
+	{
+	  if (grub_memcmp (p, rfc1533_cookie, 4))
+	    /* no RFC 1533 header found */
+	    return 0;
+	  
+	  p += 4;
+	  len -= 4;
+	}
+      
+      if (extend + len
+	  <= ((unsigned char *)
+	      &(BOOTP_DATA_ADDR->bootp_extension[MAX_BOOTP_EXTLEN])))
+	{
+	  grub_memmove (extend, p, len);
+	  extend += len;
+	}
+      else
+	{
+	  grub_printf ("Overflow in vendor data buffer! Aborting...\n");
+	  *extdata = RFC1533_END;
+	  return 0;
+	}
+      
+      p = extdata;
+      endp = extend;
+    }
+
+  if (! eof)
+    return -1;
+  
+  while (p < endp)
+    {
+      unsigned char c = *p;
+      
+      if (c == RFC1533_PAD)
+	{
+	  p++;
+	  continue;
+	}
+      else if (c == RFC1533_END)
+	{
+	  end_of_rfc1533 = endp = p;
+	  continue;
+	}
+      else if (c == RFC1533_NETMASK)
+	{
+	  grub_memmove ((char *) &netmask, p + 2, sizeof (in_addr));
+	}
+      else if (c == RFC1533_GATEWAY)
+	{
+	  /* This is a little simplistic, but it will
+	     usually be sufficient.
+	     Take only the first entry.  */
+	  if (TAG_LEN (p) >= sizeof (in_addr))
+	    grub_memmove ((char *) &arptable[ARP_GATEWAY].ipaddr, p + 2,
+			  sizeof (in_addr));
+	}
+      else if (c == RFC1533_EXTENSIONPATH)
+	extpath = p;
+#ifndef	NO_DHCP_SUPPORT
+      else if (c == RFC2132_MSG_TYPE)
+	{
+	  dhcp_reply = *(p + 2);
+	}
+      else if (c == RFC2132_SRV_ID)
+	{
+	  grub_memmove ((char *) &dhcp_server, p + 2, sizeof (in_addr));
+#ifdef DEBUG
+	  etherboot_printf ("dhcp_server = %@\n", dhcp_server.s_addr);
+#endif
+	}
+#endif /* ! NO_DHCP_SUPPORT */
+      else if (c == RFC1533_VENDOR_MAGIC
+	       && TAG_LEN(p) >= 6
+	       && ! grub_memcmp (p + 2, vendorext_magic, 4)
+	       && p[6] == RFC1533_VENDOR_MAJOR)
+	vendorext_isvalid++;
+      /* GRUB now handles its own tag. Get the name of a configuration
+	 file from the network. Cool...  */
+      else if (c == RFC1533_VENDOR_CONFIGFILE)
+	{
+	  int l = TAG_LEN (p);
+	  
+	  /* Eliminate the trailing NULs according to RFC 2132.  */
+	  while (*(p + 2 + l - 1) == '\000' && l > 0)
+	    l--;
+	  
+	  /* XXX: Should check if LEN is less than the maximum length
+	     of CONFIG_FILE. This kind of robustness will be a goal
+	     in GRUB 1.0.  */
+	  grub_memmove (config_file, p + 2, l);
+	  config_file[l] = 0;
+	}
+      
+      p += TAG_LEN (p) + 2;
+    }
+  
+  extdata = extend = endp;
+  
+  /* Perhaps we can eliminate this because we doesn't require so
+     much information, but I leave this alone.  */
+  if (block == 0 && extpath != NULL)
+    {
+      char fname[64];
+      int fnamelen = TAG_LEN (extpath);
+      
+      while (*(extpath + 2 + fnamelen - 1) == '\000' && fnamelen > 0)
+	fnamelen--;
+      
+      if (fnamelen + 1 > sizeof (fname))
+	{
+	  grub_printf ("Too long file name for Extensions Path\n");
+	  return 0;
+	}
+      else if (! fnamelen)
+	{
+	  grub_printf ("Empty file name for Extensions Path\n");
+	  return 0;
+	}
+      
+      grub_memmove (fname, extpath + 2, fnamelen);
+      fname[fnamelen] = '\000';
+      grub_printf ("Loading BOOTP-extension file: %s\n", fname);
+      tftp (fname, decode_rfc1533);
+    }
+  
+  /* Proceed with next block.  */
+  return -1;
+}
+
+/**************************************************************************
+IPCHKSUM - Checksum IP Header
+**************************************************************************/
+static unsigned short 
+ipchksum (unsigned short *ip, int len)
+{
+  unsigned long sum = 0;
+  len >>= 1;
+  while (len--)
+    {
+      sum += *(ip++);
+      if (sum > 0xFFFF)
+	sum -= 0xFFFF;
+    }
+  return (~sum) & 0x0000FFFF;
+}
+
+#define TWO_SECOND_DIVISOR (2147483647l/TICKS_PER_SEC)
+
+/**************************************************************************
+RFC2131_SLEEP_INTERVAL - sleep for expotentially longer times
+**************************************************************************/
+long
+rfc2131_sleep_interval (int base, int exp)
+{
+  static long seed = 0;
+  long q;
+  unsigned long tmo;
+  
+#ifdef BACKOFF_LIMIT
+  if (exp > BACKOFF_LIMIT)
+    exp = BACKOFF_LIMIT;
+#endif
+  if (!seed)
+    /* Initialize linear congruential generator */
+    seed = (currticks () + *((long *) &arptable[ARP_CLIENT].node)
+	    + ((short *) arptable[ARP_CLIENT].node)[2]);
+  /* simplified version of the LCG given in Bruce Schneier's
+     "Applied Cryptography" */
+  q = seed / 53668;
+  if ((seed = 40014 * (seed - 53668 * q) - 12211 *q ) < 0)
+    seed += 2147483563L;
+  tmo = (base << exp) + (TICKS_PER_SEC - (seed / TWO_SECOND_DIVISOR));
+  return tmo;
+}
+
+/**************************************************************************
+CLEANUP - shut down networking
+**************************************************************************/
+void
+cleanup_net (void)
+{
+  if (network_ready)
+    {
+      /* Stop receiving packets.  */
+      eth_disable ();
+      network_ready = 0;
+    }
+}
diff --git a/netboot/misc.c b/netboot/misc.c
new file mode 100644
index 0000000..28614fd
--- /dev/null
+++ b/netboot/misc.c
@@ -0,0 +1,266 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,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.
+ */
+
+/* Based on "src/misc.c" in etherboot-5.0.5.  */
+
+#define GRUB	1
+#include <etherboot.h>
+
+void
+sleep (int secs)
+{
+  unsigned long tmo = currticks () + secs;
+
+  while (currticks () < tmo)
+    ;
+}
+
+void
+twiddle (void)
+{
+  static unsigned long lastticks = 0;
+  static int count = 0;
+  static const char tiddles[]="-\\|/";
+  unsigned long ticks;
+
+  if (debug)
+    {
+      if ((ticks = currticks ()) == lastticks)
+	return;
+      
+      lastticks = ticks;
+      grub_putchar (tiddles[(count++) & 3]);
+      grub_putchar ('\b');
+    }
+}
+
+/* Because Etherboot uses its own formats for the printf family,
+   define separate definitions from GRUB.  */
+/**************************************************************************
+PRINTF and friends
+
+	Formats:
+		%[#]x	- 4 bytes long (8 hex digits, lower case)
+		%[#]X	- 4 bytes long (8 hex digits, upper case)
+		%[#]hx	- 2 bytes int (4 hex digits, lower case)
+		%[#]hX	- 2 bytes int (4 hex digits, upper case)
+		%[#]hhx	- 1 byte int (2 hex digits, lower case)
+		%[#]hhX	- 1 byte int (2 hex digits, upper case)
+			- optional # prefixes 0x or 0X
+		%d	- decimal int
+		%c	- char
+		%s	- string
+		%@	- Internet address in ddd.ddd.ddd.ddd notation
+		%!	- Ethernet address in xx:xx:xx:xx:xx:xx notation
+	Note: width specification not supported
+**************************************************************************/
+static int
+etherboot_vsprintf (char *buf, const char *fmt, const int *dp)
+{
+  char *p, *s;
+  
+  s = buf;
+  for ( ; *fmt != '\0'; ++fmt)
+    {
+      if (*fmt != '%')
+	{
+	  buf ? *s++ = *fmt : grub_putchar (*fmt);
+	  continue;
+	}
+      
+      if (*++fmt == 's')
+	{
+	  for (p = (char *) *dp++; *p != '\0'; p++)
+	    buf ? *s++ = *p : grub_putchar (*p);
+	}
+      else
+	{
+	  /* Length of item is bounded */
+	  char tmp[20], *q = tmp;
+	  int alt = 0;
+	  int shift = 28;
+	  
+	  if (*fmt == '#')
+	    {
+	      alt = 1;
+	      fmt++;
+	    }
+	  
+	  if (*fmt == 'h')
+	    {
+	      shift = 12;
+	      fmt++;
+	    }
+	  
+	  if (*fmt == 'h')
+	    {
+	      shift = 4;
+	      fmt++;
+	    }
+	  
+	  /*
+	   * Before each format q points to tmp buffer
+	   * After each format q points past end of item
+	   */
+	  if ((*fmt | 0x20) == 'x')
+	    {
+	      /* With x86 gcc, sizeof(long) == sizeof(int) */
+	      const long *lp = (const long *) dp;
+	      long h = *lp++;
+	      int ncase = (*fmt & 0x20);
+	      
+	      dp = (const int *) lp;
+	      if (alt)
+		{
+		  *q++ = '0';
+		  *q++ = 'X' | ncase;
+		}
+	      for (; shift >= 0; shift -= 4)
+		*q++ = "0123456789ABCDEF"[(h >> shift) & 0xF] | ncase;
+	    }
+	  else if (*fmt == 'd')
+	    {
+	      int i = *dp++;
+	      char *r;
+	      
+	      if (i < 0)
+		{
+		  *q++ = '-';
+		  i = -i;
+		}
+	      
+	      p = q;		/* save beginning of digits */
+	      do
+		{
+		  *q++ = '0' + (i % 10);
+		  i /= 10;
+		}
+	      while (i);
+	      
+	      /* reverse digits, stop in middle */
+	      r = q;		/* don't alter q */
+	      while (--r > p)
+		{
+		  i = *r;
+		  *r = *p;
+		  *p++ = i;
+		}
+	    }
+	  else if (*fmt == '@')
+	    {
+	      unsigned char *r;
+	      union
+	      {
+		long		l;
+		unsigned char	c[4];
+	      }
+	      u;
+	      const long *lp = (const long *) dp;
+	      
+	      u.l = *lp++;
+	      dp = (const int *) lp;
+	      
+	      for (r = &u.c[0]; r < &u.c[4]; ++r)
+		q += etherboot_sprintf (q, "%d.", *r);
+	      
+	      --q;
+	    }
+	  else if (*fmt == '!')
+	    {
+	      char *r;
+	      p = (char *) *dp++;
+	      
+	      for (r = p + ETH_ALEN; p < r; ++p)
+		q += etherboot_sprintf (q, "%hhX:", *p);
+	      
+	      --q;
+	    }
+	  else if (*fmt == 'c')
+	    *q++ = *dp++;
+	  else
+	    *q++ = *fmt;
+	  
+	  /* now output the saved string */
+	  for (p = tmp; p < q; ++p)
+	    buf ? *s++ = *p : grub_putchar (*p);
+	}
+    }
+  
+  if (buf)
+    *s = '\0';
+  
+  return (s - buf);
+}
+
+int
+etherboot_sprintf (char *buf, const char *fmt, ...)
+{
+  return etherboot_vsprintf (buf, fmt, ((const int *) &fmt) + 1);
+}
+
+void
+etherboot_printf (const char *fmt, ...)
+{
+  (void) etherboot_vsprintf (0, fmt, ((const int *) &fmt) + 1);
+}
+
+int
+inet_aton (char *p, in_addr *addr)
+{
+  unsigned long ip = 0;
+  int val;
+  int i;
+  
+  for (i = 0; i < 4; i++)
+    {
+      val = getdec (&p);
+      
+      if (val < 0 || val > 255)
+	return 0;
+      
+      if (i != 3 && *p++ != '.')
+	return 0;
+      
+      ip = (ip << 8) | val;
+    }
+
+  addr->s_addr = htonl (ip);
+
+  return 1;
+}
+
+int
+getdec (char **ptr)
+{
+  char *p = *ptr;
+  int ret = 0;
+  
+  if (*p < '0' || *p > '9')
+    return -1;
+  
+  while (*p >= '0' && *p <= '9')
+    {
+      ret = ret * 10 + (*p - '0');
+      p++;
+    }
+  
+  *ptr = p;
+  
+  return ret;
+}
diff --git a/netboot/natsemi.c b/netboot/natsemi.c
new file mode 100644
index 0000000..56ff42d
--- /dev/null
+++ b/netboot/natsemi.c
@@ -0,0 +1,739 @@
+/* -*- Mode:C; c-basic-offset:4; -*- */
+
+/* 
+   natsemi.c: An Etherboot driver for the NatSemi DP8381x series.
+
+   Copyright (C) 2001 Entity Cyber, Inc.
+   
+   This development of this Etherboot driver was funded by 
+   
+      Sicom Systems: http://www.sicompos.com/
+   
+   Author: Marty Connor (mdc@thinguin.org)	   
+   Adapted from a Linux driver which was written by Donald Becker
+   
+   This software may be used and distributed according to the terms
+   of the GNU Public License (GPL), incorporated herein by reference.
+   
+   Original Copyright Notice:
+   
+   Written/copyright 1999-2001 by Donald Becker.
+   
+   This software may be used and distributed according to the terms of
+   the GNU General Public License (GPL), incorporated herein by reference.
+   Drivers based on or derived from this code fall under the GPL and must
+   retain the authorship, copyright and license notice.  This file is not
+   a complete program and may only be used when the entire operating
+   system is licensed under the GPL.  License for under other terms may be
+   available.  Contact the original author for details.
+   
+   The original author may be reached as becker@scyld.com, or at
+   Scyld Computing Corporation
+   410 Severn Ave., Suite 210
+   Annapolis MD 21403
+   
+   Support information and updates available at
+   http://www.scyld.com/network/netsemi.html
+   
+   References:
+   
+   http://www.scyld.com/expert/100mbps.html
+   http://www.scyld.com/expert/NWay.html
+   Datasheet is available from:
+   http://www.national.com/pf/DP/DP83815.html
+
+*/
+
+/* Revision History */
+
+/*
+  29 May 2001  mdc     1.0
+     Initial Release.  Tested with Netgear FA311 and FA312 boards
+*/
+/* Includes */
+
+#include "etherboot.h"
+#include "nic.h"
+#include "pci.h"
+#include "cards.h"
+
+/* defines */
+
+#define OWN       0x80000000
+#define DSIZE     0x00000FFF
+#define CRC_SIZE  4
+
+/* Time in ticks before concluding the transmitter is hung. */
+#define TX_TIMEOUT       (4*TICKS_PER_SEC)
+
+#define TX_BUF_SIZE    1536
+#define RX_BUF_SIZE    1536
+
+#define NUM_RX_DESC    4              /* Number of Rx descriptor registers. */
+
+typedef unsigned char  u8;
+typedef   signed char  s8;
+typedef unsigned short u16;
+typedef   signed short s16;
+typedef unsigned int   u32;
+typedef   signed int   s32;
+
+/* helpful macroes if on a big_endian machine for changing byte order.
+   not strictly needed on Intel */
+#define le16_to_cpu(val) (val)
+#define cpu_to_le32(val) (val)
+#define get_unaligned(ptr) (*(ptr))
+#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
+#define get_u16(ptr) (*(u16 *)(ptr))
+#define virt_to_bus(x) ((unsigned long)x)
+#define virt_to_le32desc(addr)  virt_to_bus(addr)
+
+enum pcistuff {
+    PCI_USES_IO     = 0x01,
+    PCI_USES_MEM    = 0x02,
+    PCI_USES_MASTER = 0x04,
+    PCI_ADDR0       = 0x08,
+    PCI_ADDR1       = 0x10,
+};
+
+/* MMIO operations required */
+#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1)
+
+/* Offsets to the device registers.
+   Unlike software-only systems, device drivers interact with complex hardware.
+   It's not useful to define symbolic names for every register bit in the
+   device.
+*/
+enum register_offsets {
+    ChipCmd      = 0x00, 
+    ChipConfig   = 0x04, 
+    EECtrl       = 0x08, 
+    PCIBusCfg    = 0x0C,
+    IntrStatus   = 0x10, 
+    IntrMask     = 0x14, 
+    IntrEnable   = 0x18,
+    TxRingPtr    = 0x20, 
+    TxConfig     = 0x24,
+    RxRingPtr    = 0x30,
+    RxConfig     = 0x34, 
+    ClkRun       = 0x3C,
+    WOLCmd       = 0x40, 
+    PauseCmd     = 0x44,
+    RxFilterAddr = 0x48, 
+    RxFilterData = 0x4C,
+    BootRomAddr  = 0x50, 
+    BootRomData  = 0x54, 
+    SiliconRev   = 0x58, 
+    StatsCtrl    = 0x5C,
+    StatsData    = 0x60, 
+    RxPktErrs    = 0x60, 
+    RxMissed     = 0x68, 
+    RxCRCErrs    = 0x64,
+    PCIPM        = 0x44,
+    PhyStatus    = 0xC0, 
+    MIntrCtrl    = 0xC4, 
+    MIntrStatus  = 0xC8,
+
+    /* These are from the spec, around page 78... on a separate table. */
+    PGSEL        = 0xCC, 
+    PMDCSR       = 0xE4, 
+    TSTDAT       = 0xFC, 
+    DSPCFG       = 0xF4, 
+    SDCFG        = 0x8C
+};
+
+/* Bit in ChipCmd. */
+enum ChipCmdBits {
+    ChipReset = 0x100, 
+    RxReset   = 0x20, 
+    TxReset   = 0x10, 
+    RxOff     = 0x08, 
+    RxOn      = 0x04,
+    TxOff     = 0x02, 
+    TxOn      = 0x01
+};
+
+/* Bits in the RxMode register. */
+enum rx_mode_bits {
+    AcceptErr          = 0x20,
+    AcceptRunt         = 0x10,
+    AcceptBroadcast    = 0xC0000000,
+    AcceptMulticast    = 0x00200000, 
+    AcceptAllMulticast = 0x20000000,
+    AcceptAllPhys      = 0x10000000, 
+    AcceptMyPhys       = 0x08000000
+};
+
+typedef struct _BufferDesc {
+    u32              link;
+    volatile u32     cmdsts;
+    u32              bufptr;
+    u32				 software_use;
+} BufferDesc;
+
+/* Bits in network_desc.status */
+enum desc_status_bits {
+    DescOwn   = 0x80000000, 
+    DescMore  = 0x40000000, 
+    DescIntr  = 0x20000000,
+    DescNoCRC = 0x10000000,
+    DescPktOK = 0x08000000, 
+    RxTooLong = 0x00400000
+};
+
+/* Globals */
+
+static int natsemi_debug = 1;			/* 1 normal messages, 0 quiet .. 7 verbose. */
+
+const char *nic_name;
+
+static u32 SavedClkRun;
+
+
+static unsigned short vendor, dev_id;
+static unsigned long ioaddr;
+
+static unsigned int cur_rx;
+
+static unsigned int advertising;
+
+static unsigned int rx_config;
+static unsigned int tx_config;
+
+/* Note: transmit and receive buffers and descriptors must be 
+   longword aligned 
+*/
+
+static BufferDesc txd              __attribute__ ((aligned(4)));
+static BufferDesc rxd[NUM_RX_DESC] __attribute__ ((aligned(4)));
+
+#ifdef USE_LOWMEM_BUFFER
+#define txb ((char *)0x10000 - TX_BUF_SIZE)
+#define rxb ((char *)0x10000 - NUM_RX_DESC*RX_BUF_SIZE - TX_BUF_SIZE)
+#else
+static unsigned char txb[TX_BUF_SIZE] __attribute__ ((aligned(4)));
+static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE] __attribute__ ((aligned(4)));
+#endif
+
+/* Function Prototypes */
+
+struct nic *natsemi_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci);
+static int eeprom_read(long addr, int location);
+static int mdio_read(int phy_id, int location);
+static void natsemi_init(struct nic *nic);
+static void natsemi_reset(struct nic *nic);
+static void natsemi_init_rxfilter(struct nic *nic);
+static void natsemi_init_txd(struct nic *nic);
+static void natsemi_init_rxd(struct nic *nic);
+static void natsemi_set_rx_mode(struct nic *nic);
+static void natsemi_check_duplex(struct nic *nic);
+static void natsemi_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p);
+static int  natsemi_poll(struct nic *nic);
+static void natsemi_disable(struct nic *nic);
+
+/* 
+ * Function: natsemi_probe
+ *
+ * Description: Retrieves the MAC address of the card, and sets up some
+ * globals required by other routines,  and initializes the NIC, making it
+ * ready to send and receive packets.
+ *
+ * Side effects:
+ *            leaves the ioaddress of the natsemi chip in the variable ioaddr.
+ *            leaves the natsemi initialized, and ready to recieve packets.
+ *
+ * Returns:   struct nic *:          pointer to NIC data structure
+ */
+
+struct nic *
+natsemi_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci)
+{
+    int i;
+    int prev_eedata;
+    u32 tmp;
+
+    if (io_addrs == 0 || *io_addrs == 0)
+        return NULL;
+
+    /* initialize some commonly used globals */
+	
+    ioaddr     = *io_addrs & ~3;
+    vendor     = pci->vendor;
+    dev_id     = pci->dev_id;
+    nic_name   = pci->name;
+    
+    adjust_pci_device(pci);
+
+    /* natsemi has a non-standard PM control register
+     * in PCI config space.  Some boards apparently need
+     * to be brought to D0 in this manner.
+     */
+    pcibios_read_config_dword(pci->bus, pci->devfn, PCIPM, &tmp);
+    if (tmp & (0x03|0x100)) {
+	/* D0 state, disable PME assertion */
+	u32 newtmp = tmp & ~(0x03|0x100);
+	pcibios_write_config_dword(pci->bus, pci->devfn, PCIPM, newtmp);
+    }
+
+    /* get MAC address */
+
+    prev_eedata = eeprom_read(ioaddr, 6);
+    for (i = 0; i < 3; i++) {
+	int eedata = eeprom_read(ioaddr, i + 7);
+	nic->node_addr[i*2] = (eedata << 1) + (prev_eedata >> 15);
+	nic->node_addr[i*2+1] = eedata >> 7;
+	prev_eedata = eedata;
+    }
+
+    printf("\nnatsemi_probe: MAC addr %! at ioaddr %#hX\n",
+           nic->node_addr, ioaddr);
+    printf("natsemi_probe: Vendor:%#hX Device:%#hX\n", vendor, dev_id);
+    
+    /* Reset the chip to erase any previous misconfiguration. */
+    outl(ChipReset, ioaddr + ChipCmd);
+
+    advertising = mdio_read(1, 4);
+    {
+	u32 chip_config = inl(ioaddr + ChipConfig);
+	printf("%s: Transceiver default autoneg. %s "
+	       "10%s %s duplex.\n",
+	       nic_name,
+	       chip_config & 0x2000 ? "enabled, advertise" : "disabled, force",
+	       chip_config & 0x4000 ? "0" : "",
+	       chip_config & 0x8000 ? "full" : "half");
+    }
+    printf("%s: Transceiver status %hX advertising %hX\n",
+	   nic_name, (int)inl(ioaddr + 0x84), advertising);
+
+    /* Disable PME:
+     * The PME bit is initialized from the EEPROM contents.
+     * PCI cards probably have PME disabled, but motherboard
+     * implementations may have PME set to enable WakeOnLan. 
+     * With PME set the chip will scan incoming packets but
+     * nothing will be written to memory. */
+    SavedClkRun = inl(ioaddr + ClkRun);
+    outl(SavedClkRun & ~0x100, ioaddr + ClkRun);
+
+    /* initialize device */
+    natsemi_init(nic);
+
+    nic->reset    = natsemi_init;
+    nic->poll     = natsemi_poll;
+    nic->transmit = natsemi_transmit;
+    nic->disable  = natsemi_disable;
+
+    return nic;
+}
+
+/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.
+   The EEPROM code is for the common 93c06/46 EEPROMs with 6 bit addresses. 
+*/
+
+/* Delay between EEPROM clock transitions.
+   No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
+   a delay. */
+#define eeprom_delay(ee_addr)	inl(ee_addr)
+
+enum EEPROM_Ctrl_Bits {
+    EE_ShiftClk   = 0x04, 
+    EE_DataIn     = 0x01, 
+    EE_ChipSelect = 0x08, 
+    EE_DataOut    = 0x02
+};
+
+#define EE_Write0 (EE_ChipSelect)
+#define EE_Write1 (EE_ChipSelect | EE_DataIn)
+
+/* The EEPROM commands include the alway-set leading bit. */
+enum EEPROM_Cmds {
+    EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
+};
+
+static int eeprom_read(long addr, int location)
+{
+    int i;
+    int retval = 0;
+    int ee_addr = addr + EECtrl;
+    int read_cmd = location | EE_ReadCmd;
+    outl(EE_Write0, ee_addr);
+
+    /* Shift the read command bits out. */
+    for (i = 10; i >= 0; i--) {
+	short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
+	outl(dataval, ee_addr);
+	eeprom_delay(ee_addr);
+	outl(dataval | EE_ShiftClk, ee_addr);
+	eeprom_delay(ee_addr);
+    }
+    outl(EE_ChipSelect, ee_addr);
+    eeprom_delay(ee_addr);
+
+    for (i = 0; i < 16; i++) {
+	outl(EE_ChipSelect | EE_ShiftClk, ee_addr);
+	eeprom_delay(ee_addr);
+	retval |= (inl(ee_addr) & EE_DataOut) ? 1 << i : 0;
+	outl(EE_ChipSelect, ee_addr);
+	eeprom_delay(ee_addr);
+    }
+
+    /* Terminate the EEPROM access. */
+    outl(EE_Write0, ee_addr);
+    outl(0, ee_addr);
+
+    return retval;
+}
+
+/*  MII transceiver control section.
+	The 83815 series has an internal transceiver, and we present the
+	management registers as if they were MII connected. */
+
+static int mdio_read(int phy_id, int location)
+{
+    if (phy_id == 1 && location < 32)
+	return inl(ioaddr + 0x80 + (location<<2)) & 0xffff;
+    else
+	return 0xffff;
+}
+
+/* Function: natsemi_init
+ *
+ * Description: resets the ethernet controller chip and configures
+ *    registers and data structures required for sending and receiving packets.
+ *    
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * returns:   void.
+ */
+
+static void
+natsemi_init(struct nic *nic)
+{
+    natsemi_reset(nic);
+		
+    /* Disable PME:
+     * The PME bit is initialized from the EEPROM contents.
+     * PCI cards probably have PME disabled, but motherboard
+     * implementations may have PME set to enable WakeOnLan. 
+     * With PME set the chip will scan incoming packets but
+     * nothing will be written to memory. */
+    outl(SavedClkRun & ~0x100, ioaddr + ClkRun);
+
+    natsemi_init_rxfilter(nic);
+
+    natsemi_init_txd(nic);
+    natsemi_init_rxd(nic);
+
+    /* Initialize other registers. */
+    /* Configure the PCI bus bursts and FIFO thresholds. */
+    /* Configure for standard, in-spec Ethernet. */
+    if (inl(ioaddr + ChipConfig) & 0x20000000) {	/* Full duplex */
+	tx_config = 0xD0801002;
+	rx_config = 0x10000020;
+    } else {
+	tx_config = 0x10801002;
+	rx_config = 0x0020;
+    }
+    outl(tx_config, ioaddr + TxConfig);
+    outl(rx_config, ioaddr + RxConfig);
+
+    natsemi_check_duplex(nic);
+    natsemi_set_rx_mode(nic);
+
+    outl(RxOn, ioaddr + ChipCmd);
+}
+
+/* 
+ * Function: natsemi_reset
+ *
+ * Description: soft resets the controller chip
+ *
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * Returns:   void.
+ */
+static void 
+natsemi_reset(struct nic *nic)
+{
+    outl(ChipReset, ioaddr + ChipCmd);
+	
+    /* On page 78 of the spec, they recommend some settings for "optimum
+       performance" to be done in sequence.  These settings optimize some
+       of the 100Mbit autodetection circuitry.  Also, we only want to do
+       this for rev C of the chip.
+    */
+    if (inl(ioaddr + SiliconRev) == 0x302) {
+	outw(0x0001, ioaddr + PGSEL);
+	outw(0x189C, ioaddr + PMDCSR);
+	outw(0x0000, ioaddr + TSTDAT);
+	outw(0x5040, ioaddr + DSPCFG);
+	outw(0x008C, ioaddr + SDCFG);
+    }
+    /* Disable interrupts using the mask. */
+    outl(0, ioaddr + IntrMask);
+    outl(0, ioaddr + IntrEnable);
+}
+
+/* Function: natsemi_init_rxfilter
+ *
+ * Description: sets receive filter address to our MAC address
+ *
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * returns:   void.
+ */
+
+static void
+natsemi_init_rxfilter(struct nic *nic)
+{
+    int i;
+
+    for (i = 0; i < ETH_ALEN; i += 2) {
+	outl(i, ioaddr + RxFilterAddr);
+	outw(nic->node_addr[i] + (nic->node_addr[i+1] << 8), ioaddr + RxFilterData);
+    }
+}
+
+/* 
+ * Function: natsemi_init_txd
+ *
+ * Description: initializes the Tx descriptor
+ *
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * returns:   void.
+ */
+
+static void
+natsemi_init_txd(struct nic *nic)
+{
+    txd.link   = (u32) 0;
+    txd.cmdsts = (u32) 0;
+    txd.bufptr = (u32) &txb[0];
+
+    /* load Transmit Descriptor Register */
+    outl((u32) &txd, ioaddr + TxRingPtr); 
+    if (natsemi_debug > 1)
+        printf("natsemi_init_txd: TX descriptor register loaded with: %X\n", 
+               inl(ioaddr + TxRingPtr));
+}
+
+/* Function: natsemi_init_rxd
+ *
+ * Description: initializes the Rx descriptor ring
+ *    
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * Returns:   void.
+ */
+ 
+static void 
+natsemi_init_rxd(struct nic *nic) 
+{ 
+    int i;
+
+    cur_rx = 0; 
+
+    /* init RX descriptor */
+    for (i = 0; i < NUM_RX_DESC; i++) {
+        rxd[i].link   = (i+1 < NUM_RX_DESC) ? (u32) &rxd[i+1] : (u32) &rxd[0];
+        rxd[i].cmdsts = (u32) RX_BUF_SIZE;
+        rxd[i].bufptr = (u32) &rxb[i*RX_BUF_SIZE];
+        if (natsemi_debug > 1)
+            printf("natsemi_init_rxd: rxd[%d]=%X link=%X cmdsts=%X bufptr=%X\n", 
+                   i, &rxd[i], rxd[i].link, rxd[i].cmdsts, rxd[i].bufptr);
+    }
+
+    /* load Receive Descriptor Register */
+    outl((u32) &rxd[0], ioaddr + RxRingPtr);
+
+    if (natsemi_debug > 1)
+        printf("natsemi_init_rxd: RX descriptor register loaded with: %X\n", 
+               inl(ioaddr + RxRingPtr));
+}
+
+/* Function: natsemi_set_rx_mode
+ *
+ * Description: 
+ *    sets the receive mode to accept all broadcast packets and packets
+ *    with our MAC address, and reject all multicast packets.      
+ *    
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * Returns:   void.
+ */
+
+static void natsemi_set_rx_mode(struct nic *nic)
+{
+    u32 rx_mode = AcceptBroadcast | AcceptMyPhys;
+	
+    outl(rx_mode, ioaddr + RxFilterAddr);
+}
+
+static void natsemi_check_duplex(struct nic *nic)
+{
+    int duplex = inl(ioaddr + ChipConfig) & 0x20000000 ? 1 : 0;
+	
+    if (natsemi_debug)
+	printf("%s: Setting %s-duplex based on negotiated link"
+	       " capability.\n", nic_name,
+	       duplex ? "full" : "half");
+    if (duplex) {
+	rx_config |= 0x10000000;
+	tx_config |= 0xC0000000;
+    } else {
+	rx_config &= ~0x10000000;
+	tx_config &= ~0xC0000000;
+    }
+    outl(tx_config, ioaddr + TxConfig);
+    outl(rx_config, ioaddr + RxConfig);
+}
+
+/* Function: natsemi_transmit
+ *
+ * Description: transmits a packet and waits for completion or timeout.
+ *
+ * Arguments: char d[6]:          destination ethernet address.
+ *            unsigned short t:   ethernet protocol type.
+ *            unsigned short s:   size of the data-part of the packet.
+ *            char *p:            the data for the packet.
+ *    
+ * Returns:   void.
+ */
+
+static void
+natsemi_transmit(struct nic  *nic,
+		 const char  *d,     /* Destination */
+		 unsigned int t,     /* Type */
+		 unsigned int s,     /* size */
+		 const char  *p)     /* Packet */
+{
+    u32 status, to, nstype;
+    u32 tx_status;
+    
+    /* Stop the transmitter */
+    outl(TxOff, ioaddr + ChipCmd);
+
+    /* load Transmit Descriptor Register */
+    outl((u32) &txd, ioaddr + TxRingPtr);
+    if (natsemi_debug > 1)
+        printf("natsemi_transmit: TX descriptor register loaded with: %X\n", 
+               inl(ioaddr + TxRingPtr));
+
+    memcpy(txb, d, ETH_ALEN);
+    memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);
+    nstype = htons(t);
+    memcpy(txb + 2 * ETH_ALEN, (char*)&nstype, 2);
+    memcpy(txb + ETH_HLEN, p, s);
+
+    s += ETH_HLEN;
+    s &= DSIZE;
+
+    if (natsemi_debug > 1)
+        printf("natsemi_transmit: sending %d bytes ethtype %hX\n", (int) s, t);
+
+    /* pad to minimum packet size */
+    while (s < ETH_ZLEN)  
+        txb[s++] = '\0';
+
+    /* set the transmit buffer descriptor and enable Transmit State Machine */
+    txd.bufptr = (u32) &txb[0];
+    txd.cmdsts = (u32) OWN | s;
+
+    /* restart the transmitter */
+    outl(TxOn, ioaddr + ChipCmd);
+
+    if (natsemi_debug > 1)
+        printf("natsemi_transmit: Queued Tx packet size %d.\n", (int) s);
+
+    to = currticks() + TX_TIMEOUT;
+
+    while ((((volatile u32) tx_status=txd.cmdsts) & OWN) && (currticks() < to))
+        /* wait */ ;
+
+    if (currticks() >= to) {
+        printf("natsemi_transmit: TX Timeout! Tx status %X.\n", tx_status);
+    }
+
+    if (!(tx_status & 0x08000000)) {
+	printf("natsemi_transmit: Transmit error, Tx status %X.\n", tx_status);
+    }
+}
+
+/* Function: natsemi_poll
+ *
+ * Description: checks for a received packet and returns it if found.
+ *
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * Returns:   1 if    packet was received.
+ *            0 if no packet was received.
+ *
+ * Side effects:
+ *            Returns (copies) the packet to the array nic->packet.
+ *            Returns the length of the packet in nic->packetlen.
+ */
+
+static int
+natsemi_poll(struct nic *nic)
+{
+    u32 rx_status = rxd[cur_rx].cmdsts;
+    int retstat = 0;
+
+    if (natsemi_debug > 2)
+        printf("natsemi_poll: cur_rx:%d, status:%X\n", cur_rx, rx_status);
+
+    if (!(rx_status & OWN))
+        return retstat;
+
+    if (natsemi_debug > 1)
+        printf("natsemi_poll: got a packet: cur_rx:%d, status:%X\n",
+               cur_rx, rx_status);
+
+    nic->packetlen = (rx_status & DSIZE) - CRC_SIZE;
+
+    if ((rx_status & (DescMore|DescPktOK|RxTooLong)) != DescPktOK) {
+        /* corrupted packet received */
+        printf("natsemi_poll: Corrupted packet received, buffer status = %X\n",
+               rx_status);
+        retstat = 0;
+    } else {
+        /* give packet to higher level routine */
+        memcpy(nic->packet, (rxb + cur_rx*RX_BUF_SIZE), nic->packetlen);
+        retstat = 1;
+    }
+
+    /* return the descriptor and buffer to receive ring */
+    rxd[cur_rx].cmdsts = RX_BUF_SIZE;
+    rxd[cur_rx].bufptr = (u32) &rxb[cur_rx*RX_BUF_SIZE];
+        
+    if (++cur_rx == NUM_RX_DESC)
+        cur_rx = 0;
+
+    /* re-enable the potentially idle receive state machine */
+    outl(RxOn, ioaddr + ChipCmd);
+
+    return retstat;
+}
+
+/* Function: natsemi_disable
+ *
+ * Description: Turns off interrupts and stops Tx and Rx engines
+ *    
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * Returns:   void.
+ */
+
+static void
+natsemi_disable(struct nic *nic)
+{
+    /* Disable interrupts using the mask. */
+    outl(0, ioaddr + IntrMask);
+    outl(0, ioaddr + IntrEnable);
+
+    /* Stop the chip's Tx and Rx processes. */
+    outl(RxOff | TxOff, ioaddr + ChipCmd);
+	
+    /* Restore PME enable bit */
+    outl(SavedClkRun, ioaddr + ClkRun);
+}
diff --git a/netboot/ni5010.c b/netboot/ni5010.c
new file mode 100644
index 0000000..da3827a
--- /dev/null
+++ b/netboot/ni5010.c
@@ -0,0 +1,371 @@
+/**************************************************************************
+Etherboot -  BOOTP/TFTP Bootstrap Program
+Driver for NI5010.
+Code freely taken from Jan-Pascal van Best and Andreas Mohr's
+Linux NI5010 driver.
+***************************************************************************/
+
+/*
+ * 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.
+ */
+
+/* to get some global routines like printf */
+#include "etherboot.h"
+/* to get the interface to the body of the program */
+#include "nic.h"
+/* to get our own prototype */
+#include "cards.h"
+
+/* ni5010.h file included verbatim */
+/*
+ * Racal-Interlan ni5010 Ethernet definitions
+ *
+ * This is an extension to the Linux operating system, and is covered by the
+ * same Gnu Public License that covers that work.
+ *
+ * copyrights (c) 1996 by Jan-Pascal van Best (jvbest@wi.leidenuniv.nl)
+ *
+ * I have done a look in the following sources:
+ *   crynwr-packet-driver by Russ Nelson
+ */
+
+#define NI5010_BUFSIZE	2048	/* number of bytes in a buffer */
+
+#define NI5010_MAGICVAL0 0x00  /* magic-values for ni5010 card */
+#define NI5010_MAGICVAL1 0x55
+#define NI5010_MAGICVAL2 0xAA
+
+#define SA_ADDR0 0x02
+#define SA_ADDR1 0x07
+#define SA_ADDR2 0x01
+
+/* The number of low I/O ports used by the ni5010 ethercard. */
+#define NI5010_IO_EXTENT       32
+
+#define PRINTK(x) if (NI5010_DEBUG) printk x
+#define PRINTK2(x) if (NI5010_DEBUG>=2) printk x
+#define PRINTK3(x) if (NI5010_DEBUG>=3) printk x
+
+/* The various IE command registers */
+#define EDLC_XSTAT	(ioaddr + 0x00)	/* EDLC transmit csr */
+#define EDLC_XCLR	(ioaddr + 0x00)	/* EDLC transmit "Clear IRQ" */
+#define EDLC_XMASK	(ioaddr + 0x01)	/* EDLC transmit "IRQ Masks" */
+#define EDLC_RSTAT	(ioaddr + 0x02)	/* EDLC receive csr */
+#define EDLC_RCLR	(ioaddr + 0x02)	/* EDLC receive "Clear IRQ" */
+#define EDLC_RMASK	(ioaddr + 0x03)	/* EDLC receive "IRQ Masks" */
+#define EDLC_XMODE	(ioaddr + 0x04)	/* EDLC transmit Mode */
+#define EDLC_RMODE	(ioaddr + 0x05)	/* EDLC receive Mode */
+#define EDLC_RESET	(ioaddr + 0x06)	/* EDLC RESET register */
+#define EDLC_TDR1	(ioaddr + 0x07)	/* "Time Domain Reflectometry" reg1 */
+#define EDLC_ADDR	(ioaddr + 0x08)	/* EDLC station address, 6 bytes */
+	 			/* 0x0E doesn't exist for r/w */
+#define EDLC_TDR2	(ioaddr + 0x0f)	/* "Time Domain Reflectometry" reg2 */
+#define IE_GP		(ioaddr + 0x10)	/* GP pointer (word register) */
+				/* 0x11 is 2nd byte of GP Pointer */
+#define IE_RCNT		(ioaddr + 0x10)	/* Count of bytes in rcv'd packet */
+ 				/* 0x11 is 2nd byte of "Byte Count" */
+#define IE_MMODE	(ioaddr + 0x12)	/* Memory Mode register */
+#define IE_DMA_RST	(ioaddr + 0x13)	/* IE DMA Reset.  write only */
+#define IE_ISTAT	(ioaddr + 0x13)	/* IE Interrupt Status.  read only */
+#define IE_RBUF		(ioaddr + 0x14)	/* IE Receive Buffer port */
+#define IE_XBUF		(ioaddr + 0x15)	/* IE Transmit Buffer port */
+#define IE_SAPROM	(ioaddr + 0x16)	/* window on station addr prom */
+#define IE_RESET	(ioaddr + 0x17)	/* any write causes Board Reset */
+
+/* bits in EDLC_XSTAT, interrupt clear on write, status when read */
+#define XS_TPOK		0x80	/* transmit packet successful */
+#define XS_CS		0x40	/* carrier sense */
+#define XS_RCVD		0x20	/* transmitted packet received */
+#define XS_SHORT	0x10	/* transmission media is shorted */
+#define XS_UFLW		0x08	/* underflow.  iff failed board */
+#define XS_COLL		0x04	/* collision occurred */
+#define XS_16COLL	0x02	/* 16th collision occurred */
+#define XS_PERR		0x01	/* parity error */
+
+#define XS_CLR_UFLW	0x08	/* clear underflow */
+#define XS_CLR_COLL	0x04	/* clear collision */
+#define XS_CLR_16COLL	0x02	/* clear 16th collision */
+#define XS_CLR_PERR	0x01	/* clear parity error */
+
+/* bits in EDLC_XMASK, mask/enable transmit interrupts.  register is r/w */
+#define XM_TPOK		0x80	/* =1 to enable Xmt Pkt OK interrupts */
+#define XM_RCVD		0x20	/* =1 to enable Xmt Pkt Rcvd ints */
+#define XM_UFLW		0x08	/* =1 to enable Xmt Underflow ints */
+#define XM_COLL		0x04	/* =1 to enable Xmt Collision ints */
+#define XM_COLL16	0x02	/* =1 to enable Xmt 16th Coll ints */
+#define XM_PERR		0x01	/* =1 to enable Xmt Parity Error ints */
+ 				/* note: always clear this bit */
+#define XM_ALL		(XM_TPOK | XM_RCVD | XM_UFLW | XM_COLL | XM_COLL16)
+
+/* bits in EDLC_RSTAT, interrupt clear on write, status when read */
+#define RS_PKT_OK	0x80	/* received good packet */
+#define RS_RST_PKT	0x10	/* RESET packet received */
+#define RS_RUNT		0x08	/* Runt Pkt rcvd.  Len < 64 Bytes */
+#define RS_ALIGN	0x04	/* Alignment error. not 8 bit aligned */
+#define RS_CRC_ERR	0x02	/* Bad CRC on rcvd pkt */
+#define RS_OFLW		0x01	/* overflow for rcv FIFO */
+#define RS_VALID_BITS	( RS_PKT_OK | RS_RST_PKT | RS_RUNT | RS_ALIGN | RS_CRC_ERR | RS_OFLW )
+ 				/* all valid RSTAT bits */
+
+#define RS_CLR_PKT_OK	0x80	/* clear rcvd packet interrupt */
+#define RS_CLR_RST_PKT	0x10	/* clear RESET packet received */
+#define RS_CLR_RUNT	0x08	/* clear Runt Pckt received */
+#define RS_CLR_ALIGN	0x04	/* clear Alignment error */
+#define RS_CLR_CRC_ERR	0x02	/* clear CRC error */
+#define RS_CLR_OFLW	0x01	/* clear rcv FIFO Overflow */
+
+/* bits in EDLC_RMASK, mask/enable receive interrupts.  register is r/w */
+#define RM_PKT_OK	0x80	/* =1 to enable rcvd good packet ints */
+#define RM_RST_PKT	0x10	/* =1 to enable RESET packet ints */
+#define RM_RUNT		0x08	/* =1 to enable Runt Pkt rcvd ints */
+#define RM_ALIGN	0x04	/* =1 to enable Alignment error ints */
+#define RM_CRC_ERR	0x02	/* =1 to enable Bad CRC error ints */
+#define RM_OFLW		0x01	/* =1 to enable overflow error ints */
+
+/* bits in EDLC_RMODE, set Receive Packet mode.  register is r/w */
+#define RMD_TEST	0x80	/* =1 for Chip testing.  normally 0 */
+#define RMD_ADD_SIZ	0x10	/* =1 5-byte addr match.  normally 0 */
+#define RMD_EN_RUNT	0x08	/* =1 enable runt rcv.  normally 0 */
+#define RMD_EN_RST	0x04	/* =1 to rcv RESET pkt.  normally 0 */
+
+#define RMD_PROMISC	0x03	/* receive *all* packets.  unusual */
+#define RMD_MULTICAST	0x02	/* receive multicasts too.  unusual */
+#define RMD_BROADCAST	0x01	/* receive broadcasts & normal. usual */
+#define RMD_NO_PACKETS	0x00	/* don't receive any packets. unusual */
+
+/* bits in EDLC_XMODE, set Transmit Packet mode.  register is r/w */
+#define XMD_COLL_CNT	0xf0	/* coll's since success.  read-only */
+#define XMD_IG_PAR	0x08	/* =1 to ignore parity.  ALWAYS set */
+#define XMD_T_MODE	0x04	/* =1 to power xcvr. ALWAYS set this */
+#define XMD_LBC		0x02	/* =1 for loopback.  normally set */
+#define XMD_DIS_C	0x01	/* =1 disables contention. normally 0 */
+
+/* bits in EDLC_RESET, write only */
+#define RS_RESET	0x80	/* =1 to hold EDLC in reset state */
+
+/* bits in IE_MMODE, write only */
+#define MM_EN_DMA	0x80	/* =1 begin DMA xfer, Cplt clrs it */
+#define MM_EN_RCV	0x40	/* =1 allows Pkt rcv.  clr'd by rcv */
+#define MM_EN_XMT	0x20	/* =1 begin Xmt pkt.  Cplt clrs it */
+#define MM_BUS_PAGE	0x18	/* =00 ALWAYS.  Used when MUX=1 */
+#define MM_NET_PAGE	0x06	/* =00 ALWAYS.  Used when MUX=0 */
+#define MM_MUX		0x01	/* =1 means Rcv Buff on system bus */
+				/* =0 means Xmt Buff on system bus */
+
+/* bits in IE_ISTAT, read only */
+#define IS_TDIAG	0x80	/* =1 if Diagnostic problem */
+#define IS_EN_RCV	0x20	/* =1 until frame is rcv'd cplt */
+#define IS_EN_XMT	0x10	/* =1 until frame is xmt'd cplt */
+#define IS_EN_DMA	0x08	/* =1 until DMA is cplt or aborted */
+#define IS_DMA_INT	0x04	/* =0 iff DMA done interrupt. */
+#define IS_R_INT	0x02	/* =0 iff unmasked Rcv interrupt */
+#define IS_X_INT	0x01	/* =0 iff unmasked Xmt interrupt */
+
+/* NIC specific static variables go here */
+
+static unsigned short		ioaddr = 0;
+static unsigned int		bufsize_rcv = 0;
+
+#if	0
+static void show_registers(void)
+{
+	printf("XSTAT %hhX ", inb(EDLC_XSTAT));
+	printf("XMASK %hhX ", inb(EDLC_XMASK));
+	printf("RSTAT %hhX ", inb(EDLC_RSTAT));
+	printf("RMASK %hhX ", inb(EDLC_RMASK));
+	printf("RMODE %hhX ", inb(EDLC_RMODE));
+	printf("XMODE %hhX ", inb(EDLC_XMODE));
+	printf("ISTAT %hhX\n", inb(IE_ISTAT));
+}
+#endif
+
+static void reset_receiver(void)
+{
+	outw(0, IE_GP);		/* Receive packet at start of buffer */
+	outb(RS_VALID_BITS, EDLC_RCLR);	/* Clear all pending Rcv interrupts */
+	outb(MM_EN_RCV, IE_MMODE); /* Enable rcv */
+}
+
+/**************************************************************************
+RESET - Reset adapter
+***************************************************************************/
+static void ni5010_reset(struct nic *nic)
+{
+	int		i;
+
+	/* Reset the hardware here.  Don't forget to set the station address. */
+	outb(RS_RESET, EDLC_RESET);	/* Hold up EDLC_RESET while configing board */
+	outb(0, IE_RESET);	/* Hardware reset of ni5010 board */
+	outb(0, EDLC_XMASK);	/* Disable all Xmt interrupts */
+	outb(0, EDLC_RMASK);	/* Disable all Rcv interrupt */
+	outb(0xFF, EDLC_XCLR);	/* Clear all pending Xmt interrupts */
+	outb(0xFF, EDLC_RCLR);	/* Clear all pending Rcv interrupts */
+	outb(XMD_LBC, EDLC_XMODE);	/* Only loopback xmits */
+	/* Set the station address */
+	for(i = 0; i < ETH_ALEN; i++)
+		outb(nic->node_addr[i], EDLC_ADDR + i);
+	outb(XMD_IG_PAR | XMD_T_MODE | XMD_LBC, EDLC_XMODE); 
+				/* Normal packet xmit mode */
+	outb(RMD_BROADCAST, EDLC_RMODE);
+				/* Receive broadcast and normal packets */
+	reset_receiver();
+	outb(0x00, EDLC_RESET);	/* Un-reset the ni5010 */
+}
+
+/**************************************************************************
+POLL - Wait for a frame
+***************************************************************************/
+static int ni5010_poll(struct nic *nic)
+{
+	int		rcv_stat;
+
+	if (((rcv_stat = inb(EDLC_RSTAT)) & RS_VALID_BITS) != RS_PKT_OK) {
+		outb(rcv_stat, EDLC_RSTAT);	/* Clear the status */
+		return (0);
+	}
+        outb(rcv_stat, EDLC_RCLR);	/* Clear the status */
+	nic->packetlen = inw(IE_RCNT);
+	/* Read packet into buffer */
+        outb(MM_MUX, IE_MMODE);	/* Rcv buffer to system bus */
+	outw(0, IE_GP);		/* Seek to beginning of packet */
+	insb(IE_RBUF, nic->packet, nic->packetlen); 
+	return (1);
+}
+
+/**************************************************************************
+TRANSMIT - Transmit a frame
+***************************************************************************/
+static void ni5010_transmit(struct nic *nic,
+	const char *d,	/* Destination */
+	unsigned int t,	/* Type */
+	unsigned int s,	/* size */
+	const char *p)	/* Packet */
+{
+	unsigned int	len;
+	int		buf_offs, xmt_stat;
+	unsigned long	time;
+
+	len = s + ETH_HLEN;
+	if (len < ETH_ZLEN)
+		len = ETH_ZLEN;
+	buf_offs = NI5010_BUFSIZE - len;
+	outb(0, EDLC_RMASK);	/* Mask all receive interrupts */
+	outb(0, IE_MMODE);	/* Put Xmit buffer on system bus */
+	outb(0xFF, EDLC_RCLR);	/* Clear out pending rcv interrupts */
+	outw(buf_offs, IE_GP);	/* Point GP at start of packet */
+	outsb(IE_XBUF, d, ETH_ALEN);	/* Put dst in buffer */
+	outsb(IE_XBUF, nic->node_addr, ETH_ALEN);/* Put src in buffer */
+	outb(t >> 8, IE_XBUF);
+	outb(t, IE_XBUF);
+	outsb(IE_XBUF, p, s);	/* Put data in buffer */
+	while (s++ < ETH_ZLEN - ETH_HLEN)	/* Pad to min size */
+		outb(0, IE_XBUF);
+	outw(buf_offs, IE_GP);	/* Rewrite where packet starts */
+	/* should work without that outb() (Crynwr used it) */
+	/*outb(MM_MUX, IE_MMODE);*/
+	/* Xmt buffer to EDLC bus */
+	outb(MM_EN_XMT | MM_MUX, IE_MMODE);	/* Begin transmission */
+	/* wait for transmit complete */
+	while (((xmt_stat = inb(IE_ISTAT)) & IS_EN_XMT) != 0)
+		;
+	reset_receiver();	/* Immediately switch to receive */
+}
+
+/**************************************************************************
+DISABLE - Turn off ethernet interface
+***************************************************************************/
+static void ni5010_disable(struct nic *nic)
+{
+	outb(0, IE_MMODE);
+	outb(RS_RESET, EDLC_RESET);
+}
+
+static inline int rd_port(void)
+{
+	inb(IE_RBUF);
+	return inb(IE_SAPROM);
+}
+
+static int ni5010_probe1(struct nic *nic)
+{
+	int		i, boguscount = 40, data;
+
+	/* The tests are from the Linux NI5010 driver
+	   I don't understand it all, but if it works for them...  */
+	if (inb(ioaddr) == 0xFF)
+		return (0);
+	while ((rd_port() & rd_port() & rd_port()
+		& rd_port() & rd_port() & rd_port()) != 0xFF)
+	{
+		if (boguscount-- <= 0)
+			return (0);
+	}
+	for (i = 0; i < 32; i++)
+		if ((data = rd_port()) != 0xFF)
+			break;
+	if (data == 0xFF)
+		return (0);
+	if (data == SA_ADDR0 && rd_port() == SA_ADDR1 && rd_port() == SA_ADDR2) {
+		for (i = 0; i < 4; i++)
+			rd_port();
+		if (rd_port() != NI5010_MAGICVAL1 || rd_port() != NI5010_MAGICVAL2)
+			return (0);
+	} else
+		return (0);
+	for (i = 0; i < ETH_ALEN; i++) {
+		outw(i, IE_GP);
+		nic->node_addr[i] = inb(IE_SAPROM);
+	}
+	printf("\nNI5010 ioaddr %#hX, addr %!\n", ioaddr, nic->node_addr);
+/* get the size of the onboard receive buffer
+ * higher addresses than bufsize are wrapped into real buffer
+ * i.e. data for offs. 0x801 is written to 0x1 with a 2K onboard buffer
+ */
+	if (bufsize_rcv == 0) {
+        	outb(1, IE_MMODE);      /* Put Rcv buffer on system bus */
+        	outw(0, IE_GP);		/* Point GP at start of packet */
+        	outb(0, IE_RBUF);	/* set buffer byte 0 to 0 */
+        	for (i = 1; i < 0xFF; i++) {
+                	outw(i << 8, IE_GP); /* Point GP at packet size to be tested */
+                	outb(i, IE_RBUF);
+                	outw(0x0, IE_GP); /* Point GP at start of packet */
+                	data = inb(IE_RBUF);
+                	if (data == i) break;
+        	}
+		bufsize_rcv = i << 8;
+        	outw(0, IE_GP);		/* Point GP at start of packet */
+        	outb(0, IE_RBUF);	/* set buffer byte 0 to 0 again */
+	}
+	printf("Bufsize rcv/xmt=%d/%d\n", bufsize_rcv, NI5010_BUFSIZE);
+	return (1);
+}
+
+/**************************************************************************
+PROBE - Look for an adapter, this routine's visible to the outside
+***************************************************************************/
+struct nic *ni5010_probe(struct nic *nic, unsigned short *probe_addrs)
+{
+	static unsigned short	io_addrs[] = {
+		0x300, 0x320, 0x340, 0x360, 0x380, 0x3a0, 0 };
+	unsigned short		*p;
+
+	/* if probe_addrs is 0, then use list above */
+	if (probe_addrs == 0 || *probe_addrs == 0)
+		probe_addrs = io_addrs;
+	for (p = probe_addrs; (ioaddr = *p) != 0; p++) {
+		if (ni5010_probe1(nic))
+			break;
+	}
+	if (ioaddr == 0)
+		return (0);
+	ni5010_reset(nic);
+	/* point to NIC specific routines */
+	nic->reset = ni5010_reset;
+	nic->poll = ni5010_poll;
+	nic->transmit = ni5010_transmit;
+	nic->disable = ni5010_disable;
+	return (nic);
+}
diff --git a/netboot/nic.h b/netboot/nic.h
new file mode 100644
index 0000000..7a235fb
--- /dev/null
+++ b/netboot/nic.h
@@ -0,0 +1,31 @@
+ /*
+ * 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.
+ */
+
+#ifndef	NIC_H
+#define NIC_H
+
+/*
+ *	Structure returned from eth_probe and passed to other driver
+ *	functions.
+ */
+
+struct nic
+{
+	void		(*reset)P((struct nic *));
+	int		(*poll)P((struct nic *));
+	void		(*transmit)P((struct nic *, const char *d,
+				unsigned int t, unsigned int s, const char *p));
+	void		(*disable)P((struct nic *));
+	int		flags;	/* driver specific flags */
+	struct rom_info	*rom_info;	/* -> rom_info from main */
+	unsigned char	*node_addr;
+	char		*packet;
+	unsigned int	packetlen;
+	void		*priv_data;	/* driver can hang private data here */
+};
+
+#endif	/* NIC_H */
diff --git a/netboot/ns8390.c b/netboot/ns8390.c
new file mode 100644
index 0000000..07ec459
--- /dev/null
+++ b/netboot/ns8390.c
@@ -0,0 +1,835 @@
+/**************************************************************************
+ETHERBOOT -  BOOTP/TFTP Bootstrap Program
+
+Author: Martin Renters
+  Date: May/94
+
+ This code is based heavily on David Greenman's if_ed.c driver
+
+ Copyright (C) 1993-1994, David Greenman, Martin Renters.
+  This software may be used, modified, copied, distributed, and sold, in
+  both source and binary form provided that the above copyright and these
+  terms are retained. Under no circumstances are the authors responsible for
+  the proper functioning of this software, nor do the authors assume any
+  responsibility for damages incurred with its use.
+
+3c503 support added by Bill Paul (wpaul@ctr.columbia.edu) on 11/15/94
+SMC8416 support added by Bill Paul (wpaul@ctr.columbia.edu) on 12/25/94
+3c503 PIO support added by Jim Hague (jim.hague@acm.org) on 2/17/98
+RX overrun by Klaus Espenlaub (espenlaub@informatik.uni-ulm.de) on 3/10/99
+  parts taken from the Linux 8390 driver (by Donald Becker and Paul Gortmaker)
+
+**************************************************************************/
+
+#include "etherboot.h"
+#include "nic.h"
+#include "ns8390.h"
+#ifdef	INCLUDE_NS8390
+#include "pci.h"
+#endif
+#include "cards.h"
+
+static unsigned char	eth_vendor, eth_flags, eth_laar;
+static unsigned short	eth_nic_base, eth_asic_base;
+static unsigned char	eth_memsize, eth_rx_start, eth_tx_start;
+static Address		eth_bmem, eth_rmem;
+static unsigned char	eth_drain_receiver;
+
+#ifdef	INCLUDE_WD
+static struct wd_board {
+	const char *name;
+	char id;
+	char flags;
+	char memsize;
+} wd_boards[] = {
+	{"WD8003S",	TYPE_WD8003S,	0,			MEM_8192},
+	{"WD8003E",	TYPE_WD8003E,	0,			MEM_8192},
+	{"WD8013EBT",	TYPE_WD8013EBT,	FLAG_16BIT,		MEM_16384},
+	{"WD8003W",	TYPE_WD8003W,	0,			MEM_8192},
+	{"WD8003EB",	TYPE_WD8003EB,	0,			MEM_8192},
+	{"WD8013W",	TYPE_WD8013W,	FLAG_16BIT,		MEM_16384},
+	{"WD8003EP/WD8013EP",
+			TYPE_WD8013EP,	0,			MEM_8192},
+	{"WD8013WC",	TYPE_WD8013WC,	FLAG_16BIT,		MEM_16384},
+	{"WD8013EPC",	TYPE_WD8013EPC,	FLAG_16BIT,		MEM_16384},
+	{"SMC8216T",	TYPE_SMC8216T,	FLAG_16BIT | FLAG_790,	MEM_16384},
+	{"SMC8216C",	TYPE_SMC8216C,	FLAG_16BIT | FLAG_790,	MEM_16384},
+	{"SMC8416T",	TYPE_SMC8416T,	FLAG_16BIT | FLAG_790,	MEM_8192},
+	{"SMC8416C/BT",	TYPE_SMC8416C,	FLAG_16BIT | FLAG_790,	MEM_8192},
+	{"SMC8013EBP",	TYPE_SMC8013EBP,FLAG_16BIT,		MEM_16384},
+	{NULL,		0,		0,			0}
+};
+#endif
+
+#ifdef	INCLUDE_3C503
+static unsigned char	t503_output;	/* AUI or internal xcvr (Thinnet) */
+#endif
+
+#if	defined(INCLUDE_WD)
+#define	eth_probe	wd_probe
+#if	defined(INCLUDE_3C503) || defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
+Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
+#endif
+#endif
+
+#if	defined(INCLUDE_3C503)
+#define	eth_probe	t503_probe
+#if	defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || defined(INCLUDE_WD)
+Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
+#endif
+#endif
+
+#if	defined(INCLUDE_NE)
+#define	eth_probe	ne_probe
+#if	defined(INCLUDE_NS8390) || defined(INCLUDE_3C503) || defined(INCLUDE_WD)
+Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
+#endif
+#endif
+
+#if	defined(INCLUDE_NS8390)
+#define	eth_probe	nepci_probe
+#if	defined(INCLUDE_NE) || defined(INCLUDE_3C503) || defined(INCLUDE_WD)
+Error you must only define one of INCLUDE_WD, INCLUDE_3C503, INCLUDE_NE, INCLUDE_NS8390
+#endif
+#endif
+
+#if	defined(INCLUDE_3C503)
+#define	ASIC_PIO	_3COM_RFMSB
+#else
+#if	defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
+#define	ASIC_PIO	NE_DATA
+#endif
+#endif
+
+#if	defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM))
+/**************************************************************************
+ETH_PIO_READ - Read a frame via Programmed I/O
+**************************************************************************/
+static void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt)
+{
+	if (eth_flags & FLAG_16BIT) { ++cnt; cnt &= ~1; }
+	outb(D8390_COMMAND_RD2 |
+		D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
+	outb(cnt, eth_nic_base + D8390_P0_RBCR0);
+	outb(cnt>>8, eth_nic_base + D8390_P0_RBCR1);
+	outb(src, eth_nic_base + D8390_P0_RSAR0);
+	outb(src>>8, eth_nic_base + D8390_P0_RSAR1);
+	outb(D8390_COMMAND_RD0 |
+		D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
+
+#ifdef	INCLUDE_3C503
+	outb(src & 0xff, eth_asic_base + _3COM_DALSB);
+	outb(src >> 8, eth_asic_base + _3COM_DAMSB);
+	outb(t503_output | _3COM_CR_START, eth_asic_base + _3COM_CR);
+#endif
+
+	if (eth_flags & FLAG_16BIT)
+		cnt >>= 1;
+
+	while(cnt--) {
+#ifdef	INCLUDE_3C503
+		while((inb(eth_asic_base + _3COM_STREG) & _3COM_STREG_DPRDY) == 0)
+			;
+#endif
+
+		if (eth_flags & FLAG_16BIT) {
+			*((unsigned short *)dst) = inw(eth_asic_base + ASIC_PIO);
+			dst += 2;
+		}
+		else
+			*(dst++) = inb(eth_asic_base + ASIC_PIO);
+	}
+
+#ifdef	INCLUDE_3C503
+	outb(t503_output, eth_asic_base + _3COM_CR);
+#endif
+}
+
+/**************************************************************************
+ETH_PIO_WRITE - Write a frame via Programmed I/O
+**************************************************************************/
+static void eth_pio_write(const unsigned char *src, unsigned int dst, unsigned int cnt)
+{
+#ifdef	COMPEX_RL2000_FIX
+	unsigned int x;
+#endif	/* COMPEX_RL2000_FIX */
+	if (eth_flags & FLAG_16BIT) { ++cnt; cnt &= ~1; }
+	outb(D8390_COMMAND_RD2 |
+		D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
+	outb(D8390_ISR_RDC, eth_nic_base + D8390_P0_ISR);
+	outb(cnt, eth_nic_base + D8390_P0_RBCR0);
+	outb(cnt>>8, eth_nic_base + D8390_P0_RBCR1);
+	outb(dst, eth_nic_base + D8390_P0_RSAR0);
+	outb(dst>>8, eth_nic_base + D8390_P0_RSAR1);
+	outb(D8390_COMMAND_RD1 |
+		D8390_COMMAND_STA, eth_nic_base + D8390_P0_COMMAND);
+
+#ifdef	INCLUDE_3C503
+	outb(dst & 0xff, eth_asic_base + _3COM_DALSB);
+	outb(dst >> 8, eth_asic_base + _3COM_DAMSB);
+
+	outb(t503_output | _3COM_CR_DDIR | _3COM_CR_START, eth_asic_base + _3COM_CR);
+#endif
+
+	if (eth_flags & FLAG_16BIT)
+		cnt >>= 1;
+
+	while(cnt--)
+	{
+#ifdef	INCLUDE_3C503
+		while((inb(eth_asic_base + _3COM_STREG) & _3COM_STREG_DPRDY) == 0)
+			;
+#endif
+
+		if (eth_flags & FLAG_16BIT) {
+			outw(*((unsigned short *)src), eth_asic_base + ASIC_PIO);
+			src += 2;
+		}
+		else
+			outb(*(src++), eth_asic_base + ASIC_PIO);
+	}
+
+#ifdef	INCLUDE_3C503
+	outb(t503_output, eth_asic_base + _3COM_CR);
+#else
+#ifdef	COMPEX_RL2000_FIX
+	for (x = 0;
+		x < COMPEX_RL2000_TRIES &&
+		(inb(eth_nic_base + D8390_P0_ISR) & D8390_ISR_RDC)
+		!= D8390_ISR_RDC;
+		++x);
+	if (x >= COMPEX_RL2000_TRIES)
+		printf("Warning: Compex RL2000 aborted wait!\n");
+#endif	/* COMPEX_RL2000_FIX */
+	while((inb(eth_nic_base + D8390_P0_ISR) & D8390_ISR_RDC)
+		!= D8390_ISR_RDC);
+#endif
+}
+#else
+/**************************************************************************
+ETH_PIO_READ - Dummy routine when NE2000 not compiled in
+**************************************************************************/
+static void eth_pio_read(unsigned int src, unsigned char *dst, unsigned int cnt) {}
+#endif
+
+/**************************************************************************
+NS8390_RESET - Reset adapter
+**************************************************************************/
+static void ns8390_reset(struct nic *nic)
+{
+	int i;
+
+	eth_drain_receiver = 0;
+#ifdef	INCLUDE_WD
+	if (eth_flags & FLAG_790)
+		outb(D8390_COMMAND_PS0 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
+	else
+#endif
+		outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 |
+			D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
+	if (eth_flags & FLAG_16BIT)
+		outb(0x49, eth_nic_base+D8390_P0_DCR);
+	else
+		outb(0x48, eth_nic_base+D8390_P0_DCR);
+	outb(0, eth_nic_base+D8390_P0_RBCR0);
+	outb(0, eth_nic_base+D8390_P0_RBCR1);
+	outb(0x20, eth_nic_base+D8390_P0_RCR);	/* monitor mode */
+	outb(2, eth_nic_base+D8390_P0_TCR);
+	outb(eth_tx_start, eth_nic_base+D8390_P0_TPSR);
+	outb(eth_rx_start, eth_nic_base+D8390_P0_PSTART);
+#ifdef	INCLUDE_WD
+	if (eth_flags & FLAG_790) outb(0, eth_nic_base + 0x09);
+#endif
+	outb(eth_memsize, eth_nic_base+D8390_P0_PSTOP);
+	outb(eth_memsize - 1, eth_nic_base+D8390_P0_BOUND);
+	outb(0xFF, eth_nic_base+D8390_P0_ISR);
+	outb(0, eth_nic_base+D8390_P0_IMR);
+#ifdef	INCLUDE_WD
+	if (eth_flags & FLAG_790)
+		outb(D8390_COMMAND_PS1 |
+			D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
+	else
+#endif
+		outb(D8390_COMMAND_PS1 |
+			D8390_COMMAND_RD2 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
+	for (i=0; i<ETH_ALEN; i++)
+		outb(nic->node_addr[i], eth_nic_base+D8390_P1_PAR0+i);
+	for (i=0; i<ETH_ALEN; i++)
+		outb(0xFF, eth_nic_base+D8390_P1_MAR0+i);
+	outb(eth_rx_start, eth_nic_base+D8390_P1_CURR);
+#ifdef	INCLUDE_WD
+	if (eth_flags & FLAG_790)
+		outb(D8390_COMMAND_PS0 |
+			D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
+	else
+#endif
+		outb(D8390_COMMAND_PS0 |
+			D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
+	outb(0xFF, eth_nic_base+D8390_P0_ISR);
+	outb(0, eth_nic_base+D8390_P0_TCR);
+	outb(4, eth_nic_base+D8390_P0_RCR);	/* allow broadcast frames */
+
+#ifdef	INCLUDE_3C503
+        /*
+         * No way to tell whether or not we're supposed to use
+         * the 3Com's transceiver unless the user tells us.
+         * 'flags' should have some compile time default value
+         * which can be changed from the command menu.
+         */
+	t503_output = (nic->flags) ? 0 : _3COM_CR_XSEL;
+	outb(t503_output, eth_asic_base + _3COM_CR);
+#endif
+}
+
+static int ns8390_poll(struct nic *nic);
+
+#ifndef	INCLUDE_3C503
+/**************************************************************************
+ETH_RX_OVERRUN - Bring adapter back to work after an RX overrun
+**************************************************************************/
+static void eth_rx_overrun(struct nic *nic)
+{
+	int start_time;
+
+#ifdef	INCLUDE_WD
+	if (eth_flags & FLAG_790)
+		outb(D8390_COMMAND_PS0 | D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
+	else
+#endif
+		outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 |
+			D8390_COMMAND_STP, eth_nic_base+D8390_P0_COMMAND);
+
+	/* wait for at least 1.6ms - we wait one timer tick */
+	start_time = currticks();
+	while (currticks() - start_time <= 1)
+		/* Nothing */;
+
+	outb(0, eth_nic_base+D8390_P0_RBCR0);	/* reset byte counter */
+	outb(0, eth_nic_base+D8390_P0_RBCR1);
+
+	/*
+	 * Linux driver checks for interrupted TX here. This is not necessary,
+	 * because the transmit routine waits until the frame is sent.
+	 */
+
+	/* enter loopback mode and restart NIC */
+	outb(2, eth_nic_base+D8390_P0_TCR);
+#ifdef	INCLUDE_WD
+	if (eth_flags & FLAG_790)
+		outb(D8390_COMMAND_PS0 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
+	else
+#endif
+		outb(D8390_COMMAND_PS0 | D8390_COMMAND_RD2 |
+			D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
+
+	/* clear the RX ring, acknowledge overrun interrupt */
+	eth_drain_receiver = 1;
+	while (ns8390_poll(nic))
+		/* Nothing */;
+	eth_drain_receiver = 0;
+	outb(D8390_ISR_OVW, eth_nic_base+D8390_P0_ISR);
+
+	/* leave loopback mode - no packets to be resent (see Linux driver) */
+	outb(0, eth_nic_base+D8390_P0_TCR);
+}
+#endif	/* INCLUDE_3C503 */
+
+/**************************************************************************
+NS8390_TRANSMIT - Transmit a frame
+**************************************************************************/
+static void ns8390_transmit(
+	struct nic *nic,
+	const char *d,			/* Destination */
+	unsigned int t,			/* Type */
+	unsigned int s,			/* size */
+	const char *p)			/* Packet */
+{
+#ifdef	INCLUDE_3C503
+        if (!(eth_flags & FLAG_PIO)) {
+                memcpy((char *)eth_bmem, d, ETH_ALEN);	/* dst */
+                memcpy((char *)eth_bmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
+                *((char *)eth_bmem+12) = t>>8;		/* type */
+                *((char *)eth_bmem+13) = t;
+                memcpy((char *)eth_bmem+ETH_HLEN, p, s);
+                s += ETH_HLEN;
+                while (s < ETH_ZLEN) *((char *)eth_bmem+(s++)) = 0;
+        }
+#endif
+
+#ifdef	INCLUDE_WD
+	/* Memory interface */
+	if (eth_flags & FLAG_16BIT) {
+		outb(eth_laar | WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
+		inb(0x84);
+	}
+	if (eth_flags & FLAG_790) {
+		outb(WD_MSR_MENB, eth_asic_base + WD_MSR);
+		inb(0x84);
+	}
+	inb(0x84);
+	memcpy((char *)eth_bmem, d, ETH_ALEN);	/* dst */
+	memcpy((char *)eth_bmem+ETH_ALEN, nic->node_addr, ETH_ALEN); /* src */
+	*((char *)eth_bmem+12) = t>>8;		/* type */
+	*((char *)eth_bmem+13) = t;
+	memcpy((char *)eth_bmem+ETH_HLEN, p, s);
+	s += ETH_HLEN;
+	while (s < ETH_ZLEN) *((char *)eth_bmem+(s++)) = 0;
+	if (eth_flags & FLAG_790) {
+		outb(0, eth_asic_base + WD_MSR);
+		inb(0x84);
+	}
+	if (eth_flags & FLAG_16BIT) {
+		outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
+		inb(0x84);
+	}
+#endif
+
+#if	defined(INCLUDE_3C503)
+	if (eth_flags & FLAG_PIO) {
+#endif
+#if	defined(INCLUDE_NE) || defined(INCLUDE_NS8390) || (defined(INCLUDE_3C503) && !defined(T503_SHMEM))
+		/* Programmed I/O */
+		unsigned short type;
+		type = (t >> 8) | (t << 8);
+		eth_pio_write(d, eth_tx_start<<8, ETH_ALEN);
+		eth_pio_write(nic->node_addr, (eth_tx_start<<8)+ETH_ALEN, ETH_ALEN);
+		/* bcc generates worse code without (const+const) below */
+		eth_pio_write((unsigned char *)&type, (eth_tx_start<<8)+(ETH_ALEN+ETH_ALEN), 2);
+		eth_pio_write(p, (eth_tx_start<<8)+ETH_HLEN, s);
+		s += ETH_HLEN;
+		if (s < ETH_ZLEN) s = ETH_ZLEN;
+#endif
+#if	defined(INCLUDE_3C503)
+	}
+#endif
+
+#ifdef	INCLUDE_WD
+	if (eth_flags & FLAG_790)
+		outb(D8390_COMMAND_PS0 |
+			D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
+	else
+#endif
+		outb(D8390_COMMAND_PS0 |
+			D8390_COMMAND_RD2 | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
+	outb(eth_tx_start, eth_nic_base+D8390_P0_TPSR);
+	outb(s, eth_nic_base+D8390_P0_TBCR0);
+	outb(s>>8, eth_nic_base+D8390_P0_TBCR1);
+#ifdef	INCLUDE_WD
+	if (eth_flags & FLAG_790)
+		outb(D8390_COMMAND_PS0 |
+			D8390_COMMAND_TXP | D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
+	else
+#endif
+		outb(D8390_COMMAND_PS0 |
+			D8390_COMMAND_TXP | D8390_COMMAND_RD2 |
+			D8390_COMMAND_STA, eth_nic_base+D8390_P0_COMMAND);
+}
+
+/**************************************************************************
+NS8390_POLL - Wait for a frame
+**************************************************************************/
+static int ns8390_poll(struct nic *nic)
+{
+	int ret = 0;
+	unsigned char rstat, curr, next;
+	unsigned short len, frag;
+	unsigned short pktoff;
+	unsigned char *p;
+	struct ringbuffer pkthdr;
+
+#ifndef	INCLUDE_3C503
+	/* avoid infinite recursion: see eth_rx_overrun() */
+	if (!eth_drain_receiver && (inb(eth_nic_base+D8390_P0_ISR) & D8390_ISR_OVW)) {
+		eth_rx_overrun(nic);
+		return(0);
+	}
+#endif	/* INCLUDE_3C503 */
+	rstat = inb(eth_nic_base+D8390_P0_RSR);
+	if (!(rstat & D8390_RSTAT_PRX)) return(0);
+	next = inb(eth_nic_base+D8390_P0_BOUND)+1;
+	if (next >= eth_memsize) next = eth_rx_start;
+	outb(D8390_COMMAND_PS1, eth_nic_base+D8390_P0_COMMAND);
+	curr = inb(eth_nic_base+D8390_P1_CURR);
+	outb(D8390_COMMAND_PS0, eth_nic_base+D8390_P0_COMMAND);
+	if (curr >= eth_memsize) curr=eth_rx_start;
+	if (curr == next) return(0);
+#ifdef	INCLUDE_WD
+	if (eth_flags & FLAG_16BIT) {
+		outb(eth_laar | WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
+		inb(0x84);
+	}
+	if (eth_flags & FLAG_790) {
+		outb(WD_MSR_MENB, eth_asic_base + WD_MSR);
+		inb(0x84);
+	}
+	inb(0x84);
+#endif
+	pktoff = next << 8;
+	if (eth_flags & FLAG_PIO)
+		eth_pio_read(pktoff, (char *)&pkthdr, 4);
+	else
+		memcpy(&pkthdr, (char *)eth_rmem + pktoff, 4);
+	pktoff += sizeof(pkthdr);
+	/* incoming length includes FCS so must sub 4 */
+	len = pkthdr.len - 4;
+	if ((pkthdr.status & D8390_RSTAT_PRX) == 0 || len < ETH_ZLEN
+		|| len > ETH_FRAME_LEN) {
+		printf("Bogus packet, ignoring\n");
+		return (0);
+	}
+	else {
+		p = nic->packet;
+		nic->packetlen = len;		/* available to caller */
+		frag = (eth_memsize << 8) - pktoff;
+		if (len > frag) {		/* We have a wrap-around */
+			/* read first part */
+			if (eth_flags & FLAG_PIO)
+				eth_pio_read(pktoff, p, frag);
+			else
+				memcpy(p, (char *)eth_rmem + pktoff, frag);
+			pktoff = eth_rx_start << 8;
+			p += frag;
+			len -= frag;
+		}
+		/* read second part */
+		if (eth_flags & FLAG_PIO)
+			eth_pio_read(pktoff, p, len);
+		else
+			memcpy(p, (char *)eth_rmem + pktoff, len);
+		ret = 1;
+	}
+#ifdef	INCLUDE_WD
+	if (eth_flags & FLAG_790) {
+		outb(0, eth_asic_base + WD_MSR);
+		inb(0x84);
+	}
+	if (eth_flags & FLAG_16BIT) {
+		outb(eth_laar & ~WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
+		inb(0x84);
+	}
+	inb(0x84);
+#endif
+	next = pkthdr.next;		/* frame number of next packet */
+	if (next == eth_rx_start)
+		next = eth_memsize;
+	outb(next-1, eth_nic_base+D8390_P0_BOUND);
+	return(ret);
+}
+
+/**************************************************************************
+NS8390_DISABLE - Turn off adapter
+**************************************************************************/
+static void ns8390_disable(struct nic *nic)
+{
+}
+
+/**************************************************************************
+ETH_PROBE - Look for an adapter
+**************************************************************************/
+#ifdef	INCLUDE_NS8390
+struct nic *eth_probe(struct nic *nic, unsigned short *probe_addrs,
+		      struct pci_device *pci)
+#else
+struct nic *eth_probe(struct nic *nic, unsigned short *probe_addrs)
+#endif
+{
+	int i;
+	struct wd_board *brd;
+	unsigned short chksum;
+	unsigned char c;
+	eth_vendor = VENDOR_NONE;
+	eth_drain_receiver = 0;
+
+#ifdef	INCLUDE_WD
+	/******************************************************************
+	Search for WD/SMC cards
+	******************************************************************/
+	for (eth_asic_base = WD_LOW_BASE; eth_asic_base <= WD_HIGH_BASE;
+		eth_asic_base += 0x20) {
+		chksum = 0;
+		for (i=8; i<16; i++)
+			chksum += inb(eth_asic_base+i);
+		/* Extra checks to avoid soundcard */
+		if ((chksum & 0xFF) == 0xFF &&
+			inb(eth_asic_base+8) != 0xFF &&
+			inb(eth_asic_base+9) != 0xFF)
+			break;
+	}
+	if (eth_asic_base > WD_HIGH_BASE)
+		return (0);
+	/* We've found a board */
+	eth_vendor = VENDOR_WD;
+	eth_nic_base = eth_asic_base + WD_NIC_ADDR;
+	c = inb(eth_asic_base+WD_BID);	/* Get board id */
+	for (brd = wd_boards; brd->name; brd++)
+		if (brd->id == c) break;
+	if (!brd->name) {
+		printf("Unknown WD/SMC NIC type %hhX\n", c);
+		return (0);	/* Unknown type */
+	}
+	eth_flags = brd->flags;
+	eth_memsize = brd->memsize;
+	eth_tx_start = 0;
+	eth_rx_start = D8390_TXBUF_SIZE;
+	if ((c == TYPE_WD8013EP) &&
+		(inb(eth_asic_base + WD_ICR) & WD_ICR_16BIT)) {
+			eth_flags = FLAG_16BIT;
+			eth_memsize = MEM_16384;
+	}
+	if ((c & WD_SOFTCONFIG) && (!(eth_flags & FLAG_790))) {
+		eth_bmem = (0x80000 |
+		 ((inb(eth_asic_base + WD_MSR) & 0x3F) << 13));
+	} else
+		eth_bmem = WD_DEFAULT_MEM;
+	if (brd->id == TYPE_SMC8216T || brd->id == TYPE_SMC8216C) {
+		*((unsigned int *)(eth_bmem + 8192)) = (unsigned int)0;
+		if (*((unsigned int *)(eth_bmem + 8192))) {
+			brd += 2;
+			eth_memsize = brd->memsize;
+		}
+	}
+	outb(0x80, eth_asic_base + WD_MSR);	/* Reset */
+	for (i=0; i<ETH_ALEN; i++) {
+		nic->node_addr[i] = inb(i+eth_asic_base+WD_LAR);
+	}
+	printf("\n%s base %#hx, memory %#hx, addr %!\n",
+		brd->name, eth_asic_base, eth_bmem, nic->node_addr);
+	if (eth_flags & FLAG_790) {
+		outb(WD_MSR_MENB, eth_asic_base+WD_MSR);
+		outb((inb(eth_asic_base+0x04) |
+			0x80), eth_asic_base+0x04);
+		outb((((unsigned)eth_bmem >> 13) & 0x0F) |
+			(((unsigned)eth_bmem >> 11) & 0x40) |
+			(inb(eth_asic_base+0x0B) & 0xB0), eth_asic_base+0x0B);
+		outb((inb(eth_asic_base+0x04) &
+			~0x80), eth_asic_base+0x04);
+	} else {
+		outb((((unsigned)eth_bmem >> 13) & 0x3F) | 0x40, eth_asic_base+WD_MSR);
+	}
+	if (eth_flags & FLAG_16BIT) {
+		if (eth_flags & FLAG_790) {
+			eth_laar = inb(eth_asic_base + WD_LAAR);
+			outb(WD_LAAR_M16EN, eth_asic_base + WD_LAAR);
+		} else {
+			outb((eth_laar =
+				WD_LAAR_L16EN | 1), eth_asic_base + WD_LAAR);
+/*
+	The previous line used to be
+				WD_LAAR_M16EN | WD_LAAR_L16EN | 1));
+	jluke@deakin.edu.au reported that removing WD_LAAR_M16EN made
+	it work for WD8013s.  This seems to work for my 8013 boards. I
+	don't know what is really happening.  I wish I had data sheets
+	or more time to decode the Linux driver. - Ken
+*/
+		}
+		inb(0x84);
+	}
+#endif
+#ifdef	INCLUDE_3C503
+        /******************************************************************
+        Search for 3Com 3c503 if no WD/SMC cards
+        ******************************************************************/
+	if (eth_vendor == VENDOR_NONE) {
+		int	idx;
+		int	iobase_reg, membase_reg;
+		static unsigned short	base[] = {
+			0x300, 0x310, 0x330, 0x350,
+			0x250, 0x280, 0x2A0, 0x2E0, 0 };
+
+		/* Loop through possible addresses checking each one */
+
+		for (idx = 0; (eth_nic_base = base[idx]) != 0; ++idx) {
+
+			eth_asic_base = eth_nic_base + _3COM_ASIC_OFFSET;
+/*
+ * Note that we use the same settings for both 8 and 16 bit cards:
+ * both have an 8K bank of memory at page 1 while only the 16 bit
+ * cards have a bank at page 0.
+ */
+			eth_memsize = MEM_16384;
+			eth_tx_start = 32;
+			eth_rx_start = 32 + D8390_TXBUF_SIZE;
+
+		/* Check our base address. iobase and membase should */
+		/* both have a maximum of 1 bit set or be 0. */
+
+			iobase_reg = inb(eth_asic_base + _3COM_BCFR);
+			membase_reg = inb(eth_asic_base + _3COM_PCFR);
+
+			if ((iobase_reg & (iobase_reg - 1)) ||
+				(membase_reg & (membase_reg - 1)))
+				continue;		/* nope */
+
+		/* Now get the shared memory address */
+
+			eth_flags = 0;
+
+			switch (membase_reg) {
+				case _3COM_PCFR_DC000:
+					eth_bmem = 0xdc000;
+					break;
+				case _3COM_PCFR_D8000:
+					eth_bmem = 0xd8000;
+					break;
+				case _3COM_PCFR_CC000:
+					eth_bmem = 0xcc000;
+					break;
+				case _3COM_PCFR_C8000:
+					eth_bmem = 0xc8000;
+					break;
+				case _3COM_PCFR_PIO:
+					eth_flags |= FLAG_PIO;
+					eth_bmem = 0;
+					break;
+				default:
+					continue;	/* nope */
+				}
+			break;
+		}
+
+		if (base[idx] == 0)		/* not found */
+			return (0);
+#ifndef	T503_SHMEM
+		eth_flags |= FLAG_PIO;		/* force PIO mode */
+		eth_bmem = 0;
+#endif
+		eth_vendor = VENDOR_3COM;
+
+
+        /* Need this to make ns8390_poll() happy. */
+
+                eth_rmem = eth_bmem - 0x2000;
+
+        /* Reset NIC and ASIC */
+
+                outb(_3COM_CR_RST | _3COM_CR_XSEL, eth_asic_base + _3COM_CR );
+                outb(_3COM_CR_XSEL, eth_asic_base + _3COM_CR );
+
+        /* Get our ethernet address */
+
+                outb(_3COM_CR_EALO | _3COM_CR_XSEL, eth_asic_base + _3COM_CR);
+                printf("\n3Com 3c503 base %#hx, ", eth_nic_base);
+                if (eth_flags & FLAG_PIO)
+			printf("PIO mode");
+                else
+			printf("memory %#hx", eth_bmem);
+                for (i=0; i<ETH_ALEN; i++) {
+                        nic->node_addr[i] = inb(eth_nic_base+i);
+                }
+                printf(", %s, addr %!\n", nic->flags ? "AUI" : "internal xcvr",
+			nic->node_addr);
+                outb(_3COM_CR_XSEL, eth_asic_base + _3COM_CR);
+        /*
+         * Initialize GA configuration register. Set bank and enable shared
+         * mem. We always use bank 1. Disable interrupts.
+         */
+                outb(_3COM_GACFR_RSEL |
+			_3COM_GACFR_MBS0 | _3COM_GACFR_TCM | _3COM_GACFR_NIM, eth_asic_base + _3COM_GACFR);
+
+                outb(0xff, eth_asic_base + _3COM_VPTR2);
+                outb(0xff, eth_asic_base + _3COM_VPTR1);
+                outb(0x00, eth_asic_base + _3COM_VPTR0);
+        /*
+         * Clear memory and verify that it worked (we use only 8K)
+         */
+
+		if (!(eth_flags & FLAG_PIO)) {
+			memset((char *)eth_bmem, 0, 0x2000);
+			for(i = 0; i < 0x2000; ++i)
+				if (*(((char *)eth_bmem)+i)) {
+					printf ("Failed to clear 3c503 shared mem.\n");
+					return (0);
+				}
+		}
+        /*
+         * Initialize GA page/start/stop registers.
+         */
+                outb(eth_tx_start, eth_asic_base + _3COM_PSTR);
+                outb(eth_memsize, eth_asic_base + _3COM_PSPR);
+        }
+#endif
+#if	defined(INCLUDE_NE) || defined(INCLUDE_NS8390)
+	/******************************************************************
+	Search for NE1000/2000 if no WD/SMC or 3com cards
+	******************************************************************/
+	if (eth_vendor == VENDOR_NONE) {
+		char romdata[16], testbuf[32];
+		int idx;
+		static char test[] = "NE*000 memory";
+		static unsigned short base[] = {
+#ifdef	NE_SCAN
+			NE_SCAN,
+#endif
+			0 };
+		/* if no addresses supplied, fall back on defaults */
+		if (probe_addrs == 0 || probe_addrs[0] == 0)
+			probe_addrs = base;
+		eth_bmem = 0;		/* No shared memory */
+		for (idx = 0; (eth_nic_base = probe_addrs[idx]) != 0; ++idx) {
+			eth_flags = FLAG_PIO;
+			eth_asic_base = eth_nic_base + NE_ASIC_OFFSET;
+			eth_memsize = MEM_16384;
+			eth_tx_start = 32;
+			eth_rx_start = 32 + D8390_TXBUF_SIZE;
+			c = inb(eth_asic_base + NE_RESET);
+			outb(c, eth_asic_base + NE_RESET);
+			inb(0x84);
+			outb(D8390_COMMAND_STP |
+				D8390_COMMAND_RD2, eth_nic_base + D8390_P0_COMMAND);
+			outb(D8390_RCR_MON, eth_nic_base + D8390_P0_RCR);
+			outb(D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR);
+			outb(MEM_8192, eth_nic_base + D8390_P0_PSTART);
+			outb(MEM_16384, eth_nic_base + D8390_P0_PSTOP);
+#ifdef	NS8390_FORCE_16BIT
+			eth_flags |= FLAG_16BIT;	/* force 16-bit mode */
+#endif
+
+			eth_pio_write(test, 8192, sizeof(test));
+			eth_pio_read(8192, testbuf, sizeof(test));
+			if (!memcmp(test, testbuf, sizeof(test)))
+				break;
+			eth_flags |= FLAG_16BIT;
+			eth_memsize = MEM_32768;
+			eth_tx_start = 64;
+			eth_rx_start = 64 + D8390_TXBUF_SIZE;
+			outb(D8390_DCR_WTS |
+				D8390_DCR_FT1 | D8390_DCR_LS, eth_nic_base + D8390_P0_DCR);
+			outb(MEM_16384, eth_nic_base + D8390_P0_PSTART);
+			outb(MEM_32768, eth_nic_base + D8390_P0_PSTOP);
+			eth_pio_write(test, 16384, sizeof(test));
+			eth_pio_read(16384, testbuf, sizeof(test));
+			if (!memcmp(testbuf, test, sizeof(test)))
+				break;
+		}
+		if (eth_nic_base == 0)
+			return (0);
+		if (eth_nic_base > ISA_MAX_ADDR)	/* PCI probably */
+			eth_flags |= FLAG_16BIT;
+		eth_vendor = VENDOR_NOVELL;
+		eth_pio_read(0, romdata, sizeof(romdata));
+		for (i=0; i<ETH_ALEN; i++) {
+			nic->node_addr[i] = romdata[i + ((eth_flags & FLAG_16BIT) ? i : 0)];
+		}
+		printf("\nNE%c000 base %#hx, addr %!\n",
+			(eth_flags & FLAG_16BIT) ? '2' : '1', eth_nic_base,
+			nic->node_addr);
+	}
+#endif
+	if (eth_vendor == VENDOR_NONE)
+		return(0);
+        if (eth_vendor != VENDOR_3COM)
+		eth_rmem = eth_bmem;
+	ns8390_reset(nic);
+	nic->reset = ns8390_reset;
+	nic->poll = ns8390_poll;
+	nic->transmit = ns8390_transmit;
+	nic->disable = ns8390_disable;
+	return(nic);
+}
+
+/*
+ * Local variables:
+ *  c-basic-offset: 8
+ * End:
+ */
+
diff --git a/netboot/ns8390.h b/netboot/ns8390.h
new file mode 100644
index 0000000..2c4e972
--- /dev/null
+++ b/netboot/ns8390.h
@@ -0,0 +1,238 @@
+/**************************************************************************
+ETHERBOOT -  BOOTP/TFTP Bootstrap Program
+
+Author: Martin Renters
+  Date: Jun/94
+
+**************************************************************************/
+
+#define VENDOR_NONE	0
+#define VENDOR_WD	1
+#define VENDOR_NOVELL	2
+#define VENDOR_3COM	3
+
+#define FLAG_PIO	0x01
+#define FLAG_16BIT	0x02
+#define FLAG_790	0x04
+
+#define MEM_8192	32
+#define MEM_16384	64
+#define MEM_32768	128
+
+#define	ISA_MAX_ADDR	0x400
+
+/**************************************************************************
+Western Digital/SMC Board Definitions
+**************************************************************************/
+#define WD_LOW_BASE	0x200
+#define WD_HIGH_BASE	0x3e0
+#ifndef	WD_DEFAULT_MEM
+#define WD_DEFAULT_MEM	0xD0000
+#endif
+#define WD_NIC_ADDR	0x10
+
+/**************************************************************************
+Western Digital/SMC ASIC Addresses
+**************************************************************************/
+#define WD_MSR		0x00
+#define WD_ICR		0x01
+#define WD_IAR		0x02
+#define WD_BIO		0x03
+#define WD_IRR		0x04
+#define WD_LAAR		0x05
+#define WD_IJR		0x06
+#define WD_GP2		0x07
+#define WD_LAR		0x08
+#define WD_BID		0x0E
+
+#define WD_ICR_16BIT	0x01
+
+#define WD_MSR_MENB	0x40
+
+#define WD_LAAR_L16EN	0x40
+#define WD_LAAR_M16EN	0x80
+
+#define WD_SOFTCONFIG	0x20
+
+/**************************************************************************
+Western Digital/SMC Board Types
+**************************************************************************/
+#define TYPE_WD8003S	0x02
+#define TYPE_WD8003E	0x03
+#define TYPE_WD8013EBT	0x05
+#define TYPE_WD8003W	0x24
+#define TYPE_WD8003EB	0x25
+#define TYPE_WD8013W	0x26
+#define TYPE_WD8013EP	0x27
+#define TYPE_WD8013WC	0x28
+#define TYPE_WD8013EPC	0x29
+#define TYPE_SMC8216T	0x2a
+#define TYPE_SMC8216C	0x2b
+#define TYPE_SMC8416T	0x00	/* Bogus entries: the 8416 generates the */
+#define TYPE_SMC8416C	0x00	/* the same codes as the 8216. */
+#define TYPE_SMC8013EBP	0x2c
+
+/**************************************************************************
+3com 3c503 definitions
+**************************************************************************/
+
+#ifndef	_3COM_BASE
+#define _3COM_BASE 0x300
+#endif
+
+#define _3COM_TX_PAGE_OFFSET_8BIT     0x20
+#define _3COM_TX_PAGE_OFFSET_16BIT    0x0
+#define _3COM_RX_PAGE_OFFSET_16BIT    0x20
+
+#define _3COM_ASIC_OFFSET 0x400
+#define _3COM_NIC_OFFSET 0x0
+
+#define _3COM_PSTR            0
+#define _3COM_PSPR            1
+
+#define _3COM_BCFR            3
+#define _3COM_BCFR_2E0        0x01
+#define _3COM_BCFR_2A0        0x02
+#define _3COM_BCFR_280        0x04
+#define _3COM_BCFR_250        0x08
+#define _3COM_BCFR_350        0x10
+#define _3COM_BCFR_330        0x20
+#define _3COM_BCFR_310        0x40
+#define _3COM_BCFR_300        0x80
+#define _3COM_PCFR            4
+#define _3COM_PCFR_PIO        0
+#define _3COM_PCFR_C8000      0x10
+#define _3COM_PCFR_CC000      0x20
+#define _3COM_PCFR_D8000      0x40
+#define _3COM_PCFR_DC000      0x80
+#define _3COM_CR              6
+#define _3COM_CR_RST          0x01    /* Reset GA and NIC */
+#define _3COM_CR_XSEL         0x02    /* Transceiver select. BNC=1(def) AUI=0 */
+#define _3COM_CR_EALO         0x04    /* window EA PROM 0-15 to I/O base */
+#define _3COM_CR_EAHI         0x08    /* window EA PROM 16-31 to I/O base */
+#define _3COM_CR_SHARE        0x10    /* select interrupt sharing option */
+#define _3COM_CR_DBSEL        0x20    /* Double buffer select */
+#define _3COM_CR_DDIR         0x40    /* DMA direction select */
+#define _3COM_CR_START        0x80    /* Start DMA controller */
+#define _3COM_GACFR           5
+#define _3COM_GACFR_MBS0      0x01
+#define _3COM_GACFR_MBS1      0x02
+#define _3COM_GACFR_MBS2      0x04
+#define _3COM_GACFR_RSEL      0x08    /* enable shared memory */
+#define _3COM_GACFR_TEST      0x10    /* for GA testing */
+#define _3COM_GACFR_OWS       0x20    /* select 0WS access to GA */
+#define _3COM_GACFR_TCM       0x40    /* Mask DMA interrupts */
+#define _3COM_GACFR_NIM       0x80    /* Mask NIC interrupts */
+#define _3COM_STREG           7
+#define _3COM_STREG_REV       0x07    /* GA revision */
+#define _3COM_STREG_DIP       0x08    /* DMA in progress */
+#define _3COM_STREG_DTC       0x10    /* DMA terminal count */
+#define _3COM_STREG_OFLW      0x20    /* Overflow */
+#define _3COM_STREG_UFLW      0x40    /* Underflow */
+#define _3COM_STREG_DPRDY     0x80    /* Data port ready */
+#define _3COM_IDCFR           8
+#define _3COM_IDCFR_DRQ0      0x01    /* DMA request 1 select */
+#define _3COM_IDCFR_DRQ1      0x02    /* DMA request 2 select */
+#define _3COM_IDCFR_DRQ2      0x04    /* DMA request 3 select */
+#define _3COM_IDCFR_UNUSED    0x08    /* not used */
+#define _3COM_IDCFR_IRQ2      0x10    /* Interrupt request 2 select */
+#define _3COM_IDCFR_IRQ3      0x20    /* Interrupt request 3 select */
+#define _3COM_IDCFR_IRQ4      0x40    /* Interrupt request 4 select */
+#define _3COM_IDCFR_IRQ5      0x80    /* Interrupt request 5 select */
+#define _3COM_IRQ2      2
+#define _3COM_IRQ3      3
+#define _3COM_IRQ4      4
+#define _3COM_IRQ5      5
+#define _3COM_DAMSB           9
+#define _3COM_DALSB           0x0a
+#define _3COM_VPTR2           0x0b
+#define _3COM_VPTR1           0x0c
+#define _3COM_VPTR0           0x0d
+#define _3COM_RFMSB           0x0e
+#define _3COM_RFLSB           0x0f
+
+/**************************************************************************
+NE1000/2000 definitions
+**************************************************************************/
+#define NE_ASIC_OFFSET	0x10
+#define NE_RESET	0x0F		/* Used to reset card */
+#define NE_DATA		0x00		/* Used to read/write NIC mem */
+
+#define COMPEX_RL2000_TRIES	200
+
+/**************************************************************************
+8390 Register Definitions
+**************************************************************************/
+#define D8390_P0_COMMAND	0x00
+#define D8390_P0_PSTART		0x01
+#define D8390_P0_PSTOP		0x02
+#define D8390_P0_BOUND		0x03
+#define D8390_P0_TSR		0x04
+#define	D8390_P0_TPSR		0x04
+#define D8390_P0_TBCR0		0x05
+#define D8390_P0_TBCR1		0x06
+#define D8390_P0_ISR		0x07
+#define D8390_P0_RSAR0		0x08
+#define D8390_P0_RSAR1		0x09
+#define D8390_P0_RBCR0		0x0A
+#define D8390_P0_RBCR1		0x0B
+#define D8390_P0_RSR		0x0C
+#define D8390_P0_RCR		0x0C
+#define D8390_P0_TCR		0x0D
+#define D8390_P0_DCR		0x0E
+#define D8390_P0_IMR		0x0F
+#define D8390_P1_COMMAND	0x00
+#define D8390_P1_PAR0		0x01
+#define D8390_P1_PAR1		0x02
+#define D8390_P1_PAR2		0x03
+#define D8390_P1_PAR3		0x04
+#define D8390_P1_PAR4		0x05
+#define D8390_P1_PAR5		0x06
+#define D8390_P1_CURR		0x07
+#define D8390_P1_MAR0		0x08
+
+#define D8390_COMMAND_PS0	0x0		/* Page 0 select */
+#define D8390_COMMAND_PS1	0x40		/* Page 1 select */
+#define D8390_COMMAND_PS2	0x80		/* Page 2 select */
+#define	D8390_COMMAND_RD2	0x20		/* Remote DMA control */
+#define D8390_COMMAND_RD1	0x10
+#define D8390_COMMAND_RD0	0x08
+#define D8390_COMMAND_TXP	0x04		/* transmit packet */
+#define D8390_COMMAND_STA	0x02		/* start */
+#define D8390_COMMAND_STP	0x01		/* stop */
+
+#define D8390_RCR_MON		0x20		/* monitor mode */
+
+#define D8390_DCR_FT1		0x40
+#define D8390_DCR_LS		0x08		/* Loopback select */
+#define D8390_DCR_WTS		0x01		/* Word transfer select */
+
+#define D8390_ISR_PRX		0x01		/* successful recv */
+#define D8390_ISR_PTX		0x02		/* successful xmit */
+#define D8390_ISR_RXE		0x04		/* receive error */
+#define D8390_ISR_TXE		0x08		/* transmit error */
+#define D8390_ISR_OVW		0x10		/* Overflow */
+#define D8390_ISR_CNT		0x20		/* Counter overflow */
+#define D8390_ISR_RDC		0x40		/* Remote DMA complete */
+#define D8390_ISR_RST		0x80		/* reset */
+
+#define D8390_RSTAT_PRX		0x01		/* successful recv */
+#define D8390_RSTAT_CRC		0x02		/* CRC error */
+#define D8390_RSTAT_FAE		0x04		/* Frame alignment error */
+#define D8390_RSTAT_OVER	0x08		/* FIFO overrun */
+
+#define D8390_TXBUF_SIZE	6
+#define D8390_RXBUF_END		32
+#define D8390_PAGE_SIZE         256
+
+struct ringbuffer {
+	unsigned char status;
+	unsigned char next;
+	unsigned short len;
+};
+/*
+ * Local variables:
+ *  c-basic-offset: 8
+ * End:
+ */
+
diff --git a/netboot/osdep.h b/netboot/osdep.h
new file mode 100644
index 0000000..57218bf
--- /dev/null
+++ b/netboot/osdep.h
@@ -0,0 +1,94 @@
+#ifndef	__OSDEP_H__
+#define __OSDEP_H__
+
+/*
+ * 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.
+ */
+
+#define	__LITTLE_ENDIAN		/* x86 */
+
+/* Taken from /usr/include/linux/hfs_sysdep.h */
+#if defined(__BIG_ENDIAN)
+#	if !defined(__constant_htonl)
+#		define __constant_htonl(x) (x)
+#	endif
+#	if !defined(__constant_htons)
+#		define __constant_htons(x) (x)
+#	endif
+#elif defined(__LITTLE_ENDIAN)
+#	if !defined(__constant_htonl)
+#		define __constant_htonl(x) \
+        ((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \
+                             (((unsigned long int)(x) & 0x0000ff00U) <<  8) | \
+                             (((unsigned long int)(x) & 0x00ff0000U) >>  8) | \
+                             (((unsigned long int)(x) & 0xff000000U) >> 24)))
+#	endif
+#	if !defined(__constant_htons)
+#		define __constant_htons(x) \
+        ((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
+                              (((unsigned short int)(x) & 0xff00) >> 8)))
+#	endif
+#else
+#	error "Don't know if bytes are big- or little-endian!"
+#endif
+
+#define ntohl(x) \
+(__builtin_constant_p(x) ? \
+ __constant_htonl((x)) : \
+ __swap32(x))
+#define htonl(x) \
+(__builtin_constant_p(x) ? \
+ __constant_htonl((x)) : \
+ __swap32(x))
+#define ntohs(x) \
+(__builtin_constant_p(x) ? \
+ __constant_htons((x)) : \
+ __swap16(x))
+#define htons(x) \
+(__builtin_constant_p(x) ? \
+ __constant_htons((x)) : \
+ __swap16(x))
+
+static inline unsigned long int __swap32(unsigned long int x)
+{
+	__asm__("xchgb %b0,%h0\n\t"
+		"rorl $16,%0\n\t"
+		"xchgb %b0,%h0"
+		: "=q" (x)
+		: "0" (x));
+	return x;
+}
+
+static inline unsigned short int __swap16(unsigned short int x)
+{
+	__asm__("xchgb %b0,%h0"
+		: "=q" (x)
+		: "0" (x));
+	return x;
+}
+
+/* Make routines available to all */
+#define	swap32(x)	__swap32(x)
+#define	swap16(x)	__swap16(x)
+
+#include "linux-asm-io.h"
+
+typedef	unsigned long Address;
+
+/* ANSI prototyping macro */
+#ifdef	__STDC__
+#define	P(x)	x
+#else
+#define	P(x)	()
+#endif
+
+#endif
+
+/*
+ * Local variables:
+ *  c-basic-offset: 8
+ * End:
+ */
diff --git a/netboot/otulip.c b/netboot/otulip.c
new file mode 100644
index 0000000..ea2b19b
--- /dev/null
+++ b/netboot/otulip.c
@@ -0,0 +1,374 @@
+/*
+  Etherboot DEC Tulip driver
+  adapted by Ken Yap from
+
+  FreeBSD netboot DEC 21143 driver
+
+  Author: David Sharp
+    date: Nov/98
+
+ Known to work on DEC DE500 using 21143-PC chipset.
+ Even on cards with the same chipset there can be
+ incompatablity problems with the way media selection
+ and status LED settings are done.  See comments below.
+
+ Some code fragments were taken from verious places,
+ Ken Yap's etherboot, FreeBSD's if_de.c, and various
+ Linux related files.  DEC's manuals for the 21143 and
+ SROM format were very helpful.  The Linux de driver
+ development page has a number of links to useful
+ related information.  Have a look at:
+ ftp://cesdis.gsfc.nasa.gov/pub/linux/drivers/tulip-devel.html
+
+*/
+
+#include "etherboot.h"
+#include "nic.h"
+#include "pci.h"
+#include "cards.h"
+#include "otulip.h"
+
+static unsigned short vendor, dev_id;
+static unsigned short ioaddr;
+static unsigned int *membase;
+static unsigned char srom[1024];
+
+#define BUFLEN 1536     /* must be longword divisable */
+                        /* buffers must be longword aligned */
+
+/* transmit descriptor and buffer */
+static struct txdesc txd;
+
+/* receive descriptor(s) and buffer(s) */
+#define NRXD 4
+static struct rxdesc rxd[NRXD];
+static int rxd_tail = 0;
+#ifdef	USE_LOWMEM_BUFFER
+#define rxb ((char *)0x10000 - NRXD * BUFLEN)
+#define txb ((char *)0x10000 - NRXD * BUFLEN - BUFLEN)
+#else
+static unsigned char rxb[NRXD * BUFLEN];
+static unsigned char txb[BUFLEN];
+#endif
+
+static unsigned char ehdr[ETH_HLEN];    /* buffer for ethernet header */
+
+enum tulip_offsets {
+        CSR0=0,    CSR1=0x08, CSR2=0x10, CSR3=0x18, CSR4=0x20, CSR5=0x28,
+        CSR6=0x30, CSR7=0x38, CSR8=0x40, CSR9=0x48, CSR10=0x50, CSR11=0x58,
+        CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78 };
+
+
+/***************************************************************************/
+/* 21143 specific stuff  */
+/***************************************************************************/
+
+/* XXX assume 33MHz PCI bus,  this is not very accurate and should be
+   used only with gross over estimations of required delay times unless
+   you tune UADJUST to your specific processor and I/O subsystem */
+
+#define UADJUST 870
+static void udelay(unsigned long usec) {
+  unsigned long i;
+  for (i=((usec*UADJUST)/33)+1; i>0; i--) (void) TULIP_CSR_READ(csr_0);
+}
+
+/* The following srom related code was taken from FreeBSD's if_de.c */
+/* with minor alterations to make it work here.  the Linux code is */
+/* better but this was easier to use */
+
+static void delay_300ns(void)
+{
+    int idx;
+    for (idx = (300 / 33) + 1; idx > 0; idx--)
+        (void) TULIP_CSR_READ(csr_busmode);
+}
+
+#define EMIT do { TULIP_CSR_WRITE(csr_srom_mii, csr); delay_300ns(); } while (0)
+
+static void srom_idle(void)
+{
+    unsigned bit, csr;
+
+    csr  = SROMSEL ; EMIT;
+    csr  = SROMSEL | SROMRD; EMIT;
+    csr ^= SROMCS; EMIT;
+    csr ^= SROMCLKON; EMIT;
+    /*
+     * Write 25 cycles of 0 which will force the SROM to be idle.
+     */
+    for (bit = 3 + SROM_BITWIDTH + 16; bit > 0; bit--) {
+        csr ^= SROMCLKOFF; EMIT;    /* clock low; data not valid */
+        csr ^= SROMCLKON; EMIT;     /* clock high; data valid */
+    }
+    csr ^= SROMCLKOFF; EMIT;
+    csr ^= SROMCS; EMIT;
+    csr  = 0; EMIT;
+}
+
+static void srom_read(void)
+{
+    unsigned idx;
+    const unsigned bitwidth = SROM_BITWIDTH;
+    const unsigned cmdmask = (SROMCMD_RD << bitwidth);
+    const unsigned msb = 1 << (bitwidth + 3 - 1);
+    unsigned lastidx = (1 << bitwidth) - 1;
+
+    srom_idle();
+
+    for (idx = 0; idx <= lastidx; idx++) {
+        unsigned lastbit, data, bits, bit, csr;
+        csr  = SROMSEL ;                EMIT;
+        csr  = SROMSEL | SROMRD;        EMIT;
+        csr ^= SROMCSON;                EMIT;
+        csr ^=            SROMCLKON;    EMIT;
+
+        lastbit = 0;
+        for (bits = idx|cmdmask, bit = bitwidth + 3; bit > 0; bit--, bits <<= 1)
+ {
+            const unsigned thisbit = bits & msb;
+            csr ^= SROMCLKOFF; EMIT;    /* clock low; data not valid */
+            if (thisbit != lastbit) {
+                csr ^= SROMDOUT; EMIT;  /* clock low; invert data */
+            } else {
+                EMIT;
+            }
+            csr ^= SROMCLKON; EMIT;     /* clock high; data valid */
+            lastbit = thisbit;
+        }
+        csr ^= SROMCLKOFF; EMIT;
+
+        for (data = 0, bits = 0; bits < 16; bits++) {
+            data <<= 1;
+            csr ^= SROMCLKON; EMIT;     /* clock high; data valid */
+            data |= TULIP_CSR_READ(csr_srom_mii) & SROMDIN ? 1 : 0;
+            csr ^= SROMCLKOFF; EMIT;    /* clock low; data not valid */
+        }
+        srom[idx*2] = data & 0xFF;
+        srom[idx*2+1] = data >> 8;
+        csr  = SROMSEL | SROMRD; EMIT;
+        csr  = 0; EMIT;
+    }
+    srom_idle();
+}
+
+/**************************************************************************
+ETH_RESET - Reset adapter
+***************************************************************************/
+static void tulip_reset(struct nic *nic)
+{
+        int x,cnt=2;
+
+        outl(0x00000001, ioaddr + CSR0);
+        udelay(1000);
+        /* turn off reset and set cache align=16lword, burst=unlimit */
+        outl(0x01A08000, ioaddr + CSR0);
+
+	/* for some reason the media selection does not take
+           the first time se it is repeated.  */
+
+        while(cnt--) {
+        /* stop TX,RX processes */
+        if (cnt == 1)
+		outl(0x32404000, ioaddr + CSR6);
+        else
+		outl(0x32000040, ioaddr + CSR6);
+
+        /* XXX - media selection is vendor specific and hard coded right
+           here.  This should be fixed to use the hints in the SROM and
+           allow media selection by the user at runtime.  MII support
+           should also be added.  Support for chips other than the
+           21143 should be added here as well  */
+
+        /* start  set to 10Mbps half-duplex */
+
+        /* setup SIA */
+        outl(0x0, ioaddr + CSR13);              /* reset SIA */
+        outl(0x7f3f, ioaddr + CSR14);
+        outl(0x8000008, ioaddr + CSR15);
+        outl(0x0, ioaddr + CSR13);
+        outl(0x1, ioaddr + CSR13);
+        outl(0x2404000, ioaddr + CSR6);
+
+        /* initalize GP */
+        outl(0x8af0008, ioaddr + CSR15);
+        outl(0x50008, ioaddr + CSR15);
+
+        /* end  set to 10Mbps half-duplex */
+
+	if (vendor == PCI_VENDOR_ID_MACRONIX && dev_id == PCI_DEVICE_ID_MX987x5) {
+		/* do stuff for MX98715 */
+		outl(0x01a80000, ioaddr + CSR6);
+		outl(0xFFFFFFFF, ioaddr + CSR14);
+		outl(0x00001000, ioaddr + CSR12);
+	}
+
+        outl(0x0, ioaddr + CSR7);       /* disable interrupts */
+
+        /* construct setup packet which is used by the 21143 to
+           program its CAM to recognize interesting MAC addresses */
+
+        memset(&txd, 0, sizeof(struct txdesc));
+        txd.buf1addr = &txb[0];
+        txd.buf2addr = &txb[0];         /* just in case */
+        txd.buf1sz   = 192;             /* setup packet must be 192 bytes */
+        txd.buf2sz   = 0;
+        txd.control  = 0x020;           /* setup packet */
+        txd.status   = 0x80000000;      /* give ownership to 21143 */
+
+        /* construct perfect filter frame */
+        /* with mac address as first match */
+        /* and broadcast address for all others */
+
+        for(x=0;x<192;x++) txb[x] = 0xff;
+        txb[0] = nic->node_addr[0];
+        txb[1] = nic->node_addr[1];
+        txb[4] = nic->node_addr[2];
+        txb[5] = nic->node_addr[3];
+        txb[8] = nic->node_addr[4];
+        txb[9] = nic->node_addr[5];
+        outl((unsigned long)&txd, ioaddr + CSR4);        /* set xmit buf */
+        outl(0x2406000, ioaddr + CSR6);         /* start transmiter */
+
+        udelay(50000);  /* wait for the setup packet to be processed */
+
+        }
+
+        /* setup receive descriptor */
+        {
+          int x;
+          for(x=0;x<NRXD;x++) {
+            memset(&rxd[x], 0, sizeof(struct rxdesc));
+            rxd[x].buf1addr = &rxb[x * BUFLEN];
+            rxd[x].buf2addr = 0;        /* not used */
+            rxd[x].buf1sz   = BUFLEN;
+            rxd[x].buf2sz   = 0;        /* not used */
+            rxd[x].control  = 0x0;
+            rxd[x].status   = 0x80000000;       /* give ownership it to 21143 */
+          }
+          rxd[NRXD - 1].control  = 0x008;       /* Set Receive end of ring on la
+st descriptor */
+          rxd_tail = 0;
+        }
+
+        /* tell DC211XX where to find rx descriptor list */
+        outl((unsigned long)&rxd[0], ioaddr + CSR3);
+        /* start the receiver */
+        outl(0x2406002, ioaddr + CSR6);
+
+}
+
+/**************************************************************************
+ETH_TRANSMIT - Transmit a frame
+***************************************************************************/
+static const char padmap[] = {
+        0, 3, 2, 1};
+
+static void tulip_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
+{
+        unsigned long time;
+
+        /* setup ethernet header */
+
+	memcpy(ehdr, d, ETH_ALEN);
+	memcpy(&ehdr[ETH_ALEN], nic->node_addr, ETH_ALEN);
+        ehdr[ETH_ALEN*2] = (t >> 8) & 0xff;
+        ehdr[ETH_ALEN*2+1] = t & 0xff;
+
+        /* setup the transmit descriptor */
+
+        memset(&txd, 0, sizeof(struct txdesc));
+
+        txd.buf1addr = &ehdr[0];        /* ethernet header */
+        txd.buf1sz   = ETH_HLEN;
+
+        txd.buf2addr = p;               /* packet to transmit */
+        txd.buf2sz   = s;
+
+        txd.control  = 0x188;           /* LS+FS+TER */
+
+        txd.status   = 0x80000000;      /* give it to 21143 */
+
+        outl(inl(ioaddr + CSR6) & ~0x00004000, ioaddr + CSR6);
+        outl((unsigned long)&txd, ioaddr + CSR4);
+        outl(inl(ioaddr + CSR6) | 0x00004000, ioaddr + CSR6);
+
+/*   Wait for transmit to complete before returning.  not well tested.
+
+        time = currticks();
+        while(txd.status & 0x80000000) {
+          if (currticks() - time > 20) {
+            printf("transmit timeout.\n");
+            break;
+          }
+        }
+*/
+
+}
+
+/**************************************************************************
+ETH_POLL - Wait for a frame
+***************************************************************************/
+static int tulip_poll(struct nic *nic)
+{
+        if (rxd[rxd_tail].status & 0x80000000) return 0;
+
+        nic->packetlen = (rxd[rxd_tail].status & 0x3FFF0000) >> 16;
+
+        /* copy packet to working buffer */
+        /* XXX - this copy could be avoided with a little more work
+           but for now we are content with it because the optimised
+           memcpy(, , ) is quite fast */
+
+        memcpy(nic->packet, rxb + rxd_tail * BUFLEN, nic->packetlen);
+
+        /* return the descriptor and buffer to recieve ring */
+        rxd[rxd_tail].status = 0x80000000;
+        rxd_tail++;
+        if (rxd_tail == NRXD) rxd_tail = 0;
+
+        return 1;
+}
+
+static void tulip_disable(struct nic *nic)
+{
+	/* nothing for the moment */
+}
+
+/**************************************************************************
+ETH_PROBE - Look for an adapter
+***************************************************************************/
+struct nic *otulip_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci)
+{
+        int i;
+
+	if (io_addrs == 0 || *io_addrs == 0)
+		return (0);
+	vendor = pci->vendor;
+	dev_id = pci->dev_id;
+	ioaddr = *io_addrs;
+	membase = (unsigned int *)pci->membase;
+
+        /* wakeup chip */
+        pcibios_write_config_dword(pci->bus,pci->devfn,0x40,0x00000000);
+
+        /* Stop the chip's Tx and Rx processes. */
+        /* outl(inl(ioaddr + CSR6) & ~0x2002, ioaddr + CSR6); */
+        /* Clear the missed-packet counter. */
+        /* (volatile int)inl(ioaddr + CSR8); */
+
+        srom_read();
+
+	for (i=0; i < ETH_ALEN; i++)
+		nic->node_addr[i] = srom[20+i];
+
+        printf("Tulip %! at ioaddr %#hX\n", nic->node_addr, ioaddr);
+
+        tulip_reset(nic);
+
+	nic->reset = tulip_reset;
+	nic->poll = tulip_poll;
+	nic->transmit = tulip_transmit;
+	nic->disable = tulip_disable;
+        return nic;
+}
diff --git a/netboot/otulip.h b/netboot/otulip.h
new file mode 100644
index 0000000..0e1aa90
--- /dev/null
+++ b/netboot/otulip.h
@@ -0,0 +1,76 @@
+/* mostly stolen from FreeBSD if_de.c, if_devar.h */
+
+#define TULIP_CSR_READ(csr)		(membase[csr*2])
+#define CSR_READ(csr)			(membase[csr*2])
+#define TULIP_CSR_WRITE(csr, val)	(membase[csr*2] = val)
+#define CSR_WRITE(csr, val)		(membase[csr*2] = val)
+
+#define csr_0			0
+#define csr_1			1
+#define csr_2			2
+#define csr_3			3
+#define csr_4			4
+#define csr_5			5
+#define csr_6			6
+#define csr_7			7
+#define csr_8			8
+#define csr_9			9
+#define csr_10			10
+#define csr_11			11
+#define csr_12			12
+#define csr_13			13
+#define csr_14			14
+#define csr_15			15
+
+#define csr_busmode		csr_0
+#define csr_txpoll		csr_1
+#define csr_rxpoll		csr_2
+#define csr_rxlist		csr_3
+#define csr_txlist		csr_4
+#define csr_status		csr_5
+#define csr_command		csr_6
+#define csr_intr		csr_7
+#define csr_missed_frames	csr_8
+#define csr_enetrom		csr_9		/* 21040 */
+#define csr_reserved		csr_10		/* 21040 */
+#define csr_full_duplex		csr_11		/* 21040 */
+#define csr_bootrom		csr_10		/* 21041/21140A/?? */
+#define csr_gp			csr_12		/* 21140* */
+#define csr_watchdog		csr_15		/* 21140* */
+#define csr_gp_timer		csr_11		/* 21041/21140* */
+#define csr_srom_mii		csr_9		/* 21041/21140* */
+#define csr_sia_status		csr_12		/* 2104x */
+#define csr_sia_connectivity	csr_13		/* 2104x */
+#define csr_sia_tx_rx		csr_14		/* 2104x */
+#define csr_sia_general		csr_15		/* 2104x */
+
+#define SROMSEL		0x0800
+#define SROMCS		0x0001
+#define SROMCLKON	0x0002
+#define SROMCLKOFF	0x0002
+#define SROMRD		0x4000
+#define SROMWR		0x2000
+#define SROM_BITWIDTH	6
+#define SROMCMD_RD	6
+#define SROMCSON	0x0001
+#define SROMDOUT	0x0004
+#define SROMDIN		0x0008
+
+
+struct txdesc {
+	unsigned long	status;		/* owner, status */
+	unsigned long	buf1sz:11,	/* size of buffer 1 */
+			buf2sz:11,	/* size of buffer 2 */
+			control:10;	/* control bits */
+	const unsigned char *buf1addr;	/* buffer 1 address */
+	const unsigned char *buf2addr;	/* buffer 2 address */
+};
+
+struct rxdesc {
+	unsigned long	status;		/* owner, status */
+	unsigned long	buf1sz:11,	/* size of buffer 1 */
+			buf2sz:11,	/* size of buffer 2 */
+			control:10;	/* control bits */
+	unsigned char	*buf1addr;	/* buffer 1 address */
+	unsigned char	*buf2addr;	/* buffer 2 address */
+};
diff --git a/netboot/pci.c b/netboot/pci.c
new file mode 100644
index 0000000..471c856
--- /dev/null
+++ b/netboot/pci.c
@@ -0,0 +1,501 @@
+/*
+** Support for NE2000 PCI clones added David Monro June 1997
+** Generalised to other NICs by Ken Yap July 1997
+**
+** Most of this is taken from:
+**
+** /usr/src/linux/drivers/pci/pci.c
+** /usr/src/linux/include/linux/pci.h
+** /usr/src/linux/arch/i386/bios32.c
+** /usr/src/linux/include/linux/bios32.h
+** /usr/src/linux/drivers/net/ne.c
+*/
+
+/*
+ * 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.
+ */
+
+#include "etherboot.h"
+#include "pci.h"
+
+/*#define	DEBUG	1*/
+#define DEBUG	0
+
+#ifdef	CONFIG_PCI_DIRECT
+#define  PCIBIOS_SUCCESSFUL                0x00
+
+/*
+ * Functions for accessing PCI configuration space with type 1 accesses
+ */
+
+#define CONFIG_CMD(bus, device_fn, where)   (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3))
+
+int pcibios_read_config_byte(unsigned int bus, unsigned int device_fn,
+			       unsigned int where, unsigned char *value)
+{
+    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
+    *value = inb(0xCFC + (where&3));
+    return PCIBIOS_SUCCESSFUL;
+}
+
+int pcibios_read_config_word (unsigned int bus,
+    unsigned int device_fn, unsigned int where, unsigned short *value)
+{
+    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
+    *value = inw(0xCFC + (where&2));
+    return PCIBIOS_SUCCESSFUL;
+}
+
+int pcibios_read_config_dword (unsigned int bus, unsigned int device_fn,
+				 unsigned int where, unsigned int *value)
+{
+    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
+    *value = inl(0xCFC);
+    return PCIBIOS_SUCCESSFUL;
+}
+
+int pcibios_write_config_byte (unsigned int bus, unsigned int device_fn,
+				 unsigned int where, unsigned char value)
+{
+    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
+    outb(value, 0xCFC + (where&3));
+    return PCIBIOS_SUCCESSFUL;
+}
+
+int pcibios_write_config_word (unsigned int bus, unsigned int device_fn,
+				 unsigned int where, unsigned short value)
+{
+    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
+    outw(value, 0xCFC + (where&2));
+    return PCIBIOS_SUCCESSFUL;
+}
+
+int pcibios_write_config_dword (unsigned int bus, unsigned int device_fn, unsigned int where, unsigned int value)
+{
+    outl(CONFIG_CMD(bus,device_fn,where), 0xCF8);
+    outl(value, 0xCFC);
+    return PCIBIOS_SUCCESSFUL;
+}
+
+#undef CONFIG_CMD
+
+#else	 /* CONFIG_PCI_DIRECT  not defined */
+
+static struct {
+	unsigned long address;
+	unsigned short segment;
+} bios32_indirect = { 0, KERN_CODE_SEG };
+
+static long pcibios_entry;
+static struct {
+	unsigned long address;
+	unsigned short segment;
+} pci_indirect = { 0, KERN_CODE_SEG };
+
+static unsigned long bios32_service(unsigned long service)
+{
+	unsigned char return_code;	/* %al */
+	unsigned long address;		/* %ebx */
+	unsigned long length;		/* %ecx */
+	unsigned long entry;		/* %edx */
+	unsigned long flags;
+
+	save_flags(flags);
+	__asm__(
+#ifdef ABSOLUTE_WITHOUT_ASTERISK
+		"lcall (%%edi)"
+#else
+		"lcall *(%%edi)"
+#endif
+		: "=a" (return_code),
+		  "=b" (address),
+		  "=c" (length),
+		  "=d" (entry)
+		: "0" (service),
+		  "1" (0),
+		  "D" (&bios32_indirect));
+	restore_flags(flags);
+
+	switch (return_code) {
+		case 0:
+			return address + entry;
+		case 0x80:	/* Not present */
+			printf("bios32_service(%d) : not present\n", service);
+			return 0;
+		default: /* Shouldn't happen */
+			printf("bios32_service(%d) : returned %#X, mail drew@colorado.edu\n",
+				service, return_code);
+			return 0;
+	}
+}
+
+int pcibios_read_config_byte(unsigned int bus,
+        unsigned int device_fn, unsigned int where, unsigned char *value)
+{
+        unsigned long ret;
+        unsigned long bx = (bus << 8) | device_fn;
+        unsigned long flags;
+
+        save_flags(flags);
+        __asm__(
+#ifdef ABSOLUTE_WITHOUT_ASTERISK
+		"lcall (%%esi)\n\t"
+#else
+		"lcall *(%%esi)\n\t"
+#endif
+                "jc 1f\n\t"
+                "xor %%ah, %%ah\n"
+                "1:"
+                : "=c" (*value),
+                  "=a" (ret)
+                : "1" (PCIBIOS_READ_CONFIG_BYTE),
+                  "b" (bx),
+                  "D" ((long) where),
+                  "S" (&pci_indirect));
+        restore_flags(flags);
+        return (int) (ret & 0xff00) >> 8;
+}
+
+int pcibios_read_config_word(unsigned int bus,
+        unsigned int device_fn, unsigned int where, unsigned short *value)
+{
+        unsigned long ret;
+        unsigned long bx = (bus << 8) | device_fn;
+        unsigned long flags;
+
+        save_flags(flags);
+        __asm__(
+#ifdef ABSOLUTE_WITHOUT_ASTERISK
+		"lcall (%%esi)\n\t"
+#else
+		"lcall *(%%esi)\n\t"
+#endif
+                "jc 1f\n\t"
+                "xor %%ah, %%ah\n"
+                "1:"
+                : "=c" (*value),
+                  "=a" (ret)
+                : "1" (PCIBIOS_READ_CONFIG_WORD),
+                  "b" (bx),
+                  "D" ((long) where),
+                  "S" (&pci_indirect));
+        restore_flags(flags);
+        return (int) (ret & 0xff00) >> 8;
+}
+
+int pcibios_read_config_dword(unsigned int bus,
+        unsigned int device_fn, unsigned int where, unsigned int *value)
+{
+        unsigned long ret;
+        unsigned long bx = (bus << 8) | device_fn;
+        unsigned long flags;
+
+        save_flags(flags);
+        __asm__(
+#ifdef ABSOLUTE_WITHOUT_ASTERISK
+		"lcall (%%esi)\n\t"
+#else
+		"lcall *(%%esi)\n\t"
+#endif
+                "jc 1f\n\t"
+                "xor %%ah, %%ah\n"
+                "1:"
+                : "=c" (*value),
+                  "=a" (ret)
+                : "1" (PCIBIOS_READ_CONFIG_DWORD),
+                  "b" (bx),
+                  "D" ((long) where),
+                  "S" (&pci_indirect));
+        restore_flags(flags);
+        return (int) (ret & 0xff00) >> 8;
+}
+
+int pcibios_write_config_byte (unsigned int bus,
+	unsigned int device_fn, unsigned int where, unsigned char value)
+{
+	unsigned long ret;
+	unsigned long bx = (bus << 8) | device_fn;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	__asm__(
+#ifdef ABSOLUTE_WITHOUT_ASTERISK
+		"lcall (%%esi)\n\t"
+#else
+		"lcall *(%%esi)\n\t"
+#endif
+		"jc 1f\n\t"
+		"xor %%ah, %%ah\n"
+		"1:"
+		: "=a" (ret)
+		: "0" (PCIBIOS_WRITE_CONFIG_BYTE),
+		  "c" (value),
+		  "b" (bx),
+		  "D" ((long) where),
+		  "S" (&pci_indirect));
+	restore_flags(flags);
+	return (int) (ret & 0xff00) >> 8;
+}
+
+int pcibios_write_config_word (unsigned int bus,
+	unsigned int device_fn, unsigned int where, unsigned short value)
+{
+	unsigned long ret;
+	unsigned long bx = (bus << 8) | device_fn;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	__asm__(
+#ifdef ABSOLUTE_WITHOUT_ASTERISK
+		"lcall (%%esi)\n\t"
+#else
+		"lcall *(%%esi)\n\t"
+#endif
+		"jc 1f\n\t"
+		"xor %%ah, %%ah\n"
+		"1:"
+		: "=a" (ret)
+		: "0" (PCIBIOS_WRITE_CONFIG_WORD),
+		  "c" (value),
+		  "b" (bx),
+		  "D" ((long) where),
+		  "S" (&pci_indirect));
+	restore_flags(flags);
+	return (int) (ret & 0xff00) >> 8;
+}
+
+int pcibios_write_config_dword (unsigned int bus,
+	unsigned int device_fn, unsigned int where, unsigned int value)
+{
+	unsigned long ret;
+	unsigned long bx = (bus << 8) | device_fn;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	__asm__(
+#ifdef ABSOLUTE_WITHOUT_ASTERISK
+		"lcall (%%esi)\n\t"
+#else
+		"lcall *(%%esi)\n\t"
+#endif
+		"jc 1f\n\t"
+		"xor %%ah, %%ah\n"
+		"1:"
+		: "=a" (ret)
+		: "0" (PCIBIOS_WRITE_CONFIG_DWORD),
+		  "c" (value),
+		  "b" (bx),
+		  "D" ((long) where),
+		  "S" (&pci_indirect));
+	restore_flags(flags);
+	return (int) (ret & 0xff00) >> 8;
+}
+
+static void check_pcibios(void)
+{
+	unsigned long signature;
+	unsigned char present_status;
+	unsigned char major_revision;
+	unsigned char minor_revision;
+	unsigned long flags;
+	int pack;
+
+	if ((pcibios_entry = bios32_service(PCI_SERVICE))) {
+		pci_indirect.address = pcibios_entry;
+
+		save_flags(flags);
+		__asm__(
+#ifdef ABSOLUTE_WITHOUT_ASTERISK
+			"lcall (%%edi)\n\t"
+#else
+			"lcall *(%%edi)\n\t"
+#endif
+			"jc 1f\n\t"
+			"xor %%ah, %%ah\n"
+			"1:\tshl $8, %%eax\n\t"
+			"movw %%bx, %%ax"
+			: "=d" (signature),
+			  "=a" (pack)
+			: "1" (PCIBIOS_PCI_BIOS_PRESENT),
+			  "D" (&pci_indirect)
+			: "bx", "cx");
+		restore_flags(flags);
+
+		present_status = (pack >> 16) & 0xff;
+		major_revision = (pack >> 8) & 0xff;
+		minor_revision = pack & 0xff;
+		if (present_status || (signature != PCI_SIGNATURE)) {
+			printf("ERROR: BIOS32 says PCI BIOS, but no PCI "
+				"BIOS????\n");
+			pcibios_entry = 0;
+		}
+#if	DEBUG
+		if (pcibios_entry) {
+			printf ("pcibios_init : PCI BIOS revision %hhX.%hhX"
+				" entry at %#X\n", major_revision,
+				minor_revision, pcibios_entry);
+		}
+#endif
+	}
+}
+
+static void pcibios_init(void)
+{
+	union bios32 *check;
+	unsigned char sum;
+	int i, length;
+	unsigned long bios32_entry = 0;
+
+	/*
+	 * Follow the standard procedure for locating the BIOS32 Service
+	 * directory by scanning the permissible address range from
+	 * 0xe0000 through 0xfffff for a valid BIOS32 structure.
+	 *
+	 */
+
+	for (check = (union bios32 *) 0xe0000; check <= (union bios32 *) 0xffff0; ++check) {
+		if (check->fields.signature != BIOS32_SIGNATURE)
+			continue;
+		length = check->fields.length * 16;
+		if (!length)
+			continue;
+		sum = 0;
+		for (i = 0; i < length ; ++i)
+			sum += check->chars[i];
+		if (sum != 0)
+			continue;
+		if (check->fields.revision != 0) {
+			printf("pcibios_init : unsupported revision %d at %#X, mail drew@colorado.edu\n",
+				check->fields.revision, check);
+			continue;
+		}
+#if	DEBUG
+		printf("pcibios_init : BIOS32 Service Directory "
+			"structure at %#X\n", check);
+#endif
+		if (!bios32_entry) {
+			if (check->fields.entry >= 0x100000) {
+				printf("pcibios_init: entry in high "
+					"memory, giving up\n");
+				return;
+			} else {
+				bios32_entry = check->fields.entry;
+#if	DEBUG
+				printf("pcibios_init : BIOS32 Service Directory"
+					" entry at %#X\n", bios32_entry);
+#endif
+				bios32_indirect.address = bios32_entry;
+			}
+		}
+	}
+	if (bios32_entry)
+		check_pcibios();
+}
+#endif	/* CONFIG_PCI_DIRECT not defined*/
+
+static void scan_bus(struct pci_device *pcidev)
+{
+	unsigned int devfn, l, bus, buses;
+	unsigned char hdr_type = 0;
+	unsigned short vendor, device;
+	unsigned int membase, ioaddr, romaddr;
+	int i, reg;
+	unsigned int pci_ioaddr = 0;
+
+	/* Scan all PCI buses, until we find our card.
+	 * We could be smart only scan the required busses but that
+	 * is error prone, and tricky.
+	 * By scanning all possible pci busses in order we should find
+	 * our card eventually. 
+	 */
+	buses=256;
+	for (bus = 0; bus < buses; ++bus) {
+		for (devfn = 0; devfn < 0xff; ++devfn) {
+			if (PCI_FUNC (devfn) == 0)
+				pcibios_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type);
+			else if (!(hdr_type & 0x80))	/* not a multi-function device */
+				continue;
+			pcibios_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l);
+			/* some broken boards return 0 if a slot is empty: */
+			if (l == 0xffffffff || l == 0x00000000) {
+				hdr_type = 0;
+				continue;
+			}
+			vendor = l & 0xffff;
+			device = (l >> 16) & 0xffff;
+
+#if	DEBUG
+			printf("bus %hhX, function %hhX, vendor %hX, device %hX\n",
+				bus, devfn, vendor, device);
+#endif
+			for (i = 0; pcidev[i].vendor != 0; i++) {
+				if (vendor != pcidev[i].vendor
+				    || device != pcidev[i].dev_id)
+					continue;
+				pcidev[i].devfn = devfn;
+				pcidev[i].bus = bus;
+				for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
+					pcibios_read_config_dword(bus, devfn, reg, &ioaddr);
+
+					if ((ioaddr & PCI_BASE_ADDRESS_IO_MASK) == 0 || (ioaddr & PCI_BASE_ADDRESS_SPACE_IO) == 0)
+						continue;
+					/* Strip the I/O address out of the returned value */
+					ioaddr &= PCI_BASE_ADDRESS_IO_MASK;
+					/* Get the memory base address */
+					pcibios_read_config_dword(bus, devfn,
+						PCI_BASE_ADDRESS_1, &membase);
+					/* Get the ROM base address */
+					pcibios_read_config_dword(bus, devfn, PCI_ROM_ADDRESS, &romaddr);
+					romaddr >>= 10;
+					printf("Found %s at %#hx, ROM address %#hx\n",
+						pcidev[i].name, ioaddr, romaddr);
+					/* Take the first one or the one that matches in boot ROM address */
+					if (pci_ioaddr == 0 || romaddr == ((unsigned long) rom.rom_segment << 4)) {
+						pcidev[i].membase = membase;
+						pcidev[i].ioaddr = ioaddr;
+						return;
+					}
+				}
+			}
+		}
+	}
+}
+
+void eth_pci_init(struct pci_device *pcidev)
+{
+#ifndef	CONFIG_PCI_DIRECT
+	pcibios_init();
+	if (!pcibios_entry) {
+		printf("pci_init: no BIOS32 detected\n");
+		return;
+	}
+#endif
+	scan_bus(pcidev);
+	/* return values are in pcidev structures */
+}
+
+/*
+ *	Set device to be a busmaster in case BIOS neglected to do so.
+ *	Also adjust PCI latency timer to a reasonable value, 32.
+ */
+void adjust_pci_device(struct pci_device *p)
+{
+	unsigned short	new_command, pci_command;
+	unsigned char	pci_latency;
+
+	pcibios_read_config_word(p->bus, p->devfn, PCI_COMMAND, &pci_command);
+	new_command = pci_command | PCI_COMMAND_MASTER|PCI_COMMAND_IO;
+	if (pci_command != new_command) {
+		printf("The PCI BIOS has not enabled this device!\nUpdating PCI command %hX->%hX. pci_bus %hhX pci_device_fn %hhX\n",
+			   pci_command, new_command, p->bus, p->devfn);
+		pcibios_write_config_word(p->bus, p->devfn, PCI_COMMAND, new_command);
+	}
+	pcibios_read_config_byte(p->bus, p->devfn, PCI_LATENCY_TIMER, &pci_latency);
+	if (pci_latency < 32) {
+		printf("PCI latency timer (CFLT) is unreasonably low at %d. Setting to 32 clocks.\n", pci_latency);
+		pcibios_write_config_byte(p->bus, p->devfn, PCI_LATENCY_TIMER, 32);
+	}
+}
diff --git a/netboot/pci.h b/netboot/pci.h
new file mode 100644
index 0000000..a99dc14
--- /dev/null
+++ b/netboot/pci.h
@@ -0,0 +1,192 @@
+#ifndef	PCI_H
+#define PCI_H
+
+/*
+** Support for NE2000 PCI clones added David Monro June 1997
+** Generalised for other PCI NICs by Ken Yap July 1997
+**
+** Most of this is taken from:
+**
+** /usr/src/linux/drivers/pci/pci.c
+** /usr/src/linux/include/linux/pci.h
+** /usr/src/linux/arch/i386/bios32.c
+** /usr/src/linux/include/linux/bios32.h
+** /usr/src/linux/drivers/net/ne.c
+*/
+
+/*
+ * 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.
+ */
+
+#define PCI_COMMAND_IO			0x1	/* Enable response in I/O space */
+#define PCI_COMMAND_MEM			0x2	/* Enable response in mem space */
+#define PCI_COMMAND_MASTER		0x4	/* Enable bus mastering */
+#define PCI_LATENCY_TIMER		0x0d	/* 8 bits */
+
+#define PCIBIOS_PCI_FUNCTION_ID         0xb1XX
+#define PCIBIOS_PCI_BIOS_PRESENT        0xb101
+#define PCIBIOS_FIND_PCI_DEVICE         0xb102
+#define PCIBIOS_FIND_PCI_CLASS_CODE     0xb103
+#define PCIBIOS_GENERATE_SPECIAL_CYCLE  0xb106
+#define PCIBIOS_READ_CONFIG_BYTE        0xb108
+#define PCIBIOS_READ_CONFIG_WORD        0xb109
+#define PCIBIOS_READ_CONFIG_DWORD       0xb10a
+#define PCIBIOS_WRITE_CONFIG_BYTE       0xb10b
+#define PCIBIOS_WRITE_CONFIG_WORD       0xb10c
+#define PCIBIOS_WRITE_CONFIG_DWORD      0xb10d
+
+#define PCI_VENDOR_ID           0x00    /* 16 bits */
+#define PCI_DEVICE_ID           0x02    /* 16 bits */
+#define PCI_COMMAND             0x04    /* 16 bits */
+
+#define PCI_REVISION            0x08    /* 8 bits  */
+#define PCI_CLASS_CODE          0x0b    /* 8 bits */
+#define PCI_SUBCLASS_CODE       0x0a    /* 8 bits */
+#define PCI_HEADER_TYPE         0x0e    /* 8 bits */
+
+#define PCI_BASE_ADDRESS_0      0x10    /* 32 bits */
+#define PCI_BASE_ADDRESS_1      0x14    /* 32 bits */
+#define PCI_BASE_ADDRESS_2      0x18    /* 32 bits */
+#define PCI_BASE_ADDRESS_3      0x1c    /* 32 bits */
+#define PCI_BASE_ADDRESS_4      0x20    /* 32 bits */
+#define PCI_BASE_ADDRESS_5      0x24    /* 32 bits */
+
+#ifndef	PCI_BASE_ADDRESS_IO_MASK
+#define	PCI_BASE_ADDRESS_IO_MASK       (~0x03)
+#endif
+#define	PCI_BASE_ADDRESS_SPACE_IO	0x01
+#define	PCI_ROM_ADDRESS		0x30	/* 32 bits */
+#define	PCI_ROM_ADDRESS_ENABLE	0x01	/* Write 1 to enable ROM,
+					   bits 31..11 are address,
+					   10..2 are reserved */
+
+#define PCI_FUNC(devfn)           ((devfn) & 0x07)
+
+#define BIOS32_SIGNATURE        (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
+
+/* PCI signature: "PCI " */
+#define PCI_SIGNATURE           (('P' << 0) + ('C' << 8) + ('I' << 16) + (' ' << 24))
+
+/* PCI service signature: "$PCI" */
+#define PCI_SERVICE             (('$' << 0) + ('P' << 8) + ('C' << 16) + ('I' << 24))
+
+union bios32 {
+	struct {
+		unsigned long signature;	/* _32_ */
+		unsigned long entry;		/* 32 bit physical address */
+		unsigned char revision;		/* Revision level, 0 */
+		unsigned char length;		/* Length in paragraphs should be 01 */
+		unsigned char checksum;		/* All bytes must add up to zero */
+		unsigned char reserved[5];	/* Must be zero */
+	} fields;
+	char chars[16];
+};
+
+#define KERN_CODE_SEG	0x8	/* This _MUST_ match start.S */
+
+/* Stuff for asm */
+#define save_flags(x) \
+__asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */ :"memory")
+
+#define cli() __asm__ __volatile__ ("cli": : :"memory")
+
+#define restore_flags(x) \
+__asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
+
+#define PCI_VENDOR_ID_ADMTEK            0x1317
+#define PCI_DEVICE_ID_ADMTEK_0985       0x0985
+#define PCI_VENDOR_ID_REALTEK           0x10ec
+#define PCI_DEVICE_ID_REALTEK_8029      0x8029
+#define PCI_DEVICE_ID_REALTEK_8139      0x8139
+#define PCI_VENDOR_ID_WINBOND2          0x1050
+#define PCI_DEVICE_ID_WINBOND2_89C940   0x0940
+#define PCI_DEVICE_ID_WINBOND2_89C840   0x0840
+#define PCI_VENDOR_ID_COMPEX            0x11f6
+#define PCI_DEVICE_ID_COMPEX_RL2000     0x1401
+#define PCI_DEVICE_ID_COMPEX_RL100ATX   0x2011
+#define PCI_VENDOR_ID_KTI               0x8e2e
+#define PCI_DEVICE_ID_KTI_ET32P2        0x3000
+#define PCI_VENDOR_ID_NETVIN            0x4a14
+#define PCI_DEVICE_ID_NETVIN_NV5000SC   0x5000
+#define	PCI_VENDOR_ID_HOLTEK		0x12c3
+#define	PCI_DEVICE_ID_HOLTEK_HT80232	0x0058
+#define PCI_VENDOR_ID_3COM		0x10b7
+#define PCI_DEVICE_ID_3COM_3C590	0x5900
+#define PCI_DEVICE_ID_3COM_3C595	0x5950
+#define PCI_DEVICE_ID_3COM_3C595_1	0x5951
+#define PCI_DEVICE_ID_3COM_3C595_2	0x5952
+#define PCI_DEVICE_ID_3COM_3C900TPO	0x9000
+#define PCI_DEVICE_ID_3COM_3C900COMBO	0x9001
+#define PCI_DEVICE_ID_3COM_3C905TX	0x9050
+#define PCI_DEVICE_ID_3COM_3C905T4	0x9051
+#define PCI_DEVICE_ID_3COM_3C905B_TX	0x9055
+#define PCI_DEVICE_ID_3COM_3C905C_TXM	0x9200
+#define PCI_VENDOR_ID_INTEL		0x8086
+#define PCI_DEVICE_ID_INTEL_82557	0x1229
+#define PCI_DEVICE_ID_INTEL_82559ER	0x1209
+#define PCI_DEVICE_ID_INTEL_ID1029	0x1029
+#define PCI_DEVICE_ID_INTEL_ID1030	0x1030
+#define PCI_DEVICE_ID_INTEL_82562	0x2449
+#define PCI_VENDOR_ID_AMD		0x1022
+#define PCI_DEVICE_ID_AMD_LANCE		0x2000
+#define PCI_VENDOR_ID_AMD_HOMEPNA	0x1022
+#define PCI_DEVICE_ID_AMD_HOMEPNA	0x2001
+#define PCI_VENDOR_ID_SMC_1211          0x1113
+#define PCI_DEVICE_ID_SMC_1211          0x1211
+#define PCI_VENDOR_ID_DEC		0x1011
+#define PCI_DEVICE_ID_DEC_TULIP		0x0002
+#define PCI_DEVICE_ID_DEC_TULIP_FAST	0x0009
+#define PCI_DEVICE_ID_DEC_TULIP_PLUS	0x0014
+#define PCI_DEVICE_ID_DEC_21142		0x0019
+#define PCI_VENDOR_ID_SMC		0x10B8
+#ifndef	PCI_DEVICE_ID_SMC_EPIC100
+# define PCI_DEVICE_ID_SMC_EPIC100	0x0005
+#endif
+#define PCI_VENDOR_ID_MACRONIX		0x10d9
+#define PCI_DEVICE_ID_MX987x5		0x0531
+#define PCI_VENDOR_ID_LINKSYS		0x11AD
+#define PCI_DEVICE_ID_LC82C115		0xC115
+#define PCI_VENDOR_ID_VIATEC		0x1106
+#define PCI_DEVICE_ID_VIA_RHINE_I	0x3043
+#define PCI_DEVICE_ID_VIA_VT6102	0x3065
+#define PCI_DEVICE_ID_VIA_86C100A	0x6100
+#define PCI_VENDOR_ID_DAVICOM		0x1282
+#define	PCI_DEVICE_ID_DM9009		0x9009
+#define PCI_DEVICE_ID_DM9102		0x9102
+#define PCI_VENDOR_ID_SIS         	0x1039
+#define PCI_DEVICE_ID_SIS900     	0x0900   
+#define PCI_DEVICE_ID_SIS7016    	0x7016  
+#define	PCI_VENDOR_ID_DLINK		0x1186
+#define	PCI_DEVICE_ID_DFE530TXP		0x1300
+#define	PCI_VENDOR_ID_NS		0x100B
+#define	PCI_DEVICE_ID_DP83815		0x0020
+#define PCI_VENDOR_ID_OLICOM		0x108d
+#define PCI_DEVICE_ID_OLICOM_OC3136	0x0001
+#define PCI_DEVICE_ID_OLICOM_OC2315	0x0011
+#define PCI_DEVICE_ID_OLICOM_OC2325	0x0012
+#define PCI_DEVICE_ID_OLICOM_OC2183	0x0013
+#define PCI_DEVICE_ID_OLICOM_OC2326	0x0014
+#define PCI_DEVICE_ID_OLICOM_OC6151	0x0021
+
+struct pci_device {
+	unsigned short	vendor, dev_id;
+	const char	*name;
+	unsigned int	membase;
+	unsigned short	ioaddr;
+	unsigned char	devfn;
+	unsigned char	bus;
+};
+
+extern void	eth_pci_init(struct pci_device *);
+
+extern int pcibios_read_config_byte(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned char *value);
+extern int pcibios_write_config_byte (unsigned int bus, unsigned int device_fn, unsigned int where, unsigned char value);
+extern int pcibios_read_config_word(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned short *value);
+extern int pcibios_write_config_word (unsigned int bus, unsigned int device_fn, unsigned int where, unsigned short value);
+extern int pcibios_read_config_dword(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned int *value);
+extern int pcibios_write_config_dword(unsigned int bus, unsigned int device_fn, unsigned int where, unsigned int value);
+void adjust_pci_device(struct pci_device *p);
+#endif	/* PCI_H */
diff --git a/netboot/rtl8139.c b/netboot/rtl8139.c
new file mode 100644
index 0000000..62d6e3a
--- /dev/null
+++ b/netboot/rtl8139.c
@@ -0,0 +1,458 @@
+/* rtl8139.c - etherboot driver for the Realtek 8139 chipset
+
+  ported from the linux driver written by Donald Becker
+  by Rainer Bawidamann (Rainer.Bawidamann@informatik.uni-ulm.de) 1999
+
+  This software may be used and distributed according to the terms
+  of the GNU Public License, incorporated herein by reference.
+
+  changes to the original driver:
+  - removed support for interrupts, switching to polling mode (yuck!)
+  - removed support for the 8129 chip (external MII)
+
+*/
+
+/*********************************************************************/
+/* Revision History                                                  */
+/*********************************************************************/
+
+/*
+
+  06 Apr 2001	ken_yap@users.sourceforge.net (Ken Yap)
+     Following email from Hyun-Joon Cha, added a disable routine, otherwise
+     NIC remains live and can crash the kernel later.
+
+  4 Feb 2000	espenlaub@informatik.uni-ulm.de (Klaus Espenlaub)
+     Shuffled things around, removed the leftovers from the 8129 support
+     that was in the Linux driver and added a bit more 8139 definitions.
+     Moved the 8K receive buffer to a fixed, available address outside the
+     0x98000-0x9ffff range.  This is a bit of a hack, but currently the only
+     way to make room for the Etherboot features that need substantial amounts
+     of code like the ANSI console support.  Currently the buffer is just below
+     0x10000, so this even conforms to the tagged boot image specification,
+     which reserves the ranges 0x00000-0x10000 and 0x98000-0xA0000.  My
+     interpretation of this "reserved" is that Etherboot may do whatever it
+     likes, as long as its environment is kept intact (like the BIOS
+     variables).  Hopefully fixed rtl_poll() once and for all.  The symptoms
+     were that if Etherboot was left at the boot menu for several minutes, the
+     first eth_poll failed.  Seems like I am the only person who does this.
+     First of all I fixed the debugging code and then set out for a long bug
+     hunting session.  It took me about a week full time work - poking around
+     various places in the driver, reading Don Becker's and Jeff Garzik's Linux
+     driver and even the FreeBSD driver (what a piece of crap!) - and
+     eventually spotted the nasty thing: the transmit routine was acknowledging
+     each and every interrupt pending, including the RxOverrun and RxFIFIOver
+     interrupts.  This confused the RTL8139 thoroughly.  It destroyed the
+     Rx ring contents by dumping the 2K FIFO contents right where we wanted to
+     get the next packet.  Oh well, what fun.
+
+  18 Jan 2000   mdc@thinguin.org (Marty Connor)
+     Drastically simplified error handling.  Basically, if any error
+     in transmission or reception occurs, the card is reset.
+     Also, pointed all transmit descriptors to the same buffer to
+     save buffer space.  This should decrease driver size and avoid
+     corruption because of exceeding 32K during runtime.
+
+  28 Jul 1999   (Matthias Meixner - meixner@rbg.informatik.tu-darmstadt.de)
+     rtl_poll was quite broken: it used the RxOK interrupt flag instead
+     of the RxBufferEmpty flag which often resulted in very bad
+     transmission performace - below 1kBytes/s.
+
+*/
+
+#include "etherboot.h"
+#include "nic.h"
+#include "pci.h"
+#include "cards.h"
+#include "timer.h"
+
+#define RTL_TIMEOUT (1*TICKS_PER_SEC)
+
+/* PCI Tuning Parameters
+   Threshold is bytes transferred to chip before transmission starts. */
+#define TX_FIFO_THRESH 256      /* In bytes, rounded down to 32 byte units. */
+#define RX_FIFO_THRESH  4       /* Rx buffer level before first PCI xfer.  */
+#define RX_DMA_BURST    4       /* Maximum PCI burst, '4' is 256 bytes */
+#define TX_DMA_BURST    4       /* Calculate as 16<<val. */
+#define NUM_TX_DESC     4       /* Number of Tx descriptor registers. */
+#define TX_BUF_SIZE	ETH_FRAME_LEN	/* FCS is added by the chip */
+#define RX_BUF_LEN_IDX 0	/* 0, 1, 2 is allowed - 8,16,32K rx buffer */
+#define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX)
+
+#undef DEBUG_TX
+#undef DEBUG_RX
+
+/* Symbolic offsets to registers. */
+enum RTL8139_registers {
+	MAC0=0,			/* Ethernet hardware address. */
+	MAR0=8,			/* Multicast filter. */
+	TxStatus0=0x10,		/* Transmit status (four 32bit registers). */
+	TxAddr0=0x20,		/* Tx descriptors (also four 32bit). */
+	RxBuf=0x30, RxEarlyCnt=0x34, RxEarlyStatus=0x36,
+	ChipCmd=0x37, RxBufPtr=0x38, RxBufAddr=0x3A,
+	IntrMask=0x3C, IntrStatus=0x3E,
+	TxConfig=0x40, RxConfig=0x44,
+	Timer=0x48,		/* general-purpose counter. */
+	RxMissed=0x4C,		/* 24 bits valid, write clears. */
+	Cfg9346=0x50, Config0=0x51, Config1=0x52,
+	TimerIntrReg=0x54,	/* intr if gp counter reaches this value */
+	MediaStatus=0x58,
+	Config3=0x59,
+	MultiIntr=0x5C,
+	RevisionID=0x5E,	/* revision of the RTL8139 chip */
+	TxSummary=0x60,
+	MII_BMCR=0x62, MII_BMSR=0x64, NWayAdvert=0x66, NWayLPAR=0x68,
+	NWayExpansion=0x6A,
+	DisconnectCnt=0x6C, FalseCarrierCnt=0x6E,
+	NWayTestReg=0x70,
+	RxCnt=0x72,		/* packet received counter */
+	CSCR=0x74,		/* chip status and configuration register */
+	PhyParm1=0x78,TwisterParm=0x7c,PhyParm2=0x80,	/* undocumented */
+	/* from 0x84 onwards are a number of power management/wakeup frame
+	 * definitions we will probably never need to know about.  */
+};
+
+enum ChipCmdBits {
+	CmdReset=0x10, CmdRxEnb=0x08, CmdTxEnb=0x04, RxBufEmpty=0x01, };
+
+/* Interrupt register bits, using my own meaningful names. */
+enum IntrStatusBits {
+	PCIErr=0x8000, PCSTimeout=0x4000, CableLenChange= 0x2000,
+	RxFIFOOver=0x40, RxUnderrun=0x20, RxOverflow=0x10,
+	TxErr=0x08, TxOK=0x04, RxErr=0x02, RxOK=0x01,
+};
+enum TxStatusBits {
+	TxHostOwns=0x2000, TxUnderrun=0x4000, TxStatOK=0x8000,
+	TxOutOfWindow=0x20000000, TxAborted=0x40000000,
+	TxCarrierLost=0x80000000,
+};
+enum RxStatusBits {
+	RxMulticast=0x8000, RxPhysical=0x4000, RxBroadcast=0x2000,
+	RxBadSymbol=0x0020, RxRunt=0x0010, RxTooLong=0x0008, RxCRCErr=0x0004,
+	RxBadAlign=0x0002, RxStatusOK=0x0001,
+};
+
+enum MediaStatusBits {
+	MSRTxFlowEnable=0x80, MSRRxFlowEnable=0x40, MSRSpeed10=0x08,
+	MSRLinkFail=0x04, MSRRxPauseFlag=0x02, MSRTxPauseFlag=0x01,
+};
+
+enum MIIBMCRBits {
+	BMCRReset=0x8000, BMCRSpeed100=0x2000, BMCRNWayEnable=0x1000,
+	BMCRRestartNWay=0x0200, BMCRDuplex=0x0100,
+};
+
+enum CSCRBits {
+	CSCR_LinkOKBit=0x0400, CSCR_LinkChangeBit=0x0800,
+	CSCR_LinkStatusBits=0x0f000, CSCR_LinkDownOffCmd=0x003c0,
+	CSCR_LinkDownCmd=0x0f3c0,
+};
+
+/* Bits in RxConfig. */
+enum rx_mode_bits {
+	RxCfgWrap=0x80,
+	AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0x08,
+	AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01,
+};
+
+static int ioaddr;
+static unsigned int cur_rx,cur_tx;
+
+/* The RTL8139 can only transmit from a contiguous, aligned memory block.  */
+static unsigned char tx_buffer[TX_BUF_SIZE] __attribute__((aligned(4)));
+
+/* I know that this is a MEGA HACK, but the tagged boot image specification
+ * states that we can do whatever we want below 0x10000 - so we do!  */
+/* But we still give the user the choice of using an internal buffer
+   just in case - Ken */
+#ifdef	USE_LOWMEM_BUFFER
+#define rx_ring ((unsigned char *)(0x10000 - (RX_BUF_LEN + 16)))
+#else
+static unsigned char rx_ring[RX_BUF_LEN+16] __attribute__((aligned(4)));
+#endif
+
+struct nic *rtl8139_probe(struct nic *nic, unsigned short *probeaddrs,
+	struct pci_device *pci);
+static int read_eeprom(int location);
+static void rtl_reset(struct nic *nic);
+static void rtl_transmit(struct nic *nic, const char *destaddr,
+	unsigned int type, unsigned int len, const char *data);
+static int rtl_poll(struct nic *nic);
+static void rtl_disable(struct nic*);
+
+
+struct nic *rtl8139_probe(struct nic *nic, unsigned short *probeaddrs,
+	struct pci_device *pci)
+{
+	int i;
+	int speed10, fullduplex;
+
+	/* There are enough "RTL8139" strings on the console already, so
+	 * be brief and concentrate on the interesting pieces of info... */
+	printf(" - ");
+
+	/* Mask the bit that says "this is an io addr" */
+	ioaddr = probeaddrs[0] & ~3;
+
+	adjust_pci_device(pci);
+
+	/* Bring the chip out of low-power mode. */
+	outb(0x00, ioaddr + Config1);
+
+	if (read_eeprom(0) != 0xffff) {
+		unsigned short *ap = (unsigned short*)nic->node_addr;
+		for (i = 0; i < 3; i++)
+			*ap++ = read_eeprom(i + 7);
+	} else {
+		unsigned char *ap = (unsigned char*)nic->node_addr;
+		for (i = 0; i < ETH_ALEN; i++)
+			*ap++ = inb(ioaddr + MAC0 + i);
+	}
+
+	speed10 = inb(ioaddr + MediaStatus) & MSRSpeed10;
+	fullduplex = inw(ioaddr + MII_BMCR) & BMCRDuplex;
+	printf("ioaddr %#hX, addr %! %sMbps %s-duplex\n", ioaddr,
+		nic->node_addr,  speed10 ? "10" : "100",
+		fullduplex ? "full" : "half");
+
+	rtl_reset(nic);
+
+	nic->reset = rtl_reset;
+	nic->poll = rtl_poll;
+	nic->transmit = rtl_transmit;
+	nic->disable = rtl_disable;
+
+	return nic;
+}
+
+/* Serial EEPROM section. */
+
+/*  EEPROM_Ctrl bits. */
+#define EE_SHIFT_CLK    0x04    /* EEPROM shift clock. */
+#define EE_CS           0x08    /* EEPROM chip select. */
+#define EE_DATA_WRITE   0x02    /* EEPROM chip data in. */
+#define EE_WRITE_0      0x00
+#define EE_WRITE_1      0x02
+#define EE_DATA_READ    0x01    /* EEPROM chip data out. */
+#define EE_ENB          (0x80 | EE_CS)
+
+/*
+	Delay between EEPROM clock transitions.
+	No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
+*/
+
+#define eeprom_delay()  inl(ee_addr)
+
+/* The EEPROM commands include the alway-set leading bit. */
+#define EE_WRITE_CMD    (5 << 6)
+#define EE_READ_CMD     (6 << 6)
+#define EE_ERASE_CMD    (7 << 6)
+
+static int read_eeprom(int location)
+{
+	int i;
+	unsigned int retval = 0;
+	long ee_addr = ioaddr + Cfg9346;
+	int read_cmd = location | EE_READ_CMD;
+
+	outb(EE_ENB & ~EE_CS, ee_addr);
+	outb(EE_ENB, ee_addr);
+
+	/* Shift the read command bits out. */
+	for (i = 10; i >= 0; i--) {
+		int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+		outb(EE_ENB | dataval, ee_addr);
+		eeprom_delay();
+		outb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+		eeprom_delay();
+	}
+	outb(EE_ENB, ee_addr);
+	eeprom_delay();
+
+	for (i = 16; i > 0; i--) {
+		outb(EE_ENB | EE_SHIFT_CLK, ee_addr);
+		eeprom_delay();
+		retval = (retval << 1) | ((inb(ee_addr) & EE_DATA_READ) ? 1 : 0);
+		outb(EE_ENB, ee_addr);
+		eeprom_delay();
+	}
+
+	/* Terminate the EEPROM access. */
+	outb(~EE_CS, ee_addr);
+	return retval;
+}
+
+static void rtl_reset(struct nic* nic)
+{
+	int i;
+
+	outb(CmdReset, ioaddr + ChipCmd);
+
+	cur_rx = 0;
+	cur_tx = 0;
+
+	/* Give the chip 10ms to finish the reset. */
+	load_timer2(10*TICKS_PER_MS);
+	while ((inb(ioaddr + ChipCmd) & CmdReset) != 0 && timer2_running())
+		/* wait */;
+
+	for (i = 0; i < ETH_ALEN; i++)
+		outb(nic->node_addr[i], ioaddr + MAC0 + i);
+
+	/* Must enable Tx/Rx before setting transfer thresholds! */
+	outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
+	outl((RX_FIFO_THRESH<<13) | (RX_BUF_LEN_IDX<<11) | (RX_DMA_BURST<<8),
+		ioaddr + RxConfig);		/* accept no frames yet!  */
+	outl((TX_DMA_BURST<<8)|0x03000000, ioaddr + TxConfig);
+
+	/* The Linux driver changes Config1 here to use a different LED pattern
+	 * for half duplex or full/autodetect duplex (for full/autodetect, the
+	 * outputs are TX/RX, Link10/100, FULL, while for half duplex it uses
+	 * TX/RX, Link100, Link10).  This is messy, because it doesn't match
+	 * the inscription on the mounting bracket.  It should not be changed
+	 * from the configuration EEPROM default, because the card manufacturer
+	 * should have set that to match the card.  */
+
+#ifdef	DEBUG_RX
+	printf("rx ring address is %X\n",(unsigned long)rx_ring);
+#endif
+	outl((unsigned long)rx_ring, ioaddr + RxBuf);
+
+	/* Start the chip's Tx and Rx process. */
+	outl(0, ioaddr + RxMissed);
+	/* set_rx_mode */
+	outb(AcceptBroadcast|AcceptMyPhys, ioaddr + RxConfig);
+	/* If we add multicast support, the MAR0 register would have to be
+	 * initialized to 0xffffffffffffffff (two 32 bit accesses).  Etherboot
+	 * only needs broadcast (for ARP/RARP/BOOTP/DHCP) and unicast.  */
+	outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
+
+	/* Disable all known interrupts by setting the interrupt mask. */
+	outw(0, ioaddr + IntrMask);
+}
+
+static void rtl_transmit(struct nic *nic, const char *destaddr,
+	unsigned int type, unsigned int len, const char *data)
+{
+	unsigned int status, to, nstype;
+	unsigned long txstatus;
+
+	memcpy(tx_buffer, destaddr, ETH_ALEN);
+	memcpy(tx_buffer + ETH_ALEN, nic->node_addr, ETH_ALEN);
+	nstype = htons(type);
+	memcpy(tx_buffer + 2 * ETH_ALEN, (char*)&nstype, 2);
+	memcpy(tx_buffer + ETH_HLEN, data, len);
+
+	len += ETH_HLEN;
+#ifdef	DEBUG_TX
+	printf("sending %d bytes ethtype %hX\n", len, type);
+#endif
+
+	/* Note: RTL8139 doesn't auto-pad, send minimum payload (another 4
+	 * bytes are sent automatically for the FCS, totalling to 64 bytes). */
+	while (len < ETH_ZLEN) {
+		tx_buffer[len++] = '\0';
+	}
+
+	outl((unsigned long)tx_buffer, ioaddr + TxAddr0 + cur_tx*4);
+	outl(((TX_FIFO_THRESH<<11) & 0x003f0000) | len,
+		ioaddr + TxStatus0 + cur_tx*4);
+
+	to = currticks() + RTL_TIMEOUT;
+
+	do {
+		status = inw(ioaddr + IntrStatus);
+		/* Only acknlowledge interrupt sources we can properly handle
+		 * here - the RxOverflow/RxFIFOOver MUST be handled in the
+		 * rtl_poll() function.  */
+		outw(status & (TxOK | TxErr | PCIErr), ioaddr + IntrStatus);
+		if ((status & (TxOK | TxErr | PCIErr)) != 0) break;
+	} while (currticks() < to);
+
+	txstatus = inl(ioaddr+ TxStatus0 + cur_tx*4);
+
+	if (status & TxOK) {
+		cur_tx = (cur_tx + 1) % NUM_TX_DESC;
+#ifdef	DEBUG_TX
+		printf("tx done (%d ticks), status %hX txstatus %X\n",
+			to-currticks(), status, txstatus);
+#endif
+	} else {
+#ifdef	DEBUG_TX
+		printf("tx timeout/error (%d ticks), status %hX txstatus %X\n",
+			currticks()-to, status, txstatus);
+#endif
+		rtl_reset(nic);
+	}
+}
+
+static int rtl_poll(struct nic *nic)
+{
+	unsigned int status;
+	unsigned int ring_offs;
+	unsigned int rx_size, rx_status;
+
+	if (inb(ioaddr + ChipCmd) & RxBufEmpty) {
+		return 0;
+	}
+
+	status = inw(ioaddr + IntrStatus);
+	/* See below for the rest of the interrupt acknowledges.  */
+	outw(status & ~(RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus);
+
+#ifdef	DEBUG_RX
+	printf("rtl_poll: int %hX ", status);
+#endif
+
+	ring_offs = cur_rx % RX_BUF_LEN;
+	rx_status = *(unsigned int*)(rx_ring + ring_offs);
+	rx_size = rx_status >> 16;
+	rx_status &= 0xffff;
+
+	if ((rx_status & (RxBadSymbol|RxRunt|RxTooLong|RxCRCErr|RxBadAlign)) ||
+	    (rx_size < ETH_ZLEN) || (rx_size > ETH_FRAME_LEN + 4)) {
+		printf("rx error %hX\n", rx_status);
+		rtl_reset(nic);	/* this clears all interrupts still pending */
+		return 0;
+	}
+
+	/* Received a good packet */
+	nic->packetlen = rx_size - 4;	/* no one cares about the FCS */
+	if (ring_offs+4+rx_size-4 > RX_BUF_LEN) {
+		int semi_count = RX_BUF_LEN - ring_offs - 4;
+
+		memcpy(nic->packet, rx_ring + ring_offs + 4, semi_count);
+		memcpy(nic->packet+semi_count, rx_ring, rx_size-4-semi_count);
+#ifdef	DEBUG_RX
+		printf("rx packet %d+%d bytes", semi_count,rx_size-4-semi_count);
+#endif
+	} else {
+		memcpy(nic->packet, rx_ring + ring_offs + 4, nic->packetlen);
+#ifdef	DEBUG_RX
+		printf("rx packet %d bytes", rx_size-4);
+#endif
+	}
+#ifdef	DEBUG_RX
+	printf(" at %X type %hhX%hhX rxstatus %hX\n",
+		(unsigned long)(rx_ring+ring_offs+4),
+		nic->packet[12], nic->packet[13], rx_status);
+#endif
+	cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
+	outw(cur_rx - 16, ioaddr + RxBufPtr);
+	/* See RTL8139 Programming Guide V0.1 for the official handling of
+	 * Rx overflow situations.  The document itself contains basically no
+	 * usable information, except for a few exception handling rules.  */
+	outw(status & (RxFIFOOver | RxOverflow | RxOK), ioaddr + IntrStatus);
+	return 1;
+}
+
+static void rtl_disable(struct nic *nic)
+{
+	/* reset the chip */
+	outb(CmdReset, ioaddr + ChipCmd);
+
+	/* 10 ms timeout */
+	load_timer2(10*TICKS_PER_MS);
+	while ((inb(ioaddr + ChipCmd) & CmdReset) != 0 && timer2_running())
+		/* wait */;
+}
diff --git a/netboot/sis900.c b/netboot/sis900.c
new file mode 100644
index 0000000..6208a26
--- /dev/null
+++ b/netboot/sis900.c
@@ -0,0 +1,1034 @@
+/* -*- Mode:C; c-basic-offset:4; -*- */
+
+/* 
+   sis900.c: An SiS 900/7016 PCI Fast Ethernet driver for Etherboot
+   Copyright (C) 2001 Entity Cyber, Inc.
+
+   Revision:	1.0	March 1, 2001
+   
+   Author: Marty Connor (mdc@thinguin.org)
+
+   Adapted from a Linux driver which was written by Donald Becker
+   and modified by Ollie Lho and Chin-Shan Li of SiS Corporation.
+   Rewritten for Etherboot by Marty Connor.
+   
+   This software may be used and distributed according to the terms
+   of the GNU Public License (GPL), incorporated herein by reference.
+   
+   References:
+   SiS 7016 Fast Ethernet PCI Bus 10/100 Mbps LAN Controller with OnNow Support,
+   preliminary Rev. 1.0 Jan. 14, 1998
+   SiS 900 Fast Ethernet PCI Bus 10/100 Mbps LAN Single Chip with OnNow Support,
+   preliminary Rev. 1.0 Nov. 10, 1998
+   SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution,
+   preliminary Rev. 1.0 Jan. 18, 1998
+   http://www.sis.com.tw/support/databook.htm */
+
+/* Revision History */
+
+/*
+  01 March 2001  mdc     1.0
+     Initial Release.  Tested with PCI based sis900 card and ThinkNIC
+     computer.
+  20 March 2001 P.Koegel
+     added support for sis630e and PHY ICS1893 and RTL8201
+     Testet with SIS730S chipset + ICS1893
+*/
+
+
+/* Includes */
+
+#include "etherboot.h"
+#include "nic.h"
+#include "pci.h"
+#include "cards.h"
+
+#include "sis900.h"
+
+/* Globals */
+
+static int sis900_debug = 0;
+
+static unsigned short vendor, dev_id;
+static unsigned long ioaddr;
+
+static unsigned int cur_phy;
+
+static unsigned int cur_rx;
+
+static BufferDesc txd;
+static BufferDesc rxd[NUM_RX_DESC];
+
+#ifdef USE_LOWMEM_BUFFER
+#define txb ((char *)0x10000 - TX_BUF_SIZE)
+#define rxb ((char *)0x10000 - NUM_RX_DESC*RX_BUF_SIZE - TX_BUF_SIZE)
+#else
+static unsigned char txb[TX_BUF_SIZE];
+static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE];
+#endif
+
+static struct mac_chip_info {
+    const char *name;
+    u16 vendor_id, device_id, flags;
+    int io_size;
+} mac_chip_table[] = {
+    { "SiS 900 PCI Fast Ethernet", PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS900,
+      PCI_COMMAND_IO|PCI_COMMAND_MASTER, SIS900_TOTAL_SIZE},
+    { "SiS 7016 PCI Fast Ethernet",PCI_VENDOR_ID_SIS, PCI_DEVICE_ID_SIS7016,
+      PCI_COMMAND_IO|PCI_COMMAND_MASTER, SIS900_TOTAL_SIZE},
+    {0,0,0,0,0} /* 0 terminated list. */
+};
+
+static void sis900_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
+static void amd79c901_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
+static void ics1893_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
+static void rtl8201_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex);
+
+static struct mii_chip_info {
+    const char * name;
+    u16 phy_id0;
+    u16 phy_id1;
+    void (*read_mode) (struct nic *nic, int phy_addr, int *speed, int *duplex);
+} mii_chip_table[] = {
+    {"SiS 900 Internal MII PHY", 0x001d, 0x8000, sis900_read_mode},
+    {"SiS 7014 Physical Layer Solution", 0x0016, 0xf830,sis900_read_mode},
+    {"AMD 79C901 10BASE-T PHY",  0x0000, 0x35b9, amd79c901_read_mode},
+    {"AMD 79C901 HomePNA PHY",   0x0000, 0x35c8, amd79c901_read_mode},
+    {"ICS 1893 Integrated PHYceiver"   , 0x0015, 0xf441,ics1893_read_mode},
+    {"RTL 8201 10/100Mbps Phyceiver"   , 0x0000, 0x8201,rtl8201_read_mode},
+    {0,0,0,0}
+};
+
+static struct mii_phy {
+    struct mii_phy * next;
+    struct mii_chip_info * chip_info;
+    int phy_addr;
+    u16 status;
+} mii;
+
+
+// PCI to ISA bridge for SIS640E access
+static struct pci_device   pci_isa_bridge_list[] = {
+	{ 0x1039, 0x0008,
+		"SIS 85C503/5513 PCI to ISA bridge", 0, 0, 0, 0},
+	{0, 0, NULL, 0, 0, 0, 0}
+};
+
+/* Function Prototypes */
+
+struct nic *sis900_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci);
+
+static u16  sis900_read_eeprom(int location);
+static void sis900_mdio_reset(long mdio_addr);
+static void sis900_mdio_idle(long mdio_addr);
+static u16  sis900_mdio_read(int phy_id, int location);
+static void sis900_mdio_write(int phy_id, int location, int val);
+
+static void sis900_init(struct nic *nic);
+
+static void sis900_reset(struct nic *nic);
+
+static void sis900_init_rxfilter(struct nic *nic);
+static void sis900_init_txd(struct nic *nic);
+static void sis900_init_rxd(struct nic *nic);
+static void sis900_set_rx_mode(struct nic *nic);
+static void sis900_check_mode(struct nic *nic);
+
+static void sis900_transmit(struct nic *nic, const char *d, 
+                            unsigned int t, unsigned int s, const char *p);
+static int  sis900_poll(struct nic *nic);
+
+static void sis900_disable(struct nic *nic);
+
+/**
+ *	sis900_get_mac_addr: - Get MAC address for stand alone SiS900 model
+ *	@pci_dev: the sis900 pci device
+ *	@net_dev: the net device to get address for
+ *
+ *	Older SiS900 and friends, use EEPROM to store MAC address.
+ *	MAC address is read from read_eeprom() into @net_dev->dev_addr.
+ */
+
+static int sis900_get_mac_addr(struct pci_device * pci_dev , struct nic *nic)
+{
+	u16 signature;
+	int i;
+
+	/* check to see if we have sane EEPROM */
+	signature = (u16) sis900_read_eeprom( EEPROMSignature);
+	if (signature == 0xffff || signature == 0x0000) {
+		printf ("sis900_probe: Error EERPOM read %hX\n", signature);
+		return 0;
+	}
+
+	/* get MAC address from EEPROM */
+	for (i = 0; i < 3; i++)
+			((u16 *)(nic->node_addr))[i] = sis900_read_eeprom(i+EEPROMMACAddr);
+	return 1;
+}
+
+/**
+ *	sis630e_get_mac_addr: - Get MAC address for SiS630E model
+ *	@pci_dev: the sis900 pci device
+ *	@net_dev: the net device to get address for
+ *
+ *	SiS630E model, use APC CMOS RAM to store MAC address.
+ *	APC CMOS RAM is accessed through ISA bridge.
+ *	MAC address is read into @net_dev->dev_addr.
+ */
+
+static int sis630e_get_mac_addr(struct pci_device * pci_dev, struct nic *nic)
+{
+	u8 reg;
+	int i;
+	struct pci_device	*p;
+
+	// find PCI to ISA bridge
+	eth_pci_init(pci_isa_bridge_list);
+
+    /* the firts entry in this list should contain bus/devfn */
+    p = pci_isa_bridge_list;
+
+	pcibios_read_config_byte(p->bus,p->devfn, 0x48, &reg);
+	pcibios_write_config_byte(p->bus,p->devfn, 0x48, reg | 0x40);
+
+	for (i = 0; i < ETH_ALEN; i++)
+	{
+		outb(0x09 + i, 0x70);
+		((u8 *)(nic->node_addr))[i] = inb(0x71);
+	}
+	pcibios_write_config_byte(p->bus,p->devfn, 0x48, reg & ~0x40);
+
+	return 1;
+}
+
+/* 
+ * Function: sis900_probe
+ *
+ * Description: initializes initializes the NIC, retrieves the
+ *    MAC address of the card, and sets up some globals required by 
+ *    other routines.
+ *
+ * Side effects:
+ *            leaves the ioaddress of the sis900 chip in the variable ioaddr.
+ *            leaves the sis900 initialized, and ready to recieve packets.
+ *
+ * Returns:   struct nic *:          pointer to NIC data structure
+ */
+
+struct nic *sis900_probe(struct nic *nic, unsigned short *io_addrs, struct pci_device *pci)
+{
+    int i;
+    int found=0;
+    int phy_addr;
+    u16 signature;
+    u8 revision;
+    int ret;
+
+    if (io_addrs == 0 || *io_addrs == 0)
+        return NULL;
+
+    ioaddr  = *io_addrs & ~3;
+    vendor  = pci->vendor;
+    dev_id  = pci->dev_id;
+
+    /* wakeup chip */
+    pcibios_write_config_dword(pci->bus, pci->devfn, 0x40, 0x00000000);
+
+    adjust_pci_device(pci);
+
+    /* get MAC address */
+    ret = 0;
+    pcibios_read_config_byte(pci->bus,pci->devfn, PCI_REVISION, &revision);
+    if (revision == SIS630E_900_REV || revision == SIS630EA1_900_REV)
+       ret = sis630e_get_mac_addr(pci, nic);
+    else if (revision == SIS630S_900_REV)
+        ret = sis630e_get_mac_addr(pci, nic);
+    else
+        ret = sis900_get_mac_addr(pci, nic);
+
+    if (ret == 0)
+    {
+        printf ("sis900_probe: Error MAC address not found\n");
+        return NULL;
+    }
+
+    printf("\nsis900_probe: MAC addr %! at ioaddr %#hX\n",
+           nic->node_addr, ioaddr);
+    printf("sis900_probe: Vendor:%#hX Device:%#hX\n", vendor, dev_id);
+
+    /* probe for mii transceiver */
+    /* search for total of 32 possible mii phy addresses */
+
+    found = 0;
+    for (phy_addr = 0; phy_addr < 32; phy_addr++) {
+        u16 mii_status;
+        u16 phy_id0, phy_id1;
+                
+        mii_status = sis900_mdio_read(phy_addr, MII_STATUS);
+        if (mii_status == 0xffff || mii_status == 0x0000)
+            /* the mii is not accessable, try next one */
+            continue;
+                
+        phy_id0 = sis900_mdio_read(phy_addr, MII_PHY_ID0);
+        phy_id1 = sis900_mdio_read(phy_addr, MII_PHY_ID1);
+                
+        /* search our mii table for the current mii */ 
+        for (i = 0; mii_chip_table[i].phy_id1; i++) {
+
+            if (phy_id0 == mii_chip_table[i].phy_id0) {
+
+                printf("sis900_probe: %s transceiver found at address %d.\n",
+                       mii_chip_table[i].name, phy_addr);
+
+                mii.chip_info = &mii_chip_table[i];
+                mii.phy_addr  = phy_addr;
+                mii.status    = sis900_mdio_read(phy_addr, MII_STATUS);
+                mii.next      = NULL;
+
+                found=1;
+                break;
+            }
+        }
+    }
+        
+    if (found == 0) {
+        printf("sis900_probe: No MII transceivers found!\n");
+        return NULL;
+    }
+
+    /* Arbitrarily select the last PHY found as current PHY */
+    cur_phy = mii.phy_addr;
+    printf("sis900_probe: Using %s as default\n",  mii.chip_info->name);
+
+    /* initialize device */
+    sis900_init(nic);
+
+    nic->reset    = sis900_init;
+    nic->poll     = sis900_poll;
+    nic->transmit = sis900_transmit;
+    nic->disable  = sis900_disable;
+
+    return nic;
+}
+
+
+/* 
+ * EEPROM Routines:  These functions read and write to EEPROM for 
+ *    retrieving the MAC address and other configuration information about 
+ *    the card.
+ */
+
+/* Delay between EEPROM clock transitions. */
+#define eeprom_delay()  inl(ee_addr)
+
+
+/* Function: sis900_read_eeprom
+ *
+ * Description: reads and returns a given location from EEPROM
+ *
+ * Arguments: int location:       requested EEPROM location
+ *
+ * Returns:   u16:                contents of requested EEPROM location
+ *
+ */
+
+/* Read Serial EEPROM through EEPROM Access Register, Note that location is 
+   in word (16 bits) unit */
+static u16 sis900_read_eeprom(int location)
+{
+    int i;
+    u16 retval = 0;
+    long ee_addr = ioaddr + mear;
+    u32 read_cmd = location | EEread;
+
+    outl(0, ee_addr);
+    eeprom_delay();
+    outl(EECLK, ee_addr);
+    eeprom_delay();
+
+    /* Shift the read command (9) bits out. */
+    for (i = 8; i >= 0; i--) {
+        u32 dataval = (read_cmd & (1 << i)) ? EEDI | EECS : EECS;
+        outl(dataval, ee_addr);
+        eeprom_delay();
+        outl(dataval | EECLK, ee_addr);
+        eeprom_delay();
+    }
+    outb(EECS, ee_addr);
+    eeprom_delay();
+
+    /* read the 16-bits data in */
+    for (i = 16; i > 0; i--) {
+        outl(EECS, ee_addr);
+        eeprom_delay();
+        outl(EECS | EECLK, ee_addr);
+        eeprom_delay();
+        retval = (retval << 1) | ((inl(ee_addr) & EEDO) ? 1 : 0);
+        eeprom_delay();
+    }
+                
+    /* Terminate the EEPROM access. */
+    outl(0, ee_addr);
+    eeprom_delay();
+    outl(EECLK, ee_addr);
+
+    return (retval);
+}
+
+#define sis900_mdio_delay()    inl(mdio_addr)
+
+
+/* 
+   Read and write the MII management registers using software-generated
+   serial MDIO protocol. Note that the command bits and data bits are
+   send out seperately 
+*/
+
+static void sis900_mdio_idle(long mdio_addr)
+{
+    outl(MDIO | MDDIR, mdio_addr);
+    sis900_mdio_delay();
+    outl(MDIO | MDDIR | MDC, mdio_addr);
+}
+
+/* Syncronize the MII management interface by shifting 32 one bits out. */
+static void sis900_mdio_reset(long mdio_addr)
+{
+    int i;
+
+    for (i = 31; i >= 0; i--) {
+        outl(MDDIR | MDIO, mdio_addr);
+        sis900_mdio_delay();
+        outl(MDDIR | MDIO | MDC, mdio_addr);
+        sis900_mdio_delay();
+    }
+    return;
+}
+
+static u16 sis900_mdio_read(int phy_id, int location)
+{
+    long mdio_addr = ioaddr + mear;
+    int mii_cmd = MIIread|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
+    u16 retval = 0;
+    int i;
+
+    sis900_mdio_reset(mdio_addr);
+    sis900_mdio_idle(mdio_addr);
+
+    for (i = 15; i >= 0; i--) {
+        int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
+        outl(dataval, mdio_addr);
+        sis900_mdio_delay();
+        outl(dataval | MDC, mdio_addr);
+        sis900_mdio_delay();
+    }
+
+    /* Read the 16 data bits. */
+    for (i = 16; i > 0; i--) {
+        outl(0, mdio_addr);
+        sis900_mdio_delay();
+        retval = (retval << 1) | ((inl(mdio_addr) & MDIO) ? 1 : 0);
+        outl(MDC, mdio_addr);
+        sis900_mdio_delay();
+    }
+    return retval;
+}
+
+static void sis900_mdio_write(int phy_id, int location, int value)
+{
+    long mdio_addr = ioaddr + mear;
+    int mii_cmd = MIIwrite|(phy_id<<MIIpmdShift)|(location<<MIIregShift);
+    int i;
+
+    sis900_mdio_reset(mdio_addr);
+    sis900_mdio_idle(mdio_addr);
+
+    /* Shift the command bits out. */
+    for (i = 15; i >= 0; i--) {
+        int dataval = (mii_cmd & (1 << i)) ? MDDIR | MDIO : MDDIR;
+        outb(dataval, mdio_addr);
+        sis900_mdio_delay();
+        outb(dataval | MDC, mdio_addr);
+        sis900_mdio_delay();
+    }
+    sis900_mdio_delay();
+
+    /* Shift the value bits out. */
+    for (i = 15; i >= 0; i--) {
+        int dataval = (value & (1 << i)) ? MDDIR | MDIO : MDDIR;
+        outl(dataval, mdio_addr);
+        sis900_mdio_delay();
+        outl(dataval | MDC, mdio_addr);
+        sis900_mdio_delay();
+    }
+    sis900_mdio_delay();
+        
+    /* Clear out extra bits. */
+    for (i = 2; i > 0; i--) {
+        outb(0, mdio_addr);
+        sis900_mdio_delay();
+        outb(MDC, mdio_addr);
+        sis900_mdio_delay();
+    }
+    return;
+}
+
+
+/* Function: sis900_init
+ *
+ * Description: resets the ethernet controller chip and various
+ *    data structures required for sending and receiving packets.
+ *    
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * returns:   void.
+ */
+
+static void
+sis900_init(struct nic *nic)
+{
+    /* Soft reset the chip. */
+    sis900_reset(nic);
+
+    sis900_init_rxfilter(nic);
+
+    sis900_init_txd(nic);
+    sis900_init_rxd(nic);
+
+    sis900_set_rx_mode(nic);
+
+    sis900_check_mode(nic);
+
+    outl(RxENA, ioaddr + cr);
+}
+
+
+/* 
+ * Function: sis900_reset
+ *
+ * Description: disables interrupts and soft resets the controller chip
+ *
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * Returns:   void.
+ */
+
+static void 
+sis900_reset(struct nic *nic)
+{
+    int i = 0;
+    u32 status = TxRCMP | RxRCMP;
+
+    outl(0, ioaddr + ier);
+    outl(0, ioaddr + imr);
+    outl(0, ioaddr + rfcr);
+
+    outl(RxRESET | TxRESET | RESET, ioaddr + cr);
+        
+    /* Check that the chip has finished the reset. */
+    while (status && (i++ < 1000)) {
+        status ^= (inl(isr + ioaddr) & status);
+    }
+    outl(PESEL, ioaddr + cfg);
+}
+
+
+/* Function: sis_init_rxfilter
+ *
+ * Description: sets receive filter address to our MAC address
+ *
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * returns:   void.
+ */
+
+static void
+sis900_init_rxfilter(struct nic *nic)
+{
+    u32 rfcrSave;
+    int i;
+        
+    rfcrSave = inl(rfcr + ioaddr);
+
+    /* disable packet filtering before setting filter */
+    outl(rfcrSave & ~RFEN, rfcr);
+
+    /* load MAC addr to filter data register */
+    for (i = 0 ; i < 3 ; i++) {
+        u32 w;
+
+        w = (u32) *((u16 *)(nic->node_addr)+i);
+        outl((i << RFADDR_shift), ioaddr + rfcr);
+        outl(w, ioaddr + rfdr);
+
+        if (sis900_debug > 0)
+            printf("sis900_init_rxfilter: Receive Filter Addrss[%d]=%X\n",
+                   i, inl(ioaddr + rfdr));
+    }
+
+    /* enable packet filitering */
+    outl(rfcrSave | RFEN, rfcr + ioaddr);
+}
+
+
+/* 
+ * Function: sis_init_txd
+ *
+ * Description: initializes the Tx descriptor
+ *
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * returns:   void.
+ */
+
+static void
+sis900_init_txd(struct nic *nic)
+{
+    txd.link   = (u32) 0;
+    txd.cmdsts = (u32) 0;
+    txd.bufptr = (u32) &txb[0];
+
+    /* load Transmit Descriptor Register */
+    outl((u32) &txd, ioaddr + txdp); 
+    if (sis900_debug > 0)
+        printf("sis900_init_txd: TX descriptor register loaded with: %X\n", 
+               inl(ioaddr + txdp));
+}
+
+
+/* Function: sis_init_rxd
+ *
+ * Description: initializes the Rx descriptor ring
+ *    
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * Returns:   void.
+ */
+
+static void 
+sis900_init_rxd(struct nic *nic) 
+{ 
+    int i;
+
+    cur_rx = 0; 
+
+    /* init RX descriptor */
+    for (i = 0; i < NUM_RX_DESC; i++) {
+        rxd[i].link   = (i+1 < NUM_RX_DESC) ? (u32) &rxd[i+1] : (u32) &rxd[0];
+        rxd[i].cmdsts = (u32) RX_BUF_SIZE;
+        rxd[i].bufptr = (u32) &rxb[i*RX_BUF_SIZE];
+        if (sis900_debug > 0)
+            printf("sis900_init_rxd: rxd[%d]=%X link=%X cmdsts=%X bufptr=%X\n", 
+                   i, &rxd[i], rxd[i].link, rxd[i].cmdsts, rxd[i].bufptr);
+    }
+
+    /* load Receive Descriptor Register */
+    outl((u32) &rxd[0], ioaddr + rxdp);
+
+    if (sis900_debug > 0)
+        printf("sis900_init_rxd: RX descriptor register loaded with: %X\n", 
+               inl(ioaddr + rxdp));
+
+}
+
+
+/* Function: sis_init_rxd
+ *
+ * Description: 
+ *    sets the receive mode to accept all broadcast packets and packets
+ *    with our MAC address, and reject all multicast packets.      
+ *    
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * Returns:   void.
+ */
+
+static void sis900_set_rx_mode(struct nic *nic)
+{
+    int i;
+
+    /* Configure Multicast Hash Table in Receive Filter 
+       to reject all MCAST packets */
+    for (i = 0; i < 8; i++) {
+        /* why plus 0x04? That makes the correct value for hash table. */
+        outl((u32)(0x00000004+i) << RFADDR_shift, ioaddr + rfcr);
+        outl((u32)(0x0), ioaddr + rfdr);
+    }
+    /* Accept Broadcast packets, destination addresses that match 
+       our MAC address */
+    outl(RFEN | RFAAB, ioaddr + rfcr);
+
+    return;
+}
+
+
+/* Function: sis900_check_mode
+ *
+ * Description: checks the state of transmit and receive
+ *    parameters on the NIC, and updates NIC registers to match
+ *    
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * Returns:   void.
+ */
+
+static void
+sis900_check_mode (struct nic *nic)
+{
+    int speed, duplex;
+    u32 tx_flags = 0, rx_flags = 0;
+
+    mii.chip_info->read_mode(nic, cur_phy, &speed, &duplex);
+
+    tx_flags = TxATP | (TX_DMA_BURST << TxMXDMA_shift) | (TX_FILL_THRESH << TxFILLT_shift);
+    rx_flags = RX_DMA_BURST << RxMXDMA_shift;
+
+    if (speed == HW_SPEED_HOME || speed == HW_SPEED_10_MBPS) {
+        rx_flags |= (RxDRNT_10 << RxDRNT_shift);
+        tx_flags |= (TxDRNT_10 << TxDRNT_shift);
+    }
+    else {
+        rx_flags |= (RxDRNT_100 << RxDRNT_shift);
+        tx_flags |= (TxDRNT_100 << TxDRNT_shift);
+    }
+
+    if (duplex == FDX_CAPABLE_FULL_SELECTED) {
+        tx_flags |= (TxCSI | TxHBI);
+        rx_flags |= RxATX;
+    }
+
+    outl (tx_flags, ioaddr + txcfg);
+    outl (rx_flags, ioaddr + rxcfg);
+}
+
+
+/* Function: sis900_read_mode
+ *
+ * Description: retrieves and displays speed and duplex
+ *    parameters from the NIC
+ *    
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * Returns:   void.
+ */
+
+static void
+sis900_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex)
+{
+    int i = 0;
+    u32 status;
+        
+    /* STSOUT register is Latched on Transition, read operation updates it */
+    while (i++ < 2)
+        status = sis900_mdio_read(phy_addr, MII_STSOUT);
+
+    if (status & MII_STSOUT_SPD)
+        *speed = HW_SPEED_100_MBPS;
+    else
+        *speed = HW_SPEED_10_MBPS;
+
+    if (status & MII_STSOUT_DPLX)
+        *duplex = FDX_CAPABLE_FULL_SELECTED;
+    else
+        *duplex = FDX_CAPABLE_HALF_SELECTED;
+
+    if (status & MII_STSOUT_LINK_FAIL)
+        printf("sis900_read_mode: Media Link Off\n");
+    else
+        printf("sis900_read_mode: Media Link On %s %s-duplex \n", 
+               *speed == HW_SPEED_100_MBPS ? 
+               "100mbps" : "10mbps",
+               *duplex == FDX_CAPABLE_FULL_SELECTED ?
+               "full" : "half");
+}
+
+
+/* Function: amd79c901_read_mode
+ *
+ * Description: retrieves and displays speed and duplex
+ *    parameters from the NIC
+ *    
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * Returns:   void.
+ */
+
+static void
+amd79c901_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex)
+{
+    int i;
+    u16 status;
+        
+    for (i = 0; i < 2; i++)
+        status = sis900_mdio_read(phy_addr, MII_STATUS);
+
+    if (status & MII_STAT_CAN_AUTO) {
+        /* 10BASE-T PHY */
+        for (i = 0; i < 2; i++)
+            status = sis900_mdio_read(phy_addr, MII_STATUS_SUMMARY);
+        if (status & MII_STSSUM_SPD)
+            *speed = HW_SPEED_100_MBPS;
+        else
+            *speed = HW_SPEED_10_MBPS;
+        if (status & MII_STSSUM_DPLX)
+            *duplex = FDX_CAPABLE_FULL_SELECTED;
+        else
+            *duplex = FDX_CAPABLE_HALF_SELECTED;
+
+        if (status & MII_STSSUM_LINK)
+            printf("amd79c901_read_mode: Media Link On %s %s-duplex \n", 
+                   *speed == HW_SPEED_100_MBPS ? 
+                   "100mbps" : "10mbps",
+                   *duplex == FDX_CAPABLE_FULL_SELECTED ?
+                   "full" : "half");
+        else
+            printf("amd79c901_read_mode: Media Link Off\n");
+    }
+    else {
+        /* HomePNA */
+        *speed = HW_SPEED_HOME;
+        *duplex = FDX_CAPABLE_HALF_SELECTED;
+        if (status & MII_STAT_LINK)
+            printf("amd79c901_read_mode:Media Link On 1mbps half-duplex \n");
+        else
+            printf("amd79c901_read_mode: Media Link Off\n");
+    }
+}
+
+
+/**
+ *	ics1893_read_mode: - read media mode for ICS1893 PHY
+ *	@net_dev: the net device to read mode for
+ *	@phy_addr: mii phy address
+ *	@speed: the transmit speed to be determined
+ *	@duplex: the duplex mode to be determined
+ *
+ *	ICS1893 PHY use Quick Poll Detailed Status register
+ *	to determine the speed and duplex mode for sis900
+ */
+
+static void ics1893_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex)
+{
+	int i = 0;
+	u32 status;
+
+	/* MII_QPDSTS is Latched, read twice in succession will reflect the current state */
+	for (i = 0; i < 2; i++)
+		status = sis900_mdio_read(phy_addr, MII_QPDSTS);
+
+	if (status & MII_STSICS_SPD)
+		*speed = HW_SPEED_100_MBPS;
+	else
+		*speed = HW_SPEED_10_MBPS;
+
+	if (status & MII_STSICS_DPLX)
+		*duplex = FDX_CAPABLE_FULL_SELECTED;
+	else
+		*duplex = FDX_CAPABLE_HALF_SELECTED;
+
+	if (status & MII_STSICS_LINKSTS)
+		printf("ics1893_read_mode: Media Link On %s %s-duplex \n",
+		       *speed == HW_SPEED_100_MBPS ?
+		       "100mbps" : "10mbps",
+		       *duplex == FDX_CAPABLE_FULL_SELECTED ?
+		       "full" : "half");
+	else
+		printf("ics1893_read_mode: Media Link Off\n");
+}
+
+/**
+ *	rtl8201_read_mode: - read media mode for rtl8201 phy
+ *	@nic: the net device to read mode for
+ *	@phy_addr: mii phy address
+ *	@speed: the transmit speed to be determined
+ *	@duplex: the duplex mode to be determined
+ *
+ *	read MII_STATUS register from rtl8201 phy
+ *	to determine the speed and duplex mode for sis900
+ */
+
+static void rtl8201_read_mode(struct nic *nic, int phy_addr, int *speed, int *duplex)
+{
+	u32 status;
+
+	status = sis900_mdio_read(phy_addr, MII_STATUS);
+
+	if (status & MII_STAT_CAN_TX_FDX) {
+		*speed = HW_SPEED_100_MBPS;
+		*duplex = FDX_CAPABLE_FULL_SELECTED;
+	}
+	else if (status & MII_STAT_CAN_TX) {
+		*speed = HW_SPEED_100_MBPS;
+		*duplex = FDX_CAPABLE_HALF_SELECTED;
+	}
+	else if (status & MII_STAT_CAN_T_FDX) {
+		*speed = HW_SPEED_10_MBPS;
+		*duplex = FDX_CAPABLE_FULL_SELECTED;
+	}
+	else if (status & MII_STAT_CAN_T) {
+		*speed = HW_SPEED_10_MBPS;
+		*duplex = FDX_CAPABLE_HALF_SELECTED;
+	}
+
+	if (status & MII_STAT_LINK)
+		printf("rtl8201_read_mode: Media Link On %s %s-duplex \n",
+		       *speed == HW_SPEED_100_MBPS ?
+		       "100mbps" : "10mbps",
+		       *duplex == FDX_CAPABLE_FULL_SELECTED ?
+		       "full" : "half");
+	else
+		printf("rtl9201_read_config_mode: Media Link Off\n");
+}
+
+/* Function: sis900_transmit
+ *
+ * Description: transmits a packet and waits for completion or timeout.
+ *
+ * Arguments: char d[6]:          destination ethernet address.
+ *            unsigned short t:   ethernet protocol type.
+ *            unsigned short s:   size of the data-part of the packet.
+ *            char *p:            the data for the packet.
+ *    
+ * Returns:   void.
+ */
+
+static void
+sis900_transmit(struct nic  *nic,
+                const char  *d,     /* Destination */
+                unsigned int t,     /* Type */
+                unsigned int s,     /* size */
+                const char  *p)     /* Packet */
+{
+    u32 status, to, nstype;
+    u32 tx_status;
+    
+    /* Stop the transmitter */
+    outl(TxDIS, ioaddr + cr);
+
+    /* load Transmit Descriptor Register */
+    outl((u32) &txd, ioaddr + txdp); 
+    if (sis900_debug > 1)
+        printf("sis900_transmit: TX descriptor register loaded with: %X\n", 
+               inl(ioaddr + txdp));
+
+    memcpy(txb, d, ETH_ALEN);
+    memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);
+    nstype = htons(t);
+    memcpy(txb + 2 * ETH_ALEN, (char*)&nstype, 2);
+    memcpy(txb + ETH_HLEN, p, s);
+
+    s += ETH_HLEN;
+    s &= DSIZE;
+
+    if (sis900_debug > 1)
+        printf("sis900_transmit: sending %d bytes ethtype %hX\n", (int) s, t);
+
+    /* pad to minimum packet size */
+    while (s < ETH_ZLEN)  
+        txb[s++] = '\0';
+
+    /* set the transmit buffer descriptor and enable Transmit State Machine */
+    txd.bufptr = (u32) &txb[0];
+    txd.cmdsts = (u32) OWN | s;
+
+    /* restart the transmitter */
+    outl(TxENA, ioaddr + cr);
+
+    if (sis900_debug > 1)
+        printf("sis900_transmit: Queued Tx packet size %d.\n", (int) s);
+
+    to = currticks() + TX_TIMEOUT;
+
+    while ((((volatile u32) tx_status=txd.cmdsts) & OWN) && (currticks() < to))
+        /* wait */ ;
+
+    if (currticks() >= to) {
+        printf("sis900_transmit: TX Timeout! Tx status %X.\n", tx_status);
+    }
+    
+    if (tx_status & (ABORT | UNDERRUN | OWCOLL)) {
+        /* packet unsuccessfully transmited */
+        printf("sis900_transmit: Transmit error, Tx status %X.\n", tx_status);
+    }
+    /* Disable interrupts by clearing the interrupt mask. */
+    outl(0, ioaddr + imr);
+}
+
+
+/* Function: sis900_poll
+ *
+ * Description: checks for a received packet and returns it if found.
+ *
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * Returns:   1 if a packet was recieved.
+ *            0 if no pacet was recieved.
+ *
+ * Side effects:
+ *            Returns (copies) the packet to the array nic->packet.
+ *            Returns the length of the packet in nic->packetlen.
+ */
+
+static int
+sis900_poll(struct nic *nic)
+{
+    u32 rx_status = rxd[cur_rx].cmdsts;
+    int retstat = 0;
+
+    if (sis900_debug > 2)
+        printf("sis900_poll: cur_rx:%d, status:%X\n", cur_rx, rx_status);
+
+    if (!(rx_status & OWN))
+        return retstat;
+
+    if (sis900_debug > 1)
+        printf("sis900_poll: got a packet: cur_rx:%d, status:%X\n",
+               cur_rx, rx_status);
+
+    nic->packetlen = (rx_status & DSIZE) - CRC_SIZE;
+
+    if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) {
+        /* corrupted packet received */
+        printf("sis900_poll: Corrupted packet received, buffer status = %X\n",
+               rx_status);
+        retstat = 0;
+    } else {
+        /* give packet to higher level routine */
+        memcpy(nic->packet, (rxb + cur_rx*RX_BUF_SIZE), nic->packetlen);
+        retstat = 1;
+    }
+
+    /* return the descriptor and buffer to receive ring */
+    rxd[cur_rx].cmdsts = RX_BUF_SIZE;
+    rxd[cur_rx].bufptr = (u32) &rxb[cur_rx*RX_BUF_SIZE];
+        
+    if (++cur_rx == NUM_RX_DESC)
+        cur_rx = 0;
+
+    /* re-enable the potentially idle receive state machine */
+    outl(RxENA , ioaddr + cr);
+
+    return retstat;
+}
+
+
+/* Function: sis900_disable
+ *
+ * Description: Turns off interrupts and stops Tx and Rx engines
+ *    
+ * Arguments: struct nic *nic:          NIC data structure
+ *
+ * Returns:   void.
+ */
+
+static void
+sis900_disable(struct nic *nic)
+{
+    /* Disable interrupts by clearing the interrupt mask. */
+    outl(0, ioaddr + imr);
+    outl(0, ioaddr + ier);
+    
+    /* Stop the chip's Tx and Rx Status Machine */
+    outl(RxDIS | TxDIS, ioaddr + cr);
+}
diff --git a/netboot/sis900.h b/netboot/sis900.h
new file mode 100644
index 0000000..44feafb
--- /dev/null
+++ b/netboot/sis900.h
@@ -0,0 +1,363 @@
+/* -*- Mode:C; c-basic-offset:4; -*- */
+
+/* Definitions for SiS ethernet controllers including 7014/7016 and 900 
+ * References:
+ *   SiS 7016 Fast Ethernet PCI Bus 10/100 Mbps LAN Controller with OnNow Support,
+ *      preliminary Rev. 1.0 Jan. 14, 1998
+ *   SiS 900 Fast Ethernet PCI Bus 10/100 Mbps LAN Single Chip with OnNow Support,
+ *      preliminary Rev. 1.0 Nov. 10, 1998
+ *   SiS 7014 Single Chip 100BASE-TX/10BASE-T Physical Layer Solution,
+ *      preliminary Rev. 1.0 Jan. 18, 1998
+ *   http://www.sis.com.tw/support/databook.htm
+ */
+
+/* MAC operationl registers of SiS 7016 and SiS 900 ethernet controller */
+/* The I/O extent, SiS 900 needs 256 bytes of io address */
+#define SIS900_TOTAL_SIZE 0x100
+
+/* Symbolic offsets to registers. */
+enum sis900_registers {
+    cr=0x0,                 /* Command Register */
+    cfg=0x4,                /* Configuration Register */
+    mear=0x8,               /* EEPROM Access Register */
+    ptscr=0xc,              /* PCI Test Control Register */
+    isr=0x10,               /* Interrupt Status Register */
+    imr=0x14,               /* Interrupt Mask Register */
+    ier=0x18,               /* Interrupt Enable Register */
+    epar=0x18,              /* Enhanced PHY Access Register */
+    txdp=0x20,              /* Transmit Descriptor Pointer Register */
+    txcfg=0x24,             /* Transmit Configuration Register */
+    rxdp=0x30,              /* Receive Descriptor Pointer Register */
+    rxcfg=0x34,             /* Receive Configuration Register */
+    flctrl=0x38,            /* Flow Control Register */
+    rxlen=0x3c,             /* Receive Packet Length Register */
+    rfcr=0x48,              /* Receive Filter Control Register */
+    rfdr=0x4C,              /* Receive Filter Data Register */
+    pmctrl=0xB0,            /* Power Management Control Register */
+    pmer=0xB4               /* Power Management Wake-up Event Register */
+};
+
+/* Symbolic names for bits in various registers */
+enum sis900_command_register_bits {
+    RESET   = 0x00000100, 
+    SWI     = 0x00000080, 
+    RxRESET = 0x00000020,
+    TxRESET = 0x00000010, 
+    RxDIS   = 0x00000008, 
+    RxENA   = 0x00000004,
+    TxDIS   = 0x00000002, 
+    TxENA   = 0x00000001
+};
+
+enum sis900_configuration_register_bits {
+    DESCRFMT = 0x00000100, /* 7016 specific */
+    REQALG   = 0x00000080, 
+    SB       = 0x00000040, 
+    POW      = 0x00000020, 
+    EXD      = 0x00000010, 
+    PESEL    = 0x00000008, 
+    LPM      = 0x00000004, 
+    BEM      = 0x00000001
+};
+
+enum sis900_eeprom_access_reigster_bits {
+    MDC   = 0x00000040, 
+    MDDIR = 0x00000020, 
+    MDIO  = 0x00000010, /* 7016 specific */ 
+    EECS  = 0x00000008, 
+    EECLK = 0x00000004, 
+    EEDO  = 0x00000002,
+    EEDI  = 0x00000001
+};
+
+enum sis900_interrupt_register_bits {
+    WKEVT      = 0x10000000, 
+    TxPAUSEEND = 0x08000000,
+    TxPAUSE    = 0x04000000,
+    TxRCMP     = 0x02000000,
+    RxRCMP     = 0x01000000,
+    DPERR      = 0x00800000,
+    SSERR      = 0x00400000,
+    RMABT      = 0x00200000,
+    RTABT      = 0x00100000,
+    RxSOVR     = 0x00010000, 
+    HIBERR     = 0x00008000, 
+    SWINT      = 0x00001000,
+    MIBINT     = 0x00000800, 
+    TxURN      = 0x00000400,
+    TxIDLE     = 0x00000200,
+    TxERR      = 0x00000100,
+    TxDESC     = 0x00000080,
+    TxOK       = 0x00000040,
+    RxORN      = 0x00000020, 
+    RxIDLE     = 0x00000010,
+    RxEARLY    = 0x00000008,
+    RxERR      = 0x00000004,
+    RxDESC     = 0x00000002,
+    RxOK       = 0x00000001
+};
+
+enum sis900_interrupt_enable_reigster_bits {
+    IE = 0x00000001
+};
+
+/* maximum dma burst fro transmission and receive*/
+#define MAX_DMA_RANGE   7       /* actually 0 means MAXIMUM !! */
+#define TxMXDMA_shift   20
+#define RxMXDMA_shift   20
+#define TX_DMA_BURST    0
+#define RX_DMA_BURST    0
+
+/* transmit FIFO threshholds */
+#define TX_FILL_THRESH  16      /* 1/4 FIFO size */
+#define TxFILLT_shift   8
+#define TxDRNT_shift    0
+#define TxDRNT_100      48      /* 3/4 FIFO size */
+#define TxDRNT_10       16      /* 1/2 FIFO size */
+
+enum sis900_transmit_config_register_bits {
+    TxCSI   = 0x80000000,
+    TxHBI   = 0x40000000,
+    TxMLB   = 0x20000000,
+    TxATP   = 0x10000000,
+    TxIFG   = 0x0C000000,
+    TxFILLT = 0x00003F00,
+    TxDRNT  = 0x0000003F
+};
+
+/* recevie FIFO thresholds */
+#define RxDRNT_shift     1
+#define RxDRNT_100      16      /* 1/2 FIFO size */
+#define RxDRNT_10       24      /* 3/4 FIFO size */
+
+enum sis900_reveive_config_register_bits {
+    RxAEP  = 0x80000000, 
+    RxARP  = 0x40000000, 
+    RxATX  = 0x10000000,
+    RxAJAB = 0x08000000, 
+    RxDRNT = 0x0000007F
+};
+
+#define RFAA_shift      28
+#define RFADDR_shift    16
+
+enum sis900_receive_filter_control_register_bits {
+    RFEN  = 0x80000000, 
+    RFAAB = 0x40000000, 
+    RFAAM = 0x20000000,
+    RFAAP = 0x10000000, 
+    RFPromiscuous = (RFAAB|RFAAM|RFAAP)
+};
+
+enum sis900_reveive_filter_data_mask {
+    RFDAT =  0x0000FFFF
+};
+
+/* EEPROM Addresses */
+enum sis900_eeprom_address {
+    EEPROMSignature = 0x00, 
+    EEPROMVendorID  = 0x02, 
+    EEPROMDeviceID  = 0x03,
+    EEPROMMACAddr   = 0x08, 
+    EEPROMChecksum  = 0x0b
+};
+
+/* The EEPROM commands include the alway-set leading bit. Refer to NM93Cxx datasheet */
+enum sis900_eeprom_command {
+    EEread          = 0x0180, 
+    EEwrite         = 0x0140, 
+    EEerase         = 0x01C0, 
+    EEwriteEnable   = 0x0130,
+    EEwriteDisable  = 0x0100,
+    EEeraseAll      = 0x0120,
+    EEwriteAll      = 0x0110, 
+    EEaddrMask      = 0x013F, 
+};
+
+/* Manamgement Data I/O (mdio) frame */
+#define MIIread         0x6000
+#define MIIwrite        0x5002
+#define MIIpmdShift     7
+#define MIIregShift     2
+#define MIIcmdLen       16
+#define MIIcmdShift     16
+
+/* Buffer Descriptor Status*/
+enum sis900_buffer_status {
+    OWN    = 0x80000000, 
+    MORE   = 0x40000000, 
+    INTR   = 0x20000000,
+    SUPCRC = 0x10000000, 
+    INCCRC = 0x10000000,
+    OK     = 0x08000000, 
+    DSIZE  = 0x00000FFF
+};
+
+/* Status for TX Buffers */
+enum sis900_tx_buffer_status {
+    ABORT      = 0x04000000,
+    UNDERRUN   = 0x02000000, 
+    NOCARRIER  = 0x01000000,
+    DEFERD     = 0x00800000, 
+    EXCDEFER   = 0x00400000, 
+    OWCOLL     = 0x00200000,
+    EXCCOLL    = 0x00100000, 
+    COLCNT     = 0x000F0000
+};
+
+enum sis900_rx_bufer_status {
+    OVERRUN    = 0x02000000,
+    DEST       = 0x00800000,
+    BCAST      = 0x01800000,
+    MCAST      = 0x01000000,
+    UNIMATCH   = 0x00800000,
+    TOOLONG    = 0x00400000,
+    RUNT       = 0x00200000,
+    RXISERR    = 0x00100000,
+    CRCERR     = 0x00080000,
+    FAERR      = 0x00040000,
+    LOOPBK     = 0x00020000,
+    RXCOL      = 0x00010000
+};
+
+/* MII register offsets */
+enum mii_registers {
+    MII_CONTROL = 0x0000, 
+    MII_STATUS  = 0x0001,
+    MII_PHY_ID0 = 0x0002,
+    MII_PHY_ID1 = 0x0003,
+    MII_ANADV   = 0x0004,
+    MII_ANLPAR  = 0x0005,
+    MII_ANEXT   = 0x0006
+};
+
+/* mii registers specific to SiS 900 */
+enum sis_mii_registers {
+    MII_CONFIG1 = 0x0010,
+    MII_CONFIG2 = 0x0011,
+    MII_STSOUT  = 0x0012,
+    MII_MASK    = 0x0013
+};
+
+/* mii registers specific to AMD 79C901 */
+enum amd_mii_registers {
+    MII_STATUS_SUMMARY = 0x0018
+};
+
+/* mii registers specific to ICS 1893 */
+enum ics_mii_registers {
+	MII_EXTCTRL  = 0x0010, MII_QPDSTS = 0x0011, MII_10BTOP = 0x0012,
+	MII_EXTCTRL2 = 0x0013
+};
+
+
+
+/* MII Control register bit definitions. */
+enum mii_control_register_bits {
+    MII_CNTL_FDX      = 0x0100,
+    MII_CNTL_RST_AUTO = 0x0200, 
+    MII_CNTL_ISOLATE  = 0x0400,
+    MII_CNTL_PWRDWN   = 0x0800,
+    MII_CNTL_AUTO     = 0x1000,
+    MII_CNTL_SPEED    = 0x2000,
+    MII_CNTL_LPBK     = 0x4000,
+    MII_CNTL_RESET    = 0x8000
+};
+
+/* MII Status register bit  */
+enum mii_status_register_bits {
+    MII_STAT_EXT        = 0x0001,
+    MII_STAT_JAB        = 0x0002, 
+    MII_STAT_LINK       = 0x0004,
+    MII_STAT_CAN_AUTO   = 0x0008, 
+    MII_STAT_FAULT      = 0x0010,
+    MII_STAT_AUTO_DONE  = 0x0020,
+    MII_STAT_CAN_T      = 0x0800, 
+    MII_STAT_CAN_T_FDX  = 0x1000,
+    MII_STAT_CAN_TX     = 0x2000, 
+    MII_STAT_CAN_TX_FDX = 0x4000,
+    MII_STAT_CAN_T4     = 0x8000
+};
+
+#define         MII_ID1_OUI_LO          0xFC00  /* low bits of OUI mask */
+#define         MII_ID1_MODEL           0x03F0  /* model number */
+#define         MII_ID1_REV             0x000F  /* model number */
+
+/* MII NWAY Register Bits ...
+   valid for the ANAR (Auto-Negotiation Advertisement) and
+   ANLPAR (Auto-Negotiation Link Partner) registers */
+enum mii_nway_register_bits {
+    MII_NWAY_NODE_SEL = 0x001f,
+    MII_NWAY_CSMA_CD  = 0x0001,
+    MII_NWAY_T        = 0x0020,
+    MII_NWAY_T_FDX    = 0x0040,
+    MII_NWAY_TX       = 0x0080,
+    MII_NWAY_TX_FDX   = 0x0100,
+    MII_NWAY_T4       = 0x0200,
+    MII_NWAY_PAUSE    = 0x0400,
+    MII_NWAY_RF       = 0x2000,
+    MII_NWAY_ACK      = 0x4000,
+    MII_NWAY_NP       = 0x8000
+};
+
+enum mii_stsout_register_bits {
+    MII_STSOUT_LINK_FAIL = 0x4000,
+    MII_STSOUT_SPD       = 0x0080,
+    MII_STSOUT_DPLX      = 0x0040
+};
+
+enum mii_stsics_register_bits {
+	MII_STSICS_SPD  = 0x8000, MII_STSICS_DPLX = 0x4000,
+	MII_STSICS_LINKSTS = 0x0001
+};
+
+enum mii_stssum_register_bits {
+    MII_STSSUM_LINK = 0x0008,
+    MII_STSSUM_DPLX = 0x0004,
+    MII_STSSUM_AUTO = 0x0002,
+    MII_STSSUM_SPD  = 0x0001
+};
+
+enum sis900_revision_id {
+	SIS630A_900_REV = 0x80,		SIS630E_900_REV = 0x81,
+	SIS630S_900_REV = 0x82,		SIS630EA1_900_REV = 0x83
+};
+
+enum sis630_revision_id {
+	SIS630A0    = 0x00, SIS630A1      = 0x01,
+	SIS630B0    = 0x10, SIS630B1      = 0x11
+};
+
+#define FDX_CAPABLE_DUPLEX_UNKNOWN      0
+#define FDX_CAPABLE_HALF_SELECTED       1
+#define FDX_CAPABLE_FULL_SELECTED       2
+
+#define HW_SPEED_UNCONFIG               0
+#define HW_SPEED_HOME                   1
+#define HW_SPEED_10_MBPS                10
+#define HW_SPEED_100_MBPS               100
+#define HW_SPEED_DEFAULT                (HW_SPEED_100_MBPS)
+
+#define CRC_SIZE        4
+#define MAC_HEADER_SIZE 14
+
+#define TX_BUF_SIZE     1536
+#define RX_BUF_SIZE     1536
+
+#define NUM_RX_DESC     4              /* Number of Rx descriptor registers. */
+
+typedef unsigned char  u8;
+typedef   signed char  s8;
+typedef unsigned short u16;
+typedef   signed short s16;
+typedef unsigned int   u32;
+typedef   signed int   s32;
+
+/* Time in ticks before concluding the transmitter is hung. */
+#define TX_TIMEOUT       (4*TICKS_PER_SEC)
+
+typedef struct _BufferDesc {
+    u32              link;
+    volatile u32     cmdsts;
+    u32              bufptr;
+} BufferDesc;
diff --git a/netboot/sis900.txt b/netboot/sis900.txt
new file mode 100644
index 0000000..77419fa
--- /dev/null
+++ b/netboot/sis900.txt
@@ -0,0 +1,91 @@
+How I added the SIS900 card to Etherboot
+
+Author: Marty Connor (mdc@thinguin.org)
+
+Date:   25 Febrary 2001
+
+Description:
+
+This file is intended to help people who want to write an Etherboot
+driver or port another driver to Etherboot.  It is a starting point.
+Perhaps someday I may write a more detailed description of writing an
+Etherboot driver. This text should help get people started, and
+studying sis900.[ch] should help show the basic structure and
+techniques involved in writing and Etherboot driver.
+
+***********************************************************************
+
+0. Back up all the files I need to modify:
+
+cd etherboot-4.7.20/src
+cp Makefile Makefile.orig
+cp config.c config.c.orig
+cp pci.h pci.h.orig
+cp NIC NIC.orig
+cp cards.h cards.h.orig
+
+1. Edit src/Makefile to add SIS900FLAGS to defines
+
+SIS900FLAGS=	       	-DINCLUDE_SIS900
+
+2. edit src/pci.h to add PCI signatures for card
+
+#define PCI_VENDOR_ID_SIS         	0x1039
+#define PCI_DEVICE_ID_SIS900     	0x0900   
+#define PCI_DEVICE_ID_SIS7016    	0x7016  
+
+3. Edit src/config.c to add the card to the card probe list
+
+#if defined(INCLUDE_NS8390)  || defined(INCLUDE_EEPRO100)  || 
+    defined(INCLUDE_LANCE)   || defined(INCLUDE_EPIC100)   || 
+    defined(INCLUDE_TULIP)   || defined(INCLUDE_OTULIP)    ||
+    defined(INCLUDE_3C90X)   || defined(INCLUDE_3C595)     ||
+    defined(INCLUDE_RTL8139) || defined(INCLUDE_VIA_RHINE) || 
+    defined(INCLUDE_SIS900)  || defined(INCLUDE_W89C840)
+
+... and ...
+
+#ifdef INCLUDE_SIS900
+       { PCI_VENDOR_ID_SIS,     	PCI_DEVICE_ID_SIS900,
+         "SIS900", 0, 0, 0, 0},
+       { PCI_VENDOR_ID_SIS,     	PCI_DEVICE_ID_SIS7016,
+	 "SIS7016", 0, 0, 0, 0},
+#endif
+
+... and ...
+
+#ifdef INCLUDE_SIS900
+	{ "SIS900", sis900_probe, pci_ioaddrs },	
+#endif
+
+4. Edit NIC to add sis900 and sis7016 to NIC list
+
+# SIS 900 and SIS 7016
+sis900		sis900		0x1039,0x0900
+sis7016		sis900		0x1039,0x7016
+
+5. Edit cards.h to add sis900 probe routine declaration
+
+#ifdef	INCLUDE_SIS900
+extern struct nic	*sis900_probe(struct nic *, unsigned short *
+                        PCI_ARG(struct pci_device *));
+#endif
+
+***********************************************************************
+
+At this point, you can begin creating your driver source file.  See
+the "Writing and Etherboot Driver" section of the Etherboot
+documentation for some hints.  See the skel.c file for a starting
+point.  If there is a Linux driver for the card, you may be able to
+use that.  Copy and learn from existing Etherboot drivers (this is GPL
+/ Open Source software!).
+
+Join the etherboot-developers and etherboot-users mailing lists
+(information is on etherboot.sourceforge.net) for information and
+assistance. We invite more developers to help improve Etherboot.
+
+Visit the http://etherboot.sourceforge.net, http://thinguin.org, 
+http://rom-o-matic.net, and http://ltsp.org sites for information and
+assistance.
+
+Enjoy.
diff --git a/netboot/sk_g16.c b/netboot/sk_g16.c
new file mode 100644
index 0000000..46e5183
--- /dev/null
+++ b/netboot/sk_g16.c
@@ -0,0 +1,1160 @@
+/**************************************************************************
+Etherboot -  BOOTP/TFTP Bootstrap Program
+Schneider & Koch G16 NIC driver for Etherboot
+heavily based on SK G16 driver from Linux 2.0.36
+Changes to make it work with Etherboot by Georg Baum <Georg.Baum@gmx.de>
+***************************************************************************/
+
+/*-
+ * Copyright (C) 1994 by PJD Weichmann & SWS Bern, Switzerland
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU Public License, incorporated herein by reference.
+ *
+ * Module         : sk_g16.c
+ *
+ * Version        : $Revision: 1.4 $
+ *
+ * Author         : Patrick J.D. Weichmann
+ *
+ * Date Created   : 94/05/26
+ * Last Updated   : $Date: 2002/01/02 21:56:40 $
+ *
+ * Description    : Schneider & Koch G16 Ethernet Device Driver for
+ *                  Linux Kernel >= 1.1.22
+ * Update History :
+ *
+-*/
+
+/*
+ * The Schneider & Koch (SK) G16 Network device driver is based
+ * on the 'ni6510' driver from Michael Hipp which can be found at
+ * ftp://sunsite.unc.edu/pub/Linux/system/Network/drivers/nidrivers.tar.gz
+ *
+ * Sources: 1) ni6510.c by M. Hipp
+ *          2) depca.c  by D.C. Davies
+ *          3) skeleton.c by D. Becker
+ *          4) Am7990 Local Area Network Controller for Ethernet (LANCE),
+ *             AMD, Pub. #05698, June 1989
+ *
+ * Many Thanks for helping me to get things working to:
+ *
+ *                 A. Cox (A.Cox@swansea.ac.uk)
+ *                 M. Hipp (mhipp@student.uni-tuebingen.de)
+ *                 R. Bolz (Schneider & Koch, Germany)
+ *
+ * See README.sk_g16 for details about limitations and bugs for the
+ * current version.
+ *
+ * To Do:
+ *        - Support of SK_G8 and other SK Network Cards.
+ *        - Autoset memory mapped RAM. Check for free memory and then
+ *          configure RAM correctly.
+ *        - SK_close should really set card in to initial state.
+ *        - Test if IRQ 3 is not switched off. Use autoirq() functionality.
+ *          (as in /drivers/net/skeleton.c)
+ *        - Implement Multicast addressing. At minimum something like
+ *          in depca.c.
+ *        - Redo the statistics part.
+ *        - Try to find out if the board is in 8 Bit or 16 Bit slot.
+ *          If in 8 Bit mode don't use IRQ 11.
+ *        - (Try to make it slightly faster.)
+ */
+
+/* to get some global routines like printf */
+#include "etherboot.h"
+/* to get the interface to the body of the program */
+#include "nic.h"
+
+/* From linux/if_ether.h: */
+#define ETH_ZLEN	60		/* Min. octets in frame sans FCS */
+
+#include "sk_g16.h"
+
+/*
+ * Schneider & Koch Card Definitions
+ * =================================
+ */
+
+#define SK_NAME   "SK_G16"
+
+/*
+ * SK_G16 Configuration
+ * --------------------
+ */
+
+/*
+ * Abbreviations
+ * -------------
+ *
+ * RAM - used for the 16KB shared memory
+ * Boot_ROM, ROM - are used for referencing the BootEPROM
+ *
+ * SK_ADDR is a symbolic constant used to configure
+ * the behaviour of the driver and the SK_G16.
+ *
+ * SK_ADDR defines the address where the RAM will be mapped into the real
+ *         host memory.
+ *         valid addresses are from 0xa0000 to 0xfc000 in 16Kbyte steps.
+ */
+
+#define SK_ADDR         0xcc000
+
+/*
+ * In POS3 are bits A14-A19 of the address bus. These bits can be set
+ * to choose the RAM address. That's why we only can choose the RAM address
+ * in 16KB steps.
+ */
+
+#define POS_ADDR       (rom_addr>>14)  /* Do not change this line */
+
+/*
+ * SK_G16 I/O PORT's + IRQ's + Boot_ROM locations
+ * ----------------------------------------------
+ */
+
+/*
+ * As nearly every card has also SK_G16 a specified I/O Port region and
+ * only a few possible IRQ's.
+ * In the Installation Guide from Schneider & Koch is listed a possible
+ * Interrupt IRQ2. IRQ2 is always IRQ9 in boards with two cascaded interrupt
+ * controllers. So we use in SK_IRQS IRQ9.
+ */
+
+/* Don't touch any of the following #defines. */
+
+#define SK_IO_PORTS     { 0x100, 0x180, 0x208, 0x220, 0x288, 0x320, 0x328, 0x390, 0 }
+
+/*
+ * SK_G16 POS REGISTERS
+ * --------------------
+ */
+
+/*
+ * SK_G16 has a Programmable Option Select (POS) Register.
+ * The POS is composed of 8 separate registers (POS0-7) which
+ * are I/O mapped on an address set by the W1 switch.
+ *
+ */
+
+#define SK_POS_SIZE 8           /* 8 I/O Ports are used by SK_G16 */
+
+#define SK_POS0     ioaddr      /* Card-ID Low (R) */
+#define SK_POS1     ioaddr+1    /* Card-ID High (R) */
+#define SK_POS2     ioaddr+2    /* Card-Enable, Boot-ROM Disable (RW) */
+#define SK_POS3     ioaddr+3    /* Base address of RAM */
+#define SK_POS4     ioaddr+4    /* IRQ */
+
+/* POS5 - POS7 are unused */
+
+/*
+ * SK_G16 MAC PREFIX
+ * -----------------
+ */
+
+/*
+ * Scheider & Koch manufacturer code (00:00:a5).
+ * This must be checked, that we are sure it is a SK card.
+ */
+
+#define SK_MAC0         0x00
+#define SK_MAC1         0x00
+#define SK_MAC2         0x5a
+
+/*
+ * SK_G16 ID
+ * ---------
+ */
+
+/*
+ * If POS0,POS1 contain the following ID, then we know
+ * at which I/O Port Address we are.
+ */
+
+#define SK_IDLOW  0xfd
+#define SK_IDHIGH 0x6a
+
+
+/*
+ * LANCE POS Bit definitions
+ * -------------------------
+ */
+
+#define SK_ROM_RAM_ON  (POS2_CARD)
+#define SK_ROM_RAM_OFF (POS2_EPROM)
+#define SK_ROM_ON      (inb(SK_POS2) & POS2_CARD)
+#define SK_ROM_OFF     (inb(SK_POS2) | POS2_EPROM)
+#define SK_RAM_ON      (inb(SK_POS2) | POS2_CARD)
+#define SK_RAM_OFF     (inb(SK_POS2) & POS2_EPROM)
+
+#define POS2_CARD  0x0001              /* 1 = SK_G16 on      0 = off */
+#define POS2_EPROM 0x0002              /* 1 = Boot EPROM off 0 = on */
+
+/*
+ * SK_G16 Memory mapped Registers
+ * ------------------------------
+ *
+ */
+
+#define SK_IOREG        (board->ioreg) /* LANCE data registers.     */
+#define SK_PORT         (board->port)  /* Control, Status register  */
+#define SK_IOCOM        (board->iocom) /* I/O Command               */
+
+/*
+ * SK_G16 Status/Control Register bits
+ * -----------------------------------
+ *
+ * (C) Controlreg (S) Statusreg
+ */
+
+/*
+ * Register transfer: 0 = no transfer
+ *                    1 = transferring data between LANCE and I/O reg
+ */
+#define SK_IORUN        0x20
+
+/*
+ * LANCE interrupt: 0 = LANCE interrupt occurred
+ *                  1 = no LANCE interrupt occurred
+ */
+#define SK_IRQ          0x10
+
+#define SK_RESET        0x08   /* Reset SK_CARD: 0 = RESET 1 = normal */
+#define SK_RW           0x02   /* 0 = write to 1 = read from */
+#define SK_ADR          0x01   /* 0 = REG DataPort 1 = RAP Reg addr port */
+
+
+#define SK_RREG         SK_RW  /* Transferdirection to read from lance */
+#define SK_WREG         0      /* Transferdirection to write to lance */
+#define SK_RAP          SK_ADR /* Destination Register RAP */
+#define SK_RDATA        0      /* Destination Register REG DataPort */
+
+/*
+ * SK_G16 I/O Command
+ * ------------------
+ */
+
+/*
+ * Any bitcombination sets the internal I/O bit (transfer will start)
+ * when written to I/O Command
+ */
+
+#define SK_DOIO         0x80   /* Do Transfer */
+
+/*
+ * LANCE RAP (Register Address Port).
+ * ---------------------------------
+ */
+
+/*
+ * The LANCE internal registers are selected through the RAP.
+ * The Registers are:
+ *
+ * CSR0 - Status and Control flags
+ * CSR1 - Low order bits of initialize block (bits 15:00)
+ * CSR2 - High order bits of initialize block (bits 07:00, 15:08 are reserved)
+ * CSR3 - Allows redefinition of the Bus Master Interface.
+ *        This register must be set to 0x0002, which means BSWAP = 0,
+ *        ACON = 1, BCON = 0;
+ *
+ */
+
+#define CSR0            0x00
+#define CSR1            0x01
+#define CSR2            0x02
+#define CSR3            0x03
+
+/*
+ * General Definitions
+ * ===================
+ */
+
+/*
+ * Set the number of Tx and Rx buffers, using Log_2(# buffers).
+ * We have 16KB RAM which can be accessed by the LANCE. In the
+ * memory are not only the buffers but also the ring descriptors and
+ * the initialize block.
+ * Don't change anything unless you really know what you do.
+ */
+
+#define LC_LOG_TX_BUFFERS 1               /* (2 == 2^^1) 2 Transmit buffers */
+#define LC_LOG_RX_BUFFERS 2               /* (8 == 2^^3) 8 Receive buffers */
+
+/* Descriptor ring sizes */
+
+#define TMDNUM (1 << (LC_LOG_TX_BUFFERS)) /* 2 Transmit descriptor rings */
+#define RMDNUM (1 << (LC_LOG_RX_BUFFERS)) /* 8 Receive Buffers */
+
+/* Define Mask for setting RMD, TMD length in the LANCE init_block */
+
+#define TMDNUMMASK (LC_LOG_TX_BUFFERS << 29)
+#define RMDNUMMASK (LC_LOG_RX_BUFFERS << 29)
+
+/*
+ * Data Buffer size is set to maximum packet length.
+ */
+
+#define PKT_BUF_SZ              1518
+
+/*
+ * The number of low I/O ports used by the ethercard.
+ */
+
+#define ETHERCARD_TOTAL_SIZE    SK_POS_SIZE
+
+/*
+ * Portreserve is there to mark the Card I/O Port region as used.
+ * Check_region is to check if the region at ioaddr with the size "size"
+ * is free or not.
+ * Snarf_region allocates the I/O Port region.
+ */
+
+#ifndef	HAVE_PORTRESERVE
+
+#define check_region(ioaddr1, size)              0
+#define request_region(ioaddr1, size,name)       do ; while (0)
+
+#endif
+
+/*
+ * SK_DEBUG
+ *
+ * Here you can choose what level of debugging wanted.
+ *
+ * If SK_DEBUG and SK_DEBUG2 are undefined, then only the
+ *  necessary messages will be printed.
+ *
+ * If SK_DEBUG is defined, there will be many debugging prints
+ *  which can help to find some mistakes in configuration or even
+ *  in the driver code.
+ *
+ * If SK_DEBUG2 is defined, many many messages will be printed
+ *  which normally you don't need. I used this to check the interrupt
+ *  routine.
+ *
+ * (If you define only SK_DEBUG2 then only the messages for
+ *  checking interrupts will be printed!)
+ *
+ * Normal way of live is:
+ *
+ * For the whole thing get going let both symbolic constants
+ * undefined. If you face any problems and you know what's going
+ * on (you know something about the card and you can interpret some
+ * hex LANCE register output) then define SK_DEBUG
+ *
+ */
+
+#undef  SK_DEBUG	/* debugging */
+#undef  SK_DEBUG2	/* debugging with more verbose report */
+
+#ifdef	SK_DEBUG
+#define PRINTF(x) printf x
+#else
+#define PRINTF(x) /**/
+#endif
+
+#ifdef	SK_DEBUG2
+#define PRINTF2(x) printf x
+#else
+#define PRINTF2(x) /**/
+#endif
+
+/*
+ * SK_G16 RAM
+ *
+ * The components are memory mapped and can be set in a region from
+ * 0x00000 through 0xfc000 in 16KB steps.
+ *
+ * The Network components are: dual ported RAM, Prom, I/O Reg, Status-,
+ * Controlregister and I/O Command.
+ *
+ * dual ported RAM: This is the only memory region which the LANCE chip
+ *      has access to. From the Lance it is addressed from 0x0000 to
+ *      0x3fbf. The host accesses it normally.
+ *
+ * PROM: The PROM obtains the ETHERNET-MAC-Address. It is realised as a
+ *       8-Bit PROM, this means only the 16 even addresses are used of the
+ *       32 Byte Address region. Access to a odd address results in invalid
+ *       data.
+ *
+ * LANCE I/O Reg: The I/O Reg is build of 4 single Registers, Low-Byte Write,
+ *       Hi-Byte Write, Low-Byte Read, Hi-Byte Read.
+ *       Transfer from or to the LANCE is always in 16Bit so Low and High
+ *       registers are always relevant.
+ *
+ *       The Data from the Readregister is not the data in the Writeregister!!
+ *
+ * Port: Status- and Controlregister.
+ *       Two different registers which share the same address, Status is
+ *       read-only, Control is write-only.
+ *
+ * I/O Command:
+ *       Any bitcombination written in here starts the transmission between
+ *       Host and LANCE.
+ */
+
+typedef struct
+{
+	unsigned char  ram[0x3fc0];   /* 16KB dual ported ram */
+	unsigned char  rom[0x0020];   /* 32Byte PROM containing 6Byte MAC */
+	unsigned char  res1[0x0010];  /* reserved */
+	unsigned volatile short ioreg;/* LANCE I/O Register */
+	unsigned volatile char  port; /* Statusregister and Controlregister */
+	unsigned char  iocom;         /* I/O Command Register */
+} SK_RAM;
+
+/* struct  */
+
+/*
+ * This is the structure for the dual ported ram. We
+ * have exactly 16 320 Bytes. In here there must be:
+ *
+ *     - Initialize Block   (starting at a word boundary)
+ *     - Receive and Transmit Descriptor Rings (quadword boundary)
+ *     - Data Buffers (arbitrary boundary)
+ *
+ * This is because LANCE has on SK_G16 only access to the dual ported
+ * RAM and nowhere else.
+ */
+
+struct SK_ram
+{
+    struct init_block ib;
+    struct tmd tmde[TMDNUM];
+    struct rmd rmde[RMDNUM];
+    char tmdbuf[TMDNUM][PKT_BUF_SZ];
+    char rmdbuf[RMDNUM][PKT_BUF_SZ];
+};
+
+/*
+ * Structure where all necessary information is for ring buffer
+ * management and statistics.
+ */
+
+struct priv
+{
+    struct SK_ram *ram;  /* dual ported ram structure */
+    struct rmd *rmdhead; /* start of receive ring descriptors */
+    struct tmd *tmdhead; /* start of transmit ring descriptors */
+    int        rmdnum;   /* actual used ring descriptor */
+    int        tmdnum;   /* actual transmit descriptor for transmitting data */
+    int        tmdlast;  /* last sent descriptor used for error handling, etc */
+    void       *rmdbufs[RMDNUM]; /* pointer to the receive buffers */
+    void       *tmdbufs[TMDNUM]; /* pointer to the transmit buffers */
+};
+
+/* global variable declaration */
+
+/* static variables */
+
+static SK_RAM *board;  /* pointer to our memory mapped board components */
+static unsigned short	ioaddr; /* base io address */
+static struct priv	p_data;
+
+/* Macros */
+
+
+/* Function Prototypes */
+
+/*
+ * Device Driver functions
+ * -----------------------
+ * See for short explanation of each function its definitions header.
+ */
+
+static int   SK_probe1(struct nic *nic, short ioaddr1);
+
+static void SK_reset(struct nic *nic);
+static int SK_poll(struct nic *nic);
+static void SK_transmit(
+struct nic *nic,
+const char *d,			/* Destination */
+unsigned int t,			/* Type */
+unsigned int s,			/* size */
+const char *p);			/* Packet */
+static void SK_disable(struct nic *nic);
+struct nic *SK_probe(struct nic *nic, unsigned short *probe_addrs);
+
+/*
+ * LANCE Functions
+ * ---------------
+ */
+
+static int SK_lance_init(struct nic *nic, unsigned short mode);
+static void SK_reset_board(void);
+static void SK_set_RAP(int reg_number);
+static int SK_read_reg(int reg_number);
+static int SK_rread_reg(void);
+static void SK_write_reg(int reg_number, int value);
+
+/*
+ * Debugging functions
+ * -------------------
+ */
+
+static void SK_print_pos(struct nic *nic, char *text);
+static void SK_print_ram(struct nic *nic);
+
+
+/**************************************************************************
+RESET - Reset adapter
+***************************************************************************/
+static void SK_reset(struct nic *nic)
+{
+	/* put the card in its initial state */
+	SK_lance_init(nic, MODE_NORMAL);
+}
+
+/**************************************************************************
+POLL - Wait for a frame
+***************************************************************************/
+static int SK_poll(struct nic *nic)
+{
+	/* return true if there's an ethernet packet ready to read */
+	struct priv *p;         /* SK_G16 private structure */
+	struct rmd *rmdp;
+	int csr0, rmdstat, packet_there;
+    PRINTF2(("## %s: At beginning of SK_poll(). CSR0: %#hX\n",
+           SK_NAME, SK_read_reg(CSR0)));
+
+	p = nic->priv_data;
+    csr0 = SK_read_reg(CSR0);      /* store register for checking */
+
+    /*
+     * Acknowledge all of the current interrupt sources, disable
+     * Interrupts (INEA = 0)
+     */
+
+    SK_write_reg(CSR0, csr0 & CSR0_CLRALL);
+
+    if (csr0 & CSR0_ERR) /* LANCE Error */
+    {
+	printf("%s: error: %#hX", SK_NAME, csr0);
+
+        if (csr0 & CSR0_MISS)      /* No place to store packet ? */
+        {
+		printf(", Packet dropped.");
+        }
+	putchar('\n');
+    }
+
+    rmdp = p->rmdhead + p->rmdnum;
+    packet_there = 0;
+    /* As long as we own the next entry, check status and send
+     * it up to higher layer
+     */
+
+    while (!( (rmdstat = rmdp->u.s.status) & RX_OWN))
+    {
+	/*
+         * Start and end of packet must be set, because we use
+	 * the ethernet maximum packet length (1518) as buffer size.
+	 *
+	 * Because our buffers are at maximum OFLO and BUFF errors are
+	 * not to be concerned (see Data sheet)
+	 */
+
+	if ((rmdstat & (RX_STP | RX_ENP)) != (RX_STP | RX_ENP))
+	{
+	    /* Start of a frame > 1518 Bytes ? */
+
+	    if (rmdstat & RX_STP)
+	    {
+		printf("%s: packet too long\n", SK_NAME);
+	    }
+
+	    /*
+             * All other packets will be ignored until a new frame with
+	     * start (RX_STP) set follows.
+	     *
+	     * What we do is just give descriptor free for new incoming
+	     * packets.
+	     */
+
+	    rmdp->u.s.status = RX_OWN;      /* Relinquish ownership to LANCE */
+
+	}
+	else if (rmdstat & RX_ERR)          /* Receive Error ? */
+	{
+	    printf("%s: RX error: %#hX\n", SK_NAME, (int) rmdstat);
+	    rmdp->u.s.status = RX_OWN;      /* Relinquish ownership to LANCE */
+	}
+	else /* We have a packet which can be queued for the upper layers */
+	{
+
+	    int len = (rmdp->mlen & 0x0fff);  /* extract message length from receive buffer */
+
+	    /*
+             * Copy data out of our receive descriptor into nic->packet.
+	     *
+	     * (rmdp->u.buffer & 0x00ffffff) -> get address of buffer and
+	     * ignore status fields)
+	     */
+
+	    memcpy(nic->packet, (unsigned char *) (rmdp->u.buffer & 0x00ffffff), nic->packetlen = len);
+	    packet_there = 1;
+
+
+	    /*
+             * Packet is queued and marked for processing so we
+	     * free our descriptor
+	     */
+
+	    rmdp->u.s.status = RX_OWN;
+
+	    p->rmdnum++;
+	    p->rmdnum %= RMDNUM;
+
+	    rmdp = p->rmdhead + p->rmdnum;
+	}
+    }
+    SK_write_reg(CSR0, CSR0_INEA); /* Enable Interrupts */
+	return (packet_there);
+}
+
+/**************************************************************************
+TRANSMIT - Transmit a frame
+***************************************************************************/
+static void SK_transmit(
+struct nic *nic,
+const char *d,			/* Destination */
+unsigned int t,			/* Type */
+unsigned int s,			/* size */
+const char *pack)		/* Packet */
+{
+	/* send the packet to destination */
+    struct priv *p;         /* SK_G16 private structure */
+    struct tmd *tmdp;
+    short len;
+    int csr0, i, tmdstat;
+
+    PRINTF2(("## %s: At beginning of SK_transmit(). CSR0: %#hX\n",
+           SK_NAME, SK_read_reg(CSR0)));
+	p = nic->priv_data;
+	tmdp = p->tmdhead + p->tmdnum; /* Which descriptor for transmitting */
+
+	/* Copy data into dual ported ram */
+
+	memcpy(&p->ram->tmdbuf[p->tmdnum][0], d, ETH_ALEN);	/* dst */
+	memcpy(&p->ram->tmdbuf[p->tmdnum][ETH_ALEN], nic->node_addr, ETH_ALEN); /* src */
+	p->ram->tmdbuf[p->tmdnum][ETH_ALEN + ETH_ALEN] = t >> 8;	/* type */
+	p->ram->tmdbuf[p->tmdnum][ETH_ALEN + ETH_ALEN + 1] = t;	/* type */
+	memcpy(&p->ram->tmdbuf[p->tmdnum][ETH_HLEN], pack, s);
+	s += ETH_HLEN;
+	while (s < ETH_ZLEN)	/* pad to min length */
+		p->ram->tmdbuf[p->tmdnum][s++] = 0;
+	p->ram->tmde[p->tmdnum].status2 = 0x0;
+
+	/* Evaluate Packet length */
+	len = ETH_ZLEN < s ? s : ETH_ZLEN;
+
+	/* Fill in Transmit Message Descriptor */
+
+	tmdp->blen = -len;            /* set length to transmit */
+
+	/*
+	 * Packet start and end is always set because we use the maximum
+	 * packet length as buffer length.
+	 * Relinquish ownership to LANCE
+	 */
+
+	tmdp->u.s.status = TX_OWN | TX_STP | TX_ENP;
+
+	/* Start Demand Transmission */
+	SK_write_reg(CSR0, CSR0_TDMD | CSR0_INEA);
+
+    csr0 = SK_read_reg(CSR0);      /* store register for checking */
+
+    /*
+     * Acknowledge all of the current interrupt sources, disable
+     * Interrupts (INEA = 0)
+     */
+
+    SK_write_reg(CSR0, csr0 & CSR0_CLRALL);
+
+    if (csr0 & CSR0_ERR) /* LANCE Error */
+    {
+	printf("%s: error: %#hX", SK_NAME, csr0);
+
+        if (csr0 & CSR0_MISS)      /* No place to store packet ? */
+        {
+		printf(", Packet dropped.");
+        }
+	putchar('\n');
+    }
+
+
+    /* Set next buffer */
+    p->tmdlast++;
+    p->tmdlast &= TMDNUM-1;
+
+    tmdstat = tmdp->u.s.status & 0xff00; /* filter out status bits 15:08 */
+
+    /*
+     * We check status of transmitted packet.
+     * see LANCE data-sheet for error explanation
+     */
+    if (tmdstat & TX_ERR) /* Error occurred */
+    {
+	printf("%s: TX error: %#hX %#hX\n", SK_NAME, (int) tmdstat,
+		(int) tmdp->status2);
+
+	if (tmdp->status2 & TX_TDR)    /* TDR problems? */
+	{
+	    printf("%s: tdr-problems \n", SK_NAME);
+	}
+
+        if (tmdp->status2 & TX_UFLO)   /* Underflow error ? */
+        {
+            /*
+             * If UFLO error occurs it will turn transmitter of.
+             * So we must reinit LANCE
+             */
+
+            SK_lance_init(nic, MODE_NORMAL);
+        }
+
+	tmdp->status2 = 0;             /* Clear error flags */
+    }
+
+    SK_write_reg(CSR0, CSR0_INEA); /* Enable Interrupts */
+
+	/* Set pointer to next transmit buffer */
+	p->tmdnum++;
+	p->tmdnum &= TMDNUM-1;
+
+}
+
+/**************************************************************************
+DISABLE - Turn off ethernet interface
+***************************************************************************/
+static void SK_disable(struct nic *nic)
+{
+    PRINTF(("## %s: At beginning of SK_disable(). CSR0: %#hX\n",
+           SK_NAME, SK_read_reg(CSR0)));
+    PRINTF(("%s: Shutting %s down CSR0 %#hX\n", SK_NAME, SK_NAME,
+           (int) SK_read_reg(CSR0)));
+
+    SK_write_reg(CSR0, CSR0_STOP); /* STOP the LANCE */
+}
+
+/**************************************************************************
+PROBE - Look for an adapter, this routine's visible to the outside
+***************************************************************************/
+struct nic *SK_probe(struct nic *nic, unsigned short *probe_addrs)
+{
+	unsigned short		*p;
+	static unsigned short	io_addrs[] = SK_IO_PORTS;
+	/* if probe_addrs is 0, then routine can use a hardwired default */
+	putchar('\n');
+	nic->priv_data = &p_data;
+	if (probe_addrs == 0)
+		probe_addrs = io_addrs;
+	for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
+	{
+		long		offset1, offset0 = inb(ioaddr);
+		if ((offset0 == SK_IDLOW) &&
+		 ((offset1 = inb(ioaddr + 1)) == SK_IDHIGH))
+			if (SK_probe1(nic, ioaddr) >= 0)
+				break;
+	}
+	/* if board found */
+	if (ioaddr != 0)
+	{
+		/* point to NIC specific routines */
+		nic->reset = SK_reset;
+		nic->poll = SK_poll;
+		nic->transmit = SK_transmit;
+		nic->disable = SK_disable;
+		return nic;
+	}
+	/* else */
+	{
+		return 0;
+	}
+}
+
+int SK_probe1(struct nic *nic, short ioaddr1)
+{
+    int i,j;                /* Counters */
+    int sk_addr_flag = 0;   /* SK ADDR correct? 1 - no, 0 - yes */
+    unsigned int rom_addr;  /* used to store RAM address used for POS_ADDR */
+
+    struct priv *p;         /* SK_G16 private structure */
+
+    if (SK_ADDR & 0x3fff || SK_ADDR < 0xa0000)
+    {
+       /*
+        * Now here we could use a routine which searches for a free
+        * place in the ram and set SK_ADDR if found. TODO.
+        */
+            printf("%s: SK_ADDR %#hX is not valid. Check configuration.\n",
+                    SK_NAME, SK_ADDR);
+            return -1;
+    }
+
+    rom_addr = SK_ADDR;
+
+    outb(SK_ROM_RAM_OFF, SK_POS2); /* Boot_ROM + RAM off */
+    outb(POS_ADDR, SK_POS3);       /* Set RAM address */
+    outb(SK_ROM_RAM_ON, SK_POS2);  /* RAM on, BOOT_ROM on */
+#ifdef	SK_DEBUG
+    SK_print_pos(nic, "POS registers after ROM, RAM config");
+#endif
+
+    board = (SK_RAM *) rom_addr;
+	PRINTF(("adr[0]: %hX, adr[1]: %hX, adr[2]: %hX\n",
+	board->rom[0], board->rom[2], board->rom[4]));
+
+    /* Read in station address */
+    for (i = 0, j = 0; i < ETH_ALEN; i++, j+=2)
+    {
+	*(nic->node_addr+i) = board->rom[j];
+    }
+
+    /* Check for manufacturer code */
+#ifdef	SK_DEBUG
+    if (!(*(nic->node_addr+0) == SK_MAC0 &&
+	  *(nic->node_addr+1) == SK_MAC1 &&
+	  *(nic->node_addr+2) == SK_MAC2) )
+    {
+        PRINTF(("## %s: We did not find SK_G16 at RAM location.\n",
+                SK_NAME));
+	return -1;                     /* NO SK_G16 found */
+    }
+#endif
+
+    p = nic->priv_data;
+
+    /* Initialize private structure */
+
+    p->ram = (struct SK_ram *) rom_addr; /* Set dual ported RAM addr */
+    p->tmdhead = &(p->ram)->tmde[0];     /* Set TMD head */
+    p->rmdhead = &(p->ram)->rmde[0];     /* Set RMD head */
+
+    printf("Schneider & Koch G16 at %#hX, mem at %#hX, HW addr: %!\n",
+	    (unsigned int) ioaddr, (unsigned int) p->ram, nic->node_addr);
+
+    /* Initialize buffer pointers */
+
+    for (i = 0; i < TMDNUM; i++)
+    {
+	p->tmdbufs[i] = p->ram->tmdbuf[i];
+    }
+
+    for (i = 0; i < RMDNUM; i++)
+    {
+	p->rmdbufs[i] = p->ram->rmdbuf[i];
+    }
+    i = 0;
+
+    if (!(i = SK_lance_init(nic, MODE_NORMAL)))  /* LANCE init OK? */
+    {
+
+#ifdef	SK_DEBUG
+        /*
+         * This debug block tries to stop LANCE,
+         * reinit LANCE with transmitter and receiver disabled,
+         * then stop again and reinit with NORMAL_MODE
+         */
+
+        printf("## %s: After lance init. CSR0: %#hX\n",
+               SK_NAME, SK_read_reg(CSR0));
+        SK_write_reg(CSR0, CSR0_STOP);
+        printf("## %s: LANCE stopped. CSR0: %#hX\n",
+               SK_NAME, SK_read_reg(CSR0));
+        SK_lance_init(nic, MODE_DTX | MODE_DRX);
+        printf("## %s: Reinit with DTX + DRX off. CSR0: %#hX\n",
+               SK_NAME, SK_read_reg(CSR0));
+        SK_write_reg(CSR0, CSR0_STOP);
+        printf("## %s: LANCE stopped. CSR0: %#hX\n",
+               SK_NAME, SK_read_reg(CSR0));
+        SK_lance_init(nic, MODE_NORMAL);
+        printf("## %s: LANCE back to normal mode. CSR0: %#hX\n",
+               SK_NAME, SK_read_reg(CSR0));
+        SK_print_pos(nic, "POS regs before returning OK");
+
+#endif	/* SK_DEBUG */
+
+    }
+    else /* LANCE init failed */
+    {
+
+	PRINTF(("## %s: LANCE init failed: CSR0: %#hX\n",
+               SK_NAME, SK_read_reg(CSR0)));
+	return -1;
+    }
+
+#ifdef	SK_DEBUG
+    SK_print_pos(nic, "End of SK_probe1");
+    SK_print_ram(nic);
+#endif
+
+    return 0;                            /* Initialization done */
+
+} /* End of SK_probe1() */
+
+static int SK_lance_init(struct nic *nic, unsigned short mode)
+{
+    int i;
+    struct priv *p = (struct priv *) nic->priv_data;
+    struct tmd  *tmdp;
+    struct rmd  *rmdp;
+
+    PRINTF(("## %s: At beginning of LANCE init. CSR0: %#hX\n",
+           SK_NAME, SK_read_reg(CSR0)));
+
+    /* Reset LANCE */
+    SK_reset_board();
+
+    /* Initialize TMD's with start values */
+    p->tmdnum = 0;                   /* First descriptor for transmitting */
+    p->tmdlast = 0;                  /* First descriptor for reading stats */
+
+    for (i = 0; i < TMDNUM; i++)     /* Init all TMD's */
+    {
+	tmdp = p->tmdhead + i;
+
+	tmdp->u.buffer = (unsigned long) p->tmdbufs[i]; /* assign buffer */
+
+	/* Mark TMD as start and end of packet */
+	tmdp->u.s.status = TX_STP | TX_ENP;
+    }
+
+
+    /* Initialize RMD's with start values */
+
+    p->rmdnum = 0;                   /* First RMD which will be used */
+
+    for (i = 0; i < RMDNUM; i++)     /* Init all RMD's */
+    {
+	rmdp = p->rmdhead + i;
+
+
+	rmdp->u.buffer = (unsigned long) p->rmdbufs[i]; /* assign buffer */
+
+	/*
+         * LANCE must be owner at beginning so that he can fill in
+	 * receiving packets, set status and release RMD
+	 */
+
+	rmdp->u.s.status = RX_OWN;
+
+	rmdp->blen = -PKT_BUF_SZ;    /* Buffer Size in a two's complement */
+
+	rmdp->mlen = 0;              /* init message length */
+
+    }
+
+    /* Fill LANCE Initialize Block */
+
+    (p->ram)->ib.mode = mode;        /* Set operation mode */
+
+    for (i = 0; i < ETH_ALEN; i++)   /* Set physical address */
+    {
+	(p->ram)->ib.paddr[i] = *(nic->node_addr+i);
+    }
+
+    for (i = 0; i < 8; i++)          /* Set multicast, logical address */
+    {
+	(p->ram)->ib.laddr[i] = 0;   /* We do not use logical addressing */
+    }
+
+    /* Set ring descriptor pointers and set number of descriptors */
+
+    (p->ram)->ib.rdrp = (int)  p->rmdhead | RMDNUMMASK;
+    (p->ram)->ib.tdrp = (int)  p->tmdhead | TMDNUMMASK;
+
+    /* Prepare LANCE Control and Status Registers */
+
+    SK_write_reg(CSR3, CSR3_ACON);   /* Ale Control !!!THIS MUST BE SET!!!! */
+
+    /*
+     * LANCE addresses the RAM from 0x0000 to 0x3fbf and has no access to
+     * PC Memory locations.
+     *
+     * In structure SK_ram is defined that the first thing in ram
+     * is the initialization block. So his address is for LANCE always
+     * 0x0000
+     *
+     * CSR1 contains low order bits 15:0 of initialization block address
+     * CSR2 is built of:
+     *    7:0  High order bits 23:16 of initialization block address
+     *   15:8  reserved, must be 0
+     */
+
+    /* Set initialization block address (must be on word boundary) */
+    SK_write_reg(CSR1, 0);          /* Set low order bits 15:0 */
+    SK_write_reg(CSR2, 0);          /* Set high order bits 23:16 */
+
+
+    PRINTF(("## %s: After setting CSR1-3. CSR0: %#hX\n",
+           SK_NAME, SK_read_reg(CSR0)));
+
+    /* Initialize LANCE */
+
+    /*
+     * INIT = Initialize, when set, causes the LANCE to begin the
+     * initialization procedure and access the Init Block.
+     */
+
+    SK_write_reg(CSR0, CSR0_INIT);
+
+    /* Wait until LANCE finished initialization */
+
+    SK_set_RAP(CSR0);              /* Register Address Pointer to CSR0 */
+
+    for (i = 0; (i < 100) && !(SK_rread_reg() & CSR0_IDON); i++)
+	; /* Wait until init done or go ahead if problems (i>=100) */
+
+    if (i >= 100) /* Something is wrong ! */
+    {
+	printf("%s: can't init am7990, status: %#hX "
+	       "init_block: %#hX\n",
+		SK_NAME, (int) SK_read_reg(CSR0),
+		(unsigned int) &(p->ram)->ib);
+
+#ifdef	SK_DEBUG
+	SK_print_pos(nic, "LANCE INIT failed");
+#endif
+
+	return -1;                 /* LANCE init failed */
+    }
+
+    PRINTF(("## %s: init done after %d ticks\n", SK_NAME, i));
+
+    /* Clear Initialize done, enable Interrupts, start LANCE */
+
+    SK_write_reg(CSR0, CSR0_IDON | CSR0_INEA | CSR0_STRT);
+
+    PRINTF(("## %s: LANCE started. CSR0: %#hX\n", SK_NAME,
+            SK_read_reg(CSR0)));
+
+    return 0;                      /* LANCE is up and running */
+
+} /* End of SK_lance_init() */
+
+/* LANCE access functions
+ *
+ * ! CSR1-3 can only be accessed when in CSR0 the STOP bit is set !
+ */
+
+static void SK_reset_board(void)
+{
+    int i;
+
+	PRINTF(("## %s: At beginning of SK_reset_board.\n", SK_NAME));
+    SK_PORT = 0x00;           /* Reset active */
+    for (i = 0; i < 10 ; i++) /* Delay min 5ms */
+	;
+    SK_PORT = SK_RESET;       /* Set back to normal operation */
+
+} /* End of SK_reset_board() */
+
+static void SK_set_RAP(int reg_number)
+{
+    SK_IOREG = reg_number;
+    SK_PORT  = SK_RESET | SK_RAP | SK_WREG;
+    SK_IOCOM = SK_DOIO;
+
+    while (SK_PORT & SK_IORUN)
+	;
+} /* End of SK_set_RAP() */
+
+static int SK_read_reg(int reg_number)
+{
+    SK_set_RAP(reg_number);
+
+    SK_PORT  = SK_RESET | SK_RDATA | SK_RREG;
+    SK_IOCOM = SK_DOIO;
+
+    while (SK_PORT & SK_IORUN)
+	;
+    return (SK_IOREG);
+
+} /* End of SK_read_reg() */
+
+static int SK_rread_reg(void)
+{
+    SK_PORT  = SK_RESET | SK_RDATA | SK_RREG;
+
+    SK_IOCOM = SK_DOIO;
+
+    while (SK_PORT & SK_IORUN)
+	;
+    return (SK_IOREG);
+
+} /* End of SK_rread_reg() */
+
+static void SK_write_reg(int reg_number, int value)
+{
+    SK_set_RAP(reg_number);
+
+    SK_IOREG = value;
+    SK_PORT  = SK_RESET | SK_RDATA | SK_WREG;
+    SK_IOCOM = SK_DOIO;
+
+    while (SK_PORT & SK_IORUN)
+	;
+} /* End of SK_write_reg */
+
+/*
+ * Debugging functions
+ * -------------------
+ */
+
+#ifdef	SK_DEBUG
+static void SK_print_pos(struct nic *nic, char *text)
+{
+
+    unsigned char pos0 = inb(SK_POS0),
+		  pos1 = inb(SK_POS1),
+		  pos2 = inb(SK_POS2),
+		  pos3 = inb(SK_POS3),
+		  pos4 = inb(SK_POS4);
+
+
+    printf("## %s: %s.\n"
+           "##   pos0=%#hX pos1=%#hX pos2=%#hX pos3=%#hX pos4=%#hX\n",
+           SK_NAME, text, pos0, pos1, pos2, (pos3<<14), pos4);
+
+} /* End of SK_print_pos() */
+
+static void SK_print_ram(struct nic *nic)
+{
+
+    int i;
+    struct priv *p = (struct priv *) nic->priv_data;
+
+    printf("## %s: RAM Details.\n"
+           "##   RAM at %#hX tmdhead: %#hX rmdhead: %#hX initblock: %#hX\n",
+           SK_NAME,
+           (unsigned int) p->ram,
+           (unsigned int) p->tmdhead,
+           (unsigned int) p->rmdhead,
+           (unsigned int) &(p->ram)->ib);
+
+    printf("##   ");
+
+    for(i = 0; i < TMDNUM; i++)
+    {
+           if (!(i % 3)) /* Every third line do a newline */
+           {
+               printf("\n##   ");
+           }
+        printf("tmdbufs%d: %#hX ", (i+1), (int) p->tmdbufs[i]);
+    }
+    printf("##   ");
+
+    for(i = 0; i < RMDNUM; i++)
+    {
+         if (!(i % 3)) /* Every third line do a newline */
+           {
+               printf("\n##   ");
+           }
+        printf("rmdbufs%d: %#hX ", (i+1), (int) p->rmdbufs[i]);
+    }
+    putchar('\n');
+
+} /* End of SK_print_ram() */
+#endif
diff --git a/netboot/sk_g16.h b/netboot/sk_g16.h
new file mode 100644
index 0000000..ffc2c2a
--- /dev/null
+++ b/netboot/sk_g16.h
@@ -0,0 +1,168 @@
+/*-
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU Public License, incorporated herein by reference.
+ *
+ * Module         : sk_g16.h
+ * Version        : $Revision: 1.3 $
+ *
+ * Author         : M.Hipp (mhipp@student.uni-tuebingen.de)
+ * changes by     : Patrick J.D. Weichmann
+ *
+ * Date Created   : 94/05/25
+ *
+ * Description    : In here are all necessary definitions of
+ *                  the am7990 (LANCE) chip used for writing a
+ *                  network device driver which uses this chip
+ *
+ * $Log: sk_g16.h,v $
+ * Revision 1.3  2000/07/29 19:22:54  okuji
+ * update the network support to etherboot-4.6.4.
+ *
+-*/
+
+#ifndef	SK_G16_H
+
+#define SK_G16_H
+
+
+/*
+ *	Control and Status Register 0 (CSR0) bit definitions
+ *
+ * (R=Readable) (W=Writeable) (S=Set on write) (C-Clear on write)
+ *
+ */
+
+#define CSR0_ERR	0x8000	/* Error summary (R) */
+#define CSR0_BABL	0x4000	/* Babble transmitter timeout error (RC) */
+#define CSR0_CERR	0x2000	/* Collision Error (RC) */
+#define CSR0_MISS	0x1000	/* Missed packet (RC) */
+#define CSR0_MERR	0x0800	/* Memory Error  (RC) */
+#define CSR0_RINT	0x0400	/* Receiver Interrupt (RC) */
+#define CSR0_TINT       0x0200	/* Transmit Interrupt (RC) */
+#define CSR0_IDON	0x0100	/* Initialization Done (RC) */
+#define CSR0_INTR	0x0080	/* Interrupt Flag (R) */
+#define CSR0_INEA	0x0040	/* Interrupt Enable (RW) */
+#define CSR0_RXON	0x0020	/* Receiver on (R) */
+#define CSR0_TXON	0x0010  /* Transmitter on (R) */
+#define CSR0_TDMD	0x0008	/* Transmit Demand (RS) */
+#define CSR0_STOP	0x0004	/* Stop (RS) */
+#define CSR0_STRT	0x0002	/* Start (RS) */
+#define CSR0_INIT	0x0001	/* Initialize (RS) */
+
+#define CSR0_CLRALL     0x7f00  /* mask for all clearable bits */
+
+/*
+ *    Control and Status Register 3 (CSR3) bit definitions
+ *
+ */
+
+#define CSR3_BSWAP	0x0004	/* Byte Swap (RW) */
+#define CSR3_ACON	0x0002  /* ALE Control (RW) */
+#define CSR3_BCON	0x0001	/* Byte Control (RW) */
+
+/*
+ *	Initialization Block Mode operation Bit Definitions.
+ */
+
+#define MODE_PROM	0x8000	/* Promiscuous Mode */
+#define MODE_INTL	0x0040  /* Internal Loopback */
+#define MODE_DRTY	0x0020  /* Disable Retry */
+#define MODE_COLL	0x0010	/* Force Collision */
+#define MODE_DTCR	0x0008	/* Disable Transmit CRC) */
+#define MODE_LOOP	0x0004	/* Loopback */
+#define MODE_DTX	0x0002	/* Disable the Transmitter */
+#define MODE_DRX	0x0001  /* Disable the Receiver */
+
+#define MODE_NORMAL	0x0000  /* Normal operation mode */
+
+/*
+ *	Receive message descriptor status bit definitions.
+ */
+
+#define RX_OWN		0x80	/* Owner bit 0 = host, 1 = lance */
+#define RX_ERR		0x40	/* Error Summary */
+#define RX_FRAM		0x20	/* Framing Error */
+#define RX_OFLO		0x10	/* Overflow Error */
+#define RX_CRC		0x08	/* CRC Error */
+#define RX_BUFF		0x04	/* Buffer Error */
+#define RX_STP		0x02	/* Start of Packet */
+#define RX_ENP		0x01	/* End of Packet */
+
+
+/*
+ *	Transmit message descriptor status bit definitions.
+ */
+
+#define TX_OWN		0x80	/* Owner bit 0 = host, 1 = lance */
+#define TX_ERR		0x40    /* Error Summary */
+#define TX_MORE		0x10	/* More the 1 retry needed to Xmit */
+#define TX_ONE		0x08	/* One retry needed to Xmit */
+#define TX_DEF		0x04	/* Deferred */
+#define TX_STP		0x02	/* Start of Packet */
+#define TX_ENP		0x01	/* End of Packet */
+
+/*
+ *      Transmit status (2) (valid if TX_ERR == 1)
+ */
+
+#define TX_BUFF		0x8000  /* Buffering error (no ENP) */
+#define TX_UFLO		0x4000  /* Underflow (late memory) */
+#define TX_LCOL		0x1000  /* Late collision */
+#define TX_LCAR		0x0400  /* Loss of Carrier */
+#define TX_RTRY		0x0200  /* Failed after 16 retransmissions  */
+#define TX_TDR          0x003f  /* Time-domain-reflectometer-value */
+
+
+/*
+ * Structures used for Communication with the LANCE
+ */
+
+/* LANCE Initialize Block */
+
+struct init_block
+{
+  unsigned short mode;     /* Mode Register */
+  unsigned char  paddr[6]; /* Physical Address (MAC) */
+  unsigned char  laddr[8]; /* Logical Filter Address (not used) */
+  unsigned int   rdrp;     /* Receive Descriptor Ring pointer */
+  unsigned int   tdrp;     /* Transmit Descriptor Ring pointer */
+};
+
+
+/* Receive Message Descriptor Entry */
+
+struct rmd
+{
+  union rmd_u
+  {
+    unsigned long buffer;     /* Address of buffer */
+    struct rmd_s
+    {
+      unsigned char unused[3];
+      unsigned volatile char status;   /* Status Bits */
+    } s;
+  } u;
+  volatile short blen;        /* Buffer Length (two's complement) */
+  unsigned short mlen;        /* Message Byte Count */
+};
+
+
+/* Transmit Message Descriptor Entry */
+
+struct tmd
+{
+  union tmd_u
+  {
+    unsigned long  buffer;    /* Address of buffer */
+    struct tmd_s
+    {
+      unsigned char unused[3];
+      unsigned volatile char status;   /* Status Bits */
+    } s;
+  } u;
+  unsigned short blen;             /* Buffer Length (two's complement) */
+  unsigned volatile short status2; /* Error Status Bits */
+};
+
+#endif	/* End of SK_G16_H */
diff --git a/netboot/smc9000.c b/netboot/smc9000.c
new file mode 100644
index 0000000..4384a13
--- /dev/null
+++ b/netboot/smc9000.c
@@ -0,0 +1,522 @@
+ /*------------------------------------------------------------------------
+ * smc9000.c
+ * This is a Etherboot driver for SMC's 9000 series of Ethernet cards.
+ *
+ * Copyright (C) 1998 Daniel Engström <daniel.engstrom@riksnett.no>
+ * Based on the Linux SMC9000 driver, smc9194.c by Eric Stahlman
+ * Copyright (C) 1996 by Erik Stahlman <eric@vt.edu>
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU Public License, incorporated herein by reference.
+ *
+ * "Features" of the SMC chip:
+ *   4608 byte packet memory. ( for the 91C92/4.  Others have more )
+ *   EEPROM for configuration
+ *   AUI/TP selection
+ *
+ * Authors
+ *	Erik Stahlman				<erik@vt.edu>
+ *      Daniel Engström                         <daniel.engstrom@riksnett.no>
+ *
+ * History
+ * 98-09-25              Daniel Engström Etherboot driver crated from Eric's
+ *                                       Linux driver.
+ *
+ *---------------------------------------------------------------------------*/
+#define LINUX_OUT_MACROS 1
+#define SMC9000_VERBOSE  1
+#define SMC9000_DEBUG    0
+
+#include "etherboot.h"
+#include "nic.h"
+#include "cards.h"
+#include "smc9000.h"
+
+# define _outb outb
+# define _outw outw
+
+static const char       smc9000_version[] = "Version 0.99 98-09-30";
+static unsigned int	smc9000_base=0;
+static const char       *interfaces[ 2 ] = { "TP", "AUI" };
+static const char       *chip_ids[ 15 ] =  {
+   NULL, NULL, NULL,
+   /* 3 */ "SMC91C90/91C92",
+   /* 4 */ "SMC91C94",
+   /* 5 */ "SMC91C95",
+   NULL,
+   /* 7 */ "SMC91C100",
+   /* 8 */ "SMC91C100FD",
+   NULL, NULL, NULL,
+   NULL, NULL, NULL
+};
+static const char      smc91c96_id[] = "SMC91C96";
+
+/*
+ * Function: smc_reset( int ioaddr )
+ * Purpose:
+ *	This sets the SMC91xx chip to its normal state, hopefully from whatever
+ *	mess that any other DOS driver has put it in.
+ *
+ * Maybe I should reset more registers to defaults in here?  SOFTRESET  should
+ * do that for me.
+ *
+ * Method:
+ *	1.  send a SOFT RESET
+ *	2.  wait for it to finish
+ *	3.  reset the memory management unit
+ *      4.  clear all interrupts
+ *
+*/
+static void smc_reset(int ioaddr)
+{
+   /* This resets the registers mostly to defaults, but doesn't
+    * affect EEPROM.  That seems unnecessary */
+   SMC_SELECT_BANK(ioaddr, 0);
+   _outw( RCR_SOFTRESET, ioaddr + RCR );
+
+   /* this should pause enough for the chip to be happy */
+   SMC_DELAY(ioaddr);
+
+   /* Set the transmit and receive configuration registers to
+    * default values */
+   _outw(RCR_CLEAR, ioaddr + RCR);
+   _outw(TCR_CLEAR, ioaddr + TCR);
+
+   /* Reset the MMU */
+   SMC_SELECT_BANK(ioaddr, 2);
+   _outw( MC_RESET, ioaddr + MMU_CMD );
+
+   /* Note:  It doesn't seem that waiting for the MMU busy is needed here,
+    * but this is a place where future chipsets _COULD_ break.  Be wary
+    * of issuing another MMU command right after this */
+   _outb(0, ioaddr + INT_MASK);
+}
+
+
+/*----------------------------------------------------------------------
+ * Function: smc_probe( int ioaddr )
+ *
+ * Purpose:
+ *	Tests to see if a given ioaddr points to an SMC9xxx chip.
+ *	Returns a 0 on success
+ *
+ * Algorithm:
+ *	(1) see if the high byte of BANK_SELECT is 0x33
+ *	(2) compare the ioaddr with the base register's address
+ *	(3) see if I recognize the chip ID in the appropriate register
+ *
+ * ---------------------------------------------------------------------
+ */
+static int smc_probe( int ioaddr )
+{
+   word bank;
+   word	revision_register;
+   word base_address_register;
+
+   /* First, see if the high byte is 0x33 */
+   bank = inw(ioaddr + BANK_SELECT);
+   if ((bank & 0xFF00) != 0x3300) {
+      return -1;
+   }
+   /* The above MIGHT indicate a device, but I need to write to further
+    *	test this.  */
+   _outw(0x0, ioaddr + BANK_SELECT);
+   bank = inw(ioaddr + BANK_SELECT);
+   if ((bank & 0xFF00) != 0x3300) {
+      return -1;
+   }
+
+   /* well, we've already written once, so hopefully another time won't
+    *  hurt.  This time, I need to switch the bank register to bank 1,
+    *  so I can access the base address register */
+   SMC_SELECT_BANK(ioaddr, 1);
+   base_address_register = inw(ioaddr + BASE);
+
+   if (ioaddr != (base_address_register >> 3 & 0x3E0))  {
+#ifdef	SMC9000_VERBOSE
+      printf("SMC9000: IOADDR %hX doesn't match configuration (%hX)."
+	     "Probably not a SMC chip\n",
+	     ioaddr, base_address_register >> 3 & 0x3E0);
+#endif
+      /* well, the base address register didn't match.  Must not have
+       * been a SMC chip after all. */
+      return -1;
+   }
+
+
+   /* check if the revision register is something that I recognize.
+    * These might need to be added to later, as future revisions
+    * could be added.  */
+   SMC_SELECT_BANK(ioaddr, 3);
+   revision_register  = inw(ioaddr + REVISION);
+   if (!chip_ids[(revision_register >> 4) & 0xF]) {
+      /* I don't recognize this chip, so... */
+#ifdef	SMC9000_VERBOSE
+      printf("SMC9000: IO %hX: Unrecognized revision register:"
+	     " %hX, Contact author.\n", ioaddr, revision_register);
+#endif
+      return -1;
+   }
+
+   /* at this point I'll assume that the chip is an SMC9xxx.
+    * It might be prudent to check a listing of MAC addresses
+    * against the hardware address, or do some other tests. */
+   return 0;
+}
+
+
+/**************************************************************************
+ * ETH_RESET - Reset adapter
+ ***************************************************************************/
+
+static void smc9000_reset(struct nic *nic)
+{
+   smc_reset(smc9000_base);
+}
+
+/**************************************************************************
+ * ETH_TRANSMIT - Transmit a frame
+ ***************************************************************************/
+static void smc9000_transmit(
+	struct nic *nic,
+	const char *d,			/* Destination */
+	unsigned int t,			/* Type */
+	unsigned int s,			/* size */
+	const char *p)			/* Packet */
+{
+   word length; /* real, length incl. header */
+   word numPages;
+   unsigned long time_out;
+   byte	packet_no;
+   word status;
+   int i;
+
+   /* We dont pad here since we can have the hardware doing it for us */
+   length = (s + ETH_HLEN + 1)&~1;
+
+   /* convert to MMU pages */
+   numPages = length / 256;
+
+   if (numPages > 7 ) {
+#ifdef	SMC9000_VERBOSE
+      printf("SMC9000: Far too big packet error. \n");
+#endif
+      return;
+   }
+
+   /* dont try more than, say 30 times */
+   for (i=0;i<30;i++) {
+      /* now, try to allocate the memory */
+      SMC_SELECT_BANK(smc9000_base, 2);
+      _outw(MC_ALLOC | numPages, smc9000_base + MMU_CMD);
+
+      status = 0;
+      /* wait for the memory allocation to finnish */
+      for (time_out = currticks() + 5*TICKS_PER_SEC; currticks() < time_out; ) {
+	 status = inb(smc9000_base + INTERRUPT);
+	 if ( status & IM_ALLOC_INT ) {
+	    /* acknowledge the interrupt */
+	    _outb(IM_ALLOC_INT, smc9000_base + INTERRUPT);
+	    break;
+	 }
+      }
+
+      if ((status & IM_ALLOC_INT) != 0 ) {
+	 /* We've got the memory */
+	 break;
+      } else {
+	 printf("SMC9000: Memory allocation timed out, resetting MMU.\n");
+	 _outw(MC_RESET, smc9000_base + MMU_CMD);
+      }
+   }
+
+   /* If I get here, I _know_ there is a packet slot waiting for me */
+   packet_no = inb(smc9000_base + PNR_ARR + 1);
+   if (packet_no & 0x80) {
+      /* or isn't there?  BAD CHIP! */
+      printf("SMC9000: Memory allocation failed. \n");
+      return;
+   }
+
+   /* we have a packet address, so tell the card to use it */
+   _outb(packet_no, smc9000_base + PNR_ARR);
+
+   /* point to the beginning of the packet */
+   _outw(PTR_AUTOINC, smc9000_base + POINTER);
+
+#if	SMC9000_DEBUG > 2
+   printf("Trying to xmit packet of length %hX\n", length );
+#endif
+
+   /* send the packet length ( +6 for status, length and ctl byte )
+    * and the status word ( set to zeros ) */
+   _outw(0, smc9000_base + DATA_1 );
+
+   /* send the packet length ( +6 for status words, length, and ctl) */
+   _outb((length+6) & 0xFF,  smc9000_base + DATA_1);
+   _outb((length+6) >> 8 ,   smc9000_base + DATA_1);
+
+   /* Write the contents of the packet */
+
+   /* The ethernet header first... */
+   outsw(smc9000_base + DATA_1, d, ETH_ALEN >> 1);
+   outsw(smc9000_base + DATA_1, nic->node_addr, ETH_ALEN >> 1);
+   _outw(htons(t), smc9000_base + DATA_1);
+
+   /* ... the data ... */
+   outsw(smc9000_base + DATA_1 , p, s >> 1);
+
+   /* ... and the last byte, if there is one.   */
+   if ((s & 1) == 0) {
+      _outw(0, smc9000_base + DATA_1);
+   } else {
+      _outb(p[s-1], smc9000_base + DATA_1);
+      _outb(0x20, smc9000_base + DATA_1);
+   }
+
+   /* and let the chipset deal with it */
+   _outw(MC_ENQUEUE , smc9000_base + MMU_CMD);
+
+   status = 0; time_out = currticks() + 5*TICKS_PER_SEC;
+   do {
+      status = inb(smc9000_base + INTERRUPT);
+
+      if ((status & IM_TX_INT ) != 0) {
+	 word tx_status;
+
+	 /* ack interrupt */
+	 _outb(IM_TX_INT, smc9000_base + INTERRUPT);
+
+	 packet_no = inw(smc9000_base + FIFO_PORTS);
+	 packet_no &= 0x7F;
+
+	 /* select this as the packet to read from */
+	 _outb( packet_no, smc9000_base + PNR_ARR );
+
+	 /* read the first word from this packet */
+	 _outw( PTR_AUTOINC | PTR_READ, smc9000_base + POINTER );
+
+	 tx_status = inw( smc9000_base + DATA_1 );
+
+	 if (0 == (tx_status & TS_SUCCESS)) {
+#ifdef	SMC9000_VERBOSE
+	    printf("SMC9000: TX FAIL STATUS: %hX \n", tx_status);
+#endif
+	    /* re-enable transmit */
+	    SMC_SELECT_BANK(smc9000_base, 0);
+	    _outw(inw(smc9000_base + TCR ) | TCR_ENABLE, smc9000_base + TCR );
+	 }
+
+	 /* kill the packet */
+	 SMC_SELECT_BANK(smc9000_base, 2);
+	 _outw(MC_FREEPKT, smc9000_base + MMU_CMD);
+
+	 return;
+      }
+   }while(currticks() < time_out);
+
+   printf("SMC9000: Waring TX timed out, resetting board\n");
+   smc_reset(smc9000_base);
+   return;
+}
+
+/**************************************************************************
+ * ETH_POLL - Wait for a frame
+ ***************************************************************************/
+static int smc9000_poll(struct nic *nic)
+{
+   if(!smc9000_base)
+     return 0;
+
+   SMC_SELECT_BANK(smc9000_base, 2);
+   if (inw(smc9000_base + FIFO_PORTS) & FP_RXEMPTY)
+     return 0;
+
+   /*  start reading from the start of the packet */
+   _outw(PTR_READ | PTR_RCV | PTR_AUTOINC, smc9000_base + POINTER);
+
+   /* First read the status and check that we're ok */
+   if (!(inw(smc9000_base + DATA_1) & RS_ERRORS)) {
+      /* Next: read the packet length and mask off the top bits */
+      nic->packetlen = (inw(smc9000_base + DATA_1) & 0x07ff);
+
+      /* the packet length includes the 3 extra words */
+      nic->packetlen -= 6;
+#if	SMC9000_DEBUG > 2
+      printf(" Reading %d words (and %d byte(s))\n",
+	       (nic->packetlen >> 1), nic->packetlen & 1);
+#endif
+      /* read the packet (and the last "extra" word) */
+      insw(smc9000_base + DATA_1, nic->packet, (nic->packetlen+2) >> 1);
+      /* is there an odd last byte ? */
+      if (nic->packet[nic->packetlen+1] & 0x20)
+	 nic->packetlen++;
+
+      /*  error or good, tell the card to get rid of this packet */
+      _outw(MC_RELEASE, smc9000_base + MMU_CMD);
+      return 1;
+   }
+
+   printf("SMC9000: RX error\n");
+   /*  error or good, tell the card to get rid of this packet */
+   _outw(MC_RELEASE, smc9000_base + MMU_CMD);
+   return 0;
+}
+
+static void smc9000_disable(struct nic *nic)
+{
+   if(!smc9000_base)
+     return;
+
+   /* no more interrupts for me */
+   SMC_SELECT_BANK(smc9000_base, 2);
+   _outb( 0, smc9000_base + INT_MASK);
+
+   /* and tell the card to stay away from that nasty outside world */
+   SMC_SELECT_BANK(smc9000_base, 0);
+   _outb( RCR_CLEAR, smc9000_base + RCR );
+   _outb( TCR_CLEAR, smc9000_base + TCR );
+}
+
+/**************************************************************************
+ * ETH_PROBE - Look for an adapter
+ ***************************************************************************/
+
+struct nic *smc9000_probe(struct nic *nic, unsigned short *probe_addrs)
+{
+   unsigned short   revision;
+   int	            memory;
+   int              media;
+   const char *	    version_string;
+   const char *	    if_string;
+   int              i;
+
+   /*
+    * the SMC9000 can be at any of the following port addresses.  To change,
+    * for a slightly different card, you can add it to the array.  Keep in
+    * mind that the array must end in zero.
+    */
+   static unsigned short portlist[] = {
+#ifdef	SMC9000_SCAN
+      SMC9000_SCAN,
+#else
+      0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0,
+      0x300, 0x320, 0x340, 0x360, 0x380, 0x3A0, 0x3C0, 0x3E0,
+#endif
+      0 };
+
+   printf("\nSMC9000 %s\n", smc9000_version);
+#ifdef	SMC9000_VERBOSE
+   printf("Copyright (C) 1998 Daniel Engstr\x94m\n");
+   printf("Copyright (C) 1996 Eric Stahlman\n");
+#endif
+   /* if no addresses supplied, fall back on defaults */
+   if (probe_addrs == 0 || probe_addrs[0] == 0)
+     probe_addrs = portlist;
+
+   /* check every ethernet address */
+   for (i = 0; probe_addrs[i]; i++) {
+      /* check this specific address */
+      if (smc_probe(probe_addrs[i]) == 0)
+	smc9000_base = probe_addrs[i];
+   }
+
+   /* couldn't find anything */
+   if(0 == smc9000_base)
+     goto out;
+
+   /*
+    * Get the MAC address ( bank 1, regs 4 - 9 )
+    */
+   SMC_SELECT_BANK(smc9000_base, 1);
+   for ( i = 0; i < 6; i += 2 ) {
+      word address;
+
+      address = inw(smc9000_base + ADDR0 + i);
+      nic->node_addr[i+1] = address >> 8;
+      nic->node_addr[i] = address & 0xFF;
+   }
+
+
+   /* get the memory information */
+   SMC_SELECT_BANK(smc9000_base, 0);
+   memory = ( inw(smc9000_base + MCR) >> 9 )  & 0x7;  /* multiplier */
+   memory *= 256 * (inw(smc9000_base + MIR) & 0xFF);
+
+   /*
+    * Now, I want to find out more about the chip.  This is sort of
+    * redundant, but it's cleaner to have it in both, rather than having
+    * one VERY long probe procedure.
+    */
+   SMC_SELECT_BANK(smc9000_base, 3);
+   revision  = inw(smc9000_base + REVISION);
+   version_string = chip_ids[(revision >> 4) & 0xF];
+
+   if (((revision & 0xF0) >> 4 == CHIP_9196) &&
+       ((revision & 0x0F) >= REV_9196)) {
+      /* This is a 91c96. 'c96 has the same chip id as 'c94 (4) but
+       * a revision starting at 6 */
+      version_string = smc91c96_id;
+   }
+
+   if ( !version_string ) {
+      /* I shouldn't get here because this call was done before.... */
+      goto out;
+   }
+
+   /* is it using AUI or 10BaseT ? */
+   SMC_SELECT_BANK(smc9000_base, 1);
+   if (inw(smc9000_base + CONFIG) & CFG_AUI_SELECT)
+     media = 2;
+   else
+     media = 1;
+
+   if_string = interfaces[media - 1];
+
+   /* now, reset the chip, and put it into a known state */
+   smc_reset(smc9000_base);
+
+   printf("%s rev:%d I/O port:%hX Interface:%s RAM:%d bytes \n",
+	  version_string, revision & 0xF,
+	  smc9000_base, if_string, memory );
+   /*
+    * Print the Ethernet address
+    */
+   printf("Ethernet MAC address: %!\n", nic->node_addr);
+
+   SMC_SELECT_BANK(smc9000_base, 0);
+
+   /* see the header file for options in TCR/RCR NORMAL*/
+   _outw(TCR_NORMAL, smc9000_base + TCR);
+   _outw(RCR_NORMAL, smc9000_base + RCR);
+
+   /* Select which interface to use */
+   SMC_SELECT_BANK(smc9000_base, 1);
+   if ( media == 1 ) {
+      _outw( inw( smc9000_base + CONFIG ) & ~CFG_AUI_SELECT,
+	   smc9000_base + CONFIG );
+   }
+   else if ( media == 2 ) {
+      _outw( inw( smc9000_base + CONFIG ) | CFG_AUI_SELECT,
+	   smc9000_base + CONFIG );
+   }
+
+   nic->reset = smc9000_reset;
+   nic->poll = smc9000_poll;
+   nic->transmit = smc9000_transmit;
+   nic->disable = smc9000_disable;
+
+
+   return nic;
+
+out:
+#ifdef	SMC9000_VERBOSE
+   printf("No SMC9000 adapters found\n");
+#endif
+   smc9000_base = 0;
+
+   return (0);
+}
+
+
+
diff --git a/netboot/smc9000.h b/netboot/smc9000.h
new file mode 100644
index 0000000..ac7f916
--- /dev/null
+++ b/netboot/smc9000.h
@@ -0,0 +1,205 @@
+/*------------------------------------------------------------------------
+ * smc9000.h
+ *
+ * Copyright (C) 1998 by Daniel Engström
+ * Copyright (C) 1996 by Erik Stahlman
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU Public License, incorporated herein by reference.
+ *
+ * This file contains register information and access macros for
+ * the SMC91xxx chipset.
+ *
+ * Information contained in this file was obtained from the SMC91C94
+ * manual from SMC.  To get a copy, if you really want one, you can find
+ * information under www.smsc.com in the components division.
+ * ( this thanks to advice from Donald Becker ).
+ *
+ * Authors
+ *      Daniel Engström                         <daniel.engstrom@riksnett.no>
+ *	Erik Stahlman				<erik@vt.edu>
+ *
+ * History
+ * 96-01-06		 Erik Stahlman   moved definitions here from main .c
+ *                                       file
+ * 96-01-19		 Erik Stahlman	 polished this up some, and added
+ *                                       better error handling
+ * 98-09-25              Daniel Engström adjusted for Etherboot
+ * 98-09-27              Daniel Engström moved some static strings back to the
+ *                                       main .c file
+ * --------------------------------------------------------------------------*/
+#ifndef	_SMC9000_H_
+# define _SMC9000_H_
+
+/* I want some simple types */
+typedef unsigned char			byte;
+typedef unsigned short			word;
+typedef unsigned long int		dword;
+
+/*---------------------------------------------------------------
+ *
+ * A description of the SMC registers is probably in order here,
+ * although for details, the SMC datasheet is invaluable.
+ *
+ * Basically, the chip has 4 banks of registers ( 0 to 3 ), which
+ * are accessed by writing a number into the BANK_SELECT register
+ * ( I also use a SMC_SELECT_BANK macro for this ).
+ *
+ * The banks are configured so that for most purposes, bank 2 is all
+ * that is needed for simple run time tasks.
+ * ----------------------------------------------------------------------*/
+
+/*
+ * Bank Select Register:
+ *
+ *		yyyy yyyy 0000 00xx
+ *		xx		= bank number
+ *		yyyy yyyy	= 0x33, for identification purposes.
+ */
+#define	BANK_SELECT		14
+
+/* BANK 0  */
+
+#define	TCR		0	/* transmit control register */
+#define TCR_ENABLE	0x0001	/* if this is 1, we can transmit */
+#define TCR_FDUPLX	0x0800	/* receive packets sent out */
+#define TCR_STP_SQET	0x1000	/* stop transmitting if Signal quality error */
+#define	TCR_MON_CNS	0x0400	/* monitors the carrier status */
+#define	TCR_PAD_ENABLE	0x0080	/* pads short packets to 64 bytes */
+
+#define	TCR_CLEAR	0	/* do NOTHING */
+/* the normal settings for the TCR register : */
+#define	TCR_NORMAL	(TCR_ENABLE | TCR_PAD_ENABLE)
+
+
+#define EPH_STATUS	2
+#define ES_LINK_OK	0x4000	/* is the link integrity ok ? */
+
+#define	RCR		4
+#define RCR_SOFTRESET	0x8000	/* resets the chip */
+#define	RCR_STRIP_CRC	0x200	/* strips CRC */
+#define RCR_ENABLE	0x100	/* IFF this is set, we can receive packets */
+#define RCR_ALMUL	0x4	/* receive all multicast packets */
+#define	RCR_PROMISC	0x2	/* enable promiscuous mode */
+
+/* the normal settings for the RCR register : */
+#define	RCR_NORMAL	(RCR_STRIP_CRC | RCR_ENABLE)
+#define RCR_CLEAR	0x0		/* set it to a base state */
+
+#define	COUNTER		6
+#define	MIR		8
+#define	MCR		10
+/* 12 is reserved */
+
+/* BANK 1 */
+#define CONFIG			0
+#define CFG_AUI_SELECT		0x100
+#define	BASE			2
+#define	ADDR0			4
+#define	ADDR1			6
+#define	ADDR2			8
+#define	GENERAL			10
+#define	CONTROL			12
+#define	CTL_POWERDOWN		0x2000
+#define	CTL_LE_ENABLE		0x80
+#define	CTL_CR_ENABLE		0x40
+#define	CTL_TE_ENABLE		0x0020
+#define CTL_AUTO_RELEASE	0x0800
+#define	CTL_EPROM_ACCESS	0x0003 /* high if Eprom is being read */
+
+/* BANK 2 */
+#define MMU_CMD		0
+#define MC_BUSY		1	/* only readable bit in the register */
+#define MC_NOP		0
+#define	MC_ALLOC	0x20	/* or with number of 256 byte packets */
+#define	MC_RESET	0x40
+#define	MC_REMOVE	0x60	/* remove the current rx packet */
+#define MC_RELEASE	0x80	/* remove and release the current rx packet */
+#define MC_FREEPKT	0xA0	/* Release packet in PNR register */
+#define MC_ENQUEUE	0xC0	/* Enqueue the packet for transmit */
+
+#define	PNR_ARR		2
+#define FIFO_PORTS	4
+
+#define FP_RXEMPTY	0x8000
+#define FP_TXEMPTY	0x80
+
+#define	POINTER		6
+#define PTR_READ	0x2000
+#define	PTR_RCV		0x8000
+#define	PTR_AUTOINC	0x4000
+#define PTR_AUTO_INC	0x0040
+
+#define	DATA_1		8
+#define	DATA_2		10
+#define	INTERRUPT	12
+
+#define INT_MASK	13
+#define IM_RCV_INT	0x1
+#define	IM_TX_INT	0x2
+#define	IM_TX_EMPTY_INT	0x4
+#define	IM_ALLOC_INT	0x8
+#define	IM_RX_OVRN_INT	0x10
+#define	IM_EPH_INT	0x20
+#define	IM_ERCV_INT	0x40 /* not on SMC9192 */
+
+/* BANK 3 */
+#define	MULTICAST1	0
+#define	MULTICAST2	2
+#define	MULTICAST3	4
+#define	MULTICAST4	6
+#define	MGMT		8
+#define	REVISION	10 /* ( hi: chip id   low: rev # ) */
+
+
+/* this is NOT on SMC9192 */
+#define	ERCV		12
+
+/* Note that 9194 and 9196 have the smame chip id,
+ * the 9196 will have revisions starting at 6 */
+#define CHIP_9190	3
+#define CHIP_9194	4
+#define CHIP_9195	5
+#define CHIP_9196	4
+#define CHIP_91100	7
+#define CHIP_91100FD	8
+
+#define REV_9196	6
+
+/*
+ * Transmit status bits
+ */
+#define TS_SUCCESS	0x0001
+#define TS_LOSTCAR	0x0400
+#define TS_LATCOL	0x0200
+#define TS_16COL	0x0010
+
+/*
+ * Receive status bits
+ */
+#define RS_ALGNERR	0x8000
+#define RS_BADCRC	0x2000
+#define RS_ODDFRAME	0x1000
+#define RS_TOOLONG	0x0800
+#define RS_TOOSHORT	0x0400
+#define RS_MULTICAST	0x0001
+#define RS_ERRORS	(RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
+
+
+/*-------------------------------------------------------------------------
+ *  I define some macros to make it easier to do somewhat common
+ * or slightly complicated, repeated tasks.
+ --------------------------------------------------------------------------*/
+
+/* select a register bank, 0 to 3  */
+
+#define SMC_SELECT_BANK(x, y) { _outw( y, x + BANK_SELECT ); }
+
+/* define a small delay for the reset */
+#define SMC_DELAY(x) { inw( x + RCR );\
+			inw( x + RCR );\
+			inw( x + RCR ); }
+
+
+#endif	/* _SMC_9000_H_ */
+
diff --git a/netboot/tiara.c b/netboot/tiara.c
new file mode 100644
index 0000000..cbf485d
--- /dev/null
+++ b/netboot/tiara.c
@@ -0,0 +1,255 @@
+/**************************************************************************
+Etherboot -  BOOTP/TFTP Bootstrap Program
+
+TIARA (Fujitsu Etherstar) NIC driver for Etherboot
+Copyright (c) Ken Yap 1998
+
+Information gleaned from:
+
+TIARA.ASM Packet driver by Brian Fisher, Queens U, Kingston, Ontario
+Fujitsu MB86960 spec sheet (different chip but same family)
+***************************************************************************/
+
+/*
+ * 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.
+ */
+
+/* to get some global routines like printf */
+#include "etherboot.h"
+/* to get the interface to the body of the program */
+#include "nic.h"
+#include "cards.h"
+
+/*
+	EtherStar I/O Register offsets
+*/
+
+/* Offsets of registers */
+#define	DLCR_XMIT_STAT	0x00
+#define	DLCR_XMIT_MASK	0x01
+#define	DLCR_RECV_STAT	0x02
+#define	DLCR_RECV_MASK	0x03
+#define	DLCR_XMIT_MODE	0x04
+#define	DLCR_RECV_MODE	0x05
+#define	DLCR_ENABLE	0x06
+#define	DLCR_TDR_LOW	0x07
+#define	DLCR_NODE_ID	0x08
+#define	DLCR_TDR_HIGH	0x0F
+#define	BMPR_MEM_PORT	0x10
+#define	BMPR_PKT_LEN	0x12
+#define	BMPR_DMA_ENABLE	0x14
+#define	PROM_ID		0x18
+
+#define	TMST		0x80
+#define	TMT_OK		0x80
+#define	TMT_16COLL	0x02
+#define	BUF_EMPTY	0x40
+
+#define	CARD_DISABLE	0x80	/* written to DLCR_ENABLE to disable card */
+#define	CARD_ENABLE	0	/* written to DLCR_ENABLE to enable card */
+
+#define	CLEAR_STATUS	0x0F	/* used to clear status info */
+/*
+	00001111B
+	!!!!!!!!--------
+	!!!!!!!+--------CLEAR BUS WRITE ERROR
+	!!!!!!+---------CLEAR 16 COLLISION
+	!!!!!+----------CLEAR COLLISION
+	!!!!+-----------CLEAR UNDERFLOW
+	!!!+------------NC
+	!!+-------------NC
+	!+--------------NC
+	+---------------NC
+*/
+
+#define	NO_TX_IRQS	0	/* written to clear transmit IRQs */
+
+#define	CLR_RCV_STATUS	0xCF	/* clears receive status */
+
+#define	EN_RCV_IRQS	0x80	/* enable receive interrupts */
+/*
+	10000000B
+	!!!!!!!!--------
+	!!!!!!!+--------ENABLE OVERFLOW
+	!!!!!!+---------ENABLE CRC
+	!!!!!+----------ENABLE ALIGN
+	!!!!+-----------ENABLE SHORT PKT
+	!!!+------------DISABLE REMOTE RESET
+	!!+-------------RESERVED
+	!+--------------RESERVED
+	+---------------ENABLE PKT READY
+*/
+
+#define	XMIT_MODE	0x02
+/*
+	00000010B
+	!!!!!!!!---------ENABLE CARRIER DETECT
+	!!!!!!!+---------DISABLE LOOPBACK
+*/
+
+#define	RECV_MODE	0x02
+/*
+	00000010B
+	!!!!!!!!---------ACCEPT ALL PACKETS
+	!!!!!!!+---------ACCEPT PHYSICAL, MULTICAST, AND
+	!!!!!!+----------BROADCAST PACKETS
+	!!!!!+-----------DISABLE REMOTE RESET
+	!!!!+------------DISABLE SHORT PACKETS
+	!!!+-------------USE 6 BYTE ADDRESS
+	!!+--------------NC
+	!+---------------NC
+	+----------------DISABLE CRC TEST MODE
+*/
+
+/* NIC specific static variables go here */
+
+static unsigned short	ioaddr;
+
+/**************************************************************************
+RESET - Reset adapter
+***************************************************************************/
+static void tiara_reset(struct nic *nic)
+{
+	int		i;
+
+	outb(CARD_DISABLE, ioaddr + DLCR_ENABLE);
+	outb(CLEAR_STATUS, ioaddr + DLCR_XMIT_STAT);
+	outb(NO_TX_IRQS, ioaddr + DLCR_XMIT_MASK);
+	outb(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT);
+	outb(XMIT_MODE, ioaddr + DLCR_XMIT_MODE);
+	outb(RECV_MODE, ioaddr + DLCR_RECV_MODE);
+	/* Vacuum recv buffer */
+	while ((inb(ioaddr + DLCR_RECV_MODE) & BUF_EMPTY) == 0)
+		inb(ioaddr + BMPR_MEM_PORT);
+	/* Set node address */
+	for (i = 0; i < ETH_ALEN; ++i)
+		outb(nic->node_addr[i], ioaddr + DLCR_NODE_ID + i);
+	outb(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT);
+	outb(CARD_ENABLE, ioaddr + DLCR_ENABLE);
+}
+
+/**************************************************************************
+POLL - Wait for a frame
+***************************************************************************/
+static int tiara_poll(struct nic *nic)
+{
+	unsigned int		len;
+
+	if (inb(ioaddr + DLCR_RECV_MODE) & BUF_EMPTY)
+		return (0);
+	/* Ack packet */
+	outw(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT);
+	len = inw(ioaddr + BMPR_MEM_PORT);		/* throw away status */
+	len = inw(ioaddr + BMPR_MEM_PORT);
+	/* Drop overlength packets */
+	if (len > ETH_FRAME_LEN)
+		return (0);		/* should we drain the buffer? */
+	insw(ioaddr + BMPR_MEM_PORT, nic->packet, len / 2);
+	/* If it's our own, drop it */
+	if (memcmp(nic->packet + ETH_ALEN, nic->node_addr, ETH_ALEN) == 0)
+		return (0);
+	nic->packetlen = len;
+	return (1);
+}
+
+/**************************************************************************
+TRANSMIT - Transmit a frame
+***************************************************************************/
+static void tiara_transmit(
+struct nic *nic,
+const char *d,			/* Destination */
+unsigned int t,			/* Type */
+unsigned int s,			/* size */
+const char *p)			/* Packet */
+{
+	unsigned int	len;
+	unsigned long	time;
+
+	len = s + ETH_HLEN;
+	if (len < ETH_ZLEN)
+		len = ETH_ZLEN;
+	t = htons(t);
+	outsw(ioaddr + BMPR_MEM_PORT, d, ETH_ALEN / 2);
+	outsw(ioaddr + BMPR_MEM_PORT, nic->node_addr, ETH_ALEN / 2);
+	outw(t, ioaddr + BMPR_MEM_PORT);
+	outsw(ioaddr + BMPR_MEM_PORT, p, s / 2);
+	if (s & 1)					/* last byte */
+		outb(p[s-1], ioaddr + BMPR_MEM_PORT);
+	while (s++ < ETH_ZLEN - ETH_HLEN)	/* pad */
+		outb(0, ioaddr + BMPR_MEM_PORT);
+	outw(len | (TMST << 8), ioaddr + BMPR_PKT_LEN);
+	/* wait for transmit complete */
+	time = currticks() + TICKS_PER_SEC;		/* wait one second */
+	while (currticks() < time && (inb(ioaddr) & (TMT_OK|TMT_16COLL)) == 0)
+		;
+	if ((inb(ioaddr) & (TMT_OK|TMT_16COLL)) == 0)
+		printf("Tiara timed out on transmit\n");
+	/* Do we need to ack the transmit? */
+}
+
+/**************************************************************************
+DISABLE - Turn off ethernet interface
+***************************************************************************/
+static void tiara_disable(struct nic *nic)
+{
+	/* Apparently only a power down can do this properly */
+	outb(CARD_DISABLE, ioaddr + DLCR_ENABLE);
+}
+
+static int tiara_probe1(struct nic *nic)
+{
+	/* Hope all the Tiara cards have this vendor prefix */
+	static char	vendor_prefix[] = { 0x08, 0x00, 0x1A };
+	static char	all_ones[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+	int		i;
+
+	for (i = 0; i < ETH_ALEN; ++i)
+		nic->node_addr[i] = inb(ioaddr + PROM_ID + i);
+	if (memcmp(nic->node_addr, vendor_prefix, sizeof(vendor_prefix)) != 0)
+		return (0);
+	if (memcmp(nic->node_addr, all_ones, sizeof(all_ones)) == 0)
+		return (0);
+	printf("\nTiara ioaddr %#hX, addr %!\n", ioaddr, nic->node_addr);
+	return (1);
+}
+
+/**************************************************************************
+PROBE - Look for an adapter, this routine's visible to the outside
+***************************************************************************/
+struct nic *tiara_probe(struct nic *nic, unsigned short *probe_addrs)
+{
+	/* missing entries are addresses usually already used */
+	static unsigned short	io_addrs[] = {
+		0x100, 0x120, 0x140, 0x160,
+		0x180, 0x1A0, 0x1C0, 0x1E0,
+		0x200, 0x220, 0x240, /*Par*/
+		0x280, 0x2A0, 0x2C0, /*Ser*/
+		0x300, 0x320, 0x340, /*Par*/
+		0x380, /*Vid,Par*/ 0x3C0, /*Ser*/
+		0x0
+	};
+	unsigned short		*p;
+
+	/* if probe_addrs is 0, then routine can use a hardwired default */
+	if (probe_addrs == 0)
+		probe_addrs = io_addrs;
+	for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
+		if (tiara_probe1(nic))
+			break;
+	/* if board found */
+	if (ioaddr != 0)
+	{
+		tiara_reset(nic);
+		/* point to NIC specific routines */
+		nic->reset = tiara_reset;
+		nic->poll = tiara_poll;
+		nic->transmit = tiara_transmit;
+		nic->disable = tiara_disable;
+		return nic;
+	}
+	else
+		return (0);
+}
diff --git a/netboot/timer.c b/netboot/timer.c
new file mode 100644
index 0000000..2487d63
--- /dev/null
+++ b/netboot/timer.c
@@ -0,0 +1,127 @@
+/* A couple of routines to implement a low-overhead timer for drivers */
+
+ /*
+ * 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.
+ */
+
+#include	"etherboot.h"
+#include	"timer.h"
+
+void load_timer2(unsigned int ticks)
+{
+	/* Set up the timer gate, turn off the speaker */
+	outb((inb(PPC_PORTB) & ~PPCB_SPKR) | PPCB_T2GATE, PPC_PORTB);
+	outb(TIMER2_SEL|WORD_ACCESS|MODE0|BINARY_COUNT, TIMER_MODE_PORT);
+	outb(ticks & 0xFF, TIMER2_PORT);
+	outb(ticks >> 8, TIMER2_PORT);
+}
+
+#if defined(CONFIG_TSC_CURRTICKS)
+#define rdtsc(low,high) \
+     __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))
+
+#define rdtscll(val) \
+     __asm__ __volatile__ ("rdtsc" : "=A" (val))
+
+
+#define HZ TICKS_PER_SEC
+#define CLOCK_TICK_RATE	1193180U /* Underlying HZ */
+/* LATCH is used in the interval timer and ftape setup. */
+#define LATCH  ((CLOCK_TICK_RATE + HZ/2) / HZ)	/* For divider */
+
+
+/* ------ Calibrate the TSC ------- 
+ * Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
+ * Too much 64-bit arithmetic here to do this cleanly in C, and for
+ * accuracy's sake we want to keep the overhead on the CTC speaker (channel 2)
+ * output busy loop as low as possible. We avoid reading the CTC registers
+ * directly because of the awkward 8-bit access mechanism of the 82C54
+ * device.
+ */
+
+#define CALIBRATE_LATCH	(5 * LATCH)
+
+static unsigned long long calibrate_tsc(void)
+{
+	/* Set the Gate high, disable speaker */
+	outb((inb(0x61) & ~0x02) | 0x01, 0x61);
+
+	/*
+	 * Now let's take care of CTC channel 2
+	 *
+	 * Set the Gate high, program CTC channel 2 for mode 0,
+	 * (interrupt on terminal count mode), binary count,
+	 * load 5 * LATCH count, (LSB and MSB) to begin countdown.
+	 */
+	outb(0xb0, 0x43);			/* binary, mode 0, LSB/MSB, Ch 2 */
+	outb(CALIBRATE_LATCH & 0xff, 0x42);	/* LSB of count */
+	outb(CALIBRATE_LATCH >> 8, 0x42);	/* MSB of count */
+
+	{
+		unsigned long startlow, starthigh;
+		unsigned long endlow, endhigh;
+		unsigned long count;
+
+		rdtsc(startlow,starthigh);
+		count = 0;
+		do {
+			count++;
+		} while ((inb(0x61) & 0x20) == 0);
+		rdtsc(endlow,endhigh);
+
+		/* Error: ECTCNEVERSET */
+		if (count <= 1)
+			goto bad_ctc;
+
+		/* 64-bit subtract - gcc just messes up with long longs */
+		__asm__("subl %2,%0\n\t"
+			"sbbl %3,%1"
+			:"=a" (endlow), "=d" (endhigh)
+			:"g" (startlow), "g" (starthigh),
+			 "0" (endlow), "1" (endhigh));
+
+		/* Error: ECPUTOOFAST */
+		if (endhigh)
+			goto bad_ctc;
+
+		endlow /= 5;
+		return endlow;
+	}
+
+	/*
+	 * The CTC wasn't reliable: we got a hit on the very first read,
+	 * or the CPU was so fast/slow that the quotient wouldn't fit in
+	 * 32 bits..
+	 */
+bad_ctc:
+	printf("bad_ctc\n");
+	return 0;
+}
+
+
+unsigned long currticks(void)
+{
+	static unsigned long clocks_per_tick;
+	unsigned long clocks_high, clocks_low;
+	unsigned long currticks;
+	if (!clocks_per_tick) {
+		clocks_per_tick = calibrate_tsc();
+		printf("clocks_per_tick = %d\n", clocks_per_tick);
+	}
+
+	/* Read the Time Stamp Counter */
+	rdtsc(clocks_low, clocks_high);
+
+	/* currticks = clocks / clocks_per_tick; */
+	__asm__("divl %1"
+		:"=a" (currticks)
+		:"r" (clocks_per_tick), "0" (clocks_low), "d" (clocks_high));
+
+
+	return currticks;
+}
+
+#endif /* RTC_CURRTICKS */
diff --git a/netboot/timer.h b/netboot/timer.h
new file mode 100644
index 0000000..b44962a
--- /dev/null
+++ b/netboot/timer.h
@@ -0,0 +1,64 @@
+/* Defines for routines to implement a low-overhead timer for drivers */
+
+ /*
+ * 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.
+ */
+
+#ifndef	TIMER_H
+#define TIMER_H
+
+/* Ports for the 8254 timer chip */
+#define	TIMER2_PORT	0x42
+#define	TIMER_MODE_PORT	0x43
+
+/* Meaning of the mode bits */
+#define	TIMER0_SEL	0x00
+#define	TIMER1_SEL	0x40
+#define	TIMER2_SEL	0x80
+#define	READBACK_SEL	0xC0
+
+#define	LATCH_COUNT	0x00
+#define	LOBYTE_ACCESS	0x10
+#define	HIBYTE_ACCESS	0x20
+#define	WORD_ACCESS	0x30
+
+#define	MODE0		0x00
+#define	MODE1		0x02
+#define	MODE2		0x04
+#define	MODE3		0x06
+#define	MODE4		0x08
+#define	MODE5		0x0A
+
+#define	BINARY_COUNT	0x00
+#define	BCD_COUNT	0x01
+
+/* Timers tick over at this rate */
+#define	TICKS_PER_MS	1193
+
+/* Parallel Peripheral Controller Port B */
+#define	PPC_PORTB	0x61
+
+/* Meaning of the port bits */
+#define	PPCB_T2OUT	0x20	/* Bit 5 */
+#define	PPCB_SPKR	0x02	/* Bit 1 */
+#define	PPCB_T2GATE	0x01	/* Bit 0 */
+
+/* Ticks must be between 0 and 65535 (0 == 65536)
+   because it is a 16 bit counter */
+extern void load_timer2(unsigned int ticks);
+extern inline int timer2_running(void)
+{
+	return ((inb(PPC_PORTB) & PPCB_T2OUT) == 0);
+}
+
+extern inline void waiton_timer2(unsigned int ticks)
+{
+	load_timer2(ticks);
+	while ((inb(PPC_PORTB) & PPCB_T2OUT) == 0)
+		;
+}
+
+#endif	/* TIMER_H */
diff --git a/netboot/tlan.c b/netboot/tlan.c
new file mode 100644
index 0000000..03b69f7
--- /dev/null
+++ b/netboot/tlan.c
@@ -0,0 +1,3746 @@
+/**************************************************************************
+Etherboot -  BOOTP/TFTP Bootstrap Program
+TLAN driver for Etherboot
+***************************************************************************/
+
+/*
+ * 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.
+ */
+
+/* to get some global routines like printf */
+#include "etherboot.h"
+/* to get the interface to the body of the program */
+#include "nic.h"
+/* to get the PCI support functions, if this is a PCI NIC */
+#include "pci.h"
+/* to get our own prototype */
+#include "cards.h"
+
+	/*****************************************************************
+	 * TLan Definitions
+	 *
+	 ****************************************************************/
+
+#define TLAN_MIN_FRAME_SIZE	64
+#define TLAN_MAX_FRAME_SIZE	1600
+
+#define TLAN_NUM_RX_LISTS	32
+#define TLAN_NUM_TX_LISTS	64
+
+#define TLAN_IGNORE		0
+#define TLAN_RECORD		1
+
+#define TLAN_DBG(lvl, format, args...)	if (debug&lvl) printf("TLAN: " format, ##args );
+#define TLAN_DEBUG_GNRL		0x0001
+#define TLAN_DEBUG_TX		0x0002
+#define TLAN_DEBUG_RX		0x0004 
+#define TLAN_DEBUG_LIST		0x0008
+#define TLAN_DEBUG_PROBE	0x0010
+
+#define MAX_TLAN_BOARDS		8	 /* Max number of boards installed at a time */
+
+	/*****************************************************************
+	 * Device Identification Definitions
+	 *
+	 ****************************************************************/
+		
+#define PCI_DEVICE_ID_NETELLIGENT_10_T2			0xB012
+#define PCI_DEVICE_ID_NETELLIGENT_10_100_WS_5100	0xB030
+#ifndef PCI_DEVICE_ID_OLICOM_OC2183
+#define PCI_DEVICE_ID_OLICOM_OC2183			0x0013
+#endif
+#ifndef PCI_DEVICE_ID_OLICOM_OC2325
+#define PCI_DEVICE_ID_OLICOM_OC2325			0x0012
+#endif
+#ifndef PCI_DEVICE_ID_OLICOM_OC2326
+#define PCI_DEVICE_ID_OLICOM_OC2326			0x0014
+#endif
+#define TLAN_ADAPTER_NONE		0x00000000
+#define TLAN_ADAPTER_UNMANAGED_PHY	0x00000001
+#define TLAN_ADAPTER_BIT_RATE_PHY	0x00000002
+#define TLAN_ADAPTER_USE_INTERN_10	0x00000004
+#define TLAN_ADAPTER_ACTIVITY_LED	0x00000008
+#define TLAN_SPEED_DEFAULT	0
+#define TLAN_SPEED_10		10
+#define TLAN_SPEED_100		100
+#define TLAN_DUPLEX_DEFAULT	0
+#define TLAN_DUPLEX_HALF	1
+#define TLAN_DUPLEX_FULL	2
+#define TLAN_BUFFERS_PER_LIST	10
+#define TLAN_LAST_BUFFER	0x80000000
+#define TLAN_CSTAT_UNUSED	0x8000
+#define TLAN_CSTAT_FRM_CMP	0x4000
+#define TLAN_CSTAT_READY	0x3000
+#define TLAN_CSTAT_EOC		0x0800
+#define TLAN_CSTAT_RX_ERROR	0x0400
+#define TLAN_CSTAT_PASS_CRC	0x0200
+#define TLAN_CSTAT_DP_PR	0x0100
+
+	/*****************************************************************
+	 * PHY definitions
+	 *
+	 ****************************************************************/
+
+#define TLAN_PHY_MAX_ADDR	0x1F
+#define TLAN_PHY_NONE		0x20
+
+	/*****************************************************************
+	 * TLan Driver Timer Definitions
+	 *
+	 ****************************************************************/
+
+#define TLAN_TIMER_LINK_BEAT		1
+#define TLAN_TIMER_ACTIVITY		2
+#define TLAN_TIMER_PHY_PDOWN		3
+#define TLAN_TIMER_PHY_PUP		4
+#define TLAN_TIMER_PHY_RESET		5
+#define TLAN_TIMER_PHY_START_LINK	6
+#define TLAN_TIMER_PHY_FINISH_AN	7
+#define TLAN_TIMER_FINISH_RESET		8
+#define TLAN_TIMER_ACT_DELAY		(HZ/10)
+
+	/*****************************************************************
+	 * TLan Driver Eeprom Definitions
+	 *
+	 ****************************************************************/
+
+#define TLAN_EEPROM_ACK		0
+#define TLAN_EEPROM_STOP	1
+
+	/*****************************************************************
+	 * Host Register Offsets and Contents
+	 *
+	 ****************************************************************/
+
+#define TLAN_HOST_CMD			0x00
+#define 	TLAN_HC_GO		0x80000000
+#define		TLAN_HC_STOP		0x40000000
+#define		TLAN_HC_ACK		0x20000000
+#define		TLAN_HC_CS_MASK		0x1FE00000
+#define		TLAN_HC_EOC		0x00100000
+#define		TLAN_HC_RT		0x00080000
+#define		TLAN_HC_NES		0x00040000
+#define		TLAN_HC_AD_RST		0x00008000
+#define		TLAN_HC_LD_TMR		0x00004000
+#define		TLAN_HC_LD_THR		0x00002000
+#define		TLAN_HC_REQ_INT		0x00001000
+#define		TLAN_HC_INT_OFF		0x00000800
+#define		TLAN_HC_INT_ON		0x00000400
+#define		TLAN_HC_AC_MASK		0x000000FF
+#define TLAN_CH_PARM			0x04
+#define TLAN_DIO_ADR			0x08
+#define		TLAN_DA_ADR_INC		0x8000
+#define		TLAN_DA_RAM_ADR		0x4000
+#define TLAN_HOST_INT			0x0A
+#define		TLAN_HI_IV_MASK		0x1FE0
+#define		TLAN_HI_IT_MASK		0x001C
+#define TLAN_DIO_DATA			0x0C
+
+/* ThunderLAN Internal Register DIO Offsets */
+
+#define TLAN_NET_CMD			0x00
+#define		TLAN_NET_CMD_NRESET	0x80
+#define		TLAN_NET_CMD_NWRAP	0x40
+#define		TLAN_NET_CMD_CSF	0x20
+#define		TLAN_NET_CMD_CAF	0x10
+#define		TLAN_NET_CMD_NOBRX	0x08
+#define		TLAN_NET_CMD_DUPLEX	0x04
+#define		TLAN_NET_CMD_TRFRAM	0x02
+#define		TLAN_NET_CMD_TXPACE	0x01
+#define TLAN_NET_SIO			0x01
+#define 	TLAN_NET_SIO_MINTEN	0x80
+#define		TLAN_NET_SIO_ECLOK	0x40
+#define		TLAN_NET_SIO_ETXEN	0x20
+#define		TLAN_NET_SIO_EDATA	0x10
+#define		TLAN_NET_SIO_NMRST	0x08
+#define		TLAN_NET_SIO_MCLK	0x04
+#define		TLAN_NET_SIO_MTXEN	0x02
+#define		TLAN_NET_SIO_MDATA	0x01
+#define TLAN_NET_STS			0x02
+#define		TLAN_NET_STS_MIRQ	0x80
+#define		TLAN_NET_STS_HBEAT	0x40
+#define		TLAN_NET_STS_TXSTOP	0x20
+#define		TLAN_NET_STS_RXSTOP	0x10
+#define		TLAN_NET_STS_RSRVD	0x0F
+#define TLAN_NET_MASK			0x03
+#define		TLAN_NET_MASK_MASK7	0x80
+#define		TLAN_NET_MASK_MASK6	0x40
+#define		TLAN_NET_MASK_MASK5	0x20
+#define		TLAN_NET_MASK_MASK4	0x10
+#define		TLAN_NET_MASK_RSRVD	0x0F
+#define TLAN_NET_CONFIG			0x04
+#define 	TLAN_NET_CFG_RCLK	0x8000
+#define		TLAN_NET_CFG_TCLK	0x4000
+#define		TLAN_NET_CFG_BIT	0x2000
+#define		TLAN_NET_CFG_RXCRC	0x1000
+#define		TLAN_NET_CFG_PEF	0x0800
+#define		TLAN_NET_CFG_1FRAG	0x0400
+#define		TLAN_NET_CFG_1CHAN	0x0200
+#define		TLAN_NET_CFG_MTEST	0x0100
+#define		TLAN_NET_CFG_PHY_EN	0x0080
+#define		TLAN_NET_CFG_MSMASK	0x007F
+#define TLAN_MAN_TEST			0x06
+#define TLAN_DEF_VENDOR_ID		0x08
+#define TLAN_DEF_DEVICE_ID		0x0A
+#define TLAN_DEF_REVISION		0x0C
+#define TLAN_DEF_SUBCLASS		0x0D
+#define TLAN_DEF_MIN_LAT		0x0E
+#define TLAN_DEF_MAX_LAT		0x0F
+#define TLAN_AREG_0			0x10
+#define TLAN_AREG_1			0x16
+#define TLAN_AREG_2			0x1C
+#define TLAN_AREG_3			0x22
+#define TLAN_HASH_1			0x28
+#define TLAN_HASH_2			0x2C
+#define TLAN_GOOD_TX_FRMS		0x30
+#define TLAN_TX_UNDERUNS		0x33
+#define TLAN_GOOD_RX_FRMS		0x34
+#define TLAN_RX_OVERRUNS		0x37
+#define TLAN_DEFERRED_TX		0x38
+#define TLAN_CRC_ERRORS			0x3A
+#define TLAN_CODE_ERRORS		0x3B
+#define TLAN_MULTICOL_FRMS		0x3C
+#define TLAN_SINGLECOL_FRMS		0x3E
+#define TLAN_EXCESSCOL_FRMS		0x40
+#define TLAN_LATE_COLS			0x41
+#define TLAN_CARRIER_LOSS		0x42
+#define TLAN_ACOMMIT			0x43
+#define TLAN_LED_REG			0x44
+#define		TLAN_LED_ACT		0x10
+#define		TLAN_LED_LINK		0x01
+#define TLAN_BSIZE_REG			0x45
+#define TLAN_MAX_RX			0x46
+#define TLAN_INT_DIS			0x48
+#define		TLAN_ID_TX_EOC		0x04
+#define		TLAN_ID_RX_EOF		0x02
+#define		TLAN_ID_RX_EOC		0x01
+
+/* ThunderLAN Interrupt Codes */
+
+#define TLAN_INT_NUMBER_OF_INTS	8
+
+#define TLAN_INT_NONE			0x0000
+#define TLAN_INT_TX_EOF			0x0001
+#define TLAN_INT_STAT_OVERFLOW		0x0002
+#define TLAN_INT_RX_EOF			0x0003
+#define TLAN_INT_DUMMY			0x0004
+#define TLAN_INT_TX_EOC			0x0005
+#define TLAN_INT_STATUS_CHECK		0x0006
+#define TLAN_INT_RX_EOC			0x0007
+#define TLAN_TLPHY_ID			0x10
+#define TLAN_TLPHY_CTL			0x11
+#define 	TLAN_TC_IGLINK		0x8000
+#define		TLAN_TC_SWAPOL		0x4000
+#define		TLAN_TC_AUISEL		0x2000
+#define		TLAN_TC_SQEEN		0x1000
+#define		TLAN_TC_MTEST		0x0800
+#define		TLAN_TC_RESERVED	0x07F8
+#define		TLAN_TC_NFEW		0x0004
+#define		TLAN_TC_INTEN		0x0002
+#define		TLAN_TC_TINT		0x0001
+#define TLAN_TLPHY_STS			0x12
+#define		TLAN_TS_MINT		0x8000
+#define		TLAN_TS_PHOK		0x4000
+#define		TLAN_TS_POLOK		0x2000
+#define		TLAN_TS_TPENERGY	0x1000
+#define		TLAN_TS_RESERVED	0x0FFF
+#define TLAN_TLPHY_PAR			0x19
+#define		TLAN_PHY_CIM_STAT	0x0020
+#define		TLAN_PHY_SPEED_100	0x0040
+#define		TLAN_PHY_DUPLEX_FULL	0x0080
+#define		TLAN_PHY_AN_EN_STAT     0x0400
+
+
+/* ThunderLAN MII Registers */
+
+/* Generic MII/PHY Registers */
+
+#define MII_GEN_CTL			0x00
+#define 	MII_GC_RESET		0x8000
+#define		MII_GC_LOOPBK		0x4000
+#define		MII_GC_SPEEDSEL		0x2000
+#define		MII_GC_AUTOENB		0x1000
+#define		MII_GC_PDOWN		0x0800
+#define		MII_GC_ISOLATE		0x0400
+#define		MII_GC_AUTORSRT		0x0200
+#define		MII_GC_DUPLEX		0x0100
+#define		MII_GC_COLTEST		0x0080
+#define		MII_GC_RESERVED		0x007F
+#define MII_GEN_STS			0x01
+#define		MII_GS_100BT4		0x8000
+#define		MII_GS_100BTXFD		0x4000
+#define		MII_GS_100BTXHD		0x2000
+#define		MII_GS_10BTFD		0x1000
+#define		MII_GS_10BTHD		0x0800
+#define		MII_GS_RESERVED		0x07C0
+#define		MII_GS_AUTOCMPLT	0x0020
+#define		MII_GS_RFLT		0x0010
+#define		MII_GS_AUTONEG		0x0008
+#define		MII_GS_LINK		0x0004
+#define		MII_GS_JABBER		0x0002
+#define		MII_GS_EXTCAP		0x0001
+#define MII_GEN_ID_HI			0x02
+#define MII_GEN_ID_LO			0x03
+#define 	MII_GIL_OUI		0xFC00
+#define 	MII_GIL_MODEL		0x03F0
+#define 	MII_GIL_REVISION	0x000F
+#define MII_AN_ADV			0x04
+#define MII_AN_LPA			0x05
+#define MII_AN_EXP			0x06
+
+/* ThunderLAN Specific MII/PHY Registers */
+
+#define 	TLAN_TC_IGLINK		0x8000
+#define		TLAN_TC_SWAPOL		0x4000
+#define		TLAN_TC_AUISEL		0x2000
+#define		TLAN_TC_SQEEN		0x1000
+#define		TLAN_TC_MTEST		0x0800
+#define		TLAN_TC_RESERVED	0x07F8
+#define		TLAN_TC_NFEW		0x0004
+#define		TLAN_TC_INTEN		0x0002
+#define		TLAN_TC_TINT		0x0001
+#define		TLAN_TS_MINT		0x8000
+#define		TLAN_TS_PHOK		0x4000
+#define		TLAN_TS_POLOK		0x2000
+#define		TLAN_TS_TPENERGY	0x1000
+#define		TLAN_TS_RESERVED	0x0FFF
+#define		TLAN_PHY_CIM_STAT	0x0020
+#define		TLAN_PHY_SPEED_100	0x0040
+#define		TLAN_PHY_DUPLEX_FULL	0x0080
+#define		TLAN_PHY_AN_EN_STAT     0x0400
+
+/* National Sem. & Level1 PHY id's */
+#define NAT_SEM_ID1			0x2000
+#define NAT_SEM_ID2			0x5C01
+#define LEVEL1_ID1			0x7810
+#define LEVEL1_ID2			0x0000
+
+#define TLan_ClearBit( bit, port )	outb_p(inb_p(port) & ~bit, port)
+#define TLan_GetBit( bit, port )	((int) (inb_p(port) & bit))
+#define TLan_SetBit( bit, port )	outb_p(inb_p(port) | bit, port)
+
+typedef	unsigned int	u32;
+typedef	unsigned short	u16;
+typedef	unsigned char	u8;
+
+/* Routines to access internal registers. */
+
+inline u8 TLan_DioRead8(u16 base_addr, u16 internal_addr)
+{
+	outw(internal_addr, base_addr + TLAN_DIO_ADR);
+	return (inb((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x3)));
+	
+} /* TLan_DioRead8 */
+
+inline u16 TLan_DioRead16(u16 base_addr, u16 internal_addr)
+{
+	outw(internal_addr, base_addr + TLAN_DIO_ADR);
+	return (inw((base_addr + TLAN_DIO_DATA) + (internal_addr & 0x2)));
+
+} /* TLan_DioRead16 */
+
+inline u32 TLan_DioRead32(u16 base_addr, u16 internal_addr)
+{
+	outw(internal_addr, base_addr + TLAN_DIO_ADR);
+	return (inl(base_addr + TLAN_DIO_DATA));
+
+} /* TLan_DioRead32 */
+
+inline void TLan_DioWrite8(u16 base_addr, u16 internal_addr, u8 data)
+{
+	outw(internal_addr, base_addr + TLAN_DIO_ADR);
+	outb(data, base_addr + TLAN_DIO_DATA + (internal_addr & 0x3));
+
+}
+
+inline void TLan_DioWrite16(u16 base_addr, u16 internal_addr, u16 data)
+{
+	outw(internal_addr, base_addr + TLAN_DIO_ADR);
+	outw(data, base_addr + TLAN_DIO_DATA + (internal_addr & 0x2));
+
+}
+
+inline void TLan_DioWrite32(u16 base_addr, u16 internal_addr, u32 data)
+{
+	outw(internal_addr, base_addr + TLAN_DIO_ADR);
+	outl(data, base_addr + TLAN_DIO_DATA + (internal_addr & 0x2));
+
+}
+
+/* NIC specific static variables go here */
+
+/*****************************************************************************
+******************************************************************************
+
+	ThunderLAN Driver Eeprom routines
+
+	The Compaq Netelligent 10 and 10/100 cards use a Microchip 24C02A
+	EEPROM.  These functions are based on information in Microchip's
+	data sheet.  I don't know how well this functions will work with
+	other EEPROMs.
+
+******************************************************************************
+*****************************************************************************/
+
+	/***************************************************************
+	 *	TLan_EeSendStart
+	 *
+	 *	Returns:
+	 *		Nothing
+	 *	Parms:	
+	 *		io_base		The IO port base address for the
+	 *				TLAN device with the EEPROM to
+	 *				use.
+	 *
+	 *	This function sends a start cycle to an EEPROM attached
+	 *	to a TLAN chip.
+	 *
+	 **************************************************************/
+
+static void TLan_EeSendStart( u16 io_base )
+{
+	u16	sio;
+
+	outw( TLAN_NET_SIO, io_base + TLAN_DIO_ADR );
+	sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
+
+	TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
+	TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
+	TLan_SetBit( TLAN_NET_SIO_ETXEN, sio );
+	TLan_ClearBit( TLAN_NET_SIO_EDATA, sio );
+	TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
+
+} /* TLan_EeSendStart */
+
+	/***************************************************************
+	 *	TLan_EeSendByte
+	 *
+	 *	Returns:
+	 *		If the correct ack was received, 0, otherwise 1
+	 *	Parms:	io_base		The IO port base address for the
+	 *				TLAN device with the EEPROM to
+	 *				use.
+	 *		data		The 8 bits of information to
+	 *				send to the EEPROM.
+	 *		stop		If TLAN_EEPROM_STOP is passed, a
+	 *				stop cycle is sent after the
+	 *				byte is sent after the ack is
+	 *				read.
+	 *
+	 *	This function sends a byte on the serial EEPROM line,
+	 *	driving the clock to send each bit. The function then
+	 *	reverses transmission direction and reads an acknowledge
+	 *	bit.
+	 *
+	 **************************************************************/
+
+static int TLan_EeSendByte( u16 io_base, u8 data, int stop )
+{
+	int	err;
+	u8	place;
+	u16	sio;
+
+	outw( TLAN_NET_SIO, io_base + TLAN_DIO_ADR );
+	sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
+
+	/* Assume clock is low, tx is enabled; */
+	for ( place = 0x80; place != 0; place >>= 1 ) {
+		if ( place & data )
+			TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
+		else
+			TLan_ClearBit( TLAN_NET_SIO_EDATA, sio );
+		TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
+		TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
+	}
+	TLan_ClearBit( TLAN_NET_SIO_ETXEN, sio );
+	TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
+	err = TLan_GetBit( TLAN_NET_SIO_EDATA, sio );
+	TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
+	TLan_SetBit( TLAN_NET_SIO_ETXEN, sio );
+
+	if ( ( ! err ) && stop ) {
+		TLan_ClearBit( TLAN_NET_SIO_EDATA, sio );	/* STOP, raise data while clock is high */
+		TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
+		TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
+	}
+
+	return ( err );
+
+} /* TLan_EeSendByte */
+
+	/***************************************************************
+	 *	TLan_EeReceiveByte
+	 *
+	 *	Returns:
+	 *		Nothing
+	 *	Parms:
+	 *		io_base		The IO port base address for the
+	 *				TLAN device with the EEPROM to
+	 *				use.
+	 *		data		An address to a char to hold the
+	 *				data sent from the EEPROM.
+	 *		stop		If TLAN_EEPROM_STOP is passed, a
+	 *				stop cycle is sent after the
+	 *				byte is received, and no ack is
+	 *				sent.
+	 *
+	 *	This function receives 8 bits of data from the EEPROM
+	 *	over the serial link.  It then sends and ack bit, or no
+	 *	ack and a stop bit.  This function is used to retrieve
+	 *	data after the address of a byte in the EEPROM has been
+	 *	sent.
+	 *
+	 **************************************************************/
+
+static void TLan_EeReceiveByte( u16 io_base, u8 *data, int stop )
+{
+	u8  place;
+	u16 sio;
+
+	outw( TLAN_NET_SIO, io_base + TLAN_DIO_ADR );
+	sio = io_base + TLAN_DIO_DATA + TLAN_NET_SIO;
+	*data = 0;
+
+	/* Assume clock is low, tx is enabled; */
+	TLan_ClearBit( TLAN_NET_SIO_ETXEN, sio );
+	for ( place = 0x80; place; place >>= 1 ) {
+		TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
+		if ( TLan_GetBit( TLAN_NET_SIO_EDATA, sio ) )
+			*data |= place;
+		TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
+	}
+
+	TLan_SetBit( TLAN_NET_SIO_ETXEN, sio );
+	if ( ! stop ) {
+		TLan_ClearBit( TLAN_NET_SIO_EDATA, sio );	/* Ack = 0 */
+		TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
+		TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
+	} else {
+		TLan_SetBit( TLAN_NET_SIO_EDATA, sio );		/* No ack = 1 (?) */
+		TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
+		TLan_ClearBit( TLAN_NET_SIO_ECLOK, sio );
+		TLan_ClearBit( TLAN_NET_SIO_EDATA, sio );	/* STOP, raise data while clock is high */
+		TLan_SetBit( TLAN_NET_SIO_ECLOK, sio );
+		TLan_SetBit( TLAN_NET_SIO_EDATA, sio );
+	}
+
+} /* TLan_EeReceiveByte */
+
+	/***************************************************************
+	 *	TLan_EeReadByte
+	 *
+	 *	Returns:
+	 *		No error = 0, else, the stage at which the error
+	 *		occurred.
+	 *	Parms:
+	 *		io_base		The IO port base address for the
+	 *				TLAN device with the EEPROM to
+	 *				use.
+	 *		ee_addr		The address of the byte in the
+	 *				EEPROM whose contents are to be
+	 *				retrieved.
+	 *		data		An address to a char to hold the
+	 *				data obtained from the EEPROM.
+	 *
+	 *	This function reads a byte of information from an byte
+	 *	cell in the EEPROM.
+	 *
+	 **************************************************************/
+
+static int TLan_EeReadByte( u16 io_base, u8 ee_addr, u8 *data )
+{
+	int err;
+	unsigned long flags = 0;
+	int ret=0;
+
+	TLan_EeSendStart( io_base );
+	err = TLan_EeSendByte( io_base, 0xA0, TLAN_EEPROM_ACK );
+	if (err)
+	{
+		ret=1;
+		goto fail;
+	}
+	err = TLan_EeSendByte( io_base, ee_addr, TLAN_EEPROM_ACK );
+	if (err)
+	{
+		ret=2;
+		goto fail;
+	}
+	TLan_EeSendStart( io_base );
+	err = TLan_EeSendByte( io_base, 0xA1, TLAN_EEPROM_ACK );
+	if (err)
+	{
+		ret=3;
+		goto fail;
+	}
+	TLan_EeReceiveByte( io_base, data, TLAN_EEPROM_STOP );
+fail:
+
+	return ret;
+
+} /* TLan_EeReadByte */
+
+#if	0
+/* Not yet converted from Linux driver */
+/*****************************************************************************
+******************************************************************************
+
+	ThunderLAN Driver PHY Layer Routines
+
+******************************************************************************
+*****************************************************************************/
+
+	/*********************************************************************
+	 *	TLan_PhyPrint
+	 *
+	 *	Returns:
+	 *		Nothing
+	 *	Parms:
+	 *		dev	A pointer to the device structure of the
+	 *			TLAN device having the PHYs to be detailed.
+	 *				
+	 *	This function prints the registers a PHY (aka tranceiver).
+	 *
+	 ********************************************************************/
+
+void TLan_PhyPrint( struct net_device *dev )
+{
+	TLanPrivateInfo *priv = dev->priv;
+	u16 i, data0, data1, data2, data3, phy;
+
+	phy = priv->phy[priv->phyNum];
+
+	if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) {
+		printk( "TLAN:   Device %s, Unmanaged PHY.\n", dev->name );
+	} else if ( phy <= TLAN_PHY_MAX_ADDR ) {
+		printk( "TLAN:   Device %s, PHY 0x%02x.\n", dev->name, phy );
+		printk( "TLAN:      Off.  +0     +1     +2     +3 \n" );
+                for ( i = 0; i < 0x20; i+= 4 ) {
+			printk( "TLAN:      0x%02x", i );
+			TLan_MiiReadReg( dev, phy, i, &data0 );
+			printk( " 0x%04hx", data0 );
+			TLan_MiiReadReg( dev, phy, i + 1, &data1 );
+			printk( " 0x%04hx", data1 );
+			TLan_MiiReadReg( dev, phy, i + 2, &data2 );
+			printk( " 0x%04hx", data2 );
+			TLan_MiiReadReg( dev, phy, i + 3, &data3 );
+			printk( " 0x%04hx\n", data3 );
+		}
+	} else {
+		printk( "TLAN:   Device %s, Invalid PHY.\n", dev->name );
+	}
+
+} /* TLan_PhyPrint */
+
+	/*********************************************************************
+	 *	TLan_PhyDetect
+	 *
+	 *	Returns:
+	 *		Nothing
+	 *	Parms:
+	 *		dev	A pointer to the device structure of the adapter
+	 *			for which the PHY needs determined.
+	 *
+	 *	So far I've found that adapters which have external PHYs
+	 *	may also use the internal PHY for part of the functionality.
+	 *	(eg, AUI/Thinnet).  This function finds out if this TLAN
+	 *	chip has an internal PHY, and then finds the first external
+	 *	PHY (starting from address 0) if it exists).
+	 *
+	 ********************************************************************/
+
+void TLan_PhyDetect( struct net_device *dev )
+{
+	TLanPrivateInfo *priv = dev->priv;
+	u16		control;
+	u16		hi;
+	u16		lo;
+	u32		phy;
+
+	if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) {
+		priv->phyNum = 0xFFFF;
+		return;
+	}
+
+	TLan_MiiReadReg( dev, TLAN_PHY_MAX_ADDR, MII_GEN_ID_HI, &hi );
+	
+	if ( hi != 0xFFFF ) {
+		priv->phy[0] = TLAN_PHY_MAX_ADDR;
+	} else {
+		priv->phy[0] = TLAN_PHY_NONE;
+	}
+
+	priv->phy[1] = TLAN_PHY_NONE;
+	for ( phy = 0; phy <= TLAN_PHY_MAX_ADDR; phy++ ) {
+		TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &control );
+		TLan_MiiReadReg( dev, phy, MII_GEN_ID_HI, &hi );
+		TLan_MiiReadReg( dev, phy, MII_GEN_ID_LO, &lo );
+		if ( ( control != 0xFFFF ) || ( hi != 0xFFFF ) || ( lo != 0xFFFF ) ) {
+			TLAN_DBG( TLAN_DEBUG_GNRL, "PHY found at %02x %04x %04x %04x\n", phy, control, hi, lo );
+			if ( ( priv->phy[1] == TLAN_PHY_NONE ) && ( phy != TLAN_PHY_MAX_ADDR ) ) {
+				priv->phy[1] = phy;
+			}
+		}
+	}
+
+	if ( priv->phy[1] != TLAN_PHY_NONE ) {
+		priv->phyNum = 1;
+	} else if ( priv->phy[0] != TLAN_PHY_NONE ) {
+		priv->phyNum = 0;
+	} else {
+		printk( "TLAN:  Cannot initialize device, no PHY was found!\n" );
+	}
+
+} /* TLan_PhyDetect */
+
+void TLan_PhyPowerDown( struct net_device *dev )
+{
+	TLanPrivateInfo	*priv = dev->priv;
+	u16		value;
+
+	TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Powering down PHY(s).\n", dev->name );
+	value = MII_GC_PDOWN | MII_GC_LOOPBK | MII_GC_ISOLATE;
+	TLan_MiiSync( dev->base_addr );
+	TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value );
+	if ( ( priv->phyNum == 0 ) && ( priv->phy[1] != TLAN_PHY_NONE ) && ( ! ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) ) ) {
+		TLan_MiiSync( dev->base_addr );
+		TLan_MiiWriteReg( dev, priv->phy[1], MII_GEN_CTL, value );
+	}
+
+	/* Wait for 50 ms and powerup
+	 * This is abitrary.  It is intended to make sure the
+	 * tranceiver settles.
+	 */
+	TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_PUP );
+
+} /* TLan_PhyPowerDown */
+
+void TLan_PhyPowerUp( struct net_device *dev )
+{
+	TLanPrivateInfo	*priv = dev->priv;
+	u16		value;
+
+	TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Powering up PHY.\n", dev->name );
+	TLan_MiiSync( dev->base_addr );
+	value = MII_GC_LOOPBK;
+	TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value );
+	TLan_MiiSync(dev->base_addr);
+	/* Wait for 500 ms and reset the
+	 * tranceiver.  The TLAN docs say both 50 ms and
+	 * 500 ms, so do the longer, just in case.
+	 */
+	TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_RESET );
+
+} /* TLan_PhyPowerUp */
+
+void TLan_PhyReset( struct net_device *dev )
+{
+	TLanPrivateInfo	*priv = dev->priv;
+	u16		phy;
+	u16		value;
+
+	phy = priv->phy[priv->phyNum];
+
+	TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Reseting PHY.\n", dev->name );
+	TLan_MiiSync( dev->base_addr );
+	value = MII_GC_LOOPBK | MII_GC_RESET;
+	TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, value );
+	TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &value );
+	while ( value & MII_GC_RESET ) {
+		TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &value );
+	}
+
+	/* Wait for 500 ms and initialize.
+	 * I don't remember why I wait this long.
+	 * I've changed this to 50ms, as it seems long enough.
+	 */
+	TLan_SetTimer( dev, (HZ/20), TLAN_TIMER_PHY_START_LINK );
+
+} /* TLan_PhyReset */
+
+void TLan_PhyStartLink( struct net_device *dev )
+{
+	TLanPrivateInfo	*priv = dev->priv;
+	u16		ability;
+	u16		control;
+	u16		data;
+	u16		phy;
+	u16		status;
+	u16		tctl;
+
+	phy = priv->phy[priv->phyNum];
+	TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Trying to activate link.\n", dev->name );
+	TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
+	TLan_MiiReadReg( dev, phy, MII_GEN_STS, &ability );
+
+	if ( ( status & MII_GS_AUTONEG ) && 
+	     ( ! priv->aui ) ) {
+		ability = status >> 11;
+		if ( priv->speed  == TLAN_SPEED_10 && 
+		     priv->duplex == TLAN_DUPLEX_HALF) {
+			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0000);
+		} else if ( priv->speed == TLAN_SPEED_10 &&
+			    priv->duplex == TLAN_DUPLEX_FULL) {
+			priv->tlanFullDuplex = TRUE;
+			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0100);
+		} else if ( priv->speed == TLAN_SPEED_100 &&
+			    priv->duplex == TLAN_DUPLEX_HALF) {
+			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2000);
+		} else if ( priv->speed == TLAN_SPEED_100 &&
+			    priv->duplex == TLAN_DUPLEX_FULL) {
+			priv->tlanFullDuplex = TRUE;
+			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2100);
+		} else {
+	
+			/* Set Auto-Neg advertisement */
+			TLan_MiiWriteReg( dev, phy, MII_AN_ADV, (ability << 5) | 1);
+			/* Enablee Auto-Neg */
+			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1000 );
+			/* Restart Auto-Neg */
+			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1200 );
+			/* Wait for 4 sec for autonegotiation
+		 	* to complete.  The max spec time is less than this
+		 	* but the card need additional time to start AN.
+		 	* .5 sec should be plenty extra.
+		 	*/
+			printk( "TLAN: %s: Starting autonegotiation.\n", dev->name );
+			TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_PHY_FINISH_AN );
+			return;
+		}
+		
+	}	
+	
+	if ( ( priv->aui ) && ( priv->phyNum != 0 ) ) {
+		priv->phyNum = 0;
+		data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
+		TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data );
+		TLan_SetTimer( dev, (40*HZ/1000), TLAN_TIMER_PHY_PDOWN );
+		return;
+	}  else if ( priv->phyNum == 0 ) {
+        	TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tctl );
+		if ( priv->aui ) {
+                	tctl |= TLAN_TC_AUISEL;
+		} else { 
+                	tctl &= ~TLAN_TC_AUISEL;
+			control = 0;
+			if ( priv->duplex == TLAN_DUPLEX_FULL ) {
+				control |= MII_GC_DUPLEX;
+				priv->tlanFullDuplex = TRUE;
+			}
+			if ( priv->speed == TLAN_SPEED_100 ) {
+				control |= MII_GC_SPEEDSEL;
+			}
+       			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, control );
+		}
+        	TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tctl );
+	}
+
+	/* Wait for 2 sec to give the tranceiver time
+	 * to establish link.
+	 */
+	TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_FINISH_RESET );
+
+} /* TLan_PhyStartLink */
+
+void TLan_PhyFinishAutoNeg( struct net_device *dev )
+{
+	TLanPrivateInfo	*priv = dev->priv;
+	u16		an_adv;
+	u16		an_lpa;
+	u16		data;
+	u16		mode;
+	u16		phy;
+	u16		status;
+	
+	phy = priv->phy[priv->phyNum];
+
+	TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
+	udelay( 1000 );
+	TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
+
+	if ( ! ( status & MII_GS_AUTOCMPLT ) ) {
+		/* Wait for 8 sec to give the process
+		 * more time.  Perhaps we should fail after a while.
+		 */
+		 if (!priv->neg_be_verbose++) {
+			 printk(KERN_INFO "TLAN:  Giving autonegotiation more time.\n");
+		 	 printk(KERN_INFO "TLAN:  Please check that your adapter has\n");
+		 	 printk(KERN_INFO "TLAN:  been properly connected to a HUB or Switch.\n");
+			 printk(KERN_INFO "TLAN:  Trying to establish link in the background...\n");
+		 }
+		TLan_SetTimer( dev, (8*HZ), TLAN_TIMER_PHY_FINISH_AN );
+		return;
+	}
+
+	printk( "TLAN: %s: Autonegotiation complete.\n", dev->name );
+	TLan_MiiReadReg( dev, phy, MII_AN_ADV, &an_adv );
+	TLan_MiiReadReg( dev, phy, MII_AN_LPA, &an_lpa );
+	mode = an_adv & an_lpa & 0x03E0;
+	if ( mode & 0x0100 ) {
+		priv->tlanFullDuplex = TRUE;
+	} else if ( ! ( mode & 0x0080 ) && ( mode & 0x0040 ) ) {
+		priv->tlanFullDuplex = TRUE;
+	}
+
+	if ( ( ! ( mode & 0x0180 ) ) && ( priv->adapter->flags & TLAN_ADAPTER_USE_INTERN_10 ) && ( priv->phyNum != 0 ) ) {
+		priv->phyNum = 0;
+		data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
+		TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, data );
+		TLan_SetTimer( dev, (400*HZ/1000), TLAN_TIMER_PHY_PDOWN );
+		return;
+	}
+
+	if ( priv->phyNum == 0 ) {
+		if ( ( priv->duplex == TLAN_DUPLEX_FULL ) || ( an_adv & an_lpa & 0x0040 ) ) {
+			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB | MII_GC_DUPLEX );
+			printk( "TLAN:  Starting internal PHY with FULL-DUPLEX\n" );
+		} else {
+			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, MII_GC_AUTOENB );
+			printk( "TLAN:  Starting internal PHY with HALF-DUPLEX\n" );
+		}
+	}
+
+	/* Wait for 100 ms.  No reason in partiticular.
+	 */
+	TLan_SetTimer( dev, (HZ/10), TLAN_TIMER_FINISH_RESET );
+		
+} /* TLan_PhyFinishAutoNeg */
+
+#ifdef MONITOR
+
+        /*********************************************************************
+        *
+        *      TLan_phyMonitor
+        *
+        *      Returns: 
+        *              None
+        *
+        *      Params:
+        *              dev             The device structure of this device.
+        *
+        *      
+        *      This function monitors PHY condition by reading the status
+        *      register via the MII bus. This can be used to give info
+        *      about link changes (up/down), and possible switch to alternate
+        *      media.
+        *
+        * ******************************************************************/
+
+void TLan_PhyMonitor( struct net_device *dev )
+{
+	TLanPrivateInfo *priv = dev->priv;
+	u16     phy;
+	u16     phy_status;
+
+	phy = priv->phy[priv->phyNum];
+
+        /* Get PHY status register */
+        TLan_MiiReadReg( dev, phy, MII_GEN_STS, &phy_status );
+
+        /* Check if link has been lost */
+        if (!(phy_status & MII_GS_LINK)) { 
+ 	       if (priv->link) {
+		      priv->link = 0;
+	              printk(KERN_DEBUG "TLAN: %s has lost link\n", dev->name);
+	              dev->flags &= ~IFF_RUNNING;
+		      TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT );
+		      return;
+		}
+	}
+
+        /* Link restablished? */
+        if ((phy_status & MII_GS_LINK) && !priv->link) {
+ 		priv->link = 1;
+        	printk(KERN_DEBUG "TLAN: %s has reestablished link\n", dev->name);
+        	dev->flags |= IFF_RUNNING;
+        }
+
+	/* Setup a new monitor */
+	TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_LINK_BEAT );
+}	
+
+#endif /* MONITOR */
+
+/*****************************************************************************
+******************************************************************************
+
+	ThunderLAN Driver MII Routines
+
+	These routines are based on the information in Chap. 2 of the
+	"ThunderLAN Programmer's Guide", pp. 15-24.
+
+******************************************************************************
+*****************************************************************************/
+
+	/***************************************************************
+	 *	TLan_MiiReadReg
+	 *
+	 *	Returns:
+	 *		0	if ack received ok
+	 *		1	otherwise.
+	 *
+	 *	Parms:
+	 *		dev		The device structure containing
+	 *				The io address and interrupt count
+	 *				for this device.
+	 *		phy		The address of the PHY to be queried.
+	 *		reg		The register whose contents are to be
+	 *				retreived.
+	 *		val		A pointer to a variable to store the
+	 *				retrieved value.
+	 *
+	 *	This function uses the TLAN's MII bus to retreive the contents
+	 *	of a given register on a PHY.  It sends the appropriate info
+	 *	and then reads the 16-bit register value from the MII bus via
+	 *	the TLAN SIO register.
+	 *
+	 **************************************************************/
+
+int TLan_MiiReadReg( struct net_device *dev, u16 phy, u16 reg, u16 *val )
+{
+	u8	nack;
+	u16	sio, tmp;
+ 	u32	i;
+	int	err;
+	int	minten;
+	TLanPrivateInfo *priv = dev->priv;
+	unsigned long flags = 0;
+
+	err = FALSE;
+	outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
+	sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
+	
+	if (!in_irq())
+		spin_lock_irqsave(&priv->lock, flags);
+
+	TLan_MiiSync(dev->base_addr);
+
+	minten = TLan_GetBit( TLAN_NET_SIO_MINTEN, sio );
+	if ( minten )
+		TLan_ClearBit(TLAN_NET_SIO_MINTEN, sio);
+
+	TLan_MiiSendData( dev->base_addr, 0x1, 2 );	/* Start ( 01b ) */
+	TLan_MiiSendData( dev->base_addr, 0x2, 2 );	/* Read  ( 10b ) */
+	TLan_MiiSendData( dev->base_addr, phy, 5 );	/* Device #      */
+	TLan_MiiSendData( dev->base_addr, reg, 5 );	/* Register #    */
+
+	TLan_ClearBit(TLAN_NET_SIO_MTXEN, sio);		/* Change direction */
+
+	TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);		/* Clock Idle bit */
+	TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
+	TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);		/* Wait 300ns */
+
+	nack = TLan_GetBit(TLAN_NET_SIO_MDATA, sio);	/* Check for ACK */
+	TLan_SetBit(TLAN_NET_SIO_MCLK, sio);		/* Finish ACK */
+	if (nack) {					/* No ACK, so fake it */
+		for (i = 0; i < 16; i++) {
+			TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
+			TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
+		}
+		tmp = 0xffff;
+		err = TRUE;
+	} else {					/* ACK, so read data */
+		for (tmp = 0, i = 0x8000; i; i >>= 1) {
+			TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);
+			if (TLan_GetBit(TLAN_NET_SIO_MDATA, sio))
+				tmp |= i;
+			TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
+		}
+	}
+
+	TLan_ClearBit(TLAN_NET_SIO_MCLK, sio);		/* Idle cycle */
+	TLan_SetBit(TLAN_NET_SIO_MCLK, sio);
+
+	if ( minten )
+		TLan_SetBit(TLAN_NET_SIO_MINTEN, sio);
+
+	*val = tmp;
+	
+	if (!in_irq())
+		spin_unlock_irqrestore(&priv->lock, flags);
+
+	return err;
+
+} /* TLan_MiiReadReg */
+
+	/***************************************************************
+	 *	TLan_MiiSendData
+	 *
+	 *	Returns:
+	 *		Nothing
+	 *	Parms:
+	 *		base_port	The base IO port of the adapter	in
+	 *				question.
+	 *		dev		The address of the PHY to be queried.
+	 *		data		The value to be placed on the MII bus.
+	 *		num_bits	The number of bits in data that are to
+	 *				be placed on the MII bus.
+	 *
+	 *	This function sends on sequence of bits on the MII
+	 *	configuration bus.
+	 *
+	 **************************************************************/
+
+void TLan_MiiSendData( u16 base_port, u32 data, unsigned num_bits )
+{
+	u16 sio;
+	u32 i;
+
+	if ( num_bits == 0 )
+		return;
+
+	outw( TLAN_NET_SIO, base_port + TLAN_DIO_ADR );
+	sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
+	TLan_SetBit( TLAN_NET_SIO_MTXEN, sio );
+
+	for ( i = ( 0x1 << ( num_bits - 1 ) ); i; i >>= 1 ) {
+		TLan_ClearBit( TLAN_NET_SIO_MCLK, sio );
+		(void) TLan_GetBit( TLAN_NET_SIO_MCLK, sio );
+		if ( data & i )
+			TLan_SetBit( TLAN_NET_SIO_MDATA, sio );
+		else
+			TLan_ClearBit( TLAN_NET_SIO_MDATA, sio );
+		TLan_SetBit( TLAN_NET_SIO_MCLK, sio );
+		(void) TLan_GetBit( TLAN_NET_SIO_MCLK, sio );
+	}
+
+} /* TLan_MiiSendData */
+
+	/***************************************************************
+	 *	TLan_MiiSync
+	 *
+	 *	Returns:
+	 *		Nothing
+	 *	Parms:
+	 *		base_port	The base IO port of the adapter in
+	 *				question.
+	 *
+	 *	This functions syncs all PHYs in terms of the MII configuration
+	 *	bus.
+	 *
+	 **************************************************************/
+
+void TLan_MiiSync( u16 base_port )
+{
+	int i;
+	u16 sio;
+
+	outw( TLAN_NET_SIO, base_port + TLAN_DIO_ADR );
+	sio = base_port + TLAN_DIO_DATA + TLAN_NET_SIO;
+
+	TLan_ClearBit( TLAN_NET_SIO_MTXEN, sio );
+	for ( i = 0; i < 32; i++ ) {
+		TLan_ClearBit( TLAN_NET_SIO_MCLK, sio );
+		TLan_SetBit( TLAN_NET_SIO_MCLK, sio );
+	}
+
+} /* TLan_MiiSync */
+
+	/***************************************************************
+	 *	TLan_MiiWriteReg
+	 *
+	 *	Returns:
+	 *		Nothing
+	 *	Parms:
+	 *		dev		The device structure for the device
+	 *				to write to.
+	 *		phy		The address of the PHY to be written to.
+	 *		reg		The register whose contents are to be
+	 *				written.
+	 *		val		The value to be written to the register.
+	 *
+	 *	This function uses the TLAN's MII bus to write the contents of a
+	 *	given register on a PHY.  It sends the appropriate info and then
+	 *	writes the 16-bit register value from the MII configuration bus
+	 *	via the TLAN SIO register.
+	 *
+	 **************************************************************/
+
+void TLan_MiiWriteReg( struct net_device *dev, u16 phy, u16 reg, u16 val )
+{
+	u16	sio;
+	int	minten;
+	unsigned long flags = 0;
+	TLanPrivateInfo *priv = dev->priv;
+
+	outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
+	sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
+	
+	if (!in_irq())
+		spin_lock_irqsave(&priv->lock, flags);
+
+	TLan_MiiSync( dev->base_addr );
+
+	minten = TLan_GetBit( TLAN_NET_SIO_MINTEN, sio );
+	if ( minten )
+		TLan_ClearBit( TLAN_NET_SIO_MINTEN, sio );
+
+	TLan_MiiSendData( dev->base_addr, 0x1, 2 );	/* Start ( 01b ) */
+	TLan_MiiSendData( dev->base_addr, 0x1, 2 );	/* Write ( 01b ) */
+	TLan_MiiSendData( dev->base_addr, phy, 5 );	/* Device #      */
+	TLan_MiiSendData( dev->base_addr, reg, 5 );	/* Register #    */
+
+	TLan_MiiSendData( dev->base_addr, 0x2, 2 );	/* Send ACK */
+	TLan_MiiSendData( dev->base_addr, val, 16 );	/* Send Data */
+
+	TLan_ClearBit( TLAN_NET_SIO_MCLK, sio );	/* Idle cycle */
+	TLan_SetBit( TLAN_NET_SIO_MCLK, sio );
+
+	if ( minten )
+		TLan_SetBit( TLAN_NET_SIO_MINTEN, sio );
+	
+	if (!in_irq())
+		spin_unlock_irqrestore(&priv->lock, flags);
+
+} /* TLan_MiiWriteReg */
+#endif
+
+/**************************************************************************
+RESET - Reset adapter
+***************************************************************************/
+static void skel_reset(struct nic *nic)
+{
+	/* put the card in its initial state */
+}
+
+/**************************************************************************
+POLL - Wait for a frame
+***************************************************************************/
+static int skel_poll(struct nic *nic)
+{
+	/* return true if there's an ethernet packet ready to read */
+	/* nic->packet should contain data on return */
+	/* nic->packetlen should contain length of data */
+	return (0);	/* initially as this is called to flush the input */
+}
+
+/**************************************************************************
+TRANSMIT - Transmit a frame
+***************************************************************************/
+static void skel_transmit(
+	struct nic *nic,
+	const char *d,			/* Destination */
+	unsigned int t,			/* Type */
+	unsigned int s,			/* size */
+	const char *p)			/* Packet */
+{
+	/* send the packet to destination */
+}
+
+/**************************************************************************
+DISABLE - Turn off ethernet interface
+***************************************************************************/
+static void skel_disable(struct nic *nic)
+{
+}
+
+/**************************************************************************
+PROBE - Look for an adapter, this routine's visible to the outside
+You should omit the last argument struct pci_device * for a non-PCI NIC
+***************************************************************************/
+struct nic *tlan_probe(struct nic *nic, unsigned short *probe_addrs,
+	struct pci_device *p)
+{
+	/* if probe_addrs is 0, then routine can use a hardwired default */
+	/* if board found */
+	{
+		/* point to NIC specific routines */
+		nic->reset = skel_reset;
+		nic->poll = skel_poll;
+		nic->transmit = skel_transmit;
+		nic->disable = skel_disable;
+		return nic;
+	}
+	/* else */
+	return 0;
+}
+
+#if	0
+#ifndef TLAN_H
+#define TLAN_H
+/********************************************************************
+ *
+ *  Linux ThunderLAN Driver
+ *
+ *  tlan.h
+ *  by James Banks
+ *
+ *  (C) 1997-1998 Caldera, Inc.
+ *  (C) 1999-2001 Torben Mathiasen
+ * 
+ *  This software may be used and distributed according to the terms
+ *  of the GNU General Public License, incorporated herein by reference.
+ *
+ ** This file is best viewed/edited with tabstop=4, colums>=132
+ *
+ *  
+ *  Dec 10, 1999	Torben Mathiasen <torben.mathiasen@compaq.com>
+ *			New Maintainer
+ *
+ ********************************************************************/
+
+#include <asm/io.h>
+#include <asm/types.h>
+#include <linux/netdevice.h>
+
+#define FALSE			0
+#define TRUE			1
+
+#define TX_TIMEOUT		(10*HZ)	 /* We need time for auto-neg */
+
+typedef struct tlan_adapter_entry {
+	u16	vendorId;
+	u16	deviceId;
+	char	*deviceLabel;
+	u32	flags;
+	u16	addrOfs;
+} TLanAdapterEntry;
+
+	/*****************************************************************
+	 * EISA Definitions
+	 *
+	 ****************************************************************/
+
+#define EISA_ID      0xc80   /* EISA ID Registers */ 
+#define EISA_ID0     0xc80   /* EISA ID Register 0 */ 
+#define EISA_ID1     0xc81   /* EISA ID Register 1 */ 
+#define EISA_ID2     0xc82   /* EISA ID Register 2 */ 
+#define EISA_ID3     0xc83   /* EISA ID Register 3 */ 
+#define EISA_CR      0xc84   /* EISA Control Register */
+#define EISA_REG0    0xc88   /* EISA Configuration Register 0 */
+#define EISA_REG1    0xc89   /* EISA Configuration Register 1 */
+#define EISA_REG2    0xc8a   /* EISA Configuration Register 2 */
+#define EISA_REG3    0xc8f   /* EISA Configuration Register 3 */
+#define EISA_APROM   0xc90   /* Ethernet Address PROM */
+
+	/*****************************************************************
+	 * Rx/Tx List Definitions
+	 *
+	 ****************************************************************/
+
+typedef struct tlan_buffer_ref_tag {
+	u32	count;
+	u32	address;
+} TLanBufferRef;
+
+typedef struct tlan_list_tag {
+	u32		forward;
+	u16		cStat;
+	u16		frameSize;
+	TLanBufferRef	buffer[TLAN_BUFFERS_PER_LIST];
+} TLanList;
+
+typedef u8 TLanBuffer[TLAN_MAX_FRAME_SIZE];
+
+	/*****************************************************************
+	 * TLAN Private Information Structure
+	 *
+	 ****************************************************************/
+
+typedef struct tlan_private_tag {
+	struct net_device       *nextDevice;
+	void			*dmaStorage;
+	u8			*padBuffer;
+	TLanList                *rxList;
+	u8			*rxBuffer;
+	u32                     rxHead;
+	u32                     rxTail;
+	u32			rxEocCount;
+	TLanList                *txList;
+	u8			*txBuffer;
+	u32                     txHead;
+	u32                     txInProgress;
+	u32                     txTail;
+	u32			txBusyCount;
+	u32                     phyOnline;
+	u32			timerSetAt;
+	u32			timerType;
+	struct timer_list	timer;
+	struct net_device_stats	stats;
+	struct board		*adapter;
+	u32			adapterRev;
+	u32			aui;
+	u32			debug;
+	u32			duplex;
+	u32			phy[2];
+	u32			phyNum;
+	u32			speed;
+	u8			tlanRev;
+	u8			tlanFullDuplex;
+	char                    devName[8];
+	spinlock_t		lock;
+	u8			link;
+	u8			is_eisa;
+	struct tq_struct	tlan_tqueue;
+	u8			neg_be_verbose;
+} TLanPrivateInfo;
+
+#define 	TLAN_HC_GO		0x80000000
+#define		TLAN_HC_STOP		0x40000000
+#define		TLAN_HC_ACK		0x20000000
+#define		TLAN_HC_CS_MASK		0x1FE00000
+#define		TLAN_HC_EOC		0x00100000
+#define		TLAN_HC_RT		0x00080000
+#define		TLAN_HC_NES		0x00040000
+#define		TLAN_HC_AD_RST		0x00008000
+#define		TLAN_HC_LD_TMR		0x00004000
+#define		TLAN_HC_LD_THR		0x00002000
+#define		TLAN_HC_REQ_INT		0x00001000
+#define		TLAN_HC_INT_OFF		0x00000800
+#define		TLAN_HC_INT_ON		0x00000400
+#define		TLAN_HC_AC_MASK		0x000000FF
+#define		TLAN_DA_ADR_INC		0x8000
+#define		TLAN_DA_RAM_ADR		0x4000
+#define		TLAN_HI_IV_MASK		0x1FE0
+#define		TLAN_HI_IT_MASK		0x001C
+
+#define		TLAN_NET_CMD_NRESET	0x80
+#define		TLAN_NET_CMD_NWRAP	0x40
+#define		TLAN_NET_CMD_CSF	0x20
+#define		TLAN_NET_CMD_CAF	0x10
+#define		TLAN_NET_CMD_NOBRX	0x08
+#define		TLAN_NET_CMD_DUPLEX	0x04
+#define		TLAN_NET_CMD_TRFRAM	0x02
+#define		TLAN_NET_CMD_TXPACE	0x01
+#define 	TLAN_NET_SIO_MINTEN	0x80
+#define		TLAN_NET_SIO_ECLOK	0x40
+#define		TLAN_NET_SIO_ETXEN	0x20
+#define		TLAN_NET_SIO_EDATA	0x10
+#define		TLAN_NET_SIO_NMRST	0x08
+#define		TLAN_NET_SIO_MCLK	0x04
+#define		TLAN_NET_SIO_MTXEN	0x02
+#define		TLAN_NET_SIO_MDATA	0x01
+#define		TLAN_NET_STS_MIRQ	0x80
+#define		TLAN_NET_STS_HBEAT	0x40
+#define		TLAN_NET_STS_TXSTOP	0x20
+#define		TLAN_NET_STS_RXSTOP	0x10
+#define		TLAN_NET_STS_RSRVD	0x0F
+#define		TLAN_NET_MASK_MASK7	0x80
+#define		TLAN_NET_MASK_MASK6	0x40
+#define		TLAN_NET_MASK_MASK5	0x20
+#define		TLAN_NET_MASK_MASK4	0x10
+#define		TLAN_NET_MASK_RSRVD	0x0F
+#define 	TLAN_NET_CFG_RCLK	0x8000
+#define		TLAN_NET_CFG_TCLK	0x4000
+#define		TLAN_NET_CFG_BIT	0x2000
+#define		TLAN_NET_CFG_RXCRC	0x1000
+#define		TLAN_NET_CFG_PEF	0x0800
+#define		TLAN_NET_CFG_1FRAG	0x0400
+#define		TLAN_NET_CFG_1CHAN	0x0200
+#define		TLAN_NET_CFG_MTEST	0x0100
+#define		TLAN_NET_CFG_PHY_EN	0x0080
+#define		TLAN_NET_CFG_MSMASK	0x007F
+#define		TLAN_LED_ACT		0x10
+#define		TLAN_LED_LINK		0x01
+#define		TLAN_ID_TX_EOC		0x04
+#define		TLAN_ID_RX_EOF		0x02
+#define		TLAN_ID_RX_EOC		0x01
+
+#define CIRC_INC( a, b ) if ( ++a >= b ) a = 0
+
+#ifdef I_LIKE_A_FAST_HASH_FUNCTION
+/* given 6 bytes, view them as 8 6-bit numbers and return the XOR of those */
+/* the code below is about seven times as fast as the original code */
+inline u32 TLan_HashFunc( u8 *a )
+{
+        u8     hash;
+
+        hash = (a[0]^a[3]);             /* & 077 */
+        hash ^= ((a[0]^a[3])>>6);       /* & 003 */
+        hash ^= ((a[1]^a[4])<<2);       /* & 074 */
+        hash ^= ((a[1]^a[4])>>4);       /* & 017 */
+        hash ^= ((a[2]^a[5])<<4);       /* & 060 */
+        hash ^= ((a[2]^a[5])>>2);       /* & 077 */
+
+        return (hash & 077);
+}
+
+#else /* original code */
+
+inline	u32	xor( u32 a, u32 b )
+{
+	return ( ( a && ! b ) || ( ! a && b ) );
+}
+#define XOR8( a, b, c, d, e, f, g, h )	xor( a, xor( b, xor( c, xor( d, xor( e, xor( f, xor( g, h ) ) ) ) ) ) )
+#define DA( a, bit )					( ( (u8) a[bit/8] ) & ( (u8) ( 1 << bit%8 ) ) )
+
+inline u32 TLan_HashFunc( u8 *a )
+{
+	u32	hash;
+
+	hash  = XOR8( DA(a,0), DA(a, 6), DA(a,12), DA(a,18), DA(a,24), DA(a,30), DA(a,36), DA(a,42) );
+	hash |= XOR8( DA(a,1), DA(a, 7), DA(a,13), DA(a,19), DA(a,25), DA(a,31), DA(a,37), DA(a,43) ) << 1;
+	hash |= XOR8( DA(a,2), DA(a, 8), DA(a,14), DA(a,20), DA(a,26), DA(a,32), DA(a,38), DA(a,44) ) << 2;
+	hash |= XOR8( DA(a,3), DA(a, 9), DA(a,15), DA(a,21), DA(a,27), DA(a,33), DA(a,39), DA(a,45) ) << 3;
+	hash |= XOR8( DA(a,4), DA(a,10), DA(a,16), DA(a,22), DA(a,28), DA(a,34), DA(a,40), DA(a,46) ) << 4;
+	hash |= XOR8( DA(a,5), DA(a,11), DA(a,17), DA(a,23), DA(a,29), DA(a,35), DA(a,41), DA(a,47) ) << 5;
+
+	return hash;
+
+} 
+
+#endif /* I_LIKE_A_FAST_HASH_FUNCTION */
+#endif
+/*******************************************************************************
+ *
+ *  Linux ThunderLAN Driver
+ *
+ *  tlan.c
+ *  by James Banks
+ *
+ *  (C) 1997-1998 Caldera, Inc.
+ *  (C) 1998 James Banks
+ *  (C) 1999-2001 Torben Mathiasen
+ *
+ *  This software may be used and distributed according to the terms
+ *  of the GNU General Public License, incorporated herein by reference.
+ *
+ ** This file is best viewed/edited with columns>=132.
+ *
+ ** Useful (if not required) reading:
+ *
+ *		Texas Instruments, ThunderLAN Programmer's Guide,
+ *			TI Literature Number SPWU013A
+ *			available in PDF format from www.ti.com
+ *		Level One, LXT901 and LXT970 Data Sheets
+ *			available in PDF format from www.level1.com
+ *		National Semiconductor, DP83840A Data Sheet
+ *			available in PDF format from www.national.com
+ *		Microchip Technology, 24C01A/02A/04A Data Sheet
+ *			available in PDF format from www.microchip.com
+ *
+ * Change History
+ *
+ *	Tigran Aivazian <tigran@sco.com>:	TLan_PciProbe() now uses
+ *						new PCI BIOS interface.
+ *	Alan Cox	<alan@redhat.com>:	Fixed the out of memory
+ *						handling.
+ *      
+ *	Torben Mathiasen <torben.mathiasen@compaq.com> New Maintainer!
+ *
+ *	v1.1 Dec 20, 1999    - Removed linux version checking
+ *			       Patch from Tigran Aivazian. 
+ *			     - v1.1 includes Alan's SMP updates.
+ *			     - We still have problems on SMP though,
+ *			       but I'm looking into that. 
+ *			
+ *	v1.2 Jan 02, 2000    - Hopefully fixed the SMP deadlock.
+ *			     - Removed dependency of HZ being 100.
+ *			     - We now allow higher priority timers to 
+ *			       overwrite timers like TLAN_TIMER_ACTIVITY
+ *			       Patch from John Cagle <john.cagle@compaq.com>.
+ *			     - Fixed a few compiler warnings.
+ *
+ *	v1.3 Feb 04, 2000    - Fixed the remaining HZ issues.
+ *			     - Removed call to pci_present(). 
+ *			     - Removed SA_INTERRUPT flag from irq handler.
+ *			     - Added __init and __initdata to reduce resisdent 
+ *			       code size.
+ *			     - Driver now uses module_init/module_exit.
+ *			     - Rewrote init_module and tlan_probe to
+ *			       share a lot more code. We now use tlan_probe
+ *			       with builtin and module driver.
+ *			     - Driver ported to new net API. 
+ *			     - tlan.txt has been reworked to reflect current 
+ *			       driver (almost)
+ *			     - Other minor stuff
+ *
+ *	v1.4 Feb 10, 2000    - Updated with more changes required after Dave's
+ *	                       network cleanup in 2.3.43pre7 (Tigran & myself)
+ *	                     - Minor stuff.
+ *
+ *	v1.5 March 22, 2000  - Fixed another timer bug that would hang the driver
+ *			       if no cable/link were present.
+ *			     - Cosmetic changes.
+ *			     - TODO: Port completely to new PCI/DMA API
+ *			     	     Auto-Neg fallback.
+ *
+ * 	v1.6 April 04, 2000  - Fixed driver support for kernel-parameters. Haven't
+ * 			       tested it though, as the kernel support is currently 
+ * 			       broken (2.3.99p4p3).
+ * 			     - Updated tlan.txt accordingly.
+ * 			     - Adjusted minimum/maximum frame length.
+ * 			     - There is now a TLAN website up at 
+ * 			       http://tlan.kernel.dk
+ *
+ * 	v1.7 April 07, 2000  - Started to implement custom ioctls. Driver now
+ * 			       reports PHY information when used with Donald
+ * 			       Beckers userspace MII diagnostics utility.
+ *
+ * 	v1.8 April 23, 2000  - Fixed support for forced speed/duplex settings.
+ * 			     - Added link information to Auto-Neg and forced
+ * 			       modes. When NIC operates with auto-neg the driver
+ * 			       will report Link speed & duplex modes as well as
+ * 			       link partner abilities. When forced link is used,
+ * 			       the driver will report status of the established
+ * 			       link.
+ * 			       Please read tlan.txt for additional information. 
+ * 			     - Removed call to check_region(), and used 
+ * 			       return value of request_region() instead.
+ *	
+ *	v1.8a May 28, 2000   - Minor updates.
+ *
+ *	v1.9 July 25, 2000   - Fixed a few remaining Full-Duplex issues.
+ *	                     - Updated with timer fixes from Andrew Morton.
+ *	                     - Fixed module race in TLan_Open.
+ *	                     - Added routine to monitor PHY status.
+ *	                     - Added activity led support for Proliant devices.
+ *
+ *	v1.10 Aug 30, 2000   - Added support for EISA based tlan controllers 
+ *			       like the Compaq NetFlex3/E. 
+ *			     - Rewrote tlan_probe to better handle multiple
+ *			       bus probes. Probing and device setup is now
+ *			       done through TLan_Probe and TLan_init_one. Actual
+ *			       hardware probe is done with kernel API and 
+ *			       TLan_EisaProbe.
+ *			     - Adjusted debug information for probing.
+ *			     - Fixed bug that would cause general debug information 
+ *			       to be printed after driver removal. 
+ *			     - Added transmit timeout handling.
+ *			     - Fixed OOM return values in tlan_probe. 
+ *			     - Fixed possible mem leak in tlan_exit 
+ *			       (now tlan_remove_one).
+ *			     - Fixed timer bug in TLan_phyMonitor.
+ *			     - This driver version is alpha quality, please
+ *			       send me any bug issues you may encounter.
+ *
+ *	v1.11 Aug 31, 2000   - Do not try to register irq 0 if no irq line was 
+ *			       set for EISA cards.
+ *			     - Added support for NetFlex3/E with nibble-rate
+ *			       10Base-T PHY. This is untestet as I haven't got
+ *			       one of these cards.
+ *			     - Fixed timer being added twice.
+ *			     - Disabled PhyMonitoring by default as this is
+ *			       work in progress. Define MONITOR to enable it.
+ *			     - Now we don't display link info with PHYs that
+ *			       doesn't support it (level1).
+ *			     - Incresed tx_timeout beacuse of auto-neg.
+ *			     - Adjusted timers for forced speeds.
+ *
+ *	v1.12 Oct 12, 2000   - Minor fixes (memleak, init, etc.)
+ *
+ * 	v1.13 Nov 28, 2000   - Stop flooding console with auto-neg issues
+ * 			       when link can't be established.
+ *			     - Added the bbuf option as a kernel parameter.
+ *			     - Fixed ioaddr probe bug.
+ *			     - Fixed stupid deadlock with MII interrupts.
+ *			     - Added support for speed/duplex selection with 
+ *			       multiple nics.
+ *			     - Added partly fix for TX Channel lockup with
+ *			       TLAN v1.0 silicon. This needs to be investigated
+ *			       further.
+ *
+ * 	v1.14 Dec 16, 2000   - Added support for servicing multiple frames per.
+ * 			       interrupt. Thanks goes to
+ * 			       Adam Keys <adam@ti.com>
+ * 			       Denis Beaudoin <dbeaudoin@ti.com>
+ * 			       for providing the patch.
+ * 			     - Fixed auto-neg output when using multiple
+ * 			       adapters.
+ * 			     - Converted to use new taskq interface.
+ *
+ * 	v1.14a Jan 6, 2001   - Minor adjustments (spinlocks, etc.)
+ *
+ *******************************************************************************/
+
+                                                                                
+#include <linux/module.h>
+
+#include "tlan.h"
+
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/mii.h>
+
+typedef u32 (TLanIntVectorFunc)( struct net_device *, u16 );
+
+/* For removing EISA devices */
+static	struct net_device	*TLan_Eisa_Devices;
+
+static	int		TLanDevicesInstalled;
+
+/* Set speed, duplex and aui settings */
+static  int aui[MAX_TLAN_BOARDS];
+static  int duplex[MAX_TLAN_BOARDS];
+static  int speed[MAX_TLAN_BOARDS];
+static  int boards_found;
+
+MODULE_AUTHOR("Maintainer: Torben Mathiasen <torben.mathiasen@compaq.com>");
+MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet PCI adapters");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(aui, "1-" __MODULE_STRING(MAX_TLAN_BOARDS) "i");
+MODULE_PARM(duplex, "1-" __MODULE_STRING(MAX_TLAN_BOARDS) "i");
+MODULE_PARM(speed, "1-" __MODULE_STRING(MAX_TLAN_BOARDS) "i");
+MODULE_PARM(debug, "i");
+MODULE_PARM(bbuf, "i");
+MODULE_PARM_DESC(aui, "ThunderLAN use AUI port(s) (0-1)");
+MODULE_PARM_DESC(duplex, "ThunderLAN duplex setting(s) (0-default, 1-half, 2-full)");
+MODULE_PARM_DESC(speed, "ThunderLAN port speen setting(s) (0,10,100)");
+MODULE_PARM_DESC(debug, "ThunderLAN debug mask");
+MODULE_PARM_DESC(bbuf, "ThunderLAN use big buffer (0-1)");
+EXPORT_NO_SYMBOLS;
+
+/* Define this to enable Link beat monitoring */
+#undef MONITOR
+
+/* Turn on debugging. See linux/Documentation/networking/tlan.txt for details */
+static  int		debug;
+
+static	int		bbuf;
+static	u8		*TLanPadBuffer;
+static	char		TLanSignature[] = "TLAN";
+static const char tlan_banner[] = "ThunderLAN driver v1.14a\n";
+static int tlan_have_pci;
+static int tlan_have_eisa;
+
+const char *media[] = {
+	"10BaseT-HD ", "10BaseT-FD ","100baseTx-HD ", 
+	"100baseTx-FD", "100baseT4", 0
+};
+
+int media_map[] = { 0x0020, 0x0040, 0x0080, 0x0100, 0x0200,};
+
+static struct board {
+	const char	*deviceLabel;
+	u32	   	flags;
+	u16	   	addrOfs;
+} board_info[] __devinitdata = {
+	{ "Compaq Netelligent 10 T PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
+	{ "Compaq Netelligent 10/100 TX PCI UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
+	{ "Compaq Integrated NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
+	{ "Compaq NetFlex-3/P", TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },
+	{ "Compaq NetFlex-3/P", TLAN_ADAPTER_NONE, 0x83 },
+	{ "Compaq Netelligent Integrated 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
+	{ "Compaq Netelligent Dual 10/100 TX PCI UTP", TLAN_ADAPTER_NONE, 0x83 },
+	{ "Compaq Netelligent 10/100 TX Embedded UTP", TLAN_ADAPTER_NONE, 0x83 },
+	{ "Olicom OC-2183/2185", TLAN_ADAPTER_USE_INTERN_10, 0x83 },
+	{ "Olicom OC-2325", TLAN_ADAPTER_UNMANAGED_PHY, 0xF8 },
+	{ "Olicom OC-2326", TLAN_ADAPTER_USE_INTERN_10, 0xF8 },
+	{ "Compaq Netelligent 10/100 TX UTP", TLAN_ADAPTER_ACTIVITY_LED, 0x83 },
+	{ "Compaq Netelligent 10 T/2 PCI UTP/Coax", TLAN_ADAPTER_NONE, 0x83 },
+	{ "Compaq NetFlex-3/E", TLAN_ADAPTER_ACTIVITY_LED | 	/* EISA card */
+	                        TLAN_ADAPTER_UNMANAGED_PHY | TLAN_ADAPTER_BIT_RATE_PHY, 0x83 },	
+	{ "Compaq NetFlex-3/E", TLAN_ADAPTER_ACTIVITY_LED, 0x83 }, /* EISA card */
+};
+
+static struct pci_device_id tlan_pci_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL10,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3I,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_THUNDER,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 },
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETFLEX3B,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 },
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100PI,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 5 },
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100D,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 6 },
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_NETEL100I,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 7 },
+	{ PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2183,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 8 },
+	{ PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2325,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 9 },
+	{ PCI_VENDOR_ID_OLICOM, PCI_DEVICE_ID_OLICOM_OC2326,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 10 },
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_100_WS_5100,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11 },
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_NETELLIGENT_10_T2,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12 },
+	{ 0,}
+};
+MODULE_DEVICE_TABLE(pci, tlan_pci_tbl);		
+
+static void	TLan_EisaProbe( void );
+static void	TLan_Eisa_Cleanup( void );
+static int      TLan_Init( struct net_device * );
+static int	TLan_Open( struct net_device *dev );
+static int	TLan_StartTx( struct sk_buff *, struct net_device *);
+static void	TLan_HandleInterrupt( int, void *, struct pt_regs *);
+static int	TLan_Close( struct net_device *);
+static struct	net_device_stats *TLan_GetStats( struct net_device *);
+static void	TLan_SetMulticastList( struct net_device *);
+static int	TLan_ioctl( struct net_device *dev, struct ifreq *rq, int cmd);
+static int      TLan_probe1( struct pci_dev *pdev, long ioaddr, int irq, int rev, const struct pci_device_id *ent);
+static void	TLan_tx_timeout( struct net_device *dev);
+static int 	tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent);
+
+static u32	TLan_HandleInvalid( struct net_device *, u16 );
+static u32	TLan_HandleTxEOF( struct net_device *, u16 );
+static u32	TLan_HandleStatOverflow( struct net_device *, u16 );
+static u32	TLan_HandleRxEOF( struct net_device *, u16 );
+static u32	TLan_HandleDummy( struct net_device *, u16 );
+static u32	TLan_HandleTxEOC( struct net_device *, u16 );
+static u32	TLan_HandleStatusCheck( struct net_device *, u16 );
+static u32	TLan_HandleRxEOC( struct net_device *, u16 );
+
+static void	TLan_Timer( unsigned long );
+
+static void	TLan_ResetLists( struct net_device * );
+static void	TLan_FreeLists( struct net_device * );
+static void	TLan_PrintDio( u16 );
+static void	TLan_PrintList( TLanList *, char *, int );
+static void	TLan_ReadAndClearStats( struct net_device *, int );
+static void	TLan_ResetAdapter( struct net_device * );
+static void	TLan_FinishReset( struct net_device * );
+static void	TLan_SetMac( struct net_device *, int areg, char *mac );
+
+static void	TLan_PhyPrint( struct net_device * );
+static void	TLan_PhyDetect( struct net_device * );
+static void	TLan_PhyPowerDown( struct net_device * );
+static void	TLan_PhyPowerUp( struct net_device * );
+static void	TLan_PhyReset( struct net_device * );
+static void	TLan_PhyStartLink( struct net_device * );
+static void	TLan_PhyFinishAutoNeg( struct net_device * );
+#ifdef MONITOR
+static void     TLan_PhyMonitor( struct net_device * );
+#endif
+
+/*
+static int	TLan_PhyNop( struct net_device * );
+static int	TLan_PhyInternalCheck( struct net_device * );
+static int	TLan_PhyInternalService( struct net_device * );
+static int	TLan_PhyDp83840aCheck( struct net_device * );
+*/
+
+static int	TLan_MiiReadReg( struct net_device *, u16, u16, u16 * );
+static void	TLan_MiiSendData( u16, u32, unsigned );
+static void	TLan_MiiSync( u16 );
+static void	TLan_MiiWriteReg( struct net_device *, u16, u16, u16 );
+
+static void	TLan_EeSendStart( u16 );
+static int	TLan_EeSendByte( u16, u8, int );
+static void	TLan_EeReceiveByte( u16, u8 *, int );
+static int	TLan_EeReadByte( struct net_device *, u8, u8 * );
+
+static TLanIntVectorFunc *TLanIntVector[TLAN_INT_NUMBER_OF_INTS] = {
+	TLan_HandleInvalid,
+	TLan_HandleTxEOF,
+	TLan_HandleStatOverflow,
+	TLan_HandleRxEOF,
+	TLan_HandleDummy,
+	TLan_HandleTxEOC,
+	TLan_HandleStatusCheck,
+	TLan_HandleRxEOC
+};
+
+static inline void
+TLan_SetTimer( struct net_device *dev, u32 ticks, u32 type )
+{
+	TLanPrivateInfo *priv = dev->priv;
+	unsigned long flags = 0;
+	
+	if (!in_irq())
+		spin_lock_irqsave(&priv->lock, flags);
+	if ( priv->timer.function != NULL &&
+		priv->timerType != TLAN_TIMER_ACTIVITY ) { 
+		if (!in_irq())
+			spin_unlock_irqrestore(&priv->lock, flags);
+		return;
+	}
+	priv->timer.function = &TLan_Timer;
+	if (!in_irq())
+		spin_unlock_irqrestore(&priv->lock, flags);
+
+	priv->timer.data = (unsigned long) dev;
+	priv->timerSetAt = jiffies;
+	priv->timerType = type;
+	mod_timer(&priv->timer, jiffies + ticks);
+	
+} /* TLan_SetTimer */
+
+/*****************************************************************************
+******************************************************************************
+
+	ThunderLAN Driver Primary Functions
+
+	These functions are more or less common to all Linux network drivers.
+
+******************************************************************************
+*****************************************************************************/
+
+	/***************************************************************
+	 *	tlan_remove_one
+	 *
+	 *	Returns:
+	 *		Nothing
+	 *	Parms:
+	 *		None
+	 *
+	 *	Goes through the TLanDevices list and frees the device
+	 *	structs and memory associated with each device (lists
+	 *	and buffers).  It also ureserves the IO port regions
+	 *	associated with this device.
+	 *
+	 **************************************************************/
+
+static void __devexit tlan_remove_one( struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata( pdev );
+	TLanPrivateInfo	*priv = dev->priv;
+	
+	unregister_netdev( dev );
+
+	if ( priv->dmaStorage ) {
+		kfree( priv->dmaStorage );
+	}
+
+	release_region( dev->base_addr, 0x10 );
+	
+	kfree( dev );
+		
+	pci_set_drvdata( pdev, NULL );
+} 
+
+static struct pci_driver tlan_driver = {
+	name:		"tlan",
+	id_table:	tlan_pci_tbl,
+	probe:		tlan_init_one,
+	remove:		tlan_remove_one,	
+};
+
+static int __init tlan_probe(void)
+{
+	static int	pad_allocated;
+	
+	printk(KERN_INFO "%s", tlan_banner);
+	
+	TLanPadBuffer = (u8 *) kmalloc(TLAN_MIN_FRAME_SIZE, 
+					GFP_KERNEL);
+
+	if (TLanPadBuffer == NULL) {
+		printk(KERN_ERR "TLAN: Could not allocate memory for pad buffer.\n");
+		return -ENOMEM;
+	}
+
+	memset(TLanPadBuffer, 0, TLAN_MIN_FRAME_SIZE);
+	pad_allocated = 1;
+
+	TLAN_DBG(TLAN_DEBUG_PROBE, "Starting PCI Probe....\n");
+	
+	/* Use new style PCI probing. Now the kernel will
+	   do most of this for us */
+	pci_register_driver(&tlan_driver);
+
+	TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n");
+	TLan_EisaProbe();
+		
+	printk(KERN_INFO "TLAN: %d device%s installed, PCI: %d  EISA: %d\n", 
+		 TLanDevicesInstalled, TLanDevicesInstalled == 1 ? "" : "s",
+		 tlan_have_pci, tlan_have_eisa);
+
+	if (TLanDevicesInstalled == 0) {
+		pci_unregister_driver(&tlan_driver);
+		kfree(TLanPadBuffer);
+		return -ENODEV;
+	}
+	return 0;
+}
+	
+
+static int __devinit tlan_init_one( struct pci_dev *pdev,
+				    const struct pci_device_id *ent)
+{
+	return TLan_probe1( pdev, -1, -1, 0, ent);
+}
+
+/*
+	***************************************************************
+	 *	tlan_probe1
+	 *
+	 *	Returns:
+	 *		0 on success, error code on error
+	 *	Parms: 
+	 *		none
+	 *
+	 *	The name is lower case to fit in with all the rest of
+	 *	the netcard_probe names.  This function looks for 
+	 *	another TLan based adapter, setting it up with the
+	 *	allocated device struct if one is found.
+	 *	tlan_probe has been ported to the new net API and
+	 *	now allocates its own device structure. This function
+	 *	is also used by modules.
+	 *
+	 **************************************************************/
+
+static int __devinit TLan_probe1(struct pci_dev *pdev, 
+				long ioaddr, int irq, int rev, const struct pci_device_id *ent )
+{
+
+	struct net_device  *dev;
+	TLanPrivateInfo    *priv;
+	u8		   pci_rev;
+	u16		   device_id;
+	int		   reg;
+
+	if (pdev && pci_enable_device(pdev))
+		return -EIO;
+
+	dev = init_etherdev(NULL, sizeof(TLanPrivateInfo));
+	if (dev == NULL) {
+		printk(KERN_ERR "TLAN: Could not allocate memory for device.\n");
+		return -ENOMEM;
+	}
+	SET_MODULE_OWNER(dev);
+	
+	priv = dev->priv;
+
+	/* Is this a PCI device? */
+	if (pdev) {
+		u32 		   pci_io_base = 0;
+
+		priv->adapter = &board_info[ent->driver_data];
+
+		pci_read_config_byte ( pdev, PCI_REVISION_ID, &pci_rev);
+
+		for ( reg= 0; reg <= 5; reg ++ ) {
+			if (pci_resource_flags(pdev, reg) & IORESOURCE_IO) {
+				pci_io_base = pci_resource_start(pdev, reg);
+				TLAN_DBG( TLAN_DEBUG_GNRL, "IO mapping is available at %x.\n",
+						pci_io_base);
+				break;
+			}
+		}
+		if (!pci_io_base) {
+			printk(KERN_ERR "TLAN: No IO mappings available\n");
+			unregister_netdev(dev);
+			kfree(dev);
+			return -ENODEV;
+		}
+		
+		dev->base_addr = pci_io_base;
+		dev->irq = pdev->irq;
+		priv->adapterRev = pci_rev; 
+		pci_set_master(pdev);
+		pci_set_drvdata(pdev, dev);
+
+	} else	{     /* EISA card */
+		/* This is a hack. We need to know which board structure
+		 * is suited for this adapter */
+		device_id = inw(ioaddr + EISA_ID2);
+		priv->is_eisa = 1;
+		if (device_id == 0x20F1) {
+			priv->adapter = &board_info[13]; 	/* NetFlex-3/E */
+			priv->adapterRev = 23;			/* TLAN 2.3 */
+		} else {
+			priv->adapter = &board_info[14];
+			priv->adapterRev = 10;			/* TLAN 1.0 */
+		}
+		dev->base_addr = ioaddr;
+		dev->irq = irq;
+	}
+
+	/* Kernel parameters */
+	if (dev->mem_start) {
+		priv->aui    = dev->mem_start & 0x01;
+		priv->duplex = ((dev->mem_start & 0x06) == 0x06) ? 0 : (dev->mem_start & 0x06) >> 1;
+		priv->speed  = ((dev->mem_start & 0x18) == 0x18) ? 0 : (dev->mem_start & 0x18) >> 3;
+	
+		if (priv->speed == 0x1) {
+			priv->speed = TLAN_SPEED_10;
+		} else if (priv->speed == 0x2) {
+			priv->speed = TLAN_SPEED_100;
+		}
+		debug = priv->debug = dev->mem_end;
+	} else {
+		priv->aui    = aui[boards_found];
+		priv->speed  = speed[boards_found];
+		priv->duplex = duplex[boards_found];
+		priv->debug = debug;
+	}
+	
+	/* This will be used when we get an adapter error from
+	 * within our irq handler */
+	INIT_LIST_HEAD(&priv->tlan_tqueue.list);
+	priv->tlan_tqueue.sync = 0;
+	priv->tlan_tqueue.routine = (void *)(void*)TLan_tx_timeout;
+	priv->tlan_tqueue.data = dev;
+
+	spin_lock_init(&priv->lock);
+	
+	if (TLan_Init(dev)) {
+		printk(KERN_ERR "TLAN: Could not register device.\n");
+		unregister_netdev(dev);
+		kfree(dev);
+		return -EAGAIN;
+	} else {
+	
+	TLanDevicesInstalled++;
+	boards_found++;
+	
+	/* pdev is NULL if this is an EISA device */
+	if (pdev)
+		tlan_have_pci++;
+	else {
+		priv->nextDevice = TLan_Eisa_Devices;
+		TLan_Eisa_Devices = dev;
+		tlan_have_eisa++;
+	}
+	
+	printk(KERN_INFO "TLAN: %s irq=%2d, io=%04x, %s, Rev. %d\n",
+			dev->name,
+			(int) dev->irq,
+			(int) dev->base_addr,
+			priv->adapter->deviceLabel,
+			priv->adapterRev);
+	return 0;
+	}
+
+}
+
+static void TLan_Eisa_Cleanup(void)
+{
+	struct net_device *dev;
+	TLanPrivateInfo *priv;
+	
+	while( tlan_have_eisa ) {
+		dev = TLan_Eisa_Devices;
+		priv = dev->priv;
+		if (priv->dmaStorage) {
+			kfree(priv->dmaStorage);
+		}
+		release_region( dev->base_addr, 0x10);
+		unregister_netdev( dev );
+		TLan_Eisa_Devices = priv->nextDevice;
+		kfree( dev );
+		tlan_have_eisa--;
+	}
+}
+	
+		
+static void __exit tlan_exit(void)
+{
+	pci_unregister_driver(&tlan_driver);
+
+	if (tlan_have_eisa)
+		TLan_Eisa_Cleanup();
+
+	kfree( TLanPadBuffer );
+
+}
+
+/* Module loading/unloading */
+module_init(tlan_probe);
+module_exit(tlan_exit);
+
+	/**************************************************************
+	 * 	TLan_EisaProbe
+	 *
+	 *  	Returns: 0 on success, 1 otherwise
+	 *
+	 *  	Parms:	 None
+	 *
+	 *
+	 *  	This functions probes for EISA devices and calls 
+	 *  	TLan_probe1 when one is found. 
+	 *
+	 *************************************************************/
+
+static void  __init TLan_EisaProbe (void) 
+{
+	long 	ioaddr;
+	int 	rc = -ENODEV;
+	int 	irq;
+	u16	device_id;
+
+	if (!EISA_bus) {	
+		TLAN_DBG(TLAN_DEBUG_PROBE, "No EISA bus present\n");
+		return;
+	}
+	
+	/* Loop through all slots of the EISA bus */
+	for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
+		
+	TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n", (int) ioaddr + 0xC80, inw(ioaddr + EISA_ID));	
+	TLAN_DBG(TLAN_DEBUG_PROBE,"EISA_ID 0x%4x: 0x%4x\n", (int) ioaddr + 0xC82, inw(ioaddr + EISA_ID2));
+
+		TLAN_DBG(TLAN_DEBUG_PROBE, "Probing for EISA adapter at IO: 0x%4x : ",
+				   	(int) ioaddr);
+		if (request_region(ioaddr, 0x10, TLanSignature) == NULL) 
+			goto out;
+
+		if (inw(ioaddr + EISA_ID) != 0x110E) {		
+			release_region(ioaddr, 0x10);
+			goto out;
+		}
+		
+		device_id = inw(ioaddr + EISA_ID2);
+		if (device_id !=  0x20F1 && device_id != 0x40F1) { 		
+			release_region (ioaddr, 0x10);
+			goto out;
+		}
+		
+	 	if (inb(ioaddr + EISA_CR) != 0x1) { 	/* Check if adapter is enabled */
+			release_region (ioaddr, 0x10);
+			goto out2;
+		}
+		
+		if (debug == 0x10)		
+			printk("Found one\n");
+
+		/* Get irq from board */
+		switch (inb(ioaddr + 0xCC0)) {
+			case(0x10):
+				irq=5;
+				break;
+			case(0x20):
+				irq=9;
+				break;
+			case(0x40):
+				irq=10;
+				break;
+			case(0x80):
+				irq=11;
+				break;
+			default:
+				goto out;
+		}               
+		
+		
+		/* Setup the newly found eisa adapter */
+		rc = TLan_probe1( NULL, ioaddr, irq,
+					12, NULL);
+		continue;
+		
+		out:
+			if (debug == 0x10)
+				printk("None found\n");
+			continue;
+
+		out2:	if (debug == 0x10)
+				printk("Card found but it is not enabled, skipping\n");
+			continue;
+		
+	}
+
+} /* TLan_EisaProbe */
+
+	
+
+	/***************************************************************
+	 *	TLan_Init
+	 *
+	 *	Returns:
+	 *		0 on success, error code otherwise.
+	 *	Parms:
+	 *		dev	The structure of the device to be
+	 *			init'ed.
+	 *
+	 *	This function completes the initialization of the
+	 *	device structure and driver.  It reserves the IO
+	 *	addresses, allocates memory for the lists and bounce
+	 *	buffers, retrieves the MAC address from the eeprom
+	 *	and assignes the device's methods.
+	 *	
+	 **************************************************************/
+
+static int TLan_Init( struct net_device *dev )
+{
+	int		dma_size;
+	int 		err;
+	int		i;
+	TLanPrivateInfo	*priv;
+
+	priv = dev->priv;
+	
+	if (!priv->is_eisa)	/* EISA devices have already requested IO */
+		if (!request_region( dev->base_addr, 0x10, TLanSignature )) {
+			printk(KERN_ERR "TLAN: %s: IO port region 0x%lx size 0x%x in use.\n",
+				dev->name,
+				dev->base_addr,
+				0x10 );
+			return -EIO;
+		}
+	
+	if ( bbuf ) {
+		dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS )
+	           * ( sizeof(TLanList) + TLAN_MAX_FRAME_SIZE );
+	} else {
+		dma_size = ( TLAN_NUM_RX_LISTS + TLAN_NUM_TX_LISTS )
+	           * ( sizeof(TLanList) );
+	}
+	priv->dmaStorage = kmalloc(dma_size, GFP_KERNEL | GFP_DMA);
+	if ( priv->dmaStorage == NULL ) {
+		printk(KERN_ERR "TLAN:  Could not allocate lists and buffers for %s.\n",
+			dev->name );
+		release_region( dev->base_addr, 0x10 );
+		return -ENOMEM;
+	}
+	memset( priv->dmaStorage, 0, dma_size );
+	priv->rxList = (TLanList *) 
+		       ( ( ( (u32) priv->dmaStorage ) + 7 ) & 0xFFFFFFF8 );
+	priv->txList = priv->rxList + TLAN_NUM_RX_LISTS;
+	if ( bbuf ) {
+		priv->rxBuffer = (u8 *) ( priv->txList + TLAN_NUM_TX_LISTS );
+		priv->txBuffer = priv->rxBuffer
+				 + ( TLAN_NUM_RX_LISTS * TLAN_MAX_FRAME_SIZE );
+	}
+
+	err = 0;
+	for ( i = 0;  i < 6 ; i++ )
+		err |= TLan_EeReadByte( dev,
+					(u8) priv->adapter->addrOfs + i,
+					(u8 *) &dev->dev_addr[i] );
+	if ( err ) {
+		printk(KERN_ERR "TLAN: %s: Error reading MAC from eeprom: %d\n",
+			dev->name,
+			err );
+	}
+	dev->addr_len = 6;
+	
+	/* Device methods */
+	dev->open = &TLan_Open;
+	dev->hard_start_xmit = &TLan_StartTx;
+	dev->stop = &TLan_Close;
+	dev->get_stats = &TLan_GetStats;
+	dev->set_multicast_list = &TLan_SetMulticastList;
+	dev->do_ioctl = &TLan_ioctl;
+	dev->tx_timeout = &TLan_tx_timeout;
+	dev->watchdog_timeo = TX_TIMEOUT;
+
+	return 0;
+
+} /* TLan_Init */
+
+	/***************************************************************
+	 *	TLan_Open
+	 *
+	 *	Returns:
+	 *		0 on success, error code otherwise.
+	 *	Parms:
+	 *		dev	Structure of device to be opened.
+	 *
+	 *	This routine puts the driver and TLAN adapter in a
+	 *	state where it is ready to send and receive packets.
+	 *	It allocates the IRQ, resets and brings the adapter
+	 *	out of reset, and allows interrupts.  It also delays
+	 *	the startup for autonegotiation or sends a Rx GO
+	 *	command to the adapter, as appropriate.
+	 *
+	 **************************************************************/
+
+static int TLan_Open( struct net_device *dev )
+{
+	TLanPrivateInfo	*priv = dev->priv;
+	int		err;
+	
+	priv->tlanRev = TLan_DioRead8( dev->base_addr, TLAN_DEF_REVISION );
+	err = request_irq( dev->irq, TLan_HandleInterrupt, SA_SHIRQ, TLanSignature, dev );
+	
+	if ( err ) {
+		printk(KERN_ERR "TLAN:  Cannot open %s because IRQ %d is already in use.\n", dev->name, dev->irq );
+		return err;
+	}
+	
+	init_timer(&priv->timer);
+	netif_start_queue(dev);
+	
+	/* NOTE: It might not be necessary to read the stats before a
+			 reset if you don't care what the values are.
+	*/
+	TLan_ResetLists( dev );
+	TLan_ReadAndClearStats( dev, TLAN_IGNORE );
+	TLan_ResetAdapter( dev );
+
+	TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Opened.  TLAN Chip Rev: %x\n", dev->name, priv->tlanRev );
+
+	return 0;
+
+} /* TLan_Open */
+
+	/**************************************************************
+	 *	TLan_ioctl
+	 *	
+	 *	Returns:
+	 *		0 on success, error code otherwise
+	 *	Params:
+	 *		dev	structure of device to receive ioctl.
+	 *		
+	 *		rq	ifreq structure to hold userspace data.
+	 *
+	 *		cmd	ioctl command.
+	 *
+	 *
+	 *************************************************************/
+
+static int TLan_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	TLanPrivateInfo *priv = dev->priv;
+	struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
+	u32 phy   = priv->phy[priv->phyNum];
+	
+	if (!priv->phyOnline)
+		return -EAGAIN;
+
+	switch(cmd) {
+	case SIOCGMIIPHY:		/* Get address of MII PHY in use. */
+	case SIOCDEVPRIVATE:		/* for binary compat, remove in 2.5 */
+			data->phy_id = phy;
+
+	case SIOCGMIIREG:		/* Read MII PHY register. */
+	case SIOCDEVPRIVATE+1:		/* for binary compat, remove in 2.5 */
+			TLan_MiiReadReg(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, &data->val_out);
+			return 0;
+		
+
+	case SIOCSMIIREG:		/* Write MII PHY register. */
+	case SIOCDEVPRIVATE+2:		/* for binary compat, remove in 2.5 */
+			if (!capable(CAP_NET_ADMIN))
+				return -EPERM;
+			TLan_MiiWriteReg(dev, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
+			return 0;
+		default:
+			return -EOPNOTSUPP;
+	}
+} /* tlan_ioctl */
+
+	/***************************************************************
+	 * 	TLan_tx_timeout
+	 *
+	 * 	Returns: nothing
+	 *
+	 * 	Params:
+	 * 		dev	structure of device which timed out 
+	 * 			during transmit.
+	 *
+	 **************************************************************/
+
+static void TLan_tx_timeout(struct net_device *dev)
+{
+	
+	TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Transmit timed out.\n", dev->name);
+	
+	/* Ok so we timed out, lets see what we can do about it...*/
+	TLan_FreeLists( dev );
+	TLan_ResetLists( dev );		
+	TLan_ReadAndClearStats( dev, TLAN_IGNORE );
+	TLan_ResetAdapter( dev );
+	dev->trans_start = jiffies;
+	netif_wake_queue( dev );	
+
+}
+	
+
+	/***************************************************************
+	 *	TLan_StartTx
+	 *  
+	 *	Returns:
+	 *		0 on success, non-zero on failure.
+	 *	Parms:
+	 *		skb	A pointer to the sk_buff containing the
+	 *			frame to be sent.
+	 *		dev	The device to send the data on.
+	 *
+	 *	This function adds a frame to the Tx list to be sent
+	 *	ASAP.  First it	verifies that the adapter is ready and
+	 *	there is room in the queue.  Then it sets up the next
+	 *	available list, copies the frame to the	corresponding
+	 *	buffer.  If the adapter Tx channel is idle, it gives
+	 *	the adapter a Tx Go command on the list, otherwise it
+	 *	sets the forward address of the previous list to point
+	 *	to this one.  Then it frees the sk_buff.
+	 *
+	 **************************************************************/
+
+static int TLan_StartTx( struct sk_buff *skb, struct net_device *dev )
+{
+	TLanPrivateInfo *priv = dev->priv;
+	TLanList	*tail_list;
+	u8		*tail_buffer;
+	int		pad;
+	unsigned long	flags;
+
+	if ( ! priv->phyOnline ) {
+		TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT:  %s PHY is not ready\n", dev->name );
+		dev_kfree_skb_any(skb);
+		return 0;
+	}
+
+	tail_list = priv->txList + priv->txTail;
+	
+	if ( tail_list->cStat != TLAN_CSTAT_UNUSED ) {
+		TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT:  %s is busy (Head=%d Tail=%d)\n", dev->name, priv->txHead, priv->txTail );
+		netif_stop_queue(dev);
+		priv->txBusyCount++;
+		return 1;
+	}
+
+	tail_list->forward = 0;
+
+	if ( bbuf ) {
+		tail_buffer = priv->txBuffer + ( priv->txTail * TLAN_MAX_FRAME_SIZE );
+		memcpy( tail_buffer, skb->data, skb->len );
+	} else {
+		tail_list->buffer[0].address = virt_to_bus( skb->data );
+		tail_list->buffer[9].address = (u32) skb;
+	}
+
+	pad = TLAN_MIN_FRAME_SIZE - skb->len;
+
+	if ( pad > 0 ) {
+		tail_list->frameSize = (u16) skb->len + pad;
+		tail_list->buffer[0].count = (u32) skb->len;
+		tail_list->buffer[1].count = TLAN_LAST_BUFFER | (u32) pad;
+		tail_list->buffer[1].address = virt_to_bus( TLanPadBuffer );
+	} else {
+		tail_list->frameSize = (u16) skb->len;
+		tail_list->buffer[0].count = TLAN_LAST_BUFFER | (u32) skb->len;
+		tail_list->buffer[1].count = 0;
+		tail_list->buffer[1].address = 0;
+	}
+
+	spin_lock_irqsave(&priv->lock, flags);
+	tail_list->cStat = TLAN_CSTAT_READY;
+	if ( ! priv->txInProgress ) {
+		priv->txInProgress = 1;
+		TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT:  Starting TX on buffer %d\n", priv->txTail );
+		outl( virt_to_bus( tail_list ), dev->base_addr + TLAN_CH_PARM );
+		outl( TLAN_HC_GO, dev->base_addr + TLAN_HOST_CMD );
+	} else {
+		TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT:  Adding buffer %d to TX channel\n", priv->txTail );
+		if ( priv->txTail == 0 ) {
+			( priv->txList + ( TLAN_NUM_TX_LISTS - 1 ) )->forward = virt_to_bus( tail_list );
+		} else {
+			( priv->txList + ( priv->txTail - 1 ) )->forward = virt_to_bus( tail_list );
+		}
+	}
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	CIRC_INC( priv->txTail, TLAN_NUM_TX_LISTS );
+
+	if ( bbuf )
+		dev_kfree_skb_any(skb);
+		
+	dev->trans_start = jiffies;
+	return 0;
+
+} /* TLan_StartTx */
+
+	/***************************************************************
+	 *	TLan_HandleInterrupt
+	 *  
+	 *	Returns:	
+	 *		Nothing
+	 *	Parms:
+	 *		irq	The line on which the interrupt
+	 *			occurred.
+	 *		dev_id	A pointer to the device assigned to
+	 *			this irq line.
+	 *		regs	???
+	 *
+	 *	This function handles an interrupt generated by its
+	 *	assigned TLAN adapter.  The function deactivates
+	 *	interrupts on its adapter, records the type of
+	 *	interrupt, executes the appropriate subhandler, and
+	 *	acknowdges the interrupt to the adapter (thus
+	 *	re-enabling adapter interrupts.
+	 *
+	 **************************************************************/
+
+static void TLan_HandleInterrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	u32		ack;
+	struct net_device	*dev;
+	u32		host_cmd;
+	u16		host_int;
+	int		type;
+	TLanPrivateInfo *priv;
+
+	dev = dev_id;
+	priv = dev->priv;
+
+	spin_lock(&priv->lock);
+
+	host_int = inw( dev->base_addr + TLAN_HOST_INT );
+	outw( host_int, dev->base_addr + TLAN_HOST_INT );
+
+	type = ( host_int & TLAN_HI_IT_MASK ) >> 2;
+
+	ack = TLanIntVector[type]( dev, host_int );
+
+	if ( ack ) {
+		host_cmd = TLAN_HC_ACK | ack | ( type << 18 );
+		outl( host_cmd, dev->base_addr + TLAN_HOST_CMD );
+	}
+
+	spin_unlock(&priv->lock);
+
+} /* TLan_HandleInterrupts */
+
+	/***************************************************************
+	 *	TLan_Close
+	 *  
+	 * 	Returns:
+	 *		An error code.
+	 *	Parms:
+	 *		dev	The device structure of the device to
+	 *			close.
+	 *
+	 *	This function shuts down the adapter.  It records any
+	 *	stats, puts the adapter into reset state, deactivates
+	 *	its time as needed, and	frees the irq it is using.
+	 *
+	 **************************************************************/
+
+static int TLan_Close(struct net_device *dev)
+{
+	TLanPrivateInfo *priv = dev->priv;
+
+	netif_stop_queue(dev);
+	priv->neg_be_verbose = 0;
+
+	TLan_ReadAndClearStats( dev, TLAN_RECORD );
+	outl( TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD );
+	if ( priv->timer.function != NULL ) {
+		del_timer_sync( &priv->timer );
+		priv->timer.function = NULL;
+	}
+	
+	free_irq( dev->irq, dev );
+	TLan_FreeLists( dev );
+	TLAN_DBG( TLAN_DEBUG_GNRL, "Device %s closed.\n", dev->name );
+
+	return 0;
+
+} /* TLan_Close */
+
+	/***************************************************************
+	 *	TLan_GetStats
+	 *  
+	 *	Returns:
+	 *		A pointer to the device's statistics structure.
+	 *	Parms:
+	 *		dev	The device structure to return the
+	 *			stats for.
+	 *
+	 *	This function updates the devices statistics by reading
+	 *	the TLAN chip's onboard registers.  Then it returns the
+	 *	address of the statistics structure.
+	 *
+	 **************************************************************/
+
+static struct net_device_stats *TLan_GetStats( struct net_device *dev )
+{
+	TLanPrivateInfo	*priv = dev->priv;
+	int i;
+
+	/* Should only read stats if open ? */
+	TLan_ReadAndClearStats( dev, TLAN_RECORD );
+
+	TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE:  %s EOC count = %d\n", dev->name, priv->rxEocCount );
+	TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT:  %s Busy count = %d\n", dev->name, priv->txBusyCount );
+	if ( debug & TLAN_DEBUG_GNRL ) {
+		TLan_PrintDio( dev->base_addr );
+		TLan_PhyPrint( dev );		
+	}
+	if ( debug & TLAN_DEBUG_LIST ) {
+		for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ )
+			TLan_PrintList( priv->rxList + i, "RX", i );
+		for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ )
+			TLan_PrintList( priv->txList + i, "TX", i );
+	}
+	
+	return ( &( (TLanPrivateInfo *) dev->priv )->stats );
+
+} /* TLan_GetStats */
+
+	/***************************************************************
+	 *	TLan_SetMulticastList
+	 *  
+	 *	Returns:
+	 *		Nothing
+	 *	Parms:
+	 *		dev	The device structure to set the
+	 *			multicast list for.
+	 *
+	 *	This function sets the TLAN adaptor to various receive
+	 *	modes.  If the IFF_PROMISC flag is set, promiscuous
+	 *	mode is acitviated.  Otherwise,	promiscuous mode is
+	 *	turned off.  If the IFF_ALLMULTI flag is set, then
+	 *	the hash table is set to receive all group addresses.
+	 *	Otherwise, the first three multicast addresses are
+	 *	stored in AREG_1-3, and the rest are selected via the
+	 *	hash table, as necessary.
+	 *
+	 **************************************************************/
+
+static void TLan_SetMulticastList( struct net_device *dev )
+{	
+	struct dev_mc_list	*dmi = dev->mc_list;
+	u32			hash1 = 0;
+	u32			hash2 = 0;
+	int			i;
+	u32			offset;
+	u8			tmp;
+
+	if ( dev->flags & IFF_PROMISC ) {
+		tmp = TLan_DioRead8( dev->base_addr, TLAN_NET_CMD );
+		TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, tmp | TLAN_NET_CMD_CAF );
+	} else {
+		tmp = TLan_DioRead8( dev->base_addr, TLAN_NET_CMD );
+		TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, tmp & ~TLAN_NET_CMD_CAF );
+		if ( dev->flags & IFF_ALLMULTI ) {
+			for ( i = 0; i < 3; i++ ) 
+				TLan_SetMac( dev, i + 1, NULL );
+			TLan_DioWrite32( dev->base_addr, TLAN_HASH_1, 0xFFFFFFFF );
+			TLan_DioWrite32( dev->base_addr, TLAN_HASH_2, 0xFFFFFFFF );
+		} else {
+			for ( i = 0; i < dev->mc_count; i++ ) {
+				if ( i < 3 ) {
+					TLan_SetMac( dev, i + 1, (char *) &dmi->dmi_addr );
+				} else {
+					offset = TLan_HashFunc( (u8 *) &dmi->dmi_addr );
+					if ( offset < 32 ) 
+						hash1 |= ( 1 << offset );
+					else
+						hash2 |= ( 1 << ( offset - 32 ) );
+				}
+				dmi = dmi->next;
+			}
+			for ( ; i < 3; i++ ) 
+				TLan_SetMac( dev, i + 1, NULL );
+			TLan_DioWrite32( dev->base_addr, TLAN_HASH_1, hash1 );
+			TLan_DioWrite32( dev->base_addr, TLAN_HASH_2, hash2 );
+		}
+	}
+
+} /* TLan_SetMulticastList */
+
+/*****************************************************************************
+******************************************************************************
+
+        ThunderLAN Driver Interrupt Vectors and Table
+
+	Please see Chap. 4, "Interrupt Handling" of the "ThunderLAN
+	Programmer's Guide" for more informations on handling interrupts
+	generated by TLAN based adapters.  
+
+******************************************************************************
+*****************************************************************************/
+
+	/***************************************************************
+	 *	TLan_HandleInvalid
+	 *
+	 *	Returns:
+	 *		0
+	 *	Parms:
+	 *		dev		Device assigned the IRQ that was
+	 *				raised.
+	 *		host_int	The contents of the HOST_INT
+	 *				port.
+	 *
+	 *	This function handles invalid interrupts.  This should
+	 *	never happen unless some other adapter is trying to use
+	 *	the IRQ line assigned to the device.
+	 *
+	 **************************************************************/
+
+u32 TLan_HandleInvalid( struct net_device *dev, u16 host_int )
+{
+	/* printk( "TLAN:  Invalid interrupt on %s.\n", dev->name ); */
+	return 0;
+
+} /* TLan_HandleInvalid */
+
+	/***************************************************************
+	 *	TLan_HandleTxEOF
+	 *
+	 *	Returns:
+	 *		1
+	 *	Parms:
+	 *		dev		Device assigned the IRQ that was
+	 *				raised.
+	 *		host_int	The contents of the HOST_INT
+	 *				port.
+	 *
+	 *	This function handles Tx EOF interrupts which are raised
+	 *	by the adapter when it has completed sending the
+	 *	contents of a buffer.  If detemines which list/buffer
+	 *	was completed and resets it.  If the buffer was the last
+	 *	in the channel (EOC), then the function checks to see if
+	 *	another buffer is ready to send, and if so, sends a Tx
+	 *	Go command.  Finally, the driver activates/continues the
+	 *	activity LED.
+	 *
+	 **************************************************************/
+
+u32 TLan_HandleTxEOF( struct net_device *dev, u16 host_int )
+{
+	TLanPrivateInfo	*priv = dev->priv;
+	int		eoc = 0;
+	TLanList	*head_list;
+	u32		ack = 0;
+	u16		tmpCStat;
+	
+	TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT:  Handling TX EOF (Head=%d Tail=%d)\n", priv->txHead, priv->txTail );
+	head_list = priv->txList + priv->txHead;
+
+	while (((tmpCStat = head_list->cStat ) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) {
+		ack++;
+		if ( ! bbuf ) {
+			dev_kfree_skb_any( (struct sk_buff *) head_list->buffer[9].address );
+			head_list->buffer[9].address = 0;
+		}
+	
+		if ( tmpCStat & TLAN_CSTAT_EOC )
+			eoc = 1;
+			
+		priv->stats.tx_bytes += head_list->frameSize;
+
+		head_list->cStat = TLAN_CSTAT_UNUSED;
+		netif_start_queue(dev);		
+		CIRC_INC( priv->txHead, TLAN_NUM_TX_LISTS ); 
+		head_list = priv->txList + priv->txHead;
+	}
+
+	if (!ack)
+		printk(KERN_INFO "TLAN: Received interrupt for uncompleted TX frame.\n");
+	
+	if ( eoc ) {
+		TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT:  Handling TX EOC (Head=%d Tail=%d)\n", priv->txHead, priv->txTail );
+		head_list = priv->txList + priv->txHead;
+		if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
+			outl( virt_to_bus( head_list ), dev->base_addr + TLAN_CH_PARM );
+			ack |= TLAN_HC_GO;
+		} else {
+			priv->txInProgress = 0;
+		}
+	}
+	
+	if ( priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED ) {
+		TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
+		if ( priv->timer.function == NULL ) {
+			 priv->timer.function = &TLan_Timer;
+			 priv->timer.data = (unsigned long) dev;
+			 priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
+			 priv->timerSetAt = jiffies;
+			 priv->timerType = TLAN_TIMER_ACTIVITY;
+			 add_timer(&priv->timer);
+		} else if ( priv->timerType == TLAN_TIMER_ACTIVITY ) {
+			priv->timerSetAt = jiffies;
+		}
+	}
+
+	return ack;
+
+} /* TLan_HandleTxEOF */
+
+	/***************************************************************
+	 *	TLan_HandleStatOverflow
+	 *
+	 *	Returns:
+	 *		1
+	 *	Parms:
+	 *		dev		Device assigned the IRQ that was
+	 *				raised.
+	 *		host_int	The contents of the HOST_INT
+	 *				port.
+	 *
+	 *	This function handles the Statistics Overflow interrupt
+	 *	which means that one or more of the TLAN statistics
+	 *	registers has reached 1/2 capacity and needs to be read.
+	 *
+	 **************************************************************/
+
+u32 TLan_HandleStatOverflow( struct net_device *dev, u16 host_int )
+{
+	TLan_ReadAndClearStats( dev, TLAN_RECORD );
+
+	return 1;
+
+} /* TLan_HandleStatOverflow */
+
+	/***************************************************************
+	 *	TLan_HandleRxEOF
+	 *
+	 *	Returns:
+	 *		1
+	 *	Parms:
+	 *		dev		Device assigned the IRQ that was
+	 *				raised.
+	 *		host_int	The contents of the HOST_INT
+	 *				port.
+	 *
+	 *	This function handles the Rx EOF interrupt which
+	 *	indicates a frame has been received by the adapter from
+	 *	the net and the frame has been transferred to memory.
+	 *	The function determines the bounce buffer the frame has
+	 *	been loaded into, creates a new sk_buff big enough to
+	 *	hold the frame, and sends it to protocol stack.  It
+	 *	then resets the used buffer and appends it to the end
+	 *	of the list.  If the frame was the last in the Rx
+	 *	channel (EOC), the function restarts the receive channel
+	 *	by sending an Rx Go command to the adapter.  Then it
+	 *	activates/continues the activity LED.
+	 *
+	 **************************************************************/
+
+u32 TLan_HandleRxEOF( struct net_device *dev, u16 host_int )
+{
+	TLanPrivateInfo	*priv = dev->priv;
+	u32		ack = 0;
+	int		eoc = 0;
+	u8		*head_buffer;
+	TLanList	*head_list;
+	struct sk_buff	*skb;
+	TLanList	*tail_list;
+	void		*t;
+	u32		frameSize;
+	u16		tmpCStat;
+
+	TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE:  Handling RX EOF (Head=%d Tail=%d)\n", priv->rxHead, priv->rxTail );
+	head_list = priv->rxList + priv->rxHead;
+	
+	while (((tmpCStat = head_list->cStat) & TLAN_CSTAT_FRM_CMP) && (ack < 255)) {
+		frameSize = head_list->frameSize;
+		ack++;
+		if (tmpCStat & TLAN_CSTAT_EOC)
+			eoc = 1;
+		
+		if (bbuf) {
+			skb = dev_alloc_skb(frameSize + 7);
+			if (skb == NULL)
+				printk(KERN_INFO "TLAN: Couldn't allocate memory for received data.\n");
+			else {
+				head_buffer = priv->rxBuffer + (priv->rxHead * TLAN_MAX_FRAME_SIZE);
+				skb->dev = dev;
+				skb_reserve(skb, 2);
+				t = (void *) skb_put(skb, frameSize);
+		
+				priv->stats.rx_bytes += head_list->frameSize;
+
+				memcpy( t, head_buffer, frameSize );
+				skb->protocol = eth_type_trans( skb, dev );
+				netif_rx( skb );
+			}
+		} else {
+			struct sk_buff *new_skb;
+		
+			/*
+		 	*	I changed the algorithm here. What we now do
+		 	*	is allocate the new frame. If this fails we
+		 	*	simply recycle the frame.
+		 	*/
+		
+			new_skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 );
+			
+			if ( new_skb != NULL ) {
+				/* If this ever happened it would be a problem */
+				/* not any more - ac */
+				skb = (struct sk_buff *) head_list->buffer[9].address;
+				skb_trim( skb, frameSize );
+
+				priv->stats.rx_bytes += frameSize;
+
+				skb->protocol = eth_type_trans( skb, dev );
+				netif_rx( skb );
+	
+				new_skb->dev = dev;
+				skb_reserve( new_skb, 2 );
+				t = (void *) skb_put( new_skb, TLAN_MAX_FRAME_SIZE );
+				head_list->buffer[0].address = virt_to_bus( t );
+				head_list->buffer[8].address = (u32) t;
+				head_list->buffer[9].address = (u32) new_skb;
+			} else 
+				printk(KERN_WARNING "TLAN:  Couldn't allocate memory for received data.\n" );
+		}
+
+		head_list->forward = 0;
+		head_list->cStat = 0;
+		tail_list = priv->rxList + priv->rxTail;
+		tail_list->forward = virt_to_bus( head_list );
+
+		CIRC_INC( priv->rxHead, TLAN_NUM_RX_LISTS );
+		CIRC_INC( priv->rxTail, TLAN_NUM_RX_LISTS );
+		head_list = priv->rxList + priv->rxHead;
+	}
+
+	if (!ack)
+		printk(KERN_INFO "TLAN: Received interrupt for uncompleted RX frame.\n");
+	
+
+	if ( eoc ) { 
+		TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE:  Handling RX EOC (Head=%d Tail=%d)\n", priv->rxHead, priv->rxTail );
+		head_list = priv->rxList + priv->rxHead;
+		outl( virt_to_bus( head_list ), dev->base_addr + TLAN_CH_PARM );
+		ack |= TLAN_HC_GO | TLAN_HC_RT;
+		priv->rxEocCount++;
+	}
+
+	if ( priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED ) {
+		TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
+		if ( priv->timer.function == NULL )  {
+			priv->timer.function = &TLan_Timer;
+			priv->timer.data = (unsigned long) dev;
+			priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
+			priv->timerSetAt = jiffies;
+			priv->timerType = TLAN_TIMER_ACTIVITY;
+			add_timer(&priv->timer);
+		} else if ( priv->timerType == TLAN_TIMER_ACTIVITY ) {
+			priv->timerSetAt = jiffies;
+		}
+	}
+
+	dev->last_rx = jiffies;
+	
+	return ack;
+
+} /* TLan_HandleRxEOF */
+
+	/***************************************************************
+	 *	TLan_HandleDummy
+	 *
+	 *	Returns:
+	 *		1
+	 *	Parms:
+	 *		dev		Device assigned the IRQ that was
+	 *				raised.
+	 *		host_int	The contents of the HOST_INT
+	 *				port.
+	 *
+	 *	This function handles the Dummy interrupt, which is
+	 *	raised whenever a test interrupt is generated by setting
+	 *	the Req_Int bit of HOST_CMD to 1.
+	 *
+	 **************************************************************/
+
+u32 TLan_HandleDummy( struct net_device *dev, u16 host_int )
+{
+	printk( "TLAN:  Test interrupt on %s.\n", dev->name );
+	return 1;
+
+} /* TLan_HandleDummy */
+
+	/***************************************************************
+	 *	TLan_HandleTxEOC
+	 *
+	 *	Returns:
+	 *		1
+	 *	Parms:
+	 *		dev		Device assigned the IRQ that was
+	 *				raised.
+	 *		host_int	The contents of the HOST_INT
+	 *				port.
+	 *
+	 *	This driver is structured to determine EOC occurances by
+	 *	reading the CSTAT member of the list structure.  Tx EOC
+	 *	interrupts are disabled via the DIO INTDIS register.
+	 *	However, TLAN chips before revision 3.0 didn't have this
+	 *	functionality, so process EOC events if this is the
+	 *	case.
+	 *
+	 **************************************************************/
+
+u32 TLan_HandleTxEOC( struct net_device *dev, u16 host_int )
+{
+	TLanPrivateInfo	*priv = dev->priv;
+	TLanList		*head_list;
+	u32			ack = 1;
+	
+	host_int = 0;
+	if ( priv->tlanRev < 0x30 ) {
+		TLAN_DBG( TLAN_DEBUG_TX, "TRANSMIT:  Handling TX EOC (Head=%d Tail=%d) -- IRQ\n", priv->txHead, priv->txTail );
+		head_list = priv->txList + priv->txHead;
+		if ( ( head_list->cStat & TLAN_CSTAT_READY ) == TLAN_CSTAT_READY ) {
+			netif_stop_queue(dev);
+			outl( virt_to_bus( head_list ), dev->base_addr + TLAN_CH_PARM );
+			ack |= TLAN_HC_GO;
+		} else {
+			priv->txInProgress = 0;
+		}
+	}
+
+	return ack;
+
+} /* TLan_HandleTxEOC */
+
+	/***************************************************************
+	 *	TLan_HandleStatusCheck
+	 *
+	 *	Returns:
+	 *		0 if Adapter check, 1 if Network Status check.
+	 *	Parms:
+	 *		dev		Device assigned the IRQ that was
+	 *				raised.
+	 *		host_int	The contents of the HOST_INT
+	 *				port.
+	 *
+	 *	This function handles Adapter Check/Network Status
+	 *	interrupts generated by the adapter.  It checks the
+	 *	vector in the HOST_INT register to determine if it is
+	 *	an Adapter Check interrupt.  If so, it resets the
+	 *	adapter.  Otherwise it clears the status registers
+	 *	and services the PHY.
+	 *
+	 **************************************************************/
+
+u32 TLan_HandleStatusCheck( struct net_device *dev, u16 host_int )
+{	
+	TLanPrivateInfo	*priv = dev->priv;
+	u32		ack;
+	u32		error;
+	u8		net_sts;
+	u32		phy;
+	u16		tlphy_ctl;
+	u16		tlphy_sts;
+	
+	ack = 1;
+	if ( host_int & TLAN_HI_IV_MASK ) {
+		netif_stop_queue( dev );
+		error = inl( dev->base_addr + TLAN_CH_PARM );
+		printk( "TLAN:  %s: Adaptor Error = 0x%x\n", dev->name, error );
+		TLan_ReadAndClearStats( dev, TLAN_RECORD );
+		outl( TLAN_HC_AD_RST, dev->base_addr + TLAN_HOST_CMD );
+		
+		queue_task(&priv->tlan_tqueue, &tq_immediate);
+		mark_bh(IMMEDIATE_BH);
+		
+		netif_wake_queue(dev);
+		ack = 0;
+	} else {
+		TLAN_DBG( TLAN_DEBUG_GNRL, "%s: Status Check\n", dev->name );
+		phy = priv->phy[priv->phyNum];
+
+		net_sts = TLan_DioRead8( dev->base_addr, TLAN_NET_STS );
+		if ( net_sts ) {
+			TLan_DioWrite8( dev->base_addr, TLAN_NET_STS, net_sts );
+			TLAN_DBG( TLAN_DEBUG_GNRL, "%s:    Net_Sts = %x\n", dev->name, (unsigned) net_sts );
+		}
+		if ( ( net_sts & TLAN_NET_STS_MIRQ ) &&  ( priv->phyNum == 0 ) ) {
+			TLan_MiiReadReg( dev, phy, TLAN_TLPHY_STS, &tlphy_sts );
+			TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl );
+        		if ( ! ( tlphy_sts & TLAN_TS_POLOK ) && ! ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
+                		tlphy_ctl |= TLAN_TC_SWAPOL;
+                		TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
+        		} else if ( ( tlphy_sts & TLAN_TS_POLOK ) && ( tlphy_ctl & TLAN_TC_SWAPOL ) ) {
+                		tlphy_ctl &= ~TLAN_TC_SWAPOL;
+                		TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl);
+        		}
+
+			if (debug) {
+				TLan_PhyPrint( dev );		
+			}
+		}
+	}
+
+	return ack;
+
+} /* TLan_HandleStatusCheck */
+
+	/***************************************************************
+	 *	TLan_HandleRxEOC
+	 *
+	 *	Returns:
+	 *		1
+	 *	Parms:
+	 *		dev		Device assigned the IRQ that was
+	 *				raised.
+	 *		host_int	The contents of the HOST_INT
+	 *				port.
+	 *
+	 *	This driver is structured to determine EOC occurances by
+	 *	reading the CSTAT member of the list structure.  Rx EOC
+	 *	interrupts are disabled via the DIO INTDIS register.
+	 *	However, TLAN chips before revision 3.0 didn't have this
+	 *	CSTAT member or a INTDIS register, so if this chip is
+	 *	pre-3.0, process EOC interrupts normally.
+	 *
+	 **************************************************************/
+
+u32 TLan_HandleRxEOC( struct net_device *dev, u16 host_int )
+{
+	TLanPrivateInfo	*priv = dev->priv;
+	TLanList	*head_list;
+	u32		ack = 1;
+
+	if (  priv->tlanRev < 0x30 ) {
+		TLAN_DBG( TLAN_DEBUG_RX, "RECEIVE:  Handling RX EOC (Head=%d Tail=%d) -- IRQ\n", priv->rxHead, priv->rxTail );
+		head_list = priv->rxList + priv->rxHead;
+		outl( virt_to_bus( head_list ), dev->base_addr + TLAN_CH_PARM );
+		ack |= TLAN_HC_GO | TLAN_HC_RT;
+		priv->rxEocCount++;
+	}
+
+	return ack;
+
+} /* TLan_HandleRxEOC */
+
+/*****************************************************************************
+******************************************************************************
+
+	ThunderLAN Driver Timer Function
+
+******************************************************************************
+*****************************************************************************/
+
+	/***************************************************************
+	 *	TLan_Timer
+	 *
+	 *	Returns:
+	 *		Nothing
+	 *	Parms:
+	 *		data	A value given to add timer when
+	 *			add_timer was called.
+	 *
+	 *	This function handles timed functionality for the
+	 *	TLAN driver.  The two current timer uses are for
+	 *	delaying for autonegotionation and driving the ACT LED.
+	 *	-	Autonegotiation requires being allowed about
+	 *		2 1/2 seconds before attempting to transmit a
+	 *		packet.  It would be a very bad thing to hang
+	 *		the kernel this long, so the driver doesn't
+	 *		allow transmission 'til after this time, for
+	 *		certain PHYs.  It would be much nicer if all
+	 *		PHYs were interrupt-capable like the internal
+	 *		PHY.
+	 *	-	The ACT LED, which shows adapter activity, is
+	 *		driven by the driver, and so must be left on
+	 *		for a short period to power up the LED so it
+	 *		can be seen.  This delay can be changed by
+	 *		changing the TLAN_TIMER_ACT_DELAY in tlan.h,
+	 *		if desired.  100 ms  produces a slightly
+	 *		sluggish response.
+	 *
+	 **************************************************************/
+
+void TLan_Timer( unsigned long data )
+{
+	struct net_device	*dev = (struct net_device *) data;
+	TLanPrivateInfo	*priv = dev->priv;
+	u32		elapsed;
+	unsigned long	flags = 0;
+
+	priv->timer.function = NULL;
+
+	switch ( priv->timerType ) {
+#ifdef MONITOR		
+		case TLAN_TIMER_LINK_BEAT:
+			TLan_PhyMonitor( dev );
+			break;
+#endif
+		case TLAN_TIMER_PHY_PDOWN:
+			TLan_PhyPowerDown( dev );
+			break;
+		case TLAN_TIMER_PHY_PUP:
+			TLan_PhyPowerUp( dev );
+			break;
+		case TLAN_TIMER_PHY_RESET:
+			TLan_PhyReset( dev );
+			break;
+		case TLAN_TIMER_PHY_START_LINK:
+			TLan_PhyStartLink( dev );
+			break;
+		case TLAN_TIMER_PHY_FINISH_AN:
+			TLan_PhyFinishAutoNeg( dev );
+			break;
+		case TLAN_TIMER_FINISH_RESET:
+			TLan_FinishReset( dev );
+			break;
+		case TLAN_TIMER_ACTIVITY:
+			spin_lock_irqsave(&priv->lock, flags);
+			if ( priv->timer.function == NULL ) {
+				elapsed = jiffies - priv->timerSetAt;
+				if ( elapsed >= TLAN_TIMER_ACT_DELAY ) {
+					TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
+				} else  {
+					priv->timer.function = &TLan_Timer;
+					priv->timer.expires = priv->timerSetAt + TLAN_TIMER_ACT_DELAY;
+					spin_unlock_irqrestore(&priv->lock, flags);
+					add_timer( &priv->timer );
+					break;
+				}
+			}
+			spin_unlock_irqrestore(&priv->lock, flags);
+			break;
+		default:
+			break;
+	}
+
+} /* TLan_Timer */
+
+/*****************************************************************************
+******************************************************************************
+
+	ThunderLAN Driver Adapter Related Routines
+
+******************************************************************************
+*****************************************************************************/
+
+	/***************************************************************
+	 *	TLan_ResetLists
+	 *  
+	 *	Returns:
+	 *		Nothing
+	 *	Parms:
+	 *		dev	The device structure with the list
+	 *			stuctures to be reset.
+	 *
+	 *	This routine sets the variables associated with managing
+	 *	the TLAN lists to their initial values.
+	 *
+	 **************************************************************/
+
+void TLan_ResetLists( struct net_device *dev )
+{
+	TLanPrivateInfo *priv = dev->priv;
+	int		i;
+	TLanList	*list;
+	struct sk_buff	*skb;
+	void		*t = NULL;
+
+	priv->txHead = 0;
+	priv->txTail = 0;
+	for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ ) {
+		list = priv->txList + i;
+		list->cStat = TLAN_CSTAT_UNUSED;
+		if ( bbuf ) {
+			list->buffer[0].address = virt_to_bus( priv->txBuffer + ( i * TLAN_MAX_FRAME_SIZE ) );
+		} else {
+			list->buffer[0].address = 0;
+		}
+		list->buffer[2].count = 0;
+		list->buffer[2].address = 0;
+		list->buffer[9].address = 0;
+	}
+
+	priv->rxHead = 0;
+	priv->rxTail = TLAN_NUM_RX_LISTS - 1;
+	for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) {
+		list = priv->rxList + i;
+		list->cStat = TLAN_CSTAT_READY;
+		list->frameSize = TLAN_MAX_FRAME_SIZE;
+		list->buffer[0].count = TLAN_MAX_FRAME_SIZE | TLAN_LAST_BUFFER;
+		if ( bbuf ) {
+			list->buffer[0].address = virt_to_bus( priv->rxBuffer + ( i * TLAN_MAX_FRAME_SIZE ) );
+		} else {
+			skb = dev_alloc_skb( TLAN_MAX_FRAME_SIZE + 7 );
+			if ( skb == NULL ) {
+				printk( "TLAN:  Couldn't allocate memory for received data.\n" );
+				/* If this ever happened it would be a problem */
+			} else {
+				skb->dev = dev;
+				skb_reserve( skb, 2 );
+				t = (void *) skb_put( skb, TLAN_MAX_FRAME_SIZE );
+			}
+			list->buffer[0].address = virt_to_bus( t );
+			list->buffer[8].address = (u32) t;
+			list->buffer[9].address = (u32) skb;
+		}
+		list->buffer[1].count = 0;
+		list->buffer[1].address = 0;
+		if ( i < TLAN_NUM_RX_LISTS - 1 )
+			list->forward = virt_to_bus( list + 1 );
+		else
+			list->forward = 0;
+	}
+
+} /* TLan_ResetLists */
+
+void TLan_FreeLists( struct net_device *dev )
+{
+	TLanPrivateInfo *priv = dev->priv;
+	int		i;
+	TLanList	*list;
+	struct sk_buff	*skb;
+
+	if ( ! bbuf ) {
+		for ( i = 0; i < TLAN_NUM_TX_LISTS; i++ ) {
+			list = priv->txList + i;
+			skb = (struct sk_buff *) list->buffer[9].address;
+			if ( skb ) {
+				dev_kfree_skb_any( skb );
+				list->buffer[9].address = 0;
+			}
+		}
+
+		for ( i = 0; i < TLAN_NUM_RX_LISTS; i++ ) {
+			list = priv->rxList + i;
+			skb = (struct sk_buff *) list->buffer[9].address;
+			if ( skb ) {
+				dev_kfree_skb_any( skb );
+				list->buffer[9].address = 0;
+			}
+		}
+	}
+
+} /* TLan_FreeLists */
+
+	/***************************************************************
+	 *	TLan_PrintDio
+	 *  
+	 *	Returns:
+	 *		Nothing
+	 *	Parms:
+	 *		io_base		Base IO port of the device of
+	 *				which to print DIO registers.
+	 *
+	 *	This function prints out all the internal (DIO)
+	 *	registers of a TLAN chip.
+	 *
+	 **************************************************************/
+
+void TLan_PrintDio( u16 io_base )
+{
+	u32 data0, data1;
+	int	i;
+
+	printk( "TLAN:   Contents of internal registers for io base 0x%04hx.\n", io_base );
+	printk( "TLAN:      Off.  +0         +4\n" );
+	for ( i = 0; i < 0x4C; i+= 8 ) {
+		data0 = TLan_DioRead32( io_base, i );
+		data1 = TLan_DioRead32( io_base, i + 0x4 );
+		printk( "TLAN:      0x%02x  0x%08x 0x%08x\n", i, data0, data1 );
+	}
+
+} /* TLan_PrintDio */
+
+	/***************************************************************
+	 *	TLan_PrintList
+	 *  
+	 *	Returns:
+	 *		Nothing
+	 *	Parms:
+	 *		list	A pointer to the TLanList structure to
+	 *			be printed.
+	 *		type	A string to designate type of list,
+	 *			"Rx" or "Tx".
+	 *		num	The index of the list.
+	 *
+	 *	This function prints out the contents of the list
+	 *	pointed to by the list parameter.
+	 *
+	 **************************************************************/
+
+void TLan_PrintList( TLanList *list, char *type, int num)
+{
+	int i;
+
+	printk( "TLAN:   %s List %d at 0x%08x\n", type, num, (u32) list );
+	printk( "TLAN:      Forward    = 0x%08x\n",  list->forward );
+	printk( "TLAN:      CSTAT      = 0x%04hx\n", list->cStat );
+	printk( "TLAN:      Frame Size = 0x%04hx\n", list->frameSize );
+	/* for ( i = 0; i < 10; i++ ) { */
+	for ( i = 0; i < 2; i++ ) {
+		printk( "TLAN:      Buffer[%d].count, addr = 0x%08x, 0x%08x\n", i, list->buffer[i].count, list->buffer[i].address );
+	}
+
+} /* TLan_PrintList */
+
+	/***************************************************************
+	 *	TLan_ReadAndClearStats
+	 *
+	 *	Returns:
+	 *		Nothing
+	 *	Parms:
+	 *		dev	Pointer to device structure of adapter
+	 *			to which to read stats.
+	 *		record	Flag indicating whether to add 
+	 *
+	 *	This functions reads all the internal status registers
+	 *	of the TLAN chip, which clears them as a side effect.
+	 *	It then either adds the values to the device's status
+	 *	struct, or discards them, depending on whether record
+	 *	is TLAN_RECORD (!=0)  or TLAN_IGNORE (==0).
+	 *
+	 **************************************************************/
+
+void TLan_ReadAndClearStats( struct net_device *dev, int record )
+{
+	TLanPrivateInfo	*priv = dev->priv;
+	u32		tx_good, tx_under;
+	u32		rx_good, rx_over;
+	u32		def_tx, crc, code;
+	u32		multi_col, single_col;
+	u32		excess_col, late_col, loss;
+
+	outw( TLAN_GOOD_TX_FRMS, dev->base_addr + TLAN_DIO_ADR );
+	tx_good  = inb( dev->base_addr + TLAN_DIO_DATA );
+	tx_good += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
+	tx_good += inb( dev->base_addr + TLAN_DIO_DATA + 2 ) << 16;
+	tx_under = inb( dev->base_addr + TLAN_DIO_DATA + 3 );
+
+	outw( TLAN_GOOD_RX_FRMS, dev->base_addr + TLAN_DIO_ADR );
+	rx_good  = inb( dev->base_addr + TLAN_DIO_DATA );
+	rx_good += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
+	rx_good += inb( dev->base_addr + TLAN_DIO_DATA + 2 ) << 16;
+	rx_over  = inb( dev->base_addr + TLAN_DIO_DATA + 3 );
+		
+	outw( TLAN_DEFERRED_TX, dev->base_addr + TLAN_DIO_ADR );
+	def_tx  = inb( dev->base_addr + TLAN_DIO_DATA );
+	def_tx += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
+	crc     = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
+	code    = inb( dev->base_addr + TLAN_DIO_DATA + 3 );
+	
+	outw( TLAN_MULTICOL_FRMS, dev->base_addr + TLAN_DIO_ADR );
+	multi_col   = inb( dev->base_addr + TLAN_DIO_DATA );
+	multi_col  += inb( dev->base_addr + TLAN_DIO_DATA + 1 ) << 8;
+	single_col  = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
+	single_col += inb( dev->base_addr + TLAN_DIO_DATA + 3 ) << 8;
+
+	outw( TLAN_EXCESSCOL_FRMS, dev->base_addr + TLAN_DIO_ADR );
+	excess_col = inb( dev->base_addr + TLAN_DIO_DATA );
+	late_col   = inb( dev->base_addr + TLAN_DIO_DATA + 1 );
+	loss       = inb( dev->base_addr + TLAN_DIO_DATA + 2 );
+
+	if ( record ) {
+		priv->stats.rx_packets += rx_good;
+		priv->stats.rx_errors  += rx_over + crc + code;
+		priv->stats.tx_packets += tx_good;
+		priv->stats.tx_errors  += tx_under + loss;
+		priv->stats.collisions += multi_col + single_col + excess_col + late_col;
+
+		priv->stats.rx_over_errors    += rx_over;
+		priv->stats.rx_crc_errors     += crc;
+		priv->stats.rx_frame_errors   += code;
+
+		priv->stats.tx_aborted_errors += tx_under;
+		priv->stats.tx_carrier_errors += loss;
+	}
+			
+} /* TLan_ReadAndClearStats */
+
+	/***************************************************************
+	 *	TLan_Reset
+	 *
+	 *	Returns:
+	 *		0
+	 *	Parms:
+	 *		dev	Pointer to device structure of adapter
+	 *			to be reset.
+	 *
+	 *	This function resets the adapter and it's physical
+	 *	device.  See Chap. 3, pp. 9-10 of the "ThunderLAN
+	 *	Programmer's Guide" for details.  The routine tries to
+	 *	implement what is detailed there, though adjustments
+	 *	have been made.
+	 *
+	 **************************************************************/
+
+void
+TLan_ResetAdapter( struct net_device *dev )
+{
+	TLanPrivateInfo	*priv = dev->priv;
+	int		i;
+	u32		addr;
+	u32		data;
+	u8		data8;
+
+	priv->tlanFullDuplex = FALSE;
+	priv->phyOnline=0;
+/*  1.	Assert reset bit. */
+
+	data = inl(dev->base_addr + TLAN_HOST_CMD);
+	data |= TLAN_HC_AD_RST;
+	outl(data, dev->base_addr + TLAN_HOST_CMD);
+	
+	udelay(1000);
+
+/*  2.	Turn off interrupts. ( Probably isn't necessary ) */
+
+	data = inl(dev->base_addr + TLAN_HOST_CMD);
+	data |= TLAN_HC_INT_OFF;
+	outl(data, dev->base_addr + TLAN_HOST_CMD);
+
+/*  3.	Clear AREGs and HASHs. */
+
+ 	for ( i = TLAN_AREG_0; i <= TLAN_HASH_2; i += 4 ) {
+		TLan_DioWrite32( dev->base_addr, (u16) i, 0 );
+	}
+
+/*  4.	Setup NetConfig register. */
+
+	data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN | TLAN_NET_CFG_PHY_EN;
+	TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, (u16) data );
+
+/*  5.	Load Ld_Tmr and Ld_Thr in HOST_CMD. */
+
+ 	outl( TLAN_HC_LD_TMR | 0x3f, dev->base_addr + TLAN_HOST_CMD );
+ 	outl( TLAN_HC_LD_THR | 0x9, dev->base_addr + TLAN_HOST_CMD );
+
+/*  6.	Unreset the MII by setting NMRST (in NetSio) to 1. */
+
+	outw( TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR );
+	addr = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
+	TLan_SetBit( TLAN_NET_SIO_NMRST, addr );
+
+/*  7.	Setup the remaining registers. */
+
+	if ( priv->tlanRev >= 0x30 ) {
+		data8 = TLAN_ID_TX_EOC | TLAN_ID_RX_EOC;
+		TLan_DioWrite8( dev->base_addr, TLAN_INT_DIS, data8 );
+	}
+	TLan_PhyDetect( dev );
+	data = TLAN_NET_CFG_1FRAG | TLAN_NET_CFG_1CHAN;
+	
+	if ( priv->adapter->flags & TLAN_ADAPTER_BIT_RATE_PHY ) {
+		data |= TLAN_NET_CFG_BIT;
+		if ( priv->aui == 1 ) {
+			TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x0a );
+		} else if ( priv->duplex == TLAN_DUPLEX_FULL ) {
+			TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x00 );
+			priv->tlanFullDuplex = TRUE;
+		} else {
+			TLan_DioWrite8( dev->base_addr, TLAN_ACOMMIT, 0x08 );
+		}
+	}
+
+	if ( priv->phyNum == 0 ) {
+		data |= TLAN_NET_CFG_PHY_EN;
+	}
+	TLan_DioWrite16( dev->base_addr, TLAN_NET_CONFIG, (u16) data );
+
+	if ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) {
+		TLan_FinishReset( dev );
+	} else {
+		TLan_PhyPowerDown( dev );
+	}
+
+} /* TLan_ResetAdapter */
+
+void
+TLan_FinishReset( struct net_device *dev )
+{
+	TLanPrivateInfo	*priv = dev->priv;
+	u8		data;
+	u32		phy;
+	u8		sio;
+	u16		status;
+	u16		partner;
+	u16		tlphy_ctl;
+	u16 		tlphy_par;
+	u16		tlphy_id1, tlphy_id2;
+	int 		i;
+
+	phy = priv->phy[priv->phyNum];
+
+	data = TLAN_NET_CMD_NRESET | TLAN_NET_CMD_NWRAP;
+	if ( priv->tlanFullDuplex ) {
+		data |= TLAN_NET_CMD_DUPLEX;
+	}
+	TLan_DioWrite8( dev->base_addr, TLAN_NET_CMD, data );
+	data = TLAN_NET_MASK_MASK4 | TLAN_NET_MASK_MASK5; 
+	if ( priv->phyNum == 0 ) {
+		data |= TLAN_NET_MASK_MASK7; 
+	}
+	TLan_DioWrite8( dev->base_addr, TLAN_NET_MASK, data );
+	TLan_DioWrite16( dev->base_addr, TLAN_MAX_RX, ((1536)+7)&~7 );
+	TLan_MiiReadReg( dev, phy, MII_GEN_ID_HI, &tlphy_id1 );
+	TLan_MiiReadReg( dev, phy, MII_GEN_ID_LO, &tlphy_id2 );
+	
+	if ( ( priv->adapter->flags & TLAN_ADAPTER_UNMANAGED_PHY ) || ( priv->aui ) ) {
+		status = MII_GS_LINK;
+		printk( "TLAN:  %s: Link forced.\n", dev->name );
+	} else {
+		TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
+		udelay( 1000 );
+		TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
+		if ( (status & MII_GS_LINK) &&	 /* We only support link info on Nat.Sem. PHY's */ 
+			(tlphy_id1 == NAT_SEM_ID1) &&
+			(tlphy_id2 == NAT_SEM_ID2) ) {
+			TLan_MiiReadReg( dev, phy, MII_AN_LPA, &partner );
+			TLan_MiiReadReg( dev, phy, TLAN_TLPHY_PAR, &tlphy_par );
+			
+			printk( "TLAN: %s: Link active with ", dev->name );
+			if (!(tlphy_par & TLAN_PHY_AN_EN_STAT)) {
+			      	 printk( "forced 10%sMbps %s-Duplex\n", 
+						tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0",
+						tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half");
+			} else {
+				printk( "AutoNegotiation enabled, at 10%sMbps %s-Duplex\n",
+						tlphy_par & TLAN_PHY_SPEED_100 ? "" : "0",
+						tlphy_par & TLAN_PHY_DUPLEX_FULL ? "Full" : "Half");
+				printk("TLAN: Partner capability: ");
+					for (i = 5; i <= 10; i++)
+						if (partner & (1<<i))
+							printk("%s", media[i-5]);
+							printk("\n");
+			}
+
+			TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
+#ifdef MONITOR			
+			/* We have link beat..for now anyway */
+	        	priv->link = 1;
+	        	/*Enabling link beat monitoring */
+			TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_LINK_BEAT );
+#endif 
+		} else if (status & MII_GS_LINK)  {
+			printk( "TLAN: %s: Link active\n", dev->name );
+			TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK );
+		}
+	}
+
+	if ( priv->phyNum == 0 ) {
+        	TLan_MiiReadReg( dev, phy, TLAN_TLPHY_CTL, &tlphy_ctl );
+        	tlphy_ctl |= TLAN_TC_INTEN;
+        	TLan_MiiWriteReg( dev, phy, TLAN_TLPHY_CTL, tlphy_ctl );
+        	sio = TLan_DioRead8( dev->base_addr, TLAN_NET_SIO );
+        	sio |= TLAN_NET_SIO_MINTEN;
+        	TLan_DioWrite8( dev->base_addr, TLAN_NET_SIO, sio );
+	}
+
+	if ( status & MII_GS_LINK ) {
+		TLan_SetMac( dev, 0, dev->dev_addr );
+		priv->phyOnline = 1;
+		outb( ( TLAN_HC_INT_ON >> 8 ), dev->base_addr + TLAN_HOST_CMD + 1 );
+		if ( debug >= 1 && debug != TLAN_DEBUG_PROBE ) {
+			outb( ( TLAN_HC_REQ_INT >> 8 ), dev->base_addr + TLAN_HOST_CMD + 1 );
+		}
+		outl( virt_to_bus( priv->rxList ), dev->base_addr + TLAN_CH_PARM );
+		outl( TLAN_HC_GO | TLAN_HC_RT, dev->base_addr + TLAN_HOST_CMD );
+	} else {
+		printk( "TLAN: %s: Link inactive, will retry in 10 secs...\n", dev->name );
+		TLan_SetTimer( dev, (10*HZ), TLAN_TIMER_FINISH_RESET );
+		return;
+	}
+
+} /* TLan_FinishReset */
+
+	/***************************************************************
+	 *	TLan_SetMac
+	 *
+	 *	Returns:
+	 *		Nothing
+	 *	Parms:
+	 *		dev	Pointer to device structure of adapter
+	 *			on which to change the AREG.
+	 *		areg	The AREG to set the address in (0 - 3).
+	 *		mac	A pointer to an array of chars.  Each
+	 *			element stores one byte of the address.
+	 *			IE, it isn't in ascii.
+	 *
+	 *	This function transfers a MAC address to one of the
+	 *	TLAN AREGs (address registers).  The TLAN chip locks
+	 *	the register on writing to offset 0 and unlocks the
+	 *	register after writing to offset 5.  If NULL is passed
+	 *	in mac, then the AREG is filled with 0's.
+	 *
+	 **************************************************************/
+
+void TLan_SetMac( struct net_device *dev, int areg, char *mac )
+{
+	int i;
+			
+	areg *= 6;
+
+	if ( mac != NULL ) {
+		for ( i = 0; i < 6; i++ )
+			TLan_DioWrite8( dev->base_addr, TLAN_AREG_0 + areg + i, mac[i] );
+	} else {
+		for ( i = 0; i < 6; i++ )
+			TLan_DioWrite8( dev->base_addr, TLAN_AREG_0 + areg + i, 0 );
+	}
+
+} /* TLan_SetMac */
+
+#endif
diff --git a/netboot/tulip.c b/netboot/tulip.c
new file mode 100644
index 0000000..b784ea7
--- /dev/null
+++ b/netboot/tulip.c
@@ -0,0 +1,1989 @@
+/* -*- Mode:C; c-basic-offset:4; -*- */
+
+/*
+  Tulip and clone Etherboot Driver
+
+  By Marty Connor (mdc@thinguin.org)
+  Copyright (C) 2001 Entity Cyber, Inc.
+
+  This software may be used and distributed according to the terms
+  of the GNU Public License, incorporated herein by reference.
+
+  As of April 2001 this driver should support most tulip cards that 
+  the Linux tulip driver supports because Donald Becker's Linux media 
+  detection code is now included.
+
+  Based on Ken Yap's Tulip Etherboot Driver and Donald Becker's
+  Linux Tulip Driver. Supports N-Way speed auto-configuration on
+  MX98715, MX98715A and MX98725. Support inexpensive PCI 10/100 cards
+  based on the Macronix MX987x5 chip, such as the SOHOware Fast
+  model SFA110A, and the LinkSYS model LNE100TX. The NetGear
+  model FA310X, based on the LC82C168 chip is supported.
+  The TRENDnet TE100-PCIA NIC which uses a genuine Intel 21143-PD
+  chipset is supported. Also, Davicom DM9102's.
+
+  Documentation and source code used:
+  Source for Etherboot driver at
+  http://etherboot.sourceforge.net/
+  MX98715A Data Sheet and MX98715A Application Note
+  on http://www.macronix.com/  (PDF format files)
+  Source for Linux tulip driver at
+  http://cesdis.gsfc.nasa.gov/linux/drivers/tulip.html
+
+  Adapted by Ken Yap from
+  FreeBSD netboot DEC 21143 driver
+  Author: David Sharp
+  date: Nov/98
+
+  Some code fragments were taken from verious places, Ken Yap's
+  etherboot, FreeBSD's if_de.c, and various Linux related files.
+  DEC's manuals for the 21143 and SROM format were very helpful.
+  The Linux de driver development page has a number of links to
+  useful related information.  Have a look at:
+  ftp://cesdis.gsfc.nasa.gov/pub/linux/drivers/tulip-devel.html
+*/
+
+/*********************************************************************/
+/* Revision History                                                  */
+/*********************************************************************/
+
+/*
+  11 Apr 2001  mdc     [patch to etherboot 4.7.24]
+     Major rewrite to include Linux tulip driver media detection
+     code.  This driver should support a lot more cards now.
+  16 Jul 2000  mdc     0.75b11
+     Added support for ADMtek 0985 Centaur-P, a "Comet" tulip clone
+     which is used on the LinkSYS LNE100TX v4.x cards.  We already
+     support LNE100TX v2.0 cards, which use a different controller.
+  04 Jul 2000   jam     ?
+     Added test of status after receiving a packet from the card.
+     Also uncommented the tulip_disable routine.  Stray packets
+     seemed to be causing problems.
+  27 Apr 2000   njl     ?
+  29 Feb 2000   mdc     0.75b7
+     Increased reset delay to 3 seconds because Macronix cards seem to
+     need more reset time before card comes back to a usable state.
+  26 Feb 2000   mdc     0.75b6
+     Added a 1 second delay after initializing the transmitter because
+     some cards seem to need the time or they drop the first packet 
+     transmitted.
+  23 Feb 2000   mdc     0.75b5
+     removed udelay code and used currticks() for more reliable delay
+     code in reset pause and sanity timeouts.  Added function prototypes
+     and TX debugging code.
+  21 Feb 2000   mdc     patch to Etherboot 4.4.3
+     Incorporated patches from Bob Edwards and Paul Mackerras of 
+     Linuxcare's OZLabs to deal with inefficiencies in tulip_transmit
+     and udelay.  We now wait for packet transmission to complete
+     (or sanity timeout).
+  04 Feb 2000   Robert.Edwards@anu.edu.au patch to Etherboot 4.4.2
+     patch to tulip.c that implements the automatic selection of the MII
+     interface on cards using the Intel/DEC 21143 reference design, in
+     particular, the TRENDnet TE100-PCIA NIC which uses a genuine Intel
+     21143-PD chipset.
+  11 Jan 2000   mdc     0.75b4
+     Added support for NetGear FA310TX card based on the LC82C168
+     chip.  This should also support Lite-On LC82C168 boards.
+     Added simple MII support. Re-arranged code to better modularize
+     initializations.
+  04 Dec 1999   mdc     0.75b3
+     Added preliminary support for LNE100TX PCI cards.  Should work for
+     PNIC2 cards. No MII support, but single interface (RJ45) tulip
+     cards seem to not care.
+  03 Dec 1999   mdc     0.75b2
+     Renamed from mx987x5 to tulip, merged in original tulip init code
+     from tulip.c to support other tulip compatible cards.
+  02 Dec 1999   mdc     0.75b1
+     Released Beta MX987x5 Driver for code review and testing to netboot
+     and thinguin mailing lists.
+*/
+
+
+/*********************************************************************/
+/* Declarations                                                      */
+/*********************************************************************/
+
+#include "etherboot.h"
+#include "nic.h"
+#include "pci.h"
+#include "cards.h"
+
+/* User settable parameters */
+
+#undef   TULIP_DEBUG
+#undef   TULIP_DEBUG_WHERE
+static int tulip_debug = 2;             /* 1 normal messages, 0 quiet .. 7 verbose. */
+
+#define TX_TIME_OUT       2*TICKS_PER_SEC
+
+typedef unsigned char  u8;
+typedef   signed char  s8;
+typedef unsigned short u16;
+typedef   signed short s16;
+typedef unsigned int   u32;
+typedef   signed int   s32;
+
+/* helpful macros if on a big_endian machine for changing byte order.
+   not strictly needed on Intel */
+#define le16_to_cpu(val) (val)
+#define cpu_to_le32(val) (val)
+#define get_unaligned(ptr) (*(ptr))
+#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) ))
+#define get_u16(ptr) (*(u16 *)(ptr))
+#define virt_to_bus(x) ((unsigned long)x)
+#define virt_to_le32desc(addr)  virt_to_bus(addr)
+
+#define TULIP_IOTYPE  PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0
+#define TULIP_SIZE 0x80
+
+/* This is a mysterious value that can be written to CSR11 in the 21040 (only)
+   to support a pre-NWay full-duplex signaling mechanism using short frames.
+   No one knows what it should be, but if left at its default value some
+   10base2(!) packets trigger a full-duplex-request interrupt. */
+#define FULL_DUPLEX_MAGIC       0x6969
+
+static const int csr0 = 0x01A00000 | 0x8000;
+
+/*  The possible media types that can be set in options[] are: */
+#define MEDIA_MASK 31
+static const char * const medianame[32] = {
+    "10baseT", "10base2", "AUI", "100baseTx",
+    "10baseT-FDX", "100baseTx-FDX", "100baseT4", "100baseFx",
+    "100baseFx-FDX", "MII 10baseT", "MII 10baseT-FDX", "MII",
+    "10baseT(forced)", "MII 100baseTx", "MII 100baseTx-FDX", "MII 100baseT4",
+    "MII 100baseFx-HDX", "MII 100baseFx-FDX", "Home-PNA 1Mbps", "Invalid-19",
+};
+
+/* This much match tulip_tbl[]!  Note 21142 == 21143. */
+enum tulip_chips {
+    DC21040=0, DC21041=1, DC21140=2, DC21142=3, DC21143=3,
+    LC82C168, MX98713, MX98715, MX98725, AX88141, AX88140, PNIC2, COMET,
+    COMPEX9881, I21145, XIRCOM
+};
+
+enum pci_id_flags_bits {
+    /* Set PCI command register bits before calling probe1(). */
+    PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
+    /* Read and map the single following PCI BAR. */
+    PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4,
+    PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400,
+    PCI_UNUSED_IRQ=0x800,
+};
+
+struct pci_id_info {
+    char *name;
+    struct match_info {
+        u32 pci, pci_mask, subsystem, subsystem_mask;
+        u32 revision, revision_mask;                            /* Only 8 bits. */
+    } id;
+    enum pci_id_flags_bits pci_flags;
+    int io_size;                                /* Needed for I/O region check or ioremap(). */
+    int drv_flags;                              /* Driver use, intended as capability flags. */
+};
+
+static struct pci_id_info pci_id_tbl[] = {
+    { "Digital DC21040 Tulip", { 0x00021011, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, 0x80, DC21040 },
+    { "Digital DC21041 Tulip", { 0x00141011, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, 0x80, DC21041 },
+    { "Digital DS21140A Tulip", { 0x00091011, 0xffffffff, 0,0, 0x20,0xf0 },
+      TULIP_IOTYPE, 0x80, DC21140 },
+    { "Digital DS21140 Tulip", { 0x00091011, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, 0x80, DC21140 },
+    { "Digital DS21143 Tulip", { 0x00191011, 0xffffffff, 0,0, 65,0xff },
+      TULIP_IOTYPE, TULIP_SIZE, DC21142 },
+    { "Digital DS21142 Tulip", { 0x00191011, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, TULIP_SIZE, DC21142 },
+    { "Kingston KNE110tx (PNIC)", { 0x000211AD, 0xffffffff, 0xf0022646, 0xffffffff, 0, 0 },
+      TULIP_IOTYPE, 256, LC82C168 },
+    { "Lite-On 82c168 PNIC", { 0x000211AD, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, 256, LC82C168 },
+    { "Macronix 98713 PMAC", { 0x051210d9, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, 256, MX98713 },
+    { "Macronix 98715 PMAC", { 0x053110d9, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, 256, MX98715 },
+    { "Macronix 98725 PMAC", { 0x053110d9, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, 256, MX98725 },
+    { "ASIX AX88141", { 0x1400125B, 0xffffffff, 0,0, 0x10, 0xf0 },
+      TULIP_IOTYPE, 128, AX88141 },
+    { "ASIX AX88140", { 0x1400125B, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, 128, AX88140 },
+    { "Lite-On LC82C115 PNIC-II", { 0xc11511AD, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, 256, PNIC2 },
+    { "ADMtek AN981 Comet", { 0x09811317, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, 256, COMET },
+    { "ADMtek Centaur-P", { 0x09851317, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, 256, COMET },
+    { "ADMtek Centaur-C", { 0x19851317, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, 256, COMET },
+    { "Compex RL100-TX", { 0x988111F6, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, 128, COMPEX9881 },
+    { "Intel 21145 Tulip", { 0x00398086, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, 128, I21145 },
+    { "Xircom Tulip clone", { 0x0003115d, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, 128, XIRCOM },
+    { "Davicom DM9102", { 0x91021282, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, 0x80, DC21140 },
+    { "Davicom DM9100", { 0x91001282, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, 0x80, DC21140 },
+    { "Macronix mxic-98715 (EN1217)", { 0x12171113, 0xffffffff, 0, 0, 0, 0 },
+      TULIP_IOTYPE, 256, MX98715 },
+    { 0, { 0, 0, 0, 0, 0, 0 }, 0, 0, 0 },
+};
+
+enum tbl_flag {
+    HAS_MII=1, HAS_MEDIA_TABLE=2, CSR12_IN_SROM=4, ALWAYS_CHECK_MII=8,
+    HAS_PWRDWN=0x10, MC_HASH_ONLY=0x20, /* Hash-only multicast filter. */
+    HAS_PNICNWAY=0x80, HAS_NWAY=0x40,   /* Uses internal NWay xcvr. */
+    HAS_INTR_MITIGATION=0x100, IS_ASIX=0x200, HAS_8023X=0x400,
+};
+
+/* Note: this table must match  enum tulip_chips  above. */
+static struct tulip_chip_table {
+    char *chip_name;
+    int flags;
+} tulip_tbl[] = {
+    { "Digital DC21040 Tulip", 0},
+    { "Digital DC21041 Tulip", HAS_MEDIA_TABLE | HAS_NWAY },
+    { "Digital DS21140 Tulip", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM },
+    { "Digital DS21143 Tulip", HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII 
+      | HAS_PWRDWN | HAS_NWAY   | HAS_INTR_MITIGATION },
+    { "Lite-On 82c168 PNIC", HAS_MII | HAS_PNICNWAY },
+    { "Macronix 98713 PMAC", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM },
+    { "Macronix 98715 PMAC", HAS_MEDIA_TABLE },
+    { "Macronix 98725 PMAC", HAS_MEDIA_TABLE },
+    { "ASIX AX88140", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM 
+      | MC_HASH_ONLY | IS_ASIX },
+    { "ASIX AX88141", HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM | MC_HASH_ONLY 
+      | IS_ASIX },
+    { "Lite-On PNIC-II", HAS_MII | HAS_NWAY | HAS_8023X },
+    { "ADMtek Comet", MC_HASH_ONLY },
+    { "Compex 9881 PMAC",       HAS_MII | HAS_MEDIA_TABLE | CSR12_IN_SROM },
+    { "Intel DS21145 Tulip", HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII 
+      | HAS_PWRDWN | HAS_NWAY },
+    { "Xircom tulip work-alike", HAS_MII | HAS_MEDIA_TABLE | ALWAYS_CHECK_MII 
+      | HAS_PWRDWN | HAS_NWAY },
+    { 0, 0 },
+};
+
+/* A full-duplex map for media types. */
+enum MediaIs {
+    MediaIsFD = 1, MediaAlwaysFD=2, MediaIsMII=4, MediaIsFx=8,
+    MediaIs100=16};
+
+static const char media_cap[32] =
+{0,0,0,16,  3,19,16,24,  27,4,7,5, 0,20,23,20, 20,31,0,0, };
+static u8 t21040_csr13[] = {2,0x0C,8,4,  4,0,0,0, 0,0,0,0, 4,0,0,0};
+
+/* 21041 transceiver register settings: 10-T, 10-2, AUI, 10-T, 10T-FD */
+static u16 t21041_csr13[] = { 0xEF01, 0xEF09, 0xEF09, 0xEF01, 0xEF09, };
+static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x7F3F, 0x7F3D, };
+static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
+
+static u16 t21142_csr13[] = { 0x0001, 0x0009, 0x0009, 0x0000, 0x0001, };
+static u16 t21142_csr14[] = { 0xFFFF, 0x0705, 0x0705, 0x0000, 0x7F3D, };
+static u16 t21142_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, };
+
+/* Offsets to the Command and Status Registers, "CSRs".  All accesses
+   must be longword instructions and quadword aligned. */
+enum tulip_offsets {
+    CSR0=0,     CSR1=0x08,  CSR2=0x10,  CSR3=0x18,  CSR4=0x20,  CSR5=0x28,
+    CSR6=0x30,  CSR7=0x38,  CSR8=0x40,  CSR9=0x48, CSR10=0x50, CSR11=0x58,
+    CSR12=0x60, CSR13=0x68, CSR14=0x70, CSR15=0x78, CSR16=0x80, CSR20=0xA0
+};
+
+/* The bits in the CSR5 status registers, mostly interrupt sources. */
+enum status_bits {
+    TimerInt=0x800, TPLnkFail=0x1000, TPLnkPass=0x10,
+    NormalIntr=0x10000, AbnormalIntr=0x8000,
+    RxJabber=0x200, RxDied=0x100, RxNoBuf=0x80, RxIntr=0x40,
+    TxFIFOUnderflow=0x20, TxJabber=0x08, TxNoBuf=0x04, TxDied=0x02, TxIntr=0x01,
+};
+
+enum desc_status_bits {
+    DescOwnded=0x80000000, RxDescFatalErr=0x8000, RxWholePkt=0x0300,
+};
+
+struct medialeaf {
+    u8 type;
+    u8 media;
+    unsigned char *leafdata;
+};
+
+struct mediatable {
+    u16 defaultmedia;
+    u8 leafcount, csr12dir;                             /* General purpose pin directions. */
+    unsigned has_mii:1, has_nonmii:1, has_reset:6;
+    u32 csr15dir, csr15val;                             /* 21143 NWay setting. */
+    struct medialeaf mleaf[0];
+};
+
+struct mediainfo {
+    struct mediainfo *next;
+    int info_type;
+    int index;
+    unsigned char *info;
+};
+
+/* EEPROM Address width definitions */
+#define EEPROM_ADDRLEN 6
+#define EEPROM_SIZE    128              /* 2 << EEPROM_ADDRLEN */
+
+/* The EEPROM commands include the alway-set leading bit. */
+#define EE_WRITE_CMD    (5 << addr_len)
+#define EE_READ_CMD     (6 << addr_len)
+#define EE_ERASE_CMD    (7 << addr_len)
+
+/* EEPROM_Ctrl bits. */
+#define EE_SHIFT_CLK    0x02    /* EEPROM shift clock. */
+#define EE_CS           0x01    /* EEPROM chip select. */
+#define EE_DATA_WRITE   0x04    /* EEPROM chip data in. */
+#define EE_WRITE_0      0x01
+#define EE_WRITE_1      0x05
+#define EE_DATA_READ    0x08    /* EEPROM chip data out. */
+#define EE_ENB          (0x4800 | EE_CS)
+
+/* Delay between EEPROM clock transitions.  Even at 33Mhz current PCI
+   implementations don't overrun the EEPROM clock.  We add a bus
+   turn-around to insure that this remains true.  */
+#define eeprom_delay()  inl(ee_addr)
+
+/* Size of transmit and receive buffers */
+#define BUFLEN 1536
+
+/* Ring-wrap flag in length field, use for last ring entry.
+   0x01000000 means chain on buffer2 address,
+   0x02000000 means use the ring start address in CSR2/3.
+   Note: Some work-alike chips do not function correctly in chained mode.
+   The ASIX chip works only in chained mode.
+   Thus we indicate ring mode, but always write the 'next' field for
+   chained mode as well. */
+#define DESC_RING_WRAP 0x02000000
+
+/* transmit and receive descriptor format */
+struct tulip_rx_desc {
+    volatile u32 status;
+    u32 length;
+    u32 buffer1, buffer2;
+};
+
+struct tulip_tx_desc {
+    volatile u32 status;
+    u32 length;
+    u32 buffer1, buffer2;
+};
+
+/*********************************************************************/
+/* Global Storage                                                    */
+/*********************************************************************/
+
+static u32 ioaddr;
+
+/* Note: transmit and receive buffers must be longword aligned and
+   longword divisable */
+
+#define TX_RING_SIZE	2
+static struct tulip_tx_desc tx_ring[TX_RING_SIZE] __attribute__ ((aligned(4)));
+
+#ifdef USE_LOWMEM_BUFFER
+#define txb ((char *)0x10000 - BUFLEN)
+#else
+static unsigned char txb[BUFLEN] __attribute__ ((aligned(4)));
+#endif
+
+#define RX_RING_SIZE	4
+static struct tulip_rx_desc rx_ring[RX_RING_SIZE] __attribute__ ((aligned(4)));
+
+#ifdef USE_LOWMEM_BUFFER
+#define rxb ((char *)0x10000 - RX_RING_SIZE * BUFLEN - BUFLEN)
+#else
+static unsigned char rxb[RX_RING_SIZE * BUFLEN] __attribute__ ((aligned(4)));
+#endif
+
+static struct tulip_private {
+    int cur_rx;
+    int chip_id;                        /* index into tulip_tbl[]  */
+    int pci_id_idx;                     /* index into pci_id_tbl[] */
+    int revision;
+    int flags;
+    unsigned short vendor_id;           /* PCI card vendor code */
+    unsigned short dev_id;              /* PCI card device code */
+    unsigned char ehdr[ETH_HLEN];       /* buffer for ethernet header */
+    const char *nic_name;
+    unsigned int csr0, csr6;            /* Current CSR0, CSR6 settings. */
+    unsigned int if_port;
+    unsigned int full_duplex;         /* Full-duplex operation requested. */
+    unsigned int full_duplex_lock;
+    unsigned int medialock;           /* Do not sense media type. */
+    unsigned int mediasense;          /* Media sensing in progress. */
+    unsigned int nway, nwayset;     /* 21143 internal NWay. */
+    unsigned int default_port;
+    unsigned char eeprom[EEPROM_SIZE];  /* Serial EEPROM contents. */
+    u8 media_table_storage[(sizeof(struct mediatable) + 32*sizeof(struct medialeaf))];
+    u16 sym_advertise, mii_advertise;   /* NWay to-advertise. */
+    struct mediatable *mtable;
+    u16 lpar;                           /* 21143 Link partner ability. */
+    u16 advertising[4];                 /* MII advertise, from SROM table. */
+    signed char phys[4], mii_cnt;       /* MII device addresses. */
+    int cur_index;                      /* Current media index. */
+    int saved_if_port;
+} tpx;
+
+static struct tulip_private *tp;
+
+/* Known cards that have old-style EEPROMs.
+   Writing this table is described at
+   http://cesdis.gsfc.nasa.gov/linux/drivers/tulip-drivers/tulip-media.html */
+static struct fixups {
+    char *name;
+    unsigned char addr0, addr1, addr2;
+    u16 newtable[32];                           /* Max length below. */
+} eeprom_fixups[] = {
+    {"Asante", 0, 0, 0x94, {0x1e00, 0x0000, 0x0800, 0x0100, 0x018c,
+                            0x0000, 0x0000, 0xe078, 0x0001, 0x0050, 0x0018 }},
+    {"SMC9332DST", 0, 0, 0xC0, { 0x1e00, 0x0000, 0x0800, 0x041f,
+                                 0x0000, 0x009E, /* 10baseT */
+                                 0x0004, 0x009E, /* 10baseT-FD */
+                                 0x0903, 0x006D, /* 100baseTx */
+                                 0x0905, 0x006D, /* 100baseTx-FD */ }},
+    {"Cogent EM100", 0, 0, 0x92, { 0x1e00, 0x0000, 0x0800, 0x063f,
+                                   0x0107, 0x8021, /* 100baseFx */
+                                   0x0108, 0x8021, /* 100baseFx-FD */
+                                   0x0100, 0x009E, /* 10baseT */
+                                   0x0104, 0x009E, /* 10baseT-FD */
+                                   0x0103, 0x006D, /* 100baseTx */
+                                   0x0105, 0x006D, /* 100baseTx-FD */ }},
+    {"Maxtech NX-110", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x0513,
+                                     0x1001, 0x009E, /* 10base2, CSR12 0x10*/
+                                     0x0000, 0x009E, /* 10baseT */
+                                     0x0004, 0x009E, /* 10baseT-FD */
+                                     0x0303, 0x006D, /* 100baseTx, CSR12 0x03 */
+                                     0x0305, 0x006D, /* 100baseTx-FD CSR12 0x03 */}},
+    {"Accton EN1207", 0, 0, 0xE8, { 0x1e00, 0x0000, 0x0800, 0x051F,
+                                    0x1B01, 0x0000, /* 10base2,   CSR12 0x1B */
+                                    0x0B00, 0x009E, /* 10baseT,   CSR12 0x0B */
+                                    0x0B04, 0x009E, /* 10baseT-FD,CSR12 0x0B */
+                                    0x1B03, 0x006D, /* 100baseTx, CSR12 0x1B */
+                                    0x1B05, 0x006D, /* 100baseTx-FD CSR12 0x1B */
+    }},
+    {0, 0, 0, 0, {}}};
+
+static const char * block_name[] = {"21140 non-MII", "21140 MII PHY",
+                                    "21142 Serial PHY", "21142 MII PHY", "21143 SYM PHY", "21143 reset method"};
+
+
+/*********************************************************************/
+/* Function Prototypes                                               */
+/*********************************************************************/
+static int mdio_read(struct nic *nic, int phy_id, int location);
+static void mdio_write(struct nic *nic, int phy_id, int location, int value);
+static int read_eeprom(unsigned long ioaddr, int location, int addr_len);
+static void parse_eeprom(struct nic *nic);
+struct nic *tulip_probe(struct nic *nic, unsigned short *io_addrs,
+                        struct pci_device *pci);
+static void tulip_init_ring(struct nic *nic);
+static void tulip_reset(struct nic *nic);
+static void tulip_transmit(struct nic *nic, const char *d, unsigned int t,
+                           unsigned int s, const char *p);
+static int tulip_poll(struct nic *nic);
+static void tulip_disable(struct nic *nic);
+static void nway_start(struct nic *nic);
+static void pnic_do_nway(struct nic *nic);
+static void select_media(struct nic *nic, int startup);
+static void init_media(struct nic *nic);
+static void start_link(struct nic *nic);
+static int tulip_check_duplex(struct nic *nic);
+
+static void tulip_wait(unsigned int nticks);
+
+#ifdef TULIP_DEBUG_WHERE
+static void whereami(const char *str);
+#endif
+
+#ifdef TULIP_DEBUG
+static void tulip_more(void);
+#endif
+
+
+/*********************************************************************/
+/* Utility Routines                                                  */
+/*********************************************************************/
+
+#ifdef TULIP_DEBUG_WHERE
+static void whereami (const char *str)
+{
+    printf("%s: %s\n", tp->nic_name, str);
+    /* sleep(2); */
+}
+#endif
+
+#ifdef  TULIP_DEBUG
+static void tulip_more(void)
+{
+    printf("\n\n-- more --");
+    while (!iskey())
+        /* wait */;
+    getchar();
+    printf("\n\n");
+}
+#endif /* TULIP_DEBUG */
+
+static void tulip_wait(unsigned int nticks)
+{
+    unsigned int to = currticks() + nticks;
+    while (currticks() < to)
+        /* wait */ ;
+}
+
+
+/*********************************************************************/
+/* Media Descriptor Code                                             */
+/*********************************************************************/
+
+/* MII transceiver control section.
+   Read and write the MII registers using software-generated serial
+   MDIO protocol.  See the MII specifications or DP83840A data sheet
+   for details. */
+
+/* The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
+   met by back-to-back PCI I/O cycles, but we insert a delay to avoid
+   "overclocking" issues or future 66Mhz PCI. */
+#define mdio_delay() inl(mdio_addr)
+
+/* Read and write the MII registers using software-generated serial
+   MDIO protocol.  It is just different enough from the EEPROM protocol
+   to not share code.  The maxium data clock rate is 2.5 Mhz. */
+#define MDIO_SHIFT_CLK  0x10000
+#define MDIO_DATA_WRITE0 0x00000
+#define MDIO_DATA_WRITE1 0x20000
+#define MDIO_ENB                0x00000         /* Ignore the 0x02000 databook setting. */
+#define MDIO_ENB_IN             0x40000
+#define MDIO_DATA_READ  0x80000
+
+/* MII transceiver control section.
+   Read and write the MII registers using software-generated serial
+   MDIO protocol.  See the MII specifications or DP83840A data sheet
+   for details. */
+
+int mdio_read(struct nic *nic, int phy_id, int location)
+{
+    int i;
+    int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
+    int retval = 0;
+    long mdio_addr = ioaddr + CSR9;
+
+#ifdef TULIP_DEBUG_WHERE
+    whereami("mdio_read\n");
+#endif
+
+    if (tp->chip_id == LC82C168) {
+	int i = 1000;
+	outl(0x60020000 + (phy_id<<23) + (location<<18), ioaddr + 0xA0);
+	inl(ioaddr + 0xA0);
+	inl(ioaddr + 0xA0);
+	while (--i > 0)
+	    if ( ! ((retval = inl(ioaddr + 0xA0)) & 0x80000000))
+		return retval & 0xffff;
+	return 0xffff;
+    }
+
+    if (tp->chip_id == COMET) {
+	if (phy_id == 1) {
+	    if (location < 7)
+		return inl(ioaddr + 0xB4 + (location<<2));
+	    else if (location == 17)
+		return inl(ioaddr + 0xD0);
+	    else if (location >= 29 && location <= 31)
+		return inl(ioaddr + 0xD4 + ((location-29)<<2));
+	}
+	return 0xffff;
+    }
+
+    /* Establish sync by sending at least 32 logic ones. */
+    for (i = 32; i >= 0; i--) {
+	outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
+	mdio_delay();
+	outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
+	mdio_delay();
+    }
+    /* Shift the read command bits out. */
+    for (i = 15; i >= 0; i--) {
+	int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
+
+	outl(MDIO_ENB | dataval, mdio_addr);
+	mdio_delay();
+	outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
+	mdio_delay();
+    }
+    /* Read the two transition, 16 data, and wire-idle bits. */
+    for (i = 19; i > 0; i--) {
+	outl(MDIO_ENB_IN, mdio_addr);
+	mdio_delay();
+	retval = (retval << 1) | ((inl(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
+	outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
+	mdio_delay();
+    }
+    return (retval>>1) & 0xffff;
+}
+
+void mdio_write(struct nic *nic, int phy_id, int location, int value)
+{
+    int i;
+    int cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
+    long mdio_addr = ioaddr + CSR9;
+
+#ifdef TULIP_DEBUG_WHERE
+    whereami("mdio_write\n");
+#endif
+
+    if (tp->chip_id == LC82C168) {
+	int i = 1000;
+	outl(cmd, ioaddr + 0xA0);
+	do
+	    if ( ! (inl(ioaddr + 0xA0) & 0x80000000))
+		break;
+	while (--i > 0);
+	return;
+    }
+
+    if (tp->chip_id == COMET) {
+	if (phy_id != 1)
+	    return;
+	if (location < 7)
+	    outl(value, ioaddr + 0xB4 + (location<<2));
+	else if (location == 17)
+	    outl(value, ioaddr + 0xD0);
+	else if (location >= 29 && location <= 31)
+	    outl(value, ioaddr + 0xD4 + ((location-29)<<2));
+	return;
+    }
+
+    /* Establish sync by sending 32 logic ones. */
+    for (i = 32; i >= 0; i--) {
+	outl(MDIO_ENB | MDIO_DATA_WRITE1, mdio_addr);
+	mdio_delay();
+	outl(MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
+	mdio_delay();
+    }
+    /* Shift the command bits out. */
+    for (i = 31; i >= 0; i--) {
+	int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0;
+	outl(MDIO_ENB | dataval, mdio_addr);
+	mdio_delay();
+	outl(MDIO_ENB | dataval | MDIO_SHIFT_CLK, mdio_addr);
+	mdio_delay();
+    }
+    /* Clear out extra bits. */
+    for (i = 2; i > 0; i--) {
+	outl(MDIO_ENB_IN, mdio_addr);
+	mdio_delay();
+	outl(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
+	mdio_delay();
+    }
+}
+
+
+/*********************************************************************/
+/* EEPROM Reading Code                                               */
+/*********************************************************************/
+/* EEPROM routines adapted from the Linux Tulip Code */
+/* Reading a serial EEPROM is a "bit" grungy, but we work our way
+   through:->.
+*/
+static int read_eeprom(unsigned long ioaddr, int location, int addr_len)
+{
+    int i;
+    unsigned short retval = 0;
+    long ee_addr = ioaddr + CSR9;
+    int read_cmd = location | EE_READ_CMD;
+
+#ifdef TULIP_DEBUG_WHERE
+    whereami("read_eeprom\n");
+#endif
+
+    outl(EE_ENB & ~EE_CS, ee_addr);
+    outl(EE_ENB, ee_addr);
+
+    /* Shift the read command bits out. */
+    for (i = 4 + addr_len; i >= 0; i--) {
+        short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+        outl(EE_ENB | dataval, ee_addr);
+        eeprom_delay();
+        outl(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
+        eeprom_delay();
+    }
+    outl(EE_ENB, ee_addr);
+
+    for (i = 16; i > 0; i--) {
+        outl(EE_ENB | EE_SHIFT_CLK, ee_addr);
+        eeprom_delay();
+        retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0);
+        outl(EE_ENB, ee_addr);
+        eeprom_delay();
+    }
+
+    /* Terminate the EEPROM access. */
+    outl(EE_ENB & ~EE_CS, ee_addr);
+    return retval;
+}
+
+
+/*********************************************************************/
+/* EEPROM Parsing Code                                               */
+/*********************************************************************/
+static void parse_eeprom(struct nic *nic)
+{
+    unsigned char *p, *ee_data = tp->eeprom;
+    int new_advertise = 0;
+    int i;
+
+#ifdef TULIP_DEBUG_WHERE
+    whereami("parse_eeprom\n");
+#endif
+
+    tp->mtable = 0;
+    /* Detect an old-style (SA only) EEPROM layout:
+       memcmp(ee_data, ee_data+16, 8). */
+    for (i = 0; i < 8; i ++)
+        if (ee_data[i] != ee_data[16+i])
+            break;
+    if (i >= 8) {
+        /* Do a fix-up based on the vendor half of the station address. */
+        for (i = 0; eeprom_fixups[i].name; i++) {
+            if (nic->node_addr[0] == eeprom_fixups[i].addr0
+                &&  nic->node_addr[1] == eeprom_fixups[i].addr1
+                &&  nic->node_addr[2] == eeprom_fixups[i].addr2) {
+                if (nic->node_addr[2] == 0xE8  &&  ee_data[0x1a] == 0x55)
+                    i++;                /* An Accton EN1207, not an outlaw Maxtech. */
+                memcpy(ee_data + 26, eeprom_fixups[i].newtable,
+                       sizeof(eeprom_fixups[i].newtable));
+#ifdef TULIP_DEBUG
+                printf("%s: Old format EEPROM on '%s' board.\n%s: Using substitute media control info.\n",
+                       tp->nic_name, eeprom_fixups[i].name, tp->nic_name);
+#endif
+                break;
+            }
+        }
+        if (eeprom_fixups[i].name == NULL) { /* No fixup found. */
+#ifdef TULIP_DEBUG
+            printf("%s: Old style EEPROM with no media selection information.\n",
+                   tp->nic_name);
+#endif
+            return;
+        }
+    }
+
+    if (ee_data[19] > 1) {
+#ifdef TULIP_DEBUG
+        printf("%s:  Multiport cards (%d ports) may not work correctly.\n", 
+               tp->nic_name, ee_data[19]);
+#endif
+    }
+
+    p = (void *)ee_data + ee_data[27];
+
+    if (ee_data[27] == 0) {             /* No valid media table. */
+#ifdef TULIP_DEBUG
+        if (tulip_debug > 1) {
+            printf("%s:  No Valid Media Table. ee_data[27] = %hhX\n", 
+                   tp->nic_name, ee_data[27]);
+        }
+#endif
+    } else if (tp->chip_id == DC21041) {
+        int media = get_u16(p);
+        int count = p[2];
+        p += 3;
+
+        printf("%s: 21041 Media table, default media %hX (%s).\n",
+               tp->nic_name, media,
+               media & 0x0800 ? "Autosense" : medianame[media & 15]);
+        for (i = 0; i < count; i++) {
+            unsigned char media_block = *p++;
+            int media_code = media_block & MEDIA_MASK;
+            if (media_block & 0x40)
+                p += 6;
+            switch(media_code) {
+            case 0: new_advertise |= 0x0020; break;
+            case 4: new_advertise |= 0x0040; break;
+            }
+            printf("%s:  21041 media #%d, %s.\n",
+                   tp->nic_name, media_code, medianame[media_code]);
+        }
+    } else {
+        unsigned char csr12dir = 0;
+        int count;
+        struct mediatable *mtable;
+        u16 media = get_u16(p);
+
+        p += 2;
+        if (tp->flags & CSR12_IN_SROM)
+            csr12dir = *p++;
+        count = *p++;
+
+        tp->mtable = mtable = (struct mediatable *)&tp->media_table_storage[0];
+
+        mtable->defaultmedia = media;
+        mtable->leafcount = count;
+        mtable->csr12dir = csr12dir;
+        mtable->has_nonmii = mtable->has_mii = mtable->has_reset = 0;
+        mtable->csr15dir = mtable->csr15val = 0;
+
+        printf("%s:  EEPROM default media type %s.\n", tp->nic_name,
+               media & 0x0800 ? "Autosense" : medianame[media & MEDIA_MASK]);
+
+        for (i = 0; i < count; i++) {
+            struct medialeaf *leaf = &mtable->mleaf[i];
+
+            if ((p[0] & 0x80) == 0) { /* 21140 Compact block. */
+                leaf->type = 0;
+                leaf->media = p[0] & 0x3f;
+                leaf->leafdata = p;
+                if ((p[2] & 0x61) == 0x01)      /* Bogus, but Znyx boards do it. */
+                    mtable->has_mii = 1;
+                p += 4;
+            } else {
+                switch(leaf->type = p[1]) {
+                case 5:
+                    mtable->has_reset = i;
+                    leaf->media = p[2] & 0x0f;
+                    break;
+                case 1: case 3:
+                    mtable->has_mii = 1;
+                    leaf->media = 11;
+                    break;
+                case 2:
+                    if ((p[2] & 0x3f) == 0) {
+                        u32 base15 = (p[2] & 0x40) ? get_u16(p + 7) : 0x0008;
+                        u16 *p1 = (u16 *)(p + (p[2] & 0x40 ? 9 : 3));
+                        mtable->csr15dir = (get_unaligned(p1 + 0)<<16) + base15;
+                        mtable->csr15val = (get_unaligned(p1 + 1)<<16) + base15;
+                    }
+                    /* Fall through. */
+                case 0: case 4:
+                    mtable->has_nonmii = 1;
+                    leaf->media = p[2] & MEDIA_MASK;
+                    switch (leaf->media) {
+                    case 0: new_advertise |= 0x0020; break;
+                    case 4: new_advertise |= 0x0040; break;
+                    case 3: new_advertise |= 0x0080; break;
+                    case 5: new_advertise |= 0x0100; break;
+                    case 6: new_advertise |= 0x0200; break;
+                    }
+                    break;
+                default:
+                    leaf->media = 19;
+                }
+                leaf->leafdata = p + 2;
+                p += (p[0] & 0x3f) + 1;
+            }
+#ifdef TULIP_DEBUG
+            if (tulip_debug > 1  &&  leaf->media == 11) {
+                unsigned char *bp = leaf->leafdata;
+                printf("%s:  MII interface PHY %d, setup/reset sequences %d/%d long, capabilities %hhX %hhX.\n",
+                       tp->nic_name, bp[0], bp[1], bp[2 + bp[1]*2],
+                       bp[5 + bp[2 + bp[1]*2]*2], bp[4 + bp[2 + bp[1]*2]*2]);
+            }
+#endif
+            printf("%s:  Index #%d - Media %s (#%d) described "
+                   "by a %s (%d) block.\n",
+                   tp->nic_name, i, medianame[leaf->media], leaf->media,
+                   leaf->type < 6 ? block_name[leaf->type] : "UNKNOWN",
+                   leaf->type);
+        }
+        if (new_advertise)
+            tp->sym_advertise = new_advertise;
+    }
+}
+
+
+/*********************************************************************/
+/* tulip_init_ring - setup the tx and rx descriptors                */
+/*********************************************************************/
+static void tulip_init_ring(struct nic *nic)
+{
+    int i;
+
+#ifdef TULIP_DEBUG_WHERE
+    whereami("tulip_init_ring\n");
+#endif
+
+    tp->cur_rx = 0;
+
+    for (i = 0; i < RX_RING_SIZE; i++) {
+	rx_ring[i].status  = cpu_to_le32(0x80000000);
+	rx_ring[i].length  = cpu_to_le32(BUFLEN);
+	rx_ring[i].buffer1 = virt_to_le32desc(&rxb[i * BUFLEN]);
+	rx_ring[i].buffer2 = virt_to_le32desc(&rx_ring[i+1]);
+    }
+    /* Mark the last entry as wrapping the ring. */
+    rx_ring[i-1].length    = cpu_to_le32(DESC_RING_WRAP | BUFLEN);
+    rx_ring[i-1].buffer2   = virt_to_le32desc(&rx_ring[0]);
+
+    /* We only use 1 transmit buffer, but we use 2 descriptors so
+       transmit engines have somewhere to point to if they feel the need */
+
+    tx_ring[0].status  = 0x00000000;
+    tx_ring[0].buffer1 = virt_to_le32desc(&txb[0]);
+    tx_ring[0].buffer2 = virt_to_le32desc(&tx_ring[1]);
+
+    /* this descriptor should never get used, since it will never be owned
+       by the machine (status will always == 0) */
+    tx_ring[1].status  = 0x00000000;
+    tx_ring[1].buffer1 = virt_to_le32desc(&txb[0]);
+    tx_ring[1].buffer2 = virt_to_le32desc(&tx_ring[0]);
+
+    /* Mark the last entry as wrapping the ring, though this should never happen */
+    tx_ring[1].length  = cpu_to_le32(DESC_RING_WRAP | BUFLEN);
+}
+
+/*********************************************************************/
+/* eth_reset - Reset adapter                                         */
+/*********************************************************************/
+static void tulip_reset(struct nic *nic)
+{
+    int i;
+    unsigned long to;
+    u32 addr_low, addr_high;
+
+#ifdef TULIP_DEBUG_WHERE
+    whereami("tulip_reset\n");
+#endif
+
+    /* Stop Tx and RX */
+    outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
+
+    /* On some chip revs we must set the MII/SYM port before the reset!? */
+    if (tp->mii_cnt  ||  (tp->mtable  &&  tp->mtable->has_mii)) {
+	outl(0x814C0000, ioaddr + CSR6);
+    }
+  
+    /* Reset the chip, holding bit 0 set at least 50 PCI cycles. */
+    outl(0x00000001, ioaddr + CSR0);
+    tulip_wait(1);
+
+    /* turn off reset and set cache align=16lword, burst=unlimit */
+    outl(tp->csr0, ioaddr + CSR0);
+
+    /*  Wait the specified 50 PCI cycles after a reset */
+    tulip_wait(1);
+
+    /* set up transmit and receive descriptors */
+    tulip_init_ring(nic);
+
+    if (tp->chip_id == PNIC2) {
+        u32 addr_high = (nic->node_addr[1]<<8) + (nic->node_addr[0]<<0);
+        /* This address setting does not appear to impact chip operation?? */
+        outl((nic->node_addr[5]<<8) + nic->node_addr[4] +
+             (nic->node_addr[3]<<24) + (nic->node_addr[2]<<16),
+             ioaddr + 0xB0);
+        outl(addr_high + (addr_high<<16), ioaddr + 0xB8);
+    }
+
+    /* MC_HASH_ONLY boards don't support setup packets */
+    if (tp->flags & MC_HASH_ONLY) {
+        u32 addr_low = cpu_to_le32(get_unaligned((u32 *)nic->node_addr));
+        u32 addr_high = cpu_to_le32(get_unaligned((u16 *)(nic->node_addr+4)));
+
+	/* clear multicast hash filters and setup MAC address filters */
+	if (tp->flags & IS_ASIX) {
+            outl(0, ioaddr + CSR13);
+            outl(addr_low,  ioaddr + CSR14);
+            outl(1, ioaddr + CSR13);
+            outl(addr_high, ioaddr + CSR14);
+	    outl(2, ioaddr + CSR13);
+	    outl(0, ioaddr + CSR14);
+	    outl(3, ioaddr + CSR13);
+	    outl(0, ioaddr + CSR14);
+	} else if (tp->chip_id == COMET) {
+            outl(addr_low,  ioaddr + 0xA4);
+            outl(addr_high, ioaddr + 0xA8);
+            outl(0, ioaddr + 0xAC);
+            outl(0, ioaddr + 0xB0);
+	}
+    } else {
+	/* for other boards we send a setup packet to initialize
+	   the filters */
+	u32 tx_flags = 0x08000000 | 192;
+
+	/* construct perfect filter frame with mac address as first match
+	   and broadcast address for all others */
+	for (i=0; i<192; i++) 
+	    txb[i] = 0xFF;
+	txb[0] = nic->node_addr[0];
+	txb[1] = nic->node_addr[1];
+	txb[4] = nic->node_addr[2];
+	txb[5] = nic->node_addr[3];
+	txb[8] = nic->node_addr[4];
+	txb[9] = nic->node_addr[5];
+
+	tx_ring[0].length  = cpu_to_le32(tx_flags);
+	tx_ring[0].buffer1 = virt_to_le32desc(&txb[0]);
+	tx_ring[0].status  = cpu_to_le32(0x80000000);
+    }
+
+    /* Point to rx and tx descriptors */
+    outl((unsigned long)&rx_ring[0], ioaddr + CSR3);
+    outl((unsigned long)&tx_ring[0], ioaddr + CSR4);
+
+    init_media(nic);
+
+    /* set the chip's operating mode (but don't turn on xmit and recv yet) */
+    outl((tp->csr6 & ~0x00002002), ioaddr + CSR6);
+
+    /* send setup packet for cards that support it */
+    if (!(tp->flags & MC_HASH_ONLY)) {
+	/* enable transmit  wait for completion */
+	outl(tp->csr6 | 0x00002000, ioaddr + CSR6);
+	/* immediate transmit demand */
+	outl(0, ioaddr + CSR1);
+
+	to = currticks() + TX_TIME_OUT;
+	while ((tx_ring[0].status & 0x80000000) && (currticks() < to))
+	    /* wait */ ;
+
+	if (currticks() >= to) {
+	    printf ("%s: TX Setup Timeout.\n", tp->nic_name);
+	}
+    }
+
+    if (tp->chip_id == LC82C168)
+	tulip_check_duplex(nic);
+
+    /* enable transmit and receive */
+    outl(tp->csr6 | 0x00002002, ioaddr + CSR6);
+}
+
+
+/*********************************************************************/
+/* eth_transmit - Transmit a frame                                   */
+/*********************************************************************/
+static void tulip_transmit(struct nic *nic, const char *d, unsigned int t,
+                           unsigned int s, const char *p)
+{
+    u16 nstype;
+    u32 to;
+    u32 csr6 = inl(ioaddr + CSR6);
+
+#ifdef TULIP_DEBUG_WHERE    
+    whereami("tulip_transmit\n");
+#endif
+
+    /* Disable Tx */
+    outl(csr6 & ~0x00002000, ioaddr + CSR6);
+
+    memcpy(txb, d, ETH_ALEN);
+    memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);
+    nstype = htons((u16) t);
+    memcpy(txb + 2 * ETH_ALEN, (u8 *)&nstype, 2);
+    memcpy(txb + ETH_HLEN, p, s);
+
+    s += ETH_HLEN;
+    s &= 0x0FFF;
+
+    /* pad to minimum packet size */
+    while (s < ETH_ZLEN)  
+        txb[s++] = '\0';
+
+#ifdef TULIP_DEBUG
+    if (tulip_debug > 1)
+	printf("%s: sending %d bytes ethtype %hX\n", tp->nic_name, s, t);
+#endif
+        
+    /* setup the transmit descriptor */
+    /* 0x60000000 = no interrupt on completion */
+    tx_ring[0].length = cpu_to_le32(0x60000000 | s);
+    tx_ring[0].status = cpu_to_le32(0x80000000);
+
+    /* Point to transmit descriptor */
+    outl((u32)&tx_ring[0], ioaddr + CSR4);
+
+    /* Enable Tx */
+    outl(csr6 | 0x00002000, ioaddr + CSR6);
+    /* immediate transmit demand */
+    outl(0, ioaddr + CSR1);
+
+    to = currticks() + TX_TIME_OUT;
+    while ((tx_ring[0].status & 0x80000000) && (currticks() < to))
+        /* wait */ ;
+
+    if (currticks() >= to) {
+        printf ("TX Timeout!\n");
+    }
+
+    /* Disable Tx */
+    outl(csr6 & ~0x00002000, ioaddr + CSR6);
+}
+
+/*********************************************************************/
+/* eth_poll - Wait for a frame                                       */
+/*********************************************************************/
+static int tulip_poll(struct nic *nic)
+{
+
+#ifdef TULIP_DEBUG_WHERE
+    whereami("tulip_poll\n");
+#endif
+
+    /* no packet waiting. packet still owned by NIC */
+    if (rx_ring[tp->cur_rx].status & 0x80000000)
+        return 0;
+
+#ifdef TULIP_DEBUG_WHERE
+    whereami("tulip_poll got one\n");
+#endif
+
+    nic->packetlen = (rx_ring[tp->cur_rx].status & 0x3FFF0000) >> 16;
+
+    /* if we get a corrupted packet. throw it away and move on */
+    if (rx_ring[tp->cur_rx].status & 0x00008000) {
+	/* return the descriptor and buffer to receive ring */
+        rx_ring[tp->cur_rx].status = 0x80000000;
+	tp->cur_rx = (++tp->cur_rx) % RX_RING_SIZE;
+        return 0;
+    }
+
+    /* copy packet to working buffer */
+    memcpy(nic->packet, rxb + tp->cur_rx * BUFLEN, nic->packetlen);
+
+    /* return the descriptor and buffer to receive ring */
+    rx_ring[tp->cur_rx].status = 0x80000000;
+    tp->cur_rx = (++tp->cur_rx) % RX_RING_SIZE;
+
+    return 1;
+}
+
+/*********************************************************************/
+/* eth_disable - Disable the interface                               */
+/*********************************************************************/
+static void tulip_disable(struct nic *nic)
+{
+
+#ifdef TULIP_DEBUG_WHERE
+    whereami("tulip_disable\n");
+#endif
+
+    /* disable interrupts */
+    outl(0x00000000, ioaddr + CSR7);
+
+    /* Stop the chip's Tx and Rx processes. */
+    outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
+
+    /* Clear the missed-packet counter. */
+    (volatile unsigned long)inl(ioaddr + CSR8);
+}
+
+/*********************************************************************/
+/* eth_probe - Look for an adapter                                   */
+/*********************************************************************/
+struct nic *tulip_probe(struct nic *nic, unsigned short *io_addrs,
+                        struct pci_device *pci)
+{
+    u32 i, l1, l2;
+    u8  chip_rev;
+    u8 ee_data[EEPROM_SIZE];
+    unsigned short sum;
+    int chip_idx;
+    static unsigned char last_phys_addr[ETH_ALEN] = {0x00, 'L', 'i', 'n', 'u', 'x'};
+
+    if (io_addrs == 0 || *io_addrs == 0)
+        return 0;
+
+    ioaddr         = *io_addrs;
+
+    /* point to private storage */
+    tp = &tpx;
+
+    tp->vendor_id  = pci->vendor;
+    tp->dev_id     = pci->dev_id;
+    tp->nic_name   = pci->name;
+
+    tp->if_port = 0;
+    tp->default_port = 0;
+
+    adjust_pci_device(pci);
+
+    /* disable interrupts */
+    outl(0x00000000, ioaddr + CSR7);
+
+    /* Stop the chip's Tx and Rx processes. */
+    outl(inl(ioaddr + CSR6) & ~0x00002002, ioaddr + CSR6);
+
+    /* Clear the missed-packet counter. */
+    (volatile unsigned long)inl(ioaddr + CSR8);
+
+    printf("\n");                /* so we start on a fresh line */
+#ifdef TULIP_DEBUG_WHERE
+    whereami("tulip_probe\n");
+#endif
+
+#ifdef TULIP_DEBUG
+    if (tulip_debug > 1)
+	printf ("%s: Looking for Tulip Chip: Vendor=%hX  Device=%hX\n", tp->nic_name,
+		tp->vendor_id, tp->dev_id);
+#endif
+
+    /* Figure out which chip we're dealing with */
+    i = 0;
+    chip_idx = -1;
+  
+    while (pci_id_tbl[i].name) {
+        if ( (((u32) tp->dev_id << 16) | tp->vendor_id) == 
+             (pci_id_tbl[i].id.pci & pci_id_tbl[i].id.pci_mask) ) {
+            chip_idx = pci_id_tbl[i].drv_flags;
+            break;
+        }
+        i++;
+    }
+
+    if (chip_idx == -1) {
+        printf ("%s: Unknown Tulip Chip: Vendor=%hX  Device=%hX\n", tp->nic_name,
+                tp->vendor_id, tp->dev_id);
+        return 0;
+    }
+
+    tp->pci_id_idx = i;
+    tp->flags = tulip_tbl[chip_idx].flags;
+
+#ifdef TULIP_DEBUG
+    if (tulip_debug > 1) {
+	printf ("%s: tp->pci_id_idx == %d,  name == %s\n", tp->nic_name, 
+		tp->pci_id_idx, pci_id_tbl[tp->pci_id_idx].name);
+	printf ("%s: chip_idx == %d, name == %s\n", tp->nic_name, chip_idx, 
+		tulip_tbl[chip_idx].chip_name);
+    }
+#endif
+  
+    /* Bring the 21041/21143 out of sleep mode.
+       Caution: Snooze mode does not work with some boards! */
+    if (tp->flags & HAS_PWRDWN)
+        pcibios_write_config_dword(pci->bus, pci->devfn, 0x40, 0x00000000);
+
+    if (inl(ioaddr + CSR5) == 0xFFFFFFFF) {
+        printf("%s: The Tulip chip at %X is not functioning.\n",
+               tp->nic_name, ioaddr);
+        return 0;
+    }
+   
+    pcibios_read_config_byte(pci->bus, pci->devfn, PCI_REVISION, &chip_rev);
+
+    printf("%s: [chip: %s] rev %d at %hX\n", tp->nic_name,
+           tulip_tbl[chip_idx].chip_name, chip_rev, ioaddr);
+    printf("%s: Vendor=%hX  Device=%hX", tp->nic_name, tp->vendor_id, tp->dev_id);
+
+    if (chip_idx == DC21041  &&  inl(ioaddr + CSR9) & 0x8000) {
+        printf(" 21040 compatible mode.");
+        chip_idx = DC21040;
+    }
+
+    printf("\n");
+
+    /* The SROM/EEPROM interface varies dramatically. */
+    sum = 0;
+    if (chip_idx == DC21040) {
+        outl(0, ioaddr + CSR9);         /* Reset the pointer with a dummy write. */
+        for (i = 0; i < ETH_ALEN; i++) {
+            int value, boguscnt = 100000;
+            do
+                value = inl(ioaddr + CSR9);
+            while (value < 0  && --boguscnt > 0);
+            nic->node_addr[i] = value;
+            sum += value & 0xff;
+        }
+    } else if (chip_idx == LC82C168) {
+        for (i = 0; i < 3; i++) {
+            int value, boguscnt = 100000;
+            outl(0x600 | i, ioaddr + 0x98);
+            do
+                value = inl(ioaddr + CSR9);
+            while (value < 0  && --boguscnt > 0);
+            put_unaligned(le16_to_cpu(value), ((u16*)nic->node_addr) + i);
+            sum += value & 0xffff;
+        }
+    } else if (chip_idx == COMET) {
+        /* No need to read the EEPROM. */
+        put_unaligned(inl(ioaddr + 0xA4), (u32 *)nic->node_addr);
+        put_unaligned(inl(ioaddr + 0xA8), (u16 *)(nic->node_addr + 4));
+        for (i = 0; i < ETH_ALEN; i ++)
+            sum += nic->node_addr[i];
+    } else {
+        /* A serial EEPROM interface, we read now and sort it out later. */
+        int sa_offset = 0;
+        int ee_addr_size = read_eeprom(ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;
+
+        for (i = 0; i < sizeof(ee_data)/2; i++)
+            ((u16 *)ee_data)[i] =
+                le16_to_cpu(read_eeprom(ioaddr, i, ee_addr_size));
+
+        /* DEC now has a specification (see Notes) but early board makers
+           just put the address in the first EEPROM locations. */
+        /* This does  memcmp(eedata, eedata+16, 8) */
+        for (i = 0; i < 8; i ++)
+            if (ee_data[i] != ee_data[16+i])
+                sa_offset = 20;
+        if (ee_data[0] == 0xff  &&  ee_data[1] == 0xff &&  ee_data[2] == 0) {
+            sa_offset = 2;              /* Grrr, damn Matrox boards. */
+        }
+        for (i = 0; i < ETH_ALEN; i ++) {
+            nic->node_addr[i] = ee_data[i + sa_offset];
+            sum += ee_data[i + sa_offset];
+        }
+    }
+    /* Lite-On boards have the address byte-swapped. */
+    if ((nic->node_addr[0] == 0xA0  ||  nic->node_addr[0] == 0xC0)
+        &&  nic->node_addr[1] == 0x00)
+        for (i = 0; i < ETH_ALEN; i+=2) {
+            char tmp = nic->node_addr[i];
+            nic->node_addr[i] = nic->node_addr[i+1];
+            nic->node_addr[i+1] = tmp;
+        }
+
+    if (sum == 0  || sum == ETH_ALEN*0xff) {
+        printf("%s: EEPROM not present!\n", tp->nic_name);
+        for (i = 0; i < ETH_ALEN-1; i++)
+            nic->node_addr[i] = last_phys_addr[i];
+        nic->node_addr[i] = last_phys_addr[i] + 1;
+    }
+
+    for (i = 0; i < ETH_ALEN; i++)
+        last_phys_addr[i] = nic->node_addr[i];
+
+    printf("%s: %! at ioaddr %hX\n", tp->nic_name, nic->node_addr, ioaddr);
+
+    tp->chip_id = chip_idx;
+    tp->revision = chip_rev;
+    tp->csr0 = csr0;
+
+    /* BugFixes: The 21143-TD hangs with PCI Write-and-Invalidate cycles.
+       And the ASIX must have a burst limit or horrible things happen. */
+    if (chip_idx == DC21143  &&  chip_rev == 65)
+        tp->csr0 &= ~0x01000000;
+    else if (tp->flags & IS_ASIX)
+        tp->csr0 |= 0x2000;
+
+    if (media_cap[tp->default_port] & MediaIsMII) {
+        u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200 };
+        tp->mii_advertise = media2advert[tp->default_port - 9];
+        tp->mii_advertise |= (tp->flags & HAS_8023X); /* Matching bits! */
+    }
+
+    /* This is logically part of the probe routine, but too complex
+       to write inline. */
+    if (tp->flags & HAS_MEDIA_TABLE) {
+        memcpy(tp->eeprom, ee_data, sizeof(tp->eeprom));
+        parse_eeprom(nic);
+    }
+
+    start_link(nic);
+
+    /* reset the device and make ready for tx and rx of packets */
+    tulip_reset(nic);
+
+    nic->reset    = tulip_reset;
+    nic->poll     = tulip_poll;
+    nic->transmit = tulip_transmit;
+    nic->disable  = tulip_disable;
+
+    /* give the board a chance to reset before returning */
+    tulip_wait(4*TICKS_PER_SEC);
+
+    return nic;
+}
+
+static void start_link(struct nic *nic)
+{
+    int i;
+
+#ifdef TULIP_DEBUG_WHERE
+    whereami("start_link\n");
+#endif
+
+    if ((tp->flags & ALWAYS_CHECK_MII) ||
+        (tp->mtable  &&  tp->mtable->has_mii) ||
+        ( ! tp->mtable  &&  (tp->flags & HAS_MII))) {
+        unsigned int phy, phy_idx;
+        if (tp->mtable  &&  tp->mtable->has_mii) {
+            for (i = 0; i < tp->mtable->leafcount; i++)
+                if (tp->mtable->mleaf[i].media == 11) {
+                    tp->cur_index = i;
+                    tp->saved_if_port = tp->if_port;
+                    select_media(nic, 2);
+                    tp->if_port = tp->saved_if_port;
+                    break;
+                }
+        }
+
+        /* Find the connected MII xcvrs. */
+        for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(tp->phys);
+             phy++) {
+            int mii_status = mdio_read(nic, phy, 1);
+            if ((mii_status & 0x8301) == 0x8001 ||
+                ((mii_status & 0x8000) == 0  && (mii_status & 0x7800) != 0)) {
+                int mii_reg0 = mdio_read(nic, phy, 0);
+                int mii_advert = mdio_read(nic, phy, 4);
+                int to_advert;
+
+                if (tp->mii_advertise)
+                    to_advert = tp->mii_advertise;
+                else if (tp->advertising[phy_idx])
+                    to_advert = tp->advertising[phy_idx];
+                else                    /* Leave unchanged. */
+                    tp->mii_advertise = to_advert = mii_advert;
+
+                tp->phys[phy_idx++] = phy;
+                printf("%s:  MII transceiver %d config %hX status %hX advertising %hX.\n",
+                       tp->nic_name, phy, mii_reg0, mii_status, mii_advert);
+                                /* Fixup for DLink with miswired PHY. */
+                if (mii_advert != to_advert) {
+                    printf("%s:  Advertising %hX on PHY %d previously advertising %hX.\n",
+                           tp->nic_name, to_advert, phy, mii_advert);
+                    mdio_write(nic, phy, 4, to_advert);
+                }
+                                /* Enable autonegotiation: some boards default to off. */
+                mdio_write(nic, phy, 0, mii_reg0 |
+                           (tp->full_duplex ? 0x1100 : 0x1000) |
+                           (media_cap[tp->default_port]&MediaIs100 ? 0x2000:0));
+            }
+        }
+        tp->mii_cnt = phy_idx;
+        if (tp->mtable  &&  tp->mtable->has_mii  &&  phy_idx == 0) {
+            printf("%s: ***WARNING***: No MII transceiver found!\n",
+                   tp->nic_name);
+            tp->phys[0] = 1;
+        }
+    }
+
+    /* Reset the xcvr interface and turn on heartbeat. */
+    switch (tp->chip_id) {
+    case DC21040:
+        outl(0x00000000, ioaddr + CSR13);
+        outl(0x00000004, ioaddr + CSR13);
+        break;
+    case DC21041:
+        /* This is nway_start(). */
+        if (tp->sym_advertise == 0)
+            tp->sym_advertise = 0x0061;
+        outl(0x00000000, ioaddr + CSR13);
+        outl(0xFFFFFFFF, ioaddr + CSR14);
+        outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */
+        outl(inl(ioaddr + CSR6) | 0x0200, ioaddr + CSR6);
+        outl(0x0000EF01, ioaddr + CSR13);
+        break;
+    case DC21140: default:
+        if (tp->mtable)
+            outl(tp->mtable->csr12dir | 0x100, ioaddr + CSR12);
+        break;
+    case DC21142:
+    case PNIC2:
+        if (tp->mii_cnt  ||  media_cap[tp->if_port] & MediaIsMII) {
+            outl(0x82020000, ioaddr + CSR6);
+            outl(0x0000, ioaddr + CSR13);
+            outl(0x0000, ioaddr + CSR14);
+            outl(0x820E0000, ioaddr + CSR6);
+        } else
+            nway_start(nic);
+        break;
+    case LC82C168:
+        if ( ! tp->mii_cnt) {
+            tp->nway = 1;
+            tp->nwayset = 0;
+            outl(0x00420000, ioaddr + CSR6);
+            outl(0x30, ioaddr + CSR12);
+            outl(0x0001F078, ioaddr + 0xB8);
+            outl(0x0201F078, ioaddr + 0xB8); /* Turn on autonegotiation. */
+        }
+        break;
+    case MX98713: case COMPEX9881:
+        outl(0x00000000, ioaddr + CSR6);
+        outl(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */
+        outl(0x00000001, ioaddr + CSR13);
+        break;
+    case MX98715: case MX98725:
+        outl(0x01a80000, ioaddr + CSR6);
+        outl(0xFFFFFFFF, ioaddr + CSR14);
+        outl(0x00001000, ioaddr + CSR12);
+        break;
+    case COMET:
+        /* No initialization necessary. */
+        break;
+    }
+}
+
+static void nway_start(struct nic *nic)
+{
+    int csr14 = ((tp->sym_advertise & 0x0780) << 9)  |
+        ((tp->sym_advertise&0x0020)<<1) | 0xffbf;
+
+#ifdef TULIP_DEBUG_WHERE
+    whereami("nway_start\n");
+#endif
+
+    tp->if_port = 0;
+    tp->nway = tp->mediasense = 1;
+    tp->nwayset = tp->lpar = 0;
+    if (tp->chip_id == PNIC2) {
+        tp->csr6 = 0x01000000 | (tp->sym_advertise & 0x0040 ? 0x0200 : 0);
+        return;
+    }
+#ifdef TULIP_DEBUG
+    if (tulip_debug > 1)
+        printf("%s: Restarting internal NWay autonegotiation, %X.\n",
+               tp->nic_name, csr14);
+#endif
+    outl(0x0001, ioaddr + CSR13);
+    outl(csr14, ioaddr + CSR14);
+    tp->csr6 = 0x82420000 | (tp->sym_advertise & 0x0040 ? 0x0200 : 0);
+    outl(tp->csr6, ioaddr + CSR6);
+    if (tp->mtable  &&  tp->mtable->csr15dir) {
+        outl(tp->mtable->csr15dir, ioaddr + CSR15);
+        outl(tp->mtable->csr15val, ioaddr + CSR15);
+    } else if (tp->chip_id != PNIC2)
+        outw(0x0008, ioaddr + CSR15);
+    if (tp->chip_id == DC21041)                 /* Trigger NWAY. */
+        outl(0xEF01, ioaddr + CSR12);
+    else
+        outl(0x1301, ioaddr + CSR12);
+}
+
+static void init_media(struct nic *nic)
+{
+    int i;
+
+#ifdef TULIP_DEBUG_WHERE
+    whereami("init_media\n");
+#endif
+
+    tp->saved_if_port = tp->if_port;
+    if (tp->if_port == 0)
+        tp->if_port = tp->default_port;
+
+    /* Allow selecting a default media. */
+    i = 0;
+    if (tp->mtable == NULL)
+        goto media_picked;
+    if (tp->if_port) {
+        int looking_for = media_cap[tp->if_port] & MediaIsMII ? 11 :
+            (tp->if_port == 12 ? 0 : tp->if_port);
+        for (i = 0; i < tp->mtable->leafcount; i++)
+            if (tp->mtable->mleaf[i].media == looking_for) {
+                printf("%s: Using user-specified media %s.\n",
+                       tp->nic_name, medianame[tp->if_port]);
+                goto media_picked;
+            }
+    }
+    if ((tp->mtable->defaultmedia & 0x0800) == 0) {
+        int looking_for = tp->mtable->defaultmedia & 15;
+        for (i = 0; i < tp->mtable->leafcount; i++)
+            if (tp->mtable->mleaf[i].media == looking_for) {
+                printf("%s: Using EEPROM-set media %s.\n",
+                       tp->nic_name, medianame[looking_for]);
+                goto media_picked;
+            }
+    }
+    /* Start sensing first non-full-duplex media. */
+    for (i = tp->mtable->leafcount - 1;
+         (media_cap[tp->mtable->mleaf[i].media] & MediaAlwaysFD) && i > 0; i--)
+        ;
+ media_picked:
+
+    tp->csr6 = 0;
+    tp->cur_index = i;
+    tp->nwayset = 0;
+
+    if (tp->if_port) {
+        if (tp->chip_id == DC21143  &&  media_cap[tp->if_port] & MediaIsMII) {
+            /* We must reset the media CSRs when we force-select MII mode. */
+            outl(0x0000, ioaddr + CSR13);
+            outl(0x0000, ioaddr + CSR14);
+            outl(0x0008, ioaddr + CSR15);
+        }
+        select_media(nic, 1);
+        return;
+    }
+    switch(tp->chip_id) {
+    case DC21041:
+        /* tp->nway = 1;*/
+        nway_start(nic);
+        break;
+    case DC21142:
+        if (tp->mii_cnt) {
+            select_media(nic, 1);
+#ifdef TULIP_DEBUG
+            if (tulip_debug > 1)
+                printf("%s: Using MII transceiver %d, status %hX.\n",
+                       tp->nic_name, tp->phys[0], mdio_read(nic, tp->phys[0], 1));
+#endif
+            outl(0x82020000, ioaddr + CSR6);
+            tp->csr6 = 0x820E0000;
+            tp->if_port = 11;
+            outl(0x0000, ioaddr + CSR13);
+            outl(0x0000, ioaddr + CSR14);
+        } else
+            nway_start(nic);
+        break;
+    case PNIC2:
+        nway_start(nic);
+        break;
+    case LC82C168:
+        if (tp->mii_cnt) {
+            tp->if_port = 11;
+            tp->csr6 = 0x814C0000 | (tp->full_duplex ? 0x0200 : 0);
+            outl(0x0001, ioaddr + CSR15);
+        } else if (inl(ioaddr + CSR5) & TPLnkPass)
+            pnic_do_nway(nic);
+        else {
+            /* Start with 10mbps to do autonegotiation. */
+            outl(0x32, ioaddr + CSR12);
+            tp->csr6 = 0x00420000;
+            outl(0x0001B078, ioaddr + 0xB8);
+            outl(0x0201B078, ioaddr + 0xB8);
+        }
+        break;
+    case MX98713: case COMPEX9881:
+        tp->if_port = 0;
+        tp->csr6 = 0x01880000 | (tp->full_duplex ? 0x0200 : 0);
+        outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80);
+        break;
+    case MX98715: case MX98725:
+        /* Provided by BOLO, Macronix - 12/10/1998. */
+        tp->if_port = 0;
+        tp->csr6 = 0x01a80200;
+        outl(0x0f370000 | inw(ioaddr + 0x80), ioaddr + 0x80);
+        outl(0x11000 | inw(ioaddr + 0xa0), ioaddr + 0xa0);
+        break;
+    case COMET:
+        tp->if_port = 0;
+	tp->csr6 = 0x00040000;
+        break;
+    case AX88140: case AX88141:
+        tp->csr6 = tp->mii_cnt ? 0x00040100 : 0x00000100;
+        break;
+    default:
+        select_media(nic, 1);
+    }
+}
+
+static void pnic_do_nway(struct nic *nic)
+{
+    u32 phy_reg = inl(ioaddr + 0xB8);
+    u32 new_csr6 = tp->csr6 & ~0x40C40200;
+
+#ifdef TULIP_DEBUG_WHERE
+    whereami("pnic_do_nway\n");
+#endif
+
+    if (phy_reg & 0x78000000) { /* Ignore baseT4 */
+        if (phy_reg & 0x20000000)               tp->if_port = 5;
+        else if (phy_reg & 0x40000000)  tp->if_port = 3;
+        else if (phy_reg & 0x10000000)  tp->if_port = 4;
+        else if (phy_reg & 0x08000000)  tp->if_port = 0;
+        tp->nwayset = 1;
+        new_csr6 = (tp->if_port & 1) ? 0x01860000 : 0x00420000;
+        outl(0x32 | (tp->if_port & 1), ioaddr + CSR12);
+        if (tp->if_port & 1)
+            outl(0x1F868, ioaddr + 0xB8);
+        if (phy_reg & 0x30000000) {
+            tp->full_duplex = 1;
+            new_csr6 |= 0x00000200;
+        }
+#ifdef TULIP_DEBUG
+        if (tulip_debug > 1)
+            printf("%s: PNIC autonegotiated status %X, %s.\n",
+                   tp->nic_name, phy_reg, medianame[tp->if_port]);
+#endif
+        if (tp->csr6 != new_csr6) {
+            tp->csr6 = new_csr6;
+            outl(tp->csr6 | 0x0002, ioaddr + CSR6);     /* Restart Tx */
+            outl(tp->csr6 | 0x2002, ioaddr + CSR6);
+        }
+    }
+}
+
+/* Set up the transceiver control registers for the selected media type. */
+static void select_media(struct nic *nic, int startup)
+{
+    struct mediatable *mtable = tp->mtable;
+    u32 new_csr6;
+    int i;
+
+#ifdef TULIP_DEBUG_WHERE
+    whereami("select_media\n");
+#endif
+
+    if (mtable) {
+        struct medialeaf *mleaf = &mtable->mleaf[tp->cur_index];
+        unsigned char *p = mleaf->leafdata;
+        switch (mleaf->type) {
+        case 0:                                 /* 21140 non-MII xcvr. */
+#ifdef TULIP_DEBUG
+            if (tulip_debug > 1)
+                printf("%s: Using a 21140 non-MII transceiver"
+                       " with control setting %hhX.\n",
+                       tp->nic_name, p[1]);
+#endif
+            tp->if_port = p[0];
+            if (startup)
+                outl(mtable->csr12dir | 0x100, ioaddr + CSR12);
+            outl(p[1], ioaddr + CSR12);
+            new_csr6 = 0x02000000 | ((p[2] & 0x71) << 18);
+            break;
+        case 2: case 4: {
+            u16 setup[5];
+            u32 csr13val, csr14val, csr15dir, csr15val;
+            for (i = 0; i < 5; i++)
+                setup[i] = get_u16(&p[i*2 + 1]);
+
+            tp->if_port = p[0] & 15;
+            if (media_cap[tp->if_port] & MediaAlwaysFD)
+                tp->full_duplex = 1;
+
+            if (startup && mtable->has_reset) {
+                struct medialeaf *rleaf = &mtable->mleaf[mtable->has_reset];
+                unsigned char *rst = rleaf->leafdata;
+#ifdef TULIP_DEBUG
+                if (tulip_debug > 1)
+                    printf("%s: Resetting the transceiver.\n",
+                           tp->nic_name);
+#endif
+                for (i = 0; i < rst[0]; i++)
+                    outl(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15);
+            }
+#ifdef TULIP_DEBUG
+            if (tulip_debug > 1)
+                printf("%s: 21143 non-MII %s transceiver control "
+                       "%hX/%hX.\n",
+                       tp->nic_name, medianame[tp->if_port], setup[0], setup[1]);
+#endif
+            if (p[0] & 0x40) {  /* SIA (CSR13-15) setup values are provided. */
+                csr13val = setup[0];
+                csr14val = setup[1];
+                csr15dir = (setup[3]<<16) | setup[2];
+                csr15val = (setup[4]<<16) | setup[2];
+                outl(0, ioaddr + CSR13);
+                outl(csr14val, ioaddr + CSR14);
+                outl(csr15dir, ioaddr + CSR15); /* Direction */
+                outl(csr15val, ioaddr + CSR15); /* Data */
+                outl(csr13val, ioaddr + CSR13);
+            } else {
+                csr13val = 1;
+                csr14val = 0x0003FF7F;
+                csr15dir = (setup[0]<<16) | 0x0008;
+                csr15val = (setup[1]<<16) | 0x0008;
+                if (tp->if_port <= 4)
+                    csr14val = t21142_csr14[tp->if_port];
+                if (startup) {
+                    outl(0, ioaddr + CSR13);
+                    outl(csr14val, ioaddr + CSR14);
+                }
+                outl(csr15dir, ioaddr + CSR15); /* Direction */
+                outl(csr15val, ioaddr + CSR15); /* Data */
+                if (startup) outl(csr13val, ioaddr + CSR13);
+            }
+#ifdef TULIP_DEBUG
+            if (tulip_debug > 1)
+                printf("%s:  Setting CSR15 to %X/%X.\n",
+                       tp->nic_name, csr15dir, csr15val);
+#endif
+            if (mleaf->type == 4)
+                new_csr6 = 0x82020000 | ((setup[2] & 0x71) << 18);
+            else
+                new_csr6 = 0x82420000;
+            break;
+        }
+        case 1: case 3: {
+            int phy_num = p[0];
+            int init_length = p[1];
+            u16 *misc_info;
+
+            tp->if_port = 11;
+            new_csr6 = 0x020E0000;
+            if (mleaf->type == 3) {     /* 21142 */
+                u16 *init_sequence = (u16*)(p+2);
+                u16 *reset_sequence = &((u16*)(p+3))[init_length];
+                int reset_length = p[2 + init_length*2];
+                misc_info = reset_sequence + reset_length;
+                if (startup)
+                    for (i = 0; i < reset_length; i++)
+                        outl(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15);
+                for (i = 0; i < init_length; i++)
+                    outl(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15);
+            } else {
+                u8 *init_sequence = p + 2;
+                u8 *reset_sequence = p + 3 + init_length;
+                int reset_length = p[2 + init_length];
+                misc_info = (u16*)(reset_sequence + reset_length);
+                if (startup) {
+                    outl(mtable->csr12dir | 0x100, ioaddr + CSR12);
+                    for (i = 0; i < reset_length; i++)
+                        outl(reset_sequence[i], ioaddr + CSR12);
+                }
+                for (i = 0; i < init_length; i++)
+                    outl(init_sequence[i], ioaddr + CSR12);
+            }
+            tp->advertising[phy_num] = get_u16(&misc_info[1]) | 1;
+            if (startup < 2) {
+                if (tp->mii_advertise == 0)
+                    tp->mii_advertise = tp->advertising[phy_num];
+#ifdef TULIP_DEBUG
+                if (tulip_debug > 1)
+                    printf("%s:  Advertising %hX on MII %d.\n",
+                           tp->nic_name, tp->mii_advertise, tp->phys[phy_num]);
+#endif
+                mdio_write(nic, tp->phys[phy_num], 4, tp->mii_advertise);
+            }
+            break;
+        }
+        default:
+            printf("%s:  Invalid media table selection %d.\n",
+                   tp->nic_name, mleaf->type);
+            new_csr6 = 0x020E0000;
+        }
+#ifdef TULIP_DEBUG
+        if (tulip_debug > 1)
+            printf("%s: Using media type %s, CSR12 is %hhX.\n",
+                   tp->nic_name, medianame[tp->if_port],
+                   inl(ioaddr + CSR12) & 0xff);
+#endif
+    } else if (tp->chip_id == DC21041) {
+        int port = tp->if_port <= 4 ? tp->if_port : 0;
+#ifdef TULIP_DEBUG
+        if (tulip_debug > 1)
+            printf("%s: 21041 using media %s, CSR12 is %hX.\n",
+                   tp->nic_name, medianame[port == 3 ? 12: port],
+                   inl(ioaddr + CSR12));
+#endif
+        outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */
+        outl(t21041_csr14[port], ioaddr + CSR14);
+        outl(t21041_csr15[port], ioaddr + CSR15);
+        outl(t21041_csr13[port], ioaddr + CSR13);
+        new_csr6 = 0x80020000;
+    } else if (tp->chip_id == LC82C168) {
+        if (startup && ! tp->medialock)
+            tp->if_port = tp->mii_cnt ? 11 : 0;
+#ifdef TULIP_DEBUG
+        if (tulip_debug > 1)
+	    printf("%s: PNIC PHY status is %hX, media %s.\n",
+                   tp->nic_name, inl(ioaddr + 0xB8), medianame[tp->if_port]);
+#endif
+        if (tp->mii_cnt) {
+            new_csr6 = 0x810C0000;
+            outl(0x0001, ioaddr + CSR15);
+            outl(0x0201B07A, ioaddr + 0xB8);
+        } else if (startup) {
+            /* Start with 10mbps to do autonegotiation. */
+            outl(0x32, ioaddr + CSR12);
+            new_csr6 = 0x00420000;
+            outl(0x0001B078, ioaddr + 0xB8);
+            outl(0x0201B078, ioaddr + 0xB8);
+        } else if (tp->if_port == 3  ||  tp->if_port == 5) {
+            outl(0x33, ioaddr + CSR12);
+            new_csr6 = 0x01860000;
+            /* Trigger autonegotiation. */
+            outl(startup ? 0x0201F868 : 0x0001F868, ioaddr + 0xB8);
+        } else {
+            outl(0x32, ioaddr + CSR12);
+            new_csr6 = 0x00420000;
+            outl(0x1F078, ioaddr + 0xB8);
+        }
+    } else if (tp->chip_id == DC21040) {                                        /* 21040 */
+        /* Turn on the xcvr interface. */
+        int csr12 = inl(ioaddr + CSR12);
+#ifdef TULIP_DEBUG
+        if (tulip_debug > 1)
+            printf("%s: 21040 media type is %s, CSR12 is %hhX.\n",
+                   tp->nic_name, medianame[tp->if_port], csr12);
+#endif
+        if (media_cap[tp->if_port] & MediaAlwaysFD)
+            tp->full_duplex = 1;
+        new_csr6 = 0x20000;
+        /* Set the full duplux match frame. */
+        outl(FULL_DUPLEX_MAGIC, ioaddr + CSR11);
+        outl(0x00000000, ioaddr + CSR13); /* Reset the serial interface */
+        if (t21040_csr13[tp->if_port] & 8) {
+            outl(0x0705, ioaddr + CSR14);
+            outl(0x0006, ioaddr + CSR15);
+        } else {
+            outl(0xffff, ioaddr + CSR14);
+            outl(0x0000, ioaddr + CSR15);
+        }
+        outl(0x8f01 | t21040_csr13[tp->if_port], ioaddr + CSR13);
+    } else {                                    /* Unknown chip type with no media table. */
+        if (tp->default_port == 0)
+            tp->if_port = tp->mii_cnt ? 11 : 3;
+        if (media_cap[tp->if_port] & MediaIsMII) {
+            new_csr6 = 0x020E0000;
+        } else if (media_cap[tp->if_port] & MediaIsFx) {
+            new_csr6 = 0x028600000;
+        } else
+            new_csr6 = 0x038600000;
+#ifdef TULIP_DEBUG
+        if (tulip_debug > 1)
+            printf("%s: No media description table, assuming "
+                   "%s transceiver, CSR12 %hhX.\n",
+                   tp->nic_name, medianame[tp->if_port],
+                   inl(ioaddr + CSR12));
+#endif
+    }
+
+    tp->csr6 = new_csr6 | (tp->csr6 & 0xfdff) | (tp->full_duplex ? 0x0200 : 0);
+    return;
+}
+
+/*
+  Check the MII negotiated duplex and change the CSR6 setting if
+  required.
+  Return 0 if everything is OK.
+  Return < 0 if the transceiver is missing or has no link beat.
+*/
+static int tulip_check_duplex(struct nic *nic)
+{
+        unsigned int bmsr, lpa, negotiated, new_csr6;
+
+        bmsr = mdio_read(nic, tp->phys[0], 1);
+        lpa = mdio_read(nic, tp->phys[0], 5);
+
+#ifdef TULIP_DEBUG
+        if (tulip_debug > 1)
+                printf("%s: MII status %#x, Link partner report "
+                           "%#x.\n", tp->nic_name, bmsr, lpa);
+#endif
+
+        if (bmsr == 0xffff)
+                return -2;
+        if ((bmsr & 4) == 0) { 
+                int new_bmsr = mdio_read(nic, tp->phys[0], 1); 
+                if ((new_bmsr & 4) == 0) { 
+#ifdef TULIP_DEBUG
+                        if (tulip_debug  > 1)
+                                printf("%s: No link beat on the MII interface,"
+                                           " status %#x.\n", tp->nic_name, 
+                                           new_bmsr);
+#endif
+                        return -1;
+                }
+        }
+        tp->full_duplex = lpa & 0x140;
+
+        new_csr6 = tp->csr6;
+        negotiated = lpa & tp->advertising[0];
+
+        if(negotiated & 0x380) new_csr6 &= ~0x400000; 
+        else                   new_csr6 |= 0x400000;
+        if (tp->full_duplex)   new_csr6 |= 0x200; 
+        else                   new_csr6 &= ~0x200;
+
+        if (new_csr6 != tp->csr6) {
+                tp->csr6 = new_csr6;
+
+#ifdef TULIP_DEBUG
+                if (tulip_debug > 0)
+                        printf("%s: Setting %s-duplex based on MII"
+                                   "#%d link partner capability of %#x.\n",
+                                   tp->nic_name, 
+                                   tp->full_duplex ? "full" : "half",
+                                   tp->phys[0], lpa);
+#endif
+                return 1;
+        }
+
+        return 0;
+}
diff --git a/netboot/tulip.txt b/netboot/tulip.txt
new file mode 100644
index 0000000..68b7b3b
--- /dev/null
+++ b/netboot/tulip.txt
@@ -0,0 +1,53 @@
+This software may be used and distributed according to the terms of
+the GNU Public License, incorporated herein by reference.
+
+This is a tulip and clone driver for Etherboot.  See the revision
+history in the tulip.c file for information on changes.  This version
+of the driver incorporates changes from Bob Edwards and Paul Mackerras
+who cantributed changes to support the TRENDnet TE100-PCIA NIC which
+uses a genuine Intel 21143-PD chipset.  There are also various code
+cleanups to make time-based activities more reliable.
+
+Of course you have to have all the usual Etherboot environment
+(bootp/dhcp/NFS) set up, and you need a Linux kernel with v0.91g
+(7.16.99) or later of the tulip.c driver compiled in to support some
+MX98715 based cards.  That file is available at:
+
+  http://cesdis.gsfc.nasa.gov/linux/drivers/test/tulip.c
+
+NOTES
+
+I've tested this driver with a SOHOware Fast 10/100 Model SDA110A,
+a Linksys LNE100TX v2.0, and a Netgear FA310TX card, and it worked at
+both 10 and 100 mbits. Other cards based on the tulip family may work as
+well.
+
+These cards are about 20$US, are supported by Linux and now Etherboot,
+and being PCI, they auto-configure IRQ and IOADDR and auto-negotiate
+10/100 half/full duplex. It seems like a pretty good value compared to
+some of the pricier cards, and can lower the cost of building/adapting
+thin client workstations substantially while giving a considerable
+performance increase.
+
+On some PCI tulip clone chipsets (MX987x5, LC82C115, LC82C168) this driver 
+lets the card choose the fastest speed it can negotiate with the peer
+device.  On other cards, it chooses 10mbit half-duplex.
+
+I burned an AM27C256 (32KByte) EPROM with mx987x5.lzrom and it worked.
+According to the data sheet the MX98715A supports up to 64K (27C512)
+EPROMs, 
+
+I've liberally commented the code and header files in the hope that it
+will help the next person who hacks the code or needs to support some
+tulip clone card, or wishes to add functionality.
+
+Anyway, please test this if you can on your tulip based card, and let
+me (mdc@thinguin.org) and the netboot list (netboot@baghira.han.de)
+know how things go.  I also would appreciate code review by people who
+program.  I'm a strong believer in "another set of eyes".
+
+Regards,
+
+Marty Connor
+mdc@thinguin.org
+http://www.thinguin.org/
diff --git a/netboot/via-rhine.c b/netboot/via-rhine.c
new file mode 100644
index 0000000..070edb8
--- /dev/null
+++ b/netboot/via-rhine.c
@@ -0,0 +1,1180 @@
+/* rhine.c:Fast Ethernet driver for Linux. */
+/*
+	Adapted 09-jan-2000 by Paolo Marini (paolom@prisma-eng.it)
+
+        originally written by Donald Becker.
+
+	This software may be used and distributed according to the terms
+	of the GNU Public License (GPL), incorporated herein by reference.
+	Drivers derived from this code also fall under the GPL and must retain
+	this authorship and copyright notice.
+
+	Under no circumstances are the authors responsible for
+	the proper functioning of this software, nor do the authors assume any
+	responsibility for damages incurred with its use.
+
+	This driver is designed for the VIA VT86C100A Rhine-II PCI Fast Ethernet
+	controller.
+
+*/
+
+static const char *version = "rhine.c v1.0.0 2000-01-07\n";
+
+/* A few user-configurable values. */
+
+/* Size of the in-memory receive ring. */
+#define RX_BUF_LEN_IDX	3	/* 0==8K, 1==16K, 2==32K, 3==64K */
+#define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX)
+
+/* Size of the Tx bounce buffers -- must be at least (dev->mtu+14+4). */
+#define TX_BUF_SIZE	1536
+#define RX_BUF_SIZE	1536
+
+/* PCI Tuning Parameters
+   Threshold is bytes transferred to chip before transmission starts. */
+#define TX_FIFO_THRESH 256	/* In bytes, rounded down to 32 byte units. */
+
+/* The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024. */
+#define RX_FIFO_THRESH	4	/* Rx buffer level before first PCI xfer.  */
+#define RX_DMA_BURST	4	/* Maximum PCI burst, '4' is 256 bytes */
+#define TX_DMA_BURST	4
+
+/* Operational parameters that usually are not changed. */
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT  ((2000*HZ)/1000)
+
+#include "etherboot.h"
+#include "nic.h"
+#include "pci.h"
+#include "cards.h"
+
+/* define all ioaddr */
+
+#define byPAR0				ioaddr
+#define byRCR				ioaddr + 6
+#define byTCR				ioaddr + 7
+#define byCR0				ioaddr + 8
+#define byCR1				ioaddr + 9
+#define byISR0				ioaddr + 0x0c
+#define byISR1				ioaddr + 0x0d
+#define byIMR0				ioaddr + 0x0e
+#define byIMR1				ioaddr + 0x0f
+#define byMAR0				ioaddr + 0x10
+#define byMAR1				ioaddr + 0x11
+#define byMAR2				ioaddr + 0x12
+#define byMAR3				ioaddr + 0x13
+#define byMAR4				ioaddr + 0x14
+#define byMAR5				ioaddr + 0x15
+#define byMAR6				ioaddr + 0x16
+#define byMAR7				ioaddr + 0x17
+#define dwCurrentRxDescAddr		ioaddr + 0x18
+#define dwCurrentTxDescAddr		ioaddr + 0x1c
+#define dwCurrentRDSE0			ioaddr + 0x20
+#define dwCurrentRDSE1			ioaddr + 0x24
+#define dwCurrentRDSE2			ioaddr + 0x28
+#define dwCurrentRDSE3			ioaddr + 0x2c
+#define dwNextRDSE0			ioaddr + 0x30
+#define dwNextRDSE1			ioaddr + 0x34
+#define dwNextRDSE2			ioaddr + 0x38
+#define dwNextRDSE3			ioaddr + 0x3c
+#define dwCurrentTDSE0			ioaddr + 0x40
+#define dwCurrentTDSE1			ioaddr + 0x44
+#define dwCurrentTDSE2			ioaddr + 0x48
+#define dwCurrentTDSE3			ioaddr + 0x4c
+#define dwNextTDSE0			ioaddr + 0x50
+#define dwNextTDSE1			ioaddr + 0x54
+#define dwNextTDSE2			ioaddr + 0x58
+#define dwNextTDSE3			ioaddr + 0x5c
+#define dwCurrRxDMAPtr			ioaddr + 0x60
+#define dwCurrTxDMAPtr			ioaddr + 0x64
+#define byMPHY				ioaddr + 0x6c
+#define byMIISR				ioaddr + 0x6d
+#define byBCR0				ioaddr + 0x6e
+#define byBCR1				ioaddr + 0x6f
+#define byMIICR				ioaddr + 0x70
+#define byMIIAD				ioaddr + 0x71
+#define wMIIDATA			ioaddr + 0x72
+#define byEECSR				ioaddr + 0x74
+#define byTEST				ioaddr + 0x75
+#define byGPIO				ioaddr + 0x76
+#define byCFGA				ioaddr + 0x78
+#define byCFGB				ioaddr + 0x79
+#define byCFGC				ioaddr + 0x7a
+#define byCFGD				ioaddr + 0x7b
+#define wTallyCntMPA			ioaddr + 0x7c
+#define wTallyCntCRC			ioaddr + 0x7d
+/*---------------------  Exioaddr Definitions -------------------------*/
+
+/*
+ * Bits in the RCR register
+ */
+
+#define RCR_RRFT2		0x80
+#define RCR_RRFT1		0x40
+#define RCR_RRFT0		0x20
+#define RCR_PROM		0x10
+#define RCR_AB			0x08
+#define RCR_AM			0x04
+#define RCR_AR			0x02
+#define RCR_SEP			0x01
+
+/*
+ * Bits in the TCR register
+ */
+
+#define TCR_RTSF		0x80
+#define TCR_RTFT1		0x40
+#define TCR_RTFT0		0x20
+#define TCR_OFSET		0x08
+#define TCR_LB1			0x04	/* loopback[1] */
+#define TCR_LB0			0x02	/* loopback[0] */
+
+/*
+ * Bits in the CR0 register
+ */
+
+#define CR0_RDMD		0x40	/* rx descriptor polling demand */
+#define CR0_TDMD		0x20	/* tx descriptor polling demand */
+#define CR0_TXON		0x10
+#define CR0_RXON		0x08
+#define CR0_STOP		0x04	/* stop NIC, default = 1 */
+#define CR0_STRT		0x02	/* start NIC */
+#define CR0_INIT		0x01	/* start init process */
+
+
+/*
+ * Bits in the CR1 register
+ */
+
+#define CR1_SFRST		0x80	/* software reset */
+#define CR1_RDMD1		0x40	/* RDMD1 */
+#define CR1_TDMD1		0x20	/* TDMD1 */
+#define CR1_KEYPAG		0x10	/* turn on par/key */
+#define CR1_DPOLL		0x08	/* disable rx/tx auto polling */
+#define CR1_FDX			0x04	/* full duplex mode */
+#define CR1_ETEN		0x02	/* early tx mode */
+#define CR1_EREN		0x01	/* early rx mode */
+
+/*
+ * Bits in the CR register
+ */
+
+#define CR_RDMD			0x0040	/* rx descriptor polling demand */
+#define CR_TDMD			0x0020	/* tx descriptor polling demand */
+#define CR_TXON			0x0010
+#define CR_RXON			0x0008
+#define CR_STOP			0x0004	/* stop NIC, default = 1 */
+#define CR_STRT			0x0002	/* start NIC */
+#define CR_INIT			0x0001	/* start init process */
+#define CR_SFRST		0x8000	/* software reset */
+#define CR_RDMD1		0x4000	/* RDMD1 */
+#define CR_TDMD1		0x2000	/* TDMD1 */
+#define CR_KEYPAG		0x1000	/* turn on par/key */
+#define CR_DPOLL		0x0800	/* disable rx/tx auto polling */
+#define CR_FDX			0x0400	/* full duplex mode */
+#define CR_ETEN			0x0200	/* early tx mode */
+#define CR_EREN			0x0100	/* early rx mode */
+
+/*
+ * Bits in the IMR0 register
+ */
+
+#define IMR0_CNTM		0x80
+#define IMR0_BEM		0x40
+#define IMR0_RUM		0x20
+#define IMR0_TUM		0x10
+#define IMR0_TXEM		0x08
+#define IMR0_RXEM		0x04
+#define IMR0_PTXM		0x02
+#define IMR0_PRXM		0x01
+
+/* define imrshadow */
+
+#define IMRShadow		0x5AFF
+
+/*
+ * Bits in the IMR1 register
+ */
+
+#define IMR1_INITM		0x80
+#define IMR1_SRCM		0x40
+#define IMR1_NBFM		0x10
+#define IMR1_PRAIM		0x08
+#define IMR1_RES0M		0x04
+#define IMR1_ETM		0x02
+#define IMR1_ERM		0x01
+
+/*
+ * Bits in the ISR register
+ */
+
+#define ISR_INITI		0x8000
+#define ISR_SRCI		0x4000
+#define ISR_ABTI		0x2000
+#define ISR_NORBF		0x1000
+#define ISR_PKTRA		0x0800
+#define ISR_RES0		0x0400
+#define ISR_ETI			0x0200
+#define ISR_ERI			0x0100
+#define ISR_CNT			0x0080
+#define ISR_BE			0x0040
+#define ISR_RU			0x0020
+#define ISR_TU			0x0010
+#define ISR_TXE			0x0008
+#define ISR_RXE			0x0004
+#define ISR_PTX			0x0002
+#define ISR_PRX			0x0001
+
+/*
+ * Bits in the ISR0 register
+ */
+
+#define ISR0_CNT		0x80
+#define ISR0_BE			0x40
+#define ISR0_RU			0x20
+#define ISR0_TU			0x10
+#define ISR0_TXE		0x08
+#define ISR0_RXE		0x04
+#define ISR0_PTX		0x02
+#define ISR0_PRX		0x01
+
+/*
+ * Bits in the ISR1 register
+ */
+
+#define ISR1_INITI		0x80
+#define ISR1_SRCI		0x40
+#define ISR1_NORBF		0x10
+#define ISR1_PKTRA		0x08
+#define ISR1_ETI		0x02
+#define ISR1_ERI		0x01
+
+/* ISR ABNORMAL CONDITION */
+
+#define ISR_ABNORMAL ISR_BE+ISR_RU+ISR_TU+ISR_CNT+ISR_NORBF+ISR_PKTRA
+
+/*
+ * Bits in the MIISR register
+ */
+
+#define MIISR_MIIERR		0x08
+#define MIISR_MRERR		0x04
+#define MIISR_LNKFL		0x02
+#define MIISR_SPEED		0x01
+
+/*
+ * Bits in the MIICR register
+ */
+
+#define MIICR_MAUTO		0x80
+#define MIICR_RCMD		0x40
+#define MIICR_WCMD		0x20
+#define MIICR_MDPM		0x10
+#define MIICR_MOUT		0x08
+#define MIICR_MDO		0x04
+#define MIICR_MDI		0x02
+#define MIICR_MDC		0x01
+
+/*
+ * Bits in the EECSR register
+ */
+
+#define EECSR_EEPR		0x80	/* eeprom programed status, 73h means programed */
+#define EECSR_EMBP		0x40	/* eeprom embeded programming */
+#define EECSR_AUTOLD		0x20	/* eeprom content reload */
+#define EECSR_DPM		0x10	/* eeprom direct programming */
+#define EECSR_CS		0x08	/* eeprom CS pin */
+#define EECSR_SK		0x04	/* eeprom SK pin */
+#define EECSR_DI		0x02	/* eeprom DI pin */
+#define EECSR_DO		0x01	/* eeprom DO pin */
+
+/*
+ * Bits in the BCR0 register
+ */
+
+#define BCR0_CRFT2		0x20
+#define BCR0_CRFT1		0x10
+#define BCR0_CRFT0		0x08
+#define BCR0_DMAL2		0x04
+#define BCR0_DMAL1		0x02
+#define BCR0_DMAL0		0x01
+
+/*
+ * Bits in the BCR1 register
+ */
+
+#define BCR1_CTSF		0x20
+#define BCR1_CTFT1		0x10
+#define BCR1_CTFT0		0x08
+#define BCR1_POT2		0x04
+#define BCR1_POT1		0x02
+#define BCR1_POT0		0x01
+
+/*
+ * Bits in the CFGA register
+ */
+
+#define CFGA_EELOAD		0x80	/* enable eeprom embeded and direct programming */
+#define CFGA_JUMPER		0x40
+#define CFGA_MTGPIO		0x08
+#define CFGA_T10EN		0x02
+#define CFGA_AUTO		0x01
+
+/*
+ * Bits in the CFGB register
+ */
+
+#define CFGB_PD			0x80
+#define CFGB_POLEN		0x02
+#define CFGB_LNKEN		0x01
+
+/*
+ * Bits in the CFGC register
+ */
+
+#define CFGC_M10TIO		0x80
+#define CFGC_M10POL		0x40
+#define CFGC_PHY1		0x20
+#define CFGC_PHY0		0x10
+#define CFGC_BTSEL		0x08
+#define CFGC_BPS2		0x04	/* bootrom select[2] */
+#define CFGC_BPS1		0x02	/* bootrom select[1] */
+#define CFGC_BPS0		0x01	/* bootrom select[0] */
+
+/*
+ * Bits in the CFGD register
+ */
+
+#define CFGD_GPIOEN		0x80
+#define CFGD_DIAG		0x40
+#define CFGD_MAGIC		0x10
+#define CFGD_CFDX		0x04
+#define CFGD_CEREN		0x02
+#define CFGD_CETEN		0x01
+
+/* Bits in RSR */
+#define RSR_RERR		0x00000001
+#define RSR_CRC			0x00000002
+#define RSR_FAE			0x00000004
+#define RSR_FOV			0x00000008
+#define RSR_LONG		0x00000010
+#define RSR_RUNT		0x00000020
+#define RSR_SERR		0x00000040
+#define RSR_BUFF		0x00000080
+#define RSR_EDP			0x00000100
+#define RSR_STP			0x00000200
+#define RSR_CHN			0x00000400
+#define RSR_PHY			0x00000800
+#define RSR_BAR			0x00001000
+#define RSR_MAR			0x00002000
+#define RSR_RXOK		0x00008000
+#define RSR_ABNORMAL		RSR_RERR+RSR_LONG+RSR_RUNT
+
+/* Bits in TSR */
+#define TSR_NCR0		0x00000001
+#define TSR_NCR1		0x00000002
+#define TSR_NCR2		0x00000004
+#define TSR_NCR3		0x00000008
+#define TSR_COLS		0x00000010
+#define TSR_CDH			0x00000080
+#define TSR_ABT			0x00000100
+#define TSR_OWC			0x00000200
+#define TSR_CRS			0x00000400
+#define TSR_UDF			0x00000800
+#define TSR_TBUFF		0x00001000
+#define TSR_SERR		0x00002000
+#define TSR_JAB			0x00004000
+#define TSR_TERR		0x00008000
+#define TSR_ABNORMAL		TSR_TERR+TSR_OWC+TSR_ABT+TSR_JAB+TSR_CRS
+#define TSR_OWN_BIT		0x80000000
+
+#define CB_DELAY_LOOP_WAIT	10	/* 10ms */
+/* enabled mask value of irq */
+
+#define W_IMR_MASK_VALUE	0x1BFF	/* initial value of IMR */
+
+/* Ethernet address filter type */
+#define PKT_TYPE_DIRECTED	0x0001	/* obsolete, directed address is always accepted */
+#define PKT_TYPE_MULTICAST	0x0002
+#define PKT_TYPE_ALL_MULTICAST	0x0004
+#define PKT_TYPE_BROADCAST	0x0008
+#define PKT_TYPE_PROMISCUOUS	0x0020
+#define PKT_TYPE_LONG		0x2000
+#define PKT_TYPE_RUNT		0x4000
+#define PKT_TYPE_ERROR		0x8000	/* accept error packets, e.g. CRC error */
+
+/* Loopback mode */
+
+#define NIC_LB_NONE		0x00
+#define NIC_LB_INTERNAL		0x01
+#define NIC_LB_PHY		0x02	/* MII or Internal-10BaseT loopback */
+
+#define TX_RING_SIZE		2
+#define RX_RING_SIZE		2
+#define PKT_BUF_SZ		1536	/* Size of each temporary Rx buffer. */
+
+/* Transmit and receive descriptors definition */
+
+struct rhine_tx_desc
+{
+    union VTC_tx_status_tag
+    {
+	struct
+	{
+	    unsigned long ncro:1;
+	    unsigned long ncr1:1;
+	    unsigned long ncr2:1;
+	    unsigned long ncr3:1;
+	    unsigned long cols:1;
+	    unsigned long reserve_1:2;
+	    unsigned long cdh:1;
+	    unsigned long abt:1;
+	    unsigned long owc:1;
+	    unsigned long crs:1;
+	    unsigned long udf:1;
+	    unsigned long tbuff:1;
+	    unsigned long serr:1;
+	    unsigned long jab:1;
+	    unsigned long terr:1;
+	    unsigned long reserve_2:15;
+	    unsigned long own_bit:1;
+	}
+	bits;
+	unsigned long lw;
+    }
+    tx_status;
+
+    union VTC_tx_ctrl_tag
+    {
+	struct
+	{
+	    unsigned long tx_buf_size:11;
+	    unsigned long extend_tx_buf_size:4;
+	    unsigned long chn:1;
+	    unsigned long crc:1;
+	    unsigned long reserve_1:4;
+	    unsigned long stp:1;
+	    unsigned long edp:1;
+	    unsigned long ic:1;
+	    unsigned long reserve_2:8;
+	}
+	bits;
+	unsigned long lw;
+    }
+    tx_ctrl;
+
+    unsigned long buf_addr_1:32;
+    unsigned long buf_addr_2:32;
+
+};
+
+struct rhine_rx_desc
+{
+    union VTC_rx_status_tag
+    {
+	struct
+	{
+	    unsigned long rerr:1;
+	    unsigned long crc_error:1;
+	    unsigned long fae:1;
+	    unsigned long fov:1;
+	    unsigned long toolong:1;
+	    unsigned long runt:1;
+	    unsigned long serr:1;
+	    unsigned long buff:1;
+	    unsigned long edp:1;
+	    unsigned long stp:1;
+	    unsigned long chn:1;
+	    unsigned long phy:1;
+	    unsigned long bar:1;
+	    unsigned long mar:1;
+	    unsigned long reserve_1:1;
+	    unsigned long rxok:1;
+	    unsigned long frame_length:11;
+	    unsigned long reverve_2:4;
+	    unsigned long own_bit:1;
+	}
+	bits;
+	unsigned long lw;
+    }
+    rx_status;
+
+    union VTC_rx_ctrl_tag
+    {
+	struct
+	{
+	    unsigned long rx_buf_size:11;
+	    unsigned long extend_rx_buf_size:4;
+	    unsigned long reserved_1:17;
+	}
+	bits;
+	unsigned long lw;
+    }
+    rx_ctrl;
+
+    unsigned long buf_addr_1:32;
+    unsigned long buf_addr_2:32;
+
+};
+
+
+/* The I/O extent. */
+#define rhine_TOTAL_SIZE 0x80
+
+#ifdef	HAVE_DEVLIST
+struct netdev_entry rhine_drv =
+    { "rhine", rhine_probe, rhine_TOTAL_SIZE, NULL };
+#endif
+
+static int rhine_debug = 1;
+
+/*
+				Theory of Operation
+
+I. Board Compatibility
+
+This driver is designed for the VIA 86c100A Rhine-II PCI Fast Ethernet
+controller.
+
+II. Board-specific settings
+
+Boards with this chip are functional only in a bus-master PCI slot.
+
+Many operational settings are loaded from the EEPROM to the Config word at
+offset 0x78.  This driver assumes that they are correct.
+If this driver is compiled to use PCI memory space operations the EEPROM
+must be configured to enable memory ops.
+
+III. Driver operation
+
+IIIa. Ring buffers
+
+This driver uses two statically allocated fixed-size descriptor lists
+formed into rings by a branch from the final descriptor to the beginning of
+the list.  The ring sizes are set at compile time by RX/TX_RING_SIZE.
+
+IIIb/c. Transmit/Receive Structure
+
+This driver attempts to use a zero-copy receive and transmit scheme.
+
+Alas, all data buffers are required to start on a 32 bit boundary, so
+the driver must often copy transmit packets into bounce buffers.
+
+The driver allocates full frame size skbuffs for the Rx ring buffers at
+open() time and passes the skb->data field to the chip as receive data
+buffers.  When an incoming frame is less than RX_COPYBREAK bytes long,
+a fresh skbuff is allocated and the frame is copied to the new skbuff.
+When the incoming frame is larger, the skbuff is passed directly up the
+protocol stack.  Buffers consumed this way are replaced by newly allocated
+skbuffs in the last phase of netdev_rx().
+
+The RX_COPYBREAK value is chosen to trade-off the memory wasted by
+using a full-sized skbuff for small frames vs. the copying costs of larger
+frames.  New boards are typically used in generously configured machines
+and the underfilled buffers have negligible impact compared to the benefit of
+a single allocation size, so the default value of zero results in never
+copying packets.  When copying is done, the cost is usually mitigated by using
+a combined copy/checksum routine.  Copying also preloads the cache, which is
+most useful with small frames.
+
+Since the VIA chips are only able to transfer data to buffers on 32 bit
+boundaries, the the IP header at offset 14 in an ethernet frame isn't
+longword aligned for further processing.  Copying these unaligned buffers
+has the beneficial effect of 16-byte aligning the IP header.
+
+IIId. Synchronization
+
+The driver runs as two independent, single-threaded flows of control.  One
+is the send-packet routine, which enforces single-threaded use by the
+dev->tbusy flag.  The other thread is the interrupt handler, which is single
+threaded by the hardware and interrupt handling software.
+
+The send packet thread has partial control over the Tx ring and 'dev->tbusy'
+flag.  It sets the tbusy flag whenever it's queuing a Tx packet. If the next
+queue slot is empty, it clears the tbusy flag when finished otherwise it sets
+the 'lp->tx_full' flag.
+
+The interrupt handler has exclusive control over the Rx ring and records stats
+from the Tx ring.  After reaping the stats, it marks the Tx queue entry as
+empty by incrementing the dirty_tx mark. Iff the 'lp->tx_full' flag is set, it
+clears both the tx_full and tbusy flags.
+
+IV. Notes
+
+IVb. References
+
+Preliminary VT86C100A manual from http://www.via.com.tw/
+http://cesdis.gsfc.nasa.gov/linux/misc/100mbps.html
+http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
+
+IVc. Errata
+
+The VT86C100A manual is not reliable information.
+The chip does not handle unaligned transmit or receive buffers, resulting
+in significant performance degradation for bounce buffer copies on transmit
+and unaligned IP headers on receive.
+The chip does not pad to minimum transmit length.
+
+*/
+
+#define PCI_VENDOR_ID_FET		0x1106
+#define PCI_DEVICE_ID_FET_3043		0x3043
+
+/* The rest of these values should never change. */
+#define NUM_TX_DESC	2	/* Number of Tx descriptor registers. */
+
+static struct rhine_private
+{
+    char devname[8];		/* Used only for kernel debugging. */
+    const char *product_name;
+    struct rhine_rx_desc *rx_ring;
+    struct rhine_tx_desc *tx_ring;
+    char *rx_buffs[RX_RING_SIZE];
+    char *tx_buffs[TX_RING_SIZE];
+
+    /* temporary Rx buffers. */
+
+    int chip_id;
+    int chip_revision;
+    unsigned short ioaddr;
+    unsigned int cur_rx, cur_tx;	/* The next free and used entries */
+    unsigned int dirty_rx, dirty_tx;
+    /* The saved address of a sent-in-place packet/buffer, for skfree(). */
+    struct sk_buff *tx_skbuff[TX_RING_SIZE];
+    unsigned char mc_filter[8];	/* Current multicast filter. */
+    char phys[4];		/* MII device addresses. */
+    unsigned int tx_full:1;	/* The Tx queue is full. */
+    unsigned int full_duplex:1;	/* Full-duplex operation requested. */
+    unsigned int default_port:4;	/* Last dev->if_port value. */
+    unsigned int media2:4;	/* Secondary monitored media port. */
+    unsigned int medialock:1;	/* Don't sense media type. */
+    unsigned int mediasense:1;	/* Media sensing in progress. */
+}
+rhine;
+
+static struct nic *rhine_probe1 (struct nic *dev, int ioaddr,
+				 int chip_id, int options);
+static int QueryAuto (int);
+static int ReadMII (int byMIIIndex, int);
+static void WriteMII (char, char, char, int);
+static void MIIDelay (void);
+static void rhine_init_ring (struct nic *dev);
+static void rhine_disable (struct nic *nic);
+static void rhine_reset (struct nic *nic);
+static int rhine_poll (struct nic *nic);
+static void rhine_transmit (struct nic *nic, const char *d, unsigned int t,
+			    unsigned int s, const char *p);
+
+/* Linux support functions */
+#define virt_to_bus(x) ((unsigned long)x)
+#define bus_to_virt(x) ((void *)x)
+
+/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
+static void
+rhine_init_ring (struct nic *nic)
+{
+    struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
+    int i;
+
+    tp->tx_full = 0;
+    tp->cur_rx = tp->cur_tx = 0;
+    tp->dirty_rx = tp->dirty_tx = 0;
+
+    for (i = 0; i < RX_RING_SIZE; i++)
+    {
+
+	tp->rx_ring[i].rx_status.bits.own_bit = 1;
+	tp->rx_ring[i].rx_ctrl.bits.rx_buf_size = 1536;
+
+	tp->rx_ring[i].buf_addr_1 = virt_to_bus (tp->rx_buffs[i]);
+	tp->rx_ring[i].buf_addr_2 = virt_to_bus (&tp->rx_ring[i + 1]);
+	/* printf("[%d]buf1=%hX,buf2=%hX",i,tp->rx_ring[i].buf_addr_1,tp->rx_ring[i].buf_addr_2); */
+    }
+    /* Mark the last entry as wrapping the ring. */
+    /* tp->rx_ring[i-1].rx_ctrl.bits.rx_buf_size =1518; */
+    tp->rx_ring[i - 1].buf_addr_2 = virt_to_bus (&tp->rx_ring[0]);
+    /*printf("[%d]buf1=%hX,buf2=%hX",i-1,tp->rx_ring[i-1].buf_addr_1,tp->rx_ring[i-1].buf_addr_2); */
+
+    /* The Tx buffer descriptor is filled in as needed, but we
+       do need to clear the ownership bit. */
+
+    for (i = 0; i < TX_RING_SIZE; i++)
+    {
+
+	tp->tx_ring[i].tx_status.lw = 0;
+	tp->tx_ring[i].tx_ctrl.lw = 0x00e08000;
+	tp->tx_ring[i].buf_addr_1 = virt_to_bus (tp->tx_buffs[i]);
+	tp->tx_ring[i].buf_addr_2 = virt_to_bus (&tp->tx_ring[i + 1]);
+	/* printf("[%d]buf1=%hX,buf2=%hX",i,tp->tx_ring[i].buf_addr_1,tp->tx_ring[i].buf_addr_2); */
+    }
+
+    tp->tx_ring[i - 1].buf_addr_2 = virt_to_bus (&tp->tx_ring[0]);
+    /* printf("[%d]buf1=%hX,buf2=%hX",i,tp->tx_ring[i-1].buf_addr_1,tp->tx_ring[i-1].buf_addr_2); */
+}
+
+int
+QueryAuto (int ioaddr)
+{
+    int byMIIIndex;
+    int MIIReturn;
+
+	int advertising,mii_reg5;
+	int negociated;
+
+    byMIIIndex = 0x04;
+    MIIReturn = ReadMII (byMIIIndex, ioaddr);
+	advertising=MIIReturn;
+
+    byMIIIndex = 0x05;
+    MIIReturn = ReadMII (byMIIIndex, ioaddr);
+	mii_reg5=MIIReturn;
+
+	negociated=mii_reg5 & advertising;
+
+	if ( (negociated & 0x100) || (negociated & 0x1C0) == 0x40 )
+		return 1;
+	else
+		return 0;
+
+}
+
+int
+ReadMII (int byMIIIndex, int ioaddr)
+{
+    int ReturnMII;
+    char byMIIAdrbak;
+    char byMIICRbak;
+    char byMIItemp;
+
+    byMIIAdrbak = inb (byMIIAD);
+    byMIICRbak = inb (byMIICR);
+    outb (byMIICRbak & 0x7f, byMIICR);
+    MIIDelay ();
+
+    outb (byMIIIndex, byMIIAD);
+    MIIDelay ();
+
+    outb (inb (byMIICR) | 0x40, byMIICR);
+
+    byMIItemp = inb (byMIICR);
+    byMIItemp = byMIItemp & 0x40;
+
+    while (byMIItemp != 0)
+    {
+	byMIItemp = inb (byMIICR);
+	byMIItemp = byMIItemp & 0x40;
+    }
+    MIIDelay ();
+
+    ReturnMII = inw (wMIIDATA);
+
+    outb (byMIIAdrbak, byMIIAD);
+    outb (byMIICRbak, byMIICR);
+    MIIDelay ();
+
+    return (ReturnMII);
+
+}
+
+void
+WriteMII (char byMIISetByte, char byMIISetBit, char byMIIOP, int ioaddr)
+{
+    int ReadMIItmp;
+    int MIIMask;
+    char byMIIAdrbak;
+    char byMIICRbak;
+    char byMIItemp;
+
+
+    byMIIAdrbak = inb (byMIIAD);
+
+    byMIICRbak = inb (byMIICR);
+    outb (byMIICRbak & 0x7f, byMIICR);
+    MIIDelay ();
+    outb (byMIISetByte, byMIIAD);
+    MIIDelay ();
+
+    outb (inb (byMIICR) | 0x40, byMIICR);
+
+    byMIItemp = inb (byMIICR);
+    byMIItemp = byMIItemp & 0x40;
+
+    while (byMIItemp != 0)
+    {
+	byMIItemp = inb (byMIICR);
+	byMIItemp = byMIItemp & 0x40;
+    }
+    MIIDelay ();
+
+    ReadMIItmp = inw (wMIIDATA);
+    MIIMask = 0x0001;
+    MIIMask = MIIMask << byMIISetBit;
+
+
+    if (byMIIOP == 0)
+    {
+	MIIMask = ~MIIMask;
+	ReadMIItmp = ReadMIItmp & MIIMask;
+    }
+    else
+    {
+	ReadMIItmp = ReadMIItmp | MIIMask;
+
+    }
+    outw (ReadMIItmp, wMIIDATA);
+    MIIDelay ();
+
+    outb (inb (byMIICR) | 0x20, byMIICR);
+    byMIItemp = inb (byMIICR);
+    byMIItemp = byMIItemp & 0x20;
+
+    while (byMIItemp != 0)
+    {
+	byMIItemp = inb (byMIICR);
+	byMIItemp = byMIItemp & 0x20;
+    }
+    MIIDelay ();
+
+    outb (byMIIAdrbak & 0x7f, byMIIAD);
+    outb (byMIICRbak, byMIICR);
+    MIIDelay ();
+
+}
+
+void
+MIIDelay (void)
+{
+    int i;
+    for (i = 0; i < 0x7fff; i++)
+    {
+	inb (0x61);
+	inb (0x61);
+	inb (0x61);
+	inb (0x61);
+    }
+}
+
+struct nic *
+rhine_probe (struct nic *nic, unsigned short *probeaddrs,
+	       struct pci_device *pci)
+{
+    if (!pci->ioaddr)
+	return NULL;
+    nic = rhine_probe1 (nic, pci->ioaddr, 0, -1);
+
+    if (nic)
+	adjust_pci_device(pci);
+    nic->poll = rhine_poll;
+    nic->transmit = rhine_transmit;
+    nic->reset = rhine_reset;
+    nic->disable = rhine_disable;
+    rhine_reset (nic);
+
+    return nic;
+}
+
+static struct nic *
+rhine_probe1 (struct nic *nic, int ioaddr, int chip_id, int options)
+{
+    struct rhine_private *tp;
+    static int did_version = 0;	/* Already printed version info. */
+    int i;
+    unsigned int timeout;
+    int FDXFlag;
+    int byMIIvalue, LineSpeed, MIICRbak;
+
+    if (rhine_debug > 0 && did_version++ == 0)
+	printf (version);
+    /* Perhaps this should be read from the EEPROM? */
+    for (i = 0; i < ETH_ALEN; i++)
+	nic->node_addr[i] = inb (byPAR0 + i);
+    printf ("IO address %hX Ethernet Address: %!\n", ioaddr, nic->node_addr);
+
+    /* restart MII auto-negotiation */
+    WriteMII (0, 9, 1, ioaddr);
+    printf ("Analyzing Media type,this will take several seconds........");
+    for (i = 0; i < 5; i++)
+    {
+	/* need to wait 1 millisecond - we will round it up to 50-100ms */
+	timeout = currticks() + 2;
+	for (timeout = currticks() + 2; currticks() < timeout;)
+	    /* nothing */;
+	if (ReadMII (1, ioaddr) & 0x0020)
+	    break;
+    }
+    printf ("OK\n");
+
+#if	0
+	/* JJM : for Debug */
+	printf("MII : Address %hhX ",inb(ioaddr+0x6c));
+	{
+	 unsigned char st1,st2,adv1,adv2,l1,l2;
+	
+	 st1=ReadMII(1,ioaddr)>>8;
+	 st2=ReadMII(1,ioaddr)&0xFF;
+	 adv1=ReadMII(4,ioaddr)>>8;
+	 adv2=ReadMII(4,ioaddr)&0xFF;
+	 l1=ReadMII(5,ioaddr)>>8;
+	 l2=ReadMII(5,ioaddr)&0xFF;
+	 printf(" status 0x%hhX%hhX, advertising 0x%hhX%hhX, link 0x%hhX%hhX\n", st1,st2,adv1,adv2,l1,l2);
+	}
+#endif
+
+    /* query MII to know LineSpeed,duplex mode */
+    byMIIvalue = inb (ioaddr + 0x6d);
+    LineSpeed = byMIIvalue & MIISR_SPEED;
+    if (LineSpeed != 0)						//JJM
+    {
+	printf ("Linespeed=10Mbs");
+    }
+    else
+    {
+	printf ("Linespeed=100Mbs");
+    }
+	
+    FDXFlag = QueryAuto (ioaddr);
+    if (FDXFlag == 1)
+    {
+	printf (" Fullduplex\n");
+	outw (CR_FDX, byCR0);
+    }
+    else
+    {
+	printf (" Halfduplex\n");
+    }
+
+
+    /* set MII 10 FULL ON */
+    WriteMII (17, 1, 1, ioaddr);
+
+    /* turn on MII link change */
+    MIICRbak = inb (byMIICR);
+    outb (MIICRbak & 0x7F, byMIICR);
+    MIIDelay ();
+    outb (0x41, byMIIAD);
+    MIIDelay ();
+
+    /* while((inb(byMIIAD)&0x20)==0) ; */
+    outb (MIICRbak | 0x80, byMIICR);
+
+    nic->priv_data = &rhine;
+    tp = &rhine;
+    tp->chip_id = chip_id;
+    tp->ioaddr = ioaddr;
+    tp->phys[0] = -1;
+
+    /* The lower four bits are the media type. */
+    if (options > 0)
+    {
+	tp->full_duplex = (options & 16) ? 1 : 0;
+	tp->default_port = options & 15;
+	if (tp->default_port)
+	    tp->medialock = 1;
+    }
+    return nic;
+}
+
+static void
+rhine_disable (struct nic *nic)
+{
+    struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
+    int ioaddr = tp->ioaddr;
+
+    printf ("rhine disable\n");
+    /* Switch to loopback mode to avoid hardware races. */
+    writeb(0x60 | 0x01, byTCR);
+    /* Stop the chip's Tx and Rx processes. */
+    writew(CR_STOP, byCR0);
+}
+
+/**************************************************************************
+ETH_RESET - Reset adapter
+***************************************************************************/
+static void
+rhine_reset (struct nic *nic)
+{
+    struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
+    int ioaddr = tp->ioaddr;
+    int i, j;
+    int FDXFlag, CRbak;
+    int rx_ring_tmp, rx_ring_tmp1;
+    int tx_ring_tmp, tx_ring_tmp1;
+    int rx_bufs_tmp, rx_bufs_tmp1;
+    int tx_bufs_tmp, tx_bufs_tmp1;
+
+#ifdef	USE_LOWMEM_BUFFER
+#define buf1 (0x10000 - (RX_RING_SIZE * PKT_BUF_SZ + 32))
+#define buf2 (buf1 - (RX_RING_SIZE * PKT_BUF_SZ + 32))
+#define desc1 (buf2 - (TX_RING_SIZE * sizeof (struct rhine_tx_desc) + 32))
+#define desc2 (desc1 - (TX_RING_SIZE * sizeof (struct rhine_tx_desc) + 32))
+#else
+    static char buf1[RX_RING_SIZE * PKT_BUF_SZ + 32];
+    static char buf2[RX_RING_SIZE * PKT_BUF_SZ + 32];
+    static char desc1[TX_RING_SIZE * sizeof (struct rhine_tx_desc) + 32];
+    static char desc2[TX_RING_SIZE * sizeof (struct rhine_tx_desc) + 32];
+#endif
+
+    /* printf ("rhine_reset\n"); */
+    /* Soft reset the chip. */
+    /*outb(CmdReset, ioaddr + ChipCmd); */
+
+    tx_bufs_tmp = (int) buf1;
+    tx_ring_tmp = (int) desc1;
+    rx_bufs_tmp = (int) buf2;
+    rx_ring_tmp = (int) desc2;
+
+    /* tune RD TD 32 byte alignment */
+    rx_ring_tmp1 = (int) virt_to_bus ((char *) rx_ring_tmp);
+    j = (rx_ring_tmp1 + 32) & (~0x1f);
+    /* printf ("txring[%d]", j); */
+    tp->rx_ring = (struct rhine_rx_desc *) bus_to_virt (j);
+
+    tx_ring_tmp1 = (int) virt_to_bus ((char *) tx_ring_tmp);
+    j = (tx_ring_tmp1 + 32) & (~0x1f);
+    tp->tx_ring = (struct rhine_tx_desc *) bus_to_virt (j);
+    /* printf ("rxring[%X]", j); */
+
+
+    tx_bufs_tmp1 = (int) virt_to_bus ((char *) tx_bufs_tmp);
+    j = (int) (tx_bufs_tmp1 + 32) & (~0x1f);
+    tx_bufs_tmp = (int) bus_to_virt (j);
+    /* printf ("txb[%X]", j); */
+
+    rx_bufs_tmp1 = (int) virt_to_bus ((char *) rx_bufs_tmp);
+    j = (int) (rx_bufs_tmp1 + 32) & (~0x1f);
+    rx_bufs_tmp = (int) bus_to_virt (j);
+    /* printf ("rxb[%X][%X]", rx_bufs_tmp1, j); */
+
+    for (i = 0; i < RX_RING_SIZE; i++)
+    {
+	tp->rx_buffs[i] = (char *) rx_bufs_tmp;
+	/* printf("r[%X]",tp->rx_buffs[i]); */
+	rx_bufs_tmp += 1536;
+    }
+
+    for (i = 0; i < TX_RING_SIZE; i++)
+    {
+	tp->tx_buffs[i] = (char *) tx_bufs_tmp;
+	/* printf("t[%X]",tp->tx_buffs[i]);  */
+	tx_bufs_tmp += 1536;
+    }
+
+    /* software reset */
+    outb (CR1_SFRST, byCR1);
+    MIIDelay ();
+
+    /* printf ("init ring"); */
+    rhine_init_ring (nic);
+    /*write TD RD Descriptor to MAC */
+    outl (virt_to_bus (tp->rx_ring), dwCurrentRxDescAddr);
+    outl (virt_to_bus (tp->tx_ring), dwCurrentTxDescAddr);
+
+    /* close IMR */
+    outw (0x0000, byIMR0);
+
+    /* set TCR RCR threshold */
+    outb (0x06, byBCR0);
+    outb (0x00, byBCR1);
+    outb (0x2c, byRCR);
+    outb (0x60, byTCR);
+    /* Set Fulldupex */
+    FDXFlag = QueryAuto (ioaddr);
+    if (FDXFlag == 1)
+    {
+	outb (CFGD_CFDX, byCFGD);
+	outw (CR_FDX, byCR0);
+    }
+
+    /* KICK NIC to WORK */
+    CRbak = inw (byCR0);
+    CRbak = CRbak & 0xFFFB;	/* not CR_STOP */
+    outw ((CRbak | CR_STRT | CR_TXON | CR_RXON | CR_DPOLL), byCR0);
+
+    /*set IMR to work */
+    outw (IMRShadow, byIMR0);
+}
+
+static int
+rhine_poll (struct nic *nic)
+{
+    struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
+    int rxstatus, good = 0;;
+
+    if (tp->rx_ring[tp->cur_rx].rx_status.bits.own_bit == 0)
+    {
+	rxstatus = tp->rx_ring[tp->cur_rx].rx_status.lw;
+	if ((rxstatus & 0x0300) != 0x0300)
+	{
+	    printf("rhine_poll: bad status\n");
+	}
+	else if (rxstatus & (RSR_ABNORMAL))
+	{
+	    printf ("rxerr[%X]\n", rxstatus);
+	}
+	else
+	    good = 1;
+
+	if (good)
+	{
+	    nic->packetlen = tp->rx_ring[tp->cur_rx].rx_status.bits.frame_length;
+	    memcpy (nic->packet, tp->rx_buffs[tp->cur_rx], nic->packetlen);
+	    /* printf ("Packet RXed\n"); */
+	}
+	tp->rx_ring[tp->cur_rx].rx_status.bits.own_bit = 1;
+	tp->cur_rx++;
+	tp->cur_rx = tp->cur_rx % RX_RING_SIZE;
+    }
+    return good;
+}
+
+static void
+rhine_transmit (struct nic *nic,
+		const char *d, unsigned int t, unsigned int s, const char *p)
+{
+    struct rhine_private *tp = (struct rhine_private *) nic->priv_data;
+    int ioaddr = tp->ioaddr;
+    int entry;
+    unsigned char CR1bak;
+
+    /*printf ("rhine_transmit\n"); */
+    /* setup ethernet header */
+
+
+    /* Calculate the next Tx descriptor entry. */
+    entry = tp->cur_tx % TX_RING_SIZE;
+
+    memcpy (tp->tx_buffs[entry], d, ETH_ALEN);	/* dst */
+    memcpy (tp->tx_buffs[entry] + ETH_ALEN, nic->node_addr, ETH_ALEN);	/* src */
+    *((char *) tp->tx_buffs[entry] + 12) = t >> 8;	/* type */
+    *((char *) tp->tx_buffs[entry] + 13) = t;
+    memcpy (tp->tx_buffs[entry] + ETH_HLEN, p, s);
+    s += ETH_HLEN;
+    while (s < ETH_ZLEN)
+	*((char *) tp->tx_buffs[entry] + ETH_HLEN + (s++)) = 0;
+
+    tp->tx_ring[entry].tx_ctrl.bits.tx_buf_size = ETH_HLEN + s;
+
+    tp->tx_ring[entry].tx_status.bits.own_bit = 1;
+
+
+    CR1bak = inb (byCR1);
+
+    CR1bak = CR1bak | CR1_TDMD1;
+    /*printf("tdsw=[%X]",tp->tx_ring[entry].tx_status.lw); */
+    /*printf("tdcw=[%X]",tp->tx_ring[entry].tx_ctrl.lw); */
+    /*printf("tdbuf1=[%X]",tp->tx_ring[entry].buf_addr_1); */
+    /*printf("tdbuf2=[%X]",tp->tx_ring[entry].buf_addr_2); */
+    /*printf("td1=[%X]",inl(dwCurrentTDSE0)); */
+    /*printf("td2=[%X]",inl(dwCurrentTDSE1)); */
+    /*printf("td3=[%X]",inl(dwCurrentTDSE2)); */
+    /*printf("td4=[%X]",inl(dwCurrentTDSE3)); */
+
+    outb (CR1bak, byCR1);
+    tp->cur_tx++;
+
+    /*outw(IMRShadow,byIMR0); */
+    /*dev_kfree_skb(tp->tx_skbuff[entry], FREE_WRITE); */
+    /*tp->tx_skbuff[entry] = 0; */
+}
+
+/* EOF via-rhine.c */
diff --git a/netboot/w89c840.c b/netboot/w89c840.c
new file mode 100644
index 0000000..cc268c6
--- /dev/null
+++ b/netboot/w89c840.c
@@ -0,0 +1,934 @@
+/*
+ * Etherboot -  BOOTP/TFTP Bootstrap Program
+ *
+ * w89c840.c -- This file implements the winbond-840 driver for etherboot.
+ *
+ */
+
+/*
+ * Adapted by Igor V. Kovalenko
+ *  -- <garrison@mail.ru>
+ *   OR
+ *  -- <iko@crec.mipt.ru>
+ * Initial adaptaion stage, including testing, completed 23 August 2000.
+ */
+
+/*
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ *              date       version  by   what
+ *  Written:    Aug 20 2000  V0.10  iko  Initial revision.
+ * changes:     Aug 22 2000  V0.90  iko  Works!
+ *              Aug 23 2000  V0.91  iko  Cleanup, posted to etherboot
+ *                                       maintainer.
+ *              Aug 26 2000  V0.92  iko  Fixed Rx ring handling.
+ *                                       First Linux Kernel (TM)
+ *                                       successfully loaded using
+ *                                       this driver.
+ *              Jan 07 2001  V0.93  iko  Transmitter timeouts are handled
+ *                                       using timer2 routines. Proposed
+ *                                       by Ken Yap to eliminate CPU speed
+ *                                       dependency.
+ *
+ * This is the etherboot driver for cards based on Winbond W89c840F chip.
+ *
+ * It was written from skeleton source, with Donald Becker's winbond-840.c
+ * kernel driver as a guideline. Mostly the w89c840 related definitions
+ * and the lower level routines have been cut-and-pasted into this source.
+ *
+ * Frankly speaking, about 90% of the code was obtained using cut'n'paste
+ * sequence :) while the remainder appeared while brainstorming
+ * Linux Kernel 2.4.0-testX source code. Thanks, Donald and Linus!
+ *
+ * There was a demand for using this card in a rather large
+ * remote boot environment at MSKP OVTI Lab of
+ * Moscow Institute for Physics and Technology (MIPT) -- http://www.mipt.ru/
+ * so you may count that for motivation.
+ *
+ */
+
+/*
+ * If you want to see debugging output then define W89C840_DEBUG
+ */
+
+/*
+#define W89C840_DEBUG
+*/
+
+/*
+ * Keep using IO_OPS for Etherboot driver!
+ */
+#define USE_IO_OPS
+
+#include "etherboot.h"
+#include "nic.h"
+#include "pci.h"
+#include "cards.h"
+#include "timer.h"
+
+static const char *w89c840_version = "diver Version 0.92 - August 27, 2000";
+
+typedef unsigned char  u8;
+typedef   signed char  s8;
+typedef unsigned short u16;
+typedef   signed short s16;
+typedef unsigned int   u32;
+typedef   signed int   s32;
+
+/* Linux support functions */
+#define virt_to_bus(x) ((unsigned long)x)
+#define bus_to_virt(x) ((void *)x)
+
+#define virt_to_le32desc(addr)  virt_to_bus(addr)
+#define le32desc_to_virt(addr)  bus_to_virt(addr)
+
+/*
+#define cpu_to_le32(val) (val)
+#define le32_to_cpu(val) (val)
+*/
+
+/* Operational parameters that are set at compile time. */
+
+/* Keep the ring sizes a power of two for compile efficiency.
+   The compiler will convert <unsigned>'%'<2^N> into a bit mask.
+   Making the Tx ring too large decreases the effectiveness of channel
+   bonding and packet priority.
+   There are no ill effects from too-large receive rings. */
+#define TX_RING_SIZE    2
+
+#define RX_RING_SIZE    2
+
+/* The presumed FIFO size for working around the Tx-FIFO-overflow bug.
+   To avoid overflowing we don't queue again until we have room for a
+   full-size packet.
+ */
+#define TX_FIFO_SIZE (2048)
+#define TX_BUG_FIFO_LIMIT (TX_FIFO_SIZE-1514-16)
+
+/* Operational parameters that usually are not changed. */
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT  (10*TICKS_PER_MS)
+
+#define PKT_BUF_SZ  1536  /* Size of each temporary Rx buffer.*/
+
+/*
+ * Used to be this much CPU loops on Celeron@400 (?),
+ * now using real timer and TX_TIMEOUT!
+ * #define TX_LOOP_COUNT 10000000
+ */
+
+#if !defined(__OPTIMIZE__)
+#warning  You must compile this file with the correct options!
+#warning  See the last lines of the source file.
+#error You must compile this driver with "-O".
+#endif
+
+enum chip_capability_flags {CanHaveMII=1, HasBrokenTx=2};
+
+#ifdef USE_IO_OPS
+#define W840_FLAGS (PCI_USES_IO | PCI_ADDR0 | PCI_USES_MASTER)
+#else
+#define W840_FLAGS (PCI_USES_MEM | PCI_ADDR1 | PCI_USES_MASTER)
+#endif
+
+static u32 driver_flags = CanHaveMII | HasBrokenTx;
+
+/* This driver was written to use PCI memory space, however some x86 systems
+   work only with I/O space accesses.  Pass -DUSE_IO_OPS to use PCI I/O space
+   accesses instead of memory space. */
+
+#ifdef USE_IO_OPS
+#undef readb
+#undef readw
+#undef readl
+#undef writeb
+#undef writew
+#undef writel
+#define readb inb
+#define readw inw
+#define readl inl
+#define writeb outb
+#define writew outw
+#define writel outl
+#endif
+
+/* Offsets to the Command and Status Registers, "CSRs".
+   While similar to the Tulip, these registers are longword aligned.
+   Note: It's not useful to define symbolic names for every register bit in
+   the device.  The name can only partially document the semantics and make
+   the driver longer and more difficult to read.
+*/
+enum w840_offsets {
+    PCIBusCfg=0x00, TxStartDemand=0x04, RxStartDemand=0x08,
+    RxRingPtr=0x0C, TxRingPtr=0x10,
+    IntrStatus=0x14, NetworkConfig=0x18, IntrEnable=0x1C,
+    RxMissed=0x20, EECtrl=0x24, MIICtrl=0x24, BootRom=0x28, GPTimer=0x2C,
+    CurRxDescAddr=0x30, CurRxBufAddr=0x34,            /* Debug use */
+    MulticastFilter0=0x38, MulticastFilter1=0x3C, StationAddr=0x40,
+    CurTxDescAddr=0x4C, CurTxBufAddr=0x50,
+};
+
+/* Bits in the interrupt status/enable registers. */
+/* The bits in the Intr Status/Enable registers, mostly interrupt sources. */
+enum intr_status_bits {
+    NormalIntr=0x10000, AbnormalIntr=0x8000,
+    IntrPCIErr=0x2000, TimerInt=0x800,
+    IntrRxDied=0x100, RxNoBuf=0x80, IntrRxDone=0x40,
+    TxFIFOUnderflow=0x20, RxErrIntr=0x10,
+    TxIdle=0x04, IntrTxStopped=0x02, IntrTxDone=0x01,
+};
+
+/* Bits in the NetworkConfig register. */
+enum rx_mode_bits {
+    AcceptErr=0x80, AcceptRunt=0x40,
+    AcceptBroadcast=0x20, AcceptMulticast=0x10,
+    AcceptAllPhys=0x08, AcceptMyPhys=0x02,
+};
+
+enum mii_reg_bits {
+    MDIO_ShiftClk=0x10000, MDIO_DataIn=0x80000, MDIO_DataOut=0x20000,
+    MDIO_EnbOutput=0x40000, MDIO_EnbIn = 0x00000,
+};
+
+/* The Tulip Rx and Tx buffer descriptors. */
+struct w840_rx_desc {
+    s32 status;
+    s32 length;
+    u32 buffer1;
+    u32 next_desc;
+};
+
+struct w840_tx_desc {
+    s32 status;
+    s32 length;
+    u32 buffer1, buffer2;                /* We use only buffer 1.  */
+};
+
+/* Bits in network_desc.status */
+enum desc_status_bits {
+    DescOwn=0x80000000, DescEndRing=0x02000000, DescUseLink=0x01000000,
+    DescWholePkt=0x60000000, DescStartPkt=0x20000000, DescEndPkt=0x40000000,
+    DescIntr=0x80000000,
+};
+#define PRIV_ALIGN    15     /* Required alignment mask */
+#define PRIV_ALIGN_BYTES 32
+
+static struct winbond_private
+{
+    /* Descriptor rings first for alignment. */
+    struct w840_rx_desc rx_ring[RX_RING_SIZE];
+    struct w840_tx_desc tx_ring[TX_RING_SIZE];
+    struct net_device *next_module;        /* Link for devices of this type. */
+    void *priv_addr;                    /* Unaligned address for kfree */
+    const char *product_name;
+    /* Frequently used values: keep some adjacent for cache effect. */
+    int chip_id, drv_flags;
+    struct pci_dev *pci_dev;
+    int csr6;
+    struct w840_rx_desc *rx_head_desc;
+    unsigned int cur_rx, dirty_rx;        /* Producer/consumer ring indices */
+    unsigned int rx_buf_sz;                /* Based on MTU+slack. */
+    unsigned int cur_tx, dirty_tx;
+    int tx_q_bytes;
+    unsigned int tx_full:1;                /* The Tx queue is full. */
+    /* These values are keep track of the transceiver/media in use. */
+    unsigned int full_duplex:1;            /* Full-duplex operation requested. */
+    unsigned int duplex_lock:1;
+    unsigned int medialock:1;            /* Do not sense media. */
+    unsigned int default_port:4;        /* Last dev->if_port value. */
+    /* MII transceiver section. */
+    int mii_cnt;                        /* MII device addresses. */
+    u16 advertising;                    /* NWay media advertisement */
+    unsigned char phys[2];                /* MII device addresses. */
+} w840private __attribute__ ((aligned (PRIV_ALIGN_BYTES)));
+
+/* NIC specific static variables go here */
+
+static int ioaddr;
+static unsigned short eeprom [0x40];
+
+#ifdef    USE_LOWMEM_BUFFER
+#define rx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE)
+#define tx_packet ((char *)0x10000 - PKT_BUF_SZ * RX_RING_SIZE - PKT_BUF_SZ * TX_RING_SIZE)
+#else
+static char        rx_packet[PKT_BUF_SZ * RX_RING_SIZE];
+static char        tx_packet[PKT_BUF_SZ * TX_RING_SIZE];
+#endif
+
+static int  eeprom_read(long ioaddr, int location);
+static int  mdio_read(int base_address, int phy_id, int location);
+static void mdio_write(int base_address, int phy_id, int location, int value);
+
+static void check_duplex(void);
+static void set_rx_mode(void);
+static void init_ring(void);
+
+/*
+static void wait_long_time(void)
+{
+    printf("Paused - please read output above this line\n");
+    sleep(3);
+}
+*/
+
+#if defined W89C840_DEBUG
+static void decode_interrupt(u32 intr_status)
+{
+    printf("Interrupt status: ");
+
+#define TRACE_INTR(_intr_) \
+    if (intr_status & (_intr_)) { printf (" " #_intr_); }
+
+    TRACE_INTR(NormalIntr);
+    TRACE_INTR(AbnormalIntr);
+    TRACE_INTR(IntrPCIErr);
+    TRACE_INTR(TimerInt);
+    TRACE_INTR(IntrRxDied);
+    TRACE_INTR(RxNoBuf);
+    TRACE_INTR(IntrRxDone);
+    TRACE_INTR(TxFIFOUnderflow);
+    TRACE_INTR(RxErrIntr);
+    TRACE_INTR(TxIdle);
+    TRACE_INTR(IntrTxStopped);
+    TRACE_INTR(IntrTxDone);
+
+    printf("\n");
+    /*sleep(1);*/
+}
+#endif
+
+/**************************************************************************
+w89c840_reset - Reset adapter
+***************************************************************************/
+static void w89c840_reset(struct nic *nic)
+{
+    int i;
+
+    /* Reset the chip to erase previous misconfiguration.
+       No hold time required! */
+    writel(0x00000001, ioaddr + PCIBusCfg);
+
+    init_ring();
+
+    writel(virt_to_bus(w840private.rx_ring), ioaddr + RxRingPtr);
+    writel(virt_to_bus(w840private.tx_ring), ioaddr + TxRingPtr);
+
+    for (i = 0; i < ETH_ALEN; i++)
+        writeb(nic->node_addr[i], ioaddr + StationAddr + i);
+
+    /* Initialize other registers. */
+    /* Configure the PCI bus bursts and FIFO thresholds.
+       486: Set 8 longword cache alignment, 8 longword burst.
+       586: Set 16 longword cache alignment, no burst limit.
+       Cache alignment bits 15:14         Burst length 13:8
+        0000    <not allowed>         0000 align to cache    0800 8 longwords
+        4000    8  longwords        0100 1 longword        1000 16 longwords
+        8000    16 longwords        0200 2 longwords    2000 32 longwords
+        C000    32  longwords        0400 4 longwords
+       Wait the specified 50 PCI cycles after a reset by initializing
+       Tx and Rx queues and the address filter list. */
+
+    writel(0xE010, ioaddr + PCIBusCfg);
+
+    writel(0, ioaddr + RxStartDemand);
+    w840private.csr6 = 0x20022002;
+    check_duplex();
+    set_rx_mode();
+
+    /* Clear and Enable interrupts by setting the interrupt mask. */
+    writel(0x1A0F5, ioaddr + IntrStatus);
+    writel(0x1A0F5, ioaddr + IntrEnable);
+
+#if defined(W89C840_DEBUG)
+    printf("winbond-840 : Done reset.\n");
+#endif
+}
+
+static void handle_intr(u32 intr_stat)
+{
+    if ((intr_stat & (NormalIntr|AbnormalIntr)) == 0) {
+        /* we are polling, do not return now */
+        /*return 0;*/
+    } else {
+        /* Acknowledge all of the current interrupt sources ASAP. */
+        writel(intr_stat & 0x001ffff, ioaddr + IntrStatus);
+    }
+
+    if (intr_stat & AbnormalIntr) {
+        /* There was an abnormal interrupt */
+        printf("\n-=- Abnormal interrupt.\n");
+
+#if defined (W89C840_DEBUG)
+        decode_interrupt(intr_stat);
+#endif
+
+        if (intr_stat & RxNoBuf) {
+            /* There was an interrupt */
+            printf("-=- <=> No receive buffers available.\n");
+            writel(0, ioaddr + RxStartDemand);
+        }
+    }
+}
+
+/**************************************************************************
+w89c840_poll - Wait for a frame
+***************************************************************************/
+static int w89c840_poll(struct nic *nic)
+{
+    /* return true if there's an ethernet packet ready to read */
+    /* nic->packet should contain data on return */
+    /* nic->packetlen should contain length of data */
+    int packet_received = 0;
+
+    u32 intr_status = readl(ioaddr + IntrStatus);
+    /* handle_intr(intr_status); */ /* -- handled later */
+
+    do {
+        /* Code from netdev_rx(dev) */
+
+        int entry = w840private.cur_rx % RX_RING_SIZE;
+
+        struct w840_rx_desc *desc = w840private.rx_head_desc;
+        s32 status = desc->status;
+
+        if (status & DescOwn) {
+            /* DescOwn bit is still set, we should wait for RX to complete */
+            packet_received = 0;
+            break;
+        }
+
+        if ((status & 0x38008300) != 0x0300) {
+            if ((status & 0x38000300) != 0x0300) {
+                /* Ingore earlier buffers. */
+                if ((status & 0xffff) != 0x7fff) {
+                    printf("winbond-840 : Oversized Ethernet frame spanned "
+                           "multiple buffers, entry %d status %X !\n",
+                           w840private.cur_rx, status);
+                }
+            } else if (status & 0x8000) {
+                /* There was a fatal error. */
+#if defined(W89C840_DEBUG)
+                printf("winbond-840 : Receive error, Rx status %X :", status);
+                if (status & 0x0890) {
+                    printf(" RXLEN_ERROR");
+                }
+                if (status & 0x004C) {
+                    printf(", FRAME_ERROR");
+                }
+                if (status & 0x0002) {
+                    printf(", CRC_ERROR");
+                }
+                printf("\n");
+#endif
+
+                /* Simpy do a reset now... */
+                w89c840_reset(nic);
+
+                packet_received = 0;
+                break;
+            }
+        } else {
+            /* Omit the four octet CRC from the length. */
+            int pkt_len = ((status >> 16) & 0x7ff) - 4;
+
+#if defined(W89C840_DEBUG)
+            printf(" netdev_rx() normal Rx pkt ring %d length %d status %X\n", entry, pkt_len, status);
+#endif
+
+            nic->packetlen = pkt_len;
+
+            /* Check if the packet is long enough to accept without copying
+               to a minimally-sized skbuff. */
+
+            memcpy(nic->packet, le32desc_to_virt(w840private.rx_ring[entry].buffer1), pkt_len);
+            packet_received = 1;
+
+            /* Release buffer to NIC */
+            w840private.rx_ring[entry].status = DescOwn;
+
+#if defined(W89C840_DEBUG)
+            /* You will want this info for the initial debug. */
+            printf("  Rx data %hhX:%hhX:%hhX:%hhX:%hhX:"
+                   "%hhX %hhX:%hhX:%hhX:%hhX:%hhX:%hhX %hhX%hhX "
+                   "%hhX.%hhX.%hhX.%hhX.\n",
+                   nic->packet[0],  nic->packet[1],  nic->packet[2], nic->packet[3],
+                   nic->packet[4],  nic->packet[5],  nic->packet[6], nic->packet[7],
+                   nic->packet[8],  nic->packet[9],  nic->packet[10],
+                   nic->packet[11], nic->packet[12], nic->packet[13],
+                   nic->packet[14], nic->packet[15], nic->packet[16],
+                   nic->packet[17]);
+#endif
+
+        }
+
+        entry = (++w840private.cur_rx) % RX_RING_SIZE;
+        w840private.rx_head_desc = &w840private.rx_ring[entry];
+    } while (0);
+
+    if (intr_status & (AbnormalIntr | TxFIFOUnderflow | IntrPCIErr |TimerInt | IntrTxStopped)) {
+        handle_intr(intr_status);
+    }
+
+    return packet_received;
+}
+
+/**************************************************************************
+w89c840_transmit - Transmit a frame
+***************************************************************************/
+
+static void w89c840_transmit(
+    struct nic *nic,
+    const char *d,            /* Destination */
+    unsigned int t,            /* Type */
+    unsigned int s,            /* size */
+    const char *p)            /* Packet */
+{
+    /* send the packet to destination */
+    unsigned entry;
+    int transmit_status;
+
+    /* Caution: the write order is important here, set the field
+       with the "ownership" bits last. */
+
+    /* Fill in our transmit buffer */
+    entry = w840private.cur_tx % TX_RING_SIZE;
+
+    memcpy (tx_packet, d, ETH_ALEN);    /* dst */
+    memcpy (tx_packet + ETH_ALEN, nic->node_addr, ETH_ALEN);/* src */
+
+    *((char *) tx_packet + 12) = t >> 8;    /* type */
+    *((char *) tx_packet + 13) = t;
+
+    memcpy (tx_packet + ETH_HLEN, p, s);
+    s += ETH_HLEN;
+
+    while (s < ETH_ZLEN)
+    *((char *) tx_packet + ETH_HLEN + (s++)) = 0;
+
+    w840private.tx_ring[entry].buffer1 = virt_to_le32desc(tx_packet);
+
+    w840private.tx_ring[entry].length = (DescWholePkt | s);
+    if (entry >= TX_RING_SIZE-1)         /* Wrap ring */
+        w840private.tx_ring[entry].length |= (DescIntr | DescEndRing);
+    w840private.tx_ring[entry].status = (DescOwn);
+    w840private.cur_tx++;
+
+    w840private.tx_q_bytes += s;
+    writel(0, ioaddr + TxStartDemand);
+
+    /* Work around horrible bug in the chip by marking the queue as full
+       when we do not have FIFO room for a maximum sized packet. */
+
+    if ((w840private.drv_flags & HasBrokenTx) && w840private.tx_q_bytes > TX_BUG_FIFO_LIMIT) {
+        /* Actually this is left to help finding error tails later in debugging...
+         * See Linux kernel driver in winbond-840.c for details.
+         */
+        w840private.tx_full = 1;
+    }
+
+#if defined(W89C840_DEBUG)
+    printf("winbond-840 : Transmit frame # %d size %d queued in slot %d.\n", w840private.cur_tx, s, entry);
+#endif
+
+    /* Now wait for TX to complete. */
+    transmit_status = w840private.tx_ring[entry].status;
+
+    load_timer2(TX_TIMEOUT);
+
+    {
+        u32 intr_stat = 0;
+
+        while (1) {
+
+            intr_stat = readl(ioaddr + IntrStatus);
+#if defined(W89C840_DEBUG)
+            decode_interrupt(intr_stat);
+#endif
+
+            if (intr_stat & (NormalIntr | IntrTxDone)) {
+
+                while ( (transmit_status & DescOwn) && timer2_running()) {
+
+                    transmit_status = w840private.tx_ring[entry].status;
+                }
+
+                writel(intr_stat & 0x0001ffff, ioaddr + IntrStatus);
+                break;
+            }
+        }
+    }
+
+    if ((transmit_status & DescOwn) == 0) {
+
+#if defined(W89C840_DEBUG)
+        printf("winbond-840 : transmission complete after %d wait loop iterations, status %X\n",
+               TX_LOOP_COUNT - transmit_loop_counter, w840private.tx_ring[entry].status);
+#endif
+
+        return;
+    }
+
+    /* Transmit timed out... */
+
+    printf("winbond-840 : transmission TIMEOUT : status %X\n", w840private.tx_ring[entry].status);
+
+    return;
+}
+
+/**************************************************************************
+w89c840_disable - Turn off ethernet interface
+***************************************************************************/
+static void w89c840_disable(struct nic *nic)
+{
+    /* Don't know what to do to disable the board. Is this needed at all? */
+    /* Yes, a live NIC can corrupt the loaded memory later [Ken] */
+    /* Stop the chip's Tx and Rx processes. */
+    writel(w840private.csr6 &= ~0x20FA, ioaddr + NetworkConfig);
+}
+
+/**************************************************************************
+w89c840_probe - Look for an adapter, this routine's visible to the outside
+***************************************************************************/
+struct nic *w89c840_probe(struct nic *nic, unsigned short *probe_addrs, struct pci_device *p)
+{
+    u16 sum = 0;
+    int i, j, to;
+    unsigned short value;
+    int options;
+    int promisc;
+
+    if (probe_addrs == 0 || probe_addrs[0] == 0)
+        return 0;
+
+    ioaddr = probe_addrs[0]; /* Mask the bit that says "this is an io addr" */
+
+#if defined(W89C840_DEBUG)
+    printf("winbond-840: PCI bus %hhX device function %hhX: I/O address: %hX\n", p->bus, p->devfn, ioaddr);
+#endif
+
+    ioaddr = ioaddr & ~3; /* Mask the bit that says "this is an io addr" */
+
+    /* if probe_addrs is 0, then routine can use a hardwired default */
+
+    /* From Matt Hortman <mbhortman@acpthinclient.com> */
+    if (p->vendor == PCI_VENDOR_ID_WINBOND2
+        && p->dev_id == PCI_DEVICE_ID_WINBOND2_89C840) {
+
+        /* detected "Winbond W89c840 Fast Ethernet PCI NIC" */
+
+    } else if ( p->vendor == PCI_VENDOR_ID_COMPEX
+                && p->dev_id == PCI_DEVICE_ID_COMPEX_RL100ATX) {
+
+        /* detected "Compex RL100ATX Fast Ethernet PCI NIC" */
+
+    } else {
+        /* Gee, guess what? They missed again. */
+        printf("device ID : %X - is not a Compex RL100ATX NIC.\n", p->dev_id);
+        return 0;
+    }
+
+    printf(" %s\n", w89c840_version);
+
+    adjust_pci_device(p);
+
+    /* Ok. Got one. Read the eeprom. */
+    for (j = 0, i = 0; i < 0x40; i++) {
+        value = eeprom_read(ioaddr, i);
+        eeprom[i] = value;
+        sum += value;
+    }
+
+    for (i=0;i<ETH_ALEN;i++) {
+        nic->node_addr[i] =  (eeprom[i/2] >> (8*(i&1))) & 0xff;
+    }
+    printf ("Ethernet addr: %!\n", nic->node_addr);
+
+#if defined(W89C840_DEBUG)
+    printf("winbond-840: EEPROM checksum %hX, got eeprom", sum);
+#endif
+
+    /* Reset the chip to erase previous misconfiguration.
+       No hold time required! */
+    writel(0x00000001, ioaddr + PCIBusCfg);
+
+    if (driver_flags & CanHaveMII) {
+        int phy, phy_idx = 0;
+        for (phy = 1; phy < 32 && phy_idx < 4; phy++) {
+            int mii_status = mdio_read(ioaddr, phy, 1);
+            if (mii_status != 0xffff  &&  mii_status != 0x0000) {
+                w840private.phys[phy_idx++] = phy;
+                w840private.advertising = mdio_read(ioaddr, phy, 4);
+
+#if defined(W89C840_DEBUG)
+                printf("winbond-840 : MII PHY found at address %d, status "
+                       "%X advertising %hX.\n", phy, mii_status, w840private.advertising);
+#endif
+
+            }
+        }
+
+        w840private.mii_cnt = phy_idx;
+
+        if (phy_idx == 0) {
+                printf("winbond-840 : MII PHY not found -- this device may not operate correctly.\n");
+        }
+    }
+
+    /* point to NIC specific routines */
+    nic->reset = w89c840_reset;
+    nic->poll = w89c840_poll;
+    nic->transmit = w89c840_transmit;
+    nic->disable = w89c840_disable;
+
+    w89c840_reset(nic);
+
+    return nic;
+}
+
+/* Read the EEPROM and MII Management Data I/O (MDIO) interfaces.  These are
+   often serial bit streams generated by the host processor.
+   The example below is for the common 93c46 EEPROM, 64 16 bit words. */
+
+/* Delay between EEPROM clock transitions.
+   No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
+   a delay.  Note that pre-2.0.34 kernels had a cache-alignment bug that
+   made udelay() unreliable.
+   The old method of using an ISA access as a delay, __SLOW_DOWN_IO__, is
+   depricated.
+*/
+#define eeprom_delay(ee_addr)    readl(ee_addr)
+
+enum EEPROM_Ctrl_Bits {
+    EE_ShiftClk=0x02, EE_Write0=0x801, EE_Write1=0x805,
+    EE_ChipSelect=0x801, EE_DataIn=0x08,
+};
+
+/* The EEPROM commands include the alway-set leading bit. */
+enum EEPROM_Cmds {
+    EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
+};
+
+static int eeprom_read(long addr, int location)
+{
+    int i;
+    int retval = 0;
+    int ee_addr = addr + EECtrl;
+    int read_cmd = location | EE_ReadCmd;
+    writel(EE_ChipSelect, ee_addr);
+
+    /* Shift the read command bits out. */
+    for (i = 10; i >= 0; i--) {
+        short dataval = (read_cmd & (1 << i)) ? EE_Write1 : EE_Write0;
+        writel(dataval, ee_addr);
+        eeprom_delay(ee_addr);
+        writel(dataval | EE_ShiftClk, ee_addr);
+        eeprom_delay(ee_addr);
+    }
+    writel(EE_ChipSelect, ee_addr);
+
+    for (i = 16; i > 0; i--) {
+        writel(EE_ChipSelect | EE_ShiftClk, ee_addr);
+        eeprom_delay(ee_addr);
+        retval = (retval << 1) | ((readl(ee_addr) & EE_DataIn) ? 1 : 0);
+        writel(EE_ChipSelect, ee_addr);
+        eeprom_delay(ee_addr);
+    }
+
+    /* Terminate the EEPROM access. */
+    writel(0, ee_addr);
+    return retval;
+}
+
+/*  MII transceiver control section.
+    Read and write the MII registers using software-generated serial
+    MDIO protocol.  See the MII specifications or DP83840A data sheet
+    for details.
+
+    The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
+    met by back-to-back 33Mhz PCI cycles. */
+#define mdio_delay(mdio_addr) readl(mdio_addr)
+
+/* Set iff a MII transceiver on any interface requires mdio preamble.
+   This only set with older tranceivers, so the extra
+   code size of a per-interface flag is not worthwhile. */
+static char mii_preamble_required = 1;
+
+#define MDIO_WRITE0 (MDIO_EnbOutput)
+#define MDIO_WRITE1 (MDIO_DataOut | MDIO_EnbOutput)
+
+/* Generate the preamble required for initial synchronization and
+   a few older transceivers. */
+static void mdio_sync(long mdio_addr)
+{
+    int bits = 32;
+
+    /* Establish sync by sending at least 32 logic ones. */
+    while (--bits >= 0) {
+        writel(MDIO_WRITE1, mdio_addr);
+        mdio_delay(mdio_addr);
+        writel(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr);
+        mdio_delay(mdio_addr);
+    }
+}
+
+static int mdio_read(int base_address, int phy_id, int location)
+{
+    long mdio_addr = base_address + MIICtrl;
+    int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
+    int i, retval = 0;
+
+    if (mii_preamble_required)
+        mdio_sync(mdio_addr);
+
+    /* Shift the read command bits out. */
+    for (i = 15; i >= 0; i--) {
+        int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
+
+        writel(dataval, mdio_addr);
+        mdio_delay(mdio_addr);
+        writel(dataval | MDIO_ShiftClk, mdio_addr);
+        mdio_delay(mdio_addr);
+    }
+    /* Read the two transition, 16 data, and wire-idle bits. */
+    for (i = 20; i > 0; i--) {
+        writel(MDIO_EnbIn, mdio_addr);
+        mdio_delay(mdio_addr);
+        retval = (retval << 1) | ((readl(mdio_addr) & MDIO_DataIn) ? 1 : 0);
+        writel(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
+        mdio_delay(mdio_addr);
+    }
+    return (retval>>1) & 0xffff;
+}
+
+static void mdio_write(int base_address, int phy_id, int location, int value)
+{
+    long mdio_addr = base_address + MIICtrl;
+    int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
+    int i;
+
+    if (location == 4  &&  phy_id == w840private.phys[0])
+        w840private.advertising = value;
+
+    if (mii_preamble_required)
+        mdio_sync(mdio_addr);
+
+    /* Shift the command bits out. */
+    for (i = 31; i >= 0; i--) {
+        int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
+
+        writel(dataval, mdio_addr);
+        mdio_delay(mdio_addr);
+        writel(dataval | MDIO_ShiftClk, mdio_addr);
+        mdio_delay(mdio_addr);
+    }
+    /* Clear out extra bits. */
+    for (i = 2; i > 0; i--) {
+        writel(MDIO_EnbIn, mdio_addr);
+        mdio_delay(mdio_addr);
+        writel(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
+        mdio_delay(mdio_addr);
+    }
+    return;
+}
+
+static void check_duplex(void)
+{
+    int mii_reg5 = mdio_read(ioaddr, w840private.phys[0], 5);
+    int negotiated =  mii_reg5 & w840private.advertising;
+    int duplex;
+
+    if (w840private.duplex_lock  ||  mii_reg5 == 0xffff)
+        return;
+
+    duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
+    if (w840private.full_duplex != duplex) {
+        w840private.full_duplex = duplex;       
+
+#if defined(W89C840_DEBUG)
+        printf("winbond-840 : Setting %s-duplex based on MII # %d negotiated capability %X\n",
+               duplex ? "full" : "half", w840private.phys[0], negotiated);
+#endif
+
+        w840private.csr6 &= ~0x200;
+        w840private.csr6 |= duplex ? 0x200 : 0;
+    }
+}
+
+static void set_rx_mode(void)
+{
+    u32 mc_filter[2];            /* Multicast hash filter */
+    u32 rx_mode;
+
+    /* Accept all multicasts from now on. */
+    memset(mc_filter, 0xff, sizeof(mc_filter));
+
+/*
+ * Actually, should work OK with multicast enabled. -- iko
+ */
+/*
+ *  rx_mode = AcceptBroadcast | AcceptMyPhys | AcceptMulticast;
+ */
+    rx_mode = AcceptBroadcast | AcceptMyPhys;
+
+    writel(mc_filter[0], ioaddr + MulticastFilter0);
+    writel(mc_filter[1], ioaddr + MulticastFilter1);
+    w840private.csr6 &= ~0x00F8;
+    w840private.csr6 |= rx_mode;
+    writel(w840private.csr6, ioaddr + NetworkConfig);
+
+#if defined(W89C840_DEBUG)
+    printf("winbond-840 : Done setting RX mode.\n");
+#endif
+}
+
+/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
+static void init_ring(void)
+{
+    int i;
+    char * p;
+
+    w840private.tx_full = 0;
+    w840private.tx_q_bytes = w840private.cur_rx = w840private.cur_tx = 0;
+    w840private.dirty_rx = w840private.dirty_tx = 0;
+
+    w840private.rx_buf_sz = PKT_BUF_SZ;
+    w840private.rx_head_desc = &w840private.rx_ring[0];
+
+    /* Initial all Rx descriptors. Fill in the Rx buffers. */
+
+    p = &rx_packet[0];
+
+    for (i = 0; i < RX_RING_SIZE; i++) {
+        w840private.rx_ring[i].length = w840private.rx_buf_sz;
+        w840private.rx_ring[i].status = 0;
+        w840private.rx_ring[i].next_desc = virt_to_le32desc(&w840private.rx_ring[i+1]);
+
+        w840private.rx_ring[i].buffer1 = virt_to_le32desc(p + (PKT_BUF_SZ * i));
+        w840private.rx_ring[i].status = DescOwn | DescIntr;
+    }
+
+    /* Mark the last entry as wrapping the ring. */
+    w840private.rx_ring[i-1].length |= DescEndRing;
+    w840private.rx_ring[i-1].next_desc = virt_to_le32desc(&w840private.rx_ring[0]);
+
+    w840private.dirty_rx = (unsigned int)(i - RX_RING_SIZE);
+
+    for (i = 0; i < TX_RING_SIZE; i++) {
+        w840private.tx_ring[i].status = 0;
+    }
+    return;
+}
diff --git a/stage1/Makefile.am b/stage1/Makefile.am
new file mode 100644
index 0000000..0afc285
--- /dev/null
+++ b/stage1/Makefile.am
@@ -0,0 +1,15 @@
+pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
+nodist_pkglib_DATA = stage1
+
+CLEANFILES = $(nodist_pkglib_DATA)
+
+# We can't use builtins or standard includes.
+AM_CCASFLAGS = $(STAGE1_CFLAGS) -fno-builtin -nostdinc
+LDFLAGS = -nostdlib -Wl,-N,-Ttext,7C00
+
+noinst_PROGRAMS = stage1.exec
+stage1_exec_SOURCES = stage1.S stage1.h
+
+SUFFIXES = .exec
+.exec:
+	$(OBJCOPY) -O binary $< $@
diff --git a/stage1/Makefile.in b/stage1/Makefile.in
new file mode 100644
index 0000000..7134bdf
--- /dev/null
+++ b/stage1/Makefile.in
@@ -0,0 +1,433 @@
+# Makefile.in generated by automake 1.9.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  Free Software Foundation, Inc.
+# This Makefile.in 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 distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+SOURCES = $(stage1_exec_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+noinst_PROGRAMS = stage1.exec$(EXEEXT)
+subdir = stage1
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+PROGRAMS = $(noinst_PROGRAMS)
+am_stage1_exec_OBJECTS = stage1.$(OBJEXT)
+stage1_exec_OBJECTS = $(am_stage1_exec_OBJECTS)
+stage1_exec_LDADD = $(LDADD)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+CCASCOMPILE = $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS)
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(stage1_exec_SOURCES)
+DIST_SOURCES = $(stage1_exec_SOURCES)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(pkglibdir)"
+nodist_pkglibDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(nodist_pkglib_DATA)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_EXAMPLE_KERNEL_FALSE = @BUILD_EXAMPLE_KERNEL_FALSE@
+BUILD_EXAMPLE_KERNEL_TRUE = @BUILD_EXAMPLE_KERNEL_TRUE@
+CC = @CC@
+CCAS = @CCAS@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISKLESS_SUPPORT_FALSE = @DISKLESS_SUPPORT_FALSE@
+DISKLESS_SUPPORT_TRUE = @DISKLESS_SUPPORT_TRUE@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FSYS_CFLAGS = @FSYS_CFLAGS@
+GRUB_CFLAGS = @GRUB_CFLAGS@
+GRUB_LIBS = @GRUB_LIBS@
+HERCULES_SUPPORT_FALSE = @HERCULES_SUPPORT_FALSE@
+HERCULES_SUPPORT_TRUE = @HERCULES_SUPPORT_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = -nostdlib -Wl,-N,-Ttext,7C00
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
+NETBOOT_SUPPORT_FALSE = @NETBOOT_SUPPORT_FALSE@
+NETBOOT_SUPPORT_TRUE = @NETBOOT_SUPPORT_TRUE@
+NET_CFLAGS = @NET_CFLAGS@
+NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
+OBJCOPY = @OBJCOPY@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+RANLIB = @RANLIB@
+SERIAL_SPEED_SIMULATION_FALSE = @SERIAL_SPEED_SIMULATION_FALSE@
+SERIAL_SPEED_SIMULATION_TRUE = @SERIAL_SPEED_SIMULATION_TRUE@
+SERIAL_SUPPORT_FALSE = @SERIAL_SUPPORT_FALSE@
+SERIAL_SUPPORT_TRUE = @SERIAL_SUPPORT_TRUE@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STAGE1_CFLAGS = @STAGE1_CFLAGS@
+STAGE2_CFLAGS = @STAGE2_CFLAGS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_OBJCOPY = @ac_ct_OBJCOPY@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+nodist_pkglib_DATA = stage1
+CLEANFILES = $(nodist_pkglib_DATA)
+
+# We can't use builtins or standard includes.
+AM_CCASFLAGS = $(STAGE1_CFLAGS) -fno-builtin -nostdinc
+stage1_exec_SOURCES = stage1.S stage1.h
+SUFFIXES = .exec
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .exec .S .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  stage1/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu  stage1/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstPROGRAMS:
+	-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+stage1.exec$(EXEEXT): $(stage1_exec_OBJECTS) $(stage1_exec_DEPENDENCIES) 
+	@rm -f stage1.exec$(EXEEXT)
+	$(LINK) $(stage1_exec_LDFLAGS) $(stage1_exec_OBJECTS) $(stage1_exec_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+.S.o:
+	$(CCASCOMPILE) -c $<
+
+.S.obj:
+	$(CCASCOMPILE) -c `$(CYGPATH_W) '$<'`
+uninstall-info-am:
+install-nodist_pkglibDATA: $(nodist_pkglib_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(pkglibdir)" || $(mkdir_p) "$(DESTDIR)$(pkglibdir)"
+	@list='$(nodist_pkglib_DATA)'; for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  f=$(am__strip_dir) \
+	  echo " $(nodist_pkglibDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkglibdir)/$$f'"; \
+	  $(nodist_pkglibDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkglibdir)/$$f"; \
+	done
+
+uninstall-nodist_pkglibDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(nodist_pkglib_DATA)'; for p in $$list; do \
+	  f=$(am__strip_dir) \
+	  echo " rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	    $$tags $$unique; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$tags $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+	list='$(DISTFILES)'; for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+	  esac; \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+	    dir="/$$dir"; \
+	    $(mkdir_p) "$(distdir)$$dir"; \
+	  else \
+	    dir=''; \
+	  fi; \
+	  if test -d $$d/$$file; then \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(DATA)
+installdirs:
+	for dir in "$(DESTDIR)$(pkglibdir)"; do \
+	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-noinstPROGRAMS mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-nodist_pkglibDATA
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-nodist_pkglibDATA
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+	clean-noinstPROGRAMS ctags distclean distclean-compile \
+	distclean-generic distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-exec install-exec-am install-info \
+	install-info-am install-man install-nodist_pkglibDATA \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
+	tags uninstall uninstall-am uninstall-info-am \
+	uninstall-nodist_pkglibDATA
+
+.exec:
+	$(OBJCOPY) -O binary $< $@
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/stage1/stage1.S b/stage1/stage1.S
new file mode 100644
index 0000000..985963d
--- /dev/null
+++ b/stage1/stage1.S
@@ -0,0 +1,499 @@
+/* -*-Asm-*- */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,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 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.
+ */
+
+#include <stage1.h>
+	
+/*
+ *  defines for the code go here
+ */
+
+	/* Absolute addresses
+	   This makes the assembler generate the address without support
+	   from the linker. (ELF can't relocate 16-bit addresses!) */
+#define ABS(x) (x-_start+0x7c00)
+
+	/* Print message string */
+#define MSG(x)	movw $ABS(x), %si; call message
+
+	/* XXX:	binutils-2.9.1.0.x doesn't produce a short opcode for this. */
+#define	MOV_MEM_TO_AL(x)	.byte 0xa0;  .word x
+	
+	.file	"stage1.S"
+
+	.text
+
+	/* Tell GAS to generate 16-bit instructions so that this code works
+	   in real mode. */
+	.code16
+
+.globl _start; _start:
+	/*
+	 * _start is loaded at 0x7c00 and is jumped to with CS:IP 0:0x7c00
+	 */
+
+	/*
+	 * Beginning of the sector is compatible with the FAT/HPFS BIOS
+	 * parameter block.
+	 */
+
+	jmp	after_BPB
+	nop	/* do I care about this ??? */
+
+	/*
+	 * This space is for the BIOS parameter block!!!!  Don't change
+	 * the first jump, nor start the code anywhere but right after
+	 * this area.
+	 */
+
+	. = _start + 4
+
+	/* scratch space */
+mode:
+	.byte	0
+disk_address_packet:	
+sectors:
+	.long	0
+heads:
+	.long	0
+cylinders:
+	.word	0
+sector_start:
+	.byte	0
+head_start:
+	.byte	0
+cylinder_start:
+	.word	0
+	/* more space... */
+
+	. = _start + STAGE1_BPBEND
+
+	/*
+	 * End of BIOS parameter block.
+	 */
+
+stage1_version:	
+	.byte	COMPAT_VERSION_MAJOR, COMPAT_VERSION_MINOR
+boot_drive:	
+	.byte	GRUB_INVALID_DRIVE	/* the disk to load stage2 from */
+force_lba:
+	.byte	0
+stage2_address:
+	.word	0x8000
+stage2_sector:
+	.long	1
+stage2_segment:
+	.word	0x800
+
+after_BPB:
+
+/* general setup */
+	cli		/* we're not safe here! */
+
+	/*
+	 * This is a workaround for buggy BIOSes which don't pass boot
+	 * drive correctly. If GRUB is installed into a HDD, check if
+	 * DL is masked correctly. If not, assume that the BIOS passed
+	 * a bogus value and set DL to 0x80, since this is the only
+	 * possible boot drive. If GRUB is installed into a floppy,
+	 * this does nothing (only jump).
+	 */
+boot_drive_check:	
+	jmp	1f
+	testb	$0x80, %dl
+	jnz	1f
+	movb	$0x80, %dl
+1:	
+
+	/*
+	 * ljmp to the next instruction because some bogus BIOSes
+	 * jump to 07C0:0000 instead of 0000:7C00.
+	 */
+	ljmp	$0, $ABS(real_start)
+
+real_start:	
+
+	/* set up %ds and %ss as offset from 0 */
+	xorw	%ax, %ax
+	movw	%ax, %ds
+	movw	%ax, %ss
+
+	/* set up the REAL stack */
+	movw	$STAGE1_STACKSEG, %sp
+
+	sti		/* we're safe again */
+
+	/*
+	 *  Check if we have a forced disk reference here
+	 */
+	MOV_MEM_TO_AL(ABS(boot_drive))	/* movb	ABS(boot_drive), %al */
+	cmpb	$GRUB_INVALID_DRIVE, %al
+	je	1f
+	movb	%al, %dl
+1:
+	/* save drive reference first thing! */
+	pushw	%dx
+
+	/* print a notification message on the screen */
+	MSG(notification_string)
+
+	/* do not probe LBA if the drive is a floppy */
+	testb	$STAGE1_BIOS_HD_FLAG, %dl
+	jz	chs_mode
+			
+	/* check if LBA is supported */
+	movb	$0x41, %ah
+	movw	$0x55aa, %bx
+	int	$0x13
+
+	/* 
+	 *  %dl may have been clobbered by INT 13, AH=41H.
+	 *  This happens, for example, with AST BIOS 1.04.
+	 */
+	popw	%dx
+	pushw	%dx
+
+	/* use CHS if fails */
+	jc	chs_mode
+	cmpw	$0xaa55, %bx
+	jne	chs_mode
+
+	/* check if AH=0x42 is supported if FORCE_LBA is zero */
+	MOV_MEM_TO_AL(ABS(force_lba))	/* movb	ABS(force_lba), %al */
+	testb	%al, %al
+	jnz	lba_mode
+	andw	$1, %cx
+	jz	chs_mode
+	
+lba_mode:
+	/* save the total number of sectors */
+	movl	0x10(%si), %ecx
+
+	/* set %si to the disk address packet */
+	movw	$ABS(disk_address_packet), %si
+
+	/* set the mode to non-zero */
+	movb	$1, -1(%si)
+	
+	movl	ABS(stage2_sector), %ebx
+
+	/* the size and the reserved byte */
+	movw	$0x0010, (%si)
+
+	/* the blocks */
+	movw	$1, 2(%si)
+	
+	/* the absolute address (low 32 bits) */
+	movl	%ebx, 8(%si)
+
+	/* the segment of buffer address */
+	movw	$STAGE1_BUFFERSEG, 6(%si)
+
+	xorl	%eax, %eax
+	movw	%ax, 4(%si)
+	movl	%eax, 12(%si)
+	
+/*
+ * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
+ *	Call with	%ah = 0x42
+ *			%dl = drive number
+ *			%ds:%si = segment:offset of disk address packet
+ *	Return:
+ *			%al = 0x0 on success; err code on failure
+ */
+
+	movb	$0x42, %ah
+	int	$0x13
+
+	/* LBA read is not supported, so fallback to CHS.  */
+	jc	chs_mode
+
+	movw	$STAGE1_BUFFERSEG, %bx
+	jmp	copy_buffer
+		
+chs_mode:	
+	/*
+	 *  Determine the hard disk geometry from the BIOS!
+	 *  We do this first, so that LS-120 IDE floppies work correctly.
+	 */
+	movb	$8, %ah
+	int	$0x13
+	jnc	final_init
+
+	/*
+	 *  The call failed, so maybe use the floppy probe instead.
+	 */
+	testb	$STAGE1_BIOS_HD_FLAG, %dl
+	jz	floppy_probe
+
+	/* Nope, we definitely have a hard disk, and we're screwed. */
+	jmp	hd_probe_error
+
+final_init:
+	
+	movw	$ABS(sectors), %si
+
+	/* set the mode to zero */
+	movb	$0, -1(%si)
+	
+	/* save number of heads */
+	xorl	%eax, %eax
+	movb	%dh, %al
+	incw	%ax
+	movl	%eax, 4(%si)
+
+	xorw	%dx, %dx
+	movb	%cl, %dl
+	shlw	$2, %dx
+	movb	%ch, %al
+	movb	%dh, %ah
+
+	/* save number of cylinders */
+	incw	%ax
+	movw	%ax, 8(%si)
+
+	xorw	%ax, %ax
+	movb	%dl, %al
+	shrb	$2, %al
+
+	/* save number of sectors */
+	movl	%eax, (%si)
+
+setup_sectors:
+	/* load logical sector start (bottom half) */
+	movl	ABS(stage2_sector), %eax
+
+	/* zero %edx */
+	xorl	%edx, %edx
+
+	/* divide by number of sectors */
+	divl	(%si)
+
+	/* save sector start */
+	movb	%dl, 10(%si)
+
+	xorl	%edx, %edx	/* zero %edx */
+	divl	4(%si)		/* divide by number of heads */
+
+	/* save head start */
+	movb	%dl, 11(%si)
+
+	/* save cylinder start */
+	movw	%ax, 12(%si)
+
+	/* do we need too many cylinders? */
+	cmpw	8(%si), %ax
+	jge	geometry_error
+
+/*
+ *  This is the loop for taking care of BIOS geometry translation (ugh!)
+ */
+
+	/* get high bits of cylinder */
+	movb	13(%si), %dl
+
+	shlb	$6, %dl		/* shift left by 6 bits */
+	movb	10(%si), %cl	/* get sector */
+
+	incb	%cl		/* normalize sector (sectors go
+					from 1-N, not 0-(N-1) ) */
+	orb	%dl, %cl	/* composite together */
+	movb	12(%si), %ch	/* sector+hcyl in cl, cylinder in ch */
+
+	/* restore %dx */
+	popw	%dx
+	
+	/* head number */
+	movb	11(%si), %dh
+
+/*
+ * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
+ *	Call with	%ah = 0x2
+ *			%al = number of sectors
+ *			%ch = cylinder
+ *			%cl = sector (bits 6-7 are high bits of "cylinder")
+ *			%dh = head
+ *			%dl = drive (0x80 for hard disk, 0x0 for floppy disk)
+ *			%es:%bx = segment:offset of buffer
+ *	Return:
+ *			%al = 0x0 on success; err code on failure
+ */
+
+	movw	$STAGE1_BUFFERSEG, %bx
+	movw	%bx, %es	/* load %es segment with disk buffer */
+
+	xorw	%bx, %bx	/* %bx = 0, put it at 0 in the segment */
+	movw	$0x0201, %ax	/* function 2 */
+	int	$0x13
+
+	jc	read_error
+
+	movw	%es, %bx
+	
+copy_buffer:
+	movw	ABS(stage2_segment), %es
+
+	/*
+	 * We need to save %cx and %si because the startup code in
+	 * stage2 uses them without initializing them.
+	 */
+	pusha
+	pushw	%ds
+	
+	movw	$0x100, %cx
+	movw	%bx, %ds
+	xorw	%si, %si
+	xorw	%di, %di
+	
+	cld
+	
+	rep
+	movsw
+
+	popw	%ds
+	popa
+
+	/* boot stage2 */
+	jmp	*(stage2_address)
+
+/* END OF MAIN LOOP */
+
+/*
+ * BIOS Geometry translation error (past the end of the disk geometry!).
+ */
+geometry_error:
+	MSG(geometry_error_string)
+	jmp	general_error
+
+/*
+ * Disk probe failure.
+ */
+hd_probe_error:
+	MSG(hd_probe_error_string)
+	jmp	general_error
+
+/*
+ * Read error on the disk.
+ */
+read_error:
+	MSG(read_error_string)
+
+general_error:
+	MSG(general_error_string)
+
+/* go here when you need to stop the machine hard after an error condition */
+stop:	jmp	stop
+
+notification_string:	.string "GRUB "
+geometry_error_string:	.string "Geom"
+hd_probe_error_string:	.string "Hard Disk"
+read_error_string:	.string "Read"
+general_error_string:	.string " Error"
+
+/*
+ * message: write the string pointed to by %si
+ *
+ *   WARNING: trashes %si, %ax, and %bx
+ */
+
+	/*
+	 * Use BIOS "int 10H Function 0Eh" to write character in teletype mode
+	 *	%ah = 0xe	%al = character
+	 *	%bh = page	%bl = foreground color (graphics modes)
+	 */
+1:
+	movw	$0x0001, %bx
+	movb	$0xe, %ah
+	int	$0x10		/* display a byte */
+message:
+	lodsb
+	cmpb	$0, %al
+	jne	1b	/* if not end of string, jmp to display */
+	ret
+
+	/*
+	 *  Windows NT breaks compatibility by embedding a magic
+	 *  number here.
+	 */
+
+	. = _start + STAGE1_WINDOWS_NT_MAGIC
+nt_magic:	
+	.long 0
+	.word 0
+
+	/*
+	 *  This is where an MBR would go if on a hard disk.  The code
+	 *  here isn't even referenced unless we're on a floppy.  Kinda
+	 *  sneaky, huh?
+	 */
+
+part_start:	
+	. = _start + STAGE1_PARTSTART
+
+probe_values:
+	.byte	36, 18, 15, 9, 0
+
+floppy_probe:
+/*
+ *  Perform floppy probe.
+ */
+
+	movw	$ABS(probe_values-1), %si
+
+probe_loop:
+	/* reset floppy controller INT 13h AH=0 */
+	xorw	%ax, %ax
+	int	$0x13
+
+	incw	%si
+	movb	(%si), %cl
+
+	/* if number of sectors is 0, display error and die */
+	cmpb	$0, %cl
+	jne	1f
+
+/*
+ * Floppy disk probe failure.
+ */
+	MSG(fd_probe_error_string)
+	jmp	general_error
+
+fd_probe_error_string:	.string "Floppy"
+
+1:
+	/* perform read */
+	movw	$STAGE1_BUFFERSEG, %bx
+	movw	$0x201, %ax
+	movb	$0, %ch
+	movb	$0, %dh
+	int	$0x13
+
+	/* if error, jump to "probe_loop" */
+	jc	probe_loop
+
+	/* %cl is already the correct value! */
+	movb	$1, %dh
+	movb	$79, %ch
+
+	jmp	final_init
+
+	. = _start + STAGE1_PARTEND
+
+/* the last 2 bytes in the sector 0 contain the signature */
+	.word	STAGE1_SIGNATURE
diff --git a/stage1/stage1.h b/stage1/stage1.h
new file mode 100644
index 0000000..d232ade
--- /dev/null
+++ b/stage1/stage1.h
@@ -0,0 +1,86 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2002,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 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 STAGE1_HEADER
+#define STAGE1_HEADER	1
+
+
+/* Define the version numbers here, so that Stage 1 can know them.  */
+#define COMPAT_VERSION_MAJOR	3
+#define COMPAT_VERSION_MINOR	2
+#define COMPAT_VERSION		((COMPAT_VERSION_MINOR << 8) \
+					| COMPAT_VERSION_MAJOR)
+
+/* The signature for bootloader.  */
+#define STAGE1_SIGNATURE	0xaa55
+
+/* The offset of the end of BPB (BIOS Parameter Block).  */
+#define STAGE1_BPBEND		0x3e
+
+/* The offset of the major version.  */
+#define STAGE1_VER_MAJ_OFFS	0x3e
+
+/* The offset of BOOT_DRIVE.  */
+#define STAGE1_BOOT_DRIVE	0x40
+
+/* The offset of FORCE_LBA.  */
+#define STAGE1_FORCE_LBA	0x41
+
+/* The offset of STAGE2_ADDRESS.  */
+#define STAGE1_STAGE2_ADDRESS	0x42
+
+/* The offset of STAGE2_SECTOR.  */
+#define STAGE1_STAGE2_SECTOR	0x44
+
+/* The offset of STAGE2_SEGMENT.  */
+#define STAGE1_STAGE2_SEGMENT	0x48
+
+/* The offset of BOOT_DRIVE_CHECK.  */
+#define STAGE1_BOOT_DRIVE_CHECK	0x4b
+
+/* The offset of a magic number used by Windows NT.  */
+#define STAGE1_WINDOWS_NT_MAGIC	0x1b8
+
+/* The offset of the start of the partition table.  */
+#define STAGE1_PARTSTART	0x1be
+
+/* The offset of the end of the partition table.  */
+#define STAGE1_PARTEND		0x1fe
+
+/* The stack segment.  */
+#define STAGE1_STACKSEG		0x2000
+
+/* The segment of disk buffer. The disk buffer MUST be 32K long and
+   cannot straddle a 64K boundary.  */
+#define STAGE1_BUFFERSEG	0x7000
+
+/* The address of drive parameters.  */
+#define STAGE1_DRP_ADDR		0x7f00
+
+/* The size of drive parameters.  */
+#define STAGE1_DRP_SIZE		0x42
+
+/* The flag for BIOS drive number to designate a hard disk vs. a
+   floppy.  */
+#define STAGE1_BIOS_HD_FLAG	0x80
+
+/* The drive number of an invalid drive.  */
+#define GRUB_INVALID_DRIVE	0xFF
+
+#endif /* ! STAGE1_HEADER */
diff --git a/stage2/Makefile.am b/stage2/Makefile.am
new file mode 100644
index 0000000..f8e6d42
--- /dev/null
+++ b/stage2/Makefile.am
@@ -0,0 +1,272 @@
+# For test target.
+TESTS = size_test
+noinst_SCRIPTS = $(TESTS)
+
+# For dist target.
+noinst_HEADERS = apic.h defs.h dir.h disk_inode.h disk_inode_ffs.h \
+        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
+EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS)
+
+# For <stage1.h>.
+INCLUDES = -I$(top_srcdir)/stage1
+
+# The library for /sbin/grub.
+noinst_LIBRARIES = libgrub.a
+libgrub_a_SOURCES = boot.c builtins.c char_io.c cmdline.c common.c \
+	disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \
+	fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \
+	fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \
+	terminfo.c tparm.c
+libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
+	-DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
+	-DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
+	-DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \
+	-DUSE_MD5_PASSWORDS=1 -DSUPPORT_SERIAL=1 -DSUPPORT_HERCULES=1
+
+# Stage 2 and Stage 1.5's.
+pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
+
+EXTRA_PROGRAMS = nbloader.exec pxeloader.exec diskless.exec
+
+if DISKLESS_SUPPORT
+pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
+	ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \
+	reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5 \
+	nbgrub pxegrub
+noinst_DATA = pre_stage2 start start_eltorito nbloader pxeloader diskless
+noinst_PROGRAMS = pre_stage2.exec start.exec start_eltorito.exec \
+	e2fs_stage1_5.exec fat_stage1_5.exec ffs_stage1_5.exec \
+	iso9660_stage1_5.exec jfs_stage1_5.exec minix_stage1_5.exec \
+	reiserfs_stage1_5.exec ufs2_stage1_5.exec vstafs_stage1_5.exec \
+	xfs_stage1_5.exec nbloader.exec pxeloader.exec diskless.exec
+else
+pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
+	ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \
+	reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5
+noinst_DATA = pre_stage2 start start_eltorito
+noinst_PROGRAMS = pre_stage2.exec start.exec start_eltorito.exec \
+	e2fs_stage1_5.exec fat_stage1_5.exec ffs_stage1_5.exec \
+	iso9660_stage1_5.exec jfs_stage1_5.exec minix_stage1_5.exec \
+	reiserfs_stage1_5.exec ufs2_stage1_5.exec vstafs_stage1_5.exec \
+	xfs_stage1_5.exec
+endif
+MOSTLYCLEANFILES = $(noinst_PROGRAMS)
+
+PRE_STAGE2_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8200
+START_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8000
+NBLOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,0
+PXELOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00
+START_ELTORITO_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00
+
+if NETBOOT_SUPPORT
+NETBOOT_FLAGS = -I$(top_srcdir)/netboot -DSUPPORT_NETBOOT=1
+else
+NETBOOT_FLAGS =
+endif
+
+if SERIAL_SUPPORT
+SERIAL_FLAGS = -DSUPPORT_SERIAL=1
+else
+SERIAL_FLAGS =
+endif
+
+if HERCULES_SUPPORT
+HERCULES_FLAGS = -DSUPPORT_HERCULES=1
+else
+HERCULES_FLAGS =
+endif
+
+STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	$(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS)
+
+STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
+STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1
+
+# For stage2 target.
+pre_stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c char_io.c \
+	cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
+	fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
+	fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \
+	hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c
+pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
+pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
+pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
+
+if NETBOOT_SUPPORT
+pre_stage2_exec_LDADD = ../netboot/libdrivers.a
+endif
+
+if DISKLESS_SUPPORT
+BUILT_SOURCES = stage2_size.h diskless_size.h
+else
+BUILT_SOURCES = stage2_size.h
+endif
+
+CLEANFILES = $(pkglib_DATA) $(noinst_DATA) $(BUILT_SOURCES)
+
+stage2_size.h: pre_stage2
+	-rm -f stage2_size.h
+	set dummy `ls -l pre_stage2`; \
+	echo "#define STAGE2_SIZE $$6" > stage2_size.h
+
+start_exec_SOURCES = start.S
+start_exec_CCASFLAGS = $(STAGE2_COMPILE)
+start_exec_LDFLAGS = $(START_LINK)
+
+# XXX: automake doesn't provide a way to specify dependencies for object
+# files explicitly, so we must write this by a general Makefile scheme.
+# If automake change the naming scheme for per-executable objects, this
+# will be broken.
+start_exec-start.$(OBJEXT): stage2_size.h
+
+stage2: pre_stage2 start
+	-rm -f stage2
+	cat start pre_stage2 > stage2
+
+start_eltorito_exec_SOURCES = start_eltorito.S
+start_eltorito_exec_CCASFLAGS = $(STAGE2_COMPILE)
+start_eltorito_exec_LDFLAGS = $(START_ELTORITO_LINK)
+
+start_eltorito_exec-start.$(OBJEXT): stage2_size.h
+
+stage2_eltorito: pre_stage2 start_eltorito
+	-rm -f stage2_eltorito
+	cat start_eltorito pre_stage2 > stage2_eltorito
+
+# For e2fs_stage1_5 target.
+e2fs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
+	stage1_5.c fsys_ext2fs.c bios.c
+e2fs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_EXT2FS=1 \
+	-DNO_BLOCK_FILES=1
+e2fs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_EXT2FS=1 \
+	-DNO_BLOCK_FILES=1
+e2fs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For fat_stage1_5 target.
+fat_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
+	stage1_5.c fsys_fat.c bios.c
+fat_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FAT=1 \
+	-DNO_BLOCK_FILES=1
+fat_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FAT=1 \
+	-DNO_BLOCK_FILES=1
+fat_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For ffs_stage1_5 target.
+ffs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
+	stage1_5.c fsys_ffs.c bios.c
+ffs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FFS=1 \
+	-DNO_BLOCK_FILES=1
+ffs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FFS=1 \
+	-DNO_BLOCK_FILES=1
+ffs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For ufs2_stage1_5 target.
+ufs2_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
+	stage1_5.c fsys_ufs2.c bios.c
+ufs2_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_UFS2=1 \
+	-DNO_BLOCK_FILES=1
+ufs2_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_UFS2=1 \
+	-DNO_BLOCK_FILES=1
+ufs2_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For minix_stage1_5 target.
+minix_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
+	stage1_5.c fsys_minix.c bios.c
+minix_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_MINIX=1 \
+	-DNO_BLOCK_FILES=1
+minix_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_MINIX=1 \
+	-DNO_BLOCK_FILES=1
+minix_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For reiserfs_stage1_5 target.
+reiserfs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \
+	disk_io.c stage1_5.c fsys_reiserfs.c bios.c
+reiserfs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_REISERFS=1 \
+	-DNO_BLOCK_FILES=1
+reiserfs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_REISERFS=1 \
+	-DNO_BLOCK_FILES=1
+reiserfs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For vstafs_stage1_5 target.
+vstafs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \
+	disk_io.c stage1_5.c fsys_vstafs.c bios.c
+vstafs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_VSTAFS=1 \
+	-DNO_BLOCK_FILES=1
+vstafs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_VSTAFS=1 \
+	-DNO_BLOCK_FILES=1
+vstafs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For jfs_stage1_5 target.
+jfs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \
+	disk_io.c stage1_5.c fsys_jfs.c bios.c
+jfs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_JFS=1 \
+	-DNO_BLOCK_FILES=1
+jfs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_JFS=1 \
+	-DNO_BLOCK_FILES=1
+jfs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For xfs_stage1_5 target.
+xfs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \
+	disk_io.c stage1_5.c fsys_xfs.c bios.c
+xfs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_XFS=1 \
+	-DNO_BLOCK_FILES=1
+xfs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_XFS=1 \
+	-DNO_BLOCK_FILES=1
+xfs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For iso9660_stage1_5 target.
+iso9660_stage1_5_exec_SOURCES = start_eltorito.S asm.S common.c char_io.c \
+	disk_io.c stage1_5.c fsys_iso9660.c bios.c
+iso9660_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_ISO9660=1 \
+	-DNO_BLOCK_FILES=1
+iso9660_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_ISO9660=1 \
+	-DNO_BLOCK_FILES=1
+iso9660_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For diskless target.
+diskless_exec_SOURCES = $(pre_stage2_exec_SOURCES)
+diskless_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) \
+	-DSUPPORT_DISKLESS=1
+diskless_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) \
+	-DSUPPORT_DISKLESS=1
+diskless_exec_LDFLAGS = $(PRE_STAGE2_LINK)
+diskless_exec_LDADD = ../netboot/libdrivers.a
+
+diskless_size.h: diskless
+	-rm -f $@
+	set dummy `ls -l $^`; \
+	echo "#define DISKLESS_SIZE $$6" > $@
+
+# For nbloader target.
+nbloader_exec_SOURCES = nbloader.S
+nbloader_exec_CCASFLAGS = $(STAGE2_COMPILE)
+nbloader_exec_LDFLAGS = $(NBLOADER_LINK)
+
+# XXX: See the comment for start_exec-start.o.
+nbloader_exec-nbloader.$(OBJEXT): diskless_size.h
+
+# For nbgrub target.
+nbgrub: nbloader diskless
+	-rm -f $@
+	cat $^ > $@
+
+# For pxeloader target.
+pxeloader_exec_SOURCES = pxeloader.S
+pxeloader_exec_CCASFLAGS = $(STAGE2_COMPILE)
+pxeloader_exec_LDFLAGS = $(PXELOADER_LINK)
+
+# XXX: See the comment for start_exec-start.o.
+pxeloader_exec-pxeloader.$(OBJEXT): diskless_size.h
+
+# For pxegrub target.
+pxegrub: pxeloader diskless
+	-rm -f $@
+	cat $^ > $@
+
+# General rule for making a raw binary.
+SUFFIXES = .exec
+.exec:
+	$(OBJCOPY) -O binary $< $@
diff --git a/stage2/Makefile.in b/stage2/Makefile.in
new file mode 100644
index 0000000..d0062bd
--- /dev/null
+++ b/stage2/Makefile.in
@@ -0,0 +1,3250 @@
+# Makefile.in generated by automake 1.9.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  Free Software Foundation, Inc.
+# This Makefile.in 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 distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+
+
+
+SOURCES = $(libgrub_a_SOURCES) $(diskless_exec_SOURCES) $(e2fs_stage1_5_exec_SOURCES) $(fat_stage1_5_exec_SOURCES) $(ffs_stage1_5_exec_SOURCES) $(iso9660_stage1_5_exec_SOURCES) $(jfs_stage1_5_exec_SOURCES) $(minix_stage1_5_exec_SOURCES) $(nbloader_exec_SOURCES) $(pre_stage2_exec_SOURCES) $(pxeloader_exec_SOURCES) $(reiserfs_stage1_5_exec_SOURCES) $(start_exec_SOURCES) $(start_eltorito_exec_SOURCES) $(ufs2_stage1_5_exec_SOURCES) $(vstafs_stage1_5_exec_SOURCES) $(xfs_stage1_5_exec_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+EXTRA_PROGRAMS = nbloader.exec$(EXEEXT) pxeloader.exec$(EXEEXT) \
+	diskless.exec$(EXEEXT)
+@DISKLESS_SUPPORT_FALSE@noinst_PROGRAMS = pre_stage2.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_FALSE@	start.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_FALSE@	start_eltorito.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_FALSE@	e2fs_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_FALSE@	fat_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_FALSE@	ffs_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_FALSE@	iso9660_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_FALSE@	jfs_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_FALSE@	minix_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_FALSE@	reiserfs_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_FALSE@	ufs2_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_FALSE@	vstafs_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_FALSE@	xfs_stage1_5.exec$(EXEEXT)
+@DISKLESS_SUPPORT_TRUE@noinst_PROGRAMS = pre_stage2.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_TRUE@	start.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_TRUE@	start_eltorito.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_TRUE@	e2fs_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_TRUE@	fat_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_TRUE@	ffs_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_TRUE@	iso9660_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_TRUE@	jfs_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_TRUE@	minix_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_TRUE@	reiserfs_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_TRUE@	ufs2_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_TRUE@	vstafs_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_TRUE@	xfs_stage1_5.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_TRUE@	nbloader.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_TRUE@	pxeloader.exec$(EXEEXT) \
+@DISKLESS_SUPPORT_TRUE@	diskless.exec$(EXEEXT)
+subdir = stage2
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+AR = ar
+ARFLAGS = cru
+libgrub_a_AR = $(AR) $(ARFLAGS)
+libgrub_a_LIBADD =
+am_libgrub_a_OBJECTS = libgrub_a-boot.$(OBJEXT) \
+	libgrub_a-builtins.$(OBJEXT) libgrub_a-char_io.$(OBJEXT) \
+	libgrub_a-cmdline.$(OBJEXT) libgrub_a-common.$(OBJEXT) \
+	libgrub_a-disk_io.$(OBJEXT) libgrub_a-fsys_ext2fs.$(OBJEXT) \
+	libgrub_a-fsys_fat.$(OBJEXT) libgrub_a-fsys_ffs.$(OBJEXT) \
+	libgrub_a-fsys_iso9660.$(OBJEXT) libgrub_a-fsys_jfs.$(OBJEXT) \
+	libgrub_a-fsys_minix.$(OBJEXT) \
+	libgrub_a-fsys_reiserfs.$(OBJEXT) \
+	libgrub_a-fsys_ufs2.$(OBJEXT) libgrub_a-fsys_vstafs.$(OBJEXT) \
+	libgrub_a-fsys_xfs.$(OBJEXT) libgrub_a-gunzip.$(OBJEXT) \
+	libgrub_a-md5.$(OBJEXT) libgrub_a-serial.$(OBJEXT) \
+	libgrub_a-stage2.$(OBJEXT) libgrub_a-terminfo.$(OBJEXT) \
+	libgrub_a-tparm.$(OBJEXT)
+libgrub_a_OBJECTS = $(am_libgrub_a_OBJECTS)
+PROGRAMS = $(noinst_PROGRAMS)
+am__objects_1 = diskless_exec-asm.$(OBJEXT) \
+	diskless_exec-bios.$(OBJEXT) diskless_exec-boot.$(OBJEXT) \
+	diskless_exec-builtins.$(OBJEXT) \
+	diskless_exec-char_io.$(OBJEXT) \
+	diskless_exec-cmdline.$(OBJEXT) diskless_exec-common.$(OBJEXT) \
+	diskless_exec-console.$(OBJEXT) \
+	diskless_exec-disk_io.$(OBJEXT) \
+	diskless_exec-fsys_ext2fs.$(OBJEXT) \
+	diskless_exec-fsys_fat.$(OBJEXT) \
+	diskless_exec-fsys_ffs.$(OBJEXT) \
+	diskless_exec-fsys_iso9660.$(OBJEXT) \
+	diskless_exec-fsys_jfs.$(OBJEXT) \
+	diskless_exec-fsys_minix.$(OBJEXT) \
+	diskless_exec-fsys_reiserfs.$(OBJEXT) \
+	diskless_exec-fsys_ufs2.$(OBJEXT) \
+	diskless_exec-fsys_vstafs.$(OBJEXT) \
+	diskless_exec-fsys_xfs.$(OBJEXT) \
+	diskless_exec-gunzip.$(OBJEXT) \
+	diskless_exec-hercules.$(OBJEXT) diskless_exec-md5.$(OBJEXT) \
+	diskless_exec-serial.$(OBJEXT) \
+	diskless_exec-smp-imps.$(OBJEXT) \
+	diskless_exec-stage2.$(OBJEXT) \
+	diskless_exec-terminfo.$(OBJEXT) diskless_exec-tparm.$(OBJEXT)
+am_diskless_exec_OBJECTS = $(am__objects_1)
+diskless_exec_OBJECTS = $(am_diskless_exec_OBJECTS)
+diskless_exec_DEPENDENCIES = ../netboot/libdrivers.a
+am_e2fs_stage1_5_exec_OBJECTS = e2fs_stage1_5_exec-start.$(OBJEXT) \
+	e2fs_stage1_5_exec-asm.$(OBJEXT) \
+	e2fs_stage1_5_exec-common.$(OBJEXT) \
+	e2fs_stage1_5_exec-char_io.$(OBJEXT) \
+	e2fs_stage1_5_exec-disk_io.$(OBJEXT) \
+	e2fs_stage1_5_exec-stage1_5.$(OBJEXT) \
+	e2fs_stage1_5_exec-fsys_ext2fs.$(OBJEXT) \
+	e2fs_stage1_5_exec-bios.$(OBJEXT)
+e2fs_stage1_5_exec_OBJECTS = $(am_e2fs_stage1_5_exec_OBJECTS)
+e2fs_stage1_5_exec_LDADD = $(LDADD)
+am_fat_stage1_5_exec_OBJECTS = fat_stage1_5_exec-start.$(OBJEXT) \
+	fat_stage1_5_exec-asm.$(OBJEXT) \
+	fat_stage1_5_exec-common.$(OBJEXT) \
+	fat_stage1_5_exec-char_io.$(OBJEXT) \
+	fat_stage1_5_exec-disk_io.$(OBJEXT) \
+	fat_stage1_5_exec-stage1_5.$(OBJEXT) \
+	fat_stage1_5_exec-fsys_fat.$(OBJEXT) \
+	fat_stage1_5_exec-bios.$(OBJEXT)
+fat_stage1_5_exec_OBJECTS = $(am_fat_stage1_5_exec_OBJECTS)
+fat_stage1_5_exec_LDADD = $(LDADD)
+am_ffs_stage1_5_exec_OBJECTS = ffs_stage1_5_exec-start.$(OBJEXT) \
+	ffs_stage1_5_exec-asm.$(OBJEXT) \
+	ffs_stage1_5_exec-common.$(OBJEXT) \
+	ffs_stage1_5_exec-char_io.$(OBJEXT) \
+	ffs_stage1_5_exec-disk_io.$(OBJEXT) \
+	ffs_stage1_5_exec-stage1_5.$(OBJEXT) \
+	ffs_stage1_5_exec-fsys_ffs.$(OBJEXT) \
+	ffs_stage1_5_exec-bios.$(OBJEXT)
+ffs_stage1_5_exec_OBJECTS = $(am_ffs_stage1_5_exec_OBJECTS)
+ffs_stage1_5_exec_LDADD = $(LDADD)
+am_iso9660_stage1_5_exec_OBJECTS =  \
+	iso9660_stage1_5_exec-start_eltorito.$(OBJEXT) \
+	iso9660_stage1_5_exec-asm.$(OBJEXT) \
+	iso9660_stage1_5_exec-common.$(OBJEXT) \
+	iso9660_stage1_5_exec-char_io.$(OBJEXT) \
+	iso9660_stage1_5_exec-disk_io.$(OBJEXT) \
+	iso9660_stage1_5_exec-stage1_5.$(OBJEXT) \
+	iso9660_stage1_5_exec-fsys_iso9660.$(OBJEXT) \
+	iso9660_stage1_5_exec-bios.$(OBJEXT)
+iso9660_stage1_5_exec_OBJECTS = $(am_iso9660_stage1_5_exec_OBJECTS)
+iso9660_stage1_5_exec_LDADD = $(LDADD)
+am_jfs_stage1_5_exec_OBJECTS = jfs_stage1_5_exec-start.$(OBJEXT) \
+	jfs_stage1_5_exec-asm.$(OBJEXT) \
+	jfs_stage1_5_exec-common.$(OBJEXT) \
+	jfs_stage1_5_exec-char_io.$(OBJEXT) \
+	jfs_stage1_5_exec-disk_io.$(OBJEXT) \
+	jfs_stage1_5_exec-stage1_5.$(OBJEXT) \
+	jfs_stage1_5_exec-fsys_jfs.$(OBJEXT) \
+	jfs_stage1_5_exec-bios.$(OBJEXT)
+jfs_stage1_5_exec_OBJECTS = $(am_jfs_stage1_5_exec_OBJECTS)
+jfs_stage1_5_exec_LDADD = $(LDADD)
+am_minix_stage1_5_exec_OBJECTS = minix_stage1_5_exec-start.$(OBJEXT) \
+	minix_stage1_5_exec-asm.$(OBJEXT) \
+	minix_stage1_5_exec-common.$(OBJEXT) \
+	minix_stage1_5_exec-char_io.$(OBJEXT) \
+	minix_stage1_5_exec-disk_io.$(OBJEXT) \
+	minix_stage1_5_exec-stage1_5.$(OBJEXT) \
+	minix_stage1_5_exec-fsys_minix.$(OBJEXT) \
+	minix_stage1_5_exec-bios.$(OBJEXT)
+minix_stage1_5_exec_OBJECTS = $(am_minix_stage1_5_exec_OBJECTS)
+minix_stage1_5_exec_LDADD = $(LDADD)
+am_nbloader_exec_OBJECTS = nbloader_exec-nbloader.$(OBJEXT)
+nbloader_exec_OBJECTS = $(am_nbloader_exec_OBJECTS)
+nbloader_exec_LDADD = $(LDADD)
+am_pre_stage2_exec_OBJECTS = pre_stage2_exec-asm.$(OBJEXT) \
+	pre_stage2_exec-bios.$(OBJEXT) pre_stage2_exec-boot.$(OBJEXT) \
+	pre_stage2_exec-builtins.$(OBJEXT) \
+	pre_stage2_exec-char_io.$(OBJEXT) \
+	pre_stage2_exec-cmdline.$(OBJEXT) \
+	pre_stage2_exec-common.$(OBJEXT) \
+	pre_stage2_exec-console.$(OBJEXT) \
+	pre_stage2_exec-disk_io.$(OBJEXT) \
+	pre_stage2_exec-fsys_ext2fs.$(OBJEXT) \
+	pre_stage2_exec-fsys_fat.$(OBJEXT) \
+	pre_stage2_exec-fsys_ffs.$(OBJEXT) \
+	pre_stage2_exec-fsys_iso9660.$(OBJEXT) \
+	pre_stage2_exec-fsys_jfs.$(OBJEXT) \
+	pre_stage2_exec-fsys_minix.$(OBJEXT) \
+	pre_stage2_exec-fsys_reiserfs.$(OBJEXT) \
+	pre_stage2_exec-fsys_ufs2.$(OBJEXT) \
+	pre_stage2_exec-fsys_vstafs.$(OBJEXT) \
+	pre_stage2_exec-fsys_xfs.$(OBJEXT) \
+	pre_stage2_exec-gunzip.$(OBJEXT) \
+	pre_stage2_exec-hercules.$(OBJEXT) \
+	pre_stage2_exec-md5.$(OBJEXT) pre_stage2_exec-serial.$(OBJEXT) \
+	pre_stage2_exec-smp-imps.$(OBJEXT) \
+	pre_stage2_exec-stage2.$(OBJEXT) \
+	pre_stage2_exec-terminfo.$(OBJEXT) \
+	pre_stage2_exec-tparm.$(OBJEXT)
+pre_stage2_exec_OBJECTS = $(am_pre_stage2_exec_OBJECTS)
+@NETBOOT_SUPPORT_TRUE@pre_stage2_exec_DEPENDENCIES =  \
+@NETBOOT_SUPPORT_TRUE@	../netboot/libdrivers.a
+am_pxeloader_exec_OBJECTS = pxeloader_exec-pxeloader.$(OBJEXT)
+pxeloader_exec_OBJECTS = $(am_pxeloader_exec_OBJECTS)
+pxeloader_exec_LDADD = $(LDADD)
+am_reiserfs_stage1_5_exec_OBJECTS =  \
+	reiserfs_stage1_5_exec-start.$(OBJEXT) \
+	reiserfs_stage1_5_exec-asm.$(OBJEXT) \
+	reiserfs_stage1_5_exec-common.$(OBJEXT) \
+	reiserfs_stage1_5_exec-char_io.$(OBJEXT) \
+	reiserfs_stage1_5_exec-disk_io.$(OBJEXT) \
+	reiserfs_stage1_5_exec-stage1_5.$(OBJEXT) \
+	reiserfs_stage1_5_exec-fsys_reiserfs.$(OBJEXT) \
+	reiserfs_stage1_5_exec-bios.$(OBJEXT)
+reiserfs_stage1_5_exec_OBJECTS = $(am_reiserfs_stage1_5_exec_OBJECTS)
+reiserfs_stage1_5_exec_LDADD = $(LDADD)
+am_start_exec_OBJECTS = start_exec-start.$(OBJEXT)
+start_exec_OBJECTS = $(am_start_exec_OBJECTS)
+start_exec_LDADD = $(LDADD)
+am_start_eltorito_exec_OBJECTS =  \
+	start_eltorito_exec-start_eltorito.$(OBJEXT)
+start_eltorito_exec_OBJECTS = $(am_start_eltorito_exec_OBJECTS)
+start_eltorito_exec_LDADD = $(LDADD)
+am_ufs2_stage1_5_exec_OBJECTS = ufs2_stage1_5_exec-start.$(OBJEXT) \
+	ufs2_stage1_5_exec-asm.$(OBJEXT) \
+	ufs2_stage1_5_exec-common.$(OBJEXT) \
+	ufs2_stage1_5_exec-char_io.$(OBJEXT) \
+	ufs2_stage1_5_exec-disk_io.$(OBJEXT) \
+	ufs2_stage1_5_exec-stage1_5.$(OBJEXT) \
+	ufs2_stage1_5_exec-fsys_ufs2.$(OBJEXT) \
+	ufs2_stage1_5_exec-bios.$(OBJEXT)
+ufs2_stage1_5_exec_OBJECTS = $(am_ufs2_stage1_5_exec_OBJECTS)
+ufs2_stage1_5_exec_LDADD = $(LDADD)
+am_vstafs_stage1_5_exec_OBJECTS =  \
+	vstafs_stage1_5_exec-start.$(OBJEXT) \
+	vstafs_stage1_5_exec-asm.$(OBJEXT) \
+	vstafs_stage1_5_exec-common.$(OBJEXT) \
+	vstafs_stage1_5_exec-char_io.$(OBJEXT) \
+	vstafs_stage1_5_exec-disk_io.$(OBJEXT) \
+	vstafs_stage1_5_exec-stage1_5.$(OBJEXT) \
+	vstafs_stage1_5_exec-fsys_vstafs.$(OBJEXT) \
+	vstafs_stage1_5_exec-bios.$(OBJEXT)
+vstafs_stage1_5_exec_OBJECTS = $(am_vstafs_stage1_5_exec_OBJECTS)
+vstafs_stage1_5_exec_LDADD = $(LDADD)
+am_xfs_stage1_5_exec_OBJECTS = xfs_stage1_5_exec-start.$(OBJEXT) \
+	xfs_stage1_5_exec-asm.$(OBJEXT) \
+	xfs_stage1_5_exec-common.$(OBJEXT) \
+	xfs_stage1_5_exec-char_io.$(OBJEXT) \
+	xfs_stage1_5_exec-disk_io.$(OBJEXT) \
+	xfs_stage1_5_exec-stage1_5.$(OBJEXT) \
+	xfs_stage1_5_exec-fsys_xfs.$(OBJEXT) \
+	xfs_stage1_5_exec-bios.$(OBJEXT)
+xfs_stage1_5_exec_OBJECTS = $(am_xfs_stage1_5_exec_OBJECTS)
+xfs_stage1_5_exec_LDADD = $(LDADD)
+SCRIPTS = $(noinst_SCRIPTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+CCASCOMPILE = $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS)
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(libgrub_a_SOURCES) $(diskless_exec_SOURCES) \
+	$(e2fs_stage1_5_exec_SOURCES) $(fat_stage1_5_exec_SOURCES) \
+	$(ffs_stage1_5_exec_SOURCES) $(iso9660_stage1_5_exec_SOURCES) \
+	$(jfs_stage1_5_exec_SOURCES) $(minix_stage1_5_exec_SOURCES) \
+	$(nbloader_exec_SOURCES) $(pre_stage2_exec_SOURCES) \
+	$(pxeloader_exec_SOURCES) $(reiserfs_stage1_5_exec_SOURCES) \
+	$(start_exec_SOURCES) $(start_eltorito_exec_SOURCES) \
+	$(ufs2_stage1_5_exec_SOURCES) $(vstafs_stage1_5_exec_SOURCES) \
+	$(xfs_stage1_5_exec_SOURCES)
+DIST_SOURCES = $(libgrub_a_SOURCES) $(diskless_exec_SOURCES) \
+	$(e2fs_stage1_5_exec_SOURCES) $(fat_stage1_5_exec_SOURCES) \
+	$(ffs_stage1_5_exec_SOURCES) $(iso9660_stage1_5_exec_SOURCES) \
+	$(jfs_stage1_5_exec_SOURCES) $(minix_stage1_5_exec_SOURCES) \
+	$(nbloader_exec_SOURCES) $(pre_stage2_exec_SOURCES) \
+	$(pxeloader_exec_SOURCES) $(reiserfs_stage1_5_exec_SOURCES) \
+	$(start_exec_SOURCES) $(start_eltorito_exec_SOURCES) \
+	$(ufs2_stage1_5_exec_SOURCES) $(vstafs_stage1_5_exec_SOURCES) \
+	$(xfs_stage1_5_exec_SOURCES)
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(pkglibdir)"
+pkglibDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(noinst_DATA) $(pkglib_DATA)
+HEADERS = $(noinst_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+
+# Stage 2 and Stage 1.5's.
+pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_EXAMPLE_KERNEL_FALSE = @BUILD_EXAMPLE_KERNEL_FALSE@
+BUILD_EXAMPLE_KERNEL_TRUE = @BUILD_EXAMPLE_KERNEL_TRUE@
+CC = @CC@
+CCAS = @CCAS@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISKLESS_SUPPORT_FALSE = @DISKLESS_SUPPORT_FALSE@
+DISKLESS_SUPPORT_TRUE = @DISKLESS_SUPPORT_TRUE@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FSYS_CFLAGS = @FSYS_CFLAGS@
+GRUB_CFLAGS = @GRUB_CFLAGS@
+GRUB_LIBS = @GRUB_LIBS@
+HERCULES_SUPPORT_FALSE = @HERCULES_SUPPORT_FALSE@
+HERCULES_SUPPORT_TRUE = @HERCULES_SUPPORT_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
+NETBOOT_SUPPORT_FALSE = @NETBOOT_SUPPORT_FALSE@
+NETBOOT_SUPPORT_TRUE = @NETBOOT_SUPPORT_TRUE@
+NET_CFLAGS = @NET_CFLAGS@
+NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
+OBJCOPY = @OBJCOPY@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+RANLIB = @RANLIB@
+SERIAL_SPEED_SIMULATION_FALSE = @SERIAL_SPEED_SIMULATION_FALSE@
+SERIAL_SPEED_SIMULATION_TRUE = @SERIAL_SPEED_SIMULATION_TRUE@
+SERIAL_SUPPORT_FALSE = @SERIAL_SUPPORT_FALSE@
+SERIAL_SUPPORT_TRUE = @SERIAL_SUPPORT_TRUE@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STAGE1_CFLAGS = @STAGE1_CFLAGS@
+STAGE2_CFLAGS = @STAGE2_CFLAGS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_OBJCOPY = @ac_ct_OBJCOPY@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+
+# For test target.
+TESTS = size_test
+noinst_SCRIPTS = $(TESTS)
+
+# For dist target.
+noinst_HEADERS = apic.h defs.h dir.h disk_inode.h disk_inode_ffs.h \
+        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
+
+EXTRA_DIST = setjmp.S apm.S $(noinst_SCRIPTS)
+
+# For <stage1.h>.
+INCLUDES = -I$(top_srcdir)/stage1
+
+# The library for /sbin/grub.
+noinst_LIBRARIES = libgrub.a
+libgrub_a_SOURCES = boot.c builtins.c char_io.c cmdline.c common.c \
+	disk_io.c fsys_ext2fs.c fsys_fat.c fsys_ffs.c fsys_iso9660.c \
+	fsys_jfs.c fsys_minix.c fsys_reiserfs.c fsys_ufs2.c \
+	fsys_vstafs.c fsys_xfs.c gunzip.c md5.c serial.c stage2.c \
+	terminfo.c tparm.c
+
+libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \
+	-DGRUB_UTIL=1 -DFSYS_EXT2FS=1 -DFSYS_FAT=1 -DFSYS_FFS=1 \
+	-DFSYS_ISO9660=1 -DFSYS_JFS=1 -DFSYS_MINIX=1 -DFSYS_REISERFS=1 \
+	-DFSYS_UFS2=1 -DFSYS_VSTAFS=1 -DFSYS_XFS=1 \
+	-DUSE_MD5_PASSWORDS=1 -DSUPPORT_SERIAL=1 -DSUPPORT_HERCULES=1
+
+@DISKLESS_SUPPORT_FALSE@pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
+@DISKLESS_SUPPORT_FALSE@	ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \
+@DISKLESS_SUPPORT_FALSE@	reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5
+
+@DISKLESS_SUPPORT_TRUE@pkglib_DATA = stage2 stage2_eltorito e2fs_stage1_5 fat_stage1_5 \
+@DISKLESS_SUPPORT_TRUE@	ffs_stage1_5 iso9660_stage1_5 jfs_stage1_5 minix_stage1_5 \
+@DISKLESS_SUPPORT_TRUE@	reiserfs_stage1_5 ufs2_stage1_5 vstafs_stage1_5 xfs_stage1_5 \
+@DISKLESS_SUPPORT_TRUE@	nbgrub pxegrub
+
+@DISKLESS_SUPPORT_FALSE@noinst_DATA = pre_stage2 start start_eltorito
+@DISKLESS_SUPPORT_TRUE@noinst_DATA = pre_stage2 start start_eltorito nbloader pxeloader diskless
+MOSTLYCLEANFILES = $(noinst_PROGRAMS)
+PRE_STAGE2_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8200
+START_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,8000
+NBLOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,0
+PXELOADER_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00
+START_ELTORITO_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,7C00
+@NETBOOT_SUPPORT_FALSE@NETBOOT_FLAGS = 
+@NETBOOT_SUPPORT_TRUE@NETBOOT_FLAGS = -I$(top_srcdir)/netboot -DSUPPORT_NETBOOT=1
+@SERIAL_SUPPORT_FALSE@SERIAL_FLAGS = 
+@SERIAL_SUPPORT_TRUE@SERIAL_FLAGS = -DSUPPORT_SERIAL=1
+@HERCULES_SUPPORT_FALSE@HERCULES_FLAGS = 
+@HERCULES_SUPPORT_TRUE@HERCULES_FLAGS = -DSUPPORT_HERCULES=1
+STAGE2_COMPILE = $(STAGE2_CFLAGS) -fno-builtin -nostdinc \
+	$(NETBOOT_FLAGS) $(SERIAL_FLAGS) $(HERCULES_FLAGS)
+
+STAGE1_5_LINK = -nostdlib -Wl,-N -Wl,-Ttext -Wl,2000
+STAGE1_5_COMPILE = $(STAGE2_COMPILE) -DNO_DECOMPRESSION=1 -DSTAGE1_5=1
+
+# For stage2 target.
+pre_stage2_exec_SOURCES = asm.S bios.c boot.c builtins.c char_io.c \
+	cmdline.c common.c console.c disk_io.c fsys_ext2fs.c \
+	fsys_fat.c fsys_ffs.c fsys_iso9660.c fsys_jfs.c fsys_minix.c \
+	fsys_reiserfs.c fsys_ufs2.c fsys_vstafs.c fsys_xfs.c gunzip.c \
+	hercules.c md5.c serial.c smp-imps.c stage2.c terminfo.c tparm.c
+
+pre_stage2_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
+pre_stage2_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS)
+pre_stage2_exec_LDFLAGS = $(PRE_STAGE2_LINK)
+@NETBOOT_SUPPORT_TRUE@pre_stage2_exec_LDADD = ../netboot/libdrivers.a
+@DISKLESS_SUPPORT_FALSE@BUILT_SOURCES = stage2_size.h
+@DISKLESS_SUPPORT_TRUE@BUILT_SOURCES = stage2_size.h diskless_size.h
+CLEANFILES = $(pkglib_DATA) $(noinst_DATA) $(BUILT_SOURCES)
+start_exec_SOURCES = start.S
+start_exec_CCASFLAGS = $(STAGE2_COMPILE)
+start_exec_LDFLAGS = $(START_LINK)
+start_eltorito_exec_SOURCES = start_eltorito.S
+start_eltorito_exec_CCASFLAGS = $(STAGE2_COMPILE)
+start_eltorito_exec_LDFLAGS = $(START_ELTORITO_LINK)
+
+# For e2fs_stage1_5 target.
+e2fs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
+	stage1_5.c fsys_ext2fs.c bios.c
+
+e2fs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_EXT2FS=1 \
+	-DNO_BLOCK_FILES=1
+
+e2fs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_EXT2FS=1 \
+	-DNO_BLOCK_FILES=1
+
+e2fs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For fat_stage1_5 target.
+fat_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
+	stage1_5.c fsys_fat.c bios.c
+
+fat_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FAT=1 \
+	-DNO_BLOCK_FILES=1
+
+fat_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FAT=1 \
+	-DNO_BLOCK_FILES=1
+
+fat_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For ffs_stage1_5 target.
+ffs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
+	stage1_5.c fsys_ffs.c bios.c
+
+ffs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FFS=1 \
+	-DNO_BLOCK_FILES=1
+
+ffs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_FFS=1 \
+	-DNO_BLOCK_FILES=1
+
+ffs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For ufs2_stage1_5 target.
+ufs2_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
+	stage1_5.c fsys_ufs2.c bios.c
+
+ufs2_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_UFS2=1 \
+	-DNO_BLOCK_FILES=1
+
+ufs2_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_UFS2=1 \
+	-DNO_BLOCK_FILES=1
+
+ufs2_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For minix_stage1_5 target.
+minix_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c disk_io.c \
+	stage1_5.c fsys_minix.c bios.c
+
+minix_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_MINIX=1 \
+	-DNO_BLOCK_FILES=1
+
+minix_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_MINIX=1 \
+	-DNO_BLOCK_FILES=1
+
+minix_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For reiserfs_stage1_5 target.
+reiserfs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \
+	disk_io.c stage1_5.c fsys_reiserfs.c bios.c
+
+reiserfs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_REISERFS=1 \
+	-DNO_BLOCK_FILES=1
+
+reiserfs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_REISERFS=1 \
+	-DNO_BLOCK_FILES=1
+
+reiserfs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For vstafs_stage1_5 target.
+vstafs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \
+	disk_io.c stage1_5.c fsys_vstafs.c bios.c
+
+vstafs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_VSTAFS=1 \
+	-DNO_BLOCK_FILES=1
+
+vstafs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_VSTAFS=1 \
+	-DNO_BLOCK_FILES=1
+
+vstafs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For jfs_stage1_5 target.
+jfs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \
+	disk_io.c stage1_5.c fsys_jfs.c bios.c
+
+jfs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_JFS=1 \
+	-DNO_BLOCK_FILES=1
+
+jfs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_JFS=1 \
+	-DNO_BLOCK_FILES=1
+
+jfs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For xfs_stage1_5 target.
+xfs_stage1_5_exec_SOURCES = start.S asm.S common.c char_io.c \
+	disk_io.c stage1_5.c fsys_xfs.c bios.c
+
+xfs_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_XFS=1 \
+	-DNO_BLOCK_FILES=1
+
+xfs_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_XFS=1 \
+	-DNO_BLOCK_FILES=1
+
+xfs_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For iso9660_stage1_5 target.
+iso9660_stage1_5_exec_SOURCES = start_eltorito.S asm.S common.c char_io.c \
+	disk_io.c stage1_5.c fsys_iso9660.c bios.c
+
+iso9660_stage1_5_exec_CFLAGS = $(STAGE1_5_COMPILE) -DFSYS_ISO9660=1 \
+	-DNO_BLOCK_FILES=1
+
+iso9660_stage1_5_exec_CCASFLAGS = $(STAGE1_5_COMPILE) -DFSYS_ISO9660=1 \
+	-DNO_BLOCK_FILES=1
+
+iso9660_stage1_5_exec_LDFLAGS = $(STAGE1_5_LINK)
+
+# For diskless target.
+diskless_exec_SOURCES = $(pre_stage2_exec_SOURCES)
+diskless_exec_CFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) \
+	-DSUPPORT_DISKLESS=1
+
+diskless_exec_CCASFLAGS = $(STAGE2_COMPILE) $(FSYS_CFLAGS) \
+	-DSUPPORT_DISKLESS=1
+
+diskless_exec_LDFLAGS = $(PRE_STAGE2_LINK)
+diskless_exec_LDADD = ../netboot/libdrivers.a
+
+# For nbloader target.
+nbloader_exec_SOURCES = nbloader.S
+nbloader_exec_CCASFLAGS = $(STAGE2_COMPILE)
+nbloader_exec_LDFLAGS = $(NBLOADER_LINK)
+
+# For pxeloader target.
+pxeloader_exec_SOURCES = pxeloader.S
+pxeloader_exec_CCASFLAGS = $(STAGE2_COMPILE)
+pxeloader_exec_LDFLAGS = $(PXELOADER_LINK)
+
+# General rule for making a raw binary.
+SUFFIXES = .exec
+all: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) all-am
+
+.SUFFIXES:
+.SUFFIXES: .exec .S .c .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  stage2/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu  stage2/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libgrub.a: $(libgrub_a_OBJECTS) $(libgrub_a_DEPENDENCIES) 
+	-rm -f libgrub.a
+	$(libgrub_a_AR) libgrub.a $(libgrub_a_OBJECTS) $(libgrub_a_LIBADD)
+	$(RANLIB) libgrub.a
+
+clean-noinstPROGRAMS:
+	-test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+diskless.exec$(EXEEXT): $(diskless_exec_OBJECTS) $(diskless_exec_DEPENDENCIES) 
+	@rm -f diskless.exec$(EXEEXT)
+	$(LINK) $(diskless_exec_LDFLAGS) $(diskless_exec_OBJECTS) $(diskless_exec_LDADD) $(LIBS)
+e2fs_stage1_5.exec$(EXEEXT): $(e2fs_stage1_5_exec_OBJECTS) $(e2fs_stage1_5_exec_DEPENDENCIES) 
+	@rm -f e2fs_stage1_5.exec$(EXEEXT)
+	$(LINK) $(e2fs_stage1_5_exec_LDFLAGS) $(e2fs_stage1_5_exec_OBJECTS) $(e2fs_stage1_5_exec_LDADD) $(LIBS)
+fat_stage1_5.exec$(EXEEXT): $(fat_stage1_5_exec_OBJECTS) $(fat_stage1_5_exec_DEPENDENCIES) 
+	@rm -f fat_stage1_5.exec$(EXEEXT)
+	$(LINK) $(fat_stage1_5_exec_LDFLAGS) $(fat_stage1_5_exec_OBJECTS) $(fat_stage1_5_exec_LDADD) $(LIBS)
+ffs_stage1_5.exec$(EXEEXT): $(ffs_stage1_5_exec_OBJECTS) $(ffs_stage1_5_exec_DEPENDENCIES) 
+	@rm -f ffs_stage1_5.exec$(EXEEXT)
+	$(LINK) $(ffs_stage1_5_exec_LDFLAGS) $(ffs_stage1_5_exec_OBJECTS) $(ffs_stage1_5_exec_LDADD) $(LIBS)
+iso9660_stage1_5.exec$(EXEEXT): $(iso9660_stage1_5_exec_OBJECTS) $(iso9660_stage1_5_exec_DEPENDENCIES) 
+	@rm -f iso9660_stage1_5.exec$(EXEEXT)
+	$(LINK) $(iso9660_stage1_5_exec_LDFLAGS) $(iso9660_stage1_5_exec_OBJECTS) $(iso9660_stage1_5_exec_LDADD) $(LIBS)
+jfs_stage1_5.exec$(EXEEXT): $(jfs_stage1_5_exec_OBJECTS) $(jfs_stage1_5_exec_DEPENDENCIES) 
+	@rm -f jfs_stage1_5.exec$(EXEEXT)
+	$(LINK) $(jfs_stage1_5_exec_LDFLAGS) $(jfs_stage1_5_exec_OBJECTS) $(jfs_stage1_5_exec_LDADD) $(LIBS)
+minix_stage1_5.exec$(EXEEXT): $(minix_stage1_5_exec_OBJECTS) $(minix_stage1_5_exec_DEPENDENCIES) 
+	@rm -f minix_stage1_5.exec$(EXEEXT)
+	$(LINK) $(minix_stage1_5_exec_LDFLAGS) $(minix_stage1_5_exec_OBJECTS) $(minix_stage1_5_exec_LDADD) $(LIBS)
+nbloader.exec$(EXEEXT): $(nbloader_exec_OBJECTS) $(nbloader_exec_DEPENDENCIES) 
+	@rm -f nbloader.exec$(EXEEXT)
+	$(LINK) $(nbloader_exec_LDFLAGS) $(nbloader_exec_OBJECTS) $(nbloader_exec_LDADD) $(LIBS)
+pre_stage2.exec$(EXEEXT): $(pre_stage2_exec_OBJECTS) $(pre_stage2_exec_DEPENDENCIES) 
+	@rm -f pre_stage2.exec$(EXEEXT)
+	$(LINK) $(pre_stage2_exec_LDFLAGS) $(pre_stage2_exec_OBJECTS) $(pre_stage2_exec_LDADD) $(LIBS)
+pxeloader.exec$(EXEEXT): $(pxeloader_exec_OBJECTS) $(pxeloader_exec_DEPENDENCIES) 
+	@rm -f pxeloader.exec$(EXEEXT)
+	$(LINK) $(pxeloader_exec_LDFLAGS) $(pxeloader_exec_OBJECTS) $(pxeloader_exec_LDADD) $(LIBS)
+reiserfs_stage1_5.exec$(EXEEXT): $(reiserfs_stage1_5_exec_OBJECTS) $(reiserfs_stage1_5_exec_DEPENDENCIES) 
+	@rm -f reiserfs_stage1_5.exec$(EXEEXT)
+	$(LINK) $(reiserfs_stage1_5_exec_LDFLAGS) $(reiserfs_stage1_5_exec_OBJECTS) $(reiserfs_stage1_5_exec_LDADD) $(LIBS)
+start.exec$(EXEEXT): $(start_exec_OBJECTS) $(start_exec_DEPENDENCIES) 
+	@rm -f start.exec$(EXEEXT)
+	$(LINK) $(start_exec_LDFLAGS) $(start_exec_OBJECTS) $(start_exec_LDADD) $(LIBS)
+start_eltorito.exec$(EXEEXT): $(start_eltorito_exec_OBJECTS) $(start_eltorito_exec_DEPENDENCIES) 
+	@rm -f start_eltorito.exec$(EXEEXT)
+	$(LINK) $(start_eltorito_exec_LDFLAGS) $(start_eltorito_exec_OBJECTS) $(start_eltorito_exec_LDADD) $(LIBS)
+ufs2_stage1_5.exec$(EXEEXT): $(ufs2_stage1_5_exec_OBJECTS) $(ufs2_stage1_5_exec_DEPENDENCIES) 
+	@rm -f ufs2_stage1_5.exec$(EXEEXT)
+	$(LINK) $(ufs2_stage1_5_exec_LDFLAGS) $(ufs2_stage1_5_exec_OBJECTS) $(ufs2_stage1_5_exec_LDADD) $(LIBS)
+vstafs_stage1_5.exec$(EXEEXT): $(vstafs_stage1_5_exec_OBJECTS) $(vstafs_stage1_5_exec_DEPENDENCIES) 
+	@rm -f vstafs_stage1_5.exec$(EXEEXT)
+	$(LINK) $(vstafs_stage1_5_exec_LDFLAGS) $(vstafs_stage1_5_exec_OBJECTS) $(vstafs_stage1_5_exec_LDADD) $(LIBS)
+xfs_stage1_5.exec$(EXEEXT): $(xfs_stage1_5_exec_OBJECTS) $(xfs_stage1_5_exec_DEPENDENCIES) 
+	@rm -f xfs_stage1_5.exec$(EXEEXT)
+	$(LINK) $(xfs_stage1_5_exec_LDFLAGS) $(xfs_stage1_5_exec_OBJECTS) $(xfs_stage1_5_exec_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-bios.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-boot.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-builtins.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-char_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-cmdline.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-console.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-disk_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-fsys_ext2fs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-fsys_fat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-fsys_ffs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-fsys_iso9660.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-fsys_jfs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-fsys_minix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-fsys_reiserfs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-fsys_ufs2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-fsys_vstafs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-fsys_xfs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-gunzip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-hercules.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-md5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-serial.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-smp-imps.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-stage2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-terminfo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/diskless_exec-tparm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e2fs_stage1_5_exec-bios.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e2fs_stage1_5_exec-char_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e2fs_stage1_5_exec-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e2fs_stage1_5_exec-disk_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e2fs_stage1_5_exec-fsys_ext2fs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/e2fs_stage1_5_exec-stage1_5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fat_stage1_5_exec-bios.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fat_stage1_5_exec-char_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fat_stage1_5_exec-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fat_stage1_5_exec-disk_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fat_stage1_5_exec-fsys_fat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fat_stage1_5_exec-stage1_5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ffs_stage1_5_exec-bios.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ffs_stage1_5_exec-char_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ffs_stage1_5_exec-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ffs_stage1_5_exec-disk_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ffs_stage1_5_exec-fsys_ffs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ffs_stage1_5_exec-stage1_5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iso9660_stage1_5_exec-bios.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iso9660_stage1_5_exec-char_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iso9660_stage1_5_exec-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iso9660_stage1_5_exec-disk_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iso9660_stage1_5_exec-fsys_iso9660.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iso9660_stage1_5_exec-stage1_5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jfs_stage1_5_exec-bios.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jfs_stage1_5_exec-char_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jfs_stage1_5_exec-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jfs_stage1_5_exec-disk_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jfs_stage1_5_exec-fsys_jfs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jfs_stage1_5_exec-stage1_5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-boot.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-builtins.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-char_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-cmdline.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-disk_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-fsys_ext2fs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-fsys_fat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-fsys_ffs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-fsys_iso9660.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-fsys_jfs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-fsys_minix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-fsys_reiserfs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-fsys_ufs2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-fsys_vstafs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-fsys_xfs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-gunzip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-md5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-serial.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-stage2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-terminfo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgrub_a-tparm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minix_stage1_5_exec-bios.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minix_stage1_5_exec-char_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minix_stage1_5_exec-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minix_stage1_5_exec-disk_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minix_stage1_5_exec-fsys_minix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/minix_stage1_5_exec-stage1_5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-bios.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-boot.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-builtins.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-char_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-cmdline.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-console.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-disk_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_ext2fs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_fat.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_ffs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_iso9660.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_jfs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_minix.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_reiserfs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_ufs2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_vstafs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-fsys_xfs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-gunzip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-hercules.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-md5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-serial.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-smp-imps.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-stage2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-terminfo.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pre_stage2_exec-tparm.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reiserfs_stage1_5_exec-bios.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reiserfs_stage1_5_exec-char_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reiserfs_stage1_5_exec-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reiserfs_stage1_5_exec-disk_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reiserfs_stage1_5_exec-fsys_reiserfs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reiserfs_stage1_5_exec-stage1_5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ufs2_stage1_5_exec-bios.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ufs2_stage1_5_exec-char_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ufs2_stage1_5_exec-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ufs2_stage1_5_exec-disk_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ufs2_stage1_5_exec-fsys_ufs2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ufs2_stage1_5_exec-stage1_5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vstafs_stage1_5_exec-bios.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vstafs_stage1_5_exec-char_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vstafs_stage1_5_exec-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vstafs_stage1_5_exec-disk_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vstafs_stage1_5_exec-fsys_vstafs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vstafs_stage1_5_exec-stage1_5.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfs_stage1_5_exec-bios.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfs_stage1_5_exec-char_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfs_stage1_5_exec-common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfs_stage1_5_exec-disk_io.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfs_stage1_5_exec-fsys_xfs.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xfs_stage1_5_exec-stage1_5.Po@am__quote@
+
+.S.o:
+	$(CCASCOMPILE) -c $<
+
+.S.obj:
+	$(CCASCOMPILE) -c `$(CYGPATH_W) '$<'`
+
+diskless_exec-asm.o: asm.S
+	$(CCAS) $(diskless_exec_CCASFLAGS) $(CCASFLAGS) -c -o diskless_exec-asm.o `test -f 'asm.S' || echo '$(srcdir)/'`asm.S
+
+diskless_exec-asm.obj: asm.S
+	$(CCAS) $(diskless_exec_CCASFLAGS) $(CCASFLAGS) -c -o diskless_exec-asm.obj `if test -f 'asm.S'; then $(CYGPATH_W) 'asm.S'; else $(CYGPATH_W) '$(srcdir)/asm.S'; fi`
+
+e2fs_stage1_5_exec-start.o: start.S
+	$(CCAS) $(e2fs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o e2fs_stage1_5_exec-start.o `test -f 'start.S' || echo '$(srcdir)/'`start.S
+
+e2fs_stage1_5_exec-start.obj: start.S
+	$(CCAS) $(e2fs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o e2fs_stage1_5_exec-start.obj `if test -f 'start.S'; then $(CYGPATH_W) 'start.S'; else $(CYGPATH_W) '$(srcdir)/start.S'; fi`
+
+e2fs_stage1_5_exec-asm.o: asm.S
+	$(CCAS) $(e2fs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o e2fs_stage1_5_exec-asm.o `test -f 'asm.S' || echo '$(srcdir)/'`asm.S
+
+e2fs_stage1_5_exec-asm.obj: asm.S
+	$(CCAS) $(e2fs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o e2fs_stage1_5_exec-asm.obj `if test -f 'asm.S'; then $(CYGPATH_W) 'asm.S'; else $(CYGPATH_W) '$(srcdir)/asm.S'; fi`
+
+fat_stage1_5_exec-start.o: start.S
+	$(CCAS) $(fat_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o fat_stage1_5_exec-start.o `test -f 'start.S' || echo '$(srcdir)/'`start.S
+
+fat_stage1_5_exec-start.obj: start.S
+	$(CCAS) $(fat_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o fat_stage1_5_exec-start.obj `if test -f 'start.S'; then $(CYGPATH_W) 'start.S'; else $(CYGPATH_W) '$(srcdir)/start.S'; fi`
+
+fat_stage1_5_exec-asm.o: asm.S
+	$(CCAS) $(fat_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o fat_stage1_5_exec-asm.o `test -f 'asm.S' || echo '$(srcdir)/'`asm.S
+
+fat_stage1_5_exec-asm.obj: asm.S
+	$(CCAS) $(fat_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o fat_stage1_5_exec-asm.obj `if test -f 'asm.S'; then $(CYGPATH_W) 'asm.S'; else $(CYGPATH_W) '$(srcdir)/asm.S'; fi`
+
+ffs_stage1_5_exec-start.o: start.S
+	$(CCAS) $(ffs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o ffs_stage1_5_exec-start.o `test -f 'start.S' || echo '$(srcdir)/'`start.S
+
+ffs_stage1_5_exec-start.obj: start.S
+	$(CCAS) $(ffs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o ffs_stage1_5_exec-start.obj `if test -f 'start.S'; then $(CYGPATH_W) 'start.S'; else $(CYGPATH_W) '$(srcdir)/start.S'; fi`
+
+ffs_stage1_5_exec-asm.o: asm.S
+	$(CCAS) $(ffs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o ffs_stage1_5_exec-asm.o `test -f 'asm.S' || echo '$(srcdir)/'`asm.S
+
+ffs_stage1_5_exec-asm.obj: asm.S
+	$(CCAS) $(ffs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o ffs_stage1_5_exec-asm.obj `if test -f 'asm.S'; then $(CYGPATH_W) 'asm.S'; else $(CYGPATH_W) '$(srcdir)/asm.S'; fi`
+
+iso9660_stage1_5_exec-start_eltorito.o: start_eltorito.S
+	$(CCAS) $(iso9660_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o iso9660_stage1_5_exec-start_eltorito.o `test -f 'start_eltorito.S' || echo '$(srcdir)/'`start_eltorito.S
+
+iso9660_stage1_5_exec-start_eltorito.obj: start_eltorito.S
+	$(CCAS) $(iso9660_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o iso9660_stage1_5_exec-start_eltorito.obj `if test -f 'start_eltorito.S'; then $(CYGPATH_W) 'start_eltorito.S'; else $(CYGPATH_W) '$(srcdir)/start_eltorito.S'; fi`
+
+iso9660_stage1_5_exec-asm.o: asm.S
+	$(CCAS) $(iso9660_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o iso9660_stage1_5_exec-asm.o `test -f 'asm.S' || echo '$(srcdir)/'`asm.S
+
+iso9660_stage1_5_exec-asm.obj: asm.S
+	$(CCAS) $(iso9660_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o iso9660_stage1_5_exec-asm.obj `if test -f 'asm.S'; then $(CYGPATH_W) 'asm.S'; else $(CYGPATH_W) '$(srcdir)/asm.S'; fi`
+
+jfs_stage1_5_exec-start.o: start.S
+	$(CCAS) $(jfs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o jfs_stage1_5_exec-start.o `test -f 'start.S' || echo '$(srcdir)/'`start.S
+
+jfs_stage1_5_exec-start.obj: start.S
+	$(CCAS) $(jfs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o jfs_stage1_5_exec-start.obj `if test -f 'start.S'; then $(CYGPATH_W) 'start.S'; else $(CYGPATH_W) '$(srcdir)/start.S'; fi`
+
+jfs_stage1_5_exec-asm.o: asm.S
+	$(CCAS) $(jfs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o jfs_stage1_5_exec-asm.o `test -f 'asm.S' || echo '$(srcdir)/'`asm.S
+
+jfs_stage1_5_exec-asm.obj: asm.S
+	$(CCAS) $(jfs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o jfs_stage1_5_exec-asm.obj `if test -f 'asm.S'; then $(CYGPATH_W) 'asm.S'; else $(CYGPATH_W) '$(srcdir)/asm.S'; fi`
+
+minix_stage1_5_exec-start.o: start.S
+	$(CCAS) $(minix_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o minix_stage1_5_exec-start.o `test -f 'start.S' || echo '$(srcdir)/'`start.S
+
+minix_stage1_5_exec-start.obj: start.S
+	$(CCAS) $(minix_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o minix_stage1_5_exec-start.obj `if test -f 'start.S'; then $(CYGPATH_W) 'start.S'; else $(CYGPATH_W) '$(srcdir)/start.S'; fi`
+
+minix_stage1_5_exec-asm.o: asm.S
+	$(CCAS) $(minix_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o minix_stage1_5_exec-asm.o `test -f 'asm.S' || echo '$(srcdir)/'`asm.S
+
+minix_stage1_5_exec-asm.obj: asm.S
+	$(CCAS) $(minix_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o minix_stage1_5_exec-asm.obj `if test -f 'asm.S'; then $(CYGPATH_W) 'asm.S'; else $(CYGPATH_W) '$(srcdir)/asm.S'; fi`
+
+nbloader_exec-nbloader.o: nbloader.S
+	$(CCAS) $(nbloader_exec_CCASFLAGS) $(CCASFLAGS) -c -o nbloader_exec-nbloader.o `test -f 'nbloader.S' || echo '$(srcdir)/'`nbloader.S
+
+nbloader_exec-nbloader.obj: nbloader.S
+	$(CCAS) $(nbloader_exec_CCASFLAGS) $(CCASFLAGS) -c -o nbloader_exec-nbloader.obj `if test -f 'nbloader.S'; then $(CYGPATH_W) 'nbloader.S'; else $(CYGPATH_W) '$(srcdir)/nbloader.S'; fi`
+
+pre_stage2_exec-asm.o: asm.S
+	$(CCAS) $(pre_stage2_exec_CCASFLAGS) $(CCASFLAGS) -c -o pre_stage2_exec-asm.o `test -f 'asm.S' || echo '$(srcdir)/'`asm.S
+
+pre_stage2_exec-asm.obj: asm.S
+	$(CCAS) $(pre_stage2_exec_CCASFLAGS) $(CCASFLAGS) -c -o pre_stage2_exec-asm.obj `if test -f 'asm.S'; then $(CYGPATH_W) 'asm.S'; else $(CYGPATH_W) '$(srcdir)/asm.S'; fi`
+
+pxeloader_exec-pxeloader.o: pxeloader.S
+	$(CCAS) $(pxeloader_exec_CCASFLAGS) $(CCASFLAGS) -c -o pxeloader_exec-pxeloader.o `test -f 'pxeloader.S' || echo '$(srcdir)/'`pxeloader.S
+
+pxeloader_exec-pxeloader.obj: pxeloader.S
+	$(CCAS) $(pxeloader_exec_CCASFLAGS) $(CCASFLAGS) -c -o pxeloader_exec-pxeloader.obj `if test -f 'pxeloader.S'; then $(CYGPATH_W) 'pxeloader.S'; else $(CYGPATH_W) '$(srcdir)/pxeloader.S'; fi`
+
+reiserfs_stage1_5_exec-start.o: start.S
+	$(CCAS) $(reiserfs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o reiserfs_stage1_5_exec-start.o `test -f 'start.S' || echo '$(srcdir)/'`start.S
+
+reiserfs_stage1_5_exec-start.obj: start.S
+	$(CCAS) $(reiserfs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o reiserfs_stage1_5_exec-start.obj `if test -f 'start.S'; then $(CYGPATH_W) 'start.S'; else $(CYGPATH_W) '$(srcdir)/start.S'; fi`
+
+reiserfs_stage1_5_exec-asm.o: asm.S
+	$(CCAS) $(reiserfs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o reiserfs_stage1_5_exec-asm.o `test -f 'asm.S' || echo '$(srcdir)/'`asm.S
+
+reiserfs_stage1_5_exec-asm.obj: asm.S
+	$(CCAS) $(reiserfs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o reiserfs_stage1_5_exec-asm.obj `if test -f 'asm.S'; then $(CYGPATH_W) 'asm.S'; else $(CYGPATH_W) '$(srcdir)/asm.S'; fi`
+
+start_exec-start.o: start.S
+	$(CCAS) $(start_exec_CCASFLAGS) $(CCASFLAGS) -c -o start_exec-start.o `test -f 'start.S' || echo '$(srcdir)/'`start.S
+
+start_exec-start.obj: start.S
+	$(CCAS) $(start_exec_CCASFLAGS) $(CCASFLAGS) -c -o start_exec-start.obj `if test -f 'start.S'; then $(CYGPATH_W) 'start.S'; else $(CYGPATH_W) '$(srcdir)/start.S'; fi`
+
+start_eltorito_exec-start_eltorito.o: start_eltorito.S
+	$(CCAS) $(start_eltorito_exec_CCASFLAGS) $(CCASFLAGS) -c -o start_eltorito_exec-start_eltorito.o `test -f 'start_eltorito.S' || echo '$(srcdir)/'`start_eltorito.S
+
+start_eltorito_exec-start_eltorito.obj: start_eltorito.S
+	$(CCAS) $(start_eltorito_exec_CCASFLAGS) $(CCASFLAGS) -c -o start_eltorito_exec-start_eltorito.obj `if test -f 'start_eltorito.S'; then $(CYGPATH_W) 'start_eltorito.S'; else $(CYGPATH_W) '$(srcdir)/start_eltorito.S'; fi`
+
+ufs2_stage1_5_exec-start.o: start.S
+	$(CCAS) $(ufs2_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o ufs2_stage1_5_exec-start.o `test -f 'start.S' || echo '$(srcdir)/'`start.S
+
+ufs2_stage1_5_exec-start.obj: start.S
+	$(CCAS) $(ufs2_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o ufs2_stage1_5_exec-start.obj `if test -f 'start.S'; then $(CYGPATH_W) 'start.S'; else $(CYGPATH_W) '$(srcdir)/start.S'; fi`
+
+ufs2_stage1_5_exec-asm.o: asm.S
+	$(CCAS) $(ufs2_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o ufs2_stage1_5_exec-asm.o `test -f 'asm.S' || echo '$(srcdir)/'`asm.S
+
+ufs2_stage1_5_exec-asm.obj: asm.S
+	$(CCAS) $(ufs2_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o ufs2_stage1_5_exec-asm.obj `if test -f 'asm.S'; then $(CYGPATH_W) 'asm.S'; else $(CYGPATH_W) '$(srcdir)/asm.S'; fi`
+
+vstafs_stage1_5_exec-start.o: start.S
+	$(CCAS) $(vstafs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o vstafs_stage1_5_exec-start.o `test -f 'start.S' || echo '$(srcdir)/'`start.S
+
+vstafs_stage1_5_exec-start.obj: start.S
+	$(CCAS) $(vstafs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o vstafs_stage1_5_exec-start.obj `if test -f 'start.S'; then $(CYGPATH_W) 'start.S'; else $(CYGPATH_W) '$(srcdir)/start.S'; fi`
+
+vstafs_stage1_5_exec-asm.o: asm.S
+	$(CCAS) $(vstafs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o vstafs_stage1_5_exec-asm.o `test -f 'asm.S' || echo '$(srcdir)/'`asm.S
+
+vstafs_stage1_5_exec-asm.obj: asm.S
+	$(CCAS) $(vstafs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o vstafs_stage1_5_exec-asm.obj `if test -f 'asm.S'; then $(CYGPATH_W) 'asm.S'; else $(CYGPATH_W) '$(srcdir)/asm.S'; fi`
+
+xfs_stage1_5_exec-start.o: start.S
+	$(CCAS) $(xfs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o xfs_stage1_5_exec-start.o `test -f 'start.S' || echo '$(srcdir)/'`start.S
+
+xfs_stage1_5_exec-start.obj: start.S
+	$(CCAS) $(xfs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o xfs_stage1_5_exec-start.obj `if test -f 'start.S'; then $(CYGPATH_W) 'start.S'; else $(CYGPATH_W) '$(srcdir)/start.S'; fi`
+
+xfs_stage1_5_exec-asm.o: asm.S
+	$(CCAS) $(xfs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o xfs_stage1_5_exec-asm.o `test -f 'asm.S' || echo '$(srcdir)/'`asm.S
+
+xfs_stage1_5_exec-asm.obj: asm.S
+	$(CCAS) $(xfs_stage1_5_exec_CCASFLAGS) $(CCASFLAGS) -c -o xfs_stage1_5_exec-asm.obj `if test -f 'asm.S'; then $(CYGPATH_W) 'asm.S'; else $(CYGPATH_W) '$(srcdir)/asm.S'; fi`
+
+.c.o:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+libgrub_a-boot.o: boot.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-boot.o -MD -MP -MF "$(DEPDIR)/libgrub_a-boot.Tpo" -c -o libgrub_a-boot.o `test -f 'boot.c' || echo '$(srcdir)/'`boot.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-boot.Tpo" "$(DEPDIR)/libgrub_a-boot.Po"; else rm -f "$(DEPDIR)/libgrub_a-boot.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='boot.c' object='libgrub_a-boot.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-boot.o `test -f 'boot.c' || echo '$(srcdir)/'`boot.c
+
+libgrub_a-boot.obj: boot.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-boot.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-boot.Tpo" -c -o libgrub_a-boot.obj `if test -f 'boot.c'; then $(CYGPATH_W) 'boot.c'; else $(CYGPATH_W) '$(srcdir)/boot.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-boot.Tpo" "$(DEPDIR)/libgrub_a-boot.Po"; else rm -f "$(DEPDIR)/libgrub_a-boot.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='boot.c' object='libgrub_a-boot.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-boot.obj `if test -f 'boot.c'; then $(CYGPATH_W) 'boot.c'; else $(CYGPATH_W) '$(srcdir)/boot.c'; fi`
+
+libgrub_a-builtins.o: builtins.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-builtins.o -MD -MP -MF "$(DEPDIR)/libgrub_a-builtins.Tpo" -c -o libgrub_a-builtins.o `test -f 'builtins.c' || echo '$(srcdir)/'`builtins.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-builtins.Tpo" "$(DEPDIR)/libgrub_a-builtins.Po"; else rm -f "$(DEPDIR)/libgrub_a-builtins.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='builtins.c' object='libgrub_a-builtins.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-builtins.o `test -f 'builtins.c' || echo '$(srcdir)/'`builtins.c
+
+libgrub_a-builtins.obj: builtins.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-builtins.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-builtins.Tpo" -c -o libgrub_a-builtins.obj `if test -f 'builtins.c'; then $(CYGPATH_W) 'builtins.c'; else $(CYGPATH_W) '$(srcdir)/builtins.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-builtins.Tpo" "$(DEPDIR)/libgrub_a-builtins.Po"; else rm -f "$(DEPDIR)/libgrub_a-builtins.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='builtins.c' object='libgrub_a-builtins.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-builtins.obj `if test -f 'builtins.c'; then $(CYGPATH_W) 'builtins.c'; else $(CYGPATH_W) '$(srcdir)/builtins.c'; fi`
+
+libgrub_a-char_io.o: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-char_io.o -MD -MP -MF "$(DEPDIR)/libgrub_a-char_io.Tpo" -c -o libgrub_a-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-char_io.Tpo" "$(DEPDIR)/libgrub_a-char_io.Po"; else rm -f "$(DEPDIR)/libgrub_a-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='libgrub_a-char_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c
+
+libgrub_a-char_io.obj: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-char_io.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-char_io.Tpo" -c -o libgrub_a-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-char_io.Tpo" "$(DEPDIR)/libgrub_a-char_io.Po"; else rm -f "$(DEPDIR)/libgrub_a-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='libgrub_a-char_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`
+
+libgrub_a-cmdline.o: cmdline.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-cmdline.o -MD -MP -MF "$(DEPDIR)/libgrub_a-cmdline.Tpo" -c -o libgrub_a-cmdline.o `test -f 'cmdline.c' || echo '$(srcdir)/'`cmdline.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-cmdline.Tpo" "$(DEPDIR)/libgrub_a-cmdline.Po"; else rm -f "$(DEPDIR)/libgrub_a-cmdline.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='cmdline.c' object='libgrub_a-cmdline.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-cmdline.o `test -f 'cmdline.c' || echo '$(srcdir)/'`cmdline.c
+
+libgrub_a-cmdline.obj: cmdline.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-cmdline.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-cmdline.Tpo" -c -o libgrub_a-cmdline.obj `if test -f 'cmdline.c'; then $(CYGPATH_W) 'cmdline.c'; else $(CYGPATH_W) '$(srcdir)/cmdline.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-cmdline.Tpo" "$(DEPDIR)/libgrub_a-cmdline.Po"; else rm -f "$(DEPDIR)/libgrub_a-cmdline.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='cmdline.c' object='libgrub_a-cmdline.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-cmdline.obj `if test -f 'cmdline.c'; then $(CYGPATH_W) 'cmdline.c'; else $(CYGPATH_W) '$(srcdir)/cmdline.c'; fi`
+
+libgrub_a-common.o: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-common.o -MD -MP -MF "$(DEPDIR)/libgrub_a-common.Tpo" -c -o libgrub_a-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-common.Tpo" "$(DEPDIR)/libgrub_a-common.Po"; else rm -f "$(DEPDIR)/libgrub_a-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='libgrub_a-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c
+
+libgrub_a-common.obj: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-common.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-common.Tpo" -c -o libgrub_a-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-common.Tpo" "$(DEPDIR)/libgrub_a-common.Po"; else rm -f "$(DEPDIR)/libgrub_a-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='libgrub_a-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`
+
+libgrub_a-disk_io.o: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-disk_io.o -MD -MP -MF "$(DEPDIR)/libgrub_a-disk_io.Tpo" -c -o libgrub_a-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-disk_io.Tpo" "$(DEPDIR)/libgrub_a-disk_io.Po"; else rm -f "$(DEPDIR)/libgrub_a-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='libgrub_a-disk_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c
+
+libgrub_a-disk_io.obj: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-disk_io.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-disk_io.Tpo" -c -o libgrub_a-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-disk_io.Tpo" "$(DEPDIR)/libgrub_a-disk_io.Po"; else rm -f "$(DEPDIR)/libgrub_a-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='libgrub_a-disk_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`
+
+libgrub_a-fsys_ext2fs.o: fsys_ext2fs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_ext2fs.o -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_ext2fs.Tpo" -c -o libgrub_a-fsys_ext2fs.o `test -f 'fsys_ext2fs.c' || echo '$(srcdir)/'`fsys_ext2fs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_ext2fs.Tpo" "$(DEPDIR)/libgrub_a-fsys_ext2fs.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_ext2fs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ext2fs.c' object='libgrub_a-fsys_ext2fs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_ext2fs.o `test -f 'fsys_ext2fs.c' || echo '$(srcdir)/'`fsys_ext2fs.c
+
+libgrub_a-fsys_ext2fs.obj: fsys_ext2fs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_ext2fs.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_ext2fs.Tpo" -c -o libgrub_a-fsys_ext2fs.obj `if test -f 'fsys_ext2fs.c'; then $(CYGPATH_W) 'fsys_ext2fs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ext2fs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_ext2fs.Tpo" "$(DEPDIR)/libgrub_a-fsys_ext2fs.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_ext2fs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ext2fs.c' object='libgrub_a-fsys_ext2fs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_ext2fs.obj `if test -f 'fsys_ext2fs.c'; then $(CYGPATH_W) 'fsys_ext2fs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ext2fs.c'; fi`
+
+libgrub_a-fsys_fat.o: fsys_fat.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_fat.o -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_fat.Tpo" -c -o libgrub_a-fsys_fat.o `test -f 'fsys_fat.c' || echo '$(srcdir)/'`fsys_fat.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_fat.Tpo" "$(DEPDIR)/libgrub_a-fsys_fat.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_fat.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_fat.c' object='libgrub_a-fsys_fat.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_fat.o `test -f 'fsys_fat.c' || echo '$(srcdir)/'`fsys_fat.c
+
+libgrub_a-fsys_fat.obj: fsys_fat.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_fat.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_fat.Tpo" -c -o libgrub_a-fsys_fat.obj `if test -f 'fsys_fat.c'; then $(CYGPATH_W) 'fsys_fat.c'; else $(CYGPATH_W) '$(srcdir)/fsys_fat.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_fat.Tpo" "$(DEPDIR)/libgrub_a-fsys_fat.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_fat.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_fat.c' object='libgrub_a-fsys_fat.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_fat.obj `if test -f 'fsys_fat.c'; then $(CYGPATH_W) 'fsys_fat.c'; else $(CYGPATH_W) '$(srcdir)/fsys_fat.c'; fi`
+
+libgrub_a-fsys_ffs.o: fsys_ffs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_ffs.o -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_ffs.Tpo" -c -o libgrub_a-fsys_ffs.o `test -f 'fsys_ffs.c' || echo '$(srcdir)/'`fsys_ffs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_ffs.Tpo" "$(DEPDIR)/libgrub_a-fsys_ffs.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_ffs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ffs.c' object='libgrub_a-fsys_ffs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_ffs.o `test -f 'fsys_ffs.c' || echo '$(srcdir)/'`fsys_ffs.c
+
+libgrub_a-fsys_ffs.obj: fsys_ffs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_ffs.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_ffs.Tpo" -c -o libgrub_a-fsys_ffs.obj `if test -f 'fsys_ffs.c'; then $(CYGPATH_W) 'fsys_ffs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ffs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_ffs.Tpo" "$(DEPDIR)/libgrub_a-fsys_ffs.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_ffs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ffs.c' object='libgrub_a-fsys_ffs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_ffs.obj `if test -f 'fsys_ffs.c'; then $(CYGPATH_W) 'fsys_ffs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ffs.c'; fi`
+
+libgrub_a-fsys_iso9660.o: fsys_iso9660.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_iso9660.o -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_iso9660.Tpo" -c -o libgrub_a-fsys_iso9660.o `test -f 'fsys_iso9660.c' || echo '$(srcdir)/'`fsys_iso9660.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_iso9660.Tpo" "$(DEPDIR)/libgrub_a-fsys_iso9660.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_iso9660.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_iso9660.c' object='libgrub_a-fsys_iso9660.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_iso9660.o `test -f 'fsys_iso9660.c' || echo '$(srcdir)/'`fsys_iso9660.c
+
+libgrub_a-fsys_iso9660.obj: fsys_iso9660.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_iso9660.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_iso9660.Tpo" -c -o libgrub_a-fsys_iso9660.obj `if test -f 'fsys_iso9660.c'; then $(CYGPATH_W) 'fsys_iso9660.c'; else $(CYGPATH_W) '$(srcdir)/fsys_iso9660.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_iso9660.Tpo" "$(DEPDIR)/libgrub_a-fsys_iso9660.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_iso9660.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_iso9660.c' object='libgrub_a-fsys_iso9660.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_iso9660.obj `if test -f 'fsys_iso9660.c'; then $(CYGPATH_W) 'fsys_iso9660.c'; else $(CYGPATH_W) '$(srcdir)/fsys_iso9660.c'; fi`
+
+libgrub_a-fsys_jfs.o: fsys_jfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_jfs.o -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_jfs.Tpo" -c -o libgrub_a-fsys_jfs.o `test -f 'fsys_jfs.c' || echo '$(srcdir)/'`fsys_jfs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_jfs.Tpo" "$(DEPDIR)/libgrub_a-fsys_jfs.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_jfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_jfs.c' object='libgrub_a-fsys_jfs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_jfs.o `test -f 'fsys_jfs.c' || echo '$(srcdir)/'`fsys_jfs.c
+
+libgrub_a-fsys_jfs.obj: fsys_jfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_jfs.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_jfs.Tpo" -c -o libgrub_a-fsys_jfs.obj `if test -f 'fsys_jfs.c'; then $(CYGPATH_W) 'fsys_jfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_jfs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_jfs.Tpo" "$(DEPDIR)/libgrub_a-fsys_jfs.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_jfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_jfs.c' object='libgrub_a-fsys_jfs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_jfs.obj `if test -f 'fsys_jfs.c'; then $(CYGPATH_W) 'fsys_jfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_jfs.c'; fi`
+
+libgrub_a-fsys_minix.o: fsys_minix.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_minix.o -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_minix.Tpo" -c -o libgrub_a-fsys_minix.o `test -f 'fsys_minix.c' || echo '$(srcdir)/'`fsys_minix.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_minix.Tpo" "$(DEPDIR)/libgrub_a-fsys_minix.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_minix.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_minix.c' object='libgrub_a-fsys_minix.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_minix.o `test -f 'fsys_minix.c' || echo '$(srcdir)/'`fsys_minix.c
+
+libgrub_a-fsys_minix.obj: fsys_minix.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_minix.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_minix.Tpo" -c -o libgrub_a-fsys_minix.obj `if test -f 'fsys_minix.c'; then $(CYGPATH_W) 'fsys_minix.c'; else $(CYGPATH_W) '$(srcdir)/fsys_minix.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_minix.Tpo" "$(DEPDIR)/libgrub_a-fsys_minix.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_minix.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_minix.c' object='libgrub_a-fsys_minix.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_minix.obj `if test -f 'fsys_minix.c'; then $(CYGPATH_W) 'fsys_minix.c'; else $(CYGPATH_W) '$(srcdir)/fsys_minix.c'; fi`
+
+libgrub_a-fsys_reiserfs.o: fsys_reiserfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_reiserfs.o -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_reiserfs.Tpo" -c -o libgrub_a-fsys_reiserfs.o `test -f 'fsys_reiserfs.c' || echo '$(srcdir)/'`fsys_reiserfs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_reiserfs.Tpo" "$(DEPDIR)/libgrub_a-fsys_reiserfs.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_reiserfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_reiserfs.c' object='libgrub_a-fsys_reiserfs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_reiserfs.o `test -f 'fsys_reiserfs.c' || echo '$(srcdir)/'`fsys_reiserfs.c
+
+libgrub_a-fsys_reiserfs.obj: fsys_reiserfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_reiserfs.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_reiserfs.Tpo" -c -o libgrub_a-fsys_reiserfs.obj `if test -f 'fsys_reiserfs.c'; then $(CYGPATH_W) 'fsys_reiserfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_reiserfs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_reiserfs.Tpo" "$(DEPDIR)/libgrub_a-fsys_reiserfs.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_reiserfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_reiserfs.c' object='libgrub_a-fsys_reiserfs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_reiserfs.obj `if test -f 'fsys_reiserfs.c'; then $(CYGPATH_W) 'fsys_reiserfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_reiserfs.c'; fi`
+
+libgrub_a-fsys_ufs2.o: fsys_ufs2.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_ufs2.o -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_ufs2.Tpo" -c -o libgrub_a-fsys_ufs2.o `test -f 'fsys_ufs2.c' || echo '$(srcdir)/'`fsys_ufs2.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_ufs2.Tpo" "$(DEPDIR)/libgrub_a-fsys_ufs2.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_ufs2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ufs2.c' object='libgrub_a-fsys_ufs2.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_ufs2.o `test -f 'fsys_ufs2.c' || echo '$(srcdir)/'`fsys_ufs2.c
+
+libgrub_a-fsys_ufs2.obj: fsys_ufs2.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_ufs2.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_ufs2.Tpo" -c -o libgrub_a-fsys_ufs2.obj `if test -f 'fsys_ufs2.c'; then $(CYGPATH_W) 'fsys_ufs2.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ufs2.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_ufs2.Tpo" "$(DEPDIR)/libgrub_a-fsys_ufs2.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_ufs2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ufs2.c' object='libgrub_a-fsys_ufs2.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_ufs2.obj `if test -f 'fsys_ufs2.c'; then $(CYGPATH_W) 'fsys_ufs2.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ufs2.c'; fi`
+
+libgrub_a-fsys_vstafs.o: fsys_vstafs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_vstafs.o -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_vstafs.Tpo" -c -o libgrub_a-fsys_vstafs.o `test -f 'fsys_vstafs.c' || echo '$(srcdir)/'`fsys_vstafs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_vstafs.Tpo" "$(DEPDIR)/libgrub_a-fsys_vstafs.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_vstafs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_vstafs.c' object='libgrub_a-fsys_vstafs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_vstafs.o `test -f 'fsys_vstafs.c' || echo '$(srcdir)/'`fsys_vstafs.c
+
+libgrub_a-fsys_vstafs.obj: fsys_vstafs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_vstafs.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_vstafs.Tpo" -c -o libgrub_a-fsys_vstafs.obj `if test -f 'fsys_vstafs.c'; then $(CYGPATH_W) 'fsys_vstafs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_vstafs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_vstafs.Tpo" "$(DEPDIR)/libgrub_a-fsys_vstafs.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_vstafs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_vstafs.c' object='libgrub_a-fsys_vstafs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_vstafs.obj `if test -f 'fsys_vstafs.c'; then $(CYGPATH_W) 'fsys_vstafs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_vstafs.c'; fi`
+
+libgrub_a-fsys_xfs.o: fsys_xfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_xfs.o -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_xfs.Tpo" -c -o libgrub_a-fsys_xfs.o `test -f 'fsys_xfs.c' || echo '$(srcdir)/'`fsys_xfs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_xfs.Tpo" "$(DEPDIR)/libgrub_a-fsys_xfs.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_xfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_xfs.c' object='libgrub_a-fsys_xfs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_xfs.o `test -f 'fsys_xfs.c' || echo '$(srcdir)/'`fsys_xfs.c
+
+libgrub_a-fsys_xfs.obj: fsys_xfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-fsys_xfs.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-fsys_xfs.Tpo" -c -o libgrub_a-fsys_xfs.obj `if test -f 'fsys_xfs.c'; then $(CYGPATH_W) 'fsys_xfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_xfs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-fsys_xfs.Tpo" "$(DEPDIR)/libgrub_a-fsys_xfs.Po"; else rm -f "$(DEPDIR)/libgrub_a-fsys_xfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_xfs.c' object='libgrub_a-fsys_xfs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-fsys_xfs.obj `if test -f 'fsys_xfs.c'; then $(CYGPATH_W) 'fsys_xfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_xfs.c'; fi`
+
+libgrub_a-gunzip.o: gunzip.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-gunzip.o -MD -MP -MF "$(DEPDIR)/libgrub_a-gunzip.Tpo" -c -o libgrub_a-gunzip.o `test -f 'gunzip.c' || echo '$(srcdir)/'`gunzip.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-gunzip.Tpo" "$(DEPDIR)/libgrub_a-gunzip.Po"; else rm -f "$(DEPDIR)/libgrub_a-gunzip.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gunzip.c' object='libgrub_a-gunzip.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-gunzip.o `test -f 'gunzip.c' || echo '$(srcdir)/'`gunzip.c
+
+libgrub_a-gunzip.obj: gunzip.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-gunzip.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-gunzip.Tpo" -c -o libgrub_a-gunzip.obj `if test -f 'gunzip.c'; then $(CYGPATH_W) 'gunzip.c'; else $(CYGPATH_W) '$(srcdir)/gunzip.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-gunzip.Tpo" "$(DEPDIR)/libgrub_a-gunzip.Po"; else rm -f "$(DEPDIR)/libgrub_a-gunzip.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gunzip.c' object='libgrub_a-gunzip.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-gunzip.obj `if test -f 'gunzip.c'; then $(CYGPATH_W) 'gunzip.c'; else $(CYGPATH_W) '$(srcdir)/gunzip.c'; fi`
+
+libgrub_a-md5.o: md5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-md5.o -MD -MP -MF "$(DEPDIR)/libgrub_a-md5.Tpo" -c -o libgrub_a-md5.o `test -f 'md5.c' || echo '$(srcdir)/'`md5.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-md5.Tpo" "$(DEPDIR)/libgrub_a-md5.Po"; else rm -f "$(DEPDIR)/libgrub_a-md5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='md5.c' object='libgrub_a-md5.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-md5.o `test -f 'md5.c' || echo '$(srcdir)/'`md5.c
+
+libgrub_a-md5.obj: md5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-md5.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-md5.Tpo" -c -o libgrub_a-md5.obj `if test -f 'md5.c'; then $(CYGPATH_W) 'md5.c'; else $(CYGPATH_W) '$(srcdir)/md5.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-md5.Tpo" "$(DEPDIR)/libgrub_a-md5.Po"; else rm -f "$(DEPDIR)/libgrub_a-md5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='md5.c' object='libgrub_a-md5.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-md5.obj `if test -f 'md5.c'; then $(CYGPATH_W) 'md5.c'; else $(CYGPATH_W) '$(srcdir)/md5.c'; fi`
+
+libgrub_a-serial.o: serial.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-serial.o -MD -MP -MF "$(DEPDIR)/libgrub_a-serial.Tpo" -c -o libgrub_a-serial.o `test -f 'serial.c' || echo '$(srcdir)/'`serial.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-serial.Tpo" "$(DEPDIR)/libgrub_a-serial.Po"; else rm -f "$(DEPDIR)/libgrub_a-serial.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='serial.c' object='libgrub_a-serial.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-serial.o `test -f 'serial.c' || echo '$(srcdir)/'`serial.c
+
+libgrub_a-serial.obj: serial.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-serial.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-serial.Tpo" -c -o libgrub_a-serial.obj `if test -f 'serial.c'; then $(CYGPATH_W) 'serial.c'; else $(CYGPATH_W) '$(srcdir)/serial.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-serial.Tpo" "$(DEPDIR)/libgrub_a-serial.Po"; else rm -f "$(DEPDIR)/libgrub_a-serial.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='serial.c' object='libgrub_a-serial.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-serial.obj `if test -f 'serial.c'; then $(CYGPATH_W) 'serial.c'; else $(CYGPATH_W) '$(srcdir)/serial.c'; fi`
+
+libgrub_a-stage2.o: stage2.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-stage2.o -MD -MP -MF "$(DEPDIR)/libgrub_a-stage2.Tpo" -c -o libgrub_a-stage2.o `test -f 'stage2.c' || echo '$(srcdir)/'`stage2.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-stage2.Tpo" "$(DEPDIR)/libgrub_a-stage2.Po"; else rm -f "$(DEPDIR)/libgrub_a-stage2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage2.c' object='libgrub_a-stage2.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-stage2.o `test -f 'stage2.c' || echo '$(srcdir)/'`stage2.c
+
+libgrub_a-stage2.obj: stage2.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-stage2.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-stage2.Tpo" -c -o libgrub_a-stage2.obj `if test -f 'stage2.c'; then $(CYGPATH_W) 'stage2.c'; else $(CYGPATH_W) '$(srcdir)/stage2.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-stage2.Tpo" "$(DEPDIR)/libgrub_a-stage2.Po"; else rm -f "$(DEPDIR)/libgrub_a-stage2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage2.c' object='libgrub_a-stage2.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-stage2.obj `if test -f 'stage2.c'; then $(CYGPATH_W) 'stage2.c'; else $(CYGPATH_W) '$(srcdir)/stage2.c'; fi`
+
+libgrub_a-terminfo.o: terminfo.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-terminfo.o -MD -MP -MF "$(DEPDIR)/libgrub_a-terminfo.Tpo" -c -o libgrub_a-terminfo.o `test -f 'terminfo.c' || echo '$(srcdir)/'`terminfo.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-terminfo.Tpo" "$(DEPDIR)/libgrub_a-terminfo.Po"; else rm -f "$(DEPDIR)/libgrub_a-terminfo.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='terminfo.c' object='libgrub_a-terminfo.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-terminfo.o `test -f 'terminfo.c' || echo '$(srcdir)/'`terminfo.c
+
+libgrub_a-terminfo.obj: terminfo.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-terminfo.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-terminfo.Tpo" -c -o libgrub_a-terminfo.obj `if test -f 'terminfo.c'; then $(CYGPATH_W) 'terminfo.c'; else $(CYGPATH_W) '$(srcdir)/terminfo.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-terminfo.Tpo" "$(DEPDIR)/libgrub_a-terminfo.Po"; else rm -f "$(DEPDIR)/libgrub_a-terminfo.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='terminfo.c' object='libgrub_a-terminfo.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-terminfo.obj `if test -f 'terminfo.c'; then $(CYGPATH_W) 'terminfo.c'; else $(CYGPATH_W) '$(srcdir)/terminfo.c'; fi`
+
+libgrub_a-tparm.o: tparm.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-tparm.o -MD -MP -MF "$(DEPDIR)/libgrub_a-tparm.Tpo" -c -o libgrub_a-tparm.o `test -f 'tparm.c' || echo '$(srcdir)/'`tparm.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-tparm.Tpo" "$(DEPDIR)/libgrub_a-tparm.Po"; else rm -f "$(DEPDIR)/libgrub_a-tparm.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='tparm.c' object='libgrub_a-tparm.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-tparm.o `test -f 'tparm.c' || echo '$(srcdir)/'`tparm.c
+
+libgrub_a-tparm.obj: tparm.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -MT libgrub_a-tparm.obj -MD -MP -MF "$(DEPDIR)/libgrub_a-tparm.Tpo" -c -o libgrub_a-tparm.obj `if test -f 'tparm.c'; then $(CYGPATH_W) 'tparm.c'; else $(CYGPATH_W) '$(srcdir)/tparm.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/libgrub_a-tparm.Tpo" "$(DEPDIR)/libgrub_a-tparm.Po"; else rm -f "$(DEPDIR)/libgrub_a-tparm.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='tparm.c' object='libgrub_a-tparm.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgrub_a_CFLAGS) $(CFLAGS) -c -o libgrub_a-tparm.obj `if test -f 'tparm.c'; then $(CYGPATH_W) 'tparm.c'; else $(CYGPATH_W) '$(srcdir)/tparm.c'; fi`
+
+diskless_exec-bios.o: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-bios.o -MD -MP -MF "$(DEPDIR)/diskless_exec-bios.Tpo" -c -o diskless_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-bios.Tpo" "$(DEPDIR)/diskless_exec-bios.Po"; else rm -f "$(DEPDIR)/diskless_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='diskless_exec-bios.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c
+
+diskless_exec-bios.obj: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-bios.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-bios.Tpo" -c -o diskless_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-bios.Tpo" "$(DEPDIR)/diskless_exec-bios.Po"; else rm -f "$(DEPDIR)/diskless_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='diskless_exec-bios.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`
+
+diskless_exec-boot.o: boot.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-boot.o -MD -MP -MF "$(DEPDIR)/diskless_exec-boot.Tpo" -c -o diskless_exec-boot.o `test -f 'boot.c' || echo '$(srcdir)/'`boot.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-boot.Tpo" "$(DEPDIR)/diskless_exec-boot.Po"; else rm -f "$(DEPDIR)/diskless_exec-boot.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='boot.c' object='diskless_exec-boot.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-boot.o `test -f 'boot.c' || echo '$(srcdir)/'`boot.c
+
+diskless_exec-boot.obj: boot.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-boot.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-boot.Tpo" -c -o diskless_exec-boot.obj `if test -f 'boot.c'; then $(CYGPATH_W) 'boot.c'; else $(CYGPATH_W) '$(srcdir)/boot.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-boot.Tpo" "$(DEPDIR)/diskless_exec-boot.Po"; else rm -f "$(DEPDIR)/diskless_exec-boot.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='boot.c' object='diskless_exec-boot.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-boot.obj `if test -f 'boot.c'; then $(CYGPATH_W) 'boot.c'; else $(CYGPATH_W) '$(srcdir)/boot.c'; fi`
+
+diskless_exec-builtins.o: builtins.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-builtins.o -MD -MP -MF "$(DEPDIR)/diskless_exec-builtins.Tpo" -c -o diskless_exec-builtins.o `test -f 'builtins.c' || echo '$(srcdir)/'`builtins.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-builtins.Tpo" "$(DEPDIR)/diskless_exec-builtins.Po"; else rm -f "$(DEPDIR)/diskless_exec-builtins.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='builtins.c' object='diskless_exec-builtins.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-builtins.o `test -f 'builtins.c' || echo '$(srcdir)/'`builtins.c
+
+diskless_exec-builtins.obj: builtins.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-builtins.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-builtins.Tpo" -c -o diskless_exec-builtins.obj `if test -f 'builtins.c'; then $(CYGPATH_W) 'builtins.c'; else $(CYGPATH_W) '$(srcdir)/builtins.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-builtins.Tpo" "$(DEPDIR)/diskless_exec-builtins.Po"; else rm -f "$(DEPDIR)/diskless_exec-builtins.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='builtins.c' object='diskless_exec-builtins.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-builtins.obj `if test -f 'builtins.c'; then $(CYGPATH_W) 'builtins.c'; else $(CYGPATH_W) '$(srcdir)/builtins.c'; fi`
+
+diskless_exec-char_io.o: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-char_io.o -MD -MP -MF "$(DEPDIR)/diskless_exec-char_io.Tpo" -c -o diskless_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-char_io.Tpo" "$(DEPDIR)/diskless_exec-char_io.Po"; else rm -f "$(DEPDIR)/diskless_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='diskless_exec-char_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c
+
+diskless_exec-char_io.obj: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-char_io.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-char_io.Tpo" -c -o diskless_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-char_io.Tpo" "$(DEPDIR)/diskless_exec-char_io.Po"; else rm -f "$(DEPDIR)/diskless_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='diskless_exec-char_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`
+
+diskless_exec-cmdline.o: cmdline.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-cmdline.o -MD -MP -MF "$(DEPDIR)/diskless_exec-cmdline.Tpo" -c -o diskless_exec-cmdline.o `test -f 'cmdline.c' || echo '$(srcdir)/'`cmdline.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-cmdline.Tpo" "$(DEPDIR)/diskless_exec-cmdline.Po"; else rm -f "$(DEPDIR)/diskless_exec-cmdline.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='cmdline.c' object='diskless_exec-cmdline.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-cmdline.o `test -f 'cmdline.c' || echo '$(srcdir)/'`cmdline.c
+
+diskless_exec-cmdline.obj: cmdline.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-cmdline.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-cmdline.Tpo" -c -o diskless_exec-cmdline.obj `if test -f 'cmdline.c'; then $(CYGPATH_W) 'cmdline.c'; else $(CYGPATH_W) '$(srcdir)/cmdline.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-cmdline.Tpo" "$(DEPDIR)/diskless_exec-cmdline.Po"; else rm -f "$(DEPDIR)/diskless_exec-cmdline.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='cmdline.c' object='diskless_exec-cmdline.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-cmdline.obj `if test -f 'cmdline.c'; then $(CYGPATH_W) 'cmdline.c'; else $(CYGPATH_W) '$(srcdir)/cmdline.c'; fi`
+
+diskless_exec-common.o: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-common.o -MD -MP -MF "$(DEPDIR)/diskless_exec-common.Tpo" -c -o diskless_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-common.Tpo" "$(DEPDIR)/diskless_exec-common.Po"; else rm -f "$(DEPDIR)/diskless_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='diskless_exec-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c
+
+diskless_exec-common.obj: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-common.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-common.Tpo" -c -o diskless_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-common.Tpo" "$(DEPDIR)/diskless_exec-common.Po"; else rm -f "$(DEPDIR)/diskless_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='diskless_exec-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`
+
+diskless_exec-console.o: console.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-console.o -MD -MP -MF "$(DEPDIR)/diskless_exec-console.Tpo" -c -o diskless_exec-console.o `test -f 'console.c' || echo '$(srcdir)/'`console.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-console.Tpo" "$(DEPDIR)/diskless_exec-console.Po"; else rm -f "$(DEPDIR)/diskless_exec-console.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='console.c' object='diskless_exec-console.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-console.o `test -f 'console.c' || echo '$(srcdir)/'`console.c
+
+diskless_exec-console.obj: console.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-console.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-console.Tpo" -c -o diskless_exec-console.obj `if test -f 'console.c'; then $(CYGPATH_W) 'console.c'; else $(CYGPATH_W) '$(srcdir)/console.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-console.Tpo" "$(DEPDIR)/diskless_exec-console.Po"; else rm -f "$(DEPDIR)/diskless_exec-console.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='console.c' object='diskless_exec-console.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-console.obj `if test -f 'console.c'; then $(CYGPATH_W) 'console.c'; else $(CYGPATH_W) '$(srcdir)/console.c'; fi`
+
+diskless_exec-disk_io.o: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-disk_io.o -MD -MP -MF "$(DEPDIR)/diskless_exec-disk_io.Tpo" -c -o diskless_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-disk_io.Tpo" "$(DEPDIR)/diskless_exec-disk_io.Po"; else rm -f "$(DEPDIR)/diskless_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='diskless_exec-disk_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c
+
+diskless_exec-disk_io.obj: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-disk_io.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-disk_io.Tpo" -c -o diskless_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-disk_io.Tpo" "$(DEPDIR)/diskless_exec-disk_io.Po"; else rm -f "$(DEPDIR)/diskless_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='diskless_exec-disk_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`
+
+diskless_exec-fsys_ext2fs.o: fsys_ext2fs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_ext2fs.o -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_ext2fs.Tpo" -c -o diskless_exec-fsys_ext2fs.o `test -f 'fsys_ext2fs.c' || echo '$(srcdir)/'`fsys_ext2fs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_ext2fs.Tpo" "$(DEPDIR)/diskless_exec-fsys_ext2fs.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_ext2fs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ext2fs.c' object='diskless_exec-fsys_ext2fs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_ext2fs.o `test -f 'fsys_ext2fs.c' || echo '$(srcdir)/'`fsys_ext2fs.c
+
+diskless_exec-fsys_ext2fs.obj: fsys_ext2fs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_ext2fs.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_ext2fs.Tpo" -c -o diskless_exec-fsys_ext2fs.obj `if test -f 'fsys_ext2fs.c'; then $(CYGPATH_W) 'fsys_ext2fs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ext2fs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_ext2fs.Tpo" "$(DEPDIR)/diskless_exec-fsys_ext2fs.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_ext2fs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ext2fs.c' object='diskless_exec-fsys_ext2fs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_ext2fs.obj `if test -f 'fsys_ext2fs.c'; then $(CYGPATH_W) 'fsys_ext2fs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ext2fs.c'; fi`
+
+diskless_exec-fsys_fat.o: fsys_fat.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_fat.o -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_fat.Tpo" -c -o diskless_exec-fsys_fat.o `test -f 'fsys_fat.c' || echo '$(srcdir)/'`fsys_fat.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_fat.Tpo" "$(DEPDIR)/diskless_exec-fsys_fat.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_fat.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_fat.c' object='diskless_exec-fsys_fat.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_fat.o `test -f 'fsys_fat.c' || echo '$(srcdir)/'`fsys_fat.c
+
+diskless_exec-fsys_fat.obj: fsys_fat.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_fat.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_fat.Tpo" -c -o diskless_exec-fsys_fat.obj `if test -f 'fsys_fat.c'; then $(CYGPATH_W) 'fsys_fat.c'; else $(CYGPATH_W) '$(srcdir)/fsys_fat.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_fat.Tpo" "$(DEPDIR)/diskless_exec-fsys_fat.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_fat.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_fat.c' object='diskless_exec-fsys_fat.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_fat.obj `if test -f 'fsys_fat.c'; then $(CYGPATH_W) 'fsys_fat.c'; else $(CYGPATH_W) '$(srcdir)/fsys_fat.c'; fi`
+
+diskless_exec-fsys_ffs.o: fsys_ffs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_ffs.o -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_ffs.Tpo" -c -o diskless_exec-fsys_ffs.o `test -f 'fsys_ffs.c' || echo '$(srcdir)/'`fsys_ffs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_ffs.Tpo" "$(DEPDIR)/diskless_exec-fsys_ffs.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_ffs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ffs.c' object='diskless_exec-fsys_ffs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_ffs.o `test -f 'fsys_ffs.c' || echo '$(srcdir)/'`fsys_ffs.c
+
+diskless_exec-fsys_ffs.obj: fsys_ffs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_ffs.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_ffs.Tpo" -c -o diskless_exec-fsys_ffs.obj `if test -f 'fsys_ffs.c'; then $(CYGPATH_W) 'fsys_ffs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ffs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_ffs.Tpo" "$(DEPDIR)/diskless_exec-fsys_ffs.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_ffs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ffs.c' object='diskless_exec-fsys_ffs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_ffs.obj `if test -f 'fsys_ffs.c'; then $(CYGPATH_W) 'fsys_ffs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ffs.c'; fi`
+
+diskless_exec-fsys_iso9660.o: fsys_iso9660.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_iso9660.o -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_iso9660.Tpo" -c -o diskless_exec-fsys_iso9660.o `test -f 'fsys_iso9660.c' || echo '$(srcdir)/'`fsys_iso9660.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_iso9660.Tpo" "$(DEPDIR)/diskless_exec-fsys_iso9660.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_iso9660.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_iso9660.c' object='diskless_exec-fsys_iso9660.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_iso9660.o `test -f 'fsys_iso9660.c' || echo '$(srcdir)/'`fsys_iso9660.c
+
+diskless_exec-fsys_iso9660.obj: fsys_iso9660.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_iso9660.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_iso9660.Tpo" -c -o diskless_exec-fsys_iso9660.obj `if test -f 'fsys_iso9660.c'; then $(CYGPATH_W) 'fsys_iso9660.c'; else $(CYGPATH_W) '$(srcdir)/fsys_iso9660.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_iso9660.Tpo" "$(DEPDIR)/diskless_exec-fsys_iso9660.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_iso9660.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_iso9660.c' object='diskless_exec-fsys_iso9660.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_iso9660.obj `if test -f 'fsys_iso9660.c'; then $(CYGPATH_W) 'fsys_iso9660.c'; else $(CYGPATH_W) '$(srcdir)/fsys_iso9660.c'; fi`
+
+diskless_exec-fsys_jfs.o: fsys_jfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_jfs.o -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_jfs.Tpo" -c -o diskless_exec-fsys_jfs.o `test -f 'fsys_jfs.c' || echo '$(srcdir)/'`fsys_jfs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_jfs.Tpo" "$(DEPDIR)/diskless_exec-fsys_jfs.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_jfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_jfs.c' object='diskless_exec-fsys_jfs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_jfs.o `test -f 'fsys_jfs.c' || echo '$(srcdir)/'`fsys_jfs.c
+
+diskless_exec-fsys_jfs.obj: fsys_jfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_jfs.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_jfs.Tpo" -c -o diskless_exec-fsys_jfs.obj `if test -f 'fsys_jfs.c'; then $(CYGPATH_W) 'fsys_jfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_jfs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_jfs.Tpo" "$(DEPDIR)/diskless_exec-fsys_jfs.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_jfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_jfs.c' object='diskless_exec-fsys_jfs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_jfs.obj `if test -f 'fsys_jfs.c'; then $(CYGPATH_W) 'fsys_jfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_jfs.c'; fi`
+
+diskless_exec-fsys_minix.o: fsys_minix.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_minix.o -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_minix.Tpo" -c -o diskless_exec-fsys_minix.o `test -f 'fsys_minix.c' || echo '$(srcdir)/'`fsys_minix.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_minix.Tpo" "$(DEPDIR)/diskless_exec-fsys_minix.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_minix.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_minix.c' object='diskless_exec-fsys_minix.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_minix.o `test -f 'fsys_minix.c' || echo '$(srcdir)/'`fsys_minix.c
+
+diskless_exec-fsys_minix.obj: fsys_minix.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_minix.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_minix.Tpo" -c -o diskless_exec-fsys_minix.obj `if test -f 'fsys_minix.c'; then $(CYGPATH_W) 'fsys_minix.c'; else $(CYGPATH_W) '$(srcdir)/fsys_minix.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_minix.Tpo" "$(DEPDIR)/diskless_exec-fsys_minix.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_minix.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_minix.c' object='diskless_exec-fsys_minix.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_minix.obj `if test -f 'fsys_minix.c'; then $(CYGPATH_W) 'fsys_minix.c'; else $(CYGPATH_W) '$(srcdir)/fsys_minix.c'; fi`
+
+diskless_exec-fsys_reiserfs.o: fsys_reiserfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_reiserfs.o -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_reiserfs.Tpo" -c -o diskless_exec-fsys_reiserfs.o `test -f 'fsys_reiserfs.c' || echo '$(srcdir)/'`fsys_reiserfs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_reiserfs.Tpo" "$(DEPDIR)/diskless_exec-fsys_reiserfs.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_reiserfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_reiserfs.c' object='diskless_exec-fsys_reiserfs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_reiserfs.o `test -f 'fsys_reiserfs.c' || echo '$(srcdir)/'`fsys_reiserfs.c
+
+diskless_exec-fsys_reiserfs.obj: fsys_reiserfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_reiserfs.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_reiserfs.Tpo" -c -o diskless_exec-fsys_reiserfs.obj `if test -f 'fsys_reiserfs.c'; then $(CYGPATH_W) 'fsys_reiserfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_reiserfs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_reiserfs.Tpo" "$(DEPDIR)/diskless_exec-fsys_reiserfs.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_reiserfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_reiserfs.c' object='diskless_exec-fsys_reiserfs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_reiserfs.obj `if test -f 'fsys_reiserfs.c'; then $(CYGPATH_W) 'fsys_reiserfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_reiserfs.c'; fi`
+
+diskless_exec-fsys_ufs2.o: fsys_ufs2.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_ufs2.o -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_ufs2.Tpo" -c -o diskless_exec-fsys_ufs2.o `test -f 'fsys_ufs2.c' || echo '$(srcdir)/'`fsys_ufs2.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_ufs2.Tpo" "$(DEPDIR)/diskless_exec-fsys_ufs2.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_ufs2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ufs2.c' object='diskless_exec-fsys_ufs2.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_ufs2.o `test -f 'fsys_ufs2.c' || echo '$(srcdir)/'`fsys_ufs2.c
+
+diskless_exec-fsys_ufs2.obj: fsys_ufs2.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_ufs2.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_ufs2.Tpo" -c -o diskless_exec-fsys_ufs2.obj `if test -f 'fsys_ufs2.c'; then $(CYGPATH_W) 'fsys_ufs2.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ufs2.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_ufs2.Tpo" "$(DEPDIR)/diskless_exec-fsys_ufs2.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_ufs2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ufs2.c' object='diskless_exec-fsys_ufs2.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_ufs2.obj `if test -f 'fsys_ufs2.c'; then $(CYGPATH_W) 'fsys_ufs2.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ufs2.c'; fi`
+
+diskless_exec-fsys_vstafs.o: fsys_vstafs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_vstafs.o -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_vstafs.Tpo" -c -o diskless_exec-fsys_vstafs.o `test -f 'fsys_vstafs.c' || echo '$(srcdir)/'`fsys_vstafs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_vstafs.Tpo" "$(DEPDIR)/diskless_exec-fsys_vstafs.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_vstafs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_vstafs.c' object='diskless_exec-fsys_vstafs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_vstafs.o `test -f 'fsys_vstafs.c' || echo '$(srcdir)/'`fsys_vstafs.c
+
+diskless_exec-fsys_vstafs.obj: fsys_vstafs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_vstafs.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_vstafs.Tpo" -c -o diskless_exec-fsys_vstafs.obj `if test -f 'fsys_vstafs.c'; then $(CYGPATH_W) 'fsys_vstafs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_vstafs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_vstafs.Tpo" "$(DEPDIR)/diskless_exec-fsys_vstafs.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_vstafs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_vstafs.c' object='diskless_exec-fsys_vstafs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_vstafs.obj `if test -f 'fsys_vstafs.c'; then $(CYGPATH_W) 'fsys_vstafs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_vstafs.c'; fi`
+
+diskless_exec-fsys_xfs.o: fsys_xfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_xfs.o -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_xfs.Tpo" -c -o diskless_exec-fsys_xfs.o `test -f 'fsys_xfs.c' || echo '$(srcdir)/'`fsys_xfs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_xfs.Tpo" "$(DEPDIR)/diskless_exec-fsys_xfs.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_xfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_xfs.c' object='diskless_exec-fsys_xfs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_xfs.o `test -f 'fsys_xfs.c' || echo '$(srcdir)/'`fsys_xfs.c
+
+diskless_exec-fsys_xfs.obj: fsys_xfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-fsys_xfs.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-fsys_xfs.Tpo" -c -o diskless_exec-fsys_xfs.obj `if test -f 'fsys_xfs.c'; then $(CYGPATH_W) 'fsys_xfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_xfs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-fsys_xfs.Tpo" "$(DEPDIR)/diskless_exec-fsys_xfs.Po"; else rm -f "$(DEPDIR)/diskless_exec-fsys_xfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_xfs.c' object='diskless_exec-fsys_xfs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-fsys_xfs.obj `if test -f 'fsys_xfs.c'; then $(CYGPATH_W) 'fsys_xfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_xfs.c'; fi`
+
+diskless_exec-gunzip.o: gunzip.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-gunzip.o -MD -MP -MF "$(DEPDIR)/diskless_exec-gunzip.Tpo" -c -o diskless_exec-gunzip.o `test -f 'gunzip.c' || echo '$(srcdir)/'`gunzip.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-gunzip.Tpo" "$(DEPDIR)/diskless_exec-gunzip.Po"; else rm -f "$(DEPDIR)/diskless_exec-gunzip.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gunzip.c' object='diskless_exec-gunzip.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-gunzip.o `test -f 'gunzip.c' || echo '$(srcdir)/'`gunzip.c
+
+diskless_exec-gunzip.obj: gunzip.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-gunzip.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-gunzip.Tpo" -c -o diskless_exec-gunzip.obj `if test -f 'gunzip.c'; then $(CYGPATH_W) 'gunzip.c'; else $(CYGPATH_W) '$(srcdir)/gunzip.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-gunzip.Tpo" "$(DEPDIR)/diskless_exec-gunzip.Po"; else rm -f "$(DEPDIR)/diskless_exec-gunzip.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gunzip.c' object='diskless_exec-gunzip.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-gunzip.obj `if test -f 'gunzip.c'; then $(CYGPATH_W) 'gunzip.c'; else $(CYGPATH_W) '$(srcdir)/gunzip.c'; fi`
+
+diskless_exec-hercules.o: hercules.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-hercules.o -MD -MP -MF "$(DEPDIR)/diskless_exec-hercules.Tpo" -c -o diskless_exec-hercules.o `test -f 'hercules.c' || echo '$(srcdir)/'`hercules.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-hercules.Tpo" "$(DEPDIR)/diskless_exec-hercules.Po"; else rm -f "$(DEPDIR)/diskless_exec-hercules.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='hercules.c' object='diskless_exec-hercules.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-hercules.o `test -f 'hercules.c' || echo '$(srcdir)/'`hercules.c
+
+diskless_exec-hercules.obj: hercules.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-hercules.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-hercules.Tpo" -c -o diskless_exec-hercules.obj `if test -f 'hercules.c'; then $(CYGPATH_W) 'hercules.c'; else $(CYGPATH_W) '$(srcdir)/hercules.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-hercules.Tpo" "$(DEPDIR)/diskless_exec-hercules.Po"; else rm -f "$(DEPDIR)/diskless_exec-hercules.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='hercules.c' object='diskless_exec-hercules.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-hercules.obj `if test -f 'hercules.c'; then $(CYGPATH_W) 'hercules.c'; else $(CYGPATH_W) '$(srcdir)/hercules.c'; fi`
+
+diskless_exec-md5.o: md5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-md5.o -MD -MP -MF "$(DEPDIR)/diskless_exec-md5.Tpo" -c -o diskless_exec-md5.o `test -f 'md5.c' || echo '$(srcdir)/'`md5.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-md5.Tpo" "$(DEPDIR)/diskless_exec-md5.Po"; else rm -f "$(DEPDIR)/diskless_exec-md5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='md5.c' object='diskless_exec-md5.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-md5.o `test -f 'md5.c' || echo '$(srcdir)/'`md5.c
+
+diskless_exec-md5.obj: md5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-md5.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-md5.Tpo" -c -o diskless_exec-md5.obj `if test -f 'md5.c'; then $(CYGPATH_W) 'md5.c'; else $(CYGPATH_W) '$(srcdir)/md5.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-md5.Tpo" "$(DEPDIR)/diskless_exec-md5.Po"; else rm -f "$(DEPDIR)/diskless_exec-md5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='md5.c' object='diskless_exec-md5.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-md5.obj `if test -f 'md5.c'; then $(CYGPATH_W) 'md5.c'; else $(CYGPATH_W) '$(srcdir)/md5.c'; fi`
+
+diskless_exec-serial.o: serial.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-serial.o -MD -MP -MF "$(DEPDIR)/diskless_exec-serial.Tpo" -c -o diskless_exec-serial.o `test -f 'serial.c' || echo '$(srcdir)/'`serial.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-serial.Tpo" "$(DEPDIR)/diskless_exec-serial.Po"; else rm -f "$(DEPDIR)/diskless_exec-serial.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='serial.c' object='diskless_exec-serial.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-serial.o `test -f 'serial.c' || echo '$(srcdir)/'`serial.c
+
+diskless_exec-serial.obj: serial.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-serial.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-serial.Tpo" -c -o diskless_exec-serial.obj `if test -f 'serial.c'; then $(CYGPATH_W) 'serial.c'; else $(CYGPATH_W) '$(srcdir)/serial.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-serial.Tpo" "$(DEPDIR)/diskless_exec-serial.Po"; else rm -f "$(DEPDIR)/diskless_exec-serial.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='serial.c' object='diskless_exec-serial.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-serial.obj `if test -f 'serial.c'; then $(CYGPATH_W) 'serial.c'; else $(CYGPATH_W) '$(srcdir)/serial.c'; fi`
+
+diskless_exec-smp-imps.o: smp-imps.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-smp-imps.o -MD -MP -MF "$(DEPDIR)/diskless_exec-smp-imps.Tpo" -c -o diskless_exec-smp-imps.o `test -f 'smp-imps.c' || echo '$(srcdir)/'`smp-imps.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-smp-imps.Tpo" "$(DEPDIR)/diskless_exec-smp-imps.Po"; else rm -f "$(DEPDIR)/diskless_exec-smp-imps.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='smp-imps.c' object='diskless_exec-smp-imps.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-smp-imps.o `test -f 'smp-imps.c' || echo '$(srcdir)/'`smp-imps.c
+
+diskless_exec-smp-imps.obj: smp-imps.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-smp-imps.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-smp-imps.Tpo" -c -o diskless_exec-smp-imps.obj `if test -f 'smp-imps.c'; then $(CYGPATH_W) 'smp-imps.c'; else $(CYGPATH_W) '$(srcdir)/smp-imps.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-smp-imps.Tpo" "$(DEPDIR)/diskless_exec-smp-imps.Po"; else rm -f "$(DEPDIR)/diskless_exec-smp-imps.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='smp-imps.c' object='diskless_exec-smp-imps.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-smp-imps.obj `if test -f 'smp-imps.c'; then $(CYGPATH_W) 'smp-imps.c'; else $(CYGPATH_W) '$(srcdir)/smp-imps.c'; fi`
+
+diskless_exec-stage2.o: stage2.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-stage2.o -MD -MP -MF "$(DEPDIR)/diskless_exec-stage2.Tpo" -c -o diskless_exec-stage2.o `test -f 'stage2.c' || echo '$(srcdir)/'`stage2.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-stage2.Tpo" "$(DEPDIR)/diskless_exec-stage2.Po"; else rm -f "$(DEPDIR)/diskless_exec-stage2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage2.c' object='diskless_exec-stage2.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-stage2.o `test -f 'stage2.c' || echo '$(srcdir)/'`stage2.c
+
+diskless_exec-stage2.obj: stage2.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-stage2.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-stage2.Tpo" -c -o diskless_exec-stage2.obj `if test -f 'stage2.c'; then $(CYGPATH_W) 'stage2.c'; else $(CYGPATH_W) '$(srcdir)/stage2.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-stage2.Tpo" "$(DEPDIR)/diskless_exec-stage2.Po"; else rm -f "$(DEPDIR)/diskless_exec-stage2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage2.c' object='diskless_exec-stage2.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-stage2.obj `if test -f 'stage2.c'; then $(CYGPATH_W) 'stage2.c'; else $(CYGPATH_W) '$(srcdir)/stage2.c'; fi`
+
+diskless_exec-terminfo.o: terminfo.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-terminfo.o -MD -MP -MF "$(DEPDIR)/diskless_exec-terminfo.Tpo" -c -o diskless_exec-terminfo.o `test -f 'terminfo.c' || echo '$(srcdir)/'`terminfo.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-terminfo.Tpo" "$(DEPDIR)/diskless_exec-terminfo.Po"; else rm -f "$(DEPDIR)/diskless_exec-terminfo.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='terminfo.c' object='diskless_exec-terminfo.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-terminfo.o `test -f 'terminfo.c' || echo '$(srcdir)/'`terminfo.c
+
+diskless_exec-terminfo.obj: terminfo.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-terminfo.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-terminfo.Tpo" -c -o diskless_exec-terminfo.obj `if test -f 'terminfo.c'; then $(CYGPATH_W) 'terminfo.c'; else $(CYGPATH_W) '$(srcdir)/terminfo.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-terminfo.Tpo" "$(DEPDIR)/diskless_exec-terminfo.Po"; else rm -f "$(DEPDIR)/diskless_exec-terminfo.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='terminfo.c' object='diskless_exec-terminfo.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-terminfo.obj `if test -f 'terminfo.c'; then $(CYGPATH_W) 'terminfo.c'; else $(CYGPATH_W) '$(srcdir)/terminfo.c'; fi`
+
+diskless_exec-tparm.o: tparm.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-tparm.o -MD -MP -MF "$(DEPDIR)/diskless_exec-tparm.Tpo" -c -o diskless_exec-tparm.o `test -f 'tparm.c' || echo '$(srcdir)/'`tparm.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-tparm.Tpo" "$(DEPDIR)/diskless_exec-tparm.Po"; else rm -f "$(DEPDIR)/diskless_exec-tparm.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='tparm.c' object='diskless_exec-tparm.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-tparm.o `test -f 'tparm.c' || echo '$(srcdir)/'`tparm.c
+
+diskless_exec-tparm.obj: tparm.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -MT diskless_exec-tparm.obj -MD -MP -MF "$(DEPDIR)/diskless_exec-tparm.Tpo" -c -o diskless_exec-tparm.obj `if test -f 'tparm.c'; then $(CYGPATH_W) 'tparm.c'; else $(CYGPATH_W) '$(srcdir)/tparm.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/diskless_exec-tparm.Tpo" "$(DEPDIR)/diskless_exec-tparm.Po"; else rm -f "$(DEPDIR)/diskless_exec-tparm.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='tparm.c' object='diskless_exec-tparm.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(diskless_exec_CFLAGS) $(CFLAGS) -c -o diskless_exec-tparm.obj `if test -f 'tparm.c'; then $(CYGPATH_W) 'tparm.c'; else $(CYGPATH_W) '$(srcdir)/tparm.c'; fi`
+
+e2fs_stage1_5_exec-common.o: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT e2fs_stage1_5_exec-common.o -MD -MP -MF "$(DEPDIR)/e2fs_stage1_5_exec-common.Tpo" -c -o e2fs_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/e2fs_stage1_5_exec-common.Tpo" "$(DEPDIR)/e2fs_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/e2fs_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='e2fs_stage1_5_exec-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o e2fs_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c
+
+e2fs_stage1_5_exec-common.obj: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT e2fs_stage1_5_exec-common.obj -MD -MP -MF "$(DEPDIR)/e2fs_stage1_5_exec-common.Tpo" -c -o e2fs_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/e2fs_stage1_5_exec-common.Tpo" "$(DEPDIR)/e2fs_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/e2fs_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='e2fs_stage1_5_exec-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o e2fs_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`
+
+e2fs_stage1_5_exec-char_io.o: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT e2fs_stage1_5_exec-char_io.o -MD -MP -MF "$(DEPDIR)/e2fs_stage1_5_exec-char_io.Tpo" -c -o e2fs_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/e2fs_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/e2fs_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/e2fs_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='e2fs_stage1_5_exec-char_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o e2fs_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c
+
+e2fs_stage1_5_exec-char_io.obj: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT e2fs_stage1_5_exec-char_io.obj -MD -MP -MF "$(DEPDIR)/e2fs_stage1_5_exec-char_io.Tpo" -c -o e2fs_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/e2fs_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/e2fs_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/e2fs_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='e2fs_stage1_5_exec-char_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o e2fs_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`
+
+e2fs_stage1_5_exec-disk_io.o: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT e2fs_stage1_5_exec-disk_io.o -MD -MP -MF "$(DEPDIR)/e2fs_stage1_5_exec-disk_io.Tpo" -c -o e2fs_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/e2fs_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/e2fs_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/e2fs_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='e2fs_stage1_5_exec-disk_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o e2fs_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c
+
+e2fs_stage1_5_exec-disk_io.obj: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT e2fs_stage1_5_exec-disk_io.obj -MD -MP -MF "$(DEPDIR)/e2fs_stage1_5_exec-disk_io.Tpo" -c -o e2fs_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/e2fs_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/e2fs_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/e2fs_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='e2fs_stage1_5_exec-disk_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o e2fs_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`
+
+e2fs_stage1_5_exec-stage1_5.o: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT e2fs_stage1_5_exec-stage1_5.o -MD -MP -MF "$(DEPDIR)/e2fs_stage1_5_exec-stage1_5.Tpo" -c -o e2fs_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/e2fs_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/e2fs_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/e2fs_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='e2fs_stage1_5_exec-stage1_5.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o e2fs_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c
+
+e2fs_stage1_5_exec-stage1_5.obj: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT e2fs_stage1_5_exec-stage1_5.obj -MD -MP -MF "$(DEPDIR)/e2fs_stage1_5_exec-stage1_5.Tpo" -c -o e2fs_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/e2fs_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/e2fs_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/e2fs_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='e2fs_stage1_5_exec-stage1_5.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o e2fs_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`
+
+e2fs_stage1_5_exec-fsys_ext2fs.o: fsys_ext2fs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT e2fs_stage1_5_exec-fsys_ext2fs.o -MD -MP -MF "$(DEPDIR)/e2fs_stage1_5_exec-fsys_ext2fs.Tpo" -c -o e2fs_stage1_5_exec-fsys_ext2fs.o `test -f 'fsys_ext2fs.c' || echo '$(srcdir)/'`fsys_ext2fs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/e2fs_stage1_5_exec-fsys_ext2fs.Tpo" "$(DEPDIR)/e2fs_stage1_5_exec-fsys_ext2fs.Po"; else rm -f "$(DEPDIR)/e2fs_stage1_5_exec-fsys_ext2fs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ext2fs.c' object='e2fs_stage1_5_exec-fsys_ext2fs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o e2fs_stage1_5_exec-fsys_ext2fs.o `test -f 'fsys_ext2fs.c' || echo '$(srcdir)/'`fsys_ext2fs.c
+
+e2fs_stage1_5_exec-fsys_ext2fs.obj: fsys_ext2fs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT e2fs_stage1_5_exec-fsys_ext2fs.obj -MD -MP -MF "$(DEPDIR)/e2fs_stage1_5_exec-fsys_ext2fs.Tpo" -c -o e2fs_stage1_5_exec-fsys_ext2fs.obj `if test -f 'fsys_ext2fs.c'; then $(CYGPATH_W) 'fsys_ext2fs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ext2fs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/e2fs_stage1_5_exec-fsys_ext2fs.Tpo" "$(DEPDIR)/e2fs_stage1_5_exec-fsys_ext2fs.Po"; else rm -f "$(DEPDIR)/e2fs_stage1_5_exec-fsys_ext2fs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ext2fs.c' object='e2fs_stage1_5_exec-fsys_ext2fs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o e2fs_stage1_5_exec-fsys_ext2fs.obj `if test -f 'fsys_ext2fs.c'; then $(CYGPATH_W) 'fsys_ext2fs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ext2fs.c'; fi`
+
+e2fs_stage1_5_exec-bios.o: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT e2fs_stage1_5_exec-bios.o -MD -MP -MF "$(DEPDIR)/e2fs_stage1_5_exec-bios.Tpo" -c -o e2fs_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/e2fs_stage1_5_exec-bios.Tpo" "$(DEPDIR)/e2fs_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/e2fs_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='e2fs_stage1_5_exec-bios.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o e2fs_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c
+
+e2fs_stage1_5_exec-bios.obj: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT e2fs_stage1_5_exec-bios.obj -MD -MP -MF "$(DEPDIR)/e2fs_stage1_5_exec-bios.Tpo" -c -o e2fs_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/e2fs_stage1_5_exec-bios.Tpo" "$(DEPDIR)/e2fs_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/e2fs_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='e2fs_stage1_5_exec-bios.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(e2fs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o e2fs_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`
+
+fat_stage1_5_exec-common.o: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -MT fat_stage1_5_exec-common.o -MD -MP -MF "$(DEPDIR)/fat_stage1_5_exec-common.Tpo" -c -o fat_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/fat_stage1_5_exec-common.Tpo" "$(DEPDIR)/fat_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/fat_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='fat_stage1_5_exec-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o fat_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c
+
+fat_stage1_5_exec-common.obj: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -MT fat_stage1_5_exec-common.obj -MD -MP -MF "$(DEPDIR)/fat_stage1_5_exec-common.Tpo" -c -o fat_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/fat_stage1_5_exec-common.Tpo" "$(DEPDIR)/fat_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/fat_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='fat_stage1_5_exec-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o fat_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`
+
+fat_stage1_5_exec-char_io.o: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -MT fat_stage1_5_exec-char_io.o -MD -MP -MF "$(DEPDIR)/fat_stage1_5_exec-char_io.Tpo" -c -o fat_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/fat_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/fat_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/fat_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='fat_stage1_5_exec-char_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o fat_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c
+
+fat_stage1_5_exec-char_io.obj: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -MT fat_stage1_5_exec-char_io.obj -MD -MP -MF "$(DEPDIR)/fat_stage1_5_exec-char_io.Tpo" -c -o fat_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/fat_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/fat_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/fat_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='fat_stage1_5_exec-char_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o fat_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`
+
+fat_stage1_5_exec-disk_io.o: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -MT fat_stage1_5_exec-disk_io.o -MD -MP -MF "$(DEPDIR)/fat_stage1_5_exec-disk_io.Tpo" -c -o fat_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/fat_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/fat_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/fat_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='fat_stage1_5_exec-disk_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o fat_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c
+
+fat_stage1_5_exec-disk_io.obj: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -MT fat_stage1_5_exec-disk_io.obj -MD -MP -MF "$(DEPDIR)/fat_stage1_5_exec-disk_io.Tpo" -c -o fat_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/fat_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/fat_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/fat_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='fat_stage1_5_exec-disk_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o fat_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`
+
+fat_stage1_5_exec-stage1_5.o: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -MT fat_stage1_5_exec-stage1_5.o -MD -MP -MF "$(DEPDIR)/fat_stage1_5_exec-stage1_5.Tpo" -c -o fat_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/fat_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/fat_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/fat_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='fat_stage1_5_exec-stage1_5.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o fat_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c
+
+fat_stage1_5_exec-stage1_5.obj: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -MT fat_stage1_5_exec-stage1_5.obj -MD -MP -MF "$(DEPDIR)/fat_stage1_5_exec-stage1_5.Tpo" -c -o fat_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/fat_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/fat_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/fat_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='fat_stage1_5_exec-stage1_5.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o fat_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`
+
+fat_stage1_5_exec-fsys_fat.o: fsys_fat.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -MT fat_stage1_5_exec-fsys_fat.o -MD -MP -MF "$(DEPDIR)/fat_stage1_5_exec-fsys_fat.Tpo" -c -o fat_stage1_5_exec-fsys_fat.o `test -f 'fsys_fat.c' || echo '$(srcdir)/'`fsys_fat.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/fat_stage1_5_exec-fsys_fat.Tpo" "$(DEPDIR)/fat_stage1_5_exec-fsys_fat.Po"; else rm -f "$(DEPDIR)/fat_stage1_5_exec-fsys_fat.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_fat.c' object='fat_stage1_5_exec-fsys_fat.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o fat_stage1_5_exec-fsys_fat.o `test -f 'fsys_fat.c' || echo '$(srcdir)/'`fsys_fat.c
+
+fat_stage1_5_exec-fsys_fat.obj: fsys_fat.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -MT fat_stage1_5_exec-fsys_fat.obj -MD -MP -MF "$(DEPDIR)/fat_stage1_5_exec-fsys_fat.Tpo" -c -o fat_stage1_5_exec-fsys_fat.obj `if test -f 'fsys_fat.c'; then $(CYGPATH_W) 'fsys_fat.c'; else $(CYGPATH_W) '$(srcdir)/fsys_fat.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/fat_stage1_5_exec-fsys_fat.Tpo" "$(DEPDIR)/fat_stage1_5_exec-fsys_fat.Po"; else rm -f "$(DEPDIR)/fat_stage1_5_exec-fsys_fat.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_fat.c' object='fat_stage1_5_exec-fsys_fat.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o fat_stage1_5_exec-fsys_fat.obj `if test -f 'fsys_fat.c'; then $(CYGPATH_W) 'fsys_fat.c'; else $(CYGPATH_W) '$(srcdir)/fsys_fat.c'; fi`
+
+fat_stage1_5_exec-bios.o: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -MT fat_stage1_5_exec-bios.o -MD -MP -MF "$(DEPDIR)/fat_stage1_5_exec-bios.Tpo" -c -o fat_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/fat_stage1_5_exec-bios.Tpo" "$(DEPDIR)/fat_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/fat_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='fat_stage1_5_exec-bios.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o fat_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c
+
+fat_stage1_5_exec-bios.obj: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -MT fat_stage1_5_exec-bios.obj -MD -MP -MF "$(DEPDIR)/fat_stage1_5_exec-bios.Tpo" -c -o fat_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/fat_stage1_5_exec-bios.Tpo" "$(DEPDIR)/fat_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/fat_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='fat_stage1_5_exec-bios.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(fat_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o fat_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`
+
+ffs_stage1_5_exec-common.o: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ffs_stage1_5_exec-common.o -MD -MP -MF "$(DEPDIR)/ffs_stage1_5_exec-common.Tpo" -c -o ffs_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ffs_stage1_5_exec-common.Tpo" "$(DEPDIR)/ffs_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/ffs_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='ffs_stage1_5_exec-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ffs_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c
+
+ffs_stage1_5_exec-common.obj: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ffs_stage1_5_exec-common.obj -MD -MP -MF "$(DEPDIR)/ffs_stage1_5_exec-common.Tpo" -c -o ffs_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ffs_stage1_5_exec-common.Tpo" "$(DEPDIR)/ffs_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/ffs_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='ffs_stage1_5_exec-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ffs_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`
+
+ffs_stage1_5_exec-char_io.o: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ffs_stage1_5_exec-char_io.o -MD -MP -MF "$(DEPDIR)/ffs_stage1_5_exec-char_io.Tpo" -c -o ffs_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ffs_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/ffs_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/ffs_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='ffs_stage1_5_exec-char_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ffs_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c
+
+ffs_stage1_5_exec-char_io.obj: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ffs_stage1_5_exec-char_io.obj -MD -MP -MF "$(DEPDIR)/ffs_stage1_5_exec-char_io.Tpo" -c -o ffs_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ffs_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/ffs_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/ffs_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='ffs_stage1_5_exec-char_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ffs_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`
+
+ffs_stage1_5_exec-disk_io.o: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ffs_stage1_5_exec-disk_io.o -MD -MP -MF "$(DEPDIR)/ffs_stage1_5_exec-disk_io.Tpo" -c -o ffs_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ffs_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/ffs_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/ffs_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='ffs_stage1_5_exec-disk_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ffs_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c
+
+ffs_stage1_5_exec-disk_io.obj: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ffs_stage1_5_exec-disk_io.obj -MD -MP -MF "$(DEPDIR)/ffs_stage1_5_exec-disk_io.Tpo" -c -o ffs_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ffs_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/ffs_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/ffs_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='ffs_stage1_5_exec-disk_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ffs_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`
+
+ffs_stage1_5_exec-stage1_5.o: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ffs_stage1_5_exec-stage1_5.o -MD -MP -MF "$(DEPDIR)/ffs_stage1_5_exec-stage1_5.Tpo" -c -o ffs_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ffs_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/ffs_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/ffs_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='ffs_stage1_5_exec-stage1_5.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ffs_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c
+
+ffs_stage1_5_exec-stage1_5.obj: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ffs_stage1_5_exec-stage1_5.obj -MD -MP -MF "$(DEPDIR)/ffs_stage1_5_exec-stage1_5.Tpo" -c -o ffs_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ffs_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/ffs_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/ffs_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='ffs_stage1_5_exec-stage1_5.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ffs_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`
+
+ffs_stage1_5_exec-fsys_ffs.o: fsys_ffs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ffs_stage1_5_exec-fsys_ffs.o -MD -MP -MF "$(DEPDIR)/ffs_stage1_5_exec-fsys_ffs.Tpo" -c -o ffs_stage1_5_exec-fsys_ffs.o `test -f 'fsys_ffs.c' || echo '$(srcdir)/'`fsys_ffs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ffs_stage1_5_exec-fsys_ffs.Tpo" "$(DEPDIR)/ffs_stage1_5_exec-fsys_ffs.Po"; else rm -f "$(DEPDIR)/ffs_stage1_5_exec-fsys_ffs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ffs.c' object='ffs_stage1_5_exec-fsys_ffs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ffs_stage1_5_exec-fsys_ffs.o `test -f 'fsys_ffs.c' || echo '$(srcdir)/'`fsys_ffs.c
+
+ffs_stage1_5_exec-fsys_ffs.obj: fsys_ffs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ffs_stage1_5_exec-fsys_ffs.obj -MD -MP -MF "$(DEPDIR)/ffs_stage1_5_exec-fsys_ffs.Tpo" -c -o ffs_stage1_5_exec-fsys_ffs.obj `if test -f 'fsys_ffs.c'; then $(CYGPATH_W) 'fsys_ffs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ffs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ffs_stage1_5_exec-fsys_ffs.Tpo" "$(DEPDIR)/ffs_stage1_5_exec-fsys_ffs.Po"; else rm -f "$(DEPDIR)/ffs_stage1_5_exec-fsys_ffs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ffs.c' object='ffs_stage1_5_exec-fsys_ffs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ffs_stage1_5_exec-fsys_ffs.obj `if test -f 'fsys_ffs.c'; then $(CYGPATH_W) 'fsys_ffs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ffs.c'; fi`
+
+ffs_stage1_5_exec-bios.o: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ffs_stage1_5_exec-bios.o -MD -MP -MF "$(DEPDIR)/ffs_stage1_5_exec-bios.Tpo" -c -o ffs_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ffs_stage1_5_exec-bios.Tpo" "$(DEPDIR)/ffs_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/ffs_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='ffs_stage1_5_exec-bios.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ffs_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c
+
+ffs_stage1_5_exec-bios.obj: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ffs_stage1_5_exec-bios.obj -MD -MP -MF "$(DEPDIR)/ffs_stage1_5_exec-bios.Tpo" -c -o ffs_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ffs_stage1_5_exec-bios.Tpo" "$(DEPDIR)/ffs_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/ffs_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='ffs_stage1_5_exec-bios.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ffs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ffs_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`
+
+iso9660_stage1_5_exec-common.o: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -MT iso9660_stage1_5_exec-common.o -MD -MP -MF "$(DEPDIR)/iso9660_stage1_5_exec-common.Tpo" -c -o iso9660_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/iso9660_stage1_5_exec-common.Tpo" "$(DEPDIR)/iso9660_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/iso9660_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='iso9660_stage1_5_exec-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o iso9660_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c
+
+iso9660_stage1_5_exec-common.obj: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -MT iso9660_stage1_5_exec-common.obj -MD -MP -MF "$(DEPDIR)/iso9660_stage1_5_exec-common.Tpo" -c -o iso9660_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/iso9660_stage1_5_exec-common.Tpo" "$(DEPDIR)/iso9660_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/iso9660_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='iso9660_stage1_5_exec-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o iso9660_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`
+
+iso9660_stage1_5_exec-char_io.o: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -MT iso9660_stage1_5_exec-char_io.o -MD -MP -MF "$(DEPDIR)/iso9660_stage1_5_exec-char_io.Tpo" -c -o iso9660_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/iso9660_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/iso9660_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/iso9660_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='iso9660_stage1_5_exec-char_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o iso9660_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c
+
+iso9660_stage1_5_exec-char_io.obj: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -MT iso9660_stage1_5_exec-char_io.obj -MD -MP -MF "$(DEPDIR)/iso9660_stage1_5_exec-char_io.Tpo" -c -o iso9660_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/iso9660_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/iso9660_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/iso9660_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='iso9660_stage1_5_exec-char_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o iso9660_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`
+
+iso9660_stage1_5_exec-disk_io.o: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -MT iso9660_stage1_5_exec-disk_io.o -MD -MP -MF "$(DEPDIR)/iso9660_stage1_5_exec-disk_io.Tpo" -c -o iso9660_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/iso9660_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/iso9660_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/iso9660_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='iso9660_stage1_5_exec-disk_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o iso9660_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c
+
+iso9660_stage1_5_exec-disk_io.obj: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -MT iso9660_stage1_5_exec-disk_io.obj -MD -MP -MF "$(DEPDIR)/iso9660_stage1_5_exec-disk_io.Tpo" -c -o iso9660_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/iso9660_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/iso9660_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/iso9660_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='iso9660_stage1_5_exec-disk_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o iso9660_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`
+
+iso9660_stage1_5_exec-stage1_5.o: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -MT iso9660_stage1_5_exec-stage1_5.o -MD -MP -MF "$(DEPDIR)/iso9660_stage1_5_exec-stage1_5.Tpo" -c -o iso9660_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/iso9660_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/iso9660_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/iso9660_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='iso9660_stage1_5_exec-stage1_5.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o iso9660_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c
+
+iso9660_stage1_5_exec-stage1_5.obj: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -MT iso9660_stage1_5_exec-stage1_5.obj -MD -MP -MF "$(DEPDIR)/iso9660_stage1_5_exec-stage1_5.Tpo" -c -o iso9660_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/iso9660_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/iso9660_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/iso9660_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='iso9660_stage1_5_exec-stage1_5.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o iso9660_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`
+
+iso9660_stage1_5_exec-fsys_iso9660.o: fsys_iso9660.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -MT iso9660_stage1_5_exec-fsys_iso9660.o -MD -MP -MF "$(DEPDIR)/iso9660_stage1_5_exec-fsys_iso9660.Tpo" -c -o iso9660_stage1_5_exec-fsys_iso9660.o `test -f 'fsys_iso9660.c' || echo '$(srcdir)/'`fsys_iso9660.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/iso9660_stage1_5_exec-fsys_iso9660.Tpo" "$(DEPDIR)/iso9660_stage1_5_exec-fsys_iso9660.Po"; else rm -f "$(DEPDIR)/iso9660_stage1_5_exec-fsys_iso9660.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_iso9660.c' object='iso9660_stage1_5_exec-fsys_iso9660.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o iso9660_stage1_5_exec-fsys_iso9660.o `test -f 'fsys_iso9660.c' || echo '$(srcdir)/'`fsys_iso9660.c
+
+iso9660_stage1_5_exec-fsys_iso9660.obj: fsys_iso9660.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -MT iso9660_stage1_5_exec-fsys_iso9660.obj -MD -MP -MF "$(DEPDIR)/iso9660_stage1_5_exec-fsys_iso9660.Tpo" -c -o iso9660_stage1_5_exec-fsys_iso9660.obj `if test -f 'fsys_iso9660.c'; then $(CYGPATH_W) 'fsys_iso9660.c'; else $(CYGPATH_W) '$(srcdir)/fsys_iso9660.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/iso9660_stage1_5_exec-fsys_iso9660.Tpo" "$(DEPDIR)/iso9660_stage1_5_exec-fsys_iso9660.Po"; else rm -f "$(DEPDIR)/iso9660_stage1_5_exec-fsys_iso9660.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_iso9660.c' object='iso9660_stage1_5_exec-fsys_iso9660.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o iso9660_stage1_5_exec-fsys_iso9660.obj `if test -f 'fsys_iso9660.c'; then $(CYGPATH_W) 'fsys_iso9660.c'; else $(CYGPATH_W) '$(srcdir)/fsys_iso9660.c'; fi`
+
+iso9660_stage1_5_exec-bios.o: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -MT iso9660_stage1_5_exec-bios.o -MD -MP -MF "$(DEPDIR)/iso9660_stage1_5_exec-bios.Tpo" -c -o iso9660_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/iso9660_stage1_5_exec-bios.Tpo" "$(DEPDIR)/iso9660_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/iso9660_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='iso9660_stage1_5_exec-bios.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o iso9660_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c
+
+iso9660_stage1_5_exec-bios.obj: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -MT iso9660_stage1_5_exec-bios.obj -MD -MP -MF "$(DEPDIR)/iso9660_stage1_5_exec-bios.Tpo" -c -o iso9660_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/iso9660_stage1_5_exec-bios.Tpo" "$(DEPDIR)/iso9660_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/iso9660_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='iso9660_stage1_5_exec-bios.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(iso9660_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o iso9660_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`
+
+jfs_stage1_5_exec-common.o: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT jfs_stage1_5_exec-common.o -MD -MP -MF "$(DEPDIR)/jfs_stage1_5_exec-common.Tpo" -c -o jfs_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/jfs_stage1_5_exec-common.Tpo" "$(DEPDIR)/jfs_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/jfs_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='jfs_stage1_5_exec-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o jfs_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c
+
+jfs_stage1_5_exec-common.obj: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT jfs_stage1_5_exec-common.obj -MD -MP -MF "$(DEPDIR)/jfs_stage1_5_exec-common.Tpo" -c -o jfs_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/jfs_stage1_5_exec-common.Tpo" "$(DEPDIR)/jfs_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/jfs_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='jfs_stage1_5_exec-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o jfs_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`
+
+jfs_stage1_5_exec-char_io.o: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT jfs_stage1_5_exec-char_io.o -MD -MP -MF "$(DEPDIR)/jfs_stage1_5_exec-char_io.Tpo" -c -o jfs_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/jfs_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/jfs_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/jfs_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='jfs_stage1_5_exec-char_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o jfs_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c
+
+jfs_stage1_5_exec-char_io.obj: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT jfs_stage1_5_exec-char_io.obj -MD -MP -MF "$(DEPDIR)/jfs_stage1_5_exec-char_io.Tpo" -c -o jfs_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/jfs_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/jfs_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/jfs_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='jfs_stage1_5_exec-char_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o jfs_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`
+
+jfs_stage1_5_exec-disk_io.o: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT jfs_stage1_5_exec-disk_io.o -MD -MP -MF "$(DEPDIR)/jfs_stage1_5_exec-disk_io.Tpo" -c -o jfs_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/jfs_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/jfs_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/jfs_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='jfs_stage1_5_exec-disk_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o jfs_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c
+
+jfs_stage1_5_exec-disk_io.obj: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT jfs_stage1_5_exec-disk_io.obj -MD -MP -MF "$(DEPDIR)/jfs_stage1_5_exec-disk_io.Tpo" -c -o jfs_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/jfs_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/jfs_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/jfs_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='jfs_stage1_5_exec-disk_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o jfs_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`
+
+jfs_stage1_5_exec-stage1_5.o: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT jfs_stage1_5_exec-stage1_5.o -MD -MP -MF "$(DEPDIR)/jfs_stage1_5_exec-stage1_5.Tpo" -c -o jfs_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/jfs_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/jfs_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/jfs_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='jfs_stage1_5_exec-stage1_5.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o jfs_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c
+
+jfs_stage1_5_exec-stage1_5.obj: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT jfs_stage1_5_exec-stage1_5.obj -MD -MP -MF "$(DEPDIR)/jfs_stage1_5_exec-stage1_5.Tpo" -c -o jfs_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/jfs_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/jfs_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/jfs_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='jfs_stage1_5_exec-stage1_5.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o jfs_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`
+
+jfs_stage1_5_exec-fsys_jfs.o: fsys_jfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT jfs_stage1_5_exec-fsys_jfs.o -MD -MP -MF "$(DEPDIR)/jfs_stage1_5_exec-fsys_jfs.Tpo" -c -o jfs_stage1_5_exec-fsys_jfs.o `test -f 'fsys_jfs.c' || echo '$(srcdir)/'`fsys_jfs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/jfs_stage1_5_exec-fsys_jfs.Tpo" "$(DEPDIR)/jfs_stage1_5_exec-fsys_jfs.Po"; else rm -f "$(DEPDIR)/jfs_stage1_5_exec-fsys_jfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_jfs.c' object='jfs_stage1_5_exec-fsys_jfs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o jfs_stage1_5_exec-fsys_jfs.o `test -f 'fsys_jfs.c' || echo '$(srcdir)/'`fsys_jfs.c
+
+jfs_stage1_5_exec-fsys_jfs.obj: fsys_jfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT jfs_stage1_5_exec-fsys_jfs.obj -MD -MP -MF "$(DEPDIR)/jfs_stage1_5_exec-fsys_jfs.Tpo" -c -o jfs_stage1_5_exec-fsys_jfs.obj `if test -f 'fsys_jfs.c'; then $(CYGPATH_W) 'fsys_jfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_jfs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/jfs_stage1_5_exec-fsys_jfs.Tpo" "$(DEPDIR)/jfs_stage1_5_exec-fsys_jfs.Po"; else rm -f "$(DEPDIR)/jfs_stage1_5_exec-fsys_jfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_jfs.c' object='jfs_stage1_5_exec-fsys_jfs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o jfs_stage1_5_exec-fsys_jfs.obj `if test -f 'fsys_jfs.c'; then $(CYGPATH_W) 'fsys_jfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_jfs.c'; fi`
+
+jfs_stage1_5_exec-bios.o: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT jfs_stage1_5_exec-bios.o -MD -MP -MF "$(DEPDIR)/jfs_stage1_5_exec-bios.Tpo" -c -o jfs_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/jfs_stage1_5_exec-bios.Tpo" "$(DEPDIR)/jfs_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/jfs_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='jfs_stage1_5_exec-bios.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o jfs_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c
+
+jfs_stage1_5_exec-bios.obj: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT jfs_stage1_5_exec-bios.obj -MD -MP -MF "$(DEPDIR)/jfs_stage1_5_exec-bios.Tpo" -c -o jfs_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/jfs_stage1_5_exec-bios.Tpo" "$(DEPDIR)/jfs_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/jfs_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='jfs_stage1_5_exec-bios.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(jfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o jfs_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`
+
+minix_stage1_5_exec-common.o: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -MT minix_stage1_5_exec-common.o -MD -MP -MF "$(DEPDIR)/minix_stage1_5_exec-common.Tpo" -c -o minix_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/minix_stage1_5_exec-common.Tpo" "$(DEPDIR)/minix_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/minix_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='minix_stage1_5_exec-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o minix_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c
+
+minix_stage1_5_exec-common.obj: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -MT minix_stage1_5_exec-common.obj -MD -MP -MF "$(DEPDIR)/minix_stage1_5_exec-common.Tpo" -c -o minix_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/minix_stage1_5_exec-common.Tpo" "$(DEPDIR)/minix_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/minix_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='minix_stage1_5_exec-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o minix_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`
+
+minix_stage1_5_exec-char_io.o: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -MT minix_stage1_5_exec-char_io.o -MD -MP -MF "$(DEPDIR)/minix_stage1_5_exec-char_io.Tpo" -c -o minix_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/minix_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/minix_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/minix_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='minix_stage1_5_exec-char_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o minix_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c
+
+minix_stage1_5_exec-char_io.obj: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -MT minix_stage1_5_exec-char_io.obj -MD -MP -MF "$(DEPDIR)/minix_stage1_5_exec-char_io.Tpo" -c -o minix_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/minix_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/minix_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/minix_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='minix_stage1_5_exec-char_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o minix_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`
+
+minix_stage1_5_exec-disk_io.o: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -MT minix_stage1_5_exec-disk_io.o -MD -MP -MF "$(DEPDIR)/minix_stage1_5_exec-disk_io.Tpo" -c -o minix_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/minix_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/minix_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/minix_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='minix_stage1_5_exec-disk_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o minix_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c
+
+minix_stage1_5_exec-disk_io.obj: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -MT minix_stage1_5_exec-disk_io.obj -MD -MP -MF "$(DEPDIR)/minix_stage1_5_exec-disk_io.Tpo" -c -o minix_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/minix_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/minix_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/minix_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='minix_stage1_5_exec-disk_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o minix_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`
+
+minix_stage1_5_exec-stage1_5.o: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -MT minix_stage1_5_exec-stage1_5.o -MD -MP -MF "$(DEPDIR)/minix_stage1_5_exec-stage1_5.Tpo" -c -o minix_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/minix_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/minix_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/minix_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='minix_stage1_5_exec-stage1_5.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o minix_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c
+
+minix_stage1_5_exec-stage1_5.obj: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -MT minix_stage1_5_exec-stage1_5.obj -MD -MP -MF "$(DEPDIR)/minix_stage1_5_exec-stage1_5.Tpo" -c -o minix_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/minix_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/minix_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/minix_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='minix_stage1_5_exec-stage1_5.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o minix_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`
+
+minix_stage1_5_exec-fsys_minix.o: fsys_minix.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -MT minix_stage1_5_exec-fsys_minix.o -MD -MP -MF "$(DEPDIR)/minix_stage1_5_exec-fsys_minix.Tpo" -c -o minix_stage1_5_exec-fsys_minix.o `test -f 'fsys_minix.c' || echo '$(srcdir)/'`fsys_minix.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/minix_stage1_5_exec-fsys_minix.Tpo" "$(DEPDIR)/minix_stage1_5_exec-fsys_minix.Po"; else rm -f "$(DEPDIR)/minix_stage1_5_exec-fsys_minix.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_minix.c' object='minix_stage1_5_exec-fsys_minix.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o minix_stage1_5_exec-fsys_minix.o `test -f 'fsys_minix.c' || echo '$(srcdir)/'`fsys_minix.c
+
+minix_stage1_5_exec-fsys_minix.obj: fsys_minix.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -MT minix_stage1_5_exec-fsys_minix.obj -MD -MP -MF "$(DEPDIR)/minix_stage1_5_exec-fsys_minix.Tpo" -c -o minix_stage1_5_exec-fsys_minix.obj `if test -f 'fsys_minix.c'; then $(CYGPATH_W) 'fsys_minix.c'; else $(CYGPATH_W) '$(srcdir)/fsys_minix.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/minix_stage1_5_exec-fsys_minix.Tpo" "$(DEPDIR)/minix_stage1_5_exec-fsys_minix.Po"; else rm -f "$(DEPDIR)/minix_stage1_5_exec-fsys_minix.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_minix.c' object='minix_stage1_5_exec-fsys_minix.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o minix_stage1_5_exec-fsys_minix.obj `if test -f 'fsys_minix.c'; then $(CYGPATH_W) 'fsys_minix.c'; else $(CYGPATH_W) '$(srcdir)/fsys_minix.c'; fi`
+
+minix_stage1_5_exec-bios.o: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -MT minix_stage1_5_exec-bios.o -MD -MP -MF "$(DEPDIR)/minix_stage1_5_exec-bios.Tpo" -c -o minix_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/minix_stage1_5_exec-bios.Tpo" "$(DEPDIR)/minix_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/minix_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='minix_stage1_5_exec-bios.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o minix_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c
+
+minix_stage1_5_exec-bios.obj: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -MT minix_stage1_5_exec-bios.obj -MD -MP -MF "$(DEPDIR)/minix_stage1_5_exec-bios.Tpo" -c -o minix_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/minix_stage1_5_exec-bios.Tpo" "$(DEPDIR)/minix_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/minix_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='minix_stage1_5_exec-bios.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(minix_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o minix_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`
+
+pre_stage2_exec-bios.o: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-bios.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-bios.Tpo" -c -o pre_stage2_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-bios.Tpo" "$(DEPDIR)/pre_stage2_exec-bios.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='pre_stage2_exec-bios.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c
+
+pre_stage2_exec-bios.obj: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-bios.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-bios.Tpo" -c -o pre_stage2_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-bios.Tpo" "$(DEPDIR)/pre_stage2_exec-bios.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='pre_stage2_exec-bios.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`
+
+pre_stage2_exec-boot.o: boot.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-boot.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-boot.Tpo" -c -o pre_stage2_exec-boot.o `test -f 'boot.c' || echo '$(srcdir)/'`boot.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-boot.Tpo" "$(DEPDIR)/pre_stage2_exec-boot.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-boot.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='boot.c' object='pre_stage2_exec-boot.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-boot.o `test -f 'boot.c' || echo '$(srcdir)/'`boot.c
+
+pre_stage2_exec-boot.obj: boot.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-boot.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-boot.Tpo" -c -o pre_stage2_exec-boot.obj `if test -f 'boot.c'; then $(CYGPATH_W) 'boot.c'; else $(CYGPATH_W) '$(srcdir)/boot.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-boot.Tpo" "$(DEPDIR)/pre_stage2_exec-boot.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-boot.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='boot.c' object='pre_stage2_exec-boot.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-boot.obj `if test -f 'boot.c'; then $(CYGPATH_W) 'boot.c'; else $(CYGPATH_W) '$(srcdir)/boot.c'; fi`
+
+pre_stage2_exec-builtins.o: builtins.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-builtins.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-builtins.Tpo" -c -o pre_stage2_exec-builtins.o `test -f 'builtins.c' || echo '$(srcdir)/'`builtins.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-builtins.Tpo" "$(DEPDIR)/pre_stage2_exec-builtins.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-builtins.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='builtins.c' object='pre_stage2_exec-builtins.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-builtins.o `test -f 'builtins.c' || echo '$(srcdir)/'`builtins.c
+
+pre_stage2_exec-builtins.obj: builtins.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-builtins.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-builtins.Tpo" -c -o pre_stage2_exec-builtins.obj `if test -f 'builtins.c'; then $(CYGPATH_W) 'builtins.c'; else $(CYGPATH_W) '$(srcdir)/builtins.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-builtins.Tpo" "$(DEPDIR)/pre_stage2_exec-builtins.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-builtins.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='builtins.c' object='pre_stage2_exec-builtins.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-builtins.obj `if test -f 'builtins.c'; then $(CYGPATH_W) 'builtins.c'; else $(CYGPATH_W) '$(srcdir)/builtins.c'; fi`
+
+pre_stage2_exec-char_io.o: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-char_io.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-char_io.Tpo" -c -o pre_stage2_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-char_io.Tpo" "$(DEPDIR)/pre_stage2_exec-char_io.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='pre_stage2_exec-char_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c
+
+pre_stage2_exec-char_io.obj: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-char_io.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-char_io.Tpo" -c -o pre_stage2_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-char_io.Tpo" "$(DEPDIR)/pre_stage2_exec-char_io.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='pre_stage2_exec-char_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`
+
+pre_stage2_exec-cmdline.o: cmdline.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-cmdline.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-cmdline.Tpo" -c -o pre_stage2_exec-cmdline.o `test -f 'cmdline.c' || echo '$(srcdir)/'`cmdline.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-cmdline.Tpo" "$(DEPDIR)/pre_stage2_exec-cmdline.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-cmdline.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='cmdline.c' object='pre_stage2_exec-cmdline.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-cmdline.o `test -f 'cmdline.c' || echo '$(srcdir)/'`cmdline.c
+
+pre_stage2_exec-cmdline.obj: cmdline.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-cmdline.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-cmdline.Tpo" -c -o pre_stage2_exec-cmdline.obj `if test -f 'cmdline.c'; then $(CYGPATH_W) 'cmdline.c'; else $(CYGPATH_W) '$(srcdir)/cmdline.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-cmdline.Tpo" "$(DEPDIR)/pre_stage2_exec-cmdline.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-cmdline.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='cmdline.c' object='pre_stage2_exec-cmdline.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-cmdline.obj `if test -f 'cmdline.c'; then $(CYGPATH_W) 'cmdline.c'; else $(CYGPATH_W) '$(srcdir)/cmdline.c'; fi`
+
+pre_stage2_exec-common.o: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-common.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-common.Tpo" -c -o pre_stage2_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-common.Tpo" "$(DEPDIR)/pre_stage2_exec-common.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='pre_stage2_exec-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c
+
+pre_stage2_exec-common.obj: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-common.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-common.Tpo" -c -o pre_stage2_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-common.Tpo" "$(DEPDIR)/pre_stage2_exec-common.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='pre_stage2_exec-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`
+
+pre_stage2_exec-console.o: console.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-console.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-console.Tpo" -c -o pre_stage2_exec-console.o `test -f 'console.c' || echo '$(srcdir)/'`console.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-console.Tpo" "$(DEPDIR)/pre_stage2_exec-console.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-console.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='console.c' object='pre_stage2_exec-console.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-console.o `test -f 'console.c' || echo '$(srcdir)/'`console.c
+
+pre_stage2_exec-console.obj: console.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-console.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-console.Tpo" -c -o pre_stage2_exec-console.obj `if test -f 'console.c'; then $(CYGPATH_W) 'console.c'; else $(CYGPATH_W) '$(srcdir)/console.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-console.Tpo" "$(DEPDIR)/pre_stage2_exec-console.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-console.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='console.c' object='pre_stage2_exec-console.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-console.obj `if test -f 'console.c'; then $(CYGPATH_W) 'console.c'; else $(CYGPATH_W) '$(srcdir)/console.c'; fi`
+
+pre_stage2_exec-disk_io.o: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-disk_io.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-disk_io.Tpo" -c -o pre_stage2_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-disk_io.Tpo" "$(DEPDIR)/pre_stage2_exec-disk_io.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='pre_stage2_exec-disk_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c
+
+pre_stage2_exec-disk_io.obj: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-disk_io.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-disk_io.Tpo" -c -o pre_stage2_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-disk_io.Tpo" "$(DEPDIR)/pre_stage2_exec-disk_io.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='pre_stage2_exec-disk_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`
+
+pre_stage2_exec-fsys_ext2fs.o: fsys_ext2fs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_ext2fs.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_ext2fs.Tpo" -c -o pre_stage2_exec-fsys_ext2fs.o `test -f 'fsys_ext2fs.c' || echo '$(srcdir)/'`fsys_ext2fs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_ext2fs.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_ext2fs.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_ext2fs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ext2fs.c' object='pre_stage2_exec-fsys_ext2fs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_ext2fs.o `test -f 'fsys_ext2fs.c' || echo '$(srcdir)/'`fsys_ext2fs.c
+
+pre_stage2_exec-fsys_ext2fs.obj: fsys_ext2fs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_ext2fs.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_ext2fs.Tpo" -c -o pre_stage2_exec-fsys_ext2fs.obj `if test -f 'fsys_ext2fs.c'; then $(CYGPATH_W) 'fsys_ext2fs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ext2fs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_ext2fs.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_ext2fs.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_ext2fs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ext2fs.c' object='pre_stage2_exec-fsys_ext2fs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_ext2fs.obj `if test -f 'fsys_ext2fs.c'; then $(CYGPATH_W) 'fsys_ext2fs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ext2fs.c'; fi`
+
+pre_stage2_exec-fsys_fat.o: fsys_fat.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_fat.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_fat.Tpo" -c -o pre_stage2_exec-fsys_fat.o `test -f 'fsys_fat.c' || echo '$(srcdir)/'`fsys_fat.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_fat.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_fat.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_fat.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_fat.c' object='pre_stage2_exec-fsys_fat.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_fat.o `test -f 'fsys_fat.c' || echo '$(srcdir)/'`fsys_fat.c
+
+pre_stage2_exec-fsys_fat.obj: fsys_fat.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_fat.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_fat.Tpo" -c -o pre_stage2_exec-fsys_fat.obj `if test -f 'fsys_fat.c'; then $(CYGPATH_W) 'fsys_fat.c'; else $(CYGPATH_W) '$(srcdir)/fsys_fat.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_fat.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_fat.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_fat.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_fat.c' object='pre_stage2_exec-fsys_fat.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_fat.obj `if test -f 'fsys_fat.c'; then $(CYGPATH_W) 'fsys_fat.c'; else $(CYGPATH_W) '$(srcdir)/fsys_fat.c'; fi`
+
+pre_stage2_exec-fsys_ffs.o: fsys_ffs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_ffs.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_ffs.Tpo" -c -o pre_stage2_exec-fsys_ffs.o `test -f 'fsys_ffs.c' || echo '$(srcdir)/'`fsys_ffs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_ffs.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_ffs.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_ffs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ffs.c' object='pre_stage2_exec-fsys_ffs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_ffs.o `test -f 'fsys_ffs.c' || echo '$(srcdir)/'`fsys_ffs.c
+
+pre_stage2_exec-fsys_ffs.obj: fsys_ffs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_ffs.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_ffs.Tpo" -c -o pre_stage2_exec-fsys_ffs.obj `if test -f 'fsys_ffs.c'; then $(CYGPATH_W) 'fsys_ffs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ffs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_ffs.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_ffs.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_ffs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ffs.c' object='pre_stage2_exec-fsys_ffs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_ffs.obj `if test -f 'fsys_ffs.c'; then $(CYGPATH_W) 'fsys_ffs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ffs.c'; fi`
+
+pre_stage2_exec-fsys_iso9660.o: fsys_iso9660.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_iso9660.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_iso9660.Tpo" -c -o pre_stage2_exec-fsys_iso9660.o `test -f 'fsys_iso9660.c' || echo '$(srcdir)/'`fsys_iso9660.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_iso9660.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_iso9660.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_iso9660.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_iso9660.c' object='pre_stage2_exec-fsys_iso9660.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_iso9660.o `test -f 'fsys_iso9660.c' || echo '$(srcdir)/'`fsys_iso9660.c
+
+pre_stage2_exec-fsys_iso9660.obj: fsys_iso9660.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_iso9660.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_iso9660.Tpo" -c -o pre_stage2_exec-fsys_iso9660.obj `if test -f 'fsys_iso9660.c'; then $(CYGPATH_W) 'fsys_iso9660.c'; else $(CYGPATH_W) '$(srcdir)/fsys_iso9660.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_iso9660.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_iso9660.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_iso9660.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_iso9660.c' object='pre_stage2_exec-fsys_iso9660.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_iso9660.obj `if test -f 'fsys_iso9660.c'; then $(CYGPATH_W) 'fsys_iso9660.c'; else $(CYGPATH_W) '$(srcdir)/fsys_iso9660.c'; fi`
+
+pre_stage2_exec-fsys_jfs.o: fsys_jfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_jfs.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_jfs.Tpo" -c -o pre_stage2_exec-fsys_jfs.o `test -f 'fsys_jfs.c' || echo '$(srcdir)/'`fsys_jfs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_jfs.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_jfs.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_jfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_jfs.c' object='pre_stage2_exec-fsys_jfs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_jfs.o `test -f 'fsys_jfs.c' || echo '$(srcdir)/'`fsys_jfs.c
+
+pre_stage2_exec-fsys_jfs.obj: fsys_jfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_jfs.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_jfs.Tpo" -c -o pre_stage2_exec-fsys_jfs.obj `if test -f 'fsys_jfs.c'; then $(CYGPATH_W) 'fsys_jfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_jfs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_jfs.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_jfs.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_jfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_jfs.c' object='pre_stage2_exec-fsys_jfs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_jfs.obj `if test -f 'fsys_jfs.c'; then $(CYGPATH_W) 'fsys_jfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_jfs.c'; fi`
+
+pre_stage2_exec-fsys_minix.o: fsys_minix.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_minix.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_minix.Tpo" -c -o pre_stage2_exec-fsys_minix.o `test -f 'fsys_minix.c' || echo '$(srcdir)/'`fsys_minix.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_minix.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_minix.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_minix.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_minix.c' object='pre_stage2_exec-fsys_minix.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_minix.o `test -f 'fsys_minix.c' || echo '$(srcdir)/'`fsys_minix.c
+
+pre_stage2_exec-fsys_minix.obj: fsys_minix.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_minix.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_minix.Tpo" -c -o pre_stage2_exec-fsys_minix.obj `if test -f 'fsys_minix.c'; then $(CYGPATH_W) 'fsys_minix.c'; else $(CYGPATH_W) '$(srcdir)/fsys_minix.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_minix.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_minix.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_minix.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_minix.c' object='pre_stage2_exec-fsys_minix.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_minix.obj `if test -f 'fsys_minix.c'; then $(CYGPATH_W) 'fsys_minix.c'; else $(CYGPATH_W) '$(srcdir)/fsys_minix.c'; fi`
+
+pre_stage2_exec-fsys_reiserfs.o: fsys_reiserfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_reiserfs.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_reiserfs.Tpo" -c -o pre_stage2_exec-fsys_reiserfs.o `test -f 'fsys_reiserfs.c' || echo '$(srcdir)/'`fsys_reiserfs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_reiserfs.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_reiserfs.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_reiserfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_reiserfs.c' object='pre_stage2_exec-fsys_reiserfs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_reiserfs.o `test -f 'fsys_reiserfs.c' || echo '$(srcdir)/'`fsys_reiserfs.c
+
+pre_stage2_exec-fsys_reiserfs.obj: fsys_reiserfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_reiserfs.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_reiserfs.Tpo" -c -o pre_stage2_exec-fsys_reiserfs.obj `if test -f 'fsys_reiserfs.c'; then $(CYGPATH_W) 'fsys_reiserfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_reiserfs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_reiserfs.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_reiserfs.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_reiserfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_reiserfs.c' object='pre_stage2_exec-fsys_reiserfs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_reiserfs.obj `if test -f 'fsys_reiserfs.c'; then $(CYGPATH_W) 'fsys_reiserfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_reiserfs.c'; fi`
+
+pre_stage2_exec-fsys_ufs2.o: fsys_ufs2.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_ufs2.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_ufs2.Tpo" -c -o pre_stage2_exec-fsys_ufs2.o `test -f 'fsys_ufs2.c' || echo '$(srcdir)/'`fsys_ufs2.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_ufs2.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_ufs2.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_ufs2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ufs2.c' object='pre_stage2_exec-fsys_ufs2.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_ufs2.o `test -f 'fsys_ufs2.c' || echo '$(srcdir)/'`fsys_ufs2.c
+
+pre_stage2_exec-fsys_ufs2.obj: fsys_ufs2.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_ufs2.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_ufs2.Tpo" -c -o pre_stage2_exec-fsys_ufs2.obj `if test -f 'fsys_ufs2.c'; then $(CYGPATH_W) 'fsys_ufs2.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ufs2.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_ufs2.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_ufs2.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_ufs2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ufs2.c' object='pre_stage2_exec-fsys_ufs2.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_ufs2.obj `if test -f 'fsys_ufs2.c'; then $(CYGPATH_W) 'fsys_ufs2.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ufs2.c'; fi`
+
+pre_stage2_exec-fsys_vstafs.o: fsys_vstafs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_vstafs.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_vstafs.Tpo" -c -o pre_stage2_exec-fsys_vstafs.o `test -f 'fsys_vstafs.c' || echo '$(srcdir)/'`fsys_vstafs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_vstafs.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_vstafs.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_vstafs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_vstafs.c' object='pre_stage2_exec-fsys_vstafs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_vstafs.o `test -f 'fsys_vstafs.c' || echo '$(srcdir)/'`fsys_vstafs.c
+
+pre_stage2_exec-fsys_vstafs.obj: fsys_vstafs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_vstafs.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_vstafs.Tpo" -c -o pre_stage2_exec-fsys_vstafs.obj `if test -f 'fsys_vstafs.c'; then $(CYGPATH_W) 'fsys_vstafs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_vstafs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_vstafs.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_vstafs.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_vstafs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_vstafs.c' object='pre_stage2_exec-fsys_vstafs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_vstafs.obj `if test -f 'fsys_vstafs.c'; then $(CYGPATH_W) 'fsys_vstafs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_vstafs.c'; fi`
+
+pre_stage2_exec-fsys_xfs.o: fsys_xfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_xfs.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_xfs.Tpo" -c -o pre_stage2_exec-fsys_xfs.o `test -f 'fsys_xfs.c' || echo '$(srcdir)/'`fsys_xfs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_xfs.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_xfs.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_xfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_xfs.c' object='pre_stage2_exec-fsys_xfs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_xfs.o `test -f 'fsys_xfs.c' || echo '$(srcdir)/'`fsys_xfs.c
+
+pre_stage2_exec-fsys_xfs.obj: fsys_xfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-fsys_xfs.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-fsys_xfs.Tpo" -c -o pre_stage2_exec-fsys_xfs.obj `if test -f 'fsys_xfs.c'; then $(CYGPATH_W) 'fsys_xfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_xfs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-fsys_xfs.Tpo" "$(DEPDIR)/pre_stage2_exec-fsys_xfs.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-fsys_xfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_xfs.c' object='pre_stage2_exec-fsys_xfs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-fsys_xfs.obj `if test -f 'fsys_xfs.c'; then $(CYGPATH_W) 'fsys_xfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_xfs.c'; fi`
+
+pre_stage2_exec-gunzip.o: gunzip.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-gunzip.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-gunzip.Tpo" -c -o pre_stage2_exec-gunzip.o `test -f 'gunzip.c' || echo '$(srcdir)/'`gunzip.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-gunzip.Tpo" "$(DEPDIR)/pre_stage2_exec-gunzip.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-gunzip.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gunzip.c' object='pre_stage2_exec-gunzip.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-gunzip.o `test -f 'gunzip.c' || echo '$(srcdir)/'`gunzip.c
+
+pre_stage2_exec-gunzip.obj: gunzip.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-gunzip.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-gunzip.Tpo" -c -o pre_stage2_exec-gunzip.obj `if test -f 'gunzip.c'; then $(CYGPATH_W) 'gunzip.c'; else $(CYGPATH_W) '$(srcdir)/gunzip.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-gunzip.Tpo" "$(DEPDIR)/pre_stage2_exec-gunzip.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-gunzip.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='gunzip.c' object='pre_stage2_exec-gunzip.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-gunzip.obj `if test -f 'gunzip.c'; then $(CYGPATH_W) 'gunzip.c'; else $(CYGPATH_W) '$(srcdir)/gunzip.c'; fi`
+
+pre_stage2_exec-hercules.o: hercules.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-hercules.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-hercules.Tpo" -c -o pre_stage2_exec-hercules.o `test -f 'hercules.c' || echo '$(srcdir)/'`hercules.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-hercules.Tpo" "$(DEPDIR)/pre_stage2_exec-hercules.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-hercules.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='hercules.c' object='pre_stage2_exec-hercules.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-hercules.o `test -f 'hercules.c' || echo '$(srcdir)/'`hercules.c
+
+pre_stage2_exec-hercules.obj: hercules.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-hercules.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-hercules.Tpo" -c -o pre_stage2_exec-hercules.obj `if test -f 'hercules.c'; then $(CYGPATH_W) 'hercules.c'; else $(CYGPATH_W) '$(srcdir)/hercules.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-hercules.Tpo" "$(DEPDIR)/pre_stage2_exec-hercules.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-hercules.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='hercules.c' object='pre_stage2_exec-hercules.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-hercules.obj `if test -f 'hercules.c'; then $(CYGPATH_W) 'hercules.c'; else $(CYGPATH_W) '$(srcdir)/hercules.c'; fi`
+
+pre_stage2_exec-md5.o: md5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-md5.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-md5.Tpo" -c -o pre_stage2_exec-md5.o `test -f 'md5.c' || echo '$(srcdir)/'`md5.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-md5.Tpo" "$(DEPDIR)/pre_stage2_exec-md5.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-md5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='md5.c' object='pre_stage2_exec-md5.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-md5.o `test -f 'md5.c' || echo '$(srcdir)/'`md5.c
+
+pre_stage2_exec-md5.obj: md5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-md5.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-md5.Tpo" -c -o pre_stage2_exec-md5.obj `if test -f 'md5.c'; then $(CYGPATH_W) 'md5.c'; else $(CYGPATH_W) '$(srcdir)/md5.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-md5.Tpo" "$(DEPDIR)/pre_stage2_exec-md5.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-md5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='md5.c' object='pre_stage2_exec-md5.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-md5.obj `if test -f 'md5.c'; then $(CYGPATH_W) 'md5.c'; else $(CYGPATH_W) '$(srcdir)/md5.c'; fi`
+
+pre_stage2_exec-serial.o: serial.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-serial.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-serial.Tpo" -c -o pre_stage2_exec-serial.o `test -f 'serial.c' || echo '$(srcdir)/'`serial.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-serial.Tpo" "$(DEPDIR)/pre_stage2_exec-serial.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-serial.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='serial.c' object='pre_stage2_exec-serial.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-serial.o `test -f 'serial.c' || echo '$(srcdir)/'`serial.c
+
+pre_stage2_exec-serial.obj: serial.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-serial.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-serial.Tpo" -c -o pre_stage2_exec-serial.obj `if test -f 'serial.c'; then $(CYGPATH_W) 'serial.c'; else $(CYGPATH_W) '$(srcdir)/serial.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-serial.Tpo" "$(DEPDIR)/pre_stage2_exec-serial.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-serial.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='serial.c' object='pre_stage2_exec-serial.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-serial.obj `if test -f 'serial.c'; then $(CYGPATH_W) 'serial.c'; else $(CYGPATH_W) '$(srcdir)/serial.c'; fi`
+
+pre_stage2_exec-smp-imps.o: smp-imps.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-smp-imps.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-smp-imps.Tpo" -c -o pre_stage2_exec-smp-imps.o `test -f 'smp-imps.c' || echo '$(srcdir)/'`smp-imps.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-smp-imps.Tpo" "$(DEPDIR)/pre_stage2_exec-smp-imps.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-smp-imps.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='smp-imps.c' object='pre_stage2_exec-smp-imps.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-smp-imps.o `test -f 'smp-imps.c' || echo '$(srcdir)/'`smp-imps.c
+
+pre_stage2_exec-smp-imps.obj: smp-imps.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-smp-imps.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-smp-imps.Tpo" -c -o pre_stage2_exec-smp-imps.obj `if test -f 'smp-imps.c'; then $(CYGPATH_W) 'smp-imps.c'; else $(CYGPATH_W) '$(srcdir)/smp-imps.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-smp-imps.Tpo" "$(DEPDIR)/pre_stage2_exec-smp-imps.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-smp-imps.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='smp-imps.c' object='pre_stage2_exec-smp-imps.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-smp-imps.obj `if test -f 'smp-imps.c'; then $(CYGPATH_W) 'smp-imps.c'; else $(CYGPATH_W) '$(srcdir)/smp-imps.c'; fi`
+
+pre_stage2_exec-stage2.o: stage2.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-stage2.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-stage2.Tpo" -c -o pre_stage2_exec-stage2.o `test -f 'stage2.c' || echo '$(srcdir)/'`stage2.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-stage2.Tpo" "$(DEPDIR)/pre_stage2_exec-stage2.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-stage2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage2.c' object='pre_stage2_exec-stage2.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-stage2.o `test -f 'stage2.c' || echo '$(srcdir)/'`stage2.c
+
+pre_stage2_exec-stage2.obj: stage2.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-stage2.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-stage2.Tpo" -c -o pre_stage2_exec-stage2.obj `if test -f 'stage2.c'; then $(CYGPATH_W) 'stage2.c'; else $(CYGPATH_W) '$(srcdir)/stage2.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-stage2.Tpo" "$(DEPDIR)/pre_stage2_exec-stage2.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-stage2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage2.c' object='pre_stage2_exec-stage2.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-stage2.obj `if test -f 'stage2.c'; then $(CYGPATH_W) 'stage2.c'; else $(CYGPATH_W) '$(srcdir)/stage2.c'; fi`
+
+pre_stage2_exec-terminfo.o: terminfo.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-terminfo.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-terminfo.Tpo" -c -o pre_stage2_exec-terminfo.o `test -f 'terminfo.c' || echo '$(srcdir)/'`terminfo.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-terminfo.Tpo" "$(DEPDIR)/pre_stage2_exec-terminfo.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-terminfo.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='terminfo.c' object='pre_stage2_exec-terminfo.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-terminfo.o `test -f 'terminfo.c' || echo '$(srcdir)/'`terminfo.c
+
+pre_stage2_exec-terminfo.obj: terminfo.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-terminfo.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-terminfo.Tpo" -c -o pre_stage2_exec-terminfo.obj `if test -f 'terminfo.c'; then $(CYGPATH_W) 'terminfo.c'; else $(CYGPATH_W) '$(srcdir)/terminfo.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-terminfo.Tpo" "$(DEPDIR)/pre_stage2_exec-terminfo.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-terminfo.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='terminfo.c' object='pre_stage2_exec-terminfo.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-terminfo.obj `if test -f 'terminfo.c'; then $(CYGPATH_W) 'terminfo.c'; else $(CYGPATH_W) '$(srcdir)/terminfo.c'; fi`
+
+pre_stage2_exec-tparm.o: tparm.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-tparm.o -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-tparm.Tpo" -c -o pre_stage2_exec-tparm.o `test -f 'tparm.c' || echo '$(srcdir)/'`tparm.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-tparm.Tpo" "$(DEPDIR)/pre_stage2_exec-tparm.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-tparm.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='tparm.c' object='pre_stage2_exec-tparm.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-tparm.o `test -f 'tparm.c' || echo '$(srcdir)/'`tparm.c
+
+pre_stage2_exec-tparm.obj: tparm.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -MT pre_stage2_exec-tparm.obj -MD -MP -MF "$(DEPDIR)/pre_stage2_exec-tparm.Tpo" -c -o pre_stage2_exec-tparm.obj `if test -f 'tparm.c'; then $(CYGPATH_W) 'tparm.c'; else $(CYGPATH_W) '$(srcdir)/tparm.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/pre_stage2_exec-tparm.Tpo" "$(DEPDIR)/pre_stage2_exec-tparm.Po"; else rm -f "$(DEPDIR)/pre_stage2_exec-tparm.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='tparm.c' object='pre_stage2_exec-tparm.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pre_stage2_exec_CFLAGS) $(CFLAGS) -c -o pre_stage2_exec-tparm.obj `if test -f 'tparm.c'; then $(CYGPATH_W) 'tparm.c'; else $(CYGPATH_W) '$(srcdir)/tparm.c'; fi`
+
+reiserfs_stage1_5_exec-common.o: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT reiserfs_stage1_5_exec-common.o -MD -MP -MF "$(DEPDIR)/reiserfs_stage1_5_exec-common.Tpo" -c -o reiserfs_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/reiserfs_stage1_5_exec-common.Tpo" "$(DEPDIR)/reiserfs_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/reiserfs_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='reiserfs_stage1_5_exec-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o reiserfs_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c
+
+reiserfs_stage1_5_exec-common.obj: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT reiserfs_stage1_5_exec-common.obj -MD -MP -MF "$(DEPDIR)/reiserfs_stage1_5_exec-common.Tpo" -c -o reiserfs_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/reiserfs_stage1_5_exec-common.Tpo" "$(DEPDIR)/reiserfs_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/reiserfs_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='reiserfs_stage1_5_exec-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o reiserfs_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`
+
+reiserfs_stage1_5_exec-char_io.o: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT reiserfs_stage1_5_exec-char_io.o -MD -MP -MF "$(DEPDIR)/reiserfs_stage1_5_exec-char_io.Tpo" -c -o reiserfs_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/reiserfs_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/reiserfs_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/reiserfs_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='reiserfs_stage1_5_exec-char_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o reiserfs_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c
+
+reiserfs_stage1_5_exec-char_io.obj: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT reiserfs_stage1_5_exec-char_io.obj -MD -MP -MF "$(DEPDIR)/reiserfs_stage1_5_exec-char_io.Tpo" -c -o reiserfs_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/reiserfs_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/reiserfs_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/reiserfs_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='reiserfs_stage1_5_exec-char_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o reiserfs_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`
+
+reiserfs_stage1_5_exec-disk_io.o: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT reiserfs_stage1_5_exec-disk_io.o -MD -MP -MF "$(DEPDIR)/reiserfs_stage1_5_exec-disk_io.Tpo" -c -o reiserfs_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/reiserfs_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/reiserfs_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/reiserfs_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='reiserfs_stage1_5_exec-disk_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o reiserfs_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c
+
+reiserfs_stage1_5_exec-disk_io.obj: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT reiserfs_stage1_5_exec-disk_io.obj -MD -MP -MF "$(DEPDIR)/reiserfs_stage1_5_exec-disk_io.Tpo" -c -o reiserfs_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/reiserfs_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/reiserfs_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/reiserfs_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='reiserfs_stage1_5_exec-disk_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o reiserfs_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`
+
+reiserfs_stage1_5_exec-stage1_5.o: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT reiserfs_stage1_5_exec-stage1_5.o -MD -MP -MF "$(DEPDIR)/reiserfs_stage1_5_exec-stage1_5.Tpo" -c -o reiserfs_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/reiserfs_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/reiserfs_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/reiserfs_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='reiserfs_stage1_5_exec-stage1_5.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o reiserfs_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c
+
+reiserfs_stage1_5_exec-stage1_5.obj: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT reiserfs_stage1_5_exec-stage1_5.obj -MD -MP -MF "$(DEPDIR)/reiserfs_stage1_5_exec-stage1_5.Tpo" -c -o reiserfs_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/reiserfs_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/reiserfs_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/reiserfs_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='reiserfs_stage1_5_exec-stage1_5.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o reiserfs_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`
+
+reiserfs_stage1_5_exec-fsys_reiserfs.o: fsys_reiserfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT reiserfs_stage1_5_exec-fsys_reiserfs.o -MD -MP -MF "$(DEPDIR)/reiserfs_stage1_5_exec-fsys_reiserfs.Tpo" -c -o reiserfs_stage1_5_exec-fsys_reiserfs.o `test -f 'fsys_reiserfs.c' || echo '$(srcdir)/'`fsys_reiserfs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/reiserfs_stage1_5_exec-fsys_reiserfs.Tpo" "$(DEPDIR)/reiserfs_stage1_5_exec-fsys_reiserfs.Po"; else rm -f "$(DEPDIR)/reiserfs_stage1_5_exec-fsys_reiserfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_reiserfs.c' object='reiserfs_stage1_5_exec-fsys_reiserfs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o reiserfs_stage1_5_exec-fsys_reiserfs.o `test -f 'fsys_reiserfs.c' || echo '$(srcdir)/'`fsys_reiserfs.c
+
+reiserfs_stage1_5_exec-fsys_reiserfs.obj: fsys_reiserfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT reiserfs_stage1_5_exec-fsys_reiserfs.obj -MD -MP -MF "$(DEPDIR)/reiserfs_stage1_5_exec-fsys_reiserfs.Tpo" -c -o reiserfs_stage1_5_exec-fsys_reiserfs.obj `if test -f 'fsys_reiserfs.c'; then $(CYGPATH_W) 'fsys_reiserfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_reiserfs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/reiserfs_stage1_5_exec-fsys_reiserfs.Tpo" "$(DEPDIR)/reiserfs_stage1_5_exec-fsys_reiserfs.Po"; else rm -f "$(DEPDIR)/reiserfs_stage1_5_exec-fsys_reiserfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_reiserfs.c' object='reiserfs_stage1_5_exec-fsys_reiserfs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o reiserfs_stage1_5_exec-fsys_reiserfs.obj `if test -f 'fsys_reiserfs.c'; then $(CYGPATH_W) 'fsys_reiserfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_reiserfs.c'; fi`
+
+reiserfs_stage1_5_exec-bios.o: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT reiserfs_stage1_5_exec-bios.o -MD -MP -MF "$(DEPDIR)/reiserfs_stage1_5_exec-bios.Tpo" -c -o reiserfs_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/reiserfs_stage1_5_exec-bios.Tpo" "$(DEPDIR)/reiserfs_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/reiserfs_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='reiserfs_stage1_5_exec-bios.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o reiserfs_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c
+
+reiserfs_stage1_5_exec-bios.obj: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT reiserfs_stage1_5_exec-bios.obj -MD -MP -MF "$(DEPDIR)/reiserfs_stage1_5_exec-bios.Tpo" -c -o reiserfs_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/reiserfs_stage1_5_exec-bios.Tpo" "$(DEPDIR)/reiserfs_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/reiserfs_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='reiserfs_stage1_5_exec-bios.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(reiserfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o reiserfs_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`
+
+ufs2_stage1_5_exec-common.o: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ufs2_stage1_5_exec-common.o -MD -MP -MF "$(DEPDIR)/ufs2_stage1_5_exec-common.Tpo" -c -o ufs2_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ufs2_stage1_5_exec-common.Tpo" "$(DEPDIR)/ufs2_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/ufs2_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='ufs2_stage1_5_exec-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ufs2_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c
+
+ufs2_stage1_5_exec-common.obj: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ufs2_stage1_5_exec-common.obj -MD -MP -MF "$(DEPDIR)/ufs2_stage1_5_exec-common.Tpo" -c -o ufs2_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ufs2_stage1_5_exec-common.Tpo" "$(DEPDIR)/ufs2_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/ufs2_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='ufs2_stage1_5_exec-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ufs2_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`
+
+ufs2_stage1_5_exec-char_io.o: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ufs2_stage1_5_exec-char_io.o -MD -MP -MF "$(DEPDIR)/ufs2_stage1_5_exec-char_io.Tpo" -c -o ufs2_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ufs2_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/ufs2_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/ufs2_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='ufs2_stage1_5_exec-char_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ufs2_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c
+
+ufs2_stage1_5_exec-char_io.obj: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ufs2_stage1_5_exec-char_io.obj -MD -MP -MF "$(DEPDIR)/ufs2_stage1_5_exec-char_io.Tpo" -c -o ufs2_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ufs2_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/ufs2_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/ufs2_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='ufs2_stage1_5_exec-char_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ufs2_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`
+
+ufs2_stage1_5_exec-disk_io.o: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ufs2_stage1_5_exec-disk_io.o -MD -MP -MF "$(DEPDIR)/ufs2_stage1_5_exec-disk_io.Tpo" -c -o ufs2_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ufs2_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/ufs2_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/ufs2_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='ufs2_stage1_5_exec-disk_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ufs2_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c
+
+ufs2_stage1_5_exec-disk_io.obj: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ufs2_stage1_5_exec-disk_io.obj -MD -MP -MF "$(DEPDIR)/ufs2_stage1_5_exec-disk_io.Tpo" -c -o ufs2_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ufs2_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/ufs2_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/ufs2_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='ufs2_stage1_5_exec-disk_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ufs2_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`
+
+ufs2_stage1_5_exec-stage1_5.o: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ufs2_stage1_5_exec-stage1_5.o -MD -MP -MF "$(DEPDIR)/ufs2_stage1_5_exec-stage1_5.Tpo" -c -o ufs2_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ufs2_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/ufs2_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/ufs2_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='ufs2_stage1_5_exec-stage1_5.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ufs2_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c
+
+ufs2_stage1_5_exec-stage1_5.obj: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ufs2_stage1_5_exec-stage1_5.obj -MD -MP -MF "$(DEPDIR)/ufs2_stage1_5_exec-stage1_5.Tpo" -c -o ufs2_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ufs2_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/ufs2_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/ufs2_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='ufs2_stage1_5_exec-stage1_5.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ufs2_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`
+
+ufs2_stage1_5_exec-fsys_ufs2.o: fsys_ufs2.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ufs2_stage1_5_exec-fsys_ufs2.o -MD -MP -MF "$(DEPDIR)/ufs2_stage1_5_exec-fsys_ufs2.Tpo" -c -o ufs2_stage1_5_exec-fsys_ufs2.o `test -f 'fsys_ufs2.c' || echo '$(srcdir)/'`fsys_ufs2.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ufs2_stage1_5_exec-fsys_ufs2.Tpo" "$(DEPDIR)/ufs2_stage1_5_exec-fsys_ufs2.Po"; else rm -f "$(DEPDIR)/ufs2_stage1_5_exec-fsys_ufs2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ufs2.c' object='ufs2_stage1_5_exec-fsys_ufs2.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ufs2_stage1_5_exec-fsys_ufs2.o `test -f 'fsys_ufs2.c' || echo '$(srcdir)/'`fsys_ufs2.c
+
+ufs2_stage1_5_exec-fsys_ufs2.obj: fsys_ufs2.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ufs2_stage1_5_exec-fsys_ufs2.obj -MD -MP -MF "$(DEPDIR)/ufs2_stage1_5_exec-fsys_ufs2.Tpo" -c -o ufs2_stage1_5_exec-fsys_ufs2.obj `if test -f 'fsys_ufs2.c'; then $(CYGPATH_W) 'fsys_ufs2.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ufs2.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ufs2_stage1_5_exec-fsys_ufs2.Tpo" "$(DEPDIR)/ufs2_stage1_5_exec-fsys_ufs2.Po"; else rm -f "$(DEPDIR)/ufs2_stage1_5_exec-fsys_ufs2.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_ufs2.c' object='ufs2_stage1_5_exec-fsys_ufs2.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ufs2_stage1_5_exec-fsys_ufs2.obj `if test -f 'fsys_ufs2.c'; then $(CYGPATH_W) 'fsys_ufs2.c'; else $(CYGPATH_W) '$(srcdir)/fsys_ufs2.c'; fi`
+
+ufs2_stage1_5_exec-bios.o: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ufs2_stage1_5_exec-bios.o -MD -MP -MF "$(DEPDIR)/ufs2_stage1_5_exec-bios.Tpo" -c -o ufs2_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ufs2_stage1_5_exec-bios.Tpo" "$(DEPDIR)/ufs2_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/ufs2_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='ufs2_stage1_5_exec-bios.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ufs2_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c
+
+ufs2_stage1_5_exec-bios.obj: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -MT ufs2_stage1_5_exec-bios.obj -MD -MP -MF "$(DEPDIR)/ufs2_stage1_5_exec-bios.Tpo" -c -o ufs2_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/ufs2_stage1_5_exec-bios.Tpo" "$(DEPDIR)/ufs2_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/ufs2_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='ufs2_stage1_5_exec-bios.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ufs2_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o ufs2_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`
+
+vstafs_stage1_5_exec-common.o: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT vstafs_stage1_5_exec-common.o -MD -MP -MF "$(DEPDIR)/vstafs_stage1_5_exec-common.Tpo" -c -o vstafs_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/vstafs_stage1_5_exec-common.Tpo" "$(DEPDIR)/vstafs_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/vstafs_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='vstafs_stage1_5_exec-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o vstafs_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c
+
+vstafs_stage1_5_exec-common.obj: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT vstafs_stage1_5_exec-common.obj -MD -MP -MF "$(DEPDIR)/vstafs_stage1_5_exec-common.Tpo" -c -o vstafs_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/vstafs_stage1_5_exec-common.Tpo" "$(DEPDIR)/vstafs_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/vstafs_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='vstafs_stage1_5_exec-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o vstafs_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`
+
+vstafs_stage1_5_exec-char_io.o: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT vstafs_stage1_5_exec-char_io.o -MD -MP -MF "$(DEPDIR)/vstafs_stage1_5_exec-char_io.Tpo" -c -o vstafs_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/vstafs_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/vstafs_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/vstafs_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='vstafs_stage1_5_exec-char_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o vstafs_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c
+
+vstafs_stage1_5_exec-char_io.obj: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT vstafs_stage1_5_exec-char_io.obj -MD -MP -MF "$(DEPDIR)/vstafs_stage1_5_exec-char_io.Tpo" -c -o vstafs_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/vstafs_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/vstafs_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/vstafs_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='vstafs_stage1_5_exec-char_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o vstafs_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`
+
+vstafs_stage1_5_exec-disk_io.o: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT vstafs_stage1_5_exec-disk_io.o -MD -MP -MF "$(DEPDIR)/vstafs_stage1_5_exec-disk_io.Tpo" -c -o vstafs_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/vstafs_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/vstafs_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/vstafs_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='vstafs_stage1_5_exec-disk_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o vstafs_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c
+
+vstafs_stage1_5_exec-disk_io.obj: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT vstafs_stage1_5_exec-disk_io.obj -MD -MP -MF "$(DEPDIR)/vstafs_stage1_5_exec-disk_io.Tpo" -c -o vstafs_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/vstafs_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/vstafs_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/vstafs_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='vstafs_stage1_5_exec-disk_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o vstafs_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`
+
+vstafs_stage1_5_exec-stage1_5.o: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT vstafs_stage1_5_exec-stage1_5.o -MD -MP -MF "$(DEPDIR)/vstafs_stage1_5_exec-stage1_5.Tpo" -c -o vstafs_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/vstafs_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/vstafs_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/vstafs_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='vstafs_stage1_5_exec-stage1_5.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o vstafs_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c
+
+vstafs_stage1_5_exec-stage1_5.obj: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT vstafs_stage1_5_exec-stage1_5.obj -MD -MP -MF "$(DEPDIR)/vstafs_stage1_5_exec-stage1_5.Tpo" -c -o vstafs_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/vstafs_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/vstafs_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/vstafs_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='vstafs_stage1_5_exec-stage1_5.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o vstafs_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`
+
+vstafs_stage1_5_exec-fsys_vstafs.o: fsys_vstafs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT vstafs_stage1_5_exec-fsys_vstafs.o -MD -MP -MF "$(DEPDIR)/vstafs_stage1_5_exec-fsys_vstafs.Tpo" -c -o vstafs_stage1_5_exec-fsys_vstafs.o `test -f 'fsys_vstafs.c' || echo '$(srcdir)/'`fsys_vstafs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/vstafs_stage1_5_exec-fsys_vstafs.Tpo" "$(DEPDIR)/vstafs_stage1_5_exec-fsys_vstafs.Po"; else rm -f "$(DEPDIR)/vstafs_stage1_5_exec-fsys_vstafs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_vstafs.c' object='vstafs_stage1_5_exec-fsys_vstafs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o vstafs_stage1_5_exec-fsys_vstafs.o `test -f 'fsys_vstafs.c' || echo '$(srcdir)/'`fsys_vstafs.c
+
+vstafs_stage1_5_exec-fsys_vstafs.obj: fsys_vstafs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT vstafs_stage1_5_exec-fsys_vstafs.obj -MD -MP -MF "$(DEPDIR)/vstafs_stage1_5_exec-fsys_vstafs.Tpo" -c -o vstafs_stage1_5_exec-fsys_vstafs.obj `if test -f 'fsys_vstafs.c'; then $(CYGPATH_W) 'fsys_vstafs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_vstafs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/vstafs_stage1_5_exec-fsys_vstafs.Tpo" "$(DEPDIR)/vstafs_stage1_5_exec-fsys_vstafs.Po"; else rm -f "$(DEPDIR)/vstafs_stage1_5_exec-fsys_vstafs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_vstafs.c' object='vstafs_stage1_5_exec-fsys_vstafs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o vstafs_stage1_5_exec-fsys_vstafs.obj `if test -f 'fsys_vstafs.c'; then $(CYGPATH_W) 'fsys_vstafs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_vstafs.c'; fi`
+
+vstafs_stage1_5_exec-bios.o: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT vstafs_stage1_5_exec-bios.o -MD -MP -MF "$(DEPDIR)/vstafs_stage1_5_exec-bios.Tpo" -c -o vstafs_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/vstafs_stage1_5_exec-bios.Tpo" "$(DEPDIR)/vstafs_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/vstafs_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='vstafs_stage1_5_exec-bios.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o vstafs_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c
+
+vstafs_stage1_5_exec-bios.obj: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT vstafs_stage1_5_exec-bios.obj -MD -MP -MF "$(DEPDIR)/vstafs_stage1_5_exec-bios.Tpo" -c -o vstafs_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/vstafs_stage1_5_exec-bios.Tpo" "$(DEPDIR)/vstafs_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/vstafs_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='vstafs_stage1_5_exec-bios.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vstafs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o vstafs_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`
+
+xfs_stage1_5_exec-common.o: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT xfs_stage1_5_exec-common.o -MD -MP -MF "$(DEPDIR)/xfs_stage1_5_exec-common.Tpo" -c -o xfs_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/xfs_stage1_5_exec-common.Tpo" "$(DEPDIR)/xfs_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/xfs_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='xfs_stage1_5_exec-common.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o xfs_stage1_5_exec-common.o `test -f 'common.c' || echo '$(srcdir)/'`common.c
+
+xfs_stage1_5_exec-common.obj: common.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT xfs_stage1_5_exec-common.obj -MD -MP -MF "$(DEPDIR)/xfs_stage1_5_exec-common.Tpo" -c -o xfs_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/xfs_stage1_5_exec-common.Tpo" "$(DEPDIR)/xfs_stage1_5_exec-common.Po"; else rm -f "$(DEPDIR)/xfs_stage1_5_exec-common.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='common.c' object='xfs_stage1_5_exec-common.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o xfs_stage1_5_exec-common.obj `if test -f 'common.c'; then $(CYGPATH_W) 'common.c'; else $(CYGPATH_W) '$(srcdir)/common.c'; fi`
+
+xfs_stage1_5_exec-char_io.o: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT xfs_stage1_5_exec-char_io.o -MD -MP -MF "$(DEPDIR)/xfs_stage1_5_exec-char_io.Tpo" -c -o xfs_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/xfs_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/xfs_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/xfs_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='xfs_stage1_5_exec-char_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o xfs_stage1_5_exec-char_io.o `test -f 'char_io.c' || echo '$(srcdir)/'`char_io.c
+
+xfs_stage1_5_exec-char_io.obj: char_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT xfs_stage1_5_exec-char_io.obj -MD -MP -MF "$(DEPDIR)/xfs_stage1_5_exec-char_io.Tpo" -c -o xfs_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/xfs_stage1_5_exec-char_io.Tpo" "$(DEPDIR)/xfs_stage1_5_exec-char_io.Po"; else rm -f "$(DEPDIR)/xfs_stage1_5_exec-char_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='char_io.c' object='xfs_stage1_5_exec-char_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o xfs_stage1_5_exec-char_io.obj `if test -f 'char_io.c'; then $(CYGPATH_W) 'char_io.c'; else $(CYGPATH_W) '$(srcdir)/char_io.c'; fi`
+
+xfs_stage1_5_exec-disk_io.o: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT xfs_stage1_5_exec-disk_io.o -MD -MP -MF "$(DEPDIR)/xfs_stage1_5_exec-disk_io.Tpo" -c -o xfs_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/xfs_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/xfs_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/xfs_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='xfs_stage1_5_exec-disk_io.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o xfs_stage1_5_exec-disk_io.o `test -f 'disk_io.c' || echo '$(srcdir)/'`disk_io.c
+
+xfs_stage1_5_exec-disk_io.obj: disk_io.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT xfs_stage1_5_exec-disk_io.obj -MD -MP -MF "$(DEPDIR)/xfs_stage1_5_exec-disk_io.Tpo" -c -o xfs_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/xfs_stage1_5_exec-disk_io.Tpo" "$(DEPDIR)/xfs_stage1_5_exec-disk_io.Po"; else rm -f "$(DEPDIR)/xfs_stage1_5_exec-disk_io.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='disk_io.c' object='xfs_stage1_5_exec-disk_io.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o xfs_stage1_5_exec-disk_io.obj `if test -f 'disk_io.c'; then $(CYGPATH_W) 'disk_io.c'; else $(CYGPATH_W) '$(srcdir)/disk_io.c'; fi`
+
+xfs_stage1_5_exec-stage1_5.o: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT xfs_stage1_5_exec-stage1_5.o -MD -MP -MF "$(DEPDIR)/xfs_stage1_5_exec-stage1_5.Tpo" -c -o xfs_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/xfs_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/xfs_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/xfs_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='xfs_stage1_5_exec-stage1_5.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o xfs_stage1_5_exec-stage1_5.o `test -f 'stage1_5.c' || echo '$(srcdir)/'`stage1_5.c
+
+xfs_stage1_5_exec-stage1_5.obj: stage1_5.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT xfs_stage1_5_exec-stage1_5.obj -MD -MP -MF "$(DEPDIR)/xfs_stage1_5_exec-stage1_5.Tpo" -c -o xfs_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/xfs_stage1_5_exec-stage1_5.Tpo" "$(DEPDIR)/xfs_stage1_5_exec-stage1_5.Po"; else rm -f "$(DEPDIR)/xfs_stage1_5_exec-stage1_5.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='stage1_5.c' object='xfs_stage1_5_exec-stage1_5.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o xfs_stage1_5_exec-stage1_5.obj `if test -f 'stage1_5.c'; then $(CYGPATH_W) 'stage1_5.c'; else $(CYGPATH_W) '$(srcdir)/stage1_5.c'; fi`
+
+xfs_stage1_5_exec-fsys_xfs.o: fsys_xfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT xfs_stage1_5_exec-fsys_xfs.o -MD -MP -MF "$(DEPDIR)/xfs_stage1_5_exec-fsys_xfs.Tpo" -c -o xfs_stage1_5_exec-fsys_xfs.o `test -f 'fsys_xfs.c' || echo '$(srcdir)/'`fsys_xfs.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/xfs_stage1_5_exec-fsys_xfs.Tpo" "$(DEPDIR)/xfs_stage1_5_exec-fsys_xfs.Po"; else rm -f "$(DEPDIR)/xfs_stage1_5_exec-fsys_xfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_xfs.c' object='xfs_stage1_5_exec-fsys_xfs.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o xfs_stage1_5_exec-fsys_xfs.o `test -f 'fsys_xfs.c' || echo '$(srcdir)/'`fsys_xfs.c
+
+xfs_stage1_5_exec-fsys_xfs.obj: fsys_xfs.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT xfs_stage1_5_exec-fsys_xfs.obj -MD -MP -MF "$(DEPDIR)/xfs_stage1_5_exec-fsys_xfs.Tpo" -c -o xfs_stage1_5_exec-fsys_xfs.obj `if test -f 'fsys_xfs.c'; then $(CYGPATH_W) 'fsys_xfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_xfs.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/xfs_stage1_5_exec-fsys_xfs.Tpo" "$(DEPDIR)/xfs_stage1_5_exec-fsys_xfs.Po"; else rm -f "$(DEPDIR)/xfs_stage1_5_exec-fsys_xfs.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='fsys_xfs.c' object='xfs_stage1_5_exec-fsys_xfs.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o xfs_stage1_5_exec-fsys_xfs.obj `if test -f 'fsys_xfs.c'; then $(CYGPATH_W) 'fsys_xfs.c'; else $(CYGPATH_W) '$(srcdir)/fsys_xfs.c'; fi`
+
+xfs_stage1_5_exec-bios.o: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT xfs_stage1_5_exec-bios.o -MD -MP -MF "$(DEPDIR)/xfs_stage1_5_exec-bios.Tpo" -c -o xfs_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/xfs_stage1_5_exec-bios.Tpo" "$(DEPDIR)/xfs_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/xfs_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='xfs_stage1_5_exec-bios.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o xfs_stage1_5_exec-bios.o `test -f 'bios.c' || echo '$(srcdir)/'`bios.c
+
+xfs_stage1_5_exec-bios.obj: bios.c
+@am__fastdepCC_TRUE@	if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -MT xfs_stage1_5_exec-bios.obj -MD -MP -MF "$(DEPDIR)/xfs_stage1_5_exec-bios.Tpo" -c -o xfs_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/xfs_stage1_5_exec-bios.Tpo" "$(DEPDIR)/xfs_stage1_5_exec-bios.Po"; else rm -f "$(DEPDIR)/xfs_stage1_5_exec-bios.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='bios.c' object='xfs_stage1_5_exec-bios.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xfs_stage1_5_exec_CFLAGS) $(CFLAGS) -c -o xfs_stage1_5_exec-bios.obj `if test -f 'bios.c'; then $(CYGPATH_W) 'bios.c'; else $(CYGPATH_W) '$(srcdir)/bios.c'; fi`
+uninstall-info-am:
+install-pkglibDATA: $(pkglib_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(pkglibdir)" || $(mkdir_p) "$(DESTDIR)$(pkglibdir)"
+	@list='$(pkglib_DATA)'; for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  f=$(am__strip_dir) \
+	  echo " $(pkglibDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkglibdir)/$$f'"; \
+	  $(pkglibDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkglibdir)/$$f"; \
+	done
+
+uninstall-pkglibDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkglib_DATA)'; for p in $$list; do \
+	  f=$(am__strip_dir) \
+	  echo " rm -f '$(DESTDIR)$(pkglibdir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(pkglibdir)/$$f"; \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	    $$tags $$unique; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$tags $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+	@failed=0; all=0; xfail=0; xpass=0; skip=0; \
+	srcdir=$(srcdir); export srcdir; \
+	list='$(TESTS)'; \
+	if test -n "$$list"; then \
+	  for tst in $$list; do \
+	    if test -f ./$$tst; then dir=./; \
+	    elif test -f $$tst; then dir=; \
+	    else dir="$(srcdir)/"; fi; \
+	    if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *" $$tst "*) \
+		xpass=`expr $$xpass + 1`; \
+		failed=`expr $$failed + 1`; \
+		echo "XPASS: $$tst"; \
+	      ;; \
+	      *) \
+		echo "PASS: $$tst"; \
+	      ;; \
+	      esac; \
+	    elif test $$? -ne 77; then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *" $$tst "*) \
+		xfail=`expr $$xfail + 1`; \
+		echo "XFAIL: $$tst"; \
+	      ;; \
+	      *) \
+		failed=`expr $$failed + 1`; \
+		echo "FAIL: $$tst"; \
+	      ;; \
+	      esac; \
+	    else \
+	      skip=`expr $$skip + 1`; \
+	      echo "SKIP: $$tst"; \
+	    fi; \
+	  done; \
+	  if test "$$failed" -eq 0; then \
+	    if test "$$xfail" -eq 0; then \
+	      banner="All $$all tests passed"; \
+	    else \
+	      banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
+	    fi; \
+	  else \
+	    if test "$$xpass" -eq 0; then \
+	      banner="$$failed of $$all tests failed"; \
+	    else \
+	      banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \
+	    fi; \
+	  fi; \
+	  dashes="$$banner"; \
+	  skipped=""; \
+	  if test "$$skip" -ne 0; then \
+	    skipped="($$skip tests were not run)"; \
+	    test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$skipped"; \
+	  fi; \
+	  report=""; \
+	  if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+	    report="Please report to $(PACKAGE_BUGREPORT)"; \
+	    test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$report"; \
+	  fi; \
+	  dashes=`echo "$$dashes" | sed s/./=/g`; \
+	  echo "$$dashes"; \
+	  echo "$$banner"; \
+	  test -z "$$skipped" || echo "$$skipped"; \
+	  test -z "$$report" || echo "$$report"; \
+	  echo "$$dashes"; \
+	  test "$$failed" -eq 0; \
+	else :; fi
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+	list='$(DISTFILES)'; for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+	  esac; \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+	    dir="/$$dir"; \
+	    $(mkdir_p) "$(distdir)$$dir"; \
+	  else \
+	    dir=''; \
+	  fi; \
+	  if test -d $$d/$$file; then \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) check-am
+all-am: Makefile $(LIBRARIES) $(PROGRAMS) $(SCRIPTS) $(DATA) \
+		$(HEADERS)
+installdirs:
+	for dir in "$(DESTDIR)$(pkglibdir)"; do \
+	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
+	done
+install: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+	-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-am
+
+clean-am: clean-generic clean-noinstLIBRARIES clean-noinstPROGRAMS \
+	mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-pkglibDATA
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-info-am uninstall-pkglibDATA
+
+.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
+	clean-generic clean-noinstLIBRARIES clean-noinstPROGRAMS ctags \
+	distclean distclean-compile distclean-generic distclean-tags \
+	distdir dvi dvi-am html html-am info info-am install \
+	install-am install-data install-data-am install-exec \
+	install-exec-am install-info install-info-am install-man \
+	install-pkglibDATA install-strip installcheck installcheck-am \
+	installdirs maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \
+	ps ps-am tags uninstall uninstall-am uninstall-info-am \
+	uninstall-pkglibDATA
+
+
+stage2_size.h: pre_stage2
+	-rm -f stage2_size.h
+	set dummy `ls -l pre_stage2`; \
+	echo "#define STAGE2_SIZE $$6" > stage2_size.h
+
+# XXX: automake doesn't provide a way to specify dependencies for object
+# files explicitly, so we must write this by a general Makefile scheme.
+# If automake change the naming scheme for per-executable objects, this
+# will be broken.
+start_exec-start.$(OBJEXT): stage2_size.h
+
+stage2: pre_stage2 start
+	-rm -f stage2
+	cat start pre_stage2 > stage2
+
+start_eltorito_exec-start.$(OBJEXT): stage2_size.h
+
+stage2_eltorito: pre_stage2 start_eltorito
+	-rm -f stage2_eltorito
+	cat start_eltorito pre_stage2 > stage2_eltorito
+
+diskless_size.h: diskless
+	-rm -f $@
+	set dummy `ls -l $^`; \
+	echo "#define DISKLESS_SIZE $$6" > $@
+
+# XXX: See the comment for start_exec-start.o.
+nbloader_exec-nbloader.$(OBJEXT): diskless_size.h
+
+# For nbgrub target.
+nbgrub: nbloader diskless
+	-rm -f $@
+	cat $^ > $@
+
+# XXX: See the comment for start_exec-start.o.
+pxeloader_exec-pxeloader.$(OBJEXT): diskless_size.h
+
+# For pxegrub target.
+pxegrub: pxeloader diskless
+	-rm -f $@
+	cat $^ > $@
+.exec:
+	$(OBJCOPY) -O binary $< $@
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/stage2/apic.h b/stage2/apic.h
new file mode 100644
index 0000000..9241329
--- /dev/null
+++ b/stage2/apic.h
@@ -0,0 +1,72 @@
+/*
+ *  <Insert copyright here : it must be BSD-like so everyone can use it>
+ *
+ *  Author:  Erich Boleyn  <erich@uruk.org>   http://www.uruk.org/~erich/
+ *
+ *  Header file for Intel Architecture local and I/O APIC definitions.
+ *
+ *  This file was created from information in the Intel Pentium Pro
+ *  Family Developer's Manual, Volume 3: Operating System Writer's
+ *  Manual, order number 242692-001, which can be ordered from the
+ *  Intel literature center.
+ */
+
+#ifndef _APIC_H
+#define _APIC_H
+
+/*
+ *  APIC Defines.
+ */
+
+#define APIC_BROADCAST_ID		       	0xFF
+
+/*
+ *  APIC register definitions
+ */
+
+/*
+ *  Shared defines for I/O and local APIC definitions
+ */
+/* APIC version register */
+#define	APIC_VERSION(x)				((x) & 0xFF)
+/* if the APIC version is equal or greater than APIC_VER_NEW, it
+   is a "new" APIC */
+#define APIC_VER_NEW				0x10
+/* this next one is used in all cases but an old local APIC, which has
+   2 entries in it's LVT */
+#define	APIC_MAXREDIR(x)			(((x) >> 16) & 0xFF)
+/* APIC id register */
+#define	APIC_OLD_ID(x)				((x) >> 24)
+#define	APIC_NEW_ID(x)				(((x) >> 24) & 0xF)
+
+#define IOAPIC_REGSEL				0
+#define IOAPIC_RW				0x10
+#define		IOAPIC_ID			0
+#define		IOAPIC_VER			1
+#define		IOAPIC_REDIR			0x10
+#define LAPIC_ID				0x20
+#define LAPIC_VER				0x30
+#define LAPIC_TPR				0x80
+#define LAPIC_APR				0x90
+#define LAPIC_PPR				0xA0
+#define LAPIC_EOI				0xB0
+#define LAPIC_LDR				0xD0
+#define LAPIC_DFR				0xE0
+#define LAPIC_SPIV				0xF0
+#define		LAPIC_SPIV_ENABLE_APIC		0x100
+#define LAPIC_ISR				0x100
+#define LAPIC_TMR				0x180
+#define LAPIC_IRR				0x200
+#define LAPIC_ESR				0x280
+#define LAPIC_ICR				0x300
+#define		LAPIC_DEST_MASK			0xFFFFFF
+#define LAPIC_LVTT				0x320
+#define LAPIC_LVTPC		       		0x340
+#define LAPIC_LVT0				0x350
+#define LAPIC_LVT1				0x360
+#define LAPIC_LVTE				0x370
+#define LAPIC_TICR				0x380
+#define LAPIC_TCCR				0x390
+#define LAPIC_TDCR				0x3E0
+
+#endif /* _APIC_H */
diff --git a/stage2/apm.S b/stage2/apm.S
new file mode 100644
index 0000000..abf5e27
--- /dev/null
+++ b/stage2/apm.S
@@ -0,0 +1,125 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000, 2001 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.
+ */
+
+/* This is stolen from arch/i386/boot/setup.S in Linux 2.2.17 */
+/*
+!       setup.S         Copyright (C) 1991, 1992 Linus Torvalds
+*/
+
+ENTRY(get_apm_info)
+	pushl	%ebp
+	pushl	%ebx
+	pushl	%edi
+	pushl	%esi
+
+	call	EXT_C(prot_to_real)
+	.code16
+	
+	/* APM BIOS installation check */
+	movw	$0x5300, %ax
+	xorw	%bx, %bx
+	int	$0x15
+	/* error -> no APM BIOS */
+	jc	done_apm_bios
+
+	/* check for "PM" signature */
+	cmpw	$0x504d, %bx
+	/* no signature -> no APM BIOS */
+	jne	done_apm_bios
+
+	/* Is 32 bit supported? */
+	andw	$0x0002, %cx
+	/* no ... */
+	je	done_apm_bios
+
+	/* Disconnect first just in case */
+	movw	$0x5304, %ax
+	xorw	%bx, %bx
+	/* ignore return code */
+	int	$0x15
+
+	/* 32 bit connect */
+	movw	$0x5303, %ax
+	xorl	%ebx, %ebx
+	/* paranoia */
+	xorw	%cx, %cx
+	xorw	%dx, %dx
+	xorl	%esi, %esi
+	xorw	%di, %di
+	int	$0x15
+	/* error */
+	jc	no_32_apm_bios
+
+	/* BIOS code segment */
+	movw	%ax, ABS(EXT_C(apm_bios_info)) + 2
+	/* BIOS entry point offset */
+	movl	%ebx, ABS(EXT_C(apm_bios_info)) + 4
+	/* BIOS 16 bit code segment */
+	movw	%cx, ABS(EXT_C(apm_bios_info)) + 8
+	/* BIOS data segment */
+	movw	%dx, ABS(EXT_C(apm_bios_info)) + 10
+	/* BIOS code segment length */
+	movl	%esi, ABS(EXT_C(apm_bios_info)) + 14
+	/* BIOS data segment length */
+	movw	%di, ABS(EXT_C(apm_bios_info)) + 18
+
+	/*
+	 * Redo the installation check as the 32 bit connect
+	 * modifies the flags returned on some BIOSs
+	 */
+
+	/* APM BIOS installation check */
+	movw	$0x5300, %ax
+	xorw	%bx, %bx
+	/* paranoia */
+	xorw	%cx, %cx
+	int     $0x15
+	/* error -> should not happen, tidy up */
+	jc	done_apm_bios
+
+	/* check for "PM" signature */
+	cmpw	$0x504d, %bx
+	/* no signature -> should not happen, tidy up */
+	jne	done_apm_bios
+
+	/* record the APM BIOS version */
+	movw	%ax, ABS(EXT_C(apm_bios_info))
+	/* and flags */
+	movw	%cx, ABS(EXT_C(apm_bios_info)) + 12
+	jmp	done_apm_bios
+
+no_32_apm_bios:
+	/* remove 32 bit support bit */
+	andw     $0xfffd, ABS(EXT_C(apm_bios_info)) + 12
+
+done_apm_bios:
+	/* Some paranoia here: Always Disconnect from APM */
+	movw	$0x5304, %ax
+	xorw	%bx, %bx
+	/* ignore return code */
+	int     $0x15
+
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	popl	%esi
+	popl	%edi
+	popl	%ebx
+	popl	%ebp
+	ret
diff --git a/stage2/asm.S b/stage2/asm.S
new file mode 100644
index 0000000..34b6e7d
--- /dev/null
+++ b/stage2/asm.S
@@ -0,0 +1,2367 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,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 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.
+ */
+
+
+/*
+ * Note: These functions defined in this file may be called from C.
+ *       Be careful of that you must not modify some registers. Quote
+ *       from gcc-2.95.2/gcc/config/i386/i386.h:
+	
+   1 for registers not available across function calls.
+   These must include the FIXED_REGISTERS and also any
+   registers that can be used without being saved.
+   The latter must include the registers where values are returned
+   and the register where structure-value addresses are passed.
+   Aside from that, you can include as many other registers as you like.
+
+  ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
+{  1, 1, 1, 0, 0, 0, 0, 1, 1,  1,  1,  1,  1,  1,  1,  1,  1 }
+ */
+
+#define ASM_FILE
+
+#include "shared.h"
+
+#ifdef STAGE1_5
+# define	ABS(x)	((x) - EXT_C(main) + 0x2200)
+#else
+# define	ABS(x)	((x) - EXT_C(main) + 0x8200)
+#endif
+	
+	.file	"asm.S"
+
+	.text
+
+	/* Tell GAS to generate 16-bit instructions so that this code works
+	   in real mode. */
+	.code16
+
+#ifndef STAGE1_5
+	/* 
+	 * In stage2, do not link start.S with the rest of the source
+	 * files directly, so define the start symbols here just to
+	 * force ld quiet. These are not referred anyway.
+	 */
+	.globl	start, _start
+start:
+_start:
+#endif /* ! STAGE1_5 */
+	
+ENTRY(main)
+	/*
+	 *  Guarantee that "main" is loaded at 0x0:0x8200 in stage2 and
+	 *  at 0x0:0x2200 in stage1.5.
+	 */
+	ljmp $0, $ABS(codestart)
+
+	/*
+	 *  Compatibility version number
+	 *
+	 *  These MUST be at byte offset 6 and 7 of the executable
+	 *  DO NOT MOVE !!!
+	 */
+	. = EXT_C(main) + 0x6
+	.byte	COMPAT_VERSION_MAJOR, COMPAT_VERSION_MINOR
+
+	/*
+	 *  This is a special data area 8 bytes from the beginning.
+	 */
+
+	. = EXT_C(main) + 0x8
+
+VARIABLE(install_partition)
+	.long	0xFFFFFF
+/* This variable is here only because of a historical reason.  */
+VARIABLE(saved_entryno)
+	.long	0
+VARIABLE(stage2_id)
+	.byte	STAGE2_ID
+VARIABLE(force_lba)
+	.byte	0
+VARIABLE(version_string)
+	.string VERSION
+VARIABLE(config_file)
+#ifndef STAGE1_5
+	.string "/boot/grub/menu.lst"
+#else   /* STAGE1_5 */
+	.long	0xffffffff
+	.string "/boot/grub/stage2"
+#endif  /* STAGE1_5 */
+
+	/*
+	 *  Leave some breathing room for the config file name.
+	 */
+
+	. = EXT_C(main) + 0x70
+
+/* the real mode code continues... */
+codestart:
+	cli		/* we're not safe here! */
+
+	/* set up %ds, %ss, and %es */
+	xorw	%ax, %ax
+	movw	%ax, %ds
+	movw	%ax, %ss
+	movw	%ax, %es
+
+#ifndef SUPPORT_DISKLESS
+	/*
+	 * Save the sector number of the second sector (i.e. this sector)
+	 * in INSTALL_SECOND_SECTOR. See also "stage2/start.S".
+	 */
+	ADDR32	movl	%ebp, EXT_C(install_second_sector)
+#endif
+	
+	/* set up the real mode/BIOS stack */
+	movl	$STACKOFF, %ebp
+	movl	%ebp, %esp
+
+	sti		/* we're safe again */
+
+#ifndef SUPPORT_DISKLESS
+	/* save boot drive reference */
+	ADDR32	movb	%dl, EXT_C(boot_drive)
+
+	/* reset disk system (%ah = 0) */
+	int	$0x13
+#endif
+
+	/* transition to protected mode */
+	DATA32	call EXT_C(real_to_prot)
+
+	/* The ".code32" directive takes GAS out of 16-bit mode. */
+	.code32
+
+	/* clean out the bss */
+
+	/* set %edi to the bss starting address */
+#if defined(HAVE_USCORE_USCORE_BSS_START_SYMBOL)
+	movl	$__bss_start, %edi
+#elif defined(HAVE_USCORE_EDATA_SYMBOL)
+	movl	$_edata, %edi
+#elif defined(HAVE_EDATA_SYMBOL)
+	movl	$edata, %edi
+#endif
+
+	/* set %ecx to the bss end */	
+#if defined(HAVE_END_SYMBOL)
+	movl	$end, %ecx
+#elif defined(HAVE_USCORE_END_SYMBOL)
+	movl	$_end, %ecx
+#endif
+
+	/* compute the bss length */
+	subl	%edi, %ecx
+	
+	/* zero %al */
+	xorb	%al, %al
+
+	/* set the direction */
+	cld
+	
+	/* clean out */
+	rep
+	stosb
+	
+	/*
+	 *  Call the start of main body of C code, which does some
+	 *  of it's own initialization before transferring to "cmain".
+	 */
+	call EXT_C(init_bios_info)
+
+
+/*
+ *  This call is special...  it never returns...  in fact it should simply
+ *  hang at this point!
+ */
+
+ENTRY(stop)
+	call	EXT_C(prot_to_real)
+
+	/*
+	 * This next part is sort of evil.  It takes advantage of the
+	 * byte ordering on the x86 to work in either 16-bit or 32-bit
+	 * mode, so think about it before changing it.
+	 */
+
+ENTRY(hard_stop)
+	hlt
+	jmp EXT_C(hard_stop)
+
+#ifndef STAGE1_5
+/*
+ * stop_floppy()
+ *
+ * Stops the floppy drive from spinning, so that other software is
+ * jumped to with a known state.
+ */
+ENTRY(stop_floppy)
+	pusha
+	call	EXT_C(prot_to_real)
+	.code16
+	xorb	%dl, %dl
+	int	$0x13
+	DATA32  call EXT_C(real_to_prot)
+	.code32
+	popa
+	ret
+
+/*
+ * grub_reboot()
+ *
+ * Reboot the system. At the moment, rely on BIOS.
+ */
+ENTRY(grub_reboot)
+	call	EXT_C(prot_to_real)
+	.code16
+	/* cold boot */
+	movw	$0x0472, %di
+	movw	%ax, (%di)
+	ljmp	$0xFFFF, $0x0000
+	.code32
+	
+/*
+ * grub_halt(int no_apm)
+ *
+ * Halt the system, using APM if possible. If NO_APM is true, don't use
+ * APM even if it is available.
+ */
+ENTRY(grub_halt)
+	/* get the argument */
+	movl	4(%esp), %eax
+	
+	/* see if zero */
+	testl	%eax, %eax
+	jnz	EXT_C(stop)
+
+	call	EXT_C(prot_to_real)
+	.code16
+	
+	/* detect APM */
+	movw	$0x5300, %ax
+	xorw	%bx, %bx
+	int	$0x15
+	jc	EXT_C(hard_stop)
+	/* don't check %bx for buggy BIOSes... */
+
+	/* disconnect APM first */
+	movw	$0x5304, %ax
+	xorw	%bx, %bx
+	int	$0x15
+
+	/* connect APM */
+	movw	$0x5301, %ax
+	xorw	%bx, %bx
+	int	$0x15
+	jc	EXT_C(hard_stop)
+
+	/* set APM protocol level - 1.1 or bust. (this covers APM 1.2 also) */
+	movw	$0x530E, %ax
+	xorw	%bx, %bx
+	movw	$0x0101, %cx
+	int	$0x15
+	jc	EXT_C(hard_stop)
+	
+	/* set the power state to off */
+	movw	$0x5307, %ax
+	movw	$1, %bx
+	movw	$3, %cx
+	int	$0x15
+
+	/* shouldn't reach here */
+	jmp	EXT_C(hard_stop)
+	.code32
+	
+/*
+ * track_int13(int drive)
+ *
+ * Track the int13 handler to probe I/O address space.
+ */
+ENTRY(track_int13)
+	pushl	%ebp
+	movl	%esp, %ebp
+
+	pushl	%ebx
+	pushl	%edi
+
+	/* copy the original int13 handler segment:offset */
+	movl	$0x4c, %edi
+	movl	(%edi), %eax
+	movl	%eax, track_int13_addr
+		
+	/* replace the int1 handler */
+	movl	$0x4, %edi
+	pushl	(%edi)
+	movl	$ABS(int1_handler), %eax
+	movl	%eax, (%edi)
+
+	/* read the MBR to call int13 successfully */
+	movb	8(%ebp), %dl
+	
+	call	EXT_C(prot_to_real)
+	.code16
+
+	movw	$SCRATCHSEG, %ax
+	movw	%ax, %es
+	xorw	%bx, %bx
+	movw	$1, %cx
+	xorb	%dh, %dh
+
+	/* save FLAGS on the stack to emulate int13 */
+	pushfw
+	
+	/* set the TF flag */
+	/* FIXME: this can be simplified not to use AX */
+	pushfw
+	popw	%ax
+	orw	$0x100, %ax
+	pushw	%ax
+	popfw
+
+	movw	$0x0201, %ax
+
+	.byte	0x9a		/* lcall */
+track_int13_addr:
+	.word	0		/* offset */
+	.word	0		/* segment */
+
+	/* TF is cleared here automatically */
+	
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	/* restore the int1 handler */
+	movl	$0x4, %edi
+	popl	(%edi)
+
+	popl	%edi
+	popl	%ebx
+	popl	%ebp
+	
+	ret
+
+
+/*
+ * Check if the next instruction is I/O, and if this is true, add the
+ * port into the io map.
+ *
+ * Note: Probably this will make the execution of int13 very slow.
+ *
+ * Note2: In this implementation, all we can know is I/O-mapped I/O. It
+ * is impossible to detect memory-mapped I/O.
+ */
+int1_handler:
+	.code16
+	
+	pushw	%bp
+	movw	%sp, %bp
+	pushw	%ds
+	pushw	%ax
+	pushw	%si
+	pushw	%dx
+	
+	/* IP */
+	movw	2(%bp), %si
+	/* CS */
+	movw	4(%bp), %ax
+	movw	%ax, %ds
+
+	/* examine the next instruction */
+1:	lodsb	(%si), %al
+	/* skip this code if it is a prefix */
+	cmpb	$0x2E, %al
+	je	1b
+	cmpb	$0x36, %al
+	je	1b
+	cmpb	$0x3E, %al
+	je	1b
+	cmpb	$0x26, %al
+	je	1b
+	cmpb	$0x64, %al
+	jl	2f
+	cmpb	$0x67, %al
+	jle	1b
+2:	cmpb	$0xF0, %al
+	jl	3f
+	cmpb	$0xF3, %al
+	jle	1b
+	
+3:	/* check if this code is out* or in* */
+
+	/* ins? or outs? */
+	cmpb	$0x6C, %al
+	jl	4f
+	cmpb	$0x6F, %al
+	jle	5f
+
+4:	/* in? or out? (register operand version) */
+	cmpb	$0xEC, %al
+	jl	6f
+	cmpb	$0xEF, %al
+	jle	5f
+	
+6:	/* in? or out? (immediate operand version) */
+	cmpb	$0xE4, %al
+	jl	8f
+	cmpb	$0xE7, %al
+	jg	8f
+
+7:	/* immediate has a port */
+	lodsb	(%si), %al
+	movzbw	%al, %dx
+	
+5:	/* %dx has a port */
+
+	/* set %ds to zero */
+	xorw	%ax, %ax
+	movw	%ax, %ds
+		
+	/* set %si to the io map */
+	movw	$ABS(EXT_C(io_map)), %si
+
+		
+9:	/* check if the io map already has the port */
+	lodsw	(%si), %ax
+	/* check if this is the end */
+	testw	%ax, %ax
+	jz	1f
+	/* check if this matches the port */
+	cmpw	%ax, %dx
+	jne	9b
+	/* if so, leave from this handler */
+	jmp	8f
+	
+1:	/* check for the buffer overrun */
+	cmpw	$(ABS(EXT_C(io_map)) + (IO_MAP_SIZE + 1) * 2), %si
+	je	8f
+	/* add the port into the io map */
+	movw	%dx, -2(%si)
+
+8:	/* restore registers */	
+	popw	%dx
+	popw	%si
+	popw	%ax
+	popw	%ds
+	popw	%bp
+
+	iret
+	
+	.code32
+
+ENTRY(io_map)
+	.space	(IO_MAP_SIZE + 1) * 2
+	
+	
+/*
+ * set_int15_handler(void)
+ *
+ * Set up int15_handler.
+ */
+ENTRY(set_int15_handler)
+	pushl	%edi
+	
+	/* save the original int15 handler */
+	movl	$0x54, %edi
+	movw	(%edi), %ax
+	movw	%ax, ABS(int15_offset)
+	movw	2(%edi), %ax
+	movw	%ax, ABS(int15_segment)
+
+	/* save the new int15 handler */
+	movw	$ABS(int15_handler), %ax
+	movw	%ax, (%edi)
+	xorw	%ax, %ax
+	movw	%ax, 2(%edi)
+
+	popl	%edi
+	ret
+
+
+/*
+ * unset_int15_handler(void)
+ *
+ * Restore the original int15 handler
+ */
+ENTRY(unset_int15_handler)
+	pushl	%edi
+	
+	/* check if int15_handler is set */
+	movl	$0x54, %edi
+	movw	$ABS(int15_handler), %ax
+	cmpw	%ax, (%edi)
+	jne	1f
+	xorw	%ax, %ax
+	cmpw	%ax, 2(%edi)
+	jne	1f
+
+	/* restore the original */
+	movw	ABS(int15_offset), %ax
+	movw	%ax, (%edi)
+	movw	ABS(int15_segment), %ax
+	movw	%ax, 2(%edi)
+
+1:
+	popl	%edi
+	ret
+
+
+/*
+ * Translate a key code to another.
+ *
+ * Note: This implementation cannot handle more than one length
+ * scancodes (such as Right Ctrl).
+ */
+	.code16
+int15_handler:
+	/* if non-carrier, ignore it */
+	jnc	1f
+	/* check if AH=4F */
+	cmpb	$0x4F, %ah
+	jne	1f
+
+	/* E0 and E1 are special */
+	cmpb	$0xE1, %al
+	je	4f
+	cmpb	$0xE0, %al
+	/* this flag is actually the machine code (je or jmp) */
+int15_skip_flag:	
+	je	4f
+	
+	pushw	%bp
+	movw	%sp, %bp
+	
+	pushw	%bx
+	pushw	%dx
+	pushw	%ds
+	pushw	%si
+
+	/* save bits 0-6 of %al in %dl */
+	movw	%ax, %dx
+	andb	$0x7f, %dl
+	/* save the highest bit in %bl */
+	movb	%al, %bl
+	xorb	%dl, %bl
+	/* set %ds to 0 */
+	xorw	%ax, %ax
+	movw	%ax, %ds
+	/* set %si to the key map */
+	movw	$ABS(EXT_C(bios_key_map)), %si
+
+	/* find the key code from the key map */
+2:
+	lodsw
+	/* check if this is the end */
+	testw	%ax, %ax
+	jz	3f
+	/* check if this matches the key code */
+	cmpb	%al, %dl
+	jne	2b
+	/* if so, perform the mapping */
+	movb	%ah, %dl
+3:
+	/* restore %ax */
+	movw	%dx, %ax
+	orb	%bl, %al
+	/* make sure that CF is set */
+	orw	$1, 6(%bp)
+	/* restore other registers */
+	popw	%si
+	popw	%ds
+	popw	%dx
+	popw	%bx
+	popw	%bp
+	iret
+	
+4:
+	/* tricky: jmp (0x74) <-> je (0xeb) */
+	xorb	$(0x74 ^ 0xeb), ABS(int15_skip_flag)
+1:
+	/* just cascade to the original */
+	/* ljmp */
+	.byte	0xea
+int15_offset:	.word	0
+int15_segment:	.word	0
+
+	.code32
+
+	.align	4	
+ENTRY(bios_key_map)
+	.space	(KEY_MAP_SIZE + 1) * 2
+	
+	
+/*
+ * set_int13_handler(map)
+ *
+ * Copy MAP to the drive map and set up int13_handler.
+ */
+ENTRY(set_int13_handler)
+	pushl	%ebp
+	movl	%esp, %ebp
+
+	pushl	%edi
+	pushl	%esi
+
+	/* copy MAP to the drive map */
+	movl	$(DRIVE_MAP_SIZE * 2), %ecx
+	movl	$ABS(drive_map), %edi
+	movl	8(%ebp), %esi
+	cld
+	rep
+	movsb
+
+	/* save the original int13 handler */
+	movl	$0x4c, %edi
+	movw	(%edi), %ax
+	movw	%ax, ABS(int13_offset)
+	movw	2(%edi), %ax
+	movw	%ax, ABS(int13_segment)
+	
+	/* decrease the lower memory size and set it to the BIOS memory */
+	movl	$0x413, %edi
+	decw	(%edi)
+	xorl	%eax, %eax
+	movw	(%edi), %ax
+	
+	/* compute the segment */
+	shll	$6, %eax
+
+	/* save the new int13 handler */
+	movl	$0x4c, %edi
+	movw	%ax, 2(%edi)
+	xorw	%cx, %cx
+	movw	%cx, (%edi)
+
+	/* copy int13_handler to the reserved area */
+	shll	$4, %eax
+	movl	%eax, %edi
+	movl	$ABS(int13_handler), %esi
+	movl	$(int13_handler_end - int13_handler), %ecx
+	rep
+	movsb
+
+	popl	%esi
+	popl	%edi
+	popl	%ebp
+	ret
+
+	
+/* 
+ * Map a drive to another drive.
+ */
+	
+	.code16
+	
+int13_handler:
+	pushw	%ax
+	pushw	%bp
+	movw	%sp, %bp
+	
+	pushw	%si
+
+	/* set %si to the drive map */
+	movw	$(drive_map - int13_handler), %si
+	/* find the drive number from the drive map */
+	cld
+1:	
+	lodsw	%cs:(%si), %ax
+	/* check if this is the end */
+	testw	%ax, %ax
+	jz	2f
+	/* check if this matches the drive number */
+	cmpb	%al, %dl
+	jne	1b
+	/* if so, perform the mapping */
+	movb	%ah, %dl
+2:
+	/* restore %si */
+	popw	%si
+	/* save %ax in the stack */
+	pushw	%ax
+	/* simulate the interrupt call */
+	pushw	8(%bp)
+	/* set %ax and %bp to the original values */
+	movw	2(%bp), %ax
+	movw	(%bp), %bp
+	/* lcall */
+	.byte	0x9a
+int13_offset:	.word	0
+int13_segment:	.word	0
+	/* save flags */
+	pushf
+	/* restore %bp */
+	movw	%sp, %bp
+	/* save %ax */
+	pushw	%ax
+	/* set the flags in the stack to the value returned by int13 */
+	movw	(%bp), %ax
+	movw	%ax, 0xc(%bp)
+	/* check if should map the drive number */
+	movw	6(%bp), %ax
+	cmpw	$0x8, %ax
+	jne	3f
+	cmpw	$0x15, %ax
+	jne	3f
+	/* check if the mapping was performed */
+	movw	2(%bp), %ax
+	testw	%ax, %ax
+	jz	3f
+	/* perform the mapping */
+	movb	%al, %dl
+3:
+	popw	%ax
+	movw	4(%bp), %bp
+	addw	$8, %sp
+	iret
+
+	.align	4
+drive_map:	.space	(DRIVE_MAP_SIZE + 1) * 2
+int13_handler_end:
+	
+	.code32
+	
+	
+/*
+ * chain_stage1(segment, offset, part_table_addr)
+ *
+ *  This starts another stage1 loader, at segment:offset.
+ */
+
+ENTRY(chain_stage1)
+	/* no need to save anything, just use %esp */
+
+	/* store %ESI, presuming %ES is 0 */
+	movl	0xc(%esp), %esi
+
+	/* store new offset */
+	movl	0x8(%esp), %eax
+	movl	%eax, offset
+
+	/* store new segment */
+	movw	0x4(%esp), %ax
+	movw	%ax, segment
+
+	/* set up to pass boot drive */
+	movb	EXT_C(boot_drive), %dl
+
+	call	EXT_C(prot_to_real)
+	.code16
+
+#ifdef ABSOLUTE_WITHOUT_ASTERISK
+	DATA32	ADDR32	ljmp	(offset)
+#else
+	DATA32	ADDR32	ljmp	*(offset)
+#endif
+	.code32
+#endif /* STAGE1_5 */
+
+
+#ifdef STAGE1_5
+/*
+ * chain_stage2(segment, offset, second_sector)
+ *
+ *  This starts another stage2 loader, at segment:offset.  It presumes
+ *  that the other one starts with this same "asm.S" file, and passes
+ *  parameters by writing the embedded install variables.
+ */
+
+ENTRY(chain_stage2)
+	/* no need to save anything, just use %esp */
+
+	/* store new offset */
+	movl	0x8(%esp), %eax
+	movl	%eax, offset
+	movl	%eax, %ebx
+
+	/* store new segment */
+	movw	0x4(%esp), %ax
+	movw	%ax, segment
+	shll	$4, %eax
+
+	/* generate linear address */
+	addl	%eax, %ebx
+
+	/* set up to pass the partition where stage2 is located in */
+	movl	EXT_C(current_partition), %eax
+	movl	%eax, (EXT_C(install_partition)-EXT_C(main))(%ebx)
+
+	/* set up to pass the drive where stage2 is located in */
+	movb	EXT_C(current_drive), %dl
+
+	/* set up to pass the second sector of stage2 */
+	movl	0xc(%esp), %ecx
+
+	call	EXT_C(prot_to_real)
+	.code16
+
+	movl	%ecx, %ebp
+
+#ifdef ABSOLUTE_WITHOUT_ASTERISK
+	DATA32	ADDR32	ljmp	(offset)
+#else
+	DATA32	ADDR32	ljmp	*(offset)
+#endif
+
+	.code32
+#endif /* STAGE1_5 */
+	
+/*
+ *  These next two routines, "real_to_prot" and "prot_to_real" are structured
+ *  in a very specific way.  Be very careful when changing them.
+ *
+ *  NOTE:  Use of either one messes up %eax and %ebp.
+ */
+
+ENTRY(real_to_prot)
+	.code16
+	cli
+
+	/* load the GDT register */
+	DATA32	ADDR32	lgdt	gdtdesc
+
+	/* turn on protected mode */
+	movl	%cr0, %eax
+	orl	$CR0_PE_ON, %eax
+	movl	%eax, %cr0
+
+	/* jump to relocation, flush prefetch queue, and reload %cs */
+	DATA32	ljmp	$PROT_MODE_CSEG, $protcseg
+
+	/*
+	 *  The ".code32" directive only works in GAS, the GNU assembler!
+	 *  This gets out of "16-bit" mode.
+	 */
+	.code32
+
+protcseg:
+	/* reload other segment registers */
+	movw	$PROT_MODE_DSEG, %ax
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %fs
+	movw	%ax, %gs
+	movw	%ax, %ss
+
+	/* put the return address in a known safe location */
+	movl	(%esp), %eax
+	movl	%eax, STACKOFF
+
+	/* get protected mode stack */
+	movl	protstack, %eax
+	movl	%eax, %esp
+	movl	%eax, %ebp
+
+	/* get return address onto the right stack */
+	movl	STACKOFF, %eax
+	movl	%eax, (%esp)
+
+	/* zero %eax */
+	xorl	%eax, %eax
+
+	/* return on the old (or initialized) stack! */
+	ret
+
+
+ENTRY(prot_to_real)
+	/* just in case, set GDT */
+	lgdt	gdtdesc
+
+	/* save the protected mode stack */
+	movl	%esp, %eax
+	movl	%eax, protstack
+
+	/* get the return address */
+	movl	(%esp), %eax
+	movl	%eax, STACKOFF
+
+	/* set up new stack */
+	movl	$STACKOFF, %eax
+	movl	%eax, %esp
+	movl	%eax, %ebp
+
+	/* set up segment limits */
+	movw	$PSEUDO_RM_DSEG, %ax
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %fs
+	movw	%ax, %gs
+	movw	%ax, %ss
+
+	/* this might be an extra step */
+	ljmp	$PSEUDO_RM_CSEG, $tmpcseg	/* jump to a 16 bit segment */
+
+tmpcseg:
+	.code16
+
+	/* clear the PE bit of CR0 */
+	movl	%cr0, %eax
+	andl 	$CR0_PE_OFF, %eax
+	movl	%eax, %cr0
+
+	/* flush prefetch queue, reload %cs */
+	DATA32	ljmp	$0, $realcseg
+
+realcseg:
+	/* we are in real mode now
+	 * set up the real mode segment registers : DS, SS, ES
+	 */
+	/* zero %eax */
+	xorl	%eax, %eax
+
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %fs
+	movw	%ax, %gs
+	movw	%ax, %ss
+
+	/* restore interrupts */
+	sti
+
+	/* return on new stack! */
+	DATA32	ret
+
+	.code32
+
+
+/*
+ *   int biosdisk_int13_extensions (int ax, int drive, void *dap)
+ *
+ *   Call IBM/MS INT13 Extensions (int 13 %ax=AX) for DRIVE. DAP
+ *   is passed for disk address packet. If an error occurs, return
+ *   non-zero, otherwise zero.
+ */
+
+ENTRY(biosdisk_int13_extensions)
+	pushl	%ebp
+	movl	%esp, %ebp
+
+	pushl	%esi
+	pushl	%ebx
+
+	/* compute the address of disk_address_packet */
+	movl	0x10(%ebp), %eax
+	movw	%ax, %si
+	xorw	%ax, %ax
+	shrl	$4, %eax
+	movw	%ax, %cx	/* save the segment to cx */
+
+	/* drive */
+	movb	0xc(%ebp), %dl
+	/* ax */
+	movw	0x8(%ebp), %bx
+	/* enter real mode */
+	call	EXT_C(prot_to_real)
+	
+	.code16
+	movw	%bx, %ax
+	movw	%cx, %ds
+	int	$0x13		/* do the operation */
+	movb	%ah, %dl	/* save return value */
+	/* clear the data segment */
+	xorw	%ax, %ax
+	movw	%ax, %ds
+	/* back to protected mode */
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	movb	%dl, %al	/* return value in %eax */
+
+	popl	%ebx
+	popl	%esi
+	popl	%ebp
+
+	ret
+	
+/*
+ *   int biosdisk_standard (int ah, int drive, int coff, int hoff, int soff,
+ *                          int nsec, int segment)
+ *
+ *   Call standard and old INT13 (int 13 %ah=AH) for DRIVE. Read/write
+ *   NSEC sectors from COFF/HOFF/SOFF into SEGMENT. If an error occurs,
+ *   return non-zero, otherwise zero.
+ */
+
+ENTRY(biosdisk_standard)
+	pushl	%ebp
+	movl	%esp, %ebp
+
+	pushl	%ebx
+	pushl	%edi
+	pushl	%esi
+
+	/* set up CHS information */
+	movl	0x10(%ebp), %eax
+	movb	%al, %ch
+	movb	0x18(%ebp), %al
+	shlb	$2, %al
+	shrw	$2, %ax
+	movb	%al, %cl
+	movb	0x14(%ebp), %dh
+	/* drive */
+	movb	0xc(%ebp), %dl
+	/* segment */
+	movw	0x20(%ebp), %bx
+	/* save nsec and ah to %di */
+	movb	0x8(%ebp), %ah
+	movb	0x1c(%ebp), %al
+	movw	%ax, %di
+	/* enter real mode */
+	call	EXT_C(prot_to_real)
+
+	.code16
+	movw	%bx, %es
+	xorw	%bx, %bx
+	movw	$3, %si		/* attempt at least three times */
+
+1:	
+	movw	%di, %ax
+	int	$0x13		/* do the operation */
+	jnc	2f		/* check if successful */
+
+	movb	%ah, %bl	/* save return value */
+	/* if fail, reset the disk system */
+	xorw	%ax, %ax
+	int	$0x13
+	
+	decw	%si
+	cmpw	$0, %si
+	je	2f
+	xorb	%bl, %bl
+	jmp	1b		/* retry */
+2:	
+	/* back to protected mode */
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	movb	%bl, %al	/* return value in %eax */
+	
+	popl	%esi
+	popl	%edi
+	popl	%ebx
+	popl	%ebp
+
+	ret
+
+
+/*
+ *   int check_int13_extensions (int drive)
+ *
+ *   Check if LBA is supported for DRIVE. If it is supported, then return
+ *   the major version of extensions, otherwise zero.
+ */
+
+ENTRY(check_int13_extensions)
+	pushl	%ebp
+	movl	%esp, %ebp
+
+	pushl	%ebx
+
+	/* drive */
+	movb	0x8(%ebp), %dl
+	/* enter real mode */
+	call	EXT_C(prot_to_real)
+
+	.code16
+	movb	$0x41, %ah
+	movw	$0x55aa, %bx
+	int	$0x13		/* do the operation */
+	
+	/* check the result */
+	jc	1f
+	cmpw	$0xaa55, %bx
+	jne	1f
+
+	movb	%ah, %bl	/* save the major version into %bl */
+
+	/* check if AH=0x42 is supported if FORCE_LBA is zero */
+	movb	EXT_C(force_lba), %al
+	testb	%al, %al
+	jnz	2f
+	andw	$1, %cx
+	jnz	2f
+	
+1:
+	xorb	%bl, %bl
+2:
+	/* back to protected mode */
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	movb	%bl, %al	/* return value in %eax */
+
+	popl	%ebx
+	popl	%ebp
+
+	ret
+
+
+/*
+ *   int get_diskinfo_standard (int drive, unsigned long *cylinders, 
+ *                              unsigned long *heads, unsigned long *sectors)
+ *
+ *   Return the geometry of DRIVE in CYLINDERS, HEADS and SECTORS. If an
+ *   error occurs, then return non-zero, otherwise zero.
+ */
+
+ENTRY(get_diskinfo_standard)
+	pushl	%ebp
+	movl	%esp, %ebp
+
+	pushl	%ebx
+	pushl	%edi
+
+	/* drive */
+	movb	0x8(%ebp), %dl
+	/* enter real mode */
+	call	EXT_C(prot_to_real)
+
+	.code16
+	movb	$0x8, %ah
+	int	$0x13		/* do the operation */
+	/* check if successful */
+	testb	%ah, %ah
+	jnz	1f
+	/* bogus BIOSes may not return an error number */
+	testb	$0x3f, %cl	/* 0 sectors means no disk */
+	jnz	1f		/* if non-zero, then succeed */
+	/* XXX 0x60 is one of the unused error numbers */
+	movb	$0x60, %ah
+1:
+	movb	%ah, %bl	/* save return value in %bl */
+	/* back to protected mode */
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	/* restore %ebp */
+	leal	0x8(%esp), %ebp
+	
+	/* heads */
+	movb	%dh, %al
+	incl	%eax		/* the number of heads is counted from zero */
+	movl	0x10(%ebp), %edi
+	movl	%eax, (%edi)
+
+	/* sectors */
+	xorl	%eax, %eax
+	movb	%cl, %al
+	andb	$0x3f, %al
+	movl	0x14(%ebp), %edi
+	movl	%eax, (%edi)
+
+	/* cylinders */
+	shrb	$6, %cl
+	movb	%cl, %ah
+	movb	%ch, %al
+	incl	%eax		/* the number of cylinders is 
+				   counted from zero */
+	movl	0xc(%ebp), %edi
+	movl	%eax, (%edi)
+
+	xorl	%eax, %eax
+	movb	%bl, %al	/* return value in %eax */
+
+	popl	%edi
+	popl	%ebx
+	popl	%ebp
+
+	ret
+
+
+#if 0		
+/*
+ *   int get_diskinfo_floppy (int drive, unsigned long *cylinders, 
+ *                            unsigned long *heads, unsigned long *sectors)
+ *
+ *   Return the geometry of DRIVE in CYLINDERS, HEADS and SECTORS. If an
+ *   error occurs, then return non-zero, otherwise zero.
+ */
+
+ENTRY(get_diskinfo_floppy)
+	pushl	%ebp
+	movl	%esp, %ebp
+
+	pushl	%ebx
+	pushl	%esi
+
+	/* drive */
+	movb	0x8(%ebp), %dl
+	/* enter real mode */
+	call	EXT_C(prot_to_real)
+
+	.code16
+	/* init probe value */
+	movl	$probe_values-1, %esi
+1:
+	xorw	%ax, %ax
+	int	$0x13		/* reset floppy controller */
+
+	incw	%si
+	movb	(%si), %cl
+	cmpb	$0, %cl		/* probe failed if zero */
+	je	2f
+
+	/* perform read */
+	movw	$SCRATCHSEG, %ax
+	movw	%ax, %es
+	xorw	%bx, %bx
+	movw	$0x0201, %ax
+	movb	$0, %ch
+	movb	$0, %dh
+	int	$0x13
+
+	/* FIXME: Read from floppy may fail even if the geometry is correct.
+	   So should retry at least three times.  */
+	jc	1b		/* next value */
+	
+	/* succeed */
+	jmp	2f
+	
+probe_values:
+	.byte	36, 18, 15, 9, 0
+	
+2:
+	/* back to protected mode */
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	/* restore %ebp */
+	leal	0x8(%esp), %ebp
+	
+	/* cylinders */
+	movl	0xc(%ebp), %eax
+	movl	$80, %ebx
+	movl	%ebx, (%eax)
+	/* heads */
+	movl	0x10(%ebp), %eax
+	movl	$2, %ebx
+	movl	%ebx, (%eax)
+	/* sectors */
+	movl	0x14(%ebp), %eax
+	movzbl	%cl, %ebx
+	movl	%ebx, (%eax)
+
+	/* return value in %eax */
+	xorl	%eax, %eax
+	cmpb	$0, %cl
+	jne	3f
+	incl	%eax		/* %eax = 1 (non-zero) */
+3:
+	popl	%esi
+	popl	%ebx
+	popl	%ebp
+
+	ret
+#endif
+	
+
+/* Source files are splitted, as they have different copyrights.  */
+#ifndef STAGE1_5
+# include "setjmp.S"
+# include "apm.S"
+#endif /* ! STAGE1_5 */
+		
+	
+
+#ifndef STAGE1_5
+/* get_code_end() :  return the address of the end of the code
+ * This is here so that it can be replaced by asmstub.c.
+ */
+ENTRY(get_code_end)
+	/* will be the end of the bss */
+# if defined(HAVE_END_SYMBOL)
+	movl	$end, %eax
+# elif defined(HAVE_USCORE_END_SYMBOL)
+	movl	$_end, %eax
+# endif
+	shrl	$2, %eax		/* Round up to the next word. */
+	incl	%eax
+	shll	$2, %eax
+	ret
+#endif /* ! STAGE1_5 */
+
+/*
+ *
+ * get_memsize(i) :  return the memory size in KB. i == 0 for conventional
+ *		memory, i == 1 for extended memory
+ *	BIOS call "INT 12H" to get conventional memory size
+ *	BIOS call "INT 15H, AH=88H" to get extended memory size
+ *		Both have the return value in AX.
+ *
+ */
+
+ENTRY(get_memsize)
+	push	%ebp
+	push	%ebx
+
+	mov	0xc(%esp), %ebx
+
+	call	EXT_C(prot_to_real)	/* enter real mode */
+	.code16
+
+	cmpb	$0x1, %bl
+	DATA32	je	xext
+
+	int	$0x12
+	DATA32	jmp	xdone
+
+xext:
+	movb	$0x88, %ah
+	int	$0x15
+
+xdone:
+	movw	%ax, %bx
+
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	movw	%bx, %ax
+	pop	%ebx
+	pop	%ebp
+	ret
+
+
+#ifndef STAGE1_5
+
+/*
+ *
+ * get_eisamemsize() :  return packed EISA memory map, lower 16 bits is
+ *		memory between 1M and 16M in 1K parts, upper 16 bits is
+ *		memory above 16M in 64K parts.  If error, return -1.
+ *	BIOS call "INT 15H, AH=E801H" to get EISA memory map,
+ *		AX = memory between 1M and 16M in 1K parts.
+ *		BX = memory above 16M in 64K parts.
+ *
+ */
+
+ENTRY(get_eisamemsize)
+	push	%ebp
+	push	%ebx
+
+	call	EXT_C(prot_to_real)	/* enter real mode */
+	.code16
+
+	movw	$0xe801, %ax
+	int	$0x15
+
+	shll	$16, %ebx
+	movw	%ax, %bx
+
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	movl	$0xFFFFFFFF, %eax
+	cmpb	$0x86, %bh
+	je	xnoteisa
+
+	movl	%ebx, %eax
+
+xnoteisa:
+	pop	%ebx
+	pop	%ebp
+	ret
+
+/*
+ *
+ * get_mmap_entry(addr, cont) :  address and old continuation value (zero to
+ *		start), for the Query System Address Map BIOS call.
+ *
+ *  Sets the first 4-byte int value of "addr" to the size returned by
+ *  the call.  If the call fails, sets it to zero.
+ *
+ *	Returns:  new (non-zero) continuation value, 0 if done.
+ *
+ * NOTE: Currently hard-coded for a maximum buffer length of 1024.
+ */
+
+ENTRY(get_mmap_entry)
+	push	%ebp
+	push	%ebx
+	push	%edi
+	push	%esi
+
+	/* place address (+4) in ES:DI */
+	movl	0x14(%esp), %eax
+	addl	$4, %eax
+	movl	%eax, %edi
+	andl	$0xf, %edi
+	shrl	$4, %eax
+	movl	%eax, %esi
+
+	/* set continuation value */
+	movl	0x18(%esp), %ebx
+
+	/* set default maximum buffer size */
+	movl	$0x14, %ecx
+
+	/* set EDX to 'SMAP' */
+	movl	$0x534d4150, %edx
+
+	call	EXT_C(prot_to_real)	/* enter real mode */
+	.code16
+
+	movw	%si, %es
+	movl	$0xe820, %eax
+	int	$0x15
+
+	DATA32	jc	xnosmap
+
+	cmpl	$0x534d4150, %eax
+	DATA32	jne	xnosmap
+
+	cmpl	$0x14, %ecx
+	DATA32	jl	xnosmap
+
+	cmpl	$0x400, %ecx
+	DATA32	jg	xnosmap
+
+	DATA32	jmp	xsmap
+
+xnosmap:
+	movl	$0, %ecx
+
+xsmap:
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	/* write length of buffer (zero if error) into "addr" */
+	movl	0x14(%esp), %eax
+	movl	%ecx, (%eax)
+
+	/* set return value to continuation */
+	movl	%ebx, %eax
+
+	pop	%esi
+	pop	%edi
+	pop	%ebx
+	pop	%ebp
+	ret
+
+/*
+ * get_rom_config_table()
+ *
+ * Get the linear address of a ROM configuration table. Return zero,
+ * if fails.
+ */
+	
+ENTRY(get_rom_config_table)
+	pushl	%ebp
+	pushl	%ebx
+
+	/* zero %ebx for simplicity */
+	xorl	%ebx, %ebx
+	
+	call	EXT_C(prot_to_real)
+	.code16
+
+	movw	$0xc0, %ax
+	int	$0x15
+
+	jc	no_rom_table
+	testb	%ah, %ah
+	jnz	no_rom_table
+	
+	movw	%es, %dx
+	jmp	found_rom_table
+	
+no_rom_table:
+	xorw	%dx, %dx
+	xorw	%bx, %bx
+	
+found_rom_table:
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	/* compute the linear address */
+	movw	%dx, %ax
+	shll	$4, %eax
+	addl	%ebx, %eax
+
+	popl	%ebx
+	popl	%ebp
+	ret
+
+
+/*
+ * int get_vbe_controller_info (struct vbe_controller *controller_ptr)
+ *
+ * Get VBE controller information.
+ */
+
+ENTRY(get_vbe_controller_info)
+	pushl	%ebp
+	movl	%esp, %ebp
+	
+	pushl	%edi
+	pushl	%ebx
+
+	/* Convert the linear address to segment:offset */
+	movl	8(%ebp), %eax
+	movl	%eax, %edi
+	andl	$0x0000000f, %edi
+	shrl	$4, %eax
+	movl	%eax, %ebx
+
+	call	EXT_C(prot_to_real)
+	.code16
+
+	movw	%bx, %es
+	movw	$0x4F00, %ax
+	int	$0x10
+
+	movw	%ax, %bx
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	movzwl	%bx, %eax
+
+	popl	%ebx
+	popl	%edi
+	popl	%ebp
+	ret
+
+	
+/*
+ * int get_vbe_mode_info (int mode_number, struct vbe_mode *mode_ptr)
+ *
+ * Get VBE mode information.
+ */
+
+ENTRY(get_vbe_mode_info)
+	pushl	%ebp
+	movl	%esp, %ebp
+	
+	pushl	%edi
+	pushl	%ebx
+
+	/* Convert the linear address to segment:offset */
+	movl	0xc(%ebp), %eax
+	movl	%eax, %edi
+	andl	$0x0000000f, %edi
+	shrl	$4, %eax
+	movl	%eax, %ebx
+
+	/* Save the mode number in %cx */
+	movl	0x8(%ebp), %ecx
+	
+	call	EXT_C(prot_to_real)
+	.code16
+
+	movw	%bx, %es
+	movw	$0x4F01, %ax
+	int	$0x10
+
+	movw	%ax, %bx
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	movzwl	%bx, %eax
+
+	popl	%ebx
+	popl	%edi
+	popl	%ebp
+	ret
+
+	
+/*
+ * int set_vbe_mode (int mode_number)
+ *
+ * Set VBE mode. Don't support user-specified CRTC information.
+ */
+
+ENTRY(set_vbe_mode)
+	pushl	%ebp
+	movl	%esp, %ebp
+	
+	pushl	%ebx
+
+	/* Save the mode number in %bx */
+	movl	0x8(%ebp), %ebx
+	/* Clear bit D11 */
+	andl	$0xF7FF, %ebx
+	
+	call	EXT_C(prot_to_real)
+	.code16
+
+	movw	$0x4F02, %ax
+	int	$0x10
+
+	movw	%ax, %bx
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	movzwl	%bx, %eax
+
+	popl	%ebx
+	popl	%ebp
+	ret
+
+		
+/*
+ * gateA20(int linear)
+ *
+ * Gate address-line 20 for high memory.
+ *
+ * This routine is probably overconservative in what it does, but so what?
+ *
+ * It also eats any keystrokes in the keyboard buffer.  :-(
+ */
+
+ENTRY(gateA20)
+	/* first, try a BIOS call */
+	pushl	%ebp
+	movl	8(%esp), %edx
+	
+	call	EXT_C(prot_to_real)
+	
+	.code16
+	movw	$0x2400, %ax
+	testw	%dx, %dx
+	jz	1f
+	incw	%ax
+1:	stc
+	int	$0x15
+	jnc	2f
+
+	/* set non-zero if failed */
+	movb	$1, %ah
+
+	/* save the status */
+2:	movb	%ah, %dl
+
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	popl	%ebp
+	testb	%dl, %dl
+	jnz	3f
+	ret
+
+3:	/* use keyboard controller */
+	pushl	%eax
+
+	call    gloop1
+
+	movb	$KC_CMD_WOUT, %al
+	outb	$K_CMD
+
+gloopint1:
+	inb	$K_STATUS
+	andb	$K_IBUF_FUL, %al
+	jnz	gloopint1
+
+	movb	$KB_OUTPUT_MASK, %al
+	cmpb	$0, 0x8(%esp)
+	jz	gdoit
+
+	orb	$KB_A20_ENABLE, %al
+gdoit:
+	outb	$K_RDWR
+
+	call	gloop1
+
+	/* output a dummy command (USB keyboard hack) */
+	movb	$0xff, %al
+	outb	$K_CMD
+	call	gloop1
+	
+	popl	%eax
+	ret
+
+gloop1:
+	inb	$K_STATUS
+	andb	$K_IBUF_FUL, %al
+	jnz	gloop1
+
+gloop2:
+	inb	$K_STATUS
+	andb	$K_OBUF_FUL, %al
+	jz	gloop2ret
+	inb	$K_RDWR
+	jmp	gloop2
+
+gloop2ret:
+	ret
+
+
+ENTRY(patch_code)	/* labels start with "pc_" */
+	.code16
+
+	mov	%cs, %ax
+	mov	%ax, %ds
+	mov	%ax, %es
+	mov	%ax, %fs
+	mov	%ax, %gs
+	ADDR32	movl	$0, 0
+pc_stop:
+	hlt
+	DATA32	jmp	pc_stop
+ENTRY(patch_code_end)
+
+	.code32
+
+
+/*
+ * linux_boot()
+ *
+ * Does some funky things (including on the stack!), then jumps to the
+ * entry point of the Linux setup code.
+ */
+
+VARIABLE(linux_text_len)
+	.long	0
+	
+VARIABLE(linux_data_tmp_addr)
+	.long	0
+	
+VARIABLE(linux_data_real_addr)
+	.long	0
+	
+ENTRY(linux_boot)
+	/* don't worry about saving anything, we're committed at this point */
+	cld	/* forward copying */
+
+	/* copy kernel */
+	movl	EXT_C(linux_text_len), %ecx
+	addl	$3, %ecx
+	shrl	$2, %ecx
+	movl	$LINUX_BZIMAGE_ADDR, %esi
+	movl	$LINUX_ZIMAGE_ADDR, %edi
+
+	rep
+	movsl
+
+ENTRY(big_linux_boot)
+	movl	EXT_C(linux_data_real_addr), %ebx
+	
+	/* copy the real mode part */
+	movl	EXT_C(linux_data_tmp_addr), %esi
+	movl	%ebx, %edi
+	movl	$LINUX_SETUP_MOVE_SIZE, %ecx
+	cld
+	rep
+	movsb
+
+	/* change %ebx to the segment address */
+	shrl	$4, %ebx
+	movl	%ebx, %eax
+	addl	$0x20, %eax
+	movl	%eax, linux_setup_seg
+			
+	/* XXX new stack pointer in safe area for calling functions */
+	movl	$0x4000, %esp
+	call	EXT_C(stop_floppy)
+
+	/* final setup for linux boot */
+
+	call	EXT_C(prot_to_real)
+	.code16
+
+	/* final setup for linux boot */
+	cli
+	movw	%bx, %ss
+	movw	$LINUX_SETUP_STACK, %sp
+	
+	movw	%bx, %ds
+	movw	%bx, %es
+	movw	%bx, %fs
+	movw	%bx, %gs
+
+	/* jump to start */
+	/* ljmp */
+	.byte	0xea
+	.word	0
+linux_setup_seg:	
+	.word	0
+	.code32
+
+
+/*
+ * multi_boot(int start, int mb_info)
+ *
+ *  This starts a kernel in the manner expected of the multiboot standard.
+ */
+
+ENTRY(multi_boot)
+	/* no need to save anything */
+	call	EXT_C(stop_floppy)
+
+	movl	$0x2BADB002, %eax
+	movl	0x8(%esp), %ebx
+
+	/* boot kernel here (absolute address call) */
+	call	*0x4(%esp)
+
+	/* error */
+	call	EXT_C(stop)
+
+#endif /* ! STAGE1_5 */
+	
+/*
+ * void console_putchar (int c)
+ *
+ * Put the character C on the console. Because GRUB wants to write a
+ * character with an attribute, this implementation is a bit tricky.
+ * If C is a control character (CR, LF, BEL, BS), use INT 10, AH = 0Eh
+ * (TELETYPE OUTPUT). Otherwise, save the original position, put a space,
+ * save the current position, restore the original position, write the
+ * character and the attribute, and restore the current position.
+ *
+ * The reason why this is so complicated is that there is no easy way to
+ * get the height of the screen, and the TELETYPE OUPUT BIOS call doesn't
+ * support setting a background attribute.
+ */
+ENTRY(console_putchar)
+	movl	0x4(%esp), %edx
+	pusha
+#ifdef STAGE1_5
+	movb	$0x07, %bl
+#else
+	movl	EXT_C(console_current_color), %ebx
+#endif
+	
+	call	EXT_C(prot_to_real)
+	.code16
+	movb	%dl, %al
+	xorb	%bh, %bh
+
+#ifndef STAGE1_5
+	/* use teletype output if control character */
+	cmpb	$0x7, %al
+	je	1f
+	cmpb	$0x8, %al
+	je	1f
+	cmpb	$0xa, %al
+	je	1f
+	cmpb	$0xd, %al
+	je	1f
+
+	/* save the character and the attribute on the stack */
+	pushw	%ax
+	pushw	%bx
+	
+	/* get the current position */
+	movb	$0x3, %ah
+	int	$0x10
+
+	/* check the column with the width */
+	cmpb	$79, %dl
+	jl	2f
+	
+	/* print CR and LF, if next write will exceed the width */	
+	movw	$0x0e0d, %ax
+	int	$0x10
+	movb	$0x0a, %al
+	int	$0x10
+	
+	/* get the current position */
+	movb	$0x3, %ah
+	int	$0x10
+
+2:	
+	/* restore the character and the attribute */
+	popw	%bx
+	popw	%ax
+	
+	/* write the character with the attribute */
+	movb	$0x9, %ah
+	movw	$1, %cx
+	int	$0x10
+
+	/* move the cursor forward */
+	incb	%dl
+	movb	$0x2, %ah
+	int	$0x10
+
+	jmp	3f
+#endif /* ! STAGE1_5 */
+	
+1:	movb	$0xe, %ah
+	int	$0x10
+	
+3:	DATA32	call	EXT_C(real_to_prot)
+	.code32
+	
+	popa
+	ret
+
+
+#ifndef STAGE1_5
+
+/* this table is used in translate_keycode below */
+translation_table:
+	.word	KEY_LEFT, 2
+	.word	KEY_RIGHT, 6
+	.word	KEY_UP, 16
+	.word	KEY_DOWN, 14
+	.word	KEY_HOME, 1
+	.word	KEY_END, 5
+	.word	KEY_DC, 4
+	.word	KEY_BACKSPACE, 8
+	.word	KEY_PPAGE, 7
+	.word	KEY_NPAGE, 3
+	.word	0
+	
+/*
+ * translate_keycode translates the key code %dx to an ascii code.
+ */
+	.code16
+
+translate_keycode:
+	pushw	%bx
+	pushw	%si
+	
+	movw	$ABS(translation_table), %si
+	
+1:	lodsw
+	/* check if this is the end */
+	testw	%ax, %ax
+	jz	2f
+	/* load the ascii code into %ax */
+	movw	%ax, %bx
+	lodsw
+	/* check if this matches the key code */
+	cmpw	%bx, %dx
+	jne	1b
+	/* translate %dx, if successful */
+	movw	%ax, %dx
+
+2:	popw	%si
+	popw	%bx
+	ret
+
+	.code32
+	
+
+/*
+ * remap_ascii_char remaps the ascii code %dl to another if the code is
+ * contained in ASCII_KEY_MAP.
+ */
+	.code16
+	
+remap_ascii_char:
+	pushw	%si
+	
+	movw	$ABS(EXT_C(ascii_key_map)), %si
+1:
+	lodsw
+	/* check if this is the end */
+	testw	%ax, %ax
+	jz	2f
+	/* check if this matches the ascii code */
+	cmpb	%al, %dl
+	jne	1b
+	/* if so, perform the mapping */
+	movb	%ah, %dl
+2:
+	/* restore %si */
+	popw	%si
+
+	ret
+
+	.code32
+
+	.align	4
+ENTRY(ascii_key_map)
+	.space	(KEY_MAP_SIZE + 1) * 2
+	
+
+/*
+ * int console_getkey (void)
+ * BIOS call "INT 16H Function 00H" to read character from keyboard
+ *	Call with	%ah = 0x0
+ *	Return:		%ah = keyboard scan code
+ *			%al = ASCII character
+ */
+
+ENTRY(console_getkey)
+	push	%ebp
+
+	call	EXT_C(prot_to_real)
+	.code16
+
+	int	$0x16
+
+	movw	%ax, %dx		/* real_to_prot uses %eax */
+	call	translate_keycode
+	call	remap_ascii_char
+	
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	movw	%dx, %ax
+
+	pop	%ebp
+	ret
+
+
+/*
+ * int console_checkkey (void)
+ *	if there is a character pending, return it; otherwise return -1
+ * BIOS call "INT 16H Function 01H" to check whether a character is pending
+ *	Call with	%ah = 0x1
+ *	Return:
+ *		If key waiting to be input:
+ *			%ah = keyboard scan code
+ *			%al = ASCII character
+ *			Zero flag = clear
+ *		else
+ *			Zero flag = set
+ */
+ENTRY(console_checkkey)
+	push	%ebp
+	xorl	%edx, %edx
+	
+	call	EXT_C(prot_to_real)	/* enter real mode */
+	.code16
+
+	movb	$0x1, %ah
+	int	$0x16
+
+	DATA32	jz	notpending
+	
+	movw	%ax, %dx
+	call	translate_keycode
+	call	remap_ascii_char
+	DATA32	jmp	pending
+
+notpending:
+	movl	$0xFFFFFFFF, %edx
+
+pending:
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	mov	%edx, %eax
+
+	pop	%ebp
+	ret
+
+	
+/*
+ * int console_getxy (void)
+ * BIOS call "INT 10H Function 03h" to get cursor position
+ *	Call with	%ah = 0x03
+ *			%bh = page
+ *      Returns         %ch = starting scan line
+ *                      %cl = ending scan line
+ *                      %dh = row (0 is top)
+ *                      %dl = column (0 is left)
+ */
+
+
+ENTRY(console_getxy)
+	push	%ebp
+	push	%ebx                    /* save EBX */
+
+	call	EXT_C(prot_to_real)
+	.code16
+
+        xorb	%bh, %bh                /* set page to 0 */
+	movb	$0x3, %ah
+	int	$0x10			/* get cursor position */
+
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	movb	%dl, %ah
+	movb	%dh, %al
+
+	pop	%ebx
+	pop	%ebp
+	ret
+
+
+/*
+ * void console_gotoxy(int x, int y)
+ * BIOS call "INT 10H Function 02h" to set cursor position
+ *	Call with	%ah = 0x02
+ *			%bh = page
+ *                      %dh = row (0 is top)
+ *                      %dl = column (0 is left)
+ */
+
+
+ENTRY(console_gotoxy)
+	push	%ebp
+	push	%ebx                    /* save EBX */
+
+	movb	0xc(%esp), %dl           /* %dl = x */
+	movb	0x10(%esp), %dh          /* %dh = y */
+
+	call	EXT_C(prot_to_real)
+	.code16
+
+        xorb	%bh, %bh                /* set page to 0 */
+	movb	$0x2, %ah
+	int	$0x10			/* set cursor position */
+
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	pop	%ebx
+	pop	%ebp
+	ret
+
+	
+/*
+ * void console_cls (void)
+ * BIOS call "INT 10H Function 09h" to write character and attribute
+ *	Call with	%ah = 0x09
+ *                      %al = (character)
+ *                      %bh = (page number)
+ *                      %bl = (attribute)
+ *                      %cx = (number of times)
+ */
+
+
+ENTRY(console_cls)
+	push	%ebp
+	push	%ebx                    /* save EBX */
+
+	call	EXT_C(prot_to_real)
+	.code16
+
+	/* move the cursor to the beginning */
+	movb	$0x02, %ah
+	xorb	%bh, %bh
+	xorw	%dx, %dx
+	int	$0x10
+
+	/* write spaces to the entire screen */
+	movw	$0x0920, %ax
+	movw	$0x07, %bx
+	movw	$(80 * 25), %cx
+        int	$0x10
+
+	/* move back the cursor */
+	movb	$0x02, %ah
+	int	$0x10
+
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	pop	%ebx
+	pop	%ebp
+	ret
+
+	
+/*
+ * int console_setcursor (int on)
+ * BIOS call "INT 10H Function 01h" to set cursor type
+ *      Call with       %ah = 0x01
+ *                      %ch = cursor starting scanline
+ *                      %cl = cursor ending scanline
+ */
+
+console_cursor_state:
+	.byte	1
+console_cursor_shape:
+	.word	0
+	
+ENTRY(console_setcursor)
+	push	%ebp
+	push	%ebx
+
+	/* check if the standard cursor shape has already been saved */
+	movw	console_cursor_shape, %ax
+	testw	%ax, %ax
+	jne	1f
+
+	call	EXT_C(prot_to_real)
+	.code16
+
+	movb	$0x03, %ah
+	xorb	%bh, %bh
+	int	$0x10
+
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	movw	%cx, console_cursor_shape
+1:
+	/* set %cx to the designated cursor shape */
+	movw	$0x2000, %cx
+	movl	0xc(%esp), %ebx
+	testl	%ebx, %ebx
+	jz	2f
+	movw	console_cursor_shape, %cx
+2:	
+	call	EXT_C(prot_to_real)
+	.code16
+
+	movb    $0x1, %ah
+	int     $0x10 
+
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	movzbl	console_cursor_state, %eax
+	movb	%bl, console_cursor_state
+	
+	pop	%ebx
+	pop	%ebp
+	ret
+		
+/*
+ * getrtsecs()
+ *	if a seconds value can be read, read it and return it (BCD),
+ *      otherwise return 0xFF
+ * BIOS call "INT 1AH Function 02H" to check whether a character is pending
+ *	Call with	%ah = 0x2
+ *	Return:
+ *		If RT Clock can give correct values
+ *			%ch = hour (BCD)
+ *			%cl = minutes (BCD)
+ *                      %dh = seconds (BCD)
+ *                      %dl = daylight savings time (00h std, 01h daylight)
+ *			Carry flag = clear
+ *		else
+ *			Carry flag = set
+ *                         (this indicates that the clock is updating, or
+ *                          that it isn't running)
+ */
+ENTRY(getrtsecs)
+	push	%ebp
+
+	call	EXT_C(prot_to_real)	/* enter real mode */
+	.code16
+
+	movb	$0x2, %ah
+	int	$0x1a
+
+	DATA32	jnc	gottime
+	movb	$0xff, %dh
+
+gottime:
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	movb	%dh, %al
+
+	pop	%ebp
+	ret
+
+	
+/*
+ * currticks()
+ *	return the real time in ticks, of which there are about
+ *	18-20 per second
+ */
+ENTRY(currticks)
+	pushl	%ebp
+
+	call	EXT_C(prot_to_real)	/* enter real mode */
+	.code16
+
+	/* %ax is already zero */
+        int	$0x1a
+
+	DATA32	call	EXT_C(real_to_prot)
+	.code32
+
+	movl	%ecx, %eax
+	shll	$16, %eax
+	movw	%dx, %ax
+
+	popl	%ebp
+	ret
+
+#endif /* STAGE1_5 */
+
+/*
+ *  This is the area for all of the special variables.
+ */
+
+	.p2align	2	/* force 4-byte alignment */
+
+protstack:
+	.long	PROTSTACKINIT
+
+VARIABLE(boot_drive)
+#ifdef SUPPORT_DISKLESS
+	.long	NETWORK_DRIVE
+#else
+	.long	0
+#endif
+
+VARIABLE(install_second_sector)
+	.long	0
+	
+	/* an address can only be long-jumped to if it is in memory, this
+	   is used by multiple routines */
+offset:
+	.long	0x8000
+segment:
+	.word	0
+
+VARIABLE(apm_bios_info)
+	.word	0	/* version */
+	.word	0	/* cseg */
+	.long	0	/* offset */
+	.word	0	/* cseg_16 */
+	.word	0	/* dseg_16 */
+	.word	0	/* cseg_len */
+	.word	0	/* cseg_16_len */
+	.word	0	/* dseg_16_len */
+	
+/*
+ * This is the Global Descriptor Table
+ *
+ *  An entry, a "Segment Descriptor", looks like this:
+ *
+ * 31          24         19   16                 7           0
+ * ------------------------------------------------------------
+ * |             | |B| |A|       | |   |1|0|E|W|A|            |
+ * | BASE 31..24 |G|/|0|V| LIMIT |P|DPL|  TYPE   | BASE 23:16 |
+ * |             | |D| |L| 19..16| |   |1|1|C|R|A|            |
+ * ------------------------------------------------------------
+ * |                             |                            |
+ * |        BASE 15..0           |       LIMIT 15..0          |
+ * |                             |                            |
+ * ------------------------------------------------------------
+ *
+ *  Note the ordering of the data items is reversed from the above
+ *  description.
+ */
+
+	.p2align	2	/* force 4-byte alignment */
+gdt:
+	.word	0, 0
+	.byte	0, 0, 0, 0
+
+	/* code segment */
+	.word	0xFFFF, 0
+	.byte	0, 0x9A, 0xCF, 0
+
+	/* data segment */
+	.word	0xFFFF, 0
+	.byte	0, 0x92, 0xCF, 0
+
+	/* 16 bit real mode CS */
+	.word	0xFFFF, 0
+	.byte	0, 0x9E, 0, 0
+
+	/* 16 bit real mode DS */
+	.word	0xFFFF, 0
+	.byte	0, 0x92, 0, 0
+
+
+/* this is the GDT descriptor */
+gdtdesc:
+	.word	0x27			/* limit */
+	.long	gdt			/* addr */
diff --git a/stage2/bios.c b/stage2/bios.c
new file mode 100644
index 0000000..2d85e40
--- /dev/null
+++ b/stage2/bios.c
@@ -0,0 +1,317 @@
+/* bios.c - implement C part of low-level BIOS disk input and output */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,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 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.
+ */
+
+#include "shared.h"
+
+
+/* These are defined in asm.S, and never be used elsewhere, so declare the
+   prototypes here.  */
+extern int biosdisk_int13_extensions (int ax, int drive, void *dap);
+extern int biosdisk_standard (int ah, int drive,
+			      int coff, int hoff, int soff,
+			      int nsec, int segment);
+extern int check_int13_extensions (int drive);
+extern int get_diskinfo_standard (int drive,
+				  unsigned long *cylinders,
+				  unsigned long *heads,
+				  unsigned long *sectors);
+#if 0
+extern int get_diskinfo_floppy (int drive,
+				unsigned long *cylinders,
+				unsigned long *heads,
+				unsigned long *sectors);
+#endif
+
+
+/* Read/write NSEC sectors starting from SECTOR in DRIVE disk with GEOMETRY
+   from/into SEGMENT segment. If READ is BIOSDISK_READ, then read it,
+   else if READ is BIOSDISK_WRITE, then write it. If an geometry error
+   occurs, return BIOSDISK_ERROR_GEOMETRY, and if other error occurs, then
+   return the error number. Otherwise, return 0.  */
+int
+biosdisk (int read, int drive, struct geometry *geometry,
+	  int sector, int nsec, int segment)
+{
+  int err;
+  
+  if (geometry->flags & BIOSDISK_FLAG_LBA_EXTENSION)
+    {
+      struct disk_address_packet
+      {
+	unsigned char length;
+	unsigned char reserved;
+	unsigned short blocks;
+	unsigned long buffer;
+	unsigned long long block;
+      } __attribute__ ((packed)) dap;
+
+      /* XXX: Don't check the geometry by default, because some buggy
+	 BIOSes don't return the number of total sectors correctly,
+	 even if they have working LBA support. Hell.  */
+#ifdef NO_BUGGY_BIOS_IN_THE_WORLD
+      if (sector >= geometry->total_sectors)
+	return BIOSDISK_ERROR_GEOMETRY;
+#endif /* NO_BUGGY_BIOS_IN_THE_WORLD */
+
+      /* FIXME: sizeof (DAP) must be 0x10. Should assert that the compiler
+	 can't add any padding.  */
+      dap.length = sizeof (dap);
+      dap.block = sector;
+      dap.blocks = nsec;
+      dap.reserved = 0;
+      /* This is undocumented part. The address is formated in
+	 SEGMENT:ADDRESS.  */
+      dap.buffer = segment << 16;
+      
+      err = biosdisk_int13_extensions ((read + 0x42) << 8, drive, &dap);
+
+/* #undef NO_INT13_FALLBACK */
+#ifndef NO_INT13_FALLBACK
+      if (err)
+	{
+	  if (geometry->flags & BIOSDISK_FLAG_CDROM)
+	    return err;
+	  
+	  geometry->flags &= ~BIOSDISK_FLAG_LBA_EXTENSION;
+	  geometry->total_sectors = (geometry->cylinders
+				     * geometry->heads
+				     * geometry->sectors);
+	  return biosdisk (read, drive, geometry, sector, nsec, segment);
+	}
+#endif /* ! NO_INT13_FALLBACK */
+      
+    }
+  else
+    {
+      int cylinder_offset, head_offset, sector_offset;
+      int head;
+
+      /* SECTOR_OFFSET is counted from one, while HEAD_OFFSET and
+	 CYLINDER_OFFSET are counted from zero.  */
+      sector_offset = sector % geometry->sectors + 1;
+      head = sector / geometry->sectors;
+      head_offset = head % geometry->heads;
+      cylinder_offset = head / geometry->heads;
+      
+      if (cylinder_offset >= geometry->cylinders)
+	return BIOSDISK_ERROR_GEOMETRY;
+
+      err = biosdisk_standard (read + 0x02, drive,
+			       cylinder_offset, head_offset, sector_offset,
+			       nsec, segment);
+    }
+
+  return err;
+}
+
+/* Check bootable CD-ROM emulation status.  */
+static int
+get_cdinfo (int drive, struct geometry *geometry)
+{
+  int err;
+  struct iso_spec_packet
+  {
+    unsigned char size;
+    unsigned char media_type;
+    unsigned char drive_no;
+    unsigned char controller_no;
+    unsigned long image_lba;
+    unsigned short device_spec;
+    unsigned short cache_seg;
+    unsigned short load_seg;
+    unsigned short length_sec512;
+    unsigned char cylinders;
+    unsigned char sectors;
+    unsigned char heads;
+    
+    unsigned char dummy[16];
+  } __attribute__ ((packed)) cdrp;
+  
+  grub_memset (&cdrp, 0, sizeof (cdrp));
+  cdrp.size = sizeof (cdrp) - sizeof (cdrp.dummy);
+  err = biosdisk_int13_extensions (0x4B01, drive, &cdrp);
+  if (! err && cdrp.drive_no == drive)
+    {
+      if ((cdrp.media_type & 0x0F) == 0)
+        {
+          /* No emulation bootable CD-ROM */
+          geometry->flags = BIOSDISK_FLAG_LBA_EXTENSION | BIOSDISK_FLAG_CDROM;
+          geometry->cylinders = 0;
+          geometry->heads = 1;
+          geometry->sectors = 15;
+          geometry->sector_size = 2048;
+          geometry->total_sectors = MAXINT;
+          return 1;
+        }
+      else
+        {
+	  /* Floppy or hard-disk emulation */
+          geometry->cylinders
+	    = ((unsigned int) cdrp.cylinders
+	       + (((unsigned int) (cdrp.sectors & 0xC0)) << 2));
+          geometry->heads = cdrp.heads;
+          geometry->sectors = cdrp.sectors & 0x3F;
+          geometry->sector_size = SECTOR_SIZE;
+          geometry->total_sectors = (geometry->cylinders
+				     * geometry->heads
+				     * geometry->sectors);
+          return -1;
+        }
+    }
+  return 0;
+}
+
+/* Return the geometry of DRIVE in GEOMETRY. If an error occurs, return
+   non-zero, otherwise zero.  */
+int
+get_diskinfo (int drive, struct geometry *geometry)
+{
+  int err;
+
+  /* Clear the flags.  */
+  geometry->flags = 0;
+  
+  if (drive & 0x80)
+    {
+      /* hard disk or CD-ROM */
+      int version;
+      unsigned long total_sectors = 0;
+      
+      version = check_int13_extensions (drive);
+
+      if (drive >= 0x88 || version)
+	{
+	  /* Possible CD-ROM - check the status.  */
+	  if (get_cdinfo (drive, geometry))
+	    return 0;
+	}
+      
+      if (version)
+	{
+	  struct drive_parameters
+	  {
+	    unsigned short size;
+	    unsigned short flags;
+	    unsigned long cylinders;
+	    unsigned long heads;
+	    unsigned long sectors;
+	    unsigned long long total_sectors;
+	    unsigned short bytes_per_sector;
+	    /* ver 2.0 or higher */
+	    unsigned long EDD_configuration_parameters;
+	    /* ver 3.0 or higher */
+	    unsigned short signature_dpi;
+	    unsigned char length_dpi;
+	    unsigned char reserved[3];
+	    unsigned char name_of_host_bus[4];
+	    unsigned char name_of_interface_type[8];
+	    unsigned char interface_path[8];
+	    unsigned char device_path[8];
+	    unsigned char reserved2;
+	    unsigned char checksum;
+
+	    /* XXX: This is necessary, because the BIOS of Thinkpad X20
+	       writes a garbage to the tail of drive parameters,
+	       regardless of a size specified in a caller.  */
+	    unsigned char dummy[16];
+	  } __attribute__ ((packed)) drp;
+
+	  /* It is safe to clear out DRP.  */
+	  grub_memset (&drp, 0, sizeof (drp));
+	  
+	  /* PhoenixBIOS 4.0 Revision 6.0 for ZF Micro might understand 
+	     the greater buffer size for the "get drive parameters" int 
+	     0x13 call in its own way.  Supposedly the BIOS assumes even 
+	     bigger space is available and thus corrupts the stack.  
+	     This is why we specify the exactly necessary size of 0x42 
+	     bytes. */
+	  drp.size = sizeof (drp) - sizeof (drp.dummy);
+	  
+	  err = biosdisk_int13_extensions (0x4800, drive, &drp);
+	  if (! err)
+	    {
+	      /* Set the LBA flag.  */
+	      geometry->flags = BIOSDISK_FLAG_LBA_EXTENSION;
+
+	      /* I'm not sure if GRUB should check the bit 1 of DRP.FLAGS,
+		 so I omit the check for now. - okuji  */
+	      /* if (drp.flags & (1 << 1)) */
+	       
+	      /* FIXME: when the 2TB limit becomes critical, we must
+		 change the type of TOTAL_SECTORS to unsigned long
+		 long.  */
+	      if (drp.total_sectors)
+		total_sectors = drp.total_sectors & ~0L;
+	      else
+		/* Some buggy BIOSes doesn't return the total sectors
+		   correctly but returns zero. So if it is zero, compute
+		   it by C/H/S returned by the LBA BIOS call.  */
+		total_sectors = drp.cylinders * drp.heads * drp.sectors;
+	    }
+	}
+
+      /* Don't pass GEOMETRY directly, but pass each element instead,
+	 so that we can change the structure easily.  */
+      err = get_diskinfo_standard (drive,
+				   &geometry->cylinders,
+				   &geometry->heads,
+				   &geometry->sectors);
+      if (err)
+	return err;
+
+      if (! total_sectors)
+	{
+	  total_sectors = (geometry->cylinders
+			   * geometry->heads
+			   * geometry->sectors);
+	}
+      geometry->total_sectors = total_sectors;
+      geometry->sector_size = SECTOR_SIZE;
+    }
+  else
+    {
+      /* floppy disk */
+
+      /* First, try INT 13 AH=8h call.  */
+      err = get_diskinfo_standard (drive,
+				   &geometry->cylinders,
+				   &geometry->heads,
+				   &geometry->sectors);
+
+#if 0
+      /* If fails, then try floppy-specific probe routine.  */
+      if (err)
+	err = get_diskinfo_floppy (drive,
+				   &geometry->cylinders,
+				   &geometry->heads,
+				   &geometry->sectors);
+#endif
+      
+      if (err)
+	return err;
+
+      geometry->total_sectors = (geometry->cylinders
+				 * geometry->heads
+				 * geometry->sectors);
+      geometry->sector_size = SECTOR_SIZE;
+    }
+
+  return 0;
+}
diff --git a/stage2/boot.c b/stage2/boot.c
new file mode 100644
index 0000000..4185d23
--- /dev/null
+++ b/stage2/boot.c
@@ -0,0 +1,1020 @@
+/* boot.c - load and bootstrap a kernel */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  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 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.
+ */
+
+
+#include "shared.h"
+
+#include "freebsd.h"
+#include "imgact_aout.h"
+#include "i386-elf.h"
+
+static int cur_addr;
+entry_func entry_addr;
+static struct mod_list mll[99];
+static int linux_mem_size;
+
+/*
+ *  The next two functions, 'load_image' and 'load_module', are the building
+ *  blocks of the multiboot loader component.  They handle essentially all
+ *  of the gory details of loading in a bootable image and the modules.
+ */
+
+kernel_t
+load_image (char *kernel, char *arg, kernel_t suggested_type,
+	    unsigned long load_flags)
+{
+  int len, i, exec_type = 0, align_4k = 1;
+  entry_func real_entry_addr = 0;
+  kernel_t type = KERNEL_TYPE_NONE;
+  unsigned long flags = 0, text_len = 0, data_len = 0, bss_len = 0;
+  char *str = 0, *str2 = 0;
+  struct linux_kernel_header *lh;
+  union
+    {
+      struct multiboot_header *mb;
+      struct exec *aout;
+      Elf32_Ehdr *elf;
+    }
+  pu;
+  /* presuming that MULTIBOOT_SEARCH is large enough to encompass an
+     executable header */
+  unsigned char buffer[MULTIBOOT_SEARCH];
+
+  /* sets the header pointer to point to the beginning of the
+     buffer by default */
+  pu.aout = (struct exec *) buffer;
+
+  if (!grub_open (kernel))
+    return KERNEL_TYPE_NONE;
+
+  if (!(len = grub_read (buffer, MULTIBOOT_SEARCH)) || len < 32)
+    {
+      grub_close ();
+      
+      if (!errnum)
+	errnum = ERR_EXEC_FORMAT;
+
+      return KERNEL_TYPE_NONE;
+    }
+
+  for (i = 0; i < len; i++)
+    {
+      if (MULTIBOOT_FOUND ((int) (buffer + i), len - i))
+	{
+	  flags = ((struct multiboot_header *) (buffer + i))->flags;
+	  if (flags & MULTIBOOT_UNSUPPORTED)
+	    {
+	      grub_close ();
+	      errnum = ERR_BOOT_FEATURES;
+	      return KERNEL_TYPE_NONE;
+	    }
+	  type = KERNEL_TYPE_MULTIBOOT;
+	  str2 = "Multiboot";
+	  break;
+	}
+    }
+
+  /* Use BUFFER as a linux kernel header, if the image is Linux zImage
+     or bzImage.  */
+  lh = (struct linux_kernel_header *) buffer;
+  
+  /* ELF loading supported if multiboot, FreeBSD and NetBSD.  */
+  if ((type == KERNEL_TYPE_MULTIBOOT
+       || pu.elf->e_ident[EI_OSABI] == ELFOSABI_FREEBSD
+       || grub_strcmp (pu.elf->e_ident + EI_BRAND, "FreeBSD") == 0
+       || suggested_type == KERNEL_TYPE_NETBSD)
+      && len > sizeof (Elf32_Ehdr)
+      && BOOTABLE_I386_ELF ((*((Elf32_Ehdr *) buffer))))
+    {
+      if (type == KERNEL_TYPE_MULTIBOOT)
+	entry_addr = (entry_func) pu.elf->e_entry;
+      else
+	entry_addr = (entry_func) (pu.elf->e_entry & 0xFFFFFF);
+
+      if (entry_addr < (entry_func) 0x100000)
+	errnum = ERR_BELOW_1MB;
+
+      /* don't want to deal with ELF program header at some random
+         place in the file -- this generally won't happen */
+      if (pu.elf->e_phoff == 0 || pu.elf->e_phnum == 0
+	  || ((pu.elf->e_phoff + (pu.elf->e_phentsize * pu.elf->e_phnum))
+	      >= len))
+	errnum = ERR_EXEC_FORMAT;
+      str = "elf";
+
+      if (type == KERNEL_TYPE_NONE)
+	{
+	  /* At the moment, there is no way to identify a NetBSD ELF
+	     kernel, so rely on the suggested type by the user.  */
+	  if (suggested_type == KERNEL_TYPE_NETBSD)
+	    {
+	      str2 = "NetBSD";
+	      type = suggested_type;
+	    }
+	  else
+	    {
+	      str2 = "FreeBSD";
+	      type = KERNEL_TYPE_FREEBSD;
+	    }
+	}
+    }
+  else if (flags & MULTIBOOT_AOUT_KLUDGE)
+    {
+      pu.mb = (struct multiboot_header *) (buffer + i);
+      entry_addr = (entry_func) pu.mb->entry_addr;
+      cur_addr = pu.mb->load_addr;
+      /* first offset into file */
+      grub_seek (i - (pu.mb->header_addr - cur_addr));
+
+      /* If the load end address is zero, load the whole contents.  */
+      if (! pu.mb->load_end_addr)
+	pu.mb->load_end_addr = cur_addr + filemax;
+      
+      text_len = pu.mb->load_end_addr - cur_addr;
+      data_len = 0;
+
+      /* If the bss end address is zero, assume that there is no bss area.  */
+      if (! pu.mb->bss_end_addr)
+	pu.mb->bss_end_addr = pu.mb->load_end_addr;
+      
+      bss_len = pu.mb->bss_end_addr - pu.mb->load_end_addr;
+
+      if (pu.mb->header_addr < pu.mb->load_addr
+	  || pu.mb->load_end_addr <= pu.mb->load_addr
+	  || pu.mb->bss_end_addr < pu.mb->load_end_addr
+	  || (pu.mb->header_addr - pu.mb->load_addr) > i)
+	errnum = ERR_EXEC_FORMAT;
+
+      if (cur_addr < 0x100000)
+	errnum = ERR_BELOW_1MB;
+
+      pu.aout = (struct exec *) buffer;
+      exec_type = 2;
+      str = "kludge";
+    }
+  else if (len > sizeof (struct exec) && !N_BADMAG ((*(pu.aout))))
+    {
+      entry_addr = (entry_func) pu.aout->a_entry;
+
+      if (type == KERNEL_TYPE_NONE)
+	{
+	  /*
+	   *  If it doesn't have a Multiboot header, then presume
+	   *  it is either a FreeBSD or NetBSD executable.  If so,
+	   *  then use a magic number of normal ordering, ZMAGIC to
+	   *  determine if it is FreeBSD.
+	   *
+	   *  This is all because freebsd and netbsd seem to require
+	   *  masking out some address bits...  differently for each
+	   *  one...  plus of course we need to know which booting
+	   *  method to use.
+	   */
+	  entry_addr = (entry_func) ((int) entry_addr & 0xFFFFFF);
+	  
+	  if (buffer[0] == 0xb && buffer[1] == 1)
+	    {
+	      type = KERNEL_TYPE_FREEBSD;
+	      cur_addr = (int) entry_addr;
+	      str2 = "FreeBSD";
+	    }
+	  else
+	    {
+	      type = KERNEL_TYPE_NETBSD;
+	      cur_addr = (int) entry_addr & 0xF00000;
+	      if (N_GETMAGIC ((*(pu.aout))) != NMAGIC)
+		align_4k = 0;
+	      str2 = "NetBSD";
+	    }
+	}
+
+      /* first offset into file */
+      grub_seek (N_TXTOFF (*(pu.aout)));
+      text_len = pu.aout->a_text;
+      data_len = pu.aout->a_data;
+      bss_len = pu.aout->a_bss;
+
+      if (cur_addr < 0x100000)
+	errnum = ERR_BELOW_1MB;
+
+      exec_type = 1;
+      str = "a.out";
+    }
+  else if (lh->boot_flag == BOOTSEC_SIGNATURE
+	   && lh->setup_sects <= LINUX_MAX_SETUP_SECTS)
+    {
+      int big_linux = 0;
+      int setup_sects = lh->setup_sects;
+
+      if (lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0200)
+	{
+	  big_linux = (lh->loadflags & LINUX_FLAG_BIG_KERNEL);
+	  lh->type_of_loader = LINUX_BOOT_LOADER_TYPE;
+
+	  /* Put the real mode part at as a high location as possible.  */
+	  linux_data_real_addr
+	    = (char *) ((mbi.mem_lower << 10) - LINUX_SETUP_MOVE_SIZE);
+	  /* But it must not exceed the traditional area.  */
+	  if (linux_data_real_addr > (char *) LINUX_OLD_REAL_MODE_ADDR)
+	    linux_data_real_addr = (char *) LINUX_OLD_REAL_MODE_ADDR;
+
+	  if (lh->version >= 0x0201)
+	    {
+	      lh->heap_end_ptr = LINUX_HEAP_END_OFFSET;
+	      lh->loadflags |= LINUX_FLAG_CAN_USE_HEAP;
+	    }
+
+	  if (lh->version >= 0x0202)
+	    lh->cmd_line_ptr = linux_data_real_addr + LINUX_CL_OFFSET;
+	  else
+	    {
+	      lh->cl_magic = LINUX_CL_MAGIC;
+	      lh->cl_offset = LINUX_CL_OFFSET;
+	      lh->setup_move_size = LINUX_SETUP_MOVE_SIZE;
+	    }
+	}
+      else
+	{
+	  /* Your kernel is quite old...  */
+	  lh->cl_magic = LINUX_CL_MAGIC;
+	  lh->cl_offset = LINUX_CL_OFFSET;
+	  
+	  setup_sects = LINUX_DEFAULT_SETUP_SECTS;
+
+	  linux_data_real_addr = (char *) LINUX_OLD_REAL_MODE_ADDR;
+	}
+      
+      /* If SETUP_SECTS is not set, set it to the default (4).  */
+      if (! setup_sects)
+	setup_sects = LINUX_DEFAULT_SETUP_SECTS;
+
+      data_len = setup_sects << 9;
+      text_len = filemax - data_len - SECTOR_SIZE;
+
+      linux_data_tmp_addr = (char *) LINUX_BZIMAGE_ADDR + text_len;
+      
+      if (! big_linux
+	  && text_len > linux_data_real_addr - (char *) LINUX_ZIMAGE_ADDR)
+	{
+	  grub_printf (" linux 'zImage' kernel too big, try 'make bzImage'\n");
+	  errnum = ERR_WONT_FIT;
+	}
+      else if (linux_data_real_addr + LINUX_SETUP_MOVE_SIZE
+	       > RAW_ADDR ((char *) (mbi.mem_lower << 10)))
+	errnum = ERR_WONT_FIT;
+      else
+	{
+	  grub_printf ("   [Linux-%s, setup=0x%x, size=0x%x]\n",
+		       (big_linux ? "bzImage" : "zImage"), data_len, text_len);
+
+	  /* Video mode selection support. What a mess!  */
+	  /* NOTE: Even the word "mess" is not still enough to
+	     represent how wrong and bad the Linux video support is,
+	     but I don't want to hear complaints from Linux fanatics
+	     any more. -okuji  */
+	  {
+	    char *vga;
+	
+	    /* Find the substring "vga=".  */
+	    vga = grub_strstr (arg, "vga=");
+	    if (vga)
+	      {
+		char *value = vga + 4;
+		int vid_mode;
+	    
+		/* Handle special strings.  */
+		if (substring ("normal", value) < 1)
+		  vid_mode = LINUX_VID_MODE_NORMAL;
+		else if (substring ("ext", value) < 1)
+		  vid_mode = LINUX_VID_MODE_EXTENDED;
+		else if (substring ("ask", value) < 1)
+		  vid_mode = LINUX_VID_MODE_ASK;
+		else if (safe_parse_maxint (&value, &vid_mode))
+		  ;
+		else
+		  {
+		    /* ERRNUM is already set inside the function
+		       safe_parse_maxint.  */
+		    grub_close ();
+		    return KERNEL_TYPE_NONE;
+		  }
+	    
+		lh->vid_mode = vid_mode;
+	      }
+	  }
+
+	  /* Check the mem= option to limit memory used for initrd.  */
+	  {
+	    char *mem;
+	
+	    mem = grub_strstr (arg, "mem=");
+	    if (mem)
+	      {
+		char *value = mem + 4;
+	    
+		safe_parse_maxint (&value, &linux_mem_size);
+		switch (errnum)
+		  {
+		  case ERR_NUMBER_OVERFLOW:
+		    /* If an overflow occurs, use the maximum address for
+		       initrd instead. This is good, because MAXINT is
+		       greater than LINUX_INITRD_MAX_ADDRESS.  */
+		    linux_mem_size = LINUX_INITRD_MAX_ADDRESS;
+		    errnum = ERR_NONE;
+		    break;
+		
+		  case ERR_NONE:
+		    {
+		      int shift = 0;
+		  
+		      switch (grub_tolower (*value))
+			{
+			case 'g':
+			  shift += 10;
+			case 'm':
+			  shift += 10;
+			case 'k':
+			  shift += 10;
+			default:
+			  break;
+			}
+		  
+		      /* Check an overflow.  */
+		      if (linux_mem_size > (MAXINT >> shift))
+			linux_mem_size = LINUX_INITRD_MAX_ADDRESS;
+		      else
+			linux_mem_size <<= shift;
+		    }
+		    break;
+		
+		  default:
+		    linux_mem_size = 0;
+		    errnum = ERR_NONE;
+		    break;
+		  }
+	      }
+	    else
+	      linux_mem_size = 0;
+	  }
+      
+	  /* It is possible that DATA_LEN + SECTOR_SIZE is greater than
+	     MULTIBOOT_SEARCH, so the data may have been read partially.  */
+	  if (data_len + SECTOR_SIZE <= MULTIBOOT_SEARCH)
+	    grub_memmove (linux_data_tmp_addr, buffer,
+			  data_len + SECTOR_SIZE);
+	  else
+	    {
+	      grub_memmove (linux_data_tmp_addr, buffer, MULTIBOOT_SEARCH);
+	      grub_read (linux_data_tmp_addr + MULTIBOOT_SEARCH,
+			 data_len + SECTOR_SIZE - MULTIBOOT_SEARCH);
+	    }
+	  
+	  if (lh->header != LINUX_MAGIC_SIGNATURE ||
+	      lh->version < 0x0200)
+	    /* Clear the heap space.  */
+	    grub_memset (linux_data_tmp_addr + ((setup_sects + 1) << 9),
+			 0,
+			 (64 - setup_sects - 1) << 9);
+      
+	  /* Copy command-line plus memory hack to staging area.
+	     NOTE: Linux has a bug that it doesn't handle multiple spaces
+	     between two options and a space after a "mem=" option isn't
+	     removed correctly so the arguments to init could be like
+	     {"init", "", "", NULL}. This affects some not-very-clever
+	     shells. Thus, the code below does a trick to avoid the bug.
+	     That is, copy "mem=XXX" to the end of the command-line, and
+	     avoid to copy spaces unnecessarily. Hell.  */
+	  {
+	    char *src = skip_to (0, arg);
+	    char *dest = linux_data_tmp_addr + LINUX_CL_OFFSET;
+	
+	    while (dest < linux_data_tmp_addr + LINUX_CL_END_OFFSET && *src)
+	      *(dest++) = *(src++);
+	
+	    /* Old Linux kernels have problems determining the amount of
+	       the available memory.  To work around this problem, we add
+	       the "mem" option to the kernel command line.  This has its
+	       own drawbacks because newer kernels can determine the
+	       memory map more accurately.  Boot protocol 2.03, which
+	       appeared in Linux 2.4.18, provides a pointer to the kernel
+	       version string, so we could check it.  But since kernel
+	       2.4.18 and newer are known to detect memory reliably, boot
+	       protocol 2.03 already implies that the kernel is new
+	       enough.  The "mem" option is added if neither of the
+	       following conditions is met:
+	       1) The "mem" option is already present.
+	       2) The "kernel" command is used with "--no-mem-option".
+	       3) GNU GRUB is configured not to pass the "mem" option.
+	       4) The kernel supports boot protocol 2.03 or newer.  */
+	    if (! grub_strstr (arg, "mem=")
+		&& ! (load_flags & KERNEL_LOAD_NO_MEM_OPTION)
+		&& lh->version < 0x0203		/* kernel version < 2.4.18 */
+		&& dest + 15 < linux_data_tmp_addr + LINUX_CL_END_OFFSET)
+	      {
+		*dest++ = ' ';
+		*dest++ = 'm';
+		*dest++ = 'e';
+		*dest++ = 'm';
+		*dest++ = '=';
+	    
+		dest = convert_to_ascii (dest, 'u', (extended_memory + 0x400));
+		*dest++ = 'K';
+	      }
+	
+	    *dest = 0;
+	  }
+      
+	  /* offset into file */
+	  grub_seek (data_len + SECTOR_SIZE);
+      
+	  cur_addr = (int) linux_data_tmp_addr + LINUX_SETUP_MOVE_SIZE;
+	  grub_read ((char *) LINUX_BZIMAGE_ADDR, text_len);
+      
+	  if (errnum == ERR_NONE)
+	    {
+	      grub_close ();
+	  
+	      /* Sanity check.  */
+	      if (suggested_type != KERNEL_TYPE_NONE
+		  && ((big_linux && suggested_type != KERNEL_TYPE_BIG_LINUX)
+		      || (! big_linux && suggested_type != KERNEL_TYPE_LINUX)))
+		{
+		  errnum = ERR_EXEC_FORMAT;
+		  return KERNEL_TYPE_NONE;
+		}
+	  
+	      /* Ugly hack.  */
+	      linux_text_len = text_len;
+	  
+	      return big_linux ? KERNEL_TYPE_BIG_LINUX : KERNEL_TYPE_LINUX;
+	    }
+	}
+    }
+  else				/* no recognizable format */
+    errnum = ERR_EXEC_FORMAT;
+
+  /* return if error */
+  if (errnum)
+    {
+      grub_close ();
+      return KERNEL_TYPE_NONE;
+    }
+
+  /* fill the multiboot info structure */
+  mbi.cmdline = (int) arg;
+  mbi.mods_count = 0;
+  mbi.mods_addr = 0;
+  mbi.boot_device = (current_drive << 24) | current_partition;
+  mbi.flags &= ~(MB_INFO_MODS | MB_INFO_AOUT_SYMS | MB_INFO_ELF_SHDR);
+  mbi.syms.a.tabsize = 0;
+  mbi.syms.a.strsize = 0;
+  mbi.syms.a.addr = 0;
+  mbi.syms.a.pad = 0;
+
+  printf ("   [%s-%s", str2, str);
+
+  str = "";
+
+  if (exec_type)		/* can be loaded like a.out */
+    {
+      if (flags & MULTIBOOT_AOUT_KLUDGE)
+	str = "-and-data";
+
+      printf (", loadaddr=0x%x, text%s=0x%x", cur_addr, str, text_len);
+
+      /* read text, then read data */
+      if (grub_read ((char *) RAW_ADDR (cur_addr), text_len) == text_len)
+	{
+	  cur_addr += text_len;
+
+	  if (!(flags & MULTIBOOT_AOUT_KLUDGE))
+	    {
+	      /* we have to align to a 4K boundary */
+	      if (align_4k)
+		cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000;
+	      else
+		printf (", C");
+
+	      printf (", data=0x%x", data_len);
+
+	      if ((grub_read ((char *) RAW_ADDR (cur_addr), data_len)
+		   != data_len)
+		  && !errnum)
+		errnum = ERR_EXEC_FORMAT;
+	      cur_addr += data_len;
+	    }
+
+	  if (!errnum)
+	    {
+	      memset ((char *) RAW_ADDR (cur_addr), 0, bss_len);
+	      cur_addr += bss_len;
+
+	      printf (", bss=0x%x", bss_len);
+	    }
+	}
+      else if (!errnum)
+	errnum = ERR_EXEC_FORMAT;
+
+      if (!errnum && pu.aout->a_syms
+	  && pu.aout->a_syms < (filemax - filepos))
+	{
+	  int symtab_err, orig_addr = cur_addr;
+
+	  /* we should align to a 4K boundary here for good measure */
+	  if (align_4k)
+	    cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000;
+
+	  mbi.syms.a.addr = cur_addr;
+
+	  *((int *) RAW_ADDR (cur_addr)) = pu.aout->a_syms;
+	  cur_addr += sizeof (int);
+	  
+	  printf (", symtab=0x%x", pu.aout->a_syms);
+
+	  if (grub_read ((char *) RAW_ADDR (cur_addr), pu.aout->a_syms)
+	      == pu.aout->a_syms)
+	    {
+	      cur_addr += pu.aout->a_syms;
+	      mbi.syms.a.tabsize = pu.aout->a_syms;
+
+	      if (grub_read ((char *) &i, sizeof (int)) == sizeof (int))
+		{
+		  *((int *) RAW_ADDR (cur_addr)) = i;
+		  cur_addr += sizeof (int);
+
+		  mbi.syms.a.strsize = i;
+
+		  i -= sizeof (int);
+
+		  printf (", strtab=0x%x", i);
+
+		  symtab_err = (grub_read ((char *) RAW_ADDR (cur_addr), i)
+				!= i);
+		  cur_addr += i;
+		}
+	      else
+		symtab_err = 1;
+	    }
+	  else
+	    symtab_err = 1;
+
+	  if (symtab_err)
+	    {
+	      printf ("(bad)");
+	      cur_addr = orig_addr;
+	      mbi.syms.a.tabsize = 0;
+	      mbi.syms.a.strsize = 0;
+	      mbi.syms.a.addr = 0;
+	    }
+	  else
+	    mbi.flags |= MB_INFO_AOUT_SYMS;
+	}
+    }
+  else
+    /* ELF executable */
+    {
+      unsigned loaded = 0, memaddr, memsiz, filesiz;
+      Elf32_Phdr *phdr;
+
+      /* reset this to zero for now */
+      cur_addr = 0;
+
+      /* scan for program segments */
+      for (i = 0; i < pu.elf->e_phnum; i++)
+	{
+	  phdr = (Elf32_Phdr *)
+	    (pu.elf->e_phoff + ((int) buffer)
+	     + (pu.elf->e_phentsize * i));
+	  if (phdr->p_type == PT_LOAD)
+	    {
+	      /* offset into file */
+	      grub_seek (phdr->p_offset);
+	      filesiz = phdr->p_filesz;
+	      
+	      if (type == KERNEL_TYPE_FREEBSD || type == KERNEL_TYPE_NETBSD)
+		memaddr = RAW_ADDR (phdr->p_paddr & 0xFFFFFF);
+	      else
+		memaddr = RAW_ADDR (phdr->p_paddr);
+	      
+	      memsiz = phdr->p_memsz;
+	      if (memaddr < RAW_ADDR (0x100000))
+		errnum = ERR_BELOW_1MB;
+
+	      /* If the memory range contains the entry address, get the
+		 physical address here.  */
+	      if (type == KERNEL_TYPE_MULTIBOOT
+		  && (unsigned) entry_addr >= phdr->p_vaddr
+		  && (unsigned) entry_addr < phdr->p_vaddr + memsiz)
+		real_entry_addr = (entry_func) ((unsigned) entry_addr
+						+ memaddr - phdr->p_vaddr);
+		
+	      /* make sure we only load what we're supposed to! */
+	      if (filesiz > memsiz)
+		filesiz = memsiz;
+	      /* mark memory as used */
+	      if (cur_addr < memaddr + memsiz)
+		cur_addr = memaddr + memsiz;
+	      printf (", <0x%x:0x%x:0x%x>", memaddr, filesiz,
+		      memsiz - filesiz);
+	      /* increment number of segments */
+	      loaded++;
+
+	      /* load the segment */
+	      if (memcheck (memaddr, memsiz)
+		  && grub_read ((char *) memaddr, filesiz) == filesiz)
+		{
+		  if (memsiz > filesiz)
+		    memset ((char *) (memaddr + filesiz), 0, memsiz - filesiz);
+		}
+	      else
+		break;
+	    }
+	}
+
+      if (! errnum)
+	{
+	  if (! loaded)
+	    errnum = ERR_EXEC_FORMAT;
+	  else
+	    {
+	      /* Load ELF symbols.  */
+	      Elf32_Shdr *shdr = NULL;
+	      int tab_size, sec_size;
+	      int symtab_err = 0;
+
+	      mbi.syms.e.num = pu.elf->e_shnum;
+	      mbi.syms.e.size = pu.elf->e_shentsize;
+	      mbi.syms.e.shndx = pu.elf->e_shstrndx;
+	      
+	      /* We should align to a 4K boundary here for good measure.  */
+	      if (align_4k)
+		cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000;
+	      
+	      tab_size = pu.elf->e_shentsize * pu.elf->e_shnum;
+	      
+	      grub_seek (pu.elf->e_shoff);
+	      if (grub_read ((char *) RAW_ADDR (cur_addr), tab_size)
+		  == tab_size)
+		{
+		  mbi.syms.e.addr = cur_addr;
+		  shdr = (Elf32_Shdr *) mbi.syms.e.addr;
+		  cur_addr += tab_size;
+		  
+		  printf (", shtab=0x%x", cur_addr);
+  		  
+		  for (i = 0; i < mbi.syms.e.num; i++)
+		    {
+		      /* This section is a loaded section,
+			 so we don't care.  */
+		      if (shdr[i].sh_addr != 0)
+			continue;
+		      
+		      /* This section is empty, so we don't care.  */
+		      if (shdr[i].sh_size == 0)
+			continue;
+		      
+		      /* Align the section to a sh_addralign bits boundary.  */
+		      cur_addr = ((cur_addr + shdr[i].sh_addralign) & 
+				  - (int) shdr[i].sh_addralign);
+		      
+		      grub_seek (shdr[i].sh_offset);
+		      
+		      sec_size = shdr[i].sh_size;
+
+		      if (! (memcheck (cur_addr, sec_size)
+			     && (grub_read ((char *) RAW_ADDR (cur_addr),
+					    sec_size)
+				 == sec_size)))
+			{
+			  symtab_err = 1;
+			  break;
+			}
+		      
+		      shdr[i].sh_addr = cur_addr;
+		      cur_addr += sec_size;
+		    }
+		}
+	      else 
+		symtab_err = 1;
+	      
+	      if (mbi.syms.e.addr < RAW_ADDR(0x10000))
+		symtab_err = 1;
+	      
+	      if (symtab_err) 
+		{
+		  printf ("(bad)");
+		  mbi.syms.e.num = 0;
+		  mbi.syms.e.size = 0;
+		  mbi.syms.e.addr = 0;
+		  mbi.syms.e.shndx = 0;
+		  cur_addr = 0;
+		}
+	      else
+		mbi.flags |= MB_INFO_ELF_SHDR;
+	    }
+	}
+    }
+
+  if (! errnum)
+    {
+      grub_printf (", entry=0x%x]\n", (unsigned) entry_addr);
+      
+      /* If the entry address is physically different from that of the ELF
+	 header, correct it here.  */
+      if (real_entry_addr)
+	entry_addr = real_entry_addr;
+    }
+  else
+    {
+      putchar ('\n');
+      type = KERNEL_TYPE_NONE;
+    }
+
+  grub_close ();
+
+  /* Sanity check.  */
+  if (suggested_type != KERNEL_TYPE_NONE && suggested_type != type)
+    {
+      errnum = ERR_EXEC_FORMAT;
+      return KERNEL_TYPE_NONE;
+    }
+  
+  return type;
+}
+
+int
+load_module (char *module, char *arg)
+{
+  int len;
+
+  /* if we are supposed to load on 4K boundaries */
+  cur_addr = (cur_addr + 0xFFF) & 0xFFFFF000;
+
+  if (!grub_open (module))
+    return 0;
+
+  len = grub_read ((char *) cur_addr, -1);
+  if (! len)
+    {
+      grub_close ();
+      return 0;
+    }
+
+  printf ("   [Multiboot-module @ 0x%x, 0x%x bytes]\n", cur_addr, len);
+
+  /* these two simply need to be set if any modules are loaded at all */
+  mbi.flags |= MB_INFO_MODS;
+  mbi.mods_addr = (int) mll;
+
+  mll[mbi.mods_count].cmdline = (int) arg;
+  mll[mbi.mods_count].mod_start = cur_addr;
+  cur_addr += len;
+  mll[mbi.mods_count].mod_end = cur_addr;
+  mll[mbi.mods_count].pad = 0;
+
+  /* increment number of modules included */
+  mbi.mods_count++;
+
+  grub_close ();
+  return 1;
+}
+
+int
+load_initrd (char *initrd)
+{
+  int len;
+  unsigned long moveto;
+  unsigned long max_addr;
+  struct linux_kernel_header *lh
+    = (struct linux_kernel_header *) (cur_addr - LINUX_SETUP_MOVE_SIZE);
+  
+#ifndef NO_DECOMPRESSION
+  no_decompression = 1;
+#endif
+  
+  if (! grub_open (initrd))
+    goto fail;
+
+  len = grub_read ((char *) cur_addr, -1);
+  if (! len)
+    {
+      grub_close ();
+      goto fail;
+    }
+
+  if (linux_mem_size)
+    moveto = linux_mem_size;
+  else
+    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);
+  if (moveto + len >= max_addr)
+    moveto = (max_addr - len) & 0xfffff000;
+  
+  /* XXX: Linux 2.3.xx has a bug in the memory range check, so avoid
+     the last page.
+     XXX: Linux 2.2.xx has a bug in the memory range check, which is
+     worse than that of Linux 2.3.xx, so avoid the last 64kb. *sigh*  */
+  moveto -= 0x10000;
+  memmove ((void *) RAW_ADDR (moveto), (void *) cur_addr, len);
+
+  printf ("   [Linux-initrd @ 0x%x, 0x%x bytes]\n", moveto, len);
+
+  /* FIXME: Should check if the kernel supports INITRD.  */
+  lh->ramdisk_image = RAW_ADDR (moveto);
+  lh->ramdisk_size = len;
+
+  grub_close ();
+
+ fail:
+  
+#ifndef NO_DECOMPRESSION
+  no_decompression = 0;
+#endif
+
+  return ! errnum;
+}
+
+
+#ifdef GRUB_UTIL
+/* Dummy function to fake the *BSD boot.  */
+static void
+bsd_boot_entry (int flags, int bootdev, int sym_start, int sym_end,
+		int mem_upper, int mem_lower)
+{
+  stop ();
+}
+#endif
+
+
+/*
+ *  All "*_boot" commands depend on the images being loaded into memory
+ *  correctly, the variables in this file being set up correctly, and
+ *  the root partition being set in the 'saved_drive' and 'saved_partition'
+ *  variables.
+ */
+
+
+void
+bsd_boot (kernel_t type, int bootdev, char *arg)
+{
+  char *str;
+  int clval = 0, i;
+  struct bootinfo bi;
+
+#ifdef GRUB_UTIL
+  entry_addr = (entry_func) bsd_boot_entry;
+#else
+  stop_floppy ();
+#endif
+
+  while (*(++arg) && *arg != ' ');
+  str = arg;
+  while (*str)
+    {
+      if (*str == '-')
+	{
+	  while (*str && *str != ' ')
+	    {
+	      if (*str == 'C')
+		clval |= RB_CDROM;
+	      if (*str == 'a')
+		clval |= RB_ASKNAME;
+	      if (*str == 'b')
+		clval |= RB_HALT;
+	      if (*str == 'c')
+		clval |= RB_CONFIG;
+	      if (*str == 'd')
+		clval |= RB_KDB;
+	      if (*str == 'D')
+		clval |= RB_MULTIPLE;
+	      if (*str == 'g')
+		clval |= RB_GDB;
+	      if (*str == 'h')
+		clval |= RB_SERIAL;
+	      if (*str == 'm')
+		clval |= RB_MUTE;
+	      if (*str == 'r')
+		clval |= RB_DFLTROOT;
+	      if (*str == 's')
+		clval |= RB_SINGLE;
+	      if (*str == 'v')
+		clval |= RB_VERBOSE;
+	      str++;
+	    }
+	  continue;
+	}
+      str++;
+    }
+
+  if (type == KERNEL_TYPE_FREEBSD)
+    {
+      clval |= RB_BOOTINFO;
+
+      bi.bi_version = BOOTINFO_VERSION;
+
+      *arg = 0;
+      while ((--arg) > (char *) MB_CMDLINE_BUF && *arg != '/');
+      if (*arg == '/')
+	bi.bi_kernelname = arg + 1;
+      else
+	bi.bi_kernelname = 0;
+
+      bi.bi_nfs_diskless = 0;
+      bi.bi_n_bios_used = 0;	/* this field is apparently unused */
+
+      for (i = 0; i < N_BIOS_GEOM; i++)
+	{
+	  struct geometry geom;
+
+	  /* XXX Should check the return value.  */
+	  get_diskinfo (i + 0x80, &geom);
+	  /* FIXME: If HEADS or SECTORS is greater than 255, then this will
+	     break the geometry information. That is a drawback of BSD
+	     but not of GRUB.  */
+	  bi.bi_bios_geom[i] = (((geom.cylinders - 1) << 16)
+				+ (((geom.heads - 1) & 0xff) << 8)
+				+ (geom.sectors & 0xff));
+	}
+
+      bi.bi_size = sizeof (struct bootinfo);
+      bi.bi_memsizes_valid = 1;
+      bi.bi_bios_dev = saved_drive;
+      bi.bi_basemem = mbi.mem_lower;
+      bi.bi_extmem = extended_memory;
+
+      if (mbi.flags & MB_INFO_AOUT_SYMS)
+	{
+	  bi.bi_symtab = mbi.syms.a.addr;
+	  bi.bi_esymtab = mbi.syms.a.addr + 4
+	    + mbi.syms.a.tabsize + mbi.syms.a.strsize;
+	}
+#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.  */
+	}
+#endif
+      else
+	{
+	  bi.bi_symtab = 0;
+	  bi.bi_esymtab = 0;
+	}
+
+      /* call entry point */
+      (*entry_addr) (clval, bootdev, 0, 0, 0, ((int) (&bi)));
+    }
+  else
+    {
+      /*
+       *  We now pass the various bootstrap parameters to the loaded
+       *  image via the argument list.
+       *
+       *  This is the official list:
+       *
+       *  arg0 = 8 (magic)
+       *  arg1 = boot flags
+       *  arg2 = boot device
+       *  arg3 = start of symbol table (0 if not loaded)
+       *  arg4 = end of symbol table (0 if not loaded)
+       *  arg5 = transfer address from image
+       *  arg6 = transfer address for next image pointer
+       *  arg7 = conventional memory size (640)
+       *  arg8 = extended memory size (8196)
+       *
+       *  ...in actuality, we just pass the parameters used by the kernel.
+       */
+
+      /* call entry point */
+      unsigned long end_mark;
+
+      if (mbi.flags & MB_INFO_AOUT_SYMS)
+	end_mark = (mbi.syms.a.addr + 4
+		    + mbi.syms.a.tabsize + mbi.syms.a.strsize);
+      else
+	/* FIXME: it should be mbi.syms.e.size.  */
+	end_mark = 0;
+      
+      (*entry_addr) (clval, bootdev, 0, end_mark,
+		     extended_memory, mbi.mem_lower);
+    }
+}
diff --git a/stage2/builtins.c b/stage2/builtins.c
new file mode 100644
index 0000000..6af912d
--- /dev/null
+++ b/stage2/builtins.c
@@ -0,0 +1,4939 @@
+/* builtins.c - the GRUB builtin commands */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  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 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.
+ */
+
+/* Include stdio.h before shared.h, because we can't define
+   WITHOUT_LIBC_STUBS here.  */
+#ifdef GRUB_UTIL
+# include <stdio.h>
+#endif
+
+#include <shared.h>
+#include <filesys.h>
+#include <term.h>
+
+#ifdef SUPPORT_NETBOOT
+# define GRUB	1
+# include <etherboot.h>
+#endif
+
+#ifdef SUPPORT_SERIAL
+# include <serial.h>
+# include <terminfo.h>
+#endif
+
+#ifdef GRUB_UTIL
+# include <device.h>
+#else /* ! GRUB_UTIL */
+# include <apic.h>
+# include <smp-imps.h>
+#endif /* ! GRUB_UTIL */
+
+#ifdef USE_MD5_PASSWORDS
+# include <md5.h>
+#endif
+
+/* The type of kernel loaded.  */
+kernel_t kernel_type;
+/* The boot device.  */
+static int bootdev;
+/* True when the debug mode is turned on, and false
+   when it is turned off.  */
+int debug = 0;
+/* The default entry.  */
+int default_entry = 0;
+/* The fallback entry.  */
+int fallback_entryno;
+int fallback_entries[MAX_FALLBACK_ENTRIES];
+/* The number of current entry.  */
+int current_entryno;
+/* The address for Multiboot command-line buffer.  */
+static char *mb_cmdline;
+/* Whether or not the user loaded a custom command line */
+static unsigned char cmdline_loaded = 0;
+/* The password.  */
+char *password;
+/* The password type.  */
+password_t password_type;
+/* The flag for indicating that the user is authoritative.  */
+int auth = 0;
+/* The timeout.  */
+int grub_timeout = -1;
+/* Whether to show the menu or not.  */
+int show_menu = 1;
+/* The BIOS drive map.  */
+static unsigned short bios_drive_map[DRIVE_MAP_SIZE + 1];
+
+/* Prototypes for allowing straightfoward calling of builtins functions
+   inside other functions.  */
+static int configfile_func (char *arg, int flags);
+
+/* Initialize the data for builtins.  */
+void
+init_builtins (void)
+{
+  kernel_type = KERNEL_TYPE_NONE;
+  /* BSD and chainloading evil hacks!  */
+  bootdev = set_bootdev (0);
+  mb_cmdline = (char *) MB_CMDLINE_BUF;
+}
+
+/* Initialize the data for the configuration file.  */
+void
+init_config (void)
+{
+  default_entry = 0;
+  password = 0;
+  fallback_entryno = -1;
+  fallback_entries[0] = -1;
+  grub_timeout = -1;
+}
+
+/* Check a password for correctness.  Returns 0 if password was
+   correct, and a value != 0 for error, similarly to strcmp. */
+int
+check_password (char *entered, char* expected, password_t type)
+{
+  switch (type)
+    {
+    case PASSWORD_PLAIN:
+      return strcmp (entered, expected);
+
+#ifdef USE_MD5_PASSWORDS
+    case PASSWORD_MD5:
+      return check_md5_password (entered, expected);
+#endif
+    default: 
+      /* unsupported password type: be secure */
+      return 1;
+    }
+}
+
+/* Print which sector is read when loading a file.  */
+static void
+disk_read_print_func (int sector, int offset, int length)
+{
+  grub_printf ("[%d,%d,%d]", sector, offset, length);
+}
+
+
+/* blocklist */
+static int
+blocklist_func (char *arg, int flags)
+{
+  char *dummy = (char *) RAW_ADDR (0x100000);
+  int start_sector;
+  int num_sectors = 0;
+  int num_entries = 0;
+  int last_length = 0;
+
+  auto void disk_read_blocklist_func (int sector, int offset, int length);
+  
+  /* Collect contiguous blocks into one entry as many as possible,
+     and print the blocklist notation on the screen.  */
+  auto void disk_read_blocklist_func (int sector, int offset, int length)
+    {
+      if (num_sectors > 0)
+	{
+	  if (start_sector + num_sectors == sector
+	      && offset == 0 && last_length == SECTOR_SIZE)
+	    {
+	      num_sectors++;
+	      last_length = length;
+	      return;
+	    }
+	  else
+	    {
+	      if (last_length == SECTOR_SIZE)
+		grub_printf ("%s%d+%d", num_entries ? "," : "",
+			     start_sector - part_start, num_sectors);
+	      else if (num_sectors > 1)
+		grub_printf ("%s%d+%d,%d[0-%d]", num_entries ? "," : "",
+			     start_sector - part_start, num_sectors-1,
+			     start_sector + num_sectors-1 - part_start, 
+			     last_length);
+	      else
+		grub_printf ("%s%d[0-%d]", num_entries ? "," : "",
+			     start_sector - part_start, last_length);
+	      num_entries++;
+	      num_sectors = 0;
+	    }
+	}
+
+      if (offset > 0)
+	{
+	  grub_printf("%s%d[%d-%d]", num_entries ? "," : "",
+		      sector-part_start, offset, offset+length);
+	  num_entries++;
+	}
+      else
+	{
+	  start_sector = sector;
+	  num_sectors = 1;
+	  last_length = length;
+	}
+    }
+
+  /* Open the file.  */
+  if (! grub_open (arg))
+    return 1;
+
+  /* Print the device name.  */
+  grub_printf ("(%cd%d",
+	       (current_drive & 0x80) ? 'h' : 'f',
+	       current_drive & ~0x80);
+  
+  if ((current_partition & 0xFF0000) != 0xFF0000)
+    grub_printf (",%d", (current_partition >> 16) & 0xFF);
+  
+  if ((current_partition & 0x00FF00) != 0x00FF00)
+    grub_printf (",%c", 'a' + ((current_partition >> 8) & 0xFF));
+  
+  grub_printf (")");
+
+  /* Read in the whole file to DUMMY.  */
+  disk_read_hook = disk_read_blocklist_func;
+  if (! grub_read (dummy, -1))
+    goto fail;
+
+  /* The last entry may not be printed yet.  Don't check if it is a
+   * full sector, since it doesn't matter if we read too much. */
+  if (num_sectors > 0)
+    grub_printf ("%s%d+%d", num_entries ? "," : "",
+		 start_sector - part_start, num_sectors);
+
+  grub_printf ("\n");
+  
+ fail:
+  disk_read_hook = 0;
+  grub_close ();
+  return errnum;
+}
+
+static struct builtin builtin_blocklist =
+{
+  "blocklist",
+  blocklist_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "blocklist FILE",
+  "Print the blocklist notation of the file FILE."
+};
+
+/* boot */
+static int
+boot_func (char *arg, int flags)
+{
+  /* 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 ();
+
+#ifdef SUPPORT_NETBOOT
+  /* Shut down the networking.  */
+  cleanup_net ();
+#endif
+  
+  switch (kernel_type)
+    {
+    case KERNEL_TYPE_FREEBSD:
+    case KERNEL_TYPE_NETBSD:
+      /* *BSD */
+      bsd_boot (kernel_type, bootdev, (char *) mbi.cmdline);
+      break;
+
+    case KERNEL_TYPE_LINUX:
+      /* Linux */
+      linux_boot ();
+      break;
+
+    case KERNEL_TYPE_BIG_LINUX:
+      /* Big Linux */
+      big_linux_boot ();
+      break;
+
+    case KERNEL_TYPE_CHAINLOADER:
+      /* Chainloader */
+      
+      /* Check if we should set the int13 handler.  */
+      if (bios_drive_map[0] != 0)
+	{
+	  int i;
+	  
+	  /* Search for SAVED_DRIVE.  */
+	  for (i = 0; i < DRIVE_MAP_SIZE; i++)
+	    {
+	      if (! bios_drive_map[i])
+		break;
+	      else if ((bios_drive_map[i] & 0xFF) == saved_drive)
+		{
+		  /* Exchage SAVED_DRIVE with the mapped drive.  */
+		  saved_drive = (bios_drive_map[i] >> 8) & 0xFF;
+		  break;
+		}
+	    }
+	  
+	  /* Set the handler. This is somewhat dangerous.  */
+	  set_int13_handler (bios_drive_map);
+	}
+      
+      gateA20 (0);
+      boot_drive = saved_drive;
+      chain_stage1 (0, BOOTSEC_LOCATION, boot_part_addr);
+      break;
+
+    case KERNEL_TYPE_MULTIBOOT:
+      /* Multiboot */
+      multi_boot ((int) entry_addr, (int) &mbi);
+      break;
+
+    default:
+      errnum = ERR_BOOT_COMMAND;
+      return 1;
+    }
+
+  return 0;
+}
+
+static struct builtin builtin_boot =
+{
+  "boot",
+  boot_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "boot",
+  "Boot the OS/chain-loader which has been loaded."
+};
+
+
+#ifdef SUPPORT_NETBOOT
+/* bootp */
+static int
+bootp_func (char *arg, int flags)
+{
+  int with_configfile = 0;
+
+  if (grub_memcmp (arg, "--with-configfile", sizeof ("--with-configfile") - 1)
+      == 0)
+    {
+      with_configfile = 1;
+      arg = skip_to (0, arg);
+    }
+  
+  if (! bootp ())
+    {
+      if (errnum == ERR_NONE)
+	errnum = ERR_DEV_VALUES;
+
+      return 1;
+    }
+
+  /* Notify the configuration.  */
+  print_network_configuration ();
+
+  /* XXX: this can cause an endless loop, but there is no easy way to
+     detect such a loop unfortunately.  */
+  if (with_configfile)
+    configfile_func (config_file, flags);
+  
+  return 0;
+}
+
+static struct builtin builtin_bootp =
+{
+  "bootp",
+  bootp_func,
+  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
+  "bootp [--with-configfile]",
+  "Initialize a network device via BOOTP. If the option `--with-configfile'"
+  " is given, try to load a configuration file specified by the 150 vendor"
+  " tag."
+};
+#endif /* SUPPORT_NETBOOT */
+
+
+/* cat */
+static int
+cat_func (char *arg, int flags)
+{
+  char c;
+
+  if (! grub_open (arg))
+    return 1;
+
+  while (grub_read (&c, 1))
+    {
+      /* Because running "cat" with a binary file can confuse the terminal,
+	 print only some characters as they are.  */
+      if (grub_isspace (c) || (c >= ' ' && c <= '~'))
+	grub_putchar (c);
+      else
+	grub_putchar ('?');
+    }
+  
+  grub_close ();
+  return 0;
+}
+
+static struct builtin builtin_cat =
+{
+  "cat",
+  cat_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "cat FILE",
+  "Print the contents of the file FILE."
+};
+
+
+/* chainloader */
+static int
+chainloader_func (char *arg, int flags)
+{
+  int force = 0;
+  char *file = arg;
+
+  /* If the option `--force' is specified?  */
+  if (substring ("--force", arg) <= 0)
+    {
+      force = 1;
+      file = skip_to (0, arg);
+    }
+
+  /* Open the file.  */
+  if (! grub_open (file))
+    {
+      kernel_type = KERNEL_TYPE_NONE;
+      return 1;
+    }
+
+  /* Read the first block.  */
+  if (grub_read ((char *) BOOTSEC_LOCATION, SECTOR_SIZE) != SECTOR_SIZE)
+    {
+      grub_close ();
+      kernel_type = KERNEL_TYPE_NONE;
+
+      /* This below happens, if a file whose size is less than 512 bytes
+	 is loaded.  */
+      if (errnum == ERR_NONE)
+	errnum = ERR_EXEC_FORMAT;
+      
+      return 1;
+    }
+
+  /* If not loading it forcibly, check for the signature.  */
+  if (! force
+      && (*((unsigned short *) (BOOTSEC_LOCATION + BOOTSEC_SIG_OFFSET))
+	  != BOOTSEC_SIGNATURE))
+    {
+      grub_close ();
+      errnum = ERR_EXEC_FORMAT;
+      kernel_type = KERNEL_TYPE_NONE;
+      return 1;
+    }
+
+  grub_close ();
+  kernel_type = KERNEL_TYPE_CHAINLOADER;
+
+  /* XXX: Windows evil hack. For now, only the first five letters are
+     checked.  */
+  if (IS_PC_SLICE_TYPE_FAT (current_slice)
+      && ! grub_memcmp ((char *) BOOTSEC_LOCATION + BOOTSEC_BPB_SYSTEM_ID,
+			"MSWIN", 5))
+    *((unsigned long *) (BOOTSEC_LOCATION + BOOTSEC_BPB_HIDDEN_SECTORS))
+      = part_start;
+
+  errnum = ERR_NONE;
+  
+  return 0;
+}
+
+static struct builtin builtin_chainloader =
+{
+  "chainloader",
+  chainloader_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "chainloader [--force] FILE",
+  "Load the chain-loader FILE. If --force is specified, then load it"
+  " forcibly, whether the boot loader signature is present or not."
+};
+
+
+/* This function could be used to debug new filesystem code. Put a file
+   in the new filesystem and the same file in a well-tested filesystem.
+   Then, run "cmp" with the files. If no output is obtained, probably
+   the code is good, otherwise investigate what's wrong...  */
+/* cmp FILE1 FILE2 */
+static int
+cmp_func (char *arg, int flags)
+{
+  /* The filenames.  */
+  char *file1, *file2;
+  /* The addresses.  */
+  char *addr1, *addr2;
+  int i;
+  /* The size of the file.  */
+  int size;
+
+  /* Get the filenames from ARG.  */
+  file1 = arg;
+  file2 = skip_to (0, arg);
+  if (! *file1 || ! *file2)
+    {
+      errnum = ERR_BAD_ARGUMENT;
+      return 1;
+    }
+
+  /* Terminate the filenames for convenience.  */
+  nul_terminate (file1);
+  nul_terminate (file2);
+
+  /* Read the whole data from FILE1.  */
+  addr1 = (char *) RAW_ADDR (0x100000);
+  if (! grub_open (file1))
+    return 1;
+  
+  /* Get the size.  */
+  size = filemax;
+  if (grub_read (addr1, -1) != size)
+    {
+      grub_close ();
+      return 1;
+    }
+  
+  grub_close ();
+
+  /* Read the whole data from FILE2.  */
+  addr2 = addr1 + size;
+  if (! grub_open (file2))
+    return 1;
+
+  /* Check if the size of FILE2 is equal to the one of FILE2.  */
+  if (size != filemax)
+    {
+      grub_printf ("Differ in size: 0x%x [%s], 0x%x [%s]\n",
+		   size, file1, filemax, file2);
+      grub_close ();
+      return 0;
+    }
+  
+  if (! grub_read (addr2, -1))
+    {
+      grub_close ();
+      return 1;
+    }
+  
+  grub_close ();
+
+  /* Now compare ADDR1 with ADDR2.  */
+  for (i = 0; i < size; i++)
+    {
+      if (addr1[i] != addr2[i])
+	grub_printf ("Differ at the offset %d: 0x%x [%s], 0x%x [%s]\n",
+		     i, (unsigned) addr1[i], file1,
+		     (unsigned) addr2[i], file2);
+    }
+  
+  return 0;
+}
+
+static struct builtin builtin_cmp =
+{
+  "cmp",
+  cmp_func,
+  BUILTIN_CMDLINE,
+  "cmp FILE1 FILE2",
+  "Compare the file FILE1 with the FILE2 and inform the different values"
+  " if any."
+};
+
+
+/* color */
+/* Set new colors used for the menu interface. Support two methods to
+   specify a color name: a direct integer representation and a symbolic
+   color name. An example of the latter is "blink-light-gray/blue".  */
+static int
+color_func (char *arg, int flags)
+{
+  char *normal;
+  char *highlight;
+  int new_normal_color;
+  int new_highlight_color;
+  static char *color_list[16] =
+  {
+    "black",
+    "blue",
+    "green",
+    "cyan",
+    "red",
+    "magenta",
+    "brown",
+    "light-gray",
+    "dark-gray",
+    "light-blue",
+    "light-green",
+    "light-cyan",
+    "light-red",
+    "light-magenta",
+    "yellow",
+    "white"
+  };
+
+  auto int color_number (char *str);
+  
+  /* Convert the color name STR into the magical number.  */
+  auto int color_number (char *str)
+    {
+      char *ptr;
+      int i;
+      int color = 0;
+      
+      /* Find the separator.  */
+      for (ptr = str; *ptr && *ptr != '/'; ptr++)
+	;
+
+      /* If not found, return -1.  */
+      if (! *ptr)
+	return -1;
+
+      /* Terminate the string STR.  */
+      *ptr++ = 0;
+
+      /* If STR contains the prefix "blink-", then set the `blink' bit
+	 in COLOR.  */
+      if (substring ("blink-", str) <= 0)
+	{
+	  color = 0x80;
+	  str += 6;
+	}
+      
+      /* Search for the color name.  */
+      for (i = 0; i < 16; i++)
+	if (grub_strcmp (color_list[i], str) == 0)
+	  {
+	    color |= i;
+	    break;
+	  }
+
+      if (i == 16)
+	return -1;
+
+      str = ptr;
+      nul_terminate (str);
+
+      /* Search for the color name.  */      
+      for (i = 0; i < 8; i++)
+	if (grub_strcmp (color_list[i], str) == 0)
+	  {
+	    color |= i << 4;
+	    break;
+	  }
+
+      if (i == 8)
+	return -1;
+
+      return color;
+    }
+      
+  normal = arg;
+  highlight = skip_to (0, arg);
+
+  new_normal_color = color_number (normal);
+  if (new_normal_color < 0 && ! safe_parse_maxint (&normal, &new_normal_color))
+    return 1;
+  
+  /* The second argument is optional, so set highlight_color
+     to inverted NORMAL_COLOR.  */
+  if (! *highlight)
+    new_highlight_color = ((new_normal_color >> 4)
+			   | ((new_normal_color & 0xf) << 4));
+  else
+    {
+      new_highlight_color = color_number (highlight);
+      if (new_highlight_color < 0
+	  && ! safe_parse_maxint (&highlight, &new_highlight_color))
+	return 1;
+    }
+
+  if (current_term->setcolor)
+    current_term->setcolor (new_normal_color, new_highlight_color);
+  
+  return 0;
+}
+
+static struct builtin builtin_color =
+{
+  "color",
+  color_func,
+  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
+  "color NORMAL [HIGHLIGHT]",
+  "Change the menu colors. The color NORMAL is used for most"
+  " lines in the menu, and the color HIGHLIGHT is used to highlight the"
+  " line where the cursor points. If you omit HIGHLIGHT, then the"
+  " inverted color of NORMAL is used for the highlighted line."
+  " The format of a color is \"FG/BG\". FG and BG are symbolic color names."
+  " A symbolic color name must be one of these: black, blue, green,"
+  " cyan, red, magenta, brown, light-gray, dark-gray, light-blue,"
+  " light-green, light-cyan, light-red, light-magenta, yellow and white."
+  " But only the first eight names can be used for BG. You can prefix"
+  " \"blink-\" to FG if you want a blinking foreground color."
+};
+
+
+/* configfile */
+static int
+configfile_func (char *arg, int flags)
+{
+  char *new_config = config_file;
+
+  /* Check if the file ARG is present.  */
+  if (! grub_open (arg))
+    return 1;
+
+  grub_close ();
+  
+  /* Copy ARG to CONFIG_FILE.  */
+  while ((*new_config++ = *arg++) != 0)
+    ;
+
+#ifdef GRUB_UTIL
+  /* Force to load the configuration file.  */
+  use_config_file = 1;
+#endif
+
+  /* Make sure that the user will not be authoritative.  */
+  auth = 0;
+  
+  /* Restart cmain.  */
+  grub_longjmp (restart_env, 0);
+
+  /* Never reach here.  */
+  return 0;
+}
+
+static struct builtin builtin_configfile =
+{
+  "configfile",
+  configfile_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "configfile FILE",
+  "Load FILE as the configuration file."
+};
+
+
+/* debug */
+static int
+debug_func (char *arg, int flags)
+{
+  if (debug)
+    {
+      debug = 0;
+      grub_printf (" Debug mode is turned off\n");
+    }
+  else
+    {
+      debug = 1;
+      grub_printf (" Debug mode is turned on\n");
+    }
+
+  return 0;
+}
+
+static struct builtin builtin_debug =
+{
+  "debug",
+  debug_func,
+  BUILTIN_CMDLINE,
+  "debug",
+  "Turn on/off the debug mode."
+};
+
+
+/* default */
+static int
+default_func (char *arg, int flags)
+{
+#ifndef SUPPORT_DISKLESS
+  if (grub_strcmp (arg, "saved") == 0)
+    {
+      default_entry = saved_entryno;
+      return 0;
+    }
+#endif /* SUPPORT_DISKLESS */
+  
+  if (! safe_parse_maxint (&arg, &default_entry))
+    return 1;
+
+  return 0;
+}
+
+static struct builtin builtin_default =
+{
+  "default",
+  default_func,
+  BUILTIN_MENU,
+#if 0
+  "default [NUM | `saved']",
+  "Set the default entry to entry number NUM (if not specified, it is"
+  " 0, the first entry) or the entry number saved by savedefault."
+#endif
+};
+
+
+#ifdef GRUB_UTIL
+/* device */
+static int
+device_func (char *arg, int flags)
+{
+  char *drive = arg;
+  char *device;
+
+  /* Get the drive number from DRIVE.  */
+  if (! set_device (drive))
+    return 1;
+
+  /* Get the device argument.  */
+  device = skip_to (0, drive);
+  
+  /* Terminate DEVICE.  */
+  nul_terminate (device);
+
+  if (! *device || ! check_device (device))
+    {
+      errnum = ERR_FILE_NOT_FOUND;
+      return 1;
+    }
+
+  assign_device_name (current_drive, device);
+  
+  return 0;
+}
+
+static struct builtin builtin_device =
+{
+  "device",
+  device_func,
+  BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "device DRIVE DEVICE",
+  "Specify DEVICE as the actual drive for a BIOS drive DRIVE. This command"
+  " can be used only in the grub shell."
+};
+#endif /* GRUB_UTIL */
+
+
+#ifdef SUPPORT_NETBOOT
+/* dhcp */
+static int
+dhcp_func (char *arg, int flags)
+{
+  /* For now, this is an alias for bootp.  */
+  return bootp_func (arg, flags);
+}
+
+static struct builtin builtin_dhcp =
+{
+  "dhcp",
+  dhcp_func,
+  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
+  "dhcp",
+  "Initialize a network device via DHCP."
+};
+#endif /* SUPPORT_NETBOOT */
+
+
+/* displayapm */
+static int
+displayapm_func (char *arg, int flags)
+{
+  if (mbi.flags & MB_INFO_APM_TABLE)
+    {
+      grub_printf ("APM BIOS information:\n"
+		   " Version:          0x%x\n"
+		   " 32-bit CS:        0x%x\n"
+		   " Offset:           0x%x\n"
+		   " 16-bit CS:        0x%x\n"
+		   " 16-bit DS:        0x%x\n"
+		   " 32-bit CS length: 0x%x\n"
+		   " 16-bit CS length: 0x%x\n"
+		   " 16-bit DS length: 0x%x\n",
+		   (unsigned) apm_bios_info.version,
+		   (unsigned) apm_bios_info.cseg,
+		   apm_bios_info.offset,
+		   (unsigned) apm_bios_info.cseg_16,
+		   (unsigned) apm_bios_info.dseg_16,
+		   (unsigned) apm_bios_info.cseg_len,
+		   (unsigned) apm_bios_info.cseg_16_len,
+		   (unsigned) apm_bios_info.dseg_16_len);
+    }
+  else
+    {
+      grub_printf ("No APM BIOS found or probe failed\n");
+    }
+
+  return 0;
+}
+
+static struct builtin builtin_displayapm =
+{
+  "displayapm",
+  displayapm_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "displayapm",
+  "Display APM BIOS information."
+};
+
+
+/* displaymem */
+static int
+displaymem_func (char *arg, int flags)
+{
+  if (get_eisamemsize () != -1)
+    grub_printf (" EISA Memory BIOS Interface is present\n");
+  if (get_mmap_entry ((void *) SCRATCHADDR, 0) != 0
+      || *((int *) SCRATCHADDR) != 0)
+    grub_printf (" Address Map BIOS Interface is present\n");
+
+  grub_printf (" Lower memory: %uK, "
+	       "Upper memory (to first chipset hole): %uK\n",
+	       mbi.mem_lower, mbi.mem_upper);
+
+  if (mbi.flags & MB_INFO_MEM_MAP)
+    {
+      struct AddrRangeDesc *map = (struct AddrRangeDesc *) mbi.mmap_addr;
+      int end_addr = mbi.mmap_addr + mbi.mmap_length;
+
+      grub_printf (" [Address Range Descriptor entries "
+		   "immediately follow (values are 64-bit)]\n");
+      while (end_addr > (int) map)
+	{
+	  char *str;
+
+	  if (map->Type == MB_ARD_MEMORY)
+	    str = "Usable RAM";
+	  else
+	    str = "Reserved";
+	  grub_printf ("   %s:  Base Address:  0x%x X 4GB + 0x%x,\n"
+		       "      Length:   0x%x X 4GB + 0x%x bytes\n",
+		       str,
+		       (unsigned long) (map->BaseAddr >> 32),
+		       (unsigned long) (map->BaseAddr & 0xFFFFFFFF),
+		       (unsigned long) (map->Length >> 32),
+		       (unsigned long) (map->Length & 0xFFFFFFFF));
+
+	  map = ((struct AddrRangeDesc *) (((int) map) + 4 + map->size));
+	}
+    }
+
+  return 0;
+}
+
+static struct builtin builtin_displaymem =
+{
+  "displaymem",
+  displaymem_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "displaymem",
+  "Display what GRUB thinks the system address space map of the"
+  " machine is, including all regions of physical RAM installed."
+};
+
+
+/* dump FROM TO */
+#ifdef GRUB_UTIL
+static int
+dump_func (char *arg, int flags)
+{
+  char *from, *to;
+  FILE *fp;
+  char c;
+  
+  from = arg;
+  to = skip_to (0, arg);
+  if (! *from || ! *to)
+    {
+      errnum = ERR_BAD_ARGUMENT;
+      return 1;
+    }
+
+  nul_terminate (from);
+  nul_terminate (to);
+  
+  if (! grub_open (from))
+    return 1;
+
+  fp = fopen (to, "w");
+  if (! fp)
+    {
+      errnum = ERR_WRITE;
+      return 1;
+    }
+
+  while (grub_read (&c, 1))
+    if (fputc (c, fp) == EOF)
+      {
+	errnum = ERR_WRITE;
+	fclose (fp);
+	return 1;
+      }
+
+  if (fclose (fp) == EOF)
+    {
+      errnum = ERR_WRITE;
+      return 1;
+    }
+
+  grub_close ();
+  return 0;
+}
+
+static struct builtin builtin_dump =
+  {
+    "dump",
+    dump_func,
+    BUILTIN_CMDLINE,
+    "dump FROM TO",
+    "Dump the contents of the file FROM to the file TO. FROM must be"
+    " a GRUB file and TO must be an OS file."
+  };
+#endif /* GRUB_UTIL */
+
+
+static char embed_info[32];
+/* embed */
+/* Embed a Stage 1.5 in the first cylinder after MBR or in the
+   bootloader block in a FFS.  */
+static int
+embed_func (char *arg, int flags)
+{
+  char *stage1_5;
+  char *device;
+  char *stage1_5_buffer = (char *) RAW_ADDR (0x100000);
+  int len, size;
+  int sector;
+  
+  stage1_5 = arg;
+  device = skip_to (0, stage1_5);
+
+  /* Open a Stage 1.5.  */
+  if (! grub_open (stage1_5))
+    return 1;
+
+  /* Read the whole of the Stage 1.5.  */
+  len = grub_read (stage1_5_buffer, -1);
+  grub_close ();
+  
+  if (errnum)
+    return 1;
+  
+  size = (len + SECTOR_SIZE - 1) / SECTOR_SIZE;
+  
+  /* Get the device where the Stage 1.5 will be embedded.  */
+  set_device (device);
+  if (errnum)
+    return 1;
+
+  if (current_partition == 0xFFFFFF)
+    {
+      /* Embed it after the MBR.  */
+      
+      char mbr[SECTOR_SIZE];
+      char ezbios_check[2*SECTOR_SIZE];
+      int i;
+      
+      /* Open the partition.  */
+      if (! open_partition ())
+	return 1;
+
+      /* No floppy has MBR.  */
+      if (! (current_drive & 0x80))
+	{
+	  errnum = ERR_DEV_VALUES;
+	  return 1;
+	}
+      
+      /* Read the MBR of CURRENT_DRIVE.  */
+      if (! rawread (current_drive, PC_MBR_SECTOR, 0, SECTOR_SIZE, mbr))
+	return 1;
+      
+      /* Sanity check.  */
+      if (! PC_MBR_CHECK_SIG (mbr))
+	{
+	  errnum = ERR_BAD_PART_TABLE;
+	  return 1;
+	}
+
+      /* Check if the disk can store the Stage 1.5.  */
+      for (i = 0; i < 4; i++)
+	if (PC_SLICE_TYPE (mbr, i) && PC_SLICE_START (mbr, i) - 1 < size)
+	  {
+	    errnum = ERR_NO_DISK_SPACE;
+	    return 1;
+	  }
+      
+      /* Check for EZ-BIOS signature. It should be in the third
+       * sector, but due to remapping it can appear in the second, so
+       * load and check both.  
+       */
+      if (! rawread (current_drive, 1, 0, 2 * SECTOR_SIZE, ezbios_check))
+	return 1;
+
+      if (! memcmp (ezbios_check + 3, "AERMH", 5)
+	  || ! memcmp (ezbios_check + 512 + 3, "AERMH", 5))
+	{
+	  /* The space after the MBR is used by EZ-BIOS which we must 
+	   * not overwrite.
+	   */
+	  errnum = ERR_NO_DISK_SPACE;
+	  return 1;
+	}
+
+      sector = 1;
+    }
+  else
+    {
+      /* Embed it in the bootloader block in the filesystem.  */
+      int start_sector;
+      
+      /* Open the partition.  */
+      if (! open_device ())
+	return 1;
+
+      /* Check if the current slice supports embedding.  */
+      if (fsys_table[fsys_type].embed_func == 0
+	  || ! fsys_table[fsys_type].embed_func (&start_sector, size))
+	{
+	  errnum = ERR_DEV_VALUES;
+	  return 1;
+	}
+
+      sector = part_start + start_sector;
+    }
+
+  /* Clear the cache.  */
+  buf_track = -1;
+
+  /* Now perform the embedding.  */
+  if (! devwrite (sector - part_start, size, stage1_5_buffer))
+    return 1;
+  
+  grub_printf (" %d sectors are embedded.\n", size);
+  grub_sprintf (embed_info, "%d+%d", sector - part_start, size);
+  return 0;
+}
+
+static struct builtin builtin_embed =
+{
+  "embed",
+  embed_func,
+  BUILTIN_CMDLINE,
+  "embed STAGE1_5 DEVICE",
+  "Embed the Stage 1.5 STAGE1_5 in the sectors after MBR if DEVICE"
+  " is a drive, or in the \"bootloader\" area if DEVICE is a FFS partition."
+  " Print the number of sectors which STAGE1_5 occupies if successful."
+};
+
+
+/* fallback */
+static int
+fallback_func (char *arg, int flags)
+{
+  int i = 0;
+
+  while (*arg)
+    {
+      int entry;
+      int j;
+      
+      if (! safe_parse_maxint (&arg, &entry))
+	return 1;
+
+      /* Remove duplications to prevent infinite looping.  */
+      for (j = 0; j < i; j++)
+	if (entry == fallback_entries[j])
+	  break;
+      if (j != i)
+	continue;
+      
+      fallback_entries[i++] = entry;
+      if (i == MAX_FALLBACK_ENTRIES)
+	break;
+      
+      arg = skip_to (0, arg);
+    }
+
+  if (i < MAX_FALLBACK_ENTRIES)
+    fallback_entries[i] = -1;
+
+  fallback_entryno = (i == 0) ? -1 : 0;
+  
+  return 0;
+}
+
+static struct builtin builtin_fallback =
+{
+  "fallback",
+  fallback_func,
+  BUILTIN_MENU,
+#if 0
+  "fallback NUM...",
+  "Go into unattended boot mode: if the default boot entry has any"
+  " errors, instead of waiting for the user to do anything, it"
+  " immediately starts over using the NUM entry (same numbering as the"
+  " `default' command). This obviously won't help if the machine"
+  " was rebooted by a kernel that GRUB loaded."
+#endif
+};
+
+
+/* find */
+/* Search for the filename ARG in all of partitions.  */
+static int
+find_func (char *arg, int flags)
+{
+  char *filename = arg;
+  unsigned long drive;
+  unsigned long tmp_drive = saved_drive;
+  unsigned long tmp_partition = saved_partition;
+  int got_file = 0;
+  
+  /* Floppies.  */
+  for (drive = 0; drive < 8; drive++)
+    {
+      current_drive = drive;
+      current_partition = 0xFFFFFF;
+      
+      if (open_device ())
+	{
+	  saved_drive = current_drive;
+	  saved_partition = current_partition;
+	  if (grub_open (filename))
+	    {
+	      grub_close ();
+	      grub_printf (" (fd%d)\n", drive);
+	      got_file = 1;
+	    }
+	}
+
+      errnum = ERR_NONE;
+    }
+
+  /* Hard disks.  */
+  for (drive = 0x80; drive < 0x88; drive++)
+    {
+      unsigned long part = 0xFFFFFF;
+      unsigned long start, len, offset, ext_offset;
+      int type, entry;
+      char buf[SECTOR_SIZE];
+
+      current_drive = drive;
+      while (next_partition (drive, 0xFFFFFF, &part, &type,
+			     &start, &len, &offset, &entry,
+			     &ext_offset, buf))
+	{
+	  if (type != PC_SLICE_TYPE_NONE
+	      && ! IS_PC_SLICE_TYPE_BSD (type)
+	      && ! IS_PC_SLICE_TYPE_EXTENDED (type))
+	    {
+	      current_partition = part;
+	      if (open_device ())
+		{
+		  saved_drive = current_drive;
+		  saved_partition = current_partition;
+		  if (grub_open (filename))
+		    {
+		      int bsd_part = (part >> 8) & 0xFF;
+		      int pc_slice = part >> 16;
+		      
+		      grub_close ();
+		      
+		      if (bsd_part == 0xFF)
+			grub_printf (" (hd%d,%d)\n",
+				     drive - 0x80, pc_slice);
+		      else
+			grub_printf (" (hd%d,%d,%c)\n",
+				     drive - 0x80, pc_slice, bsd_part + 'a');
+
+		      got_file = 1;
+		    }
+		}
+	    }
+
+	  /* We want to ignore any error here.  */
+	  errnum = ERR_NONE;
+	}
+
+      /* next_partition always sets ERRNUM in the last call, so clear
+	 it.  */
+      errnum = ERR_NONE;
+    }
+
+  saved_drive = tmp_drive;
+  saved_partition = tmp_partition;
+
+  if (got_file)
+    {
+      errnum = ERR_NONE;
+      return 0;
+    }
+
+  errnum = ERR_FILE_NOT_FOUND;
+  return 1;
+}
+
+static struct builtin builtin_find =
+{
+  "find",
+  find_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "find FILENAME",
+  "Search for the filename FILENAME in all of partitions and print the list of"
+  " the devices which contain the file."
+};
+
+
+/* fstest */
+static int
+fstest_func (char *arg, int flags)
+{
+  if (disk_read_hook)
+    {
+      disk_read_hook = NULL;
+      printf (" Filesystem tracing is now off\n");
+    }
+  else
+    {
+      disk_read_hook = disk_read_print_func;
+      printf (" Filesystem tracing is now on\n");
+    }
+
+  return 0;
+}
+
+static struct builtin builtin_fstest =
+{
+  "fstest",
+  fstest_func,
+  BUILTIN_CMDLINE,
+  "fstest",
+  "Toggle filesystem test mode."
+};
+
+
+/* geometry */
+static int
+geometry_func (char *arg, int flags)
+{
+  struct geometry geom;
+  char *msg;
+  char *device = arg;
+#ifdef GRUB_UTIL
+  char *ptr;
+#endif
+
+  /* Get the device number.  */
+  set_device (device);
+  if (errnum)
+    return 1;
+
+  /* Check for the geometry.  */
+  if (get_diskinfo (current_drive, &geom))
+    {
+      errnum = ERR_NO_DISK;
+      return 1;
+    }
+
+  /* Attempt to read the first sector, because some BIOSes turns out not
+     to support LBA even though they set the bit 0 in the support
+     bitmap, only after reading something actually.  */
+  if (biosdisk (BIOSDISK_READ, current_drive, &geom, 0, 1, SCRATCHSEG))
+    {
+      errnum = ERR_READ;
+      return 1;
+    }
+
+#ifdef GRUB_UTIL
+  ptr = skip_to (0, device);
+  if (*ptr)
+    {
+      char *cylinder, *head, *sector, *total_sector;
+      int num_cylinder, num_head, num_sector, num_total_sector;
+
+      cylinder = ptr;
+      head = skip_to (0, cylinder);
+      sector = skip_to (0, head);
+      total_sector = skip_to (0, sector);
+      if (! safe_parse_maxint (&cylinder, &num_cylinder)
+	  || ! safe_parse_maxint (&head, &num_head)
+	  || ! safe_parse_maxint (&sector, &num_sector))
+	return 1;
+
+      disks[current_drive].cylinders = num_cylinder;
+      disks[current_drive].heads = num_head;
+      disks[current_drive].sectors = num_sector;
+
+      if (safe_parse_maxint (&total_sector, &num_total_sector))
+	disks[current_drive].total_sectors = num_total_sector;
+      else
+	disks[current_drive].total_sectors
+	  = num_cylinder * num_head * num_sector;
+      errnum = 0;
+
+      geom = disks[current_drive];
+      buf_drive = -1;
+    }
+#endif /* GRUB_UTIL */
+
+#ifdef GRUB_UTIL
+  msg = device_map[current_drive];
+#else
+  if (geom.flags & BIOSDISK_FLAG_LBA_EXTENSION)
+    msg = "LBA";
+  else
+    msg = "CHS";
+#endif
+
+  grub_printf ("drive 0x%x: C/H/S = %d/%d/%d, "
+	       "The number of sectors = %d, %s\n",
+	       current_drive,
+	       geom.cylinders, geom.heads, geom.sectors,
+	       geom.total_sectors, msg);
+  real_open_partition (1);
+
+  return 0;
+}
+
+static struct builtin builtin_geometry =
+{
+  "geometry",
+  geometry_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "geometry DRIVE [CYLINDER HEAD SECTOR [TOTAL_SECTOR]]",
+  "Print the information for a drive DRIVE. In the grub shell, you can"
+  " set the geometry of the drive arbitrarily. The number of the cylinders,"
+  " the one of the heads, the one of the sectors and the one of the total"
+  " sectors are set to CYLINDER, HEAD, SECTOR and TOTAL_SECTOR,"
+  " respectively. If you omit TOTAL_SECTOR, then it will be calculated based"
+  " on the C/H/S values automatically."
+};
+
+
+/* halt */
+static int
+halt_func (char *arg, int flags)
+{
+  int no_apm;
+
+  no_apm = (grub_memcmp (arg, "--no-apm", 8) == 0);
+  grub_halt (no_apm);
+  
+  /* Never reach here.  */
+  return 1;
+}
+
+static struct builtin builtin_halt =
+{
+  "halt",
+  halt_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "halt [--no-apm]",
+  "Halt your system. If APM is avaiable on it, turn off the power using"
+  " the APM BIOS, unless you specify the option `--no-apm'."
+};
+
+
+/* help */
+#define MAX_SHORT_DOC_LEN	39
+#define MAX_LONG_DOC_LEN	66
+
+static int
+help_func (char *arg, int flags)
+{
+  int all = 0;
+  
+  if (grub_memcmp (arg, "--all", sizeof ("--all") - 1) == 0)
+    {
+      all = 1;
+      arg = skip_to (0, arg);
+    }
+  
+  if (! *arg)
+    {
+      /* Invoked with no argument. Print the list of the short docs.  */
+      struct builtin **builtin;
+      int left = 1;
+
+      for (builtin = builtin_table; *builtin != 0; builtin++)
+	{
+	  int len;
+	  int i;
+
+	  /* If this cannot be used in the command-line interface,
+	     skip this.  */
+	  if (! ((*builtin)->flags & BUILTIN_CMDLINE))
+	    continue;
+	  
+	  /* If this doesn't need to be listed automatically and "--all"
+	     is not specified, skip this.  */
+	  if (! all && ! ((*builtin)->flags & BUILTIN_HELP_LIST))
+	    continue;
+
+	  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;
+
+	  for (i = 0; i < len; i++)
+	    grub_putchar ((*builtin)->short_doc[i]);
+
+	  for (; i < MAX_SHORT_DOC_LEN; i++)
+	    grub_putchar (' ');
+
+	  if (! left)
+	    grub_putchar ('\n');
+
+	  left = ! left;
+	}
+
+      /* If the last entry was at the left column, no newline was printed
+	 at the end.  */
+      if (! left)
+	grub_putchar ('\n');
+    }
+  else
+    {
+      /* Invoked with one or more patterns.  */
+      do
+	{
+	  struct builtin **builtin;
+	  char *next_arg;
+
+	  /* Get the next argument.  */
+	  next_arg = skip_to (0, arg);
+
+	  /* Terminate ARG.  */
+	  nul_terminate (arg);
+
+	  for (builtin = builtin_table; *builtin; builtin++)
+	    {
+	      /* Skip this if this is only for the configuration file.  */
+	      if (! ((*builtin)->flags & BUILTIN_CMDLINE))
+		continue;
+
+	      if (substring (arg, (*builtin)->name) < 1)
+		{
+		  char *doc = (*builtin)->long_doc;
+
+		  /* At first, print the name and the short doc.  */
+		  grub_printf ("%s: %s\n",
+			       (*builtin)->name, (*builtin)->short_doc);
+
+		  /* Print the long doc.  */
+		  while (*doc)
+		    {
+		      int len = grub_strlen (doc);
+		      int i;
+
+		      /* If LEN is too long, fold DOC.  */
+		      if (len > MAX_LONG_DOC_LEN)
+			{
+			  /* Fold this line at the position of a space.  */
+			  for (len = MAX_LONG_DOC_LEN; len > 0; len--)
+			    if (doc[len - 1] == ' ')
+			      break;
+			}
+
+		      grub_printf ("    ");
+		      for (i = 0; i < len; i++)
+			grub_putchar (*doc++);
+		      grub_putchar ('\n');
+		    }
+		}
+	    }
+
+	  arg = next_arg;
+	}
+      while (*arg);
+    }
+
+  return 0;
+}
+
+static struct builtin builtin_help =
+{
+  "help",
+  help_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "help [--all] [PATTERN ...]",
+  "Display helpful information about builtin commands. Not all commands"
+  " aren't shown without the option `--all'."
+};
+
+
+/* hiddenmenu */
+static int
+hiddenmenu_func (char *arg, int flags)
+{
+  show_menu = 0;
+  return 0;
+}
+
+static struct builtin builtin_hiddenmenu =
+{
+  "hiddenmenu",
+  hiddenmenu_func,
+  BUILTIN_MENU,
+#if 0
+  "hiddenmenu",
+  "Hide the menu."
+#endif
+};
+
+
+/* hide */
+static int
+hide_func (char *arg, int flags)
+{
+  if (! set_device (arg))
+    return 1;
+
+  if (! set_partition_hidden_flag (1))
+    return 1;
+
+  return 0;
+}
+
+static struct builtin builtin_hide =
+{
+  "hide",
+  hide_func,
+  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
+  "hide PARTITION",
+  "Hide PARTITION by setting the \"hidden\" bit in"
+  " its partition type code."
+};
+
+
+#ifdef SUPPORT_NETBOOT
+/* ifconfig */
+static int
+ifconfig_func (char *arg, int flags)
+{
+  char *svr = 0, *ip = 0, *gw = 0, *sm = 0;
+  
+  if (! eth_probe ())
+    {
+      grub_printf ("No ethernet card found.\n");
+      errnum = ERR_DEV_VALUES;
+      return 1;
+    }
+  
+  while (*arg) 
+    {
+      if (! grub_memcmp ("--server=", arg, sizeof ("--server=") - 1))
+	svr = arg + sizeof("--server=") - 1;
+      else if (! grub_memcmp ("--address=", arg, sizeof ("--address=") - 1))
+	ip = arg + sizeof ("--address=") - 1;
+      else if (! grub_memcmp ("--gateway=", arg, sizeof ("--gateway=") - 1))
+	gw = arg + sizeof ("--gateway=") - 1;
+      else if (! grub_memcmp ("--mask=", arg, sizeof("--mask=") - 1))
+	sm = arg + sizeof ("--mask=") - 1;
+      else
+	{
+	  errnum = ERR_BAD_ARGUMENT;
+	  return 1;
+	}
+      
+      arg = skip_to (0, arg);
+    }
+  
+  if (! ifconfig (ip, sm, gw, svr))
+    {
+      errnum = ERR_BAD_ARGUMENT;
+      return 1;
+    }
+  
+  print_network_configuration ();
+  return 0;
+}
+
+static struct builtin builtin_ifconfig =
+{
+  "ifconfig",
+  ifconfig_func,
+  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
+  "ifconfig [--address=IP] [--gateway=IP] [--mask=MASK] [--server=IP]",
+  "Configure the IP address, the netmask, the gateway and the server"
+  " address or print current network configuration."
+};
+#endif /* SUPPORT_NETBOOT */
+
+
+/* impsprobe */
+static int
+impsprobe_func (char *arg, int flags)
+{
+#ifdef GRUB_UTIL
+  /* In the grub shell, we cannot probe IMPS.  */
+  errnum = ERR_UNRECOGNIZED;
+  return 1;
+#else /* ! GRUB_UTIL */
+  if (!imps_probe ())
+    printf (" No MPS information found or probe failed\n");
+
+  return 0;
+#endif /* ! GRUB_UTIL */
+}
+
+static struct builtin builtin_impsprobe =
+{
+  "impsprobe",
+  impsprobe_func,
+  BUILTIN_CMDLINE,
+  "impsprobe",
+  "Probe the Intel Multiprocessor Specification 1.1 or 1.4"
+  " configuration table and boot the various CPUs which are found into"
+  " a tight loop."
+};
+
+
+/* initrd */
+static int
+initrd_func (char *arg, int flags)
+{
+  switch (kernel_type)
+    {
+    case KERNEL_TYPE_LINUX:
+    case KERNEL_TYPE_BIG_LINUX:
+      if (! load_initrd (arg))
+	return 1;
+      break;
+
+    default:
+      errnum = ERR_NEED_LX_KERNEL;
+      return 1;
+    }
+
+  return 0;
+}
+
+static struct builtin builtin_initrd =
+{
+  "initrd",
+  initrd_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "initrd FILE [ARG ...]",
+  "Load an initial ramdisk FILE for a Linux format boot image and set the"
+  " appropriate parameters in the Linux setup area in memory."
+};
+
+
+/* install */
+static int
+install_func (char *arg, int flags)
+{
+  char *stage1_file, *dest_dev, *file, *addr;
+  char *stage1_buffer = (char *) RAW_ADDR (0x100000);
+  char *stage2_buffer = stage1_buffer + SECTOR_SIZE;
+  char *old_sect = stage2_buffer + SECTOR_SIZE;
+  char *stage2_first_buffer = old_sect + SECTOR_SIZE;
+  char *stage2_second_buffer = stage2_first_buffer + SECTOR_SIZE;
+  /* XXX: Probably SECTOR_SIZE is reasonable.  */
+  char *config_filename = stage2_second_buffer + SECTOR_SIZE;
+  char *dummy = config_filename + SECTOR_SIZE;
+  int new_drive = GRUB_INVALID_DRIVE;
+  int dest_drive, dest_partition, dest_sector;
+  int src_drive, src_partition, src_part_start;
+  int i;
+  struct geometry dest_geom, src_geom;
+  int saved_sector;
+  int stage2_first_sector, stage2_second_sector;
+  char *ptr;
+  int installaddr, installlist;
+  /* Point to the location of the name of a configuration file in Stage 2.  */
+  char *config_file_location;
+  /* If FILE is a Stage 1.5?  */
+  int is_stage1_5 = 0;
+  /* Must call grub_close?  */
+  int is_open = 0;
+  /* If LBA is forced?  */
+  int is_force_lba = 0;
+  /* Was the last sector full? */
+  int last_length = SECTOR_SIZE;
+  
+#ifdef GRUB_UTIL
+  /* If the Stage 2 is in a partition mounted by an OS, this will store
+     the filename under the OS.  */
+  char *stage2_os_file = 0;
+#endif /* GRUB_UTIL */
+  
+  auto void disk_read_savesect_func (int sector, int offset, int length);
+  auto void disk_read_blocklist_func (int sector, int offset, int length);
+  
+  /* Save the first sector of Stage2 in STAGE2_SECT.  */
+  auto void disk_read_savesect_func (int sector, int offset, int length)
+    {
+      if (debug)
+	printf ("[%d]", sector);
+
+      /* ReiserFS has files which sometimes contain data not aligned
+         on sector boundaries.  Returning an error is better than
+         silently failing. */
+      if (offset != 0 || length != SECTOR_SIZE)
+	errnum = ERR_UNALIGNED;
+
+      saved_sector = sector;
+    }
+
+  /* Write SECTOR to INSTALLLIST, and update INSTALLADDR and
+     INSTALLSECT.  */
+  auto void disk_read_blocklist_func (int sector, int offset, int length)
+    {
+      if (debug)
+	printf("[%d]", sector);
+
+      if (offset != 0 || last_length != SECTOR_SIZE)
+	{
+	  /* We found a non-sector-aligned data block. */
+	  errnum = ERR_UNALIGNED;
+	  return;
+	}
+
+      last_length = length;
+
+      if (*((unsigned long *) (installlist - 4))
+	  + *((unsigned short *) installlist) != sector
+	  || installlist == (int) stage2_first_buffer + SECTOR_SIZE + 4)
+	{
+	  installlist -= 8;
+
+	  if (*((unsigned long *) (installlist - 8)))
+	    errnum = ERR_WONT_FIT;
+	  else
+	    {
+	      *((unsigned short *) (installlist + 2)) = (installaddr >> 4);
+	      *((unsigned long *) (installlist - 4)) = sector;
+	    }
+	}
+
+      *((unsigned short *) installlist) += 1;
+      installaddr += 512;
+    }
+
+  /* First, check the GNU-style long option.  */
+  while (1)
+    {
+      if (grub_memcmp ("--force-lba", arg, sizeof ("--force-lba") - 1) == 0)
+	{
+	  is_force_lba = 1;
+	  arg = skip_to (0, arg);
+	}
+#ifdef GRUB_UTIL
+      else if (grub_memcmp ("--stage2=", arg, sizeof ("--stage2=") - 1) == 0)
+	{
+	  stage2_os_file = arg + sizeof ("--stage2=") - 1;
+	  arg = skip_to (0, arg);
+	  nul_terminate (stage2_os_file);
+	}
+#endif /* GRUB_UTIL */
+      else
+	break;
+    }
+  
+  stage1_file = arg;
+  dest_dev = skip_to (0, stage1_file);
+  if (*dest_dev == 'd')
+    {
+      new_drive = 0;
+      dest_dev = skip_to (0, dest_dev);
+    }
+  file = skip_to (0, dest_dev);
+  addr = skip_to (0, file);
+
+  /* Get the installation address.  */
+  if (! safe_parse_maxint (&addr, &installaddr))
+    {
+      /* ADDR is not specified.  */
+      installaddr = 0;
+      ptr = addr;
+      errnum = 0;
+    }
+  else
+    ptr = skip_to (0, addr);
+
+#ifndef NO_DECOMPRESSION
+  /* Do not decompress Stage 1 or Stage 2.  */
+  no_decompression = 1;
+#endif
+
+  /* Read Stage 1.  */
+  is_open = grub_open (stage1_file);
+  if (! is_open
+      || ! grub_read (stage1_buffer, SECTOR_SIZE) == SECTOR_SIZE)
+    goto fail;
+
+  /* Read the old sector from DEST_DEV.  */
+  if (! set_device (dest_dev)
+      || ! open_partition ()
+      || ! devread (0, 0, SECTOR_SIZE, old_sect))
+    goto fail;
+
+  /* Store the information for the destination device.  */
+  dest_drive = current_drive;
+  dest_partition = current_partition;
+  dest_geom = buf_geom;
+  dest_sector = part_start;
+
+  /* Copy the possible DOS BPB, 59 bytes at byte offset 3.  */
+  grub_memmove (stage1_buffer + BOOTSEC_BPB_OFFSET,
+		old_sect + BOOTSEC_BPB_OFFSET,
+		BOOTSEC_BPB_LENGTH);
+
+  /* If for a hard disk, copy the possible MBR/extended part table.  */
+  if (dest_drive & 0x80)
+    grub_memmove (stage1_buffer + STAGE1_WINDOWS_NT_MAGIC,
+		  old_sect + STAGE1_WINDOWS_NT_MAGIC,
+		  STAGE1_PARTEND - STAGE1_WINDOWS_NT_MAGIC);
+
+  /* Check for the version and the signature of Stage 1.  */
+  if (*((short *)(stage1_buffer + STAGE1_VER_MAJ_OFFS)) != COMPAT_VERSION
+      || (*((unsigned short *) (stage1_buffer + BOOTSEC_SIG_OFFSET))
+	  != BOOTSEC_SIGNATURE))
+    {
+      errnum = ERR_BAD_VERSION;
+      goto fail;
+    }
+
+  /* This below is not true any longer. But should we leave this alone?  */
+  
+  /* If DEST_DRIVE is a floppy, Stage 2 must have the iteration probe
+     routine.  */
+  if (! (dest_drive & 0x80)
+      && (*((unsigned char *) (stage1_buffer + BOOTSEC_PART_OFFSET)) == 0x80
+	  || stage1_buffer[BOOTSEC_PART_OFFSET] == 0))
+    {
+      errnum = ERR_BAD_VERSION;
+      goto fail;
+    }
+
+  grub_close ();
+  
+  /* Open Stage 2.  */
+  is_open = grub_open (file);
+  if (! is_open)
+    goto fail;
+
+  src_drive = current_drive;
+  src_partition = current_partition;
+  src_part_start = part_start;
+  src_geom = buf_geom;
+  
+  if (! new_drive)
+    new_drive = src_drive;
+  else if (src_drive != dest_drive)
+    grub_printf ("Warning: the option `d' was not used, but the Stage 1 will"
+		 " be installed on a\ndifferent drive than the drive where"
+		 " the Stage 2 resides.\n");
+
+  /* Set the boot drive.  */
+  *((unsigned char *) (stage1_buffer + STAGE1_BOOT_DRIVE)) = new_drive;
+
+  /* Set the "force LBA" flag.  */
+  *((unsigned char *) (stage1_buffer + STAGE1_FORCE_LBA)) = is_force_lba;
+
+  /* If DEST_DRIVE is a hard disk, enable the workaround, which is
+     for buggy BIOSes which don't pass boot drive correctly. Instead,
+     they pass 0x00 or 0x01 even when booted from 0x80.  */
+  if (dest_drive & BIOS_FLAG_FIXED_DISK)
+    /* Replace the jmp (2 bytes) with double nop's.  */
+    *((unsigned short *) (stage1_buffer + STAGE1_BOOT_DRIVE_CHECK))
+      = 0x9090;
+  
+  /* Read the first sector of Stage 2.  */
+  disk_read_hook = disk_read_savesect_func;
+  if (grub_read (stage2_first_buffer, SECTOR_SIZE) != SECTOR_SIZE)
+    goto fail;
+
+  stage2_first_sector = saved_sector;
+  
+  /* Read the second sector of Stage 2.  */
+  if (grub_read (stage2_second_buffer, SECTOR_SIZE) != SECTOR_SIZE)
+    goto fail;
+
+  stage2_second_sector = saved_sector;
+  
+  /* Check for the version of Stage 2.  */
+  if (*((short *) (stage2_second_buffer + STAGE2_VER_MAJ_OFFS))
+      != COMPAT_VERSION)
+    {
+      errnum = ERR_BAD_VERSION;
+      goto fail;
+    }
+
+  /* Check for the Stage 2 id.  */
+  if (stage2_second_buffer[STAGE2_STAGE2_ID] != STAGE2_ID_STAGE2)
+    is_stage1_5 = 1;
+
+  /* If INSTALLADDR is not specified explicitly in the command-line,
+     determine it by the Stage 2 id.  */
+  if (! installaddr)
+    {
+      if (! is_stage1_5)
+	/* Stage 2.  */
+	installaddr = 0x8000;
+      else
+	/* Stage 1.5.  */
+	installaddr = 0x2000;
+    }
+
+  *((unsigned long *) (stage1_buffer + STAGE1_STAGE2_SECTOR))
+    = stage2_first_sector;
+  *((unsigned short *) (stage1_buffer + STAGE1_STAGE2_ADDRESS))
+    = installaddr;
+  *((unsigned short *) (stage1_buffer + STAGE1_STAGE2_SEGMENT))
+    = installaddr >> 4;
+
+  i = (int) stage2_first_buffer + SECTOR_SIZE - 4;
+  while (*((unsigned long *) i))
+    {
+      if (i < (int) stage2_first_buffer
+	  || (*((int *) (i - 4)) & 0x80000000)
+	  || *((unsigned short *) i) >= 0xA00
+	  || *((short *) (i + 2)) == 0)
+	{
+	  errnum = ERR_BAD_VERSION;
+	  goto fail;
+	}
+
+      *((int *) i) = 0;
+      *((int *) (i - 4)) = 0;
+      i -= 8;
+    }
+
+  installlist = (int) stage2_first_buffer + SECTOR_SIZE + 4;
+  installaddr += SECTOR_SIZE;
+  
+  /* Read the whole of Stage2 except for the first sector.  */
+  grub_seek (SECTOR_SIZE);
+
+  disk_read_hook = disk_read_blocklist_func;
+  if (! grub_read (dummy, -1))
+    goto fail;
+  
+  disk_read_hook = 0;
+  
+  /* Find a string for the configuration filename.  */
+  config_file_location = stage2_second_buffer + STAGE2_VER_STR_OFFS;
+  while (*(config_file_location++))
+    ;
+
+  /* Set the "force LBA" flag for Stage2.  */
+  *((unsigned char *) (stage2_second_buffer + STAGE2_FORCE_LBA))
+    = is_force_lba;
+  
+  if (*ptr == 'p')
+    {
+      *((long *) (stage2_second_buffer + STAGE2_INSTALLPART))
+	= src_partition;
+      if (is_stage1_5)
+	{
+	  /* Reset the device information in FILE if it is a Stage 1.5.  */
+	  unsigned long device = 0xFFFFFFFF;
+
+	  grub_memmove (config_file_location, (char *) &device,
+			sizeof (device));
+	}
+
+      ptr = skip_to (0, ptr);
+    }
+
+  if (*ptr)
+    {
+      grub_strcpy (config_filename, ptr);
+      nul_terminate (config_filename);
+	
+      if (! is_stage1_5)
+	/* If it is a Stage 2, just copy PTR to CONFIG_FILE_LOCATION.  */
+	grub_strcpy (config_file_location, ptr);
+      else
+	{
+	  char *real_config;
+	  unsigned long device;
+
+	  /* Translate the external device syntax to the internal device
+	     syntax.  */
+	  if (! (real_config = set_device (ptr)))
+	    {
+	      /* The Stage 2 PTR does not contain the device name, so
+		 use the root device instead.  */
+	      errnum = ERR_NONE;
+	      current_drive = saved_drive;
+	      current_partition = saved_partition;
+	      real_config = ptr;
+	    }
+	  
+	  if (current_drive == src_drive)
+	    {
+	      /* If the drive where the Stage 2 resides is the same as
+		 the one where the Stage 1.5 resides, do not embed the
+		 drive number.  */
+	      current_drive = GRUB_INVALID_DRIVE;
+	    }
+
+	  device = (current_drive << 24) | current_partition;
+	  grub_memmove (config_file_location, (char *) &device,
+			sizeof (device));
+	  grub_strcpy (config_file_location + sizeof (device),
+		       real_config);
+	}
+
+      /* If a Stage 1.5 is used, then we need to modify the Stage2.  */
+      if (is_stage1_5)
+	{
+	  char *real_config_filename = skip_to (0, ptr);
+	  
+	  is_open = grub_open (config_filename);
+	  if (! is_open)
+	    goto fail;
+
+	  /* Skip the first sector.  */
+	  grub_seek (SECTOR_SIZE);
+	  
+	  disk_read_hook = disk_read_savesect_func;
+	  if (grub_read (stage2_buffer, SECTOR_SIZE) != SECTOR_SIZE)
+	    goto fail;
+	  
+	  disk_read_hook = 0;
+	  grub_close ();
+	  is_open = 0;
+	  
+	  /* Sanity check.  */
+	  if (*(stage2_buffer + STAGE2_STAGE2_ID) != STAGE2_ID_STAGE2)
+	    {
+	      errnum = ERR_BAD_VERSION;
+	      goto fail;
+	    }
+
+	  /* Set the "force LBA" flag for Stage2.  */
+	  *(stage2_buffer + STAGE2_FORCE_LBA) = is_force_lba;
+
+	  /* If REAL_CONFIG_FILENAME is specified, copy it to the Stage2.  */
+	  if (*real_config_filename)
+	    {
+	      /* Specified */
+	      char *location;
+	      
+	      /* Find a string for the configuration filename.  */
+	      location = stage2_buffer + STAGE2_VER_STR_OFFS;
+	      while (*(location++))
+		;
+	      
+	      /* Copy the name.  */
+	      grub_strcpy (location, real_config_filename);
+	    }
+	  
+	  /* Write it to the disk.  */
+	  buf_track = -1;
+
+#ifdef GRUB_UTIL
+	  /* In the grub shell, access the Stage 2 via the OS filesystem
+	     service, if possible.  */
+	  if (stage2_os_file)
+	    {
+	      FILE *fp;
+
+	      fp = fopen (stage2_os_file, "r+");
+	      if (! fp)
+		{
+		  errnum = ERR_FILE_NOT_FOUND;
+		  goto fail;
+		}
+
+	      if (fseek (fp, SECTOR_SIZE, SEEK_SET) != 0)
+		{
+		  fclose (fp);
+		  errnum = ERR_BAD_VERSION;
+		  goto fail;
+		}
+
+	      if (fwrite (stage2_buffer, 1, SECTOR_SIZE, fp)
+		  != SECTOR_SIZE)
+		{
+		  fclose (fp);
+		  errnum = ERR_WRITE;
+		  goto fail;
+		}
+
+	      fclose (fp);
+	    }
+	  else
+#endif /* GRUB_UTIL */
+	    {
+	      if (! devwrite (saved_sector - part_start, 1, stage2_buffer))
+		goto fail;
+	    }
+	}
+    }
+
+  /* Clear the cache.  */
+  buf_track = -1;
+
+  /* Write the modified sectors of Stage2 to the disk.  */
+#ifdef GRUB_UTIL
+  if (! is_stage1_5 && stage2_os_file)
+    {
+      FILE *fp;
+
+      fp = fopen (stage2_os_file, "r+");
+      if (! fp)
+	{
+	  errnum = ERR_FILE_NOT_FOUND;
+	  goto fail;
+	}
+
+      if (fwrite (stage2_first_buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE)
+	{
+	  fclose (fp);
+	  errnum = ERR_WRITE;
+	  goto fail;
+	}
+
+      if (fwrite (stage2_second_buffer, 1, SECTOR_SIZE, fp) != SECTOR_SIZE)
+	{
+	  fclose (fp);
+	  errnum = ERR_WRITE;
+	  goto fail;
+	}
+
+      fclose (fp);
+    }
+  else
+#endif /* GRUB_UTIL */
+    {
+      /* The first.  */
+      current_drive = src_drive;
+      current_partition = src_partition;
+
+      if (! open_partition ())
+	goto fail;
+
+      if (! devwrite (stage2_first_sector - src_part_start, 1,
+		      stage2_first_buffer))
+	goto fail;
+
+      if (! devwrite (stage2_second_sector - src_part_start, 1,
+		      stage2_second_buffer))
+	goto fail;
+    }
+  
+  /* Write the modified sector of Stage 1 to the disk.  */
+  current_drive = dest_drive;
+  current_partition = dest_partition;
+  if (! open_partition ())
+    goto fail;
+
+  devwrite (0, 1, stage1_buffer);
+
+ fail:
+  if (is_open)
+    grub_close ();
+  
+  disk_read_hook = 0;
+  
+#ifndef NO_DECOMPRESSION
+  no_decompression = 0;
+#endif
+
+  return errnum;
+}
+
+static struct builtin builtin_install =
+{
+  "install",
+  install_func,
+  BUILTIN_CMDLINE,
+  "install [--stage2=STAGE2_FILE] [--force-lba] STAGE1 [d] DEVICE STAGE2 [ADDR] [p] [CONFIG_FILE] [REAL_CONFIG_FILE]",
+  "Install STAGE1 on DEVICE, and install a blocklist for loading STAGE2"
+  " as a Stage 2. If the option `d' is present, the Stage 1 will always"
+  " look for the disk where STAGE2 was installed, rather than using"
+  " the booting drive. The Stage 2 will be loaded at address ADDR, which"
+  " will be determined automatically if you don't specify it. If"
+  " the option `p' or CONFIG_FILE is present, then the first block"
+  " of Stage 2 is patched with new values of the partition and name"
+  " of the configuration file used by the true Stage 2 (for a Stage 1.5,"
+  " this is the name of the true Stage 2) at boot time. If STAGE2 is a Stage"
+  " 1.5 and REAL_CONFIG_FILE is present, then the Stage 2 CONFIG_FILE is"
+  " patched with the configuration filename REAL_CONFIG_FILE."
+  " If the option `--force-lba' is specified, disable some sanity checks"
+  " for LBA mode. If the option `--stage2' is specified, rewrite the Stage"
+  " 2 via your OS's filesystem instead of the raw device."
+};
+
+
+/* ioprobe */
+static int
+ioprobe_func (char *arg, int flags)
+{
+#ifdef GRUB_UTIL
+  
+  errnum = ERR_UNRECOGNIZED;
+  return 1;
+  
+#else /* ! GRUB_UTIL */
+  
+  unsigned short *port;
+  
+  /* Get the drive number.  */
+  set_device (arg);
+  if (errnum)
+    return 1;
+
+  /* Clean out IO_MAP.  */
+  grub_memset ((char *) io_map, 0, IO_MAP_SIZE * sizeof (unsigned short));
+
+  /* Track the int13 handler.  */
+  track_int13 (current_drive);
+  
+  /* Print out the result.  */
+  for (port = io_map; *port != 0; port++)
+    grub_printf (" 0x%x", (unsigned int) *port);
+
+  return 0;
+  
+#endif /* ! GRUB_UTIL */
+}
+
+static struct builtin builtin_ioprobe =
+{
+  "ioprobe",
+  ioprobe_func,
+  BUILTIN_CMDLINE,
+  "ioprobe DRIVE",
+  "Probe I/O ports used for the drive DRIVE."
+};
+
+
+/* kernel */
+static int
+kernel_func (char *arg, int flags)
+{
+  int len;
+  kernel_t suggested_type = KERNEL_TYPE_NONE;
+  unsigned long load_flags = 0;
+
+#ifndef AUTO_LINUX_MEM_OPT
+  load_flags |= KERNEL_LOAD_NO_MEM_OPTION;
+#endif
+
+  /* Deal with GNU-style long options.  */
+  while (1)
+    {
+      /* If the option `--type=TYPE' is specified, convert the string to
+	 a kernel type.  */
+      if (grub_memcmp (arg, "--type=", 7) == 0)
+	{
+	  arg += 7;
+	  
+	  if (grub_memcmp (arg, "netbsd", 6) == 0)
+	    suggested_type = KERNEL_TYPE_NETBSD;
+	  else if (grub_memcmp (arg, "freebsd", 7) == 0)
+	    suggested_type = KERNEL_TYPE_FREEBSD;
+	  else if (grub_memcmp (arg, "openbsd", 7) == 0)
+	    /* XXX: For now, OpenBSD is identical to NetBSD, from GRUB's
+	       point of view.  */
+	    suggested_type = KERNEL_TYPE_NETBSD;
+	  else if (grub_memcmp (arg, "linux", 5) == 0)
+	    suggested_type = KERNEL_TYPE_LINUX;
+	  else if (grub_memcmp (arg, "biglinux", 8) == 0)
+	    suggested_type = KERNEL_TYPE_BIG_LINUX;
+	  else if (grub_memcmp (arg, "multiboot", 9) == 0)
+	    suggested_type = KERNEL_TYPE_MULTIBOOT;
+	  else
+	    {
+	      errnum = ERR_BAD_ARGUMENT;
+	      return 1;
+	    }
+	}
+      /* If the `--no-mem-option' is specified, don't pass a Linux's mem
+	 option automatically. If the kernel is another type, this flag
+	 has no effect.  */
+    else if (grub_memcmp (arg, "--no-mem-option", 15) == 0)
+        load_flags |= KERNEL_LOAD_NO_MEM_OPTION;
+    else if (grub_memcmp(arg, "--use-cmd-line", 14) == 0) {
+        if (!cmdline_loaded) {
+            errnum = ERR_BAD_ARGUMENT;
+            return 1;
+        }
+    }
+      else
+	break;
+
+      /* Try the next.  */
+      arg = skip_to (0, arg);
+    }
+
+  if (!cmdline_loaded) {
+    len = grub_strlen (arg);
+
+    /* Reset MB_CMDLINE.  */
+    mb_cmdline = (char *) MB_CMDLINE_BUF;
+    if (len + 1 > MB_CMDLINE_BUFLEN)
+      {
+        errnum = ERR_WONT_FIT;
+        return 1;
+      }
+    grub_memmove (mb_cmdline, arg, len + 1);
+  } else {
+    len = grub_strlen(mb_cmdline);
+  }
+
+
+  /* Copy the command-line to MB_CMDLINE.  */
+  kernel_type = load_image (arg, mb_cmdline, suggested_type, load_flags);
+  if (kernel_type == KERNEL_TYPE_NONE)
+    return 1;
+
+  mb_cmdline += len + 1;
+
+  return 0;
+}
+
+static struct builtin builtin_kernel =
+{
+  "kernel",
+  kernel_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "kernel [--no-mem-option] [--type=TYPE] [--use-cmd-line] FILE [ARG ...]",
+  "Attempt to load the primary boot image from FILE. The rest of the"
+  " line is passed verbatim as the \"kernel command line\".  Any modules"
+  " must be reloaded after using this command. The option --type is used"
+  " to suggest what type of kernel to be loaded. TYPE must be either of"
+  " \"netbsd\", \"freebsd\", \"openbsd\", \"linux\", \"biglinux\" and"
+  " \"multiboot\". The option --no-mem-option tells GRUB not to pass a"
+  " Linux's mem option automatically. If the option --use-cmd-line is"
+  " provided, then GRUB ignores the rest of the line, and instead passes"
+  " the command line loaded with \"cmdline\" command to the kernel."
+};
+
+
+/* cmdline */
+static int
+cmdline_func (char *arg, int flags)
+{
+  int len;
+
+  if (!grub_open(arg))
+    return 1;
+
+  if (filemax > MB_CMDLINE_BUFLEN) {
+      grub_close();
+      errnum = ERR_WONT_FIT;
+      return 1;
+  }
+
+  if (!(len = grub_read (mb_cmdline, MB_CMDLINE_BUFLEN - 1))) {
+      grub_close();
+      return 1;
+  }
+
+  grub_close();
+
+  mb_cmdline[len] = 0;
+  grub_printf("Loaded kernel cmdline args: %s\n", mb_cmdline);
+  cmdline_loaded = 1;
+  return 0;
+}
+
+static struct builtin builtin_cmdline =
+{
+  "cmdline",
+  cmdline_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "cmdline FILE",
+  "Attempt to load a file that contains the default kernel command line."
+};
+
+
+/* lock */
+static int
+lock_func (char *arg, int flags)
+{
+  if (! auth && password)
+    {
+      errnum = ERR_PRIVILEGED;
+      return 1;
+    }
+
+  return 0;
+}
+
+static struct builtin builtin_lock =
+{
+  "lock",
+  lock_func,
+  BUILTIN_CMDLINE,
+  "lock",
+  "Break a command execution unless the user is authenticated."
+};
+  
+
+/* makeactive */
+static int
+makeactive_func (char *arg, int flags)
+{
+  if (! make_saved_active ())
+    return 1;
+
+  return 0;
+}
+
+static struct builtin builtin_makeactive =
+{
+  "makeactive",
+  makeactive_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "makeactive",
+  "Set the active partition on the root disk to GRUB's root device."
+  " This command is limited to _primary_ PC partitions on a hard disk."
+};
+
+
+/* map */
+/* Map FROM_DRIVE to TO_DRIVE.  */
+static int
+map_func (char *arg, int flags)
+{
+  char *to_drive;
+  char *from_drive;
+  unsigned long to, from;
+  int i;
+  
+  to_drive = arg;
+  from_drive = skip_to (0, arg);
+
+  /* Get the drive number for TO_DRIVE.  */
+  set_device (to_drive);
+  if (errnum)
+    return 1;
+  to = current_drive;
+
+  /* Get the drive number for FROM_DRIVE.  */
+  set_device (from_drive);
+  if (errnum)
+    return 1;
+  from = current_drive;
+
+  /* Search for an empty slot in BIOS_DRIVE_MAP.  */
+  for (i = 0; i < DRIVE_MAP_SIZE; i++)
+    {
+      /* Perhaps the user wants to override the map.  */
+      if ((bios_drive_map[i] & 0xff) == from)
+	break;
+      
+      if (! bios_drive_map[i])
+	break;
+    }
+
+  if (i == DRIVE_MAP_SIZE)
+    {
+      errnum = ERR_WONT_FIT;
+      return 1;
+    }
+
+  if (to == from)
+    /* If TO is equal to FROM, delete the entry.  */
+    grub_memmove ((char *) &bios_drive_map[i], (char *) &bios_drive_map[i + 1],
+		  sizeof (unsigned short) * (DRIVE_MAP_SIZE - i));
+  else
+    bios_drive_map[i] = from | (to << 8);
+  
+  return 0;
+}
+
+static struct builtin builtin_map =
+{
+  "map",
+  map_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "map TO_DRIVE FROM_DRIVE",
+  "Map the drive FROM_DRIVE to the drive TO_DRIVE. This is necessary"
+  " when you chain-load some operating systems, such as DOS, if such an"
+  " OS resides at a non-first drive."
+};
+
+
+#ifdef USE_MD5_PASSWORDS
+/* md5crypt */
+static int
+md5crypt_func (char *arg, int flags)
+{
+  char crypted[36];
+  char key[32];
+  unsigned int seed;
+  int i;
+  const char *const seedchars =
+    "./0123456789ABCDEFGHIJKLMNOPQRST"
+    "UVWXYZabcdefghijklmnopqrstuvwxyz";
+  
+  /* First create a salt.  */
+
+  /* The magical prefix.  */
+  grub_memset (crypted, 0, sizeof (crypted));
+  grub_memmove (crypted, "$1$", 3);
+
+  /* Create the length of a salt.  */
+  seed = currticks ();
+
+  /* Generate a salt.  */
+  for (i = 0; i < 8 && seed; i++)
+    {
+      /* FIXME: This should be more random.  */
+      crypted[3 + i] = seedchars[seed & 0x3f];
+      seed >>= 6;
+    }
+
+  /* A salt must be terminated with `$', if it is less than 8 chars.  */
+  crypted[3 + i] = '$';
+
+#ifdef DEBUG_MD5CRYPT
+  grub_printf ("salt = %s\n", crypted);
+#endif
+  
+  /* Get a password.  */
+  grub_memset (key, 0, sizeof (key));
+  get_cmdline ("Password: ", key, sizeof (key) - 1, '*', 0);
+
+  /* Crypt the key.  */
+  make_md5_password (key, crypted);
+
+  grub_printf ("Encrypted: %s\n", crypted);
+  return 0;
+}
+
+static struct builtin builtin_md5crypt =
+{
+  "md5crypt",
+  md5crypt_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "md5crypt",
+  "Generate a password in MD5 format."
+};
+#endif /* USE_MD5_PASSWORDS */
+
+
+/* module */
+static int
+module_func (char *arg, int flags)
+{
+  int len = grub_strlen (arg);
+
+  switch (kernel_type)
+    {
+    case KERNEL_TYPE_MULTIBOOT:
+      if (mb_cmdline + len + 1 > (char *) MB_CMDLINE_BUF + MB_CMDLINE_BUFLEN)
+	{
+	  errnum = ERR_WONT_FIT;
+	  return 1;
+	}
+      grub_memmove (mb_cmdline, arg, len + 1);
+      if (! load_module (arg, mb_cmdline))
+	return 1;
+      mb_cmdline += len + 1;
+      break;
+
+    case KERNEL_TYPE_LINUX:
+    case KERNEL_TYPE_BIG_LINUX:
+      if (! load_initrd (arg))
+	return 1;
+      break;
+
+    default:
+      errnum = ERR_NEED_MB_KERNEL;
+      return 1;
+    }
+
+  return 0;
+}
+
+static struct builtin builtin_module =
+{
+  "module",
+  module_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "module FILE [ARG ...]",
+  "Load a boot module FILE for a Multiboot format boot image (no"
+  " interpretation of the file contents is made, so users of this"
+  " command must know what the kernel in question expects). The"
+  " rest of the line is passed as the \"module command line\", like"
+  " the `kernel' command."
+};
+
+
+/* modulenounzip */
+static int
+modulenounzip_func (char *arg, int flags)
+{
+  int ret;
+
+#ifndef NO_DECOMPRESSION
+  no_decompression = 1;
+#endif
+
+  ret = module_func (arg, flags);
+
+#ifndef NO_DECOMPRESSION
+  no_decompression = 0;
+#endif
+
+  return ret;
+}
+
+static struct builtin builtin_modulenounzip =
+{
+  "modulenounzip",
+  modulenounzip_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "modulenounzip FILE [ARG ...]",
+  "The same as `module', except that automatic decompression is"
+  " disabled."
+};
+
+
+/* pager [on|off] */
+static int
+pager_func (char *arg, int flags)
+{
+  /* If ARG is empty, toggle the flag.  */
+  if (! *arg)
+    use_pager = ! use_pager;
+  else if (grub_memcmp (arg, "on", 2) == 0)
+    use_pager = 1;
+  else if (grub_memcmp (arg, "off", 3) == 0)
+    use_pager = 0;
+  else
+    {
+      errnum = ERR_BAD_ARGUMENT;
+      return 1;
+    }
+
+  grub_printf (" Internal pager is now %s\n", use_pager ? "on" : "off");
+  return 0;
+}
+
+static struct builtin builtin_pager =
+{
+  "pager",
+  pager_func,
+  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
+  "pager [FLAG]",
+  "Toggle pager mode with no argument. If FLAG is given and its value"
+  " is `on', turn on the mode. If FLAG is `off', turn off the mode."
+};
+
+
+/* partnew PART TYPE START LEN */
+static int
+partnew_func (char *arg, int flags)
+{
+  int new_type, new_start, new_len;
+  int start_cl, start_ch, start_dh;
+  int end_cl, end_ch, end_dh;
+  int entry;
+  char mbr[512];
+
+  /* Convert a LBA address to a CHS address in the INT 13 format.  */
+  auto void lba_to_chs (int lba, int *cl, int *ch, int *dh);
+  void lba_to_chs (int lba, int *cl, int *ch, int *dh)
+    {
+      int cylinder, head, sector;
+
+      sector = lba % buf_geom.sectors + 1;
+      head = (lba / buf_geom.sectors) % buf_geom.heads;
+      cylinder = lba / (buf_geom.sectors * buf_geom.heads);
+
+      if (cylinder >= buf_geom.cylinders)
+	cylinder = buf_geom.cylinders - 1;
+      
+      *cl = sector | ((cylinder & 0x300) >> 2);
+      *ch = cylinder & 0xFF;
+      *dh = head;
+    }
+      
+  /* Get the drive and the partition.  */
+  if (! set_device (arg))
+    return 1;
+
+  /* The drive must be a hard disk.  */
+  if (! (current_drive & 0x80))
+    {
+      errnum = ERR_BAD_ARGUMENT;
+      return 1;
+    }
+
+  /* The partition must a primary partition.  */
+  if ((current_partition >> 16) > 3
+      || (current_partition & 0xFFFF) != 0xFFFF)
+    {
+      errnum = ERR_BAD_ARGUMENT;
+      return 1;
+    }
+
+  entry = current_partition >> 16;
+  
+  /* Get the new partition type.  */
+  arg = skip_to (0, arg);
+  if (! safe_parse_maxint (&arg, &new_type))
+    return 1;
+
+  /* The partition type is unsigned char.  */
+  if (new_type > 0xFF)
+    {
+      errnum = ERR_BAD_ARGUMENT;
+      return 1;
+    }
+
+  /* Get the new partition start.  */
+  arg = skip_to (0, arg);
+  if (! safe_parse_maxint (&arg, &new_start))
+    return 1;
+  
+  /* Get the new partition length.  */
+  arg = skip_to (0, arg);
+  if (! safe_parse_maxint (&arg, &new_len))
+    return 1;
+
+  /* Read the MBR.  */
+  if (! rawread (current_drive, 0, 0, SECTOR_SIZE, mbr))
+    return 1;
+
+  /* Check if the new partition will fit in the disk.  */
+  if (new_start + new_len > buf_geom.total_sectors)
+    {
+      errnum = ERR_GEOM;
+      return 1;
+    }
+
+  /* Store the partition information in the MBR.  */
+  lba_to_chs (new_start, &start_cl, &start_ch, &start_dh);
+  lba_to_chs (new_start + new_len - 1, &end_cl, &end_ch, &end_dh);
+
+  PC_SLICE_FLAG (mbr, entry) = 0;
+  PC_SLICE_HEAD (mbr, entry) = start_dh;
+  PC_SLICE_SEC (mbr, entry) = start_cl;
+  PC_SLICE_CYL (mbr, entry) = start_ch;
+  PC_SLICE_TYPE (mbr, entry) = new_type;
+  PC_SLICE_EHEAD (mbr, entry) = end_dh;
+  PC_SLICE_ESEC (mbr, entry) = end_cl;
+  PC_SLICE_ECYL (mbr, entry) = end_ch;
+  PC_SLICE_START (mbr, entry) = new_start;
+  PC_SLICE_LENGTH (mbr, entry) = new_len;
+
+  /* Make sure that the MBR has a valid signature.  */
+  PC_MBR_SIG (mbr) = PC_MBR_SIGNATURE;
+  
+  /* Write back the MBR to the disk.  */
+  buf_track = -1;
+  if (! rawwrite (current_drive, 0, mbr))
+    return 1;
+
+  return 0;
+}
+
+static struct builtin builtin_partnew =
+{
+  "partnew",
+  partnew_func,
+  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
+  "partnew PART TYPE START LEN",
+  "Create a primary partition at the starting address START with the"
+  " length LEN, with the type TYPE. START and LEN are in sector units."
+};
+
+
+/* parttype PART TYPE */
+static int
+parttype_func (char *arg, int flags)
+{
+  int new_type;
+  unsigned long part = 0xFFFFFF;
+  unsigned long start, len, offset, ext_offset;
+  int entry, type;
+  char mbr[512];
+
+  /* Get the drive and the partition.  */
+  if (! set_device (arg))
+    return 1;
+
+  /* The drive must be a hard disk.  */
+  if (! (current_drive & 0x80))
+    {
+      errnum = ERR_BAD_ARGUMENT;
+      return 1;
+    }
+  
+  /* The partition must be a PC slice.  */
+  if ((current_partition >> 16) == 0xFF
+      || (current_partition & 0xFFFF) != 0xFFFF)
+    {
+      errnum = ERR_BAD_ARGUMENT;
+      return 1;
+    }
+
+  /* Get the new partition type.  */
+  arg = skip_to (0, arg);
+  if (! safe_parse_maxint (&arg, &new_type))
+    return 1;
+
+  /* The partition type is unsigned char.  */
+  if (new_type > 0xFF)
+    {
+      errnum = ERR_BAD_ARGUMENT;
+      return 1;
+    }
+
+  /* Look for the partition.  */
+  while (next_partition (current_drive, 0xFFFFFF, &part, &type,
+			 &start, &len, &offset, &entry,
+			 &ext_offset, mbr))
+    {
+      if (part == current_partition)
+	{
+	  /* Found.  */
+
+	  /* Set the type to NEW_TYPE.  */
+	  PC_SLICE_TYPE (mbr, entry) = new_type;
+	  
+	  /* Write back the MBR to the disk.  */
+	  buf_track = -1;
+	  if (! rawwrite (current_drive, offset, mbr))
+	    return 1;
+
+	  /* Succeed.  */
+	  return 0;
+	}
+    }
+
+  /* The partition was not found.  ERRNUM was set by next_partition.  */
+  return 1;
+}
+
+static struct builtin builtin_parttype =
+{
+  "parttype",
+  parttype_func,
+  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
+  "parttype PART TYPE",
+  "Change the type of the partition PART to TYPE."
+};
+
+
+/* password */
+static int
+password_func (char *arg, int flags)
+{
+  int len;
+  password_t type = PASSWORD_PLAIN;
+
+#ifdef USE_MD5_PASSWORDS
+  if (grub_memcmp (arg, "--md5", 5) == 0)
+    {
+      type = PASSWORD_MD5;
+      arg = skip_to (0, arg);
+    }
+#endif
+  if (grub_memcmp (arg, "--", 2) == 0)
+    {
+      type = PASSWORD_UNSUPPORTED;
+      arg = skip_to (0, arg);
+    }
+
+  if ((flags & (BUILTIN_CMDLINE | BUILTIN_SCRIPT)) != 0)
+    {
+      /* Do password check! */
+      char entered[32];
+      
+      /* Wipe out any previously entered password */
+      entered[0] = 0;
+      get_cmdline ("Password: ", entered, 31, '*', 0);
+
+      nul_terminate (arg);
+      if (check_password (entered, arg, type) != 0)
+	{
+	  errnum = ERR_PRIVILEGED;
+	  return 1;
+	}
+    }
+  else
+    {
+      len = grub_strlen (arg);
+      
+      /* PASSWORD NUL NUL ... */
+      if (len + 2 > PASSWORD_BUFLEN)
+	{
+	  errnum = ERR_WONT_FIT;
+	  return 1;
+	}
+      
+      /* Copy the password and clear the rest of the buffer.  */
+      password = (char *) PASSWORD_BUF;
+      grub_memmove (password, arg, len);
+      grub_memset (password + len, 0, PASSWORD_BUFLEN - len);
+      password_type = type;
+    }
+  return 0;
+}
+
+static struct builtin builtin_password =
+{
+  "password",
+  password_func,
+  BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_NO_ECHO,
+  "password [--md5] PASSWD [FILE]",
+  "If used in the first section of a menu file, disable all"
+  " interactive editing control (menu entry editor and"
+  " command line). If the password PASSWD is entered, it loads the"
+  " FILE as a new config file and restarts the GRUB Stage 2. If you"
+  " omit the argument FILE, then GRUB just unlocks privileged"
+  " instructions.  You can also use it in the script section, in"
+  " which case it will ask for the password, before continueing."
+  " The option --md5 tells GRUB that PASSWD is encrypted with"
+  " md5crypt."
+};
+
+
+/* pause */
+static int
+pause_func (char *arg, int flags)
+{
+  printf("%s\n", arg);
+
+  /* If ESC is returned, then abort this entry.  */
+  if (ASCII_CHAR (getkey ()) == 27)
+    return 1;
+
+  return 0;
+}
+
+static struct builtin builtin_pause =
+{
+  "pause",
+  pause_func,
+  BUILTIN_CMDLINE | BUILTIN_NO_ECHO,
+  "pause [MESSAGE ...]",
+  "Print MESSAGE, then wait until a key is pressed."
+};
+
+
+#ifdef GRUB_UTIL
+/* quit */
+static int
+quit_func (char *arg, int flags)
+{
+  stop ();
+  
+  /* Never reach here.  */
+  return 0;
+}
+
+static struct builtin builtin_quit =
+{
+  "quit",
+  quit_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "quit",
+  "Exit from the GRUB shell."
+};
+#endif /* GRUB_UTIL */
+
+
+#ifdef SUPPORT_NETBOOT
+/* rarp */
+static int
+rarp_func (char *arg, int flags)
+{
+  if (! rarp ())
+    {
+      if (errnum == ERR_NONE)
+	errnum = ERR_DEV_VALUES;
+
+      return 1;
+    }
+
+  /* Notify the configuration.  */
+  print_network_configuration ();
+  return 0;
+}
+
+static struct builtin builtin_rarp =
+{
+  "rarp",
+  rarp_func,
+  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
+  "rarp",
+  "Initialize a network device via RARP."
+};
+#endif /* SUPPORT_NETBOOT */
+
+
+static int
+read_func (char *arg, int flags)
+{
+  int addr;
+
+  if (! safe_parse_maxint (&arg, &addr))
+    return 1;
+
+  grub_printf ("Address 0x%x: Value 0x%x\n",
+	       addr, *((unsigned *) RAW_ADDR (addr)));
+  return 0;
+}
+
+static struct builtin builtin_read =
+{
+  "read",
+  read_func,
+  BUILTIN_CMDLINE,
+  "read ADDR",
+  "Read a 32-bit value from memory at address ADDR and"
+  " display it in hex format."
+};
+
+
+/* reboot */
+static int
+reboot_func (char *arg, int flags)
+{
+  grub_reboot ();
+
+  /* Never reach here.  */
+  return 1;
+}
+
+static struct builtin builtin_reboot =
+{
+  "reboot",
+  reboot_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "reboot",
+  "Reboot your system."
+};
+
+
+/* Print the root device information.  */
+static void
+print_root_device (void)
+{
+  if (saved_drive == NETWORK_DRIVE)
+    {
+      /* Network drive.  */
+      grub_printf (" (nd):");
+    }
+  else if (saved_drive & 0x80)
+    {
+      /* Hard disk drive.  */
+      grub_printf (" (hd%d", saved_drive - 0x80);
+      
+      if ((saved_partition & 0xFF0000) != 0xFF0000)
+	grub_printf (",%d", saved_partition >> 16);
+
+      if ((saved_partition & 0x00FF00) != 0x00FF00)
+	grub_printf (",%c", ((saved_partition >> 8) & 0xFF) + 'a');
+
+      grub_printf ("):");
+    }
+  else
+    {
+      /* Floppy disk drive.  */
+      grub_printf (" (fd%d):", saved_drive);
+    }
+
+  /* Print the filesystem information.  */
+  current_partition = saved_partition;
+  current_drive = saved_drive;
+  print_fsys_type ();
+}
+
+static int
+real_root_func (char *arg, int attempt_mount)
+{
+  int hdbias = 0;
+  char *biasptr;
+  char *next;
+
+  /* If ARG is empty, just print the current root device.  */
+  if (! *arg)
+    {
+      print_root_device ();
+      return 0;
+    }
+  
+  /* Call set_device to get the drive and the partition in ARG.  */
+  next = set_device (arg);
+  if (! next)
+    return 1;
+
+  /* Ignore ERR_FSYS_MOUNT.  */
+  if (attempt_mount)
+    {
+      if (! open_device () && errnum != ERR_FSYS_MOUNT)
+	return 1;
+    }
+  else
+    {
+      /* This is necessary, because the location of a partition table
+	 must be set appropriately.  */
+      if (open_partition ())
+	{
+	  set_bootdev (0);
+	  if (errnum)
+	    return 1;
+	}
+    }
+  
+  /* Clear ERRNUM.  */
+  errnum = 0;
+  saved_partition = current_partition;
+  saved_drive = current_drive;
+
+  if (attempt_mount)
+    {
+      /* BSD and chainloading evil hacks !!  */
+      biasptr = skip_to (0, next);
+      safe_parse_maxint (&biasptr, &hdbias);
+      errnum = 0;
+      bootdev = set_bootdev (hdbias);
+      if (errnum)
+	return 1;
+      
+      /* Print the type of the filesystem.  */
+      print_fsys_type ();
+    }
+  
+  return 0;
+}
+
+static int
+root_func (char *arg, int flags)
+{
+  return real_root_func (arg, 1);
+}
+
+static struct builtin builtin_root =
+{
+  "root",
+  root_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "root [DEVICE [HDBIAS]]",
+  "Set the current \"root device\" to the device DEVICE, then"
+  " attempt to mount it to get the partition size (for passing the"
+  " partition descriptor in `ES:ESI', used by some chain-loaded"
+  " bootloaders), the BSD drive-type (for booting BSD kernels using"
+  " their native boot format), and correctly determine "
+  " the PC partition where a BSD sub-partition is located. The"
+  " optional HDBIAS parameter is a number to tell a BSD kernel"
+  " how many BIOS drive numbers are on controllers before the current"
+  " one. For example, if there is an IDE disk and a SCSI disk, and your"
+  " FreeBSD root partition is on the SCSI disk, then use a `1' for HDBIAS."
+};
+
+
+/* rootnoverify */
+static int
+rootnoverify_func (char *arg, int flags)
+{
+  return real_root_func (arg, 0);
+}
+
+static struct builtin builtin_rootnoverify =
+{
+  "rootnoverify",
+  rootnoverify_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "rootnoverify [DEVICE [HDBIAS]]",
+  "Similar to `root', but don't attempt to mount the partition. This"
+  " is useful for when an OS is outside of the area of the disk that"
+  " GRUB can read, but setting the correct root device is still"
+  " desired. Note that the items mentioned in `root' which"
+  " derived from attempting the mount will NOT work correctly."
+};
+
+
+/* savedefault */
+static int
+savedefault_func (char *arg, int flags)
+{
+#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
+  unsigned long tmp_drive = saved_drive;
+  unsigned long tmp_partition = saved_partition;
+  char *default_file = (char *) DEFAULT_FILE_BUF;
+  char buf[10];
+  char sect[SECTOR_SIZE];
+  int entryno;
+  int sector_count = 0;
+  int saved_sectors[2];
+  int saved_offsets[2];
+  int saved_lengths[2];
+
+  /* Save sector information about at most two sectors.  */
+  auto void disk_read_savesect_func (int sector, int offset, int length);
+  void disk_read_savesect_func (int sector, int offset, int length)
+    {
+      if (sector_count < 2)
+	{
+	  saved_sectors[sector_count] = sector;
+	  saved_offsets[sector_count] = offset;
+	  saved_lengths[sector_count] = length;
+	}
+      sector_count++;
+    }
+  
+  /* This command is only useful when you boot an entry from the menu
+     interface.  */
+  if (! (flags & BUILTIN_SCRIPT))
+    {
+      errnum = ERR_UNRECOGNIZED;
+      return 1;
+    }
+
+  /* Determine a saved entry number.  */
+  if (*arg)
+    {
+      if (grub_memcmp (arg, "fallback", sizeof ("fallback") - 1) == 0)
+	{
+	  int i;
+	  int index = 0;
+	  
+	  for (i = 0; i < MAX_FALLBACK_ENTRIES; i++)
+	    {
+	      if (fallback_entries[i] < 0)
+		break;
+	      if (fallback_entries[i] == current_entryno)
+		{
+		  index = i + 1;
+		  break;
+		}
+	    }
+	  
+	  if (index >= MAX_FALLBACK_ENTRIES || fallback_entries[index] < 0)
+	    {
+	      /* This is the last.  */
+	      errnum = ERR_BAD_ARGUMENT;
+	      return 1;
+	    }
+
+	  entryno = fallback_entries[index];
+	}
+      else if (! safe_parse_maxint (&arg, &entryno))
+	return 1;
+    }
+  else
+    entryno = current_entryno;
+
+  /* Open the default file.  */
+  saved_drive = boot_drive;
+  saved_partition = install_partition;
+  if (grub_open (default_file))
+    {
+      int len;
+      
+      disk_read_hook = disk_read_savesect_func;
+      len = grub_read (buf, sizeof (buf));
+      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;
+	}
+      
+      /* Set up a string to be written.  */
+      grub_memset (buf, '\n', sizeof (buf));
+      grub_sprintf (buf, "%d", entryno);
+      
+      if (saved_lengths[0] < sizeof (buf))
+	{
+	  /* The file is anchored to another file and the first few bytes
+	     are spanned in two sectors. Uggh...  */
+	  if (! rawread (current_drive, saved_sectors[0], 0, SECTOR_SIZE,
+			 sect))
+	    goto fail;
+	  grub_memmove (sect + saved_offsets[0], buf, saved_lengths[0]);
+	  if (! rawwrite (current_drive, saved_sectors[0], sect))
+	    goto fail;
+
+	  if (! rawread (current_drive, saved_sectors[1], 0, SECTOR_SIZE,
+			 sect))
+	    goto fail;
+	  grub_memmove (sect + saved_offsets[1],
+			buf + saved_lengths[0],
+			sizeof (buf) - saved_lengths[0]);
+	  if (! rawwrite (current_drive, saved_sectors[1], sect))
+	    goto fail;
+	}
+      else
+	{
+	  /* This is a simple case. It fits into a single sector.  */
+	  if (! rawread (current_drive, saved_sectors[0], 0, SECTOR_SIZE,
+			 sect))
+	    goto fail;
+	  grub_memmove (sect + saved_offsets[0], buf, sizeof (buf));
+	  if (! rawwrite (current_drive, saved_sectors[0], sect))
+	    goto fail;
+	}
+
+      /* Clear the cache.  */
+      buf_track = -1;
+    }
+
+ fail:
+  saved_drive = tmp_drive;
+  saved_partition = tmp_partition;
+  return errnum;
+#else /* ! SUPPORT_DISKLESS && ! GRUB_UTIL */
+  errnum = ERR_UNRECOGNIZED;
+  return 1;
+#endif /* ! SUPPORT_DISKLESS && ! GRUB_UTIL */
+}
+
+static struct builtin builtin_savedefault =
+{
+  "savedefault",
+  savedefault_func,
+  BUILTIN_CMDLINE,
+  "savedefault [NUM | `fallback']",
+  "Save the current entry as the default boot entry if no argument is"
+  " specified. If a number is specified, this number is saved. If"
+  " `fallback' is used, next fallback entry is saved."
+};
+
+
+#ifdef SUPPORT_SERIAL
+/* serial */
+static int
+serial_func (char *arg, int flags)
+{
+  unsigned short port = serial_hw_get_port (0);
+  unsigned int speed = 9600;
+  int word_len = UART_8BITS_WORD;
+  int parity = UART_NO_PARITY;
+  int stop_bit_len = UART_1_STOP_BIT;
+
+  /* Process GNU-style long options.
+     FIXME: We should implement a getopt-like function, to avoid
+     duplications.  */
+  while (1)
+    {
+      if (grub_memcmp (arg, "--unit=", sizeof ("--unit=") - 1) == 0)
+	{
+	  char *p = arg + sizeof ("--unit=") - 1;
+	  int unit;
+	  
+	  if (! safe_parse_maxint (&p, &unit))
+	    return 1;
+	  
+	  if (unit < 0 || unit > 3)
+	    {
+	      errnum = ERR_DEV_VALUES;
+	      return 1;
+	    }
+
+	  port = serial_hw_get_port (unit);
+	}
+      else if (grub_memcmp (arg, "--speed=", sizeof ("--speed=") - 1) == 0)
+	{
+	  char *p = arg + sizeof ("--speed=") - 1;
+	  int num;
+	  
+	  if (! safe_parse_maxint (&p, &num))
+	    return 1;
+
+	  speed = (unsigned int) num;
+	}
+      else if (grub_memcmp (arg, "--port=", sizeof ("--port=") - 1) == 0)
+	{
+	  char *p = arg + sizeof ("--port=") - 1;
+	  int num;
+	  
+	  if (! safe_parse_maxint (&p, &num))
+	    return 1;
+
+	  port = (unsigned short) num;
+	}
+      else if (grub_memcmp (arg, "--word=", sizeof ("--word=") - 1) == 0)
+	{
+	  char *p = arg + sizeof ("--word=") - 1;
+	  int len;
+	  
+	  if (! safe_parse_maxint (&p, &len))
+	    return 1;
+
+	  switch (len)
+	    {
+	    case 5: word_len = UART_5BITS_WORD; break;
+	    case 6: word_len = UART_6BITS_WORD; break;
+	    case 7: word_len = UART_7BITS_WORD; break;
+	    case 8: word_len = UART_8BITS_WORD; break;
+	    default:
+	      errnum = ERR_BAD_ARGUMENT;
+	      return 1;
+	    }
+	}
+      else if (grub_memcmp (arg, "--stop=", sizeof ("--stop=") - 1) == 0)
+	{
+	  char *p = arg + sizeof ("--stop=") - 1;
+	  int len;
+	  
+	  if (! safe_parse_maxint (&p, &len))
+	    return 1;
+
+	  switch (len)
+	    {
+	    case 1: stop_bit_len = UART_1_STOP_BIT; break;
+	    case 2: stop_bit_len = UART_2_STOP_BITS; break;
+	    default:
+	      errnum = ERR_BAD_ARGUMENT;
+	      return 1;
+	    }
+	}
+      else if (grub_memcmp (arg, "--parity=", sizeof ("--parity=") - 1) == 0)
+	{
+	  char *p = arg + sizeof ("--parity=") - 1;
+
+	  if (grub_memcmp (p, "no", sizeof ("no") - 1) == 0)
+	    parity = UART_NO_PARITY;
+	  else if (grub_memcmp (p, "odd", sizeof ("odd") - 1) == 0)
+	    parity = UART_ODD_PARITY;
+	  else if (grub_memcmp (p, "even", sizeof ("even") - 1) == 0)
+	    parity = UART_EVEN_PARITY;
+	  else
+	    {
+	      errnum = ERR_BAD_ARGUMENT;
+	      return 1;
+	    }
+	}
+# ifdef GRUB_UTIL
+      /* In the grub shell, don't use any port number but open a tty
+	 device instead.  */
+      else if (grub_memcmp (arg, "--device=", sizeof ("--device=") - 1) == 0)
+	{
+	  char *p = arg + sizeof ("--device=") - 1;
+	  char dev[256];	/* XXX */
+	  char *q = dev;
+	  
+	  while (*p && ! grub_isspace (*p))
+	    *q++ = *p++;
+	  
+	  *q = 0;
+	  serial_set_device (dev);
+	}
+# endif /* GRUB_UTIL */
+      else
+	break;
+
+      arg = skip_to (0, arg);
+    }
+
+  /* Initialize the serial unit.  */
+  if (! serial_hw_init (port, speed, word_len, parity, stop_bit_len))
+    {
+      errnum = ERR_BAD_ARGUMENT;
+      return 1;
+    }
+  
+  return 0;
+}
+
+static struct builtin builtin_serial =
+{
+  "serial",
+  serial_func,
+  BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "serial [--unit=UNIT] [--port=PORT] [--speed=SPEED] [--word=WORD] [--parity=PARITY] [--stop=STOP] [--device=DEV]",
+  "Initialize a serial device. UNIT is a digit that specifies which serial"
+  " device is used (e.g. 0 == COM1). If you need to specify the port number,"
+  " set it by --port. SPEED is the DTE-DTE speed. WORD is the word length,"
+  " PARITY is the type of parity, which is one of `no', `odd' and `even'."
+  " STOP is the length of stop bit(s). The option --device can be used only"
+  " in the grub shell, which specifies the file name of a tty device. The"
+  " default values are COM1, 9600, 8N1."
+};
+#endif /* SUPPORT_SERIAL */
+
+
+/* setkey */
+struct keysym
+{
+  char *unshifted_name;			/* the name in unshifted state */
+  char *shifted_name;			/* the name in shifted state */
+  unsigned char unshifted_ascii;	/* the ascii code in unshifted state */
+  unsigned char shifted_ascii;		/* the ascii code in shifted state */
+  unsigned char keycode;		/* keyboard scancode */
+};
+
+/* The table for key symbols. If the "shifted" member of an entry is
+   NULL, the entry does not have shifted state.  */
+static struct keysym keysym_table[] =
+{
+  {"escape",		0,		0x1b,	0,	0x01},
+  {"1",			"exclam",	'1',	'!',	0x02},
+  {"2",			"at",		'2',	'@',	0x03},
+  {"3",			"numbersign",	'3',	'#',	0x04},
+  {"4",			"dollar",	'4',	'$',	0x05},
+  {"5",			"percent",	'5',	'%',	0x06},
+  {"6",			"caret",	'6',	'^',	0x07},
+  {"7",			"ampersand",	'7',	'&',	0x08},
+  {"8",			"asterisk",	'8',	'*',	0x09},
+  {"9",			"parenleft",	'9',	'(',	0x0a},
+  {"0",			"parenright",	'0',	')',	0x0b},
+  {"minus",		"underscore",	'-',	'_',	0x0c},
+  {"equal",		"plus",		'=',	'+',	0x0d},
+  {"backspace",		0,		'\b',	0,	0x0e},
+  {"tab",		0,		'\t',	0,	0x0f},
+  {"q",			"Q",		'q',	'Q',	0x10},
+  {"w",			"W",		'w',	'W',	0x11},
+  {"e",			"E",		'e',	'E',	0x12},
+  {"r",			"R",		'r',	'R',	0x13},
+  {"t",			"T",		't',	'T',	0x14},
+  {"y",			"Y",		'y',	'Y',	0x15},
+  {"u",			"U",		'u',	'U',	0x16},
+  {"i",			"I",		'i',	'I',	0x17},
+  {"o",			"O",		'o',	'O',	0x18},
+  {"p",			"P",		'p',	'P',	0x19},
+  {"bracketleft",	"braceleft",	'[',	'{',	0x1a},
+  {"bracketright",	"braceright",	']',	'}',	0x1b},
+  {"enter",		0,		'\n',	0,	0x1c},
+  {"control",		0,		0,	0,	0x1d},
+  {"a",			"A",		'a',	'A',	0x1e},
+  {"s",			"S",		's',	'S',	0x1f},
+  {"d",			"D",		'd',	'D',	0x20},
+  {"f",			"F",		'f',	'F',	0x21},
+  {"g",			"G",		'g',	'G',	0x22},
+  {"h",			"H",		'h',	'H',	0x23},
+  {"j",			"J",		'j',	'J',	0x24},
+  {"k",			"K",		'k',	'K',	0x25},
+  {"l",			"L",		'l',	'L',	0x26},
+  {"semicolon",		"colon",	';',	':',	0x27},
+  {"quote",		"doublequote",	'\'',	'"',	0x28},
+  {"backquote",		"tilde",	'`',	'~',	0x29},
+  {"shift",		0,		0,	0,	0x2a},
+  {"backslash",		"bar",		'\\',	'|',	0x2b},
+  {"z",			"Z",		'z',	'Z',	0x2c},
+  {"x",			"X",		'x',	'X',	0x2d},
+  {"c",			"C",		'c',	'C',	0x2e},
+  {"v",			"V",		'v',	'V',	0x2f},
+  {"b",			"B",		'b',	'B',	0x30},
+  {"n",			"N",		'n',	'N',	0x31},
+  {"m",			"M",		'm',	'M',	0x32},
+  {"comma",		"less",		',',	'<',	0x33},
+  {"period",		"greater",	'.',	'>',	0x34},
+  {"slash",		"question",	'/',	'?',	0x35},
+  {"alt",		0,		0,	0,	0x38},
+  {"space",		0,		' ',	0,	0x39},
+  {"capslock",		0,		0,	0,	0x3a},
+  {"F1",		0,		0,	0,	0x3b},
+  {"F2",		0,		0,	0,	0x3c},
+  {"F3",		0,		0,	0,	0x3d},
+  {"F4",		0,		0,	0,	0x3e},
+  {"F5",		0,		0,	0,	0x3f},
+  {"F6",		0,		0,	0,	0x40},
+  {"F7",		0,		0,	0,	0x41},
+  {"F8",		0,		0,	0,	0x42},
+  {"F9",		0,		0,	0,	0x43},
+  {"F10",		0,		0,	0,	0x44},
+  /* Caution: do not add NumLock here! we cannot deal with it properly.  */
+  {"delete",		0,		0x7f,	0,	0x53}
+};
+
+static int
+setkey_func (char *arg, int flags)
+{
+  char *to_key, *from_key;
+  int to_code, from_code;
+  int map_in_interrupt = 0;
+  
+  auto int find_key_code (char *key);
+  auto int find_ascii_code (char *key);
+  
+  auto int find_key_code (char *key)
+    {
+      int i;
+
+      for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++)
+	{
+	  if (keysym_table[i].unshifted_name &&
+	      grub_strcmp (key, keysym_table[i].unshifted_name) == 0)
+	    return keysym_table[i].keycode;
+	  else if (keysym_table[i].shifted_name &&
+		   grub_strcmp (key, keysym_table[i].shifted_name) == 0)
+	    return keysym_table[i].keycode;
+	}
+      
+      return 0;
+    }
+  
+  auto int find_ascii_code (char *key)
+    {
+      int i;
+      
+      for (i = 0; i < sizeof (keysym_table) / sizeof (keysym_table[0]); i++)
+	{
+	  if (keysym_table[i].unshifted_name &&
+	      grub_strcmp (key, keysym_table[i].unshifted_name) == 0)
+	    return keysym_table[i].unshifted_ascii;
+	  else if (keysym_table[i].shifted_name &&
+		   grub_strcmp (key, keysym_table[i].shifted_name) == 0)
+	    return keysym_table[i].shifted_ascii;
+	}
+      
+      return 0;
+    }
+  
+  to_key = arg;
+  from_key = skip_to (0, to_key);
+
+  if (! *to_key)
+    {
+      /* If the user specifies no argument, reset the key mappings.  */
+      grub_memset (bios_key_map, 0, KEY_MAP_SIZE * sizeof (unsigned short));
+      grub_memset (ascii_key_map, 0, KEY_MAP_SIZE * sizeof (unsigned short));
+
+      return 0;
+    }
+  else if (! *from_key)
+    {
+      /* The user must specify two arguments or zero argument.  */
+      errnum = ERR_BAD_ARGUMENT;
+      return 1;
+    }
+  
+  nul_terminate (to_key);
+  nul_terminate (from_key);
+  
+  to_code = find_ascii_code (to_key);
+  from_code = find_ascii_code (from_key);
+  if (! to_code || ! from_code)
+    {
+      map_in_interrupt = 1;
+      to_code = find_key_code (to_key);
+      from_code = find_key_code (from_key);
+      if (! to_code || ! from_code)
+	{
+	  errnum = ERR_BAD_ARGUMENT;
+	  return 1;
+	}
+    }
+  
+  if (map_in_interrupt)
+    {
+      int i;
+      
+      /* Find an empty slot.  */
+      for (i = 0; i < KEY_MAP_SIZE; i++)
+	{
+	  if ((bios_key_map[i] & 0xff) == from_code)
+	    /* Perhaps the user wants to overwrite the map.  */
+	    break;
+	  
+	  if (! bios_key_map[i])
+	    break;
+	}
+      
+      if (i == KEY_MAP_SIZE)
+	{
+	  errnum = ERR_WONT_FIT;
+	  return 1;
+	}
+      
+      if (to_code == from_code)
+	/* If TO is equal to FROM, delete the entry.  */
+	grub_memmove ((char *) &bios_key_map[i],
+		      (char *) &bios_key_map[i + 1],
+		      sizeof (unsigned short) * (KEY_MAP_SIZE - i));
+      else
+	bios_key_map[i] = (to_code << 8) | from_code;
+      
+      /* Ugly but should work.  */
+      unset_int15_handler ();
+      set_int15_handler ();
+    }
+  else
+    {
+      int i;
+      
+      /* Find an empty slot.  */
+      for (i = 0; i < KEY_MAP_SIZE; i++)
+	{
+	  if ((ascii_key_map[i] & 0xff) == from_code)
+	    /* Perhaps the user wants to overwrite the map.  */
+	    break;
+	  
+	  if (! ascii_key_map[i])
+	    break;
+	}
+      
+      if (i == KEY_MAP_SIZE)
+	{
+	  errnum = ERR_WONT_FIT;
+	  return 1;
+	}
+      
+      if (to_code == from_code)
+	/* If TO is equal to FROM, delete the entry.  */
+	grub_memmove ((char *) &ascii_key_map[i],
+		      (char *) &ascii_key_map[i + 1],
+		      sizeof (unsigned short) * (KEY_MAP_SIZE - i));
+      else
+	ascii_key_map[i] = (to_code << 8) | from_code;
+    }
+      
+  return 0;
+}
+
+static struct builtin builtin_setkey =
+{
+  "setkey",
+  setkey_func,
+  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
+  "setkey [TO_KEY FROM_KEY]",
+  "Change the keyboard map. The key FROM_KEY is mapped to the key TO_KEY."
+  " A key must be an alphabet, a digit, or one of these: escape, exclam,"
+  " at, numbersign, dollar, percent, caret, ampersand, asterisk, parenleft,"
+  " parenright, minus, underscore, equal, plus, backspace, tab, bracketleft,"
+  " braceleft, bracketright, braceright, enter, control, semicolon, colon,"
+  " quote, doublequote, backquote, tilde, shift, backslash, bar, comma,"
+  " less, period, greater, slash, question, alt, space, capslock, FX (X"
+  " is a digit), and delete. If no argument is specified, reset key"
+  " mappings."
+};
+
+
+/* setup */
+static int
+setup_func (char *arg, int flags)
+{
+  /* Point to the string of the installed drive/partition.  */
+  char *install_ptr;
+  /* Point to the string of the drive/parition where the GRUB images
+     reside.  */
+  char *image_ptr;
+  unsigned long installed_drive, installed_partition;
+  unsigned long image_drive, image_partition;
+  unsigned long tmp_drive, tmp_partition;
+  char stage1[64];
+  char stage2[64];
+  char config_filename[64];
+  char real_config_filename[64];
+  char cmd_arg[256];
+  char device[16];
+  char *buffer = (char *) RAW_ADDR (0x100000);
+  int is_force_lba = 0;
+  char *stage2_arg = 0;
+  char *prefix = 0;
+
+  auto int check_file (char *file);
+  auto void sprint_device (int drive, int partition);
+  auto int embed_stage1_5 (char * stage1_5, int drive, int partition);
+  
+  /* Check if the file FILE exists like Autoconf.  */
+  int check_file (char *file)
+    {
+      int ret;
+      
+      grub_printf (" Checking if \"%s\" exists... ", file);
+      ret = grub_open (file);
+      if (ret)
+	{
+	  grub_close ();
+	  grub_printf ("yes\n");
+	}
+      else
+	grub_printf ("no\n");
+
+      return ret;
+    }
+  
+  /* Construct a device name in DEVICE.  */
+  void sprint_device (int drive, int partition)
+    {
+      grub_sprintf (device, "(%cd%d",
+		    (drive & 0x80) ? 'h' : 'f',
+		    drive & ~0x80);
+      if ((partition & 0xFF0000) != 0xFF0000)
+	{
+	  char tmp[16];
+	  grub_sprintf (tmp, ",%d", (partition >> 16) & 0xFF);
+	  grub_strncat (device, tmp, 256);
+	}
+      if ((partition & 0x00FF00) != 0x00FF00)
+	{
+	  char tmp[16];
+	  grub_sprintf (tmp, ",%c", 'a' + ((partition >> 8) & 0xFF));
+	  grub_strncat (device, tmp, 256);
+	}
+      grub_strncat (device, ")", 256);
+    }
+  
+  int embed_stage1_5 (char *stage1_5, int drive, int partition)
+    {
+      /* We install GRUB into the MBR, so try to embed the
+	 Stage 1.5 in the sectors right after the MBR.  */
+      sprint_device (drive, partition);
+      grub_sprintf (cmd_arg, "%s %s", stage1_5, device);
+	      
+      /* Notify what will be run.  */
+      grub_printf (" Running \"embed %s\"... ", cmd_arg);
+      
+      embed_func (cmd_arg, flags);
+      if (! errnum)
+	{
+	  /* Construct the blocklist representation.  */
+	  grub_sprintf (buffer, "%s%s", device, embed_info);
+	  grub_printf ("succeeded\n");
+	  return 1;
+	}
+      else
+	{
+	  grub_printf ("failed (this is not fatal)\n");
+	  return 0;
+	}
+    }
+	  
+  struct stage1_5_map {
+    char *fsys;
+    char *name;
+  };
+  struct stage1_5_map stage1_5_map[] =
+  {
+    {"ext2fs",   "/e2fs_stage1_5"},
+    {"fat",      "/fat_stage1_5"},
+    {"ufs2",     "/ufs2_stage1_5"},
+    {"ffs",      "/ffs_stage1_5"},
+    {"iso9660",  "/iso9660_stage1_5"},
+    {"jfs",      "/jfs_stage1_5"},
+    {"minix",    "/minix_stage1_5"},
+    {"reiserfs", "/reiserfs_stage1_5"},
+    {"vstafs",   "/vstafs_stage1_5"},
+    {"xfs",      "/xfs_stage1_5"}
+  };
+
+  tmp_drive = saved_drive;
+  tmp_partition = saved_partition;
+
+  /* Check if the user specifies --force-lba.  */
+  while (1)
+    {
+      if (grub_memcmp ("--force-lba", arg, sizeof ("--force-lba") - 1) == 0)
+	{
+	  is_force_lba = 1;
+	  arg = skip_to (0, arg);
+	}
+      else if (grub_memcmp ("--prefix=", arg, sizeof ("--prefix=") - 1) == 0)
+	{
+	  prefix = arg + sizeof ("--prefix=") - 1;
+	  arg = skip_to (0, arg);
+	  nul_terminate (prefix);
+	}
+#ifdef GRUB_UTIL
+      else if (grub_memcmp ("--stage2=", arg, sizeof ("--stage2=") - 1) == 0)
+	{
+	  stage2_arg = arg;
+	  arg = skip_to (0, arg);
+	  nul_terminate (stage2_arg);
+	}
+#endif /* GRUB_UTIL */
+      else
+	break;
+    }
+  
+  install_ptr = arg;
+  image_ptr = skip_to (0, install_ptr);
+
+  /* Make sure that INSTALL_PTR is valid.  */
+  set_device (install_ptr);
+  if (errnum)
+    return 1;
+
+  installed_drive = current_drive;
+  installed_partition = current_partition;
+  
+  /* Mount the drive pointed by IMAGE_PTR.  */
+  if (*image_ptr)
+    {
+      /* If the drive/partition where the images reside is specified,
+	 get the drive and the partition.  */
+      set_device (image_ptr);
+      if (errnum)
+	return 1;
+    }
+  else
+    {
+      /* If omitted, use SAVED_PARTITION and SAVED_DRIVE.  */
+      current_drive = saved_drive;
+      current_partition = saved_partition;
+    }
+
+  image_drive = saved_drive = current_drive;
+  image_partition = saved_partition = current_partition;
+
+  /* Open it.  */
+  if (! open_device ())
+    goto fail;
+
+  /* Check if stage1 exists. If the user doesn't specify the option
+     `--prefix', attempt /boot/grub and /grub.  */
+  /* NOTE: It is dangerous to run this command without `--prefix' in the
+     grub shell, since that affects `--stage2'.  */
+  if (! prefix)
+    {
+      prefix = "/boot/grub";
+      grub_sprintf (stage1, "%s%s", prefix, "/stage1");
+      if (! check_file (stage1))
+	{
+	  errnum = ERR_NONE;
+	  prefix = "/grub";
+	  grub_sprintf (stage1, "%s%s", prefix, "/stage1");
+	  if (! check_file (stage1))
+	    goto fail;
+	}
+    }
+  else
+    {
+      grub_sprintf (stage1, "%s%s", prefix, "/stage1");
+      if (! check_file (stage1))
+	goto fail;
+    }
+
+  /* The prefix was determined.  */
+  grub_sprintf (stage2, "%s%s", prefix, "/stage2");
+  grub_sprintf (config_filename, "%s%s", prefix, "/menu.lst");
+  *real_config_filename = 0;
+
+  /* Check if stage2 exists.  */
+  if (! check_file (stage2))
+    goto fail;
+
+  {
+    char *fsys = fsys_table[fsys_type].name;
+    int i;
+    int size = sizeof (stage1_5_map) / sizeof (stage1_5_map[0]);
+    
+    /* Iterate finding the same filesystem name as FSYS.  */
+    for (i = 0; i < size; i++)
+      if (grub_strcmp (fsys, stage1_5_map[i].fsys) == 0)
+	{
+	  /* OK, check if the Stage 1.5 exists.  */
+	  char stage1_5[64];
+	  
+	  grub_sprintf (stage1_5, "%s%s", prefix, stage1_5_map[i].name);
+	  if (check_file (stage1_5))
+	    {
+	      if (embed_stage1_5 (stage1_5, 
+				    installed_drive, installed_partition)
+		  || embed_stage1_5 (stage1_5, 
+				     image_drive, image_partition))
+		{
+		  grub_strcpy (real_config_filename, config_filename);
+		  sprint_device (image_drive, image_partition);
+		  grub_sprintf (config_filename, "%s%s", device, stage2);
+		  grub_strcpy (stage2, buffer);
+		}
+	    }
+	  errnum = 0;
+	  break;
+	}
+  }
+
+  /* Construct a string that is used by the command "install" as its
+     arguments.  */
+  sprint_device (installed_drive, installed_partition);
+  
+#if 1
+  /* Don't embed a drive number unnecessarily.  */
+  grub_sprintf (cmd_arg, "%s%s%s%s %s%s %s p %s %s",
+		is_force_lba? "--force-lba " : "",
+		stage2_arg? stage2_arg : "",
+		stage2_arg? " " : "",
+		stage1,
+		(installed_drive != image_drive) ? "d " : "",
+		device,
+		stage2,
+		config_filename,
+		real_config_filename);
+#else /* NOT USED */
+  /* This code was used, because we belived some BIOSes had a problem
+     that they didn't pass a booting drive correctly. It turned out,
+     however, stage1 could trash a booting drive when checking LBA support,
+     because some BIOSes modified the register %dx in INT 13H, AH=48H.
+     So it becamed unclear whether GRUB should use a pre-defined booting
+     drive or not. If the problem still exists, it would be necessary to
+     switch back to this code.  */
+  grub_sprintf (cmd_arg, "%s%s%s%s d %s %s p %s %s",
+		is_force_lba? "--force-lba " : "",
+		stage2_arg? stage2_arg : "",
+		stage2_arg? " " : "",
+		stage1,
+		device,
+		stage2,
+		config_filename,
+		real_config_filename);
+#endif /* NOT USED */
+  
+  /* Notify what will be run.  */
+  grub_printf (" Running \"install %s\"... ", cmd_arg);
+
+  /* Make sure that SAVED_DRIVE and SAVED_PARTITION are identical
+     with IMAGE_DRIVE and IMAGE_PARTITION, respectively.  */
+  saved_drive = image_drive;
+  saved_partition = image_partition;
+  
+  /* Run the command.  */
+  if (! install_func (cmd_arg, flags))
+    grub_printf ("succeeded\nDone.\n");
+  else
+    grub_printf ("failed\n");
+
+ fail:
+  saved_drive = tmp_drive;
+  saved_partition = tmp_partition;
+  return errnum;
+}
+
+static struct builtin builtin_setup =
+{
+  "setup",
+  setup_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "setup [--prefix=DIR] [--stage2=STAGE2_FILE] [--force-lba] INSTALL_DEVICE [IMAGE_DEVICE]",
+  "Set up the installation of GRUB automatically. This command uses"
+  " the more flexible command \"install\" in the backend and installs"
+  " GRUB into the device INSTALL_DEVICE. If IMAGE_DEVICE is specified,"
+  " then find the GRUB images in the device IMAGE_DEVICE, otherwise"
+  " use the current \"root device\", which can be set by the command"
+  " \"root\". If you know that your BIOS should support LBA but GRUB"
+  " doesn't work in LBA mode, specify the option `--force-lba'."
+  " If you install GRUB under the grub shell and you cannot unmount the"
+  " partition where GRUB images reside, specify the option `--stage2'"
+  " to tell GRUB the file name under your OS."
+};
+
+
+#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
+/* terminal */
+static int
+terminal_func (char *arg, int flags)
+{
+  /* The index of the default terminal in TERM_TABLE.  */
+  int default_term = -1;
+  struct term_entry *prev_term = current_term;
+  int to = -1;
+  int lines = 0;
+  int no_message = 0;
+  unsigned long term_flags = 0;
+  /* XXX: Assume less than 32 terminals.  */
+  unsigned long term_bitmap = 0;
+
+  /* Get GNU-style long options.  */
+  while (1)
+    {
+      if (grub_memcmp (arg, "--dumb", sizeof ("--dumb") - 1) == 0)
+	term_flags |= TERM_DUMB;
+      else if (grub_memcmp (arg, "--no-echo", sizeof ("--no-echo") - 1) == 0)
+	/* ``--no-echo'' implies ``--no-edit''.  */
+	term_flags |= (TERM_NO_ECHO | TERM_NO_EDIT);
+      else if (grub_memcmp (arg, "--no-edit", sizeof ("--no-edit") - 1) == 0)
+	term_flags |= TERM_NO_EDIT;
+      else if (grub_memcmp (arg, "--timeout=", sizeof ("--timeout=") - 1) == 0)
+	{
+	  char *val = arg + sizeof ("--timeout=") - 1;
+	  
+	  if (! safe_parse_maxint (&val, &to))
+	    return 1;
+	}
+      else if (grub_memcmp (arg, "--lines=", sizeof ("--lines=") - 1) == 0)
+	{
+	  char *val = arg + sizeof ("--lines=") - 1;
+
+	  if (! safe_parse_maxint (&val, &lines))
+	    return 1;
+
+	  /* Probably less than four is meaningless....  */
+	  if (lines < 4)
+	    {
+	      errnum = ERR_BAD_ARGUMENT;
+	      return 1;
+	    }
+	}
+      else if (grub_memcmp (arg, "--silent", sizeof ("--silent") - 1) == 0)
+	no_message = 1;
+      else
+	break;
+
+      arg = skip_to (0, arg);
+    }
+  
+  /* If no argument is specified, show current setting.  */
+  if (! *arg)
+    {
+      grub_printf ("%s%s%s%s\n",
+		   current_term->name,
+		   current_term->flags & TERM_DUMB ? " (dumb)" : "",
+		   current_term->flags & TERM_NO_EDIT ? " (no edit)" : "",
+		   current_term->flags & TERM_NO_ECHO ? " (no echo)" : "");
+      return 0;
+    }
+
+  while (*arg)
+    {
+      int i;
+      char *next = skip_to (0, arg);
+      
+      nul_terminate (arg);
+
+      for (i = 0; term_table[i].name; i++)
+	{
+	  if (grub_strcmp (arg, term_table[i].name) == 0)
+	    {
+	      if (term_table[i].flags & TERM_NEED_INIT)
+		{
+		  errnum = ERR_DEV_NEED_INIT;
+		  return 1;
+		}
+	      
+	      if (default_term < 0)
+		default_term = i;
+
+	      term_bitmap |= (1 << i);
+	      break;
+	    }
+	}
+
+      if (! term_table[i].name)
+	{
+	  errnum = ERR_BAD_ARGUMENT;
+	  return 1;
+	}
+
+      arg = next;
+    }
+
+  /* If multiple terminals are specified, wait until the user pushes any
+     key on one of the terminals.  */
+  if (term_bitmap & ~(1 << default_term))
+    {
+      int time1, time2 = -1;
+
+      /* XXX: Disable the pager.  */
+      count_lines = -1;
+      
+      /* Get current time.  */
+      while ((time1 = getrtsecs ()) == 0xFF)
+	;
+
+      /* Wait for a key input.  */
+      while (to)
+	{
+	  int i;
+
+	  for (i = 0; term_table[i].name; i++)
+	    {
+	      if (term_bitmap & (1 << i))
+		{
+		  if (term_table[i].checkkey () >= 0)
+		    {
+		      (void) term_table[i].getkey ();
+		      default_term = i;
+		      
+		      goto end;
+		    }
+		}
+	    }
+	  
+	  /* Prompt the user, once per sec.  */
+	  if ((time1 = getrtsecs ()) != time2 && time1 != 0xFF)
+	    {
+	      if (! no_message)
+		{
+		  /* Need to set CURRENT_TERM to each of selected
+		     terminals.  */
+		  for (i = 0; term_table[i].name; i++)
+		    if (term_bitmap & (1 << i))
+		      {
+			current_term = term_table + i;
+			grub_printf ("\rPress any key to continue.\n");
+		      }
+		  
+		  /* Restore CURRENT_TERM.  */
+		  current_term = prev_term;
+		}
+	      
+	      time2 = time1;
+	      if (to > 0)
+		to--;
+	    }
+	}
+    }
+
+ 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;
+  
+  /* If the interface is currently the command-line,
+     restart it to repaint the screen.  */
+  if (current_term != prev_term && (flags & BUILTIN_CMDLINE))
+    grub_longjmp (restart_cmdline_env, 0);
+  
+  return 0;
+}
+
+static struct builtin builtin_terminal =
+{
+  "terminal",
+  terminal_func,
+  BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "terminal [--dumb] [--no-echo] [--no-edit] [--timeout=SECS] [--lines=LINES] [--silent] [console] [serial] [hercules]",
+  "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"
+  " argument is specified, print current setting. The option --dumb"
+  " specifies that your terminal is dumb, otherwise, vt100-compatibility"
+  " is assumed. If you specify --no-echo, input characters won't be echoed."
+  " If you specify --no-edit, the BASH-like editing feature will be disabled."
+  " If --timeout is present, this command will wait at most for SECS"
+  " seconds. The option --lines specifies the maximum number of lines."
+  " The option --silent is used to suppress messages."
+};
+#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
+
+
+#ifdef SUPPORT_SERIAL
+static int
+terminfo_func (char *arg, int flags)
+{
+  struct terminfo term;
+
+  if (*arg)
+    {
+      struct
+      {
+	const char *name;
+	char *var;
+      }
+      options[] =
+	{
+	  {"--name=", term.name},
+	  {"--cursor-address=", term.cursor_address},
+	  {"--clear-screen=", term.clear_screen},
+	  {"--enter-standout-mode=", term.enter_standout_mode},
+	  {"--exit-standout-mode=", term.exit_standout_mode}
+	};
+
+      grub_memset (&term, 0, sizeof (term));
+      
+      while (*arg)
+	{
+	  int i;
+	  char *next = skip_to (0, arg);
+	      
+	  nul_terminate (arg);
+	  
+	  for (i = 0; i < sizeof (options) / sizeof (options[0]); i++)
+	    {
+	      const char *name = options[i].name;
+	      int len = grub_strlen (name);
+	      
+	      if (! grub_memcmp (arg, name, len))
+		{
+		  grub_strcpy (options[i].var, ti_unescape_string (arg + len));
+		  break;
+		}
+	    }
+
+	  if (i == sizeof (options) / sizeof (options[0]))
+	    {
+	      errnum = ERR_BAD_ARGUMENT;
+	      return errnum;
+	    }
+
+	  arg = next;
+	}
+
+      if (term.name[0] == 0 || term.cursor_address[0] == 0)
+	{
+	  errnum = ERR_BAD_ARGUMENT;
+	  return errnum;
+	}
+
+      ti_set_term (&term);
+    }
+  else
+    {
+      /* No option specifies printing out current settings.  */
+      ti_get_term (&term);
+
+      grub_printf ("name=%s\n",
+		   ti_escape_string (term.name));
+      grub_printf ("cursor_address=%s\n",
+		   ti_escape_string (term.cursor_address));
+      grub_printf ("clear_screen=%s\n",
+		   ti_escape_string (term.clear_screen));
+      grub_printf ("enter_standout_mode=%s\n",
+		   ti_escape_string (term.enter_standout_mode));
+      grub_printf ("exit_standout_mode=%s\n",
+		   ti_escape_string (term.exit_standout_mode));
+    }
+
+  return 0;
+}
+
+static struct builtin builtin_terminfo =
+{
+  "terminfo",
+  terminfo_func,
+  BUILTIN_MENU | BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "terminfo [--name=NAME --cursor-address=SEQ [--clear-screen=SEQ]"
+  " [--enter-standout-mode=SEQ] [--exit-standout-mode=SEQ]]",
+  
+  "Define the capabilities of your terminal. Use this command to"
+  " define escape sequences, if it is not vt100-compatible."
+  " You may use \\e for ESC and ^X for a control character."
+  " If no option is specified, the current settings are printed."
+};
+#endif /* SUPPORT_SERIAL */
+	  
+
+/* testload */
+static int
+testload_func (char *arg, int flags)
+{
+  int i;
+
+  kernel_type = KERNEL_TYPE_NONE;
+
+  if (! grub_open (arg))
+    return 1;
+
+  disk_read_hook = disk_read_print_func;
+
+  /* Perform filesystem test on the specified file.  */
+  /* Read whole file first. */
+  grub_printf ("Whole file: ");
+
+  grub_read ((char *) RAW_ADDR (0x100000), -1);
+
+  /* Now compare two sections of the file read differently.  */
+
+  for (i = 0; i < 0x10ac0; i++)
+    {
+      *((unsigned char *) RAW_ADDR (0x200000 + i)) = 0;
+      *((unsigned char *) RAW_ADDR (0x300000 + i)) = 1;
+    }
+
+  /* First partial read.  */
+  grub_printf ("\nPartial read 1: ");
+
+  grub_seek (0);
+  grub_read ((char *) RAW_ADDR (0x200000), 0x7);
+  grub_read ((char *) RAW_ADDR (0x200007), 0x100);
+  grub_read ((char *) RAW_ADDR (0x200107), 0x10);
+  grub_read ((char *) RAW_ADDR (0x200117), 0x999);
+  grub_read ((char *) RAW_ADDR (0x200ab0), 0x10);
+  grub_read ((char *) RAW_ADDR (0x200ac0), 0x10000);
+
+  /* Second partial read.  */
+  grub_printf ("\nPartial read 2: ");
+
+  grub_seek (0);
+  grub_read ((char *) RAW_ADDR (0x300000), 0x10000);
+  grub_read ((char *) RAW_ADDR (0x310000), 0x10);
+  grub_read ((char *) RAW_ADDR (0x310010), 0x7);
+  grub_read ((char *) RAW_ADDR (0x310017), 0x10);
+  grub_read ((char *) RAW_ADDR (0x310027), 0x999);
+  grub_read ((char *) RAW_ADDR (0x3109c0), 0x100);
+
+  grub_printf ("\nHeader1 = 0x%x, next = 0x%x, next = 0x%x, next = 0x%x\n",
+	       *((int *) RAW_ADDR (0x200000)),
+	       *((int *) RAW_ADDR (0x200004)),
+	       *((int *) RAW_ADDR (0x200008)),
+	       *((int *) RAW_ADDR (0x20000c)));
+
+  grub_printf ("Header2 = 0x%x, next = 0x%x, next = 0x%x, next = 0x%x\n",
+	       *((int *) RAW_ADDR (0x300000)),
+	       *((int *) RAW_ADDR (0x300004)),
+	       *((int *) RAW_ADDR (0x300008)),
+	       *((int *) RAW_ADDR (0x30000c)));
+
+  for (i = 0; i < 0x10ac0; i++)
+    if (*((unsigned char *) RAW_ADDR (0x200000 + i))
+	!= *((unsigned char *) RAW_ADDR (0x300000 + i)))
+      break;
+
+  grub_printf ("Max is 0x10ac0: i=0x%x, filepos=0x%x\n", i, filepos);
+  disk_read_hook = 0;
+  grub_close ();
+  return 0;
+}
+
+static struct builtin builtin_testload =
+{
+  "testload",
+  testload_func,
+  BUILTIN_CMDLINE,
+  "testload FILE",
+  "Read the entire contents of FILE in several different ways and"
+  " compares them, to test the filesystem code. The output is somewhat"
+  " cryptic, but if no errors are reported and the final `i=X,"
+  " filepos=Y' reading has X and Y equal, then it is definitely"
+  " consistent, and very likely works correctly subject to a"
+  " consistent offset error. If this test succeeds, then a good next"
+  " step is to try loading a kernel."
+};
+
+
+/* testvbe MODE */
+static int
+testvbe_func (char *arg, int flags)
+{
+  int mode_number;
+  struct vbe_controller controller;
+  struct vbe_mode mode;
+  
+  if (! *arg)
+    {
+      errnum = ERR_BAD_ARGUMENT;
+      return 1;
+    }
+
+  if (! safe_parse_maxint (&arg, &mode_number))
+    return 1;
+
+  /* Preset `VBE2'.  */
+  grub_memmove (controller.signature, "VBE2", 4);
+
+  /* Detect VBE BIOS.  */
+  if (get_vbe_controller_info (&controller) != 0x004F)
+    {
+      grub_printf (" VBE BIOS is not present.\n");
+      return 0;
+    }
+  
+  if (controller.version < 0x0200)
+    {
+      grub_printf (" VBE version %d.%d is not supported.\n",
+		   (int) (controller.version >> 8),
+		   (int) (controller.version & 0xFF));
+      return 0;
+    }
+
+  if (get_vbe_mode_info (mode_number, &mode) != 0x004F
+      || (mode.mode_attributes & 0x0091) != 0x0091)
+    {
+      grub_printf (" Mode 0x%x is not supported.\n", mode_number);
+      return 0;
+    }
+
+  /* Now trip to the graphics mode.  */
+  if (set_vbe_mode (mode_number | (1 << 14)) != 0x004F)
+    {
+      grub_printf (" Switching to Mode 0x%x failed.\n", mode_number);
+      return 0;
+    }
+
+  /* Draw something on the screen...  */
+  {
+    unsigned char *base_buf = (unsigned char *) mode.phys_base;
+    int scanline = controller.version >= 0x0300
+      ? mode.linear_bytes_per_scanline : mode.bytes_per_scanline;
+    /* FIXME: this assumes that any depth is a modulo of 8.  */
+    int bpp = mode.bits_per_pixel / 8;
+    int width = mode.x_resolution;
+    int height = mode.y_resolution;
+    int x, y;
+    unsigned color = 0;
+
+    /* Iterate drawing on the screen, until the user hits any key.  */
+    while (checkkey () == -1)
+      {
+	for (y = 0; y < height; y++)
+	  {
+	    unsigned char *line_buf = base_buf + scanline * y;
+	    
+	    for (x = 0; x < width; x++)
+	      {
+		unsigned char *buf = line_buf + bpp * x;
+		int i;
+
+		for (i = 0; i < bpp; i++, buf++)
+		  *buf = (color >> (i * 8)) & 0xff;
+	      }
+
+	    color++;
+	  }
+      }
+
+    /* Discard the input.  */
+    getkey ();
+  }
+  
+  /* Back to the default text mode.  */
+  if (set_vbe_mode (0x03) != 0x004F)
+    {
+      /* Why?!  */
+      grub_reboot ();
+    }
+
+  return 0;
+}
+
+static struct builtin builtin_testvbe =
+{
+  "testvbe",
+  testvbe_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "testvbe MODE",
+  "Test the VBE mode MODE. Hit any key to return."
+};
+
+
+#ifdef SUPPORT_NETBOOT
+/* tftpserver */
+static int
+tftpserver_func (char *arg, int flags)
+{
+  if (! *arg || ! ifconfig (0, 0, 0, arg))
+    {
+      errnum = ERR_BAD_ARGUMENT;
+      return 1;
+    }
+
+  print_network_configuration ();
+  return 0;
+}
+
+static struct builtin builtin_tftpserver =
+{
+  "tftpserver",
+  tftpserver_func,
+  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
+  "tftpserver IPADDR",
+  "Override the TFTP server address."
+};
+#endif /* SUPPORT_NETBOOT */
+
+
+/* timeout */
+static int
+timeout_func (char *arg, int flags)
+{
+  if (! safe_parse_maxint (&arg, &grub_timeout))
+    return 1;
+
+  return 0;
+}
+
+static struct builtin builtin_timeout =
+{
+  "timeout",
+  timeout_func,
+  BUILTIN_MENU,
+#if 0
+  "timeout SEC",
+  "Set a timeout, in SEC seconds, before automatically booting the"
+  " default entry (normally the first entry defined)."
+#endif
+};
+
+
+/* title */
+static int
+title_func (char *arg, int flags)
+{
+  /* This function is not actually used at least currently.  */
+  return 0;
+}
+
+static struct builtin builtin_title =
+{
+  "title",
+  title_func,
+  BUILTIN_TITLE,
+#if 0
+  "title [NAME ...]",
+  "Start a new boot entry, and set its name to the contents of the"
+  " rest of the line, starting with the first non-space character."
+#endif
+};
+
+
+/* unhide */
+static int
+unhide_func (char *arg, int flags)
+{
+  if (! set_device (arg))
+    return 1;
+
+  if (! set_partition_hidden_flag (0))
+    return 1;
+
+  return 0;
+}
+
+static struct builtin builtin_unhide =
+{
+  "unhide",
+  unhide_func,
+  BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST,
+  "unhide PARTITION",
+  "Unhide PARTITION by clearing the \"hidden\" bit in its"
+  " partition type code."
+};
+
+
+/* uppermem */
+static int
+uppermem_func (char *arg, int flags)
+{
+  if (! safe_parse_maxint (&arg, (int *) &mbi.mem_upper))
+    return 1;
+
+  mbi.flags &= ~MB_INFO_MEM_MAP;
+  return 0;
+}
+
+static struct builtin builtin_uppermem =
+{
+  "uppermem",
+  uppermem_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "uppermem KBYTES",
+  "Force GRUB to assume that only KBYTES kilobytes of upper memory are"
+  " installed.  Any system address range maps are discarded."
+};
+
+
+/* vbeprobe */
+static int
+vbeprobe_func (char *arg, int flags)
+{
+  struct vbe_controller controller;
+  unsigned short *mode_list;
+  int mode_number = -1;
+  
+  auto unsigned long vbe_far_ptr_to_linear (unsigned long);
+  
+  unsigned long vbe_far_ptr_to_linear (unsigned long ptr)
+    {
+      unsigned short seg = (ptr >> 16);
+      unsigned short off = (ptr & 0xFFFF);
+
+      return (seg << 4) + off;
+    }
+  
+  if (*arg)
+    {
+      if (! safe_parse_maxint (&arg, &mode_number))
+	return 1;
+    }
+  
+  /* Set the signature to `VBE2', to obtain VBE 3.0 information.  */
+  grub_memmove (controller.signature, "VBE2", 4);
+  
+  if (get_vbe_controller_info (&controller) != 0x004F)
+    {
+      grub_printf (" VBE BIOS is not present.\n");
+      return 0;
+    }
+
+  /* Check the version.  */
+  if (controller.version < 0x0200)
+    {
+      grub_printf (" VBE version %d.%d is not supported.\n",
+		   (int) (controller.version >> 8),
+		   (int) (controller.version & 0xFF));
+      return 0;
+    }
+
+  /* Print some information.  */
+  grub_printf (" VBE version %d.%d\n",
+	       (int) (controller.version >> 8),
+	       (int) (controller.version & 0xFF));
+
+  /* Iterate probing modes.  */
+  for (mode_list
+	 = (unsigned short *) vbe_far_ptr_to_linear (controller.video_mode);
+       *mode_list != 0xFFFF;
+       mode_list++)
+    {
+      struct vbe_mode mode;
+      
+      if (get_vbe_mode_info (*mode_list, &mode) != 0x004F)
+	continue;
+
+      /* Skip this, if this is not supported or linear frame buffer
+	 mode is not support.  */
+      if ((mode.mode_attributes & 0x0081) != 0x0081)
+	continue;
+
+      if (mode_number == -1 || mode_number == *mode_list)
+	{
+	  char *model;
+	  switch (mode.memory_model)
+	    {
+	    case 0x00: model = "Text"; break;
+	    case 0x01: model = "CGA graphics"; break;
+	    case 0x02: model = "Hercules graphics"; break;
+	    case 0x03: model = "Planar"; break;
+	    case 0x04: model = "Packed pixel"; break;
+	    case 0x05: model = "Non-chain 4, 256 color"; break;
+	    case 0x06: model = "Direct Color"; break;
+	    case 0x07: model = "YUV"; break;
+	    default: model = "Unknown"; break;
+	    }
+	  
+	  grub_printf ("  0x%x: %s, %ux%ux%u\n",
+		       (unsigned) *mode_list,
+		       model,
+		       (unsigned) mode.x_resolution,
+		       (unsigned) mode.y_resolution,
+		       (unsigned) mode.bits_per_pixel);
+	  
+	  if (mode_number != -1)
+	    break;
+	}
+    }
+
+  if (mode_number != -1 && mode_number != *mode_list)
+    grub_printf ("  Mode 0x%x is not found or supported.\n", mode_number);
+  
+  return 0;
+}
+
+static struct builtin builtin_vbeprobe =
+{
+  "vbeprobe",
+  vbeprobe_func,
+  BUILTIN_CMDLINE | BUILTIN_HELP_LIST,
+  "vbeprobe [MODE]",
+  "Probe VBE information. If the mode number MODE is specified, show only"
+  " the information about only the mode."
+};
+  
+
+/* The table of builtin commands. Sorted in dictionary order.  */
+struct builtin *builtin_table[] =
+{
+  &builtin_blocklist,
+  &builtin_boot,
+#ifdef SUPPORT_NETBOOT
+  &builtin_bootp,
+#endif /* SUPPORT_NETBOOT */
+  &builtin_cat,
+  &builtin_chainloader,
+  &builtin_cmdline,
+  &builtin_cmp,
+  &builtin_color,
+  &builtin_configfile,
+  &builtin_debug,
+  &builtin_default,
+#ifdef GRUB_UTIL
+  &builtin_device,
+#endif /* GRUB_UTIL */
+#ifdef SUPPORT_NETBOOT
+  &builtin_dhcp,
+#endif /* SUPPORT_NETBOOT */
+  &builtin_displayapm,
+  &builtin_displaymem,
+#ifdef GRUB_UTIL
+  &builtin_dump,
+#endif /* GRUB_UTIL */
+  &builtin_embed,
+  &builtin_fallback,
+  &builtin_find,
+  &builtin_fstest,
+  &builtin_geometry,
+  &builtin_halt,
+  &builtin_help,
+  &builtin_hiddenmenu,
+  &builtin_hide,
+#ifdef SUPPORT_NETBOOT
+  &builtin_ifconfig,
+#endif /* SUPPORT_NETBOOT */
+  &builtin_impsprobe,
+  &builtin_initrd,
+  &builtin_install,
+  &builtin_ioprobe,
+  &builtin_kernel,
+  &builtin_lock,
+  &builtin_makeactive,
+  &builtin_map,
+#ifdef USE_MD5_PASSWORDS
+  &builtin_md5crypt,
+#endif /* USE_MD5_PASSWORDS */
+  &builtin_module,
+  &builtin_modulenounzip,
+  &builtin_pager,
+  &builtin_partnew,
+  &builtin_parttype,
+  &builtin_password,
+  &builtin_pause,
+#ifdef GRUB_UTIL
+  &builtin_quit,
+#endif /* GRUB_UTIL */
+#ifdef SUPPORT_NETBOOT
+  &builtin_rarp,
+#endif /* SUPPORT_NETBOOT */
+  &builtin_read,
+  &builtin_reboot,
+  &builtin_root,
+  &builtin_rootnoverify,
+  &builtin_savedefault,
+#ifdef SUPPORT_SERIAL
+  &builtin_serial,
+#endif /* SUPPORT_SERIAL */
+  &builtin_setkey,
+  &builtin_setup,
+#if defined(SUPPORT_SERIAL) || defined(SUPPORT_HERCULES)
+  &builtin_terminal,
+#endif /* SUPPORT_SERIAL || SUPPORT_HERCULES */
+#ifdef SUPPORT_SERIAL
+  &builtin_terminfo,
+#endif /* SUPPORT_SERIAL */
+  &builtin_testload,
+  &builtin_testvbe,
+#ifdef SUPPORT_NETBOOT
+  &builtin_tftpserver,
+#endif /* SUPPORT_NETBOOT */
+  &builtin_timeout,
+  &builtin_title,
+  &builtin_unhide,
+  &builtin_uppermem,
+  &builtin_vbeprobe,
+  0
+};
diff --git a/stage2/char_io.c b/stage2/char_io.c
new file mode 100644
index 0000000..c86c240
--- /dev/null
+++ b/stage2/char_io.c
@@ -0,0 +1,1283 @@
+/* char_io.c - basic console input and output */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,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 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.
+ */
+
+#include <shared.h>
+#include <term.h>
+
+#ifdef SUPPORT_HERCULES
+# include <hercules.h>
+#endif
+
+#ifdef SUPPORT_SERIAL
+# include <serial.h>
+#endif
+
+#ifndef STAGE1_5
+struct term_entry term_table[] =
+  {
+    {
+      "console",
+      0,
+      console_putchar,
+      console_checkkey,
+      console_getkey,
+      console_getxy,
+      console_gotoxy,
+      console_cls,
+      console_setcolorstate,
+      console_setcolor,
+      console_setcursor
+    },
+#ifdef SUPPORT_SERIAL
+    {
+      "serial",
+      /* A serial device must be initialized.  */
+      TERM_NEED_INIT,
+      serial_putchar,
+      serial_checkkey,
+      serial_getkey,
+      serial_getxy,
+      serial_gotoxy,
+      serial_cls,
+      serial_setcolorstate,
+      0,
+      0
+    },
+#endif /* SUPPORT_SERIAL */
+#ifdef SUPPORT_HERCULES
+    {
+      "hercules",
+      0,
+      hercules_putchar,
+      console_checkkey,
+      console_getkey,
+      hercules_getxy,
+      hercules_gotoxy,
+      hercules_cls,
+      hercules_setcolorstate,
+      hercules_setcolor,
+      hercules_setcursor
+    },      
+#endif /* SUPPORT_HERCULES */
+    /* This must be the last entry.  */
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+  };
+
+/* This must be console.  */
+struct term_entry *current_term = term_table;
+
+int max_lines = 24;
+int count_lines = -1;
+int use_pager = 1;
+#endif
+
+void
+print_error (void)
+{
+  if (errnum > ERR_NONE && errnum < MAX_ERR_NUM)
+#ifndef STAGE1_5
+    /* printf("\7\n %s\n", err_list[errnum]); */
+    printf ("\nError %u: %s\n", errnum, err_list[errnum]);
+#else /* STAGE1_5 */
+    printf ("Error %u\n", errnum);
+#endif /* STAGE1_5 */
+}
+
+char *
+convert_to_ascii (char *buf, int c,...)
+{
+  unsigned long num = *((&c) + 1), mult = 10;
+  char *ptr = buf;
+
+#ifndef STAGE1_5
+  if (c == 'x' || c == 'X')
+    mult = 16;
+
+  if ((num & 0x80000000uL) && c == 'd')
+    {
+      num = (~num) + 1;
+      *(ptr++) = '-';
+      buf++;
+    }
+#endif
+
+  do
+    {
+      int dig = num % mult;
+      *(ptr++) = ((dig > 9) ? dig + 'a' - 10 : '0' + dig);
+    }
+  while (num /= mult);
+
+  /* reorder to correct direction!! */
+  {
+    char *ptr1 = ptr - 1;
+    char *ptr2 = buf;
+    while (ptr1 > ptr2)
+      {
+	int tmp = *ptr1;
+	*ptr1 = *ptr2;
+	*ptr2 = tmp;
+	ptr1--;
+	ptr2++;
+      }
+  }
+
+  return ptr;
+}
+
+void
+grub_putstr (const char *str)
+{
+  while (*str)
+    grub_putchar (*str++);
+}
+
+void
+grub_printf (const char *format,...)
+{
+  int *dataptr = (int *) &format;
+  char c, str[16];
+  
+  dataptr++;
+
+  while ((c = *(format++)) != 0)
+    {
+      if (c != '%')
+	grub_putchar (c);
+      else
+	switch (c = *(format++))
+	  {
+#ifndef STAGE1_5
+	  case 'd':
+	  case 'x':
+	  case 'X':
+#endif
+	  case 'u':
+	    *convert_to_ascii (str, c, *((unsigned long *) dataptr++)) = 0;
+	    grub_putstr (str);
+	    break;
+
+#ifndef STAGE1_5
+	  case 'c':
+	    grub_putchar ((*(dataptr++)) & 0xff);
+	    break;
+
+	  case 's':
+	    grub_putstr ((char *) *(dataptr++));
+	    break;
+#endif
+	  }
+    }
+}
+
+#ifndef STAGE1_5
+int
+grub_sprintf (char *buffer, const char *format, ...)
+{
+  /* XXX hohmuth
+     ugly hack -- should unify with printf() */
+  int *dataptr = (int *) &format;
+  char c, *ptr, str[16];
+  char *bp = buffer;
+
+  dataptr++;
+
+  while ((c = *format++) != 0)
+    {
+      if (c != '%')
+	*bp++ = c; /* putchar(c); */
+      else
+	switch (c = *(format++))
+	  {
+	  case 'd': case 'u': case 'x':
+	    *convert_to_ascii (str, c, *((unsigned long *) dataptr++)) = 0;
+
+	    ptr = str;
+
+	    while (*ptr)
+	      *bp++ = *(ptr++); /* putchar(*(ptr++)); */
+	    break;
+
+	  case 'c': *bp++ = (*(dataptr++))&0xff;
+	    /* putchar((*(dataptr++))&0xff); */
+	    break;
+
+	  case 's':
+	    ptr = (char *) (*(dataptr++));
+
+	    while ((c = *ptr++) != 0)
+	      *bp++ = c; /* putchar(c); */
+	    break;
+	  }
+    }
+
+  *bp = 0;
+  return bp - buffer;
+}
+
+
+void
+init_page (void)
+{
+  cls ();
+
+  grub_printf ("\n    GNU GRUB  version %s  (%dK lower / %dK upper memory)\n\n",
+	  version_string, mbi.mem_lower, mbi.mem_upper);
+}
+
+/* The number of the history entries.  */
+static int num_history = 0;
+
+/* Get the NOth history. If NO is less than zero or greater than or
+   equal to NUM_HISTORY, return NULL. Otherwise return a valid string.  */
+static char *
+get_history (int no)
+{
+  if (no < 0 || no >= num_history)
+    return 0;
+
+  return (char *) HISTORY_BUF + MAX_CMDLINE * no;
+}
+
+/* Add CMDLINE to the history buffer.  */
+static void
+add_history (const char *cmdline, int no)
+{
+  grub_memmove ((char *) HISTORY_BUF + MAX_CMDLINE * (no + 1),
+		(char *) HISTORY_BUF + MAX_CMDLINE * no,
+		MAX_CMDLINE * (num_history - no));
+  grub_strcpy ((char *) HISTORY_BUF + MAX_CMDLINE * no, cmdline);
+  if (num_history < HISTORY_SIZE)
+    num_history++;
+}
+
+static int
+real_get_cmdline (char *prompt, char *cmdline, int maxlen,
+		  int echo_char, int readline)
+{
+  /* This is a rather complicated function. So explain the concept.
+     
+     A command-line consists of ``section''s. A section is a part of the
+     line which may be displayed on the screen, but a section is never
+     displayed with another section simultaneously.
+
+     Each section is basically 77 or less characters, but the exception
+     is the first section, which is 78 or less characters, because the
+     starting point is special. See below.
+
+     The first section contains a prompt and a command-line (or the
+     first part of a command-line when it is too long to be fit in the
+     screen). So, in the first section, the number of command-line
+     characters displayed is 78 minus the length of the prompt (or
+     less). If the command-line has more characters, `>' is put at the
+     position 78 (zero-origin), to inform the user of the hidden
+     characters.
+
+     Other sections always have `<' at the first position, since there
+     is absolutely a section before each section. If there is a section
+     after another section, this section consists of 77 characters and
+     `>' at the last position. The last section has 77 or less
+     characters and doesn't have `>'.
+
+     Each section other than the last shares some characters with the
+     previous section. This region is called ``margin''. If the cursor
+     is put at the magin which is shared by the first section and the
+     second, the first section is displayed. Otherwise, a displayed
+     section is switched to another section, only if the cursor is put
+     outside that section.  */
+
+  /* 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
+  
+  int xpos, lpos, c, section;
+  /* The length of PROMPT.  */
+  int plen;
+  /* The length of the command-line.  */
+  int llen;
+  /* The index for the history.  */
+  int history = -1;
+  /* The working buffer for the command-line.  */
+  char *buf = (char *) CMDLINE_BUF;
+  /* The kill buffer.  */
+  char *kill_buf = (char *) KILL_BUF;
+  
+  /* Nested function definitions for code simplicity.  */
+
+  /* The forward declarations of nested functions are prefixed
+     with `auto'.  */
+  auto void cl_refresh (int full, int len);
+  auto void cl_backward (int count);
+  auto void cl_forward (int count);
+  auto void cl_insert (const char *str);
+  auto void cl_delete (int count);
+  auto void cl_init (void);
+  
+  /* Move the cursor backward.  */
+  void cl_backward (int count)
+    {
+      lpos -= count;
+      
+      /* If the cursor is in the first section, display the first section
+	 instead of the second.  */
+      if (section == 1 && plen + lpos < CMDLINE_WIDTH)
+	cl_refresh (1, 0);
+      else if (xpos - count < 1)
+	cl_refresh (1, 0);
+      else
+	{
+	  xpos -= count;
+
+	  if (current_term->flags & TERM_DUMB)
+	    {
+	      int i;
+	      
+	      for (i = 0; i < count; i++)
+		grub_putchar ('\b');
+	    }
+	  else
+	    gotoxy (xpos, getxy () & 0xFF);
+	}
+    }
+
+  /* Move the cursor forward.  */
+  void cl_forward (int count)
+    {
+      lpos += count;
+
+      /* If the cursor goes outside, scroll the screen to the right.  */
+      if (xpos + count >= CMDLINE_WIDTH)
+	cl_refresh (1, 0);
+      else
+	{
+	  xpos += count;
+
+	  if (current_term->flags & TERM_DUMB)
+	    {
+	      int i;
+	      
+	      for (i = lpos - count; i < lpos; i++)
+		{
+		  if (! echo_char)
+		    grub_putchar (buf[i]);
+		  else
+		    grub_putchar (echo_char);
+		}
+	    }
+	  else
+	    gotoxy (xpos, getxy () & 0xFF);
+	}
+    }
+
+  /* Refresh the screen. If FULL is true, redraw the full line, otherwise,
+     only LEN characters from LPOS.  */
+  void cl_refresh (int full, int len)
+    {
+      int i;
+      int start;
+      int pos = xpos;
+      
+      if (full)
+	{
+	  /* Recompute the section number.  */
+	  if (lpos + plen < CMDLINE_WIDTH)
+	    section = 0;
+	  else
+	    section = ((lpos + plen - CMDLINE_WIDTH)
+		       / (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN) + 1);
+
+	  /* From the start to the end.  */
+	  len = CMDLINE_WIDTH;
+	  pos = 0;
+	  grub_putchar ('\r');
+
+	  /* If SECTION is the first section, print the prompt, otherwise,
+	     print `<'.  */
+	  if (section == 0)
+	    {
+	      grub_printf ("%s", prompt);
+	      len -= plen;
+	      pos += plen;
+	    }
+	  else
+	    {
+	      grub_putchar ('<');
+	      len--;
+	      pos++;
+	    }
+	}
+
+      /* Compute the index to start writing BUF and the resulting position
+	 on the screen.  */
+      if (section == 0)
+	{
+	  int offset = 0;
+	  
+	  if (! full)
+	    offset = xpos - plen;
+	  
+	  start = 0;
+	  xpos = lpos + plen;
+	  start += offset;
+	}
+      else
+	{
+	  int offset = 0;
+	  
+	  if (! full)
+	    offset = xpos - 1;
+	  
+	  start = ((section - 1) * (CMDLINE_WIDTH - 1 - CMDLINE_MARGIN)
+		   + CMDLINE_WIDTH - plen - CMDLINE_MARGIN);
+	  xpos = lpos + 1 - start;
+	  start += offset;
+	}
+
+      /* Print BUF. If ECHO_CHAR is not zero, put it instead.  */
+      for (i = start; i < start + len && i < llen; i++)
+	{
+	  if (! echo_char)
+	    grub_putchar (buf[i]);
+	  else
+	    grub_putchar (echo_char);
+
+	  pos++;
+	}
+      
+      /* Fill up the rest of the line with spaces.  */
+      for (; i < start + len; i++)
+	{
+	  grub_putchar (' ');
+	  pos++;
+	}
+      
+      /* 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 (start + len < llen)
+	    grub_putchar ('>');
+	  else
+	    grub_putchar (' ');
+	  
+	  pos++;
+	}
+      
+      /* Back to XPOS.  */
+      if (current_term->flags & TERM_DUMB)
+	{
+	  for (i = 0; i < pos - xpos; i++)
+	    grub_putchar ('\b');
+	}
+      else
+	gotoxy (xpos, getxy () & 0xFF);
+    }
+
+  /* Initialize the command-line.  */
+  void cl_init (void)
+    {
+      /* Distinguish us from other lines and error messages!  */
+      grub_putchar ('\n');
+
+      /* Print full line and set position here.  */
+      cl_refresh (1, 0);
+    }
+
+  /* Insert STR to BUF.  */
+  void cl_insert (const char *str)
+    {
+      int l = grub_strlen (str);
+
+      if (llen + l < maxlen)
+	{
+	  if (lpos == llen)
+	    grub_memmove (buf + lpos, str, l + 1);
+	  else
+	    {
+	      grub_memmove (buf + lpos + l, buf + lpos, llen - lpos + 1);
+	      grub_memmove (buf + lpos, str, l);
+	    }
+	  
+	  llen += l;
+	  lpos += l;
+	  if (xpos + l >= CMDLINE_WIDTH)
+	    cl_refresh (1, 0);
+	  else if (xpos + l + llen - lpos > CMDLINE_WIDTH)
+	    cl_refresh (0, CMDLINE_WIDTH - xpos);
+	  else
+	    cl_refresh (0, l + llen - lpos);
+	}
+    }
+
+  /* Delete COUNT characters in BUF.  */
+  void cl_delete (int count)
+    {
+      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);
+      else
+	cl_refresh (0, llen + count - lpos);
+    }
+
+  plen = grub_strlen (prompt);
+  llen = grub_strlen (cmdline);
+
+  if (maxlen > MAX_CMDLINE)
+    {
+      maxlen = MAX_CMDLINE;
+      if (llen >= MAX_CMDLINE)
+	{
+	  llen = MAX_CMDLINE - 1;
+	  cmdline[MAX_CMDLINE] = 0;
+	}
+    }
+  lpos = llen;
+  grub_strcpy (buf, cmdline);
+
+  cl_init ();
+
+  while ((c = ASCII_CHAR (getkey ())) != '\n' && c != '\r')
+    {
+      /* If READLINE is non-zero, handle readline-like key bindings.  */
+      if (readline)
+	{
+	  switch (c)
+	    {
+	    case 9:		/* TAB lists completions */
+	      {
+		int i;
+		/* POS points to the first space after a command.  */
+		int pos = 0;
+		int ret;
+		char *completion_buffer = (char *) COMPLETION_BUF;
+		int equal_pos = -1;
+		int is_filename;
+
+		/* Find the first word.  */
+		while (buf[pos] == ' ')
+		  pos++;
+		while (buf[pos] && buf[pos] != '=' && buf[pos] != ' ')
+		  pos++;
+
+		is_filename = (lpos > pos);
+
+		/* Find the position of the equal character after a
+		   command, and replace it with a space.  */
+		for (i = pos; buf[i] && buf[i] != ' '; i++)
+		  if (buf[i] == '=')
+		    {
+		      equal_pos = i;
+		      buf[i] = ' ';
+		      break;
+		    }
+
+		/* Find the position of the first character in this
+		   word.  */
+		for (i = lpos; i > 0 && buf[i - 1] != ' '; i--)
+		  ;
+
+		/* Invalidate the cache, because the user may exchange
+		   removable disks.  */
+		buf_drive = -1;
+
+		/* Copy this word to COMPLETION_BUFFER and do the
+		   completion.  */
+		grub_memmove (completion_buffer, buf + i, lpos - i);
+		completion_buffer[lpos - i] = 0;
+		ret = print_completions (is_filename, 1);
+		errnum = ERR_NONE;
+
+		if (ret >= 0)
+		  {
+		    /* Found, so insert COMPLETION_BUFFER.  */
+		    cl_insert (completion_buffer + lpos - i);
+
+		    if (ret > 0)
+		      {
+			/* There are more than one candidates, so print
+			   the list.  */
+			grub_putchar ('\n');
+			print_completions (is_filename, 0);
+			errnum = ERR_NONE;
+		      }
+		  }
+
+		/* Restore the command-line.  */
+		if (equal_pos >= 0)
+		  buf[equal_pos] = '=';
+
+		if (ret)
+		  cl_init ();
+	      }
+	      break;
+	    case 1:		/* C-a go to beginning of line */
+	      cl_backward (lpos);
+	      break;
+	    case 5:		/* C-e go to end of line */
+	      cl_forward (llen - lpos);
+	      break;
+	    case 6:		/* C-f forward one character */
+	      if (lpos < llen)
+		cl_forward (1);
+	      break;
+	    case 2:		/* C-b backward one character */
+	      if (lpos > 0)
+		cl_backward (1);
+	      break;
+	    case 21:		/* C-u kill to beginning of line */
+	      if (lpos == 0)
+		break;
+	      /* Copy the string being deleted to KILL_BUF.  */
+	      grub_memmove (kill_buf, buf, lpos);
+	      kill_buf[lpos] = 0;
+	      {
+		/* XXX: Not very clever.  */
+		
+		int count = lpos;
+		
+		cl_backward (lpos);
+		cl_delete (count);
+	      }
+	      break;
+	    case 11:		/* C-k kill to end of line */
+	      if (lpos == llen)
+		break;
+	      /* Copy the string being deleted to KILL_BUF.  */
+	      grub_memmove (kill_buf, buf + lpos, llen - lpos + 1);
+	      cl_delete (llen - lpos);
+	      break;
+	    case 25:		/* C-y yank the kill buffer */
+	      cl_insert (kill_buf);
+	      break;
+	    case 16:		/* C-p fetch the previous command */
+	      {
+		char *p;
+
+		if (history < 0)
+		  /* Save the working buffer.  */
+		  grub_strcpy (cmdline, buf);
+		else if (grub_strcmp (get_history (history), buf) != 0)
+		  /* If BUF is modified, add it into the history list.  */
+		  add_history (buf, history);
+
+		history++;
+		p = get_history (history);
+		if (! p)
+		  {
+		    history--;
+		    break;
+		  }
+
+		grub_strcpy (buf, p);
+		llen = grub_strlen (buf);
+		lpos = llen;
+		cl_refresh (1, 0);
+	      }
+	      break;
+	    case 14:		/* C-n fetch the next command */
+	      {
+		char *p;
+
+		if (history < 0)
+		  {
+		    break;
+		  }
+		else if (grub_strcmp (get_history (history), buf) != 0)
+		  /* If BUF is modified, add it into the history list.  */
+		  add_history (buf, history);
+
+		history--;
+		p = get_history (history);
+		if (! p)
+		  p = cmdline;
+
+		grub_strcpy (buf, p);
+		llen = grub_strlen (buf);
+		lpos = llen;
+		cl_refresh (1, 0);
+	      }
+	      break;
+	    }
+	}
+
+      /* ESC, C-d and C-h are always handled. Actually C-d is not
+	 functional if READLINE is zero, as the cursor cannot go
+	 backward, but that's ok.  */
+      switch (c)
+	{
+	case 27:	/* ESC immediately return 1 */
+	  return 1;
+	case 4:		/* C-d delete character under cursor */
+	  if (lpos == llen)
+	    break;
+	  cl_delete (1);
+	  break;
+	case 8:		/* C-h backspace */
+# ifdef GRUB_UTIL
+	case 127:	/* also backspace */
+# endif
+	  if (lpos > 0)
+	    {
+	      cl_backward (1);
+	      cl_delete (1);
+	    }
+	  break;
+	default:		/* insert printable character into line */
+	  if (c >= ' ' && c <= '~')
+	    {
+	      char str[2];
+
+	      str[0] = c;
+	      str[1] = 0;
+	      cl_insert (str);
+	    }
+	}
+    }
+
+  grub_putchar ('\n');
+
+  /* If ECHO_CHAR is NUL, remove the leading spaces.  */
+  lpos = 0;
+  if (! echo_char)
+    while (buf[lpos] == ' ')
+      lpos++;
+
+  /* Copy the working buffer to CMDLINE.  */
+  grub_memmove (cmdline, buf + lpos, llen - lpos + 1);
+
+  /* If the readline-like feature is turned on and CMDLINE is not
+     empty, add it into the history list.  */
+  if (readline && lpos < llen)
+    add_history (cmdline, 0);
+
+  return 0;
+}
+
+/* Don't use this with a MAXLEN greater than 1600 or so!  The problem
+   is that GET_CMDLINE depends on the everything fitting on the screen
+   at once.  So, the whole screen is about 2000 characters, minus the
+   PROMPT, and space for error and status lines, etc.  MAXLEN must be
+   at least 1, and PROMPT and CMDLINE must be valid strings (not NULL
+   or zero-length).
+
+   If ECHO_CHAR is nonzero, echo it instead of the typed character. */
+int
+get_cmdline (char *prompt, char *cmdline, int maxlen,
+	     int echo_char, int readline)
+{
+  int old_cursor;
+  int ret;
+
+  old_cursor = setcursor (1);
+  
+  /* Because it is hard to deal with different conditions simultaneously,
+     less functional cases are handled here. Assume that TERM_NO_ECHO
+     implies TERM_NO_EDIT.  */
+  if (current_term->flags & (TERM_NO_ECHO | TERM_NO_EDIT))
+    {
+      char *p = cmdline;
+      int c;
+      
+      /* Make sure that MAXLEN is not too large.  */
+      if (maxlen > MAX_CMDLINE)
+	maxlen = MAX_CMDLINE;
+
+      /* Print only the prompt. The contents of CMDLINE is simply discarded,
+	 even if it is not empty.  */
+      grub_printf ("%s", prompt);
+
+      /* Gather characters until a newline is gotten.  */
+      while ((c = ASCII_CHAR (getkey ())) != '\n' && c != '\r')
+	{
+	  /* Return immediately if ESC is pressed.  */
+	  if (c == 27)
+	    {
+	      setcursor (old_cursor);
+	      return 1;
+	    }
+
+	  /* Printable characters are added into CMDLINE.  */
+	  if (c >= ' ' && c <= '~')
+	    {
+	      if (! (current_term->flags & TERM_NO_ECHO))
+		grub_putchar (c);
+
+	      /* Preceding space characters must be ignored.  */
+	      if (c != ' ' || p != cmdline)
+		*p++ = c;
+	    }
+	}
+
+      *p = 0;
+
+      if (! (current_term->flags & TERM_NO_ECHO))
+	grub_putchar ('\n');
+
+      setcursor (old_cursor);
+      return 0;
+    }
+
+  /* Complicated features are left to real_get_cmdline.  */
+  ret = real_get_cmdline (prompt, cmdline, maxlen, echo_char, readline);
+  setcursor (old_cursor);
+  return ret;
+}
+
+int
+safe_parse_maxint (char **str_ptr, int *myint_ptr)
+{
+  char *ptr = *str_ptr;
+  int myint = 0;
+  int mult = 10, found = 0;
+
+  /*
+   *  Is this a hex number?
+   */
+  if (*ptr == '0' && tolower (*(ptr + 1)) == 'x')
+    {
+      ptr += 2;
+      mult = 16;
+    }
+
+  while (1)
+    {
+      /* A bit tricky. This below makes use of the equivalence:
+	 (A >= B && A <= C) <=> ((A - B) <= (C - B))
+	 when C > B and A is unsigned.  */
+      unsigned int digit;
+
+      digit = tolower (*ptr) - '0';
+      if (digit > 9)
+	{
+	  digit -= 'a' - '0';
+	  if (mult == 10 || digit > 5)
+	    break;
+	  digit += 10;
+	}
+
+      found = 1;
+      if (myint > ((MAXINT - digit) / mult))
+	{
+	  errnum = ERR_NUMBER_OVERFLOW;
+	  return 0;
+	}
+      myint = (myint * mult) + digit;
+      ptr++;
+    }
+
+  if (!found)
+    {
+      errnum = ERR_NUMBER_PARSING;
+      return 0;
+    }
+
+  *str_ptr = ptr;
+  *myint_ptr = myint;
+
+  return 1;
+}
+#endif /* STAGE1_5 */
+
+#if !defined(STAGE1_5) || defined(FSYS_FAT)
+int
+grub_tolower (int c)
+{
+  if (c >= 'A' && c <= 'Z')
+    return (c + ('a' - 'A'));
+
+  return c;
+}
+#endif /* ! STAGE1_5 || FSYS_FAT */
+
+int
+grub_isspace (int c)
+{
+  switch (c)
+    {
+    case ' ':
+    case '\t':
+    case '\r':
+    case '\n':
+      return 1;
+    default:
+      break;
+    }
+
+  return 0;
+}
+
+#if !defined(STAGE1_5) || defined(FSYS_ISO9660)
+int
+grub_memcmp (const char *s1, const char *s2, int n)
+{
+  while (n)
+    {
+      if (*s1 < *s2)
+	return -1;
+      else if (*s1 > *s2)
+	return 1;
+      s1++;
+      s2++;
+      n--;
+    }
+
+  return 0;
+}
+#endif /* ! STAGE1_5 || FSYS_ISO9660 */
+
+#ifndef STAGE1_5
+int
+grub_strncat (char *s1, const char *s2, int n)
+{
+  int i = -1;
+
+  while (++i < n && s1[i] != 0);
+
+  while (i < n && (s1[i++] = *(s2++)) != 0);
+
+  s1[n - 1] = 0;
+
+  if (i >= n)
+    return 0;
+
+  s1[i] = 0;
+
+  return 1;
+}
+#endif /* ! STAGE1_5 */
+
+/* XXX: This below is an evil hack. Certainly, we should change the
+   strategy to determine what should be defined and what shouldn't be
+   defined for each image. For example, it would be better to create
+   a static library supporting minimal standard C functions and link
+   each image with the library. Complicated things should be left to
+   computer, definitely. -okuji  */
+#if !defined(STAGE1_5) || defined(FSYS_VSTAFS)
+int
+grub_strcmp (const char *s1, const char *s2)
+{
+  while (*s1 || *s2)
+    {
+      if (*s1 < *s2)
+	return -1;
+      else if (*s1 > *s2)
+	return 1;
+      s1 ++;
+      s2 ++;
+    }
+
+  return 0;
+}
+#endif /* ! STAGE1_5 || FSYS_VSTAFS */
+
+#ifndef STAGE1_5
+/* Wait for a keypress and return its code.  */
+int
+getkey (void)
+{
+  return current_term->getkey ();
+}
+
+/* Check if a key code is available.  */
+int
+checkkey (void)
+{
+  return current_term->checkkey ();
+}
+#endif /* ! STAGE1_5 */
+
+/* Display an ASCII character.  */
+void
+grub_putchar (int c)
+{
+  if (c == '\n')
+    grub_putchar ('\r');
+#ifndef STAGE1_5
+  else if (c == '\t' && current_term->getxy)
+    {
+      int n;
+      
+      n = 8 - ((current_term->getxy () >> 8) & 3);
+      while (n--)
+	grub_putchar (' ');
+      
+      return;
+    }
+#endif /* ! STAGE1_5 */
+  
+#ifdef STAGE1_5
+  
+  /* In Stage 1.5, only the normal console is supported.  */
+  console_putchar (c);
+  
+#else /* ! STAGE1_5 */
+
+  if (c == '\n')
+    {
+      /* 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;
+	    }
+	}
+    }
+
+  current_term->putchar (c);
+  
+#endif /* ! STAGE1_5 */
+}
+
+#ifndef STAGE1_5
+void
+gotoxy (int x, int y)
+{
+  current_term->gotoxy (x, y);
+}
+
+int
+getxy (void)
+{
+  return current_term->getxy ();
+}
+
+void
+cls (void)
+{
+  /* If the terminal is dumb, there is no way to clean the terminal.  */
+  if (current_term->flags & TERM_DUMB)
+    grub_putchar ('\n');
+  else
+    current_term->cls ();
+}
+
+int
+setcursor (int on)
+{
+  if (current_term->setcursor)
+    return current_term->setcursor (on);
+
+  return 1;
+}
+#endif /* ! STAGE1_5 */
+
+int
+substring (const char *s1, const char *s2)
+{
+  while (*s1 == *s2)
+    {
+      /* The strings match exactly. */
+      if (! *(s1++))
+	return 0;
+      s2 ++;
+    }
+
+  /* S1 is a substring of S2. */
+  if (*s1 == 0)
+    return -1;
+
+  /* S1 isn't a substring. */
+  return 1;
+}
+
+#ifndef STAGE1_5
+/* Terminate the string STR with NUL.  */
+int
+nul_terminate (char *str)
+{
+  int ch;
+  
+  while (*str && ! grub_isspace (*str))
+    str++;
+
+  ch = *str;
+  *str = 0;
+  return ch;
+}
+
+char *
+grub_strstr (const char *s1, const char *s2)
+{
+  while (*s1)
+    {
+      const char *ptr, *tmp;
+
+      ptr = s1;
+      tmp = s2;
+
+      while (*tmp && *ptr == *tmp)
+	ptr++, tmp++;
+      
+      if (tmp > s2 && ! *tmp)
+	return (char *) s1;
+
+      s1++;
+    }
+
+  return 0;
+}
+
+int
+grub_strlen (const char *str)
+{
+  int len = 0;
+
+  while (*str++)
+    len++;
+
+  return len;
+}
+#endif /* ! STAGE1_5 */
+
+int
+memcheck (int addr, int len)
+{
+#ifdef GRUB_UTIL
+  auto int start_addr (void);
+  auto int end_addr (void);
+  
+  auto int start_addr (void)
+    {
+      int ret;
+# if defined(HAVE_START_SYMBOL)
+      asm volatile ("movl	$start, %0" : "=a" (ret));
+# elif defined(HAVE_USCORE_START_SYMBOL)
+      asm volatile ("movl	$_start, %0" : "=a" (ret));
+# endif
+      return ret;
+    }
+
+  auto int end_addr (void)
+    {
+      int ret;
+# if defined(HAVE_END_SYMBOL)
+      asm volatile ("movl	$end, %0" : "=a" (ret));
+# elif defined(HAVE_USCORE_END_SYMBOL)
+      asm volatile ("movl	$_end, %0" : "=a" (ret));
+# endif
+      return ret;
+    }
+
+  if (start_addr () <= addr && end_addr () > addr + len)
+    return ! errnum;
+#endif /* GRUB_UTIL */
+
+  if ((addr < RAW_ADDR (0x1000))
+      || (addr < RAW_ADDR (0x100000)
+	  && RAW_ADDR (mbi.mem_lower * 1024) < (addr + len))
+      || (addr >= RAW_ADDR (0x100000)
+	  && RAW_ADDR (mbi.mem_upper * 1024) < ((addr - 0x100000) + len)))
+    errnum = ERR_WONT_FIT;
+
+  return ! errnum;
+}
+
+void *
+grub_memmove (void *to, const void *from, int len)
+{
+   if (memcheck ((int) to, len))
+     {
+       /* This assembly code is stolen from
+	  linux-2.2.2/include/asm-i386/string.h. This is not very fast
+	  but compact.  */
+       int d0, d1, d2;
+
+       if (to < from)
+	 {
+	   asm volatile ("cld\n\t"
+			 "rep\n\t"
+			 "movsb"
+			 : "=&c" (d0), "=&S" (d1), "=&D" (d2)
+			 : "0" (len),"1" (from),"2" (to)
+			 : "memory");
+	 }
+       else
+	 {
+	   asm volatile ("std\n\t"
+			 "rep\n\t"
+			 "movsb\n\t"
+			 "cld"
+			 : "=&c" (d0), "=&S" (d1), "=&D" (d2)
+			 : "0" (len),
+			 "1" (len - 1 + (const char *) from),
+			 "2" (len - 1 + (char *) to)
+			 : "memory");
+	 }
+     }
+
+   return errnum ? NULL : to;
+}
+
+void *
+grub_memset (void *start, int c, int len)
+{
+  char *p = start;
+
+  if (memcheck ((int) start, len))
+    {
+      while (len -- > 0)
+	*p ++ = c;
+    }
+
+  return errnum ? NULL : start;
+}
+
+#ifndef STAGE1_5
+char *
+grub_strcpy (char *dest, const char *src)
+{
+  grub_memmove (dest, src, grub_strlen (src) + 1);
+  return dest;
+}
+#endif /* ! STAGE1_5 */
+
+#ifndef GRUB_UTIL
+# undef memcpy
+/* GCC emits references to memcpy() for struct copies etc.  */
+void *memcpy (void *dest, const void *src, int n)  __attribute__ ((alias ("grub_memmove")));
+#endif
diff --git a/stage2/cmdline.c b/stage2/cmdline.c
new file mode 100644
index 0000000..a6ee309
--- /dev/null
+++ b/stage2/cmdline.c
@@ -0,0 +1,257 @@
+/* cmdline.c - the device-independent GRUB text command line */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,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 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.
+ */
+
+#include <shared.h>
+
+#ifdef SUPPORT_DISKLESS
+# define GRUB	1
+# include <etherboot.h>
+#endif
+
+grub_jmp_buf restart_cmdline_env;
+
+/* Find the next word from CMDLINE and return the pointer. If
+   AFTER_EQUAL is non-zero, assume that the character `=' is treated as
+   a space. Caution: this assumption is for backward compatibility.  */
+char *
+skip_to (int after_equal, char *cmdline)
+{
+  /* Skip until we hit whitespace, or maybe an equal sign. */
+  while (*cmdline && *cmdline != ' ' && *cmdline != '\t' &&
+	 ! (after_equal && *cmdline == '='))
+    cmdline ++;
+
+  /* Skip whitespace, and maybe equal signs. */
+  while (*cmdline == ' ' || *cmdline == '\t' ||
+	 (after_equal && *cmdline == '='))
+    cmdline ++;
+
+  return cmdline;
+}
+
+/* Print a helpful message for the command-line interface.  */
+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."));
+}
+
+/* Find the builtin whose command name is COMMAND and return the
+   pointer. If not found, return 0.  */
+struct builtin *
+find_command (char *command)
+{
+  char *ptr;
+  char c;
+  struct builtin **builtin;
+
+  /* Find the first space and terminate the command name.  */
+  ptr = command;
+  while (*ptr && *ptr != ' ' && *ptr != '\t' && *ptr != '=')
+    ptr ++;
+
+  c = *ptr;
+  *ptr = 0;
+
+  /* Seek out the builtin whose command name is COMMAND.  */
+  for (builtin = builtin_table; *builtin != 0; builtin++)
+    {
+      int ret = grub_strcmp (command, (*builtin)->name);
+
+      if (ret == 0)
+	{
+	  /* Find the builtin for COMMAND.  */
+	  *ptr = c;
+	  return *builtin;
+	}
+      else if (ret < 0)
+	break;
+    }
+
+  /* Cannot find COMMAND.  */
+  errnum = ERR_UNRECOGNIZED;
+  *ptr = c;
+  return 0;
+}
+
+/* Initialize the data for the command-line.  */
+static void
+init_cmdline (void)
+{
+  /* Initialization.  */
+  saved_drive = boot_drive;
+  saved_partition = install_partition;
+  current_drive = GRUB_INVALID_DRIVE;
+  errnum = 0;
+  count_lines = -1;
+  
+  /* Restore memory probe state.  */
+  mbi.mem_upper = saved_mem_upper;
+  if (mbi.mmap_length)
+    mbi.flags |= MB_INFO_MEM_MAP;
+
+  /* Initialize the data for the builtin commands.  */
+  init_builtins ();
+}
+
+/* Enter the command-line interface. HEAP is used for the command-line
+   buffer. Return only if FOREVER is nonzero and get_cmdline returns
+   nonzero (ESC is pushed).  */
+void
+enter_cmdline (char *heap, int forever)
+{
+  /* Initialize the data and print a message.  */
+  init_cmdline ();
+  grub_setjmp (restart_cmdline_env);
+  init_page ();
+#ifdef SUPPORT_DISKLESS
+  print_network_configuration ();
+  grub_putchar ('\n');
+#endif
+  print_cmdline_message (forever);
+  
+  while (1)
+    {
+      struct builtin *builtin;
+      char *arg;
+
+      *heap = 0;
+      print_error ();
+      errnum = ERR_NONE;
+
+      /* Get the command-line with the minimal BASH-like interface.  */
+      if (get_cmdline (PACKAGE "> ", heap, 2048, 0, 1))
+	return;
+
+      /* If there was no command, grab a new one. */
+      if (! heap[0])
+	continue;
+
+      /* Find a builtin.  */
+      builtin = find_command (heap);
+      if (! builtin)
+	continue;
+
+      /* If BUILTIN cannot be run in the command-line, skip it.  */
+      if (! (builtin->flags & BUILTIN_CMDLINE))
+	{
+	  errnum = ERR_UNRECOGNIZED;
+	  continue;
+	}
+
+      /* Invalidate the cache, because the user may exchange removable
+	 disks.  */
+      buf_drive = -1;
+
+      /* Start to count lines, only if the internal pager is in use.  */
+      if (use_pager)
+	count_lines = 0;
+      
+      /* Run BUILTIN->FUNC.  */
+      arg = skip_to (1, heap);
+      (builtin->func) (arg, BUILTIN_CMDLINE);
+
+      /* Finish the line count.  */
+      count_lines = -1;
+    }
+}
+
+/* Run an entry from the script SCRIPT. HEAP is used for the
+   command-line buffer. If an error occurs, return non-zero, otherwise
+   return zero.  */
+int
+run_script (char *script, char *heap)
+{
+  char *old_entry;
+  char *cur_entry = script;
+
+  /* Initialize the data.  */
+  init_cmdline ();
+
+  while (1)
+    {
+      struct builtin *builtin;
+      char *arg;
+
+      print_error ();
+
+      if (errnum)
+	{
+	  errnum = ERR_NONE;
+
+	  /* If a fallback entry is defined, don't prompt a user's
+	     intervention.  */
+	  if (fallback_entryno < 0)
+	    {
+	      grub_printf ("\nPress any key to continue...");
+	      (void) getkey ();
+	    }
+	  
+	  return 1;
+	}
+
+      /* Copy the first string in CUR_ENTRY to HEAP.  */
+      old_entry = cur_entry;
+      while (*cur_entry++)
+	;
+
+      grub_memmove (heap, old_entry, (int) cur_entry - (int) old_entry);
+      if (! *heap)
+	{
+	  /* If there is no more command in SCRIPT...  */
+
+	  /* If any kernel is not loaded, just exit successfully.  */
+	  if (kernel_type == KERNEL_TYPE_NONE)
+	    return 0;
+
+	  /* Otherwise, the command boot is run implicitly.  */
+	  grub_memmove (heap, "boot", 5);
+	}
+
+      /* Find a builtin.  */
+      builtin = find_command (heap);
+      if (! builtin)
+	{
+	  grub_printf ("%s\n", old_entry);
+	  continue;
+	}
+
+      if (! (builtin->flags & BUILTIN_NO_ECHO))
+	grub_printf ("%s\n", old_entry);
+
+      /* If BUILTIN cannot be run in the command-line, skip it.  */
+      if (! (builtin->flags & BUILTIN_CMDLINE))
+	{
+	  errnum = ERR_UNRECOGNIZED;
+	  continue;
+	}
+
+      /* Invalidate the cache, because the user may exchange removable
+	 disks.  */
+      buf_drive = -1;
+
+      /* Run BUILTIN->FUNC.  */
+      arg = skip_to (1, heap);
+      (builtin->func) (arg, BUILTIN_SCRIPT);
+    }
+}
diff --git a/stage2/common.c b/stage2/common.c
new file mode 100644
index 0000000..09f9e31
--- /dev/null
+++ b/stage2/common.c
@@ -0,0 +1,337 @@
+/* common.c - miscellaneous shared variables and routines */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,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 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.
+ */
+
+#include <shared.h>
+
+#ifdef SUPPORT_DISKLESS
+# define GRUB	1
+# include <etherboot.h>
+#endif
+
+/*
+ *  Shared BIOS/boot data.
+ */
+
+struct multiboot_info mbi;
+unsigned long saved_drive;
+unsigned long saved_partition;
+unsigned long cdrom_drive;
+#ifndef STAGE1_5
+unsigned long saved_mem_upper;
+
+/* This saves the maximum size of extended memory (in KB).  */
+unsigned long extended_memory;
+#endif
+
+/*
+ *  Error code stuff.
+ */
+
+grub_error_t errnum = ERR_NONE;
+
+#ifndef STAGE1_5
+
+char *err_list[] =
+{
+  [ERR_NONE] = 0,
+  [ERR_BAD_ARGUMENT] = "Invalid argument",
+  [ERR_BAD_FILENAME] =
+  "Filename must be either an absolute pathname or blocklist",
+  [ERR_BAD_FILETYPE] = "Bad file or directory type",
+  [ERR_BAD_GZIP_DATA] = "Bad or corrupt data while decompressing file",
+  [ERR_BAD_GZIP_HEADER] = "Bad or incompatible header in compressed file",
+  [ERR_BAD_PART_TABLE] = "Partition table invalid or corrupt",
+  [ERR_BAD_VERSION] = "Mismatched or corrupt version of stage1/stage2",
+  [ERR_BELOW_1MB] = "Loading below 1MB is not supported",
+  [ERR_BOOT_COMMAND] = "Kernel must be loaded before booting",
+  [ERR_BOOT_FAILURE] = "Unknown boot failure",
+  [ERR_BOOT_FEATURES] = "Unsupported Multiboot features requested",
+  [ERR_DEV_FORMAT] = "Unrecognized device string",
+  [ERR_DEV_NEED_INIT] = "Device not initialized yet",
+  [ERR_DEV_VALUES] = "Invalid device requested",
+  [ERR_EXEC_FORMAT] = "Invalid or unsupported executable format",
+  [ERR_FILELENGTH] =
+  "Filesystem compatibility error, cannot read whole file",
+  [ERR_FILE_NOT_FOUND] = "File not found",
+  [ERR_FSYS_CORRUPT] = "Inconsistent filesystem structure",
+  [ERR_FSYS_MOUNT] = "Cannot mount selected partition",
+  [ERR_GEOM] = "Selected cylinder exceeds maximum supported by BIOS",
+  [ERR_NEED_LX_KERNEL] = "Linux kernel must be loaded before initrd",
+  [ERR_NEED_MB_KERNEL] = "Multiboot kernel must be loaded before modules",
+  [ERR_NO_DISK] = "Selected disk does not exist",
+  [ERR_NO_DISK_SPACE] = "No spare sectors on the disk",
+  [ERR_NO_PART] = "No such partition",
+  [ERR_NUMBER_OVERFLOW] = "Overflow while parsing number",
+  [ERR_NUMBER_PARSING] = "Error while parsing number",
+  [ERR_OUTSIDE_PART] = "Attempt to access block outside partition",
+  [ERR_PRIVILEGED] = "Must be authenticated",
+  [ERR_READ] = "Disk read error",
+  [ERR_SYMLINK_LOOP] = "Too many symbolic links",
+  [ERR_UNALIGNED] = "File is not sector aligned",
+  [ERR_UNRECOGNIZED] = "Unrecognized command",
+  [ERR_WONT_FIT] = "Selected item cannot fit into memory",
+  [ERR_WRITE] = "Disk write error",
+};
+
+
+/* static for BIOS memory map fakery */
+static struct AddrRangeDesc fakemap[3] =
+{
+  {20, 0, 0, MB_ARD_MEMORY},
+  {20, 0x100000, 0, MB_ARD_MEMORY},
+  {20, 0x1000000, 0, MB_ARD_MEMORY}
+};
+
+/* A big problem is that the memory areas aren't guaranteed to be:
+   (1) contiguous, (2) sorted in ascending order, or (3) non-overlapping.
+   Thus this kludge.  */
+static unsigned long
+mmap_avail_at (unsigned long bottom)
+{
+  unsigned long long top;
+  unsigned long addr;
+  int cont;
+  
+  top = bottom;
+  do
+    {
+      for (cont = 0, addr = mbi.mmap_addr;
+	   addr < mbi.mmap_addr + mbi.mmap_length;
+	   addr += *((unsigned long *) addr) + 4)
+	{
+	  struct AddrRangeDesc *desc = (struct AddrRangeDesc *) addr;
+	  
+	  if (desc->Type == MB_ARD_MEMORY
+	      && desc->BaseAddr <= top
+	      && desc->BaseAddr + desc->Length > top)
+	    {
+	      top = desc->BaseAddr + desc->Length;
+	      cont++;
+	    }
+	}
+    }
+  while (cont);
+
+  /* For now, GRUB assumes 32bits addresses, so...  */
+  if (top > 0xFFFFFFFF)
+    top = 0xFFFFFFFF;
+  
+  return (unsigned long) top - bottom;
+}
+#endif /* ! STAGE1_5 */
+
+/* This queries for BIOS information.  */
+void
+init_bios_info (void)
+{
+#ifndef STAGE1_5
+  unsigned long cont, memtmp, addr;
+  int drive;
+#endif
+
+  /*
+   *  Get information from BIOS on installed RAM.
+   */
+
+  mbi.mem_lower = get_memsize (0);
+  mbi.mem_upper = get_memsize (1);
+
+#ifndef STAGE1_5
+  /*
+   *  We need to call this somewhere before trying to put data
+   *  above 1 MB, since without calling it, address line 20 will be wired
+   *  to 0.  Not too desirable.
+   */
+
+  gateA20 (1);
+
+  /* Store the size of extended memory in EXTENDED_MEMORY, in order to
+     tell it to non-Multiboot OSes.  */
+  extended_memory = mbi.mem_upper;
+  
+  /*
+   *  The "mbi.mem_upper" variable only recognizes upper memory in the
+   *  first memory region.  If there are multiple memory regions,
+   *  the rest are reported to a Multiboot-compliant OS, but otherwise
+   *  unused by GRUB.
+   */
+
+  addr = get_code_end ();
+  mbi.mmap_addr = addr;
+  mbi.mmap_length = 0;
+  cont = 0;
+
+  do
+    {
+      cont = get_mmap_entry ((void *) addr, cont);
+
+      /* If the returned buffer's length is zero, quit. */
+      if (! *((unsigned long *) addr))
+	break;
+
+      mbi.mmap_length += *((unsigned long *) addr) + 4;
+      addr += *((unsigned long *) addr) + 4;
+    }
+  while (cont);
+
+  if (mbi.mmap_length)
+    {
+      unsigned long long max_addr;
+      
+      /*
+       *  This is to get the lower memory, and upper memory (up to the
+       *  first memory hole), into the "mbi.mem_{lower,upper}"
+       *  elements.  This is for OS's that don't care about the memory
+       *  map, but might care about total RAM available.
+       */
+      mbi.mem_lower = mmap_avail_at (0) >> 10;
+      mbi.mem_upper = mmap_avail_at (0x100000) >> 10;
+
+      /* Find the maximum available address. Ignore any memory holes.  */
+      for (max_addr = 0, addr = mbi.mmap_addr;
+	   addr < mbi.mmap_addr + mbi.mmap_length;
+	   addr += *((unsigned long *) addr) + 4)
+	{
+	  struct AddrRangeDesc *desc = (struct AddrRangeDesc *) addr;
+	  
+	  if (desc->Type == MB_ARD_MEMORY && desc->Length > 0
+	      && desc->BaseAddr + desc->Length > max_addr)
+	    max_addr = desc->BaseAddr + desc->Length;
+	}
+
+      extended_memory = (max_addr - 0x100000) >> 10;
+    }
+  else if ((memtmp = get_eisamemsize ()) != -1)
+    {
+      cont = memtmp & ~0xFFFF;
+      memtmp = memtmp & 0xFFFF;
+
+      if (cont != 0)
+	extended_memory = (cont >> 10) + 0x3c00;
+      else
+	extended_memory = memtmp;
+      
+      if (!cont || (memtmp == 0x3c00))
+	memtmp += (cont >> 10);
+      else
+	{
+	  /* XXX should I do this at all ??? */
+
+	  mbi.mmap_addr = (unsigned long) fakemap;
+	  mbi.mmap_length = sizeof (fakemap);
+	  fakemap[0].Length = (mbi.mem_lower << 10);
+	  fakemap[1].Length = (memtmp << 10);
+	  fakemap[2].Length = cont;
+	}
+
+      mbi.mem_upper = memtmp;
+    }
+
+  saved_mem_upper = mbi.mem_upper;
+
+  /* Get the drive info.  */
+  /* FIXME: This should be postponed until a Multiboot kernel actually
+     requires it, because this could slow down the start-up
+     unreasonably.  */
+  mbi.drives_length = 0;
+  mbi.drives_addr = addr;
+
+  /* For now, GRUB doesn't probe floppies, since it is trivial to map
+     floppy drives to BIOS drives.  */
+  for (drive = 0x80; drive < 0x88; drive++)
+    {
+      struct geometry geom;
+      struct drive_info *info = (struct drive_info *) addr;
+      unsigned short *port;
+      
+      /* Get the geometry. This ensures that the drive is present.  */
+      if (get_diskinfo (drive, &geom))
+	break;
+      
+      /* Clean out the I/O map.  */
+      grub_memset ((char *) io_map, 0,
+		   IO_MAP_SIZE * sizeof (unsigned short));
+
+      /* Disable to probe I/O ports temporarily, because this doesn't
+	 work with some BIOSes (maybe they are too buggy).  */
+#if 0
+      /* Track the int13 handler.  */
+      track_int13 (drive);
+#endif
+
+      /* Set the information.  */
+      info->drive_number = drive;
+      info->drive_mode = ((geom.flags & BIOSDISK_FLAG_LBA_EXTENSION)
+			  ? MB_DI_LBA_MODE : MB_DI_CHS_MODE);
+      info->drive_cylinders = geom.cylinders;
+      info->drive_heads = geom.heads;
+      info->drive_sectors = geom.sectors;
+
+      addr += sizeof (struct drive_info);
+      for (port = io_map; *port; port++, addr += sizeof (unsigned short))
+	*((unsigned short *) addr) = *port;
+
+      info->size = addr - (unsigned long) info;
+      mbi.drives_length += info->size;
+    }
+
+  /* Get the ROM configuration table by INT 15, AH=C0h.  */
+  mbi.config_table = get_rom_config_table ();
+
+  /* Set the boot loader name.  */
+  mbi.boot_loader_name = (unsigned long) "GNU GRUB " VERSION;
+
+  /* Get the APM BIOS table.  */
+  get_apm_info ();
+  if (apm_bios_info.version)
+    mbi.apm_table = (unsigned long) &apm_bios_info;
+  
+  /*
+   *  Initialize other Multiboot Info flags.
+   */
+
+  mbi.flags = (MB_INFO_MEMORY | MB_INFO_CMDLINE | MB_INFO_BOOTDEV
+	       | MB_INFO_DRIVE_INFO | MB_INFO_CONFIG_TABLE
+	       | MB_INFO_BOOT_LOADER_NAME);
+  
+  if (apm_bios_info.version)
+    mbi.flags |= MB_INFO_APM_TABLE;
+
+#endif /* STAGE1_5 */
+
+  /* Set boot drive and partition.  */
+  saved_drive = boot_drive;
+  saved_partition = install_partition;
+
+  /* Set cdrom drive.  */
+  {
+    struct geometry geom;
+    
+    /* Get the geometry.  */
+    if (get_diskinfo (boot_drive, &geom)
+	|| ! (geom.flags & BIOSDISK_FLAG_CDROM))
+      cdrom_drive = GRUB_INVALID_DRIVE;
+    else
+      cdrom_drive = boot_drive;
+  }
+  
+  /* Start main routine here.  */
+  cmain ();
+}
diff --git a/stage2/console.c b/stage2/console.c
new file mode 100644
index 0000000..fbe212e
--- /dev/null
+++ b/stage2/console.c
@@ -0,0 +1,62 @@
+/* term_console.c - console input and output */
+/*
+ *  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.
+ */
+
+#include <shared.h>
+#include <term.h>
+
+/* These functions are defined in asm.S instead of this file:
+   console_putchar, console_checkkey, console_getkey, console_getxy,
+   console_gotoxy, console_cls, and console_nocursor.  */
+
+int console_current_color = A_NORMAL;
+static int console_standard_color = A_NORMAL;
+static int console_normal_color = A_NORMAL;
+static int console_highlight_color = A_REVERSE;
+static color_state console_color_state = COLOR_STATE_STANDARD;
+
+void
+console_setcolorstate (color_state state)
+{
+  switch (state) {
+    case COLOR_STATE_STANDARD:
+      console_current_color = console_standard_color;
+      break;
+    case COLOR_STATE_NORMAL:
+      console_current_color = console_normal_color;
+      break;
+    case COLOR_STATE_HIGHLIGHT:
+      console_current_color = console_highlight_color;
+      break;
+    default:
+      console_current_color = console_standard_color;
+      break;
+  }
+
+  console_color_state = state;
+}
+
+void
+console_setcolor (int normal_color, int highlight_color)
+{
+  console_normal_color = normal_color;
+  console_highlight_color = highlight_color;
+
+  console_setcolorstate (console_color_state);
+}
diff --git a/stage2/defs.h b/stage2/defs.h
new file mode 100644
index 0000000..f2f2683
--- /dev/null
+++ b/stage2/defs.h
@@ -0,0 +1,94 @@
+/* 
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ * 
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ * 
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ * 
+ * Carnegie Mellon requests users of this software to return to
+ * 
+ *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ * 
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * Common definitions for Berkeley Fast File System.
+ */
+
+/*
+ * Compatibility definitions for disk IO.
+ */
+
+/*
+ * Disk devices do all IO in 512-byte blocks.
+ */
+#define	DEV_BSIZE	512
+
+/*
+ * Conversion between bytes and disk blocks.
+ */
+#define	btodb(byte_offset)	((byte_offset) >> 9)
+#define	dbtob(block_number)	((block_number) << 9)
+
+/*
+ * Compatibility definitions for old type names.
+ */
+
+typedef unsigned char u_char;	/* unsigned char */
+typedef unsigned short u_short;	/* unsigned short */
+typedef unsigned int u_int;	/* unsigned int */
+
+typedef struct _quad_
+  {
+    unsigned int val[2];	/* 2 int values make... */
+  }
+quad;				/* an 8-byte item */
+
+typedef unsigned int mach_time_t;	/* an unsigned int */
+typedef unsigned int mach_daddr_t;	/* an unsigned int */
+typedef unsigned int mach_off_t;	/* another unsigned int */
+
+typedef unsigned short mach_uid_t;
+typedef unsigned short mach_gid_t;
+typedef unsigned int mach_ino_t;
+
+#define	NBBY	8
+
+/*
+ * The file system is made out of blocks of at most MAXBSIZE units,
+ * with smaller units (fragments) only in the last direct block.
+ * MAXBSIZE primarily determines the size of buffers in the buffer
+ * pool.  It may be made larger without any effect on existing
+ * file systems; however, making it smaller may make some file
+ * systems unmountable.
+ *
+ * Note that the disk devices are assumed to have DEV_BSIZE "sectors"
+ * and that fragments must be some multiple of this size.
+ */
+#define	MAXBSIZE	8192
+#define	MAXFRAG		8
+
+/*
+ * MAXPATHLEN defines the longest permissible path length
+ * after expanding symbolic links.
+ *
+ * MAXSYMLINKS defines the maximum number of symbolic links
+ * that may be expanded in a path name.  It should be set
+ * high enough to allow all legitimate uses, but halt infinite
+ * loops reasonably quickly.
+ */
+
+#define	MAXPATHLEN	1024
+#define	MAXSYMLINKS	8
diff --git a/stage2/dir.h b/stage2/dir.h
new file mode 100644
index 0000000..287bf60
--- /dev/null
+++ b/stage2/dir.h
@@ -0,0 +1,147 @@
+
+/* 
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ * 
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ * 
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ * 
+ * Carnegie Mellon requests users of this software to return to
+ * 
+ *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ * 
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * Copyright (c) 1982, 1986, 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *	@(#)dir.h	7.6 (Berkeley) 5/9/89
+ */
+
+#ifndef _BOOT_UFS_DIR_H_
+#define	_BOOT_UFS_DIR_H_
+
+/*
+ * A directory consists of some number of blocks of DIRBLKSIZ
+ * bytes, where DIRBLKSIZ is chosen such that it can be transferred
+ * to disk in a single atomic operation (e.g. 512 bytes on most machines).
+ *
+ * Each DIRBLKSIZ byte block contains some number of directory entry
+ * structures, which are of variable length.  Each directory entry has
+ * a struct direct at the front of it, containing its inode number,
+ * the length of the entry, and the length of the name contained in
+ * the entry.  These are followed by the name padded to a 4 byte boundary
+ * with null bytes.  All names are guaranteed null terminated.
+ * The maximum length of a name in a directory is MAXNAMLEN.
+ *
+ * The macro DIRSIZ(dp) gives the amount of space required to represent
+ * a directory entry.  Free space in a directory is represented by
+ * entries which have dp->d_reclen > DIRSIZ(dp).  All DIRBLKSIZ bytes
+ * in a directory block are claimed by the directory entries.  This
+ * usually results in the last entry in a directory having a large
+ * dp->d_reclen.  When entries are deleted from a directory, the
+ * space is returned to the previous entry in the same directory
+ * block by increasing its dp->d_reclen.  If the first entry of
+ * a directory block is free, then its dp->d_ino is set to 0.
+ * Entries other than the first in a directory do not normally have
+ * dp->d_ino set to 0.
+ */
+#define DIRBLKSIZ	DEV_BSIZE
+#define	MAXNAMLEN	255
+
+struct direct
+  {
+    u_int d_ino;		/* inode number of entry */
+    u_short d_reclen;		/* length of this record */
+    u_short d_namlen;		/* length of string in d_name */
+    char d_name[MAXNAMLEN + 1];	/* name with length <= MAXNAMLEN */
+  };
+
+/*
+ * The DIRSIZ macro gives the minimum record length which will hold
+ * the directory entry.  This requires the amount of space in struct direct
+ * without the d_name field, plus enough space for the name with a terminating
+ * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
+ */
+#undef DIRSIZ
+#define DIRSIZ(dp) \
+    ((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
+
+#ifdef KERNEL
+/*
+ * Template for manipulating directories.
+ * Should use struct direct's, but the name field
+ * is MAXNAMLEN - 1, and this just won't do.
+ */
+struct dirtemplate
+  {
+    u_int dot_ino;
+    short dot_reclen;
+    short dot_namlen;
+    char dot_name[4];		/* must be multiple of 4 */
+    u_int dotdot_ino;
+    short dotdot_reclen;
+    short dotdot_namlen;
+    char dotdot_name[4];	/* ditto */
+  };
+#endif
+
+/*
+ * The following information should be obtained from <dirent.h>
+ * and is provided solely (and temporarily) for backward compatibility.
+ */
+#ifndef KERNEL
+#define d_fileno d_ino		/* compatibility with POSIX */
+#ifndef DEV_BSIZE
+#define	DEV_BSIZE	512
+#endif
+/*
+ * Definitions for library routines operating on directories.
+ */
+typedef struct _dirdesc
+  {
+    int dd_fd;
+    int dd_loc;
+    int dd_size;
+    char dd_buf[DIRBLKSIZ];
+  }
+DIR;
+
+#define dirfd(dirp)	((dirp)->dd_fd)
+
+#ifndef NULL
+#define NULL 0
+#endif
+extern DIR *opendir ();
+extern struct direct *readdir ();
+extern int telldir ();
+extern void seekdir ();
+#define rewinddir(dirp)	seekdir((dirp), (long)0)
+extern void closedir ();
+#endif /* not KERNEL */
+#endif /* _BOOT_UFS_DIR_H_ */
diff --git a/stage2/disk_inode.h b/stage2/disk_inode.h
new file mode 100644
index 0000000..2103cb8
--- /dev/null
+++ b/stage2/disk_inode.h
@@ -0,0 +1,110 @@
+/*
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * Copyright (c) 1982, 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *	@(#)inode.h	7.5 (Berkeley) 7/3/89
+ */
+
+#ifndef	_BOOT_UFS_DISK_INODE_H_
+#define	_BOOT_UFS_DISK_INODE_H_
+
+/*
+ * The I node is the focus of all file activity in the BSD Fast File System.
+ * There is a unique inode allocated for each active file,
+ * each current directory, each mounted-on file, text file, and the root.
+ * An inode is 'named' by its dev/inumber pair. (iget/iget.c)
+ * Data in icommon is read in from permanent inode on volume.
+ */
+
+#define	FFS_NDADDR	12	/* direct addresses in inode */
+#define	FFS_NIADDR	3	/* indirect addresses in inode */
+
+#define	FFS_MAX_FASTLINK_SIZE	((FFS_NDADDR + FFS_NIADDR) \
+				 * sizeof (mach_daddr_t))
+
+struct icommon
+  {
+    u_short ic_mode;		/*  0: mode and type of file */
+    short ic_nlink;		/*  2: number of links to file */
+    mach_uid_t ic_uid;		/*  4: owner's user id */
+    mach_gid_t ic_gid;		/*  6: owner's group id */
+    quad ic_size;		/*  8: number of bytes in file */
+    mach_time_t ic_atime;	/* 16: time last accessed */
+    int ic_atspare;
+    mach_time_t ic_mtime;	/* 24: time last modified */
+    int ic_mtspare;
+    mach_time_t ic_ctime;	/* 32: last time inode changed */
+    int ic_ctspare;
+    union
+      {
+	struct
+	  {
+	    mach_daddr_t Mb_db[FFS_NDADDR];	/* 40: disk block addresses */
+	    mach_daddr_t Mb_ib[FFS_NIADDR];	/* 88: indirect blocks */
+	  }
+	ic_Mb;
+	char ic_Msymlink[FFS_MAX_FASTLINK_SIZE];
+	/* 40: symbolic link name */
+      }
+    ic_Mun;
+#define	ic_db		ic_Mun.ic_Mb.Mb_db
+#define	ic_ib		ic_Mun.ic_Mb.Mb_ib
+#define	ic_symlink	ic_Mun.ic_Msymlink
+    int ic_flags;		/* 100: status, currently unused */
+    int ic_blocks;		/* 104: blocks actually held */
+    int ic_gen;			/* 108: generation number */
+    int ic_spare[4];		/* 112: reserved, currently unused */
+  };
+
+/*
+ *	Same structure, but on disk.
+ */
+struct dinode
+  {
+    union
+      {
+	struct icommon di_com;
+	char di_char[128];
+      }
+    di_un;
+  };
+#define	di_ic	di_un.di_com
+
+#endif /* _BOOT_UFS_DISK_INODE_H_ */
diff --git a/stage2/disk_inode_ffs.h b/stage2/disk_inode_ffs.h
new file mode 100644
index 0000000..1c8caa1
--- /dev/null
+++ b/stage2/disk_inode_ffs.h
@@ -0,0 +1,101 @@
+/* 
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ * 
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ * 
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ * 
+ * Carnegie Mellon requests users of this software to return to
+ * 
+ *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ * 
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * Copyright (c) 1982, 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *	@(#)inode.h	7.5 (Berkeley) 7/3/89
+ */
+
+#ifndef	_BOOT_UFS_DISK_INODE_FFS_H_
+#define	_BOOT_UFS_DISK_INODE_FFS_H_
+
+#define	NDADDR	FFS_NDADDR
+#define	NIADDR	FFS_NIADDR
+
+#define	MAX_FASTLINK_SIZE	FFS_MAX_FASTLINK_SIZE
+
+#define	IC_FASTLINK	0x0001	/* Symbolic link in inode */
+
+#define	i_mode		ic_mode
+#define	i_nlink		ic_nlink
+#define	i_uid		ic_uid
+#define	i_gid		ic_gid
+#if	defined(BYTE_MSF) && BYTE_MSF
+#define	i_size		ic_size.val[1]
+#else /* BYTE_LSF */
+#define	i_size		ic_size.val[0]
+#endif
+#define	i_db		ic_db
+#define	i_ib		ic_ib
+#define	i_atime		ic_atime
+#define	i_mtime		ic_mtime
+#define	i_ctime		ic_ctime
+#define i_blocks	ic_blocks
+#define	i_rdev		ic_db[0]
+#define	i_symlink	ic_symlink
+#define i_flags		ic_flags
+#define i_gen		ic_gen
+
+/* modes */
+#define	IFMT	0xf000		/* type of file */
+#define	IFCHR	0x2000		/* character special */
+#define	IFDIR	0x4000		/* directory */
+#define	IFBLK	0x6000		/* block special */
+#define	IFREG	0x8000		/* regular */
+#define	IFLNK	0xa000		/* symbolic link */
+#define	IFSOCK	0xc000		/* socket */
+
+
+#define	ISUID		0x0800	/* set user id on execution */
+#define	ISGID		0x0400	/* set group id on execution */
+#define	ISVTX		0x0200	/* save swapped text even after use */
+#define	IREAD		0x0100	/* read, write, execute permissions */
+#define	IWRITE		0x0080
+#define	IEXEC		0x0040
+
+#ifdef EEK
+#define f_fs		u.ffs.ffs_fs
+#define i_ic		u.ffs.ffs_ic
+#define f_nindir	u.ffs.ffs_nindir
+#define f_blk		u.ffs.ffs_blk
+#define f_blksize	u.ffs.ffs_blksize
+#define f_blkno		u.ffs.ffs_blkno
+#endif /* EEK */
+
+#endif	/* _BOOT_UFS_DISK_INODE_FFS_H_ */
diff --git a/stage2/disk_io.c b/stage2/disk_io.c
new file mode 100644
index 0000000..b9bc526
--- /dev/null
+++ b/stage2/disk_io.c
@@ -0,0 +1,1790 @@
+/* disk_io.c - implement abstract BIOS disk input and output */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  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 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.
+ */
+
+
+#include <shared.h>
+#include <filesys.h>
+
+#ifdef SUPPORT_NETBOOT
+# define GRUB	1
+# include <etherboot.h>
+#endif
+
+#ifdef GRUB_UTIL
+# include <device.h>
+#endif
+
+/* instrumentation variables */
+void (*disk_read_hook) (int, int, int) = NULL;
+void (*disk_read_func) (int, int, int) = NULL;
+
+#ifndef STAGE1_5
+int print_possibilities;
+
+static int do_completion;
+static int unique;
+static char *unique_string;
+
+#endif
+
+int fsmax;
+struct fsys_entry fsys_table[NUM_FSYS + 1] =
+{
+  /* TFTP should come first because others don't handle net device.  */
+# ifdef FSYS_TFTP
+  {"tftp", tftp_mount, tftp_read, tftp_dir, tftp_close, 0},
+# endif
+# ifdef FSYS_FAT
+  {"fat", fat_mount, fat_read, fat_dir, 0, 0},
+# endif
+# ifdef FSYS_EXT2FS
+  {"ext2fs", ext2fs_mount, ext2fs_read, ext2fs_dir, 0, 0},
+# endif
+# ifdef FSYS_MINIX
+  {"minix", minix_mount, minix_read, minix_dir, 0, 0},
+# endif
+# ifdef FSYS_REISERFS
+  {"reiserfs", reiserfs_mount, reiserfs_read, reiserfs_dir, 0, reiserfs_embed},
+# endif
+# ifdef FSYS_VSTAFS
+  {"vstafs", vstafs_mount, vstafs_read, vstafs_dir, 0, 0},
+# endif
+# ifdef FSYS_JFS
+  {"jfs", jfs_mount, jfs_read, jfs_dir, 0, jfs_embed},
+# endif
+# ifdef FSYS_XFS
+  {"xfs", xfs_mount, xfs_read, xfs_dir, 0, 0},
+# endif
+# ifdef FSYS_UFS2
+  {"ufs2", ufs2_mount, ufs2_read, ufs2_dir, 0, ufs2_embed},
+# endif
+# ifdef FSYS_ISO9660
+  {"iso9660", iso9660_mount, iso9660_read, iso9660_dir, 0, 0},
+# endif
+  /* XX FFS should come last as it's superblock is commonly crossing tracks
+     on floppies from track 1 to 2, while others only use 1.  */
+# ifdef FSYS_FFS
+  {"ffs", ffs_mount, ffs_read, ffs_dir, 0, ffs_embed},
+# endif
+  {0, 0, 0, 0, 0, 0}
+};
+
+
+/* These have the same format as "boot_drive" and "install_partition", but
+   are meant to be working values. */
+unsigned long current_drive = GRUB_INVALID_DRIVE;
+unsigned long current_partition;
+
+#ifndef STAGE1_5
+/* The register ESI should contain the address of the partition to be
+   used for loading a chain-loader when chain-loading the loader.  */
+unsigned long boot_part_addr = 0;
+#endif
+
+/*
+ *  Global variables describing details of the filesystem
+ */
+
+/* FIXME: BSD evil hack */
+#include "freebsd.h"
+int bsd_evil_hack;
+
+/* filesystem type */
+int fsys_type = NUM_FSYS;
+#ifndef NO_BLOCK_FILES
+static int block_file = 0;
+#endif /* NO_BLOCK_FILES */
+
+/* these are the translated numbers for the open partition */
+unsigned long part_start;
+unsigned long part_length;
+
+int current_slice;
+
+/* disk buffer parameters */
+int buf_drive = -1;
+int buf_track;
+struct geometry buf_geom;
+
+/* filesystem common variables */
+int filepos;
+int filemax;
+
+static inline unsigned long
+log2 (unsigned long word)
+{
+  asm volatile ("bsfl %1,%0"
+		: "=r" (word)
+		: "r" (word));
+  return word;
+}
+
+int
+rawread (int drive, int sector, int byte_offset, int byte_len, char *buf)
+{
+  int slen, sectors_per_vtrack;
+  int sector_size_bits = log2 (buf_geom.sector_size);
+
+  if (byte_len <= 0)
+    return 1;
+
+  while (byte_len > 0 && !errnum)
+    {
+      int soff, num_sect, track, size = byte_len;
+      char *bufaddr;
+
+      /*
+       *  Check track buffer.  If it isn't valid or it is from the
+       *  wrong disk, then reset the disk geometry.
+       */
+      if (buf_drive != drive)
+	{
+	  if (get_diskinfo (drive, &buf_geom))
+	    {
+	      errnum = ERR_NO_DISK;
+	      return 0;
+	    }
+	  buf_drive = drive;
+	  buf_track = -1;
+	  sector_size_bits = log2 (buf_geom.sector_size);
+	}
+
+      /* Make sure that SECTOR is valid.  */
+      if (sector < 0 || sector >= buf_geom.total_sectors)
+	{
+	  errnum = ERR_GEOM;
+	  return 0;
+	}
+      
+      slen = ((byte_offset + byte_len + buf_geom.sector_size - 1)
+	      >> sector_size_bits);
+      
+      /* Eliminate a buffer overflow.  */
+      if ((buf_geom.sectors << sector_size_bits) > BUFFERLEN)
+	sectors_per_vtrack = (BUFFERLEN >> sector_size_bits);
+      else
+	sectors_per_vtrack = buf_geom.sectors;
+      
+      /* Get the first sector of track.  */
+      soff = sector % sectors_per_vtrack;
+      track = sector - soff;
+      num_sect = sectors_per_vtrack - soff;
+      bufaddr = ((char *) BUFFERADDR
+		 + (soff << sector_size_bits) + byte_offset);
+
+      if (track != buf_track)
+	{
+	  int bios_err, read_start = track, read_len = sectors_per_vtrack;
+
+	  /*
+	   *  If there's more than one read in this entire loop, then
+	   *  only make the earlier reads for the portion needed.  This
+	   *  saves filling the buffer with data that won't be used!
+	   */
+	  if (slen > num_sect)
+	    {
+	      read_start = sector;
+	      read_len = num_sect;
+	      bufaddr = (char *) BUFFERADDR + byte_offset;
+	    }
+
+	  bios_err = biosdisk (BIOSDISK_READ, drive, &buf_geom,
+			       read_start, read_len, BUFFERSEG);
+	  if (bios_err)
+	    {
+	      buf_track = -1;
+
+	      if (bios_err == BIOSDISK_ERROR_GEOMETRY)
+		errnum = ERR_GEOM;
+	      else
+		{
+		  /*
+		   *  If there was an error, try to load only the
+		   *  required sector(s) rather than failing completely.
+		   */
+		  if (slen > num_sect
+		      || biosdisk (BIOSDISK_READ, drive, &buf_geom,
+				   sector, slen, BUFFERSEG))
+		    errnum = ERR_READ;
+
+		  bufaddr = (char *) BUFFERADDR + byte_offset;
+		}
+	    }
+	  else
+	    buf_track = track;
+
+	  if ((buf_track == 0 || sector == 0)
+	      && (PC_SLICE_TYPE (BUFFERADDR, 0) == PC_SLICE_TYPE_EZD
+		  || PC_SLICE_TYPE (BUFFERADDR, 1) == PC_SLICE_TYPE_EZD
+		  || PC_SLICE_TYPE (BUFFERADDR, 2) == PC_SLICE_TYPE_EZD
+		  || PC_SLICE_TYPE (BUFFERADDR, 3) == PC_SLICE_TYPE_EZD))
+	    {
+	      /* This is a EZD disk map sector 0 to sector 1 */
+	      if (buf_track == 0 || slen >= 2)
+		{
+		  /* We already read the sector 1, copy it to sector 0 */
+		  memmove ((char *) BUFFERADDR, 
+			   (char *) BUFFERADDR + buf_geom.sector_size,
+			   buf_geom.sector_size);
+		}
+	      else
+		{
+		  if (biosdisk (BIOSDISK_READ, drive, &buf_geom,
+				1, 1, BUFFERSEG))
+		    errnum = ERR_READ;
+		}
+	    }
+	}
+	  
+      if (size > ((num_sect << sector_size_bits) - byte_offset))
+	size = (num_sect << sector_size_bits) - byte_offset;
+
+      /*
+       *  Instrumentation to tell which sectors were read and used.
+       */
+      if (disk_read_func)
+	{
+	  int sector_num = sector;
+	  int length = buf_geom.sector_size - byte_offset;
+	  if (length > size)
+	    length = size;
+	  (*disk_read_func) (sector_num++, byte_offset, length);
+	  length = size - length;
+	  if (length > 0)
+	    {
+	      while (length > buf_geom.sector_size)
+		{
+		  (*disk_read_func) (sector_num++, 0, buf_geom.sector_size);
+		  length -= buf_geom.sector_size;
+		}
+	      (*disk_read_func) (sector_num, 0, length);
+	    }
+	}
+
+      grub_memmove (buf, bufaddr, size);
+
+      buf += size;
+      byte_len -= size;
+      sector += num_sect;
+      byte_offset = 0;
+    }
+
+  return (!errnum);
+}
+
+
+int
+devread (int sector, int byte_offset, int byte_len, char *buf)
+{
+  /*
+   *  Check partition boundaries
+   */
+  if (sector < 0
+      || ((sector + ((byte_offset + byte_len - 1) >> SECTOR_BITS))
+	  >= part_length))
+    {
+      errnum = ERR_OUTSIDE_PART;
+      return 0;
+    }
+
+  /*
+   *  Get the read to the beginning of a partition.
+   */
+  sector += byte_offset >> SECTOR_BITS;
+  byte_offset &= SECTOR_SIZE - 1;
+
+#if !defined(STAGE1_5)
+  if (disk_read_hook && debug)
+    printf ("<%d, %d, %d>", sector, byte_offset, byte_len);
+#endif /* !STAGE1_5 */
+
+  /*
+   *  Call RAWREAD, which is very similar, but:
+   *
+   *    --  It takes an extra parameter, the drive number.
+   *    --  It requires that "sector" is relative to the beginning
+   *            of the disk.
+   *    --  It doesn't handle offsets of more than 511 bytes into the
+   *            sector.
+   */
+  return rawread (current_drive, part_start + sector, byte_offset,
+		  byte_len, buf);
+}
+
+#ifndef STAGE1_5
+int
+rawwrite (int drive, int sector, char *buf)
+{
+  if (sector == 0)
+    {
+      if (biosdisk (BIOSDISK_READ, drive, &buf_geom, 0, 1, SCRATCHSEG))
+	{
+	  errnum = ERR_WRITE;
+	  return 0;
+	}
+
+      if (PC_SLICE_TYPE (SCRATCHADDR, 0) == PC_SLICE_TYPE_EZD
+	  || PC_SLICE_TYPE (SCRATCHADDR, 1) == PC_SLICE_TYPE_EZD
+	  || PC_SLICE_TYPE (SCRATCHADDR, 2) == PC_SLICE_TYPE_EZD
+	  || PC_SLICE_TYPE (SCRATCHADDR, 3) == PC_SLICE_TYPE_EZD)
+	sector = 1;
+    }
+  
+  memmove ((char *) SCRATCHADDR, buf, SECTOR_SIZE);
+  if (biosdisk (BIOSDISK_WRITE, drive, &buf_geom,
+		sector, 1, SCRATCHSEG))
+    {
+      errnum = ERR_WRITE;
+      return 0;
+    }
+
+  if (sector - sector % buf_geom.sectors == buf_track)
+    /* Clear the cache.  */
+    buf_track = -1;
+
+  return 1;
+}
+
+int
+devwrite (int sector, int sector_count, char *buf)
+{
+#if defined(GRUB_UTIL) && defined(__linux__)
+  if (current_partition != 0xFFFFFF
+      && is_disk_device (device_map, current_drive))
+    {
+      /* If the grub shell is running under Linux and the user wants to
+	 embed a Stage 1.5 into a partition instead of a MBR, use system
+	 calls directly instead of biosdisk, because of the bug in
+	 Linux. *sigh*  */
+      return write_to_partition (device_map, current_drive, current_partition,
+				 sector, sector_count, buf);
+    }
+  else
+#endif /* GRUB_UTIL && __linux__ */
+    {
+      int i;
+      
+      for (i = 0; i < sector_count; i++)
+	{
+	  if (! rawwrite (current_drive, part_start + sector + i, 
+			  buf + (i << SECTOR_BITS)))
+	      return 0;
+
+	}
+      return 1;
+    }
+}
+
+static int
+sane_partition (void)
+{
+  /* network drive */
+  if (current_drive == NETWORK_DRIVE)
+    return 1;
+  
+  if (!(current_partition & 0xFF000000uL)
+      && ((current_drive & 0xFFFFFF7F) < 8
+	  || current_drive == cdrom_drive)
+      && (current_partition & 0xFF) == 0xFF
+      && ((current_partition & 0xFF00) == 0xFF00
+	  || (current_partition & 0xFF00) < 0x800)
+      && ((current_partition >> 16) == 0xFF
+	  || (current_drive & 0x80)))
+    return 1;
+
+  errnum = ERR_DEV_VALUES;
+  return 0;
+}
+#endif /* ! STAGE1_5 */
+
+static void
+attempt_mount (void)
+{
+#ifndef STAGE1_5
+  for (fsys_type = 0; fsys_type < NUM_FSYS; fsys_type++)
+    if ((fsys_table[fsys_type].mount_func) ())
+      break;
+
+  if (fsys_type == NUM_FSYS && errnum == ERR_NONE)
+    errnum = ERR_FSYS_MOUNT;
+#else
+  fsys_type = 0;
+  if ((*(fsys_table[fsys_type].mount_func)) () != 1)
+    {
+      fsys_type = NUM_FSYS;
+      errnum = ERR_FSYS_MOUNT;
+    }
+#endif
+}
+
+
+#ifndef STAGE1_5
+/* Turn on the active flag for the partition SAVED_PARTITION in the
+   drive SAVED_DRIVE. If an error occurs, return zero, otherwise return
+   non-zero.  */
+int
+make_saved_active (void)
+{
+  char mbr[512];
+
+  if (saved_drive & 0x80)
+    {
+      /* Hard disk */
+      int part = saved_partition >> 16;
+
+      /* If the partition is not a primary partition, the active flag is
+	 meaningless. (XXX: Really?)  */
+      if (part > 3)
+	{
+	  errnum = ERR_DEV_VALUES;
+	  return 0;
+	}
+
+      /* Read the MBR in the scratch space.  */
+      if (! rawread (saved_drive, 0, 0, SECTOR_SIZE, mbr))
+	return 0;
+
+      /* If the partition is an extended partition, setting the active
+	 flag violates the specification by IBM.  */
+      if (IS_PC_SLICE_TYPE_EXTENDED (PC_SLICE_TYPE (mbr, part)))
+	{
+	  errnum = ERR_DEV_VALUES;
+	  return 0;
+	}
+
+      /* Check if the active flag is disabled.  */
+      if (PC_SLICE_FLAG (mbr, part) != PC_SLICE_FLAG_BOOTABLE)
+	{
+	  int i;
+
+	  /* Clear all the active flags in this table.  */
+	  for (i = 0; i < 4; i++)
+	    PC_SLICE_FLAG (mbr, i) = 0;
+
+	  /* Set the flag.  */
+	  PC_SLICE_FLAG (mbr, part) = PC_SLICE_FLAG_BOOTABLE;
+
+	  /* Write back the MBR.  */
+	  if (! rawwrite (saved_drive, 0, mbr))
+	    return 0;
+	}
+    }
+  else
+    {
+      /* If the drive is not a hard disk drive, you shouldn't call this
+	 function. (XXX: Should I just ignore this error?)  */
+      errnum = ERR_DEV_VALUES;
+      return 0;
+    }
+
+  return 1;
+}
+
+/* Hide/Unhide CURRENT_PARTITION.  */
+int
+set_partition_hidden_flag (int hidden)
+{
+  unsigned long part = 0xFFFFFF;
+  unsigned long start, len, offset, ext_offset;
+  int entry, type;
+  char mbr[512];
+  
+  /* The drive must be a hard disk.  */
+  if (! (current_drive & 0x80))
+    {
+      errnum = ERR_BAD_ARGUMENT;
+      return 1;
+    }
+  
+  /* The partition must be a PC slice.  */
+  if ((current_partition >> 16) == 0xFF
+      || (current_partition & 0xFFFF) != 0xFFFF)
+    {
+      errnum = ERR_BAD_ARGUMENT;
+      return 1;
+    }
+  
+  /* Look for the partition.  */
+  while (next_partition (current_drive, 0xFFFFFF, &part, &type,           
+			 &start, &len, &offset, &entry,
+			 &ext_offset, mbr))
+    {                                                                       
+      if (part == current_partition)
+	{
+	  /* Found.  */
+	  if (hidden)
+	    PC_SLICE_TYPE (mbr, entry) |= PC_SLICE_TYPE_HIDDEN_FLAG;
+	  else
+	    PC_SLICE_TYPE (mbr, entry) &= ~PC_SLICE_TYPE_HIDDEN_FLAG;       
+	  
+	  /* Write back the MBR to the disk.  */
+	  buf_track = -1;
+	  if (! rawwrite (current_drive, offset, mbr))
+	    return 1;
+	  
+	  /* Succeed.  */
+	  return 0;
+	}
+    }
+  
+  return 1;
+}
+
+
+static void
+check_and_print_mount (void)
+{
+  attempt_mount ();
+  if (errnum == ERR_FSYS_MOUNT)
+    errnum = ERR_NONE;
+  if (!errnum)
+    print_fsys_type ();
+  print_error ();
+}
+#endif /* STAGE1_5 */
+
+
+/* Get the information on next partition on the drive DRIVE.
+   The caller must not modify the contents of the arguments when
+   iterating this function. The partition representation in GRUB will
+   be stored in *PARTITION. Likewise, the partition type in *TYPE, the
+   start sector in *START, the length in *LEN, the offset of the
+   partition table in *OFFSET, the entry number in the table in *ENTRY,
+   the offset of the extended partition in *EXT_OFFSET.
+   BUF is used to store a MBR, the boot sector of a partition, or
+   a BSD label sector, and it must be at least 512 bytes length.
+   When calling this function first, *PARTITION must be initialized to
+   0xFFFFFF. The return value is zero if fails, otherwise non-zero.  */
+int
+next_partition (unsigned long drive, unsigned long dest,
+		unsigned long *partition, int *type,
+		unsigned long *start, unsigned long *len,
+		unsigned long *offset, int *entry,
+		unsigned long *ext_offset, char *buf)
+{
+  /* Forward declarations.  */
+  auto int next_bsd_partition (void);
+  auto int next_pc_slice (void);
+
+  /* Get next BSD partition in current PC slice.  */
+  int next_bsd_partition (void)
+    {
+      int i;
+      int bsd_part_no = (*partition & 0xFF00) >> 8;
+
+      /* If this is the first time...  */
+      if (bsd_part_no == 0xFF)
+	{
+	  /* Check if the BSD label is within current PC slice.  */
+	  if (*len < BSD_LABEL_SECTOR + 1)
+	    {
+	      errnum = ERR_BAD_PART_TABLE;
+	      return 0;
+	    }
+
+	  /* Read the BSD label.  */
+	  if (! rawread (drive, *start + BSD_LABEL_SECTOR,
+			 0, SECTOR_SIZE, buf))
+	    return 0;
+
+	  /* Check if it is valid.  */
+	  if (! BSD_LABEL_CHECK_MAG (buf))
+	    {
+	      errnum = ERR_BAD_PART_TABLE;
+	      return 0;
+	    }
+	  
+	  bsd_part_no = -1;
+	}
+
+      /* Search next valid BSD partition.  */
+      for (i = bsd_part_no + 1; i < BSD_LABEL_NPARTS (buf); i++)
+	{
+	  if (BSD_PART_TYPE (buf, i))
+	    {
+	      /* Note that *TYPE and *PARTITION were set
+		 for current PC slice.  */
+	      *type = (BSD_PART_TYPE (buf, i) << 8) | (*type & 0xFF);
+	      *start = BSD_PART_START (buf, i);
+	      *len = BSD_PART_LENGTH (buf, i);
+	      *partition = (*partition & 0xFF00FF) | (i << 8);
+
+#ifndef STAGE1_5
+	      /* XXX */
+	      if ((drive & 0x80) && BSD_LABEL_DTYPE (buf) == DTYPE_SCSI)
+		bsd_evil_hack = 4;
+#endif /* ! STAGE1_5 */
+	      
+	      return 1;
+	    }
+	}
+
+      errnum = ERR_NO_PART;
+      return 0;
+    }
+
+  /* Get next PC slice. Be careful of that this function may return
+     an empty PC slice (i.e. a partition whose type is zero) as well.  */
+  int next_pc_slice (void)
+    {
+      int pc_slice_no = (*partition & 0xFF0000) >> 16;
+
+      /* If this is the first time...  */
+      if (pc_slice_no == 0xFF)
+	{
+	  *offset = 0;
+	  *ext_offset = 0;
+	  *entry = -1;
+	  pc_slice_no = -1;
+	}
+
+      /* Read the MBR or the boot sector of the extended partition.  */
+      if (! rawread (drive, *offset, 0, SECTOR_SIZE, buf))
+	return 0;
+
+      /* Check if it is valid.  */
+      if (! PC_MBR_CHECK_SIG (buf))
+	{
+	  errnum = ERR_BAD_PART_TABLE;
+	  return 0;
+	}
+
+      /* Increase the entry number.  */
+      (*entry)++;
+
+      /* If this is out of current partition table...  */
+      if (*entry == PC_SLICE_MAX)
+	{
+	  int i;
+
+	  /* Search the first extended partition in current table.  */
+	  for (i = 0; i < PC_SLICE_MAX; i++)
+	    {
+	      if (IS_PC_SLICE_TYPE_EXTENDED (PC_SLICE_TYPE (buf, i)))
+		{
+		  /* Found. Set the new offset and the entry number,
+		     and restart this function.  */
+		  *offset = *ext_offset + PC_SLICE_START (buf, i);
+		  if (! *ext_offset)
+		    *ext_offset = *offset;
+		  *entry = -1;
+		  return next_pc_slice ();
+		}
+	    }
+
+	  errnum = ERR_NO_PART;
+	  return 0;
+	}
+      
+      *type = PC_SLICE_TYPE (buf, *entry);
+      *start = *offset + PC_SLICE_START (buf, *entry);
+      *len = PC_SLICE_LENGTH (buf, *entry);
+
+      /* The calculation of a PC slice number is complicated, because of
+	 the rather odd definition of extended partitions. Even worse,
+	 there is no guarantee that this is consistent with every
+	 operating systems. Uggh.  */
+      if (pc_slice_no < PC_SLICE_MAX
+	  || (! IS_PC_SLICE_TYPE_EXTENDED (*type)
+	      && *type != PC_SLICE_TYPE_NONE))
+	pc_slice_no++;
+      
+      *partition = (pc_slice_no << 16) | 0xFFFF;
+      return 1;
+    }
+
+  /* Start the body of this function.  */
+  
+#ifndef STAGE1_5
+  if (current_drive == NETWORK_DRIVE)
+    return 0;
+#endif
+
+  /* If previous partition is a BSD partition or a PC slice which
+     contains BSD partitions...  */
+  if ((*partition != 0xFFFFFF && IS_PC_SLICE_TYPE_BSD (*type & 0xff))
+      || ! (drive & 0x80))
+    {
+      if (*type == PC_SLICE_TYPE_NONE)
+	*type = PC_SLICE_TYPE_FREEBSD;
+      
+      /* Get next BSD partition, if any.  */
+      if (next_bsd_partition ())
+	return 1;
+
+      /* If the destination partition is a BSD partition and current
+	 BSD partition has any error, abort the operation.  */
+      if ((dest & 0xFF00) != 0xFF00
+	  && ((dest & 0xFF0000) == 0xFF0000
+	      || (dest & 0xFF0000) == (*partition & 0xFF0000)))
+	return 0;
+
+      /* Ignore the error.  */
+      errnum = ERR_NONE;
+    }
+	  
+  return next_pc_slice ();
+}
+
+#ifndef STAGE1_5
+static unsigned long cur_part_offset;
+static unsigned long cur_part_addr;
+#endif
+
+/* Open a partition.  */
+int
+real_open_partition (int flags)
+{
+  unsigned long dest_partition = current_partition;
+  unsigned long part_offset;
+  unsigned long ext_offset;
+  int entry;
+  char buf[SECTOR_SIZE];
+  int bsd_part, pc_slice;
+
+  /* For simplicity.  */
+  auto int next (void);
+  int next (void)
+    {
+      int ret = next_partition (current_drive, dest_partition,
+				&current_partition, &current_slice,
+				&part_start, &part_length,
+				&part_offset, &entry, &ext_offset, buf);
+      bsd_part = (current_partition >> 8) & 0xFF;
+      pc_slice = current_partition >> 16;
+      return ret;
+    }
+  
+#ifndef STAGE1_5
+  /* network drive */
+  if (current_drive == NETWORK_DRIVE)
+    return 1;
+  
+  if (! sane_partition ())
+    return 0;
+#endif
+
+  bsd_evil_hack = 0;
+  current_slice = 0;
+  part_start = 0;
+
+  /* Make sure that buf_geom is valid. */
+  if (buf_drive != current_drive)
+    {
+      if (get_diskinfo (current_drive, &buf_geom))
+	{
+	  errnum = ERR_NO_DISK;
+	  return 0;
+	}
+      buf_drive = current_drive;
+      buf_track = -1;
+    }
+  part_length = buf_geom.total_sectors;
+
+  /* If this is the whole disk, return here.  */
+  if (! flags && current_partition == 0xFFFFFF)
+    return 1;
+
+  if (flags)
+    dest_partition = 0xFFFFFF;
+
+  /* Initialize CURRENT_PARTITION for next_partition.  */
+  current_partition = 0xFFFFFF;
+  
+  while (next ())
+    {
+#ifndef STAGE1_5
+    loop_start:
+      
+      cur_part_offset = part_offset;
+      cur_part_addr = BOOT_PART_TABLE + (entry << 4);
+#endif /* ! STAGE1_5 */
+
+      /* If this is a valid partition...  */
+      if (current_slice)
+	{
+#ifndef STAGE1_5
+	  /* Display partition information.  */
+	  if (flags && ! IS_PC_SLICE_TYPE_EXTENDED (current_slice))
+	    {
+	      if (! do_completion)
+		{
+		  if (current_drive & 0x80)
+		    grub_printf ("   Partition num: %d, ",
+				 current_partition >> 16);
+
+		  if (! IS_PC_SLICE_TYPE_BSD (current_slice))
+		    check_and_print_mount ();
+		  else
+		    {
+		      int got_part = 0;
+		      int saved_slice = current_slice;
+		      
+		      while (next ())
+			{
+			  if (bsd_part == 0xFF)
+			    break;
+			  
+			  if (! got_part)
+			    {
+			      grub_printf ("[BSD sub-partitions immediately follow]\n");
+			      got_part = 1;
+			    }
+			  
+			  grub_printf ("     BSD Partition num: \'%c\', ",
+				       bsd_part + 'a');
+			  check_and_print_mount ();
+			}
+
+		      if (! got_part)
+			grub_printf (" No BSD sub-partition found, partition type 0x%x\n",
+				     saved_slice);
+		      
+		      if (errnum)
+			{
+			  errnum = ERR_NONE;
+			  break;
+			}
+		      
+		      goto loop_start;
+		    }
+		}
+	      else
+		{
+		  if (bsd_part != 0xFF)
+		    {
+		      char str[16];
+		      
+		      if (! (current_drive & 0x80)
+			  || (dest_partition >> 16) == pc_slice)
+			grub_sprintf (str, "%c)", bsd_part + 'a');
+		      else
+			grub_sprintf (str, "%d,%c)",
+				      pc_slice, bsd_part + 'a');
+		      print_a_completion (str);
+		    }
+		  else if (! IS_PC_SLICE_TYPE_BSD (current_slice))
+		    {
+		      char str[8];
+		      
+		      grub_sprintf (str, "%d)", pc_slice);
+		      print_a_completion (str);
+		    }
+		}
+	    }
+	  
+	  errnum = ERR_NONE;
+#endif /* ! STAGE1_5 */
+	  
+	  /* Check if this is the destination partition.  */
+	  if (! flags
+	      && (dest_partition == current_partition
+		  || ((dest_partition >> 16) == 0xFF
+		      && ((dest_partition >> 8) & 0xFF) == bsd_part)))
+	    return 1;
+	}
+    }
+
+#ifndef STAGE1_5
+  if (flags)
+    {
+      if (! (current_drive & 0x80))
+	{
+	  current_partition = 0xFFFFFF;
+	  check_and_print_mount ();
+	}
+      
+      errnum = ERR_NONE;
+      return 1;
+    }
+#endif /* ! STAGE1_5 */
+  
+  return 0;
+}
+
+
+int
+open_partition (void)
+{
+  return real_open_partition (0);
+}
+
+
+#ifndef STAGE1_5
+/* XX used for device completion in 'set_device' and 'print_completions' */
+static int incomplete, disk_choice;
+static enum
+{
+  PART_UNSPECIFIED = 0,
+  PART_DISK,
+  PART_CHOSEN,
+}
+part_choice;
+#endif /* ! STAGE1_5 */
+
+char *
+set_device (char *device)
+{
+#ifdef STAGE1_5
+    /* In Stage 1.5, the first 4 bytes of FILENAME has a device number.  */
+  unsigned long dev = *((unsigned long *) device);
+  int drive = (dev >> 24) & 0xFF;
+  int partition = dev & 0xFFFFFF;
+
+  /* If DRIVE is disabled, use SAVED_DRIVE instead.  */
+  if (drive == GRUB_INVALID_DRIVE)
+    current_drive = saved_drive;
+  else
+    current_drive = drive;
+
+  /* The `partition' part must always have a valid number.  */
+  current_partition = partition;
+  
+  return device + sizeof (unsigned long);
+  
+#else /* ! STAGE1_5 */
+  
+  int result = 0;
+
+  incomplete = 0;
+  disk_choice = 1;
+  part_choice = PART_UNSPECIFIED;
+  current_drive = saved_drive;
+  current_partition = 0xFFFFFF;
+
+  if (*device == '(' && !*(device + 1))
+    /* user has given '(' only, let disk_choice handle what disks we have */
+    return device + 1;
+
+  if (*device == '(' && *(++device))
+    {
+      if (*device != ',' && *device != ')')
+	{
+	  char ch = *device;
+#ifdef SUPPORT_NETBOOT
+	  if (*device == 'f' || *device == 'h'
+	      || (*device == 'n' && network_ready)
+	      || (*device == 'c' && cdrom_drive != GRUB_INVALID_DRIVE))
+#else
+	  if (*device == 'f' || *device == 'h'
+	      || (*device == 'c' && cdrom_drive != GRUB_INVALID_DRIVE))
+#endif /* SUPPORT_NETBOOT */
+	    {
+	      /* user has given '([fhn]', check for resp. add 'd' and
+		 let disk_choice handle what disks we have */
+	      if (!*(device + 1))
+		{
+		  device++;
+		  *device++ = 'd';
+		  *device = '\0';
+		  return device;
+		}
+	      else if (*(device + 1) == 'd' && !*(device + 2))
+		return device + 2;
+	    }
+
+	  if ((*device == 'f'
+	       || *device == 'h'
+#ifdef SUPPORT_NETBOOT
+	       || (*device == 'n' && network_ready)
+#endif
+	       || (*device == 'c' && cdrom_drive != GRUB_INVALID_DRIVE))
+	      && (device += 2, (*(device - 1) != 'd')))
+	    errnum = ERR_NUMBER_PARSING;
+	  
+#ifdef SUPPORT_NETBOOT
+	  if (ch == 'n' && network_ready)
+	    current_drive = NETWORK_DRIVE;
+	  else
+#endif /* SUPPORT_NETBOOT */
+	    {
+	      if (ch == 'c' && cdrom_drive != GRUB_INVALID_DRIVE)
+		current_drive = cdrom_drive;
+	      else
+		{
+		  safe_parse_maxint (&device, (int *) &current_drive);
+		  
+		  disk_choice = 0;
+		  if (ch == 'h')
+		    current_drive += 0x80;
+		}
+	    }
+	}
+
+      if (errnum)
+	return 0;
+
+      if (*device == ')')
+	{
+	  part_choice = PART_CHOSEN;
+	  result = 1;
+	}
+      else if (*device == ',')
+	{
+	  /* Either an absolute PC or BSD partition. */
+	  disk_choice = 0;
+	  part_choice ++;
+	  device++;
+
+	  if (*device >= '0' && *device <= '9')
+	    {
+	      part_choice ++;
+	      current_partition = 0;
+
+	      if (!(current_drive & 0x80)
+		  || !safe_parse_maxint (&device, (int *) &current_partition)
+		  || current_partition > 254)
+		{
+		  errnum = ERR_DEV_FORMAT;
+		  return 0;
+		}
+
+	      current_partition = (current_partition << 16) + 0xFFFF;
+
+	      if (*device == ',')
+		device++;
+	      
+	      if (*device >= 'a' && *device <= 'h')
+		{
+		  current_partition = (((*(device++) - 'a') << 8)
+				       | (current_partition & 0xFF00FF));
+		}
+	    }
+	  else if (*device >= 'a' && *device <= 'h')
+	    {
+	      part_choice ++;
+	      current_partition = ((*(device++) - 'a') << 8) | 0xFF00FF;
+	    }
+
+	  if (*device == ')')
+	    {
+	      if (part_choice == PART_DISK)
+		{
+		  current_partition = saved_partition;
+		  part_choice ++;
+		}
+
+	      result = 1;
+	    }
+	}
+    }
+
+  if (! sane_partition ())
+    return 0;
+  
+  if (result)
+    return device + 1;
+  else
+    {
+      if (!*device)
+	incomplete = 1;
+      errnum = ERR_DEV_FORMAT;
+    }
+
+  return 0;
+  
+#endif /* ! STAGE1_5 */
+}
+
+/*
+ *  This performs a "mount" on the current device, both drive and partition
+ *  number.
+ */
+
+int
+open_device (void)
+{
+  if (open_partition ())
+    attempt_mount ();
+
+  if (errnum != ERR_NONE)
+    return 0;
+
+  return 1;
+}
+
+
+#ifndef STAGE1_5
+int
+set_bootdev (int hdbias)
+{
+  int i, j;
+
+  /* Copy the boot partition information to 0x7be-0x7fd for chain-loading.  */
+  if ((saved_drive & 0x80) && cur_part_addr)
+    {
+      if (rawread (saved_drive, cur_part_offset,
+		   0, SECTOR_SIZE, (char *) SCRATCHADDR))
+	{
+	  char *dst, *src;
+      
+	  /* Need only the partition table.
+	     XXX: We cannot use grub_memmove because BOOT_PART_TABLE
+	     (0x07be) is less than 0x1000.  */
+	  dst = (char *) BOOT_PART_TABLE;
+	  src = (char *) SCRATCHADDR + BOOTSEC_PART_OFFSET;
+	  while (dst < (char *) BOOT_PART_TABLE + BOOTSEC_PART_LENGTH)
+	    *dst++ = *src++;
+	  
+	  /* Set the active flag of the booted partition.  */
+	  for (i = 0; i < 4; i++)
+	    PC_SLICE_FLAG (BOOT_PART_TABLE, i) = 0;
+	  
+	  *((unsigned char *) cur_part_addr) = PC_SLICE_FLAG_BOOTABLE;
+	  boot_part_addr = cur_part_addr;
+	}
+      else
+	return 0;
+    }
+  
+  /*
+   *  Set BSD boot device.
+   */
+  i = (saved_partition >> 16) + 2;
+  if (saved_partition == 0xFFFFFF)
+    i = 1;
+  else if ((saved_partition >> 16) == 0xFF)
+    i = 0;
+
+  /* FIXME: extremely evil hack!!! */
+  j = 2;
+  if (saved_drive & 0x80)
+    j = bsd_evil_hack;
+
+  return MAKEBOOTDEV (j, (i >> 4), (i & 0xF),
+		      ((saved_drive - hdbias) & 0x7F),
+		      ((saved_partition >> 8) & 0xFF));
+}
+#endif /* STAGE1_5 */
+
+
+static char *
+setup_part (char *filename)
+{
+#ifdef STAGE1_5
+
+  if (! (filename = set_device (filename)))
+    {
+      current_drive = GRUB_INVALID_DRIVE;
+      return 0;
+    }
+  
+# ifndef NO_BLOCK_FILES
+  if (*filename != '/')
+    open_partition ();
+  else
+# endif /* ! NO_BLOCK_FILES */
+    open_device ();
+  
+#else /* ! STAGE1_5 */
+  
+  if (*filename == '(')
+    {
+      if ((filename = set_device (filename)) == 0)
+	{
+	  current_drive = GRUB_INVALID_DRIVE;
+	  return 0;
+	}
+# ifndef NO_BLOCK_FILES
+      if (*filename != '/')
+	open_partition ();
+      else
+# endif /* ! NO_BLOCK_FILES */
+	open_device ();
+    }
+  else if (saved_drive != current_drive
+	   || saved_partition != current_partition
+	   || (*filename == '/' && fsys_type == NUM_FSYS)
+	   || buf_drive == -1)
+    {
+      current_drive = saved_drive;
+      current_partition = saved_partition;
+      /* allow for the error case of "no filesystem" after the partition
+         is found.  This makes block files work fine on no filesystem */
+# ifndef NO_BLOCK_FILES
+      if (*filename != '/')
+	open_partition ();
+      else
+# endif /* ! NO_BLOCK_FILES */
+	open_device ();
+    }
+  
+#endif /* ! STAGE1_5 */
+  
+  if (errnum && (*filename == '/' || errnum != ERR_FSYS_MOUNT))
+    return 0;
+  else
+    errnum = 0;
+
+#ifndef STAGE1_5
+  if (!sane_partition ())
+    return 0;
+#endif
+
+  return filename;
+}
+
+
+#ifndef STAGE1_5
+/*
+ *  This prints the filesystem type or gives relevant information.
+ */
+
+void
+print_fsys_type (void)
+{
+  if (! do_completion)
+    {
+      printf (" Filesystem type ");
+      
+      if (fsys_type != NUM_FSYS)
+	printf ("is %s, ", fsys_table[fsys_type].name);
+      else
+	printf ("unknown, ");
+      
+      if (current_partition == 0xFFFFFF)
+	printf ("using whole disk\n");
+      else
+	printf ("partition type 0x%x\n", current_slice & 0xFF);
+    }
+}
+#endif /* STAGE1_5 */
+
+#ifndef STAGE1_5
+/* If DO_COMPLETION is true, just print NAME. Otherwise save the unique
+   part into UNIQUE_STRING.  */
+void
+print_a_completion (char *name)
+{
+  /* If NAME is "." or "..", do not count it.  */
+  if (grub_strcmp (name, ".") == 0 || grub_strcmp (name, "..") == 0)
+    return;
+  
+  if (do_completion)
+    {
+      char *buf = unique_string;
+      
+      if (! unique)
+	while ((*buf++ = *name++))
+	  ;
+      else
+	{
+	  while (*buf && (*buf == *name))
+	    {
+	      buf++;
+	      name++;
+	    }
+	  /* mismatch, strip it.  */
+	  *buf = '\0';
+	}
+    }
+  else
+    grub_printf (" %s", name);
+  
+  unique++;
+}
+
+/*
+ *  This lists the possible completions of a device string, filename, or
+ *  any sane combination of the two.
+ */
+
+int
+print_completions (int is_filename, int is_completion)
+{
+  char *buf = (char *) COMPLETION_BUF;
+  char *ptr = buf;
+
+  unique_string = (char *) UNIQUE_BUF;
+  *unique_string = 0;
+  unique = 0;
+  do_completion = is_completion;
+
+  if (! is_filename)
+    {
+      /* Print the completions of builtin commands.  */
+      struct builtin **builtin;
+
+      if (! is_completion)
+	grub_printf (" Possible commands are:");
+      
+      for (builtin = builtin_table; (*builtin); builtin++)
+	{
+	  /* If *BUILTIN cannot be run in the command-line, skip it.  */
+	  if (! ((*builtin)->flags & BUILTIN_CMDLINE))
+	    continue;
+
+	  if (substring (buf, (*builtin)->name) <= 0)
+	    print_a_completion ((*builtin)->name);
+	}
+
+      if (is_completion && *unique_string)
+	{
+	  if (unique == 1)
+	    {
+	      char *u = unique_string + grub_strlen (unique_string);
+
+	      *u++ = ' ';
+	      *u = 0;
+	    }
+	  
+	  grub_strcpy (buf, unique_string);
+	}
+
+      if (! is_completion)
+	grub_putchar ('\n');
+      
+      print_error ();
+      do_completion = 0;
+      if (errnum)
+	return -1;
+      else
+	return unique - 1;
+    }
+
+  if (*buf == '/' || (ptr = set_device (buf)) || incomplete)
+    {
+      errnum = 0;
+
+      if (*buf == '(' && (incomplete || ! *ptr))
+	{
+	  if (! part_choice)
+	    {
+	      /* disk completions */
+	      int disk_no, i, j;
+	      struct geometry geom;
+
+	      if (! is_completion)
+		grub_printf (" Possible disks are: ");
+
+	      if (!ptr
+		  || *(ptr-1) != 'd'
+#ifdef SUPPORT_NETBOOT
+		  || *(ptr-2) != 'n'
+#endif /* SUPPORT_NETBOOT */
+		  || *(ptr-2) != 'c')
+		{
+		  for (i = (ptr && (*(ptr-1) == 'd' && *(ptr-2) == 'h') ? 1:0);
+		       i < (ptr && (*(ptr-1) == 'd' && *(ptr-2) == 'f') ? 1:2);
+		       i++)
+		    {
+		      for (j = 0; j < 8; j++)
+			{
+			  disk_no = (i * 0x80) + j;
+			  if ((disk_choice || disk_no == current_drive)
+			      && ! get_diskinfo (disk_no, &geom))
+			    {
+			      char dev_name[8];
+
+			      grub_sprintf (dev_name, "%cd%d", i ? 'h':'f', j);
+			      print_a_completion (dev_name);
+			    }
+			}
+		    }
+		}
+
+	      if (cdrom_drive != GRUB_INVALID_DRIVE
+		  && (disk_choice || cdrom_drive == current_drive)
+		  && (!ptr
+		      || *(ptr-1) == '('
+		      || (*(ptr-1) == 'd' && *(ptr-2) == 'c')))
+		print_a_completion ("cd");
+
+# ifdef SUPPORT_NETBOOT
+	      if (network_ready
+		  && (disk_choice || NETWORK_DRIVE == current_drive)
+		  && (!ptr
+		      || *(ptr-1) == '('
+		      || (*(ptr-1) == 'd' && *(ptr-2) == 'n')))
+		print_a_completion ("nd");
+# endif /* SUPPORT_NETBOOT */
+
+	      if (is_completion && *unique_string)
+		{
+		  ptr = buf;
+		  while (*ptr != '(')
+		    ptr--;
+		  ptr++;
+		  grub_strcpy (ptr, unique_string);
+		  if (unique == 1)
+		    {
+		      ptr += grub_strlen (ptr);
+		      if (*unique_string == 'h')
+			{
+			  *ptr++ = ',';
+			  *ptr = 0;
+			}
+		      else
+			{
+			  *ptr++ = ')';
+			  *ptr = 0;
+			}
+		    }
+		}
+
+	      if (! is_completion)
+		grub_putchar ('\n');
+	    }
+	  else
+	    {
+	      /* partition completions */
+	      if (part_choice == PART_CHOSEN
+		  && open_partition ()
+		  && ! IS_PC_SLICE_TYPE_BSD (current_slice))
+		{
+		  unique = 1;
+		  ptr = buf + grub_strlen (buf);
+		  if (*(ptr - 1) != ')')
+		    {
+		      *ptr++ = ')';
+		      *ptr = 0;
+		    }
+		}
+	      else
+		{
+		  if (! is_completion)
+		    grub_printf (" Possible partitions are:\n");
+		  real_open_partition (1);
+		  
+		  if (is_completion && *unique_string)
+		    {
+		      ptr = buf;
+		      while (*ptr++ != ',')
+			;
+		      grub_strcpy (ptr, unique_string);
+		    }
+		}
+	    }
+	}
+      else if (ptr && *ptr == '/')
+	{
+	  /* filename completions */
+	  if (! is_completion)
+	    grub_printf (" Possible files are:");
+	  
+	  dir (buf);
+	  
+	  if (is_completion && *unique_string)
+	    {
+	      ptr += grub_strlen (ptr);
+	      while (*ptr != '/')
+		ptr--;
+	      ptr++;
+	      
+	      grub_strcpy (ptr, unique_string);
+	      
+	      if (unique == 1)
+		{
+		  ptr += grub_strlen (unique_string);
+
+		  /* Check if the file UNIQUE_STRING is a directory.  */
+		  *ptr = '/';
+		  *(ptr + 1) = 0;
+		  
+		  dir (buf);
+		  
+		  /* Restore the original unique value.  */
+		  unique = 1;
+		  
+		  if (errnum)
+		    {
+		      /* Regular file */
+		      errnum = 0;
+		      *ptr = ' ';
+		      *(ptr + 1) = 0;
+		    }
+		}
+	    }
+	  
+	  if (! is_completion)
+	    grub_putchar ('\n');
+	}
+      else
+	errnum = ERR_BAD_FILENAME;
+    }
+
+  print_error ();
+  do_completion = 0;
+  if (errnum)
+    return -1;
+  else
+    return unique - 1;
+}
+#endif /* STAGE1_5 */
+
+
+/*
+ *  This is the generic file open function.
+ */
+
+int
+grub_open (char *filename)
+{
+#ifndef NO_DECOMPRESSION
+  compressed_file = 0;
+#endif /* NO_DECOMPRESSION */
+
+  /* if any "dir" function uses/sets filepos, it must
+     set it to zero before returning if opening a file! */
+  filepos = 0;
+
+  if (!(filename = setup_part (filename)))
+    return 0;
+
+#ifndef NO_BLOCK_FILES
+  block_file = 0;
+#endif /* NO_BLOCK_FILES */
+
+  /* This accounts for partial filesystem implementations. */
+  fsmax = MAXINT;
+
+  if (*filename != '/')
+    {
+#ifndef NO_BLOCK_FILES
+      char *ptr = filename;
+      int tmp, list_addr = BLK_BLKLIST_START;
+      filemax = 0;
+
+      while (list_addr < BLK_MAX_ADDR)
+	{
+	  tmp = 0;
+	  safe_parse_maxint (&ptr, &tmp);
+	  errnum = 0;
+
+	  if (*ptr != '+')
+	    {
+	      if ((*ptr && *ptr != '/' && !isspace (*ptr))
+		  || tmp == 0 || tmp > filemax)
+		errnum = ERR_BAD_FILENAME;
+	      else
+		filemax = tmp;
+
+	      break;
+	    }
+
+	  /* since we use the same filesystem buffer, mark it to
+	     be remounted */
+	  fsys_type = NUM_FSYS;
+
+	  BLK_BLKSTART (list_addr) = tmp;
+	  ptr++;
+
+	  if (!safe_parse_maxint (&ptr, &tmp)
+	      || tmp == 0
+	      || (*ptr && *ptr != ',' && *ptr != '/' && !isspace (*ptr)))
+	    {
+	      errnum = ERR_BAD_FILENAME;
+	      break;
+	    }
+
+	  BLK_BLKLENGTH (list_addr) = tmp;
+
+	  filemax += (tmp * SECTOR_SIZE);
+	  list_addr += BLK_BLKLIST_INC_VAL;
+
+	  if (*ptr != ',')
+	    break;
+
+	  ptr++;
+	}
+
+      if (list_addr < BLK_MAX_ADDR && ptr != filename && !errnum)
+	{
+	  block_file = 1;
+	  BLK_CUR_FILEPOS = 0;
+	  BLK_CUR_BLKLIST = BLK_BLKLIST_START;
+	  BLK_CUR_BLKNUM = 0;
+
+#ifndef NO_DECOMPRESSION
+	  return gunzip_test_header ();
+#else /* NO_DECOMPRESSION */
+	  return 1;
+#endif /* NO_DECOMPRESSION */
+	}
+#else /* NO_BLOCK_FILES */
+      errnum = ERR_BAD_FILENAME;
+#endif /* NO_BLOCK_FILES */
+    }
+
+  if (!errnum && fsys_type == NUM_FSYS)
+    errnum = ERR_FSYS_MOUNT;
+
+# ifndef STAGE1_5
+  /* set "dir" function to open a file */
+  print_possibilities = 0;
+# endif
+
+  if (!errnum && (*(fsys_table[fsys_type].dir_func)) (filename))
+    {
+#ifndef NO_DECOMPRESSION
+      return gunzip_test_header ();
+#else /* NO_DECOMPRESSION */
+      return 1;
+#endif /* NO_DECOMPRESSION */
+    }
+
+  return 0;
+}
+
+
+int
+grub_read (char *buf, int len)
+{
+  /* Make sure "filepos" is a sane value */
+  if ((filepos < 0) || (filepos > filemax))
+    filepos = filemax;
+
+  /* Make sure "len" is a sane value */
+  if ((len < 0) || (len > (filemax - filepos)))
+    len = filemax - filepos;
+
+  /* if target file position is past the end of
+     the supported/configured filesize, then
+     there is an error */
+  if (filepos + len > fsmax)
+    {
+      errnum = ERR_FILELENGTH;
+      return 0;
+    }
+
+#ifndef NO_DECOMPRESSION
+  if (compressed_file)
+    return gunzip_read (buf, len);
+#endif /* NO_DECOMPRESSION */
+
+#ifndef NO_BLOCK_FILES
+  if (block_file)
+    {
+      int size, off, ret = 0;
+
+      while (len && !errnum)
+	{
+	  /* we may need to look for the right block in the list(s) */
+	  if (filepos < BLK_CUR_FILEPOS)
+	    {
+	      BLK_CUR_FILEPOS = 0;
+	      BLK_CUR_BLKLIST = BLK_BLKLIST_START;
+	      BLK_CUR_BLKNUM = 0;
+	    }
+
+	  /* run BLK_CUR_FILEPOS up to filepos */
+	  while (filepos > BLK_CUR_FILEPOS)
+	    {
+	      if ((filepos - (BLK_CUR_FILEPOS & ~(SECTOR_SIZE - 1)))
+		  >= SECTOR_SIZE)
+		{
+		  BLK_CUR_FILEPOS += SECTOR_SIZE;
+		  BLK_CUR_BLKNUM++;
+
+		  if (BLK_CUR_BLKNUM >= BLK_BLKLENGTH (BLK_CUR_BLKLIST))
+		    {
+		      BLK_CUR_BLKLIST += BLK_BLKLIST_INC_VAL;
+		      BLK_CUR_BLKNUM = 0;
+		    }
+		}
+	      else
+		BLK_CUR_FILEPOS = filepos;
+	    }
+
+	  off = filepos & (SECTOR_SIZE - 1);
+	  size = ((BLK_BLKLENGTH (BLK_CUR_BLKLIST) - BLK_CUR_BLKNUM)
+		  * SECTOR_SIZE) - off;
+	  if (size > len)
+	    size = len;
+
+	  disk_read_func = disk_read_hook;
+
+	  /* read current block and put it in the right place in memory */
+	  devread (BLK_BLKSTART (BLK_CUR_BLKLIST) + BLK_CUR_BLKNUM,
+		   off, size, buf);
+
+	  disk_read_func = NULL;
+
+	  len -= size;
+	  filepos += size;
+	  ret += size;
+	  buf += size;
+	}
+
+      if (errnum)
+	ret = 0;
+
+      return ret;
+    }
+#endif /* NO_BLOCK_FILES */
+
+  if (fsys_type == NUM_FSYS)
+    {
+      errnum = ERR_FSYS_MOUNT;
+      return 0;
+    }
+
+  return (*(fsys_table[fsys_type].read_func)) (buf, len);
+}
+
+#ifndef STAGE1_5
+/* Reposition a file offset.  */
+int
+grub_seek (int offset)
+{
+  if (offset > filemax || offset < 0)
+    return -1;
+
+  filepos = offset;
+  return offset;
+}
+
+int
+dir (char *dirname)
+{
+#ifndef NO_DECOMPRESSION
+  compressed_file = 0;
+#endif /* NO_DECOMPRESSION */
+
+  if (!(dirname = setup_part (dirname)))
+    return 0;
+
+  if (*dirname != '/')
+    errnum = ERR_BAD_FILENAME;
+
+  if (fsys_type == NUM_FSYS)
+    errnum = ERR_FSYS_MOUNT;
+
+  if (errnum)
+    return 0;
+
+  /* set "dir" function to list completions */
+  print_possibilities = 1;
+
+  return (*(fsys_table[fsys_type].dir_func)) (dirname);
+}
+#endif /* STAGE1_5 */
+
+void 
+grub_close (void)
+{
+#ifndef NO_BLOCK_FILES
+  if (block_file)
+    return;
+#endif /* NO_BLOCK_FILES */
+  
+  if (fsys_table[fsys_type].close_func != 0)
+    (*(fsys_table[fsys_type].close_func)) ();
+}
diff --git a/stage2/fat.h b/stage2/fat.h
new file mode 100644
index 0000000..7fed6ba
--- /dev/null
+++ b/stage2/fat.h
@@ -0,0 +1,100 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2001  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.
+ */
+
+
+/*
+ *  Defines for the FAT BIOS Parameter Block (embedded in the first block
+ *  of the partition.
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+/* Note that some shorts are not aligned, and must therefore
+ * be declared as array of two bytes.
+ */
+struct fat_bpb {
+	__s8	ignored[3];	/* Boot strap short or near jump */
+	__s8	system_id[8];	/* Name - can be used to special case
+				   partition manager volumes */
+	__u8	bytes_per_sect[2];	/* bytes per logical sector */
+	__u8	sects_per_clust;/* sectors/cluster */
+	__u8	reserved_sects[2];	/* reserved sectors */
+	__u8	num_fats;	/* number of FATs */
+	__u8	dir_entries[2];	/* root directory entries */
+	__u8	short_sectors[2];	/* number of sectors */
+	__u8	media;		/* media code (unused) */
+	__u16	fat_length;	/* sectors/FAT */
+	__u16	secs_track;	/* sectors per track */
+	__u16	heads;		/* number of heads */
+	__u32	hidden;		/* hidden sectors (unused) */
+	__u32	long_sectors;	/* number of sectors (if short_sectors == 0) */
+
+	/* The following fields are only used by FAT32 */
+	__u32	fat32_length;	/* sectors/FAT */
+	__u16	flags;		/* bit 8: fat mirroring, low 4: active fat */
+	__u8	version[2];	/* major, minor filesystem version */
+	__u32	root_cluster;	/* first cluster in root directory */
+	__u16	info_sector;	/* filesystem info sector */
+	__u16	backup_boot;	/* backup boot sector */
+	__u16	reserved2[6];	/* Unused */
+};
+
+#define FAT_CVT_U16(bytarr) (* (__u16*)(bytarr))
+
+/*
+ *  Defines how to differentiate a 12-bit and 16-bit FAT.
+ */
+
+#define FAT_MAX_12BIT_CLUST       4087	/* 4085 + 2 */
+
+/*
+ *  Defines for the file "attribute" byte
+ */
+
+#define FAT_ATTRIB_OK_MASK        0x37
+#define FAT_ATTRIB_NOT_OK_MASK    0xC8
+#define FAT_ATTRIB_DIR            0x10
+#define FAT_ATTRIB_LONGNAME       0x0F
+
+/*
+ *  Defines for FAT directory entries
+ */
+
+#define FAT_DIRENTRY_LENGTH       32
+
+#define FAT_DIRENTRY_ATTRIB(entry) \
+  (*((unsigned char *) (entry+11)))
+#define FAT_DIRENTRY_VALID(entry) \
+  ( ((*((unsigned char *) entry)) != 0) \
+    && ((*((unsigned char *) entry)) != 0xE5) \
+    && !(FAT_DIRENTRY_ATTRIB(entry) & FAT_ATTRIB_NOT_OK_MASK) )
+#define FAT_DIRENTRY_FIRST_CLUSTER(entry) \
+  ((*((unsigned short *) (entry+26)))+(*((unsigned short *) (entry+20)) << 16))
+#define FAT_DIRENTRY_FILELENGTH(entry) \
+  (*((unsigned long *) (entry+28)))
+
+#define FAT_LONGDIR_ID(entry) \
+  (*((unsigned char *) (entry)))
+#define FAT_LONGDIR_ALIASCHECKSUM(entry) \
+  (*((unsigned char *) (entry+13)))
diff --git a/stage2/filesys.h b/stage2/filesys.h
new file mode 100644
index 0000000..bbad8b9
--- /dev/null
+++ b/stage2/filesys.h
@@ -0,0 +1,165 @@
+/* filesys.h - abstract filesystem interface */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,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
+ *  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.
+ */
+
+#include "pc_slice.h"
+
+#ifdef FSYS_FFS
+#define FSYS_FFS_NUM 1
+int ffs_mount (void);
+int ffs_read (char *buf, int len);
+int ffs_dir (char *dirname);
+int ffs_embed (int *start_sector, int needed_sectors);
+#else
+#define FSYS_FFS_NUM 0
+#endif
+
+#ifdef FSYS_UFS2
+#define FSYS_UFS2_NUM 1
+int ufs2_mount (void);
+int ufs2_read (char *buf, int len);
+int ufs2_dir (char *dirname);
+int ufs2_embed (int *start_sector, int needed_sectors);
+#else
+#define FSYS_UFS2_NUM 0
+#endif
+
+#ifdef FSYS_FAT
+#define FSYS_FAT_NUM 1
+int fat_mount (void);
+int fat_read (char *buf, int len);
+int fat_dir (char *dirname);
+#else
+#define FSYS_FAT_NUM 0
+#endif
+
+#ifdef FSYS_EXT2FS
+#define FSYS_EXT2FS_NUM 1
+int ext2fs_mount (void);
+int ext2fs_read (char *buf, int len);
+int ext2fs_dir (char *dirname);
+#else
+#define FSYS_EXT2FS_NUM 0
+#endif
+
+#ifdef FSYS_MINIX
+#define FSYS_MINIX_NUM 1
+int minix_mount (void);
+int minix_read (char *buf, int len);
+int minix_dir (char *dirname);
+#else
+#define FSYS_MINIX_NUM 0
+#endif
+
+#ifdef FSYS_REISERFS
+#define FSYS_REISERFS_NUM 1
+int reiserfs_mount (void);
+int reiserfs_read (char *buf, int len);
+int reiserfs_dir (char *dirname);
+int reiserfs_embed (int *start_sector, int needed_sectors);
+#else
+#define FSYS_REISERFS_NUM 0
+#endif
+
+#ifdef FSYS_VSTAFS
+#define FSYS_VSTAFS_NUM 1
+int vstafs_mount (void);
+int vstafs_read (char *buf, int len);
+int vstafs_dir (char *dirname);
+#else
+#define FSYS_VSTAFS_NUM 0
+#endif
+
+#ifdef FSYS_JFS
+#define FSYS_JFS_NUM 1
+int jfs_mount (void);
+int jfs_read (char *buf, int len);
+int jfs_dir (char *dirname);
+int jfs_embed (int *start_sector, int needed_sectors);
+#else
+#define FSYS_JFS_NUM 0
+#endif
+
+#ifdef FSYS_XFS
+#define FSYS_XFS_NUM 1
+int xfs_mount (void);
+int xfs_read (char *buf, int len);
+int xfs_dir (char *dirname);
+#else
+#define FSYS_XFS_NUM 0
+#endif
+
+#ifdef FSYS_TFTP
+#define FSYS_TFTP_NUM 1
+int tftp_mount (void);
+int tftp_read (char *buf, int len);
+int tftp_dir (char *dirname);
+void tftp_close (void);
+#else
+#define FSYS_TFTP_NUM 0
+#endif
+
+#ifdef FSYS_ISO9660
+#define FSYS_ISO9660_NUM 1
+int iso9660_mount (void);
+int iso9660_read (char *buf, int len);
+int iso9660_dir (char *dirname);
+#else
+#define FSYS_ISO9660_NUM 0
+#endif
+
+#ifndef NUM_FSYS
+#define NUM_FSYS	\
+  (FSYS_FFS_NUM + FSYS_FAT_NUM + FSYS_EXT2FS_NUM + FSYS_MINIX_NUM	\
+   + FSYS_REISERFS_NUM + FSYS_VSTAFS_NUM + FSYS_JFS_NUM + FSYS_XFS_NUM	\
+   + FSYS_TFTP_NUM + FSYS_ISO9660_NUM + FSYS_UFS2_NUM)
+#endif
+
+/* defines for the block filesystem info area */
+#ifndef NO_BLOCK_FILES
+#define BLK_CUR_FILEPOS      (*((int*)FSYS_BUF))
+#define BLK_CUR_BLKLIST      (*((int*)(FSYS_BUF+4)))
+#define BLK_CUR_BLKNUM       (*((int*)(FSYS_BUF+8)))
+#define BLK_MAX_ADDR         (FSYS_BUF+0x7FF9)
+#define BLK_BLKSTART(l)      (*((int*)l))
+#define BLK_BLKLENGTH(l)     (*((int*)(l+4)))
+#define BLK_BLKLIST_START    (FSYS_BUF+12)
+#define BLK_BLKLIST_INC_VAL  8
+#endif /* NO_BLOCK_FILES */
+
+/* this next part is pretty ugly, but it keeps it in one place! */
+
+struct fsys_entry
+{
+  char *name;
+  int (*mount_func) (void);
+  int (*read_func) (char *buf, int len);
+  int (*dir_func) (char *dirname);
+  void (*close_func) (void);
+  int (*embed_func) (int *start_sector, int needed_sectors);
+};
+
+#ifdef STAGE1_5
+# define print_possibilities 0
+#else
+extern int print_possibilities;
+#endif
+
+extern int fsmax;
+extern struct fsys_entry fsys_table[NUM_FSYS + 1];
diff --git a/stage2/freebsd.h b/stage2/freebsd.h
new file mode 100644
index 0000000..ffbf602
--- /dev/null
+++ b/stage2/freebsd.h
@@ -0,0 +1,95 @@
+
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2001  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.
+ */
+
+/* command-line parameter defines */
+#define RB_ASKNAME      0x01	/* ask for file name to reboot from */
+#define RB_SINGLE       0x02	/* reboot to single user only */
+#define RB_NOSYNC       0x04	/* dont sync before reboot */
+#define RB_HALT         0x08	/* don't reboot, just halt */
+#define RB_INITNAME     0x10	/* name given for /etc/init (unused) */
+#define RB_DFLTROOT     0x20	/* use compiled-in rootdev */
+#define RB_KDB          0x40	/* give control to kernel debugger */
+#define RB_RDONLY       0x80	/* mount root fs read-only */
+#define RB_DUMP         0x100	/* dump kernel memory before reboot */
+#define RB_MINIROOT     0x200	/* mini-root present in memory at boot time */
+#define RB_CONFIG       0x400	/* invoke user configuration routing */
+#define RB_VERBOSE      0x800	/* print all potentially useful info */
+#define RB_SERIAL       0x1000	/* user serial port as console */
+#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_MULTIPLE	0x20000000	/* Use multiple consoles */
+
+#define RB_BOOTINFO     0x80000000	/* have `struct bootinfo *' arg */
+
+/*
+ * Constants for converting boot-style device number to type,
+ * adaptor (uba, mba, etc), unit number and partition number.
+ * Type (== major device number) is in the low byte
+ * for backward compatibility.  Except for that of the "magic
+ * number", each mask applies to the shifted value.
+ * Format:
+ *       (4) (4) (4) (4)  (8)     (8)
+ *      --------------------------------
+ *      |MA | AD| CT| UN| PART  | TYPE |
+ *      --------------------------------
+ */
+#define B_ADAPTORSHIFT          24
+#define B_CONTROLLERSHIFT       20
+#define B_UNITSHIFT             16
+#define B_PARTITIONSHIFT        8
+#define B_TYPESHIFT             0
+
+#define B_DEVMAGIC      ((unsigned long)0xa0000000)
+
+#define MAKEBOOTDEV(type, adaptor, controller, unit, partition) \
+        (((type) << B_TYPESHIFT) | ((adaptor) << B_ADAPTORSHIFT) | \
+        ((controller) << B_CONTROLLERSHIFT) | ((unit) << B_UNITSHIFT) | \
+        ((partition) << B_PARTITIONSHIFT) | B_DEVMAGIC)
+
+
+/* Only change the version number if you break compatibility. */
+#define BOOTINFO_VERSION        1
+
+#define N_BIOS_GEOM             8
+
+/*
+ * 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
+ * normal value.
+ */
+struct bootinfo
+  {
+    unsigned int bi_version;
+    unsigned char *bi_kernelname;
+    struct nfs_diskless *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;
+  };
diff --git a/stage2/fs.h b/stage2/fs.h
new file mode 100644
index 0000000..8ed4fe0
--- /dev/null
+++ b/stage2/fs.h
@@ -0,0 +1,457 @@
+/* 
+ * Mach Operating System
+ * Copyright (c) 1991,1990 Carnegie Mellon University
+ * All Rights Reserved.
+ * 
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ * 
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ * 
+ * Carnegie Mellon requests users of this software to return to
+ * 
+ *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ * 
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ *	@(#)fs.h	7.7 (Berkeley) 5/9/89
+ */
+
+/*
+ * Each disk drive contains some number of file systems.
+ * A file system consists of a number of cylinder groups.
+ * Each cylinder group has inodes and data.
+ *
+ * A file system is described by its super-block, which in turn
+ * describes the cylinder groups.  The super-block is critical
+ * data and is replicated in each cylinder group to protect against
+ * catastrophic loss.  This is done at `newfs' time and the critical
+ * super-block data does not change, so the copies need not be
+ * referenced further unless disaster strikes.
+ *
+ * For file system fs, the offsets of the various blocks of interest
+ * are given in the super block as:
+ *	[fs->fs_sblkno]		Super-block
+ *	[fs->fs_cblkno]		Cylinder group block
+ *	[fs->fs_iblkno]		Inode blocks
+ *	[fs->fs_dblkno]		Data blocks
+ * The beginning of cylinder group cg in fs, is given by
+ * the ``cgbase(fs, cg)'' macro.
+ *
+ * The first boot and super blocks are given in absolute disk addresses.
+ * The byte-offset forms are preferred, as they don't imply a sector size.
+ */
+#define BBSIZE		8192
+#define SBSIZE		8192
+#define	BBOFF		((mach_off_t)(0))
+#define	SBOFF		((mach_off_t)(BBOFF + BBSIZE))
+#define	BBLOCK		((mach_daddr_t)(0))
+#define	SBLOCK		((mach_daddr_t)(BBLOCK + BBSIZE / DEV_BSIZE))
+
+/*
+ * Addresses stored in inodes are capable of addressing fragments
+ * of `blocks'. File system blocks of at most size MAXBSIZE can 
+ * be optionally broken into 2, 4, or 8 pieces, each of which is
+ * addressible; these pieces may be DEV_BSIZE, or some multiple of
+ * a DEV_BSIZE unit.
+ *
+ * Large files consist of exclusively large data blocks.  To avoid
+ * undue wasted disk space, the last data block of a small file may be
+ * allocated as only as many fragments of a large block as are
+ * necessary.  The file system format retains only a single pointer
+ * to such a fragment, which is a piece of a single large block that
+ * has been divided.  The size of such a fragment is determinable from
+ * information in the inode, using the ``blksize(fs, ip, lbn)'' macro.
+ *
+ * The file system records space availability at the fragment level;
+ * to determine block availability, aligned fragments are examined.
+ *
+ * The root inode is the root of the file system.
+ * Inode 0 can't be used for normal purposes and
+ * historically bad blocks were linked to inode 1,
+ * thus the root inode is 2. (inode 1 is no longer used for
+ * this purpose, however numerous dump tapes make this
+ * assumption, so we are stuck with it)
+ */
+#define	ROOTINO		((mach_ino_t)2)	/* i number of all roots */
+
+/*
+ * MINBSIZE is the smallest allowable block size.
+ * In order to insure that it is possible to create files of size
+ * 2^32 with only two levels of indirection, MINBSIZE is set to 4096.
+ * MINBSIZE must be big enough to hold a cylinder group block,
+ * thus changes to (struct cg) must keep its size within MINBSIZE.
+ * Note that super blocks are always of size SBSIZE,
+ * and that both SBSIZE and MAXBSIZE must be >= MINBSIZE.
+ */
+#define MINBSIZE	4096
+
+/*
+ * The path name on which the file system is mounted is maintained
+ * in fs_fsmnt. MAXMNTLEN defines the amount of space allocated in 
+ * the super block for this name.
+ * The limit on the amount of summary information per file system
+ * is defined by MAXCSBUFS. It is currently parameterized for a
+ * maximum of two million cylinders.
+ */
+#define MAXMNTLEN 512
+#define MAXCSBUFS 32
+
+/*
+ * Per cylinder group information; summarized in blocks allocated
+ * from first cylinder group data blocks.  These blocks have to be
+ * read in from fs_csaddr (size fs_cssize) in addition to the
+ * super block.
+ *
+ * N.B. sizeof(struct csum) must be a power of two in order for
+ * the ``fs_cs'' macro to work (see below).
+ */
+struct csum
+  {
+    int cs_ndir;		/* number of directories */
+    int cs_nbfree;		/* number of free blocks */
+    int cs_nifree;		/* number of free inodes */
+    int cs_nffree;		/* number of free frags */
+  };
+
+/*
+ * Super block for a file system.
+ */
+#define	FS_MAGIC	0x011954
+struct fs
+  {
+    int xxx1;			/* struct       fs *fs_link; */
+    int xxx2;			/* struct       fs *fs_rlink; */
+    mach_daddr_t fs_sblkno;	/* addr of super-block in filesys */
+    mach_daddr_t fs_cblkno;	/* offset of cyl-block in filesys */
+    mach_daddr_t fs_iblkno;	/* offset of inode-blocks in filesys */
+    mach_daddr_t fs_dblkno;	/* offset of first data after cg */
+    int fs_cgoffset;		/* cylinder group offset in cylinder */
+    int fs_cgmask;		/* used to calc mod fs_ntrak */
+    mach_time_t fs_time;	/* last time written */
+    int fs_size;		/* number of blocks in fs */
+    int fs_dsize;		/* number of data blocks in fs */
+    int fs_ncg;			/* number of cylinder groups */
+    int fs_bsize;		/* size of basic blocks in fs */
+    int fs_fsize;		/* size of frag blocks in fs */
+    int fs_frag;		/* number of frags in a block in fs */
+/* these are configuration parameters */
+    int fs_minfree;		/* minimum percentage of free blocks */
+    int fs_rotdelay;		/* num of ms for optimal next block */
+    int fs_rps;			/* disk revolutions per second */
+/* these fields can be computed from the others */
+    int fs_bmask;		/* ``blkoff'' calc of blk offsets */
+    int fs_fmask;		/* ``fragoff'' calc of frag offsets */
+    int fs_bshift;		/* ``lblkno'' calc of logical blkno */
+    int fs_fshift;		/* ``numfrags'' calc number of frags */
+/* these are configuration parameters */
+    int fs_maxcontig;		/* max number of contiguous blks */
+    int fs_maxbpg;		/* max number of blks per cyl group */
+/* these fields can be computed from the others */
+    int fs_fragshift;		/* block to frag shift */
+    int fs_fsbtodb;		/* fsbtodb and dbtofsb shift constant */
+    int fs_sbsize;		/* actual size of super block */
+    int fs_csmask;		/* csum block offset */
+    int fs_csshift;		/* csum block number */
+    int fs_nindir;		/* value of NINDIR */
+    int fs_inopb;		/* value of INOPB */
+    int fs_nspf;		/* value of NSPF */
+/* yet another configuration parameter */
+    int fs_optim;		/* optimization preference, see below */
+/* these fields are derived from the hardware */
+    int fs_npsect;		/* # sectors/track including spares */
+    int fs_interleave;		/* hardware sector interleave */
+    int fs_trackskew;		/* sector 0 skew, per track */
+    int fs_headswitch;		/* head switch time, usec */
+    int fs_trkseek;		/* track-to-track seek, usec */
+/* sizes determined by number of cylinder groups and their sizes */
+    mach_daddr_t fs_csaddr;	/* blk addr of cyl grp summary area */
+    int fs_cssize;		/* size of cyl grp summary area */
+    int fs_cgsize;		/* cylinder group size */
+/* these fields are derived from the hardware */
+    int fs_ntrak;		/* tracks per cylinder */
+    int fs_nsect;		/* sectors per track */
+    int fs_spc;			/* sectors per cylinder */
+/* this comes from the disk driver partitioning */
+    int fs_ncyl;		/* cylinders in file system */
+/* these fields can be computed from the others */
+    int fs_cpg;			/* cylinders per group */
+    int fs_ipg;			/* inodes per group */
+    int fs_fpg;			/* blocks per group * fs_frag */
+/* this data must be re-computed after crashes */
+    struct csum fs_cstotal;	/* cylinder summary information */
+/* these fields are cleared at mount time */
+    char fs_fmod;		/* super block modified flag */
+    char fs_clean;		/* file system is clean flag */
+    char fs_ronly;		/* mounted read-only flag */
+    char fs_flags;		/* currently unused flag */
+    char fs_fsmnt[MAXMNTLEN];	/* name mounted on */
+/* these fields retain the current block allocation info */
+    int fs_cgrotor;		/* last cg searched */
+#if 1
+    int was_fs_csp[MAXCSBUFS];
+#else
+    struct csum *fs_csp[MAXCSBUFS];	/* list of fs_cs info buffers */
+#endif
+    int fs_cpc;			/* cyl per cycle in postbl */
+    short fs_opostbl[16][8];	/* old rotation block list head */
+    long fs_sparecon[50];	/* reserved for future constants */
+    long fs_contigsumsize;	/* size of cluster summary array */
+    long fs_maxsymlinklen;	/* max length of an internal symlink */
+    long fs_inodefmt;		/* format of on-disk inodes */
+    quad fs_maxfilesize;	/* maximum representable file size */
+    quad fs_qbmask;		/* ~fs_bmask - for use with quad size */
+    quad fs_qfmask;		/* ~fs_fmask - for use with quad size */
+    long fs_state;		/* validate fs_clean field */
+    int fs_postblformat;	/* format of positional layout tables */
+    int fs_nrpos;		/* number of rotaional positions */
+    int fs_postbloff;		/* (short) rotation block list head */
+    int fs_rotbloff;		/* (u_char) blocks for each rotation */
+    int fs_magic;		/* magic number */
+    u_char fs_space[1];		/* list of blocks for each rotation */
+/* actually longer */
+  };
+/*
+ * Preference for optimization.
+ */
+#define FS_OPTTIME	0	/* minimize allocation time */
+#define FS_OPTSPACE	1	/* minimize disk fragmentation */
+
+/*
+ * Rotational layout table format types
+ */
+#define FS_42POSTBLFMT		-1	/* 4.2BSD rotational table format */
+#define FS_DYNAMICPOSTBLFMT	1	/* dynamic rotational table format */
+/*
+ * Macros for access to superblock array structures
+ */
+#define fs_postbl(fs, cylno) \
+    (((fs)->fs_postblformat == FS_42POSTBLFMT) \
+    ? ((fs)->fs_opostbl[cylno]) \
+    : ((short *)((char *)(fs) + (fs)->fs_postbloff) + (cylno) * (fs)->fs_nrpos))
+#define fs_rotbl(fs) \
+    (((fs)->fs_postblformat == FS_42POSTBLFMT) \
+    ? ((fs)->fs_space) \
+    : ((u_char *)((char *)(fs) + (fs)->fs_rotbloff)))
+
+/*
+ * Convert cylinder group to base address of its global summary info.
+ *
+ * N.B. This macro assumes that sizeof(struct csum) is a power of two.
+ */
+#define fs_cs(fs, indx) \
+	fs_csp[(indx) >> (fs)->fs_csshift][(indx) & ~(fs)->fs_csmask]
+
+/*
+ * Cylinder group block for a file system.
+ */
+#define	CG_MAGIC	0x090255
+struct cg
+  {
+    int xxx1;			/* struct       cg *cg_link; */
+    int cg_magic;		/* magic number */
+    mach_time_t cg_time;		/* time last written */
+    int cg_cgx;			/* we are the cgx'th cylinder group */
+    short cg_ncyl;		/* number of cyl's this cg */
+    short cg_niblk;		/* number of inode blocks this cg */
+    int cg_ndblk;		/* number of data blocks this cg */
+    struct csum cg_cs;		/* cylinder summary information */
+    int cg_rotor;		/* position of last used block */
+    int cg_frotor;		/* position of last used frag */
+    int cg_irotor;		/* position of last used inode */
+    int cg_frsum[MAXFRAG];	/* counts of available frags */
+    int cg_btotoff;		/* (long) block totals per cylinder */
+    int cg_boff;		/* (short) free block positions */
+    int cg_iusedoff;		/* (char) used inode map */
+    int cg_freeoff;		/* (u_char) free block map */
+    int cg_nextfreeoff;		/* (u_char) next available space */
+    int cg_sparecon[16];	/* reserved for future use */
+    u_char cg_space[1];		/* space for cylinder group maps */
+/* actually longer */
+  };
+/*
+ * Macros for access to cylinder group array structures
+ */
+#define cg_blktot(cgp) \
+    (((cgp)->cg_magic != CG_MAGIC) \
+    ? (((struct ocg *)(cgp))->cg_btot) \
+    : ((int *)((char *)(cgp) + (cgp)->cg_btotoff)))
+#define cg_blks(fs, cgp, cylno) \
+    (((cgp)->cg_magic != CG_MAGIC) \
+    ? (((struct ocg *)(cgp))->cg_b[cylno]) \
+    : ((short *)((char *)(cgp) + (cgp)->cg_boff) + (cylno) * (fs)->fs_nrpos))
+#define cg_inosused(cgp) \
+    (((cgp)->cg_magic != CG_MAGIC) \
+    ? (((struct ocg *)(cgp))->cg_iused) \
+    : ((char *)((char *)(cgp) + (cgp)->cg_iusedoff)))
+#define cg_blksfree(cgp) \
+    (((cgp)->cg_magic != CG_MAGIC) \
+    ? (((struct ocg *)(cgp))->cg_free) \
+    : ((u_char *)((char *)(cgp) + (cgp)->cg_freeoff)))
+#define cg_chkmagic(cgp) \
+    ((cgp)->cg_magic == CG_MAGIC || ((struct ocg *)(cgp))->cg_magic == CG_MAGIC)
+
+/*
+ * The following structure is defined
+ * for compatibility with old file systems.
+ */
+struct ocg
+  {
+    int xxx1;			/* struct       ocg *cg_link; */
+    int xxx2;			/* struct       ocg *cg_rlink; */
+    mach_time_t cg_time;	/* time last written */
+    int cg_cgx;			/* we are the cgx'th cylinder group */
+    short cg_ncyl;		/* number of cyl's this cg */
+    short cg_niblk;		/* number of inode blocks this cg */
+    int cg_ndblk;		/* number of data blocks this cg */
+    struct csum cg_cs;		/* cylinder summary information */
+    int cg_rotor;		/* position of last used block */
+    int cg_frotor;		/* position of last used frag */
+    int cg_irotor;		/* position of last used inode */
+    int cg_frsum[8];		/* counts of available frags */
+    int cg_btot[32];		/* block totals per cylinder */
+    short cg_b[32][8];		/* positions of free blocks */
+    char cg_iused[256];		/* used inode map */
+    int cg_magic;		/* magic number */
+    u_char cg_free[1];		/* free block map */
+/* actually longer */
+  };
+
+/*
+ * Turn file system block numbers into disk block addresses.
+ * This maps file system blocks to device size blocks.
+ */
+#define fsbtodb(fs, b)	((b) << (fs)->fs_fsbtodb)
+#define	dbtofsb(fs, b)	((b) >> (fs)->fs_fsbtodb)
+
+/*
+ * Cylinder group macros to locate things in cylinder groups.
+ * They calc file system addresses of cylinder group data structures.
+ */
+#define	cgbase(fs, c)	((mach_daddr_t)((fs)->fs_fpg * (c)))
+#define cgstart(fs, c) \
+	(cgbase(fs, c) + (fs)->fs_cgoffset * ((c) & ~((fs)->fs_cgmask)))
+#define	cgsblock(fs, c)	(cgstart(fs, c) + (fs)->fs_sblkno)	/* super blk */
+#define	cgtod(fs, c)	(cgstart(fs, c) + (fs)->fs_cblkno)	/* cg block */
+#define	cgimin(fs, c)	(cgstart(fs, c) + (fs)->fs_iblkno)	/* inode blk */
+#define	cgdmin(fs, c)	(cgstart(fs, c) + (fs)->fs_dblkno)	/* 1st data */
+
+/*
+ * Macros for handling inode numbers:
+ *     inode number to file system block offset.
+ *     inode number to cylinder group number.
+ *     inode number to file system block address.
+ */
+#define	itoo(fs, x)	((x) % INOPB(fs))
+#define	itog(fs, x)	((x) / (fs)->fs_ipg)
+#define	itod(fs, x) \
+	((mach_daddr_t)(cgimin(fs, itog(fs, x)) + \
+	(blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs))))))
+
+/*
+ * Give cylinder group number for a file system block.
+ * Give cylinder group block number for a file system block.
+ */
+#define	dtog(fs, d)	((d) / (fs)->fs_fpg)
+#define	dtogd(fs, d)	((d) % (fs)->fs_fpg)
+
+/*
+ * Extract the bits for a block from a map.
+ * Compute the cylinder and rotational position of a cyl block addr.
+ */
+#define blkmap(fs, map, loc) \
+    (((map)[(loc) / NBBY] >> ((loc) % NBBY)) & (0xff >> (NBBY - (fs)->fs_frag)))
+#define cbtocylno(fs, bno) \
+    ((bno) * NSPF(fs) / (fs)->fs_spc)
+#define cbtorpos(fs, bno) \
+    (((bno) * NSPF(fs) % (fs)->fs_spc / (fs)->fs_nsect * (fs)->fs_trackskew + \
+     (bno) * NSPF(fs) % (fs)->fs_spc % (fs)->fs_nsect * (fs)->fs_interleave) % \
+     (fs)->fs_nsect * (fs)->fs_nrpos / (fs)->fs_npsect)
+
+/*
+ * The following macros optimize certain frequently calculated
+ * quantities by using shifts and masks in place of divisions
+ * modulos and multiplications.
+ */
+#define blkoff(fs, loc)		/* calculates (loc % fs->fs_bsize) */ \
+	((loc) & ~(fs)->fs_bmask)
+#define fragoff(fs, loc)	/* calculates (loc % fs->fs_fsize) */ \
+	((loc) & ~(fs)->fs_fmask)
+#define lblkno(fs, loc)		/* calculates (loc / fs->fs_bsize) */ \
+	((loc) >> (fs)->fs_bshift)
+#define numfrags(fs, loc)	/* calculates (loc / fs->fs_fsize) */ \
+	((loc) >> (fs)->fs_fshift)
+#define blkroundup(fs, size)	/* calculates roundup(size, fs->fs_bsize) */ \
+	(((size) + (fs)->fs_bsize - 1) & (fs)->fs_bmask)
+#define fragroundup(fs, size)	/* calculates roundup(size, fs->fs_fsize) */ \
+	(((size) + (fs)->fs_fsize - 1) & (fs)->fs_fmask)
+#define fragstoblks(fs, frags)	/* calculates (frags / fs->fs_frag) */ \
+	((frags) >> (fs)->fs_fragshift)
+#define blkstofrags(fs, blks)	/* calculates (blks * fs->fs_frag) */ \
+	((blks) << (fs)->fs_fragshift)
+#define fragnum(fs, fsb)	/* calculates (fsb % fs->fs_frag) */ \
+	((fsb) & ((fs)->fs_frag - 1))
+#define blknum(fs, fsb)		/* calculates rounddown(fsb, fs->fs_frag) */ \
+	((fsb) &~ ((fs)->fs_frag - 1))
+
+/*
+ * Determine the number of available frags given a
+ * percentage to hold in reserve
+ */
+#define freespace(fs, percentreserved) \
+	(blkstofrags((fs), (fs)->fs_cstotal.cs_nbfree) + \
+	(fs)->fs_cstotal.cs_nffree - ((fs)->fs_dsize * (percentreserved) / 100))
+
+/*
+ * Determining the size of a file block in the file system.
+ */
+#define blksize(fs, ip, lbn) \
+	(((lbn) >= NDADDR || (ip)->i_size >= ((lbn) + 1) << (fs)->fs_bshift) \
+	    ? (fs)->fs_bsize \
+	    : (fragroundup(fs, blkoff(fs, (ip)->i_size))))
+#define dblksize(fs, dip, lbn) \
+	(((lbn) >= NDADDR || (dip)->di_size >= ((lbn) + 1) << (fs)->fs_bshift) \
+	    ? (fs)->fs_bsize \
+	    : (fragroundup(fs, blkoff(fs, (dip)->di_size))))
+
+/*
+ * Number of disk sectors per block; assumes DEV_BSIZE byte sector size.
+ */
+#define	NSPB(fs)	((fs)->fs_nspf << (fs)->fs_fragshift)
+#define	NSPF(fs)	((fs)->fs_nspf)
+
+/*
+ * INOPB is the number of inodes in a secondary storage block.
+ */
+#define	INOPB(fs)	((fs)->fs_inopb)
+#define	INOPF(fs)	((fs)->fs_inopb >> (fs)->fs_fragshift)
+
+/*
+ * NINDIR is the number of indirects in a file system block.
+ */
+#define	NINDIR(fs)	((fs)->fs_nindir)
diff --git a/stage2/fsys_ext2fs.c b/stage2/fsys_ext2fs.c
new file mode 100644
index 0000000..560048f
--- /dev/null
+++ b/stage2/fsys_ext2fs.c
@@ -0,0 +1,789 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999, 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 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef FSYS_EXT2FS
+
+#include "shared.h"
+#include "filesys.h"
+
+static int mapblock1, mapblock2;
+
+/* sizes are always in bytes, BLOCK values are always in DEV_BSIZE (sectors) */
+#define DEV_BSIZE 512
+
+/* include/linux/fs.h */
+#define BLOCK_SIZE 1024		/* initial block size for superblock read */
+/* made up, defaults to 1 but can be passed via mount_opts */
+#define WHICH_SUPER 1
+/* kind of from fs/ext2/super.c */
+#define SBLOCK (WHICH_SUPER * BLOCK_SIZE / DEV_BSIZE)	/* = 2 */
+
+/* include/asm-i386/types.h */
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+/*
+ * Constants relative to the data blocks, from ext2_fs.h
+ */
+#define EXT2_NDIR_BLOCKS                12
+#define EXT2_IND_BLOCK                  EXT2_NDIR_BLOCKS
+#define EXT2_DIND_BLOCK                 (EXT2_IND_BLOCK + 1)
+#define EXT2_TIND_BLOCK                 (EXT2_DIND_BLOCK + 1)
+#define EXT2_N_BLOCKS                   (EXT2_TIND_BLOCK + 1)
+
+/* include/linux/ext2_fs.h */
+struct ext2_super_block
+  {
+    __u32 s_inodes_count;	/* Inodes count */
+    __u32 s_blocks_count;	/* Blocks count */
+    __u32 s_r_blocks_count;	/* Reserved blocks count */
+    __u32 s_free_blocks_count;	/* Free blocks count */
+    __u32 s_free_inodes_count;	/* Free inodes count */
+    __u32 s_first_data_block;	/* First Data Block */
+    __u32 s_log_block_size;	/* Block size */
+    __s32 s_log_frag_size;	/* Fragment size */
+    __u32 s_blocks_per_group;	/* # Blocks per group */
+    __u32 s_frags_per_group;	/* # Fragments per group */
+    __u32 s_inodes_per_group;	/* # Inodes per group */
+    __u32 s_mtime;		/* Mount time */
+    __u32 s_wtime;		/* Write time */
+    __u16 s_mnt_count;		/* Mount count */
+    __s16 s_max_mnt_count;	/* Maximal mount count */
+    __u16 s_magic;		/* Magic signature */
+    __u16 s_state;		/* File system state */
+    __u16 s_errors;		/* Behaviour when detecting errors */
+    __u16 s_pad;
+    __u32 s_lastcheck;		/* time of last check */
+    __u32 s_checkinterval;	/* max. time between checks */
+    __u32 s_creator_os;		/* OS */
+    __u32 s_rev_level;		/* Revision level */
+    __u16 s_def_resuid;		/* Default uid for reserved blocks */
+    __u16 s_def_resgid;		/* Default gid for reserved blocks */
+    __u32 s_reserved[235];	/* Padding to the end of the block */
+  };
+
+struct ext2_group_desc
+  {
+    __u32 bg_block_bitmap;	/* Blocks bitmap block */
+    __u32 bg_inode_bitmap;	/* Inodes bitmap block */
+    __u32 bg_inode_table;	/* Inodes table block */
+    __u16 bg_free_blocks_count;	/* Free blocks count */
+    __u16 bg_free_inodes_count;	/* Free inodes count */
+    __u16 bg_used_dirs_count;	/* Directories count */
+    __u16 bg_pad;
+    __u32 bg_reserved[3];
+  };
+
+struct ext2_inode
+  {
+    __u16 i_mode;		/* File mode */
+    __u16 i_uid;		/* Owner Uid */
+    __u32 i_size;		/* 4: Size in bytes */
+    __u32 i_atime;		/* Access time */
+    __u32 i_ctime;		/* 12: Creation time */
+    __u32 i_mtime;		/* Modification time */
+    __u32 i_dtime;		/* 20: Deletion Time */
+    __u16 i_gid;		/* Group Id */
+    __u16 i_links_count;	/* 24: Links count */
+    __u32 i_blocks;		/* Blocks count */
+    __u32 i_flags;		/* 32: File flags */
+    union
+      {
+	struct
+	  {
+	    __u32 l_i_reserved1;
+	  }
+	linux1;
+	struct
+	  {
+	    __u32 h_i_translator;
+	  }
+	hurd1;
+	struct
+	  {
+	    __u32 m_i_reserved1;
+	  }
+	masix1;
+      }
+    osd1;			/* OS dependent 1 */
+    __u32 i_block[EXT2_N_BLOCKS];	/* 40: Pointers to blocks */
+    __u32 i_version;		/* File version (for NFS) */
+    __u32 i_file_acl;		/* File ACL */
+    __u32 i_dir_acl;		/* Directory ACL */
+    __u32 i_faddr;		/* Fragment address */
+    union
+      {
+	struct
+	  {
+	    __u8 l_i_frag;	/* Fragment number */
+	    __u8 l_i_fsize;	/* Fragment size */
+	    __u16 i_pad1;
+	    __u32 l_i_reserved2[2];
+	  }
+	linux2;
+	struct
+	  {
+	    __u8 h_i_frag;	/* Fragment number */
+	    __u8 h_i_fsize;	/* Fragment size */
+	    __u16 h_i_mode_high;
+	    __u16 h_i_uid_high;
+	    __u16 h_i_gid_high;
+	    __u32 h_i_author;
+	  }
+	hurd2;
+	struct
+	  {
+	    __u8 m_i_frag;	/* Fragment number */
+	    __u8 m_i_fsize;	/* Fragment size */
+	    __u16 m_pad1;
+	    __u32 m_i_reserved2[2];
+	  }
+	masix2;
+      }
+    osd2;			/* OS dependent 2 */
+  };
+
+/* linux/limits.h */
+#define NAME_MAX         255	/* # chars in a file name */
+
+/* linux/posix_type.h */
+typedef long linux_off_t;
+
+/* linux/ext2fs.h */
+#define EXT2_NAME_LEN 255
+struct ext2_dir_entry
+  {
+    __u32 inode;		/* Inode number */
+    __u16 rec_len;		/* Directory entry length */
+    __u8 name_len;		/* Name length */
+    __u8 file_type;
+    char name[EXT2_NAME_LEN];	/* File name */
+  };
+
+/* linux/ext2fs.h */
+/*
+ * EXT2_DIR_PAD defines the directory entries boundaries
+ *
+ * NOTE: It must be a multiple of 4
+ */
+#define EXT2_DIR_PAD                    4
+#define EXT2_DIR_ROUND                  (EXT2_DIR_PAD - 1)
+#define EXT2_DIR_REC_LEN(name_len)      (((name_len) + 8 + EXT2_DIR_ROUND) & \
+                                         ~EXT2_DIR_ROUND)
+
+
+/* ext2/super.c */
+#define log2(n) ffz(~(n))
+
+#define EXT2_SUPER_MAGIC      0xEF53	/* include/linux/ext2_fs.h */
+#define EXT2_ROOT_INO              2	/* include/linux/ext2_fs.h */
+#define PATH_MAX                1024	/* include/linux/limits.h */
+#define MAX_LINK_COUNT             5	/* number of symbolic links to follow */
+
+/* made up, these are pointers into FSYS_BUF */
+/* read once, always stays there: */
+#define SUPERBLOCK \
+    ((struct ext2_super_block *)(FSYS_BUF))
+#define GROUP_DESC \
+    ((struct ext2_group_desc *) \
+     ((int)SUPERBLOCK + sizeof(struct ext2_super_block)))
+#define INODE \
+    ((struct ext2_inode *)((int)GROUP_DESC + EXT2_BLOCK_SIZE(SUPERBLOCK)))
+#define DATABLOCK1 \
+    ((int)((int)INODE + sizeof(struct ext2_inode)))
+#define DATABLOCK2 \
+    ((int)((int)DATABLOCK1 + EXT2_BLOCK_SIZE(SUPERBLOCK)))
+
+/* linux/ext2_fs.h */
+#define EXT2_ADDR_PER_BLOCK(s)          (EXT2_BLOCK_SIZE(s) / sizeof (__u32))
+#define EXT2_ADDR_PER_BLOCK_BITS(s)		(log2(EXT2_ADDR_PER_BLOCK(s)))
+
+/* linux/ext2_fs.h */
+#define EXT2_BLOCK_SIZE_BITS(s)        ((s)->s_log_block_size + 10)
+/* kind of from ext2/super.c */
+#define EXT2_BLOCK_SIZE(s)	(1 << EXT2_BLOCK_SIZE_BITS(s))
+/* linux/ext2fs.h */
+#define EXT2_DESC_PER_BLOCK(s) \
+     (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
+/* linux/stat.h */
+#define S_IFMT  00170000
+#define S_IFLNK  0120000
+#define S_IFREG  0100000
+#define S_IFDIR  0040000
+#define S_ISLNK(m)	(((m) & S_IFMT) == S_IFLNK)
+#define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)
+#define S_ISDIR(m)      (((m) & S_IFMT) == S_IFDIR)
+
+/* include/asm-i386/bitops.h */
+/*
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ */
+static __inline__ unsigned long
+ffz (unsigned long word)
+{
+  __asm__ ("bsfl %1,%0"
+:	   "=r" (word)
+:	   "r" (~word));
+  return word;
+}
+
+/* check filesystem types and read superblock into memory buffer */
+int
+ext2fs_mount (void)
+{
+  int retval = 1;
+
+  if ((((current_drive & 0x80) || (current_slice != 0))
+       && (current_slice != PC_SLICE_TYPE_EXT2FS)
+       && (current_slice != PC_SLICE_TYPE_LINUX_RAID)
+       && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_EXT2FS))
+       && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_OTHER)))
+      || part_length < (SBLOCK + (sizeof (struct ext2_super_block) / DEV_BSIZE))
+      || !devread (SBLOCK, 0, sizeof (struct ext2_super_block),
+		   (char *) SUPERBLOCK)
+      || SUPERBLOCK->s_magic != EXT2_SUPER_MAGIC)
+      retval = 0;
+
+  return retval;
+}
+
+/* Takes a file system block number and reads it into BUFFER. */
+static int
+ext2_rdfsb (int fsblock, int buffer)
+{
+#ifdef E2DEBUG
+  printf ("fsblock %d buffer %d\n", fsblock, buffer);
+#endif /* E2DEBUG */
+  return devread (fsblock * (EXT2_BLOCK_SIZE (SUPERBLOCK) / DEV_BSIZE), 0,
+		  EXT2_BLOCK_SIZE (SUPERBLOCK), (char *) buffer);
+}
+
+/* from
+  ext2/inode.c:ext2_bmap()
+*/
+/* Maps LOGICAL_BLOCK (the file offset divided by the blocksize) into
+   a physical block (the location in the file system) via an inode. */
+static int
+ext2fs_block_map (int logical_block)
+{
+
+#ifdef E2DEBUG
+  unsigned char *i;
+  for (i = (unsigned char *) INODE;
+       i < ((unsigned char *) INODE + sizeof (struct ext2_inode));
+       i++)
+    {
+      printf ("%c", "0123456789abcdef"[*i >> 4]);
+      printf ("%c", "0123456789abcdef"[*i % 16]);
+      if (!((i + 1 - (unsigned char *) INODE) % 16))
+	{
+	  printf ("\n");
+	}
+      else
+	{
+	  printf (" ");
+	}
+    }
+  printf ("logical block %d\n", logical_block);
+#endif /* E2DEBUG */
+
+  /* if it is directly pointed to by the inode, return that physical addr */
+  if (logical_block < EXT2_NDIR_BLOCKS)
+    {
+#ifdef E2DEBUG
+      printf ("returning %d\n", (unsigned char *) (INODE->i_block[logical_block]));
+      printf ("returning %d\n", INODE->i_block[logical_block]);
+#endif /* E2DEBUG */
+      return INODE->i_block[logical_block];
+    }
+  /* else */
+  logical_block -= EXT2_NDIR_BLOCKS;
+  /* try the indirect block */
+  if (logical_block < EXT2_ADDR_PER_BLOCK (SUPERBLOCK))
+    {
+      if (mapblock1 != 1
+	  && !ext2_rdfsb (INODE->i_block[EXT2_IND_BLOCK], DATABLOCK1))
+	{
+	  errnum = ERR_FSYS_CORRUPT;
+	  return -1;
+	}
+      mapblock1 = 1;
+      return ((__u32 *) DATABLOCK1)[logical_block];
+    }
+  /* else */
+  logical_block -= EXT2_ADDR_PER_BLOCK (SUPERBLOCK);
+  /* now try the double indirect block */
+  if (logical_block < (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2)))
+    {
+      int bnum;
+      if (mapblock1 != 2
+	  && !ext2_rdfsb (INODE->i_block[EXT2_DIND_BLOCK], DATABLOCK1))
+	{
+	  errnum = ERR_FSYS_CORRUPT;
+	  return -1;
+	}
+      mapblock1 = 2;
+      if ((bnum = (((__u32 *) DATABLOCK1)
+		   [logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)]))
+	  != mapblock2
+	  && !ext2_rdfsb (bnum, DATABLOCK2))
+	{
+	  errnum = ERR_FSYS_CORRUPT;
+	  return -1;
+	}
+      mapblock2 = bnum;
+      return ((__u32 *) DATABLOCK2)
+	[logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
+    }
+  /* else */
+  mapblock2 = -1;
+  logical_block -= (1 << (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK) * 2));
+  if (mapblock1 != 3
+      && !ext2_rdfsb (INODE->i_block[EXT2_TIND_BLOCK], DATABLOCK1))
+    {
+      errnum = ERR_FSYS_CORRUPT;
+      return -1;
+    }
+  mapblock1 = 3;
+  if (!ext2_rdfsb (((__u32 *) DATABLOCK1)
+		   [logical_block >> (EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK)
+				      * 2)],
+		   DATABLOCK2))
+    {
+      errnum = ERR_FSYS_CORRUPT;
+      return -1;
+    }
+  if (!ext2_rdfsb (((__u32 *) DATABLOCK2)
+		   [(logical_block >> EXT2_ADDR_PER_BLOCK_BITS (SUPERBLOCK))
+		    & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)],
+		   DATABLOCK2))
+    {
+      errnum = ERR_FSYS_CORRUPT;
+      return -1;
+    }
+  return ((__u32 *) DATABLOCK2)
+    [logical_block & (EXT2_ADDR_PER_BLOCK (SUPERBLOCK) - 1)];
+}
+
+/* preconditions: all preconds of ext2fs_block_map */
+int
+ext2fs_read (char *buf, int len)
+{
+  int logical_block;
+  int offset;
+  int map;
+  int ret = 0;
+  int size = 0;
+
+#ifdef E2DEBUG
+  static char hexdigit[] = "0123456789abcdef";
+  unsigned char *i;
+  for (i = (unsigned char *) INODE;
+       i < ((unsigned char *) INODE + sizeof (struct ext2_inode));
+       i++)
+    {
+      printf ("%c", hexdigit[*i >> 4]);
+      printf ("%c", hexdigit[*i % 16]);
+      if (!((i + 1 - (unsigned char *) INODE) % 16))
+	{
+	  printf ("\n");
+	}
+      else
+	{
+	  printf (" ");
+	}
+    }
+#endif /* E2DEBUG */
+  while (len > 0)
+    {
+      /* find the (logical) block component of our location */
+      logical_block = filepos >> EXT2_BLOCK_SIZE_BITS (SUPERBLOCK);
+      offset = filepos & (EXT2_BLOCK_SIZE (SUPERBLOCK) - 1);
+      map = ext2fs_block_map (logical_block);
+#ifdef E2DEBUG
+      printf ("map=%d\n", map);
+#endif /* E2DEBUG */
+      if (map < 0)
+	break;
+
+      size = EXT2_BLOCK_SIZE (SUPERBLOCK);
+      size -= offset;
+      if (size > len)
+	size = len;
+
+      if (map == 0) {
+        memset ((char *) buf, 0, size);
+      } else {
+        disk_read_func = disk_read_hook;
+
+        devread (map * (EXT2_BLOCK_SIZE (SUPERBLOCK) / DEV_BSIZE),
+	         offset, size, buf);
+
+        disk_read_func = NULL;
+      }
+
+      buf += size;
+      len -= size;
+      filepos += size;
+      ret += size;
+    }
+
+  if (errnum)
+    ret = 0;
+
+  return ret;
+}
+
+
+/* Based on:
+   def_blk_fops points to
+   blkdev_open, which calls (I think):
+   sys_open()
+   do_open()
+   open_namei()
+   dir_namei() which accesses current->fs->root
+     fs->root was set during original mount:
+     (something)... which calls (I think):
+     ext2_read_super()
+     iget()
+     __iget()
+     read_inode()
+     ext2_read_inode()
+       uses desc_per_block_bits, which is set in ext2_read_super()
+       also uses group descriptors loaded during ext2_read_super()
+   lookup()
+   ext2_lookup()
+   ext2_find_entry()
+   ext2_getblk()
+
+*/
+
+static inline
+int ext2_is_fast_symlink (void)
+{
+  int ea_blocks;
+  ea_blocks = INODE->i_file_acl ? EXT2_BLOCK_SIZE (SUPERBLOCK) / DEV_BSIZE : 0;
+  return INODE->i_blocks == ea_blocks;
+}
+
+/* preconditions: ext2fs_mount already executed, therefore supblk in buffer
+ *   known as SUPERBLOCK
+ * returns: 0 if error, nonzero iff we were able to find the file successfully
+ * postconditions: on a nonzero return, buffer known as INODE contains the
+ *   inode of the file we were trying to look up
+ * side effects: messes up GROUP_DESC buffer area
+ */
+int
+ext2fs_dir (char *dirname)
+{
+  int current_ino = EXT2_ROOT_INO;	/* start at the root */
+  int updir_ino = current_ino;	/* the parent of the current directory */
+  int group_id;			/* which group the inode is in */
+  int group_desc;		/* fs pointer to that group */
+  int desc;			/* index within that group */
+  int ino_blk;			/* fs pointer of the inode's information */
+  int str_chk = 0;		/* used to hold the results of a string compare */
+  struct ext2_group_desc *gdp;
+  struct ext2_inode *raw_inode;	/* inode info corresponding to current_ino */
+
+  char linkbuf[PATH_MAX];	/* buffer for following symbolic links */
+  int link_count = 0;
+
+  char *rest;
+  char ch;			/* temp char holder */
+
+  int off;			/* offset within block of directory entry (off mod blocksize) */
+  int loc;			/* location within a directory */
+  int blk;			/* which data blk within dir entry (off div blocksize) */
+  long map;			/* fs pointer of a particular block from dir entry */
+  struct ext2_dir_entry *dp;	/* pointer to directory entry */
+#ifdef E2DEBUG
+  unsigned char *i;
+#endif	/* E2DEBUG */
+
+  /* loop invariants:
+     current_ino = inode to lookup
+     dirname = pointer to filename component we are cur looking up within
+     the directory known pointed to by current_ino (if any)
+   */
+
+  while (1)
+    {
+#ifdef E2DEBUG
+      printf ("inode %d\n", current_ino);
+      printf ("dirname=%s\n", dirname);
+#endif /* E2DEBUG */
+
+      /* look up an inode */
+      group_id = (current_ino - 1) / (SUPERBLOCK->s_inodes_per_group);
+      group_desc = group_id >> log2 (EXT2_DESC_PER_BLOCK (SUPERBLOCK));
+      desc = group_id & (EXT2_DESC_PER_BLOCK (SUPERBLOCK) - 1);
+#ifdef E2DEBUG
+      printf ("ipg=%d, dpb=%d\n", SUPERBLOCK->s_inodes_per_group,
+	      EXT2_DESC_PER_BLOCK (SUPERBLOCK));
+      printf ("group_id=%d group_desc=%d desc=%d\n", group_id, group_desc, desc);
+#endif /* E2DEBUG */
+      if (!ext2_rdfsb (
+			(WHICH_SUPER + group_desc + SUPERBLOCK->s_first_data_block),
+			(int) GROUP_DESC))
+	{
+	  return 0;
+	}
+      gdp = GROUP_DESC;
+      ino_blk = gdp[desc].bg_inode_table +
+	(((current_ino - 1) % (SUPERBLOCK->s_inodes_per_group))
+	 >> log2 (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)));
+#ifdef E2DEBUG
+      printf ("inode table fsblock=%d\n", ino_blk);
+#endif /* E2DEBUG */
+      if (!ext2_rdfsb (ino_blk, (int) INODE))
+	{
+	  return 0;
+	}
+
+      /* reset indirect blocks! */
+      mapblock2 = mapblock1 = -1;
+
+      raw_inode = INODE +
+	((current_ino - 1)
+	 & (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode) - 1));
+#ifdef E2DEBUG
+      printf ("ipb=%d, sizeof(inode)=%d\n",
+	      (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode)),
+	      sizeof (struct ext2_inode));
+      printf ("inode=%x, raw_inode=%x\n", INODE, raw_inode);
+      printf ("offset into inode table block=%d\n", (int) raw_inode - (int) INODE);
+      for (i = (unsigned char *) INODE; i <= (unsigned char *) raw_inode;
+	   i++)
+	{
+	  printf ("%c", "0123456789abcdef"[*i >> 4]);
+	  printf ("%c", "0123456789abcdef"[*i % 16]);
+	  if (!((i + 1 - (unsigned char *) INODE) % 16))
+	    {
+	      printf ("\n");
+	    }
+	  else
+	    {
+	      printf (" ");
+	    }
+	}
+      printf ("first word=%x\n", *((int *) raw_inode));
+#endif /* E2DEBUG */
+
+      /* copy inode to fixed location */
+      memmove ((void *) INODE, (void *) raw_inode, sizeof (struct ext2_inode));
+
+#ifdef E2DEBUG
+      printf ("first word=%x\n", *((int *) INODE));
+#endif /* E2DEBUG */
+
+      /* If we've got a symbolic link, then chase it. */
+      if (S_ISLNK (INODE->i_mode))
+	{
+	  int len;
+	  if (++link_count > MAX_LINK_COUNT)
+	    {
+	      errnum = ERR_SYMLINK_LOOP;
+	      return 0;
+	    }
+
+	  /* Find out how long our remaining name is. */
+	  len = 0;
+	  while (dirname[len] && !isspace (dirname[len]))
+	    len++;
+
+	  /* Get the symlink size. */
+	  filemax = (INODE->i_size);
+	  if (filemax + len > sizeof (linkbuf) - 2)
+	    {
+	      errnum = ERR_FILELENGTH;
+	      return 0;
+	    }
+
+	  if (len)
+	    {
+	      /* Copy the remaining name to the end of the symlink data.
+	         Note that DIRNAME and LINKBUF may overlap! */
+	      memmove (linkbuf + filemax, dirname, len);
+	    }
+	  linkbuf[filemax + len] = '\0';
+
+	  /* Read the symlink data. */
+	  if (! ext2_is_fast_symlink ())
+	    {
+	      /* Read the necessary blocks, and reset the file pointer. */
+	      len = grub_read (linkbuf, filemax);
+	      filepos = 0;
+	      if (!len)
+		return 0;
+	    }
+	  else
+	    {
+	      /* Copy the data directly from the inode. */
+	      len = filemax;
+	      memmove (linkbuf, (char *) INODE->i_block, len);
+	    }
+
+#ifdef E2DEBUG
+	  printf ("symlink=%s\n", linkbuf);
+#endif
+
+	  dirname = linkbuf;
+	  if (*dirname == '/')
+	    {
+	      /* It's an absolute link, so look it up in root. */
+	      current_ino = EXT2_ROOT_INO;
+	      updir_ino = current_ino;
+	    }
+	  else
+	    {
+	      /* Relative, so look it up in our parent directory. */
+	      current_ino = updir_ino;
+	    }
+
+	  /* Try again using the new name. */
+	  continue;
+	}
+
+      /* if end of filename, INODE points to the file's inode */
+      if (!*dirname || isspace (*dirname))
+	{
+	  if (!S_ISREG (INODE->i_mode))
+	    {
+	      errnum = ERR_BAD_FILETYPE;
+	      return 0;
+	    }
+
+	  filemax = (INODE->i_size);
+	  return 1;
+	}
+
+      /* else we have to traverse a directory */
+      updir_ino = current_ino;
+
+      /* skip over slashes */
+      while (*dirname == '/')
+	dirname++;
+
+      /* if this isn't a directory of sufficient size to hold our file, abort */
+      if (!(INODE->i_size) || !S_ISDIR (INODE->i_mode))
+	{
+	  errnum = ERR_BAD_FILETYPE;
+	  return 0;
+	}
+
+      /* skip to next slash or end of filename (space) */
+      for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/';
+	   rest++);
+
+      /* look through this directory and find the next filename component */
+      /* invariant: rest points to slash after the next filename component */
+      *rest = 0;
+      loc = 0;
+
+      do
+	{
+
+#ifdef E2DEBUG
+	  printf ("dirname=%s, rest=%s, loc=%d\n", dirname, rest, loc);
+#endif /* E2DEBUG */
+
+	  /* if our location/byte offset into the directory exceeds the size,
+	     give up */
+	  if (loc >= INODE->i_size)
+	    {
+	      if (print_possibilities < 0)
+		{
+# if 0
+		  putchar ('\n');
+# endif
+		}
+	      else
+		{
+		  errnum = ERR_FILE_NOT_FOUND;
+		  *rest = ch;
+		}
+	      return (print_possibilities < 0);
+	    }
+
+	  /* else, find the (logical) block component of our location */
+	  blk = loc >> EXT2_BLOCK_SIZE_BITS (SUPERBLOCK);
+
+	  /* we know which logical block of the directory entry we are looking
+	     for, now we have to translate that to the physical (fs) block on
+	     the disk */
+	  map = ext2fs_block_map (blk);
+#ifdef E2DEBUG
+	  printf ("fs block=%d\n", map);
+#endif /* E2DEBUG */
+	  mapblock2 = -1;
+	  if ((map < 0) || !ext2_rdfsb (map, DATABLOCK2))
+	    {
+	      errnum = ERR_FSYS_CORRUPT;
+	      *rest = ch;
+	      return 0;
+	    }
+	  off = loc & (EXT2_BLOCK_SIZE (SUPERBLOCK) - 1);
+	  dp = (struct ext2_dir_entry *) (DATABLOCK2 + off);
+	  /* advance loc prematurely to next on-disk directory entry  */
+	  loc += dp->rec_len;
+
+	  /* NOTE: ext2fs filenames are NOT null-terminated */
+
+#ifdef E2DEBUG
+	  printf ("directory entry ino=%d\n", dp->inode);
+	  if (dp->inode)
+	    printf ("entry=%s\n", dp->name);
+#endif /* E2DEBUG */
+
+	  if (dp->inode)
+	    {
+	      int saved_c = dp->name[dp->name_len];
+
+	      dp->name[dp->name_len] = 0;
+	      str_chk = substring (dirname, dp->name);
+
+# ifndef STAGE1_5
+	      if (print_possibilities && ch != '/'
+		  && (!*dirname || str_chk <= 0))
+		{
+		  if (print_possibilities > 0)
+		    print_possibilities = -print_possibilities;
+		  print_a_completion (dp->name);
+		}
+# endif
+
+	      dp->name[dp->name_len] = saved_c;
+	    }
+
+	}
+      while (!dp->inode || (str_chk || (print_possibilities && ch != '/')));
+
+      current_ino = dp->inode;
+      *(dirname = rest) = ch;
+    }
+  /* never get here */
+}
+
+#endif /* FSYS_EXT2_FS */
diff --git a/stage2/fsys_fat.c b/stage2/fsys_fat.c
new file mode 100644
index 0000000..f40e658
--- /dev/null
+++ b/stage2/fsys_fat.c
@@ -0,0 +1,488 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,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
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef FSYS_FAT
+
+#include "shared.h"
+#include "filesys.h"
+#include "fat.h"
+
+struct fat_superblock 
+{
+  int fat_offset;
+  int fat_length;
+  int fat_size;
+  int root_offset;
+  int root_max;
+  int data_offset;
+  
+  int num_sectors;
+  int num_clust;
+  int clust_eof_marker;
+  int sects_per_clust;
+  int sectsize_bits;
+  int clustsize_bits;
+  int root_cluster;
+  
+  int cached_fat;
+  int file_cluster;
+  int current_cluster_num;
+  int current_cluster;
+};
+
+/* pointer(s) into filesystem info buffer for DOS stuff */
+#define FAT_SUPER ( (struct fat_superblock *) \
+ 		    ( FSYS_BUF + 32256) )/* 512 bytes long */
+#define FAT_BUF   ( FSYS_BUF + 30208 )	/* 4 sector FAT buffer */
+#define NAME_BUF  ( FSYS_BUF + 29184 )	/* Filename buffer (833 bytes) */
+
+#define FAT_CACHE_SIZE 2048
+
+static __inline__ unsigned long
+log2 (unsigned long word)
+{
+  __asm__ ("bsfl %1,%0"
+	   : "=r" (word)
+	   : "r" (word));
+  return word;
+}
+
+int
+fat_mount (void)
+{
+  struct fat_bpb bpb;
+  __u32 magic, first_fat;
+  
+  /* Check partition type for harddisk */
+  if (((current_drive & 0x80) || (current_slice != 0))
+      && ! IS_PC_SLICE_TYPE_FAT (current_slice)
+      && (! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_MSDOS)))
+    return 0;
+  
+  /* Read bpb */
+  if (! devread (0, 0, sizeof (bpb), (char *) &bpb))
+    return 0;
+
+  /* Check if the number of sectors per cluster is zero here, to avoid
+     zero division.  */
+  if (bpb.sects_per_clust == 0)
+    return 0;
+  
+  FAT_SUPER->sectsize_bits = log2 (FAT_CVT_U16 (bpb.bytes_per_sect));
+  FAT_SUPER->clustsize_bits
+    = FAT_SUPER->sectsize_bits + log2 (bpb.sects_per_clust);
+  
+  /* Fill in info about super block */
+  FAT_SUPER->num_sectors = FAT_CVT_U16 (bpb.short_sectors) 
+    ? FAT_CVT_U16 (bpb.short_sectors) : bpb.long_sectors;
+  
+  /* FAT offset and length */
+  FAT_SUPER->fat_offset = FAT_CVT_U16 (bpb.reserved_sects);
+  FAT_SUPER->fat_length = 
+    bpb.fat_length ? bpb.fat_length : bpb.fat32_length;
+  
+  /* Rootdir offset and length for FAT12/16 */
+  FAT_SUPER->root_offset = 
+    FAT_SUPER->fat_offset + bpb.num_fats * FAT_SUPER->fat_length;
+  FAT_SUPER->root_max = FAT_DIRENTRY_LENGTH * FAT_CVT_U16(bpb.dir_entries);
+  
+  /* Data offset and number of clusters */
+  FAT_SUPER->data_offset = 
+    FAT_SUPER->root_offset
+    + ((FAT_SUPER->root_max - 1) >> FAT_SUPER->sectsize_bits) + 1;
+  FAT_SUPER->num_clust = 
+    2 + ((FAT_SUPER->num_sectors - FAT_SUPER->data_offset) 
+	 / bpb.sects_per_clust);
+  FAT_SUPER->sects_per_clust = bpb.sects_per_clust;
+  
+  if (!bpb.fat_length)
+    {
+      /* This is a FAT32 */
+      if (FAT_CVT_U16(bpb.dir_entries))
+ 	return 0;
+      
+      if (bpb.flags & 0x0080)
+	{
+	  /* FAT mirroring is disabled, get active FAT */
+	  int active_fat = bpb.flags & 0x000f;
+	  if (active_fat >= bpb.num_fats)
+	    return 0;
+	  FAT_SUPER->fat_offset += active_fat * FAT_SUPER->fat_length;
+	}
+      
+      FAT_SUPER->fat_size = 8;
+      FAT_SUPER->root_cluster = bpb.root_cluster;
+
+      /* Yes the following is correct.  FAT32 should be called FAT28 :) */
+      FAT_SUPER->clust_eof_marker = 0xffffff8;
+    } 
+  else 
+    {
+      if (!FAT_SUPER->root_max)
+ 	return 0;
+      
+      FAT_SUPER->root_cluster = -1;
+      if (FAT_SUPER->num_clust > FAT_MAX_12BIT_CLUST) 
+	{
+	  FAT_SUPER->fat_size = 4;
+	  FAT_SUPER->clust_eof_marker = 0xfff8;
+	} 
+      else
+	{
+	  FAT_SUPER->fat_size = 3;
+	  FAT_SUPER->clust_eof_marker = 0xff8;
+	}
+    }
+
+  /* Now do some sanity checks */
+  
+  if (FAT_CVT_U16(bpb.bytes_per_sect) != (1 << FAT_SUPER->sectsize_bits)
+      || FAT_CVT_U16(bpb.bytes_per_sect) != SECTOR_SIZE
+      || bpb.sects_per_clust != (1 << (FAT_SUPER->clustsize_bits
+ 				       - FAT_SUPER->sectsize_bits))
+      || FAT_SUPER->num_clust <= 2
+      || (FAT_SUPER->fat_size * FAT_SUPER->num_clust / (2 * SECTOR_SIZE)
+ 	  > FAT_SUPER->fat_length))
+    return 0;
+  
+  /* kbs: Media check on first FAT entry [ported from PUPA] */
+
+  if (!devread(FAT_SUPER->fat_offset, 0,
+               sizeof(first_fat), (char *)&first_fat))
+    return 0;
+
+  if (FAT_SUPER->fat_size == 8)
+    {
+      first_fat &= 0x0fffffff;
+      magic = 0x0fffff00;
+    }
+  else if (FAT_SUPER->fat_size == 4)
+    {
+      first_fat &= 0x0000ffff;
+      magic = 0xff00;
+    }
+  else
+    {
+      first_fat &= 0x00000fff;
+      magic = 0x0f00;
+    }
+
+  /* Ignore the 3rd bit, because some BIOSes assigns 0xF0 to the media
+     descriptor, even if it is a so-called superfloppy (e.g. an USB key).
+     The check may be too strict for this kind of stupid BIOSes, as
+     they overwrite the media descriptor.  */
+  if ((first_fat | 0x8) != (magic | bpb.media | 0x8))
+    return 0;
+
+  FAT_SUPER->cached_fat = - 2 * FAT_CACHE_SIZE;
+  return 1;
+}
+
+int
+fat_read (char *buf, int len)
+{
+  int logical_clust;
+  int offset;
+  int ret = 0;
+  int size;
+  
+  if (FAT_SUPER->file_cluster < 0)
+    {
+      /* root directory for fat16 */
+      size = FAT_SUPER->root_max - filepos;
+      if (size > len)
+ 	size = len;
+      if (!devread(FAT_SUPER->root_offset, filepos, size, buf))
+ 	return 0;
+      filepos += size;
+      return size;
+    }
+  
+  logical_clust = filepos >> FAT_SUPER->clustsize_bits;
+  offset = (filepos & ((1 << FAT_SUPER->clustsize_bits) - 1));
+  if (logical_clust < FAT_SUPER->current_cluster_num)
+    {
+      FAT_SUPER->current_cluster_num = 0;
+      FAT_SUPER->current_cluster = FAT_SUPER->file_cluster;
+    }
+  
+  while (len > 0)
+    {
+      int sector;
+      while (logical_clust > FAT_SUPER->current_cluster_num)
+	{
+	  /* calculate next cluster */
+	  int fat_entry = 
+	    FAT_SUPER->current_cluster * FAT_SUPER->fat_size;
+	  int next_cluster;
+	  int cached_pos = (fat_entry - FAT_SUPER->cached_fat);
+	  
+	  if (cached_pos < 0 || 
+	      (cached_pos + FAT_SUPER->fat_size) > 2*FAT_CACHE_SIZE)
+	    {
+	      FAT_SUPER->cached_fat = (fat_entry & ~(2*SECTOR_SIZE - 1));
+	      cached_pos = (fat_entry - FAT_SUPER->cached_fat);
+	      sector = FAT_SUPER->fat_offset
+		+ FAT_SUPER->cached_fat / (2*SECTOR_SIZE);
+	      if (!devread (sector, 0, FAT_CACHE_SIZE, (char*) FAT_BUF))
+		return 0;
+	    }
+	  next_cluster = * (unsigned long *) (FAT_BUF + (cached_pos >> 1));
+	  if (FAT_SUPER->fat_size == 3)
+	    {
+	      if (cached_pos & 1)
+		next_cluster >>= 4;
+	      next_cluster &= 0xFFF;
+	    }
+	  else if (FAT_SUPER->fat_size == 4)
+	    next_cluster &= 0xFFFF;
+	  
+	  if (next_cluster >= FAT_SUPER->clust_eof_marker)
+	    return ret;
+	  if (next_cluster < 2 || next_cluster >= FAT_SUPER->num_clust)
+	    {
+	      errnum = ERR_FSYS_CORRUPT;
+	      return 0;
+	    }
+	  
+	  FAT_SUPER->current_cluster = next_cluster;
+	  FAT_SUPER->current_cluster_num++;
+	}
+      
+      sector = FAT_SUPER->data_offset +
+	((FAT_SUPER->current_cluster - 2) << (FAT_SUPER->clustsize_bits
+ 					      - FAT_SUPER->sectsize_bits));
+      size = (1 << FAT_SUPER->clustsize_bits) - offset;
+      if (size > len)
+	size = len;
+      
+      disk_read_func = disk_read_hook;
+      
+      devread(sector, offset, size, buf);
+      
+      disk_read_func = NULL;
+      
+      len -= size;
+      buf += size;
+      ret += size;
+      filepos += size;
+      logical_clust++;
+      offset = 0;
+    }
+  return errnum ? 0 : ret;
+}
+
+int
+fat_dir (char *dirname)
+{
+  char *rest, ch, dir_buf[FAT_DIRENTRY_LENGTH];
+  char *filename = (char *) NAME_BUF;
+  int attrib = FAT_ATTRIB_DIR;
+#ifndef STAGE1_5
+  int do_possibilities = 0;
+#endif
+  
+  /* XXX I18N:
+   * the positions 2,4,6 etc are high bytes of a 16 bit unicode char 
+   */
+  static unsigned char longdir_pos[] = 
+  { 1, 3, 5, 7, 9, 14, 16, 18, 20, 22, 24, 28, 30 };
+  int slot = -2;
+  int alias_checksum = -1;
+  
+  FAT_SUPER->file_cluster = FAT_SUPER->root_cluster;
+  filepos = 0;
+  FAT_SUPER->current_cluster_num = MAXINT;
+  
+  /* main loop to find desired directory entry */
+ loop:
+  
+  /* if we have a real file (and we're not just printing possibilities),
+     then this is where we want to exit */
+  
+  if (!*dirname || isspace (*dirname))
+    {
+      if (attrib & FAT_ATTRIB_DIR)
+	{
+	  errnum = ERR_BAD_FILETYPE;
+	  return 0;
+	}
+      
+      return 1;
+    }
+  
+  /* continue with the file/directory name interpretation */
+  
+  while (*dirname == '/')
+    dirname++;
+  
+  if (!(attrib & FAT_ATTRIB_DIR))
+    {
+      errnum = ERR_BAD_FILETYPE;
+      return 0;
+    }
+  /* Directories don't have a file size */
+  filemax = MAXINT;
+  
+  for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++);
+  
+  *rest = 0;
+  
+# ifndef STAGE1_5
+  if (print_possibilities && ch != '/')
+    do_possibilities = 1;
+# endif
+  
+  while (1)
+    {
+      if (fat_read (dir_buf, FAT_DIRENTRY_LENGTH) != FAT_DIRENTRY_LENGTH
+	  || dir_buf[0] == 0)
+	{
+	  if (!errnum)
+	    {
+# ifndef STAGE1_5
+	      if (print_possibilities < 0)
+		{
+#if 0
+		  putchar ('\n');
+#endif
+		  return 1;
+		}
+# endif /* STAGE1_5 */
+	      
+	      errnum = ERR_FILE_NOT_FOUND;
+	      *rest = ch;
+	    }
+	  
+	  return 0;
+	}
+      
+      if (FAT_DIRENTRY_ATTRIB (dir_buf) == FAT_ATTRIB_LONGNAME)
+	{
+	  /* This is a long filename.  The filename is build from back
+	   * to front and may span multiple entries.  To bind these
+	   * entries together they all contain the same checksum over
+	   * the short alias.
+	   *
+	   * The id field tells if this is the first entry (the last
+	   * part) of the long filename, and also at which offset this
+	   * belongs.
+	   *
+	   * We just write the part of the long filename this entry
+	   * describes and continue with the next dir entry.
+	   */
+	  int i, offset;
+	  unsigned char id = FAT_LONGDIR_ID(dir_buf);
+	  
+	  if ((id & 0x40)) 
+	    {
+	      id &= 0x3f;
+	      slot = id;
+	      filename[slot * 13] = 0;
+	      alias_checksum = FAT_LONGDIR_ALIASCHECKSUM(dir_buf);
+	    } 
+	  
+	  if (id != slot || slot == 0
+	      || alias_checksum != FAT_LONGDIR_ALIASCHECKSUM(dir_buf))
+	    {
+	      alias_checksum = -1;
+	      continue;
+	    }
+	  
+	  slot--;
+	  offset = slot * 13;
+	  
+	  for (i=0; i < 13; i++)
+	    filename[offset+i] = dir_buf[longdir_pos[i]];
+	  continue;
+	}
+      
+      if (!FAT_DIRENTRY_VALID (dir_buf))
+	continue;
+      
+      if (alias_checksum != -1 && slot == 0)
+	{
+	  int i;
+	  unsigned char sum;
+	  
+	  slot = -2;
+	  for (sum = 0, i = 0; i< 11; i++)
+	    sum = ((sum >> 1) | (sum << 7)) + dir_buf[i];
+	  
+	  if (sum == alias_checksum)
+	    {
+# ifndef STAGE1_5
+	      if (do_possibilities)
+		goto print_filename;
+# endif /* STAGE1_5 */
+	      
+	      if (substring (dirname, filename) == 0)
+		break;
+	    }
+	}
+      
+      /* XXX convert to 8.3 filename format here */
+      {
+	int i, j, c;
+	
+	for (i = 0; i < 8 && (c = filename[i] = tolower (dir_buf[i]))
+	       && !isspace (c); i++);
+	
+	filename[i++] = '.';
+	
+	for (j = 0; j < 3 && (c = filename[i + j] = tolower (dir_buf[8 + j]))
+	       && !isspace (c); j++);
+	
+	if (j == 0)
+	  i--;
+	
+	filename[i + j] = 0;
+      }
+      
+# ifndef STAGE1_5
+      if (do_possibilities)
+	{
+	print_filename:
+	  if (substring (dirname, filename) <= 0)
+	    {
+	      if (print_possibilities > 0)
+		print_possibilities = -print_possibilities;
+	      print_a_completion (filename);
+	    }
+	  continue;
+	}
+# endif /* STAGE1_5 */
+      
+      if (substring (dirname, filename) == 0)
+	break;
+    }
+  
+  *(dirname = rest) = ch;
+  
+  attrib = FAT_DIRENTRY_ATTRIB (dir_buf);
+  filemax = FAT_DIRENTRY_FILELENGTH (dir_buf);
+  filepos = 0;
+  FAT_SUPER->file_cluster = FAT_DIRENTRY_FIRST_CLUSTER (dir_buf);
+  FAT_SUPER->current_cluster_num = MAXINT;
+  
+  /* go back to main loop at top of function */
+  goto loop;
+}
+
+#endif /* FSYS_FAT */
diff --git a/stage2/fsys_ffs.c b/stage2/fsys_ffs.c
new file mode 100644
index 0000000..c8f2801
--- /dev/null
+++ b/stage2/fsys_ffs.c
@@ -0,0 +1,310 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000, 2001  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.
+ */
+
+/*
+ * Elements of this file were originally from the FreeBSD "biosboot"
+ * bootloader file "disk.c" dated 4/12/95.
+ *
+ * The license and header comments from that file are included here.
+ */
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ *	from: Mach, Revision 2.2  92/04/04  11:35:49  rpd
+ *	$Id: fsys_ffs.c,v 1.10 2001/11/12 06:57:29 okuji Exp $
+ */
+
+#ifdef FSYS_FFS
+
+#include "shared.h"
+
+#include "filesys.h"
+
+#include "defs.h"
+#include "disk_inode.h"
+#include "disk_inode_ffs.h"
+#include "dir.h"
+#include "fs.h"
+
+/* used for filesystem map blocks */
+static int mapblock;
+static int mapblock_offset;
+static int mapblock_bsize;
+
+/* pointer to superblock */
+#define SUPERBLOCK ((struct fs *) ( FSYS_BUF + 8192 ))
+#define INODE ((struct icommon *) ( FSYS_BUF + 16384 ))
+#define MAPBUF ( FSYS_BUF + 24576 )
+#define MAPBUF_LEN 8192
+
+
+int
+ffs_mount (void)
+{
+  int retval = 1;
+
+  if ((((current_drive & 0x80) || (current_slice != 0))
+       && ! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_BSDFFS))
+      || part_length < (SBLOCK + (SBSIZE / DEV_BSIZE))
+      || !devread (SBLOCK, 0, SBSIZE, (char *) SUPERBLOCK)
+      || SUPERBLOCK->fs_magic != FS_MAGIC)
+    retval = 0;
+
+  mapblock = -1;
+  mapblock_offset = -1;
+  
+  return retval;
+}
+
+static int
+block_map (int file_block)
+{
+  int bnum, offset, bsize;
+  
+  if (file_block < NDADDR)
+    return (INODE->i_db[file_block]);
+  
+  /* If the blockmap loaded does not include FILE_BLOCK,
+     load a new blockmap.  */
+  if ((bnum = fsbtodb (SUPERBLOCK, INODE->i_ib[0])) != mapblock
+      || (mapblock_offset <= bnum && bnum <= mapblock_offset + mapblock_bsize))
+    {
+      if (MAPBUF_LEN < SUPERBLOCK->fs_bsize)
+	{
+	  offset = ((file_block - NDADDR) % NINDIR (SUPERBLOCK));
+	  bsize = MAPBUF_LEN;
+	  
+	  if (offset + MAPBUF_LEN > SUPERBLOCK->fs_bsize)
+	    offset = (SUPERBLOCK->fs_bsize - MAPBUF_LEN) / sizeof (int);
+	}
+      else
+	{
+	  bsize = SUPERBLOCK->fs_bsize;
+	  offset = 0;
+	}
+      
+      if (! devread (bnum, offset * sizeof (int), bsize, (char *) MAPBUF))
+	{
+	  mapblock = -1;
+	  mapblock_bsize = -1;
+	  mapblock_offset = -1;
+	  errnum = ERR_FSYS_CORRUPT;
+	  return -1;
+	}
+      
+      mapblock = bnum;
+      mapblock_bsize = bsize;
+      mapblock_offset = offset;
+    }
+  
+  return (((int *) MAPBUF)[((file_block - NDADDR) % NINDIR (SUPERBLOCK))
+			  - mapblock_offset]);
+}
+
+
+int
+ffs_read (char *buf, int len)
+{
+  int logno, off, size, map, ret = 0;
+  
+  while (len && !errnum)
+    {
+      off = blkoff (SUPERBLOCK, filepos);
+      logno = lblkno (SUPERBLOCK, filepos);
+      size = blksize (SUPERBLOCK, INODE, logno);
+
+      if ((map = block_map (logno)) < 0)
+	break;
+
+      size -= off;
+
+      if (size > len)
+	size = len;
+
+      disk_read_func = disk_read_hook;
+
+      devread (fsbtodb (SUPERBLOCK, map), off, size, buf);
+
+      disk_read_func = NULL;
+
+      buf += size;
+      len -= size;
+      filepos += size;
+      ret += size;
+    }
+
+  if (errnum)
+    ret = 0;
+
+  return ret;
+}
+
+
+int
+ffs_dir (char *dirname)
+{
+  char *rest, ch;
+  int block, off, loc, map, ino = ROOTINO;
+  struct direct *dp;
+
+/* main loop to find destination inode */
+loop:
+
+  /* load current inode (defaults to the root inode) */
+
+	if (!devread (fsbtodb (SUPERBLOCK, itod (SUPERBLOCK, ino)),
+								ino % (SUPERBLOCK->fs_inopb) * sizeof (struct dinode),
+								sizeof (struct dinode), (char *) INODE))
+			return 0;			/* XXX what return value? */
+
+  /* if we have a real file (and we're not just printing possibilities),
+     then this is where we want to exit */
+
+  if (!*dirname || isspace (*dirname))
+    {
+      if ((INODE->i_mode & IFMT) != IFREG)
+	{
+	  errnum = ERR_BAD_FILETYPE;
+	  return 0;
+	}
+
+      filemax = INODE->i_size;
+
+      /* incomplete implementation requires this! */
+      fsmax = (NDADDR + NINDIR (SUPERBLOCK)) * SUPERBLOCK->fs_bsize;
+      return 1;
+    }
+
+  /* continue with file/directory name interpretation */
+
+  while (*dirname == '/')
+    dirname++;
+
+  if (!(INODE->i_size) || ((INODE->i_mode & IFMT) != IFDIR))
+    {
+      errnum = ERR_BAD_FILETYPE;
+      return 0;
+    }
+
+  for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++);
+
+  *rest = 0;
+  loc = 0;
+
+  /* loop for reading a the entries in a directory */
+
+  do
+    {
+      if (loc >= INODE->i_size)
+	{
+#if 0
+	  putchar ('\n');
+#endif
+
+	  if (print_possibilities < 0)
+	    return 1;
+
+	  errnum = ERR_FILE_NOT_FOUND;
+	  *rest = ch;
+	  return 0;
+	}
+
+      if (!(off = blkoff (SUPERBLOCK, loc)))
+	{
+	  block = lblkno (SUPERBLOCK, loc);
+
+	  if ((map = block_map (block)) < 0
+	      || !devread (fsbtodb (SUPERBLOCK, map), 0,
+			   blksize (SUPERBLOCK, INODE, block),
+			   (char *) FSYS_BUF))
+	    {
+	      errnum = ERR_FSYS_CORRUPT;
+	      *rest = ch;
+	      return 0;
+	    }
+	}
+
+      dp = (struct direct *) (FSYS_BUF + off);
+      loc += dp->d_reclen;
+
+#ifndef STAGE1_5
+      if (dp->d_ino && print_possibilities && ch != '/'
+	  && (!*dirname || substring (dirname, dp->d_name) <= 0))
+	{
+	  if (print_possibilities > 0)
+	    print_possibilities = -print_possibilities;
+
+	  print_a_completion (dp->d_name);
+	}
+#endif /* STAGE1_5 */
+    }
+  while (!dp->d_ino || (substring (dirname, dp->d_name) != 0
+			|| (print_possibilities && ch != '/')));
+
+  /* only get here if we have a matching directory entry */
+
+  ino = dp->d_ino;
+  *(dirname = rest) = ch;
+
+  /* go back to main loop at top of function */
+  goto loop;
+}
+
+int
+ffs_embed (int *start_sector, int needed_sectors)
+{
+  /* XXX: I don't know if this is really correct. Someone who is
+     familiar with BSD should check for this.  */
+  if (needed_sectors > 14)
+    return 0;
+  
+  *start_sector = 1;
+#if 1
+  /* FIXME: Disable the embedding in FFS until someone checks if
+     the code above is correct.  */
+  return 0;
+#else
+  return 1;
+#endif
+}
+
+#endif /* FSYS_FFS */
diff --git a/stage2/fsys_iso9660.c b/stage2/fsys_iso9660.c
new file mode 100644
index 0000000..90e4aa8
--- /dev/null
+++ b/stage2/fsys_iso9660.c
@@ -0,0 +1,442 @@
+/*
+ *  ISO 9660 filesystem backend for GRUB (GRand Unified Bootloader)
+ *  including Rock Ridge Extensions support
+ *
+ *  Copyright (C) 1998, 1999  Kousuke Takai  <tak@kmc.kyoto-u.ac.jp>
+ *
+ *  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.
+ */
+/*
+ *  References:
+ *	linux/fs/isofs/rock.[ch]
+ *	mkisofs-1.11.1/diag/isoinfo.c
+ *	mkisofs-1.11.1/iso9660.h
+ *		(all are written by Eric Youngdale)
+ *
+ *  Modifications by:
+ *	Leonid Lisovskiy   <lly@pisem.net>	2003
+ */
+
+#ifdef FSYS_ISO9660
+
+#include "shared.h"
+#include "filesys.h"
+#include "iso9660.h"
+
+/* iso9660 super-block data in memory */
+struct iso_sb_info {
+  unsigned long vol_sector;
+
+};
+
+/* iso fs inode data in memory */
+struct iso_inode_info {
+  unsigned long file_start;
+};
+
+#define ISO_SUPER	\
+    ((struct iso_sb_info *)(FSYS_BUF))
+#define INODE		\
+    ((struct iso_inode_info *)(FSYS_BUF+sizeof(struct iso_sb_info)))
+#define PRIMDESC        ((struct iso_primary_descriptor *)(FSYS_BUF + 2048))
+#define DIRREC          ((struct iso_directory_record *)(FSYS_BUF + 4096))
+#define RRCONT_BUF      ((unsigned char *)(FSYS_BUF + 6144))
+#define NAME_BUF        ((unsigned char *)(FSYS_BUF + 8192))
+
+
+static inline unsigned long
+log2 (unsigned long word)
+{
+  asm volatile ("bsfl %1,%0"
+		:          "=r" (word)
+		:          "r" (word));
+  return word;
+}
+
+static int
+iso9660_devread (int sector, int byte_offset, int byte_len, char *buf)
+{
+  unsigned short sector_size_lg2 = log2(buf_geom.sector_size);
+
+  /*
+   * We have to use own devread() function since BIOS return wrong geometry
+   */
+  if (sector < 0)
+    {
+      errnum = ERR_OUTSIDE_PART;
+      return 0;
+    }
+  if (byte_len <= 0)
+    return 1;
+
+  sector += (byte_offset >> sector_size_lg2);
+  byte_offset &= (buf_geom.sector_size - 1);
+  asm volatile ("shl%L0 %1,%0"
+		: "=r"(sector)
+		: "Ic"((int8_t)(ISO_SECTOR_BITS - sector_size_lg2)),
+		"0"(sector));
+
+#if !defined(STAGE1_5)
+  if (disk_read_hook && debug)
+    printf ("<%d, %d, %d>", sector, byte_offset, byte_len);
+#endif /* !STAGE1_5 */
+
+  return rawread(current_drive, part_start + sector, byte_offset, byte_len, buf);
+}
+
+int
+iso9660_mount (void)
+{
+  unsigned int sector;
+
+  /*
+   *  Because there is no defined slice type ID for ISO-9660 filesystem,
+   *  this test will pass only either (1) if entire disk is used, or
+   *  (2) if current partition is BSD style sub-partition whose ID is
+   *  ISO-9660.
+   */
+  if ((current_partition != 0xFFFFFF)
+      && !IS_PC_SLICE_TYPE_BSD_WITH_FS(current_slice, FS_ISO9660))
+    return 0;
+
+  /*
+   *  Currently, only FIRST session of MultiSession disks are supported !!!
+   */
+  for (sector = 16 ; sector < 32 ; sector++)
+    {
+      if (!iso9660_devread(sector, 0, sizeof(*PRIMDESC), (char *)PRIMDESC)) 
+	break;
+      /* check ISO_VD_PRIMARY and ISO_STANDARD_ID */
+      if (PRIMDESC->type.l == ISO_VD_PRIMARY
+	  && !memcmp(PRIMDESC->id, ISO_STANDARD_ID, sizeof(PRIMDESC->id)))
+	{
+	  ISO_SUPER->vol_sector = sector;
+	  INODE->file_start = 0;
+	  fsmax = PRIMDESC->volume_space_size.l;
+	  return 1;
+	}
+    }
+
+  return 0;
+}
+
+int
+iso9660_dir (char *dirname)
+{
+  struct iso_directory_record *idr;
+  RR_ptr_t rr_ptr;
+  struct rock_ridge *ce_ptr;
+  unsigned int pathlen;
+  int size;
+  unsigned int extent;
+  unsigned char file_type;
+  unsigned int rr_len;
+  unsigned char rr_flag;
+
+  idr = &PRIMDESC->root_directory_record;
+  INODE->file_start = 0;
+
+  do
+    {
+      while (*dirname == '/')	/* skip leading slashes */
+	dirname++;
+      /* pathlen = strcspn(dirname, "/\n\t "); */
+      for (pathlen = 0 ;
+	   dirname[pathlen]
+	     && !isspace(dirname[pathlen]) && dirname[pathlen] != '/' ;
+	   pathlen++)
+	;
+
+      size = idr->size.l;
+      extent = idr->extent.l;
+
+      while (size > 0)
+	{
+	  if (!iso9660_devread(extent, 0, ISO_SECTOR_SIZE, (char *)DIRREC))
+	    {
+	      errnum = ERR_FSYS_CORRUPT;
+	      return 0;
+	    }
+	  extent++;
+
+	  idr = (struct iso_directory_record *)DIRREC;
+	  for (; idr->length.l > 0;
+	       idr = (struct iso_directory_record *)((char *)idr + idr->length.l) )
+	    {
+	      const char *name = idr->name;
+	      unsigned int name_len = idr->name_len.l;
+
+	      file_type = (idr->flags.l & 2) ? ISO_DIRECTORY : ISO_REGULAR;
+	      if (name_len == 1)
+		{
+		  if ((name[0] == 0) ||	/* self */
+		      (name[0] == 1)) 	/* parent */
+		    continue;
+		}
+	      if (name_len > 2 && CHECK2(name + name_len - 2, ';', '1'))
+		{
+		  name_len -= 2;	/* truncate trailing file version */
+		  if (name_len > 1 && name[name_len - 1] == '.')
+		    name_len--;		/* truncate trailing dot */
+		}
+
+	      /*
+	       *  Parse Rock-Ridge extension
+	       */
+	      rr_len = (idr->length.l - idr->name_len.l
+			- sizeof(struct iso_directory_record)
+			+ sizeof(idr->name));
+	      rr_ptr.ptr = ((unsigned char *)idr + idr->name_len.l
+			    + sizeof(struct iso_directory_record)
+			    - sizeof(idr->name));
+	      if (rr_ptr.i & 1)
+		rr_ptr.i++, rr_len--;
+	      ce_ptr = NULL;
+	      rr_flag = RR_FLAG_NM | RR_FLAG_PX /*| RR_FLAG_SL*/;
+
+	      while (rr_len >= 4)
+		{
+		  if (rr_ptr.rr->version != 1)
+		    {
+#ifndef STAGE1_5
+		      if (debug)
+			printf(
+			       "Non-supported version (%d) RockRidge chunk "
+			       "`%c%c'\n", rr_ptr.rr->version,
+			       rr_ptr.rr->signature & 0xFF,
+			       rr_ptr.rr->signature >> 8);
+#endif
+		    }
+		  else
+		    {
+		      switch (rr_ptr.rr->signature)
+			{
+			case RRMAGIC('R', 'R'):
+			  if ( rr_ptr.rr->len >= (4+sizeof(struct RR)))
+			    rr_flag &= rr_ptr.rr->u.rr.flags.l;
+			  break;
+			case RRMAGIC('N', 'M'):
+			  name = rr_ptr.rr->u.nm.name;
+			  name_len = rr_ptr.rr->len - (4+sizeof(struct NM));
+			  rr_flag &= ~RR_FLAG_NM;
+			  break;
+			case RRMAGIC('P', 'X'):
+			  if (rr_ptr.rr->len >= (4+sizeof(struct PX)))
+			    {
+			      file_type = ((rr_ptr.rr->u.px.mode.l & POSIX_S_IFMT)
+					   == POSIX_S_IFREG
+					   ? ISO_REGULAR
+					   : ((rr_ptr.rr->u.px.mode.l & POSIX_S_IFMT)
+					      == POSIX_S_IFDIR
+					      ? ISO_DIRECTORY : ISO_OTHER));
+			      rr_flag &= ~RR_FLAG_PX;
+			    }
+			  break;
+			case RRMAGIC('C', 'E'):
+			  if (rr_ptr.rr->len >= (4+sizeof(struct CE)))
+			    ce_ptr = rr_ptr.rr;
+			  break;
+#if 0		// RockRidge symlinks are not supported yet
+			case RRMAGIC('S', 'L'):
+			  {
+			    int slen;
+			    unsigned char rootflag, prevflag;
+			    char *rpnt = NAME_BUF+1024;
+			    struct SL_component *slp;
+
+			    slen = rr_ptr.rr->len - (4+1);
+			    slp = &rr_ptr.rr->u.sl.link;
+			    while (slen > 1)
+			      {
+				rootflag = 0;
+				switch (slp->flags.l)
+				  {
+				  case 0:
+				    memcpy(rpnt, slp->text, slp->len);
+				    rpnt += slp->len;
+				    break;
+				  case 4:
+				    *rpnt++ = '.';
+				    /* fallthru */
+				  case 2:
+				    *rpnt++ = '.';
+				    break;
+				  case 8:
+				    rootflag = 1;
+				    *rpnt++ = '/';
+				    break;
+				  default:
+				    printf("Symlink component flag not implemented (%d)\n",
+					   slp->flags.l);
+				    slen = 0;
+				    break;
+				  }
+				slen -= slp->len + 2;
+				prevflag = slp->flags.l;
+				slp = (struct SL_component *) ((char *) slp + slp->len + 2);
+
+				if (slen < 2)
+				  {
+				    /*
+				     * If there is another SL record, and this component
+				     * record isn't continued, then add a slash.
+				     */
+				    if ((!rootflag) && (rr_ptr.rr->u.sl.flags.l & 1) && !(prevflag & 1))
+				      *rpnt++='/';
+				    break;
+				  }
+
+				/*
+				 * If this component record isn't continued, then append a '/'.
+				 */
+				if (!rootflag && !(prevflag & 1))
+				  *rpnt++ = '/';
+			      }
+			    *rpnt++ = '\0';
+			    grub_putstr(NAME_BUF+1024);// debug print!
+			  }
+			  rr_flag &= ~RR_FLAG_SL;
+			  break;
+#endif
+			default:
+			  break;
+			}
+		    }
+		  if (!rr_flag)
+		    /*
+		     * There is no more extension we expects...
+		     */
+		    break;
+
+		  rr_len -= rr_ptr.rr->len;
+		  rr_ptr.ptr += rr_ptr.rr->len;
+		  if (rr_len < 4 && ce_ptr != NULL)
+		    {
+		      /* preserve name before loading new extent. */
+		      if( RRCONT_BUF <= (unsigned char *)name
+			  && (unsigned char *)name < RRCONT_BUF + ISO_SECTOR_SIZE )
+			{
+			  memcpy(NAME_BUF, name, name_len);
+			  name = NAME_BUF;
+			}
+		      rr_ptr.ptr = RRCONT_BUF + ce_ptr->u.ce.offset.l;
+		      rr_len = ce_ptr->u.ce.size.l;
+		      if (!iso9660_devread(ce_ptr->u.ce.extent.l, 0, ISO_SECTOR_SIZE, RRCONT_BUF))
+			{
+			  errnum = 0;	/* this is not fatal. */
+			  break;
+			}
+		      ce_ptr = NULL;
+		    }
+		} /* rr_len >= 4 */
+
+	      filemax = MAXINT;
+	      if (name_len >= pathlen
+		  && !memcmp(name, dirname, pathlen))
+		{
+		  if (dirname[pathlen] == '/' || !print_possibilities)
+		    {
+		      /*
+		       *  DIRNAME is directory component of pathname,
+		       *  or we are to open a file.
+		       */
+		      if (pathlen == name_len)
+			{
+			  if (dirname[pathlen] == '/')
+			    {
+			      if (file_type != ISO_DIRECTORY)
+				{
+				  errnum = ERR_BAD_FILETYPE;
+				  return 0;
+				}
+			      goto next_dir_level;
+			    }
+			  if (file_type != ISO_REGULAR)
+			    {
+			      errnum = ERR_BAD_FILETYPE;
+			      return 0;
+			    }
+			  INODE->file_start = idr->extent.l;
+			  filepos = 0;
+			  filemax = idr->size.l;
+			  return 1;
+			}
+		    }
+		  else	/* Completion */
+		    {
+#ifndef STAGE1_5
+		      if (print_possibilities > 0)
+			print_possibilities = -print_possibilities;
+		      memcpy(NAME_BUF, name, name_len);
+		      NAME_BUF[name_len] = '\0';
+		      print_a_completion (NAME_BUF);
+#endif
+		    }
+		}
+	    } /* for */
+
+	  size -= ISO_SECTOR_SIZE;
+	} /* size>0 */
+
+      if (dirname[pathlen] == '/' || print_possibilities >= 0)
+	{
+	  errnum = ERR_FILE_NOT_FOUND;
+	  return 0;
+	}
+
+    next_dir_level:
+      dirname += pathlen;
+
+    } while (*dirname == '/');
+
+  return 1;
+}
+
+int
+iso9660_read (char *buf, int len)
+{
+  int sector, blkoffset, size, ret;
+
+  if (INODE->file_start == 0)
+    return 0;
+
+  ret = 0;
+  blkoffset = filepos & (ISO_SECTOR_SIZE - 1);
+  sector = filepos >> ISO_SECTOR_BITS;
+  while (len > 0)
+    {
+      size = ISO_SECTOR_SIZE - blkoffset;
+      if (size > len)
+        size = len;
+
+      disk_read_func = disk_read_hook;
+
+      if (!iso9660_devread(INODE->file_start + sector, blkoffset, size, buf))
+	return 0;
+
+      disk_read_func = NULL;
+
+      len -= size;
+      buf += size;
+      ret += size;
+      filepos += size;
+      sector++;
+      blkoffset = 0;
+    }
+
+  return ret;
+}
+
+#endif /* FSYS_ISO9660 */
diff --git a/stage2/fsys_jfs.c b/stage2/fsys_jfs.c
new file mode 100644
index 0000000..307f836
--- /dev/null
+++ b/stage2/fsys_jfs.c
@@ -0,0 +1,403 @@
+/* fsys_jfs.c - an implementation for the IBM JFS file system */
+/*  
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2001,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.
+ */
+
+#ifdef FSYS_JFS
+
+#include "shared.h"
+#include "filesys.h"
+#include "jfs.h"
+
+#define MAX_LINK_COUNT	8
+
+#define DTTYPE_INLINE	0
+#define DTTYPE_PAGE	1
+
+struct jfs_info
+{
+	int bsize;
+	int l2bsize;
+	int bdlog;
+	int xindex;
+	int xlastindex;
+	int sindex;
+	int slastindex;
+	int de_index;
+	int dttype;
+	xad_t *xad;
+	ldtentry_t *de;
+};
+
+static struct jfs_info jfs;
+
+#define xtpage		((xtpage_t *)FSYS_BUF)
+#define dtpage		((dtpage_t *)((char *)FSYS_BUF + 4096))
+#define fileset		((dinode_t *)((char *)FSYS_BUF + 8192))
+#define inode		((dinode_t *)((char *)FSYS_BUF + 8192 + sizeof(dinode_t)))
+#define dtroot		((dtroot_t *)(&inode->di_btroot))
+
+static ldtentry_t de_always[2] = {
+	{1, -1, 2, {'.', '.'}},
+	{1, -1, 1, {'.'}}
+};
+
+static int
+isinxt (s64 key, s64 offset, s64 len)
+{
+	return (key >= offset) ? (key < offset + len ? 1 : 0) : 0;
+}
+
+static xad_t *
+first_extent (dinode_t *di)
+{
+	xtpage_t *xtp;
+
+	jfs.xindex = 2;
+	xtp = (xtpage_t *)&di->di_btroot;
+	jfs.xad = &xtp->xad[2];
+	if (xtp->header.flag & BT_LEAF) {
+	    	jfs.xlastindex = xtp->header.nextindex;
+	} else {
+		do {
+			devread (addressXAD (jfs.xad) << jfs.bdlog, 0,
+				 sizeof(xtpage_t), (char *)xtpage);
+			jfs.xad = &xtpage->xad[2];
+		} while (!(xtpage->header.flag & BT_LEAF));
+		jfs.xlastindex = xtpage->header.nextindex;
+	}
+
+	return jfs.xad;
+}
+
+static xad_t *
+next_extent (void)
+{
+	if (++jfs.xindex < jfs.xlastindex) {
+	} else if (xtpage->header.next) {
+		devread (xtpage->header.next << jfs.bdlog, 0,
+			 sizeof(xtpage_t), (char *)xtpage);
+		jfs.xlastindex = xtpage->header.nextindex;
+		jfs.xindex = XTENTRYSTART;
+		jfs.xad = &xtpage->xad[XTENTRYSTART];
+	} else {
+		return NULL;
+	}
+	return ++jfs.xad;
+}
+
+
+static void
+di_read (u32 inum, dinode_t *di)
+{
+	s64 key;
+	u32 xd, ioffset;
+	s64 offset;
+	xad_t *xad;
+	pxd_t pxd;
+
+	key = (((inum >> L2INOSPERIAG) << L2INOSPERIAG) + 4096) >> jfs.l2bsize;
+	xd = (inum & (INOSPERIAG - 1)) >> L2INOSPEREXT;
+	ioffset = ((inum & (INOSPERIAG - 1)) & (INOSPEREXT - 1)) << L2DISIZE;
+	xad = first_extent (fileset);
+	do {
+		offset = offsetXAD (xad);
+		if (isinxt (key, offset, lengthXAD (xad))) {
+			devread ((addressXAD (xad) + key - offset) << jfs.bdlog,
+				 3072 + xd*sizeof(pxd_t), sizeof(pxd_t), (char *)&pxd);
+			devread (addressPXD (&pxd) << jfs.bdlog,
+				 ioffset, DISIZE, (char *)di);
+			break;
+		}
+	} while ((xad = next_extent ()));
+}
+
+static ldtentry_t *
+next_dentry (void)
+{
+	ldtentry_t *de;
+	s8 *stbl;
+
+	if (jfs.dttype == DTTYPE_INLINE) {
+		if (jfs.sindex < jfs.slastindex) {
+			return (ldtentry_t *)&dtroot->slot[(int)dtroot->header.stbl[jfs.sindex++]];
+		}
+	} else {
+		de = (ldtentry_t *)dtpage->slot;
+		stbl = (s8 *)&de[(int)dtpage->header.stblindex];
+		if (jfs.sindex < jfs.slastindex) {
+			return &de[(int)stbl[jfs.sindex++]];
+		} else if (dtpage->header.next) {
+			devread (dtpage->header.next << jfs.bdlog, 0,
+				 sizeof(dtpage_t), (char *)dtpage);
+			jfs.slastindex = dtpage->header.nextindex;
+			jfs.sindex = 1;
+			return &de[(int)((s8 *)&de[(int)dtpage->header.stblindex])[0]];
+		}
+	}
+
+	return (jfs.de_index < 2) ? &de_always[jfs.de_index++] : NULL;
+}
+
+static ldtentry_t *
+first_dentry (void)
+{
+	dtroot_t *dtr;
+	pxd_t *xd;
+	idtentry_t *de;
+
+	dtr = (dtroot_t *)&inode->di_btroot;
+	jfs.sindex = 0;
+	jfs.de_index = 0;
+
+	de_always[0].inumber = inode->di_parent;
+	de_always[1].inumber = inode->di_number;
+	if (dtr->header.flag & BT_LEAF) {
+		jfs.dttype = DTTYPE_INLINE;
+		jfs.slastindex = dtr->header.nextindex;
+	} else {
+		de = (idtentry_t *)dtpage->slot;
+		jfs.dttype = DTTYPE_PAGE;
+		xd = &((idtentry_t *)dtr->slot)[(int)dtr->header.stbl[0]].xd;
+		for (;;) {
+			devread (addressPXD (xd) << jfs.bdlog, 0,
+				 sizeof(dtpage_t), (char *)dtpage);
+			if (dtpage->header.flag & BT_LEAF)
+				break;
+			xd = &de[(int)((s8 *)&de[(int)dtpage->header.stblindex])[0]].xd;
+		}
+		jfs.slastindex = dtpage->header.nextindex;
+	}
+
+	return next_dentry ();
+}
+
+
+static dtslot_t *
+next_dslot (int next)
+{
+	return (jfs.dttype == DTTYPE_INLINE)
+		? (dtslot_t *)&dtroot->slot[next]
+		: &((dtslot_t *)dtpage->slot)[next];
+}
+
+static void
+uni2ansi (UniChar *uni, char *ansi, int len)
+{
+	for (; len; len--, uni++)
+		*ansi++ = (*uni & 0xff80) ? '?' : *(char *)uni;
+}
+
+int
+jfs_mount (void)
+{
+	struct jfs_superblock super;
+
+	if (part_length < MINJFS >> SECTOR_BITS
+	    || !devread (SUPER1_OFF >> SECTOR_BITS, 0,
+			 sizeof(struct jfs_superblock), (char *)&super)
+	    || (super.s_magic != JFS_MAGIC)
+	    || !devread ((AITBL_OFF >> SECTOR_BITS) + FILESYSTEM_I,
+			 0, DISIZE, (char*)fileset)) {
+		return 0;
+	}
+
+	jfs.bsize = super.s_bsize;
+	jfs.l2bsize = super.s_l2bsize;
+	jfs.bdlog = jfs.l2bsize - SECTOR_BITS;
+
+	return 1;
+}
+
+int
+jfs_read (char *buf, int len)
+{
+	xad_t *xad;
+	s64 endofprev, endofcur;
+	s64 offset, xadlen;
+	int toread, startpos, endpos;
+
+	startpos = filepos;
+	endpos = filepos + len;
+	endofprev = (1ULL << 62) - 1;
+	xad = first_extent (inode);
+	do {
+		offset = offsetXAD (xad);
+		xadlen = lengthXAD (xad);
+		if (isinxt (filepos >> jfs.l2bsize, offset, xadlen)) {
+			endofcur = (offset + xadlen) << jfs.l2bsize; 
+			toread = (endofcur >= endpos)
+				  ? len : (endofcur - filepos);
+
+			disk_read_func = disk_read_hook;
+			devread (addressXAD (xad) << jfs.bdlog,
+				 filepos - (offset << jfs.l2bsize), toread, buf);
+			disk_read_func = NULL;
+
+			buf += toread;
+			len -= toread;
+			filepos += toread;
+		} else if (offset > endofprev) {
+			toread = ((offset << jfs.l2bsize) >= endpos)
+				  ? len : ((offset - endofprev) << jfs.l2bsize);
+			len -= toread;
+			filepos += toread;
+			for (; toread; toread--) {
+				*buf++ = 0;
+			}
+			continue;
+		}
+		endofprev = offset + xadlen; 
+		xad = next_extent ();
+	} while (len > 0 && xad);
+
+	return filepos - startpos;
+}
+
+int
+jfs_dir (char *dirname)
+{
+	char *ptr, *rest, ch;
+	ldtentry_t *de;
+	dtslot_t *ds;
+	u32 inum, parent_inum;
+	s64 di_size;
+	u32 di_mode;
+	int namlen, cmp, n, link_count;
+	char namebuf[JFS_NAME_MAX + 1], linkbuf[JFS_PATH_MAX];
+
+	parent_inum = inum = ROOT_I;
+	link_count = 0;
+	for (;;) {
+		di_read (inum, inode);
+		di_size = inode->di_size;
+		di_mode = inode->di_mode;
+
+		if ((di_mode & IFMT) == IFLNK) {
+			if (++link_count > MAX_LINK_COUNT) {
+				errnum = ERR_SYMLINK_LOOP;
+				return 0;
+			}
+			if (di_size < (di_mode & INLINEEA ? 256 : 128)) {
+				grub_memmove (linkbuf, inode->di_fastsymlink, di_size);
+				n = di_size;
+			} else if (di_size < JFS_PATH_MAX - 1) {
+				filepos = 0;
+				filemax = di_size;
+				n = jfs_read (linkbuf, filemax);
+			} else {
+				errnum = ERR_FILELENGTH;
+				return 0;
+			}
+
+			inum = (linkbuf[0] == '/') ? ROOT_I : parent_inum;
+			while (n < (JFS_PATH_MAX - 1) && (linkbuf[n++] = *dirname++));
+			linkbuf[n] = 0;
+			dirname = linkbuf;
+			continue;
+		}
+
+		if (!*dirname || isspace (*dirname)) {
+			if ((di_mode & IFMT) != IFREG) {
+				errnum = ERR_BAD_FILETYPE;
+				return 0;
+			}
+			filepos = 0;
+			filemax = di_size;
+			return 1;
+		}
+
+		if ((di_mode & IFMT) != IFDIR) {
+			errnum = ERR_BAD_FILETYPE;
+			return 0;
+		}
+
+		for (; *dirname == '/'; dirname++);
+
+		for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++);
+		*rest = 0;
+
+		de = first_dentry ();
+		for (;;) {
+			namlen = de->namlen;
+			if (de->next == -1) {
+				uni2ansi (de->name, namebuf, namlen);
+				namebuf[namlen] = 0;
+			} else {
+				uni2ansi (de->name, namebuf, DTLHDRDATALEN);
+				ptr = namebuf;
+				ptr += DTLHDRDATALEN;
+				namlen -= DTLHDRDATALEN;
+				ds = next_dslot (de->next);
+				while (ds->next != -1) {
+					uni2ansi (ds->name, ptr, DTSLOTDATALEN);
+					ptr += DTSLOTDATALEN;
+					namlen -= DTSLOTDATALEN;
+					ds = next_dslot (ds->next);
+				}
+				uni2ansi (ds->name, ptr, namlen);
+				ptr += namlen;
+				*ptr = 0;
+			}
+
+			cmp = (!*dirname) ? -1 : substring (dirname, namebuf);
+#ifndef STAGE1_5
+			if (print_possibilities && ch != '/'
+			    && cmp <= 0) {
+				if (print_possibilities > 0)
+					print_possibilities = -print_possibilities;
+				print_a_completion (namebuf);
+			} else
+#endif
+			if (cmp == 0) {
+				parent_inum = inum;
+				inum = de->inumber;
+		        	*(dirname = rest) = ch;
+				break;
+			}
+			de = next_dentry ();
+			if (de == NULL) {
+				if (print_possibilities < 0)
+					return 1;
+
+				errnum = ERR_FILE_NOT_FOUND;
+				*rest = ch;
+				return 0;
+			}
+		}
+	}
+}
+
+int
+jfs_embed (int *start_sector, int needed_sectors)
+{
+	struct jfs_superblock super;
+
+	if (needed_sectors > 63
+	    || !devread (SUPER1_OFF >> SECTOR_BITS, 0,
+			 sizeof (struct jfs_superblock),
+			 (char *)&super)
+	    || (super.s_magic != JFS_MAGIC)) {
+		return 0;
+	}
+
+	*start_sector = 1;
+	return 1;
+}
+
+#endif /* FSYS_JFS */
diff --git a/stage2/fsys_minix.c b/stage2/fsys_minix.c
new file mode 100644
index 0000000..5c76796
--- /dev/null
+++ b/stage2/fsys_minix.c
@@ -0,0 +1,534 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,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.
+ */
+
+/* Restrictions:
+   This is MINIX V1 only (yet)
+   Disk creation is like:
+   mkfs.minix -c DEVICE 
+*/
+
+#ifdef FSYS_MINIX
+
+#include "shared.h"
+#include "filesys.h"
+
+/* #define DEBUG_MINIX */
+
+/* indirect blocks */
+static int mapblock1, mapblock2, namelen;
+
+/* sizes are always in bytes, BLOCK values are always in DEV_BSIZE (sectors) */
+#define DEV_BSIZE 512
+
+/* include/linux/fs.h */
+#define BLOCK_SIZE_BITS 10
+#define BLOCK_SIZE 	(1<<BLOCK_SIZE_BITS)
+
+/* made up, defaults to 1 but can be passed via mount_opts */
+#define WHICH_SUPER 1
+/* kind of from fs/ext2/super.c (is OK for minix) */
+#define SBLOCK (WHICH_SUPER * BLOCK_SIZE / DEV_BSIZE)	/* = 2 */
+
+/* include/asm-i386/type.h */
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+
+/* include/linux/minix_fs.h */
+#define MINIX_ROOT_INO 1
+
+/* Not the same as the bogus LINK_MAX in <linux/limits.h>. Oh well. */
+#define MINIX_LINK_MAX  250
+#define MINIX2_LINK_MAX 65530
+
+#define MINIX_I_MAP_SLOTS       8
+#define MINIX_Z_MAP_SLOTS       64
+#define MINIX_SUPER_MAGIC       0x137F          /* original minix fs */
+#define MINIX_SUPER_MAGIC2      0x138F          /* minix fs, 30 char names */
+#define MINIX2_SUPER_MAGIC      0x2468          /* minix V2 fs */
+#define MINIX2_SUPER_MAGIC2     0x2478          /* minix V2 fs, 30 char names */
+#define MINIX_VALID_FS          0x0001          /* Clean fs. */
+#define MINIX_ERROR_FS          0x0002          /* fs has errors. */
+
+#define MINIX_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix_inode)))
+#define MINIX2_INODES_PER_BLOCK ((BLOCK_SIZE)/(sizeof (struct minix2_inode)))
+
+#define MINIX_V1                0x0001          /* original minix fs */
+#define MINIX_V2                0x0002          /* minix V2 fs */
+
+/* originally this is : 
+#define INODE_VERSION(inode)    inode->i_sb->u.minix_sb.s_version
+   here we have */
+#define INODE_VERSION(inode)	(SUPERBLOCK->s_version)
+
+/*
+ * This is the original minix inode layout on disk.
+ * Note the 8-bit gid and atime and ctime.
+ */
+struct minix_inode {
+	__u16 i_mode;
+	__u16 i_uid;
+	__u32 i_size;
+	__u32 i_time;
+	__u8  i_gid;
+	__u8  i_nlinks;
+	__u16 i_zone[9];
+};
+
+/*
+ * The new minix inode has all the time entries, as well as
+ * long block numbers and a third indirect block (7+1+1+1
+ * instead of 7+1+1). Also, some previously 8-bit values are
+ * now 16-bit. The inode is now 64 bytes instead of 32.
+ */
+struct minix2_inode {
+	__u16 i_mode;
+	__u16 i_nlinks;
+	__u16 i_uid;
+	__u16 i_gid;
+	__u32 i_size;
+	__u32 i_atime;
+	__u32 i_mtime;
+	__u32 i_ctime;
+	__u32 i_zone[10];
+};
+
+/*
+ * minix super-block data on disk
+ */
+struct minix_super_block {
+        __u16 s_ninodes;
+        __u16 s_nzones;
+        __u16 s_imap_blocks;
+        __u16 s_zmap_blocks;
+        __u16 s_firstdatazone;
+        __u16 s_log_zone_size;
+        __u32 s_max_size;
+        __u16 s_magic;
+        __u16 s_state;
+        __u32 s_zones;
+};
+
+struct minix_dir_entry {
+        __u16 inode;
+        char name[0];
+};
+
+/* made up, these are pointers into FSYS_BUF */
+/* read once, always stays there: */
+#define SUPERBLOCK \
+    ((struct minix_super_block *)(FSYS_BUF))
+#define INODE \
+    ((struct minix_inode *)((int) SUPERBLOCK + BLOCK_SIZE))
+#define DATABLOCK1 \
+    ((int)((int)INODE + sizeof(struct minix_inode)))
+#define DATABLOCK2 \
+    ((int)((int)DATABLOCK1 + BLOCK_SIZE))
+
+/* linux/stat.h */
+#define S_IFMT  00170000
+#define S_IFLNK  0120000
+#define S_IFREG  0100000
+#define S_IFDIR  0040000
+#define S_ISLNK(m)	(((m) & S_IFMT) == S_IFLNK)
+#define S_ISREG(m)      (((m) & S_IFMT) == S_IFREG)
+#define S_ISDIR(m)      (((m) & S_IFMT) == S_IFDIR)
+
+#define PATH_MAX                1024	/* include/linux/limits.h */
+#define MAX_LINK_COUNT             5	/* number of symbolic links to follow */
+
+/* check filesystem types and read superblock into memory buffer */
+int
+minix_mount (void)
+{
+  if (((current_drive & 0x80) || current_slice != 0)
+      && ! IS_PC_SLICE_TYPE_MINIX (current_slice)
+      && ! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_OTHER))
+    return 0;			/* The partition is not of MINIX type */
+  
+  if (part_length < (SBLOCK +
+		     (sizeof (struct minix_super_block) / DEV_BSIZE)))
+    return 0;			/* The partition is too short */
+  
+  if (!devread (SBLOCK, 0, sizeof (struct minix_super_block),
+		(char *) SUPERBLOCK))
+    return 0;			/* Cannot read superblock */
+  
+  switch (SUPERBLOCK->s_magic)
+    {
+    case MINIX_SUPER_MAGIC:
+      namelen = 14;
+      break;
+    case MINIX_SUPER_MAGIC2:
+      namelen = 30;
+      break;
+    default:
+      return 0;			/* Unsupported type */
+    }
+
+  return 1;
+}
+
+/* Takes a file system block number and reads it into BUFFER. */
+static int
+minix_rdfsb (int fsblock, int buffer)
+{
+  return devread (fsblock * (BLOCK_SIZE / DEV_BSIZE), 0,
+		  BLOCK_SIZE, (char *) buffer);
+}
+
+/* Maps LOGICAL_BLOCK (the file offset divided by the blocksize) into
+   a physical block (the location in the file system) via an inode. */
+static int
+minix_block_map (int logical_block)
+{
+  int i;
+
+  if (logical_block < 7)
+    return INODE->i_zone[logical_block];
+
+  logical_block -= 7;
+  if (logical_block < 512)
+    {
+      i = INODE->i_zone[7];
+      
+      if (!i || ((mapblock1 != 1)
+		 && !minix_rdfsb (i, DATABLOCK1)))
+	{
+	  errnum = ERR_FSYS_CORRUPT;
+	  return -1;
+	}
+      mapblock1 = 1;
+      return ((__u16 *) DATABLOCK1) [logical_block];
+    }
+
+  logical_block -= 512;
+  i = INODE->i_zone[8];
+  if (!i || ((mapblock1 != 2)
+	     && !minix_rdfsb (i, DATABLOCK1)))
+    {
+      errnum = ERR_FSYS_CORRUPT;
+      return -1;
+    }
+  mapblock1 = 2;
+  i = ((__u16 *) DATABLOCK1)[logical_block >> 9];
+  if (!i || ((mapblock2 != i)
+	     && !minix_rdfsb (i, DATABLOCK2)))
+    {
+      errnum = ERR_FSYS_CORRUPT;
+      return -1;
+    }
+  mapblock2 = i;
+  return ((__u16 *) DATABLOCK2)[logical_block & 511];
+}
+
+/* read from INODE into BUF */
+int
+minix_read (char *buf, int len)
+{
+  int logical_block;
+  int offset;
+  int map;
+  int ret = 0;
+  int size = 0;
+
+  while (len > 0)
+    {
+      /* find the (logical) block component of our location */
+      logical_block = filepos >> BLOCK_SIZE_BITS;
+      offset = filepos & (BLOCK_SIZE - 1);
+      map = minix_block_map (logical_block);
+#ifdef DEBUG_MINIX
+      printf ("map=%d\n", map);
+#endif
+      if (map < 0)
+	break;
+
+      size = BLOCK_SIZE;
+      size -= offset;
+      if (size > len)
+	size = len;
+
+      disk_read_func = disk_read_hook;
+
+      devread (map * (BLOCK_SIZE / DEV_BSIZE),
+	       offset, size, buf);
+
+      disk_read_func = NULL;
+
+      buf += size;
+      len -= size;
+      filepos += size;
+      ret += size;
+    }
+
+  if (errnum)
+    ret = 0;
+
+  return ret;
+}
+
+/* preconditions: minix_mount already executed, therefore supblk in buffer
+     known as SUPERBLOCK
+   returns: 0 if error, nonzero iff we were able to find the file successfully
+   postconditions: on a nonzero return, buffer known as INODE contains the
+     inode of the file we were trying to look up
+   side effects: none yet  */
+int
+minix_dir (char *dirname)
+{
+  int current_ino = MINIX_ROOT_INO;  /* start at the root */
+  int updir_ino = current_ino;	     /* the parent of the current directory */
+  int ino_blk;			     /* fs pointer of the inode's info */
+
+  int str_chk = 0;		     /* used ot hold the results of a string
+				        compare */
+
+  struct minix_inode * raw_inode;    /* inode info for current_ino */
+
+  char linkbuf[PATH_MAX];	     /* buffer for following sym-links */
+  int link_count = 0;
+
+  char * rest;
+  char ch;
+
+  int off;			     /* offset within block of directory 
+					entry */
+  int loc;			     /* location within a directory */
+  int blk;			     /* which data blk within dir entry */
+  long map;			     /* fs pointer of a particular block from
+					dir entry */
+  struct minix_dir_entry * dp;	     /* pointer to directory entry */
+
+  /* loop invariants:
+     current_ino = inode to lookup
+     dirname = pointer to filename component we are cur looking up within
+     the directory known pointed to by current_ino (if any) */
+
+#ifdef DEBUG_MINIX
+  printf ("\n");
+#endif  
+
+  while (1)
+    {
+#ifdef DEBUG_MINIX
+      printf ("inode %d, dirname %s\n", current_ino, dirname);
+#endif
+
+      ino_blk = (2 + SUPERBLOCK->s_imap_blocks + SUPERBLOCK->s_zmap_blocks
+		 + (current_ino - 1) / MINIX_INODES_PER_BLOCK);
+      if (! minix_rdfsb (ino_blk, (int) INODE))
+	return 0;
+
+      /* reset indirect blocks! */
+      mapblock2 = mapblock1 = -1;
+
+      raw_inode = INODE + ((current_ino - 1) % MINIX_INODES_PER_BLOCK);
+
+      /* copy inode to fixed location */
+      memmove ((void *) INODE, (void *) raw_inode, 
+	       sizeof (struct minix_inode));
+
+      /* If we've got a symbolic link, then chase it. */
+      if (S_ISLNK (INODE->i_mode))
+	{
+	  int len;
+
+	  if (++link_count > MAX_LINK_COUNT)
+	    {
+	      errnum = ERR_SYMLINK_LOOP;
+	      return 0;
+	    }
+#ifdef DEBUG_MINIX
+	  printf ("S_ISLNK (%s)\n", dirname);
+#endif
+
+	  /* Find out how long our remaining name is. */
+	  len = 0;
+	  while (dirname[len] && !isspace (dirname[len]))
+	    len++;
+
+	  /* Get the symlink size. */
+	  filemax = (INODE->i_size);
+	  if (filemax + len > sizeof (linkbuf) - 2)
+	    {
+	      errnum = ERR_FILELENGTH;
+	      return 0;
+	    }
+
+	  if (len)
+	    {
+	      /* Copy the remaining name to the end of the symlink data.
+	         Note that DIRNAME and LINKBUF may overlap! */
+	      memmove (linkbuf + filemax, dirname, len);
+	    }
+	  linkbuf[filemax + len] = '\0';
+
+	  /* Read the necessary blocks, and reset the file pointer. */
+	  len = grub_read (linkbuf, filemax);
+	  filepos = 0;
+	  if (!len)
+	    return 0;
+
+#ifdef DEBUG_MINIX
+	  printf ("symlink=%s\n", linkbuf);
+#endif
+
+	  dirname = linkbuf;
+	  if (*dirname == '/')
+	    {
+	      /* It's an absolute link, so look it up in root. */
+	      current_ino = MINIX_ROOT_INO;
+	      updir_ino = current_ino;
+	    }
+	  else
+	    {
+	      /* Relative, so look it up in our parent directory. */
+	      current_ino = updir_ino;
+	    }
+
+	  /* Try again using the new name. */
+	  continue;
+	}
+
+      /* If end of filename, INODE points to the file's inode */
+      if (!*dirname || isspace (*dirname))
+	{
+	  if (!S_ISREG (INODE->i_mode))
+	    {
+	      errnum = ERR_BAD_FILETYPE;
+	      return 0;
+	    }
+
+	  filemax = (INODE->i_size);
+	  return 1;
+	}
+
+      /* else we have to traverse a directory */
+      updir_ino = current_ino;
+
+      /* skip over slashes */
+      while (*dirname == '/')
+	dirname++;
+
+      /* if this isn't a directory of sufficient size to hold our file, 
+	 abort */
+      if (!(INODE->i_size) || !S_ISDIR (INODE->i_mode))
+	{
+	  errnum = ERR_BAD_FILETYPE;
+	  return 0;
+	}
+
+      /* skip to next slash or end of filename (space) */
+      for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/';
+	   rest++);
+
+      /* look through this directory and find the next filename component */
+      /* invariant: rest points to slash after the next filename component */
+      *rest = 0;
+      loc = 0;
+
+      do
+	{
+#ifdef DEBUG_MINIX
+	  printf ("dirname=`%s', rest=`%s', loc=%d\n", dirname, rest, loc);
+#endif
+
+	  /* if our location/byte offset into the directory exceeds the size,
+	     give up */
+	  if (loc >= INODE->i_size)
+	    {
+	      if (print_possibilities < 0)
+		{
+#if 0
+		  putchar ('\n');
+#endif
+		}
+	      else
+		{
+		  errnum = ERR_FILE_NOT_FOUND;
+		  *rest = ch;
+		}
+	      return (print_possibilities < 0);
+	    }
+
+	  /* else, find the (logical) block component of our location */
+	  blk = loc >> BLOCK_SIZE_BITS;
+
+	  /* we know which logical block of the directory entry we are looking
+	     for, now we have to translate that to the physical (fs) block on
+	     the disk */
+	  map = minix_block_map (blk);
+#ifdef DEBUG_MINIX
+	  printf ("fs block=%d\n", map);
+#endif
+	  mapblock2 = -1;
+	  if ((map < 0) || !minix_rdfsb (map, DATABLOCK2))
+	    {
+	      errnum = ERR_FSYS_CORRUPT;
+	      *rest = ch;
+	      return 0;
+	    }
+	  off = loc & (BLOCK_SIZE - 1);
+	  dp = (struct minix_dir_entry *) (DATABLOCK2 + off);
+	  /* advance loc prematurely to next on-disk directory entry  */
+	  loc += sizeof (dp->inode) + namelen;
+
+	  /* NOTE: minix filenames are NULL terminated if < NAMELEN
+	     else exact */
+
+#ifdef DEBUG_MINIX
+	  printf ("directory entry ino=%d\n", dp->inode);
+	  if (dp->inode)
+	    printf ("entry=%s\n", dp->name);
+#endif
+
+	  if (dp->inode)
+	    {
+	      int saved_c = dp->name[namelen];
+
+	      dp->name[namelen] = 0;
+	      str_chk = substring (dirname, dp->name);
+
+# ifndef STAGE1_5
+	      if (print_possibilities && ch != '/'
+		  && (!*dirname || str_chk <= 0))
+		{
+		  if (print_possibilities > 0)
+		    print_possibilities = -print_possibilities;
+		  print_a_completion (dp->name);
+		}
+# endif
+
+	      dp->name[namelen] = saved_c;
+	    }
+
+	}
+      while (!dp->inode || (str_chk || (print_possibilities && ch != '/')));
+
+      current_ino = dp->inode;
+      *(dirname = rest) = ch;
+    }
+  /* never get here */
+}
+
+#endif /* FSYS_MINIX */
diff --git a/stage2/fsys_reiserfs.c b/stage2/fsys_reiserfs.c
new file mode 100644
index 0000000..93ec5f8
--- /dev/null
+++ b/stage2/fsys_reiserfs.c
@@ -0,0 +1,1238 @@
+/* fsys_reiserfs.c - an implementation for the ReiserFS filesystem */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000, 2001  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.
+ */
+
+#ifdef FSYS_REISERFS
+#include "shared.h"
+#include "filesys.h"
+
+#undef REISERDEBUG
+
+/* Some parts of this code (mainly the structures and defines) are
+ * from the original reiser fs code, as found in the linux kernel.
+ */
+
+/* include/asm-i386/types.h */
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+typedef __signed__ int __s32;
+typedef unsigned int __u32;
+typedef unsigned long long __u64;
+
+/* linux/posix_type.h */
+typedef long linux_off_t;
+
+/* linux/little_endian.h */
+#define __cpu_to_le64(x) ((__u64) (x))
+#define __le64_to_cpu(x) ((__u64) (x))
+#define __cpu_to_le32(x) ((__u32) (x))
+#define __le32_to_cpu(x) ((__u32) (x))
+#define __cpu_to_le16(x) ((__u16) (x))
+#define __le16_to_cpu(x) ((__u16) (x))
+
+/* include/linux/reiser_fs.h */
+/* This is the new super block of a journaling reiserfs system */
+struct reiserfs_super_block
+{
+  __u32 s_block_count;			/* blocks count         */
+  __u32 s_free_blocks;                  /* free blocks count    */
+  __u32 s_root_block;           	/* root block number    */
+  __u32 s_journal_block;           	/* journal block number    */
+  __u32 s_journal_dev;           	/* journal device number  */
+  __u32 s_journal_size; 		/* size of the journal on FS creation.  used to make sure they don't overflow it */
+  __u32 s_journal_trans_max;            /* max number of blocks in a transaction.  */
+  __u32 s_journal_magic;                /* random value made on fs creation */
+  __u32 s_journal_max_batch;            /* max number of blocks to batch into a trans */
+  __u32 s_journal_max_commit_age;       /* in seconds, how old can an async commit be */
+  __u32 s_journal_max_trans_age;        /* in seconds, how old can a transaction be */
+  __u16 s_blocksize;                   	/* block size           */
+  __u16 s_oid_maxsize;			/* max size of object id array  */
+  __u16 s_oid_cursize;			/* current size of object id array */
+  __u16 s_state;                       	/* valid or error       */
+  char s_magic[16];                     /* reiserfs magic string indicates that file system is reiserfs */
+  __u16 s_tree_height;                  /* height of disk tree */
+  __u16 s_bmap_nr;                      /* amount of bitmap blocks needed to address each block of file system */
+  __u16 s_version;
+  char s_unused[128];			/* zero filled by mkreiserfs */
+};
+
+#define REISERFS_MAX_SUPPORTED_VERSION 2
+#define REISERFS_SUPER_MAGIC_STRING "ReIsErFs"
+#define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
+#define REISER3FS_SUPER_MAGIC_STRING "ReIsEr3Fs"
+
+#define MAX_HEIGHT 7
+
+/* must be correct to keep the desc and commit structs at 4k */
+#define JOURNAL_TRANS_HALF 1018
+
+/* first block written in a commit.  */
+struct reiserfs_journal_desc {
+  __u32 j_trans_id;			/* id of commit */
+  __u32 j_len;				/* length of commit. len +1 is the commit block */
+  __u32 j_mount_id;			/* mount id of this trans*/
+  __u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for the first blocks */
+  char j_magic[12];
+};
+
+/* last block written in a commit */
+struct reiserfs_journal_commit {
+  __u32 j_trans_id;			/* must match j_trans_id from the desc block */
+  __u32 j_len;			/* ditto */
+  __u32 j_realblock[JOURNAL_TRANS_HALF]; /* real locations for the last blocks */
+  char j_digest[16];			/* md5 sum of all the blocks involved, including desc and commit. not used, kill it */
+};
+
+/* this header block gets written whenever a transaction is considered
+   fully flushed, and is more recent than the last fully flushed
+   transaction.  
+   fully flushed means all the log blocks and all the real blocks are
+   on disk, and this transaction does not need to be replayed.  
+*/
+struct reiserfs_journal_header {
+  /* id of last fully flushed transaction */
+  __u32 j_last_flush_trans_id;
+  /* offset in the log of where to start replay after a crash */
+  __u32 j_first_unflushed_offset;
+  /* mount id to detect very old transactions */
+  __u32 j_mount_id;
+};
+
+/* magic string to find desc blocks in the journal */
+#define JOURNAL_DESC_MAGIC "ReIsErLB" 
+
+
+/*
+ * directories use this key as well as old files
+ */
+struct offset_v1
+{
+  /*
+   * for regular files this is the offset to the first byte of the
+   * body, contained in the object-item, as measured from the start of
+   * the entire body of the object.
+   *
+   * for directory entries, k_offset consists of hash derived from
+   * hashing the name and using few bits (23 or more) of the resulting
+   * hash, and generation number that allows distinguishing names with
+   * hash collisions. If number of collisions overflows generation
+   * number, we return EEXIST.  High order bit is 0 always 
+   */
+  __u32 k_offset;
+  __u32 k_uniqueness;
+};
+
+struct offset_v2
+{
+  /*
+   * for regular files this is the offset to the first byte of the
+   * body, contained in the object-item, as measured from the start of
+   * the entire body of the object.
+   *
+   * for directory entries, k_offset consists of hash derived from
+   * hashing the name and using few bits (23 or more) of the resulting
+   * hash, and generation number that allows distinguishing names with
+   * hash collisions. If number of collisions overflows generation
+   * number, we return EEXIST.  High order bit is 0 always 
+   */
+  __u64 k_offset:60;
+  __u64 k_type: 4;
+};
+
+
+struct key
+{
+  /* packing locality: by default parent directory object id */
+  __u32 k_dir_id;
+  /* object identifier */
+  __u32 k_objectid;
+  /* the offset and node type (old and new form) */
+  union
+  {
+    struct offset_v1 v1;
+    struct offset_v2 v2;
+  }
+  u;
+};
+
+#define KEY_SIZE (sizeof (struct key))
+
+/* Header of a disk block.  More precisely, header of a formatted leaf
+   or internal node, and not the header of an unformatted node. */
+struct block_head
+{       
+  __u16 blk_level;        /* Level of a block in the tree. */
+  __u16 blk_nr_item;      /* Number of keys/items in a block. */
+  __u16 blk_free_space;   /* Block free space in bytes. */
+  struct key  blk_right_delim_key; /* Right delimiting key for this block (supported for leaf level nodes
+				      only) */
+};
+#define BLKH_SIZE (sizeof (struct block_head))
+#define DISK_LEAF_NODE_LEVEL  1 /* Leaf node level.                       */
+
+struct item_head
+{
+  struct key ih_key; 	/* Everything in the tree is found by searching for it based on its key.*/
+  
+  union
+  {
+    __u16 ih_free_space; /* The free space in the last unformatted node of an indirect item if this
+			    is an indirect item.  This equals 0xFFFF iff this is a direct item or
+			    stat data item. Note that the key, not this field, is used to determine
+			    the item type, and thus which field this union contains. */
+    __u16 ih_entry_count; /* Iff this is a directory item, this field equals the number of directory
+			     entries in the directory item. */
+  }
+  u;
+  __u16 ih_item_len;           /* total size of the item body                  */
+  __u16 ih_item_location;      /* an offset to the item body within the block  */
+  __u16 ih_version;	       /* ITEM_VERSION_1 for all old items, 
+				  ITEM_VERSION_2 for new ones. 
+				  Highest bit is set by fsck
+                                  temporary, cleaned after all done */
+};
+/* size of item header     */
+#define IH_SIZE (sizeof (struct item_head))
+
+#define ITEM_VERSION_1 0
+#define ITEM_VERSION_2 1
+#define IH_KEY_OFFSET(ih) ((ih)->ih_version == ITEM_VERSION_1 \
+			   ? (ih)->ih_key.u.v1.k_offset \
+			   : (ih)->ih_key.u.v2.k_offset)
+
+#define IH_KEY_ISTYPE(ih, type) ((ih)->ih_version == ITEM_VERSION_1 \
+				 ? (ih)->ih_key.u.v1.k_uniqueness == V1_##type \
+				 : (ih)->ih_key.u.v2.k_type == V2_##type)
+
+struct disk_child
+{
+  unsigned long       dc_block_number;              /* Disk child's block number. */
+  unsigned short      dc_size;		            /* Disk child's used space.   */
+};
+
+#define DC_SIZE (sizeof (struct disk_child))
+
+/* Stat Data on disk.
+ *
+ * Note that reiserfs has two different forms of stat data.  Luckily
+ * the fields needed by grub are at the same position.
+ */
+struct stat_data
+{
+  __u16 sd_mode;	/* file type, permissions */
+  __u16 sd_notused1[3]; /* fields not needed by reiserfs */
+  __u32 sd_size;	/* file size */
+  __u32 sd_size_hi;	/* file size high 32 bits (since version 2) */
+};
+
+struct reiserfs_de_head
+{
+  __u32 deh_offset;  /* third component of the directory entry key */
+  __u32 deh_dir_id;  /* objectid of the parent directory of the
+			object, that is referenced by directory entry */
+  __u32 deh_objectid;/* objectid of the object, that is referenced by
+                        directory entry */
+  __u16 deh_location;/* offset of name in the whole item */
+  __u16 deh_state;   /* whether 1) entry contains stat data (for
+			future), and 2) whether entry is hidden
+			(unlinked) */
+};
+
+#define DEH_SIZE (sizeof (struct reiserfs_de_head))
+
+#define DEH_Statdata (1 << 0)			/* not used now */
+#define DEH_Visible  (1 << 2)
+
+#define SD_OFFSET  0
+#define SD_UNIQUENESS 0
+#define DOT_OFFSET 1
+#define DOT_DOT_OFFSET 2
+#define DIRENTRY_UNIQUENESS 500
+
+#define V1_TYPE_STAT_DATA 0x0
+#define V1_TYPE_DIRECT 0xffffffff
+#define V1_TYPE_INDIRECT 0xfffffffe
+#define V1_TYPE_DIRECTORY_MAX 0xfffffffd
+#define V2_TYPE_STAT_DATA 0
+#define V2_TYPE_INDIRECT 1
+#define V2_TYPE_DIRECT 2
+#define V2_TYPE_DIRENTRY 3 
+
+#define REISERFS_ROOT_OBJECTID 2
+#define REISERFS_ROOT_PARENT_OBJECTID 1
+#define REISERFS_DISK_OFFSET_IN_BYTES (64 * 1024)
+/* the spot for the super in versions 3.5 - 3.5.11 (inclusive) */
+#define REISERFS_OLD_DISK_OFFSET_IN_BYTES (8 * 1024)
+#define REISERFS_OLD_BLOCKSIZE 4096
+
+#define S_ISREG(mode) (((mode) & 0170000) == 0100000)
+#define S_ISDIR(mode) (((mode) & 0170000) == 0040000)
+#define S_ISLNK(mode) (((mode) & 0170000) == 0120000)
+
+#define PATH_MAX       1024	/* include/linux/limits.h */
+#define MAX_LINK_COUNT    5	/* number of symbolic links to follow */
+
+/* The size of the node cache */
+#define FSYSREISER_CACHE_SIZE 24*1024
+#define FSYSREISER_MIN_BLOCKSIZE SECTOR_SIZE
+#define FSYSREISER_MAX_BLOCKSIZE FSYSREISER_CACHE_SIZE / 3
+
+/* Info about currently opened file */
+struct fsys_reiser_fileinfo
+{
+  __u32 k_dir_id;
+  __u32 k_objectid;
+};
+
+/* In memory info about the currently mounted filesystem */
+struct fsys_reiser_info
+{
+  /* The last read item head */
+  struct item_head *current_ih;
+  /* The last read item */
+  char *current_item;
+  /* The information for the currently opened file */
+  struct fsys_reiser_fileinfo fileinfo;
+  /* The start of the journal */
+  __u32 journal_block;
+  /* The size of the journal */
+  __u32 journal_block_count;
+  /* The first valid descriptor block in journal
+     (relative to journal_block) */
+  __u32 journal_first_desc;
+
+  /* The ReiserFS version. */
+  __u16 version;
+  /* The current depth of the reiser tree. */
+  __u16 tree_depth;
+  /* SECTOR_SIZE << blocksize_shift == blocksize. */
+  __u8  blocksize_shift;
+  /* 1 << full_blocksize_shift == blocksize. */
+  __u8  fullblocksize_shift;
+  /* The reiserfs block size  (must be a power of 2) */
+  __u16 blocksize;
+  /* The number of cached tree nodes */
+  __u16 cached_slots;
+  /* The number of valid transactions in journal */
+  __u16 journal_transactions;
+  
+  unsigned int blocks[MAX_HEIGHT];
+  unsigned int next_key_nr[MAX_HEIGHT];
+};
+
+/* The cached s+tree blocks in FSYS_BUF,  see below
+ * for a more detailed description.
+ */
+#define ROOT     ((char *) ((int) FSYS_BUF))
+#define CACHE(i) (ROOT + ((i) << INFO->fullblocksize_shift))
+#define LEAF     CACHE (DISK_LEAF_NODE_LEVEL)
+
+#define BLOCKHEAD(cache) ((struct block_head *) cache)
+#define ITEMHEAD         ((struct item_head  *) ((int) LEAF + BLKH_SIZE))
+#define KEY(cache)       ((struct key        *) ((int) cache + BLKH_SIZE))
+#define DC(cache)        ((struct disk_child *) \
+			  ((int) cache + BLKH_SIZE + KEY_SIZE * nr_item))
+/* The fsys_reiser_info block.
+ */
+#define INFO \
+    ((struct fsys_reiser_info *) ((int) FSYS_BUF + FSYSREISER_CACHE_SIZE))
+/* 
+ * The journal cache.  For each transaction it contains the number of
+ * blocks followed by the real block numbers of this transaction.  
+ *
+ * If the block numbers of some transaction won't fit in this space,
+ * this list is stopped with a 0xffffffff marker and the remaining
+ * uncommitted transactions aren't cached.  
+ */
+#define JOURNAL_START    ((__u32 *) (INFO + 1))
+#define JOURNAL_END      ((__u32 *) (FSYS_BUF + FSYS_BUFLEN))
+
+
+static __inline__ unsigned long
+log2 (unsigned long word)
+{
+  __asm__ ("bsfl %1,%0"
+	   : "=r" (word)
+	   : "r" (word));
+  return word;
+}
+
+static __inline__ int
+is_power_of_two (unsigned long word)
+{
+  return (word & -word) == word;
+}
+
+static int 
+journal_read (int block, int len, char *buffer) 
+{
+  return devread ((INFO->journal_block + block) << INFO->blocksize_shift, 
+		  0, len, buffer);
+}
+
+/* Read a block from ReiserFS file system, taking the journal into
+ * account.  If the block nr is in the journal, the block from the
+ * journal taken.  
+ */
+static int
+block_read (int blockNr, int start, int len, char *buffer)
+{
+  int transactions = INFO->journal_transactions;
+  int desc_block = INFO->journal_first_desc;
+  int journal_mask = INFO->journal_block_count - 1;
+  int translatedNr = blockNr;
+  __u32 *journal_table = JOURNAL_START;
+  while (transactions-- > 0) 
+    {
+      int i = 0;
+      int j_len;
+      if (*journal_table != 0xffffffff)
+	{
+	  /* Search for the blockNr in cached journal */
+	  j_len = *journal_table++;
+	  while (i++ < j_len)
+	    {
+	      if (*journal_table++ == blockNr)
+		{
+		  journal_table += j_len - i;
+		  goto found;
+		}
+	    }
+	}
+      else
+	{
+	  /* This is the end of cached journal marker.  The remaining
+	   * transactions are still on disk.
+	   */
+	  struct reiserfs_journal_desc   desc;
+	  struct reiserfs_journal_commit commit;
+
+	  if (! journal_read (desc_block, sizeof (desc), (char *) &desc))
+	    return 0;
+
+	  j_len = desc.j_len;
+	  while (i < j_len && i < JOURNAL_TRANS_HALF)
+	    if (desc.j_realblock[i++] == blockNr)
+	      goto found;
+	  
+	  if (j_len >= JOURNAL_TRANS_HALF)
+	    {
+	      int commit_block = (desc_block + 1 + j_len) & journal_mask;
+	      if (! journal_read (commit_block, 
+				  sizeof (commit), (char *) &commit))
+		return 0;
+	      while (i < j_len)
+		if (commit.j_realblock[i++ - JOURNAL_TRANS_HALF] == blockNr)
+		  goto found;
+	    }
+	}
+      goto not_found;
+      
+    found:
+      translatedNr = INFO->journal_block + ((desc_block + i) & journal_mask);
+#ifdef REISERDEBUG
+      printf ("block_read: block %d is mapped to journal block %d.\n", 
+	      blockNr, translatedNr - INFO->journal_block);
+#endif
+      /* We must continue the search, as this block may be overwritten
+       * in later transactions.
+       */
+    not_found:
+      desc_block = (desc_block + 2 + j_len) & journal_mask;
+    }
+  return devread (translatedNr << INFO->blocksize_shift, start, len, buffer);
+}
+
+/* Init the journal data structure.  We try to cache as much as
+ * possible in the JOURNAL_START-JOURNAL_END space, but if it is full
+ * we can still read the rest from the disk on demand.
+ *
+ * The first number of valid transactions and the descriptor block of the
+ * first valid transaction are held in INFO.  The transactions are all 
+ * adjacent, but we must take care of the journal wrap around. 
+ */
+static int
+journal_init (void)
+{
+  unsigned int block_count = INFO->journal_block_count;
+  unsigned int desc_block;
+  unsigned int commit_block;
+  unsigned int next_trans_id;
+  struct reiserfs_journal_header header;
+  struct reiserfs_journal_desc   desc;
+  struct reiserfs_journal_commit commit;
+  __u32 *journal_table = JOURNAL_START;
+
+  journal_read (block_count, sizeof (header), (char *) &header);
+  desc_block = header.j_first_unflushed_offset;
+  if (desc_block >= block_count)
+    return 0;
+
+  INFO->journal_first_desc = desc_block;
+  next_trans_id = header.j_last_flush_trans_id + 1;
+
+#ifdef REISERDEBUG
+  printf ("journal_init: last flushed %d\n", 
+	  header.j_last_flush_trans_id);
+#endif
+
+  while (1) 
+    {
+      journal_read (desc_block, sizeof (desc), (char *) &desc);
+      if (substring (JOURNAL_DESC_MAGIC, desc.j_magic) > 0
+	  || desc.j_trans_id != next_trans_id
+	  || desc.j_mount_id != header.j_mount_id)
+	/* no more valid transactions */
+	break;
+      
+      commit_block = (desc_block + desc.j_len + 1) & (block_count - 1);
+      journal_read (commit_block, sizeof (commit), (char *) &commit);
+      if (desc.j_trans_id != commit.j_trans_id
+	  || desc.j_len != commit.j_len)
+	/* no more valid transactions */
+	break;
+      
+#ifdef REISERDEBUG
+      printf ("Found valid transaction %d/%d at %d.\n", 
+	      desc.j_trans_id, desc.j_mount_id, desc_block);
+#endif
+
+      next_trans_id++;
+      if (journal_table < JOURNAL_END)
+	{
+	  if ((journal_table + 1 + desc.j_len) >= JOURNAL_END)
+	    {
+	      /* The table is almost full; mark the end of the cached
+	       * journal.*/
+	      *journal_table = 0xffffffff;
+	      journal_table = JOURNAL_END;
+	    }
+	  else
+	    {
+	      int i;
+	      /* Cache the length and the realblock numbers in the table.
+	       * The block number of descriptor can easily be computed.
+	       * and need not to be stored here.
+	       */
+	      *journal_table++ = desc.j_len;
+	      for (i = 0; i < desc.j_len && i < JOURNAL_TRANS_HALF; i++)
+		{
+		  *journal_table++ = desc.j_realblock[i];
+#ifdef REISERDEBUG
+		  printf ("block %d is in journal %d.\n", 
+			  desc.j_realblock[i], desc_block);
+#endif
+		}
+	      for (     ; i < desc.j_len; i++)
+		{
+		  *journal_table++ = commit.j_realblock[i-JOURNAL_TRANS_HALF];
+#ifdef REISERDEBUG
+		  printf ("block %d is in journal %d.\n", 
+			  commit.j_realblock[i-JOURNAL_TRANS_HALF], 
+			  desc_block);
+#endif
+		}
+	    }
+	}
+      desc_block = (commit_block + 1) & (block_count - 1);
+    }
+#ifdef REISERDEBUG
+  printf ("Transaction %d/%d at %d isn't valid.\n", 
+	  desc.j_trans_id, desc.j_mount_id, desc_block);
+#endif
+
+  INFO->journal_transactions
+    = next_trans_id - header.j_last_flush_trans_id - 1;
+  return errnum == 0;
+}
+
+/* check filesystem types and read superblock into memory buffer */
+int
+reiserfs_mount (void)
+{
+  struct reiserfs_super_block super;
+  int superblock = REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS;
+
+  if (part_length < superblock + (sizeof (super) >> SECTOR_BITS)
+      || ! devread (superblock, 0, sizeof (struct reiserfs_super_block), 
+		(char *) &super)
+      || (substring (REISER3FS_SUPER_MAGIC_STRING, super.s_magic) > 0
+	  && substring (REISER2FS_SUPER_MAGIC_STRING, super.s_magic) > 0
+	  && substring (REISERFS_SUPER_MAGIC_STRING, super.s_magic) > 0)
+      || (/* check that this is not a copy inside the journal log */
+	  super.s_journal_block * super.s_blocksize
+	  <= REISERFS_DISK_OFFSET_IN_BYTES))
+    {
+      /* Try old super block position */
+      superblock = REISERFS_OLD_DISK_OFFSET_IN_BYTES >> SECTOR_BITS;
+      if (part_length < superblock + (sizeof (super) >> SECTOR_BITS)
+	  || ! devread (superblock, 0, sizeof (struct reiserfs_super_block), 
+			(char *) &super))
+	return 0;
+
+      if (substring (REISER3FS_SUPER_MAGIC_STRING, super.s_magic) > 0
+	  && substring (REISER2FS_SUPER_MAGIC_STRING, super.s_magic) > 0
+	  && substring (REISERFS_SUPER_MAGIC_STRING, super.s_magic) > 0)
+	{
+	  /* pre journaling super block ? */
+	  if (substring (REISERFS_SUPER_MAGIC_STRING, 
+			 (char*) ((int) &super + 20)) > 0)
+	    return 0;
+	  
+	  super.s_blocksize = REISERFS_OLD_BLOCKSIZE;
+	  super.s_journal_block = 0;
+	  super.s_version = 0;
+	}
+    }
+
+  /* check the version number.  */
+  if (super.s_version > REISERFS_MAX_SUPPORTED_VERSION)
+    return 0;
+  
+  INFO->version = super.s_version;
+  INFO->blocksize = super.s_blocksize;
+  INFO->fullblocksize_shift = log2 (super.s_blocksize);
+  INFO->blocksize_shift = INFO->fullblocksize_shift - SECTOR_BITS;
+  INFO->cached_slots = 
+    (FSYSREISER_CACHE_SIZE >> INFO->fullblocksize_shift) - 1;
+
+#ifdef REISERDEBUG
+  printf ("reiserfs_mount: version=%d, blocksize=%d\n", 
+	  INFO->version, INFO->blocksize);
+#endif /* REISERDEBUG */
+
+  /* Clear node cache. */
+  memset (INFO->blocks, 0, sizeof (INFO->blocks));
+
+  if (super.s_blocksize < FSYSREISER_MIN_BLOCKSIZE
+      || super.s_blocksize > FSYSREISER_MAX_BLOCKSIZE
+      || (SECTOR_SIZE << INFO->blocksize_shift) != super.s_blocksize)
+    return 0;
+
+  /* Initialize journal code.  If something fails we end with zero
+   * journal_transactions, so we don't access the journal at all.  
+   */
+  INFO->journal_transactions = 0;
+  if (super.s_journal_block != 0 && super.s_journal_dev == 0)
+    {
+      INFO->journal_block = super.s_journal_block;
+      INFO->journal_block_count = super.s_journal_size;
+      if (is_power_of_two (INFO->journal_block_count))
+	journal_init ();
+
+      /* Read in super block again, maybe it is in the journal */
+      block_read (superblock >> INFO->blocksize_shift, 
+		  0, sizeof (struct reiserfs_super_block), (char *) &super);
+    }
+
+  if (! block_read (super.s_root_block, 0, INFO->blocksize, (char*) ROOT))
+    return 0;
+  
+  INFO->tree_depth = BLOCKHEAD (ROOT)->blk_level;
+  
+#ifdef REISERDEBUG
+  printf ("root read_in: block=%d, depth=%d\n", 
+	  super.s_root_block, INFO->tree_depth);
+#endif /* REISERDEBUG */
+
+  if (INFO->tree_depth >= MAX_HEIGHT)
+    return 0;
+  if (INFO->tree_depth == DISK_LEAF_NODE_LEVEL)
+    {
+      /* There is only one node in the whole filesystem, 
+       * which is simultanously leaf and root */
+      memcpy (LEAF, ROOT, INFO->blocksize);
+    }
+  return 1;
+}
+
+/***************** TREE ACCESSING METHODS *****************************/
+
+/* I assume you are familiar with the ReiserFS tree, if not go to
+ * http://www.namesys.com/content_table.html
+ *
+ * My tree node cache is organized as following
+ *   0   ROOT node
+ *   1   LEAF node  (if the ROOT is also a LEAF it is copied here
+ *   2-n other nodes on current path from bottom to top.  
+ *       if there is not enough space in the cache, the top most are
+ *       omitted.
+ *
+ * I have only two methods to find a key in the tree:
+ *   search_stat(dir_id, objectid) searches for the stat entry (always
+ *       the first entry) of an object.
+ *   next_key() gets the next key in tree order.
+ *
+ * This means, that I can only sequential reads of files are
+ * efficient, but this really doesn't hurt for grub.  
+ */
+
+/* Read in the node at the current path and depth into the node cache.
+ * You must set INFO->blocks[depth] before.
+ */
+static char *
+read_tree_node (unsigned int blockNr, int depth)
+{
+  char* cache = CACHE(depth);
+  int num_cached = INFO->cached_slots;
+  if (depth < num_cached)
+    {
+      /* This is the cached part of the path.  Check if same block is
+       * needed.  
+       */
+      if (blockNr == INFO->blocks[depth])
+	return cache;
+    }
+  else
+    cache = CACHE(num_cached);
+
+#ifdef REISERDEBUG
+  printf ("  next read_in: block=%d (depth=%d)\n",
+	  blockNr, depth);
+#endif /* REISERDEBUG */
+  if (! block_read (blockNr, 0, INFO->blocksize, cache))
+    return 0;
+  /* Make sure it has the right node level */
+  if (BLOCKHEAD (cache)->blk_level != depth)
+    {
+      errnum = ERR_FSYS_CORRUPT;
+      return 0;
+    }
+
+  INFO->blocks[depth] = blockNr;
+  return cache;
+}
+
+/* Get the next key, i.e. the key following the last retrieved key in
+ * tree order.  INFO->current_ih and 
+ * INFO->current_info are adapted accordingly.  */
+static int
+next_key (void)
+{
+  int depth;
+  struct item_head *ih = INFO->current_ih + 1;
+  char *cache;
+  
+#ifdef REISERDEBUG
+  printf ("next_key:\n  old ih: key %d:%d:%d:%d version:%d\n", 
+	  INFO->current_ih->ih_key.k_dir_id, 
+	  INFO->current_ih->ih_key.k_objectid, 
+	  INFO->current_ih->ih_key.u.v1.k_offset,
+	  INFO->current_ih->ih_key.u.v1.k_uniqueness,
+	  INFO->current_ih->ih_version);
+#endif /* REISERDEBUG */
+  
+  if (ih == &ITEMHEAD[BLOCKHEAD (LEAF)->blk_nr_item])
+    {
+      depth = DISK_LEAF_NODE_LEVEL;
+      /* The last item, was the last in the leaf node.  
+       * Read in the next block 
+       */
+      do
+	{
+	  if (depth == INFO->tree_depth)
+	    {
+	      /* There are no more keys at all.
+	       * Return a dummy item with MAX_KEY */
+	      ih = (struct item_head *) &BLOCKHEAD (LEAF)->blk_right_delim_key;
+	      goto found;
+	    }
+	  depth++;
+#ifdef REISERDEBUG
+	  printf ("  depth=%d, i=%d\n", depth, INFO->next_key_nr[depth]);
+#endif /* REISERDEBUG */
+	}
+      while (INFO->next_key_nr[depth] == 0);
+      
+      if (depth == INFO->tree_depth)
+	cache = ROOT;
+      else if (depth <= INFO->cached_slots)
+	cache = CACHE (depth);
+      else 
+	{
+	  cache = read_tree_node (INFO->blocks[depth], depth);
+	  if (! cache)
+	    return 0;
+	}
+      
+      do
+	{
+	  int nr_item = BLOCKHEAD (cache)->blk_nr_item;
+	  int key_nr = INFO->next_key_nr[depth]++;
+#ifdef REISERDEBUG
+	  printf ("  depth=%d, i=%d/%d\n", depth, key_nr, nr_item);
+#endif /* REISERDEBUG */
+	  if (key_nr == nr_item)
+	    /* This is the last item in this block, set the next_key_nr to 0 */
+	    INFO->next_key_nr[depth] = 0;
+
+	  cache = read_tree_node (DC (cache)[key_nr].dc_block_number, --depth);
+	  if (! cache)
+	    return 0;
+	}
+      while (depth > DISK_LEAF_NODE_LEVEL);
+      
+      ih = ITEMHEAD;
+    }
+ found:
+  INFO->current_ih   = ih;
+  INFO->current_item = &LEAF[ih->ih_item_location];
+#ifdef REISERDEBUG
+  printf ("  new ih: key %d:%d:%d:%d version:%d\n", 
+	  INFO->current_ih->ih_key.k_dir_id, 
+	  INFO->current_ih->ih_key.k_objectid, 
+	  INFO->current_ih->ih_key.u.v1.k_offset,
+	  INFO->current_ih->ih_key.u.v1.k_uniqueness,
+	  INFO->current_ih->ih_version);
+#endif /* REISERDEBUG */
+  return 1;
+}
+
+/* preconditions: reiserfs_mount already executed, therefore 
+ *   INFO block is valid
+ * returns: 0 if error (errnum is set), 
+ *   nonzero iff we were able to find the key successfully.
+ * postconditions: on a nonzero return, the current_ih and 
+ *   current_item fields describe the key that equals the
+ *   searched key.  INFO->next_key contains the next key after
+ *   the searched key.
+ * side effects: messes around with the cache.
+ */
+static int
+search_stat (__u32 dir_id, __u32 objectid) 
+{
+  char *cache;
+  int depth;
+  int nr_item;
+  int i;
+  struct item_head *ih;
+#ifdef REISERDEBUG
+  printf ("search_stat:\n  key %d:%d:0:0\n", dir_id, objectid);
+#endif /* REISERDEBUG */
+  
+  depth = INFO->tree_depth;
+  cache = ROOT;
+  
+  while (depth > DISK_LEAF_NODE_LEVEL)
+    {
+      struct key *key;
+      nr_item = BLOCKHEAD (cache)->blk_nr_item;
+      
+      key = KEY (cache);
+      
+      for (i = 0; i < nr_item; i++) 
+	{
+	  if (key->k_dir_id > dir_id
+	      || (key->k_dir_id == dir_id 
+		  && (key->k_objectid > objectid
+		      || (key->k_objectid == objectid
+			  && (key->u.v1.k_offset
+			      | key->u.v1.k_uniqueness) > 0))))
+	    break;
+	  key++;
+	}
+      
+#ifdef REISERDEBUG
+      printf ("  depth=%d, i=%d/%d\n", depth, i, nr_item);
+#endif /* REISERDEBUG */
+      INFO->next_key_nr[depth] = (i == nr_item) ? 0 : i+1;
+      cache = read_tree_node (DC (cache)[i].dc_block_number, --depth);
+      if (! cache)
+	return 0;
+    }
+  
+  /* cache == LEAF */
+  nr_item = BLOCKHEAD (LEAF)->blk_nr_item;
+  ih = ITEMHEAD;
+  for (i = 0; i < nr_item; i++) 
+    {
+      if (ih->ih_key.k_dir_id == dir_id 
+	  && ih->ih_key.k_objectid == objectid
+	  && ih->ih_key.u.v1.k_offset == 0
+	  && ih->ih_key.u.v1.k_uniqueness == 0)
+	{
+#ifdef REISERDEBUG
+	  printf ("  depth=%d, i=%d/%d\n", depth, i, nr_item);
+#endif /* REISERDEBUG */
+	  INFO->current_ih   = ih;
+	  INFO->current_item = &LEAF[ih->ih_item_location];
+	  return 1;
+	}
+      ih++;
+    }
+  errnum = ERR_FSYS_CORRUPT;
+  return 0;
+}
+
+int
+reiserfs_read (char *buf, int len)
+{
+  unsigned int blocksize;
+  unsigned int offset;
+  unsigned int to_read;
+  char *prev_buf = buf;
+  
+#ifdef REISERDEBUG
+  printf ("reiserfs_read: filepos=%d len=%d, offset=%x:%x\n",
+	  filepos, len, (__u64) IH_KEY_OFFSET (INFO->current_ih) - 1);
+#endif /* REISERDEBUG */
+  
+  if (INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid
+      || IH_KEY_OFFSET (INFO->current_ih) > filepos + 1)
+    {
+      search_stat (INFO->fileinfo.k_dir_id, INFO->fileinfo.k_objectid);
+      goto get_next_key;
+    }
+  
+  while (! errnum)
+    {
+      if (INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid)
+	break;
+      
+      offset = filepos - IH_KEY_OFFSET (INFO->current_ih) + 1;
+      blocksize = INFO->current_ih->ih_item_len;
+      
+#ifdef REISERDEBUG
+      printf ("  loop: filepos=%d len=%d, offset=%d blocksize=%d\n",
+	      filepos, len, offset, blocksize);
+#endif /* REISERDEBUG */
+      
+      if (IH_KEY_ISTYPE(INFO->current_ih, TYPE_DIRECT)
+	  && offset < blocksize)
+	{
+#ifdef REISERDEBUG
+	  printf ("direct_read: offset=%d, blocksize=%d\n",
+		  offset, blocksize);
+#endif /* REISERDEBUG */
+	  to_read = blocksize - offset;
+	  if (to_read > len)
+	    to_read = len;
+	  
+	  if (disk_read_hook != NULL)
+	    {
+	      disk_read_func = disk_read_hook;
+	      
+	      block_read (INFO->blocks[DISK_LEAF_NODE_LEVEL],
+			  (INFO->current_item - LEAF + offset), to_read, buf);
+	      
+	      disk_read_func = NULL;
+	    }
+	  else
+	    memcpy (buf, INFO->current_item + offset, to_read);
+	  goto update_buf_len;
+	}
+      else if (IH_KEY_ISTYPE(INFO->current_ih, TYPE_INDIRECT))
+	{
+	  blocksize = (blocksize >> 2) << INFO->fullblocksize_shift;
+#ifdef REISERDEBUG
+	  printf ("indirect_read: offset=%d, blocksize=%d\n",
+		  offset, blocksize);
+#endif /* REISERDEBUG */
+	  
+	  while (offset < blocksize)
+	    {
+	      __u32 blocknr = ((__u32 *) INFO->current_item)
+		[offset >> INFO->fullblocksize_shift];
+	      int blk_offset = offset & (INFO->blocksize-1);
+	      
+	      to_read = INFO->blocksize - blk_offset;
+	      if (to_read > len)
+		to_read = len;
+	      
+	      disk_read_func = disk_read_hook;
+	      
+	      /* Journal is only for meta data.  Data blocks can be read
+	       * directly without using block_read
+	       */
+	      devread (blocknr << INFO->blocksize_shift,
+		       blk_offset, to_read, buf);
+	      
+	      disk_read_func = NULL;
+	    update_buf_len:
+	      len -= to_read;
+	      buf += to_read;
+	      offset += to_read;
+	      filepos += to_read;
+	      if (len == 0)
+		goto done;
+	    }
+	}
+    get_next_key:
+      next_key ();
+    }
+ done:
+  return errnum ? 0 : buf - prev_buf;
+}
+
+
+/* preconditions: reiserfs_mount already executed, therefore 
+ *   INFO block is valid
+ * returns: 0 if error, nonzero iff we were able to find the file successfully
+ * postconditions: on a nonzero return, INFO->fileinfo contains the info
+ *   of the file we were trying to look up, filepos is 0 and filemax is 
+ *   the size of the file.
+ */
+int
+reiserfs_dir (char *dirname)
+{
+  struct reiserfs_de_head *de_head;
+  char *rest, ch;
+  __u32 dir_id, objectid, parent_dir_id = 0, parent_objectid = 0;
+#ifndef STAGE1_5
+  int do_possibilities = 0;
+#endif /* ! STAGE1_5 */
+  char linkbuf[PATH_MAX];	/* buffer for following symbolic links */
+  int link_count = 0;
+  int mode;
+
+  dir_id = REISERFS_ROOT_PARENT_OBJECTID;
+  objectid = REISERFS_ROOT_OBJECTID;
+  
+  while (1)
+    {
+#ifdef REISERDEBUG
+      printf ("dirname=%s\n", dirname);
+#endif /* REISERDEBUG */
+      
+      /* Search for the stat info first. */
+      if (! search_stat (dir_id, objectid))
+	return 0;
+      
+#ifdef REISERDEBUG
+      printf ("sd_mode=%x sd_size=%d\n", 
+	      ((struct stat_data *) INFO->current_item)->sd_mode,
+	      ((struct stat_data *) INFO->current_item)->sd_size);
+#endif /* REISERDEBUG */
+      
+      mode = ((struct stat_data *) INFO->current_item)->sd_mode;
+
+      /* If we've got a symbolic link, then chase it. */
+      if (S_ISLNK (mode))
+	{
+	  int len;
+	  if (++link_count > MAX_LINK_COUNT)
+	    {
+	      errnum = ERR_SYMLINK_LOOP;
+	      return 0;
+	    }
+
+	  /* Get the symlink size. */
+	  filemax = ((struct stat_data *) INFO->current_item)->sd_size;
+
+	  /* Find out how long our remaining name is. */
+	  len = 0;
+	  while (dirname[len] && !isspace (dirname[len]))
+	    len++;
+
+	  if (filemax + len > sizeof (linkbuf) - 1)
+	    {
+	      errnum = ERR_FILELENGTH;
+	      return 0;
+	    }
+ 	  
+	  /* Copy the remaining name to the end of the symlink data.
+	     Note that DIRNAME and LINKBUF may overlap! */
+	  grub_memmove (linkbuf + filemax, dirname, len+1);
+
+	  INFO->fileinfo.k_dir_id = dir_id;
+	  INFO->fileinfo.k_objectid = objectid;
+  	  filepos = 0;
+	  if (! next_key ()
+	      || reiserfs_read (linkbuf, filemax) != filemax)
+	    {
+	      if (! errnum)
+		errnum = ERR_FSYS_CORRUPT;
+	      return 0;
+	    }
+
+#ifdef REISERDEBUG
+	  printf ("symlink=%s\n", linkbuf);
+#endif /* REISERDEBUG */
+
+	  dirname = linkbuf;
+	  if (*dirname == '/')
+	    {
+	      /* It's an absolute link, so look it up in root. */
+	      dir_id = REISERFS_ROOT_PARENT_OBJECTID;
+	      objectid = REISERFS_ROOT_OBJECTID;
+	    }
+	  else
+	    {
+	      /* Relative, so look it up in our parent directory. */
+	      dir_id   = parent_dir_id;
+	      objectid = parent_objectid;
+	    }
+
+	  /* Now lookup the new name. */
+	  continue;
+	}
+
+      /* if we have a real file (and we're not just printing possibilities),
+	 then this is where we want to exit */
+      
+      if (! *dirname || isspace (*dirname))
+	{
+	  if (! S_ISREG (mode))
+	    {
+	      errnum = ERR_BAD_FILETYPE;
+	      return 0;
+	    }
+	  
+	  filepos = 0;
+	  filemax = ((struct stat_data *) INFO->current_item)->sd_size;
+	  
+	  /* If this is a new stat data and size is > 4GB set filemax to 
+	   * maximum
+	   */
+	  if (INFO->current_ih->ih_version == ITEM_VERSION_2
+	      && ((struct stat_data *) INFO->current_item)->sd_size_hi > 0)
+	    filemax = 0xffffffff;
+	  
+	  INFO->fileinfo.k_dir_id = dir_id;
+	  INFO->fileinfo.k_objectid = objectid;
+	  return next_key ();
+	}
+      
+      /* continue with the file/directory name interpretation */
+      while (*dirname == '/')
+	dirname++;
+      if (! S_ISDIR (mode))
+	{
+	  errnum = ERR_BAD_FILETYPE;
+	  return 0;
+	}
+      for (rest = dirname; (ch = *rest) && ! isspace (ch) && ch != '/'; rest++);
+      *rest = 0;
+      
+# ifndef STAGE1_5
+      if (print_possibilities && ch != '/')
+	do_possibilities = 1;
+# endif /* ! STAGE1_5 */
+      
+      while (1)
+	{
+	  char *name_end;
+	  int num_entries;
+	  
+	  if (! next_key ())
+	    return 0;
+#ifdef REISERDEBUG
+	  printf ("ih: key %d:%d:%d:%d version:%d\n", 
+		  INFO->current_ih->ih_key.k_dir_id, 
+		  INFO->current_ih->ih_key.k_objectid, 
+		  INFO->current_ih->ih_key.u.v1.k_offset,
+		  INFO->current_ih->ih_key.u.v1.k_uniqueness,
+		  INFO->current_ih->ih_version);
+#endif /* REISERDEBUG */
+	  
+	  if (INFO->current_ih->ih_key.k_objectid != objectid)
+	    break;
+	  
+	  name_end = INFO->current_item + INFO->current_ih->ih_item_len;
+	  de_head = (struct reiserfs_de_head *) INFO->current_item;
+	  num_entries = INFO->current_ih->u.ih_entry_count;
+	  while (num_entries > 0)
+	    {
+	      char *filename = INFO->current_item + de_head->deh_location;
+	      char  tmp = *name_end;
+	      if ((de_head->deh_state & DEH_Visible))
+		{
+		  int cmp;
+		  /* Directory names in ReiserFS are not null
+		   * terminated.  We write a temporary 0 behind it.
+		   * NOTE: that this may overwrite the first block in
+		   * the tree cache.  That doesn't hurt as long as we
+		   * don't call next_key () in between.  
+		   */
+		  *name_end = 0;
+		  cmp = substring (dirname, filename);
+		  *name_end = tmp;
+# ifndef STAGE1_5
+		  if (do_possibilities)
+		    {
+		      if (cmp <= 0)
+			{
+			  if (print_possibilities > 0)
+			    print_possibilities = -print_possibilities;
+			  *name_end = 0;
+			  print_a_completion (filename);
+			  *name_end = tmp;
+			}
+		    }
+		  else
+# endif /* ! STAGE1_5 */
+		    if (cmp == 0)
+		      goto found;
+		}
+	      /* The beginning of this name marks the end of the next name.
+	       */
+	      name_end = filename;
+	      de_head++;
+	      num_entries--;
+	    }
+	}
+      
+# ifndef STAGE1_5
+      if (print_possibilities < 0)
+	return 1;
+# endif /* ! STAGE1_5 */
+      
+      errnum = ERR_FILE_NOT_FOUND;
+      *rest = ch;
+      return 0;
+      
+    found:
+      
+      *rest = ch;
+      dirname = rest;
+
+      parent_dir_id = dir_id;
+      parent_objectid = objectid;
+      dir_id = de_head->deh_dir_id;
+      objectid = de_head->deh_objectid;
+    }
+}
+
+int
+reiserfs_embed (int *start_sector, int needed_sectors)
+{
+  struct reiserfs_super_block super;
+  int num_sectors;
+  
+  if (! devread (REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS, 0, 
+		 sizeof (struct reiserfs_super_block), (char *) &super))
+    return 0;
+  
+  *start_sector = 1; /* reserve first sector for stage1 */
+  if ((substring (REISERFS_SUPER_MAGIC_STRING, super.s_magic) <= 0
+       || substring (REISER2FS_SUPER_MAGIC_STRING, super.s_magic) <= 0
+       || substring (REISER3FS_SUPER_MAGIC_STRING, super.s_magic) <= 0)
+      && (/* check that this is not a super block copy inside
+	   * the journal log */
+	  super.s_journal_block * super.s_blocksize 
+	  > REISERFS_DISK_OFFSET_IN_BYTES))
+    num_sectors = (REISERFS_DISK_OFFSET_IN_BYTES >> SECTOR_BITS) - 1;
+  else
+    num_sectors = (REISERFS_OLD_DISK_OFFSET_IN_BYTES >> SECTOR_BITS) - 1;
+  
+  return (needed_sectors <= num_sectors);
+}
+#endif /* FSYS_REISERFS */
diff --git a/stage2/fsys_ufs2.c b/stage2/fsys_ufs2.c
new file mode 100644
index 0000000..698aca4
--- /dev/null
+++ b/stage2/fsys_ufs2.c
@@ -0,0 +1,331 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000, 2001  Free Software Foundation, Inc.
+ *  Copyright (c) 2004  Valery Hromov
+ *
+ *  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.
+ */
+
+/*
+ * Elements of this file were originally from the FreeBSD "biosboot"
+ * bootloader file "disk.c" dated 4/12/95.
+ *
+ * The license and header comments from that file are included here.
+ */
+
+/*
+ * Mach Operating System
+ * Copyright (c) 1992, 1991 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ *
+ *	from: Mach, Revision 2.2  92/04/04  11:35:49  rpd
+ *	$Id: fsys_ufs2.c,v 1.2 2004/06/19 12:17:52 okuji Exp $
+ */
+
+#ifdef FSYS_UFS2
+
+#include "shared.h"
+#include "filesys.h"
+
+#include "ufs2.h"
+
+/* used for filesystem map blocks */
+static int mapblock;
+static int mapblock_offset;
+static int mapblock_bsize;
+
+static int sblock_try[] = SBLOCKSEARCH;
+static ufs2_daddr_t sblockloc;
+static int type;
+
+/* pointer to superblock */
+#define SUPERBLOCK ((struct fs *) ( FSYS_BUF + 8192 ))
+
+#define INODE_UFS2 ((struct ufs2_dinode *) ( FSYS_BUF + 16384 ))
+
+#define MAPBUF ( FSYS_BUF + 24576 )
+#define MAPBUF_LEN 8192
+
+int
+ufs2_mount (void)
+{
+  int retval = 0;
+  int i;
+
+  sblockloc = -1;
+  type = 0;
+  
+  if (! (((current_drive & 0x80) || (current_slice != 0))
+	 && ! IS_PC_SLICE_TYPE_BSD_WITH_FS (current_slice, FS_BSDFFS)))
+    {
+      for (i = 0; sblock_try[i] != -1; ++i)
+	{
+	  if (! (part_length < (sblock_try[i] + (SBLOCKSIZE / DEV_BSIZE))
+		 || ! devread (0, sblock_try[i], SBLOCKSIZE, (char *) SUPERBLOCK)))
+	    {
+	      if (SUPERBLOCK->fs_magic == FS_UFS2_MAGIC /* &&
+							   (SUPERBLOCK->fs_sblockloc == sblockloc ||
+						     (SUPERBLOCK->fs_old_flags & FS_FLAGS_UPDATED) == 0)*/)
+		{
+		  type = 2;
+		}
+	      else
+		{
+		  continue;
+		}
+	      
+	      retval = 1;
+	      sblockloc = sblock_try[i];
+	      break;
+	    }
+	}
+    }
+  
+  mapblock = -1;
+  mapblock_offset = -1;
+  
+  return retval;
+}
+
+static grub_int64_t
+block_map (int file_block)
+{
+  int bnum, offset, bsize;
+  
+  if (file_block < NDADDR)
+    return (INODE_UFS2->di_db[file_block]);
+  
+  /* If the blockmap loaded does not include FILE_BLOCK,
+     load a new blockmap.  */
+
+  if ((bnum = fsbtodb (SUPERBLOCK, INODE_UFS2->di_ib[0])) != mapblock
+      || (mapblock_offset <= bnum && bnum <= mapblock_offset + mapblock_bsize))
+    {
+      if (MAPBUF_LEN < SUPERBLOCK->fs_bsize)
+	{
+	  offset = ((file_block - NDADDR) % NINDIR (SUPERBLOCK));
+	  bsize = MAPBUF_LEN;
+	  
+	  if (offset + MAPBUF_LEN > SUPERBLOCK->fs_bsize)
+	    offset = (SUPERBLOCK->fs_bsize - MAPBUF_LEN) / sizeof (int);
+	}
+      else
+	{
+	  bsize = SUPERBLOCK->fs_bsize;
+	  offset = 0;
+	}
+      
+      if (! devread (bnum, offset * sizeof (int), bsize, (char *) MAPBUF))
+	{
+	  mapblock = -1;
+	  mapblock_bsize = -1;
+	  mapblock_offset = -1;
+	  errnum = ERR_FSYS_CORRUPT;
+	  return -1;
+	}
+      
+      mapblock = bnum;
+      mapblock_bsize = bsize;
+      mapblock_offset = offset;
+    }
+  
+  return (((grub_int64_t *) MAPBUF)[((file_block - NDADDR) % NINDIR (SUPERBLOCK))
+				    - mapblock_offset]);
+}
+
+int
+ufs2_read (char *buf, int len)
+{
+  int logno, off, size, ret = 0;
+  grub_int64_t map;
+
+  while (len && !errnum)
+    {
+      off = blkoff (SUPERBLOCK, filepos);
+      logno = lblkno (SUPERBLOCK, filepos);
+      size = blksize (SUPERBLOCK, INODE_UFS2, logno);
+
+      if ((map = block_map (logno)) < 0)
+	break; 
+
+      size -= off;
+
+      if (size > len)
+	size = len;
+
+      disk_read_func = disk_read_hook;
+
+      devread (fsbtodb (SUPERBLOCK, map), off, size, buf);
+
+      disk_read_func = NULL;
+
+      buf += size;
+      len -= size;
+      filepos += size;
+      ret += size;
+    }
+
+  if (errnum)
+    ret = 0;
+
+  return ret;
+}
+
+int
+ufs2_dir (char *dirname)
+{
+  char *rest, ch;
+  int block, off, loc, ino = ROOTINO;
+  grub_int64_t map;
+  struct direct *dp;
+
+/* main loop to find destination inode */
+loop:
+
+  /* load current inode (defaults to the root inode) */
+
+    if (!devread (fsbtodb (SUPERBLOCK, ino_to_fsba (SUPERBLOCK, ino)),
+	    ino % (SUPERBLOCK->fs_inopb) * sizeof (struct ufs2_dinode),
+	    sizeof (struct ufs2_dinode), (char *) INODE_UFS2))
+		    return 0;			/* XXX what return value? */
+
+  /* if we have a real file (and we're not just printing possibilities),
+     then this is where we want to exit */
+
+  if (!*dirname || isspace (*dirname))
+    {
+      if ((INODE_UFS2->di_mode & IFMT) != IFREG)
+	{
+	  errnum = ERR_BAD_FILETYPE;
+	  return 0;
+	}
+
+      filemax = INODE_UFS2->di_size;
+
+      /* incomplete implementation requires this! */
+      fsmax = (NDADDR + NINDIR (SUPERBLOCK)) * SUPERBLOCK->fs_bsize;
+      return 1;
+    }
+
+  /* continue with file/directory name interpretation */
+
+  while (*dirname == '/')
+    dirname++;
+
+  if (!(INODE_UFS2->di_size) || ((INODE_UFS2->di_mode & IFMT) != IFDIR))
+    {
+      errnum = ERR_BAD_FILETYPE;
+      return 0;
+    }
+
+  for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++);
+
+  *rest = 0;
+  loc = 0;
+
+  /* loop for reading a the entries in a directory */
+
+  do
+    {
+      if (loc >= INODE_UFS2->di_size)
+	{
+	  if (print_possibilities < 0)
+	    return 1;
+
+	  errnum = ERR_FILE_NOT_FOUND;
+	  *rest = ch;
+	  return 0;
+	}
+
+      if (!(off = blkoff (SUPERBLOCK, loc)))
+	{
+	  block = lblkno (SUPERBLOCK, loc);
+
+	  if ((map = block_map (block)) < 0
+	      || !devread (fsbtodb (SUPERBLOCK, map), 0,
+			   blksize (SUPERBLOCK, INODE_UFS2, block),
+			   (char *) FSYS_BUF))
+	    {
+	      errnum = ERR_FSYS_CORRUPT;
+	      *rest = ch;
+	      return 0;
+	    }
+	}
+
+      dp = (struct direct *) (FSYS_BUF + off);
+      loc += dp->d_reclen;
+
+#ifndef STAGE1_5
+      if (dp->d_ino && print_possibilities && ch != '/'
+	  && (!*dirname || substring (dirname, dp->d_name) <= 0))
+	{
+	  if (print_possibilities > 0)
+	    print_possibilities = -print_possibilities;
+
+	  print_a_completion (dp->d_name);
+	}
+#endif /* STAGE1_5 */
+    }
+  while (!dp->d_ino || (substring (dirname, dp->d_name) != 0
+			|| (print_possibilities && ch != '/')));
+
+  /* only get here if we have a matching directory entry */
+
+  ino = dp->d_ino;
+  *(dirname = rest) = ch;
+
+  /* go back to main loop at top of function */
+  goto loop;
+}
+
+int
+ufs2_embed (int *start_sector, int needed_sectors)
+{
+  /* XXX: I don't know if this is really correct. Someone who is
+     familiar with BSD should check for this.  */
+  if (needed_sectors > 14)
+    return 0;
+  
+  *start_sector = 1;
+#if 1
+  /* FIXME: Disable the embedding in FFS until someone checks if
+     the code above is correct.  */
+  return 0;
+#else
+  return 1;
+#endif
+}
+
+#endif /* FSYS_UFS2 */
diff --git a/stage2/fsys_vstafs.c b/stage2/fsys_vstafs.c
new file mode 100644
index 0000000..a116717
--- /dev/null
+++ b/stage2/fsys_vstafs.c
@@ -0,0 +1,252 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2001   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.
+ */
+
+#ifdef FSYS_VSTAFS
+
+#include "shared.h"
+#include "filesys.h"
+#include "vstafs.h"
+
+
+static void get_file_info (int sector);
+static struct dir_entry *vstafs_readdir (long sector);
+static struct dir_entry *vstafs_nextdir (void);
+
+
+#define FIRST_SECTOR	((struct first_sector *) FSYS_BUF)
+#define FILE_INFO	((struct fs_file *) (int) FIRST_SECTOR + 8192)
+#define DIRECTORY_BUF	((struct dir_entry *) (int) FILE_INFO + 512)
+
+#define ROOT_SECTOR	1
+
+/*
+ * In f_sector we store the sector number in which the information about
+ * the found file is.
+ */
+extern int filepos;
+static int f_sector;
+
+int 
+vstafs_mount (void)
+{
+  int retval = 1;
+  
+  if( (((current_drive & 0x80) || (current_slice != 0))
+       && current_slice != PC_SLICE_TYPE_VSTAFS)
+      ||  ! devread (0, 0, BLOCK_SIZE, (char *) FSYS_BUF)
+      ||  FIRST_SECTOR->fs_magic != 0xDEADFACE)
+    retval = 0;
+  
+  return retval;
+}
+
+static void 
+get_file_info (int sector)
+{
+  devread (sector, 0, BLOCK_SIZE, (char *) FILE_INFO);
+}
+
+static int curr_ext, current_direntry, current_blockpos;
+static struct alloc *a;
+
+static struct dir_entry *
+vstafs_readdir (long sector)
+{
+  /*
+   * Get some information from the current directory
+   */
+  get_file_info (sector);
+  if (FILE_INFO->type != 2)
+    {
+      errnum = ERR_FILE_NOT_FOUND;
+      return 0;
+    }
+  
+  a = FILE_INFO->blocks;
+  curr_ext = 0;
+  devread (a[curr_ext].a_start, 0, 512, (char *) DIRECTORY_BUF);
+  current_direntry = 11;
+  current_blockpos = 0;
+  
+  return &DIRECTORY_BUF[10];
+}
+
+static struct dir_entry *
+vstafs_nextdir (void)
+{
+  if (current_direntry > 15)
+    {
+      current_direntry = 0;
+      if (++current_blockpos > (a[curr_ext].a_len - 1))
+	{
+	  current_blockpos = 0;
+	  curr_ext++;
+	}
+      
+      if (curr_ext < FILE_INFO->extents)
+	{
+	  devread (a[curr_ext].a_start + current_blockpos, 0,
+		   512, (char *) DIRECTORY_BUF);
+	}
+      else
+	{
+	  /* errnum =ERR_FILE_NOT_FOUND; */
+	  return 0;
+	}
+    }
+  
+  return &DIRECTORY_BUF[current_direntry++];
+}
+
+int 
+vstafs_dir (char *dirname)
+{
+  char *fn, ch;
+  struct dir_entry *d;
+  /* int l, i, s; */
+  
+  /*
+   * Read in the entries of the current directory.
+   */
+  f_sector = ROOT_SECTOR;
+  do
+    {
+      if (! (d = vstafs_readdir (f_sector)))
+	{
+	  return 0;
+	}
+      
+      /*
+       * Find the file in the path
+       */
+      while (*dirname == '/') dirname++;
+      fn = dirname;
+      while ((ch = *fn) && ch != '/' && ! isspace (ch)) fn++;
+      *fn = 0;
+      
+      do
+	{
+	  if (d->name[0] == 0 || d->name[0] & 0x80)
+	    continue;
+	  
+#ifndef STAGE1_5
+	  if (print_possibilities && ch != '/'
+	      && (! *dirname || strcmp (dirname, d->name) <= 0))
+	    {
+	      if (print_possibilities > 0)
+		print_possibilities = -print_possibilities;
+	      
+	      printf ("  %s", d->name);
+	    }
+#endif
+	  if (! grub_strcmp (dirname, d->name))
+	    {
+	      f_sector = d->start;
+	      get_file_info (f_sector);
+	      filemax = FILE_INFO->len; 
+	      break;
+	    }
+	}
+      while ((d =vstafs_nextdir ()));
+      
+      *(dirname = fn) = ch;
+      if (! d)
+	{
+	  if (print_possibilities < 0)
+	    {
+	      putchar ('\n');
+	      return 1;
+	    }
+	  
+	  errnum = ERR_FILE_NOT_FOUND;
+	  return 0;
+	}
+    }
+  while (*dirname && ! isspace (ch));
+  
+  return 1;
+}
+
+int 
+vstafs_read (char *addr, int len)
+{
+  struct alloc *a;
+  int size, ret = 0, offset, curr_len = 0;
+  int curr_ext;
+  char extent;
+  int ext_size;
+  char *curr_pos;
+  
+  get_file_info (f_sector);
+  size = FILE_INFO->len-VSTAFS_START_DATA;
+  a = FILE_INFO->blocks;
+  
+  if (filepos > 0)
+    {
+      if (filepos < a[0].a_len * 512 - VSTAFS_START_DATA)
+	{
+	  offset = filepos + VSTAFS_START_DATA;
+	  extent = 0;
+	  curr_len = a[0].a_len * 512 - offset - filepos; 
+	}
+      else
+	{
+	  ext_size = a[0].a_len * 512 - VSTAFS_START_DATA;
+	  offset = filepos - ext_size;
+	  extent = 1;
+	  do
+	    {
+	      curr_len -= ext_size;
+	      offset -= ext_size;
+	      ext_size = a[extent+1].a_len * 512;
+	    }
+	  while (extent < FILE_INFO->extents && offset>ext_size);
+	}
+    }
+  else
+    {
+      offset = VSTAFS_START_DATA;
+      extent = 0;
+      curr_len = a[0].a_len * 512 - offset;
+    }
+  
+  curr_pos = addr;
+  if (curr_len > len)
+    curr_len = len;
+  
+  for (curr_ext=extent;
+       curr_ext < FILE_INFO->extents; 
+       curr_len = a[curr_ext].a_len * 512, curr_pos += curr_len, curr_ext++)
+    {
+      ret += curr_len;
+      size -= curr_len;
+      if (size < 0)
+	{
+	  ret += size;
+	  curr_len += size;
+	}
+      
+      devread (a[curr_ext].a_start,offset, curr_len, curr_pos);
+      offset = 0;
+    }
+  
+  return ret;
+}
+
+#endif /* FSYS_VSTAFS */
diff --git a/stage2/fsys_xfs.c b/stage2/fsys_xfs.c
new file mode 100644
index 0000000..76c4c13
--- /dev/null
+++ b/stage2/fsys_xfs.c
@@ -0,0 +1,624 @@
+/* fsys_xfs.c - an implementation for the SGI XFS file system */
+/*  
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2001,2002,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 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifdef FSYS_XFS
+
+#include "shared.h"
+#include "filesys.h"
+#include "xfs.h"
+
+#define MAX_LINK_COUNT	8
+
+typedef struct xad {
+	xfs_fileoff_t offset;
+	xfs_fsblock_t start;
+	xfs_filblks_t len;
+} xad_t;
+
+struct xfs_info {
+	int bsize;
+	int dirbsize;
+	int isize;
+	unsigned int agblocks;
+	int bdlog;
+	int blklog;
+	int inopblog;
+	int agblklog;
+	int agnolog;
+	unsigned int nextents;
+	xfs_daddr_t next;
+	xfs_daddr_t daddr;
+	xfs_dablk_t forw;
+	xfs_dablk_t dablk;
+	xfs_bmbt_rec_32_t *xt;
+	xfs_bmbt_ptr_t ptr0;
+	int btnode_ptr0_off;
+	int i8param;
+	int dirpos;
+	int dirmax;
+	int blkoff;
+	int fpos;
+	xfs_ino_t rootino;
+};
+
+static struct xfs_info xfs;
+
+#define dirbuf		((char *)FSYS_BUF)
+#define filebuf		((char *)FSYS_BUF + 4096)
+#define inode		((xfs_dinode_t *)((char *)FSYS_BUF + 8192))
+#define icore		(inode->di_core)
+
+#define	mask32lo(n)	(((xfs_uint32_t)1 << (n)) - 1)
+
+#define	XFS_INO_MASK(k)		((xfs_uint32_t)((1ULL << (k)) - 1))
+#define	XFS_INO_OFFSET_BITS	xfs.inopblog
+#define	XFS_INO_AGBNO_BITS	xfs.agblklog
+#define	XFS_INO_AGINO_BITS	(xfs.agblklog + xfs.inopblog)
+#define	XFS_INO_AGNO_BITS	xfs.agnolog
+
+static inline xfs_agblock_t
+agino2agbno (xfs_agino_t agino)
+{
+	return agino >> XFS_INO_OFFSET_BITS;
+}
+
+static inline xfs_agnumber_t
+ino2agno (xfs_ino_t ino)
+{
+	return ino >> XFS_INO_AGINO_BITS;
+}
+
+static inline xfs_agino_t
+ino2agino (xfs_ino_t ino)
+{
+	return ino & XFS_INO_MASK(XFS_INO_AGINO_BITS);
+}
+
+static inline int
+ino2offset (xfs_ino_t ino)
+{
+	return ino & XFS_INO_MASK(XFS_INO_OFFSET_BITS);
+}
+
+static inline __const__ xfs_uint16_t
+le16 (xfs_uint16_t x)
+{
+	__asm__("xchgb %b0,%h0"	\
+		: "=q" (x) \
+		:  "0" (x)); \
+		return x;
+}
+
+static inline __const__ xfs_uint32_t
+le32 (xfs_uint32_t x)
+{
+#if 0
+        /* 386 doesn't have bswap.  */
+	__asm__("bswap %0" : "=r" (x) : "0" (x));
+#else
+	/* This is slower but this works on all x86 architectures.  */
+	__asm__("xchgb %b0, %h0" \
+		"\n\troll $16, %0" \
+		"\n\txchgb %b0, %h0" \
+		: "=q" (x) : "0" (x));
+#endif
+	return x;
+}
+
+static inline __const__ xfs_uint64_t
+le64 (xfs_uint64_t x)
+{
+	xfs_uint32_t h = x >> 32;
+        xfs_uint32_t l = x & ((1ULL<<32)-1);
+        return (((xfs_uint64_t)le32(l)) << 32) | ((xfs_uint64_t)(le32(h)));
+}
+
+
+static xfs_fsblock_t
+xt_start (xfs_bmbt_rec_32_t *r)
+{
+	return (((xfs_fsblock_t)(le32 (r->l1) & mask32lo(9))) << 43) | 
+	       (((xfs_fsblock_t)le32 (r->l2)) << 11) |
+	       (((xfs_fsblock_t)le32 (r->l3)) >> 21);
+}
+
+static xfs_fileoff_t
+xt_offset (xfs_bmbt_rec_32_t *r)
+{
+	return (((xfs_fileoff_t)le32 (r->l0) &
+		mask32lo(31)) << 23) |
+		(((xfs_fileoff_t)le32 (r->l1)) >> 9);
+}
+
+static xfs_filblks_t
+xt_len (xfs_bmbt_rec_32_t *r)
+{
+	return le32(r->l3) & mask32lo(21);
+}
+
+static inline int
+xfs_highbit32(xfs_uint32_t v)
+{
+	int i;
+
+	if (--v) {
+		for (i = 0; i < 31; i++, v >>= 1) {
+			if (v == 0)
+				return i;
+		}
+	}
+	return 0;
+}
+
+static int
+isinxt (xfs_fileoff_t key, xfs_fileoff_t offset, xfs_filblks_t len)
+{
+	return (key >= offset) ? (key < offset + len ? 1 : 0) : 0;
+}
+
+static xfs_daddr_t
+agb2daddr (xfs_agnumber_t agno, xfs_agblock_t agbno)
+{
+	return ((xfs_fsblock_t)agno*xfs.agblocks + agbno) << xfs.bdlog;
+}
+
+static xfs_daddr_t
+fsb2daddr (xfs_fsblock_t fsbno)
+{
+	return agb2daddr ((xfs_agnumber_t)(fsbno >> xfs.agblklog),
+			 (xfs_agblock_t)(fsbno & mask32lo(xfs.agblklog)));
+}
+
+#undef offsetof
+#define offsetof(t,m)	((int)&(((t *)0)->m))
+
+static inline int
+btroot_maxrecs (void)
+{
+	int tmp = icore.di_forkoff ? (icore.di_forkoff << 3) : xfs.isize;
+
+	return (tmp - sizeof(xfs_bmdr_block_t) - offsetof(xfs_dinode_t, di_u)) /
+		(sizeof (xfs_bmbt_key_t) + sizeof (xfs_bmbt_ptr_t));
+}
+
+static int
+di_read (xfs_ino_t ino)
+{
+	xfs_agino_t agino;
+	xfs_agnumber_t agno;
+	xfs_agblock_t agbno;
+	xfs_daddr_t daddr;
+	int offset;
+
+	agno = ino2agno (ino);
+	agino = ino2agino (ino);
+	agbno = agino2agbno (agino);
+	offset = ino2offset (ino);
+	daddr = agb2daddr (agno, agbno);
+
+	devread (daddr, offset*xfs.isize, xfs.isize, (char *)inode);
+
+	xfs.ptr0 = *(xfs_bmbt_ptr_t *)
+		    (inode->di_u.di_c + sizeof(xfs_bmdr_block_t)
+		    + btroot_maxrecs ()*sizeof(xfs_bmbt_key_t));
+
+	return 1;
+}
+
+static void
+init_extents (void)
+{
+	xfs_bmbt_ptr_t ptr0;
+	xfs_btree_lblock_t h;
+
+	switch (icore.di_format) {
+	case XFS_DINODE_FMT_EXTENTS:
+		xfs.xt = inode->di_u.di_bmx;
+		xfs.nextents = le32 (icore.di_nextents);
+		break;
+	case XFS_DINODE_FMT_BTREE:
+		ptr0 = xfs.ptr0;
+		for (;;) {
+			xfs.daddr = fsb2daddr (le64(ptr0));
+			devread (xfs.daddr, 0,
+				 sizeof(xfs_btree_lblock_t), (char *)&h);
+			if (!h.bb_level) {
+				xfs.nextents = le16(h.bb_numrecs);
+				xfs.next = fsb2daddr (le64(h.bb_rightsib));
+				xfs.fpos = sizeof(xfs_btree_block_t);
+				return;
+			}
+			devread (xfs.daddr, xfs.btnode_ptr0_off,
+				 sizeof(xfs_bmbt_ptr_t), (char *)&ptr0);
+		}
+	}
+}
+
+static xad_t *
+next_extent (void)
+{
+	static xad_t xad;
+
+	switch (icore.di_format) {
+	case XFS_DINODE_FMT_EXTENTS:
+		if (xfs.nextents == 0)
+			return NULL;
+		break;
+	case XFS_DINODE_FMT_BTREE:
+		if (xfs.nextents == 0) {
+			xfs_btree_lblock_t h;
+			if (xfs.next == 0)
+				return NULL;
+			xfs.daddr = xfs.next;
+			devread (xfs.daddr, 0, sizeof(xfs_btree_lblock_t), (char *)&h);
+			xfs.nextents = le16(h.bb_numrecs);
+			xfs.next = fsb2daddr (le64(h.bb_rightsib));
+			xfs.fpos = sizeof(xfs_btree_block_t);
+		}
+		/* Yeah, I know that's slow, but I really don't care */
+		devread (xfs.daddr, xfs.fpos, sizeof(xfs_bmbt_rec_t), filebuf);
+		xfs.xt = (xfs_bmbt_rec_32_t *)filebuf;
+		xfs.fpos += sizeof(xfs_bmbt_rec_32_t);
+	}
+	xad.offset = xt_offset (xfs.xt);
+	xad.start = xt_start (xfs.xt);
+	xad.len = xt_len (xfs.xt);
+	++xfs.xt;
+	--xfs.nextents;
+
+	return &xad;
+}
+
+/*
+ * Name lies - the function reads only first 100 bytes
+ */
+static void
+xfs_dabread (void)
+{
+	xad_t *xad;
+	xfs_fileoff_t offset;;
+
+	init_extents ();
+	while ((xad = next_extent ())) {
+		offset = xad->offset;
+		if (isinxt (xfs.dablk, offset, xad->len)) {
+			devread (fsb2daddr (xad->start + xfs.dablk - offset),
+				 0, 100, dirbuf);
+			break;
+		}
+	}
+}
+
+static inline xfs_ino_t
+sf_ino (char *sfe, int namelen)
+{
+	void *p = sfe + namelen + 3;
+
+	return (xfs.i8param == 0)
+		? le64(*(xfs_ino_t *)p) : le32(*(xfs_uint32_t *)p);
+}
+
+static inline xfs_ino_t
+sf_parent_ino (void)
+{
+	return (xfs.i8param == 0)
+		? le64(*(xfs_ino_t *)(&inode->di_u.di_dir2sf.hdr.parent))
+		: le32(*(xfs_uint32_t *)(&inode->di_u.di_dir2sf.hdr.parent));
+}
+
+static inline int
+roundup8 (int n)
+{
+	return ((n+7)&~7);
+}
+
+static char *
+next_dentry (xfs_ino_t *ino)
+{
+	int namelen = 1;
+	int toread;
+	static char usual[2][3] = {".", ".."};
+	static xfs_dir2_sf_entry_t *sfe;
+	char *name = usual[0];
+
+	if (xfs.dirpos >= xfs.dirmax) {
+		if (xfs.forw == 0)
+			return NULL;
+		xfs.dablk = xfs.forw;
+		xfs_dabread ();
+#define h	((xfs_dir2_leaf_hdr_t *)dirbuf)
+		xfs.dirmax = le16 (h->count) - le16 (h->stale);
+		xfs.forw = le32 (h->info.forw);
+#undef h
+		xfs.dirpos = 0;
+	}
+
+	switch (icore.di_format) {
+	case XFS_DINODE_FMT_LOCAL:
+		switch (xfs.dirpos) {
+		case -2:
+			*ino = 0;
+			break;
+		case -1:
+			*ino = sf_parent_ino ();
+			++name;
+			++namelen;
+			sfe = (xfs_dir2_sf_entry_t *)
+				(inode->di_u.di_c 
+				 + sizeof(xfs_dir2_sf_hdr_t)
+				 - xfs.i8param);
+			break;
+		default:
+			namelen = sfe->namelen;
+			*ino = sf_ino ((char *)sfe, namelen);
+			name = sfe->name;
+			sfe = (xfs_dir2_sf_entry_t *)
+				  ((char *)sfe + namelen + 11 - xfs.i8param);
+		}
+		break;
+	case XFS_DINODE_FMT_BTREE:
+	case XFS_DINODE_FMT_EXTENTS:
+#define dau	((xfs_dir2_data_union_t *)dirbuf)
+		for (;;) {
+			if (xfs.blkoff >= xfs.dirbsize) {
+				xfs.blkoff = sizeof(xfs_dir2_data_hdr_t);
+				filepos &= ~(xfs.dirbsize - 1);
+				filepos |= xfs.blkoff;
+			}
+			xfs_read (dirbuf, 4);
+			xfs.blkoff += 4;
+			if (dau->unused.freetag == XFS_DIR2_DATA_FREE_TAG) {
+				toread = roundup8 (le16(dau->unused.length)) - 4;
+				xfs.blkoff += toread;
+				filepos += toread;
+				continue;
+			}
+			break;
+		}
+		xfs_read ((char *)dirbuf + 4, 5);
+		*ino = le64 (dau->entry.inumber);
+		namelen = dau->entry.namelen;
+#undef dau
+		toread = roundup8 (namelen + 11) - 9;
+		xfs_read (dirbuf, toread);
+		name = (char *)dirbuf;
+		xfs.blkoff += toread + 5;
+	}
+	++xfs.dirpos;
+	name[namelen] = 0;
+
+	return name;
+}
+
+static char *
+first_dentry (xfs_ino_t *ino)
+{
+	xfs.forw = 0;
+	switch (icore.di_format) {
+	case XFS_DINODE_FMT_LOCAL:
+		xfs.dirmax = inode->di_u.di_dir2sf.hdr.count;
+		xfs.i8param = inode->di_u.di_dir2sf.hdr.i8count ? 0 : 4;
+		xfs.dirpos = -2;
+		break;
+	case XFS_DINODE_FMT_EXTENTS:
+	case XFS_DINODE_FMT_BTREE:
+		filepos = 0;
+		xfs_read (dirbuf, sizeof(xfs_dir2_data_hdr_t));
+		if (((xfs_dir2_data_hdr_t *)dirbuf)->magic == le32(XFS_DIR2_BLOCK_MAGIC)) {
+#define tail		((xfs_dir2_block_tail_t *)dirbuf)
+			filepos = xfs.dirbsize - sizeof(*tail);
+			xfs_read (dirbuf, sizeof(*tail));
+			xfs.dirmax = le32 (tail->count) - le32 (tail->stale);
+#undef tail
+		} else {
+			xfs.dablk = (1ULL << 35) >> xfs.blklog;
+#define h		((xfs_dir2_leaf_hdr_t *)dirbuf)
+#define n		((xfs_da_intnode_t *)dirbuf)
+			for (;;) {
+				xfs_dabread ();
+				if ((n->hdr.info.magic == le16(XFS_DIR2_LEAFN_MAGIC))
+				    || (n->hdr.info.magic == le16(XFS_DIR2_LEAF1_MAGIC))) {
+					xfs.dirmax = le16 (h->count) - le16 (h->stale);
+					xfs.forw = le32 (h->info.forw);
+					break;
+				}
+				xfs.dablk = le32 (n->btree[0].before);
+			}
+#undef n
+#undef h
+		}
+		xfs.blkoff = sizeof(xfs_dir2_data_hdr_t);
+		filepos = xfs.blkoff;
+		xfs.dirpos = 0;
+	}
+	return next_dentry (ino);
+}
+
+int
+xfs_mount (void)
+{
+	xfs_sb_t super;
+
+	if (!devread (0, 0, sizeof(super), (char *)&super)
+	    || (le32(super.sb_magicnum) != XFS_SB_MAGIC)
+	    || ((le16(super.sb_versionnum) 
+		& XFS_SB_VERSION_NUMBITS) != XFS_SB_VERSION_4) ) {
+		return 0;
+	}
+
+	xfs.bsize = le32 (super.sb_blocksize);
+	xfs.blklog = super.sb_blocklog;
+	xfs.bdlog = xfs.blklog - SECTOR_BITS;
+	xfs.rootino = le64 (super.sb_rootino);
+	xfs.isize = le16 (super.sb_inodesize);
+	xfs.agblocks = le32 (super.sb_agblocks);
+	xfs.dirbsize = xfs.bsize << super.sb_dirblklog;
+
+	xfs.inopblog = super.sb_inopblog;
+	xfs.agblklog = super.sb_agblklog;
+	xfs.agnolog = xfs_highbit32 (le32(super.sb_agcount));
+
+	xfs.btnode_ptr0_off =
+		((xfs.bsize - sizeof(xfs_btree_block_t)) /
+		(sizeof (xfs_bmbt_key_t) + sizeof (xfs_bmbt_ptr_t)))
+		 * sizeof(xfs_bmbt_key_t) + sizeof(xfs_btree_block_t);
+
+	return 1;
+}
+
+int
+xfs_read (char *buf, int len)
+{
+	xad_t *xad;
+	xfs_fileoff_t endofprev, endofcur, offset;
+	xfs_filblks_t xadlen;
+	int toread, startpos, endpos;
+
+	if (icore.di_format == XFS_DINODE_FMT_LOCAL) {
+		grub_memmove (buf, inode->di_u.di_c + filepos, len);
+		filepos += len;
+		return len;
+	}
+
+	startpos = filepos;
+	endpos = filepos + len;
+	endofprev = (xfs_fileoff_t)-1;
+	init_extents ();
+	while (len > 0 && (xad = next_extent ())) {
+		offset = xad->offset;
+		xadlen = xad->len;
+		if (isinxt (filepos >> xfs.blklog, offset, xadlen)) {
+			endofcur = (offset + xadlen) << xfs.blklog; 
+			toread = (endofcur >= endpos)
+				  ? len : (endofcur - filepos);
+
+			disk_read_func = disk_read_hook;
+			devread (fsb2daddr (xad->start),
+				 filepos - (offset << xfs.blklog), toread, buf);
+			disk_read_func = NULL;
+
+			buf += toread;
+			len -= toread;
+			filepos += toread;
+		} else if (offset > endofprev) {
+			toread = ((offset << xfs.blklog) >= endpos)
+				  ? len : ((offset - endofprev) << xfs.blklog);
+			len -= toread;
+			filepos += toread;
+			for (; toread; toread--) {
+				*buf++ = 0;
+			}
+			continue;
+		}
+		endofprev = offset + xadlen; 
+	}
+
+	return filepos - startpos;
+}
+
+int
+xfs_dir (char *dirname)
+{
+	xfs_ino_t ino, parent_ino, new_ino;
+	xfs_fsize_t di_size;
+	int di_mode;
+	int cmp, n, link_count;
+	char linkbuf[xfs.bsize];
+	char *rest, *name, ch;
+
+	parent_ino = ino = xfs.rootino;
+	link_count = 0;
+	for (;;) {
+		di_read (ino);
+		di_size = le64 (icore.di_size);
+		di_mode = le16 (icore.di_mode);
+
+		if ((di_mode & IFMT) == IFLNK) {
+			if (++link_count > MAX_LINK_COUNT) {
+				errnum = ERR_SYMLINK_LOOP;
+				return 0;
+			}
+			if (di_size < xfs.bsize - 1) {
+				filepos = 0;
+				filemax = di_size;
+				n = xfs_read (linkbuf, filemax);
+			} else {
+				errnum = ERR_FILELENGTH;
+				return 0;
+			}
+
+			ino = (linkbuf[0] == '/') ? xfs.rootino : parent_ino;
+			while (n < (xfs.bsize - 1) && (linkbuf[n++] = *dirname++));
+			linkbuf[n] = 0;
+			dirname = linkbuf;
+			continue;
+		}
+
+		if (!*dirname || isspace (*dirname)) {
+			if ((di_mode & IFMT) != IFREG) {
+				errnum = ERR_BAD_FILETYPE;
+				return 0;
+			}
+			filepos = 0;
+			filemax = di_size;
+			return 1;
+		}
+
+		if ((di_mode & IFMT) != IFDIR) {
+			errnum = ERR_BAD_FILETYPE;
+			return 0;
+		}
+
+		for (; *dirname == '/'; dirname++);
+
+		for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/'; rest++);
+		*rest = 0;
+
+		name = first_dentry (&new_ino);
+		for (;;) {
+			cmp = (!*dirname) ? -1 : substring (dirname, name);
+#ifndef STAGE1_5
+			if (print_possibilities && ch != '/' && cmp <= 0) {
+				if (print_possibilities > 0)
+					print_possibilities = -print_possibilities;
+				print_a_completion (name);
+			} else
+#endif
+			if (cmp == 0) {
+				parent_ino = ino;
+				if (new_ino)
+					ino = new_ino;
+		        	*(dirname = rest) = ch;
+				break;
+			}
+			name = next_dentry (&new_ino);
+			if (name == NULL) {
+				if (print_possibilities < 0)
+					return 1;
+
+				errnum = ERR_FILE_NOT_FOUND;
+				*rest = ch;
+				return 0;
+			}
+		}
+	}
+}
+
+#endif /* FSYS_XFS */
diff --git a/stage2/gunzip.c b/stage2/gunzip.c
new file mode 100644
index 0000000..8835089
--- /dev/null
+++ b/stage2/gunzip.c
@@ -0,0 +1,1235 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999  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.
+ */
+
+/*
+ * Most of this file was originally the source file "inflate.c", written
+ * by Mark Adler.  It has been very heavily modified.  In particular, the
+ * original would run through the whole file at once, and this version can
+ * be stopped and restarted on any boundary during the decompression process.
+ *
+ * The license and header comments that file are included here.
+ */
+
+/* inflate.c -- Not copyrighted 1992 by Mark Adler
+   version c10p1, 10 January 1993 */
+
+/* You can do whatever you like with this source file, though I would
+   prefer that if you modify it and redistribute it that you include
+   comments to that effect with your name and the date.  Thank you.
+ */
+
+/*
+   Inflate deflated (PKZIP's method 8 compressed) data.  The compression
+   method searches for as much of the current string of bytes (up to a
+   length of 258) in the previous 32K bytes.  If it doesn't find any
+   matches (of at least length 3), it codes the next byte.  Otherwise, it
+   codes the length of the matched string and its distance backwards from
+   the current position.  There is a single Huffman code that codes both
+   single bytes (called "literals") and match lengths.  A second Huffman
+   code codes the distance information, which follows a length code.  Each
+   length or distance code actually represents a base value and a number
+   of "extra" (sometimes zero) bits to get to add to the base value.  At
+   the end of each deflated block is a special end-of-block (EOB) literal/
+   length code.  The decoding process is basically: get a literal/length
+   code; if EOB then done; if a literal, emit the decoded byte; if a
+   length then get the distance and emit the referred-to bytes from the
+   sliding window of previously emitted data.
+
+   There are (currently) three kinds of inflate blocks: stored, fixed, and
+   dynamic.  The compressor deals with some chunk of data at a time, and
+   decides which method to use on a chunk-by-chunk basis.  A chunk might
+   typically be 32K or 64K.  If the chunk is uncompressible, then the
+   "stored" method is used.  In this case, the bytes are simply stored as
+   is, eight bits per byte, with none of the above coding.  The bytes are
+   preceded by a count, since there is no longer an EOB code.
+
+   If the data is compressible, then either the fixed or dynamic methods
+   are used.  In the dynamic method, the compressed data is preceded by
+   an encoding of the literal/length and distance Huffman codes that are
+   to be used to decode this block.  The representation is itself Huffman
+   coded, and so is preceded by a description of that code.  These code
+   descriptions take up a little space, and so for small blocks, there is
+   a predefined set of codes, called the fixed codes.  The fixed method is
+   used if the block codes up smaller that way (usually for quite small
+   chunks), otherwise the dynamic method is used.  In the latter case, the
+   codes are customized to the probabilities in the current block, and so
+   can code it much better than the pre-determined fixed codes.
+
+   The Huffman codes themselves are decoded using a mutli-level table
+   lookup, in order to maximize the speed of decoding plus the speed of
+   building the decoding tables.  See the comments below that precede the
+   lbits and dbits tuning parameters.
+ */
+
+
+/*
+   Notes beyond the 1.93a appnote.txt:
+
+   1. Distance pointers never point before the beginning of the output
+      stream.
+   2. Distance pointers can point back across blocks, up to 32k away.
+   3. There is an implied maximum of 7 bits for the bit length table and
+      15 bits for the actual data.
+   4. If only one code exists, then it is encoded using one bit.  (Zero
+      would be more efficient, but perhaps a little confusing.)  If two
+      codes exist, they are coded using one bit each (0 and 1).
+   5. There is no way of sending zero distance codes--a dummy must be
+      sent if there are none.  (History: a pre 2.0 version of PKZIP would
+      store blocks with no distance codes, but this was discovered to be
+      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
+      zero distance codes, which is sent as one code of zero bits in
+      length.
+   6. There are up to 286 literal/length codes.  Code 256 represents the
+      end-of-block.  Note however that the static length tree defines
+      288 codes just to fill out the Huffman codes.  Codes 286 and 287
+      cannot be used though, since there is no length base or extra bits
+      defined for them.  Similarly, there are up to 30 distance codes.
+      However, static trees define 32 codes (all 5 bits) to fill out the
+      Huffman codes, but the last two had better not show up in the data.
+   7. Unzip can check dynamic Huffman blocks for complete code sets.
+      The exception is that a single code would not be complete (see #4).
+   8. The five bits following the block type is really the number of
+      literal codes sent minus 257.
+   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
+      (1+6+6).  Therefore, to output three times the length, you output
+      three codes (1+1+1), whereas to output four times the same length,
+      you only need two codes (1+3).  Hmm.
+  10. In the tree reconstruction algorithm, Code = Code + Increment
+      only if BitLength(i) is not zero.  (Pretty obvious.)
+  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)
+  12. Note: length code 284 can represent 227-258, but length code 285
+      really is 258.  The last length deserves its own, short code
+      since it gets used a lot in very redundant files.  The length
+      258 is special since 258 - 3 (the min match length) is 255.
+  13. The literal/length and distance code bit lengths are read as a
+      single stream of lengths.  It is possible (and advantageous) for
+      a repeat code (16, 17, or 18) to go across the boundary between
+      the two sets of lengths.
+ */
+
+#ifndef NO_DECOMPRESSION
+
+#include "shared.h"
+
+#include "filesys.h"
+
+/* so we can disable decompression  */
+int no_decompression = 0;
+
+/* used to tell if "read" should be redirected to "gunzip_read" */
+int compressed_file;
+
+/* internal variables only */
+static int gzip_data_offset;
+static int gzip_filepos;
+static int gzip_filemax;
+static int gzip_fsmax;
+static int saved_filepos;
+static unsigned long gzip_crc;
+
+/* internal extra variables for use of inflate code */
+static int block_type;
+static int block_len;
+static int last_block;
+static int code_state;
+
+
+/* Function prototypes */
+static void initialize_tables (void);
+
+/*
+ *  Linear allocator.
+ */
+
+static unsigned long linalloc_topaddr;
+
+static void *
+linalloc (int size)
+{
+  linalloc_topaddr = (linalloc_topaddr - size) & ~3;
+  return (void *) linalloc_topaddr;
+}
+
+static void
+reset_linalloc (void)
+{
+  linalloc_topaddr = RAW_ADDR ((mbi.mem_upper << 10) + 0x100000);
+}
+
+
+/* internal variable swap function */
+static void
+gunzip_swap_values (void)
+{
+  register int itmp;
+
+  /* swap filepos */
+  itmp = filepos;
+  filepos = gzip_filepos;
+  gzip_filepos = itmp;
+
+  /* swap filemax */
+  itmp = filemax;
+  filemax = gzip_filemax;
+  gzip_filemax = itmp;
+
+  /* swap fsmax */
+  itmp = fsmax;
+  fsmax = gzip_fsmax;
+  gzip_fsmax = itmp;
+}
+
+
+/* internal function for eating variable-length header fields */
+static int
+bad_field (int len)
+{
+  char ch = 1;
+  int not_retval = 1;
+
+  do
+    {
+      if (len >= 0)
+	{
+	  if (!(len--))
+	    break;
+	}
+      else
+	{
+	  if (!ch)
+	    break;
+	}
+    }
+  while ((not_retval = grub_read (&ch, 1)) == 1);
+
+  return (!not_retval);
+}
+
+
+/* Little-Endian defines for the 2-byte magic number for gzip files */
+#define GZIP_HDR_LE      0x8B1F
+#define OLD_GZIP_HDR_LE  0x9E1F
+
+/* Compression methods (see algorithm.doc) */
+#define STORED      0
+#define COMPRESSED  1
+#define PACKED      2
+#define LZHED       3
+/* methods 4 to 7 reserved */
+#define DEFLATED    8
+#define MAX_METHODS 9
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01	/* bit 0 set: file probably ascii text */
+#define CONTINUATION 0x02	/* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04	/* bit 2 set: extra field present */
+#define ORIG_NAME    0x08	/* bit 3 set: original file name present */
+#define COMMENT      0x10	/* bit 4 set: file comment present */
+#define ENCRYPTED    0x20	/* bit 5 set: file is encrypted */
+#define RESERVED     0xC0	/* bit 6,7:   reserved */
+
+#define UNSUPP_FLAGS (CONTINUATION|ENCRYPTED|RESERVED)
+
+/* inflate block codes */
+#define INFLATE_STORED    0
+#define INFLATE_FIXED     1
+#define INFLATE_DYNAMIC   2
+
+typedef unsigned char uch;
+typedef unsigned short ush;
+typedef unsigned long ulg;
+
+/*
+ *  Window Size
+ *
+ *  This must be a power of two, and at least 32K for zip's deflate method
+ */
+
+#define WSIZE 0x8000
+
+
+int
+gunzip_test_header (void)
+{
+  unsigned char buf[10];
+  
+  /* "compressed_file" is already reset to zero by this point */
+
+  /*
+   *  This checks if the file is gzipped.  If a problem occurs here
+   *  (other than a real error with the disk) then we don't think it
+   *  is a compressed file, and simply mark it as such.
+   */
+  if (no_decompression
+      || grub_read (buf, 10) != 10
+      || ((*((unsigned short *) buf) != GZIP_HDR_LE)
+	  && (*((unsigned short *) buf) != OLD_GZIP_HDR_LE)))
+    {
+      filepos = 0;
+      return ! errnum;
+    }
+
+  /*
+   *  This does consistency checking on the header data.  If a
+   *  problem occurs from here on, then we have corrupt or otherwise
+   *  bad data, and the error should be reported to the user.
+   */
+  if (buf[2] != DEFLATED
+      || (buf[3] & UNSUPP_FLAGS)
+      || ((buf[3] & EXTRA_FIELD)
+	  && (grub_read (buf, 2) != 2
+	      || bad_field (*((unsigned short *) buf))))
+      || ((buf[3] & ORIG_NAME) && bad_field (-1))
+      || ((buf[3] & COMMENT) && bad_field (-1)))
+    {
+      if (! errnum)
+	errnum = ERR_BAD_GZIP_HEADER;
+      
+      return 0;
+    }
+
+  gzip_data_offset = filepos;
+  
+  filepos = filemax - 8;
+  
+  if (grub_read (buf, 8) != 8)
+    {
+      if (! errnum)
+	errnum = ERR_BAD_GZIP_HEADER;
+      
+      return 0;
+    }
+
+  gzip_crc = *((unsigned long *) buf);
+  gzip_fsmax = gzip_filemax = *((unsigned long *) (buf + 4));
+
+  initialize_tables ();
+
+  compressed_file = 1;
+  gunzip_swap_values ();
+  /*
+   *  Now "gzip_*" values refer to the compressed data.
+   */
+
+  filepos = 0;
+
+  return 1;
+}
+
+
+/* Huffman code lookup table entry--this entry is four bytes for machines
+   that have 16-bit pointers (e.g. PC's in the small or medium model).
+   Valid extra bits are 0..13.  e == 15 is EOB (end of block), e == 16
+   means that v is a literal, 16 < e < 32 means that v is a pointer to
+   the next table, which codes e - 16 bits, and lastly e == 99 indicates
+   an unused code.  If a code with e == 99 is looked up, this implies an
+   error in the data. */
+struct huft
+{
+  uch e;			/* number of extra bits or operation */
+  uch b;			/* number of bits in this code or subcode */
+  union
+    {
+      ush n;			/* literal, length base, or distance base */
+      struct huft *t;		/* pointer to next level of table */
+    }
+  v;
+};
+
+
+/* The inflate algorithm uses a sliding 32K byte window on the uncompressed
+   stream to find repeated byte strings.  This is implemented here as a
+   circular buffer.  The index is updated simply by incrementing and then
+   and'ing with 0x7fff (32K-1). */
+/* It is left to other modules to supply the 32K area.  It is assumed
+   to be usable as if it were declared "uch slide[32768];" or as just
+   "uch *slide;" and then malloc'ed in the latter case.  The definition
+   must be in unzip.h, included above. */
+
+
+/* sliding window in uncompressed data */
+static uch slide[WSIZE];
+
+/* current position in slide */
+static unsigned wp;
+
+
+/* Tables for deflate from PKZIP's appnote.txt. */
+static unsigned bitorder[] =
+{				/* Order of the bit length code lengths */
+  16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+static ush cplens[] =
+{				/* Copy lengths for literal codes 257..285 */
+  3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+  35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+	/* note: see note #13 above about the 258 in this list. */
+static ush cplext[] =
+{				/* Extra bits for literal codes 257..285 */
+  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+  3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99};	/* 99==invalid */
+static ush cpdist[] =
+{				/* Copy offsets for distance codes 0..29 */
+  1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+  257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+  8193, 12289, 16385, 24577};
+static ush cpdext[] =
+{				/* Extra bits for distance codes */
+  0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+  7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+  12, 12, 13, 13};
+
+
+/*
+   Huffman code decoding is performed using a multi-level table lookup.
+   The fastest way to decode is to simply build a lookup table whose
+   size is determined by the longest code.  However, the time it takes
+   to build this table can also be a factor if the data being decoded
+   is not very long.  The most common codes are necessarily the
+   shortest codes, so those codes dominate the decoding time, and hence
+   the speed.  The idea is you can have a shorter table that decodes the
+   shorter, more probable codes, and then point to subsidiary tables for
+   the longer codes.  The time it costs to decode the longer codes is
+   then traded against the time it takes to make longer tables.
+
+   This results of this trade are in the variables lbits and dbits
+   below.  lbits is the number of bits the first level table for literal/
+   length codes can decode in one step, and dbits is the same thing for
+   the distance codes.  Subsequent tables are also less than or equal to
+   those sizes.  These values may be adjusted either when all of the
+   codes are shorter than that, in which case the longest code length in
+   bits is used, or when the shortest code is *longer* than the requested
+   table size, in which case the length of the shortest code in bits is
+   used.
+
+   There are two different values for the two tables, since they code a
+   different number of possibilities each.  The literal/length table
+   codes 286 possible values, or in a flat code, a little over eight
+   bits.  The distance table codes 30 possible values, or a little less
+   than five bits, flat.  The optimum values for speed end up being
+   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
+   The optimum values may differ though from machine to machine, and
+   possibly even between compilers.  Your mileage may vary.
+ */
+
+
+static int lbits = 9;		/* bits in base literal/length lookup table */
+static int dbits = 6;		/* bits in base distance lookup table */
+
+
+/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
+#define BMAX 16			/* maximum bit length of any code (16 for explode) */
+#define N_MAX 288		/* maximum number of codes in any set */
+
+
+static unsigned hufts;		/* track memory usage */
+
+
+/* Macros for inflate() bit peeking and grabbing.
+   The usage is:
+
+        NEEDBITS(j)
+        x = b & mask_bits[j];
+        DUMPBITS(j)
+
+   where NEEDBITS makes sure that b has at least j bits in it, and
+   DUMPBITS removes the bits from b.  The macros use the variable k
+   for the number of bits in b.  Normally, b and k are register
+   variables for speed, and are initialized at the beginning of a
+   routine that uses these macros from a global bit buffer and count.
+
+   If we assume that EOB will be the longest code, then we will never
+   ask for bits with NEEDBITS that are beyond the end of the stream.
+   So, NEEDBITS should not read any more bytes than are needed to
+   meet the request.  Then no bytes need to be "returned" to the buffer
+   at the end of the last block.
+
+   However, this assumption is not true for fixed blocks--the EOB code
+   is 7 bits, but the other literal/length codes can be 8 or 9 bits.
+   (The EOB code is shorter than other codes because fixed blocks are
+   generally short.  So, while a block always has an EOB, many other
+   literal/length codes have a significantly lower probability of
+   showing up at all.)  However, by making the first table have a
+   lookup of seven bits, the EOB code will be found in that first
+   lookup, and so will not require that too many bits be pulled from
+   the stream.
+ */
+
+static ulg bb;			/* bit buffer */
+static unsigned bk;		/* bits in bit buffer */
+
+static ush mask_bits[] =
+{
+  0x0000,
+  0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+  0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+
+#define NEEDBITS(n) do {while(k<(n)){b|=((ulg)get_byte())<<k;k+=8;}} while (0)
+#define DUMPBITS(n) do {b>>=(n);k-=(n);} while (0)
+
+#define INBUFSIZ  0x2000
+
+static uch inbuf[INBUFSIZ];
+static int bufloc;
+
+static int
+get_byte (void)
+{
+  if (filepos == gzip_data_offset || bufloc == INBUFSIZ)
+    {
+      bufloc = 0;
+      grub_read (inbuf, INBUFSIZ);
+    }
+
+  return inbuf[bufloc++];
+}
+
+/* decompression global pointers */
+static struct huft *tl;		/* literal/length code table */
+static struct huft *td;		/* distance code table */
+static int bl;			/* lookup bits for tl */
+static int bd;			/* lookup bits for td */
+
+
+/* more function prototypes */
+static int huft_build (unsigned *, unsigned, unsigned, ush *, ush *,
+		       struct huft **, int *);
+static int inflate_codes_in_window (void);
+
+
+/* Given a list of code lengths and a maximum table size, make a set of
+   tables to decode that set of codes.  Return zero on success, one if
+   the given code set is incomplete (the tables are still built in this
+   case), two if the input is invalid (all zero length codes or an
+   oversubscribed set of lengths), and three if not enough memory. */
+
+static int
+huft_build (unsigned *b,	/* code lengths in bits (all assumed <= BMAX) */
+	    unsigned n,		/* number of codes (assumed <= N_MAX) */
+	    unsigned s,		/* number of simple-valued codes (0..s-1) */
+	    ush * d,		/* list of base values for non-simple codes */
+	    ush * e,		/* list of extra bits for non-simple codes */
+	    struct huft **t,	/* result: starting table */
+	    int *m)		/* maximum lookup bits, returns actual */
+{
+  unsigned a;			/* counter for codes of length k */
+  unsigned c[BMAX + 1];		/* bit length count table */
+  unsigned f;			/* i repeats in table every f entries */
+  int g;			/* maximum code length */
+  int h;			/* table level */
+  register unsigned i;		/* counter, current code */
+  register unsigned j;		/* counter */
+  register int k;		/* number of bits in current code */
+  int l;			/* bits per table (returned in m) */
+  register unsigned *p;		/* pointer into c[], b[], or v[] */
+  register struct huft *q;	/* points to current table */
+  struct huft r;		/* table entry for structure assignment */
+  struct huft *u[BMAX];		/* table stack */
+  unsigned v[N_MAX];		/* values in order of bit length */
+  register int w;		/* bits before this table == (l * h) */
+  unsigned x[BMAX + 1];		/* bit offsets, then code stack */
+  unsigned *xp;			/* pointer into x */
+  int y;			/* number of dummy codes added */
+  unsigned z;			/* number of entries in current table */
+
+  /* Generate counts for each bit length */
+  memset ((char *) c, 0, sizeof (c));
+  p = b;
+  i = n;
+  do
+    {
+      c[*p]++;			/* assume all entries <= BMAX */
+      p++;			/* Can't combine with above line (Solaris bug) */
+    }
+  while (--i);
+  if (c[0] == n)		/* null input--all zero length codes */
+    {
+      *t = (struct huft *) NULL;
+      *m = 0;
+      return 0;
+    }
+
+  /* Find minimum and maximum length, bound *m by those */
+  l = *m;
+  for (j = 1; j <= BMAX; j++)
+    if (c[j])
+      break;
+  k = j;			/* minimum code length */
+  if ((unsigned) l < j)
+    l = j;
+  for (i = BMAX; i; i--)
+    if (c[i])
+      break;
+  g = i;			/* maximum code length */
+  if ((unsigned) l > i)
+    l = i;
+  *m = l;
+
+  /* Adjust last length count to fill out codes, if needed */
+  for (y = 1 << j; j < i; j++, y <<= 1)
+    if ((y -= c[j]) < 0)
+      return 2;			/* bad input: more codes than bits */
+  if ((y -= c[i]) < 0)
+    return 2;
+  c[i] += y;
+
+  /* Generate starting offsets into the value table for each length */
+  x[1] = j = 0;
+  p = c + 1;
+  xp = x + 2;
+  while (--i)
+    {				/* note that i == g from above */
+      *xp++ = (j += *p++);
+    }
+
+  /* Make a table of values in order of bit lengths */
+  p = b;
+  i = 0;
+  do
+    {
+      if ((j = *p++) != 0)
+	v[x[j]++] = i;
+    }
+  while (++i < n);
+
+  /* Generate the Huffman codes and for each, make the table entries */
+  x[0] = i = 0;			/* first Huffman code is zero */
+  p = v;			/* grab values in bit order */
+  h = -1;			/* no tables yet--level -1 */
+  w = -l;			/* bits decoded == (l * h) */
+  u[0] = (struct huft *) NULL;	/* just to keep compilers happy */
+  q = (struct huft *) NULL;	/* ditto */
+  z = 0;			/* ditto */
+
+  /* go through the bit lengths (k already is bits in shortest code) */
+  for (; k <= g; k++)
+    {
+      a = c[k];
+      while (a--)
+	{
+	  /* here i is the Huffman code of length k bits for value *p */
+	  /* make tables up to required level */
+	  while (k > w + l)
+	    {
+	      h++;
+	      w += l;		/* previous table always l bits */
+
+	      /* compute minimum size table less than or equal to l bits */
+	      z = (z = g - w) > (unsigned) l ? l : z;	/* upper limit on table size */
+	      if ((f = 1 << (j = k - w)) > a + 1)	/* try a k-w bit table */
+		{		/* too few codes for k-w bit table */
+		  f -= a + 1;	/* deduct codes from patterns left */
+		  xp = c + k;
+		  while (++j < z)	/* try smaller tables up to z bits */
+		    {
+		      if ((f <<= 1) <= *++xp)
+			break;	/* enough codes to use up j bits */
+		      f -= *xp;	/* else deduct codes from patterns */
+		    }
+		}
+	      z = 1 << j;	/* table entries for j-bit table */
+
+	      /* allocate and link in new table */
+	      q = (struct huft *) linalloc ((z + 1) * sizeof (struct huft));
+
+	      hufts += z + 1;	/* track memory usage */
+	      *t = q + 1;	/* link to list for huft_free() */
+	      *(t = &(q->v.t)) = (struct huft *) NULL;
+	      u[h] = ++q;	/* table starts after link */
+
+	      /* connect to last table, if there is one */
+	      if (h)
+		{
+		  x[h] = i;	/* save pattern for backing up */
+		  r.b = (uch) l;	/* bits to dump before this table */
+		  r.e = (uch) (16 + j);		/* bits in this table */
+		  r.v.t = q;	/* pointer to this table */
+		  j = i >> (w - l);	/* (get around Turbo C bug) */
+		  u[h - 1][j] = r;	/* connect to last table */
+		}
+	    }
+
+	  /* set up table entry in r */
+	  r.b = (uch) (k - w);
+	  if (p >= v + n)
+	    r.e = 99;		/* out of values--invalid code */
+	  else if (*p < s)
+	    {
+	      r.e = (uch) (*p < 256 ? 16 : 15);		/* 256 is end-of-block code */
+	      r.v.n = (ush) (*p);	/* simple code is just the value */
+	      p++;		/* one compiler does not like *p++ */
+	    }
+	  else
+	    {
+	      r.e = (uch) e[*p - s];	/* non-simple--look up in lists */
+	      r.v.n = d[*p++ - s];
+	    }
+
+	  /* fill code-like entries with r */
+	  f = 1 << (k - w);
+	  for (j = i >> w; j < z; j += f)
+	    q[j] = r;
+
+	  /* backwards increment the k-bit code i */
+	  for (j = 1 << (k - 1); i & j; j >>= 1)
+	    i ^= j;
+	  i ^= j;
+
+	  /* backup over finished tables */
+	  while ((i & ((1 << w) - 1)) != x[h])
+	    {
+	      h--;		/* don't need to update q */
+	      w -= l;
+	    }
+	}
+    }
+
+  /* Return true (1) if we were given an incomplete table */
+  return y != 0 && g != 1;
+}
+
+
+/*
+ *  inflate (decompress) the codes in a deflated (compressed) block.
+ *  Return an error code or zero if it all goes ok.
+ */
+
+static unsigned inflate_n, inflate_d;
+
+static int
+inflate_codes_in_window (void)
+{
+  register unsigned e;		/* table entry flag/number of extra bits */
+  unsigned n, d;		/* length and index for copy */
+  unsigned w;			/* current window position */
+  struct huft *t;		/* pointer to table entry */
+  unsigned ml, md;		/* masks for bl and bd bits */
+  register ulg b;		/* bit buffer */
+  register unsigned k;		/* number of bits in bit buffer */
+
+  /* make local copies of globals */
+  d = inflate_d;
+  n = inflate_n;
+  b = bb;			/* initialize bit buffer */
+  k = bk;
+  w = wp;			/* initialize window position */
+
+  /* inflate the coded data */
+  ml = mask_bits[bl];		/* precompute masks for speed */
+  md = mask_bits[bd];
+  for (;;)			/* do until end of block */
+    {
+      if (!code_state)
+	{
+	  NEEDBITS ((unsigned) bl);
+	  if ((e = (t = tl + ((unsigned) b & ml))->e) > 16)
+	    do
+	      {
+		if (e == 99)
+		  {
+		    errnum = ERR_BAD_GZIP_DATA;
+		    return 0;
+		  }
+		DUMPBITS (t->b);
+		e -= 16;
+		NEEDBITS (e);
+	      }
+	    while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e) > 16);
+	  DUMPBITS (t->b);
+
+	  if (e == 16)		/* then it's a literal */
+	    {
+	      slide[w++] = (uch) t->v.n;
+	      if (w == WSIZE)
+		break;
+	    }
+	  else
+	    /* it's an EOB or a length */
+	    {
+	      /* exit if end of block */
+	      if (e == 15)
+		{
+		  block_len = 0;
+		  break;
+		}
+
+	      /* get length of block to copy */
+	      NEEDBITS (e);
+	      n = t->v.n + ((unsigned) b & mask_bits[e]);
+	      DUMPBITS (e);
+
+	      /* decode distance of block to copy */
+	      NEEDBITS ((unsigned) bd);
+	      if ((e = (t = td + ((unsigned) b & md))->e) > 16)
+		do
+		  {
+		    if (e == 99)
+		      {
+			errnum = ERR_BAD_GZIP_DATA;
+			return 0;
+		      }
+		    DUMPBITS (t->b);
+		    e -= 16;
+		    NEEDBITS (e);
+		  }
+		while ((e = (t = t->v.t + ((unsigned) b & mask_bits[e]))->e)
+		       > 16);
+	      DUMPBITS (t->b);
+	      NEEDBITS (e);
+	      d = w - t->v.n - ((unsigned) b & mask_bits[e]);
+	      DUMPBITS (e);
+	      code_state++;
+	    }
+	}
+
+      if (code_state)
+	{
+	  /* do the copy */
+	  do
+	    {
+	      n -= (e = (e = WSIZE - ((d &= WSIZE - 1) > w ? d : w)) > n ? n
+		    : e);
+	      if (w - d >= e)
+		{
+		  memmove (slide + w, slide + d, e);
+		  w += e;
+		  d += e;
+		}
+	      else
+		/* purposefully use the overlap for extra copies here!! */
+		{
+		  while (e--)
+		    slide[w++] = slide[d++];
+		}
+	      if (w == WSIZE)
+		break;
+	    }
+	  while (n);
+
+	  if (!n)
+	    code_state--;
+
+	  /* did we break from the loop too soon? */
+	  if (w == WSIZE)
+	    break;
+	}
+    }
+
+  /* restore the globals from the locals */
+  inflate_d = d;
+  inflate_n = n;
+  wp = w;			/* restore global window pointer */
+  bb = b;			/* restore global bit buffer */
+  bk = k;
+
+  return !block_len;
+}
+
+
+/* get header for an inflated type 0 (stored) block. */
+
+static void
+init_stored_block (void)
+{
+  register ulg b;		/* bit buffer */
+  register unsigned k;		/* number of bits in bit buffer */
+
+  /* make local copies of globals */
+  b = bb;			/* initialize bit buffer */
+  k = bk;
+
+  /* go to byte boundary */
+  DUMPBITS (k & 7);
+
+  /* get the length and its complement */
+  NEEDBITS (16);
+  block_len = ((unsigned) b & 0xffff);
+  DUMPBITS (16);
+  NEEDBITS (16);
+  if (block_len != (unsigned) ((~b) & 0xffff))
+    errnum = ERR_BAD_GZIP_DATA;
+  DUMPBITS (16);
+
+  /* restore global variables */
+  bb = b;
+  bk = k;
+}
+
+
+/* get header for an inflated type 1 (fixed Huffman codes) block.  We should
+   either replace this with a custom decoder, or at least precompute the
+   Huffman tables. */
+
+static void
+init_fixed_block ()
+{
+  int i;			/* temporary variable */
+  unsigned l[288];		/* length list for huft_build */
+
+  /* set up literal table */
+  for (i = 0; i < 144; i++)
+    l[i] = 8;
+  for (; i < 256; i++)
+    l[i] = 9;
+  for (; i < 280; i++)
+    l[i] = 7;
+  for (; i < 288; i++)		/* make a complete, but wrong code set */
+    l[i] = 8;
+  bl = 7;
+  if ((i = huft_build (l, 288, 257, cplens, cplext, &tl, &bl)) != 0)
+    {
+      errnum = ERR_BAD_GZIP_DATA;
+      return;
+    }
+
+  /* set up distance table */
+  for (i = 0; i < 30; i++)	/* make an incomplete code set */
+    l[i] = 5;
+  bd = 5;
+  if ((i = huft_build (l, 30, 0, cpdist, cpdext, &td, &bd)) > 1)
+    {
+      errnum = ERR_BAD_GZIP_DATA;
+      return;
+    }
+
+  /* indicate we're now working on a block */
+  code_state = 0;
+  block_len++;
+}
+
+
+/* get header for an inflated type 2 (dynamic Huffman codes) block. */
+
+static void
+init_dynamic_block (void)
+{
+  int i;			/* temporary variables */
+  unsigned j;
+  unsigned l;			/* last length */
+  unsigned m;			/* mask for bit lengths table */
+  unsigned n;			/* number of lengths to get */
+  unsigned nb;			/* number of bit length codes */
+  unsigned nl;			/* number of literal/length codes */
+  unsigned nd;			/* number of distance codes */
+  unsigned ll[286 + 30];	/* literal/length and distance code lengths */
+  register ulg b;		/* bit buffer */
+  register unsigned k;		/* number of bits in bit buffer */
+
+  /* make local bit buffer */
+  b = bb;
+  k = bk;
+
+  /* read in table lengths */
+  NEEDBITS (5);
+  nl = 257 + ((unsigned) b & 0x1f);	/* number of literal/length codes */
+  DUMPBITS (5);
+  NEEDBITS (5);
+  nd = 1 + ((unsigned) b & 0x1f);	/* number of distance codes */
+  DUMPBITS (5);
+  NEEDBITS (4);
+  nb = 4 + ((unsigned) b & 0xf);	/* number of bit length codes */
+  DUMPBITS (4);
+  if (nl > 286 || nd > 30)
+    {
+      errnum = ERR_BAD_GZIP_DATA;
+      return;
+    }
+
+  /* read in bit-length-code lengths */
+  for (j = 0; j < nb; j++)
+    {
+      NEEDBITS (3);
+      ll[bitorder[j]] = (unsigned) b & 7;
+      DUMPBITS (3);
+    }
+  for (; j < 19; j++)
+    ll[bitorder[j]] = 0;
+
+  /* build decoding table for trees--single level, 7 bit lookup */
+  bl = 7;
+  if ((i = huft_build (ll, 19, 19, NULL, NULL, &tl, &bl)) != 0)
+    {
+      errnum = ERR_BAD_GZIP_DATA;
+      return;
+    }
+
+  /* read in literal and distance code lengths */
+  n = nl + nd;
+  m = mask_bits[bl];
+  i = l = 0;
+  while ((unsigned) i < n)
+    {
+      NEEDBITS ((unsigned) bl);
+      j = (td = tl + ((unsigned) b & m))->b;
+      DUMPBITS (j);
+      j = td->v.n;
+      if (j < 16)		/* length of code in bits (0..15) */
+	ll[i++] = l = j;	/* save last length in l */
+      else if (j == 16)		/* repeat last length 3 to 6 times */
+	{
+	  NEEDBITS (2);
+	  j = 3 + ((unsigned) b & 3);
+	  DUMPBITS (2);
+	  if ((unsigned) i + j > n)
+	    {
+	      errnum = ERR_BAD_GZIP_DATA;
+	      return;
+	    }
+	  while (j--)
+	    ll[i++] = l;
+	}
+      else if (j == 17)		/* 3 to 10 zero length codes */
+	{
+	  NEEDBITS (3);
+	  j = 3 + ((unsigned) b & 7);
+	  DUMPBITS (3);
+	  if ((unsigned) i + j > n)
+	    {
+	      errnum = ERR_BAD_GZIP_DATA;
+	      return;
+	    }
+	  while (j--)
+	    ll[i++] = 0;
+	  l = 0;
+	}
+      else
+	/* j == 18: 11 to 138 zero length codes */
+	{
+	  NEEDBITS (7);
+	  j = 11 + ((unsigned) b & 0x7f);
+	  DUMPBITS (7);
+	  if ((unsigned) i + j > n)
+	    {
+	      errnum = ERR_BAD_GZIP_DATA;
+	      return;
+	    }
+	  while (j--)
+	    ll[i++] = 0;
+	  l = 0;
+	}
+    }
+
+  /* free decoding table for trees */
+  reset_linalloc ();
+
+  /* restore the global bit buffer */
+  bb = b;
+  bk = k;
+
+  /* build the decoding tables for literal/length and distance codes */
+  bl = lbits;
+  if ((i = huft_build (ll, nl, 257, cplens, cplext, &tl, &bl)) != 0)
+    {
+#if 0
+      if (i == 1)
+	printf ("gunzip: incomplete literal tree\n");
+#endif
+
+      errnum = ERR_BAD_GZIP_DATA;
+      return;
+    }
+  bd = dbits;
+  if ((i = huft_build (ll + nl, nd, 0, cpdist, cpdext, &td, &bd)) != 0)
+    {
+#if 0
+      if (i == 1)
+	printf ("gunzip: incomplete distance tree\n");
+#endif
+
+      errnum = ERR_BAD_GZIP_DATA;
+      return;
+    }
+
+  /* indicate we're now working on a block */
+  code_state = 0;
+  block_len++;
+}
+
+
+static void
+get_new_block (void)
+{
+  register ulg b;		/* bit buffer */
+  register unsigned k;		/* number of bits in bit buffer */
+
+  hufts = 0;
+
+  /* make local bit buffer */
+  b = bb;
+  k = bk;
+
+  /* read in last block bit */
+  NEEDBITS (1);
+  last_block = (int) b & 1;
+  DUMPBITS (1);
+
+  /* read in block type */
+  NEEDBITS (2);
+  block_type = (unsigned) b & 3;
+  DUMPBITS (2);
+
+  /* restore the global bit buffer */
+  bb = b;
+  bk = k;
+
+  if (block_type == INFLATE_STORED)
+    init_stored_block ();
+  if (block_type == INFLATE_FIXED)
+    init_fixed_block ();
+  if (block_type == INFLATE_DYNAMIC)
+    init_dynamic_block ();
+}
+
+
+static void
+inflate_window (void)
+{
+  /* initialize window */
+  wp = 0;
+
+  /*
+   *  Main decompression loop.
+   */
+
+  while (wp < WSIZE && !errnum)
+    {
+      if (!block_len)
+	{
+	  if (last_block)
+	    break;
+
+	  get_new_block ();
+	}
+
+      if (block_type > INFLATE_DYNAMIC)
+	errnum = ERR_BAD_GZIP_DATA;
+
+      if (errnum)
+	return;
+
+      /*
+       *  Expand stored block here.
+       */
+      if (block_type == INFLATE_STORED)
+	{
+	  int w = wp;
+
+	  /*
+	   *  This is basically a glorified pass-through
+	   */
+
+	  while (block_len && w < WSIZE && !errnum)
+	    {
+	      slide[w++] = get_byte ();
+	      block_len--;
+	    }
+
+	  wp = w;
+
+	  continue;
+	}
+
+      /*
+       *  Expand other kind of block.
+       */
+
+      if (inflate_codes_in_window ())
+	reset_linalloc ();
+    }
+
+  saved_filepos += WSIZE;
+
+  /* XXX do CRC calculation here! */
+}
+
+
+static void
+initialize_tables (void)
+{
+  saved_filepos = 0;
+  filepos = gzip_data_offset;
+
+  /* initialize window, bit buffer */
+  bk = 0;
+  bb = 0;
+
+  /* reset partial decompression code */
+  last_block = 0;
+  block_len = 0;
+
+  /* reset memory allocation stuff */
+  reset_linalloc ();
+}
+
+
+int
+gunzip_read (char *buf, int len)
+{
+  int ret = 0;
+
+  compressed_file = 0;
+  gunzip_swap_values ();
+  /*
+   *  Now "gzip_*" values refer to the uncompressed data.
+   */
+
+  /* do we reset decompression to the beginning of the file? */
+  if (saved_filepos > gzip_filepos + WSIZE)
+    initialize_tables ();
+
+  /*
+   *  This loop operates upon uncompressed data only.  The only
+   *  special thing it does is to make sure the decompression
+   *  window is within the range of data it needs.
+   */
+
+  while (len > 0 && !errnum)
+    {
+      register int size;
+      register char *srcaddr;
+
+      while (gzip_filepos >= saved_filepos)
+	inflate_window ();
+
+      srcaddr = (char *) ((gzip_filepos & (WSIZE - 1)) + slide);
+      size = saved_filepos - gzip_filepos;
+      if (size > len)
+	size = len;
+
+      memmove (buf, srcaddr, size);
+
+      buf += size;
+      len -= size;
+      gzip_filepos += size;
+      ret += size;
+    }
+
+  compressed_file = 1;
+  gunzip_swap_values ();
+  /*
+   *  Now "gzip_*" values refer to the compressed data.
+   */
+
+  if (errnum)
+    ret = 0;
+
+  return ret;
+}
+
+#endif /* ! NO_DECOMPRESSION */
diff --git a/stage2/hercules.c b/stage2/hercules.c
new file mode 100644
index 0000000..4c0280b
--- /dev/null
+++ b/stage2/hercules.c
@@ -0,0 +1,186 @@
+/* hercules.c - hercules console interface */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2001,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.
+ */
+
+#ifdef SUPPORT_HERCULES
+
+#include <shared.h>
+#include <hercules.h>
+#include <term.h>
+
+/* The position of the cursor.  */
+static int herc_x;
+static int herc_y;
+
+static int herc_standard_color = A_NORMAL;
+static int herc_normal_color = A_NORMAL;
+static int herc_highlight_color = A_REVERSE;
+static int herc_current_color = A_NORMAL;
+static color_state herc_color_state = COLOR_STATE_STANDARD;
+static int herc_cursor_state = 1;
+
+/* Write a byte to a port.  */
+static inline void
+outb (unsigned short port, unsigned char value)
+{
+  asm volatile ("outb	%b0, %w1" : : "a" (value), "Nd" (port));
+}
+
+static void
+herc_set_cursor (void)
+{
+  unsigned offset = herc_y * HERCULES_WIDTH + herc_x;
+  
+  outb (HERCULES_INDEX_REG, 0x0f);
+  outb (0x80, 0);
+  outb (HERCULES_DATA_REG, offset & 0xFF);
+  outb (0x80, 0);
+  
+  outb (HERCULES_INDEX_REG, 0x0e);
+  outb (0x80, 0);
+  outb (HERCULES_DATA_REG, offset >> 8);
+  outb (0x80, 0);
+}
+
+void
+hercules_putchar (int c)
+{
+  switch (c)
+    {
+    case '\b':
+      if (herc_x > 0)
+	herc_x--;
+      break;
+      
+    case '\n':
+      herc_y++;
+      break;
+      
+    case '\r':
+      herc_x = 0;
+      break;
+
+    case '\a':
+      break;
+
+    default:
+      {
+	volatile unsigned short *video
+	  = (unsigned short *) HERCULES_VIDEO_ADDR;
+	
+	video[herc_y * HERCULES_WIDTH + herc_x]
+	  = (herc_current_color << 8) | c;
+	herc_x++;
+	if (herc_x >= HERCULES_WIDTH)
+	  {
+	    herc_x = 0;
+	    herc_y++;
+	  }
+      }
+      break;
+    }
+
+  if (herc_y >= HERCULES_HEIGHT)
+    {
+      volatile unsigned long *video = (unsigned long *) HERCULES_VIDEO_ADDR;
+      int i;
+      
+      herc_y = HERCULES_HEIGHT - 1;
+      grub_memmove ((char *) HERCULES_VIDEO_ADDR,
+		    (char *) HERCULES_VIDEO_ADDR + HERCULES_WIDTH * 2,
+		    HERCULES_WIDTH * (HERCULES_HEIGHT - 1) * 2);
+      for (i = HERCULES_WIDTH * (HERCULES_HEIGHT - 1) / 2;
+	   i < HERCULES_WIDTH * HERCULES_HEIGHT / 2;
+	   i++)
+	video[i] = 0x07200720;
+    }
+}
+
+void
+hercules_cls (void)
+{
+  int i;
+  volatile unsigned long *video = (unsigned long *) HERCULES_VIDEO_ADDR;
+  
+  for (i = 0; i < HERCULES_WIDTH * HERCULES_HEIGHT / 2; i++)
+    video[i] = 0x07200720;
+
+  herc_x = herc_y = 0;
+  herc_set_cursor ();
+}
+
+int
+hercules_getxy (void)
+{
+  return (herc_x << 8) | herc_y;
+}
+
+void
+hercules_gotoxy (int x, int y)
+{
+  herc_x = x;
+  herc_y = y;
+  herc_set_cursor ();
+}
+
+void
+hercules_setcolorstate (color_state state)
+{
+  switch (state) {
+    case COLOR_STATE_STANDARD:
+      herc_current_color = herc_standard_color;
+      break;
+    case COLOR_STATE_NORMAL:
+      herc_current_color = herc_normal_color;
+      break;
+    case COLOR_STATE_HIGHLIGHT:
+      herc_current_color = herc_highlight_color;
+      break;
+    default:
+      herc_current_color = herc_standard_color;
+      break;
+  }
+
+  herc_color_state = state;
+}
+
+void
+hercules_setcolor (int normal_color, int highlight_color)
+{
+  herc_normal_color = normal_color;
+  herc_highlight_color = highlight_color;
+  
+  hercules_setcolorstate (herc_color_state);
+}
+
+int
+hercules_setcursor (int on)
+{
+  int old_state = herc_cursor_state;
+  
+  outb (HERCULES_INDEX_REG, 0x0a);
+  outb (0x80, 0);
+  outb (HERCULES_DATA_REG, on ? 0 : (1 << 5));
+  outb (0x80, 0);
+  herc_cursor_state = on;
+
+  return old_state;
+}
+
+#endif /* SUPPORT_HERCULES */
diff --git a/stage2/hercules.h b/stage2/hercules.h
new file mode 100644
index 0000000..aaf794f
--- /dev/null
+++ b/stage2/hercules.h
@@ -0,0 +1,31 @@
+/* hercules.h - hercules console interface */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2001  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 GRUB_HERCULES_HEADER
+#define GRUB_HERCULES_HEADER	1
+
+/* Macros.  */
+#define HERCULES_VIDEO_ADDR	RAW_ADDR (0xB0000)
+#define HERCULES_WIDTH		80
+#define HERCULES_HEIGHT		25
+#define HERCULES_INDEX_REG	0x3b4
+#define HERCULES_DATA_REG	0x3b5
+
+#endif /* ! GRUB_HERCULES_HEADER */
diff --git a/stage2/i386-elf.h b/stage2/i386-elf.h
new file mode 100644
index 0000000..7162e3d
--- /dev/null
+++ b/stage2/i386-elf.h
@@ -0,0 +1,237 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2001,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.
+ */
+
+/* 32-bit data types */
+
+typedef unsigned long Elf32_Addr;
+typedef unsigned short Elf32_Half;
+typedef unsigned long Elf32_Off;
+typedef signed long Elf32_Sword;
+typedef unsigned long Elf32_Word;
+/* "unsigned char" already exists */
+
+/* ELF header */
+typedef struct
+{
+  
+#define EI_NIDENT 16
+  
+  /* first four characters are defined below */
+#define EI_MAG0		0
+#define ELFMAG0		0x7f
+#define EI_MAG1		1
+#define ELFMAG1		'E'
+#define EI_MAG2		2
+#define ELFMAG2		'L'
+#define EI_MAG3		3
+#define ELFMAG3		'F'
+  
+#define EI_CLASS	4	/* data sizes */
+#define ELFCLASS32	1	/* i386 -- up to 32-bit data sizes present */
+  
+#define EI_DATA		5	/* data type and ordering */
+#define ELFDATA2LSB	1	/* i386 -- LSB 2's complement */
+  
+#define EI_VERSION	6	/* version number.  "e_version" must be the same */
+#define EV_CURRENT      1	/* current version number */
+
+#define EI_OSABI	7	/* operating system/ABI indication */
+#define ELFOSABI_FREEBSD	9
+  
+#define EI_ABIVERSION	8	/* ABI version */
+  
+#define EI_PAD		9	/* from here in is just padding */
+  
+#define EI_BRAND	8	/* start of OS branding (This is
+				   obviously illegal against the ELF
+				   standard.) */
+  
+  unsigned char e_ident[EI_NIDENT];	/* basic identification block */
+  
+#define ET_EXEC		2	/* we only care about executable types */
+  Elf32_Half e_type;		/* file types */
+  
+#define EM_386		3	/* i386 -- obviously use this one */
+  Elf32_Half e_machine;	/* machine types */
+  Elf32_Word e_version;	/* use same as "EI_VERSION" above */
+  Elf32_Addr e_entry;		/* entry point of the program */
+  Elf32_Off e_phoff;		/* program header table file offset */
+  Elf32_Off e_shoff;		/* section header table file offset */
+  Elf32_Word e_flags;		/* flags */
+  Elf32_Half e_ehsize;		/* elf header size in bytes */
+  Elf32_Half e_phentsize;	/* program header entry size */
+  Elf32_Half e_phnum;		/* number of entries in program header */
+  Elf32_Half e_shentsize;	/* section header entry size */
+  Elf32_Half e_shnum;		/* number of entries in section header */
+  
+#define SHN_UNDEF       0
+#define SHN_LORESERVE   0xff00
+#define SHN_LOPROC      0xff00
+#define SHN_HIPROC      0xff1f
+#define SHN_ABS         0xfff1
+#define SHN_COMMON      0xfff2
+#define SHN_HIRESERVE   0xffff
+  Elf32_Half e_shstrndx;	/* section header table index */
+}
+Elf32_Ehdr;
+
+
+#define BOOTABLE_I386_ELF(h) \
+ ((h.e_ident[EI_MAG0] == ELFMAG0) & (h.e_ident[EI_MAG1] == ELFMAG1) \
+  & (h.e_ident[EI_MAG2] == ELFMAG2) & (h.e_ident[EI_MAG3] == ELFMAG3) \
+  & (h.e_ident[EI_CLASS] == ELFCLASS32) & (h.e_ident[EI_DATA] == ELFDATA2LSB) \
+  & (h.e_ident[EI_VERSION] == EV_CURRENT) & (h.e_type == ET_EXEC) \
+  & (h.e_machine == EM_386) & (h.e_version == EV_CURRENT))
+
+/* section table - ? */
+typedef struct
+{
+  Elf32_Word	sh_name;		/* Section name (string tbl index) */
+  Elf32_Word	sh_type;		/* Section type */
+  Elf32_Word	sh_flags;		/* Section flags */
+  Elf32_Addr	sh_addr;		/* Section virtual addr at execution */
+  Elf32_Off	sh_offset;		/* Section file offset */
+  Elf32_Word	sh_size;		/* Section size in bytes */
+  Elf32_Word	sh_link;		/* Link to another section */
+  Elf32_Word	sh_info;		/* Additional section information */
+  Elf32_Word	sh_addralign;		/* Section alignment */
+  Elf32_Word	sh_entsize;		/* Entry size if section holds table */
+}
+Elf32_Shdr;
+
+/* symbol table - page 4-25, figure 4-15 */
+typedef struct
+{
+  Elf32_Word st_name;
+  Elf32_Addr st_value;
+  Elf32_Word st_size;
+  unsigned char st_info;
+  unsigned char st_other;
+  Elf32_Half st_shndx;
+}
+Elf32_Sym;
+
+/* symbol type and binding attributes - page 4-26 */
+
+#define ELF32_ST_BIND(i)    ((i) >> 4)
+#define ELF32_ST_TYPE(i)    ((i) & 0xf)
+#define ELF32_ST_INFO(b,t)  (((b)<<4)+((t)&0xf))
+
+/* symbol binding - page 4-26, figure 4-16 */
+
+#define STB_LOCAL    0
+#define STB_GLOBAL   1
+#define STB_WEAK     2
+#define STB_LOPROC  13
+#define STB_HIPROC  15
+
+/* symbol types - page 4-28, figure 4-17 */
+
+#define STT_NOTYPE   0
+#define STT_OBJECT   1
+#define STT_FUNC     2
+#define STT_SECTION  3
+#define STT_FILE     4
+#define STT_LOPROC  13
+#define STT_HIPROC  15
+
+
+/* Macros to split/combine relocation type and symbol page 4-32 */
+
+#define ELF32_R_SYM(__i)	((__i)>>8)
+#define ELF32_R_TYPE(__i)	((unsigned char) (__i))
+#define ELF32_R_INFO(__s, __t)	(((__s)<<8) + (unsigned char) (__t))
+
+
+/* program header - page 5-2, figure 5-1 */
+
+typedef struct
+{
+  Elf32_Word p_type;
+  Elf32_Off p_offset;
+  Elf32_Addr p_vaddr;
+  Elf32_Addr p_paddr;
+  Elf32_Word p_filesz;
+  Elf32_Word p_memsz;
+  Elf32_Word p_flags;
+  Elf32_Word p_align;
+}
+Elf32_Phdr;
+
+/* segment types - page 5-3, figure 5-2 */
+
+#define PT_NULL		0
+#define PT_LOAD		1
+#define PT_DYNAMIC	2
+#define PT_INTERP	3
+#define PT_NOTE		4
+#define PT_SHLIB	5
+#define PT_PHDR		6
+
+#define PT_LOPROC	0x70000000
+#define PT_HIPROC	0x7fffffff
+
+/* segment permissions - page 5-6 */
+
+#define PF_X		0x1
+#define PF_W		0x2
+#define PF_R		0x4
+#define PF_MASKPROC	0xf0000000
+
+
+/* dynamic structure - page 5-15, figure 5-9 */
+
+typedef struct
+{
+  Elf32_Sword d_tag;
+  union
+  {
+    Elf32_Word d_val;
+    Elf32_Addr d_ptr;
+  }
+  d_un;
+}
+Elf32_Dyn;
+
+/* Dynamic array tags - page 5-16, figure 5-10.  */
+
+#define DT_NULL		0
+#define DT_NEEDED	1
+#define DT_PLTRELSZ	2
+#define DT_PLTGOT	3
+#define DT_HASH		4
+#define DT_STRTAB	5
+#define DT_SYMTAB	6
+#define DT_RELA		7
+#define DT_RELASZ	8
+#define DT_RELAENT      9
+#define DT_STRSZ	10
+#define DT_SYMENT	11
+#define DT_INIT		12
+#define DT_FINI		13
+#define DT_SONAME	14
+#define DT_RPATH	15
+#define DT_SYMBOLIC	16
+#define DT_REL		17
+#define DT_RELSZ	18
+#define DT_RELENT	19
+#define DT_PLTREL	20
+#define DT_DEBUG	21
+#define DT_TEXTREL	22
+#define DT_JMPREL	23
diff --git a/stage2/imgact_aout.h b/stage2/imgact_aout.h
new file mode 100644
index 0000000..f0d46c0
--- /dev/null
+++ b/stage2/imgact_aout.h
@@ -0,0 +1,158 @@
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: @(#)exec.h	8.1 (Berkeley) 6/11/93
+ *	$Id: imgact_aout.h,v 1.1 1999/06/24 00:03:22 okuji Exp $
+ */
+/*
+ *  11/23/95 - Kludge to get "ntohl" null macro added.  -- ESB
+ *           - and for __LDPGSZ
+ */
+
+#ifndef	_IMGACT_AOUT_H_
+#define	_IMGACT_AOUT_H_
+
+/* XXX ESB */
+#define ntohl(x) ((x << 24) | ((x & 0xFF00) << 8) \
+		  | ((x >> 8) & 0xFF00) | (x >> 24))
+#define htonl(x) ntohl(x)
+#define __LDPGSZ 0x1000
+
+#define N_GETMAGIC(ex) \
+	( (ex).a_midmag & 0xffff )
+#define N_GETMID(ex) \
+	( (N_GETMAGIC_NET(ex) == ZMAGIC) ? N_GETMID_NET(ex) : \
+	((ex).a_midmag >> 16) & 0x03ff )
+#define N_GETFLAG(ex) \
+	( (N_GETMAGIC_NET(ex) == ZMAGIC) ? N_GETFLAG_NET(ex) : \
+	((ex).a_midmag >> 26) & 0x3f )
+#define N_SETMAGIC(ex,mag,mid,flag) \
+	( (ex).a_midmag = (((flag) & 0x3f) <<26) | (((mid) & 0x03ff) << 16) | \
+	((mag) & 0xffff) )
+
+#define N_GETMAGIC_NET(ex) \
+	(ntohl((ex).a_midmag) & 0xffff)
+#define N_GETMID_NET(ex) \
+	((ntohl((ex).a_midmag) >> 16) & 0x03ff)
+#define N_GETFLAG_NET(ex) \
+	((ntohl((ex).a_midmag) >> 26) & 0x3f)
+#define N_SETMAGIC_NET(ex,mag,mid,flag) \
+	( (ex).a_midmag = htonl( (((flag)&0x3f)<<26) | (((mid)&0x03ff)<<16) | \
+	(((mag)&0xffff)) ) )
+
+#define N_ALIGN(ex,x) \
+	(N_GETMAGIC(ex) == ZMAGIC || N_GETMAGIC(ex) == QMAGIC || \
+	 N_GETMAGIC_NET(ex) == ZMAGIC || N_GETMAGIC_NET(ex) == QMAGIC ? \
+	 ((x) + __LDPGSZ - 1) & ~(unsigned long)(__LDPGSZ - 1) : (x))
+
+/* Valid magic number check. */
+#define	N_BADMAG(ex) \
+	(N_GETMAGIC(ex) != OMAGIC && N_GETMAGIC(ex) != NMAGIC && \
+	 N_GETMAGIC(ex) != ZMAGIC && N_GETMAGIC(ex) != QMAGIC && \
+	 N_GETMAGIC_NET(ex) != OMAGIC && N_GETMAGIC_NET(ex) != NMAGIC && \
+	 N_GETMAGIC_NET(ex) != ZMAGIC && N_GETMAGIC_NET(ex) != QMAGIC)
+
+
+/* Address of the bottom of the text segment. */
+#define N_TXTADDR(ex) \
+	((N_GETMAGIC(ex) == OMAGIC || N_GETMAGIC(ex) == NMAGIC || \
+	N_GETMAGIC(ex) == ZMAGIC) ? 0 : __LDPGSZ)
+
+/* Address of the bottom of the data segment. */
+#define N_DATADDR(ex) \
+	N_ALIGN(ex, N_TXTADDR(ex) + (ex).a_text)
+
+/* Text segment offset. */
+#define	N_TXTOFF(ex) \
+	(N_GETMAGIC(ex) == ZMAGIC ? __LDPGSZ : (N_GETMAGIC(ex) == QMAGIC || \
+	N_GETMAGIC_NET(ex) == ZMAGIC) ? 0 : sizeof(struct exec))
+
+/* Data segment offset. */
+#define	N_DATOFF(ex) \
+	N_ALIGN(ex, N_TXTOFF(ex) + (ex).a_text)
+
+/* Relocation table offset. */
+#define N_RELOFF(ex) \
+	N_ALIGN(ex, N_DATOFF(ex) + (ex).a_data)
+
+/* Symbol table offset. */
+#define N_SYMOFF(ex) \
+	(N_RELOFF(ex) + (ex).a_trsize + (ex).a_drsize)
+
+/* String table offset. */
+#define	N_STROFF(ex) 	(N_SYMOFF(ex) + (ex).a_syms)
+
+/*
+ * Header prepended to each a.out file.
+ * only manipulate the a_midmag field via the
+ * N_SETMAGIC/N_GET{MAGIC,MID,FLAG} macros in a.out.h
+ */
+
+struct exec
+  {
+    unsigned long a_midmag;	/* htonl(flags<<26 | mid<<16 | magic) */
+    unsigned long a_text;	/* text segment size */
+    unsigned long a_data;	/* initialized data size */
+    unsigned long a_bss;	/* uninitialized data size */
+    unsigned long a_syms;	/* symbol table size */
+    unsigned long a_entry;	/* entry point */
+    unsigned long a_trsize;	/* text relocation size */
+    unsigned long a_drsize;	/* data relocation size */
+  };
+#define a_magic a_midmag	/* XXX Hack to work with current kern_execve.c */
+
+/* a_magic */
+#define	OMAGIC          0x107	/* 0407 old impure format */
+#define	NMAGIC          0x108	/* 0410 read-only text */
+#define	ZMAGIC          0x10b	/* 0413 demand load format */
+#define QMAGIC          0xcc	/* 0314 "compact" demand load format */
+
+/* a_mid */
+#define	MID_ZERO	0	/* unknown - implementation dependent */
+#define	MID_SUN010	1	/* sun 68010/68020 binary */
+#define	MID_SUN020	2	/* sun 68020-only binary */
+#define MID_I386	134	/* i386 BSD binary */
+#define MID_SPARC	138	/* sparc */
+#define	MID_HP200	200	/* hp200 (68010) BSD binary */
+#define	MID_HP300	300	/* hp300 (68020+68881) BSD binary */
+#define	MID_HPUX	0x20C	/* hp200/300 HP-UX binary */
+#define	MID_HPUX800     0x20B	/* hp800 HP-UX binary */
+
+/*
+ * a_flags
+ */
+#define EX_PIC		0x10	/* contains position independant code */
+#define EX_DYNAMIC	0x20	/* contains run-time link-edit info */
+#define EX_DPMASK	0x30	/* mask for the above */
+
+#endif /* !_IMGACT_AOUT_H_ */
diff --git a/stage2/iso9660.h b/stage2/iso9660.h
new file mode 100644
index 0000000..4a6a8cc
--- /dev/null
+++ b/stage2/iso9660.h
@@ -0,0 +1,206 @@
+/*
+ *  ISO 9660 filesystem backend for GRUB (GRand Unified Bootloader)
+ *  including Rock Ridge Extensions support
+ *
+ *  Copyright (C) 1998, 1999  Kousuke Takai  <tak@kmc.kyoto-u.ac.jp>
+ *
+ *  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.
+ */
+/*
+ *  References:
+ *	linux/fs/isofs/rock.[ch]
+ *	mkisofs-1.11.1/diag/isoinfo.c
+ *	mkisofs-1.11.1/iso9660.h
+ *		(all are written by Eric Youngdale)
+ */
+
+#ifndef _ISO9660_H_
+#define _ISO9660_H_
+
+#define ISO_SECTOR_BITS              (11)
+#define ISO_SECTOR_SIZE              (1<<ISO_SECTOR_BITS)
+
+#define	ISO_REGULAR	1	/* regular file	*/
+#define	ISO_DIRECTORY	2	/* directory	*/
+#define	ISO_OTHER	0	/* other file (with Rock Ridge) */
+
+#define	RR_FLAG_PX	0x01	/* have POSIX file attributes */
+#define RR_FLAG_PN	0x02	/* POSIX devices */
+#define RR_FLAG_SL	0x04	/* Symbolic link */
+#define	RR_FLAG_NM	0x08	/* have alternate file name   */
+#define RR_FLAG_CL	0x10	/* Child link */
+#define RR_FLAG_PL	0x20	/* Parent link */
+#define RR_FLAG_RE	0x40	/* Relocation directory */
+#define RR_FLAG_TF	0x80	/* Timestamps */
+
+/* POSIX file attributes for Rock Ridge extensions */
+#define	POSIX_S_IFMT	0xF000
+#define	POSIX_S_IFREG	0x8000
+#define	POSIX_S_IFDIR	0x4000
+
+/* volume descriptor types */
+#define ISO_VD_PRIMARY 1
+#define ISO_VD_END 255
+
+#define ISO_STANDARD_ID "CD001"
+
+#ifndef ASM_FILE
+
+#ifndef	__BIT_TYPES_DEFINED__
+typedef		 int	 int8_t	__attribute__((mode(QI)));
+typedef unsigned int   u_int8_t	__attribute__((mode(QI)));
+typedef		 int	int16_t	__attribute__((mode(HI)));
+typedef unsigned int  u_int16_t	__attribute__((mode(HI)));
+typedef		 int	int32_t	__attribute__((mode(SI)));
+typedef unsigned int  u_int32_t	__attribute__((mode(SI)));
+#endif
+
+typedef	union {
+  u_int8_t l,b;
+}	iso_8bit_t;
+
+typedef	struct __iso_16bit {
+  u_int16_t l, b;
+} iso_16bit_t __attribute__ ((packed));
+
+typedef	struct __iso_32bit {
+  u_int32_t l, b;
+} iso_32bit_t __attribute__ ((packed));
+
+typedef u_int8_t		iso_date_t[7];
+
+struct iso_directory_record {
+  iso_8bit_t	length;
+  iso_8bit_t	ext_attr_length;
+  iso_32bit_t	extent;
+  iso_32bit_t	size;
+  iso_date_t	date;
+  iso_8bit_t	flags;
+  iso_8bit_t	file_unit_size;
+  iso_8bit_t	interleave;
+  iso_16bit_t	volume_seq_number;
+  iso_8bit_t	name_len;
+  u_int8_t	name[1];
+} __attribute__ ((packed));
+
+struct iso_primary_descriptor {
+  iso_8bit_t	type;
+  u_int8_t	id[5];
+  iso_8bit_t	version;
+  u_int8_t	_unused1[1];
+  u_int8_t	system_id[32];
+  u_int8_t	volume_id[32];
+  u_int8_t	_unused2[8];
+  iso_32bit_t	volume_space_size;
+  u_int8_t	_unused3[32];
+  iso_16bit_t	volume_set_size;
+  iso_16bit_t	volume_seq_number;
+  iso_16bit_t	logical_block_size;
+  iso_32bit_t	path_table_size;
+  u_int8_t	type_l_path_table[4];
+  u_int8_t	opt_type_l_path_table[4];
+  u_int8_t	type_m_path_table[4];
+  u_int8_t	opt_type_m_path_table[4];
+  struct iso_directory_record root_directory_record;
+  u_int8_t	volume_set_id[128];
+  u_int8_t	publisher_id[128];
+  u_int8_t	preparer_id[128];
+  u_int8_t	application_id[128];
+  u_int8_t	copyright_file_id[37];
+  u_int8_t	abstract_file_id[37];
+  u_int8_t	bibliographic_file_id[37];
+  u_int8_t	creation_date[17];
+  u_int8_t	modification_date[17];
+  u_int8_t	expiration_date[17];
+  u_int8_t	effective_date[17];
+  iso_8bit_t	file_structure_version;
+  u_int8_t	_unused4[1];
+  u_int8_t	application_data[512];
+  u_int8_t	_unused5[653];
+} __attribute__ ((packed));
+
+struct rock_ridge {
+  u_int16_t	signature;
+  u_int8_t	len;
+  u_int8_t	version;
+  union {
+    struct SP {
+      u_int16_t	magic;
+      u_int8_t	skip;
+    } sp;
+    struct CE {
+      iso_32bit_t	extent;
+      iso_32bit_t	offset;
+      iso_32bit_t	size;
+    } ce;
+    struct ER {
+      u_int8_t	len_id;
+      u_int8_t	len_des;
+      u_int8_t	len_src;
+      u_int8_t	ext_ver;
+      u_int8_t	data[0];
+    } er;
+    struct RR {
+      iso_8bit_t	flags;
+    } rr;
+    struct PX {
+      iso_32bit_t	mode;
+      iso_32bit_t	nlink;
+      iso_32bit_t	uid;
+      iso_32bit_t	gid;
+    } px;
+    struct PN {
+      iso_32bit_t	dev_high;
+      iso_32bit_t	dev_low;
+    } pn;
+    struct SL {
+      iso_8bit_t flags;
+      struct SL_component {
+	iso_8bit_t	flags;
+	u_int8_t		len;
+	u_int8_t		text[0];
+      } link;
+    } sl;
+    struct NM {
+      iso_8bit_t	flags;
+      u_int8_t	name[0];
+    } nm;
+    struct CL {
+      iso_32bit_t	location;
+    } cl;
+    struct PL {
+      iso_32bit_t	location;
+    } pl;
+    struct TF {
+      iso_8bit_t	flags;
+      iso_date_t	times[0];
+    } tf;
+  } u;
+} __attribute__ ((packed));
+
+typedef	union RR_ptr {
+  struct rock_ridge *rr;
+  char		  *ptr;
+  int		   i;
+} RR_ptr_t;
+
+#define	RRMAGIC(c1, c2)	((c1)|(c2) << 8)
+
+#define	CHECK2(ptr, c1, c2) \
+	(*(unsigned short *)(ptr) == (((c1) | (c2) << 8) & 0xFFFF))
+
+#endif /* !ASM_FILE */
+
+#endif /* _ISO9660_H_ */
diff --git a/stage2/jfs.h b/stage2/jfs.h
new file mode 100644
index 0000000..e596a1b
--- /dev/null
+++ b/stage2/jfs.h
@@ -0,0 +1,601 @@
+/* jfs.h - an extractions from linux/include/linux/jfs/jfs* into one file */
+/*   
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000  International Business Machines  Corp.
+ *  Copyright (C) 2001  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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _JFS_H_
+#define _JFS_H_
+
+/* those are from jfs_filsys.h */
+
+/*
+ *	 file system option (superblock flag)
+ */
+/* platform option (conditional compilation) */
+#define JFS_AIX		0x80000000	/* AIX support */
+/*	POSIX name/directory  support */
+
+#define JFS_OS2		0x40000000	/* OS/2 support */
+/*	case-insensitive name/directory support */
+
+#define JFS_LINUX      	0x10000000	/* Linux support */
+/*	case-sensitive name/directory support */
+
+/* directory option */
+#define JFS_UNICODE	0x00000001	/* unicode name */
+
+/* bba */
+#define	JFS_SWAP_BYTES		0x00100000	/* running on big endian computer */
+
+
+/*
+ *	buffer cache configuration
+ */
+/* page size */
+#ifdef PSIZE
+#undef PSIZE
+#endif
+#define	PSIZE		4096	/* page size (in byte) */
+
+/*
+ *	fs fundamental size
+ *
+ * PSIZE >= file system block size >= PBSIZE >= DISIZE
+ */
+#define	PBSIZE		512	/* physical block size (in byte) */
+#define DISIZE		512	/* on-disk inode size (in byte) */
+#define L2DISIZE	9
+#define	INOSPERIAG	4096	/* number of disk inodes per iag */
+#define	L2INOSPERIAG	12
+#define INOSPEREXT	32	/* number of disk inode per extent */
+#define L2INOSPEREXT	5
+
+/* Minimum number of bytes supported for a JFS partition */
+#define MINJFS			(0x1000000)
+
+/*
+ * fixed byte offset address
+ */
+#define SUPER1_OFF	0x8000	/* primary superblock */
+
+#define AITBL_OFF	(SUPER1_OFF + PSIZE + (PSIZE << 1))
+
+/*
+ *	fixed reserved inode number
+ */
+/* aggregate inode */
+#define	AGGREGATE_I	1	/* aggregate inode map inode */
+#define	FILESYSTEM_I	16	/* 1st/only fileset inode in ait:
+				 * fileset inode map inode
+				 */
+
+/* per fileset inode */
+#define	ROOT_I		2	/* fileset root inode */
+
+/*
+ *	directory configuration
+ */
+#define JFS_NAME_MAX	255
+#define JFS_PATH_MAX	PSIZE
+
+typedef unsigned char u8;
+typedef char s8;
+typedef unsigned short u16;
+typedef short s16;
+typedef unsigned int u32;
+typedef int s32;
+typedef unsigned long long u64;
+typedef long long s64;
+
+typedef u16 UniChar;
+
+/* these from jfs_btree.h */
+
+/* btpaget_t flag */
+#define BT_TYPE		0x07	/* B+-tree index */
+#define	BT_ROOT		0x01	/* root page */
+#define	BT_LEAF		0x02	/* leaf page */
+#define	BT_INTERNAL	0x04	/* internal page */
+#define	BT_RIGHTMOST	0x10	/* rightmost page */
+#define	BT_LEFTMOST	0x20	/* leftmost page */
+
+/* those are from jfs_types.h */
+
+struct timestruc_t {
+	u32 tv_sec;
+	u32 tv_nsec;
+};
+
+/*
+ *	physical xd (pxd)
+ */
+typedef struct {
+	unsigned len:24;
+	unsigned addr1:8;
+	u32 addr2;
+} pxd_t;
+
+/* xd_t field extraction */
+#define	lengthPXD(pxd)	((pxd)->len)
+#define	addressPXD(pxd)	(((s64)((pxd)->addr1)) << 32 | ((pxd)->addr2))
+
+/*
+ *	data extent descriptor (dxd)
+ */
+typedef struct {
+	unsigned flag:8;	/* 1: flags */
+	unsigned rsrvd:24;	/* 3: */
+	u32 size;		/* 4: size in byte */
+	unsigned len:24;	/* 3: length in unit of fsblksize */
+	unsigned addr1:8;	/* 1: address in unit of fsblksize */
+	u32 addr2;		/* 4: address in unit of fsblksize */
+} dxd_t;			/* - 16 - */
+
+/*
+ *	DASD limit information - stored in directory inode
+ */
+typedef struct dasd {
+	u8 thresh;		/* Alert Threshold (in percent) */
+	u8 delta;		/* Alert Threshold delta (in percent)   */
+	u8 rsrvd1;
+	u8 limit_hi;		/* DASD limit (in logical blocks)       */
+	u32 limit_lo;		/* DASD limit (in logical blocks)       */
+	u8 rsrvd2[3];
+	u8 used_hi;		/* DASD usage (in logical blocks)       */
+	u32 used_lo;		/* DASD usage (in logical blocks)       */
+} dasd_t;
+
+
+/* from jfs_superblock.h */
+
+#define JFS_MAGIC 	0x3153464A	/* "JFS1" */
+
+struct jfs_superblock
+{
+	u32 s_magic;		/* 4: magic number */
+	u32 s_version;		/* 4: version number */
+
+	s64 s_size;		/* 8: aggregate size in hardware/LVM blocks;
+				 * VFS: number of blocks
+				 */
+	s32 s_bsize;		/* 4: aggregate block size in bytes; 
+				 * VFS: fragment size
+				 */
+	s16 s_l2bsize;		/* 2: log2 of s_bsize */
+	s16 s_l2bfactor;	/* 2: log2(s_bsize/hardware block size) */
+	s32 s_pbsize;		/* 4: hardware/LVM block size in bytes */
+	s16 s_l2pbsize;		/* 2: log2 of s_pbsize */
+	s16 pad;		/* 2: padding necessary for alignment */
+
+	u32 s_agsize;		/* 4: allocation group size in aggr. blocks */
+
+	u32 s_flag;		/* 4: aggregate attributes:
+				 *    see jfs_filsys.h
+				 */
+	u32 s_state;		/* 4: mount/unmount/recovery state: 
+				 *    see jfs_filsys.h
+				 */
+	s32 s_compress;		/* 4: > 0 if data compression */
+
+	pxd_t s_ait2;		/* 8: first extent of secondary
+				 *    aggregate inode table
+				 */
+
+	pxd_t s_aim2;		/* 8: first extent of secondary
+				 *    aggregate inode map
+				 */
+	u32 s_logdev;		/* 4: device address of log */
+	s32 s_logserial;	/* 4: log serial number at aggregate mount */
+	pxd_t s_logpxd;		/* 8: inline log extent */
+
+	pxd_t s_fsckpxd;	/* 8: inline fsck work space extent */
+
+	struct timestruc_t s_time;	/* 8: time last updated */
+
+	s32 s_fsckloglen;	/* 4: Number of filesystem blocks reserved for
+				 *    the fsck service log.  
+				 *    N.B. These blocks are divided among the
+				 *         versions kept.  This is not a per
+				 *         version size.
+				 *    N.B. These blocks are included in the 
+				 *         length field of s_fsckpxd.
+				 */
+	s8 s_fscklog;		/* 1: which fsck service log is most recent
+				 *    0 => no service log data yet
+				 *    1 => the first one
+				 *    2 => the 2nd one
+				 */
+	char s_fpack[11];	/* 11: file system volume name 
+				 *     N.B. This must be 11 bytes to
+				 *          conform with the OS/2 BootSector
+				 *          requirements
+				 */
+
+	/* extendfs() parameter under s_state & FM_EXTENDFS */
+	s64 s_xsize;		/* 8: extendfs s_size */
+	pxd_t s_xfsckpxd;	/* 8: extendfs fsckpxd */
+	pxd_t s_xlogpxd;	/* 8: extendfs logpxd */
+	/* - 128 byte boundary - */
+
+	/*
+	 *      DFS VFS support (preliminary) 
+	 */
+	char s_attach;		/* 1: VFS: flag: set when aggregate is attached
+				 */
+	u8 rsrvd4[7];		/* 7: reserved - set to 0 */
+
+	u64 totalUsable;	/* 8: VFS: total of 1K blocks which are
+				 * available to "normal" (non-root) users.
+				 */
+	u64 minFree;		/* 8: VFS: # of 1K blocks held in reserve for 
+				 * exclusive use of root.  This value can be 0,
+				 * and if it is then totalUsable will be equal 
+				 * to # of blocks in aggregate.  I believe this
+				 * means that minFree + totalUsable = # blocks.
+				 * In that case, we don't need to store both 
+				 * totalUsable and minFree since we can compute
+				 * one from the other.  I would guess minFree 
+				 * would be the one we should store, and 
+				 * totalUsable would be the one we should 
+				 * compute.  (Just a guess...)
+				 */
+
+	u64 realFree;		/* 8: VFS: # of free 1K blocks can be used by 
+				 * "normal" users.  It may be this is something
+				 * we should compute when asked for instead of 
+				 * storing in the superblock.  I don't know how
+				 * often this information is needed.
+				 */
+	/*
+	 *      graffiti area
+	 */
+};
+
+/* from jfs_dtree.h */
+
+/*
+ *      entry segment/slot
+ *
+ * an entry consists of type dependent head/only segment/slot and
+ * additional segments/slots linked vi next field;
+ * N.B. last/only segment of entry is terminated by next = -1;
+ */
+/*
+ *	directory page slot
+ */
+typedef struct {
+	s8 next;		/* 1: */
+	s8 cnt;			/* 1: */
+	UniChar name[15];	/* 30: */
+} dtslot_t;			/* (32) */
+
+#define DTSLOTDATALEN	15
+
+/*
+ *	 internal node entry head/only segment
+ */
+typedef struct {
+	pxd_t xd;		/* 8: child extent descriptor */
+
+	s8 next;		/* 1: */
+	u8 namlen;		/* 1: */
+	UniChar name[11];	/* 22: 2-byte aligned */
+} idtentry_t;			/* (32) */
+
+/*
+ *	leaf node entry head/only segment
+ *
+ * 	For legacy filesystems, name contains 13 unichars -- no index field
+ */
+typedef struct {
+	u32 inumber;		/* 4: 4-byte aligned */
+	s8 next;		/* 1: */
+	u8 namlen;		/* 1: */
+	UniChar name[11];	/* 22: 2-byte aligned */
+	u32 index;		/* 4: index into dir_table */
+} ldtentry_t;			/* (32) */
+
+#define DTLHDRDATALEN	11
+
+/*
+ * dir_table used for directory traversal during readdir
+*/ 
+
+/*
+ * Maximum entry in inline directory table
+ */
+
+typedef struct dir_table_slot {
+	u8 rsrvd;	/* 1: */
+	u8 flag;	/* 1: 0 if free */
+	u8 slot;	/* 1: slot within leaf page of entry */
+	u8 addr1;	/* 1: upper 8 bits of leaf page address */
+	u32 addr2;	/* 4: lower 32 bits of leaf page address -OR-
+			      index of next entry when this entry was deleted */
+} dir_table_slot_t;	/* (8) */
+
+/*
+ *	directory root page (in-line in on-disk inode):
+ *
+ * cf. dtpage_t below.
+ */
+typedef union {
+	struct {
+		dasd_t DASD;	/* 16: DASD limit/usage info  F226941 */
+
+		u8 flag;	/* 1: */
+		s8 nextindex;	/* 1: next free entry in stbl */
+		s8 freecnt;	/* 1: free count */
+		s8 freelist;	/* 1: freelist header */
+
+		u32 idotdot;	/* 4: parent inode number */
+
+		s8 stbl[8];	/* 8: sorted entry index table */
+	} header;		/* (32) */
+
+	dtslot_t slot[9];
+} dtroot_t;
+
+/*
+ *	directory regular page:
+ *
+ *	entry slot array of 32 byte slot
+ *
+ * sorted entry slot index table (stbl):
+ * contiguous slots at slot specified by stblindex,
+ * 1-byte per entry
+ *   512 byte block:  16 entry tbl (1 slot)
+ *  1024 byte block:  32 entry tbl (1 slot)
+ *  2048 byte block:  64 entry tbl (2 slot)
+ *  4096 byte block: 128 entry tbl (4 slot)
+ *
+ * data area:
+ *   512 byte block:  16 - 2 =  14 slot
+ *  1024 byte block:  32 - 2 =  30 slot
+ *  2048 byte block:  64 - 3 =  61 slot
+ *  4096 byte block: 128 - 5 = 123 slot
+ *
+ * N.B. index is 0-based; index fields refer to slot index
+ * except nextindex which refers to entry index in stbl;
+ * end of entry stot list or freelist is marked with -1.
+ */
+typedef union {
+	struct {
+		s64 next;	/* 8: next sibling */
+		s64 prev;	/* 8: previous sibling */
+
+		u8 flag;	/* 1: */
+		s8 nextindex;	/* 1: next entry index in stbl */
+		s8 freecnt;	/* 1: */
+		s8 freelist;	/* 1: slot index of head of freelist */
+
+		u8 maxslot;	/* 1: number of slots in page slot[] */
+		s8 stblindex;	/* 1: slot index of start of stbl */
+		u8 rsrvd[2];	/* 2: */
+
+		pxd_t self;	/* 8: self pxd */
+	} header;		/* (32) */
+
+	dtslot_t slot[128];
+} dtpage_t;
+
+/* from jfs_xtree.h */
+
+/*
+ *      extent allocation descriptor (xad)
+ */
+typedef struct xad {
+	unsigned flag:8;	/* 1: flag */
+	unsigned rsvrd:16;	/* 2: reserved */
+	unsigned off1:8;	/* 1: offset in unit of fsblksize */
+	u32 off2;		/* 4: offset in unit of fsblksize */
+	unsigned len:24;	/* 3: length in unit of fsblksize */
+	unsigned addr1:8;	/* 1: address in unit of fsblksize */
+	u32 addr2;		/* 4: address in unit of fsblksize */
+} xad_t;			/* (16) */
+
+/* xad_t field extraction */
+#define offsetXAD(xad)	(((s64)((xad)->off1)) << 32 | ((xad)->off2))
+#define addressXAD(xad)	(((s64)((xad)->addr1)) << 32 | ((xad)->addr2))
+#define lengthXAD(xad)	((xad)->len)
+
+/* possible values for maxentry */
+#define XTPAGEMAXSLOT   256
+#define XTENTRYSTART    2
+
+/*
+ *      xtree page:
+ */
+typedef union {
+	struct xtheader {
+		s64 next;	/* 8: */
+		s64 prev;	/* 8: */
+
+		u8 flag;	/* 1: */
+		u8 rsrvd1;	/* 1: */
+		s16 nextindex;	/* 2: next index = number of entries */
+		s16 maxentry;	/* 2: max number of entries */
+		s16 rsrvd2;	/* 2: */
+
+		pxd_t self;	/* 8: self */
+	} header;		/* (32) */
+
+	xad_t xad[XTPAGEMAXSLOT];	/* 16 * maxentry: xad array */
+} xtpage_t;
+
+/* from jfs_dinode.h */
+
+struct dinode {
+	/*
+	 *      I. base area (128 bytes)
+	 *      ------------------------
+	 *
+	 * define generic/POSIX attributes
+	 */
+	u32 di_inostamp;	/* 4: stamp to show inode belongs to fileset */
+	s32 di_fileset;		/* 4: fileset number */
+	u32 di_number;		/* 4: inode number, aka file serial number */
+	u32 di_gen;		/* 4: inode generation number */
+
+	pxd_t di_ixpxd;		/* 8: inode extent descriptor */
+
+	s64 di_size;		/* 8: size */
+	s64 di_nblocks;		/* 8: number of blocks allocated */
+
+	u32 di_nlink;		/* 4: number of links to the object */
+
+	u32 di_uid;		/* 4: user id of owner */
+	u32 di_gid;		/* 4: group id of owner */
+
+	u32 di_mode;		/* 4: attribute, format and permission */
+
+	struct timestruc_t di_atime;	/* 8: time last data accessed */
+	struct timestruc_t di_ctime;	/* 8: time last status changed */
+	struct timestruc_t di_mtime;	/* 8: time last data modified */
+	struct timestruc_t di_otime;	/* 8: time created */
+
+	dxd_t di_acl;		/* 16: acl descriptor */
+
+	dxd_t di_ea;		/* 16: ea descriptor */
+
+	s32 di_next_index;  /* 4: Next available dir_table index */
+
+	s32 di_acltype;		/* 4: Type of ACL */
+
+	/*
+	 * 	Extension Areas.
+	 *
+	 *	Historically, the inode was partitioned into 4 128-byte areas,
+	 *	the last 3 being defined as unions which could have multiple
+	 *	uses.  The first 96 bytes had been completely unused until
+	 *	an index table was added to the directory.  It is now more
+	 *	useful to describe the last 3/4 of the inode as a single
+	 *	union.  We would probably be better off redesigning the
+	 *	entire structure from scratch, but we don't want to break
+	 *	commonality with OS/2's JFS at this time.
+	 */
+	union {
+		struct {
+			/*
+			 * This table contains the information needed to
+			 * find a directory entry from a 32-bit index.
+			 * If the index is small enough, the table is inline,
+			 * otherwise, an x-tree root overlays this table
+			 */
+			dir_table_slot_t _table[12];	/* 96: inline */
+
+			dtroot_t _dtroot;		/* 288: dtree root */
+		} _dir;					/* (384) */
+#define di_dirtable	u._dir._table
+#define di_dtroot	u._dir._dtroot
+#define di_parent       di_dtroot.header.idotdot
+#define di_DASD		di_dtroot.header.DASD
+
+		struct {
+			union {
+				u8 _data[96];		/* 96: unused */
+				struct {
+					void *_imap;	/* 4: unused */
+					u32 _gengen;	/* 4: generator */
+				} _imap;
+			} _u1;				/* 96: */
+#define di_gengen	u._file._u1._imap._gengen
+
+			union {
+				xtpage_t _xtroot;
+				struct {
+					u8 unused[16];	/* 16: */
+					dxd_t _dxd;	/* 16: */
+					union {
+						u32 _rdev;	/* 4: */
+						u8 _fastsymlink[128];
+					} _u;
+					u8 _inlineea[128];
+				} _special;
+			} _u2;
+		} _file;
+#define di_xtroot	u._file._u2._xtroot
+#define di_dxd		u._file._u2._special._dxd
+#define di_btroot	di_xtroot
+#define di_inlinedata	u._file._u2._special._u
+#define di_rdev		u._file._u2._special._u._rdev
+#define di_fastsymlink	u._file._u2._special._u._fastsymlink
+#define di_inlineea     u._file._u2._special._inlineea
+	} u;
+};
+
+typedef struct dinode dinode_t;
+
+/* di_mode */
+#define IFMT	0xF000		/* S_IFMT - mask of file type */
+#define IFDIR	0x4000		/* S_IFDIR - directory */
+#define IFREG	0x8000		/* S_IFREG - regular file */
+#define IFLNK	0xA000		/* S_IFLNK - symbolic link */
+
+/* extended mode bits (on-disk inode di_mode) */
+#define INLINEEA        0x00040000	/* inline EA area free */
+
+/* from jfs_imap.h */
+
+#define	EXTSPERIAG	128	/* number of disk inode extent per iag  */
+#define SMAPSZ		4	/* number of words per summary map      */
+#define	MAXAG		128	/* maximum number of allocation groups  */
+
+/*
+ *	inode allocation map:
+ * 
+ * inode allocation map consists of 
+ * . the inode map control page and
+ * . inode allocation group pages (per 4096 inodes)
+ * which are addressed by standard JFS xtree.
+ */
+/*
+ *	inode allocation group page (per 4096 inodes of an AG)
+ */
+typedef struct {
+	s64 agstart;		/* 8: starting block of ag              */
+	s32 iagnum;		/* 4: inode allocation group number     */
+	s32 inofreefwd;		/* 4: ag inode free list forward        */
+	s32 inofreeback;	/* 4: ag inode free list back           */
+	s32 extfreefwd;		/* 4: ag inode extent free list forward */
+	s32 extfreeback;	/* 4: ag inode extent free list back    */
+	s32 iagfree;		/* 4: iag free list                     */
+
+	/* summary map: 1 bit per inode extent */
+	s32 inosmap[SMAPSZ];	/* 16: sum map of mapwords w/ free inodes;
+				 *      note: this indicates free and backed
+				 *      inodes, if the extent is not backed the
+				 *      value will be 1.  if the extent is
+				 *      backed but all inodes are being used the
+				 *      value will be 1.  if the extent is
+				 *      backed but at least one of the inodes is
+				 *      free the value will be 0.
+				 */
+	s32 extsmap[SMAPSZ];	/* 16: sum map of mapwords w/ free extents */
+	s32 nfreeinos;		/* 4: number of free inodes             */
+	s32 nfreeexts;		/* 4: number of free extents            */
+	/* (72) */
+	u8 pad[1976];		/* 1976: pad to 2048 bytes */
+	/* allocation bit map: 1 bit per inode (0 - free, 1 - allocated) */
+	u32 wmap[EXTSPERIAG];	/* 512: working allocation map  */
+	u32 pmap[EXTSPERIAG];	/* 512: persistent allocation map */
+	pxd_t inoext[EXTSPERIAG];	/* 1024: inode extent addresses */
+} iag_t;			/* (4096) */
+
+#endif /* _JFS_H_ */
diff --git a/stage2/mb_header.h b/stage2/mb_header.h
new file mode 100644
index 0000000..2193457
--- /dev/null
+++ b/stage2/mb_header.h
@@ -0,0 +1,90 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000   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.
+ */
+
+/*
+ *  MultiBoot Header description
+ */
+
+struct multiboot_header
+{
+  /* Must be MULTIBOOT_MAGIC - see below.  */
+  unsigned magic;
+  
+  /* Feature flags - see below.  */
+  unsigned flags;
+  
+  /*
+   * Checksum
+   *
+   * The above fields plus this one must equal 0 mod 2^32.
+   */
+  unsigned checksum;
+  
+  /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set.  */
+  unsigned header_addr;
+  unsigned load_addr;
+  unsigned load_end_addr;
+  unsigned bss_end_addr;
+  unsigned entry_addr;
+
+  /* These are only valid if MULTIBOOT_VIDEO_MODE is set.  */
+  unsigned mode_type;
+  unsigned width;
+  unsigned height;
+  unsigned depth;
+};
+
+/*
+ * The entire multiboot_header must be contained
+ * within the first MULTIBOOT_SEARCH bytes of the kernel image.
+ */
+#define MULTIBOOT_SEARCH		8192
+#define MULTIBOOT_FOUND(addr, len) \
+  (! ((addr) & 0x3) \
+   && (len) >= 12 \
+   && *((int *) (addr)) == MULTIBOOT_MAGIC \
+   && ! (*((unsigned *) (addr)) + *((unsigned *) (addr + 4)) \
+	 + *((unsigned *) (addr + 8))) \
+   && (! (MULTIBOOT_AOUT_KLUDGE & *((int *) (addr + 4))) || (len) >= 32) \
+   && (! (MULTIBOOT_VIDEO_MODE & *((int *) (addr + 4))) || (len) >= 48))
+
+/* Magic value identifying the multiboot_header.  */
+#define MULTIBOOT_MAGIC			0x1BADB002
+
+/*
+ * Features flags for 'flags'.
+ * If a boot loader sees a flag in MULTIBOOT_MUSTKNOW set
+ * and it doesn't understand it, it must fail.
+ */
+#define MULTIBOOT_MUSTKNOW		0x0000FFFF
+
+/* currently unsupported flags...  this is a kind of version number.  */
+#define MULTIBOOT_UNSUPPORTED		0x0000FFF8
+
+/* Align all boot modules on i386 page (4KB) boundaries.  */
+#define MULTIBOOT_PAGE_ALIGN		0x00000001
+
+/* Must pass memory information to OS.  */
+#define MULTIBOOT_MEMORY_INFO		0x00000002
+
+/* Must pass video information to OS.  */
+#define MULTIBOOT_VIDEO_MODE		0x00000004
+
+/* This flag indicates the use of the address fields in the header.  */
+#define MULTIBOOT_AOUT_KLUDGE		0x00010000
diff --git a/stage2/mb_info.h b/stage2/mb_info.h
new file mode 100644
index 0000000..1e1e63b
--- /dev/null
+++ b/stage2/mb_info.h
@@ -0,0 +1,217 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,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 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.
+ */
+
+/*
+ *  The structure type "mod_list" is used by the "multiboot_info" structure.
+ */
+
+struct mod_list
+{
+  /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */
+  unsigned long mod_start;
+  unsigned long mod_end;
+  
+  /* Module command line */
+  unsigned long cmdline;
+  
+  /* padding to take it to 16 bytes (must be zero) */
+  unsigned long pad;
+};
+
+
+/*
+ *  INT-15, AX=E820 style "AddressRangeDescriptor"
+ *  ...with a "size" parameter on the front which is the structure size - 4,
+ *  pointing to the next one, up until the full buffer length of the memory
+ *  map has been reached.
+ */
+
+struct AddrRangeDesc
+{
+  unsigned long size;
+  unsigned long long BaseAddr;
+  unsigned long long Length;
+  unsigned long Type;
+  
+  /* unspecified optional padding... */
+} __attribute__ ((packed));
+
+/* usable memory "Type", all others are reserved.  */
+#define MB_ARD_MEMORY		1
+
+
+/* Drive Info structure.  */
+struct drive_info
+{
+  /* The size of this structure.  */
+  unsigned long size;
+
+  /* The BIOS drive number.  */
+  unsigned char drive_number;
+
+  /* The access mode (see below).  */
+  unsigned char drive_mode;
+
+  /* The BIOS geometry.  */
+  unsigned short drive_cylinders;
+  unsigned char drive_heads;
+  unsigned char drive_sectors;
+
+  /* The array of I/O ports used for the drive.  */
+  unsigned short drive_ports[0];
+};
+
+/* Drive Mode.  */
+#define MB_DI_CHS_MODE		0
+#define MB_DI_LBA_MODE		1
+
+
+/* APM BIOS info.  */
+struct apm_info
+{
+  unsigned short version;
+  unsigned short cseg;
+  unsigned long offset;
+  unsigned short cseg_16;
+  unsigned short dseg_16;
+  unsigned short cseg_len;
+  unsigned short cseg_16_len;
+  unsigned short dseg_16_len;
+};
+
+
+/*
+ *  MultiBoot Info description
+ *
+ *  This is the struct passed to the boot image.  This is done by placing
+ *  its address in the EAX register.
+ */
+
+struct multiboot_info
+{
+  /* MultiBoot info version number */
+  unsigned long flags;
+  
+  /* Available memory from BIOS */
+  unsigned long mem_lower;
+  unsigned long mem_upper;
+  
+  /* "root" partition */
+  unsigned long boot_device;
+  
+  /* Kernel command line */
+  unsigned long cmdline;
+  
+  /* Boot-Module list */
+  unsigned long mods_count;
+  unsigned long mods_addr;
+  
+  union
+  {
+    struct
+    {
+      /* (a.out) Kernel symbol table info */
+      unsigned long tabsize;
+      unsigned long strsize;
+      unsigned long addr;
+      unsigned long pad;
+    }
+    a;
+    
+    struct
+    {
+      /* (ELF) Kernel section header table */
+      unsigned long num;
+      unsigned long size;
+      unsigned long addr;
+      unsigned long shndx;
+    }
+    e;
+  }
+  syms;
+  
+  /* Memory Mapping buffer */
+  unsigned long mmap_length;
+  unsigned long mmap_addr;
+  
+  /* Drive Info buffer */
+  unsigned long drives_length;
+  unsigned long drives_addr;
+  
+  /* ROM configuration table */
+  unsigned long config_table;
+  
+  /* Boot Loader Name */
+  unsigned long boot_loader_name;
+
+  /* APM table */
+  unsigned long apm_table;
+
+  /* Video */
+  unsigned long vbe_control_info;
+  unsigned long vbe_mode_info;
+  unsigned short vbe_mode;
+  unsigned short vbe_interface_seg;
+  unsigned short vbe_interface_off;
+  unsigned short vbe_interface_len;
+};
+
+/*
+ *  Flags to be set in the 'flags' parameter above
+ */
+
+/* is there basic lower/upper memory information? */
+#define MB_INFO_MEMORY			0x00000001
+/* is there a boot device set? */
+#define MB_INFO_BOOTDEV			0x00000002
+/* is the command-line defined? */
+#define MB_INFO_CMDLINE			0x00000004
+/* are there modules to do something with? */
+#define MB_INFO_MODS			0x00000008
+
+/* These next two are mutually exclusive */
+
+/* is there a symbol table loaded? */
+#define MB_INFO_AOUT_SYMS		0x00000010
+/* is there an ELF section header table? */
+#define MB_INFO_ELF_SHDR		0x00000020
+
+/* is there a full memory map? */
+#define MB_INFO_MEM_MAP			0x00000040
+
+/* Is there drive info?  */
+#define MB_INFO_DRIVE_INFO		0x00000080
+
+/* Is there a config table?  */
+#define MB_INFO_CONFIG_TABLE		0x00000100
+
+/* Is there a boot loader name?  */
+#define MB_INFO_BOOT_LOADER_NAME	0x00000200
+
+/* Is there a APM table?  */
+#define MB_INFO_APM_TABLE		0x00000400
+
+/* Is there video information?  */
+#define MB_INFO_VIDEO_INFO		0x00000800
+
+/*
+ *  The following value must be present in the EAX register.
+ */
+
+#define MULTIBOOT_VALID			0x2BADB002
diff --git a/stage2/md5.c b/stage2/md5.c
new file mode 100644
index 0000000..21205ba
--- /dev/null
+++ b/stage2/md5.c
@@ -0,0 +1,383 @@
+/* md5.c - an implementation of the MD5 algorithm and MD5 crypt */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000, 2001  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.
+ */
+
+/* See RFC 1321 for a description of the MD5 algorithm.
+ */
+
+#include <md5.h>
+#ifndef TEST
+# include <shared.h>
+#endif
+
+#ifdef TEST
+# include <string.h>
+# define USE_MD5_PASSWORDS
+# define USE_MD5
+#endif
+
+#ifdef USE_MD5_PASSWORDS
+# define USE_MD5
+#endif
+
+#ifdef USE_MD5
+
+#define cpu_to_le32(x) (x)
+#define le32_to_cpu(x) cpu_to_le32(x)
+typedef unsigned int UINT4;
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x >> (32 - (n)))))
+
+static UINT4 initstate[4] =
+{
+  0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 
+};
+
+static char s1[4] = {  7, 12, 17, 22 };
+static char s2[4] = {  5,  9, 14, 20 };
+static char s3[4] = {  4, 11, 16, 23 };
+static char s4[4] = {  6, 10, 15, 21 };
+
+static UINT4 T[64] =
+{
+  0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
+  0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+  0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
+  0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
+  0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
+  0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
+  0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
+  0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
+  0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
+  0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+  0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
+  0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
+  0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
+  0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+  0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
+  0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
+};
+
+static const char *b64t =
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static UINT4 state[4];
+static unsigned int length;
+static unsigned char buffer[64];
+
+static void
+md5_transform (const unsigned char block[64])
+{
+  int i, j;
+  UINT4 a,b,c,d,tmp;
+  const UINT4 *x = (UINT4 *) block;
+
+  a = state[0];
+  b = state[1];
+  c = state[2];
+  d = state[3];
+
+  /* Round 1 */
+  for (i = 0; i < 16; i++)
+    {
+      tmp = a + F (b, c, d) + le32_to_cpu (x[i]) + T[i];
+      tmp = ROTATE_LEFT (tmp, s1[i & 3]);
+      tmp += b;
+      a = d; d = c; c = b; b = tmp;
+    }
+  /* Round 2 */
+  for (i = 0, j = 1; i < 16; i++, j += 5)
+    {
+      tmp = a + G (b, c, d) + le32_to_cpu (x[j & 15]) + T[i+16];
+      tmp = ROTATE_LEFT (tmp, s2[i & 3]);
+      tmp += b;
+      a = d; d = c; c = b; b = tmp;
+    }
+  /* Round 3 */
+  for (i = 0, j = 5; i < 16; i++, j += 3)
+    {
+      tmp = a + H (b, c, d) + le32_to_cpu (x[j & 15]) + T[i+32];
+      tmp = ROTATE_LEFT (tmp, s3[i & 3]);
+      tmp += b;
+      a = d; d = c; c = b; b = tmp;
+    }
+  /* Round 4 */
+  for (i = 0, j = 0; i < 16; i++, j += 7)
+    {
+      tmp = a + I (b, c, d) + le32_to_cpu (x[j & 15]) + T[i+48];
+      tmp = ROTATE_LEFT (tmp, s4[i & 3]);
+      tmp += b;
+      a = d; d = c; c = b; b = tmp;
+    }
+
+  state[0] += a;
+  state[1] += b;
+  state[2] += c;
+  state[3] += d;
+}
+
+static void
+md5_init(void)
+{
+  memcpy ((char *) state, (char *) initstate, sizeof (initstate));
+  length = 0;
+}
+
+static void
+md5_update (const char *input, int inputlen)
+{
+  int buflen = length & 63;
+  length += inputlen;
+  if (buflen + inputlen < 64) 
+    {
+      memcpy (buffer + buflen, input, inputlen);
+      buflen += inputlen;
+      return;
+    }
+  
+  memcpy (buffer + buflen, input, 64 - buflen);
+  md5_transform (buffer);
+  input += 64 - buflen;
+  inputlen -= 64 - buflen;
+  while (inputlen >= 64)
+    {
+      md5_transform (input);
+      input += 64;
+      inputlen -= 64;
+    }
+  memcpy (buffer, input, inputlen);
+  buflen = inputlen;
+}
+
+static unsigned char *
+md5_final()
+{
+  int i, buflen = length & 63;
+
+  buffer[buflen++] = 0x80;
+  memset (buffer+buflen, 0, 64 - buflen);
+  if (buflen > 56)
+    {
+      md5_transform (buffer);
+      memset (buffer, 0, 64);
+      buflen = 0;
+    }
+  
+  *(UINT4 *) (buffer + 56) = cpu_to_le32 (8 * length);
+  *(UINT4 *) (buffer + 60) = 0;
+  md5_transform (buffer);
+
+  for (i = 0; i < 4; i++)
+    state[i] = cpu_to_le32 (state[i]);
+  return (unsigned char *) state;
+}
+
+#ifdef USE_MD5_PASSWORDS
+/* If CHECK is true, check a password for correctness. Returns 0
+   if password was correct, and a value != 0 for error, similarly
+   to strcmp.
+   If CHECK is false, crypt KEY and save the result in CRYPTED.
+   CRYPTED must have a salt.  */
+int
+md5_password (const char *key, char *crypted, int check)
+{
+  int keylen = strlen (key);
+  char *salt = crypted + 3; /* skip $1$ header */
+  char *p; 
+  int saltlen;
+  int i, n;
+  unsigned char alt_result[16];
+  unsigned char *digest;
+
+  if (check)
+    {
+      /* If our crypted password isn't 3 chars, then it can't be md5
+	 crypted. So, they don't match.  */
+      if (strlen(crypted) <= 3)
+	return 1;
+      
+      saltlen = strstr (salt, "$") - salt;
+    }
+  else
+    {
+      char *end = strstr (salt, "$");
+      if (end && end - salt < 8)
+	saltlen = end - salt;
+      else
+	saltlen = 8;
+
+      salt[saltlen] = '$';
+    }
+  
+  md5_init ();
+  md5_update (key, keylen);
+  md5_update (salt, saltlen);
+  md5_update (key, keylen);
+  digest = md5_final ();
+  memcpy (alt_result, digest, 16);
+  
+  memcpy ((char *) state, (char *) initstate, sizeof (initstate));
+  length = 0;
+  md5_update (key, keylen);
+  md5_update (crypted, 3 + saltlen); /* include the $1$ header */
+  for (i = keylen; i > 16; i -= 16)
+    md5_update (alt_result, 16);
+  md5_update (alt_result, i);
+
+  for (i = keylen; i > 0; i >>= 1)
+    md5_update (key + ((i & 1) ? keylen : 0), 1);
+  digest = md5_final ();
+
+  for (i = 0; i < 1000; i++)
+    {
+      memcpy (alt_result, digest, 16);
+
+      memcpy ((char *) state, (char *) initstate, sizeof (initstate));
+      length = 0;
+      if ((i & 1) != 0)
+	md5_update (key, keylen);
+      else
+	md5_update (alt_result, 16);
+      
+      if (i % 3 != 0)
+	md5_update (salt, saltlen);
+
+      if (i % 7 != 0)
+	md5_update (key, keylen);
+
+      if ((i & 1) != 0)
+	md5_update (alt_result, 16);
+      else
+	md5_update (key, keylen);
+      digest = md5_final ();
+    }
+
+  p = salt + saltlen + 1;
+  for (i = 0; i < 5; i++)
+    {
+      unsigned int w = 
+	digest[i == 4 ? 5 : 12+i] | (digest[6+i] << 8) | (digest[i] << 16);
+      for (n = 4; n-- > 0;)
+	{
+	  if (check)
+	    {
+	      if (*p++ != b64t[w & 0x3f])
+		return 1;
+	    }
+	  else
+	    {
+	      *p++ = b64t[w & 0x3f];
+	    }
+	  
+	  w >>= 6;
+	}
+    }
+  {
+    unsigned int w = digest[11];
+    for (n = 2; n-- > 0;)
+      {
+	if (check)
+	  {
+	    if (*p++ != b64t[w & 0x3f])
+	      return 1;
+	  }
+	else
+	  {
+	    *p++ = b64t[w & 0x3f];
+	  }
+	
+	w >>= 6;
+      }
+  }
+
+  if (! check)
+    *p = '\0';
+  
+  return *p;
+}
+#endif
+
+#ifdef TEST
+static char *
+md5 (const char *input) 
+{
+  memcpy ((char *) state, (char *) initstate, sizeof (initstate));
+  length = 0;
+  md5_update (input, strlen (input));
+  return md5_final ();
+}
+
+static void
+test (char *buffer, char *expected) 
+{
+  char result[16 * 3 +1];
+  unsigned char* digest = md5 (buffer);
+  int i;
+
+  for (i=0; i < 16; i++)
+    sprintf (result+2*i, "%02x", digest[i]);
+
+  if (strcmp (result, expected))
+    printf ("MD5(%s) failed: %s\n", buffer, result);
+  else
+    printf ("MD5(%s) OK\n", buffer);
+}
+
+int
+main (void)
+{
+  test ("", "d41d8cd98f00b204e9800998ecf8427e");
+  test ("a", "0cc175b9c0f1b6a831c399e269772661");
+  test ("abc", "900150983cd24fb0d6963f7d28e17f72");
+  test ("message digest", "f96b697d7cb7938d525a2f31aaf161d0");
+  test ("abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b");
+  test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
+	"d174ab98d277d9f5a5611c2c9f419d9f");
+  test ("12345678901234567890123456789012345678901234567890123456789012345678901234567890",
+	"57edf4a22be3c955ac49da2e2107b67a");
+  test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz3456",
+	"6831fa90115bb9a54fbcd4f9fee0b5c4");
+  test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz345",
+	"bc40505cc94a43b7ff3e2ac027325233");
+  test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz34567",
+	"fa94b73a6f072a0239b52acacfbcf9fa");
+  test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz345678901234",
+	"bd201eae17f29568927414fa326f1267");
+  test ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz34567890123",
+	"80063db1e6b70a2e91eac903f0e46b85");
+
+  if (check_md5_password ("Hello world!",
+			  "$1$saltstri$YMyguxXMBpd2TEZ.vS/3q1"))
+    printf ("Password differs\n");
+  else
+    printf ("Password OK\n");
+  return 0;
+}
+#endif
+
+#endif
diff --git a/stage2/md5.h b/stage2/md5.h
new file mode 100644
index 0000000..c1dbd06
--- /dev/null
+++ b/stage2/md5.h
@@ -0,0 +1,30 @@
+/* md5.h - an implementation of the MD5 algorithm and MD5 crypt */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000  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.
+ */
+
+/* If CHECK is true, check a password for correctness. Returns 0
+   if password was correct, and a value != 0 for error, similarly
+   to strcmp.
+   If CHECK is false, crypt KEY and save the result in CRYPTED.
+   CRYPTED must have a salt.  */
+extern int md5_password (const char *key, char *crypted, int check);
+
+/* For convenience.  */
+#define check_md5_password(key,crypted)	md5_password((key), (crypted), 1)
+#define make_md5_password(key,crypted)	md5_password((key), (crypted), 0)
diff --git a/stage2/nbi.h b/stage2/nbi.h
new file mode 100644
index 0000000..3f70e21
--- /dev/null
+++ b/stage2/nbi.h
@@ -0,0 +1,33 @@
+/* nbi.h - definitions for Net Boot Image */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000  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 GRUB_NBI_HEADER
+#define GRUB_NBI_HEADER
+
+#define NBI_MAGIC		0x1B031336
+#define NBI_DEST_ADDR		0x10000
+#define NBI_DEST_SEG		0x1000
+#define NBI_DEST_OFF		0x0000
+#define RELOCATED_ADDR		0x8000
+#define RELOCATED_SEG		0x0800
+#define RELOCATED_OFF		0x0000
+#define STAGE2_START_ADDR	0x8200
+
+#endif /* ! GRUB_NBI_HEADER */
diff --git a/stage2/nbloader.S b/stage2/nbloader.S
new file mode 100644
index 0000000..57ad936
--- /dev/null
+++ b/stage2/nbloader.S
@@ -0,0 +1,121 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000   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.
+ */
+
+#include <nbi.h>
+#include <diskless_size.h>
+			
+	.file	"nbloader.S"
+	.text
+	.code16
+	
+	/* Just a dummy entry */
+.globl _start; _start:
+
+	/*
+	 * netboot image header
+	 */
+
+	.long	NBI_MAGIC
+	.long	0x00000004
+	/* load address of the first block  */
+	.word	NBI_DEST_OFF
+	.word	NBI_DEST_SEG
+	/* start addr of the relocation code */
+	.word	NBI_DEST_OFF + (relocate - _start)
+	.word	NBI_DEST_SEG
+
+	.long	0x04000004
+	.long	NBI_DEST_ADDR + 0x0200
+	.long	DISKLESS_SIZE
+	.long	DISKLESS_SIZE
+
+relocate:
+	/*
+	 * This code is for now located at 0x10000.
+	 * Relocate the code in two steps:
+	 * 1. Copy the first 32k to 0x8000 and jump to the relocated area.
+	 * 2. Copy the rest to 0x10000 (0x8000 + 32k).
+	 */
+
+	/* Copy the first 32k  */
+	movw	$NBI_DEST_SEG, %ax
+	movw	%ax, %ds
+	movw	$RELOCATED_SEG, %ax
+	movw	%ax, %es
+	xorw	%si, %si
+	xorw	%di, %di
+	/* Always copy 32k bytes */
+	movw	$0x4000, %cx
+
+	cld
+	rep
+	movsw
+
+	/* Jump to the relocated address */
+	ljmp	$0, $(RELOCATED_ADDR + copy_rest - _start)
+
+	/* Copy the rest */
+copy_rest:
+	/* Set %edx to the number of bytes */
+	movl	$(DISKLESS_SIZE + 0x200 - 0x8000), %edx
+	
+copy_loop:
+	/* Check the rest */
+	orl	%edx, %edx
+	jz	boot_stage2
+
+	/* Copy by 32k, as that is easy to implement */
+	movl	$0x8000, %ecx
+	cmpl	%ecx, %edx
+	jg	copy
+	movl	%edx, %ecx
+	
+copy:
+	/* Update the number of rest bytes */
+	subl	%ecx, %edx
+
+	/* Add 0x0800 (32k >> 4) into %es and %ds */
+	movw	%es, %ax
+	addw	$0x0800, %ax
+	movw	%ax, %es
+	movw	%ds, %ax
+	addw	$0x800, %ax
+	movw	%ax, %ds
+	
+	/* Zero the offsets */
+	xorw	%si, %si
+	xorw	%di, %di
+	
+	/* Use word-size copy */
+	addw	$1, %cx
+	shrw	$1, %cx
+
+	/* The direction is already correct */
+	rep
+	movsw
+
+	jmp	copy_loop
+
+	/* Jump to the stage2 */
+boot_stage2:
+	ljmp	$0, $STAGE2_START_ADDR
+	
+	/* This ensures that the length of this image will be 1 sector */
+	. = _start + 0x200 - 1
+	.byte	0
diff --git a/stage2/pc_slice.h b/stage2/pc_slice.h
new file mode 100644
index 0000000..a38d97f
--- /dev/null
+++ b/stage2/pc_slice.h
@@ -0,0 +1,251 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 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 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 _PC_SLICE_H
+#define _PC_SLICE_H
+
+/*
+ *  These define the basic PC MBR sector characteristics
+ */
+
+#define PC_MBR_SECTOR  0
+
+#define PC_MBR_SIG_OFFSET  510
+#define PC_MBR_SIGNATURE   0xaa55
+
+#define PC_SLICE_OFFSET 446
+#define PC_SLICE_MAX    4
+
+
+/*
+ *  Defines to guarantee structural alignment.
+ */
+
+#define PC_MBR_CHECK_SIG(mbr_ptr) \
+  ( *( (unsigned short *) (((int) mbr_ptr) + PC_MBR_SIG_OFFSET) ) \
+   == PC_MBR_SIGNATURE )
+
+#define PC_MBR_SIG(mbr_ptr) \
+  ( *( (unsigned short *) (((int) mbr_ptr) + PC_MBR_SIG_OFFSET) ) )
+
+#define PC_SLICE_FLAG(mbr_ptr, part) \
+  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET \
+			  + (part << 4)) ) )
+
+#define PC_SLICE_HEAD(mbr_ptr, part) \
+  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 1 \
+			  + (part << 4)) ) )
+
+#define PC_SLICE_SEC(mbr_ptr, part) \
+  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 2 \
+			  + (part << 4)) ) )
+
+#define PC_SLICE_CYL(mbr_ptr, part) \
+  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 3 \
+			  + (part << 4)) ) )
+
+#define PC_SLICE_TYPE(mbr_ptr, part) \
+  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 4 \
+			  + (part << 4)) ) )
+
+#define PC_SLICE_EHEAD(mbr_ptr, part) \
+  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 5 \
+			  + (part << 4)) ) )
+
+#define PC_SLICE_ESEC(mbr_ptr, part) \
+  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 6 \
+			  + (part << 4)) ) )
+
+#define PC_SLICE_ECYL(mbr_ptr, part) \
+  ( *( (unsigned char *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 7 \
+			  + (part << 4)) ) )
+
+#define PC_SLICE_START(mbr_ptr, part) \
+  ( *( (unsigned long *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 8 \
+			  + (part << 4)) ) )
+
+#define PC_SLICE_LENGTH(mbr_ptr, part) \
+  ( *( (unsigned long *) (((int) mbr_ptr) + PC_SLICE_OFFSET + 12 \
+			  + (part << 4)) ) )
+
+
+/*
+ *  PC flag types are defined here.
+ */
+
+#define PC_SLICE_FLAG_NONE      0
+#define PC_SLICE_FLAG_BOOTABLE  0x80
+
+/*
+ *  Known PC partition types are defined here.
+ */
+
+/* This is not a flag actually, but used as if it were a flag.  */
+#define PC_SLICE_TYPE_HIDDEN_FLAG	0x10
+
+#define PC_SLICE_TYPE_NONE         	0
+#define PC_SLICE_TYPE_FAT12        	1
+#define PC_SLICE_TYPE_FAT16_LT32M  	4
+#define PC_SLICE_TYPE_EXTENDED     	5
+#define PC_SLICE_TYPE_FAT16_GT32M  	6
+#define PC_SLICE_TYPE_FAT32		0xb
+#define PC_SLICE_TYPE_FAT32_LBA		0xc
+#define PC_SLICE_TYPE_FAT16_LBA		0xe
+#define PC_SLICE_TYPE_WIN95_EXTENDED	0xf
+#define PC_SLICE_TYPE_EZD        	0x55
+#define PC_SLICE_TYPE_MINIX		0x80
+#define PC_SLICE_TYPE_LINUX_MINIX	0x81
+#define PC_SLICE_TYPE_EXT2FS       	0x83
+#define PC_SLICE_TYPE_LINUX_EXTENDED	0x85
+#define PC_SLICE_TYPE_VSTAFS		0x9e
+#define PC_SLICE_TYPE_DELL_UTIL		0xde
+#define PC_SLICE_TYPE_LINUX_RAID	0xfd
+
+
+/* For convinience.  */
+/* Check if TYPE is a FAT partition type. Clear the hidden flag before
+   the check, to allow the user to mount a hidden partition in GRUB.  */
+#define IS_PC_SLICE_TYPE_FAT(type)	\
+  ({ int _type = (type) & ~PC_SLICE_TYPE_HIDDEN_FLAG; \
+     _type == PC_SLICE_TYPE_FAT12 \
+     || _type == PC_SLICE_TYPE_FAT16_LT32M \
+     || _type == PC_SLICE_TYPE_FAT16_GT32M \
+     || _type == PC_SLICE_TYPE_FAT16_LBA \
+     || _type == PC_SLICE_TYPE_FAT32 \
+     || _type == PC_SLICE_TYPE_FAT32_LBA \
+     || _type == PC_SLICE_TYPE_DELL_UTIL; })
+
+#define IS_PC_SLICE_TYPE_EXTENDED(type)	\
+  (((type) == PC_SLICE_TYPE_EXTENDED)	\
+   || ((type) == PC_SLICE_TYPE_WIN95_EXTENDED)	\
+   || ((type) == PC_SLICE_TYPE_LINUX_EXTENDED))
+
+#define IS_PC_SLICE_TYPE_MINIX(type) \
+  (((type) == PC_SLICE_TYPE_MINIX)	\
+   || ((type) == PC_SLICE_TYPE_LINUX_MINIX))
+
+/* these ones are special, as they use their own partitioning scheme
+   to subdivide the PC partitions from there.  */
+#define PC_SLICE_TYPE_FREEBSD		0xa5
+#define PC_SLICE_TYPE_OPENBSD		0xa6
+#define PC_SLICE_TYPE_NETBSD		0xa9
+
+/* For convenience.  */
+#define IS_PC_SLICE_TYPE_BSD_WITH_FS(type,fs)	\
+  ((type) == (PC_SLICE_TYPE_FREEBSD | ((fs) << 8)) \
+   || (type) == (PC_SLICE_TYPE_OPENBSD | ((fs) << 8)) \
+   || (type) == (PC_SLICE_TYPE_NETBSD | (fs) << 8))
+
+#define IS_PC_SLICE_TYPE_BSD(type)	IS_PC_SLICE_TYPE_BSD_WITH_FS(type,0)
+
+/*
+ *  *BSD-style disklabel & partition definitions.
+ *
+ *  This is a subdivided slice of type 'PC_SLICE_TYPE_BSD', so all of
+ *  these, except where noted, are relative to the slice in question.
+ */
+
+#define BSD_LABEL_SECTOR 1
+#define BSD_LABEL_MAGIC  0x82564557
+
+#define BSD_LABEL_MAG_OFFSET 0
+#define BSD_LABEL_MAG2_OFFSET 132
+#define BSD_LABEL_NPARTS_OFFSET 138
+#define BSD_LABEL_NPARTS_MAX 8
+
+#define BSD_PART_OFFSET 148
+
+
+/*
+ *  Defines to guarantee structural alignment.
+ */
+
+#define BSD_LABEL_CHECK_MAG(l_ptr) \
+  ( *( (unsigned long *) (((int) l_ptr) + BSD_LABEL_MAG_OFFSET) ) \
+   == ( (unsigned long) BSD_LABEL_MAGIC ) )
+
+#define BSD_LABEL_MAG(l_ptr) \
+  ( *( (unsigned long *) (((int) l_ptr) + BSD_LABEL_MAG_OFFSET) ) )
+
+#define BSD_LABEL_DTYPE(l_ptr) \
+  ( *( (unsigned short *) (((int) l_ptr) + BSD_LABEL_MAG_OFFSET + 4) ) )
+
+#define BSD_LABEL_NPARTS(l_ptr) \
+  ( *( (unsigned short *) (((int) l_ptr) + BSD_LABEL_NPARTS_OFFSET) ) )
+
+#define BSD_PART_LENGTH(l_ptr, part) \
+  ( *( (unsigned long *) (((int) l_ptr) + BSD_PART_OFFSET \
+			  + (part << 4)) ) )
+
+#define BSD_PART_START(l_ptr, part) \
+  ( *( (unsigned long *) (((int) l_ptr) + BSD_PART_OFFSET + 4 \
+			  + (part << 4)) ) )
+
+#define BSD_PART_FRAG_SIZE(l_ptr, part) \
+  ( *( (unsigned long *) (((int) l_ptr) + BSD_PART_OFFSET + 8 \
+			  + (part << 4)) ) )
+
+#define BSD_PART_TYPE(l_ptr, part) \
+  ( *( (unsigned char *) (((int) l_ptr) + BSD_PART_OFFSET + 12 \
+			  + (part << 4)) ) )
+
+#define BSD_PART_FRAGS_PER_BLOCK(l_ptr, part) \
+  ( *( (unsigned char *) (((int) l_ptr) + BSD_PART_OFFSET + 13 \
+			  + (part << 4)) ) )
+
+#define BSD_PART_EXTRA(l_ptr, part) \
+  ( *( (unsigned short *) (((int) l_ptr) + BSD_PART_OFFSET + 14 \
+			  + (part << 4)) ) )
+
+
+/* possible values for the "DISKTYPE"... all essentially irrelevant
+   except for DTYPE_SCSI */
+#define DTYPE_SMD               1	/* SMD, XSMD; VAX hp/up */
+#define DTYPE_MSCP              2	/* MSCP */
+#define DTYPE_DEC               3	/* other DEC (rk, rl) */
+#define DTYPE_SCSI              4	/* SCSI */
+#define DTYPE_ESDI              5	/* ESDI interface */
+#define DTYPE_ST506             6	/* ST506 etc. */
+#define DTYPE_HPIB              7	/* CS/80 on HP-IB */
+#define DTYPE_HPFL              8	/* HP Fiber-link */
+#define DTYPE_FLOPPY            10	/* floppy */
+
+
+/* possible values for the *BSD-style partition type */
+#define	FS_UNUSED	0	/* unused */
+#define	FS_SWAP		1	/* swap */
+#define	FS_V6		2	/* Sixth Edition */
+#define	FS_V7		3	/* Seventh Edition */
+#define	FS_SYSV		4	/* System V */
+#define	FS_V71K		5	/* V7 with 1K blocks (4.1, 2.9) */
+#define	FS_V8		6	/* Eighth Edition, 4K blocks */
+#define	FS_BSDFFS	7	/* 4.2BSD fast file system */
+#define	FS_MSDOS	8	/* MSDOS file system */
+#define	FS_BSDLFS	9	/* 4.4BSD log-structured file system */
+#define	FS_OTHER	10	/* in use, but unknown/unsupported */
+#define	FS_HPFS		11	/* OS/2 high-performance file system */
+#define	FS_ISO9660	12	/* ISO 9660, normally CD-ROM */
+#define	FS_BOOT		13	/* partition contains bootstrap */
+#define	FS_ADOS		14	/* AmigaDOS fast file system */
+#define	FS_HFS		15	/* Macintosh HFS */
+#define	FS_FILECORE	16	/* Acorn Filecore Filing System */
+#define	FS_EXT2FS	17	/* Linux Extended 2 file system */
+
+
+#endif /* _PC_SLICE_H */
diff --git a/stage2/preset_menu.c b/stage2/preset_menu.c
new file mode 100644
index 0000000..f024174
--- /dev/null
+++ b/stage2/preset_menu.c
@@ -0,0 +1,22 @@
+const char *preset_menu =
+    "serial --unit=0 --speed=115200\n"
+    "terminal --timeout=0 --dumb console\n"
+    "rootnoverify (hd0,0)\n"
+    "default 2\n"
+    "fallback 1 0\n"
+    "timeout 3\n"
+    "\n"
+    "title sysloader\n"
+    "cmdline (hd0,0)/cmdline\n"
+    "kernel --use-cmd-line (hd0,0)/kernel\n"
+    "initrd (hd0,0)/ramdisk\n"
+    "\n"
+    "title recovery\n"
+    "cmdline (hd0,1)/cmdline\n"
+    "kernel --use-cmd-line (hd0,1)/kernel\n"
+    "initrd (hd0,1)/ramdisk\n"
+    "\n"
+    "title std_boot\n"
+    "cmdline (hd0,2)/cmdline\n"
+    "kernel --use-cmd-line (hd0,2)/kernel\n"
+    "initrd (hd0,2)/ramdisk\n";
diff --git a/stage2/pxeloader.S b/stage2/pxeloader.S
new file mode 100644
index 0000000..80e95fe
--- /dev/null
+++ b/stage2/pxeloader.S
@@ -0,0 +1,36 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000   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.
+ */
+
+	.file	"pxeloader.S"
+	.text
+
+	/* Start with the prehistoric environment... */
+	.code16
+	
+	/* Let's go */
+.globl _start; _start:
+
+	/* Jump to the real world */
+	ljmp	$0, $0x8200
+
+	/* This region is a junk. Do you say that this is wasteful?
+	   But I like that the memory layout of the body is consistent
+	   among different stage2s rather than scamping just for 1.5KB. */
+	. = _start + 0x8200 - 0x7C00 - 1
+	.byte	0
diff --git a/stage2/serial.c b/stage2/serial.c
new file mode 100644
index 0000000..16c376f
--- /dev/null
+++ b/stage2/serial.c
@@ -0,0 +1,434 @@
+/* serial.c - serial device interface */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,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.
+ */
+
+#ifdef SUPPORT_SERIAL
+
+#include <shared.h>
+#include <serial.h>
+#include <term.h>
+#include <terminfo.h>
+
+/* An input buffer.  */
+static char input_buf[8];
+static int npending = 0;
+
+static int serial_x;
+static int serial_y;
+
+static int keep_track = 1;
+
+
+/* Hardware-dependent definitions.  */
+
+#ifndef GRUB_UTIL
+/* The structure for speed vs. divisor.  */
+struct divisor
+{
+  int speed;
+  unsigned short div;
+};
+
+/* Store the port number of a serial unit.  */
+static unsigned short serial_hw_port = 0;
+
+/* The table which lists common configurations.  */
+static struct divisor divisor_tab[] =
+  {
+    { 2400,   0x0030 },
+    { 4800,   0x0018 },
+    { 9600,   0x000C },
+    { 19200,  0x0006 },
+    { 38400,  0x0003 },
+    { 57600,  0x0002 },
+    { 115200, 0x0001 }
+  };
+
+/* Read a byte from a port.  */
+static inline unsigned char
+inb (unsigned short port)
+{
+  unsigned char value;
+
+  asm volatile ("inb	%w1, %0" : "=a" (value) : "Nd" (port));
+  asm volatile ("outb	%%al, $0x80" : : );
+  
+  return value;
+}
+
+/* Write a byte to a port.  */
+static inline void
+outb (unsigned short port, unsigned char value)
+{
+  asm volatile ("outb	%b0, %w1" : : "a" (value), "Nd" (port));
+  asm volatile ("outb	%%al, $0x80" : : );
+}
+
+/* Fetch a key.  */
+int
+serial_hw_fetch (void)
+{
+  if (inb (serial_hw_port + UART_LSR) & UART_DATA_READY)
+    return inb (serial_hw_port + UART_RX);
+
+  return -1;
+}
+
+/* Put a chararacter.  */
+void
+serial_hw_put (int c)
+{
+  int timeout = 100000;
+
+  /* Wait until the transmitter holding register is empty.  */
+  while ((inb (serial_hw_port + UART_LSR) & UART_EMPTY_TRANSMITTER) == 0)
+    {
+      if (--timeout == 0)
+	/* There is something wrong. But what can I do?  */
+	return;
+    }
+
+  outb (serial_hw_port + UART_TX, c);
+}
+
+void
+serial_hw_delay (void)
+{
+  outb (0x80, 0);
+}
+
+/* Return the port number for the UNITth serial device.  */
+unsigned short
+serial_hw_get_port (int unit)
+{
+  /* The BIOS data area.  */
+  const unsigned short *addr = (const unsigned short *) 0x0400;
+  
+  return addr[unit];
+}
+
+/* Initialize a serial device. PORT is the port number for a serial device.
+   SPEED is a DTE-DTE speed which must be one of these: 2400, 4800, 9600,
+   19200, 38400, 57600 and 115200. WORD_LEN is the word length to be used
+   for the device. Likewise, PARITY is the type of the parity and
+   STOP_BIT_LEN is the length of the stop bit. The possible values for
+   WORD_LEN, PARITY and STOP_BIT_LEN are defined in the header file as
+   macros.  */
+int
+serial_hw_init (unsigned short port, unsigned int speed,
+		int word_len, int parity, int stop_bit_len)
+{
+  int i;
+  unsigned short div = 0;
+  unsigned char status = 0;
+  
+  /* Turn off the interrupt.  */
+  outb (port + UART_IER, 0);
+
+  /* Set DLAB.  */
+  outb (port + UART_LCR, UART_DLAB);
+  
+  /* Set the baud rate.  */
+  for (i = 0; i < sizeof (divisor_tab) / sizeof (divisor_tab[0]); i++)
+    if (divisor_tab[i].speed == speed)
+      {
+	div = divisor_tab[i].div;
+	break;
+      }
+  
+  if (div == 0)
+    return 0;
+  
+  outb (port + UART_DLL, div & 0xFF);
+  outb (port + UART_DLH, div >> 8);
+  
+  /* Set the line status.  */
+  status |= parity | word_len | stop_bit_len;
+  outb (port + UART_LCR, status);
+
+  /* Enable the FIFO.  */
+  outb (port + UART_FCR, UART_ENABLE_FIFO);
+
+  /* Turn on DTR, RTS, and OUT2.  */
+  outb (port + UART_MCR, UART_ENABLE_MODEM);
+
+  /* Store the port number.  */
+  serial_hw_port = port;
+  
+  /* Drain the input buffer.  */
+  while (serial_checkkey () != -1)
+    (void) serial_getkey ();
+
+  /* Get rid of TERM_NEED_INIT from the serial terminal.  */
+  for (i = 0; term_table[i].name; i++)
+    if (grub_strcmp (term_table[i].name, "serial") == 0)
+      {
+	term_table[i].flags &= ~TERM_NEED_INIT;
+	break;
+      }
+
+  /* FIXME: should check if the serial terminal was found.  */
+  
+  return 1;
+}
+#endif /* ! GRUB_UTIL */
+
+
+/* Generic definitions.  */
+
+static void
+serial_translate_key_sequence (void)
+{
+  const struct
+  {
+    char key;
+    char ascii;
+  }
+  three_code_table[] =
+    {
+      {'A', 16},
+      {'B', 14},
+      {'C', 6},
+      {'D', 2},
+      {'F', 5},
+      {'H', 1},
+      {'4', 4}
+    };
+
+  const struct
+  {
+    short key;
+    char ascii;
+  }
+  four_code_table[] =
+    {
+      {('1' | ('~' << 8)), 1},
+      {('3' | ('~' << 8)), 4},
+      {('5' | ('~' << 8)), 7},
+      {('6' | ('~' << 8)), 3},
+    };
+  
+  /* The buffer must start with ``ESC [''.  */
+  if (*((unsigned short *) input_buf) != ('\e' | ('[' << 8)))
+    return;
+  
+  if (npending >= 3)
+    {
+      int i;
+
+      for (i = 0;
+	   i < sizeof (three_code_table) / sizeof (three_code_table[0]);
+	   i++)
+	if (three_code_table[i].key == input_buf[2])
+	  {
+	    input_buf[0] = three_code_table[i].ascii;
+	    npending -= 2;
+	    grub_memmove (input_buf + 1, input_buf + 3, npending - 1);
+	    return;
+	  }
+    }
+
+  if (npending >= 4)
+    {
+      int i;
+      short key = *((short *) (input_buf + 2));
+
+      for (i = 0;
+	   i < sizeof (four_code_table) / sizeof (four_code_table[0]);
+	   i++)
+	if (four_code_table[i].key == key)
+	  {
+	    input_buf[0] = four_code_table[i].ascii;
+	    npending -= 3;
+	    grub_memmove (input_buf + 1, input_buf + 4, npending - 1);
+	    return;
+	  }
+    }
+}
+    
+static
+int fill_input_buf (int nowait)
+{
+  int i;
+
+  for (i = 0; i < 10000 && npending < sizeof (input_buf); i++)
+    {
+      int c;
+
+      c = serial_hw_fetch ();
+      if (c >= 0)
+	{
+	  input_buf[npending++] = c;
+
+	  /* Reset the counter to zero, to wait for the same interval.  */
+	  i = 0;
+	}
+      
+      if (nowait)
+	break;
+    }
+
+  /* Translate some key sequences.  */
+  serial_translate_key_sequence ();
+	  
+  return npending;
+}
+
+/* The serial version of getkey.  */
+int
+serial_getkey (void)
+{
+  int c;
+  
+  while (! fill_input_buf (0))
+    ;
+
+  c = input_buf[0];
+  npending--;
+  grub_memmove (input_buf, input_buf + 1, npending);
+  
+  return c;
+}
+
+/* The serial version of checkkey.  */
+int
+serial_checkkey (void)
+{
+  if (fill_input_buf (1))
+    return input_buf[0];
+
+  return -1;
+}
+
+/* The serial version of grub_putchar.  */
+void
+serial_putchar (int c)
+{
+  /* Keep track of the cursor.  */
+  if (keep_track)
+    {
+      /* The serial terminal doesn't have VGA fonts.  */
+      switch (c)
+	{
+	case DISP_UL:
+	  c = ACS_ULCORNER;
+	  break;
+	case DISP_UR:
+	  c = ACS_URCORNER;
+	  break;
+	case DISP_LL:
+	  c = ACS_LLCORNER;
+	  break;
+	case DISP_LR:
+	  c = ACS_LRCORNER;
+	  break;
+	case DISP_HORIZ:
+	  c = ACS_HLINE;
+	  break;
+	case DISP_VERT:
+	  c = ACS_VLINE;
+	  break;
+	case DISP_LEFT:
+	  c = ACS_LARROW;
+	  break;
+	case DISP_RIGHT:
+	  c = ACS_RARROW;
+	  break;
+	case DISP_UP:
+	  c = ACS_UARROW;
+	  break;
+	case DISP_DOWN:
+	  c = ACS_DARROW;
+	  break;
+	default:
+	  break;
+	}
+      
+      switch (c)
+	{
+	case '\r':
+	  serial_x = 0;
+	  break;
+	  
+	case '\n':
+	  serial_y++;
+	  break;
+	  
+	case '\b':
+	case 127:
+	  if (serial_x > 0)
+	    serial_x--;
+	  break;
+	  
+	case '\a':
+	  break;
+	  
+	default:
+	  if (serial_x >= 79)
+	    {
+	      serial_putchar ('\r');
+	      serial_putchar ('\n');
+	    }
+	  serial_x++;
+	  break;
+	}
+    }
+  
+  serial_hw_put (c);
+}
+
+int
+serial_getxy (void)
+{
+  return (serial_x << 8) | serial_y;
+}
+
+void
+serial_gotoxy (int x, int y)
+{
+  keep_track = 0;
+  ti_cursor_address (x, y);
+  keep_track = 1;
+  
+  serial_x = x;
+  serial_y = y;
+}
+
+void
+serial_cls (void)
+{
+  keep_track = 0;
+  ti_clear_screen ();
+  keep_track = 1;
+  
+  serial_x = serial_y = 0;
+}
+
+void
+serial_setcolorstate (color_state state)
+{
+  keep_track = 0;
+  if (state == COLOR_STATE_HIGHLIGHT)
+    ti_enter_standout_mode ();
+  else
+    ti_exit_standout_mode ();
+  keep_track = 1;
+}
+
+#endif /* SUPPORT_SERIAL */
diff --git a/stage2/serial.h b/stage2/serial.h
new file mode 100644
index 0000000..76c2227
--- /dev/null
+++ b/stage2/serial.h
@@ -0,0 +1,93 @@
+/* serial.h - serial device interface */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,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 GRUB_SERIAL_HEADER
+#define GRUB_SERIAL_HEADER	1
+
+/* Macros.  */
+
+/* The offsets of UART registers.  */
+#define UART_TX		0
+#define UART_RX		0
+#define UART_DLL	0
+#define UART_IER	1
+#define UART_DLH	1
+#define UART_IIR	2
+#define UART_FCR	2
+#define UART_LCR	3
+#define UART_MCR	4
+#define UART_LSR	5
+#define UART_MSR	6
+#define UART_SR		7
+
+/* For LSR bits.  */
+#define UART_DATA_READY		0x01
+#define UART_EMPTY_TRANSMITTER	0x20
+
+/* The type of parity.  */
+#define UART_NO_PARITY		0x00
+#define UART_ODD_PARITY		0x08
+#define UART_EVEN_PARITY	0x18
+
+/* The type of word length.  */
+#define UART_5BITS_WORD	0x00
+#define UART_6BITS_WORD	0x01
+#define UART_7BITS_WORD	0x02
+#define UART_8BITS_WORD	0x03
+
+/* The type of the length of stop bit.  */
+#define UART_1_STOP_BIT		0x00
+#define UART_2_STOP_BITS	0x04
+
+/* the switch of DLAB.  */
+#define UART_DLAB	0x80
+
+/* Enable the FIFO.  */
+#define UART_ENABLE_FIFO	0xC7
+
+/* Turn on DTR, RTS, and OUT2.  */
+#define UART_ENABLE_MODEM	0x0B
+
+
+/* Function prototypes.  */
+
+/* Fetch a key.  */
+int serial_hw_fetch (void);
+
+/* Put a character.  */
+void serial_hw_put (int c);
+
+/* Insert a delay.  */
+void serial_hw_delay (void);
+
+/* Return the port number for the UNITth serial device.  */
+unsigned short serial_hw_get_port (int unit);
+
+/* Initialize a serial device.  */
+int serial_hw_init (unsigned short port, unsigned int speed,
+		    int word_len, int parity, int stop_bit_len);
+
+#ifdef GRUB_UTIL
+/* Set the file name of a serial device (or a pty device). This is a
+   function specific to the grub shell.  */
+void serial_set_device (const char *device);
+#endif /* GRUB_UTIL */
+
+#endif /* ! GRUB_SERIAL_HEADER */
diff --git a/stage2/setjmp.S b/stage2/setjmp.S
new file mode 100644
index 0000000..59161fe
--- /dev/null
+++ b/stage2/setjmp.S
@@ -0,0 +1,81 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000 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.
+ */
+
+/* This is stolen from libc/x86/setjmp.S in the OSKit */
+/* 
+ * Mach Operating System
+ * Copyright (c) 1991,1990,1989 Carnegie Mellon University
+ * All Rights Reserved.
+ * 
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ * 
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ * 
+ * Carnegie Mellon requests users of this software to return to
+ * 
+ *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
+ *  School of Computer Science
+ *  Carnegie Mellon University
+ *  Pittsburgh PA 15213-3890
+ * 
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * C library -- _setjmp, _longjmp
+ *
+ *      _longjmp(a,v)
+ * will generate a "return(v)" from
+ * the last call to
+ *      _setjmp(a)
+ * by restoring registers from the stack,
+ * The previous signal state is NOT restored.
+ *
+ */
+	
+ENTRY(grub_setjmp)
+	movl	4(%esp), %ecx		/* fetch buffer */
+	movl	%ebx, 0(%ecx)
+	movl	%esi, 4(%ecx)
+	movl	%edi, 8(%ecx)
+	movl	%ebp, 12(%ecx)		/* save frame pointer of caller */
+	popl	%edx
+	movl	%esp, 16(%ecx)		/* save stack pointer of caller */
+	movl	%edx, 20(%ecx)		/* save pc of caller */
+	xorl	%eax, %eax
+        jmp     *%edx
+
+ENTRY(grub_longjmp)
+	movl	8(%esp), %eax		/* return(v) */
+	movl	4(%esp), %ecx		/* fetch buffer */
+	movl	0(%ecx), %ebx
+	movl	4(%ecx), %esi
+	movl	8(%ecx), %edi
+	movl	12(%ecx), %ebp
+	movl	16(%ecx), %esp
+	orl	%eax, %eax
+	jnz	0f
+	incl	%eax
+0:	jmp	*20(%ecx)		/* done, return.... */
diff --git a/stage2/shared.h b/stage2/shared.h
new file mode 100644
index 0000000..77eef11
--- /dev/null
+++ b/stage2/shared.h
@@ -0,0 +1,996 @@
+/* shared.h - definitions used in all GRUB-specific code */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  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 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.
+ */
+
+/*
+ *  Generic defines to use anywhere
+ */
+
+#ifndef GRUB_SHARED_HEADER
+#define GRUB_SHARED_HEADER	1
+
+#include <config.h>
+
+/* Add an underscore to a C symbol in assembler code if needed. */
+#ifdef HAVE_ASM_USCORE
+# define EXT_C(sym) _ ## sym
+#else
+# define EXT_C(sym) sym
+#endif
+
+/* Maybe redirect memory requests through grub_scratch_mem. */
+#ifdef GRUB_UTIL
+extern char *grub_scratch_mem;
+# define RAW_ADDR(x) ((x) + (int) grub_scratch_mem)
+# define RAW_SEG(x) (RAW_ADDR ((x) << 4) >> 4)
+#else
+# define RAW_ADDR(x) (x)
+# define RAW_SEG(x) (x)
+#endif
+
+/*
+ *  Integer sizes
+ */
+
+#define MAXINT     0x7FFFFFFF
+
+/* Maximum command line size. Before you blindly increase this value,
+   see the comment in char_io.c (get_cmdline).  */
+#define MAX_CMDLINE 1600
+#define NEW_HEAPSIZE 1500
+
+/* 512-byte scratch area */
+#define SCRATCHADDR  RAW_ADDR (0x77e00)
+#define SCRATCHSEG   RAW_SEG (0x77e0)
+
+/*
+ *  This is the location of the raw device buffer.  It is 31.5K
+ *  in size.
+ */
+
+#define BUFFERLEN   0x7e00
+#define BUFFERADDR  RAW_ADDR (0x70000)
+#define BUFFERSEG   RAW_SEG (0x7000)
+
+#define BOOT_PART_TABLE	RAW_ADDR (0x07be)
+
+/*
+ *  BIOS disk defines
+ */
+#define BIOSDISK_READ			0x0
+#define BIOSDISK_WRITE			0x1
+#define BIOSDISK_ERROR_GEOMETRY		0x100
+#define BIOSDISK_FLAG_LBA_EXTENSION	0x1
+#define BIOSDISK_FLAG_CDROM		0x2
+
+/*
+ *  This is the filesystem (not raw device) buffer.
+ *  It is 32K in size, do not overrun!
+ */
+
+#define FSYS_BUFLEN  0x8000
+#define FSYS_BUF RAW_ADDR (0x68000)
+
+/* Command-line buffer for Multiboot kernels and modules. This area
+   includes the area into which Stage 1.5 and Stage 1 are loaded, but
+   that's no problem.  */
+#define MB_CMDLINE_BUF		RAW_ADDR (0x2000)
+#define MB_CMDLINE_BUFLEN	0x6000
+
+/* The buffer for the password.  */
+#define PASSWORD_BUF		RAW_ADDR (0x78000)
+#define PASSWORD_BUFLEN		0x200
+
+/* THe buffer for the filename of "/boot/grub/default".  */
+#define DEFAULT_FILE_BUF	(PASSWORD_BUF + PASSWORD_BUFLEN)
+#define DEFAULT_FILE_BUFLEN	0x60
+
+/* The buffer for the command-line.  */
+#define CMDLINE_BUF		(DEFAULT_FILE_BUF + DEFAULT_FILE_BUFLEN)
+#define CMDLINE_BUFLEN		MAX_CMDLINE
+
+/* The kill buffer for the command-line.  */
+#define KILL_BUF		(CMDLINE_BUF + CMDLINE_BUFLEN)
+#define KILL_BUFLEN		MAX_CMDLINE
+
+/* The history buffer for the command-line.  */
+#define HISTORY_BUF		(KILL_BUF + KILL_BUFLEN)
+#define HISTORY_SIZE		5
+#define HISTORY_BUFLEN		(MAX_CMDLINE * HISTORY_SIZE)
+
+/* The buffer for the completion.  */
+#define COMPLETION_BUF		(HISTORY_BUF + HISTORY_BUFLEN)
+#define COMPLETION_BUFLEN	MAX_CMDLINE
+
+/* The buffer for the unique string.  */
+#define UNIQUE_BUF		(COMPLETION_BUF + COMPLETION_BUFLEN)
+#define UNIQUE_BUFLEN		MAX_CMDLINE
+
+/* The buffer for the menu entries.  */
+#define MENU_BUF		(UNIQUE_BUF + UNIQUE_BUFLEN)
+#define MENU_BUFLEN		(0x8000 + PASSWORD_BUF - MENU_BUF)
+
+/* The size of the drive map.  */
+#define DRIVE_MAP_SIZE		8
+
+/* The size of the key map.  */
+#define KEY_MAP_SIZE		128
+
+/* The size of the io map.  */
+#define IO_MAP_SIZE		128
+
+/*
+ *  Linux setup parameters
+ */
+
+#define LINUX_MAGIC_SIGNATURE		0x53726448	/* "HdrS" */
+#define LINUX_DEFAULT_SETUP_SECTS	4
+#define LINUX_FLAG_CAN_USE_HEAP		0x80
+#define LINUX_INITRD_MAX_ADDRESS	0x38000000
+#define LINUX_MAX_SETUP_SECTS		64
+#define LINUX_BOOT_LOADER_TYPE		0x71
+#define LINUX_HEAP_END_OFFSET		(0x9000 - 0x200)
+
+#define LINUX_BZIMAGE_ADDR		RAW_ADDR (0x100000)
+#define LINUX_ZIMAGE_ADDR		RAW_ADDR (0x10000)
+#define LINUX_OLD_REAL_MODE_ADDR	RAW_ADDR (0x90000)
+#define LINUX_SETUP_STACK		0x9000
+
+#define LINUX_FLAG_BIG_KERNEL		0x1
+
+/* Linux's video mode selection support. Actually I hate it!  */
+#define LINUX_VID_MODE_NORMAL		0xFFFF
+#define LINUX_VID_MODE_EXTENDED		0xFFFE
+#define LINUX_VID_MODE_ASK		0xFFFD
+
+#define LINUX_CL_OFFSET			0x9000
+#define LINUX_CL_END_OFFSET		0x90FF
+#define LINUX_SETUP_MOVE_SIZE		0x9100
+#define LINUX_CL_MAGIC			0xA33F
+
+/*
+ *  General disk stuff
+ */
+
+#define SECTOR_SIZE		0x200
+#define SECTOR_BITS		9
+#define BIOS_FLAG_FIXED_DISK	0x80
+
+#define BOOTSEC_LOCATION		RAW_ADDR (0x7C00)
+#define BOOTSEC_SIGNATURE		0xAA55
+#define BOOTSEC_BPB_OFFSET		0x3
+#define BOOTSEC_BPB_LENGTH		0x3B
+#define BOOTSEC_BPB_SYSTEM_ID		0x3
+#define BOOTSEC_BPB_HIDDEN_SECTORS	0x1C
+#define BOOTSEC_PART_OFFSET		0x1BE
+#define BOOTSEC_PART_LENGTH		0x40
+#define BOOTSEC_SIG_OFFSET		0x1FE
+#define BOOTSEC_LISTSIZE		8
+
+/* Not bad, perhaps.  */
+#define NETWORK_DRIVE	0x20
+
+/*
+ *  GRUB specific information
+ *    (in LSB order)
+ */
+
+#include <stage1.h>
+
+#define STAGE2_VER_MAJ_OFFS	0x6
+#define STAGE2_INSTALLPART	0x8
+#define STAGE2_SAVED_ENTRYNO	0xc
+#define STAGE2_STAGE2_ID	0x10
+#define STAGE2_FORCE_LBA	0x11
+#define STAGE2_VER_STR_OFFS	0x12
+
+/* Stage 2 identifiers */
+#define STAGE2_ID_STAGE2		0
+#define STAGE2_ID_FFS_STAGE1_5		1
+#define STAGE2_ID_E2FS_STAGE1_5		2
+#define STAGE2_ID_FAT_STAGE1_5		3
+#define STAGE2_ID_MINIX_STAGE1_5	4
+#define STAGE2_ID_REISERFS_STAGE1_5	5
+#define STAGE2_ID_VSTAFS_STAGE1_5	6
+#define STAGE2_ID_JFS_STAGE1_5		7
+#define STAGE2_ID_XFS_STAGE1_5		8
+#define STAGE2_ID_ISO9660_STAGE1_5	9
+#define STAGE2_ID_UFS2_STAGE1_5		10
+
+#ifndef STAGE1_5
+# define STAGE2_ID	STAGE2_ID_STAGE2
+#else
+# if defined(FSYS_FFS)
+#  define STAGE2_ID	STAGE2_ID_FFS_STAGE1_5
+# elif defined(FSYS_EXT2FS)
+#  define STAGE2_ID	STAGE2_ID_E2FS_STAGE1_5
+# elif defined(FSYS_FAT)
+#  define STAGE2_ID	STAGE2_ID_FAT_STAGE1_5
+# elif defined(FSYS_MINIX)
+#  define STAGE2_ID	STAGE2_ID_MINIX_STAGE1_5
+# elif defined(FSYS_REISERFS)
+#  define STAGE2_ID	STAGE2_ID_REISERFS_STAGE1_5
+# elif defined(FSYS_VSTAFS)
+#  define STAGE2_ID	STAGE2_ID_VSTAFS_STAGE1_5
+# elif defined(FSYS_JFS)
+#  define STAGE2_ID	STAGE2_ID_JFS_STAGE1_5
+# elif defined(FSYS_XFS)
+#  define STAGE2_ID	STAGE2_ID_XFS_STAGE1_5
+# elif defined(FSYS_ISO9660)
+#  define STAGE2_ID	STAGE2_ID_ISO9660_STAGE1_5
+# elif defined(FSYS_UFS2)
+#  define STAGE2_ID	STAGE2_ID_UFS2_STAGE1_5
+# else
+#  error "unknown Stage 2"
+# endif
+#endif
+
+/*
+ *  defines for use when switching between real and protected mode
+ */
+
+#define CR0_PE_ON	0x1
+#define CR0_PE_OFF	0xfffffffe
+#define PROT_MODE_CSEG	0x8
+#define PROT_MODE_DSEG  0x10
+#define PSEUDO_RM_CSEG	0x18
+#define PSEUDO_RM_DSEG	0x20
+#define STACKOFF	(0x2000 - 0x10)
+#define PROTSTACKINIT   (FSYS_BUF - 0x10)
+
+
+/*
+ * Assembly code defines
+ *
+ * "EXT_C" is assumed to be defined in the Makefile by the configure
+ *   command.
+ */
+
+#define ENTRY(x) .globl EXT_C(x) ; EXT_C(x):
+#define VARIABLE(x) ENTRY(x)
+
+
+#define K_RDWR  	0x60	/* keyboard data & cmds (read/write) */
+#define K_STATUS	0x64	/* keyboard status */
+#define K_CMD		0x64	/* keybd ctlr command (write-only) */
+
+#define K_OBUF_FUL 	0x01	/* output buffer full */
+#define K_IBUF_FUL 	0x02	/* input buffer full */
+
+#define KC_CMD_WIN	0xd0	/* read  output port */
+#define KC_CMD_WOUT	0xd1	/* write output port */
+#define KB_OUTPUT_MASK  0xdd	/* enable output buffer full interrupt
+				   enable data line
+				   enable clock line */
+#define KB_A20_ENABLE   0x02
+
+/* Codes for getchar. */
+#define ASCII_CHAR(x)   ((x) & 0xFF)
+#if !defined(GRUB_UTIL) || !defined(HAVE_LIBCURSES)
+# define KEY_LEFT        0x4B00
+# define KEY_RIGHT       0x4D00
+# define KEY_UP          0x4800
+# define KEY_DOWN        0x5000
+# define KEY_IC          0x5200	/* insert char */
+# define KEY_DC          0x5300	/* delete char */
+# define KEY_BACKSPACE   0x0008
+# define KEY_HOME        0x4700
+# define KEY_END         0x4F00
+# define KEY_NPAGE       0x5100
+# define KEY_PPAGE       0x4900
+# define A_NORMAL        0x7
+# define A_REVERSE       0x70
+#elif defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
+
+/* In old BSD curses, A_NORMAL and A_REVERSE are not defined, so we
+   define them here if they are undefined.  */
+#ifndef A_NORMAL
+# define A_NORMAL	0
+#endif /* ! A_NORMAL */
+#ifndef A_REVERSE
+# ifdef A_STANDOUT
+#  define A_REVERSE	A_STANDOUT
+# else /* ! A_STANDOUT */
+#  define A_REVERSE	0
+# endif /* ! A_STANDOUT */
+#endif /* ! A_REVERSE */
+
+/* Define ACS_* ourselves, since the definitions are not consistent among
+   various curses implementations.  */
+#undef ACS_ULCORNER
+#undef ACS_URCORNER
+#undef ACS_LLCORNER
+#undef ACS_LRCORNER
+#undef ACS_HLINE
+#undef ACS_VLINE
+#undef ACS_LARROW
+#undef ACS_RARROW
+#undef ACS_UARROW
+#undef ACS_DARROW
+
+#define ACS_ULCORNER	'+'
+#define ACS_URCORNER	'+'
+#define ACS_LLCORNER	'+'
+#define ACS_LRCORNER	'+'
+#define ACS_HLINE	'-'
+#define ACS_VLINE	'|'
+#define ACS_LARROW	'<'
+#define ACS_RARROW	'>'
+#define ACS_UARROW	'^'
+#define ACS_DARROW	'v'
+
+/* Special graphics characters for IBM displays. */
+#define DISP_UL		218
+#define DISP_UR		191
+#define DISP_LL		192
+#define DISP_LR		217
+#define DISP_HORIZ	196
+#define DISP_VERT	179
+#define DISP_LEFT	0x1b
+#define DISP_RIGHT	0x1a
+#define DISP_UP		0x18
+#define DISP_DOWN	0x19
+
+/* Remap some libc-API-compatible function names so that we prevent
+   circularararity. */
+#ifndef WITHOUT_LIBC_STUBS
+#define memmove grub_memmove
+#define memcpy grub_memmove	/* we don't need a separate memcpy */
+#define memset grub_memset
+#define isspace grub_isspace
+#define printf grub_printf
+#define sprintf grub_sprintf
+#undef putchar
+#define putchar grub_putchar
+#define strncat grub_strncat
+#define strstr grub_strstr
+#define memcmp grub_memcmp
+#define strcmp grub_strcmp
+#define tolower grub_tolower
+#define strlen grub_strlen
+#define strcpy grub_strcpy
+#endif /* WITHOUT_LIBC_STUBS */
+
+
+#ifndef ASM_FILE
+/*
+ *  Below this should be ONLY defines and other constructs for C code.
+ */
+
+/* multiboot stuff */
+
+#include "mb_header.h"
+#include "mb_info.h"
+
+/* For the Linux/i386 boot protocol version 2.03.  */
+struct linux_kernel_header
+{
+  char code1[0x0020];
+  unsigned short cl_magic;		/* Magic number 0xA33F */
+  unsigned short cl_offset;		/* The offset of command line */
+  char code2[0x01F1 - 0x0020 - 2 - 2];
+  unsigned char setup_sects;		/* The size of the setup in sectors */
+  unsigned short root_flags;		/* If the root is mounted readonly */
+  unsigned short syssize;		/* obsolete */
+  unsigned short swap_dev;		/* obsolete */
+  unsigned short ram_size;		/* obsolete */
+  unsigned short vid_mode;		/* Video mode control */
+  unsigned short root_dev;		/* Default root device number */
+  unsigned short boot_flag;		/* 0xAA55 magic number */
+  unsigned short jump;			/* Jump instruction */
+  unsigned long header;			/* Magic signature "HdrS" */
+  unsigned short version;		/* Boot protocol version supported */
+  unsigned long realmode_swtch;		/* Boot loader hook */
+  unsigned long start_sys;		/* Points to kernel version string */
+  unsigned char type_of_loader;		/* Boot loader identifier */
+  unsigned char loadflags;		/* Boot protocol option flags */
+  unsigned short setup_move_size;	/* Move to high memory size */
+  unsigned long code32_start;		/* Boot loader hook */
+  unsigned long ramdisk_image;		/* initrd load address */
+  unsigned long ramdisk_size;		/* initrd size */
+  unsigned long bootsect_kludge;	/* obsolete */
+  unsigned short heap_end_ptr;		/* Free memory after setup end */
+  unsigned short pad1;			/* Unused */
+  char *cmd_line_ptr;			/* Points to the kernel command line */
+  unsigned long initrd_addr_max;	/* The highest address of initrd */
+} __attribute__ ((packed));
+
+/* Memory map address range descriptor used by GET_MMAP_ENTRY. */
+struct mmar_desc
+{
+  unsigned long desc_len;	/* Size of this descriptor. */
+  unsigned long long addr;	/* Base address. */
+  unsigned long long length;	/* Length in bytes. */
+  unsigned long type;		/* Type of address range. */
+} __attribute__ ((packed));
+
+/* VBE controller information.  */
+struct vbe_controller
+{
+  unsigned char signature[4];
+  unsigned short version;
+  unsigned long oem_string;
+  unsigned long capabilities;
+  unsigned long video_mode;
+  unsigned short total_memory;
+  unsigned short oem_software_rev;
+  unsigned long oem_vendor_name;
+  unsigned long oem_product_name;
+  unsigned long oem_product_rev;
+  unsigned char reserved[222];
+  unsigned char oem_data[256];
+} __attribute__ ((packed));
+
+/* VBE mode information.  */
+struct vbe_mode
+{
+  unsigned short mode_attributes;
+  unsigned char win_a_attributes;
+  unsigned char win_b_attributes;
+  unsigned short win_granularity;
+  unsigned short win_size;
+  unsigned short win_a_segment;
+  unsigned short win_b_segment;
+  unsigned long win_func;
+  unsigned short bytes_per_scanline;
+
+  /* >=1.2 */
+  unsigned short x_resolution;
+  unsigned short y_resolution;
+  unsigned char x_char_size;
+  unsigned char y_char_size;
+  unsigned char number_of_planes;
+  unsigned char bits_per_pixel;
+  unsigned char number_of_banks;
+  unsigned char memory_model;
+  unsigned char bank_size;
+  unsigned char number_of_image_pages;
+  unsigned char reserved0;
+
+  /* direct color */
+  unsigned char red_mask_size;
+  unsigned char red_field_position;
+  unsigned char green_mask_size;
+  unsigned char green_field_position;
+  unsigned char blue_mask_size;
+  unsigned char blue_field_position;
+  unsigned char reserved_mask_size;
+  unsigned char reserved_field_position;
+  unsigned char direct_color_mode_info;
+
+  /* >=2.0 */
+  unsigned long phys_base;
+  unsigned long reserved1;
+  unsigned short reversed2;
+
+  /* >=3.0 */
+  unsigned short linear_bytes_per_scanline;
+  unsigned char banked_number_of_image_pages;
+  unsigned char linear_number_of_image_pages;
+  unsigned char linear_red_mask_size;
+  unsigned char linear_red_field_position;
+  unsigned char linear_green_mask_size;
+  unsigned char linear_green_field_position;
+  unsigned char linear_blue_mask_size;
+  unsigned char linear_blue_field_position;
+  unsigned char linear_reserved_mask_size;
+  unsigned char linear_reserved_field_position;
+  unsigned long max_pixel_clock;
+
+  unsigned char reserved3[189];
+} __attribute__ ((packed));
+
+
+#undef NULL
+#define NULL         ((void *) 0)
+
+/* Error codes (descriptions are in common.c) */
+typedef enum
+{
+  ERR_NONE = 0,
+  ERR_BAD_FILENAME,
+  ERR_BAD_FILETYPE,
+  ERR_BAD_GZIP_DATA,
+  ERR_BAD_GZIP_HEADER,
+  ERR_BAD_PART_TABLE,
+  ERR_BAD_VERSION,
+  ERR_BELOW_1MB,
+  ERR_BOOT_COMMAND,
+  ERR_BOOT_FAILURE,
+  ERR_BOOT_FEATURES,
+  ERR_DEV_FORMAT,
+  ERR_DEV_VALUES,
+  ERR_EXEC_FORMAT,
+  ERR_FILELENGTH,
+  ERR_FILE_NOT_FOUND,
+  ERR_FSYS_CORRUPT,
+  ERR_FSYS_MOUNT,
+  ERR_GEOM,
+  ERR_NEED_LX_KERNEL,
+  ERR_NEED_MB_KERNEL,
+  ERR_NO_DISK,
+  ERR_NO_PART,
+  ERR_NUMBER_PARSING,
+  ERR_OUTSIDE_PART,
+  ERR_READ,
+  ERR_SYMLINK_LOOP,
+  ERR_UNRECOGNIZED,
+  ERR_WONT_FIT,
+  ERR_WRITE,
+  ERR_BAD_ARGUMENT,
+  ERR_UNALIGNED,
+  ERR_PRIVILEGED,
+  ERR_DEV_NEED_INIT,
+  ERR_NO_DISK_SPACE,
+  ERR_NUMBER_OVERFLOW,
+
+  MAX_ERR_NUM
+} grub_error_t;
+
+extern unsigned long install_partition;
+extern unsigned long boot_drive;
+extern unsigned long install_second_sector;
+extern struct apm_info apm_bios_info;
+extern unsigned long boot_part_addr;
+extern int saved_entryno;
+extern unsigned char force_lba;
+extern char version_string[];
+extern char config_file[];
+extern unsigned long linux_text_len;
+extern char *linux_data_tmp_addr;
+extern char *linux_data_real_addr;
+
+#ifdef GRUB_UTIL
+/* If not using config file, this variable is set to zero,
+   otherwise non-zero.  */
+extern int use_config_file;
+/* If using the preset menu, this variable is set to non-zero,
+   otherwise zero.  */
+extern int use_preset_menu;
+/* If not using curses, this variable is set to zero, otherwise non-zero.  */
+extern int use_curses;
+/* The flag for verbose messages.  */
+extern int verbose;
+/* The flag for read-only.  */
+extern int read_only;
+/* The number of floppies to be probed.  */
+extern int floppy_disks;
+/* The map between BIOS drives and UNIX device file names.  */
+extern char **device_map;
+/* The filename which stores the information about a device map.  */
+extern char *device_map_file;
+/* The array of geometries.  */
+extern struct geometry *disks;
+/* Assign DRIVE to a device name DEVICE.  */
+extern void assign_device_name (int drive, const char *device);
+#endif
+
+#ifndef STAGE1_5
+/* GUI interface variables. */
+# define MAX_FALLBACK_ENTRIES	8
+extern int fallback_entries[MAX_FALLBACK_ENTRIES];
+extern int fallback_entryno;
+extern int default_entry;
+extern int current_entryno;
+
+/* The constants for password types.  */
+typedef enum
+{
+  PASSWORD_PLAIN,
+  PASSWORD_MD5,
+  PASSWORD_UNSUPPORTED
+}
+password_t;
+
+extern char *password;
+extern password_t password_type;
+extern int auth;
+extern char commands[];
+
+/* For `more'-like feature.  */
+extern int max_lines;
+extern int count_lines;
+extern int use_pager;
+#endif
+
+#ifndef NO_DECOMPRESSION
+extern int no_decompression;
+extern int compressed_file;
+#endif
+
+/* instrumentation variables */
+extern void (*disk_read_hook) (int, int, int);
+extern void (*disk_read_func) (int, int, int);
+
+#ifndef STAGE1_5
+/* The flag for debug mode.  */
+extern int debug;
+#endif /* STAGE1_5 */
+
+extern unsigned long current_drive;
+extern unsigned long current_partition;
+
+extern int fsys_type;
+
+/* The information for a disk geometry. The CHS information is only for
+   DOS/Partition table compatibility, and the real number of sectors is
+   stored in TOTAL_SECTORS.  */
+struct geometry
+{
+  /* The number of cylinders */
+  unsigned long cylinders;
+  /* The number of heads */
+  unsigned long heads;
+  /* The number of sectors */
+  unsigned long sectors;
+  /* The total number of sectors */
+  unsigned long total_sectors;
+  /* Device sector size */
+  unsigned long sector_size;
+  /* Flags */
+  unsigned long flags;
+};
+
+extern unsigned long part_start;
+extern unsigned long part_length;
+
+extern int current_slice;
+
+extern int buf_drive;
+extern int buf_track;
+extern struct geometry buf_geom;
+
+/* these are the current file position and maximum file position */
+extern int filepos;
+extern int filemax;
+
+/*
+ *  Common BIOS/boot data.
+ */
+
+extern struct multiboot_info mbi;
+extern unsigned long saved_drive;
+extern unsigned long saved_partition;
+extern unsigned long cdrom_drive;
+#ifndef STAGE1_5
+extern unsigned long saved_mem_upper;
+extern unsigned long extended_memory;
+#endif
+
+/*
+ *  Error variables.
+ */
+
+extern grub_error_t errnum;
+extern char *err_list[];
+
+/* Simplify declaration of entry_addr. */
+typedef void (*entry_func) (int, int, int, int, int, int)
+     __attribute__ ((noreturn));
+
+extern entry_func entry_addr;
+
+/* Enter the stage1.5/stage2 C code after the stack is set up. */
+void cmain (void);
+
+/* Halt the processor (called after an unrecoverable error). */
+void stop (void) __attribute__ ((noreturn));
+
+/* Reboot the system.  */
+void grub_reboot (void) __attribute__ ((noreturn));
+
+/* Halt the system, using APM if possible. If NO_APM is true, don't use
+   APM even if it is available.  */
+void grub_halt (int no_apm) __attribute__ ((noreturn));
+
+/* Copy MAP to the drive map and set up int13_handler.  */
+void set_int13_handler (unsigned short *map);
+
+/* Set up int15_handler.  */
+void set_int15_handler (void);
+
+/* Restore the original int15 handler.  */
+void unset_int15_handler (void);
+
+/* Track the int13 handler to probe I/O address space.  */
+void track_int13 (int drive);
+
+/* The key map.  */
+extern unsigned short bios_key_map[];
+extern unsigned short ascii_key_map[];
+extern unsigned short io_map[];
+
+/* calls for direct boot-loader chaining */
+void chain_stage1 (unsigned long segment, unsigned long offset,
+		   unsigned long part_table_addr)
+     __attribute__ ((noreturn));
+void chain_stage2 (unsigned long segment, unsigned long offset,
+		   int second_sector)
+     __attribute__ ((noreturn));
+
+/* do some funky stuff, then boot linux */
+void linux_boot (void) __attribute__ ((noreturn));
+
+/* do some funky stuff, then boot bzImage linux */
+void big_linux_boot (void) __attribute__ ((noreturn));
+
+/* booting a multiboot executable */
+void multi_boot (int start, int mb_info) __attribute__ ((noreturn));
+
+/* If LINEAR is nonzero, then set the Intel processor to linear mode.
+   Otherwise, bit 20 of all memory accesses is always forced to zero,
+   causing a wraparound effect for bugwards compatibility with the
+   8086 CPU. */
+void gateA20 (int linear);
+
+/* memory probe routines */
+int get_memsize (int type);
+int get_eisamemsize (void);
+
+/* Fetch the next entry in the memory map and return the continuation
+   value.  DESC is a pointer to the descriptor buffer, and CONT is the
+   previous continuation value (0 to get the first entry in the
+   map). */
+int get_mmap_entry (struct mmar_desc *desc, int cont);
+
+/* Get the linear address of a ROM configuration table. Return zero,
+   if fails.  */
+unsigned long get_rom_config_table (void);
+
+/* Get APM BIOS information.  */
+void get_apm_info (void);
+
+/* Get VBE controller information.  */
+int get_vbe_controller_info (struct vbe_controller *controller);
+
+/* Get VBE mode information.  */
+int get_vbe_mode_info (int mode_number, struct vbe_mode *mode);
+
+/* Set VBE mode.  */
+int set_vbe_mode (int mode_number);
+
+/* Return the data area immediately following our code. */
+int get_code_end (void);
+
+/* low-level timing info */
+int getrtsecs (void);
+int currticks (void);
+
+/* Clear the screen. */
+void cls (void);
+
+/* Turn on/off cursor. */
+int setcursor (int on);
+
+/* Get the current cursor position (where 0,0 is the top left hand
+   corner of the screen).  Returns packed values, (RET >> 8) is x,
+   (RET & 0xff) is y. */
+int getxy (void);
+
+/* Set the cursor position. */
+void gotoxy (int x, int y);
+
+/* Displays an ASCII character.  IBM displays will translate some
+   characters to special graphical ones (see the DISP_* constants). */
+void grub_putchar (int c);
+
+/* Wait for a keypress, and return its packed BIOS/ASCII key code.
+   Use ASCII_CHAR(ret) to extract the ASCII code. */
+int getkey (void);
+
+/* Like GETKEY, but doesn't block, and returns -1 if no keystroke is
+   available. */
+int checkkey (void);
+
+/* Low-level disk I/O */
+int get_diskinfo (int drive, struct geometry *geometry);
+int biosdisk (int subfunc, int drive, struct geometry *geometry,
+	      int sector, int nsec, int segment);
+void stop_floppy (void);
+
+/* Command-line interface functions. */
+#ifndef STAGE1_5
+
+/* The flags for the builtins.  */
+#define BUILTIN_CMDLINE		0x1	/* Run in the command-line.  */
+#define BUILTIN_MENU		0x2	/* Run in the menu.  */
+#define BUILTIN_TITLE		0x4	/* Only for the command title.  */
+#define BUILTIN_SCRIPT		0x8	/* Run in the script.  */
+#define BUILTIN_NO_ECHO		0x10	/* Don't print command on booting. */
+#define BUILTIN_HELP_LIST	0x20	/* Show help in listing.  */
+
+/* The table for a builtin.  */
+struct builtin
+{
+  /* The command name.  */
+  char *name;
+  /* The callback function.  */
+  int (*func) (char *, int);
+  /* The combination of the flags defined above.  */
+  int flags;
+  /* The short version of the documentation.  */
+  char *short_doc;
+  /* The long version of the documentation.  */
+  char *long_doc;
+};
+
+/* All the builtins are registered in this.  */
+extern struct builtin *builtin_table[];
+
+/* The constants for kernel types.  */
+typedef enum
+{
+  KERNEL_TYPE_NONE,		/* None is loaded.  */
+  KERNEL_TYPE_MULTIBOOT,	/* Multiboot.  */
+  KERNEL_TYPE_LINUX,		/* Linux.  */
+  KERNEL_TYPE_BIG_LINUX,	/* Big Linux.  */
+  KERNEL_TYPE_FREEBSD,		/* FreeBSD.  */
+  KERNEL_TYPE_NETBSD,		/* NetBSD.  */
+  KERNEL_TYPE_CHAINLOADER	/* Chainloader.  */
+}
+kernel_t;
+
+extern kernel_t kernel_type;
+extern int show_menu;
+extern int grub_timeout;
+
+void init_builtins (void);
+void init_config (void);
+char *skip_to (int after_equal, char *cmdline);
+struct builtin *find_command (char *command);
+void print_cmdline_message (int forever);
+void enter_cmdline (char *heap, int forever);
+int run_script (char *script, char *heap);
+#endif
+
+/* C library replacement functions with identical semantics. */
+void grub_printf (const char *format,...);
+int grub_sprintf (char *buffer, const char *format, ...);
+int grub_tolower (int c);
+int grub_isspace (int c);
+int grub_strncat (char *s1, const char *s2, int n);
+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);
+char *grub_strstr (const char *s1, const char *s2);
+int grub_memcmp (const char *s1, const char *s2, int n);
+int grub_strcmp (const char *s1, const char *s2);
+int grub_strlen (const char *str);
+char *grub_strcpy (char *dest, const char *src);
+
+#ifndef GRUB_UTIL
+typedef unsigned long grub_jmp_buf[6];
+#else
+/* In the grub shell, use the libc jmp_buf instead.  */
+# include <setjmp.h>
+# define grub_jmp_buf jmp_buf
+#endif
+
+#ifdef GRUB_UTIL
+# define grub_setjmp	setjmp
+# define grub_longjmp	longjmp
+#else /* ! GRUB_UTIL */
+int grub_setjmp (grub_jmp_buf env);
+void grub_longjmp (grub_jmp_buf env, int val);
+#endif /* ! GRUB_UTIL */
+
+/* The environment for restarting Stage 2.  */
+extern grub_jmp_buf restart_env;
+/* The environment for restarting the command-line interface.  */
+extern grub_jmp_buf restart_cmdline_env;
+
+/* misc */
+void init_page (void);
+void print_error (void);
+char *convert_to_ascii (char *buf, int c, ...);
+int get_cmdline (char *prompt, char *cmdline, int maxlen,
+		 int echo_char, int history);
+int substring (const char *s1, const char *s2);
+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);
+void grub_putstr (const char *str);
+
+#ifndef NO_DECOMPRESSION
+/* Compression support. */
+int gunzip_test_header (void);
+int gunzip_read (char *buf, int len);
+#endif /* NO_DECOMPRESSION */
+
+int rawread (int drive, int sector, int byte_offset, int byte_len, char *buf);
+int devread (int sector, int byte_offset, int byte_len, char *buf);
+int rawwrite (int drive, int sector, char *buf);
+int devwrite (int sector, int sector_len, char *buf);
+
+/* Parse a device string and initialize the global parameters. */
+char *set_device (char *device);
+int open_device (void);
+int real_open_partition (int flags);
+int open_partition (void);
+int next_partition (unsigned long drive, unsigned long dest,
+		    unsigned long *partition, int *type,
+		    unsigned long *start, unsigned long *len,
+		    unsigned long *offset, int *entry,
+		    unsigned long *ext_offset, char *buf);
+
+/* Sets device to the one represented by the SAVED_* parameters. */
+int make_saved_active (void);
+
+/* Set or clear the current root partition's hidden flag.  */
+int set_partition_hidden_flag (int hidden);
+
+/* Open a file or directory on the active device, using GRUB's
+   internal filesystem support. */
+int grub_open (char *filename);
+
+/* Read LEN bytes into BUF from the file that was opened with
+   GRUB_OPEN.  If LEN is -1, read all the remaining data in the file.  */
+int grub_read (char *buf, int len);
+
+/* Reposition a file offset.  */
+int grub_seek (int offset);
+
+/* Close a file.  */
+void grub_close (void);
+
+/* List the contents of the directory that was opened with GRUB_OPEN,
+   printing all completions. */
+int dir (char *dirname);
+
+int set_bootdev (int hdbias);
+
+/* Display statistics on the current active device. */
+void print_fsys_type (void);
+
+/* Display device and filename completions. */
+void print_a_completion (char *filename);
+int print_completions (int is_filename, int is_completion);
+
+/* Copies the current partition data to the desired address. */
+void copy_current_part_entry (char *buf);
+
+#ifndef STAGE1_5
+void bsd_boot (kernel_t type, int bootdev, char *arg)
+     __attribute__ ((noreturn));
+
+/* Define flags for load_image here.  */
+/* Don't pass a Linux's mem option automatically.  */
+#define KERNEL_LOAD_NO_MEM_OPTION	(1 << 0)
+
+kernel_t load_image (char *kernel, char *arg, kernel_t suggested_type,
+		     unsigned long load_flags);
+
+int load_module (char *module, char *arg);
+int load_initrd (char *initrd);
+
+int check_password(char *entered, char* expected, password_t type);
+#endif
+
+void init_bios_info (void);
+
+#endif /* ASM_FILE */
+
+#endif /* ! GRUB_SHARED_HEADER */
diff --git a/stage2/size_test b/stage2/size_test
new file mode 100755
index 0000000..f2b8c94
--- /dev/null
+++ b/stage2/size_test
@@ -0,0 +1,54 @@
+#!/bin/sh
+
+# Check the sizes of Stage 2 and Stage 1.5's.
+# Copyright (C) 1999,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.
+
+# Written by OKUJI Yoshinori <okuji@kuicr.kyoto-u.ac.jp>
+
+
+# This function checks if the size of the first argument (filename) is
+# greater than the second argument (limit). If so, then exit with the
+# status 1, otherwise do nothing.
+check ()
+{
+    file=$1
+    limit=$2
+    set dummy `ls -l $file`
+    size=$6
+    if test $size -gt $limit; then
+	echo "$file is too big ($size > $limit)."
+	exit 1
+    fi
+}
+
+# The bootloader area of a FFS partition is 14 sectors.
+check ffs_stage1_5 7168
+
+check ufs2_stage1_5 7168
+
+# Stage 1.5 can be installed in the sectors immediately after MBR in the
+# first cylinder, so the size is (63 - 1) sectors.
+check fat_stage1_5 31744
+
+# Likewise.
+check e2fs_stage1_5 31744
+
+# Likewise.
+check minix_stage1_5 31744
+
+# Success.
+exit 0
diff --git a/stage2/smp-imps.c b/stage2/smp-imps.c
new file mode 100644
index 0000000..a44d786
--- /dev/null
+++ b/stage2/smp-imps.c
@@ -0,0 +1,756 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,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
+ *  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.
+ */
+
+/*
+ *  <Insert copyright here : it must be BSD-like so anyone can use it>
+ *
+ *  Author:  Erich Boleyn  <erich@uruk.org>   http://www.uruk.org/~erich/
+ *
+ *  Source file implementing Intel MultiProcessor Specification (MPS)
+ *  version 1.1 and 1.4 SMP hardware control for Intel Architecture CPUs,
+ *  with hooks for running correctly on a standard PC without the hardware.
+ *
+ *  This file was created from information in the Intel MPS version 1.4
+ *  document, order number 242016-004, which can be ordered from the
+ *  Intel literature center.
+ *
+ *  General limitations of this code:
+ *
+ *   (1) : This code has never been tested on an MPS-compatible system with
+ *           486 CPUs, but is expected to work.
+ *   (2) : Presumes "int", "long", and "unsigned" are 32 bits in size, and
+ *	     that 32-bit pointers and memory addressing is used uniformly.
+ */
+
+#define _SMP_IMPS_C
+
+
+/*
+ *  XXXXX  The following absolutely must be defined!!!
+ *
+ *  The "KERNEL_PRINT" could be made a null macro with no danger, of
+ *  course, but pretty much nothing would work without the other
+ *  ones defined.
+ */
+
+#if 0
+#define KERNEL_PRINT(x)		/* some kind of print function */
+#define CMOS_WRITE_BYTE(x,y)	/* write unsigned char "y" at CMOS loc "x" */
+#define CMOS_READ_BYTE(x)	/* read unsigned char at CMOS loc "x" */
+#define PHYS_TO_VIRTUAL(x)	/* convert physical address "x" to virtual */
+#define VIRTUAL_TO_PHYS(x)	/* convert virtual address "x" to physical */
+#endif
+
+
+/*
+ *  This is the Intel MultiProcessor Spec debugging/display code.
+ */
+
+#define IMPS_DEBUG
+#define KERNEL_PRINT(x)         printf x
+#define CMOS_WRITE_BYTE(x, y)	cmos_write_byte(x, y)
+#define CMOS_READ_BYTE(x)	cmos_read_byte(x)
+#define PHYS_TO_VIRTUAL(x)	(x)
+#define VIRTUAL_TO_PHYS(x)	(x)
+
+static inline unsigned char
+inb (unsigned short port)
+{
+  unsigned char data;
+
+  __asm __volatile ("inb %1,%0" :"=a" (data):"d" (port));
+  return data;
+}
+
+static inline void
+outb (unsigned short port, unsigned char val)
+{
+  __asm __volatile ("outb %0,%1"::"a" (val), "d" (port));
+}
+
+
+static inline void
+cmos_write_byte (int loc, int val)
+{
+  outb (0x70, loc);
+  outb (0x71, val);
+}
+
+static inline unsigned
+cmos_read_byte (int loc)
+{
+  outb (0x70, loc);
+  return inb (0x71);
+}
+
+
+/*
+ *  Includes here
+ */
+
+#include "shared.h"
+#include "apic.h"
+#include "smp-imps.h"
+
+
+/*
+ *  Defines that are here so as not to be in the global header file.
+ */
+#define EBDA_SEG_ADDR			0x40E
+#define BIOS_RESET_VECTOR		0x467
+#define LAPIC_ADDR_DEFAULT		0xFEE00000uL
+#define IOAPIC_ADDR_DEFAULT		0xFEC00000uL
+#define CMOS_RESET_CODE			0xF
+#define		CMOS_RESET_JUMP		0xa
+#define CMOS_BASE_MEMORY		0x15
+
+
+/*
+ *  Static defines here for SMP use.
+ */
+
+#define DEF_ENTRIES	23
+
+static int lapic_dummy = 0;
+static struct
+  {
+    imps_processor proc[2];
+    imps_bus bus[2];
+    imps_ioapic ioapic;
+    imps_interrupt intin[16];
+    imps_interrupt lintin[2];
+  }
+defconfig =
+{
+  {
+    {
+      IMPS_BCT_PROCESSOR, 0, 0, 0, 0, 0
+    }
+    ,
+    {
+      IMPS_BCT_PROCESSOR, 1, 0, 0, 0, 0
+    }
+  }
+  ,
+  {
+    {
+      IMPS_BCT_BUS, 0,
+      {
+	'E', 'I', 'S', 'A', ' ', ' '
+      }
+    }
+    ,
+    {
+      255, 1,
+      {
+	'P', 'C', 'I', ' ', ' ', ' '
+      }
+    }
+  }
+  ,
+  {
+    IMPS_BCT_IOAPIC, 0, 0, IMPS_FLAG_ENABLED, IOAPIC_ADDR_DEFAULT
+  }
+  ,
+  {
+    {
+      IMPS_BCT_IO_INTERRUPT, IMPS_INT_EXTINT, 0, 0, 0, 0xFF, 0
+    }
+    ,
+    {
+      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 1, 0xFF, 1
+    }
+    ,
+    {
+      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 0, 0xFF, 2
+    }
+    ,
+    {
+      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 3, 0xFF, 3
+    }
+    ,
+    {
+      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 4, 0xFF, 4
+    }
+    ,
+    {
+      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 5, 0xFF, 5
+    }
+    ,
+    {
+      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 6, 0xFF, 6
+    }
+    ,
+    {
+      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 7, 0xFF, 7
+    }
+    ,
+    {
+      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 8, 0xFF, 8
+    }
+    ,
+    {
+      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 9, 0xFF, 9
+    }
+    ,
+    {
+      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 10, 0xFF, 10
+    }
+    ,
+    {
+      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 11, 0xFF, 11
+    }
+    ,
+    {
+      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 12, 0xFF, 12
+    }
+    ,
+    {
+      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 13, 0xFF, 13
+    }
+    ,
+    {
+      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 14, 0xFF, 14
+    }
+    ,
+    {
+      IMPS_BCT_IO_INTERRUPT, IMPS_INT_INT, 0, 0, 15, 0xFF, 15
+    }
+  }
+  ,
+  {
+    {
+      IMPS_BCT_LOCAL_INTERRUPT, IMPS_INT_EXTINT, 0, 0, 15, 0xFF, 0
+    }
+    ,
+    {
+      IMPS_BCT_LOCAL_INTERRUPT, IMPS_INT_NMI, 0, 0, 15, 0xFF, 1
+    }
+  }
+};
+
+/*
+ *  Exported globals here.
+ */
+
+/*
+ *  "imps_any_new_apics" is non-zero if any of the APICS (local or I/O)
+ *  are *not* an 82489DX.  This is useful to determine if more than 15
+ *  CPUs can be supported (true if zero).
+ */
+static int imps_any_new_apics = 0;
+#if 0
+volatile int imps_release_cpus = 0;
+#endif
+/*
+ *  "imps_enabled" is non-zero if the probe sequence found IMPS
+ *  information and was successful.
+ */
+static int imps_enabled = 0;
+/*
+ *  This represents the number of CPUs found.
+ */
+static int imps_num_cpus = 1;
+/*
+ *  This contains the local APIC hardware address.
+ */
+static unsigned imps_lapic_addr = ((unsigned) (&lapic_dummy)) - LAPIC_ID;
+/*
+ *  These map from virtual cpu numbers to APIC id's and back.
+ */
+static unsigned char imps_cpu_apic_map[IMPS_MAX_CPUS];
+static unsigned char imps_apic_cpu_map[IMPS_MAX_CPUS];
+
+
+/*
+ *  MPS checksum function
+ *
+ *  Function finished.
+ */
+
+static int
+get_checksum (unsigned start, int length)
+{
+  unsigned sum = 0;
+
+  while (length-- > 0)
+    {
+      sum += *((unsigned char *) (start++));
+    }
+
+  return (sum & 0xFF);
+}
+
+
+/*
+ *  Primary function for booting individual CPUs.
+ *
+ *  This must be modified to perform whatever OS-specific initialization
+ *  that is required.
+ */
+
+static int
+boot_cpu (imps_processor * proc)
+{
+  unsigned bootaddr, accept_status;
+  unsigned bios_reset_vector = PHYS_TO_VIRTUAL (BIOS_RESET_VECTOR);
+
+  /* %%%%% ESB */
+  extern char patch_code[];
+  bootaddr = 256 * 1024;
+  memmove ((char *) bootaddr, patch_code, 32);
+
+  /*
+   *  Generic CPU startup sequence starts here.
+   */
+
+  /* set BIOS reset vector */
+  CMOS_WRITE_BYTE (CMOS_RESET_CODE, CMOS_RESET_JUMP);
+  *((volatile unsigned *) bios_reset_vector) = bootaddr << 12;
+
+  /* clear the error register */
+  if (proc->apic_ver & 0x10)
+    {
+      IMPS_LAPIC_WRITE (LAPIC_ESR, 0);
+      accept_status = IMPS_LAPIC_READ (LAPIC_ESR);
+    }
+
+#if 0
+  /* assert INIT IPI */
+  cfg = IMPS_LAPIC_READ (LAPIC_ICR + 1);
+  cfg &= LAPIC_DEST_MASK;
+  IMPS_LAPIC_WRITE (LAPIC_ICR + 1, cfg);
+  cfg = IMPS_LAPIC_READ (LAPIC_ACR);
+  cfg &=;
+
+  /* %%%%% ESB finish adding startup sequence */
+#endif
+
+  /* clean up BIOS reset vector */
+  CMOS_WRITE_BYTE (CMOS_RESET_CODE, 0);
+  *((volatile unsigned *) bios_reset_vector) = 0;
+
+  /*
+   *  Generic CPU startup sequence ends here.
+   */
+
+  KERNEL_PRINT (("\n"));
+
+  return 1;
+
+  /* XXXXX add OS-specific initialization here! */
+}
+
+
+/*
+ *  read bios stuff and fill tables
+ */
+
+static void
+add_processor (imps_processor * proc)
+{
+  int apicid = proc->apic_id;
+
+  KERNEL_PRINT (("  Processor [APIC id %d ver %d]:  ",
+		 apicid, proc->apic_ver));
+  if (!(proc->flags & IMPS_FLAG_ENABLED))
+    {
+      KERNEL_PRINT (("DISABLED\n"));
+      return;
+    }
+  if (proc->apic_ver > 0xF)
+    {
+      imps_any_new_apics = 1;
+    }
+  if (proc->flags & (IMPS_CPUFLAG_BOOT))
+    {
+      KERNEL_PRINT (("#0  Bootstrap Processor (BSP)\n"));
+      return;
+    }
+  imps_cpu_apic_map[imps_num_cpus] = apicid;
+  imps_apic_cpu_map[apicid] = imps_num_cpus;
+  if (boot_cpu (proc))
+    {
+
+      /*  XXXXX  add OS-specific setup for secondary CPUs here */
+
+      imps_num_cpus++;
+    }
+}
+
+
+static void
+add_bus (imps_bus * bus)
+{
+  char str[8];
+
+  memmove (str, bus->bus_type, 6);
+  str[6] = 0;
+  KERNEL_PRINT (("  Bus id %d is %s\n", bus->id, str));
+
+  /*  XXXXX  add OS-specific code here */
+}
+
+
+static void
+add_ioapic (imps_ioapic * ioapic)
+{
+  KERNEL_PRINT (("  I/O APIC id %d ver %d, address: 0x%x  ",
+		 ioapic->id, ioapic->ver, ioapic->addr));
+  if (!(ioapic->flags & IMPS_FLAG_ENABLED))
+    {
+      KERNEL_PRINT (("DISABLED\n"));
+      return;
+    }
+  KERNEL_PRINT (("\n"));
+
+  /*  XXXXX  add OS-specific code here */
+}
+
+
+static void
+imps_read_config_table (unsigned start, int count)
+{
+  while (count-- > 0)
+    {
+      switch (*((unsigned char *) start))
+	{
+	case IMPS_BCT_PROCESSOR:
+	  add_processor ((imps_processor *) start);
+	  start += 12;		/* 20 total */
+	  break;
+	case IMPS_BCT_BUS:
+	  add_bus ((imps_bus *) start);
+	  break;
+	case IMPS_BCT_IOAPIC:
+	  add_ioapic ((imps_ioapic *) start);
+	  break;
+#if 0				/*  XXXXX  uncomment this if "add_io_interrupt" is implemented */
+	case IMPS_BCT_IO_INTERRUPT:
+	  add_io_interrupt ((imps_interrupt *) start);
+	  break;
+#endif
+#if 0				/*  XXXXX  uncomment this if "add_local_interrupt" is implemented */
+	case IMPS_BCT_LOCAL_INTERRUPT:
+	  add_local_interupt ((imps_interrupt *) start);
+	  break;
+#endif
+	default:
+	  break;
+	}
+      start += 8;
+    }
+}
+
+
+static int
+imps_bad_bios (imps_fps * fps_ptr)
+{
+  int sum;
+  imps_cth *local_cth_ptr
+  = (imps_cth *) PHYS_TO_VIRTUAL (fps_ptr->cth_ptr);
+
+  if (fps_ptr->feature_info[0] > IMPS_FPS_DEFAULT_MAX)
+    {
+      KERNEL_PRINT (("    Invalid MP System Configuration type %d\n",
+		     fps_ptr->feature_info[0]));
+      return 1;
+    }
+
+  if (fps_ptr->cth_ptr)
+    {
+      sum = get_checksum ((unsigned) local_cth_ptr,
+			  local_cth_ptr->base_length);
+      if (local_cth_ptr->sig != IMPS_CTH_SIGNATURE || sum)
+	{
+	  KERNEL_PRINT
+			(("    Bad MP Config Table sig 0x%x and/or checksum 0x%x\n",
+			(unsigned) (fps_ptr->cth_ptr), sum));
+	  return 1;
+	}
+      if (local_cth_ptr->spec_rev != fps_ptr->spec_rev)
+	{
+	  KERNEL_PRINT (("    Bad MP Config Table sub-revision # %d\n", local_cth_ptr->spec_rev));
+	  return 1;
+	}
+      if (local_cth_ptr->extended_length)
+	{
+	  sum = (get_checksum (((unsigned) local_cth_ptr)
+			       + local_cth_ptr->base_length,
+			       local_cth_ptr->extended_length)
+		 + local_cth_ptr->extended_checksum) & 0xFF;
+	  if (sum)
+	    {
+	      KERNEL_PRINT
+			    (("    Bad Extended MP Config Table checksum 0x%x\n", sum));
+	      return 1;
+	    }
+	}
+    }
+  else if (!fps_ptr->feature_info[0])
+    {
+      KERNEL_PRINT (("    Missing configuration information\n"));
+      return 1;
+    }
+
+  return 0;
+}
+
+
+static void
+imps_read_bios (imps_fps * fps_ptr)
+{
+  int apicid;
+  unsigned cth_start, cth_count;
+  imps_cth *local_cth_ptr
+  = (imps_cth *) PHYS_TO_VIRTUAL (fps_ptr->cth_ptr);
+  char *str_ptr;
+
+  KERNEL_PRINT (("Intel MultiProcessor Spec 1.%d BIOS support detected\n",
+		 fps_ptr->spec_rev));
+
+  /*
+   *  Do all checking of errors which would definitely
+   *  lead to failure of the SMP boot here.
+   */
+
+  if (imps_bad_bios (fps_ptr))
+    {
+      KERNEL_PRINT (("    Disabling MPS support\n"));
+      return;
+    }
+
+  if (fps_ptr->feature_info[1] & IMPS_FPS_IMCRP_BIT)
+    {
+      str_ptr = "IMCR and PIC";
+    }
+  else
+    {
+      str_ptr = "Virtual Wire";
+    }
+  if (fps_ptr->cth_ptr)
+    {
+      imps_lapic_addr = local_cth_ptr->lapic_addr;
+    }
+  else
+    {
+      imps_lapic_addr = LAPIC_ADDR_DEFAULT;
+    }
+  KERNEL_PRINT
+		(("    APIC config: \"%s mode\"    Local APIC address: 0x%x\n",
+		 str_ptr, imps_lapic_addr));
+  imps_lapic_addr = PHYS_TO_VIRTUAL (imps_lapic_addr);
+
+  /*
+   *  Setup primary CPU.
+   */
+  apicid = IMPS_LAPIC_READ (LAPIC_SPIV);
+  IMPS_LAPIC_WRITE (LAPIC_SPIV, apicid | LAPIC_SPIV_ENABLE_APIC);
+  imps_any_new_apics = IMPS_LAPIC_READ (LAPIC_VER) & 0xF0;
+  apicid = IMPS_APIC_ID (IMPS_LAPIC_READ (LAPIC_ID));
+  imps_cpu_apic_map[0] = apicid;
+  imps_apic_cpu_map[apicid] = 0;
+
+  if (fps_ptr->cth_ptr)
+    {
+      char str1[16], str2[16];
+      memcpy (str1, local_cth_ptr->oem_id, 8);
+      str1[8] = 0;
+      memcpy (str2, local_cth_ptr->prod_id, 12);
+      str2[12] = 0;
+      KERNEL_PRINT (("  OEM id: %s  Product id: %s\n", str1, str2));
+      cth_start = ((unsigned) local_cth_ptr) + sizeof (imps_cth);
+      cth_count = local_cth_ptr->entry_count;
+    }
+  else
+    {
+      *((volatile unsigned *) IOAPIC_ADDR_DEFAULT) = IOAPIC_ID;
+      defconfig.ioapic.id
+	= IMPS_APIC_ID (*((volatile unsigned *)
+			  (IOAPIC_ADDR_DEFAULT + IOAPIC_RW)));
+      *((volatile unsigned *) IOAPIC_ADDR_DEFAULT) = IOAPIC_VER;
+      defconfig.ioapic.ver
+	= APIC_VERSION (*((volatile unsigned *)
+			  (IOAPIC_ADDR_DEFAULT + IOAPIC_RW)));
+      defconfig.proc[apicid].flags
+	= IMPS_FLAG_ENABLED | IMPS_CPUFLAG_BOOT;
+      defconfig.proc[!apicid].flags = IMPS_FLAG_ENABLED;
+      imps_num_cpus = 2;
+      if (fps_ptr->feature_info[0] == 1
+	  || fps_ptr->feature_info[0] == 5)
+	{
+	  memcpy (defconfig.bus[0].bus_type, "ISA   ", 6);
+	}
+      if (fps_ptr->feature_info[0] == 4
+	  || fps_ptr->feature_info[0] == 7)
+	{
+	  memcpy (defconfig.bus[0].bus_type, "MCA   ", 6);
+	}
+      if (fps_ptr->feature_info[0] > 4)
+	{
+	  defconfig.proc[0].apic_ver = 0x10;
+	  defconfig.proc[1].apic_ver = 0x10;
+	  defconfig.bus[1].type = IMPS_BCT_BUS;
+	}
+      if (fps_ptr->feature_info[0] == 2)
+	{
+	  defconfig.intin[2].type = 255;
+	  defconfig.intin[13].type = 255;
+	}
+      if (fps_ptr->feature_info[0] == 7)
+	{
+	  defconfig.intin[0].type = 255;
+	}
+      cth_start = (unsigned) &defconfig;
+      cth_count = DEF_ENTRIES;
+    }
+  imps_read_config_table (cth_start, cth_count);
+
+  /* %%%%% ESB read extended entries here */
+
+  imps_enabled = 1;
+}
+
+
+/*
+ *  Given a region to check, this actually looks for the "MP Floating
+ *  Pointer Structure".  The return value indicates if the correct
+ *  signature and checksum for a floating pointer structure of the
+ *  appropriate spec revision was found.  If so, then do not search
+ *  further.
+ *
+ *  NOTE:  The memory scan will always be in the bottom 1 MB.
+ *
+ *  This function presumes that "start" will always be aligned to a 16-bit
+ *  boundary.
+ *
+ *  Function finished.
+ */
+
+static int
+imps_scan (unsigned start, unsigned length)
+{
+  IMPS_DEBUG_PRINT (("Scanning from 0x%x for %d bytes\n",
+		     start, length));
+
+  while (length > 0)
+    {
+      imps_fps *fps_ptr = (imps_fps *) PHYS_TO_VIRTUAL (start);
+
+      if (fps_ptr->sig == IMPS_FPS_SIGNATURE
+	  && fps_ptr->length == 1
+	  && (fps_ptr->spec_rev == 1 || fps_ptr->spec_rev == 4)
+	  && !get_checksum (start, 16))
+	{
+	  IMPS_DEBUG_PRINT (("Found MP Floating Structure Pointer at %x\n", start));
+	  imps_read_bios (fps_ptr);
+	  return 1;
+	}
+
+      length -= 16;
+      start += 16;
+    }
+
+  return 0;
+}
+
+
+/*
+ *  This is the primary function for probing for MPS compatible hardware
+ *  and BIOS information.  Call this during the early stages of OS startup,
+ *  before memory can be messed up.
+ *
+ *  The probe looks for the "MP Floating Pointer Structure" at locations
+ *  listed at the top of page 4-2 of the spec.
+ *
+ *  Environment requirements from the OS to run:
+ *
+ *   (1) : A non-linear virtual to physical memory mapping is probably OK,
+ *	     as (I think) the structures all fall within page boundaries,
+ *	     but a linear mapping is recommended.  Currently assumes that
+ *	     the mapping will remain identical over time (which should be
+ *	     OK since it only accesses memory which shouldn't be munged
+ *	     by the OS anyway).
+ *   (2) : The OS only consumes memory which the BIOS says is OK to use,
+ *	     and not any of the BIOS standard areas (the areas 0x400 to
+ *	     0x600, the EBDA, 0xE0000 to 0xFFFFF, and unreported physical
+ *	     RAM).  Sometimes a small amount of physical RAM is not
+ *	     reported by the BIOS, to be used to store MPS and other
+ *	     information.
+ *   (3) : It must be possible to read the CMOS.
+ *   (4) : There must be between 512K and 640K of lower memory (this is a
+ *	     sanity check).
+ *
+ *  Function finished.
+ */
+
+int
+imps_probe (void)
+{
+  /*
+   *  Determine possible address of the EBDA
+   */
+  unsigned ebda_addr = *((unsigned short *)
+			 PHYS_TO_VIRTUAL (EBDA_SEG_ADDR)) << 4;
+
+  /*
+   *  Determine amount of installed lower memory (not *available*
+   *  lower memory).
+   *
+   *  NOTE:  This should work reliably as long as we verify the
+   *         machine is at least a system that could possibly have
+   *         MPS compatibility to begin with.
+   */
+  unsigned mem_lower = ((CMOS_READ_BYTE (CMOS_BASE_MEMORY + 1) << 8)
+			| CMOS_READ_BYTE (CMOS_BASE_MEMORY)) << 10;
+
+#ifdef IMPS_DEBUG
+  imps_enabled = 0;
+  imps_num_cpus = 1;
+#endif
+
+  /*
+   *  Sanity check : if this isn't reasonable, it is almost impossibly
+   *    unlikely to be an MPS compatible machine, so return failure.
+   */
+  if (mem_lower < 512 * 1024 || mem_lower > 640 * 1024)
+    {
+      return 0;
+    }
+
+  if (ebda_addr > mem_lower - 1024
+      || ebda_addr + *((unsigned char *) PHYS_TO_VIRTUAL (ebda_addr))
+      * 1024 > mem_lower)
+    {
+      ebda_addr = 0;
+    }
+
+  if (((ebda_addr && imps_scan (ebda_addr, 1024))
+       || (!ebda_addr && imps_scan (mem_lower - 1024, 1024))
+       || imps_scan (0xF0000, 0x10000)) && imps_enabled)
+    {
+      return 1;
+    }
+
+  /*
+   *  If no BIOS info on MPS hardware is found, then return failure.
+   */
+
+  return 0;
+}
diff --git a/stage2/smp-imps.h b/stage2/smp-imps.h
new file mode 100644
index 0000000..c0fdce3
--- /dev/null
+++ b/stage2/smp-imps.h
@@ -0,0 +1,208 @@
+/*
+ *  <Insert copyright here : it must be BSD-like so everyone can use it>
+ *
+ *  Author:  Erich Boleyn  <erich@uruk.org>   http://www.uruk.org/~erich/
+ *
+ *  Header file implementing Intel MultiProcessor Specification (MPS)
+ *  version 1.1 and 1.4 SMP hardware control for Intel Architecture CPUs,
+ *  with hooks for running correctly on a standard PC without the hardware.
+ *
+ *  This file was created from information in the Intel MPS version 1.4
+ *  document, order number 242016-004, which can be ordered from the
+ *  Intel literature center.
+ */
+
+#ifndef _SMP_IMPS_H
+#define _SMP_IMPS_H
+
+/* make sure "apic.h" is included */
+#ifndef _APIC_H
+#error		Must include "apic.h" before "smp-imps.h"
+#endif /* !_APIC_H */
+
+/*
+ *  Defines used.
+ */
+
+#ifdef IMPS_DEBUG
+#define IMPS_DEBUG_PRINT(x)  KERNEL_PRINT(x)
+#else /* !IMPS_DEBUG */
+#define IMPS_DEBUG_PRINT(x)
+#endif /* !IMPS_DEBUG */
+
+#define IMPS_MAX_CPUS			APIC_BROADCAST_ID
+
+/*
+ *  Defines representing limitations on values usable in different
+ *  situations.  This mostly depends on whether the APICs are old
+ *  (82489DX) or new (SIO or Pentium/Pentium Pro integrated APICs).
+ *
+ *  NOTE:  It appears that the APICs must either be all old or all new,
+ *    or broadcasts won't work right.
+ *  NOTE #2:  Given that, the maximum ID which can be sent to predictably
+ *    is 14 for new APICs and 254 for old APICs.  So, this all implies that
+ *    a maximum of 15 processors is supported with the new APICs, and a
+ *    maximum of 255 processors with the old APICs.
+ */
+
+#define IMPS_APIC_ID(x)							\
+  ( imps_any_new_apics ? APIC_NEW_ID(x) : APIC_OLD_ID(x) )
+
+/*
+ *  This is the value that must be in the "sig" member of the MP
+ *  Floating Pointer Structure.
+ */
+#define IMPS_FPS_SIGNATURE	('_' | ('M'<<8) | ('P'<<16) | ('_'<<24))
+#define IMPS_FPS_IMCRP_BIT	0x80
+#define IMPS_FPS_DEFAULT_MAX	7
+
+/*
+ *  This is the value that must be in the "sig" member of the MP
+ *  Configuration Table Header.
+ */
+#define IMPS_CTH_SIGNATURE	('P' | ('C'<<8) | ('M'<<16) | ('P'<<24))
+
+/*
+ *  These are the "type" values for Base MP Configuration Table entries.
+ */
+#define		IMPS_FLAG_ENABLED	1
+#define IMPS_BCT_PROCESSOR		0
+#define		IMPS_CPUFLAG_BOOT	2
+#define IMPS_BCT_BUS			1
+#define IMPS_BCT_IOAPIC			2
+#define IMPS_BCT_IO_INTERRUPT		3
+#define IMPS_BCT_LOCAL_INTERRUPT	4
+#define		IMPS_INT_INT		0
+#define		IMPS_INT_NMI		1
+#define		IMPS_INT_SMI		2
+#define		IMPS_INT_EXTINT		3
+
+
+/*
+ *  Typedefs and data item definitions done here.
+ */
+
+typedef struct imps_fps imps_fps;	/* MP floating pointer structure */
+typedef struct imps_cth imps_cth;	/* MP configuration table header */
+typedef struct imps_processor imps_processor;
+typedef struct imps_bus imps_bus;
+typedef struct imps_ioapic imps_ioapic;
+typedef struct imps_interrupt imps_interrupt;
+
+
+/*
+ *  Data structures defined here
+ */
+
+/*
+ *  MP Floating Pointer Structure (fps)
+ *
+ *  Look at page 4-3 of the MP spec for the starting definitions of
+ *  this structure.
+ */
+struct imps_fps
+  {
+    unsigned sig;
+    imps_cth *cth_ptr;
+    unsigned char length;
+    unsigned char spec_rev;
+    unsigned char checksum;
+    unsigned char feature_info[5];
+  };
+
+/*
+ *  MP Configuration Table Header  (cth)
+ *
+ *  Look at page 4-5 of the MP spec for the starting definitions of
+ *  this structure.
+ */
+struct imps_cth
+  {
+    unsigned sig;
+    unsigned short base_length;
+    unsigned char spec_rev;
+    unsigned char checksum;
+    char oem_id[8];
+    char prod_id[12];
+    unsigned oem_table_ptr;
+    unsigned short oem_table_size;
+    unsigned short entry_count;
+    unsigned lapic_addr;
+    unsigned short extended_length;
+    unsigned char extended_checksum;
+    char reserved[1];
+  };
+
+/*
+ *  Base MP Configuration Table Types.  They are sorted according to
+ *  type (i.e. all of type 0 come first, etc.).  Look on page 4-6 for
+ *  the start of the descriptions.
+ */
+
+struct imps_processor
+  {
+    unsigned char type;		/* must be 0 */
+    unsigned char apic_id;
+    unsigned char apic_ver;
+    unsigned char flags;
+    unsigned signature;
+    unsigned features;
+    char reserved[8];
+  };
+
+struct imps_bus
+  {
+    unsigned char type;		/* must be 1 */
+    unsigned char id;
+    char bus_type[6];
+  };
+
+struct imps_ioapic
+  {
+    unsigned char type;		/* must be 2 */
+    unsigned char id;
+    unsigned char ver;
+    unsigned char flags;
+    unsigned addr;
+  };
+
+struct imps_interrupt
+  {
+    unsigned char type;		/* must be 3 or 4 */
+    unsigned char int_type;
+    unsigned short flags;
+    unsigned char source_bus_id;
+    unsigned char source_bus_irq;
+    unsigned char dest_apic_id;
+    unsigned char dest_apic_intin;
+  };
+
+
+/*
+ *  Exported globals here.
+ */
+
+/*
+ *  This is the primary function for probing for Intel MPS 1.1/1.4
+ *  compatible hardware and BIOS information.  While probing the CPUs
+ *  information returned from the BIOS, this also starts up each CPU
+ *  and gets it ready for use.
+ *
+ *  Call this during the early stages of OS startup, before memory can
+ *  be messed up.
+ *
+ *  Returns 1 if IMPS information was found and is valid, else 0.
+ */
+
+int imps_probe (void);
+
+
+/*
+ *  Defines that use variables
+ */
+
+#define IMPS_LAPIC_READ(x)  (*((volatile unsigned *) (imps_lapic_addr+(x))))
+#define IMPS_LAPIC_WRITE(x, y)   \
+   (*((volatile unsigned *) (imps_lapic_addr+(x))) = (y))
+
+#endif /* !_SMP_IMPS_H */
diff --git a/stage2/stage1_5.c b/stage2/stage1_5.c
new file mode 100644
index 0000000..5c45d4c
--- /dev/null
+++ b/stage2/stage1_5.c
@@ -0,0 +1,69 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2001,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.
+ */
+
+#include "shared.h"
+
+static int saved_sector = -1;
+
+static void
+disk_read_savesect_func (int sector, int offset, int length)
+{
+  saved_sector = sector;
+}
+
+void
+cmain (void)
+{
+  grub_printf ("\n\nGRUB loading, please wait...\n");
+
+  /*
+   *  Here load the true second-stage boot-loader.
+   */
+
+  if (grub_open (config_file))
+    {
+      int ret;
+
+      disk_read_hook = disk_read_savesect_func;
+      grub_read ((char *) 0x8000, SECTOR_SIZE * 2);
+      disk_read_hook = NULL;
+
+      /* Sanity check: catch an internal error.  */
+      if (saved_sector == -1)
+	{
+	  grub_printf ("internal error: the second sector of Stage 2 is unknown.");
+	  stop ();
+	}
+      
+      ret = grub_read ((char *) 0x8000 + SECTOR_SIZE * 2, -1);
+      
+      grub_close ();
+
+      if (ret)
+	chain_stage2 (0, 0x8200, saved_sector);
+    }
+
+  /*
+   *  If not, then print error message and die.
+   */
+
+  print_error ();
+
+  stop ();
+}
diff --git a/stage2/stage2.c b/stage2/stage2.c
new file mode 100644
index 0000000..03c45ea
--- /dev/null
+++ b/stage2/stage2.c
@@ -0,0 +1,1075 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000,2001,2002,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
+ *  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.
+ */
+
+#include <shared.h>
+#include <term.h>
+
+grub_jmp_buf restart_env;
+
+#if defined(PRESET_MENU_STRING) && defined(PRESET_MENU_EXTERNAL)
+#error Defining both PRESET_MENU_STRING and PRESET_MENU_EXTERNAL does not \
+       make sense. Please only define one.
+#endif
+
+#if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS) || \
+    defined(PRESET_MENU_EXTERNAL)
+
+# if defined(PRESET_MENU_STRING)
+static const char *preset_menu = PRESET_MENU_STRING;
+# elif defined(PRESET_MENU_EXTERNAL)
+extern const char *preset_menu;
+# elif defined(SUPPORT_DISKLESS)
+/* Execute the command "bootp" automatically.  */
+static const char *preset_menu = "bootp\n";
+# endif /* SUPPORT_DISKLESS */
+
+static int preset_menu_offset;
+
+static int
+open_preset_menu (void)
+{
+#ifdef GRUB_UTIL
+  /* Unless the user explicitly requests to use the preset menu,
+     always opening the preset menu fails in the grub shell.  */
+  if (! use_preset_menu)
+    return 0;
+#endif /* GRUB_UTIL */
+  
+  preset_menu_offset = 0;
+  return preset_menu != 0;
+}
+
+static int
+read_from_preset_menu (char *buf, int maxlen)
+{
+  int len = grub_strlen (preset_menu + preset_menu_offset);
+
+  if (len > maxlen)
+    len = maxlen;
+
+  grub_memmove (buf, preset_menu + preset_menu_offset, len);
+  preset_menu_offset += len;
+
+  return len;
+}
+
+static void
+close_preset_menu (void)
+{
+  /* Disable the preset menu.  */
+  preset_menu = 0;
+}
+
+#else /* ! PRESET_MENU_STRING && ! SUPPORT_DISKLESS */
+
+#define open_preset_menu()	0
+#define read_from_preset_menu(buf, maxlen)	0
+#define close_preset_menu()
+
+#endif /* ! PRESET_MENU_STRING && ! SUPPORT_DISKLESS */
+
+static char *
+get_entry (char *list, int num, int nested)
+{
+  int i;
+
+  for (i = 0; i < num; i++)
+    {
+      do
+	{
+	  while (*(list++));
+	}
+      while (nested && *(list++));
+    }
+
+  return list;
+}
+
+/* Print an entry in a line of the menu box.  */
+static void
+print_entry (int y, int highlight, char *entry)
+{
+  int x;
+
+  if (current_term->setcolorstate)
+    current_term->setcolorstate (COLOR_STATE_NORMAL);
+  
+  if (highlight && current_term->setcolorstate)
+    current_term->setcolorstate (COLOR_STATE_HIGHLIGHT);
+
+  gotoxy (2, y);
+  grub_putchar (' ');
+  for (x = 3; x < 75; x++)
+    {
+      if (*entry && x <= 72)
+	{
+	  if (x == 72)
+	    grub_putchar (DISP_RIGHT);
+	  else
+	    grub_putchar (*entry++);
+	}
+      else
+	grub_putchar (' ');
+    }
+  gotoxy (74, y);
+
+  if (current_term->setcolorstate)
+    current_term->setcolorstate (COLOR_STATE_STANDARD);
+}
+
+/* Print entries in the menu box.  */
+static void
+print_entries (int y, int size, int first, int entryno, char *menu_entries)
+{
+  int i;
+  
+  gotoxy (77, y + 1);
+
+  if (first)
+    grub_putchar (DISP_UP);
+  else
+    grub_putchar (' ');
+
+  menu_entries = get_entry (menu_entries, first, 0);
+
+  for (i = 0; i < size; i++)
+    {
+      print_entry (y + i + 1, entryno == i, menu_entries);
+
+      while (*menu_entries)
+	menu_entries++;
+
+      if (*(menu_entries - 1))
+	menu_entries++;
+    }
+
+  gotoxy (77, y + size);
+
+  if (*menu_entries)
+    grub_putchar (DISP_DOWN);
+  else
+    grub_putchar (' ');
+
+  gotoxy (74, y + entryno + 1);
+}
+
+static void
+print_entries_raw (int size, int first, char *menu_entries)
+{
+  int i;
+
+#define LINE_LENGTH 67
+
+  for (i = 0; i < LINE_LENGTH; i++)
+    grub_putchar ('-');
+  grub_putchar ('\n');
+
+  for (i = first; i < size; i++)
+    {
+      /* grub's printf can't %02d so ... */
+      if (i < 10)
+	grub_putchar (' ');
+      grub_printf ("%d: %s\n", i, get_entry (menu_entries, i, 0));
+    }
+
+  for (i = 0; i < LINE_LENGTH; i++)
+    grub_putchar ('-');
+  grub_putchar ('\n');
+
+#undef LINE_LENGTH
+}
+
+
+static void
+print_border (int y, int size)
+{
+  int i;
+
+  if (current_term->setcolorstate)
+    current_term->setcolorstate (COLOR_STATE_NORMAL);
+  
+  gotoxy (1, y);
+
+  grub_putchar (DISP_UL);
+  for (i = 0; i < 73; i++)
+    grub_putchar (DISP_HORIZ);
+  grub_putchar (DISP_UR);
+
+  i = 1;
+  while (1)
+    {
+      gotoxy (1, y + i);
+
+      if (i > size)
+	break;
+      
+      grub_putchar (DISP_VERT);
+      gotoxy (75, y + i);
+      grub_putchar (DISP_VERT);
+
+      i++;
+    }
+
+  grub_putchar (DISP_LL);
+  for (i = 0; i < 73; i++)
+    grub_putchar (DISP_HORIZ);
+  grub_putchar (DISP_LR);
+
+  if (current_term->setcolorstate)
+    current_term->setcolorstate (COLOR_STATE_STANDARD);
+}
+
+static void
+run_menu (char *menu_entries, char *config_entries, int num_entries,
+	  char *heap, int entryno)
+{
+  int c, time1, time2 = -1, first_entry = 0;
+  char *cur_entry = 0;
+
+  /*
+   *  Main loop for menu UI.
+   */
+
+restart:
+  /* Dumb terminal always use all entries for display 
+     invariant for TERM_DUMB: first_entry == 0  */
+  if (! (current_term->flags & TERM_DUMB))
+    {
+      while (entryno > 11)
+	{
+	  first_entry++;
+	  entryno--;
+	}
+    }
+
+  /* If the timeout was expired or wasn't set, force to show the menu
+     interface. */
+  if (grub_timeout < 0)
+    show_menu = 1;
+  
+  /* If SHOW_MENU is false, don't display the menu until ESC is pressed.  */
+  if (! show_menu)
+    {
+      /* Get current time.  */
+      while ((time1 = getrtsecs ()) == 0xFF)
+	;
+
+      while (1)
+	{
+	  /* Check if ESC is pressed.  */
+	  if (checkkey () != -1 && ASCII_CHAR (getkey ()) == '\e')
+	    {
+	      grub_timeout = -1;
+	      show_menu = 1;
+	      break;
+	    }
+
+	  /* If GRUB_TIMEOUT is expired, boot the default entry.  */
+	  if (grub_timeout >=0
+	      && (time1 = getrtsecs ()) != time2
+	      && time1 != 0xFF)
+	    {
+	      if (grub_timeout <= 0)
+		{
+		  grub_timeout = -1;
+		  goto boot_entry;
+		}
+	      
+	      time2 = time1;
+	      grub_timeout--;
+	      
+	      /* Print a message.  */
+	      grub_printf ("\rPress `ESC' to enter the menu... %d   ",
+			   grub_timeout);
+	    }
+	}
+    }
+
+  /* Only display the menu if the user wants to see it. */
+  if (show_menu)
+    {
+      init_page ();
+      setcursor (0);
+
+      if (current_term->flags & TERM_DUMB)
+	print_entries_raw (num_entries, first_entry, menu_entries);
+      else
+	print_border (3, 12);
+
+      grub_printf ("\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.");
+	}
+      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.");
+	  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.");
+	}
+
+      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);
+    }
+
+  /* XX using RT clock now, need to initialize value */
+  while ((time1 = getrtsecs()) == 0xFF);
+
+  while (1)
+    {
+      /* Initialize to NULL just in case...  */
+      cur_entry = NULL;
+
+      if (grub_timeout >= 0 && (time1 = getrtsecs()) != time2 && time1 != 0xFF)
+	{
+	  if (grub_timeout <= 0)
+	    {
+	      grub_timeout = -1;
+	      break;
+	    }
+
+	  /* else not booting yet! */
+	  time2 = time1;
+
+	  if (current_term->flags & TERM_DUMB)
+	      grub_printf ("\r    Entry %d will be booted automatically in %d seconds.   ", 
+			   entryno, grub_timeout);
+	  else
+	    {
+	      gotoxy (3, 22);
+	      grub_printf ("The highlighted entry will be booted automatically in %d seconds.    ",
+			   grub_timeout);
+	      gotoxy (74, 4 + entryno);
+	  }
+	  
+	  grub_timeout--;
+	}
+
+      /* Check for a keypress, however if TIMEOUT has been expired
+	 (GRUB_TIMEOUT == -1) relax in GETKEY even if no key has been
+	 pressed.  
+	 This avoids polling (relevant in the grub-shell and later on
+	 in grub if interrupt driven I/O is done).  */
+      if (checkkey () >= 0 || grub_timeout < 0)
+	{
+	  /* Key was pressed, show which entry is selected before GETKEY,
+	     since we're comming in here also on GRUB_TIMEOUT == -1 and
+	     hang in GETKEY */
+	  if (current_term->flags & TERM_DUMB)
+	    grub_printf ("\r    Highlighted entry is %d: ", entryno);
+
+	  c = ASCII_CHAR (getkey ());
+
+	  if (grub_timeout >= 0)
+	    {
+	      if (current_term->flags & TERM_DUMB)
+		grub_putchar ('\r');
+	      else
+		gotoxy (3, 22);
+	      printf ("                                                                    ");
+	      grub_timeout = -1;
+	      fallback_entryno = -1;
+	      if (! (current_term->flags & TERM_DUMB))
+		gotoxy (74, 4 + entryno);
+	    }
+
+	  /* We told them above (at least in SUPPORT_SERIAL) to use
+	     '^' or 'v' so accept these keys.  */
+	  if (c == 16 || c == '^')
+	    {
+	      if (current_term->flags & TERM_DUMB)
+		{
+		  if (entryno > 0)
+		    entryno--;
+		}
+	      else
+		{
+		  if (entryno > 0)
+		    {
+		      print_entry (4 + entryno, 0,
+				   get_entry (menu_entries,
+					      first_entry + entryno,
+					      0));
+		      entryno--;
+		      print_entry (4 + entryno, 1,
+				   get_entry (menu_entries,
+					      first_entry + entryno,
+					      0));
+		    }
+		  else if (first_entry > 0)
+		    {
+		      first_entry--;
+		      print_entries (3, 12, first_entry, entryno,
+				     menu_entries);
+		    }
+		}
+	    }
+	  else if ((c == 14 || c == 'v')
+		   && first_entry + entryno + 1 < num_entries)
+	    {
+	      if (current_term->flags & TERM_DUMB)
+		entryno++;
+	      else
+		{
+		  if (entryno < 11)
+		    {
+		      print_entry (4 + entryno, 0,
+				   get_entry (menu_entries,
+					      first_entry + entryno,
+					      0));
+		      entryno++;
+		      print_entry (4 + entryno, 1,
+				   get_entry (menu_entries,
+					      first_entry + entryno,
+					      0));
+		  }
+		else if (num_entries > 12 + first_entry)
+		  {
+		    first_entry++;
+		    print_entries (3, 12, first_entry, entryno, menu_entries);
+		  }
+		}
+	    }
+	  else if (c == 7)
+	    {
+	      /* Page Up */
+	      first_entry -= 12;
+	      if (first_entry < 0)
+		{
+		  entryno += first_entry;
+		  first_entry = 0;
+		  if (entryno < 0)
+		    entryno = 0;
+		}
+	      print_entries (3, 12, first_entry, entryno, menu_entries);
+	    }
+	  else if (c == 3)
+	    {
+	      /* Page Down */
+	      first_entry += 12;
+	      if (first_entry + entryno + 1 >= num_entries)
+		{
+		  first_entry = num_entries - 12;
+		  if (first_entry < 0)
+		    first_entry = 0;
+		  entryno = num_entries - first_entry - 1;
+		}
+	      print_entries (3, 12, first_entry, entryno, menu_entries);
+	    }
+
+	  if (config_entries)
+	    {
+	      if ((c == '\n') || (c == '\r') || (c == 6))
+		break;
+	    }
+	  else
+	    {
+	      if ((c == 'd') || (c == 'o') || (c == 'O'))
+		{
+		  if (! (current_term->flags & TERM_DUMB))
+		    print_entry (4 + entryno, 0,
+				 get_entry (menu_entries,
+					    first_entry + entryno,
+					    0));
+
+		  /* insert after is almost exactly like insert before */
+		  if (c == 'o')
+		    {
+		      /* But `o' differs from `O', since it may causes
+			 the menu screen to scroll up.  */
+		      if (entryno < 11 || (current_term->flags & TERM_DUMB))
+			entryno++;
+		      else
+			first_entry++;
+		      
+		      c = 'O';
+		    }
+
+		  cur_entry = get_entry (menu_entries,
+					 first_entry + entryno,
+					 0);
+
+		  if (c == 'O')
+		    {
+		      grub_memmove (cur_entry + 2, cur_entry,
+				    ((int) heap) - ((int) cur_entry));
+
+		      cur_entry[0] = ' ';
+		      cur_entry[1] = 0;
+
+		      heap += 2;
+
+		      num_entries++;
+		    }
+		  else if (num_entries > 0)
+		    {
+		      char *ptr = get_entry(menu_entries,
+					    first_entry + entryno + 1,
+					    0);
+
+		      grub_memmove (cur_entry, ptr,
+				    ((int) heap) - ((int) ptr));
+		      heap -= (((int) ptr) - ((int) cur_entry));
+
+		      num_entries--;
+
+		      if (entryno >= num_entries)
+			entryno--;
+		      if (first_entry && num_entries < 12 + first_entry)
+			first_entry--;
+		    }
+
+		  if (current_term->flags & TERM_DUMB)
+		    {
+		      grub_printf ("\n\n");
+		      print_entries_raw (num_entries, first_entry,
+					 menu_entries);
+		      grub_printf ("\n");
+		    }
+		  else
+		    print_entries (3, 12, first_entry, entryno, menu_entries);
+		}
+
+	      cur_entry = menu_entries;
+	      if (c == 27)
+		return;
+	      if (c == 'b')
+		break;
+	    }
+
+	  if (! auth && password)
+	    {
+	      if (c == 'p')
+		{
+		  /* Do password check here! */
+		  char entered[32];
+		  char *pptr = password;
+
+		  if (current_term->flags & TERM_DUMB)
+		    grub_printf ("\r                                    ");
+		  else
+		    gotoxy (1, 21);
+
+		  /* Wipe out the previously entered password */
+		  grub_memset (entered, 0, sizeof (entered));
+		  get_cmdline (" Password: ", entered, 31, '*', 0);
+
+		  while (! isspace (*pptr) && *pptr)
+		    pptr++;
+
+		  /* Make sure that PASSWORD is NUL-terminated.  */
+		  *pptr++ = 0;
+
+		  if (! check_password (entered, password, password_type))
+		    {
+		      char *new_file = config_file;
+		      while (isspace (*pptr))
+			pptr++;
+
+		      /* If *PPTR is NUL, then allow the user to use
+			 privileged instructions, otherwise, load
+			 another configuration file.  */
+		      if (*pptr != 0)
+			{
+			  while ((*(new_file++) = *(pptr++)) != 0)
+			    ;
+
+			  /* Make sure that the user will not have
+			     authority in the next configuration.  */
+			  auth = 0;
+			  return;
+			}
+		      else
+			{
+			  /* Now the user is superhuman.  */
+			  auth = 1;
+			  goto restart;
+			}
+		    }
+		  else
+		    {
+		      grub_printf ("Failed!\n      Press any key to continue...");
+		      getkey ();
+		      goto restart;
+		    }
+		}
+	    }
+	  else
+	    {
+	      if (c == 'e')
+		{
+		  int new_num_entries = 0, i = 0;
+		  char *new_heap;
+
+		  if (config_entries)
+		    {
+		      new_heap = heap;
+		      cur_entry = get_entry (config_entries,
+					     first_entry + entryno,
+					     1);
+		    }
+		  else
+		    {
+		      /* safe area! */
+		      new_heap = heap + NEW_HEAPSIZE + 1;
+		      cur_entry = get_entry (menu_entries,
+					     first_entry + entryno,
+					     0);
+		    }
+
+		  do
+		    {
+		      while ((*(new_heap++) = cur_entry[i++]) != 0);
+		      new_num_entries++;
+		    }
+		  while (config_entries && cur_entry[i]);
+
+		  /* this only needs to be done if config_entries is non-NULL,
+		     but it doesn't hurt to do it always */
+		  *(new_heap++) = 0;
+
+		  if (config_entries)
+		    run_menu (heap, NULL, new_num_entries, new_heap, 0);
+		  else
+		    {
+		      cls ();
+		      print_cmdline_message (0);
+
+		      new_heap = heap + NEW_HEAPSIZE + 1;
+
+		      saved_drive = boot_drive;
+		      saved_partition = install_partition;
+		      current_drive = GRUB_INVALID_DRIVE;
+
+		      if (! get_cmdline (PACKAGE " edit> ", new_heap,
+					 NEW_HEAPSIZE + 1, 0, 1))
+			{
+			  int j = 0;
+
+			  /* get length of new command */
+			  while (new_heap[j++])
+			    ;
+
+			  if (j < 2)
+			    {
+			      j = 2;
+			      new_heap[0] = ' ';
+			      new_heap[1] = 0;
+			    }
+
+			  /* align rest of commands properly */
+			  grub_memmove (cur_entry + j, cur_entry + i,
+					(int) heap - ((int) cur_entry + i));
+
+			  /* copy command to correct area */
+			  grub_memmove (cur_entry, new_heap, j);
+
+			  heap += (j - i);
+			}
+		    }
+
+		  goto restart;
+		}
+	      if (c == 'c')
+		{
+		  enter_cmdline (heap, 0);
+		  goto restart;
+		}
+#ifdef GRUB_UTIL
+	      if (c == 'q')
+		{
+		  /* The same as ``quit''.  */
+		  stop ();
+		}
+#endif
+	    }
+	}
+    }
+  
+  /* Attempt to boot an entry.  */
+  
+ boot_entry:
+  
+  cls ();
+  setcursor (1);
+  
+  while (1)
+    {
+      if (config_entries)
+	printf ("  Booting \'%s\'\n\n",
+		get_entry (menu_entries, first_entry + entryno, 0));
+      else
+	printf ("  Booting command-list\n\n");
+
+      if (! cur_entry)
+	cur_entry = get_entry (config_entries, first_entry + entryno, 1);
+
+      /* Set CURRENT_ENTRYNO for the command "savedefault".  */
+      current_entryno = first_entry + entryno;
+      
+      if (run_script (cur_entry, heap))
+	{
+	  if (fallback_entryno >= 0)
+	    {
+	      cur_entry = NULL;
+	      first_entry = 0;
+	      entryno = fallback_entries[fallback_entryno];
+	      fallback_entryno++;
+	      if (fallback_entryno >= MAX_FALLBACK_ENTRIES
+		  || fallback_entries[fallback_entryno] < 0)
+		fallback_entryno = -1;
+	    }
+	  else
+	    break;
+	}
+      else
+	break;
+    }
+
+  show_menu = 1;
+  goto restart;
+}
+
+
+static int
+get_line_from_config (char *cmdline, int maxlen, int read_from_file)
+{
+  int pos = 0, literal = 0, comment = 0;
+  char c;  /* since we're loading it a byte at a time! */
+  
+  while (1)
+    {
+      if (read_from_file)
+	{
+	  if (! grub_read (&c, 1))
+	    break;
+	}
+      else
+	{
+	  if (! read_from_preset_menu (&c, 1))
+	    break;
+	}
+
+      /* Skip all carriage returns.  */
+      if (c == '\r')
+	continue;
+
+      /* Replace tabs with spaces.  */
+      if (c == '\t')
+	c = ' ';
+
+      /* The previous is a backslash, then...  */
+      if (literal)
+	{
+	  /* If it is a newline, replace it with a space and continue.  */
+	  if (c == '\n')
+	    {
+	      c = ' ';
+	      
+	      /* Go back to overwrite a backslash.  */
+	      if (pos > 0)
+		pos--;
+	    }
+	    
+	  literal = 0;
+	}
+	  
+      /* translate characters first! */
+      if (c == '\\' && ! literal)
+	literal = 1;
+
+      if (comment)
+	{
+	  if (c == '\n')
+	    comment = 0;
+	}
+      else if (! pos)
+	{
+	  if (c == '#')
+	    comment = 1;
+	  else if ((c != ' ') && (c != '\n'))
+	    cmdline[pos++] = c;
+	}
+      else
+	{
+	  if (c == '\n')
+	    break;
+
+	  if (pos < maxlen)
+	    cmdline[pos++] = c;
+	}
+    }
+
+  cmdline[pos] = 0;
+
+  return pos;
+}
+
+
+/* This is the starting function in C.  */
+void
+cmain (void)
+{
+  int config_len, menu_len, num_entries;
+  char *config_entries, *menu_entries;
+  char *kill_buf = (char *) KILL_BUF;
+
+  auto void reset (void);
+  void reset (void)
+    {
+      count_lines = -1;
+      config_len = 0;
+      menu_len = 0;
+      num_entries = 0;
+      config_entries = (char *) mbi.drives_addr + mbi.drives_length;
+      menu_entries = (char *) MENU_BUF;
+      init_config ();
+    }
+  
+  /* Initialize the environment for restarting Stage 2.  */
+  grub_setjmp (restart_env);
+  
+  /* Initialize the kill buffer.  */
+  *kill_buf = 0;
+
+  /* Never return.  */
+  for (;;)
+    {
+      int is_opened, is_preset;
+
+      reset ();
+      
+      /* Here load the configuration file.  */
+      
+#ifdef GRUB_UTIL
+      if (use_config_file)
+#endif /* GRUB_UTIL */
+	{
+	  char *default_file = (char *) DEFAULT_FILE_BUF;
+	  int i;
+	  
+	  /* Get a saved default entry if possible.  */
+	  saved_entryno = 0;
+	  *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 (grub_open (default_file))
+	    {
+	      char buf[10]; /* This is good enough.  */
+	      char *p = buf;
+	      int len;
+	      
+	      len = grub_read (buf, sizeof (buf));
+	      if (len > 0)
+		{
+		  buf[sizeof (buf) - 1] = 0;
+		  safe_parse_maxint (&p, &saved_entryno);
+		}
+
+	      grub_close ();
+	    }
+	  errnum = ERR_NONE;
+	  
+	  do
+	    {
+	      /* STATE 0:  Before any title command.
+		 STATE 1:  In a title command.
+		 STATE >1: In a entry after a title command.  */
+	      int state = 0, prev_config_len = 0, prev_menu_len = 0;
+	      char *cmdline;
+
+	      /* Try the preset menu first. This will succeed at most once,
+		 because close_preset_menu disables the preset menu.  */
+	      is_opened = is_preset = open_preset_menu ();
+	      if (! is_opened)
+		{
+		  is_opened = grub_open (config_file);
+		  errnum = ERR_NONE;
+		}
+
+	      if (! is_opened)
+		break;
+
+	      /* This is necessary, because the menu must be overrided.  */
+	      reset ();
+	      
+	      cmdline = (char *) CMDLINE_BUF;
+	      while (get_line_from_config (cmdline, NEW_HEAPSIZE,
+					   ! is_preset))
+		{
+		  struct builtin *builtin;
+		  
+		  /* Get the pointer to the builtin structure.  */
+		  builtin = find_command (cmdline);
+		  errnum = 0;
+		  if (! builtin)
+		    /* Unknown command. Just skip now.  */
+		    continue;
+		  
+		  if (builtin->flags & BUILTIN_TITLE)
+		    {
+		      char *ptr;
+		      
+		      /* the command "title" is specially treated.  */
+		      if (state > 1)
+			{
+			  /* The next title is found.  */
+			  num_entries++;
+			  config_entries[config_len++] = 0;
+			  prev_menu_len = menu_len;
+			  prev_config_len = config_len;
+			}
+		      else
+			{
+			  /* The first title is found.  */
+			  menu_len = prev_menu_len;
+			  config_len = prev_config_len;
+			}
+		      
+		      /* Reset the state.  */
+		      state = 1;
+		      
+		      /* Copy title into menu area.  */
+		      ptr = skip_to (1, cmdline);
+		      while ((menu_entries[menu_len++] = *(ptr++)) != 0)
+			;
+		    }
+		  else if (! state)
+		    {
+		      /* Run a command found is possible.  */
+		      if (builtin->flags & BUILTIN_MENU)
+			{
+			  char *arg = skip_to (1, cmdline);
+			  (builtin->func) (arg, BUILTIN_MENU);
+			  errnum = 0;
+			}
+		      else
+			/* Ignored.  */
+			continue;
+		    }
+		  else
+		    {
+		      char *ptr = cmdline;
+		      
+		      state++;
+		      /* Copy config file data to config area.  */
+		      while ((config_entries[config_len++] = *ptr++) != 0)
+			;
+		    }
+		}
+	      
+	      if (state > 1)
+		{
+		  /* Finish the last entry.  */
+		  num_entries++;
+		  config_entries[config_len++] = 0;
+		}
+	      else
+		{
+		  menu_len = prev_menu_len;
+		  config_len = prev_config_len;
+		}
+	      
+	      menu_entries[menu_len++] = 0;
+	      config_entries[config_len++] = 0;
+	      grub_memmove (config_entries + config_len, menu_entries,
+			    menu_len);
+	      menu_entries = config_entries + config_len;
+
+	      /* Make sure that all fallback entries are valid.  */
+	      if (fallback_entryno >= 0)
+		{
+		  for (i = 0; i < MAX_FALLBACK_ENTRIES; i++)
+		    {
+		      if (fallback_entries[i] < 0)
+			break;
+		      if (fallback_entries[i] >= num_entries)
+			{
+			  grub_memmove (fallback_entries + i,
+					fallback_entries + i + 1,
+					((MAX_FALLBACK_ENTRIES - i - 1)
+					 * sizeof (int)));
+			  i--;
+			}
+		    }
+
+		  if (fallback_entries[0] < 0)
+		    fallback_entryno = -1;
+		}
+	      /* Check if the default entry is present. Otherwise reset
+		 it to fallback if fallback is valid, or to DEFAULT_ENTRY 
+		 if not.  */
+	      if (default_entry >= num_entries)
+		{
+		  if (fallback_entryno >= 0)
+		    {
+		      default_entry = fallback_entries[0];
+		      fallback_entryno++;
+		      if (fallback_entryno >= MAX_FALLBACK_ENTRIES
+			  || fallback_entries[fallback_entryno] < 0)
+			fallback_entryno = -1;
+		    }
+		  else
+		    default_entry = 0;
+		}
+	      
+	      if (is_preset)
+		close_preset_menu ();
+	      else
+		grub_close ();
+	    }
+	  while (is_preset);
+	}
+
+      if (! num_entries)
+	{
+	  /* If no acceptable config file, goto command-line, starting
+	     heap from where the config entries would have been stored
+	     if there were any.  */
+	  enter_cmdline (config_entries, 1);
+	}
+      else
+	{
+	  /* Run menu interface.  */
+	  run_menu (menu_entries, config_entries, num_entries,
+		    menu_entries + menu_len, default_entry);
+	}
+    }
+}
diff --git a/stage2/start.S b/stage2/start.S
new file mode 100644
index 0000000..9a7d504
--- /dev/null
+++ b/stage2/start.S
@@ -0,0 +1,409 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001   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.
+ */
+
+#define ASM_FILE
+#include <shared.h>
+
+#ifndef STAGE1_5
+#include <stage2_size.h>
+#endif
+	
+/*
+ *  defines for the code go here
+ */
+
+	/* Absolute addresses
+	   This makes the assembler generate the address without support
+	   from the linker. (ELF can't relocate 16-bit addresses!) */
+#ifdef STAGE1_5
+# define ABS(x) (x-_start+0x2000)
+#else
+# define ABS(x) (x-_start+0x8000)
+#endif /* STAGE1_5 */
+	
+	/* Print message string */
+#define MSG(x)	movw $ABS(x), %si; call message
+
+	.file	"start.S"
+
+	.text
+
+	/* Tell GAS to generate 16-bit instructions so that this code works
+	   in real mode. */
+	.code16
+
+	.globl	start, _start
+start:
+_start:	
+	/*
+	 * _start is loaded at 0x8000 and is jumped to with
+	 * CS:IP 0:0x8000 in stage2.
+	 */
+
+	/* 
+	 * we continue to use the stack for stage1 and assume that
+	 * some registers are set to correct values. See stage1.S
+	 * for more information.
+	 */
+	
+	/* save drive reference first thing! */
+	pushw	%dx
+
+	/* print a notification message on the screen */
+	pushw	%si
+	MSG(notification_string)
+	popw	%si
+	
+	/* this sets up for the first run through "bootloop" */
+	movw	$ABS(firstlist - BOOTSEC_LISTSIZE), %di
+
+	/* save the sector number of the second sector in %ebp */
+	movl	(%di), %ebp
+
+        /* this is the loop for reading the secondary boot-loader in */
+bootloop:
+
+	/* check the number of sectors to read */
+	cmpw	$0, 4(%di)
+
+	/* if zero, go to the start function */
+	je	bootit
+
+setup_sectors:	
+	/* check if we use LBA or CHS */
+	cmpb	$0, -1(%si)
+
+	/* jump to chs_mode if zero */
+	je	chs_mode
+
+lba_mode:	
+	/* load logical sector start */
+	movl	(%di), %ebx
+
+	/* the maximum is limited to 0x7f because of Phoenix EDD */
+	xorl	%eax, %eax
+	movb	$0x7f, %al
+
+	/* how many do we really want to read? */
+	cmpw	%ax, 4(%di)	/* compare against total number of sectors */
+
+	/* which is greater? */
+	jg	1f
+
+	/* if less than, set to total */
+	movw	4(%di), %ax
+
+1:	
+	/* subtract from total */
+	subw	%ax, 4(%di)
+
+	/* add into logical sector start */
+	addl	%eax, (%di)
+
+	/* set up disk address packet */
+
+	/* the size and the reserved byte */
+	movw	$0x0010, (%si)
+
+	/* the number of sectors */
+	movw	%ax, 2(%si)
+
+	/* the absolute address (low 32 bits) */
+	movl	%ebx, 8(%si)
+
+	/* the segment of buffer address */
+	movw	$BUFFERSEG, 6(%si)
+
+	/* save %ax from destruction! */
+	pushw	%ax
+
+	/* zero %eax */
+	xorl	%eax, %eax
+
+	/* the offset of buffer address */
+	movw	%ax, 4(%si)
+
+	/* the absolute address (high 32 bits) */
+	movl	%eax, 12(%si)
+
+
+/*
+ * BIOS call "INT 0x13 Function 0x42" to read sectors from disk into memory
+ *	Call with	%ah = 0x42
+ *			%dl = drive number
+ *			%ds:%si = segment:offset of disk address packet
+ *	Return:
+ *			%al = 0x0 on success; err code on failure
+ */
+
+	movb	$0x42, %ah
+	int	$0x13
+
+	jc	read_error
+
+	movw	$BUFFERSEG, %bx
+	jmp	copy_buffer
+			
+chs_mode:	
+	/* load logical sector start (bottom half) */
+	movl	(%di), %eax
+
+	/* zero %edx */
+	xorl	%edx, %edx
+
+	/* divide by number of sectors */
+	divl	(%si)
+
+	/* save sector start */
+	movb	%dl, 10(%si)
+
+	xorl	%edx, %edx	/* zero %edx */
+	divl	4(%si)		/* divide by number of heads */
+
+	/* save head start */
+	movb	%dl, 11(%si)
+
+	/* save cylinder start */
+	movw	%ax, 12(%si)
+
+	/* do we need too many cylinders? */
+	cmpw	8(%si), %ax
+	jge	geometry_error
+
+	/* determine the maximum sector length of this read */
+	movw	(%si), %ax	/* get number of sectors per track/head */
+
+	/* subtract sector start */
+	subb	10(%si), %al
+
+	/* how many do we really want to read? */
+	cmpw	%ax, 4(%di)	/* compare against total number of sectors */
+
+
+	/* which is greater? */
+	jg	2f
+
+	/* if less than, set to total */
+	movw	4(%di), %ax
+
+2:	
+	/* subtract from total */
+	subw	%ax, 4(%di)
+
+	/* add into logical sector start */
+	addl	%eax, (%di)
+
+/*
+ *  This is the loop for taking care of BIOS geometry translation (ugh!)
+ */
+
+	/* get high bits of cylinder */
+	movb	13(%si), %dl
+
+	shlb	$6, %dl		/* shift left by 6 bits */
+	movb	10(%si), %cl	/* get sector */
+
+	incb	%cl		/* normalize sector (sectors go
+					from 1-N, not 0-(N-1) ) */
+	orb	%dl, %cl	/* composite together */
+	movb	12(%si), %ch	/* sector+hcyl in cl, cylinder in ch */
+
+	/* restore %dx */
+	popw	%dx
+	pushw	%dx
+
+	/* head number */
+	movb	11(%si), %dh
+
+	pushw	%ax	/* save %ax from destruction! */
+
+/*
+ * BIOS call "INT 0x13 Function 0x2" to read sectors from disk into memory
+ *	Call with	%ah = 0x2
+ *			%al = number of sectors
+ *			%ch = cylinder
+ *			%cl = sector (bits 6-7 are high bits of "cylinder")
+ *			%dh = head
+ *			%dl = drive (0x80 for hard disk, 0x0 for floppy disk)
+ *			%es:%bx = segment:offset of buffer
+ *	Return:
+ *			%al = 0x0 on success; err code on failure
+ */
+
+	movw	$BUFFERSEG, %bx
+	movw	%bx, %es	/* load %es segment with disk buffer */
+
+	xorw	%bx, %bx	/* %bx = 0, put it at 0 in the segment */
+	movb	$0x2, %ah	/* function 2 */
+	int	$0x13
+
+	jc	read_error
+
+	/* save source segment */
+	movw	%es, %bx
+	
+copy_buffer:	
+
+	/* load addresses for copy from disk buffer to destination */
+	movw	6(%di), %es	/* load destination segment */
+
+	/* restore %ax */
+	popw	%ax
+
+	/* determine the next possible destination address (presuming
+		512 byte sectors!) */
+	shlw	$5, %ax		/* shift %ax five bits to the left */
+	addw	%ax, 6(%di)	/* add the corrected value to the destination
+				   address for next time */
+
+	/* save addressing regs */
+	pusha
+	pushw	%ds
+
+	/* get the copy length */
+	shlw	$4, %ax
+	movw	%ax, %cx
+
+	xorw	%di, %di	/* zero offset of destination addresses */
+	xorw	%si, %si	/* zero offset of source addresses */
+	movw	%bx, %ds	/* restore the source segment */
+
+	cld		/* sets the copy direction to forward */
+
+	/* perform copy */
+	rep		/* sets a repeat */
+	movsb		/* this runs the actual copy */
+
+	/* restore addressing regs and print a dot with correct DS 
+	   (MSG modifies SI, which is saved, and unused AX and BX) */
+	popw	%ds
+	MSG(notification_step)
+	popa
+
+	/* check if finished with this dataset */
+	cmpw	$0, 4(%di)
+	jne	setup_sectors
+
+	/* update position to load from */
+	subw	$BOOTSEC_LISTSIZE, %di
+
+	/* jump to bootloop */
+	jmp	bootloop
+
+/* END OF MAIN LOOP */
+
+bootit:
+	/* print a newline */
+	MSG(notification_done)
+	popw	%dx	/* this makes sure %dl is our "boot" drive */
+#ifdef STAGE1_5
+	ljmp	$0, $0x2200
+#else /* ! STAGE1_5 */
+	ljmp	$0, $0x8200
+#endif /* ! STAGE1_5 */
+
+
+/*
+ * BIOS Geometry translation error (past the end of the disk geometry!).
+ */
+geometry_error:
+	MSG(geometry_error_string)
+	jmp	general_error
+
+/*
+ * Read error on the disk.
+ */
+read_error:
+	MSG(read_error_string)
+
+general_error:
+	MSG(general_error_string)
+
+/* go here when you need to stop the machine hard after an error condition */
+stop:	jmp	stop
+
+#ifdef STAGE1_5
+notification_string:	.string "Loading stage1.5"
+#else
+notification_string:	.string "Loading stage2"
+#endif
+
+notification_step:	.string "."
+notification_done:	.string "\r\n"
+	
+geometry_error_string:	.string "Geom"
+read_error_string:	.string "Read"
+general_error_string:	.string " Error"
+
+/*
+ * message: write the string pointed to by %si
+ *
+ *   WARNING: trashes %si, %ax, and %bx
+ */
+
+	/*
+	 * Use BIOS "int 10H Function 0Eh" to write character in teletype mode
+	 *	%ah = 0xe	%al = character
+	 *	%bh = page	%bl = foreground color (graphics modes)
+	 */
+1:
+	movw	$0x0001, %bx
+	movb	$0xe, %ah
+	int	$0x10		/* display a byte */
+
+	incw	%si
+message:
+	movb	(%si), %al
+	cmpb	$0, %al
+	jne	1b	/* if not end of string, jmp to display */
+	ret
+lastlist:
+
+/*
+ *  This area is an empty space between the main body of code below which
+ *  grows up (fixed after compilation, but between releases it may change
+ *  in size easily), and the lists of sectors to read, which grows down
+ *  from a fixed top location.
+ */
+
+	.word 0
+	.word 0
+
+	. = _start + 0x200 - BOOTSEC_LISTSIZE
+	
+        /* fill the first data listing with the default */
+blocklist_default_start:
+	.long 2		/* this is the sector start parameter, in logical
+			   sectors from the start of the disk, sector 0 */
+blocklist_default_len:
+			/* this is the number of sectors to read */
+#ifdef STAGE1_5
+	.word 0		/* the command "install" will fill this up */
+#else
+	.word (STAGE2_SIZE + 511) >> 9
+#endif
+blocklist_default_seg:
+#ifdef STAGE1_5
+	.word 0x220
+#else
+	.word 0x820	/* this is the segment of the starting address
+			   to load the data into */
+#endif
+	
+firstlist:	/* this label has to be after the list data!!! */
diff --git a/stage2/start_eltorito.S b/stage2/start_eltorito.S
new file mode 100644
index 0000000..99a7109
--- /dev/null
+++ b/stage2/start_eltorito.S
@@ -0,0 +1,326 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1994-2002  H. Peter Anvin
+ *  Copyright (C) 1999,2000,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
+ *  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.
+ *
+ */
+	
+/*
+ Most of this file was originally "isolinux.asm" from SYSLINUX package.
+ It has been very heavily modified.
+*/
+
+#define ASM_FILE
+#include "stage1.h"
+#include "shared.h"
+#include "iso9660.h"
+
+#ifndef STAGE1_5
+#include "stage2_size.h"
+#endif
+
+
+	/* Absolute addresses
+	   This makes the assembler generate the address without support
+	   from the linker. (ELF can't relocate 16-bit addresses!) */
+#define ABS(x)			(x-_start+BOOTSEC_LOCATION)
+
+#ifdef STAGE1_5
+# define STAGE_ADDR		0x2000
+#else
+# define STAGE_ADDR		0x8000
+#endif /* STAGE1_5 */
+
+	/* Print message string */
+#define MSG(x)			mov $ABS(x), %si; call message;
+
+	.file	"start_eltorito.S"
+
+	.text
+
+	/* Tell GAS to generate 16-bit instructions so that this code works
+	   in real mode. */
+	.code16
+
+	.globl	start, _start
+
+/*
+ * Primary entry point.	 Because BIOSes are buggy, we only load the first
+ * CD-ROM sector (2K) of the file, so the number one priority is actually
+ * loading the rest.
+ */
+start:
+_start:
+	cli
+	ljmp	$0, $ABS(real_start)
+
+	. = _start + 8			    /* Pad to file offset 8 */
+
+		/* This table gets filled in by mkisofs using the
+		   -boot-info-table option */
+bi_pvd:		.long 0xDEADBEEF	    /* LBA of primary volume descript */
+bi_file:	.long 0xDEADBEEF	    /* LBA of boot file */
+bi_length:	.long 0xDEADBEEF	    /* Length of boot file */
+bi_csum:	.long 0xDEADBEEF	    /* Checksum of boot file */
+bi_reserved:	.space (10*4)		    /* Reserved */
+
+real_start:
+	xor	%ax, %ax
+	mov	%ax, %ss
+	mov	%ax, %ds
+	mov	%ax, %es
+	mov	%ax, %fs
+	mov	%ax, %gs
+	mov	$STAGE1_STACKSEG, %sp	    /* set up the REAL stack */
+	sti
+	cld
+
+	/* save drive reference first thing! */
+	mov	%dl, ABS(BootDrive)
+
+	/* print a notification message on the screen */
+	MSG(notification_string)
+
+load_image:
+	/* Set up boot file sector, size, load address */
+	mov	ABS(bi_length), %eax
+	add	$(ISO_SECTOR_SIZE-1), %eax
+	shr	$ISO_SECTOR_BITS, %eax	    /* dwords->sectors */
+	mov	%ax, %bp		    /* boot file sectors */
+	mov	$(STAGE_ADDR >> 4), %bx
+	mov	%bx, %es
+	xor	%bx, %bx
+	mov	ABS(bi_file), %eax
+	call	getlinsec
+	mov	%ds, %ax
+	mov	%ax, %es
+
+	MSG(notification_done)
+bootit:
+	/* save the sector number of the second sector in %ebp */
+	mov	$ABS(firstlist - BOOTSEC_LISTSIZE), %si
+	mov	(%si), %ebp
+	mov	ABS(BootDrive), %dl	    /* this makes sure %dl is our "boot" drive */
+	ljmp	$0, $(STAGE_ADDR+SECTOR_SIZE)  /* jump to main() in asm.S */
+
+/* go here when you need to stop the machine hard after an error condition */
+stop:	jmp	stop
+
+
+/*
+ * Get linear sectors - EBIOS LBA addressing, 2048-byte sectors.
+ *
+ * Note that we can't always do this as a single request, because at least
+ * Phoenix BIOSes has a 127-sector limit.  To be on the safe side, stick
+ * to 16 sectors (32K) per request.
+ *
+ * Input:
+ *	 EAX	 - Linear sector number
+ *	 ES:BX	 - Target buffer
+ *	 BP	 - Sector count
+ */
+getlinsec:
+	mov	$ABS(dapa), %si		   /* Load up the DAPA */
+	mov	%bx, 4(%si)
+	mov	%es, %bx
+	mov	%bx, 6(%si)
+	mov	%eax, 8(%si)
+1:
+	push	%bp
+	push	%si
+	cmp	ABS(MaxTransfer), %bp
+	jbe	2f
+	mov	ABS(MaxTransfer), %bp
+2:
+	mov	%bp, 2(%si)
+	mov	ABS(BootDrive), %dl
+	mov	$0x42, %ah		    /* Extended Read */
+	call	xint13
+	pop	%si
+	pop	%bp
+	movzwl	2(%si), %eax		    /* Sectors we read */
+	add	%eax, 8(%si)		    /* Advance sector pointer */
+	sub	%ax, %bp		    /* Sectors left */
+	shl	$(ISO_SECTOR_BITS-4), %ax   /* 2048-byte sectors -> segment */
+	add	%ax, 6(%si)		    /* Advance buffer pointer */
+
+	pushal
+	MSG(notification_step)
+	popal
+	cmp	$0, %bp
+	ja	1b
+	mov	8(%si), %eax		    /* Return next sector */
+	ret
+
+/*
+ * INT 13h with retry
+ */
+xint13:
+	movb	$6, ABS(RetryCount)
+	pushal
+.try:
+	int	$0x13
+	jc	1f
+	add	$(8*4), %sp		    /* Clean up stack */
+	ret
+1:
+	mov	%ah, %dl		    /* Save error code */
+	decb	ABS(RetryCount)
+	jz	.real_error
+	mov	ABS(RetryCount), %al
+	mov	ABS(dapa+2), %ah	    /* Sector transfer count */
+	cmp	$2, %al			    /* Only 2 attempts left */
+	ja	2f
+	mov	$1, %ah			    /* Drop transfer size to 1 */
+	jmp	.setmaxtr
+2:
+	cmp	$3, %al
+	ja	3f			    /* First time, just try again */
+	shr	$1, %ah			    /* Otherwise, try to reduce */
+	adc	$0, %ah			    /* the max transfer size, but not */
+.setmaxtr:
+	mov	%ah, ABS(MaxTransfer)
+	mov	%ah, ABS(dapa+2)
+3:
+	popal
+	jmp	.try
+
+.real_error:
+	MSG(read_error_string)
+	mov	%dl, %al
+	call	printhex2
+	popal
+	jmp	stop
+
+
+
+/*
+ * message: write the string pointed to by %si
+ *
+ *   WARNING: trashes %si, %ax, and %bx
+ */
+
+	/*
+	 * Use BIOS "int 10H Function 0Eh" to write character in teletype mode
+	 *	%ah = 0xe	%al = character
+	 *	%bh = page	%bl = foreground color (graphics modes)
+	 */
+1:
+	mov	$0x0001, %bx
+	mov	$0x0E, %ah
+	int	$0x10		/* display a byte */
+
+message:
+	lodsb
+	or	%al, %al
+	jne	1b		/* if not end of string, jmp to display */
+	ret
+
+/*
+ * printhex[248]: Write a hex number in (AL, AX, EAX) to the console
+ */
+printhex2:
+	pushal
+	rol	$24, %eax
+	mov	$2, %cx
+	jmp	1f
+printhex4:
+	pushal
+	rol	$16, %eax
+	mov	$4, %cx
+	jmp	1f
+printhex8:
+	pushal
+	mov	$8, %cx
+1:
+	rol	$4, %eax
+	push	%eax
+	and	$0x0F, %al
+	cmp	$10, %al
+	jae	.high
+.low:	add	$('0'), %al
+	jmp	2f
+.high:	add	$('A'-10), %al
+2:
+	mov	$0x0001, %bx
+	mov	$0x0E, %ah
+	int	$0x10		/* display a char */
+	pop	%eax
+	loop	1b
+	popal
+	ret
+
+/**************************************************************************/
+#ifdef STAGE1_5
+notification_string:	.string "Loading stage1.5 "
+#else
+notification_string:	.string "Loading stage2 "
+#endif
+
+notification_step:	.string "."
+notification_done:	.string "\r\n"
+
+read_error_string:	.string "Read error 0x"
+
+/*
+ * EBIOS disk address packet
+ */
+		.align 8
+dapa:		.byte 16		   /* Packet size */
+		.byte 0			   /* reserved */
+		.word 0			   /* +2 Block count */
+		.word 0			   /* +4 Offset of buffer */
+		.word 0			   /* +6 Segment of buffer */
+		.long 0			   /* +8 LBA (LSW) */
+		.long 0			   /* +C LBA (MSW) */
+
+VARIABLE(BootDrive)
+	.byte 0xFF
+VARIABLE(MaxTransfer)
+	.word 16			   /* Max sectors per transfer (32Kb) */
+VARIABLE(RetryCount)
+	.byte 0
+
+
+/*
+ *  This area is an empty space between the main body of code below which
+ *  grows up (fixed after compilation, but between releases it may change
+ *  in size easily), and the lists of sectors to read, which grows down
+ *  from a fixed top location.
+ */
+
+	.word 0
+	.word 0
+
+	. = _start + SECTOR_SIZE - BOOTSEC_LISTSIZE
+
+	/* fill the first data listing with the default */
+blocklist_default_start:/* this is the sector start parameter, in logical
+			   sectors from the start of the disk, sector 0 */
+	.long 0
+
+blocklist_default_len:	/* this is the number of sectors to read */
+#ifdef STAGE1_5
+	.word 0
+#else
+	.word (STAGE2_SIZE + ISO_SECTOR_SIZE - 1) >> ISO_SECTOR_BITS
+#endif
+blocklist_default_seg:	/* this is the segment of the starting address
+			   to load the data into */
+	.word (STAGE_ADDR + SECTOR_SIZE) >> 4
+
+firstlist:	/* this label has to be after the list data!!! */
diff --git a/stage2/term.h b/stage2/term.h
new file mode 100644
index 0000000..8261c7c
--- /dev/null
+++ b/stage2/term.h
@@ -0,0 +1,127 @@
+/* term.h - definitions for terminal handling */
+/*
+ *  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 GRUB_TERM_HEADER
+#define GRUB_TERM_HEADER	1
+
+/* These are used to represent the various color states we use */
+typedef enum
+{
+  /* represents the color used to display all text that does not use the user
+   * defined colors below
+   */
+  COLOR_STATE_STANDARD,
+  /* represents the user defined colors for normal text */
+  COLOR_STATE_NORMAL,
+  /* represents the user defined colors for highlighted text */
+  COLOR_STATE_HIGHLIGHT
+} color_state;
+
+#ifndef STAGE1_5
+
+/* Flags for representing the capabilities of a terminal.  */
+/* Some notes about the flags:
+   - These flags are used by higher-level functions but not terminals
+   themselves.
+   - If a terminal is dumb, you may assume that only putchar, getkey and
+   checkkey are called.
+   - Some fancy features (nocursor, setcolor, and highlight) can be set to
+   NULL.  */
+
+/* Set when input characters shouldn't be echoed back.  */
+#define TERM_NO_ECHO		(1 << 0)
+/* Set when the editing feature should be disabled.  */
+#define TERM_NO_EDIT		(1 << 1)
+/* Set when the terminal cannot do fancy things.  */
+#define TERM_DUMB		(1 << 2)
+/* Set when the terminal needs to be initialized.  */
+#define TERM_NEED_INIT		(1 << 16)
+
+struct term_entry
+{
+  /* The name of a terminal.  */
+  const char *name;
+  /* The feature flags defined above.  */
+  unsigned long flags;
+  /* Put a character.  */
+  void (*putchar) (int c);
+  /* Check if any input character is available.  */
+  int (*checkkey) (void);
+  /* Get a character.  */
+  int (*getkey) (void);
+  /* Get the cursor position. The return value is ((X << 8) | Y).  */
+  int (*getxy) (void);
+  /* Go to the position (X, Y).  */
+  void (*gotoxy) (int x, int y);
+  /* Clear the screen.  */
+  void (*cls) (void);
+  /* Set the current color to be used */
+  void (*setcolorstate) (color_state state);
+  /* Set the normal color and the highlight color. The format of each
+     color is VGA's.  */
+  void (*setcolor) (int normal_color, int highlight_color);
+  /* Turn on/off the cursor.  */
+  int (*setcursor) (int on);
+};
+
+/* This lists up available terminals.  */
+extern struct term_entry term_table[];
+/* This points to the current terminal. This is useful, because only
+   a single terminal is enabled normally.  */
+extern struct term_entry *current_term;
+
+#endif /* ! STAGE1_5 */
+
+/* The console stuff.  */
+extern int console_current_color;
+void console_putchar (int c);
+
+#ifndef STAGE1_5
+int console_checkkey (void);
+int console_getkey (void);
+int console_getxy (void);
+void console_gotoxy (int x, int y);
+void console_cls (void);
+void console_setcolorstate (color_state state);
+void console_setcolor (int normal_color, int highlight_color);
+int console_setcursor (int on);
+#endif
+
+#ifdef SUPPORT_SERIAL
+void serial_putchar (int c);
+int serial_checkkey (void);
+int serial_getkey (void);
+int serial_getxy (void);
+void serial_gotoxy (int x, int y);
+void serial_cls (void);
+void serial_setcolorstate (color_state state);
+#endif
+
+#ifdef SUPPORT_HERCULES
+void hercules_putchar (int c);
+int hercules_getxy (void);
+void hercules_gotoxy (int x, int y);
+void hercules_cls (void);
+void hercules_setcolorstate (color_state state);
+void hercules_setcolor (int normal_color, int highlight_color);
+int hercules_setcursor (int on);
+#endif
+
+#endif /* ! GRUB_TERM_HEADER */
diff --git a/stage2/terminfo.c b/stage2/terminfo.c
new file mode 100644
index 0000000..c1c1575
--- /dev/null
+++ b/stage2/terminfo.c
@@ -0,0 +1,258 @@
+/* terminfo.c - read a terminfo entry from the command line */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2002,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 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.
+ *
+ * ######################################################################
+ *
+ * This file contains various functions dealing with different 
+ * terminal capabilities. It knows the difference between a vt52 and vt100 
+ * terminal (and much more) and is mainly used the terminal emulation
+ * in the serial driver.
+ */
+
+#include <shared.h>
+#include "terminfo.h"
+#include "tparm.h"
+#include "serial.h"
+
+/* Current terminal capabilities. Default is "vt100".  */
+struct terminfo term =
+  {
+    .name                = "vt100",
+    .cursor_address      = "\e[%i%p1%d;%p2%dH",
+    .clear_screen        = "\e[H\e[J",
+    .enter_standout_mode = "\e[7m",
+    .exit_standout_mode  = "\e[m"
+  };
+
+/* A number of escape sequences are provided in the string valued
+   capabilities for easy encoding of characters there.  Both \E and \e
+   map to an ESCAPE character, ^x maps to a control-x for any
+   appropriate x, and the sequences \n \l \r \t \b \f \s give a
+   newline, line-feed, return, tab, backspace, form-feed, and space.
+   Other escapes include \^ for ^, \\ for \, \, for comma, \: for :,
+   and \0 for null.  (\0 will produce \200, which does not terminate a
+   string but behaves as a null character on most terminals, provid­
+   ing CS7 is specified.  See stty(1).)  Finally, characters may be
+   given as three octal digits after a \.  */
+
+char *
+ti_unescape_memory (const char *in, const char *end) 
+{
+  static char out_buffer[256];
+  char c;
+  char *out;
+
+  out = out_buffer;
+  do
+    {
+      c = *(in++);
+      switch (c) 
+	{
+	case '^':
+	  if (*in >= 'A' && *in <= 'Z')
+	    {
+	      *out = (*in) - 'A';
+	      in++;
+	    }
+	  else
+	    {
+	      *out = '^';
+	    }
+	  break;
+	case '\\':
+	  c = *(in++);
+	  if (c >= '0' && c <= '9')
+	    {
+	      // octal number
+	      int n = 0;
+	      do
+		{
+		  n = (n << 4) | (c - '0');
+		  c = *(in++);
+		}
+	      while (c >= '0' && c <= '9');
+	      
+	      *out++ = (char)(n & 0xff);
+	      
+	      // redo last character
+	      in--;
+	      
+	      break;
+	    } 
+
+	  switch (c) 
+	    {
+	    case 'e':
+	    case 'E':
+	      *out++ = '\e';
+	      break;
+	    case 'n':
+	      *out++ = '\n';
+	      break;
+	    case 'r':
+	      *out++ = '\r';
+	      break;
+	    case 't':
+	      *out++ = '\t';
+	      break;
+	    case 'b':
+	      *out++ = '\b';
+	      break;
+	    case 'f':
+	      *out++ = '\f';
+	      break;
+	    case 's':
+	      *out++ = ' ';
+	      break;
+	    case '\\':
+	      *out++ = '\\';
+	      break;
+	    case '^':
+	      *out++ = '^';
+	      break;
+	    case ',':
+	      *out++ = ',';
+	      break;
+	    case ':':
+	      *out++ = ':';
+	      break;
+	    case '0':
+	      *out++ = '\200';
+	      break;
+	    }
+	  break;
+	default:
+	  *out++ = c;
+	  break;
+	}
+    }
+  while (in <= end);
+  
+  return out_buffer;
+}
+
+char *
+ti_unescape_string (const char *in) 
+{
+  return ti_unescape_memory (in, in + grub_strlen (in));
+}
+
+/* convert a memory region containing binary character into an external
+ * ascii representation. The binary characters will be replaced by an
+ * "ecsape notation". E.g. "033" will become "\e". */
+char *
+ti_escape_memory (const char *in, const char *end) 
+{
+  static char out_buffer[256];
+  char c;
+  char *out;
+
+  out = out_buffer;
+  do
+    {
+      c = *(in++);
+      switch (c)
+	{
+	case '\e':
+	  *out++ = '\\'; *out++ = 'e'; break;
+	case ' ':
+	  *out++ = '\\'; *out++ = 's'; break;
+	case '\\':
+	  *out++ = '\\'; *out++ = '\\'; break;
+	case '0' ... '9':
+	case 'a' ... 'z':
+	case 'A' ... 'Z':
+	case '%':
+	case '+':
+	case '-':
+	case '*':
+	case '/':
+	case ';':
+	case ':':
+	case '{':
+	case '}':
+	case '[':
+	case ']':
+	  *out++ = c; break;
+	case 0 ... 25:
+	  *out++ = '^'; *out++ = 'A' + c; break;
+	default:
+	  *out++ = '\\'; 
+	  *out++ = ((c >> 8) & 7) + '0';
+	  *out++ = ((c >> 4) & 7) + '0';
+	  *out++ = ((c >> 0) & 7) + '0';
+	  break;
+	}
+    }
+  while (in < end);
+  
+  *out++ = 0;
+  
+  return out_buffer;
+}
+
+/* convert a string containing binary character into an external ascii
+ * representation. */
+char *
+ti_escape_string (const char *in) 
+{
+  return ti_escape_memory (in, in + grub_strlen (in));
+}
+
+/* move the cursor to the given position starting with "0". */
+void
+ti_cursor_address (int x, int y)
+{
+  grub_putstr (grub_tparm (term.cursor_address, y, x));
+}
+
+/* clear the screen. */
+void 
+ti_clear_screen (void)
+{
+  grub_putstr (grub_tparm (term.clear_screen));
+}
+
+/* enter reverse video */
+void 
+ti_enter_standout_mode (void)
+{
+  grub_putstr (grub_tparm (term.enter_standout_mode));
+}
+
+/* exit reverse video */
+void 
+ti_exit_standout_mode (void)
+{
+  grub_putstr (grub_tparm (term.exit_standout_mode));
+}
+
+/* set the current terminal emulation to use */
+void 
+ti_set_term (const struct terminfo *new)
+{
+  grub_memmove (&term, new, sizeof (struct terminfo));
+}
+
+/* get the current terminal emulation */
+void
+ti_get_term(struct terminfo *copy)
+{
+  grub_memmove (copy, &term, sizeof (struct terminfo));
+}
diff --git a/stage2/terminfo.h b/stage2/terminfo.h
new file mode 100644
index 0000000..2e59761
--- /dev/null
+++ b/stage2/terminfo.h
@@ -0,0 +1,51 @@
+/* terminfo.h - read a terminfo entry from the command line */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 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 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 GRUB_TERMCAP_HEADER
+#define GRUB_TERMCAP_HEADER	1
+
+#define TERMINFO_LEN 40
+
+typedef struct terminfo
+{
+  char name[TERMINFO_LEN];
+  char cursor_address[TERMINFO_LEN];
+  char clear_screen[TERMINFO_LEN];
+  char enter_standout_mode[TERMINFO_LEN];
+  char exit_standout_mode[TERMINFO_LEN];
+}
+terminfo;
+
+
+/* Function prototypes.  */
+char *ti_escape_memory (const char *in, const char *end);
+char *ti_escape_string (const char *in);
+char *ti_unescape_memory (const char *in, const char *end);
+char *ti_unescape_string (const char *in);
+
+void ti_set_term (const struct terminfo *new);
+void ti_get_term (struct terminfo *copy);
+
+void ti_cursor_address (int x, int y);
+void ti_clear_screen (void);
+void ti_enter_standout_mode (void);
+void ti_exit_standout_mode (void);
+
+#endif /* ! GRUB_TERMCAP_HEADER */
diff --git a/stage2/tparm.c b/stage2/tparm.c
new file mode 100644
index 0000000..ff78d53
--- /dev/null
+++ b/stage2/tparm.c
@@ -0,0 +1,726 @@
+/****************************************************************************
+ * Copyright (c) 1998,2000,2002 Free Software Foundation, Inc.              *
+ *                                                                          *
+ * Permission is hereby granted, free of charge, to any person obtaining a  *
+ * copy of this software and associated documentation files (the            *
+ * "Software"), to deal in the Software without restriction, including      *
+ * without limitation the rights to use, copy, modify, merge, publish,      *
+ * distribute, distribute with modifications, sublicense, and/or sell       *
+ * copies of the Software, and to permit persons to whom the Software is    *
+ * furnished to do so, subject to the following conditions:                 *
+ *                                                                          *
+ * The above copyright notice and this permission notice shall be included  *
+ * in all copies or substantial portions of the Software.                   *
+ *                                                                          *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
+ * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
+ * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
+ *                                                                          *
+ * Except as contained in this notice, the name(s) of the above copyright   *
+ * holders shall not be used in advertising or otherwise to promote the     *
+ * sale, use or other dealings in this Software without prior written       *
+ * authorization.                                                           *
+ ****************************************************************************/
+
+/**********************************************************************
+ * This code is a modification of lib_tparm.c found in ncurses-5.2. The
+ * modification are for use in grub by replacing all libc function through
+ * special grub functions. This also meant to delete all dynamic memory
+ * allocation and replace it by a number of fixed buffers.
+ *
+ * Modifications by Tilmann Bubeck <t.bubeck@reinform.de> 2002
+ **********************************************************************/
+
+/****************************************************************************
+ *  Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995               *
+ *     and: Eric S. Raymond <esr@snark.thyrsus.com>                         *
+ ****************************************************************************/
+
+/*
+ *	tparm.c
+ *
+ */
+
+#include "shared.h"
+
+#include "tparm.h"
+
+/*
+ * Common/troublesome character definitions
+ */
+typedef char grub_bool;
+#define isdigit(c) ((c) >= '0' && (c) <= '9')
+#ifndef FALSE
+# define FALSE (0)
+#endif
+#ifndef TRUE
+# define TRUE (!FALSE)
+#endif
+#define MAX_FORMAT_LEN 256
+#define max(a,b) ((a) > (b) ? (a) : (b))
+
+//MODULE_ID("$Id: tparm.c,v 1.1 2002/11/29 20:39:24 okuji Exp $")
+
+/*
+ *	char *
+ *	tparm(string, ...)
+ *
+ *	Substitute the given parameters into the given string by the following
+ *	rules (taken from terminfo(5)):
+ *
+ *	     Cursor addressing and other strings  requiring  parame-
+ *	ters in the terminal are described by a parameterized string
+ *	capability, with like escapes %x in  it.   For  example,  to
+ *	address  the  cursor, the cup capability is given, using two
+ *	parameters: the row and column to  address  to.   (Rows  and
+ *	columns  are  numbered  from  zero and refer to the physical
+ *	screen visible to the user, not to any  unseen  memory.)  If
+ *	the terminal has memory relative cursor addressing, that can
+ *	be indicated by
+ *
+ *	     The parameter mechanism uses  a  stack  and  special  %
+ *	codes  to manipulate it.  Typically a sequence will push one
+ *	of the parameters onto the stack and then print it  in  some
+ *	format.  Often more complex operations are necessary.
+ *
+ *	     The % encodings have the following meanings:
+ *
+ *	     %%        outputs `%'
+ *	     %c        print pop() like %c in printf()
+ *	     %s        print pop() like %s in printf()
+ *           %[[:]flags][width[.precision]][doxXs]
+ *                     as in printf, flags are [-+#] and space
+ *                     The ':' is used to avoid making %+ or %-
+ *                     patterns (see below).
+ *
+ *	     %p[1-9]   push ith parm
+ *	     %P[a-z]   set dynamic variable [a-z] to pop()
+ *	     %g[a-z]   get dynamic variable [a-z] and push it
+ *	     %P[A-Z]   set static variable [A-Z] to pop()
+ *	     %g[A-Z]   get static variable [A-Z] and push it
+ *	     %l        push strlen(pop)
+ *	     %'c'      push char constant c
+ *	     %{nn}     push integer constant nn
+ *
+ *	     %+ %- %* %/ %m
+ *	               arithmetic (%m is mod): push(pop() op pop())
+ *	     %& %| %^  bit operations: push(pop() op pop())
+ *	     %= %> %<  logical operations: push(pop() op pop())
+ *	     %A %O     logical and & or operations for conditionals
+ *	     %! %~     unary operations push(op pop())
+ *	     %i        add 1 to first two parms (for ANSI terminals)
+ *
+ *	     %? expr %t thenpart %e elsepart %;
+ *	               if-then-else, %e elsepart is optional.
+ *	               else-if's are possible ala Algol 68:
+ *	               %? c1 %t b1 %e c2 %t b2 %e c3 %t b3 %e c4 %t b4 %e b5 %;
+ *
+ *	For those of the above operators which are binary and not commutative,
+ *	the stack works in the usual way, with
+ *			%gx %gy %m
+ *	resulting in x mod y, not the reverse.
+ */
+
+#define STACKSIZE	20
+
+typedef struct {
+    union {
+	unsigned int num;
+	char *str;
+    } data;
+    grub_bool num_type;
+} stack_frame;
+
+static stack_frame stack[STACKSIZE];
+static int stack_ptr;
+
+static char out_buff[256];
+static int out_size = 256;
+static int out_used;
+
+static inline void
+get_space(int need)
+{
+    need += out_used;
+    if (need > out_size) {
+	// FIX ME! buffer full, what now?
+	;
+    }
+}
+
+static inline void
+save_text(const char *fmt, const char *s, int len)
+{
+    int s_len = grub_strlen(s);
+    if (len > (int) s_len)
+	s_len = len;
+
+    get_space(s_len + 1);
+
+    (void) grub_sprintf(out_buff + out_used, fmt, s);
+    out_used += grub_strlen(out_buff + out_used);
+}
+
+static inline void
+save_number(const char *fmt, int number, int len)
+{
+    if (len < 30)
+	len = 30;		/* actually log10(MAX_INT)+1 */
+
+    get_space(len + 1);
+
+    (void) grub_sprintf(out_buff + out_used, fmt, number);
+    out_used += grub_strlen(out_buff + out_used);
+}
+
+static inline void
+save_char(int c)
+{
+    if (c == 0)
+	c = 0200;
+    get_space(1);
+    out_buff[out_used++] = c;
+}
+
+static inline void
+npush(int x)
+{
+    if (stack_ptr < STACKSIZE) {
+	stack[stack_ptr].num_type = TRUE;
+	stack[stack_ptr].data.num = x;
+	stack_ptr++;
+    }
+}
+
+static inline int
+npop(void)
+{
+    int result = 0;
+    if (stack_ptr > 0) {
+	stack_ptr--;
+	if (stack[stack_ptr].num_type)
+	    result = stack[stack_ptr].data.num;
+    }
+    return result;
+}
+
+static inline void
+spush(char *x)
+{
+    if (stack_ptr < STACKSIZE) {
+	stack[stack_ptr].num_type = FALSE;
+	stack[stack_ptr].data.str = x;
+	stack_ptr++;
+    }
+}
+
+static inline char *
+spop(void)
+{
+    static char dummy[] = "";	/* avoid const-cast */
+    char *result = dummy;
+    if (stack_ptr > 0) {
+	stack_ptr--;
+	if (!stack[stack_ptr].num_type && stack[stack_ptr].data.str != 0)
+	    result = stack[stack_ptr].data.str;
+    }
+    return result;
+}
+
+static inline const char *
+parse_format(const char *s, char *format, int *len)
+{
+    grub_bool done = FALSE;
+    grub_bool allowminus = FALSE;
+    grub_bool dot = FALSE;
+    grub_bool err = FALSE;
+    char *fmt = format;
+    int prec = 0;
+    int width = 0;
+    int value = 0;
+
+    *len = 0;
+    *format++ = '%';
+    while (*s != '\0' && !done) {
+	switch (*s) {
+	case 'c':		/* FALLTHRU */
+	case 'd':		/* FALLTHRU */
+	case 'o':		/* FALLTHRU */
+	case 'x':		/* FALLTHRU */
+	case 'X':		/* FALLTHRU */
+	case 's':
+	    *format++ = *s;
+	    done = TRUE;
+	    break;
+	case '.':
+	    *format++ = *s++;
+	    if (dot) {
+		err = TRUE;
+	    } else {
+		dot = TRUE;
+		prec = value;
+	    }
+	    value = 0;
+	    break;
+	case '#':
+	    *format++ = *s++;
+	    break;
+	case ' ':
+	    *format++ = *s++;
+	    break;
+	case ':':
+	    s++;
+	    allowminus = TRUE;
+	    break;
+	case '-':
+	    if (allowminus) {
+		*format++ = *s++;
+	    } else {
+		done = TRUE;
+	    }
+	    break;
+	default:
+	    if (isdigit(*s)) {
+		value = (value * 10) + (*s - '0');
+		if (value > 10000)
+		    err = TRUE;
+		*format++ = *s++;
+	    } else {
+		done = TRUE;
+	    }
+	}
+    }
+
+    /*
+     * If we found an error, ignore (and remove) the flags.
+     */
+    if (err) {
+	prec = width = value = 0;
+	format = fmt;
+	*format++ = '%';
+	*format++ = *s;
+    }
+
+    if (dot)
+	width = value;
+    else
+	prec = value;
+
+    *format = '\0';
+    /* return maximum string length in print */
+    *len = (prec > width) ? prec : width;
+    return s;
+}
+
+#define isUPPER(c) ((c) >= 'A' && (c) <= 'Z')
+#define isLOWER(c) ((c) >= 'a' && (c) <= 'z')
+
+static inline char *
+tparam_internal(const char *string, int *dataptr)
+{
+#define NUM_VARS 26
+    char *p_is_s[9];
+    int param[9];
+    int lastpop;
+    int popcount;
+    int number;
+    int len;
+    int level;
+    int x, y;
+    int i;
+    int len2;
+    register const char *cp;
+    static int len_fmt = MAX_FORMAT_LEN;
+    static char dummy[] = "";
+    static char format[MAX_FORMAT_LEN];
+    static int dynamic_var[NUM_VARS];
+    static int static_vars[NUM_VARS];
+
+    out_used = 0;
+    if (string == NULL)
+	return NULL;
+
+    if ((len2 = grub_strlen(string)) > len_fmt) {
+	return NULL;
+    }
+
+    /*
+     * Find the highest parameter-number referred to in the format string.
+     * Use this value to limit the number of arguments copied from the
+     * variable-length argument list.
+     */
+
+    number = 0;
+    lastpop = -1;
+    popcount = 0;
+    grub_memset(p_is_s, 0, sizeof(p_is_s));
+
+    /*
+     * Analyze the string to see how many parameters we need from the varargs
+     * list, and what their types are.  We will only accept string parameters
+     * if they appear as a %l or %s format following an explicit parameter
+     * reference (e.g., %p2%s).  All other parameters are numbers.
+     *
+     * 'number' counts coarsely the number of pop's we see in the string, and
+     * 'popcount' shows the highest parameter number in the string.  We would
+     * like to simply use the latter count, but if we are reading termcap
+     * strings, there may be cases that we cannot see the explicit parameter
+     * numbers.
+     */
+    for (cp = string; (cp - string) < (int) len2;) {
+	if (*cp == '%') {
+	    cp++;
+	    cp = parse_format(cp, format, &len);
+	    switch (*cp) {
+	    default:
+		break;
+
+	    case 'd':		/* FALLTHRU */
+	    case 'o':		/* FALLTHRU */
+	    case 'x':		/* FALLTHRU */
+	    case 'X':		/* FALLTHRU */
+	    case 'c':		/* FALLTHRU */
+		number++;
+		lastpop = -1;
+		break;
+
+	    case 'l':
+	    case 's':
+		if (lastpop > 0)
+		    p_is_s[lastpop - 1] = dummy;
+		++number;
+		break;
+
+	    case 'p':
+		cp++;
+		i = (*cp - '0');
+		if (i >= 0 && i <= 9) {
+		    lastpop = i;
+		    if (lastpop > popcount)
+			popcount = lastpop;
+		}
+		break;
+
+	    case 'P':
+	    case 'g':
+		cp++;
+		break;
+
+	    case '\'':
+		cp += 2;
+		lastpop = -1;
+		break;
+
+	    case '{':
+		cp++;
+		while (*cp >= '0' && *cp <= '9') {
+		    cp++;
+		}
+		break;
+
+	    case '+':
+	    case '-':
+	    case '*':
+	    case '/':
+	    case 'm':
+	    case 'A':
+	    case 'O':
+	    case '&':
+	    case '|':
+	    case '^':
+	    case '=':
+	    case '<':
+	    case '>':
+	    case '!':
+	    case '~':
+		lastpop = -1;
+		number += 2;
+		break;
+
+	    case 'i':
+		lastpop = -1;
+		if (popcount < 2)
+		    popcount = 2;
+		break;
+	    }
+	}
+	if (*cp != '\0')
+	    cp++;
+    }
+
+    if (number > 9)
+	number = 9;
+    for (i = 0; i < max(popcount, number); i++) {
+	/*
+	 * A few caps (such as plab_norm) have string-valued parms.
+	 * We'll have to assume that the caller knows the difference, since
+	 * a char* and an int may not be the same size on the stack.
+	 */
+	if (p_is_s[i] != 0) {
+	  p_is_s[i] = (char *)(*(dataptr++));
+	} else {
+	  param[i] = (int)(*(dataptr++));
+	}
+    }
+
+    /*
+     * This is a termcap compatibility hack.  If there are no explicit pop
+     * operations in the string, load the stack in such a way that
+     * successive pops will grab successive parameters.  That will make
+     * the expansion of (for example) \E[%d;%dH work correctly in termcap
+     * style, which means tparam() will expand termcap strings OK.
+     */
+    stack_ptr = 0;
+    if (popcount == 0) {
+	popcount = number;
+	for (i = number - 1; i >= 0; i--)
+	    npush(param[i]);
+    }
+
+    while (*string) {
+        /* skip delay timings */
+	if (*string == '$' && *(string + 1) == '<') {
+	    while( *string && *string != '>') 
+	        string++;
+	    if ( *string == '>' ) string++;
+	} else if ( *string == '%') {
+	    string++;
+	    string = parse_format(string, format, &len);
+	    switch (*string) {
+	    default:
+		break;
+	    case '%':
+		save_char('%');
+		break;
+
+	    case 'd':		/* FALLTHRU */
+	    case 'o':		/* FALLTHRU */
+	    case 'x':		/* FALLTHRU */
+	    case 'X':		/* FALLTHRU */
+	    case 'c':		/* FALLTHRU */
+		save_number(format, npop(), len);
+		break;
+
+	    case 'l':
+		save_number("%d", strlen(spop()), 0);
+		break;
+
+	    case 's':
+		save_text(format, spop(), len);
+		break;
+
+	    case 'p':
+		string++;
+		i = (*string - '1');
+		if (i >= 0 && i < 9) {
+		    if (p_is_s[i])
+			spush(p_is_s[i]);
+		    else
+			npush(param[i]);
+		}
+		break;
+
+	    case 'P':
+		string++;
+		if (isUPPER(*string)) {
+		    i = (*string - 'A');
+		    static_vars[i] = npop();
+		} else if (isLOWER(*string)) {
+		    i = (*string - 'a');
+		    dynamic_var[i] = npop();
+		}
+		break;
+
+	    case 'g':
+		string++;
+		if (isUPPER(*string)) {
+		    i = (*string - 'A');
+		    npush(static_vars[i]);
+		} else if (isLOWER(*string)) {
+		    i = (*string - 'a');
+		    npush(dynamic_var[i]);
+		}
+		break;
+
+	    case '\'':
+		string++;
+		npush(*string);
+		string++;
+		break;
+
+	    case '{':
+		number = 0;
+		string++;
+		while (*string >= '0' && *string <= '9') {
+		    number = number * 10 + *string - '0';
+		    string++;
+		}
+		npush(number);
+		break;
+
+	    case '+':
+		npush(npop() + npop());
+		break;
+
+	    case '-':
+		y = npop();
+		x = npop();
+		npush(x - y);
+		break;
+
+	    case '*':
+		npush(npop() * npop());
+		break;
+
+	    case '/':
+		y = npop();
+		x = npop();
+		npush(y ? (x / y) : 0);
+		break;
+
+	    case 'm':
+		y = npop();
+		x = npop();
+		npush(y ? (x % y) : 0);
+		break;
+
+	    case 'A':
+		npush(npop() && npop());
+		break;
+
+	    case 'O':
+		npush(npop() || npop());
+		break;
+
+	    case '&':
+		npush(npop() & npop());
+		break;
+
+	    case '|':
+		npush(npop() | npop());
+		break;
+
+	    case '^':
+		npush(npop() ^ npop());
+		break;
+
+	    case '=':
+		y = npop();
+		x = npop();
+		npush(x == y);
+		break;
+
+	    case '<':
+		y = npop();
+		x = npop();
+		npush(x < y);
+		break;
+
+	    case '>':
+		y = npop();
+		x = npop();
+		npush(x > y);
+		break;
+
+	    case '!':
+		npush(!npop());
+		break;
+
+	    case '~':
+		npush(~npop());
+		break;
+
+	    case 'i':
+		if (p_is_s[0] == 0)
+		    param[0]++;
+		if (p_is_s[1] == 0)
+		    param[1]++;
+		break;
+
+	    case '?':
+		break;
+
+	    case 't':
+		x = npop();
+		if (!x) {
+		    /* scan forward for %e or %; at level zero */
+		    string++;
+		    level = 0;
+		    while (*string) {
+			if (*string == '%') {
+			    string++;
+			    if (*string == '?')
+				level++;
+			    else if (*string == ';') {
+				if (level > 0)
+				    level--;
+				else
+				    break;
+			    } else if (*string == 'e' && level == 0)
+				break;
+			}
+
+			if (*string)
+			    string++;
+		    }
+		}
+		break;
+
+	    case 'e':
+		/* scan forward for a %; at level zero */
+		string++;
+		level = 0;
+		while (*string) {
+		    if (*string == '%') {
+			string++;
+			if (*string == '?')
+			    level++;
+			else if (*string == ';') {
+			    if (level > 0)
+				level--;
+			    else
+				break;
+			}
+		    }
+
+		    if (*string)
+			string++;
+		}
+		break;
+
+	    case ';':
+		break;
+
+	    }			/* endswitch (*string) */
+	} else {             	/* endelse (*string == '%') */
+	    save_char(*string);
+	}
+
+	if (*string == '\0')
+	    break;
+
+	string++;
+    }				/* endwhile (*string) */
+
+    get_space(1);
+    out_buff[out_used] = '\0';
+
+    return (out_buff);
+}
+
+char *
+grub_tparm(const char *string,...)
+{
+    char *result;
+    int *dataptr = (int *) &string;
+
+    dataptr++;
+
+    result = tparam_internal(string, dataptr);
+
+    return result;
+}
diff --git a/stage2/tparm.h b/stage2/tparm.h
new file mode 100644
index 0000000..e2c1b68
--- /dev/null
+++ b/stage2/tparm.h
@@ -0,0 +1,28 @@
+/* tparm.h - parameter formatting of terminfo */
+/*
+ *  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 GRUB_TPARM_HEADER
+#define GRUB_TPARM_HEADER	1
+
+
+/* Function prototypes.  */
+char *grub_tparm (const char *string, ...);
+
+#endif /* ! GRUB_TERMCAP_HEADER */
diff --git a/stage2/ufs2.h b/stage2/ufs2.h
new file mode 100644
index 0000000..ba2ef30
--- /dev/null
+++ b/stage2/ufs2.h
@@ -0,0 +1,439 @@
+/*
+ * Copyright (C) 2004 Free Software Foundation, Inc.
+ * Copyright (c) 2002 Networks Associates Technology, Inc.
+ * All rights reserved.
+ *
+ * This software was developed for the FreeBSD Project by Marshall
+ * Kirk McKusick and Network Associates Laboratories, the Security
+ * Research Division of Network Associates, Inc. under DARPA/SPAWAR
+ * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
+ * research program
+ *
+ * Copyright (c) 1982, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The names of the authors may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)dinode.h	8.3 (Berkeley) 1/21/94
+ * $FreeBSD: src/sys/ufs/ufs/dinode.h,v 1.11 2002/07/16 22:36:00 mckusick Exp $
+ */
+
+#ifndef _GRUB_UFS2_H_
+#define _GRUB_UFS2_H_
+
+typedef signed char            grub_int8_t;
+typedef signed short           grub_int16_t;
+typedef signed int             grub_int32_t;
+typedef signed long long int   grub_int64_t;
+typedef unsigned char          grub_uint8_t;
+typedef unsigned short         grub_uint16_t;
+typedef unsigned int           grub_uint32_t;
+typedef unsigned long long int grub_uint64_t;
+
+typedef grub_uint8_t                grub_u_char;
+typedef grub_uint32_t               grub_u_int;
+
+typedef grub_uint8_t                grub_u_int8_t;
+typedef grub_uint16_t               grub_u_int16_t;
+typedef grub_uint32_t               grub_u_int32_t;
+typedef grub_uint64_t               grub_u_int64_t;
+
+#define i_size di_size
+
+
+#define DEV_BSIZE 512
+
+/*
+ * The root inode is the root of the filesystem.  Inode 0 can't be used for
+ * normal purposes and historically bad blocks were linked to inode 1, thus
+ * the root inode is 2.  (Inode 1 is no longer used for this purpose, however
+ * numerous dump tapes make this assumption, so we are stuck with it).
+ */
+#define	ROOTINO	((grub_ino_t)2)
+
+/*
+ * The size of physical and logical block numbers and time fields in UFS.
+ */
+typedef grub_int32_t ufs1_daddr_t;
+typedef	grub_int64_t	ufs2_daddr_t;
+typedef grub_int64_t ufs_lbn_t;
+typedef grub_int64_t ufs_time_t;
+
+/* inode number */
+typedef grub_uint32_t      grub_ino_t;
+
+/* File permissions. */
+#define	IEXEC		0000100		/* Executable. */
+#define	IWRITE		0000200		/* Writeable. */
+#define	IREAD		0000400		/* Readable. */
+#define	ISVTX		0001000		/* Sticky bit. */
+#define	ISGID		0002000		/* Set-gid. */
+#define	ISUID		0004000		/* Set-uid. */
+
+/* File types. */
+#define	IFMT		0170000		/* Mask of file type. */
+#define	IFIFO		0010000		/* Named pipe (fifo). */
+#define	IFCHR		0020000		/* Character device. */
+#define	IFDIR		0040000		/* Directory file. */
+#define	IFBLK		0060000		/* Block device. */
+#define	IFREG		0100000		/* Regular file. */
+#define	IFLNK		0120000		/* Symbolic link. */
+#define	IFSOCK		0140000		/* UNIX domain socket. */
+#define	IFWHT		0160000		/* Whiteout. */
+
+/*
+ * A dinode contains all the meta-data associated with a UFS2 file.
+ * This structure defines the on-disk format of a dinode. Since
+ * this structure describes an on-disk structure, all its fields
+ * are defined by types with precise widths.
+ */
+
+#define	NXADDR	2			/* External addresses in inode. */
+#define	NDADDR	12			/* Direct addresses in inode. */
+#define	NIADDR	3			/* Indirect addresses in inode. */
+
+struct ufs1_dinode {
+	grub_u_int16_t       di_mode;        /*   0: IFMT, permissions; see below. */
+	grub_int16_t         di_nlink;       /*   2: File link count. */
+	union {
+		grub_u_int16_t oldids[2];    /*   4: Ffs: old user and group ids. */
+	} di_u;
+	grub_u_int64_t       di_size;        /*   8: File byte count. */
+	grub_int32_t         di_atime;       /*  16: Last access time. */
+	grub_int32_t         di_atimensec;   /*  20: Last access time. */
+	grub_int32_t         di_mtime;       /*  24: Last modified time. */
+	grub_int32_t         di_mtimensec;   /*  28: Last modified time. */
+	grub_int32_t         di_ctime;       /*  32: Last inode change time. */
+	grub_int32_t         di_ctimensec;   /*  36: Last inode change time. */
+	ufs1_daddr_t    di_db[NDADDR];  /*  40: Direct disk blocks. */
+	ufs1_daddr_t    di_ib[NIADDR];  /*  88: Indirect disk blocks. */
+	grub_u_int32_t       di_flags;       /* 100: Status flags (chflags). */
+	grub_int32_t         di_blocks;      /* 104: Blocks actually held. */
+	grub_int32_t         di_gen;         /* 108: Generation number. */
+	grub_u_int32_t       di_uid;         /* 112: File owner. */
+	grub_u_int32_t       di_gid;         /* 116: File group. */
+	grub_int32_t         di_spare[2];    /* 120: Reserved; currently unused */
+};
+
+struct ufs2_dinode {
+	grub_u_int16_t	di_mode;	/*   0: IFMT, permissions; see below. */
+	grub_int16_t		di_nlink;	/*   2: File link count. */
+	grub_u_int32_t	di_uid;		/*   4: File owner. */
+	grub_u_int32_t	di_gid;		/*   8: File group. */
+	grub_u_int32_t	di_blksize;	/*  12: Inode blocksize. */
+	grub_u_int64_t	di_size;	/*  16: File byte count. */
+	grub_u_int64_t	di_blocks;	/*  24: Bytes actually held. */
+	ufs_time_t	di_atime;	/*  32: Last access time. */
+	ufs_time_t	di_mtime;	/*  40: Last modified time. */
+	ufs_time_t	di_ctime;	/*  48: Last inode change time. */
+	ufs_time_t	di_birthtime;	/*  56: Inode creation time. */
+	grub_int32_t		di_mtimensec;	/*  64: Last modified time. */
+	grub_int32_t		di_atimensec;	/*  68: Last access time. */
+	grub_int32_t		di_ctimensec;	/*  72: Last inode change time. */
+	grub_int32_t		di_birthnsec;	/*  76: Inode creation time. */
+	grub_int32_t		di_gen;		/*  80: Generation number. */
+	grub_u_int32_t	di_kernflags;	/*  84: Kernel flags. */
+	grub_u_int32_t	di_flags;	/*  88: Status flags (chflags). */
+	grub_int32_t		di_extsize;	/*  92: External attributes block. */
+	ufs2_daddr_t	di_extb[NXADDR];/*  96: External attributes block. */
+	ufs2_daddr_t	di_db[NDADDR];	/* 112: Direct disk blocks. */
+	ufs2_daddr_t	di_ib[NIADDR];	/* 208: Indirect disk blocks. */
+	grub_int64_t		di_spare[3];	/* 232: Reserved; currently unused */
+};
+
+#define	MAXNAMLEN	255
+
+struct	direct {
+	grub_u_int32_t d_ino;		/* inode number of entry */
+	grub_u_int16_t d_reclen;		/* length of this record */
+	grub_u_int8_t  d_type; 		/* file type, see below */
+	grub_u_int8_t  d_namlen;		/* length of string in d_name */
+	char	  d_name[MAXNAMLEN + 1];/* name with length <= MAXNAMLEN */
+};
+
+/*
+ * File types
+ */
+#define DT_UNKNOWN       0
+#define DT_FIFO          1
+#define DT_CHR           2
+#define DT_DIR           4
+#define DT_BLK           6
+#define DT_REG           8
+#define DT_LNK          10
+#define DT_SOCK         12
+#define DT_WHT          14
+
+/*
+ * Superblock offsets
+ */
+#define SBLOCK_FLOPPY        0
+#define SBLOCK_UFS1       8192
+#define SBLOCK_UFS2      65536
+#define SBLOCK_PIGGY    262144
+#define SBLOCKSIZE        8192
+#define SBLOCKSEARCH \
+	{ SBLOCK_UFS2, SBLOCK_UFS1, SBLOCK_FLOPPY, SBLOCK_PIGGY, -1 }
+
+#define MAXMNTLEN	512
+
+#define	NOCSPTRS	((128 / sizeof(void *)) - 4)
+
+/*
+ * The maximum number of snapshot nodes that can be associated
+ * with each filesystem. This limit affects only the number of
+ * snapshot files that can be recorded within the superblock so
+ * that they can be found when the filesystem is mounted. However,
+ * maintaining too many will slow the filesystem performance, so
+ * having this limit is a good idea.
+ */
+#define FSMAXSNAP 20
+	
+/*
+ * Per cylinder group information; summarized in blocks allocated
+ * from first cylinder group data blocks.  These blocks have to be
+ * read in from fs_csaddr (size fs_cssize) in addition to the
+ * super block.
+ */
+struct csum {
+	grub_int32_t	cs_ndir;		/* number of directories */
+	grub_int32_t	cs_nbfree;		/* number of free blocks */
+	grub_int32_t	cs_nifree;		/* number of free inodes */
+	grub_int32_t	cs_nffree;		/* number of free frags */
+};
+
+struct csum_total {
+	grub_int64_t	cs_ndir;		/* number of directories */
+	grub_int64_t	cs_nbfree;		/* number of free blocks */
+	grub_int64_t	cs_nifree;		/* number of free inodes */
+	grub_int64_t	cs_nffree;		/* number of free frags */
+	grub_int64_t	cs_numclusters;		/* number of free clusters */
+	grub_int64_t	cs_spare[3];		/* future expansion */
+};
+
+/*
+ * Super block for an FFS filesystem.
+ */
+struct fs {
+	grub_int32_t	 fs_firstfield;		/* historic filesystem linked list, */
+	grub_int32_t	 fs_unused_1;		/*     used for incore super blocks */
+	grub_int32_t	 fs_sblkno;		/* offset of super-block in filesys */
+	grub_int32_t	 fs_cblkno;		/* offset of cyl-block in filesys */
+	grub_int32_t	 fs_iblkno;		/* offset of inode-blocks in filesys */
+	grub_int32_t	 fs_dblkno;		/* offset of first data after cg */
+	grub_int32_t	 fs_old_cgoffset;	/* cylinder group offset in cylinder */
+	grub_int32_t	 fs_old_cgmask;		/* used to calc mod fs_ntrak */
+	grub_int32_t  fs_old_time;		/* last time written */
+	grub_int32_t	 fs_old_size;		/* number of blocks in fs */
+	grub_int32_t	 fs_old_dsize;		/* number of data blocks in fs */
+	grub_int32_t	 fs_ncg;		/* number of cylinder groups */
+	grub_int32_t	 fs_bsize;		/* size of basic blocks in fs */
+	grub_int32_t	 fs_fsize;		/* size of frag blocks in fs */
+	grub_int32_t	 fs_frag;		/* number of frags in a block in fs */
+/* these are configuration parameters */
+	grub_int32_t	 fs_minfree;		/* minimum percentage of free blocks */
+	grub_int32_t	 fs_old_rotdelay;	/* num of ms for optimal next block */
+	grub_int32_t	 fs_old_rps;		/* disk revolutions per second */
+/* these fields can be computed from the others */
+	grub_int32_t	 fs_bmask;		/* ``blkoff'' calc of blk offsets */
+	grub_int32_t	 fs_fmask;		/* ``fragoff'' calc of frag offsets */
+	grub_int32_t	 fs_bshift;		/* ``lblkno'' calc of logical blkno */
+	grub_int32_t	 fs_fshift;		/* ``numfrags'' calc number of frags */
+/* these are configuration parameters */
+	grub_int32_t	 fs_maxcontig;		/* max number of contiguous blks */
+	grub_int32_t	 fs_maxbpg;		/* max number of blks per cyl group */
+/* these fields can be computed from the others */
+	grub_int32_t	 fs_fragshift;		/* block to frag shift */
+	grub_int32_t	 fs_fsbtodb;		/* fsbtodb and dbtofsb shift constant */
+	grub_int32_t	 fs_sbsize;		/* actual size of super block */
+	grub_int32_t	 fs_spare1[2];		/* old fs_csmask */
+					/* old fs_csshift */
+	grub_int32_t	 fs_nindir;		/* value of NINDIR */
+	grub_int32_t	 fs_inopb;		/* value of INOPB */
+	grub_int32_t	 fs_old_nspf;		/* value of NSPF */
+/* yet another configuration parameter */
+	grub_int32_t	 fs_optim;		/* optimization preference, see below */
+	grub_int32_t	 fs_old_npsect;		/* # sectors/track including spares */
+	grub_int32_t	 fs_old_interleave;	/* hardware sector interleave */
+	grub_int32_t	 fs_old_trackskew;	/* sector 0 skew, per track */
+	grub_int32_t	 fs_id[2];		/* unique filesystem id */
+/* sizes determined by number of cylinder groups and their sizes */
+	grub_int32_t	 fs_old_csaddr;		/* blk addr of cyl grp summary area */
+	grub_int32_t	 fs_cssize;		/* size of cyl grp summary area */
+	grub_int32_t	 fs_cgsize;		/* cylinder group size */
+	grub_int32_t	 fs_spare2;		/* old fs_ntrak */
+	grub_int32_t	 fs_old_nsect;		/* sectors per track */
+	grub_int32_t  fs_old_spc;		/* sectors per cylinder */
+	grub_int32_t	 fs_old_ncyl;		/* cylinders in filesystem */
+	grub_int32_t	 fs_old_cpg;		/* cylinders per group */
+	grub_int32_t	 fs_ipg;		/* inodes per group */
+	grub_int32_t	 fs_fpg;		/* blocks per group * fs_frag */
+/* this data must be re-computed after crashes */
+	struct	csum fs_old_cstotal;	/* cylinder summary information */
+/* these fields are cleared at mount time */
+	grub_int8_t   fs_fmod;		/* super block modified flag */
+	grub_int8_t   fs_clean;		/* filesystem is clean flag */
+	grub_int8_t 	 fs_ronly;		/* mounted read-only flag */
+	grub_int8_t   fs_old_flags;		/* old FS_ flags */
+	grub_u_char	 fs_fsmnt[MAXMNTLEN];	/* name mounted on */
+/* these fields retain the current block allocation info */
+	grub_int32_t	 fs_cgrotor;		/* last cg searched */
+	void 	*fs_ocsp[NOCSPTRS];	/* padding; was list of fs_cs buffers */
+	grub_u_int8_t *fs_contigdirs;	/* # of contiguously allocated dirs */
+	struct	csum *fs_csp;		/* cg summary info buffer for fs_cs */
+	grub_int32_t	*fs_maxcluster;		/* max cluster in each cyl group */
+	grub_u_int	*fs_active;		/* used by snapshots to track fs */
+	grub_int32_t	 fs_old_cpc;		/* cyl per cycle in postbl */
+	grub_int32_t	 fs_maxbsize;		/* maximum blocking factor permitted */
+	grub_int64_t	 fs_sparecon64[17];	/* old rotation block list head */
+	grub_int64_t	 fs_sblockloc;		/* byte offset of standard superblock */
+	struct	csum_total fs_cstotal;	/* cylinder summary information */
+	ufs_time_t fs_time;		/* last time written */
+	grub_int64_t	 fs_size;		/* number of blocks in fs */
+	grub_int64_t	 fs_dsize;		/* number of data blocks in fs */
+	ufs2_daddr_t fs_csaddr;		/* blk addr of cyl grp summary area */
+	grub_int64_t	 fs_pendingblocks;	/* blocks in process of being freed */
+	grub_int32_t	 fs_pendinginodes;	/* inodes in process of being freed */
+	grub_int32_t	 fs_snapinum[FSMAXSNAP];/* list of snapshot inode numbers */
+	grub_int32_t	 fs_avgfilesize;	/* expected average file size */
+	grub_int32_t	 fs_avgfpdir;		/* expected # of files per directory */
+	grub_int32_t	 fs_save_cgsize;	/* save real cg size to use fs_bsize */
+	grub_int32_t	 fs_sparecon32[26];	/* reserved for future constants */
+	grub_int32_t  fs_flags;		/* see FS_ flags below */
+	grub_int32_t	 fs_contigsumsize;	/* size of cluster summary array */ 
+	grub_int32_t	 fs_maxsymlinklen;	/* max length of an internal symlink */
+	grub_int32_t	 fs_old_inodefmt;	/* format of on-disk inodes */
+	grub_u_int64_t fs_maxfilesize;	/* maximum representable file size */
+	grub_int64_t	 fs_qbmask;		/* ~fs_bmask for use with 64-bit size */
+	grub_int64_t	 fs_qfmask;		/* ~fs_fmask for use with 64-bit size */
+	grub_int32_t	 fs_state;		/* validate fs_clean field */
+	grub_int32_t	 fs_old_postblformat;	/* format of positional layout tables */
+	grub_int32_t	 fs_old_nrpos;		/* number of rotational positions */
+	grub_int32_t	 fs_spare5[2];		/* old fs_postbloff */
+					/* old fs_rotbloff */
+	grub_int32_t	 fs_magic;		/* magic number */
+};
+
+/*
+ * Filesystem identification
+ */
+#define FS_UFS1_MAGIC   0x011954        /* UFS1 fast filesystem magic number */
+#define	FS_UFS2_MAGIC	0x19540119	/* UFS2 fast filesystem magic number */
+
+/*
+ * Turn filesystem block numbers into disk block addresses.
+ * This maps filesystem blocks to device size blocks.
+ */
+#define fsbtodb(fs, b)	((b) << (fs)->fs_fsbtodb)
+#define	dbtofsb(fs, b)	((b) >> (fs)->fs_fsbtodb)
+
+/*
+ * Cylinder group macros to locate things in cylinder groups.
+ * They calc filesystem addresses of cylinder group data structures.
+ */
+#define	cgbase(fs, c)	((ufs2_daddr_t)((fs)->fs_fpg * (c)))
+#define	cgimin(fs, c)	(cgstart(fs, c) + (fs)->fs_iblkno)	/* inode blk */
+#define cgstart(fs, c)							\
+       ((fs)->fs_magic == FS_UFS2_MAGIC ? cgbase(fs, c) :		\
+       (cgbase(fs, c) + (fs)->fs_old_cgoffset * ((c) & ~((fs)->fs_old_cgmask))))
+
+/*
+ * Macros for handling inode numbers:
+ *     inode number to filesystem block offset.
+ *     inode number to cylinder group number.
+ *     inode number to filesystem block address.
+ */
+#define	ino_to_cg(fs, x)	((x) / (fs)->fs_ipg)
+#define	ino_to_fsba(fs, x)						\
+	((ufs2_daddr_t)(cgimin(fs, ino_to_cg(fs, x)) +			\
+	    (blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs))))))
+#define	ino_to_fsbo(fs, x)	((x) % INOPB(fs))
+
+/*
+ * The following macros optimize certain frequently calculated
+ * quantities by using shifts and masks in place of divisions
+ * modulos and multiplications.
+ */
+#define blkoff(fs, loc)		/* calculates (loc % fs->fs_bsize) */ \
+	((loc) & (fs)->fs_qbmask)
+
+/* Use this only when `blk' is known to be small, e.g., < NDADDR. */
+#define smalllblktosize(fs, blk)    /* calculates (blk * fs->fs_bsize) */ \
+	((blk) << (fs)->fs_bshift)
+
+
+#define lblkno(fs, loc)		/* calculates (loc / fs->fs_bsize) */ \
+	((loc) >> (fs)->fs_bshift)
+
+#define fragroundup(fs, size)	/* calculates roundup(size, fs->fs_fsize) */ \
+	(((size) + (fs)->fs_qfmask) & (fs)->fs_fmask)
+
+#define fragstoblks(fs, frags)	/* calculates (frags / fs->fs_frag) */ \
+	((frags) >> (fs)->fs_fragshift)
+#define blkstofrags(fs, blks)	/* calculates (blks * fs->fs_frag) */ \
+	((blks) << (fs)->fs_fragshift)
+#define fragnum(fs, fsb)	/* calculates (fsb % fs->fs_frag) */ \
+	((fsb) & ((fs)->fs_frag - 1))
+#define blknum(fs, fsb)		/* calculates rounddown(fsb, fs->fs_frag) */ \
+	((fsb) &~ ((fs)->fs_frag - 1))
+
+/*
+ * Determining the size of a file block in the filesystem.
+ */
+#define blksize(fs, ip, lbn) \
+	(((lbn) >= NDADDR || (ip)->i_size >= smalllblktosize(fs, (lbn) + 1)) \
+	    ? (fs)->fs_bsize \
+	    : (fragroundup(fs, blkoff(fs, (ip)->i_size))))
+#define sblksize(fs, size, lbn) \
+	(((lbn) >= NDADDR || (size) >= ((lbn) + 1) << (fs)->fs_bshift) \
+	  ? (fs)->fs_bsize \
+	  : (fragroundup(fs, blkoff(fs, (size)))))
+
+
+/*
+ * Number of inodes in a secondary storage block/fragment.
+ */
+#define	INOPB(fs)	((fs)->fs_inopb)
+#define	INOPF(fs)	((fs)->fs_inopb >> (fs)->fs_fragshift)
+
+/*
+ * Number of indirects in a filesystem block.
+ */
+#define	NINDIR(fs)	((fs)->fs_nindir)
+
+#define FS_UNCLEAN    0x01      /* filesystem not clean at mount */
+#define FS_DOSOFTDEP  0x02      /* filesystem using soft dependencies */
+#define FS_NEEDSFSCK  0x04      /* filesystem needs sync fsck before mount */
+#define FS_INDEXDIRS  0x08      /* kernel supports indexed directories */
+#define FS_ACLS       0x10      /* file system has ACLs enabled */
+#define FS_MULTILABEL 0x20      /* file system is MAC multi-label */
+#define FS_FLAGS_UPDATED 0x80   /* flags have been moved to new location */
+
+#endif /* _GRUB_UFS2_H_ */
diff --git a/stage2/vstafs.h b/stage2/vstafs.h
new file mode 100644
index 0000000..cc7820c
--- /dev/null
+++ b/stage2/vstafs.h
@@ -0,0 +1,88 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2001   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 VSTAFS_H
+#define VSTAFS_H	1
+
+
+#define LINE			16
+#define BLOCK_SIZE		512
+#define VSTAFS_START_DATA	320
+
+struct bootrecord
+{
+  unsigned char flag;
+  unsigned char s_sector;
+  unsigned char s_head;
+  unsigned char s_cylinder;
+  unsigned char p_type;
+  unsigned char e_sector;
+  unsigned char e_head;
+  unsigned char e_cylinder;
+  unsigned long start_lba;
+  unsigned long nr_sector_lba;
+};
+
+struct alloc
+{
+  unsigned long a_start;
+  unsigned long a_len;
+};
+
+struct first_sector
+{
+  unsigned long fs_magic;
+  unsigned long fs_size;
+  unsigned long fs_extsize;
+  unsigned long fs_free;
+  struct  alloc fs_freesecs[0];
+};
+
+struct prot
+{
+  unsigned char len;
+  unsigned char pdefault;
+  unsigned char id[7];
+  unsigned char bits[7];
+};
+
+struct fs_file
+{
+  unsigned long prev;
+  unsigned long rev;
+  unsigned long len;
+  unsigned short type;
+  unsigned short nlink;
+  struct prot pprot;
+  unsigned int owner;
+  unsigned int extents;
+  struct alloc blocks[32];
+  long fs_ctime, fs_mtime; /* it is not lon but time_t */
+  char pad[16];
+  char data[0];
+};
+
+struct dir_entry
+{
+  char name[28];
+  unsigned long start;
+};
+
+#endif /* ! VSTAFS_H */
diff --git a/stage2/xfs.h b/stage2/xfs.h
new file mode 100644
index 0000000..02f8dcd
--- /dev/null
+++ b/stage2/xfs.h
@@ -0,0 +1,544 @@
+/* xfs.h - an extraction from xfsprogs-1.3.5/include/xfs* into one file */
+/* 
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2000  Silicon Graphics, Inc.  All Rights Reserved.
+ *  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 version 2 of the GNU General Public License as
+ *  published by the Free Software Foundation.
+ * 
+ *  This program is distributed in the hope that it would be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * 
+ *  Further, this software is distributed without any warranty that it is
+ *  free of the rightful claim of any third person regarding infringement
+ *  or the like.  Any license provided herein, whether implied or
+ *  otherwise, applies only to this software file.  Patent licenses, if
+ *  any, provided herein do not apply to combinations of this program with
+ *  other software, or any other product whatsoever.
+ * 
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write the Free Software Foundation, Inc., 59
+ *  Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ *  Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ *  Mountain View, CA  94043, or:
+ * 
+ *  http://www.sgi.com 
+ * 
+ *  For further information regarding this notice, see: 
+ * 
+ *  http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+typedef signed char	xfs_int8_t;
+typedef unsigned char	xfs_uint8_t;
+typedef short		xfs_int16_t;
+typedef unsigned short	xfs_uint16_t;
+typedef int		xfs_int32_t;
+typedef unsigned int	xfs_uint32_t;
+typedef long long	xfs_int64_t;
+typedef unsigned long long xfs_uint64_t;
+
+typedef xfs_uint64_t	xfs_ino_t;
+typedef	xfs_uint32_t	xfs_agino_t;
+typedef xfs_int64_t	xfs_daddr_t;
+typedef xfs_int64_t	xfs_off_t;
+typedef xfs_uint8_t	uuid_t[16];
+
+
+/* those are from xfs_types.h */
+
+typedef xfs_uint32_t	xfs_agblock_t;	/* blockno in alloc. group */
+typedef	xfs_uint32_t	xfs_extlen_t;	/* extent length in blocks */
+typedef	xfs_uint32_t	xfs_agnumber_t;	/* allocation group number */
+typedef xfs_int32_t	xfs_extnum_t;	/* # of extents in a file */
+typedef xfs_int16_t	xfs_aextnum_t;	/* # extents in an attribute fork */
+typedef	xfs_int64_t	xfs_fsize_t;	/* bytes in a file */
+
+typedef	xfs_uint32_t	xfs_dablk_t;	/* dir/attr block number (in file) */
+typedef	xfs_uint32_t	xfs_dahash_t;	/* dir/attr hash value */
+
+/*
+ * Disk based types:
+ */
+typedef xfs_uint64_t	xfs_dfsbno_t;	/* blockno in filesystem (agno|agbno) */
+typedef xfs_uint64_t	xfs_drfsbno_t;	/* blockno in filesystem (raw) */
+typedef	xfs_uint64_t	xfs_drtbno_t;	/* extent (block) in realtime area */
+typedef	xfs_uint64_t	xfs_dfiloff_t;	/* block number in a file */
+
+typedef	xfs_uint64_t	xfs_fsblock_t;	/* blockno in filesystem (agno|agbno) */
+typedef	xfs_uint64_t	xfs_fileoff_t;	/* block number in a file */
+typedef	xfs_uint64_t	xfs_filblks_t;	/* number of blocks in a file */
+
+
+/* those are from xfs_sb.h */
+
+#define	XFS_SB_MAGIC		0x58465342	/* 'XFSB'*/
+#define	XFS_SB_VERSION_4	4		/* 6.2+ - bitmask version */
+#define	XFS_SB_VERSION_NUMBITS	0x000f
+
+typedef struct xfs_sb
+{
+	xfs_uint32_t	sb_magicnum;	/* magic number == XFS_SB_MAGIC */
+	xfs_uint32_t	sb_blocksize;	/* logical block size, bytes */
+	xfs_drfsbno_t	sb_dblocks;	/* number of data blocks */
+	xfs_drfsbno_t	sb_rblocks;	/* number of realtime blocks */
+	xfs_drtbno_t	sb_rextents;	/* number of realtime extents */
+	uuid_t		sb_uuid;	/* file system unique id */
+	xfs_dfsbno_t	sb_logstart;	/* starting block of log if internal */
+	xfs_ino_t	sb_rootino;	/* root inode number */
+	xfs_ino_t	sb_rbmino;	/* bitmap inode for realtime extents */
+	xfs_ino_t	sb_rsumino;	/* summary inode for rt bitmap */
+	xfs_agblock_t	sb_rextsize;	/* realtime extent size, blocks */
+	xfs_agblock_t	sb_agblocks;	/* size of an allocation group */
+	xfs_agnumber_t	sb_agcount;	/* number of allocation groups */
+	xfs_extlen_t	sb_rbmblocks;	/* number of rt bitmap blocks */
+	xfs_extlen_t	sb_logblocks;	/* number of log blocks */
+	xfs_uint16_t	sb_versionnum;	/* header version == XFS_SB_VERSION */
+	xfs_uint16_t	sb_sectsize;	/* volume sector size, bytes */
+	xfs_uint16_t	sb_inodesize;	/* inode size, bytes */
+	xfs_uint16_t	sb_inopblock;	/* inodes per block */
+	char		sb_fname[12];	/* file system name */
+	xfs_uint8_t	sb_blocklog;	/* log2 of sb_blocksize */
+	xfs_uint8_t	sb_sectlog;	/* log2 of sb_sectsize */
+	xfs_uint8_t	sb_inodelog;	/* log2 of sb_inodesize */
+	xfs_uint8_t	sb_inopblog;	/* log2 of sb_inopblock */
+	xfs_uint8_t	sb_agblklog;	/* log2 of sb_agblocks (rounded up) */
+	xfs_uint8_t	sb_rextslog;	/* log2 of sb_rextents */
+	xfs_uint8_t	sb_inprogress;	/* mkfs is in progress, don't mount */
+	xfs_uint8_t	sb_imax_pct;	/* max % of fs for inode space */
+					/* statistics */
+	/*
+	 * These fields must remain contiguous.  If you really
+	 * want to change their layout, make sure you fix the
+	 * code in xfs_trans_apply_sb_deltas().
+	 */
+	xfs_uint64_t	sb_icount;	/* allocated inodes */
+	xfs_uint64_t	sb_ifree;	/* free inodes */
+	xfs_uint64_t	sb_fdblocks;	/* free data blocks */
+	xfs_uint64_t	sb_frextents;	/* free realtime extents */
+	/*
+	 * End contiguous fields.
+	 */
+	xfs_ino_t	sb_uquotino;	/* user quota inode */
+	xfs_ino_t	sb_gquotino;	/* group quota inode */
+	xfs_uint16_t	sb_qflags;	/* quota flags */
+	xfs_uint8_t	sb_flags;	/* misc. flags */
+	xfs_uint8_t	sb_shared_vn;	/* shared version number */
+	xfs_extlen_t	sb_inoalignmt;	/* inode chunk alignment, fsblocks */
+	xfs_uint32_t	sb_unit;	/* stripe or raid unit */
+	xfs_uint32_t	sb_width;	/* stripe or raid width */	
+	xfs_uint8_t	sb_dirblklog;	/* log2 of dir block size (fsbs) */
+        xfs_uint8_t       sb_dummy[7];    /* padding */
+} xfs_sb_t;
+
+
+/* those are from xfs_btree.h */
+
+/*
+ * Long form header: bmap btrees.
+ */
+typedef struct xfs_btree_lblock
+{
+	xfs_uint32_t	bb_magic;	/* magic number for block type */
+	xfs_uint16_t	bb_level;	/* 0 is a leaf */
+	xfs_uint16_t	bb_numrecs;	/* current # of data records */
+	xfs_dfsbno_t	bb_leftsib;	/* left sibling block or NULLDFSBNO */
+	xfs_dfsbno_t	bb_rightsib;	/* right sibling block or NULLDFSBNO */
+} xfs_btree_lblock_t;
+
+/*
+ * Combined header and structure, used by common code.
+ */
+typedef struct xfs_btree_hdr
+{
+	xfs_uint32_t	bb_magic;	/* magic number for block type */
+	xfs_uint16_t	bb_level;	/* 0 is a leaf */
+	xfs_uint16_t	bb_numrecs;	/* current # of data records */
+} xfs_btree_hdr_t;
+
+typedef struct xfs_btree_block
+{
+	xfs_btree_hdr_t	bb_h;		/* header */
+	union		{
+		struct	{
+			xfs_agblock_t	bb_leftsib;
+			xfs_agblock_t	bb_rightsib;
+		}	s;		/* short form pointers */
+		struct	{
+			xfs_dfsbno_t	bb_leftsib;
+			xfs_dfsbno_t	bb_rightsib;
+		}	l;		/* long form pointers */
+	}		bb_u;		/* rest */
+} xfs_btree_block_t;
+
+/* those are from xfs_bmap_btree.h */
+
+/*
+ * Bmap root header, on-disk form only.
+ */
+typedef struct xfs_bmdr_block
+{
+	xfs_uint16_t	bb_level;	/* 0 is a leaf */
+	xfs_uint16_t	bb_numrecs;	/* current # of data records */
+} xfs_bmdr_block_t;
+
+/*
+ * Bmap btree record and extent descriptor.
+ * For 32-bit kernels,
+ *  l0:31 is an extent flag (value 1 indicates non-normal).
+ *  l0:0-30 and l1:9-31 are startoff.
+ *  l1:0-8, l2:0-31, and l3:21-31 are startblock.
+ *  l3:0-20 are blockcount.
+ * For 64-bit kernels,
+ *  l0:63 is an extent flag (value 1 indicates non-normal).
+ *  l0:9-62 are startoff.
+ *  l0:0-8 and l1:21-63 are startblock.
+ *  l1:0-20 are blockcount.
+ */
+
+#define	BMBT_USE_64	1
+
+typedef struct xfs_bmbt_rec_32
+{
+	xfs_uint32_t		l0, l1, l2, l3;
+} xfs_bmbt_rec_32_t;
+typedef struct xfs_bmbt_rec_64
+{
+	xfs_uint64_t		l0, l1;
+} xfs_bmbt_rec_64_t;
+
+#if BMBT_USE_64
+typedef	xfs_uint64_t	xfs_bmbt_rec_base_t;	/* use this for casts */
+typedef xfs_bmbt_rec_64_t xfs_bmbt_rec_t, xfs_bmdr_rec_t;
+#else	/* !BMBT_USE_64 */
+typedef	xfs_uint32_t	xfs_bmbt_rec_base_t;	/* use this for casts */
+typedef xfs_bmbt_rec_32_t xfs_bmbt_rec_t, xfs_bmdr_rec_t;
+#endif	/* BMBT_USE_64 */
+
+/*
+ * Key structure for non-leaf levels of the tree.
+ */
+typedef struct xfs_bmbt_key
+{
+	xfs_dfiloff_t	br_startoff;	/* starting file offset */
+} xfs_bmbt_key_t, xfs_bmdr_key_t;
+
+typedef xfs_dfsbno_t xfs_bmbt_ptr_t, xfs_bmdr_ptr_t;	/* btree pointer type */
+					/* btree block header type */
+typedef	struct xfs_btree_lblock xfs_bmbt_block_t;
+
+
+/* those are from xfs_dir2.h */
+/*
+ * Directory version 2.
+ * There are 4 possible formats:
+ *	shortform
+ *	single block - data with embedded leaf at the end
+ *	multiple data blocks, single leaf+freeindex block
+ *	data blocks, node&leaf blocks (btree), freeindex blocks
+ *
+ *	The shortform format is in xfs_dir2_sf.h.
+ *	The single block format is in xfs_dir2_block.h.
+ *	The data block format is in xfs_dir2_data.h.
+ *	The leaf and freeindex block formats are in xfs_dir2_leaf.h.
+ *	Node blocks are the same as the other version, in xfs_da_btree.h.
+ */
+
+/*
+ * Byte offset in data block and shortform entry.
+ */
+typedef	xfs_uint16_t	xfs_dir2_data_off_t;
+
+/*
+ * Byte offset in a directory.
+ */
+typedef	xfs_off_t		xfs_dir2_off_t;
+
+/* those are from xfs_da_btree.h */
+/*========================================================================
+ * Directory Structure when greater than XFS_LBSIZE(mp) bytes.
+ *========================================================================*/
+
+/*
+ * This structure is common to both leaf nodes and non-leaf nodes in the Btree.
+ *
+ * Is is used to manage a doubly linked list of all blocks at the same
+ * level in the Btree, and to identify which type of block this is.
+ */
+#define	XFS_DIR2_LEAF1_MAGIC	0xd2f1	/* magic number: v2 dirlf single blks */
+#define	XFS_DIR2_LEAFN_MAGIC	0xd2ff	/* magic number: v2 dirlf multi blks */
+
+typedef struct xfs_da_blkinfo {
+	xfs_dablk_t forw;			/* previous block in list */
+	xfs_dablk_t back;			/* following block in list */
+	xfs_uint16_t magic;			/* validity check on block */
+	xfs_uint16_t pad;				/* unused */
+} xfs_da_blkinfo_t;
+
+/*
+ * This is the structure of the root and intermediate nodes in the Btree.
+ * The leaf nodes are defined above.
+ *
+ * Entries are not packed.
+ *
+ * Since we have duplicate keys, use a binary search but always follow
+ * all match in the block, not just the first match found.
+ */
+
+typedef struct xfs_da_intnode {
+	struct xfs_da_node_hdr {	/* constant-structure header block */
+		xfs_da_blkinfo_t info;	/* block type, links, etc. */
+		xfs_uint16_t count;	/* count of active entries */
+		xfs_uint16_t level;	/* level above leaves (leaf == 0) */
+	} hdr;
+	struct xfs_da_node_entry {
+		xfs_dahash_t hashval;	/* hash value for this descendant */
+		xfs_dablk_t before;	/* Btree block before this key */
+	} btree[1];			/* variable sized array of keys */
+} xfs_da_intnode_t;
+
+
+/* those are from xfs_dir2_data.h */
+/*
+ * Directory format 2, data block structures.
+ */
+
+/*
+ * Constants.
+ */
+#define	XFS_DIR2_DATA_FREE_TAG	0xffff
+#define	XFS_DIR2_DATA_FD_COUNT	3
+
+/*
+ * Structures.
+ */
+
+/*
+ * Describe a free area in the data block.
+ * The freespace will be formatted as a xfs_dir2_data_unused_t.
+ */
+typedef struct xfs_dir2_data_free {
+	xfs_dir2_data_off_t	offset;		/* start of freespace */
+	xfs_dir2_data_off_t	length;		/* length of freespace */
+} xfs_dir2_data_free_t;
+
+/*
+ * Header for the data blocks.
+ * Always at the beginning of a directory-sized block.
+ * The code knows that XFS_DIR2_DATA_FD_COUNT is 3.
+ */
+typedef struct xfs_dir2_data_hdr {
+	xfs_uint32_t		magic;		/* XFS_DIR2_DATA_MAGIC */
+						/* or XFS_DIR2_BLOCK_MAGIC */
+	xfs_dir2_data_free_t	bestfree[XFS_DIR2_DATA_FD_COUNT];
+} xfs_dir2_data_hdr_t;
+
+/*
+ * Active entry in a data block.  Aligned to 8 bytes.
+ * Tag appears as the last 2 bytes.
+ */
+typedef struct xfs_dir2_data_entry {
+	xfs_ino_t		inumber;	/* inode number */
+	xfs_uint8_t		namelen;	/* name length */
+	xfs_uint8_t		name[1];	/* name bytes, no null */
+						/* variable offset */
+	xfs_dir2_data_off_t	tag;		/* starting offset of us */
+} xfs_dir2_data_entry_t;
+
+/*
+ * Unused entry in a data block.  Aligned to 8 bytes.
+ * Tag appears as the last 2 bytes.
+ */
+typedef struct xfs_dir2_data_unused {
+	xfs_uint16_t		freetag;	/* XFS_DIR2_DATA_FREE_TAG */
+	xfs_dir2_data_off_t	length;		/* total free length */
+						/* variable offset */
+	xfs_dir2_data_off_t	tag;		/* starting offset of us */
+} xfs_dir2_data_unused_t;
+
+typedef union {
+	xfs_dir2_data_entry_t	entry;
+	xfs_dir2_data_unused_t	unused;
+} xfs_dir2_data_union_t;
+
+
+/* those are from xfs_dir2_leaf.h */
+/*
+ * Directory version 2, leaf block structures.
+ */
+
+/*
+ * Leaf block header.
+ */
+typedef struct xfs_dir2_leaf_hdr {
+	xfs_da_blkinfo_t	info;		/* header for da routines */
+	xfs_uint16_t		count;		/* count of entries */
+	xfs_uint16_t		stale;		/* count of stale entries */
+} xfs_dir2_leaf_hdr_t;
+
+
+/* those are from xfs_dir2_block.h */
+/*
+ * xfs_dir2_block.h
+ * Directory version 2, single block format structures
+ */
+
+/*
+ * The single block format is as follows:
+ * xfs_dir2_data_hdr_t structure
+ * xfs_dir2_data_entry_t and xfs_dir2_data_unused_t structures
+ * xfs_dir2_leaf_entry_t structures
+ * xfs_dir2_block_tail_t structure
+ */
+
+#define	XFS_DIR2_BLOCK_MAGIC	0x58443242	/* XD2B: for one block dirs */
+
+typedef struct xfs_dir2_block_tail {
+	xfs_uint32_t	count;			/* count of leaf entries */
+	xfs_uint32_t	stale;			/* count of stale lf entries */
+} xfs_dir2_block_tail_t;
+
+
+/* those are from xfs_dir2_sf.h */
+
+/*
+ * Directory layout when stored internal to an inode.
+ *
+ * Small directories are packed as tightly as possible so as to
+ * fit into the literal area of the inode.
+ */
+
+/*
+ * Inode number stored as 8 8-bit values.
+ */
+typedef	struct { xfs_uint8_t i[8]; } xfs_dir2_ino8_t;
+
+/*
+ * Inode number stored as 4 8-bit values.
+ * Works a lot of the time, when all the inode numbers in a directory
+ * fit in 32 bits.
+ */
+typedef struct { xfs_uint8_t i[4]; } xfs_dir2_ino4_t;
+
+typedef union {
+	xfs_dir2_ino8_t	i8;
+	xfs_dir2_ino4_t	i4;
+} xfs_dir2_inou_t;
+
+/*
+ * Normalized offset (in a data block) of the entry, really xfs_dir2_data_off_t.
+ * Only need 16 bits, this is the byte offset into the single block form.
+ */
+typedef struct { xfs_uint8_t i[2]; } xfs_dir2_sf_off_t;
+
+/*
+ * The parent directory has a dedicated field, and the self-pointer must
+ * be calculated on the fly.
+ *
+ * Entries are packed toward the top as tightly as possible.  The header
+ * and the elements must be bcopy()'d out into a work area to get correct
+ * alignment for the inode number fields.
+ */
+typedef struct xfs_dir2_sf_hdr {
+	xfs_uint8_t		count;		/* count of entries */
+	xfs_uint8_t		i8count;	/* count of 8-byte inode #s */
+	xfs_dir2_inou_t		parent;		/* parent dir inode number */
+} xfs_dir2_sf_hdr_t;
+
+typedef struct xfs_dir2_sf_entry {
+	xfs_uint8_t		namelen;	/* actual name length */
+	xfs_dir2_sf_off_t	offset;		/* saved offset */
+	xfs_uint8_t		name[1];	/* name, variable size */
+	xfs_dir2_inou_t		inumber;	/* inode number, var. offset */
+} xfs_dir2_sf_entry_t;
+
+typedef struct xfs_dir2_sf {
+	xfs_dir2_sf_hdr_t	hdr;		/* shortform header */
+	xfs_dir2_sf_entry_t	list[1];	/* shortform entries */
+} xfs_dir2_sf_t;
+
+/* those are from xfs_dinode.h */
+
+#define	XFS_DINODE_VERSION_1	1
+#define	XFS_DINODE_VERSION_2	2
+#define	XFS_DINODE_MAGIC	0x494e	/* 'IN' */
+
+/*
+ * Disk inode structure.
+ * This is just the header; the inode is expanded to fill a variable size
+ * with the last field expanding.  It is split into the core and "other"
+ * because we only need the core part in the in-core inode.
+ */
+typedef struct xfs_timestamp {
+	xfs_int32_t	t_sec;		/* timestamp seconds */
+	xfs_int32_t	t_nsec;		/* timestamp nanoseconds */
+} xfs_timestamp_t;
+
+/*
+ * Note: Coordinate changes to this structure with the XFS_DI_* #defines
+ * below and the offsets table in xfs_ialloc_log_di().
+ */
+typedef struct xfs_dinode_core
+{
+	xfs_uint16_t	di_magic;	/* inode magic # = XFS_DINODE_MAGIC */
+	xfs_uint16_t	di_mode;	/* mode and type of file */
+	xfs_int8_t	di_version;	/* inode version */
+	xfs_int8_t	di_format;	/* format of di_c data */
+	xfs_uint16_t	di_onlink;	/* old number of links to file */
+	xfs_uint32_t	di_uid;		/* owner's user id */
+	xfs_uint32_t	di_gid;		/* owner's group id */
+	xfs_uint32_t	di_nlink;	/* number of links to file */
+	xfs_uint16_t	di_projid;	/* owner's project id */
+	xfs_uint8_t	di_pad[10];	/* unused, zeroed space */
+	xfs_timestamp_t	di_atime;	/* time last accessed */
+	xfs_timestamp_t	di_mtime;	/* time last modified */
+	xfs_timestamp_t	di_ctime;	/* time created/inode modified */
+	xfs_fsize_t	di_size;	/* number of bytes in file */
+	xfs_drfsbno_t	di_nblocks;	/* # of direct & btree blocks used */
+	xfs_extlen_t	di_extsize;	/* basic/minimum extent size for file */
+	xfs_extnum_t	di_nextents;	/* number of extents in data fork */
+	xfs_aextnum_t	di_anextents;	/* number of extents in attribute fork*/
+	xfs_uint8_t	di_forkoff;	/* attr fork offs, <<3 for 64b align */
+	xfs_int8_t	di_aformat;	/* format of attr fork's data */
+	xfs_uint32_t	di_dmevmask;	/* DMIG event mask */
+	xfs_uint16_t	di_dmstate;	/* DMIG state info */
+	xfs_uint16_t	di_flags;	/* random flags, XFS_DIFLAG_... */
+	xfs_uint32_t	di_gen;		/* generation number */
+} xfs_dinode_core_t;
+
+typedef struct xfs_dinode
+{
+	xfs_dinode_core_t	di_core;
+	xfs_agino_t		di_next_unlinked;/* agi unlinked list ptr */
+	union {
+		xfs_bmdr_block_t di_bmbt;	/* btree root block */
+		xfs_bmbt_rec_32_t di_bmx[1];	/* extent list */
+		xfs_dir2_sf_t	di_dir2sf;	/* shortform directory v2 */
+		char		di_c[1];	/* local contents */
+	} di_u;
+} xfs_dinode_t;
+
+/*
+ * Values for di_format
+ */
+typedef enum xfs_dinode_fmt
+{
+	XFS_DINODE_FMT_DEV,		/* CHR, BLK: di_dev */
+	XFS_DINODE_FMT_LOCAL,		/* DIR, REG: di_c */
+					/* LNK: di_symlink */
+	XFS_DINODE_FMT_EXTENTS,		/* DIR, REG, LNK: di_bmx */
+	XFS_DINODE_FMT_BTREE,		/* DIR, REG, LNK: di_bmbt */
+	XFS_DINODE_FMT_UUID 		/* MNT: di_uuid */
+} xfs_dinode_fmt_t;
+
+/*
+ * File types (mode field)
+ */
+#define	IFMT		0170000		/* type of file */
+#define	IFDIR		0040000		/* directory */
+#define	IFREG		0100000		/* regular */
+#define	IFLNK		0120000		/* symbolic link */
diff --git a/stamp-h1 b/stamp-h1
new file mode 100644
index 0000000..4547fe1
--- /dev/null
+++ b/stamp-h1
@@ -0,0 +1 @@
+timestamp for config.h
diff --git a/util/Makefile.am b/util/Makefile.am
new file mode 100644
index 0000000..2e04711
--- /dev/null
+++ b/util/Makefile.am
@@ -0,0 +1,12 @@
+bin_PROGRAMS = mbchk
+sbin_SCRIPTS = grub-install grub-md5-crypt grub-terminfo \
+	grub-set-default
+noinst_SCRIPTS = grub-image mkbimage
+
+EXTRA_DIST = mkbimage
+
+# XXX: Need to search for a header file in docs, because of multiboot.h.
+AM_CFLAGS = -I$(top_srcdir)/lib -I$(top_srcdir)/docs
+
+mbchk_SOURCES = mbchk.c
+mbchk_LDADD = ../lib/libcommon.a
diff --git a/util/Makefile.in b/util/Makefile.in
new file mode 100644
index 0000000..e700cf7
--- /dev/null
+++ b/util/Makefile.in
@@ -0,0 +1,478 @@
+# Makefile.in generated by automake 1.9.4 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004  Free Software Foundation, Inc.
+# This Makefile.in 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 distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+SOURCES = $(mbchk_SOURCES)
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+bin_PROGRAMS = mbchk$(EXEEXT)
+subdir = util
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+	$(srcdir)/grub-image.in $(srcdir)/grub-install.in \
+	$(srcdir)/grub-md5-crypt.in $(srcdir)/grub-set-default.in \
+	$(srcdir)/grub-terminfo.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = grub-image grub-install grub-md5-crypt \
+	grub-terminfo grub-set-default
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_mbchk_OBJECTS = mbchk.$(OBJEXT)
+mbchk_OBJECTS = $(am_mbchk_OBJECTS)
+mbchk_DEPENDENCIES = ../lib/libcommon.a
+sbinSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+SCRIPTS = $(noinst_SCRIPTS) $(sbin_SCRIPTS)
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(mbchk_SOURCES)
+DIST_SOURCES = $(mbchk_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BUILD_EXAMPLE_KERNEL_FALSE = @BUILD_EXAMPLE_KERNEL_FALSE@
+BUILD_EXAMPLE_KERNEL_TRUE = @BUILD_EXAMPLE_KERNEL_TRUE@
+CC = @CC@
+CCAS = @CCAS@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISKLESS_SUPPORT_FALSE = @DISKLESS_SUPPORT_FALSE@
+DISKLESS_SUPPORT_TRUE = @DISKLESS_SUPPORT_TRUE@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FSYS_CFLAGS = @FSYS_CFLAGS@
+GRUB_CFLAGS = @GRUB_CFLAGS@
+GRUB_LIBS = @GRUB_LIBS@
+HERCULES_SUPPORT_FALSE = @HERCULES_SUPPORT_FALSE@
+HERCULES_SUPPORT_TRUE = @HERCULES_SUPPORT_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+NETBOOT_DRIVERS = @NETBOOT_DRIVERS@
+NETBOOT_SUPPORT_FALSE = @NETBOOT_SUPPORT_FALSE@
+NETBOOT_SUPPORT_TRUE = @NETBOOT_SUPPORT_TRUE@
+NET_CFLAGS = @NET_CFLAGS@
+NET_EXTRAFLAGS = @NET_EXTRAFLAGS@
+OBJCOPY = @OBJCOPY@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PERL = @PERL@
+RANLIB = @RANLIB@
+SERIAL_SPEED_SIMULATION_FALSE = @SERIAL_SPEED_SIMULATION_FALSE@
+SERIAL_SPEED_SIMULATION_TRUE = @SERIAL_SPEED_SIMULATION_TRUE@
+SERIAL_SUPPORT_FALSE = @SERIAL_SUPPORT_FALSE@
+SERIAL_SUPPORT_TRUE = @SERIAL_SUPPORT_TRUE@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STAGE1_CFLAGS = @STAGE1_CFLAGS@
+STAGE2_CFLAGS = @STAGE2_CFLAGS@
+STRIP = @STRIP@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_OBJCOPY = @ac_ct_OBJCOPY@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+sbin_SCRIPTS = grub-install grub-md5-crypt grub-terminfo \
+	grub-set-default
+
+noinst_SCRIPTS = grub-image mkbimage
+EXTRA_DIST = mkbimage
+
+# XXX: Need to search for a header file in docs, because of multiboot.h.
+AM_CFLAGS = -I$(top_srcdir)/lib -I$(top_srcdir)/docs
+mbchk_SOURCES = mbchk.c
+mbchk_LDADD = ../lib/libcommon.a
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu  util/Makefile'; \
+	cd $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu  util/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+grub-image: $(top_builddir)/config.status $(srcdir)/grub-image.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+grub-install: $(top_builddir)/config.status $(srcdir)/grub-install.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+grub-md5-crypt: $(top_builddir)/config.status $(srcdir)/grub-md5-crypt.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+grub-terminfo: $(top_builddir)/config.status $(srcdir)/grub-terminfo.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+grub-set-default: $(top_builddir)/config.status $(srcdir)/grub-set-default.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+install-binPROGRAMS: $(bin_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+	@list='$(bin_PROGRAMS)'; for p in $$list; do \
+	  p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+	  if test -f $$p \
+	  ; then \
+	    f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+	   echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+	   $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+	  else :; fi; \
+	done
+
+uninstall-binPROGRAMS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_PROGRAMS)'; for p in $$list; do \
+	  f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+	  echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(bindir)/$$f"; \
+	done
+
+clean-binPROGRAMS:
+	-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+mbchk$(EXEEXT): $(mbchk_OBJECTS) $(mbchk_DEPENDENCIES) 
+	@rm -f mbchk$(EXEEXT)
+	$(LINK) $(mbchk_LDFLAGS) $(mbchk_OBJECTS) $(mbchk_LDADD) $(LIBS)
+install-sbinSCRIPTS: $(sbin_SCRIPTS)
+	@$(NORMAL_INSTALL)
+	test -z "$(sbindir)" || $(mkdir_p) "$(DESTDIR)$(sbindir)"
+	@list='$(sbin_SCRIPTS)'; for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  if test -f $$d$$p; then \
+	    f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+	    echo " $(sbinSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(sbindir)/$$f'"; \
+	    $(sbinSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(sbindir)/$$f"; \
+	  else :; fi; \
+	done
+
+uninstall-sbinSCRIPTS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(sbin_SCRIPTS)'; for p in $$list; do \
+	  f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+	  echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(sbindir)/$$f"; \
+	done
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mbchk.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@	if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCC_TRUE@	then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+uninstall-info-am:
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	    $$tags $$unique; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	tags=; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '    { files[$$0] = 1; } \
+	       END { for (i in files) print i; }'`; \
+	test -z "$(CTAGS_ARGS)$$tags$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$tags $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && cd $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+	list='$(DISTFILES)'; for file in $$list; do \
+	  case $$file in \
+	    $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+	    $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+	  esac; \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+	  if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+	    dir="/$$dir"; \
+	    $(mkdir_p) "$(distdir)$$dir"; \
+	  else \
+	    dir=''; \
+	  fi; \
+	  if test -d $$d/$$file; then \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+	    fi; \
+	    cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+	  else \
+	    test -f $(distdir)/$$file \
+	    || cp -p $$d/$$file $(distdir)/$$file \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(SCRIPTS)
+installdirs:
+	for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)"; do \
+	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
+	done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-exec-am: install-binPROGRAMS install-sbinSCRIPTS
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-info-am \
+	uninstall-sbinSCRIPTS
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+	clean-generic ctags distclean distclean-compile \
+	distclean-generic distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-binPROGRAMS \
+	install-data install-data-am install-exec install-exec-am \
+	install-info install-info-am install-man install-sbinSCRIPTS \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
+	tags uninstall uninstall-am uninstall-binPROGRAMS \
+	uninstall-info-am uninstall-sbinSCRIPTS
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/util/grub-image b/util/grub-image
new file mode 100644
index 0000000..d012980
--- /dev/null
+++ b/util/grub-image
@@ -0,0 +1,138 @@
+#! /bin/sh
+# grub-image - Create a GRUB boot filesystem image and tarball
+# Gordon Matzigkeit <gord@fig.org>, 2000-07-25
+#
+#   Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+prefix=/usr/local
+exec_prefix=${prefix}
+sbindir=${exec_prefix}/sbin
+libdir=${exec_prefix}/lib
+PACKAGE=grub
+host_cpu=x86_64
+host_os=linux-gnu
+host_vendor=unknown
+context=${host_cpu}-${host_vendor}
+pkglibdir=${libdir}/${PACKAGE}/${context}
+
+mke2fs=`which mke2fs`
+
+progname=`echo "$0" | sed 's%^.*/%%'`
+thisdir=`echo "$0" | sed 's%/[^/]*$%%'`
+test "X$thisdir" = "X$0" && thisdir=.
+
+# See if we were invoked from within the build directory, and if so,
+# use the built files rather than the installed ones.
+if test -f $thisdir/../stage2/stage2; then
+  grub_shell="$thisdir/../grub/grub"
+  stage1dir="$thisdir/../stage1"
+  stage2dir="$thisdir/../stage2"
+else
+  grub_shell=${sbindir}/grub
+  stage1dir="$pkglibdir"
+  stage2dir="$pkglibdir"
+fi
+
+# Exit on any error.
+set -e
+
+# Get GRUB's version from the Grub shell, since we use the
+# installed files.
+VERSION=`$grub_shell --version | sed -e 's/^.* \([0-9.]*\).*$/\1/'`
+test "X$VERSION" != X
+
+bootdir=${PACKAGE}-${VERSION}-${context}
+image=$bootdir.ext2fs
+
+# Create the tarball.
+if test ! -f $bootdir.tar.gz; then
+  echo "# Creating \`$bootdir.tar.gz'"
+  mkdir -p $bootdir/boot/grub
+  cp -p $stage1dir/stage1 $stage2dir/*_stage1_5 $stage2dir/stage2 \
+    $bootdir/boot/grub
+  test ! -f menu.lst || cp -p menu.lst $bootdir/boot/grub
+  trap "rm -f $bootdir.tar.gz" 0
+  GZIP=-9 tar -zcf $bootdir.tar.gz $bootdir
+  trap '' 0
+  rm -rf $bootdir
+fi
+
+# Create a new filesystem image of the specified size.
+if test ! -f $image; then
+  tarsize=`zcat $bootdir.tar.gz | wc -c`
+
+  # Add about 30% (20% overhead plus 10% breathing room), and convert
+  # to kilobytes.  This factor was determined empirically.
+  SIZE=`expr $tarsize \* 130 / 100 / 1024`k
+  echo "# Creating $SIZE disk image \`$image'"
+  trap "rm -f $image" 0
+  dd if=/dev/zero of=$image bs=$SIZE count=1 >/dev/null
+  $mke2fs -F $image
+  trap '' 0
+fi
+
+
+# Attempt to mount the image.
+echo "# Mounting \`$image'"
+test -d $bootdir || mkdir $bootdir
+case "$host_os" in
+gnu*)
+  settrans -a $bootdir /hurd/ext2fs $image
+  umount="settrans -a $bootdir"
+  ;;
+
+linux*)
+  # This requires running as root, and using the loop device.
+  i=0
+  while test -e /dev/loop$i; do
+    if /sbin/losetup /dev/loop$i $image; then
+      break
+    fi
+    i=`expr $i + 1`
+  done
+
+  # Silly losetup doesn't report an error!
+  mount /dev/loop$i $bootdir
+  umount="umount $bootdir && /sbin/losetup -d /dev/loop$i && trap '' 0"
+  ;;
+
+*)
+  echo "$progname: Mounting \`$image' under \`$host_os' is not supported" 1>&2
+  exit 1
+  ;;
+esac
+trap "$umount" 0
+
+# Extract our tarball into the image, then unmount it.
+echo "# Copying files into \`$image':"
+tar -zxvf $bootdir.tar.gz
+
+echo "# \`$image' usage:"
+df $bootdir
+eval $umount
+rmdir $bootdir || :
+
+# Use the GRUB shell to properly set up GRUB on the image.
+echo "# Installing GRUB in \`$image'"
+cat <<EOF | $grub_shell --batch --device-map=/dev/null
+device (fd0) $image
+root (fd0)
+install /boot/grub/stage1 (fd0) /boot/grub/stage2
+quit
+EOF
+
+exit 0
diff --git a/util/grub-image.in b/util/grub-image.in
new file mode 100644
index 0000000..ea63250
--- /dev/null
+++ b/util/grub-image.in
@@ -0,0 +1,138 @@
+#! /bin/sh
+# grub-image - Create a GRUB boot filesystem image and tarball
+# Gordon Matzigkeit <gord@fig.org>, 2000-07-25
+#
+#   Copyright (C) 2000, 2002 Free Software Foundation, Inc.
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libdir=@libdir@
+PACKAGE=@PACKAGE@
+host_cpu=@host_cpu@
+host_os=@host_os@
+host_vendor=@host_vendor@
+context=${host_cpu}-${host_vendor}
+pkglibdir=${libdir}/${PACKAGE}/${context}
+
+mke2fs=`which mke2fs`
+
+progname=`echo "$0" | sed 's%^.*/%%'`
+thisdir=`echo "$0" | sed 's%/[^/]*$%%'`
+test "X$thisdir" = "X$0" && thisdir=.
+
+# See if we were invoked from within the build directory, and if so,
+# use the built files rather than the installed ones.
+if test -f $thisdir/../stage2/stage2; then
+  grub_shell="$thisdir/../grub/grub"
+  stage1dir="$thisdir/../stage1"
+  stage2dir="$thisdir/../stage2"
+else
+  grub_shell=${sbindir}/grub
+  stage1dir="$pkglibdir"
+  stage2dir="$pkglibdir"
+fi
+
+# Exit on any error.
+set -e
+
+# Get GRUB's version from the Grub shell, since we use the
+# installed files.
+VERSION=`$grub_shell --version | sed -e 's/^.* \([0-9.]*\).*$/\1/'`
+test "X$VERSION" != X
+
+bootdir=${PACKAGE}-${VERSION}-${context}
+image=$bootdir.ext2fs
+
+# Create the tarball.
+if test ! -f $bootdir.tar.gz; then
+  echo "# Creating \`$bootdir.tar.gz'"
+  mkdir -p $bootdir/boot/grub
+  cp -p $stage1dir/stage1 $stage2dir/*_stage1_5 $stage2dir/stage2 \
+    $bootdir/boot/grub
+  test ! -f menu.lst || cp -p menu.lst $bootdir/boot/grub
+  trap "rm -f $bootdir.tar.gz" 0
+  GZIP=-9 tar -zcf $bootdir.tar.gz $bootdir
+  trap '' 0
+  rm -rf $bootdir
+fi
+
+# Create a new filesystem image of the specified size.
+if test ! -f $image; then
+  tarsize=`zcat $bootdir.tar.gz | wc -c`
+
+  # Add about 30% (20% overhead plus 10% breathing room), and convert
+  # to kilobytes.  This factor was determined empirically.
+  SIZE=`expr $tarsize \* 130 / 100 / 1024`k
+  echo "# Creating $SIZE disk image \`$image'"
+  trap "rm -f $image" 0
+  dd if=/dev/zero of=$image bs=$SIZE count=1 >/dev/null
+  $mke2fs -F $image
+  trap '' 0
+fi
+
+
+# Attempt to mount the image.
+echo "# Mounting \`$image'"
+test -d $bootdir || mkdir $bootdir
+case "$host_os" in
+gnu*)
+  settrans -a $bootdir /hurd/ext2fs $image
+  umount="settrans -a $bootdir"
+  ;;
+
+linux*)
+  # This requires running as root, and using the loop device.
+  i=0
+  while test -e /dev/loop$i; do
+    if /sbin/losetup /dev/loop$i $image; then
+      break
+    fi
+    i=`expr $i + 1`
+  done
+
+  # Silly losetup doesn't report an error!
+  mount /dev/loop$i $bootdir
+  umount="umount $bootdir && /sbin/losetup -d /dev/loop$i && trap '' 0"
+  ;;
+
+*)
+  echo "$progname: Mounting \`$image' under \`$host_os' is not supported" 1>&2
+  exit 1
+  ;;
+esac
+trap "$umount" 0
+
+# Extract our tarball into the image, then unmount it.
+echo "# Copying files into \`$image':"
+tar -zxvf $bootdir.tar.gz
+
+echo "# \`$image' usage:"
+df $bootdir
+eval $umount
+rmdir $bootdir || :
+
+# Use the GRUB shell to properly set up GRUB on the image.
+echo "# Installing GRUB in \`$image'"
+cat <<EOF | $grub_shell --batch --device-map=/dev/null
+device (fd0) $image
+root (fd0)
+install /boot/grub/stage1 (fd0) /boot/grub/stage2
+quit
+EOF
+
+exit 0
diff --git a/util/grub-install b/util/grub-install
new file mode 100644
index 0000000..2f71070
--- /dev/null
+++ b/util/grub-install
@@ -0,0 +1,477 @@
+#! /bin/sh
+
+# Install GRUB on your drive.
+#   Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Initialize some variables.
+prefix=/usr/local
+exec_prefix=${prefix}
+sbindir=${exec_prefix}/sbin
+libdir=${exec_prefix}/lib
+PACKAGE=grub
+VERSION=0.97
+host_cpu=x86_64
+host_os=linux-gnu
+host_vendor=unknown
+pkglibdir=${libdir}/${PACKAGE}/${host_cpu}-${host_vendor}
+
+grub_shell=${sbindir}/grub
+grub_set_default=${sbindir}/grub-set-default
+log_file=/tmp/grub-install.log.$$
+img_file=/tmp/grub-install.img.$$
+rootdir=
+grub_prefix=/boot/grub
+
+install_device=
+no_floppy=
+force_lba=
+recheck=no
+debug=no
+
+# look for secure tempfile creation wrappers on this platform
+if test -x /bin/tempfile; then
+    mklog="/bin/tempfile --prefix=grub"
+    mkimg="/bin/tempfile --prefix=grub"
+elif test -x /bin/mktemp; then
+    mklog="/bin/mktemp /tmp/grub-install.log.XXXXXX"
+    mkimg="/bin/mktemp /tmp/grub-install.img.XXXXXX"
+else
+    mklog=""
+    mkimg=""
+fi
+
+# Usage: usage
+# Print the usage.
+usage () {
+    cat <<EOF
+Usage: grub-install [OPTION] install_device
+Install GRUB on your drive.
+
+  -h, --help              print this message and exit
+  -v, --version           print the version information and exit
+  --root-directory=DIR    install GRUB images under the directory DIR
+                          instead of the root directory
+  --grub-shell=FILE       use FILE as the grub shell
+  --no-floppy             do not probe any floppy drive
+  --force-lba             force GRUB to use LBA mode even for a buggy
+                          BIOS
+  --recheck               probe a device map even if it already exists
+
+INSTALL_DEVICE can be a GRUB device name or a system device filename.
+
+grub-install copies GRUB images into the DIR/boot directory specfied by
+--root-directory, and uses the grub shell to install grub into the boot
+sector.
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+}
+
+# Usage: convert os_device
+# Convert an OS device to the corresponding GRUB drive.
+# This part is OS-specific.
+convert () {
+    # First, check if the device file exists.
+    if test -e "$1"; then
+	:
+    else
+	echo "$1: Not found or not a block device." 1>&2
+	exit 1
+    fi
+
+    # Break the device name into the disk part and the partition part.
+    case "$host_os" in
+    linux*)
+	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%' \
+				  -e 's%/part[0-9]*$%/disc%' \
+				  -e 's%\(c[0-7]d[0-9]*\).*$%\1%'`
+	tmp_part=`echo "$1" | sed -e 's%.*/[sh]d[a-z]\([0-9]*\)$%\1%' \
+				  -e 's%.*d[0-9]*p%%' \
+				  -e 's%.*/fd[0-9]*$%%' \
+				  -e 's%.*/floppy/[0-9]*$%%' \
+				  -e 's%.*/\(disc\|part\([0-9]*\)\)$%\2%' \
+				  -e 's%.*c[0-7]d[0-9]*p%%'`
+	;;
+    gnu*)
+	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_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%"`
+	;;
+    netbsd* | knetbsd*-gnu)
+	tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([sw]d[0-9]*\).*$%r\1d%' \
+	    | sed 's%r\{0,1\}\(fd[0-9]*\).*$%r\1a%'`
+	tmp_part=`echo "$1" \
+	    | sed "s%.*/r\{0,1\}[sw]d[0-9]\([abe-p]\)%\1%"`
+	;;
+    *)
+	echo "grub-install does not support your OS yet." 1>&2
+	exit 1 ;;
+    esac
+
+    # Get the drive name.
+    tmp_drive=`grep -v '^#' $device_map | grep "$tmp_disk *$" \
+	| sed 's%.*\(([hf]d[0-9][a-g0-9,]*)\).*%\1%'`
+
+    # If not found, print an error message and exit.
+    if test "x$tmp_drive" = x; then
+	echo "$1 does not have any corresponding BIOS drive." 1>&2
+	exit 1
+    fi
+
+    if test "x$tmp_part" != x; then
+	# If a partition is specified, we need to translate it into the
+	# GRUB's syntax.
+	case "$host_os" in
+	linux*)
+	    echo "$tmp_drive" | sed "s%)$%,`expr $tmp_part - 1`)%" ;;
+	gnu*)
+	    if echo $tmp_part | grep "^s" >/dev/null; then
+		tmp_pc_slice=`echo $tmp_part \
+		    | sed "s%s\([0-9]*\)[a-g]*$%\1%"`
+		tmp_drive=`echo "$tmp_drive" \
+		    | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
+	    fi
+	    if echo $tmp_part | grep "[a-g]$" >/dev/null; then
+		tmp_bsd_partition=`echo "$tmp_part" \
+		    | sed "s%[^a-g]*\([a-g]\)$%\1%"`
+		tmp_drive=`echo "$tmp_drive" \
+		    | sed "s%)%,$tmp_bsd_partition)%"`
+	    fi
+	    echo "$tmp_drive" ;;
+	freebsd* | kfreebsd*-gnu)
+	    if echo $tmp_part | grep "^s" >/dev/null; then
+		tmp_pc_slice=`echo $tmp_part \
+		    | sed "s%s\([0-9]*\)[a-h]*$%\1%"`
+		tmp_drive=`echo "$tmp_drive" \
+		    | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
+	    fi
+	    if echo $tmp_part | grep "[a-h]$" >/dev/null; then
+		tmp_bsd_partition=`echo "$tmp_part" \
+		    | sed "s%s\{0,1\}[0-9]*\([a-h]\)$%\1%"`
+		tmp_drive=`echo "$tmp_drive" \
+		    | sed "s%)%,$tmp_bsd_partition)%"`
+	    fi
+	    echo "$tmp_drive" ;;
+	netbsd* | knetbsd*-gnu)
+	    if echo $tmp_part | grep "^[abe-p]$" >/dev/null; then
+		tmp_bsd_partition=`echo "$tmp_part" \
+		    | sed "s%\([a-p]\)$%\1%"`
+		tmp_drive=`echo "$tmp_drive" \
+		    | sed "s%)%,$tmp_bsd_partition)%"`
+	    fi
+	    echo "$tmp_drive" ;;
+	esac
+    else
+	# If no partition is specified, just print the drive name.
+	echo "$tmp_drive"
+    fi
+}
+
+# Usage: resolve_symlink file
+# Find the real file/device that file points at
+resolve_symlink () {
+	tmp_fname=$1
+	# Resolve symlinks
+	while test -L $tmp_fname; do
+		tmp_new_fname=`ls -al $tmp_fname | sed -n 's%.*-> \(.*\)%\1%p'`
+		if test -z "$tmp_new_fname"; then
+			echo "Unrecognized ls output" 2>&1
+			exit 1
+		fi
+
+		# Convert relative symlinks
+		case $tmp_new_fname in
+			/*) tmp_fname="$tmp_new_fname"
+			;;
+			*) tmp_fname="`echo $tmp_fname | sed 's%/[^/]*$%%'`/$tmp_new_fname"
+			;;
+		esac
+	done
+	echo "$tmp_fname"
+}
+
+# Usage: find_device file
+# Find block device on which the file resides.
+find_device () {
+    # For now, this uses the program `df' to get the device name, but is
+    # this really portable?
+    tmp_fname=`df $1/ | sed -n 's%.*\(/dev/[^ 	]*\).*%\1%p'`
+
+    if test -z "$tmp_fname"; then
+	echo "Could not find device for $1" 2>&1
+	exit 1
+    fi
+
+	tmp_fname=`resolve_symlink $tmp_fname`
+
+    echo "$tmp_fname"
+}
+
+# Check the arguments.
+for option in "$@"; do
+    case "$option" in
+    -h | --help)
+	usage
+	exit 0 ;;
+    -v | --version)
+	echo "grub-install (GNU GRUB ${VERSION})"
+	exit 0 ;;
+    --root-directory=*)
+	rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
+    --grub-shell=*)
+	grub_shell=`echo "$option" | sed 's/--grub-shell=//'` ;;
+    --no-floppy)
+	no_floppy="--no-floppy" ;;
+    --force-lba)
+	force_lba="--force-lba" ;;
+    --recheck)
+	recheck=yes ;;
+    # This is an undocumented feature...
+    --debug)
+	debug=yes ;;
+    -*)
+	echo "Unrecognized option \`$option'" 1>&2
+	usage
+	exit 1
+	;;
+    *)
+	if test "x$install_device" != x; then
+	    echo "More than one install_devices?" 1>&2
+	    usage
+	    exit 1
+	fi
+	install_device="${option}" ;;
+    esac
+done
+
+if test "x$install_device" = x; then
+    echo "install_device not specified." 1>&2
+    usage
+    exit 1
+fi
+
+# If the debugging feature is enabled, print commands.
+if test $debug = yes; then
+    set -x
+fi
+
+# Initialize these directories here, since ROOTDIR was initialized.
+case "$host_os" in
+netbsd* | openbsd*)
+    # Because /boot is used for the boot block in NetBSD and OpenBSD, use /grub
+    # instead of /boot/grub.
+    grub_prefix=/grub
+    bootdir=${rootdir}
+    ;;
+*)
+    # Use /boot/grub by default.
+    bootdir=${rootdir}/boot
+    ;;
+esac
+
+grubdir=${bootdir}/grub
+device_map=${grubdir}/device.map
+
+# Check if GRUB is installed.
+# This is necessary, because the user can specify "grub --read-only".
+set $grub_shell dummy
+if test -f "$1"; then
+    :
+else
+    echo "$1: Not found." 1>&2
+    exit 1
+fi
+
+if test -f "$pkglibdir/stage1"; then
+    :
+else
+    echo "${pkglibdir}/stage1: Not found." 1>&2
+    exit 1
+fi
+
+if test -f "$pkglibdir/stage2"; then
+    :
+else
+    echo "${pkglibdir}/stage2: Not found." 1>&2
+    exit 1
+fi
+
+# Don't check for *stage1_5, because it is not fatal even if any
+# Stage 1.5 does not exist.
+
+# Create the GRUB directory if it is not present.
+test -d "$bootdir" || mkdir "$bootdir" || exit 1
+test -d "$grubdir" || mkdir "$grubdir" || exit 1
+
+# If --recheck is specified, remove the device map, if present.
+if test $recheck = yes; then
+    rm -f $device_map
+fi
+
+# Create the device map file if it is not present.
+if test -f "$device_map"; then
+    :
+else
+    # Create a safe temporary file.
+    test -n "$mklog" && log_file=`$mklog`
+
+    $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
+quit
+EOF
+    if grep "Error [0-9]*: " $log_file >/dev/null; then
+	cat $log_file 1>&2
+	exit 1
+    fi
+
+    rm -f $log_file
+fi
+
+# Make sure that there is no duplicated entry.
+tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' $device_map \
+    | sort | uniq -d | sed -n 1p`
+if test -n "$tmp"; then
+    echo "The drive $tmp is defined multiple times in the device map $device_map" 1>&2
+    exit 1
+fi
+
+# Check for INSTALL_DEVICE.
+case "$install_device" in
+/dev/*)
+    install_device=`resolve_symlink "$install_device"`
+    install_drive=`convert "$install_device"`
+    # I don't know why, but some shells wouldn't die if exit is
+    # called in a function.
+    if test "x$install_drive" = x; then
+	exit 1
+    fi ;;
+\([hf]d[0-9]*\))
+    install_drive="$install_device" ;;
+[hf]d[0-9]*)
+    # The GRUB format with no parenthesis.
+    install_drive="($install_device)" ;;
+*)
+    echo "Format of install_device not recognized." 1>&2
+    usage
+    exit 1 ;;
+esac
+
+# Get the root drive.
+root_device=`find_device ${rootdir}`
+bootdir_device=`find_device ${bootdir}`
+
+# Check if the boot directory is in the same device as the root directory.
+if test "x$root_device" != "x$bootdir_device"; then
+    # Perhaps the user has a separate boot partition.
+    root_device=$bootdir_device
+    grub_prefix="/grub"
+fi
+
+# Convert the root device to a GRUB drive.
+root_drive=`convert "$root_device"`
+if test "x$root_drive" = x; then
+    exit 1
+fi
+
+# Check if the root directory exists in the same device as the grub
+# directory.
+grubdir_device=`find_device ${grubdir}`
+
+if test "x$grubdir_device" != "x$root_device"; then
+    # For now, cannot deal with this situation.
+    cat <<EOF 1>&2
+You must set the root directory by the option --root-directory, because
+$grubdir does not exist in the root device $root_device.
+EOF
+    exit 1
+fi
+
+# Copy the GRUB images to the GRUB directory.
+for file in ${grubdir}/stage1 ${grubdir}/stage2 ${grubdir}/*stage1_5; do
+    rm -f $file || exit 1
+done
+for file in \
+    ${pkglibdir}/stage1 ${pkglibdir}/stage2 ${pkglibdir}/*stage1_5; do
+    cp -f $file ${grubdir} || exit 1
+done
+
+# Make a default file.
+${grub_set_default} --root-directory=${rootdir} default
+
+# Make sure that GRUB reads the same images as the host OS.
+test -n "$mkimg" && img_file=`$mkimg`
+test -n "$mklog" && log_file=`$mklog`
+
+for file in ${grubdir}/stage1 ${grubdir}/stage2 ${grubdir}/*stage1_5; do
+    count=5
+    tmp=`echo $file | sed "s|^${grubdir}|${grub_prefix}|"`
+    while test $count -gt 0; do
+	$grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
+dump ${root_drive}${tmp} ${img_file}
+quit
+EOF
+	if grep "Error [0-9]*: " $log_file >/dev/null; then
+	    :
+	elif cmp $file $img_file >/dev/null; then
+	    break
+	fi
+	sleep 1
+	count=`expr $count - 1`    
+    done
+    if test $count -eq 0; then
+	echo "The file $file not read correctly." 1>&2
+	exit 1
+    fi
+done
+
+rm -f $img_file
+rm -f $log_file
+
+# Create a safe temporary file.
+test -n "$mklog" && log_file=`$mklog`
+
+# Now perform the installation.
+$grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
+root $root_drive
+setup $force_lba --stage2=$grubdir/stage2 --prefix=$grub_prefix $install_drive
+quit
+EOF
+
+if grep "Error [0-9]*: " $log_file >/dev/null || test $debug = yes; then
+    cat $log_file 1>&2
+    exit 1
+fi
+
+rm -f $log_file
+
+# Prompt the user to check if the device map is correct.
+echo "Installation finished. No error reported."
+echo "This is the contents of the device map $device_map."
+echo "Check if this is correct or not. If any of the lines is incorrect,"
+echo "fix it and re-run the script \`grub-install'."
+echo
+
+cat $device_map
+
+# Bye.
+exit 0
diff --git a/util/grub-install.in b/util/grub-install.in
new file mode 100644
index 0000000..2e598b0
--- /dev/null
+++ b/util/grub-install.in
@@ -0,0 +1,477 @@
+#! /bin/sh
+
+# Install GRUB on your drive.
+#   Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Initialize some variables.
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+libdir=@libdir@
+PACKAGE=@PACKAGE@
+VERSION=@VERSION@
+host_cpu=@host_cpu@
+host_os=@host_os@
+host_vendor=@host_vendor@
+pkglibdir=${libdir}/${PACKAGE}/${host_cpu}-${host_vendor}
+
+grub_shell=${sbindir}/grub
+grub_set_default=${sbindir}/grub-set-default
+log_file=/tmp/grub-install.log.$$
+img_file=/tmp/grub-install.img.$$
+rootdir=
+grub_prefix=/boot/grub
+
+install_device=
+no_floppy=
+force_lba=
+recheck=no
+debug=no
+
+# look for secure tempfile creation wrappers on this platform
+if test -x /bin/tempfile; then
+    mklog="/bin/tempfile --prefix=grub"
+    mkimg="/bin/tempfile --prefix=grub"
+elif test -x /bin/mktemp; then
+    mklog="/bin/mktemp /tmp/grub-install.log.XXXXXX"
+    mkimg="/bin/mktemp /tmp/grub-install.img.XXXXXX"
+else
+    mklog=""
+    mkimg=""
+fi
+
+# Usage: usage
+# Print the usage.
+usage () {
+    cat <<EOF
+Usage: grub-install [OPTION] install_device
+Install GRUB on your drive.
+
+  -h, --help              print this message and exit
+  -v, --version           print the version information and exit
+  --root-directory=DIR    install GRUB images under the directory DIR
+                          instead of the root directory
+  --grub-shell=FILE       use FILE as the grub shell
+  --no-floppy             do not probe any floppy drive
+  --force-lba             force GRUB to use LBA mode even for a buggy
+                          BIOS
+  --recheck               probe a device map even if it already exists
+
+INSTALL_DEVICE can be a GRUB device name or a system device filename.
+
+grub-install copies GRUB images into the DIR/boot directory specfied by
+--root-directory, and uses the grub shell to install grub into the boot
+sector.
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+}
+
+# Usage: convert os_device
+# Convert an OS device to the corresponding GRUB drive.
+# This part is OS-specific.
+convert () {
+    # First, check if the device file exists.
+    if test -e "$1"; then
+	:
+    else
+	echo "$1: Not found or not a block device." 1>&2
+	exit 1
+    fi
+
+    # Break the device name into the disk part and the partition part.
+    case "$host_os" in
+    linux*)
+	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%' \
+				  -e 's%/part[0-9]*$%/disc%' \
+				  -e 's%\(c[0-7]d[0-9]*\).*$%\1%'`
+	tmp_part=`echo "$1" | sed -e 's%.*/[sh]d[a-z]\([0-9]*\)$%\1%' \
+				  -e 's%.*d[0-9]*p%%' \
+				  -e 's%.*/fd[0-9]*$%%' \
+				  -e 's%.*/floppy/[0-9]*$%%' \
+				  -e 's%.*/\(disc\|part\([0-9]*\)\)$%\2%' \
+				  -e 's%.*c[0-7]d[0-9]*p%%'`
+	;;
+    gnu*)
+	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_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%"`
+	;;
+    netbsd* | knetbsd*-gnu)
+	tmp_disk=`echo "$1" | sed 's%r\{0,1\}\([sw]d[0-9]*\).*$%r\1d%' \
+	    | sed 's%r\{0,1\}\(fd[0-9]*\).*$%r\1a%'`
+	tmp_part=`echo "$1" \
+	    | sed "s%.*/r\{0,1\}[sw]d[0-9]\([abe-p]\)%\1%"`
+	;;
+    *)
+	echo "grub-install does not support your OS yet." 1>&2
+	exit 1 ;;
+    esac
+
+    # Get the drive name.
+    tmp_drive=`grep -v '^#' $device_map | grep "$tmp_disk *$" \
+	| sed 's%.*\(([hf]d[0-9][a-g0-9,]*)\).*%\1%'`
+
+    # If not found, print an error message and exit.
+    if test "x$tmp_drive" = x; then
+	echo "$1 does not have any corresponding BIOS drive." 1>&2
+	exit 1
+    fi
+
+    if test "x$tmp_part" != x; then
+	# If a partition is specified, we need to translate it into the
+	# GRUB's syntax.
+	case "$host_os" in
+	linux*)
+	    echo "$tmp_drive" | sed "s%)$%,`expr $tmp_part - 1`)%" ;;
+	gnu*)
+	    if echo $tmp_part | grep "^s" >/dev/null; then
+		tmp_pc_slice=`echo $tmp_part \
+		    | sed "s%s\([0-9]*\)[a-g]*$%\1%"`
+		tmp_drive=`echo "$tmp_drive" \
+		    | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
+	    fi
+	    if echo $tmp_part | grep "[a-g]$" >/dev/null; then
+		tmp_bsd_partition=`echo "$tmp_part" \
+		    | sed "s%[^a-g]*\([a-g]\)$%\1%"`
+		tmp_drive=`echo "$tmp_drive" \
+		    | sed "s%)%,$tmp_bsd_partition)%"`
+	    fi
+	    echo "$tmp_drive" ;;
+	freebsd* | kfreebsd*-gnu)
+	    if echo $tmp_part | grep "^s" >/dev/null; then
+		tmp_pc_slice=`echo $tmp_part \
+		    | sed "s%s\([0-9]*\)[a-h]*$%\1%"`
+		tmp_drive=`echo "$tmp_drive" \
+		    | sed "s%)%,\`expr "$tmp_pc_slice" - 1\`)%"`
+	    fi
+	    if echo $tmp_part | grep "[a-h]$" >/dev/null; then
+		tmp_bsd_partition=`echo "$tmp_part" \
+		    | sed "s%s\{0,1\}[0-9]*\([a-h]\)$%\1%"`
+		tmp_drive=`echo "$tmp_drive" \
+		    | sed "s%)%,$tmp_bsd_partition)%"`
+	    fi
+	    echo "$tmp_drive" ;;
+	netbsd* | knetbsd*-gnu)
+	    if echo $tmp_part | grep "^[abe-p]$" >/dev/null; then
+		tmp_bsd_partition=`echo "$tmp_part" \
+		    | sed "s%\([a-p]\)$%\1%"`
+		tmp_drive=`echo "$tmp_drive" \
+		    | sed "s%)%,$tmp_bsd_partition)%"`
+	    fi
+	    echo "$tmp_drive" ;;
+	esac
+    else
+	# If no partition is specified, just print the drive name.
+	echo "$tmp_drive"
+    fi
+}
+
+# Usage: resolve_symlink file
+# Find the real file/device that file points at
+resolve_symlink () {
+	tmp_fname=$1
+	# Resolve symlinks
+	while test -L $tmp_fname; do
+		tmp_new_fname=`ls -al $tmp_fname | sed -n 's%.*-> \(.*\)%\1%p'`
+		if test -z "$tmp_new_fname"; then
+			echo "Unrecognized ls output" 2>&1
+			exit 1
+		fi
+
+		# Convert relative symlinks
+		case $tmp_new_fname in
+			/*) tmp_fname="$tmp_new_fname"
+			;;
+			*) tmp_fname="`echo $tmp_fname | sed 's%/[^/]*$%%'`/$tmp_new_fname"
+			;;
+		esac
+	done
+	echo "$tmp_fname"
+}
+
+# Usage: find_device file
+# Find block device on which the file resides.
+find_device () {
+    # For now, this uses the program `df' to get the device name, but is
+    # this really portable?
+    tmp_fname=`df $1/ | sed -n 's%.*\(/dev/[^ 	]*\).*%\1%p'`
+
+    if test -z "$tmp_fname"; then
+	echo "Could not find device for $1" 2>&1
+	exit 1
+    fi
+
+	tmp_fname=`resolve_symlink $tmp_fname`
+
+    echo "$tmp_fname"
+}
+
+# Check the arguments.
+for option in "$@"; do
+    case "$option" in
+    -h | --help)
+	usage
+	exit 0 ;;
+    -v | --version)
+	echo "grub-install (GNU GRUB ${VERSION})"
+	exit 0 ;;
+    --root-directory=*)
+	rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
+    --grub-shell=*)
+	grub_shell=`echo "$option" | sed 's/--grub-shell=//'` ;;
+    --no-floppy)
+	no_floppy="--no-floppy" ;;
+    --force-lba)
+	force_lba="--force-lba" ;;
+    --recheck)
+	recheck=yes ;;
+    # This is an undocumented feature...
+    --debug)
+	debug=yes ;;
+    -*)
+	echo "Unrecognized option \`$option'" 1>&2
+	usage
+	exit 1
+	;;
+    *)
+	if test "x$install_device" != x; then
+	    echo "More than one install_devices?" 1>&2
+	    usage
+	    exit 1
+	fi
+	install_device="${option}" ;;
+    esac
+done
+
+if test "x$install_device" = x; then
+    echo "install_device not specified." 1>&2
+    usage
+    exit 1
+fi
+
+# If the debugging feature is enabled, print commands.
+if test $debug = yes; then
+    set -x
+fi
+
+# Initialize these directories here, since ROOTDIR was initialized.
+case "$host_os" in
+netbsd* | openbsd*)
+    # Because /boot is used for the boot block in NetBSD and OpenBSD, use /grub
+    # instead of /boot/grub.
+    grub_prefix=/grub
+    bootdir=${rootdir}
+    ;;
+*)
+    # Use /boot/grub by default.
+    bootdir=${rootdir}/boot
+    ;;
+esac
+
+grubdir=${bootdir}/grub
+device_map=${grubdir}/device.map
+
+# Check if GRUB is installed.
+# This is necessary, because the user can specify "grub --read-only".
+set $grub_shell dummy
+if test -f "$1"; then
+    :
+else
+    echo "$1: Not found." 1>&2
+    exit 1
+fi
+
+if test -f "$pkglibdir/stage1"; then
+    :
+else
+    echo "${pkglibdir}/stage1: Not found." 1>&2
+    exit 1
+fi
+
+if test -f "$pkglibdir/stage2"; then
+    :
+else
+    echo "${pkglibdir}/stage2: Not found." 1>&2
+    exit 1
+fi
+
+# Don't check for *stage1_5, because it is not fatal even if any
+# Stage 1.5 does not exist.
+
+# Create the GRUB directory if it is not present.
+test -d "$bootdir" || mkdir "$bootdir" || exit 1
+test -d "$grubdir" || mkdir "$grubdir" || exit 1
+
+# If --recheck is specified, remove the device map, if present.
+if test $recheck = yes; then
+    rm -f $device_map
+fi
+
+# Create the device map file if it is not present.
+if test -f "$device_map"; then
+    :
+else
+    # Create a safe temporary file.
+    test -n "$mklog" && log_file=`$mklog`
+
+    $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
+quit
+EOF
+    if grep "Error [0-9]*: " $log_file >/dev/null; then
+	cat $log_file 1>&2
+	exit 1
+    fi
+
+    rm -f $log_file
+fi
+
+# Make sure that there is no duplicated entry.
+tmp=`sed -n '/^([fh]d[0-9]*)/s/\(^(.*)\).*/\1/p' $device_map \
+    | sort | uniq -d | sed -n 1p`
+if test -n "$tmp"; then
+    echo "The drive $tmp is defined multiple times in the device map $device_map" 1>&2
+    exit 1
+fi
+
+# Check for INSTALL_DEVICE.
+case "$install_device" in
+/dev/*)
+    install_device=`resolve_symlink "$install_device"`
+    install_drive=`convert "$install_device"`
+    # I don't know why, but some shells wouldn't die if exit is
+    # called in a function.
+    if test "x$install_drive" = x; then
+	exit 1
+    fi ;;
+\([hf]d[0-9]*\))
+    install_drive="$install_device" ;;
+[hf]d[0-9]*)
+    # The GRUB format with no parenthesis.
+    install_drive="($install_device)" ;;
+*)
+    echo "Format of install_device not recognized." 1>&2
+    usage
+    exit 1 ;;
+esac
+
+# Get the root drive.
+root_device=`find_device ${rootdir}`
+bootdir_device=`find_device ${bootdir}`
+
+# Check if the boot directory is in the same device as the root directory.
+if test "x$root_device" != "x$bootdir_device"; then
+    # Perhaps the user has a separate boot partition.
+    root_device=$bootdir_device
+    grub_prefix="/grub"
+fi
+
+# Convert the root device to a GRUB drive.
+root_drive=`convert "$root_device"`
+if test "x$root_drive" = x; then
+    exit 1
+fi
+
+# Check if the root directory exists in the same device as the grub
+# directory.
+grubdir_device=`find_device ${grubdir}`
+
+if test "x$grubdir_device" != "x$root_device"; then
+    # For now, cannot deal with this situation.
+    cat <<EOF 1>&2
+You must set the root directory by the option --root-directory, because
+$grubdir does not exist in the root device $root_device.
+EOF
+    exit 1
+fi
+
+# Copy the GRUB images to the GRUB directory.
+for file in ${grubdir}/stage1 ${grubdir}/stage2 ${grubdir}/*stage1_5; do
+    rm -f $file || exit 1
+done
+for file in \
+    ${pkglibdir}/stage1 ${pkglibdir}/stage2 ${pkglibdir}/*stage1_5; do
+    cp -f $file ${grubdir} || exit 1
+done
+
+# Make a default file.
+${grub_set_default} --root-directory=${rootdir} default
+
+# Make sure that GRUB reads the same images as the host OS.
+test -n "$mkimg" && img_file=`$mkimg`
+test -n "$mklog" && log_file=`$mklog`
+
+for file in ${grubdir}/stage1 ${grubdir}/stage2 ${grubdir}/*stage1_5; do
+    count=5
+    tmp=`echo $file | sed "s|^${grubdir}|${grub_prefix}|"`
+    while test $count -gt 0; do
+	$grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
+dump ${root_drive}${tmp} ${img_file}
+quit
+EOF
+	if grep "Error [0-9]*: " $log_file >/dev/null; then
+	    :
+	elif cmp $file $img_file >/dev/null; then
+	    break
+	fi
+	sleep 1
+	count=`expr $count - 1`    
+    done
+    if test $count -eq 0; then
+	echo "The file $file not read correctly." 1>&2
+	exit 1
+    fi
+done
+
+rm -f $img_file
+rm -f $log_file
+
+# Create a safe temporary file.
+test -n "$mklog" && log_file=`$mklog`
+
+# Now perform the installation.
+$grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file
+root $root_drive
+setup $force_lba --stage2=$grubdir/stage2 --prefix=$grub_prefix $install_drive
+quit
+EOF
+
+if grep "Error [0-9]*: " $log_file >/dev/null || test $debug = yes; then
+    cat $log_file 1>&2
+    exit 1
+fi
+
+rm -f $log_file
+
+# Prompt the user to check if the device map is correct.
+echo "Installation finished. No error reported."
+echo "This is the contents of the device map $device_map."
+echo "Check if this is correct or not. If any of the lines is incorrect,"
+echo "fix it and re-run the script \`grub-install'."
+echo
+
+cat $device_map
+
+# Bye.
+exit 0
diff --git a/util/grub-md5-crypt b/util/grub-md5-crypt
new file mode 100644
index 0000000..aaed7c4
--- /dev/null
+++ b/util/grub-md5-crypt
@@ -0,0 +1,99 @@
+#! /bin/sh
+
+# Encrypt a password in MD5 format
+#   Copyright (C) 2000,2002 Free Software Foundation, Inc.
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Replaced by the configure script.
+prefix=/usr/local
+exec_prefix=${prefix}
+sbindir=${exec_prefix}/sbin
+
+# Initialize some variables.
+grub_shell=${sbindir}/grub
+progname="grub-md5-crypt"
+
+# Check the arguments.
+for option in "$@"; do
+    case "$option" in
+    -h | --help)
+	cat <<EOF
+Usage: $progname [OPTION]
+Encrypt a password in MD5 format.
+
+  -h, --help              print this message and exit
+  -v, --version           print the version information and exit
+  --grub-shell=FILE       use FILE as the grub shell
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+	exit 0
+	;;
+
+    -v | --version)
+	echo "$progname (GNU GRUB ${VERSION})"
+	exit 0
+	;;
+
+    --grub-shell=*)
+	grub_shell=`echo "$option" | sed 's/--grub-shell=//'`
+	;;
+
+    *)
+	echo "$progname: unrecognized option \`$option'"
+	echo "Usage: $progname [OPTION]"
+	echo "Try \`$progname --help' for more information."
+	exit 1
+	;;
+    esac
+done
+
+# Suppress echo backs. I don't know if this is really portable. -okuji
+stty -echo
+
+# Prompt to enter a password.
+echo -n "Password: "
+read -r password
+echo
+
+# One more time.
+echo -n "Retype password: "
+read -r password2
+echo
+
+# Resume echo backs.
+stty echo
+
+if test "x$password" = x; then
+    echo "Empty password is not permitted."
+    exit 1
+fi
+
+if test "x$password" != "x$password2"; then
+    echo "Sorry, passwords do not match."
+    exit 1
+fi
+
+# Run the grub shell.
+$grub_shell --batch --device-map=/dev/null <<EOF \
+    | grep "^Encrypted: " | sed 's/^Encrypted: //'
+md5crypt
+$password
+quit
+EOF
+
+# Bye.
+exit 0
diff --git a/util/grub-md5-crypt.in b/util/grub-md5-crypt.in
new file mode 100644
index 0000000..c030c87
--- /dev/null
+++ b/util/grub-md5-crypt.in
@@ -0,0 +1,99 @@
+#! /bin/sh
+
+# Encrypt a password in MD5 format
+#   Copyright (C) 2000,2002 Free Software Foundation, Inc.
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Replaced by the configure script.
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+sbindir=@sbindir@
+
+# Initialize some variables.
+grub_shell=${sbindir}/grub
+progname="grub-md5-crypt"
+
+# Check the arguments.
+for option in "$@"; do
+    case "$option" in
+    -h | --help)
+	cat <<EOF
+Usage: $progname [OPTION]
+Encrypt a password in MD5 format.
+
+  -h, --help              print this message and exit
+  -v, --version           print the version information and exit
+  --grub-shell=FILE       use FILE as the grub shell
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+	exit 0
+	;;
+
+    -v | --version)
+	echo "$progname (GNU GRUB ${VERSION})"
+	exit 0
+	;;
+
+    --grub-shell=*)
+	grub_shell=`echo "$option" | sed 's/--grub-shell=//'`
+	;;
+
+    *)
+	echo "$progname: unrecognized option \`$option'"
+	echo "Usage: $progname [OPTION]"
+	echo "Try \`$progname --help' for more information."
+	exit 1
+	;;
+    esac
+done
+
+# Suppress echo backs. I don't know if this is really portable. -okuji
+stty -echo
+
+# Prompt to enter a password.
+echo -n "Password: "
+read -r password
+echo
+
+# One more time.
+echo -n "Retype password: "
+read -r password2
+echo
+
+# Resume echo backs.
+stty echo
+
+if test "x$password" = x; then
+    echo "Empty password is not permitted."
+    exit 1
+fi
+
+if test "x$password" != "x$password2"; then
+    echo "Sorry, passwords do not match."
+    exit 1
+fi
+
+# Run the grub shell.
+$grub_shell --batch --device-map=/dev/null <<EOF \
+    | grep "^Encrypted: " | sed 's/^Encrypted: //'
+md5crypt
+$password
+quit
+EOF
+
+# Bye.
+exit 0
diff --git a/util/grub-set-default b/util/grub-set-default
new file mode 100644
index 0000000..ec3e8b7
--- /dev/null
+++ b/util/grub-set-default
@@ -0,0 +1,114 @@
+#! /bin/sh
+
+# Set a default boot entry for GRUB
+#   Copyright (C) 2004 Free Software Foundation, Inc.
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Initialize some variables.
+PACKAGE=grub
+VERSION=0.97
+
+rootdir=
+entry=
+
+# Usage: usage
+# Print the usage.
+usage () {
+    cat <<EOF
+Usage: grub-set-default [OPTION] entry
+Set the default boot entry for GRUB.
+
+  -h, --help              print this message and exit
+  -v, --version           print the version information and exit
+  --root-directory=DIR    Use the directory DIR instead of the root directory
+
+ENTRY is a number or the special keyword \`default\'.
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+}
+
+# Check the arguments.
+for option in "$@"; do
+    case "$option" in
+    -h | --help)
+	usage
+	exit 0 ;;
+    -v | --version)
+	echo "grub-set-default (GNU GRUB ${VERSION})"
+	exit 0 ;;
+    --root-directory=*)
+	rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
+    -*)
+	echo "Unrecognized option \`$option'" 1>&2
+	usage
+	exit 1
+	;;
+    *)
+	if test "x$entry" != x; then
+	    echo "More than one entries?" 1>&2
+	    usage
+	    exit 1
+	fi
+	# We don't care about what the user specified actually.
+	entry="${option}" ;;
+    esac
+done
+
+if test "x$entry" = x; then
+    echo "entry not specified." 1>&2
+    usage
+    exit 1
+fi
+
+# Determine the GRUB directory. This is different among OSes.
+grubdir=${rootdir}/boot/grub
+if test -d ${grubdir}; then
+    :
+else
+    grubdir=${rootdir}/grub
+    if test -d ${grubdir}; then
+	:
+    else
+	echo "No GRUB directory found under ${rootdir}/" 1>&2
+	exit 1
+    fi
+fi
+
+file=${grubdir}/default
+if test -f ${file}; then
+    chmod 0600 ${file}
+    rm -f ${file}
+fi
+cat <<EOF > $file
+$entry
+#
+#
+#
+#
+#
+#
+#
+#
+#
+#
+# WARNING: If you want to edit this file directly, do not remove any line
+# from this file, including this warning. Using \`grub-set-default\' is
+# strongly recommended.
+EOF
+
+# Bye.
+exit 0
diff --git a/util/grub-set-default.in b/util/grub-set-default.in
new file mode 100644
index 0000000..dc5b783
--- /dev/null
+++ b/util/grub-set-default.in
@@ -0,0 +1,114 @@
+#! /bin/sh
+
+# Set a default boot entry for GRUB
+#   Copyright (C) 2004 Free Software Foundation, Inc.
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Initialize some variables.
+PACKAGE=@PACKAGE@
+VERSION=@VERSION@
+
+rootdir=
+entry=
+
+# Usage: usage
+# Print the usage.
+usage () {
+    cat <<EOF
+Usage: grub-set-default [OPTION] entry
+Set the default boot entry for GRUB.
+
+  -h, --help              print this message and exit
+  -v, --version           print the version information and exit
+  --root-directory=DIR    Use the directory DIR instead of the root directory
+
+ENTRY is a number or the special keyword \`default\'.
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+}
+
+# Check the arguments.
+for option in "$@"; do
+    case "$option" in
+    -h | --help)
+	usage
+	exit 0 ;;
+    -v | --version)
+	echo "grub-set-default (GNU GRUB ${VERSION})"
+	exit 0 ;;
+    --root-directory=*)
+	rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
+    -*)
+	echo "Unrecognized option \`$option'" 1>&2
+	usage
+	exit 1
+	;;
+    *)
+	if test "x$entry" != x; then
+	    echo "More than one entries?" 1>&2
+	    usage
+	    exit 1
+	fi
+	# We don't care about what the user specified actually.
+	entry="${option}" ;;
+    esac
+done
+
+if test "x$entry" = x; then
+    echo "entry not specified." 1>&2
+    usage
+    exit 1
+fi
+
+# Determine the GRUB directory. This is different among OSes.
+grubdir=${rootdir}/boot/grub
+if test -d ${grubdir}; then
+    :
+else
+    grubdir=${rootdir}/grub
+    if test -d ${grubdir}; then
+	:
+    else
+	echo "No GRUB directory found under ${rootdir}/" 1>&2
+	exit 1
+    fi
+fi
+
+file=${grubdir}/default
+if test -f ${file}; then
+    chmod 0600 ${file}
+    rm -f ${file}
+fi
+cat <<EOF > $file
+$entry
+#
+#
+#
+#
+#
+#
+#
+#
+#
+#
+# WARNING: If you want to edit this file directly, do not remove any line
+# from this file, including this warning. Using \`grub-set-default\' is
+# strongly recommended.
+EOF
+
+# Bye.
+exit 0
diff --git a/util/grub-terminfo b/util/grub-terminfo
new file mode 100644
index 0000000..7c2d1bc
--- /dev/null
+++ b/util/grub-terminfo
@@ -0,0 +1,95 @@
+#! /bin/sh
+# Generate a terminfo command from a terminfo name.
+#
+# Copyright (C) 2002  Free Software Foundation, Inc.
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+VERSION=0.97
+
+usage () {
+    cat <<EOF
+Usage: grub-terminfo TERMNAME
+Generate a terminfo command from a terminfo name.
+
+  -h, --help              print this message and exit
+  -v, --version           print the version information and exit
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+}
+
+error () {
+    echo "grub-terminfo: error: $1" 1>&2
+}
+
+termname=
+
+for option in "$@"; do
+    case "$option" in
+    -h | --help)
+        usage
+	exit 0 ;;
+    -v | --version)
+	echo "grub-terminfo (GNU GRUB ${VERSION})"
+	exit 0 ;;
+    -*)
+	error "Unrecognized option \`$option'"
+	usage
+	exit 1 ;;
+    *)
+	if test "x$termname" != x; then
+	    error "More than one terminfo names?"
+	    usage
+	    exit 1
+	fi
+	termname="$option" ;;
+    esac
+done
+
+if test "x$termname" = x; then
+    error "termname not specified"
+    usage
+    exit 1
+fi
+
+get_seq () {
+    infocmp -L -1 -g $termname | sed -n -e "/$1/s/^[^=]*=\\(.*\\),\$/\\1/p"
+}
+
+cursor_address="`get_seq cursor_address`"
+if test "x$cursor_address" = x; then
+    error "cursor_address not found"
+    exit 1
+fi
+cursor_address="--cursor-address=$cursor_address"
+
+clear_screen="`get_seq clear_screen`"
+if test "x$clear_screen" != x; then
+    clear_screen="--clear-screen=$clear_screen"
+fi
+
+enter_standout_mode="`get_seq enter_standout_mode`"
+if test "x$enter_standout_mode" != x; then
+    enter_standout_mode="--enter-standout-mode=$enter_standout_mode"
+fi
+
+exit_standout_mode="`get_seq exit_standout_mode`"
+if test "x$exit_standout_mode" != x; then
+    exit_standout_mode="--exit-standout-mode=$exit_standout_mode"
+fi
+
+echo "terminfo --name=$termname" $cursor_address $clear_screen \
+    $enter_standout_mode $exit_standout_mode
diff --git a/util/grub-terminfo.in b/util/grub-terminfo.in
new file mode 100644
index 0000000..e41b418
--- /dev/null
+++ b/util/grub-terminfo.in
@@ -0,0 +1,95 @@
+#! /bin/sh
+# Generate a terminfo command from a terminfo name.
+#
+# Copyright (C) 2002  Free Software Foundation, Inc.
+#
+# This file 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+VERSION=@VERSION@
+
+usage () {
+    cat <<EOF
+Usage: grub-terminfo TERMNAME
+Generate a terminfo command from a terminfo name.
+
+  -h, --help              print this message and exit
+  -v, --version           print the version information and exit
+
+Report bugs to <bug-grub@gnu.org>.
+EOF
+}
+
+error () {
+    echo "grub-terminfo: error: $1" 1>&2
+}
+
+termname=
+
+for option in "$@"; do
+    case "$option" in
+    -h | --help)
+        usage
+	exit 0 ;;
+    -v | --version)
+	echo "grub-terminfo (GNU GRUB ${VERSION})"
+	exit 0 ;;
+    -*)
+	error "Unrecognized option \`$option'"
+	usage
+	exit 1 ;;
+    *)
+	if test "x$termname" != x; then
+	    error "More than one terminfo names?"
+	    usage
+	    exit 1
+	fi
+	termname="$option" ;;
+    esac
+done
+
+if test "x$termname" = x; then
+    error "termname not specified"
+    usage
+    exit 1
+fi
+
+get_seq () {
+    infocmp -L -1 -g $termname | sed -n -e "/$1/s/^[^=]*=\\(.*\\),\$/\\1/p"
+}
+
+cursor_address="`get_seq cursor_address`"
+if test "x$cursor_address" = x; then
+    error "cursor_address not found"
+    exit 1
+fi
+cursor_address="--cursor-address=$cursor_address"
+
+clear_screen="`get_seq clear_screen`"
+if test "x$clear_screen" != x; then
+    clear_screen="--clear-screen=$clear_screen"
+fi
+
+enter_standout_mode="`get_seq enter_standout_mode`"
+if test "x$enter_standout_mode" != x; then
+    enter_standout_mode="--enter-standout-mode=$enter_standout_mode"
+fi
+
+exit_standout_mode="`get_seq exit_standout_mode`"
+if test "x$exit_standout_mode" != x; then
+    exit_standout_mode="--exit-standout-mode=$exit_standout_mode"
+fi
+
+echo "terminfo --name=$termname" $cursor_address $clear_screen \
+    $enter_standout_mode $exit_standout_mode
diff --git a/util/mbchk.c b/util/mbchk.c
new file mode 100644
index 0000000..fd71858
--- /dev/null
+++ b/util/mbchk.c
@@ -0,0 +1,244 @@
+/* mbchk - a simple checker for the format of a Multiboot kernel */
+/*
+ *  Copyright (C) 1999,2001,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.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <multiboot.h>
+
+static int quiet = 0;
+static char *optstring = "hvq";
+static struct option longopts[] =
+{
+  {"help", no_argument, 0, 'h'},
+  {"version", no_argument, 0, 'v'},
+  {"quiet", no_argument, 0, 'q'},
+  {0}
+};
+
+static void
+usage (int status)
+{
+  if (status)
+    fprintf (stderr, "Try ``mbchk --help'' for more information.\n");
+  else
+    printf ("Usage: mbchk [OPTION]... [FILE]...\n"
+	    "Check if the format of FILE complies with the Multiboot Specification.\n"
+	    "\n"
+	    "-q, --quiet                suppress all normal output\n"
+	    "-h, --help                 display this help and exit\n"
+	    "-v, --version              output version information and exit.\n"
+	    "\n"
+	    "Report bugs to <bug-grub@gnu.org>.\n");
+
+  exit (status);
+}
+
+static int
+check_multiboot (const char *filename, FILE *fp)
+{
+  multiboot_header_t *mbh = 0;
+  int i;
+  char buf[8192];
+
+  if (fread (buf, 1, 8192, fp) < 0)
+    {
+      fprintf (stderr, "%s: Read error.\n", filename);
+      return 0;
+    }
+
+  for (i = 0; i < 8192 - sizeof (multiboot_header_t); i++)
+    {
+      unsigned long magic = *((unsigned long *) (buf + i));
+
+      if (magic == MULTIBOOT_HEADER_MAGIC)
+	{
+	  mbh = (multiboot_header_t *) (buf + i);
+	  break;
+	}
+    }
+
+  if (! mbh)
+    {
+      fprintf (stderr, "%s: No Multiboot header.\n", filename);
+      return 0;
+    }
+
+  if (! quiet)
+    printf ("%s: The Multiboot header is found at the offset %d.\n",
+	    filename, i);
+
+  /* Check for the checksum.  */
+  if (mbh->magic + mbh->flags + mbh->checksum != 0)
+    {
+      fprintf (stderr,
+	       "%s: Bad checksum (0x%lx).\n",
+	       filename, mbh->checksum);
+      return 0;
+    }
+
+  /* Reserved flags must be zero.  */
+  if (mbh->flags & ~0x00010003)
+    {
+      fprintf (stderr,
+	       "%s: Non-zero is found in reserved flags (0x%lx).\n",
+	       filename, mbh->flags);
+      return 0;
+    }
+
+  if (! quiet)
+    {
+      printf ("%s: Page alignment is turned %s.\n",
+	      filename, (mbh->flags & 0x1)? "on" : "off");
+      printf ("%s: Memory information is turned %s.\n",
+	      filename, (mbh->flags & 0x2)? "on" : "off");
+      printf ("%s: Address fields is turned %s.\n",
+	      filename, (mbh->flags & 0x10000)? "on" : "off");
+    }
+
+  /* Check for the address fields.  */
+  if (mbh->flags & 0x10000)
+    {
+      if (mbh->header_addr < mbh->load_addr)
+	{
+	  fprintf (stderr,
+		   "%s: header_addr is less than "
+		   "load_addr (0x%lx > 0x%lx).\n",
+		   filename, mbh->header_addr, mbh->load_addr);
+	  return 0;
+	}
+
+      if (mbh->load_end_addr && mbh->load_addr >= mbh->load_end_addr)
+	{
+	  fprintf (stderr,
+		   "%s: load_addr is not less than load_end_addr"
+		   " (0x%lx >= 0x%lx).\n",
+		   filename, mbh->load_addr, mbh->load_end_addr);
+	  return 0;
+	}
+
+      if (mbh->bss_end_addr && mbh->load_end_addr > mbh->bss_end_addr)
+	{
+	  fprintf (stderr,
+		   "%s: load_end_addr is greater than bss_end_addr"
+		   " (0x%lx > 0x%lx).\n",
+		   filename, mbh->load_end_addr, mbh->bss_end_addr);
+	  return 0;
+	}
+
+      if (mbh->load_addr > mbh->entry_addr)
+	{
+	  fprintf (stderr,
+		   "%s: load_addr is greater than entry_addr"
+		   " (0x%lx > 0x%lx).\n",
+		   filename, mbh->load_addr, mbh->entry_addr);
+	  return 0;
+	}
+
+      /* FIXME: It is better to check if the entry address is within the
+	 file, especially when the load end address is zero.  */
+      if (mbh->load_end_addr && mbh->load_end_addr <= mbh->entry_addr)
+	{
+	  fprintf (stderr,
+		   "%s: load_end_addr is not greater than entry_addr"
+		   " (0x%lx <= 0x%lx).\n",
+		   filename, mbh->load_end_addr, mbh->entry_addr);
+	  return 0;
+	}
+
+      /* This is a GRUB-specific limitation.  */
+      if (mbh->load_addr < 0x100000)
+	{
+	  fprintf (stderr,
+		   "%s: Cannot be loaded at less than 1MB by GRUB"
+		   " (0x%lx).\n",
+		   filename, mbh->load_addr);
+	  return 0;
+	}
+    }
+
+  if (! quiet)
+    printf ("%s: All checks passed.\n", filename);
+
+  return 1;
+}
+
+int
+main (int argc, char *argv[])
+{
+  int c;
+
+  do
+    {
+      c = getopt_long (argc, argv, optstring, longopts, 0);
+      switch (c)
+	{
+	case EOF:
+	  break;
+
+	case 'h':
+	  usage (0);
+	  break;
+
+	case 'v':
+	  printf ("mbchk (GNU GRUB " VERSION ")\n");
+	  exit (0);
+	  break;
+
+	case 'q':
+	  quiet = 1;
+	  break;
+
+	default:
+	  usage (1);
+	  break;
+	}
+    }
+  while (c != EOF);
+
+  if (optind < argc)
+    {
+      while (optind < argc)
+	{
+	  FILE *fp;
+
+	  fp = fopen (argv[optind], "r");
+	  if (! fp)
+	    {
+	      fprintf (stderr, "%s: No such file.\n", argv[optind]);
+	      exit (1);
+	    }
+
+	  if (! check_multiboot (argv[optind], fp))
+	    exit (1);
+
+	  fclose (fp);
+	  optind++;
+	}
+    }
+  else
+    {
+      if (! check_multiboot ("<stdin>", stdin))
+	exit (1);
+    }
+
+  return 0;
+}
diff --git a/util/mkbimage b/util/mkbimage
new file mode 100644
index 0000000..689f694
--- /dev/null
+++ b/util/mkbimage
@@ -0,0 +1,417 @@
+#!/bin/sh
+# MaKe a Bootable IMAGE --- 1.44, 2.88 and El Torito no-emulation mode
+# C) 2001,2002,2003 Thierry Laronde <tlaronde@polynum.org>
+# C) 2001,2002,2003 Robert Millan <robertmh@gnu.org>
+
+
+# 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, you can either send email to this
+# program's maintainer or write to: The Free Software Foundation,
+# Inc.; 59 Temple Place, Suite 330; Boston, MA 02111-1307, USA.
+
+# $Id: mkbimage,v 1.19 2004/07/21 14:43:04 robertmh Exp $
+
+# Global variables
+tarfile=
+dir=
+fs= #file system type
+decompress=
+image_type=
+uname=`uname -s`
+PATH=/sbin:$PATH
+
+# You can set GRUB_PATH  if you need to use a specially located GRUB.
+# This MUST end by a '/'!
+
+
+#----------------------------DON'T CHANGE: INTERNALS
+
+block_size=512
+cylinders=
+heads=
+sectors=
+cyl_size=
+type_option=
+geo_option=
+image=
+bk_120=$((2 * 15 * 80))
+bk_144=$((2 * 18 * 80))
+bk_288=$((2 * 36 * 80))
+bk_160=$((2 * 20 * 80))
+bk_168=$((2 * 21 * 80))
+bk_174=$((2 * 21 * 83))
+lo_options=
+device_map=
+mkfs_options=
+debug=
+stage2_os_name=
+
+# Name by which this script was invoked.
+program=`echo "$0" | sed -e 's/[^\/]*\///g'`
+version_number='$Revision: 1.19 $'
+
+usage="
+Usage: $program [-hVF] [-t TYPE] [-d DIRECTORY] [-s FS_TYPE] -f TAR_FILE
+Make a Bootable IMAGE using GRUB as a bootloader
+
+Options:
+ Actions:
+ -d DIRECTORY [default CWD]
+	    Directory where the boot.image and the partition subdirectories
+	    are/will be created
+ -f TAR_FILE
+	    Name of the tar file containing the filesystem to install. Can
+	    be a pure tar file [.tar] or a compressed tar file
+	    [.tar.gz|.tar.bz2]
+ -s FS_TYPE
+	    Type of the file system to create on the virtual disk. Choices 
+	    are:
+		ext2 on GNU [default is ext2]
+		ext2, minix or msdos on GNU/Linux [default is ext2]
+
+ -t TYPE
+	    Type of the image to create. Choices are '1.20', '1.44', '1.60',
+	    '1.68', '1.74', '2.88' or 'hd' [default is hd]
+ -F
+	    Force to set the set_dpt flag (unnecessary 99% of the time! Be
+	    careful! 
+ Informations:
+ -D     
+	    turn Debugging on [xtrace]
+ -h|--help	
+	    display this Help and exit
+ -V|--version	
+	    display Version information and exit
+
+Copyright (c) 2001,2002,2003 Thierry Laronde <tlaronde@polynum.org>. 
+Copyright (c) 2001,2002 Robert Millan <zeratul2@wanadoo.es>.
+GPLed."
+
+version="mkbimage $version_number
+
+Written by Thierry Laronde and Robert Millan.
+
+Copyright (c) 2001,2002,2003 Thierry Laronde <tlaronde@polynum.org>.
+Copyright (c) 2001,2002,2003 Robert Millan <zeratul2@wanadoo.es>.
+
+This is free software under the GPL version 2 or later; see the source for 
+copying conditions.  There is NO warranty, not even for MERCHANTABILITY or 
+FITNESS FOR A PARTICULAR PURPOSE."
+
+# Functions
+
+error ()
+{
+	case $1 in
+	bug) echo "This is a bug!";
+		echo "$usage";;
+	option) echo "Unknow option"; echo "$usage";;
+	missing_argument) echo "You must give an argument to the option!";
+		echo "$usage";;
+	missing_option) echo "You must indicate at least one option!";
+		echo "$usage";;
+	must_be_root) echo "You must be root! (or install e2tools/mtools)";;
+	unknown_fs)	if [ $uname = Linux ];
+				then echo "The GNU/Linux supported fs are: ext2, minix or msdos!";
+			elif [ $uname = GNU ];
+				then echo "The GNU supported fs is ext2!";
+			fi;;
+	unknown_format) echo "The tar file must be .tar|.tar.gz|.tar.bz2!";;
+	wont_fit) echo "The files won't fit on the selected type of media!";;
+	wrong_directory) echo "Directory inexistant or not given!";
+		echo "$usage";;
+	wrong_file) echo "File inexistant or empty!";
+		echo "$usage";;
+	wrong_type) echo "The type specified is not a valid one!";
+		echo "$usage";;
+	esac	
+	exit 1
+}
+
+# create a filesystem of type $fs in $image with offset $offset
+mkbimage_mkfs ()
+{
+  case $offset in
+    0)  lo_options="";;
+    *) lo_options="-o $offset";;
+  esac
+
+  if [ "$offset" = "0" ] ; then
+    mkfs.$fs -F $image
+  elif [ `id -u` = "0" ] ; then
+    losetup $lo_options /dev/loop1 $image
+    mkfs.$fs /dev/loop1
+    losetup -d /dev/loop1
+  else
+    error must_be_root
+  fi
+}
+
+# copy ${image}1/* to ${image}:/, assuming ${image} contains a filesystem
+# of type $fs in offset $offset
+mkbimage_cp ()
+{
+  case $offset in
+    0)  lo_options="";;
+    *)  lo_options="-o $offset";;
+  esac
+  case $fs in
+    ext2)
+      cp="e2cp";
+      mkdir="e2mkdir";;
+    vfat)
+      cp="mcopy";
+      mkdir="mmd";;
+    *)
+      cp="";
+      mkdir="";;
+  esac
+
+  if [ "$offset" = 0 ] && which $cp > /dev/null ; then
+    for dir in $(cd ${image}1 && find -type d) ; do
+	$mkdir ${image}:$dir
+    done
+    for file in $(cd ${image}1 && find -type f) ; do
+	$cp ${image}1/$file ${image}:$file
+    done
+  elif [ "`id -u`" = "0" ] ; then
+    losetup $lo_options /dev/loop1 $image
+    mkdir ${image}.mnt
+    mount -t $fs /dev/loop1 ${image}.mnt
+    cp -a ${image}1/* ${image}.mnt/ && sync
+    umount ${image}.mnt
+    rmdir ${image}.mnt
+    losetup -d /dev/loop1
+  else
+    error must_be_root
+  fi
+}
+
+#**********************************************************************
+#                          MAIN PROGRAM                               *
+#**********************************************************************
+
+#---------------------- Getting the options
+
+[ $# -eq 0 ] && error missing_option;
+
+while [ $# -gt 0 ]; do
+	case "$1" in
+		-d) shift;
+			dir="$1";
+			[ ! -d "$1" ] && error wrong_directory;;
+		-f) shift;
+			tarfile="$1";
+			[ -z "$tarfile" ] && error missing_argument;;
+		-s) shift;
+			fs="$1";;
+		-t) shift;
+			image_type="$1";;
+		-F) geo_option="-F";;
+		-D) debug="-v";
+		    set -x;;
+		-h|--help) echo "$usage"; exit 0;;
+		-V|--version) echo "$version"; exit 0;;
+	 	*) error option ;;
+	esac
+shift	
+done
+#---------------------- Sanity checks
+[ ! "$tarfile" ] && error missing_argument;
+[ ! -s "$tarfile" ] && error wrong_file;
+
+if [ ! "$image_type" ]; then
+	image_type=hd;
+elif [ "$image_type" != "1.20" ] && [ "$image_type" != "1.44" ] \
+  && [ "$image_type" != "1.60" ] && [ "$image_type" != "1.68" ] \
+  && [ "$image_type" != "2.88" ] && [ "$image_type" != "1.74" ] \
+  && [ "$image_type" != "hd" ] && [ "$image_type" != "1.60" ] ; then
+  error wrong_type ;
+fi
+
+[ ! "$fs" ] && fs=ext2
+
+# Carlo Contavalli reported that I [TL] have forgotten to specify the
+# partition ID for sfdisk to correctly fill the partition table (ext2 is the
+# default on Linux, so this worked in this case...). This is fixed below.
+case "$fs" in
+	ext2) mkfs_options="-m 0";
+		  part_id="83";; # This is the default
+#	ufs)	if [ $uname = Linux ];
+#		then error unknown_fs;
+#		fi;;
+	minix)	if [ $uname = GNU ];
+		then error unknown_fs;
+		else 
+			mkfs_options="-v"; # Minix version 2
+			part_id="81";
+		fi;;
+	msdos)	if [ $uname = GNU ];
+		then error unknown_fs;
+		else 
+			mkfs_options="-f 1 -F 12"; # the smallest...
+			part_id="1"; 
+		fi;;
+	*) error unknown_fs;;
+esac
+
+# What type of tar file has been given ?
+
+suffix=`echo "$tarfile" | sed -n 's/^.*\.\([targbz2]\{2,3\}\)$/\1/p'`
+case "$suffix" in
+	tar) decompress="cat";;
+	gz) decompress="gunzip -c";;
+	bz2) decompress="bunzip2 -c";;
+	*) error unknown_format;;
+esac
+#---------------------- Initializations
+
+[ ! "$dir" ] && dir=`pwd`
+
+image=$dir/$image_type.image
+device_map=$dir/device.map
+
+# First, find the size of the tar file in block_size.
+file_size=`$decompress $tarfile | wc -c | tr -d ' '`
+file_size=$(($file_size / $block_size + 1))
+
+# Increase in order to be sure that with a fs there will be enough
+# room (trying 110%)
+file_size=$(($file_size + $file_size / 10))
+
+case "$image_type" in
+  hd) heads=16;
+    sectors=63;
+    cyl_size=$((16 * 63));
+    # Create the minimum number of cylinders. At the moment, we leave
+    # some space by rounding everything up by adding 1 cylinder, plus
+    # another one for MBR + reserved track.
+    cylinders=$(($file_size / $cyl_size + 2));; 
+  1.20) [ $file_size -ge $bk_120 ] && error wont_fit; 
+    heads=2;
+    sectors=15;
+    cyl_size=$((2 * 15));
+    cylinders=80;;
+  1.44) [ $file_size -ge $bk_144 ] && error wont_fit; 
+    heads=2;
+    sectors=18;
+    cyl_size=$((2 * 18));
+    cylinders=80;;
+  1.60) [ $file_size -ge $bk_160 ] && error wont_fit; 
+    heads=2;
+    sectors=20;
+    cyl_size=$((2 * 20));
+    cylinders=80;
+    geo_option="-F";;
+  1.68) [ $file_size -ge $bk_168 ] && error wont_fit; 
+    heads=2;
+    sectors=21;
+    cyl_size=$((2 * 21));
+    cylinders=80;;
+  1.74) [ $file_size -ge $bk_174 ] && error wont_fit; 
+    heads=2;
+    sectors=21;
+    cyl_size=$((2 * 21));
+    cylinders=83;;
+  2.88) [ $file_size -ge $bk_288 ] && error wont_fit;
+    heads=2;
+    sectors=36;
+    cyl_size=$((2 * 36));
+    cylinders=80;;
+  *) error bug;;
+esac
+
+type_option="-t $image_type"
+
+# We start by creating a virtual disk which size is the number of
+# cylinders of $cyl_size mandatory to put the files stocked in the $tarfile
+# Create the empty virtual disk
+dd if=/dev/zero of=$image bs=$block_size count=$(($cyl_size * $cylinders))
+
+# We then format the virtual disk
+# NOTE: the El Torito specification wants only one partition. So we
+# create the first, and the remaining 3 entries are empty.
+
+if [ "$image_type" = "hd" ]; then
+  sfdisk -C $cylinders -H $heads -S $sectors -D $image<<EOT
+,,$part_id,*,0,1,1
+
+
+EOT
+  offset="$(($sectors * $block_size))" 
+  type_option=
+else
+  offset="0"
+fi
+
+# It's time now to create the filesystem on the first partition.
+mkbimage_mkfs
+
+# then untar the files
+[ ! -e ${image}1 ] || { echo "${image}1 exists, please remove it first"; exit 1;}
+mkdir -p ${image}1
+$decompress $tarfile | tar -C ${image}1 $debug -xf -
+
+# copy the untarred files into the filesystem image
+mkbimage_cp
+
+#We verify that the stage2 exists and we search the name
+stage2_os_name=`find ${image}1 -name stage2 -type f`
+
+[ -r "$stage2_os_name" ] || { echo "I can't find stage2!"; exit 1;}
+
+#------------------------- GRUB stuff
+if [ "$image_type" = "hd" ]; then
+	device='(hd0)'
+	root='(hd0,0)'
+else
+	device='(fd0)'
+	root='(fd0)'
+fi
+
+cat<<EOT >$device_map
+$device	${image}
+EOT
+
+${GRUB_PATH}grub --device-map=$device_map --batch<<EOT
+geometry $device $cylinders $heads $sectors
+root $root
+setup $device
+geometry $geo_option -w $type_option $device $cylinders $heads $sectors
+EOT
+
+echo "-------------------WHAT'S NEXT?-------------------------------------"
+echo
+
+cat <<EOF
+If you have created an image aimed to a floppy, then something like:
+
+dd if=<type>.image of=/dev/fd0[u<size>] bs=512
+
+will be more than enough... if you have formated the floppy correctly
+using \`superformat' to be found in \`fdutils' package.
+
+For El Torito floppy emulation :
+
+mkisofs -b <image> -c boot.catalog -o raw.iso <dir>
+
+And for El Torito Hard Disk emulation:
+
+mkisofs -b <image> -hard-disk-boot -c boot.catalog -o raw.iso <dir> 
+
+Enjoy!
+EOF
+
+rm -rf ${image}1
+
+exit 0