aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:29:32 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:29:32 -0800
commit5b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4 (patch)
treef46d6b23eaeeaf5a28396d258ee29eb4c1580749
parentf5050cedfb9a8ad5a08e9038ca23ee6a8892495e (diff)
downloadgrub-5b1eb061628a97aae48a9c0bcaa96eb0bfa07aa4.tar.gz
-rw-r--r--AUTHORS54
-rw-r--r--Android.mk192
-rw-r--r--BUGS7
-rw-r--r--COPYING340
-rw-r--r--ChangeLog9075
-rw-r--r--INSTALL266
-rw-r--r--MAINTENANCE60
-rw-r--r--MODULE_LICENSE_GPL0
-rw-r--r--Makefile.am4
-rw-r--r--Makefile.in605
-rw-r--r--NEWS558
-rw-r--r--README23
-rw-r--r--THANKS123
-rw-r--r--TODO102
-rw-r--r--acinclude.m4366
-rw-r--r--aclocal.m41061
-rw-r--r--android.lst0
-rwxr-xr-xcompile142
-rwxr-xr-xconfig.guess1453
-rw-r--r--config.h107
-rw-r--r--config.h.in106
-rw-r--r--config.log957
-rwxr-xr-xconfig.status1248
-rwxr-xr-xconfig.sub1566
-rwxr-xr-xconfigure7639
-rw-r--r--configure.ac670
-rwxr-xr-xdepcomp522
-rw-r--r--docs/Makefile.am65
-rw-r--r--docs/Makefile.in770
-rw-r--r--docs/boot.S80
-rw-r--r--docs/boot.S.texi80
-rw-r--r--docs/grub-install.852
-rw-r--r--docs/grub-md5-crypt.832
-rw-r--r--docs/grub-terminfo.829
-rw-r--r--docs/grub.871
-rw-r--r--docs/grub.info4455
-rw-r--r--docs/grub.texi3984
-rwxr-xr-xdocs/help2man517
-rw-r--r--docs/internals.texi427
-rw-r--r--docs/kernel.c284
-rw-r--r--docs/kernel.c.texi284
-rw-r--r--docs/mbchk.127
-rwxr-xr-xdocs/mdate-sh170
-rw-r--r--docs/menu.lst82
-rw-r--r--docs/multiboot.h119
-rw-r--r--docs/multiboot.h.texi119
-rw-r--r--docs/multiboot.info1662
-rw-r--r--docs/multiboot.texi1234
-rw-r--r--docs/src2texi16
-rw-r--r--docs/stamp-vti4
-rw-r--r--docs/texinfo.tex7086
-rw-r--r--docs/version.texi4
-rw-r--r--grub/Makefile.am19
-rw-r--r--grub/Makefile.in445
-rw-r--r--grub/asmstub.c1275
-rw-r--r--grub/main.c265
-rwxr-xr-xinstall-sh323
-rw-r--r--lib/Makefile.am6
-rw-r--r--lib/Makefile.in416
-rw-r--r--lib/device.c915
-rw-r--r--lib/device.h48
-rw-r--r--lib/getopt.c1053
-rw-r--r--lib/getopt.h133
-rw-r--r--lib/getopt1.c190
-rwxr-xr-xmissing353
-rwxr-xr-xmkinstalldirs150
-rw-r--r--netboot/3c509.c620
-rw-r--r--netboot/3c509.h397
-rw-r--r--netboot/3c595.c503
-rw-r--r--netboot/3c595.h435
-rw-r--r--netboot/3c90x.c929
-rw-r--r--netboot/3c90x.txt307
-rw-r--r--netboot/Makefile.am219
-rw-r--r--netboot/Makefile.in1091
-rw-r--r--netboot/README.netboot168
-rw-r--r--netboot/cards.h183
-rw-r--r--netboot/config.c598
-rw-r--r--netboot/cs89x0.c659
-rw-r--r--netboot/cs89x0.h461
-rw-r--r--netboot/cs89x0.txt26
-rw-r--r--netboot/davicom.c692
-rw-r--r--netboot/depca.c752
-rw-r--r--netboot/eepro.c586
-rw-r--r--netboot/eepro100.c654
-rw-r--r--netboot/epic100.c481
-rw-r--r--netboot/epic100.h188
-rw-r--r--netboot/etherboot.h547
-rw-r--r--netboot/fa311.c421
-rw-r--r--netboot/fsys_tftp.c497
-rw-r--r--netboot/i82586.c825
-rw-r--r--netboot/lance.c564
-rw-r--r--netboot/linux-asm-io.h187
-rw-r--r--netboot/linux-asm-string.h291
-rw-r--r--netboot/main.c1171
-rw-r--r--netboot/misc.c266
-rw-r--r--netboot/natsemi.c739
-rw-r--r--netboot/ni5010.c371
-rw-r--r--netboot/nic.h31
-rw-r--r--netboot/ns8390.c835
-rw-r--r--netboot/ns8390.h238
-rw-r--r--netboot/osdep.h94
-rw-r--r--netboot/otulip.c374
-rw-r--r--netboot/otulip.h76
-rw-r--r--netboot/pci.c501
-rw-r--r--netboot/pci.h192
-rw-r--r--netboot/rtl8139.c458
-rw-r--r--netboot/sis900.c1034
-rw-r--r--netboot/sis900.h363
-rw-r--r--netboot/sis900.txt91
-rw-r--r--netboot/sk_g16.c1160
-rw-r--r--netboot/sk_g16.h168
-rw-r--r--netboot/smc9000.c522
-rw-r--r--netboot/smc9000.h205
-rw-r--r--netboot/tiara.c255
-rw-r--r--netboot/timer.c127
-rw-r--r--netboot/timer.h64
-rw-r--r--netboot/tlan.c3746
-rw-r--r--netboot/tulip.c1989
-rw-r--r--netboot/tulip.txt53
-rw-r--r--netboot/via-rhine.c1180
-rw-r--r--netboot/w89c840.c934
-rw-r--r--stage1/Makefile.am15
-rw-r--r--stage1/Makefile.in433
-rw-r--r--stage1/stage1.S499
-rw-r--r--stage1/stage1.h86
-rw-r--r--stage2/Makefile.am272
-rw-r--r--stage2/Makefile.in3250
-rw-r--r--stage2/apic.h72
-rw-r--r--stage2/apm.S125
-rw-r--r--stage2/asm.S2367
-rw-r--r--stage2/bios.c317
-rw-r--r--stage2/boot.c1020
-rw-r--r--stage2/builtins.c4939
-rw-r--r--stage2/char_io.c1283
-rw-r--r--stage2/cmdline.c257
-rw-r--r--stage2/common.c337
-rw-r--r--stage2/console.c62
-rw-r--r--stage2/defs.h94
-rw-r--r--stage2/dir.h147
-rw-r--r--stage2/disk_inode.h110
-rw-r--r--stage2/disk_inode_ffs.h101
-rw-r--r--stage2/disk_io.c1790
-rw-r--r--stage2/fat.h100
-rw-r--r--stage2/filesys.h165
-rw-r--r--stage2/freebsd.h95
-rw-r--r--stage2/fs.h457
-rw-r--r--stage2/fsys_ext2fs.c789
-rw-r--r--stage2/fsys_fat.c488
-rw-r--r--stage2/fsys_ffs.c310
-rw-r--r--stage2/fsys_iso9660.c442
-rw-r--r--stage2/fsys_jfs.c403
-rw-r--r--stage2/fsys_minix.c534
-rw-r--r--stage2/fsys_reiserfs.c1238
-rw-r--r--stage2/fsys_ufs2.c331
-rw-r--r--stage2/fsys_vstafs.c252
-rw-r--r--stage2/fsys_xfs.c624
-rw-r--r--stage2/gunzip.c1235
-rw-r--r--stage2/hercules.c186
-rw-r--r--stage2/hercules.h31
-rw-r--r--stage2/i386-elf.h237
-rw-r--r--stage2/imgact_aout.h158
-rw-r--r--stage2/iso9660.h206
-rw-r--r--stage2/jfs.h601
-rw-r--r--stage2/mb_header.h90
-rw-r--r--stage2/mb_info.h217
-rw-r--r--stage2/md5.c383
-rw-r--r--stage2/md5.h30
-rw-r--r--stage2/nbi.h33
-rw-r--r--stage2/nbloader.S121
-rw-r--r--stage2/pc_slice.h251
-rw-r--r--stage2/preset_menu.c22
-rw-r--r--stage2/pxeloader.S36
-rw-r--r--stage2/serial.c434
-rw-r--r--stage2/serial.h93
-rw-r--r--stage2/setjmp.S81
-rw-r--r--stage2/shared.h996
-rwxr-xr-xstage2/size_test54
-rw-r--r--stage2/smp-imps.c756
-rw-r--r--stage2/smp-imps.h208
-rw-r--r--stage2/stage1_5.c69
-rw-r--r--stage2/stage2.c1075
-rw-r--r--stage2/start.S409
-rw-r--r--stage2/start_eltorito.S326
-rw-r--r--stage2/term.h127
-rw-r--r--stage2/terminfo.c258
-rw-r--r--stage2/terminfo.h51
-rw-r--r--stage2/tparm.c726
-rw-r--r--stage2/tparm.h28
-rw-r--r--stage2/ufs2.h439
-rw-r--r--stage2/vstafs.h88
-rw-r--r--stage2/xfs.h544
-rw-r--r--stamp-h11
-rw-r--r--util/Makefile.am12
-rw-r--r--util/Makefile.in478
-rw-r--r--util/grub-image138
-rw-r--r--util/grub-image.in138
-rw-r--r--util/grub-install477
-rw-r--r--util/grub-install.in477
-rw-r--r--util/grub-md5-crypt99
-rw-r--r--util/grub-md5-crypt.in99
-rw-r--r--util/grub-set-default114
-rw-r--r--util/grub-set-default.in114
-rw-r--r--util/grub-terminfo95
-rw-r--r--util/grub-terminfo.in95
-rw-r--r--util/mbchk.c244
-rw-r--r--util/mkbimage417
206 files changed, 122409 insertions, 0 deletions
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
@@ -0,0 +1,4455 @@
+This is ../../docs/grub.info, produced by makeinfo version 4.8 from
+../../docs/grub.texi.
+
+INFO-DIR-SECTION Kernel
+START-INFO-DIR-ENTRY
+* 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-INFO-DIR-ENTRY
+
+ Copyright (C) 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 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.
+
+
+File: grub.info, Node: Top, Next: Introduction, Up: (dir)
+
+GRUB manual
+***********
+
+This is the documentation of GNU GRUB, the GRand Unified Bootloader, a
+flexible and powerful boot loader program for PCs.
+
+ This edition documents version 0.97.
+
+* 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::
+
+
+File: grub.info, Node: Introduction, Next: Naming convention, Prev: Top, Up: Top
+
+1 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
+
+
+File: grub.info, Node: Overview, Next: History, Up: Introduction
+
+1.1 Overview
+============
+
+Briefly, a "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 "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(1) (*note Overview-Footnote-1::). 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
+(*note Command-line interface::), or a menu interface (*note 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 (*note
+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 (*note Naming convention::) to GRUB, how to
+install GRUB on your drive (*note Installation::), and how to boot your
+OSes (*note Booting::), step by step.
+
+ Besides the GRUB boot loader itself, there is a "grub shell" `grub'
+(*note 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.
+
+
+File: grub.info, Node: Overview-Footnotes, Up: Overview
+
+ (1) "chain-load" is the mechanism for loading unsupported operating
+systems by loading another boot loader. It is typically used for
+loading DOS or Windows.
+
+
+File: grub.info, Node: History, Next: Features, Prev: Overview, Up: Introduction
+
+1.2 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
+(*note Multiboot Specification: (multiboot)Top.), 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. *Note Obtaining and Building
+GRUB::, for more information.
+
+
+File: grub.info, Node: Features, Next: Role of a boot loader, Prev: History, Up: Introduction
+
+1.3 GRUB features
+=================
+
+The primary requirement for GRUB is that it be compliant with the
+"Multiboot Specification", which is described in *Note Multiboot
+Specification: (multiboot)Top.
+
+ The other goals, listed in approximate order of importance, are:
+
+ * Basic functions must be straightforward for end-users.
+
+ * Rich functionality to support kernel experts and designers.
+
+ * 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.
+
+ Except for specific compatibility modes (chain-loading and the Linux
+"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):
+
+Recognize multiple executable formats
+ Support many of the "a.out" variants plus "ELF". Symbol tables are
+ also loaded.
+
+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.
+
+Load multiples modules
+ Fully support the Multiboot feature of loading multiple modules.
+
+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 (*note Commands::) are a superset of those
+ supported on the command-line. An example configuration file is
+ provided in *Note Configuration::.
+
+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.
+
+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 (*note Commands::) are a subset of those
+ supported for configuration files. Editing commands closely
+ resembles the Bash command-line (*note Bash: (features)Command
+ Line Editing.), with <TAB>-completion of commands, devices,
+ partitions, and files in a directory depending on context.
+
+Support multiple filesystem types
+ Support multiple filesystem types transparently, plus a useful
+ explicit blocklist notation. The currently supported filesystem
+ types are "BSD FFS", "DOS FAT16 and FAT32", "Minix fs", "Linux
+ ext2fs", "ReiserFS", "JFS", "XFS", and "VSTa fs". *Note
+ Filesystem::, for more information.
+
+Support automatic decompression
+ Can decompress files which were compressed by `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.(1) (*note
+ Features-Footnote-1::)
+
+ 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.
+
+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.
+
+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.
+
+Detect all installed RAM
+ GRUB can generally find all the installed RAM on a PC-compatible
+ machine. It uses an advanced BIOS query technique for finding all
+ memory regions. As described on the Multiboot Specification (*note
+ Multiboot Specification: (multiboot)Top.), not all kernels make
+ use of this information, but GRUB provides it for those who do.
+
+Support Logical Block Address mode
+ In traditional disk calls (called "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 ("LBA") mode. GRUB automatically detects if LBA mode is
+ available and uses it if available. In LBA mode, GRUB can access
+ the entire disk.
+
+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 "TFTP"
+ protocol.
+
+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.
+
+
+File: grub.info, Node: Features-Footnotes, Up: Features
+
+ (1) There are a few pathological cases where loading a very badly
+organized ELF kernel might take longer, but in practice this never
+happen.
+
+
+File: grub.info, Node: Role of a boot loader, Prev: Features, Up: Introduction
+
+1.4 The role of a boot loader
+=============================
+
+The following is a quotation from Gordon Matzigkeit, a GRUB fanatic:
+
+ 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
+ _boot loader_ is the most important software of all. I used to
+ refer to the above systems as either "LILO"(1) (*note Role of a
+ boot loader-Footnote-1::) 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... GRUB!
+
+ 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.
+
+
+File: grub.info, Node: Role of a boot loader-Footnotes, Up: Role of a boot loader
+
+ (1) The LInux LOader, a boot loader that everybody uses, but nobody
+likes.
+
+
+File: grub.info, Node: Naming convention, Next: Installation, Prev: Introduction, Up: Top
+
+2 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:
+
+ (fd0)
+
+ First of all, GRUB requires that the device name be enclosed with
+`(' and `)'. The `fd' part means that it is a floppy disk. The number
+`0' is the drive number, which is counted from _zero_. This expression
+means that GRUB will use the whole floppy disk.
+
+ (hd0,1)
+
+ Here, `hd' means it is a hard disk drive. The first integer `0'
+indicates the drive number, that is, the first hard disk, while the
+second integer, `1', indicates the partition number (or the PC slice
+number in the BSD terminology). Once again, please note that the
+partition numbers are counted from _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.
+
+ (hd0,4)
+
+ This specifies the first "extended partition" of the first hard disk
+drive. Note that the partition numbers for extended partitions are
+counted from `4', regardless of the actual number of primary partitions
+on your hard disk.
+
+ (hd1,a)
+
+ This means the BSD `a' partition of the second hard disk. If you
+need to specify which PC slice number should be used, use something
+like this: `(hd1,0,a)'. If the PC slice number is omitted, GRUB
+searches for the first PC slice which has a BSD `a' partition.
+
+ Of course, to actually access the disks or partitions with GRUB, you
+need to use the device specification in a command, like `root (fd0)' or
+`unhide (hd0,2)'. To help you find out which number specifies a
+partition you want, the GRUB command-line (*note Command-line
+interface::) options have argument completion. This means that, for
+example, you only need to type
+
+ root (
+
+ followed by a <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 _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:
+
+ (hd0,0)/vmlinuz
+
+ This specifies the file named `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.
+
+
+File: grub.info, Node: Installation, Next: Booting, Prev: Naming convention, Up: Top
+
+3 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
+(*note 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 `grub-install' (*note 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
+`/usr/lib/grub/i386-pc'. If you do not use grub-install, then you need
+to copy the files `stage1', `stage2', and `*stage1_5' to the directory
+`/boot/grub', and run the `grub-set-default' (*note Invoking
+grub-set-default::) if you intend to use `default saved' (*note
+default::) in your configuration file. Hereafter, the directory where
+GRUB images are initially placed (normally `/usr/lib/grub/i386-pc')
+will be called the "image directory", and the directory where the boot
+loader needs to find them (usually `/boot/grub') will be called the
+"boot directory".
+
+* Menu:
+
+* Creating a GRUB boot floppy::
+* Installing GRUB natively::
+* Installing GRUB using grub-install::
+* Making a GRUB bootable CD-ROM::
+
+
+File: grub.info, Node: Creating a GRUB boot floppy, Next: Installing GRUB natively, Up: Installation
+
+3.1 Creating a GRUB boot floppy
+===============================
+
+To create a GRUB boot floppy, you need to take the files `stage1' and
+`stage2' from the image directory, and write them to the first and the
+second block of the floppy disk, respectively.
+
+ *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:
+
+ # cd /usr/lib/grub/i386-pc
+ # dd if=stage1 of=/dev/fd0 bs=512 count=1
+ 1+0 records in
+ 1+0 records out
+ # dd if=stage2 of=/dev/fd0 bs=512 seek=1
+ 153+1 records in
+ 153+1 records out
+ #
+
+ The device file name may be different. Consult the manual for your
+OS.
+
+
+File: grub.info, Node: Installing GRUB natively, Next: Installing GRUB using grub-install, Prev: Creating a GRUB boot floppy, Up: Installation
+
+3.2 Installing GRUB natively
+============================
+
+*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 `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 *Note Installing GRUB
+using grub-install::.
+
+ Once started, GRUB will show the command-line interface (*note
+Command-line interface::). First, set the GRUB's "root device"(1)
+(*note Installing GRUB natively-Footnote-1::) to the partition
+containing the boot directory, like this:
+
+ grub> root (hd0,0)
+
+ If you are not sure which partition actually holds this directory,
+use the command `find' (*note find::), like this:
+
+ grub> find /boot/grub/stage1
+
+ This will search for the file name `/boot/grub/stage1' and show the
+devices which contain the file.
+
+ Once you've set the root device correctly, run the command `setup'
+(*note setup::):
+
+ grub> setup (hd0)
+
+ 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:
+
+ grub> setup (hd0,0)
+
+ 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 *Note Booting:: to find out how to boot
+your operating systems from GRUB.
+
+
+File: grub.info, Node: Installing GRUB natively-Footnotes, Up: Installing GRUB natively
+
+ (1) 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 `kernel'.
+
+
+File: grub.info, Node: Installing GRUB using grub-install, Next: Making a GRUB bootable CD-ROM, Prev: Installing GRUB natively, Up: Installation
+
+3.3 Installing GRUB using grub-install
+======================================
+
+*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 "guesses" the mapping. This will succeed
+in most cases, but not always. Therefore, GRUB provides you with a map
+file called the "device map", which you must fix if it is wrong. *Note
+Device map::, for more details.
+
+ If you still do want to install GRUB under a UNIX-like OS (such as
+GNU), invoke the program `grub-install' (*note Invoking grub-install::)
+as the superuser ("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 `/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:
+
+ # grub-install /dev/hda
+
+ Likewise, under GNU/Hurd, this has the same effect:
+
+ # grub-install /dev/hd0
+
+ If it is the first BIOS drive, this is the same as well:
+
+ # grub-install '(hd0)'
+
+ Or you can omit the parentheses:
+
+ # grub-install hd0
+
+ 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
+`--root-directory'. The typical usage is that you create a GRUB boot
+floppy with a filesystem. Here is an example:
+
+ # mke2fs /dev/fd0
+ # mount -t ext2 /dev/fd0 /mnt
+ # grub-install --root-directory=/mnt fd0
+ # umount /mnt
+
+ Another example is when you have a separate boot partition which is
+mounted at `/boot'. Since GRUB is a boot loader, it doesn't know
+anything about mountpoints at all. Thus, you need to run `grub-install'
+like this:
+
+ # grub-install --root-directory=/boot /dev/hda
+
+ By the way, as noted above, it is quite difficult to guess BIOS
+drives correctly under a UNIX-like OS. Thus, `grub-install' will prompt
+you to check if it could really guess the correct mappings, after the
+installation. The format is defined in *Note 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 `grub-install' is actually just a shell script and the
+real task is done by the grub shell `grub' (*note Invoking the grub
+shell::). Therefore, you may run `grub' directly to install GRUB,
+without using `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.
+
+
+File: grub.info, Node: Making a GRUB bootable CD-ROM, Prev: Installing GRUB using grub-install, Up: Installation
+
+3.4 Making a GRUB bootable CD-ROM
+=================================
+
+GRUB supports the "no emulation mode" in the El Torito specification(1)
+(*note Making a GRUB bootable CD-ROM-Footnote-1::). 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
+`stage2_eltorito'. The only GRUB files you need to have in your
+bootable CD-ROM are this `stage2_eltorito' and optionally a config file
+`menu.lst'. You don't need to use `stage1' or `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, `iso':
+
+ $ mkdir iso
+
+ Make a directory for GRUB:
+
+ $ mkdir -p iso/boot/grub
+
+ Copy the file `stage2_eltorito':
+
+ $ cp /usr/lib/grub/i386-pc/stage2_eltorito iso/boot/grub
+
+ If desired, make the config file `menu.lst' under `iso/boot/grub'
+(*note Configuration::), and copy any files and directories for the
+disc to the directory `iso/'.
+
+ Finally, make a ISO9660 image file like this:
+
+ $ mkisofs -R -b boot/grub/stage2_eltorito -no-emul-boot \
+ -boot-load-size 4 -boot-info-table -o grub.iso iso
+
+ This produces a file named `grub.iso', which then can be burned into
+a CD (or a DVD). `mkisofs' has already set up the disc to boot from
+the `boot/grub/stage2_eltorito' file, so there is no need to setup GRUB
+on the disc. (Note that the `-boot-load-size 4' bit is required for
+compatibility with the BIOS on many older machines.)
+
+ You can use the device `(cd)' to access a CD-ROM in your config
+file. This is not required; GRUB automatically sets the root device to
+`(cd)' when booted from a CD-ROM. It is only necessary to refer to
+`(cd)' if you want to access other drives as well.
+
+
+File: grub.info, Node: Making a GRUB bootable CD-ROM-Footnotes, Up: Making a GRUB bootable CD-ROM
+
+ (1) El Torito is a specification for bootable CD using BIOS
+functions.
+
+
+File: grub.info, Node: Booting, Next: Configuration, Prev: Installation, Up: Top
+
+4 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
+
+
+File: grub.info, Node: General boot methods, Next: OS-specific notes, Up: Booting
+
+4.1 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::
+
+
+File: grub.info, Node: Loading an operating system directly, Next: Chain-loading, Up: General boot methods
+
+4.1.1 How to boot an OS directly with GRUB
+------------------------------------------
+
+Multiboot (*note Multiboot Specification: (multiboot)Top.) 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 (*note
+Chain-loading::).
+
+ Generally, GRUB can boot any Multiboot-compliant OS in the following
+steps:
+
+ 1. Set GRUB's root device to the drive where the OS images are stored
+ with the command `root' (*note root::).
+
+ 2. Load the kernel image with the command `kernel' (*note kernel::).
+
+ 3. If you need modules, load them with the command `module' (*note
+ module::) or `modulenounzip' (*note modulenounzip::).
+
+ 4. Run the command `boot' (*note boot::).
+
+ Linux, FreeBSD, NetBSD and OpenBSD can be booted in a similar
+manner. You load a kernel image with the command `kernel' and then run
+the command `boot'. If the kernel requires some parameters, just append
+the parameters to `kernel', after the file name of the kernel. Also,
+please refer to *Note OS-specific notes::, for information on your
+OS-specific issues.
+
+
+File: grub.info, Node: Chain-loading, Prev: Loading an operating system directly, Up: General boot methods
+
+4.1.2 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 "boot sector" of the partition on which the
+operating system is installed.
+
+ 1. Set GRUB's root device to the partition by the command
+ `rootnoverify' (*note rootnoverify::):
+
+ grub> rootnoverify (hd0,0)
+
+ 2. Set the "active" flag in the partition using the command
+ `makeactive'(1) (*note Chain-loading-Footnote-1::) (*note
+ makeactive::):
+
+ grub> makeactive
+
+ 3. Load the boot loader with the command `chainloader' (*note
+ chainloader::):
+
+ grub> chainloader +1
+
+ `+1' indicates that GRUB should read one sector from the start of
+ the partition. The complete description about this syntax can be
+ found in *Note Block list syntax::.
+
+ 4. Run the command `boot' (*note boot::).
+
+ However, DOS and Windows have some deficiencies, so you might have to
+use more complicated instructions. *Note DOS/Windows::, for more
+information.
+
+
+File: grub.info, Node: Chain-loading-Footnotes, Up: Chain-loading
+
+ (1) This is not necessary for most of the modern operating systems.
+
+
+File: grub.info, Node: OS-specific notes, Next: Making your system robust, Prev: General boot methods, Up: Booting
+
+4.2 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::
+
+
+File: grub.info, Node: GNU/Hurd, Next: GNU/Linux, Up: OS-specific notes
+
+4.2.1 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.
+
+ 1. Set GRUB's root device to the same drive as GNU/Hurd's. Probably
+ the command `find /boot/gnumach' or similar can help you (*note
+ find::).
+
+ 2. Load the kernel and the module, like this:
+
+ grub> kernel /boot/gnumach root=hd0s1
+ grub> module /boot/serverboot
+
+ 3. Run the command `boot' (*note boot::).
+
+
+File: grub.info, Node: GNU/Linux, Next: FreeBSD, Prev: GNU/Hurd, Up: OS-specific notes
+
+4.2.2 GNU/Linux
+---------------
+
+It is relatively easy to boot GNU/Linux from GRUB, because it somewhat
+resembles to boot a Multiboot-compliant OS.
+
+ 1. Set GRUB's root device to the same drive as GNU/Linux's. Probably
+ the command `find /vmlinuz' or similar can help you (*note find::).
+
+ 2. Load the kernel:
+
+ grub> kernel /vmlinuz root=/dev/hda1
+
+ If you need to specify some kernel parameters, just append them to
+ the command. For example, to set `vga' to `ext', do this:
+
+ grub> kernel /vmlinuz root=/dev/hda1 vga=ext
+
+ See the documentation in the Linux source tree for complete
+ information on the available options.
+
+ 3. If you use an initrd, execute the command `initrd' (*note
+ initrd::) after `kernel':
+
+ grub> initrd /initrd
+
+ 4. Finally, run the command `boot' (*note boot::).
+
+ *Caution:* If you use an initrd and specify the `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 `uppermem' _before_ loading the kernel. *Note uppermem::,
+for more information.
+
+
+File: grub.info, Node: FreeBSD, Next: NetBSD, Prev: GNU/Linux, Up: OS-specific notes
+
+4.2.3 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 `/boot/loader'
+instead. See this example:
+
+ grub> root (hd0,a)
+ grub> kernel /boot/loader
+ grub> boot
+
+
+File: grub.info, Node: NetBSD, Next: OpenBSD, Prev: FreeBSD, Up: OS-specific notes
+
+4.2.4 NetBSD
+------------
+
+GRUB can load NetBSD a.out and ELF directly, follow these steps:
+
+ 1. Set GRUB's root device with `root' (*note root::).
+
+ 2. Load the kernel with `kernel' (*note kernel::). You should append
+ the ugly option `--type=netbsd', if you want to load an ELF
+ kernel, like this:
+
+ grub> kernel --type=netbsd /netbsd-elf
+
+ 3. Run `boot' (*note boot::).
+
+ 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 *Note Chain-loading::.
+
+
+File: grub.info, Node: OpenBSD, Next: DOS/Windows, Prev: NetBSD, Up: OS-specific notes
+
+4.2.5 OpenBSD
+-------------
+
+The booting instruction is exactly the same as for NetBSD (*note
+NetBSD::).
+
+
+File: grub.info, Node: DOS/Windows, Next: SCO UnixWare, Prev: OpenBSD, Up: OS-specific notes
+
+4.2.6 DOS/Windows
+-----------------
+
+GRUB cannot boot DOS or Windows directly, so you must chain-load them
+(*note 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 `map' (*note map::), like this:
+
+ grub> map (hd0) (hd1)
+ grub> map (hd1) (hd0)
+
+ This performs a "virtual" swap between your first and second hard
+drive.
+
+ *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 "hide"s a DOS (or Windows) partition (*note hide::), DOS (or
+Windows) will ignore the partition. If GRUB "unhide"s a DOS (or
+Windows) partition (*note 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:
+
+ grub> unhide (hd0,0)
+ grub> hide (hd0,1)
+ grub> rootnoverify (hd0,0)
+ grub> chainloader +1
+ grub> makeactive
+ grub> boot
+
+
+File: grub.info, Node: SCO UnixWare, Next: QNX, Prev: DOS/Windows, Up: OS-specific notes
+
+4.2.7 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 `--force' to
+`chainloader' (*note chainloader::), like this:
+
+ grub> rootnoverify (hd1,0)
+ grub> chainloader --force +1
+ grub> makeactive
+ grub> boot
+
+
+File: grub.info, Node: QNX, Prev: SCO UnixWare, Up: OS-specific notes
+
+4.2.8 QNX
+---------
+
+QNX seems to use a bigger boot loader, so you need to boot it up, like
+this:
+
+ grub> rootnoverify (hd1,1)
+ grub> chainloader +4
+ grub> boot
+
+
+File: grub.info, Node: Making your system robust, Prev: OS-specific notes, Up: Booting
+
+4.3 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:
+
+ 1. 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.
+
+ 2. You must direct GRUB to boot a working system when the new system
+ fails. This is possible with the "fallback" system in GRUB.
+
+ 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::
+
+
+File: grub.info, Node: Booting once-only, Next: Booting fallback systems, Up: Making your system robust
+
+4.3.1 Booting once-only
+-----------------------
+
+You can teach GRUB to boot an entry only at next boot time. Suppose
+that your have an old kernel `old_kernel' and a new kernel
+`new_kernel'. You know that `old_kernel' can boot your system
+correctly, and you want to test `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:
+
+ 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!!!
+
+ Note that this configuration file uses `default saved' (*note
+default::) at the head and `savedefault 0' (*note 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 `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 `0' is the entry of
+`the old kernel'.
+
+ The next step is to tell GRUB to boot the new kernel at next boot
+time. For this, execute `grub-set-default' (*note Invoking
+grub-set-default::):
+
+ # grub-set-default 1
+
+ This command sets the saved entry to `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 "fallback" mechanism of GRUB. Look at next subsection for this
+feature.
+
+
+File: grub.info, Node: Booting fallback systems, Prev: Booting once-only, Up: Making your system robust
+
+4.3.2 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, `A', `B' and `C'. `A' is a
+system which you want to boot by default. `B' is a backup system which
+is supposed to boot safely. `C' is another backup system which is used
+in case where `B' is broken.
+
+ Then you may want GRUB to boot the first system which is bootable
+among `A', `B' and `C'. A configuration file can be written in this way:
+
+ 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
+
+ Note that `default saved' (*note default::), `fallback 1 2' and
+`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 `A', GRUB saves `1' as next boot entry,
+because the command `fallback' specifies that `1' is the first fallback
+entry. The entry `1' is `B', so GRUB will try to boot `B' at next boot
+time.
+
+ Likewise, when GRUB tries to boot `B', GRUB saves `2' as next boot
+entry, because `fallback' specifies `2' as next fallback entry. This
+makes sure that GRUB will boot `C' after booting `B'.
+
+ It is noteworthy that GRUB uses fallback entries both when GRUB
+itself fails in booting an entry and when `A' or `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 `grub-set-default' (*note Invoking
+grub-set-default::) when `A' starts correctly or you fix `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 `rc.local' to
+boot `A' by default:
+
+ # grub-set-default 0
+
+ where `0' is the number of the boot entry for the system `A'.
+
+ If you want to see what is current default entry, you can look at the
+file `/boot/grub/default' (or `/grub/default' in some systems). Because
+this file is plain-text, you can just `cat' this file. But it is
+strongly recommended *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
+`grub-set-default' when you need to change the default entry.
+
+
+File: grub.info, Node: Configuration, Next: Network, Prev: Booting, Up: Top
+
+5 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
+(*note 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, `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 (*note Menu-specific
+commands::) before any of the items (starting with `title' (*note
+title::)).
+
+ #
+ # Sample boot menu configuration file
+ #
+
+ As you may have guessed, these lines are comments. Lines starting
+with a hash character (`#'), and blank lines, are ignored by GRUB.
+
+ # By default, boot the first entry.
+ default 0
+
+ The first entry (here, counting starts with number zero, not one!)
+will be the default choice.
+
+ # Boot automatically after 30 secs.
+ timeout 30
+
+ As the comment says, GRUB will boot automatically in 30 seconds,
+unless interrupted with a keypress.
+
+ # Fallback to the second entry.
+ fallback 1
+
+ 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 *Note Menu-specific commands::.
+Other descriptions can be found in *Note Commands::.
+
+ Now, on to the actual OS definitions. You will see that each entry
+begins with a special command, `title' (*note title::), and the action
+is described after it. Note that there is no command `boot' (*note
+boot::) at the end of each item. That is because GRUB automatically
+executes `boot' if it loads other commands successfully.
+
+ The argument for the command `title' is used to display a short
+title/description of the entry in the menu. Since `title' displays the
+argument as is, you can write basically anything there.
+
+ # For booting GNU/Hurd
+ title GNU/Hurd
+ root (hd0,0)
+ kernel /boot/gnumach.gz root=hd0s1
+ module /boot/serverboot.gz
+
+ This boots GNU/Hurd from the first hard disk.
+
+ # For booting GNU/Linux
+ title GNU/Linux
+ kernel (hd1,0)/vmlinuz root=/dev/hdb1
+
+ This boots GNU/Linux, but from the second hard disk.
+
+ # 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
+
+ This boots Mach with a kernel on a floppy, but the root filesystem at
+hd0s3. It also contains a `pause' line (*note pause::), which will
+cause GRUB to display a prompt and delay, before actually executing the
+rest of the commands and booting.
+
+ # For booting FreeBSD
+ title FreeBSD
+ root (hd0,2,a)
+ kernel /boot/loader
+
+ This item will boot FreeBSD kernel loaded from the `a' partition of
+the third PC slice of the first hard disk.
+
+ # 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
+
+ This will boot OS/2, using a chain-loader (*note Chain-loading::).
+
+ # 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
+
+ The same as the above, but for Windows.
+
+ # For installing GRUB into the hard disk
+ title Install GRUB into the hard disk
+ root (hd0,0)
+ setup (hd0)
+
+ This will just (re)install GRUB onto the hard disk.
+
+ # Change the colors.
+ title Change the colors
+ color light-green/brown blink-red/blue
+
+ In the last entry, the command `color' is used (*note 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 *Note 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.
+
+
+File: grub.info, Node: Network, Next: Serial terminal, Prev: Configuration, Up: Top
+
+6 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 `netboot/README.netboot' in the source distribution.
+
+* Menu:
+
+* General usage of network support::
+* Diskless::
+
+
+File: grub.info, Node: General usage of network support, Next: Diskless, Up: Network
+
+6.1 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(1) (*note General usage of network support-Footnote-1::).
+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 `bootp' (*note bootp::), `dhcp' (*note dhcp::) or `rarp'
+(*note 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 `ifconfig', like this:
+
+ grub> ifconfig --address=192.168.110.23 --server=192.168.110.14
+
+ You can also use `ifconfig' in conjuction with `bootp', `dhcp' or
+`rarp' (e.g. to reassign the server address manually). *Note
+ifconfig::, for more details.
+
+ Finally, download your OS images from your network. The network can
+be accessed using the network drive `(nd)'. Everything else is very
+similar to the normal instructions (*note Booting::).
+
+ Here is an example:
+
+ grub> 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> root (nd)
+ grub> kernel /tftproot/gnumach.gz root=sd0s1
+ grub> module /tftproot/serverboot.gz
+ grub> boot
+
+
+File: grub.info, Node: General usage of network support-Footnotes, Up: General usage of network support
+
+ (1) RARP is not advised, since it cannot serve much information
+
+
+File: grub.info, Node: Diskless, Prev: General usage of network support, Up: Network
+
+6.2 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 ROM, such as a PXE ROM or a free software package
+like Etherboot. Such a Boot 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, `nbgrub' and `pxegrub' (*note
+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 ROM, use `pxegrub'. If the machine has an NBI loader
+such as Etherboot, use `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 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
+`150', to get the name of a configuration file. The following is an
+example with a BOOTP configuration:
+
+ .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":
+
+ Note that you should specify the drive name `(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 (*note Preset Menu::).
+
+ See the manual of your BOOTP/DHCP server for more information. The
+exact syntax should differ a little from the example.
+
+
+File: grub.info, Node: Serial terminal, Next: Preset Menu, Prev: Network, Up: Top
+
+7 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
+`--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:
+
+ grub> serial --unit=0 --speed=9600
+ grub> terminal serial
+
+ The command `serial' initializes the serial unit 0 with the speed
+9600bps. The serial unit 0 is usually called `COM1', so, if you want to
+use COM2, you must specify `--unit=1' instead. This command accepts
+many other options, so please refer to *Note serial::, for more details.
+
+ The command `terminal' (*note 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 `console' to the command, as
+`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 `--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.
+
+
+File: grub.info, Node: Preset Menu, Next: Security, Prev: Serial terminal, Up: Top
+
+8 Embedding a configuration file into GRUB
+******************************************
+
+GRUB supports a "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 `serial' (*note serial::) and `terminal'
+(*note terminal::) before anything else at the start-up time.
+
+ How the preset menu works is slightly complicated:
+
+ 1. 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.
+
+ 2. GRUB checks if the configuration file is available. Note that this
+ check is performed *regardless of the existence of the preset
+ menu*. The configuration file is loaded even if the preset menu was
+ loaded.
+
+ 3. 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.
+
+ To enable the preset menu feature, you must rebuild GRUB specifying a
+file to the configure script with the option `--enable-preset-menu'.
+The file has the same semantics as normal configuration files (*note
+Configuration::).
+
+ Another point you should take care is that the diskless support
+(*note Diskless::) diverts the preset menu. Diskless images embed a
+preset menu to execute the command `bootp' (*note 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:
+
+ # Set up the serial terminal, first of all.
+ serial --unit=0 --speed=19200
+ terminal --timeout=0 serial
+
+ # Initialize the network.
+ dhcp
+
+
+File: grub.info, Node: Security, Next: Images, Prev: Preset Menu, Up: Top
+
+9 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 `/etc/passwd' in the command-line interface by the
+command `cat' (*note cat::). So it is necessary to disable all the
+interactive operations.
+
+ Thus, GRUB provides a "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 `password' in your configuration file (*note
+password::), like this:
+
+ password --md5 PASSWORD
+
+ If this is specified, GRUB disallows any interactive control, until
+you press the key <p> and enter a correct password. The option `--md5'
+tells GRUB that `PASSWORD' is in MD5 format. If it is omitted, GRUB
+assumes the `PASSWORD' is in clear text.
+
+ You can encrypt your password with the command `md5crypt' (*note
+md5crypt::). For example, run the grub shell (*note Invoking the grub
+shell::), and enter your password:
+
+ grub> md5crypt
+ Password: **********
+ Encrypted: $1$U$JK7xFegdxWH6VuppCUSIb.
+
+ Then, cut and paste the encrypted password to your configuration
+file.
+
+ Also, you can specify an optional argument to `password'. See this
+example:
+
+ password PASSWORD /boot/grub/menu-admin.lst
+
+ In this case, GRUB will load `/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 `lock' (*note lock::). This command always
+fails until you enter the valid password, so you can use it, like this:
+
+ title Boot DOS
+ lock
+ rootnoverify (hd0,1)
+ makeactive
+ chainload +1
+
+ You should insert `lock' right after `title', because any user can
+execute commands in an entry until GRUB encounters `lock'.
+
+ You can also use the command `password' instead of `lock'. In this
+case the boot process will ask for the password and stop if it was
+entered incorrectly. Since the `password' takes its own PASSWORD
+argument this is useful if you want different passwords for different
+entries.
+
+
+File: grub.info, Node: Images, Next: Filesystem, Prev: Security, Up: Top
+
+10 GRUB image files
+*******************
+
+GRUB consists of several images: two essential stages, optional stages
+called "Stage 1.5", one image for bootable CD-ROM, and two network boot
+images. Here is a short overview of them. *Note Internals::, for more
+details.
+
+`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 `stage1' must do is to load Stage 2 or Stage 1.5 from a local
+ disk. Because of the size restriction, `stage1' encodes the
+ location of Stage 2 (or Stage 1.5) in a block list format, so it
+ never understand any filesystem structure.
+
+`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.
+
+`e2fs_stage1_5'
+`fat_stage1_5'
+`ffs_stage1_5'
+`jfs_stage1_5'
+`minix_stage1_5'
+`reiserfs_stage1_5'
+`vstafs_stage1_5'
+`xfs_stage1_5'
+ These are called "Stage 1.5", because they serve as a bridge
+ between `stage1' and `stage2', that is to say, Stage 1.5 is loaded
+ by Stage 1 and Stage 1.5 loads Stage 2. The difference between
+ `stage1' and `*_stage1_5' is that the former doesn't understand
+ any filesystem while the latter understands one filesystem (e.g.
+ `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.
+
+`stage2_eltorito'
+ This is a boot image for CD-ROMs using the "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 `(cd)'.
+
+`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.
+
+`pxegrub'
+ This is another network boot image for the Preboot Execution
+ Environment used by several Netboot ROMs. This is identical to
+ `nbgrub', except for the format.
+
+
+File: grub.info, Node: Filesystem, Next: Interface, Prev: Images, Up: Top
+
+11 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 `find' (*note find::).
+
+* Menu:
+
+* Device syntax:: How to specify devices
+* File name syntax:: How to specify files
+* Block list syntax:: How to specify block lists
+
+
+File: grub.info, Node: Device syntax, Next: File name syntax, Up: Filesystem
+
+11.1 How to specify devices
+===========================
+
+The device syntax is like this:
+
+ `(DEVICE[,PART-NUM][,BSD-SUBPART-LETTER])'
+
+ `[]' means the parameter is optional. DEVICE should be either `fd'
+or `hd' followed by a digit, like `fd0'. But you can also set DEVICE
+to a hexadecimal or a decimal number which is a BIOS drive number, so
+the following are equivalent:
+
+ (hd0)
+ (0x80)
+ (128)
+
+ PART-NUM represents the partition number of DEVICE, starting from
+zero for primary partitions and from four for extended partitions, and
+BSD-SUBPART-LETTER represents the BSD disklabel subpartition, such as
+`a' or `e'.
+
+ A shortcut for specifying BSD subpartitions is
+`(DEVICE,BSD-SUBPART-LETTER)', in this case, GRUB searches for the
+first PC partition containing a BSD disklabel, then finds the
+subpartition BSD-SUBPART-LETTER. Here is an example:
+
+ (hd0,a)
+
+ The syntax `(hd0)' represents using the entire disk (or the MBR when
+installing GRUB), while the syntax `(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, `(nd)', is
+also available. Before using the network drive, you must initialize the
+network. *Note Network::, for more information.
+
+ If you boot GRUB from a CD-ROM, `(cd)' is available. *Note Making a
+GRUB bootable CD-ROM::, for details.
+
+
+File: grub.info, Node: File name syntax, Next: Block list syntax, Prev: Device syntax, Up: Filesystem
+
+11.2 How to specify files
+=========================
+
+There are two ways to specify files, by "absolute file name" and by
+"block list".
+
+ An absolute file name resembles a Unix absolute file name, using `/'
+for the directory separator (not `\' as in DOS). One example is
+`(hd0,0)/boot/grub/menu.lst'. This means the 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 "root device"
+implicitly. So if you set the root device to, say, `(hd1,0)' by the
+command `root' (*note root::), then `/boot/kernel' is the same as
+`(hd1,0)/boot/kernel'.
+
+
+File: grub.info, Node: Block list syntax, Prev: File name syntax, Up: Filesystem
+
+11.3 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
+`[OFFSET]+LENGTH[,[OFFSET]+LENGTH]...'. Here is an example:
+
+ `0+100,200+1,300+300'
+
+ 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 (*note File name syntax::), if a blocklist
+does not contain a device name, then GRUB uses GRUB's "root device". So
+`(hd0,1)+1' is the same as `+1' when the root device is `(hd0,1)'.
+
+
+File: grub.info, Node: Interface, Next: Commands, Prev: Filesystem, Up: Top
+
+12 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 "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
+
+
+File: grub.info, Node: Command-line interface, Next: Menu interface, Up: Interface
+
+12.1 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(1) (*note Command-line
+interface-Footnote-1::). The commands (*note 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:
+
+<C-f>
+<PC right key>
+ Move forward one character.
+
+<C-b>
+<PC left key>
+ Move back one character.
+
+<C-a>
+<HOME>
+ Move to the start of the line.
+
+<C-e>
+<END>
+ Move the the end of the line.
+
+<C-d>
+<DEL>
+ Delete the character underneath the cursor.
+
+<C-h>
+<BS>
+ Delete the character to the left of the cursor.
+
+<C-k>
+ Kill the text from the current cursor position to the end of the
+ line.
+
+<C-u>
+ Kill backward from the cursor to the beginning of the line.
+
+<C-y>
+ Yank the killed text back into the buffer at the cursor.
+
+<C-p>
+<PC up key>
+ Move up through the history list.
+
+<C-n>
+<PC down key>
+ Move down through the history list.
+
+ When typing commands interactively, if the cursor is within or before
+the first word in the command-line, pressing the <TAB> key (or <C-i>)
+will display a listing of the available commands, and if the cursor is
+after the first word, the `<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 `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.
+
+
+File: grub.info, Node: Command-line interface-Footnotes, Up: Command-line interface
+
+ (1) However, this behavior will be changed in the future version, in
+a user-invisible way.
+
+
+File: grub.info, Node: Menu interface, Next: Menu entry editor, Prev: Command-line interface, Up: Interface
+
+12.2 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 "boot entries" to
+the user to choose from. Use the arrow keys to select the entry of
+choice, then press <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 <c>
+(which operates exactly like the non-config-file version of GRUB, but
+allows one to return to the menu if desired by pressing <ESC>) or to
+edit any of the "boot entries" by pressing <e>.
+
+ If you protect the menu interface with a password (*note Security::),
+all you can do is choose an entry by pressing <RET>, or press <p> to
+enter the password.
+
+
+File: grub.info, Node: Menu entry editor, Next: Hidden menu interface, Prev: Menu interface, Up: Interface
+
+12.3 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 <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 <RET>, GRUB replaces the line in question in the boot entry
+with the changes (unless it was aborted via <ESC>, in which case the
+changes are thrown away).
+
+ If you want to add a new line to the menu entry, press <o> if adding
+a line after the current line or press <O> if before the current line.
+
+ To delete a line, hit the key <d>. Although GRUB unfortunately does
+not support "undo", you can do almost the same thing by just returning
+to the main menu.
+
+
+File: grub.info, Node: Hidden menu interface, Prev: Menu entry editor, Up: Interface
+
+12.4 The hidden menu interface
+==============================
+
+When your terminal is dumb or you request GRUB to hide the menu
+interface explicitly with the command `hiddenmenu' (*note
+hiddenmenu::), GRUB doesn't show the menu interface (*note Menu
+interface::) and automatically boots the default entry, unless
+interrupted by pressing <ESC>.
+
+ When you interrupt the timeout and your terminal is dumb, GRUB falls
+back to the command-line interface (*note Command-line interface::).
+
+
+File: grub.info, Node: Commands, Next: Troubleshooting, Prev: Interface, Up: Top
+
+13 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::
+
+
+File: grub.info, Node: Menu-specific commands, Next: General commands, Up: Commands
+
+13.1 The list of commands for the menu only
+===========================================
+
+The semantics used in parsing the configuration file are the following:
+
+ * The menu-specific commands have to be used before any others.
+
+ * The files _must_ be in plain-text format.
+
+ * `#' at the beginning of a line in a configuration file means it is
+ only a comment.
+
+ * Options are separated by spaces.
+
+ * All numbers can be either decimal or hexadecimal. A hexadecimal
+ number must be preceded by `0x', and is case-insensitive.
+
+ * Extra options or text at the end of the line are ignored unless
+ otherwise specified.
+
+ * Unrecognized commands are added to the current entry, except
+ before entries start, where they are ignored.
+
+ 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
+
+
+File: grub.info, Node: default, Next: fallback, Up: Menu-specific commands
+
+13.1.1 default
+--------------
+
+ -- Command: default num
+ Set the default entry to the entry number NUM. Numbering starts
+ from 0, and the entry number 0 is the default if the command is not
+ used.
+
+ You can specify `saved' instead of a number. In this case, the
+ default entry is the entry saved with the command `savedefault'.
+ *Note savedefault::, for more information.
+
+
+File: grub.info, Node: fallback, Next: hiddenmenu, Prev: default, Up: Menu-specific commands
+
+13.1.2 fallback
+---------------
+
+ -- 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 NUM entry (same numbering as the
+ `default' command (*note default::)). This obviously won't help if
+ the machine was rebooted by a kernel that GRUB loaded. You can
+ specify multiple fallback entry numbers.
+
+
+File: grub.info, Node: hiddenmenu, Next: timeout, Prev: fallback, Up: Menu-specific commands
+
+13.1.3 hiddenmenu
+-----------------
+
+ -- 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 <ESC> before the timeout expires.
+ See also *Note Hidden menu interface::.
+
+
+File: grub.info, Node: timeout, Next: title, Prev: hiddenmenu, Up: Menu-specific commands
+
+13.1.4 timeout
+--------------
+
+ -- Command: timeout sec
+ Set a timeout, in SEC seconds, before automatically booting the
+ default entry (normally the first entry defined).
+
+
+File: grub.info, Node: title, Prev: timeout, Up: Menu-specific commands
+
+13.1.5 title
+------------
+
+ -- Command: 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.
+
+
+File: grub.info, Node: General commands, Next: Command-line and menu entry commands, Prev: Menu-specific commands, Up: Commands
+
+13.2 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
+
+
+File: grub.info, Node: bootp, Next: color, Up: General commands
+
+13.2.1 bootp
+------------
+
+ -- Command: bootp [`--with-configfile']
+ Initialize a network device via the "BOOTP" protocol. This command
+ is only available if GRUB is compiled with netboot support. See
+ also *Note Network::.
+
+ If you specify `--with-configfile' to this command, GRUB will
+ fetch and load a configuration file specified by your BOOTP server
+ with the vendor tag `150'.
+
+
+File: grub.info, Node: color, Next: device, Prev: bootp, Up: General commands
+
+13.2.2 color
+------------
+
+ -- Command: color normal [highlight]
+ Change the menu colors. The color NORMAL is used for most lines in
+ the menu (*note Menu interface::), 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
+ `FOREGROUND/BACKGROUND'. FOREGROUND and BACKGROUND are symbolic
+ color names. A symbolic color name must be one of these:
+
+ * black
+
+ * blue
+
+ * green
+
+ * cyan
+
+ * red
+
+ * magenta
+
+ * brown
+
+ * light-gray
+
+ *These below can be specified only for the foreground.*
+
+ * dark-gray
+
+ * light-blue
+
+ * light-green
+
+ * light-cyan
+
+ * light-red
+
+ * light-magenta
+
+ * yellow
+
+ * white
+
+ But only the first eight names can be used for BACKGROUND. You can
+ prefix `blink-' to 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:
+
+ # Set default colors.
+ color light-gray/blue black/light-gray
+
+ # Change the colors.
+ title OS-BS like
+ color magenta/blue black/magenta
+
+
+File: grub.info, Node: device, Next: dhcp, Prev: color, Up: General commands
+
+13.2.3 device
+-------------
+
+ -- Command: device drive file
+ In the grub shell, specify the file FILE as the actual drive for a
+ BIOS drive 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:
+
+ grub> device (fd0) /floppy-image
+ grub> device (hd0) /dev/sd0
+
+ This command can be used only in the grub shell (*note Invoking
+ the grub shell::).
+
+
+File: grub.info, Node: dhcp, Next: hide, Prev: device, Up: General commands
+
+13.2.4 dhcp
+-----------
+
+ -- Command: dhcp [-with-configfile]
+ Initialize a network device via the "DHCP" protocol. Currently,
+ this command is just an alias for `bootp', since the two protocols
+ are very similar. This command is only available if GRUB is
+ compiled with netboot support. See also *Note Network::.
+
+ If you specify `--with-configfile' to this command, GRUB will
+ fetch and load a configuration file specified by your DHCP server
+ with the vendor tag `150'.
+
+
+File: grub.info, Node: hide, Next: ifconfig, Prev: dhcp, Up: General commands
+
+13.2.5 hide
+-----------
+
+ -- Command: hide partition
+ Hide the partition PARTITION by setting the "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 *Note DOS/Windows::.
+
+
+File: grub.info, Node: ifconfig, Next: pager, Prev: hide, Up: General commands
+
+13.2.6 ifconfig
+---------------
+
+ -- Command: ifconfig [`--server=server'] [`--gateway=gateway']
+ [`--mask=mask'] [`--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 `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 *Note Network::.
+
+
+File: grub.info, Node: pager, Next: partnew, Prev: ifconfig, Up: General commands
+
+13.2.7 pager
+------------
+
+ -- Command: pager [flag]
+ Toggle or set the state of the internal pager. If FLAG is `on',
+ the internal pager is enabled. If FLAG is `off', it is disabled.
+ If no argument is given, the state is toggled.
+
+
+File: grub.info, Node: partnew, Next: parttype, Prev: pager, Up: General commands
+
+13.2.8 partnew
+--------------
+
+ -- Command: partnew part type from len
+ Create a new primary partition. PART is a partition specification
+ in GRUB syntax (*note Naming convention::); TYPE is the partition
+ type and must be a number in the range `0-0xff'; FROM is the
+ starting address and LEN is the length, both in sector units.
+
+
+File: grub.info, Node: parttype, Next: password, Prev: partnew, Up: General commands
+
+13.2.9 parttype
+---------------
+
+ -- Command: parttype part type
+ Change the type of an existing partition. PART is a partition
+ specification in GRUB syntax (*note Naming convention::); TYPE is
+ the new partition type and must be a number in the range 0-0xff.
+
+
+File: grub.info, Node: password, Next: rarp, Prev: parttype, Up: General commands
+
+13.2.10 password
+----------------
+
+ -- Command: password [`--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 `lock'. If the password
+ PASSWD is entered, it loads the NEW-CONFIG-FILE as a new config
+ file and restarts the GRUB Stage 2, if 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 `--md5' tells GRUB that PASSWD is
+ encrypted with `md5crypt' (*note md5crypt::).
+
+
+File: grub.info, Node: rarp, Next: serial, Prev: password, Up: General commands
+
+13.2.11 rarp
+------------
+
+ -- Command: rarp
+ Initialize a network device via the "RARP" protocol. This command
+ is only available if GRUB is compiled with netboot support. See
+ also *Note Network::.
+
+
+File: grub.info, Node: serial, Next: setkey, Prev: rarp, Up: General commands
+
+13.2.12 serial
+--------------
+
+ -- Command: serial [`--unit=unit'] [`--port=port'] [`--speed=speed']
+ [`--word=word'] [`--parity=parity'] [`--stop=stop']
+ [`--device=dev']
+ Initialize a serial device. 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. PORT is the I/O port
+ where the UART is to be found; if specified it takes precedence
+ over UNIT. SPEED is the transmission speed; default is 9600. WORD
+ and 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. PARITY is one of `no', `odd', `even' and
+ defaults to `no'. The 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 (*note Invoking the grub shell::).
+
+ The serial port is not used as a communication channel unless the
+ `terminal' command is used (*note terminal::).
+
+ This command is only available if GRUB is compiled with serial
+ support. See also *Note Serial terminal::.
+
+
+File: grub.info, Node: setkey, Next: terminal, Prev: serial, Up: General commands
+
+13.2.13 setkey
+--------------
+
+ -- Command: setkey [to_key from_key]
+ Change the keyboard map. The key FROM_KEY is mapped to the key
+ TO_KEY. If no argument is specified, reset key mappings. Note that
+ this command _does not_ exchange the keys. If you want to exchange
+ the keys, run this command again with the arguments exchanged,
+ like this:
+
+ grub> setkey capslock control
+ grub> setkey control capslock
+
+ A key must be an alphabet letter, a digit, or one of these symbols:
+ `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'. This table
+ describes to which character each of the symbols corresponds:
+
+ `exclam'
+ `!'
+
+ `at'
+ `@'
+
+ `numbersign'
+ `#'
+
+ `dollar'
+ `$'
+
+ `percent'
+ `%'
+
+ `caret'
+ `^'
+
+ `ampersand'
+ `&'
+
+ `asterisk'
+ `*'
+
+ `parenleft'
+ `('
+
+ `parenright'
+ `)'
+
+ `minus'
+ `-'
+
+ `underscore'
+ `_'
+
+ `equal'
+ `='
+
+ `plus'
+ `+'
+
+ `bracketleft'
+ `['
+
+ `braceleft'
+ `{'
+
+ `bracketright'
+ `]'
+
+ `braceright'
+ `}'
+
+ `semicolon'
+ `;'
+
+ `colon'
+ `:'
+
+ `quote'
+ `''
+
+ `doublequote'
+ `"'
+
+ `backquote'
+ ``'
+
+ `tilde'
+ `~'
+
+ `backslash'
+ `\'
+
+ `bar'
+ `|'
+
+ `comma'
+ `,'
+
+ `less'
+ `<'
+
+ `period'
+ `.'
+
+ `greater'
+ `>'
+
+ `slash'
+ `/'
+
+ `question'
+ `?'
+
+ `space'
+ ` '
+
+
+File: grub.info, Node: terminal, Next: terminfo, Prev: setkey, Up: General commands
+
+13.2.14 terminal
+----------------
+
+ -- Command: terminal [`--dumb'] [`--no-echo'] [`--no-edit']
+ [`--timeout=secs'] [`--lines=lines'] [`--silent'] [`console']
+ [`serial'] [`hercules']
+ Select a terminal for user interaction. The terminal is assumed to
+ be VT100-compatible unless `--dumb' is specified. If both
+ `console' and `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 *Note 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 `hercules' as the argument.
+
+ The 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 `--silent' suppresses the message to prompt you to hit
+ any key. This might be useful if your system has no terminal
+ device.
+
+ The option `--no-echo' has GRUB not to echo back input characters.
+ This implies the option `--no-edit'.
+
+ The option `--no-edit' disables the BASH-like editing feature.
+
+
+File: grub.info, Node: terminfo, Next: tftpserver, Prev: terminal, Up: General commands
+
+13.2.15 terminfo
+----------------
+
+ -- Command: 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.
+
+ You can use the utility `grub-terminfo' to generate appropriate
+ arguments to this command. *Note Invoking grub-terminfo::.
+
+ If no option is specified, the current settings are printed.
+
+
+File: grub.info, Node: tftpserver, Next: unhide, Prev: terminfo, Up: General commands
+
+13.2.16 tftpserver
+------------------
+
+ -- Command: tftpserver ipaddr
+ *Caution:* This command exists only for backward compatibility.
+ Use `ifconfig' (*note ifconfig::) instead.
+
+ Override a TFTP server address returned by a BOOTP/DHCP/RARP
+ server. The argument IPADDR must be in dotted decimal format, like
+ `192.168.0.15'. This command is only available if GRUB is compiled
+ with netboot support. See also *Note Network::.
+
+
+File: grub.info, Node: unhide, Prev: tftpserver, Up: General commands
+
+13.2.17 unhide
+--------------
+
+ -- Command: unhide partition
+ Unhide the partition PARTITION by clearing the "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
+ *Note DOS/Windows::.
+
+
+File: grub.info, Node: Command-line and menu entry commands, Prev: General commands, Up: Commands
+
+13.3 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 `help' (*note 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
+
+
+File: grub.info, Node: blocklist, Next: boot, Up: Command-line and menu entry commands
+
+13.3.1 blocklist
+----------------
+
+ -- Command: blocklist file
+ Print the block list notation of the file FILE. *Note Block list
+ syntax::.
+
+
+File: grub.info, Node: boot, Next: cat, Prev: blocklist, Up: Command-line and menu entry commands
+
+13.3.2 boot
+-----------
+
+ -- 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).
+
+
+File: grub.info, Node: cat, Next: chainloader, Prev: boot, Up: Command-line and menu entry commands
+
+13.3.3 cat
+----------
+
+ -- Command: cat file
+ Display the contents of the file FILE. This command may be useful
+ to remind you of your OS's root partition:
+
+ grub> cat /etc/fstab
+
+
+File: grub.info, Node: chainloader, Next: cmp, Prev: cat, Up: Command-line and menu entry commands
+
+13.3.4 chainloader
+------------------
+
+ -- Command: chainloader [`--force'] file
+ Load 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 `+1'. If you specify the
+ option `--force', then load 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 (*note SCO
+ UnixWare::).
+
+
+File: grub.info, Node: cmp, Next: configfile, Prev: chainloader, Up: Command-line and menu entry commands
+
+13.3.5 cmp
+----------
+
+ -- Command: cmp file1 file2
+ Compare the file FILE1 with the file FILE2. If they differ in
+ size, print the sizes like this:
+
+ Differ in size: 0x1234 [foo], 0x4321 [bar]
+
+ If the sizes are equal but the bytes at an offset differ, then
+ print the bytes like this:
+
+ Differ at the offset 777: 0xbe [foo], 0xef [bar]
+
+ If they are completely identical, nothing will be printed.
+
+
+File: grub.info, Node: configfile, Next: debug, Prev: cmp, Up: Command-line and menu entry commands
+
+13.3.6 configfile
+-----------------
+
+ -- Command: configfile file
+ Load FILE as a configuration file.
+
+
+File: grub.info, Node: debug, Next: displayapm, Prev: configfile, Up: Command-line and menu entry commands
+
+13.3.7 debug
+------------
+
+ -- 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.
+
+
+File: grub.info, Node: displayapm, Next: displaymem, Prev: debug, Up: Command-line and menu entry commands
+
+13.3.8 displayapm
+-----------------
+
+ -- Command: displayapm
+ Display APM BIOS information.
+
+
+File: grub.info, Node: displaymem, Next: embed, Prev: displayapm, Up: Command-line and menu entry commands
+
+13.3.9 displaymem
+-----------------
+
+ -- Command: displaymem
+ Display what GRUB thinks the system address space map of the
+ machine is, including all regions of physical RAM installed. GRUB's
+ "upper/lower memory" display uses the standard BIOS interface for
+ the available memory in the first megabyte, or "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 "upper
+ memory" (the standard PC "upper memory" interface is limited to
+ reporting a maximum of 64MB).
+
+
+File: grub.info, Node: embed, Next: find, Prev: displaymem, Up: Command-line and menu entry commands
+
+13.3.10 embed
+-------------
+
+ -- Command: embed stage1_5 device
+ Embed the Stage 1.5 STAGE1_5 in the sectors after the MBR if
+ DEVICE is a drive, or in the "boot loader" area if DEVICE is a FFS
+ partition or a ReiserFS partition.(1) (*note embed-Footnote-1::)
+ Print the number of sectors which STAGE1_5 occupies, if successful.
+
+ Usually, you don't need to run this command directly. *Note
+ setup::.
+
+
+File: grub.info, Node: embed-Footnotes, Up: embed
+
+ (1) The latter feature has not been implemented yet.
+
+
+File: grub.info, Node: find, Next: fstest, Prev: embed, Up: Command-line and menu entry commands
+
+13.3.11 find
+------------
+
+ -- Command: find filename
+ Search for the file name FILENAME in all mountable partitions and
+ print the list of the devices which contain the file. The file
+ name FILENAME should be an absolute file name like
+ `/boot/grub/stage1'.
+
+
+File: grub.info, Node: fstest, Next: geometry, Prev: find, Up: Command-line and menu entry commands
+
+13.3.12 fstest
+--------------
+
+ -- 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
+ `<PARTITION-OFFSET-SECTOR, BYTE-OFFSET, BYTE-LENGTH>' for
+ high-level reads inside a partition, and `[DISK-OFFSET-SECTOR]'
+ for low-level sector requests from the disk. Filesystem test mode
+ is turned off by any use of the `install' (*note install::) or
+ `testload' (*note testload::) commands.
+
+
+File: grub.info, Node: geometry, Next: halt, Prev: fstest, Up: Command-line and menu entry commands
+
+13.3.13 geometry
+----------------
+
+ -- Command: geometry drive [cylinder head sector [total_sector]]
+ Print the information for the drive 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.
+
+
+File: grub.info, Node: halt, Next: help, Prev: geometry, Up: Command-line and menu entry commands
+
+13.3.14 halt
+------------
+
+ -- Command: halt `--no-apm'
+ The command halts the computer. If the `--no-apm' option is
+ specified, no APM BIOS call is performed. Otherwise, the computer
+ is shut down using APM.
+
+
+File: grub.info, Node: help, Next: impsprobe, Prev: halt, Up: Command-line and menu entry commands
+
+13.3.15 help
+------------
+
+ -- Command: help `--all' [pattern ...]
+ Display helpful information about builtin commands. If you do not
+ specify PATTERN, this command shows short descriptions of most of
+ available commands. If you specify the option `--all' to this
+ command, short descriptions of rarely used commands (such as *Note
+ testload::) are displayed as well.
+
+ If you specify any PATTERNS, it displays longer information about
+ each of the commands which match those PATTERNS.
+
+
+File: grub.info, Node: impsprobe, Next: initrd, Prev: help, Up: Command-line and menu entry commands
+
+13.3.16 impsprobe
+-----------------
+
+ -- 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.
+
+
+File: grub.info, Node: initrd, Next: install, Prev: impsprobe, Up: Command-line and menu entry commands
+
+13.3.17 initrd
+--------------
+
+ -- Command: initrd file ...
+ Load an initial ramdisk for a Linux format boot image and set the
+ appropriate parameters in the Linux setup area in memory. See also
+ *Note GNU/Linux::.
+
+
+File: grub.info, Node: install, Next: ioprobe, Prev: initrd, Up: Command-line and menu entry commands
+
+13.3.18 install
+---------------
+
+ -- Command: install [`--force-lba'] [`--stage2=os_stage2_file']
+ stage1_file [`d'] dest_dev stage2_file [addr] [`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 `setup' (*note setup::)
+ instead.
+
+ In short, it will perform a full install presuming the Stage 2 or
+ Stage 1.5(1) (*note install-Footnote-1::) is in its final install
+ location.
+
+ In slightly more detail, it will load STAGE1_FILE, validate that
+ it is a GRUB Stage 1 of the right version number, install in it a
+ blocklist for loading STAGE2_FILE as a Stage 2. If the option `d'
+ is present, the Stage 1 will always look for the actual disk
+ STAGE2_FILE was installed on, rather than using the booting drive.
+ The Stage 2 will be loaded at address ADDR, which must be `0x8000'
+ for a true Stage 2, and `0x2000' for a Stage 1.5. If ADDR is not
+ present, GRUB will determine the address automatically. It then
+ writes the completed Stage 1 to the first block of the device
+ DEST_DEV. If the options `p' or CONFIG_FILE are present, then it
+ reads the first block of stage2, modifies it with the values of
+ the partition STAGE2_FILE was found on (for `p') or places the
+ string CONFIG_FILE into the area telling the stage2 where to look
+ for a configuration file at boot time. Likewise, if
+ REAL_CONFIG_FILE is present and STAGE2_FILE is a Stage 1.5, then
+ the Stage 2 CONFIG_FILE is patched with the configuration file
+ name 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.
+
+ *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 `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:
+
+
+ Fujitsu LifeBook 400 BIOS version 31J0103A
+
+
+ HP Vectra XU 6/200 BIOS version GG.06.11
+
+ *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
+ `--force-lba'. Don't use this option if you know that your BIOS
+ doesn't have LBA support.
+
+ *Caution3:* You must specify the 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.
+
+
+File: grub.info, Node: install-Footnotes, Up: install
+
+ (1) They're loaded the same way, so we will refer to the Stage 1.5
+as a Stage 2 from now on.
+
+
+File: grub.info, Node: ioprobe, Next: kernel, Prev: install, Up: Command-line and menu entry commands
+
+13.3.19 ioprobe
+---------------
+
+ -- Command: ioprobe drive
+ Probe I/O ports used for the drive DRIVE. This command will list
+ the I/O ports on the screen. For technical information, *Note
+ Internals::.
+
+
+File: grub.info, Node: kernel, Next: lock, Prev: ioprobe, Up: Command-line and menu entry commands
+
+13.3.20 kernel
+--------------
+
+ -- Command: kernel [`--type=type'] [`--no-mem-option'] file ...
+ Attempt to load the primary boot image (Multiboot a.out or ELF,
+ Linux zImage or bzImage, FreeBSD a.out, NetBSD a.out, etc.) from
+ FILE. The rest of the line is passed verbatim as the "kernel
+ command-line". Any modules must be reloaded after using this
+ command.
+
+ This command also accepts the option `--type' so that you can
+ specify the kernel type of FILE explicitly. The argument TYPE must
+ be one of these: `netbsd', `freebsd', `openbsd', `linux',
+ `biglinux', and `multiboot'. However, you need to specify it only
+ if you want to load a NetBSD ELF kernel, because GRUB can
+ automatically determine a kernel type in the other cases, quite
+ safely.
+
+ The option `--no-mem-option' is effective only for Linux. If the
+ option is specified, GRUB doesn't pass the option `mem=' to the
+ kernel. This option is implied for Linux kernels 2.4.18 and newer.
+
+
+File: grub.info, Node: lock, Next: makeactive, Prev: kernel, Up: Command-line and menu entry commands
+
+13.3.21 lock
+------------
+
+ -- Command: lock
+ Prevent normal users from executing arbitrary menu entries. You
+ must use the command `password' if you really want this command to
+ be useful (*note password::).
+
+ This command is used in a menu, as shown in this example:
+
+ title This entry is too dangerous to be executed by normal users
+ lock
+ root (hd0,a)
+ kernel /no-security-os
+
+ See also *Note Security::.
+
+
+File: grub.info, Node: makeactive, Next: map, Prev: lock, Up: Command-line and menu entry commands
+
+13.3.22 makeactive
+------------------
+
+ -- Command: 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.
+
+
+File: grub.info, Node: map, Next: md5crypt, Prev: makeactive, Up: Command-line and menu entry commands
+
+13.3.23 map
+-----------
+
+ -- Command: 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. Here is an example:
+
+ grub> map (hd0) (hd1)
+ grub> map (hd1) (hd0)
+
+ The example exchanges the order between the first hard disk and the
+ second hard disk. See also *Note DOS/Windows::.
+
+
+File: grub.info, Node: md5crypt, Next: module, Prev: map, Up: Command-line and menu entry commands
+
+13.3.24 md5crypt
+----------------
+
+ -- Command: md5crypt
+ Prompt to enter a password, and encrypt it in MD5 format. The
+ encrypted password can be used with the command `password' (*note
+ password::). See also *Note Security::.
+
+
+File: grub.info, Node: module, Next: modulenounzip, Prev: md5crypt, Up: Command-line and menu entry commands
+
+13.3.25 module
+--------------
+
+ -- Command: module file ...
+ Load a boot module 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 "module command-line", like the
+ `kernel' command. You must load a Multiboot kernel image before
+ loading any module. See also *Note modulenounzip::.
+
+
+File: grub.info, Node: modulenounzip, Next: pause, Prev: module, Up: Command-line and menu entry commands
+
+13.3.26 modulenounzip
+---------------------
+
+ -- Command: modulenounzip file ...
+ The same as `module' (*note module::), except that automatic
+ decompression is disabled.
+
+
+File: grub.info, Node: pause, Next: quit, Prev: modulenounzip, Up: Command-line and menu entry commands
+
+13.3.27 pause
+-------------
+
+ -- Command: pause message ...
+ Print the MESSAGE, then wait until a key is pressed. Note that
+ placing <^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.
+
+
+File: grub.info, Node: quit, Next: reboot, Prev: pause, Up: Command-line and menu entry commands
+
+13.3.28 quit
+------------
+
+ -- Command: quit
+ Exit from the grub shell `grub' (*note Invoking the grub shell::).
+ This command can be used only in the grub shell.
+
+
+File: grub.info, Node: reboot, Next: read, Prev: quit, Up: Command-line and menu entry commands
+
+13.3.29 reboot
+--------------
+
+ -- Command: reboot
+ Reboot the computer.
+
+
+File: grub.info, Node: read, Next: root, Prev: reboot, Up: Command-line and menu entry commands
+
+13.3.30 read
+------------
+
+ -- Command: read addr
+ Read a 32-bit value from memory at address ADDR and display it in
+ hex format.
+
+
+File: grub.info, Node: root, Next: rootnoverify, Prev: read, Up: Command-line and menu entry commands
+
+13.3.31 root
+------------
+
+ -- Command: 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 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 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.
+
+ See also *Note rootnoverify::.
+
+
+File: grub.info, Node: rootnoverify, Next: savedefault, Prev: root, Up: Command-line and menu entry commands
+
+13.3.32 rootnoverify
+--------------------
+
+ -- Command: rootnoverify device [hdbias]
+ Similar to `root' (*note 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' above
+ which derived from attempting the mount will _not_ work correctly.
+
+
+File: grub.info, Node: savedefault, Next: setup, Prev: rootnoverify, Up: Command-line and menu entry commands
+
+13.3.33 savedefault
+-------------------
+
+ -- Command: savedefault num
+ Save the current menu entry or NUM if specified as a default
+ entry. Here is an example:
+
+ 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
+
+ With this configuration, GRUB will choose the entry booted
+ previously as the default entry.
+
+ You can specify `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 *Note default:: and *Note Invoking grub-set-default::.
+
+
+File: grub.info, Node: setup, Next: testload, Prev: savedefault, Up: Command-line and menu entry commands
+
+13.3.34 setup
+-------------
+
+ -- Command: setup [`--force-lba'] [`--stage2=os_stage2_file']
+ [`--prefix=dir'] install_device [image_device]
+ Set up the installation of GRUB automatically. This command uses
+ the more flexible command `install' (*note install::) in the
+ backend and installs GRUB into the device INSTALL_DEVICE. If
+ IMAGE_DEVICE is specified, then find the GRUB images (*note
+ Images::) in the device IMAGE_DEVICE, otherwise use the current
+ "root device", which can be set by the command `root'. If
+ INSTALL_DEVICE is a hard disk, then embed a Stage 1.5 in the disk
+ if possible.
+
+ The option `--prefix' specifies the directory under which GRUB
+ images are put. If it is not specified, GRUB automatically
+ searches them in `/boot/grub' and `/grub'.
+
+ The options `--force-lba' and `--stage2' are just passed to
+ `install' if specified. *Note install::, for more information.
+
+
+File: grub.info, Node: testload, Next: testvbe, Prev: setup, Up: Command-line and menu entry commands
+
+13.3.35 testload
+----------------
+
+ -- Command: testload file
+ Read the entire contents of 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 `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.
+
+
+File: grub.info, Node: testvbe, Next: uppermem, Prev: testload, Up: Command-line and menu entry commands
+
+13.3.36 testvbe
+---------------
+
+ -- Command: testvbe mode
+ Test the VESA BIOS EXTENSION mode MODE. This command will switch
+ your video card to the graphics mode, and show an endless
+ animation. Hit any key to return. See also *Note vbeprobe::.
+
+
+File: grub.info, Node: uppermem, Next: vbeprobe, Prev: testvbe, Up: Command-line and menu entry commands
+
+13.3.37 uppermem
+----------------
+
+ -- Command: uppermem kbytes
+ Force GRUB to assume that only KBYTES kilobytes of upper memory
+ are installed. Any system address range maps are discarded.
+
+ *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 RAM on all new machines the author has ever heard of. It can
+ also be used for debugging purposes to lie to an OS.
+
+
+File: grub.info, Node: vbeprobe, Prev: uppermem, Up: Command-line and menu entry commands
+
+13.3.38 vbeprobe
+----------------
+
+ -- Command: vbeprobe [mode]
+ Probe VESA BIOS EXTENSION information. If the mode MODE is
+ specified, show only the information about MODE. Otherwise, this
+ command lists up available VBE modes on the screen. See also *Note
+ testvbe::.
+
+
+File: grub.info, Node: Troubleshooting, Next: Invoking the grub shell, Prev: Commands, Up: Top
+
+14 Error messages reported by GRUB
+**********************************
+
+This chapter describes error messages reported by GRUB when you
+encounter trouble. *Note 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
+
+
+File: grub.info, Node: Stage1 errors, Next: Stage1.5 errors, Up: Troubleshooting
+
+14.1 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 `<CTRL>-<ALT>-<DEL>' will reboot.
+
+ The following is a comprehensive list of error messages for the
+Stage 1:
+
+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.
+
+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.
+
+Read Error
+ A disk read error happened while trying to read the stage2 or
+ stage1.5.
+
+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).
+
+
+File: grub.info, Node: Stage1.5 errors, Next: Stage2 errors, Prev: Stage1 errors, Up: Troubleshooting
+
+14.2 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 `Error NUM' and then halt. Pressing
+`<CTRL>-<ALT>-<DEL>' will reboot.
+
+ The error numbers correspond to the errors reported by Stage 2.
+*Note Stage2 errors::.
+
+
+File: grub.info, Node: Stage2 errors, Prev: Stage1.5 errors, Up: Troubleshooting
+
+14.3 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):
+
+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 *Note Filesystem::.
+
+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.
+
+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.
+
+4 : Bad or incompatible header in compressed file
+ This error is returned if the file header for a supposedly
+ compressed file is bad.
+
+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.
+
+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.
+
+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.
+
+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.
+
+9 : Unknown boot failure
+ This error is returned if the boot attempt did not succeed for
+ reasons which are unknown.
+
+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.
+
+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 *Note
+ Filesystem::.
+
+12 : Invalid device requested
+ This error is returned if a device string is recognizable but does
+ not fall under the other device errors.
+
+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).
+
+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.
+
+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.
+
+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.
+
+17 : Cannot mount selected partition
+ This error is returned if the partition requested exists, but the
+ filesystem type cannot be recognized by GRUB.
+
+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).
+
+19 : Linux kernel must be loaded before initrd
+ This error is returned if the initrd command is used before
+ loading a Linux kernel.
+
+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.
+
+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.
+
+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.
+
+23 : Error while parsing number
+ This error is returned if GRUB was expecting to read a number and
+ encountered bad data.
+
+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).
+
+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.
+
+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.
+
+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.
+
+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.
+
+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.
+
+30 : Invalid argument
+ This error is returned if an argument specified to a command is
+ invalid.
+
+31 : File is not sector aligned
+ This error may occur only when you access a ReiserFS partition by
+ block-lists (e.g. the command `install'). In this case, you should
+ mount the partition with the `-o notail' option.
+
+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.
+
+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.
+
+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.
+
+
+File: grub.info, Node: Invoking the grub shell, Next: Invoking grub-install, Prev: Troubleshooting, Up: Top
+
+15 Invoking the grub shell
+**************************
+
+This chapter documents the grub shell `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 `grub'
+* Device map:: The map between BIOS drives and OS devices
+
+
+File: grub.info, Node: Basic usage, Next: Installation under UNIX, Up: Invoking the grub shell
+
+15.1 Introduction into the grub shell
+=====================================
+
+You can use the 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. `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 (*note Commands::) in `grub'. It is emulated by replacing BIOS
+calls with UNIX system calls and libc functions.
+
+ The command `grub' accepts the following options:
+
+`--help'
+ Print a summary of the command-line options and exit.
+
+`--version'
+ Print the version number of GRUB and exit.
+
+`--verbose'
+ Print some verbose messages for debugging purpose.
+
+`--device-map=FILE'
+ Use the device map file FILE. The format is described in *Note
+ Device map::.
+
+`--no-floppy'
+ Do not probe any floppy drive. This option has no effect if the
+ option `--device-map' is specified (*note Device map::).
+
+`--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 (*note Device map::), the
+ grub shell just ignores this option.
+
+`--config-file=FILE'
+ Read the configuration file FILE instead of `/boot/grub/menu.lst'.
+ The format is the same as the normal GRUB syntax. See *Note
+ Filesystem::, for more information.
+
+`--boot-drive=DRIVE'
+ Set the stage2 BOOT_DRIVE to DRIVE. This argument should be an
+ integer (decimal, octal or hexadecimal).
+
+`--install-partition=PAR'
+ Set the stage2 INSTALL_PARTITION to PAR. This argument should be
+ an integer (decimal, octal or hexadecimal).
+
+`--no-config-file'
+ Do not use the configuration file even if it can be read.
+
+`--no-curses'
+ Do not use the screen handling interface by the curses even if it
+ is available.
+
+`--batch'
+ This option has the same meaning as `--no-config-file --no-curses'.
+
+`--read-only'
+ Disable writing to any disk.
+
+`--hold'
+ Wait until a debugger will attach. This option is useful when you
+ want to debug the startup code.
+
+
+File: grub.info, Node: Installation under UNIX, Next: Device map, Prev: Basic usage, Up: Invoking the grub shell
+
+15.2 How to install GRUB via `grub'
+===================================
+
+The installation procedure is the same as under the "native" Stage 2.
+*Note Installation::, for more information. The command `grub'-specific
+information is described here.
+
+ What you should be careful about is "buffer cache". `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:
+
+ * If you can unmount drives to which GRUB may write any amount of
+ data, unmount them before running `grub'.
+
+ * 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.
+
+ * If a drive must be mounted with the read-write flag, make sure
+ that no activity is being done on it while the command `grub' is
+ running.
+
+ * 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.
+
+ In addition, enter the command `quit' when you finish the
+installation. That is _very important_ because `quit' makes the buffer
+cache consistent. Do not push <C-c>.
+
+ If you want to install GRUB non-interactively, specify `--batch'
+option in the command-line. This is a simple example:
+
+ #!/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
+
+
+File: grub.info, Node: Device map, Prev: Installation under UNIX, Up: Invoking the grub shell
+
+15.3 The map between BIOS drives and OS devices
+===============================================
+
+When you specify the option `--device-map' (*note Basic usage::), the
+grub shell creates the "device map file" automatically unless it
+already exists. The file name `/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:
+
+ DEVICE FILE
+
+ DEVICE is a drive specified in the GRUB syntax (*note Device
+syntax::), and 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 `#'.
+
+
+File: grub.info, Node: Invoking grub-install, Next: Invoking grub-md5-crypt, Prev: Invoking the grub shell, Up: Top
+
+16 Invoking grub-install
+************************
+
+The program `grub-install' installs GRUB on your drive using the grub
+shell (*note Invoking the grub shell::). You must specify the device
+name on which you want to install GRUB, like this:
+
+ grub-install INSTALL_DEVICE
+
+ The device name INSTALL_DEVICE is an OS device name or a GRUB device
+name.
+
+ `grub-install' accepts the following options:
+
+`--help'
+ Print a summary of the command-line options and exit.
+
+`--version'
+ Print the version number of GRUB and exit.
+
+`--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.
+
+`--root-directory=DIR'
+ Install GRUB images under the directory 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 "boot" partition which is mounted on
+ `/boot':
+
+ grub-install --root-directory=/boot hd0
+
+`--grub-shell=FILE'
+ Use FILE as the grub shell. You can append arbitrary options to
+ FILE after the file name, like this:
+
+ grub-install --grub-shell="grub --read-only" /dev/fd0
+
+`--recheck'
+ Recheck the device map, even if `/boot/grub/device.map' already
+ exists. You should use this option whenever you add/remove a disk
+ into/from your computer.
+
+
+File: grub.info, Node: Invoking grub-md5-crypt, Next: Invoking grub-terminfo, Prev: Invoking grub-install, Up: Top
+
+17 Invoking grub-md5-crypt
+**************************
+
+The program `grub-md5-crypt' encrypts a password in MD5 format. This
+is just a frontend of the grub shell (*note Invoking the grub shell::).
+Passwords encrypted by this program can be used with the command
+`password' (*note password::).
+
+ `grub-md5-crypt' accepts the following options:
+
+`--help'
+ Print a summary of the command-line options and exit.
+
+`--version'
+ Print the version information and exit.
+
+`--grub-shell=FILE'
+ Use FILE as the grub shell.
+
+
+File: grub.info, Node: Invoking grub-terminfo, Next: Invoking grub-set-default, Prev: Invoking grub-md5-crypt, Up: Top
+
+18 Invoking grub-terminfo
+*************************
+
+The program `grub-terminfo' generates a terminfo command from a
+terminfo name (*note 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).
+
+ `grub-terminfo' accepts the following options:
+
+`--help'
+ Print a summary of the command-line options and exit.
+
+`--version'
+ Print the version information and exit.
+
+ You must specify one argument to this command. For example:
+
+ grub-terminfo vt52
+
+
+File: grub.info, Node: Invoking grub-set-default, Next: Invoking mbchk, Prev: Invoking grub-terminfo, Up: Top
+
+19 Invoking grub-set-default
+****************************
+
+The program `grub-set-default' sets the default boot entry for GRUB.
+This automatically creates a file named `default' under your GRUB
+directory (i.e. `/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 `default saved' in your configuration file (*note default::),
+and to save next default boot entry when you use `savedefault' in a
+boot entry (*note savedefault::).
+
+ `grub-set-default' accepts the following options:
+
+`--help'
+ Print a summary of the command-line options and exit.
+
+`--version'
+ Print the version information and exit.
+
+`--root-directory=DIR'
+ Use the directory DIR instead of the root directory (i.e. `/') to
+ define the location of the default file. This is useful when you
+ mount a disk which is used for another system.
+
+ You must specify a single argument to `grub-set-default'. This
+argument is normally the number of a default boot entry. For example,
+if you have this configuration file:
+
+ default saved
+ timeout 10
+
+ title GNU/Hurd
+ root (hd0,0)
+ ...
+
+ title GNU/Linux
+ root (hd0,1)
+ ...
+
+ and if you want to set the next default boot entry to GNU/Linux, you
+may execute this command:
+
+ grub-set-default 1
+
+ Because the entry for GNU/Linux is `1'. Note that entries are
+counted from zero. So, if you want to specify GNU/Hurd here, then you
+should specify `0'.
+
+ This feature is very useful if you want to test a new kernel or to
+make your system quite robust. *Note Making your system robust::, for
+more hints about how to set up a robust system.
+
+
+File: grub.info, Node: Invoking mbchk, Next: Obtaining and Building GRUB, Prev: Invoking grub-set-default, Up: Top
+
+20 Invoking mbchk
+*****************
+
+The program `mbchk' checks for the format of a Multiboot kernel. We
+recommend using this program before booting your own kernel by GRUB.
+
+ `mbchk' accepts the following options:
+
+`--help'
+ Print a summary of the command-line options and exit.
+
+`--version'
+ Print the version number of GRUB and exit.
+
+`--quiet'
+ Suppress all normal output.
+
+
+File: grub.info, Node: Obtaining and Building GRUB, Next: Reporting bugs, Prev: Invoking mbchk, Up: Top
+
+Appendix A How to obtain and build GRUB
+***************************************
+
+ *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
+ `http://sources.redhat.com/binutils/', to obtain information on
+ how to get the latest version.
+
+ GRUB is available from the GNU alpha archive site
+`ftp://alpha.gnu.org/gnu/grub' or any of its mirrors. The file will be
+named grub-version.tar.gz. The current version is 0.97, so the file you
+should grab is:
+
+ `ftp://alpha.gnu.org/gnu/grub/grub-0.97.tar.gz'
+
+ To unbundle GRUB use the instruction:
+
+ zcat grub-0.97.tar.gz | tar xvf -
+
+ which will create a directory called `grub-0.97' with all the
+sources. You can look at the file `INSTALL' for detailed instructions
+on how to build and install GRUB, but you should be able to just do:
+
+ cd grub-0.97
+ ./configure
+ make install
+
+ This will install the grub shell `grub' (*note Invoking the grub
+shell::), the Multiboot checker `mbchk' (*note Invoking mbchk::), and
+the GRUB images. This will also install the GRUB manual.
+
+ Also, the latest version is available from the CVS. See
+`http://savannah.gnu.org/cvs/?group=grub' for more information.
+
+
+File: grub.info, Node: Reporting bugs, Next: Future, Prev: Obtaining and Building GRUB, Up: Top
+
+Appendix B Reporting bugs
+*************************
+
+These are the guideline for how to report bugs. Take a look at this
+list below before you submit bugs:
+
+ 1. Before getting unsettled, read this manual through and through.
+ Also, see the GNU GRUB FAQ
+ (http://www.gnu.org/software/grub/grub-faq.html).
+
+ 2. 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.
+
+ 3. If you have trouble with the installation, inform us of how you
+ installed GRUB. Don't omit error messages, if any. Just `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.
+
+ 4. If GRUB cannot boot your operating system, write down _everything_
+ you see on the screen. Don't paraphrase them, like `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.
+
+ 5. Explain what you wanted to do. It is very useful to know your
+ purpose and your wish, and how GRUB didn't satisfy you.
+
+ 6. 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.
+
+ 7. 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.
+
+ If you follow the guideline above, submit a report to the Bug
+Tracking System (http://savannah.gnu.org/bugs/?group=grub).
+Alternatively, you can submit a report via electronic mail to
+<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.
+
+
+File: grub.info, Node: Future, Next: Internals, Prev: Reporting bugs, Up: Top
+
+Appendix C 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 the homepage (http://www.gnu.org/software/grub/grub.html).
+
+
+File: grub.info, Node: Internals, Next: Index, Prev: Future, Up: Top
+
+Appendix D 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
+
+
+File: grub.info, Node: Memory map, Next: Embedded data, Up: Internals
+
+D.1 The memory map of various components
+========================================
+
+GRUB consists of two distinct components, called "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:
+
+0 to 4K-1
+ BIOS and real mode interrupts
+
+0x07BE to 0x07FF
+ Partition table passed to another boot loader
+
+down from 8K-1
+ Real mode stack
+
+0x2000 to ?
+ The optional Stage 1.5 is loaded here
+
+0x2000 to 0x7FFF
+ Command-line buffer for Multiboot kernels and modules
+
+0x7C00 to 0x7DFF
+ Stage 1 is loaded here by BIOS or another boot loader
+
+0x7F00 to 0x7F42
+ LBA drive parameters
+
+0x8000 to ?
+ Stage2 is loaded here
+
+The end of Stage 2 to 416K-1
+ Heap, in particular used for the menu
+
+down from 416K-1
+ Protected mode stack
+
+416K to 448K-1
+ Filesystem buffer
+
+448K to 479.5K-1
+ Raw device buffer
+
+479.5K to 480K-1
+ 512-byte scratch area
+
+480K to 512K-1
+ Buffers for various functions, such as password, command-line, cut
+ and paste, and completion.
+
+The last 1K of lower memory
+ Disk swapping code and data
+
+ See the file `stage2/shared.h', for more information.
+
+
+File: grub.info, Node: Embedded data, Next: Filesystem interface, Prev: Memory map, Up: Internals
+
+D.2 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:
+
+`0x3E'
+ The version number (not GRUB's, but the installation mechanism's).
+
+`0x40'
+ The boot drive. If it is 0xFF, use a drive passed by BIOS.
+
+`0x41'
+ The flag for if forcing LBA.
+
+`0x42'
+ The starting address of Stage 2.
+
+`0x44'
+ The first sector of Stage 2.
+
+`0x48'
+ The starting segment of Stage 2.
+
+`0x1FE'
+ The signature (`0xAA55').
+
+ See the file `stage1/stage1.S', for more information.
+
+ In the first sector of Stage 1.5 and Stage 2, the block lists are
+recorded between `firstlist' and `lastlist'. The address of `lastlist'
+is determined when assembling the 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 `firstlist' label. Note that it is always from the
+beginning of the disk, but _not_ relative to the partition boundaries.
+
+ In the second sector of Stage 1.5 and Stage 2, these are defined:
+
+`0x6'
+ The version number (likewise, the installation mechanism's).
+
+`0x8'
+ The installed partition.
+
+`0xC'
+ The saved entry number.
+
+`0x10'
+ The identifier.
+
+`0x11'
+ The flag for if forcing LBA.
+
+`0x12'
+ The version string (GRUB's).
+
+`0x12' + "the length of the version string"
+ The name of a configuration file.
+
+ See the file `stage2/asm.S', for more information.
+
+
+File: grub.info, Node: Filesystem interface, Next: Command interface, Prev: Embedded data, Up: Internals
+
+D.3 The generic interface for filesystems
+=========================================
+
+For any particular partition, it is presumed that only one of the
+"normal" filesystems such as FAT, FFS, or ext2fs can be used, so there
+is a switch table managed by the functions in `disk_io.c'. The notation
+is that you can only "mount" one at a time.
+
+ The block list filesystem has a special place in the system. In
+addition to the "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:
+
+`current_drive'
+ The current BIOS drive number (numbered from 0, if a floppy, and
+ numbered from 0x80, if a hard disk).
+
+`current_partition'
+ The current partition number.
+
+`current_slice'
+ The current partition type.
+
+`saved_drive'
+ The "drive" part of the root device.
+
+`saved_partition'
+ The "partition" part of the root device.
+
+`part_start'
+ The current partition starting address, in sectors.
+
+`part_length'
+ The current partition length, in sectors.
+
+`print_possibilities'
+ True when the `dir' function should print the possible completions
+ of a file, and false when it should try to actually open a file of
+ that name.
+
+`FSYS_BUF'
+ Filesystem buffer which is 32K in size, to use in any way which the
+ filesystem backend desires.
+
+ The variables which need to be written by a filesystem backend are:
+
+`filepos'
+ The current position in the file, in sectors.
+
+ *Caution:* the value of 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!
+
+`filemax'
+ The length of the file.
+
+`disk_read_func'
+ The value of DISK_READ_HOOK _only_ during reading of data for the
+ file, not any other fs data, inodes, FAT tables, whatever, then
+ set to `NULL' at all other times (it will be `NULL' by default).
+ If this isn't done correctly, then the `testload' and `install'
+ commands won't work correctly.
+
+ The functions expected to be used by the filesystem backend are:
+
+`devread'
+ Only read sectors from within a partition. Sector 0 is the first
+ sector in the partition.
+
+`grub_read'
+ If the backend uses the block list code, then `grub_read' can be
+ used, after setting BLOCK_FILE to 1.
+
+`print_a_completion'
+ If PRINT_POSSIBILITIES is true, call `print_a_completion' for each
+ possible file name. Otherwise, the file name completion won't work.
+
+ The functions expected to be defined by the filesystem backend are
+described at least moderately in the file `filesys.h'. Their usage is
+fairly evident from their use in the functions in `disk_io.c', look for
+the use of the FSYS_TABLE array.
+
+ *Caution:* The semantics are such that then `mount'ing the
+filesystem, presume the filesystem buffer `FSYS_BUF' is corrupted, and
+(re-)load all important contents. When opening and reading a file,
+presume that the data from the `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).
+
+
+File: grub.info, Node: Command interface, Next: Bootstrap tricks, Prev: Filesystem interface, Up: Internals
+
+D.4 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 `int' value. The "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 ERRNUM.
+
+ The table of the information is represented by the structure `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 `title').
+
+ The table is finally registered in the table BUILTIN_TABLE, so that
+`run_script' and `enter_cmdline' can find the command. See the files
+`cmdline.c' and `builtins.c', for more details.
+
+
+File: grub.info, Node: Bootstrap tricks, Next: I/O ports detection, Prev: Command interface, Up: Internals
+
+D.5 The bootstrap mechanism used in GRUB
+========================================
+
+The disk space can be used in a boot loader is very restricted because
+a MBR (*note MBR::) is only 512 bytes but it also contains a partition
+table (*note 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, "Stage 1" and "Stage 2" (and optionally "Stage
+1.5"). *Note 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 "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 (*note 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:
+
+ 1. Initialize the system briefly.
+
+ 2. Detect the geometry and the accessing mode of the "loading drive".
+
+ 3. Load the first sector of Stage 2.
+
+ 4. Jump to the starting address of the Stage 2.
+
+ The flow of Stage 2 (and Stage 1.5) is:
+
+ 1. 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.
+
+ 2. Long jump to the real starting address.
+
+ Note that Stage 2 (or Stage 1.5) does not probe the geometry or the
+accessing mode of the "loading drive", since Stage 1 has already probed
+them.
+
+
+File: grub.info, Node: I/O ports detection, Next: Memory detection, Prev: Bootstrap tricks, Up: Internals
+
+D.6 How to probe I/O ports used by INT 13H
+==========================================
+
+FIXME: I will write this chapter after implementing the new technique.
+
+
+File: grub.info, Node: Memory detection, Next: Low-level disk I/O, Prev: I/O ports detection, Up: Internals
+
+D.7 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.
+
+
+File: grub.info, Node: Low-level disk I/O, Next: MBR, Prev: Memory detection, Up: Internals
+
+D.8 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.
+
+
+File: grub.info, Node: MBR, Next: Partition table, Prev: Low-level disk I/O, Up: Internals
+
+D.9 The structure of Master Boot Record
+=======================================
+
+FIXME: Likewise.
+
+
+File: grub.info, Node: Partition table, Next: Submitting patches, Prev: MBR, Up: Internals
+
+D.10 The format of partition tables
+===================================
+
+FIXME: Probably the original chapter is derived from "How It Works", so
+I will rewrite this chapter.
+
+
+File: grub.info, Node: Submitting patches, Prev: Partition table, Up: Internals
+
+D.11 Where and how you should send patches
+==========================================
+
+When you write patches for GRUB, please send them to the mailing list
+<bug-grub@gnu.org>. Here is the list of items of which you should take
+care:
+
+ * 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.
+
+ * Use as late code as possible, for the original code. The CVS
+ repository always has the current version (*note Obtaining and
+ Building GRUB::).
+
+ * Write ChangeLog entries. *Note Change Logs: (standards)Change
+ Logs, if you don't know how to write ChangeLog.
+
+ * Make patches in unified diff format. `diff -urN' is appropriate in
+ most cases.
+
+ * Don't make patches reversely. Reverse patches are difficult to
+ read and use.
+
+ * 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.
+
+ * 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.
+
+
+File: grub.info, Node: Index, Prev: Internals, Up: Top
+
+Index
+*****
+
+
+* Menu:
+
+* blocklist: blocklist. (line 7)
+* boot: boot. (line 7)
+* bootp: bootp. (line 7)
+* cat: cat. (line 7)
+* chainloader: chainloader. (line 7)
+* cmp: cmp. (line 7)
+* color: color. (line 7)
+* configfile: configfile. (line 7)
+* current_drive: Filesystem interface. (line 19)
+* current_partition: Filesystem interface. (line 23)
+* current_slice: Filesystem interface. (line 26)
+* debug: debug. (line 7)
+* default: default. (line 7)
+* device: device. (line 7)
+* devread: Filesystem interface. (line 71)
+* dhcp: dhcp. (line 7)
+* disk_read_func: Filesystem interface. (line 62)
+* displayapm: displayapm. (line 7)
+* displaymem: displaymem. (line 7)
+* embed: embed. (line 7)
+* fallback: fallback. (line 7)
+* filemax: Filesystem interface. (line 59)
+* filepos: Filesystem interface. (line 52)
+* find: find. (line 7)
+* fstest: fstest. (line 7)
+* FSYS_BUF: Filesystem interface. (line 46)
+* geometry: geometry. (line 7)
+* grub_read: Filesystem interface. (line 75)
+* halt: halt. (line 7)
+* help: help. (line 7)
+* hiddenmenu: hiddenmenu. (line 7)
+* hide: hide. (line 7)
+* ifconfig: ifconfig. (line 8)
+* impsprobe: impsprobe. (line 7)
+* initrd: initrd. (line 7)
+* install: install. (line 9)
+* ioprobe: ioprobe. (line 7)
+* kernel: kernel. (line 7)
+* lock: lock. (line 7)
+* makeactive: makeactive. (line 7)
+* map: map. (line 7)
+* md5crypt: md5crypt. (line 7)
+* module: module. (line 7)
+* modulenounzip: modulenounzip. (line 7)
+* pager: pager. (line 7)
+* part_length: Filesystem interface. (line 38)
+* part_start: Filesystem interface. (line 35)
+* partnew: partnew. (line 7)
+* parttype: parttype. (line 7)
+* password: password. (line 7)
+* pause: pause. (line 7)
+* print_a_completion: Filesystem interface. (line 79)
+* print_possibilities: Filesystem interface. (line 41)
+* quit: quit. (line 7)
+* rarp: rarp. (line 7)
+* read: read. (line 7)
+* reboot: reboot. (line 7)
+* root: root. (line 7)
+* rootnoverify: rootnoverify. (line 7)
+* saved_drive: Filesystem interface. (line 29)
+* saved_partition: Filesystem interface. (line 32)
+* savedefault: savedefault. (line 7)
+* serial: serial. (line 9)
+* setkey: setkey. (line 7)
+* setup: setup. (line 8)
+* terminal: terminal. (line 9)
+* terminfo: terminfo. (line 9)
+* testload: testload. (line 7)
+* testvbe: testvbe. (line 7)
+* tftpserver: tftpserver. (line 7)
+* timeout: timeout. (line 7)
+* title: title. (line 7)
+* unhide: unhide. (line 7)
+* uppermem: uppermem. (line 7)
+* vbeprobe: vbeprobe. (line 7)
+
+
+
+Tag Table:
+Node: Top1487
+Node: Introduction3266
+Node: Overview3643
+Node: Overview-Footnotes5865
+Ref: Overview-Footnote-15926
+Node: History6087
+Node: Features7208
+Node: Features-Footnotes12976
+Ref: Features-Footnote-113037
+Node: Role of a boot loader13182
+Node: Role of a boot loader-Footnotes14520
+Ref: Role of a boot loader-Footnote-114607
+Node: Naming convention14686
+Node: Installation17621
+Node: Creating a GRUB boot floppy19363
+Node: Installing GRUB natively20181
+Node: Installing GRUB natively-Footnotes22461
+Ref: Installing GRUB natively-Footnote-122554
+Node: Installing GRUB using grub-install22739
+Node: Making a GRUB bootable CD-ROM25685
+Node: Making a GRUB bootable CD-ROM-Footnotes27730
+Ref: Making a GRUB bootable CD-ROM-Footnote-127833
+Node: Booting27908
+Node: General boot methods28363
+Node: Loading an operating system directly29104
+Node: Chain-loading30408
+Node: Chain-loading-Footnotes31718
+Ref: Chain-loading-Footnote-131789
+Node: OS-specific notes31861
+Node: GNU/Hurd32237
+Node: GNU/Linux32856
+Node: FreeBSD34104
+Node: NetBSD34617
+Node: OpenBSD35275
+Node: DOS/Windows35475
+Node: SCO UnixWare37301
+Node: QNX37719
+Node: Making your system robust37969
+Node: Booting once-only39294
+Node: Booting fallback systems41219
+Node: Configuration44066
+Node: Network48495
+Node: General usage of network support48989
+Node: General usage of network support-Footnotes50850
+Ref: General usage of network support-Footnote-150959
+Node: Diskless51027
+Node: Serial terminal53211
+Node: Preset Menu55444
+Node: Security57812
+Node: Images60620
+Node: Filesystem63131
+Node: Device syntax63814
+Node: File name syntax65308
+Node: Block list syntax66051
+Node: Interface66784
+Node: Command-line interface67661
+Node: Command-line interface-Footnotes69602
+Ref: Command-line interface-Footnote-169691
+Node: Menu interface69786
+Node: Menu entry editor70796
+Node: Hidden menu interface71875
+Node: Commands72452
+Node: Menu-specific commands73029
+Node: default74200
+Node: fallback74678
+Node: hiddenmenu75229
+Node: timeout75717
+Node: title75995
+Node: General commands76266
+Node: bootp77579
+Node: color78058
+Node: device79532
+Node: dhcp80104
+Node: hide80689
+Node: ifconfig81066
+Node: pager81642
+Node: partnew81976
+Node: parttype82412
+Node: password82779
+Node: rarp83598
+Node: serial83899
+Node: setkey85172
+Node: terminal87341
+Node: terminfo88878
+Node: tftpserver89565
+Node: unhide90111
+Node: Command-line and menu entry commands90486
+Node: blocklist93017
+Node: boot93259
+Node: cat93580
+Node: chainloader93884
+Node: cmp94500
+Node: configfile95051
+Node: debug95265
+Node: displayapm95649
+Node: displaymem95860
+Node: embed96562
+Node: embed-Footnotes97096
+Ref: embed-Footnote-197151
+Node: find97208
+Node: fstest97588
+Node: geometry98273
+Node: halt98885
+Node: help99212
+Node: impsprobe99833
+Node: initrd100232
+Node: install100571
+Node: install-Footnotes103415
+Ref: install-Footnote-1103474
+Node: ioprobe103571
+Node: kernel103896
+Node: lock105016
+Node: makeactive105591
+Node: map105903
+Node: md5crypt106470
+Node: module106817
+Node: modulenounzip107394
+Node: pause107687
+Node: quit108101
+Node: reboot108377
+Node: read108558
+Node: root108800
+Node: rootnoverify109677
+Node: savedefault110232
+Node: setup111208
+Node: testload112274
+Node: testvbe112884
+Node: uppermem113255
+Node: vbeprobe113837
+Node: Troubleshooting114220
+Node: Stage1 errors114758
+Node: Stage1.5 errors116135
+Node: Stage2 errors116573
+Node: Invoking the grub shell124033
+Node: Basic usage124786
+Node: Installation under UNIX127073
+Node: Device map128748
+Node: Invoking grub-install129896
+Node: Invoking grub-md5-crypt131484
+Node: Invoking grub-terminfo132133
+Node: Invoking grub-set-default132899
+Node: Invoking mbchk134700
+Node: Obtaining and Building GRUB135214
+Node: Reporting bugs136631
+Node: Future139435
+Node: Internals139926
+Node: Memory map141149
+Node: Embedded data142627
+Node: Filesystem interface144644
+Node: Command interface148077
+Node: Bootstrap tricks149392
+Node: I/O ports detection151541
+Node: Memory detection151813
+Node: Low-level disk I/O152105
+Node: MBR152374
+Node: Partition table152571
+Node: Submitting patches152844
+Node: Index154332
+
+End Tag Table
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
@@ -0,0 +1,1662 @@
+This is ../../docs/multiboot.info, produced by makeinfo version 4.7
+from ../../docs/multiboot.texi.
+
+INFO-DIR-SECTION Kernel
+START-INFO-DIR-ENTRY
+* Multiboot Specification: (multiboot). Multiboot Specification.
+END-INFO-DIR-ENTRY
+
+ Copyright (C) 1995, 96 Bryan Ford <baford@cs.utah.edu> Copyright (C)
+1995, 96 Erich Stefan Boleyn <erich@uruk.org> Copyright (C) 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.
+
+
+File: multiboot.info, Node: Top, Next: Overview, Up: (dir)
+
+Multiboot Specification
+***********************
+
+This file documents Multiboot Specification, the proposal for the boot
+sequence standard. This edition documents version 0.6.93.
+
+* Menu:
+
+* Overview::
+* Terminology::
+* Specification::
+* Examples::
+* History::
+* Index::
+
+
+File: multiboot.info, Node: Overview, Next: Terminology, Prev: Top, Up: Top
+
+1 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::
+
+
+File: multiboot.info, Node: Motivation, Next: Architecture, Up: Overview
+
+1.1 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
+"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 _not_ specify how boot loaders should work -- only
+how they must interface with the operating system being loaded.
+
+
+File: multiboot.info, Node: Architecture, Next: Operating systems, Prev: Motivation, Up: Overview
+
+1.2 The target architecture
+===========================
+
+This specification is primarily targeted at 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.
+
+
+File: multiboot.info, Node: Operating systems, Next: Boot sources, Prev: Architecture, Up: Overview
+
+1.3 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.
+
+
+File: multiboot.info, Node: Boot sources, Next: Boot-time configuration, Prev: Operating systems, Up: Overview
+
+1.4 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 "block lists" (e.g. LILO), loading from a special
+"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.
+
+
+File: multiboot.info, Node: Boot-time configuration, Next: Convenience to operating systems, Prev: Boot sources, Up: Overview
+
+1.5 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.
+
+
+File: multiboot.info, Node: Convenience to operating systems, Next: Boot modules, Prev: Boot-time configuration, Up: Overview
+
+1.6 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 `nm' or
+disassemble OS images just like normal executables. Specialized tools
+should not be required to create OS images in a _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 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 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 "Multiboot header"
+(*note 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.
+
+
+File: multiboot.info, Node: Boot modules, Prev: Convenience to operating systems, Up: Overview
+
+1.7 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.
+
+
+File: multiboot.info, Node: Terminology, Next: Specification, Prev: Overview, Up: Top
+
+2 The definitions of terms used through the specification
+*********************************************************
+
+"must"
+ We use the term "must", when any boot loader or OS image needs to
+ follow a rule -- otherwise, the boot loader or OS image is _not_
+ Multiboot-compliant.
+
+"should"
+ We use the term "should", when any boot loader or OS image is
+ recommended to follow a rule, but it doesn't need to follow the
+ rule.
+
+"may"
+ We use the term "may", when any boot loader or OS image is allowed
+ to follow a rule.
+
+"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 _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 "Multiboot-compliant"; earlier boot loader
+ stages may be designed in whatever way is most convenient.
+
+"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.
+
+"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.
+
+"Multiboot-compliant"
+ A boot loader or an OS image which follows the rules defined as
+ "must" is Multiboot-compliant. When this specification specifies a
+ rule as "should" or "may", a Multiboot-complaint boot loader/OS
+ image doesn't need to follow the rule.
+
+"u8"
+ The type of unsigned 8-bit data.
+
+"u16"
+ The type of unsigned 16-bit data. Because the target architecture
+ is little-endian, u16 is coded in little-endian.
+
+"u32"
+ The type of unsigned 32-bit data. Because the target architecture
+ is little-endian, u32 is coded in little-endian.
+
+"u64"
+ The type of unsigned 64-bit data. Because the target architecture
+ is little-endian, u64 is coded in little-endian.
+
+
+File: multiboot.info, Node: Specification, Next: Examples, Prev: Terminology, Up: Top
+
+3 The exact definitions of Multiboot Specification
+**************************************************
+
+There are three main aspects of a boot loader/OS image interface:
+
+ 1. The format of an OS image as seen by a boot loader.
+
+ 2. The state of a machine when a boot loader starts an operating
+ system.
+
+ 3. The format of information passed by a boot loader to an operating
+ system.
+
+* Menu:
+
+* OS image format::
+* Machine state::
+* Boot information format::
+
+
+File: multiboot.info, Node: OS image format, Next: Machine state, Up: Specification
+
+3.1 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
+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 "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 _as early as possible_, and may be embedded in
+the beginning of the text segment after the _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::
+
+
+File: multiboot.info, Node: Header layout, Next: Header magic fields, Up: OS image format
+
+3.1.1 The layout of Multiboot header
+------------------------------------
+
+The layout of the Multiboot header must be as follows:
+
+Offset Type Field Name Note
+0 u32 magic required
+4 u32 flags required
+8 u32 checksum required
+12 u32 header_addr if flags[16] is set
+16 u32 load_addr if flags[16] is set
+20 u32 load_end_addr if flags[16] is set
+24 u32 bss_end_addr if flags[16] is set
+28 u32 entry_addr if flags[16] is set
+32 u32 mode_type if flags[2] is set
+36 u32 width if flags[2] is set
+40 u32 height if flags[2] is set
+44 u32 depth if flags[2] is set
+
+ The fields `magic', `flags' and `checksum' are defined in *Note
+Header magic fields::, the fields `header_addr', `load_addr',
+`load_end_addr', `bss_end_addr' and `entry_addr' are defined in *Note
+Header address fields::, and the fields `mode_type', `width', `height'
+and `depth' are defind in *Note Header graphics fields::.
+
+
+File: multiboot.info, Node: Header magic fields, Next: Header address fields, Prev: Header layout, Up: OS image format
+
+3.1.2 The magic fields of Multiboot header
+------------------------------------------
+
+`magic'
+ The field `magic' is the magic number identifying the header,
+ which must be the hexadecimal value `0x1BADB002'.
+
+`flags'
+ The field `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 `flags' word must be set to zero in OS images. This
+ way, the `flags' fields serves for version control as well as
+ simple feature selection.
+
+ If bit 0 in the `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 `flags' word is set, then information on available
+ memory via at least the `mem_*' fields of the Multiboot information
+ structure (*note Boot information format::) must be included. If
+ the boot loader is capable of passing a memory map (the `mmap_*'
+ fields) and one exists, then it may be included as well.
+
+ If bit 2 in the `flags' word is set, information about the video
+ mode table (*note Boot information format::) must be available to
+ the kernel.
+
+ If bit 16 in the `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 ELF format, but it
+ _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 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.
+
+`checksum'
+ The field `checksum' is a 32-bit unsigned value which, when added
+ to the other magic fields (i.e. `magic' and `flags'), must have a
+ 32-bit unsigned sum of zero.
+
+
+File: multiboot.info, Node: Header address fields, Next: Header graphics fields, Prev: Header magic fields, Up: OS image format
+
+3.1.3 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:
+
+`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
+ "synchronize" the mapping between OS image offsets and physical
+ memory addresses.
+
+`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.
+
+`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.
+
+`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.
+
+`entry_addr'
+ The physical address to which the boot loader should jump in order
+ to start running the operating system.
+
+
+File: multiboot.info, Node: Header graphics fields, Prev: Header address fields, Up: OS image format
+
+3.1.4 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 _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:
+
+`mode_type'
+ Contains `0' for linear graphics mode or `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
+ `0'.
+
+`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.
+
+`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.
+
+`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.
+
+
+File: multiboot.info, Node: Machine state, Next: Boot information format, Prev: OS image format, Up: Specification
+
+3.2 Machine state
+=================
+
+When the boot loader invokes the 32-bit operating system, the machine
+must have the following state:
+
+`EAX'
+ Must contain the magic value `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).
+
+`EBX'
+ Must contain the 32-bit physical address of the Multiboot
+ information structure provided by the boot loader (*note Boot
+ information format::).
+
+`CS'
+ Must be a 32-bit read/execute code segment with an offset of `0'
+ and a limit of `0xFFFFFFFF'. The exact value is undefined.
+
+`DS'
+`ES'
+`FS'
+`GS'
+`SS'
+ Must be a 32-bit read/write data segment with an offset of `0' and
+ a limit of `0xFFFFFFFF'. The exact values are all undefined.
+
+`A20 gate'
+ Must be enabled.
+
+`CR0'
+ Bit 31 (PG) must be cleared. Bit 0 (PE) must be set. Other bits are
+ all undefined.
+
+`EFLAGS'
+ Bit 17 (VM) must be cleared. Bit 9 (IF) must be cleared. Other bits
+ are all undefined.
+
+ All other processor registers and flag bits are undefined. This
+includes, in particular:
+
+`ESP'
+ The OS image must create its own stack as soon as it needs one.
+
+`GDTR'
+ Even though the segment registers are set up as described above,
+ the `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 `GDT'.
+
+`IDTR'
+ The OS image must leave interrupts disabled until it sets up its
+ own `IDT'.
+
+ However, other machine state should be left by the boot loader in
+"normal working order", i.e. as initialized by the BIOS (or DOS, if
+that's what the boot loader runs from). In other words, the operating
+system should be able to make BIOS calls and such after being loaded,
+as long as it does not overwrite the BIOS data structures before doing
+so. Also, the boot loader must leave the PIC programmed with the normal
+BIOS/DOS values, even if it changed them during the switch to 32-bit
+mode.
+
+
+File: multiboot.info, Node: Boot information format, Prev: Machine state, Up: Specification
+
+3.3 Boot information format
+===========================
+
+FIXME: Split this chapter like the chapter "OS image format".
+
+ Upon entry to the operating system, the `EBX' register contains the
+physical address of a "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:
+
+ +-------------------+
+ 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 |
+ +-------------------+
+
+ 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
+`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 `flags' word is set, then the `mem_*' fields are
+valid. `mem_lower' and `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 `flags' word is set, then the `boot_device' field is
+valid, and indicates which BIOS disk device the boot loader loaded the
+OS image from. If the OS image was not loaded from a 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 "root"
+device, but is not required to. The `boot_device' field is laid out in
+four one-byte subfields as follows:
+
+ +-------+-------+-------+-------+
+ | drive | part1 | part2 | part3 |
+ +-------+-------+-------+-------+
+
+ The first byte contains the BIOS drive number as understood by the
+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. `part1'
+specifies the "top-level" partition number, `part2' specifies a
+"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 `part1' contains the DOS partition number,
+and `part2' and `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
+"disklabel" strategy, then `part1' contains the DOS partition number,
+`part2' contains the BSD sub-partition within that DOS partition, and
+`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 `part1' will be 5, and `part2' and `part3' will both be
+0xFF.
+
+ If bit 2 of the `flags' longword is set, the `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 `flags' is set, then the `mods' fields indicate to
+the kernel what boot modules were loaded along with the kernel image,
+and where they can be found. `mods_count' contains the number of
+modules loaded; `mods_addr' contains the physical address of the first
+module structure. `mods_count' may be zero, indicating no boot modules
+were loaded, even if bit 1 of `flags' is set. Each module structure is
+formatted as follows:
+
+ +-------------------+
+ 0 | mod_start |
+ 4 | mod_end |
+ +-------------------+
+ 8 | string |
+ +-------------------+
+ 12 | reserved (0) |
+ +-------------------+
+
+ The first two fields contain the start and end addresses of the boot
+module itself. The `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 `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 `reserved' field must be set
+to 0 by the boot loader and ignored by the operating system.
+
+ *Caution:* Bits 4 & 5 are mutually exclusive.
+
+ If bit 4 in the `flags' word is set, then the following fields in
+the Multiboot information structure starting at byte 28 are valid:
+
+ +-------------------+
+ 28 | tabsize |
+ 32 | strsize |
+ 36 | addr |
+ 40 | reserved (0) |
+ +-------------------+
+
+ These indicate where the symbol table from an a.out kernel image can
+be found. `addr' is the physical address of the size (4-byte unsigned
+long) of an array of a.out format "nlist" structures, followed
+immediately by the array itself, then the size (4-byte unsigned long) of
+a set of zero-terminated ASCII strings (plus sizeof(unsigned long) in
+this case), and finally the set of strings itself. `tabsize' is equal
+to its size parameter (found at the beginning of the symbol section),
+and `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 `tabsize' may be 0, indicating no symbols, even
+if bit 4 in the `flags' word is set.
+
+ If bit 5 in the `flags' word is set, then the following fields in
+the Multiboot information structure starting at byte 28 are valid:
+
+ +-------------------+
+ 28 | num |
+ 32 | size |
+ 36 | addr |
+ 40 | shndx |
+ +-------------------+
+
+ 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 `shdr_*' entries
+(`shdr_num', etc.) in the Executable and Linkable Format (ELF)
+specification in the program header. All sections are loaded, and the
+physical address fields of the ELF section header then refer to where
+the sections are in memory (refer to the i386 ELF documentation for
+details as to how to read the section header(s)). Note that `shdr_num'
+may be 0, indicating no symbols, even if bit 5 in the `flags' word is
+set.
+
+ If bit 6 in the `flags' word is set, then the `mmap_*' fields are
+valid, and indicate the address and length of a buffer containing a
+memory map of the machine provided by the BIOS. `mmap_addr' is the
+address, and `mmap_length' is the total size of the buffer. The buffer
+consists of one or more of the following size/structure pairs (`size'
+is really used for skipping to the next pair):
+
+ +-------------------+
+ -4 | size |
+ +-------------------+
+ 0 | base_addr_low |
+ 4 | base_addr_high |
+ 8 | length_low |
+ 12 | length_high |
+ 16 | type |
+ +-------------------+
+
+ where `size' is the size of the associated structure in bytes, which
+can be greater than the minimum of 20 bytes. `base_addr_low' is the
+lower 32 bits of the starting address, and `base_addr_high' is the
+upper 32 bits, for a total of a 64-bit starting address. `length_low'
+is the lower 32 bits of the size of the memory region in bytes, and
+`length_high' is the upper 32 bits, for a total of a 64-bit length.
+`type' is the variety of address range represented, where a value of 1
+indicates available RAM, and all other values currently indicated a
+reserved area.
+
+ The map provided is guaranteed to list all standard RAM that should
+be available for normal use.
+
+ If bit 7 in the `flags' is set, then the `drives_*' fields are
+valid, and indicate the address of the physical address of the first
+drive structure and the size of drive structures. `drives_addr' is the
+address, and `drives_length' is the total size of drive structures.
+Note that `drives_length' may be zero. Each drive structure is
+formatted as follows:
+
+ +-------------------+
+ 0 | size |
+ +-------------------+
+ 4 | drive_number |
+ +-------------------+
+ 5 | drive_mode |
+ +-------------------+
+ 6 | drive_cylinders |
+ 8 | drive_heads |
+ 9 | drive_sectors |
+ +-------------------+
+ 10 - xx | drive_ports |
+ +-------------------+
+
+ The `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 `drive_number' field contains the BIOS drive number. The
+`drive_mode' field represents the access mode used by the boot loader.
+Currently, the following modes are defined:
+
+`0'
+ CHS mode (traditional cylinder/head/sector addressing mode).
+
+`1'
+ LBA mode (Logical Block Addressing mode).
+
+ The three fields, `drive_cylinders', `drive_heads' and
+`drive_sectors', indicate the geometry of the drive detected by the
+BIOS. `drive_cylinders' contains the number of the cylinders.
+`drive_heads' contains the number of the heads. `drive_sectors'
+contains the number of the sectors per track.
+
+ The `drive_ports' field contains the array of the I/O ports used for
+the drive in the 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 DMA controller's ports).
+
+ If bit 8 in the `flags' is set, then the `config_table' field is
+valid, and indicates the address of the ROM configuration table
+returned by the "GET CONFIGURATION" BIOS call. If the BIOS call fails,
+then the size of the table must be _zero_.
+
+ If bit 9 in the `flags' is set, the `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 `flags' is set, the `apm_table' field is valid, and
+contains the physical address of an APM table defined as below:
+
+ +----------------------+
+ 0 | version |
+ 2 | cseg |
+ 4 | offset |
+ 8 | cseg_16 |
+ 10 | dseg |
+ 12 | flags |
+ 14 | cseg_len |
+ 16 | cseg_16_len |
+ 18 | dseg_len |
+ +----------------------+
+
+ The fields `version', `cseg', `offset', `cseg_16', `dseg', `flags',
+`cseg_len', `cseg_16_len', `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 `offset' is 4 bytes, and the others are 2 bytes. See Advanced
+Power Management (APM) BIOS Interface Specification
+(http://www.microsoft.com/hwdev/busbios/amp_12.htm), for more
+information.
+
+ If bit 11 in the `flags' is set, the graphics table is available.
+This must only be done if the kernel has indicated in the `Multiboot
+Header' that it accepts a graphics mode.
+
+ The fields `vbe_control_info' and `vbe_mode_info' contain the
+physical addresses of VBE control information returned by the VBE
+Function 00h and VBE mode information returned by the VBE Function 01h,
+respectively.
+
+ The field `vbe_mode' indicates current video mode in the format
+specified in VBE 3.0.
+
+ The rest fields `vbe_interface_seg', `vbe_interface_off', and
+`vbe_interface_len' contain the table of a protected mode interface
+defined in VBE 2.0+. If this information is not available, those fields
+contain zero. Note that 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 VBE, but
+Multiboot boot loaders may simulate VBE on non-VBE modes, as if they
+were VBE modes.
+
+
+File: multiboot.info, Node: Examples, Next: History, Prev: Specification, Up: Top
+
+4 Examples
+**********
+
+*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::
+
+
+File: multiboot.info, Node: Notes on PC, Next: BIOS device mapping techniques, Up: Examples
+
+4.1 Notes on PC
+===============
+
+In reference to bit 0 of the `flags' parameter in the Multiboot
+information structure, if the bootloader in question uses older 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 _highly_ recommended that boot loaders perform a
+thorough memory probe.
+
+ In reference to bit 1 of the `flags' parameter in the Multiboot
+information structure, it is recognized that determination of which
+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 BIOS device mapping techniques (*note BIOS
+device mapping techniques::).
+
+ In reference to bit 6 of the `flags' parameter in the Multiboot
+information structure, it is important to note that the data structure
+used there (starting with `BaseAddrLow') is the data returned by the
+INT 15h, AX=E820h -- Query System Address Map call. See *Note Query
+System Address Map: (grub.info)Query System Address Map, for more
+information. The interface here is meant to allow a boot loader to work
+unmodified with any reasonable extensions of the BIOS interface,
+passing along any extra data to be interpreted by the operating system
+as desired.
+
+
+File: multiboot.info, Node: BIOS device mapping techniques, Next: Example OS code, Prev: Notes on PC, Up: Examples
+
+4.2 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 BIOS devices when not all of them have operating system
+drivers.
+
+* Menu:
+
+* Data comparison technique::
+* I/O restriction technique::
+
+
+File: multiboot.info, Node: Data comparison technique, Next: I/O restriction technique, Up: BIOS device mapping techniques
+
+4.2.1 Data comparison technique
+-------------------------------
+
+Before activating _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:
+
+ 1. The data on some BIOS devices might be identical (so the part
+ reading the drives from the BIOS should have some mechanism to give
+ up).
+
+ 2. There might be extra drives not accessible from the BIOS which are
+ identical to some drive used by the BIOS (so it should be capable
+ of giving up there as well).
+
+
+File: multiboot.info, Node: I/O restriction technique, Prev: Data comparison technique, Up: BIOS device mapping techniques
+
+4.2.2 I/O restriction technique
+-------------------------------
+
+This first step may be unnecessary, but first create copy-on-write
+mappings for the device drivers writing into PC RAM. Keep the original
+copies for the "clean BIOS virtual machine" to be created later.
+
+ For each device driver brought online, determine which BIOS devices
+become inaccessible by:
+
+ 1. Create a "clean BIOS virtual machine".
+
+ 2. Set the I/O permission map for the I/O area claimed by the device
+ driver to no permissions (neither read nor write).
+
+ 3. Access each device.
+
+ 4. Record which devices succeed, and those which try to access the
+ "restricted" I/O areas (hopefully, this will be an "xor"
+ situation).
+
+ For each device driver, given how many of the 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 BIOS
+numbers, but they pretty much always count from the lowest logically
+numbered devices on the controller.
+
+
+File: multiboot.info, Node: Example OS code, Next: Example boot loader code, Prev: BIOS device mapping techniques, Up: Examples
+
+4.3 Example OS code
+===================
+
+In this distribution, the example Multiboot kernel `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
+`docs' in the GRUB distribution.
+
+ The kernel `kernel' consists of only three files: `boot.S',
+`kernel.c' and `multiboot.h'. The assembly source `boot.S' is written
+in GAS (*note GNU assembler: (as.info)Top.), 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 `EFLAGS', and then call the function `cmain' defined
+in `kernel.c'. If `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 `kernel.c' contains the function
+`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 `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::
+
+
+File: multiboot.info, Node: multiboot.h, Next: boot.S, Up: Example OS code
+
+4.3.1 multiboot.h
+-----------------
+
+This is the source code in the file `multiboot.h':
+
+ /* 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 */
+
+
+File: multiboot.info, Node: boot.S, Next: kernel.c, Prev: multiboot.h, Up: Example OS code
+
+4.3.2 boot.S
+------------
+
+In the file `boot.S':
+
+ /* 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
+
+
+File: multiboot.info, Node: kernel.c, Next: Other Multiboot kernels, Prev: boot.S, Up: Example OS code
+
+4.3.3 kernel.c
+--------------
+
+And, in the file `kernel.c':
+
+ /* 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;
+ }
+ }
+ }
+ }
+
+
+File: multiboot.info, Node: Other Multiboot kernels, Prev: kernel.c, Up: Example OS code
+
+4.3.4 Other Multiboot kernels
+-----------------------------
+
+Other useful information should be available in Multiboot kernels, such
+as GNU Mach and Fiasco `http://os.inf.tu-dresden.de/fiasco/'. And, it
+is worth mentioning the OSKit
+`http://www.cs.utah.edu/projects/flux/oskit/', which provides a library
+supporting the specification.
+
+
+File: multiboot.info, Node: Example boot loader code, Prev: Example OS code, Up: Examples
+
+4.4 Example boot loader code
+============================
+
+The GNU GRUB (*note GRUB: (grub.info)Top.) 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:
+
+ `ftp://alpha.gnu.org/gnu/grub'
+
+ See the webpage `http://www.gnu.org/software/grub/grub.html', for
+more information.
+
+
+File: multiboot.info, Node: History, Next: Index, Prev: Examples, Up: Top
+
+5 The change log of this specification
+**************************************
+
+0.7
+ * "Multiboot Standard" is renamed to "Multiboot Specification".
+
+ * Graphics fields are added to Multiboot header.
+
+ * BIOS drive information, BIOS configuration table, the name of
+ a boot loader, APM information, and graphics information are
+ added to Multiboot information.
+
+ * Rewritten in Texinfo format.
+
+ * Rewritten, using more strict words.
+
+ * The maintainer changes to the GNU GRUB maintainer team
+ <bug-grub@gnu.org>, from Bryan Ford and Erich Stefan Boleyn.
+
+0.6
+ * A few wording changes.
+
+ * Header checksum.
+
+ * Clasification of machine state passed to an operating system.
+
+0.5
+ * Name change.
+
+0.4
+ * Major changes plus HTMLification.
+
+
+File: multiboot.info, Node: Index, Prev: History, Up: Top
+
+Index
+*****
+
+
+* Menu:
+
+
+Tag Table:
+Node: Top990
+Node: Overview1326
+Node: Motivation1794
+Node: Architecture3191
+Node: Operating systems3724
+Node: Boot sources4518
+Node: Boot-time configuration5488
+Node: Convenience to operating systems6096
+Node: Boot modules8327
+Node: Terminology9476
+Node: Specification11855
+Node: OS image format12418
+Node: Header layout13476
+Node: Header magic fields14644
+Node: Header address fields17505
+Node: Header graphics fields19351
+Node: Machine state20737
+Node: Boot information format22997
+Node: Examples38368
+Node: Notes on PC38741
+Node: BIOS device mapping techniques40307
+Node: Data comparison technique41217
+Node: I/O restriction technique42079
+Node: Example OS code43296
+Node: multiboot.h44838
+Node: boot.S48662
+Node: kernel.c51286
+Node: Other Multiboot kernels60013
+Node: Example boot loader code60444
+Node: History60970
+Node: Index61891
+
+End Tag Table
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