grub-0.97/0000777000076500007650000000000010237300265007425 500000000000000grub-0.97/util/0000777000076500007650000000000010237300265010402 500000000000000grub-0.97/util/Makefile.am0000644000076500007650000000052710065114546012362 00000000000000bin_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 grub-0.97/util/Makefile.in0000644000076500007650000003662010237276237012405 00000000000000# 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: grub-0.97/util/grub-image.in0000644000076500007650000000737510075737670012717 00000000000000#! /bin/sh # grub-image - Create a GRUB boot filesystem image and tarball # Gordon Matzigkeit , 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 } # 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 <$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 <&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 <$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 <$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 grub-0.97/util/grub-md5-crypt.in0000644000076500007650000000440607703000157013434 00000000000000#! /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 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 } # 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 < $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 grub-0.97/util/grub-terminfo.in0000644000076500007650000000465607703000157013442 00000000000000#! /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 } 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 grub-0.97/util/mbchk.c0000644000076500007650000001276607744527615011605 00000000000000/* 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 #include #include #include #include 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 .\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)) exit (1); } return 0; } grub-0.97/util/mkbimage0000644000076500007650000002565610100530433012022 00000000000000#!/bin/sh # MaKe a Bootable IMAGE --- 1.44, 2.88 and El Torito no-emulation mode # C) 2001,2002,2003 Thierry Laronde # C) 2001,2002,2003 Robert Millan # This program is free software; you can redistribute 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 . Copyright (c) 2001,2002 Robert Millan . GPLed." version="mkbimage $version_number Written by Thierry Laronde and Robert Millan. Copyright (c) 2001,2002,2003 Thierry Laronde . Copyright (c) 2001,2002,2003 Robert Millan . 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<$device_map $device ${image} EOT ${GRUB_PATH}grub --device-map=$device_map --batch<.image of=/dev/fd0[u] 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 -c boot.catalog -o raw.iso And for El Torito Hard Disk emulation: mkisofs -b -hard-disk-boot -c boot.catalog -o raw.iso Enjoy! EOF rm -rf ${image}1 exit 0 grub-0.97/README0000644000076500007650000000204107703000157010217 00000000000000This 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 . grub-0.97/acinclude.m40000644000076500007650000002451610043543406011543 00000000000000dnl 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 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* ]) grub-0.97/configure.ac0000644000076500007650000004766010237275423011653 00000000000000dnl 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 grub-0.97/aclocal.m40000644000076500007650000011607510237276116011222 00000000000000# 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 /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]) grub-0.97/Makefile.am0000644000076500007650000000025510043543406011400 00000000000000# 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 grub-0.97/Makefile.in0000644000076500007650000004622610237276240011425 00000000000000# 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: grub-0.97/config.h.in0000644000076500007650000000527110237276763011410 00000000000000/* 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 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 header file. */ #undef HAVE_INTTYPES_H /* Define if you have a curses library */ #undef HAVE_LIBCURSES /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_NCURSES_CURSES_H /* Define to 1 if you have the 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 header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the 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 grub-0.97/configure0000755000076500007650000067530610237276754011310 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.59 for GRUB 0.97. # # Report bugs to . # # 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 #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #if STDC_HEADERS # include # include #else # if HAVE_STDLIB_H # include # endif #endif #if HAVE_STRING_H # if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #if HAVE_UNISTD_H # include #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 if you have libraries in a nonstandard directory CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory 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 . _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 &5\"") >&5 (eval $ac_compiler --version &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 (eval $ac_compiler -v &5) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 (eval $ac_compiler -V &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 #include #include #include /* 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 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 to if __STDC__ is defined, since # 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 #else # include #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 _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 to if __STDC__ is defined, since # 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 #else # include #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 _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 #include #include #include 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 _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 _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 #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 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 ." _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 <>$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 <>$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 grub-0.97/AUTHORS0000644000076500007650000000401010031325355010403 00000000000000VaX#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. grub-0.97/COPYING0000644000076500007650000004310507703000156010377 00000000000000 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. Copyright (C) 19yy This program is free software; you can redistribute 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. , 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. grub-0.97/ChangeLog0000644000076500007650000121001310237276646011130 000000000000002005-05-08 Yoshinori K. Okuji * 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 * 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 . 2005-03-28 Yoshinori K. Okuji * 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 * stage2/stage2.c (cmain): Initialize DEFAULT_FILE to an empty string. Reported by NATORI Shin . 2005-03-15 Yoshinori K. Okuji * 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 * 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 * 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 * 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 * 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 * 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 * configure.ac (AC_INIT): Upgraded to 0.96. 2004-10-11 Jason Thomas Patch from Stefanus Du Toit * 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 * 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 * stage2/cmdline.c (run_script): Fix a reversed conditional. Reported by Alban Crequy . 2004-08-07 Jason Thomas From Michael Hohnbaum : * stage2/fsys_ext2fs.c (ext2fs_read): Handle sparse files. 2004-07-24 Yoshinori K. Okuji * stage2/stage2.c (cmain): Terminate DEFAULT_FILE with NUL correctly. Reported by Alban Crequy . 2004-07-21 Robert Millan Patch from David Weinehall * util/mkbimage: Fix XSI-isms (for supporting POSIX-only shells). 2004-07-20 Robert Millan * util/grub-install.in: Detect GNU/k*BSD systems as well. 2004-07-16 Yoshinori K. Okuji * util/grub-install.in (convert): Fix the sed statement for Linux. The expression was ambigious in some cases. 2004-06-29 Robert Millan * util/grub-set-default.in: Fix minor syntax error (non-escaped characters). 2004-06-24 Robert Millan 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 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 * 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 * 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 * stage2/Makefile.am (noinst_HEADERS): Added ufs2.h. 2004-06-13 Yoshinori K. Okuji * configure.ac (AC_INIT): Upgraded to 0.95. 2004-05-23 Yoshinori K. Okuji * 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 . 2004-05-20 Damian Ivereigh * 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 * 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 From Sergey Matveychuk : * 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 * 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 * 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 From Yann Dirson : * util/mkbimage: Misc syntax fixes. 2004-04-29 Jeroen Dekkers * 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 * 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 * 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 * 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 * 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 . * docs/grub.texi (Invoking grub-md5-crypt): Fixed the chapter name. Reported by Martin Pool . 2004-04-04 Yoshinori K. Okuji * 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 . 2004-03-28 Pavel Roskin * 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 * 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 : * 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 From Daniele Zelante : * 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 * stage2/serial.c (serial_putchar): Handle the character code 127 as a backspace. Reported by Florian Engelhardt . 2004-03-12 Yoshinori K. Okuji From Boji Tony Kannanthanam : * 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 From Sergey Matveychuk : * 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 * docs/grub.texi (partnew): Change @var{to} to @var{len}. 2004-02-18 Yoshinori K. Okuji From Yury V. Umanets : * 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 * 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 From Thomas Schwinge : * 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 : * 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 * 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 : * docs/grub.texi: Many bug fixes. 2004-01-17 Yoshinori K. Okuji * lib/device.c [__linux__] (MAJOR): Support 32 bit and 64 bit dev_t. This code is stolen from glibc. Suggested by Shen Feng . 2004-01-11 Yoshinori K. Okuji * 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 * 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 and Seemant Kulleen 2003-11-30 Yoshinori K. Okuji * 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 . 2003-10-19 Yoshinori K. Okuji 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 From KB Sriram : * 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 * config.guess: Update from official source (CVS). * config.sub: Likewise. 2003-09-18 Robert Millan * docs/texinfo.tex: Update from ftp.gnu.org. 2003-09-05 KB Sriram * stage2/fsys_fat.c: Fix missdetection of ext2fs as fatfs. 2003-09-05 Robert Millan * docs/menu.lst (GNU/Linux): Add commented initrd command, which is consistent with documentation. 2003-09-01 Robert Millan * docs/menu.lst: Add NetBSD, OpenBSD, GNU/KFreeBSD and GNU/KNetBSD. 2003-08-13 Jason Thomas * 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 . 2003-08-12 Jochen Hoenicke * 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 * 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 * 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 * 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 * 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 . 2003-03-19 Yoshinori K. Okuji From Adam Lackorzynski : * stage2/shared.h (KEY_NPAGE): Changed to 0x5100. (KEY_PPAGE): Changed to 0x4900. 2003-03-19 Yoshinori K. Okuji * 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 . 2003-03-10 Yoshinori K. Okuji From Andrew Walrond : * stage2/fsys_reiserfs.c (struct reiserfs_journal_header): Remove an unnecessary ``long''. 2003-03-10 Yoshinori K. Okuji 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 * util/grub-install.in (find_device): Fix the sed script. 2003-02-17 Yoshinori K. Okuji * 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 : * 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 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 From Steven Dick : * 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 From Karsten Scheibler : * stage2/terminfo.c (term): Don't use a C99-style initializer. 2003-01-16 Yoshinori K. Okuji From H.J. Lu : * 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 * 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 From Jeremy Katz: * configure.in: Support building on x86_64 with gcc -m32. 2003-01-02 Yoshinori K. Okuji 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 * 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 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 * stage2/char_io.c (init_page): Change the software name from "GRUB" to "GNU GRUB". This was inaccurate. Reported by Ciaran O'Riordan . 2002-12-04 Yoshinori K. Okuji * 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 * 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 * stage2/disk_io.c (set_device): If '(n' is given, add 'd' into DEVICE. Reported by Pavel Roskin. 2002-12-03 Yoshinori K. Okuji 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 * 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 From Alexander Langer : * 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 * docs/grub.texi (Reporting bugs): Specify the project page of the BTS instead of the BTS itself. 2002-11-30 Yoshinori K. Okuji * 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 : * 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 * 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 * 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 * docs/grub.texi (QNX): New subsection. Reported by Marian-Nicolae V. ION . 2002-10-28 Yoshinori K. Okuji * 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 . 2002-10-10 Jason Thomas * stage2/builtins.c (setup_func): Added missing space to --force-lba option. Reported by Kenneth Crudup 2002-10-06 Yoshinori K. Okuji * stage2/asm.S (gateA20): Output a dummy command (0xff), as a workaround for USB keyboard hanging problem. Suggested by Hidetoshi Nishimaki . 2002-10-06 Yoshinori K. Okuji * 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 * 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 * configure.in (--disable-serial): Fix a typo in the description. 2002-08-20 Jason Thomas 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 * 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 From Mark Kettenis : * 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 * 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 * 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 * 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 * stage2/serial.c [!GRUB_UTIL] (serial_hw_fetch): Fixed a typo. Reported by Ilguiz Latypov. 2002-07-01 Yoshinori K. Okuji * Makefile.am (AUTOMAKE_OPTIONS): New variable. Specify the required Automake version explicitly. 2002-06-30 Yoshinori K. Okuji * 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 * stage2/serial.c [!GRUB_UTIL] (serial_hw_fetch): Fixed the conditional statement. Reported by Ilguiz Latypov. 2002-06-24 Yoshinori K. Okuji * MAINTENANCE: New file. 2002-06-15 Yoshinori K. Okuji * 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 * 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 . 2002-06-12 Yoshinori K. Okuji * 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 . 2002-06-12 Yoshinori K. Okuji * util/grub-md5-crypt.in: Prompt to retype a password, and check if the passwords matches. Suggested by Matt Perry . 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 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 * docs/grub.texi (FAQ): Removed. See the GNU GRUB FAQ on the web instead. 2002-05-31 Yoshinori K. Okuji * docs/grub.texi (Reporting bugs): Recommend using the BTS on Savannah rather than the list bug-grub. 2002-05-25 Yoshinori K. Okuji * 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 * stage2/builtins.c (real_root_func): New function. (root_func): Just call real_root_func. (rootnoverify_func): Likewise. 2002-05-23 Yoshinori K. Okuji * configure.in (AM_INIT_AUTOMAKE): Changed the version number to 0.93. 2002-05-23 Yoshinori K. Okuji 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 . * 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 * 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 * 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 * 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 * netboot/fsys_tftp.c (tftp_read): Don't call buf_fill unless SIZE is positive. 2002-05-08 Yoshinori K. Okuji * 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 From Jean-Jacques Michel : * 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 * 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 * stage2/builtins.c [SUPPORT_SERIAL] (terminal_func): Added a new option ``--silent''. This suppresses messages, if specified. 2002-04-29 Yoshinori K. Okuji * config.guess: New upstream version. * config.sub: Likewise. 2002-04-20 Yoshinori K. Okuji * netboot/config.c (PCI_NIC) [INCLUDE_DAVICOM]: Fix typos. Reported by Julien Perrot . 2002-04-17 Yoshinori K. Okuji * stage2/builtins.c [SUPPORT_SERIAL] (terminal_func): Set COUNT_LINES to -1, to disable the pager. 2002-04-16 Yoshinori K. Okuji * docs/grub.texi (Obtaining and Building GRUB): Update the link to the binutils site. 2002-04-06 Pavel Roskin * util/grub-install.in: Fix hardcoded /dev/hda1. 2002-04-06 Yoshinori K. Okuji * 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 * stage2/builtins.c (setup_func): Don't embed a drive number, if unnecessary. 2002-03-29 Yoshinori K. Okuji * 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 * netboot/eepro100.c (eepro100_probe): Increase the delay at the initialization. 2002-03-26 Yoshinori K. Okuji * 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 * 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 * 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 * 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 * 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 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 * 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 * stage2/builtins.c (setup_func): Add a VSTa fs entry into STAGE1_5_MAP. 2002-02-05 Yoshinori K. Okuji * 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 * 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 * 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 * stage2/builtins.c (displaymem_func): Use hex digits to display for consistency. 2002-02-04 Jason Thomas From Denis Kitzman : * 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 * 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 * 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 * 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 * configure.in (AM_INIT_AUTOMAKE): The version number is upgraded to 0.91. 2002-01-15 Yoshinori K. Okuji * docs/grub.texi (Preset Menu): New chapter. 2002-01-15 Yoshinori K. Okuji * docs/grub.texi: Added some text about JFS and XFS. 2002-01-08 Yoshinori K. Okuji * 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 * 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 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 * 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 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 * util/grub-install.in: Support using mktemp as well as tempfile for secure temporary file creation. 2002-01-02 Jeremy Katz * stage2/md5.c (md5_password): Ensure the password exists before trying to check against the md5 crypted version. 2001-12-30 Yoshinori K. Okuji * 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 * 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 From John Goerzen : * util/grub-install.in (convert): Added NetBSD support. 2001-12-30 Yoshinori K. Okuji * util/grub-install.in: Set GRUB_PREFIX and BOOTDIR to "/grub" and "${rootdir}" respectively in NetBSD. 2001-12-30 Yoshinori K. Okuji * 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 From Michael Sullivan : * 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 * stage2/fsys_fat.c (fat_read): Fix the contradictory comment. Reported by Filip Van Raemdonck . 2001-12-11 Yoshinori K. Okuji * 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 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 * 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 . 2001-12-10 Yoshinori K. Okuji * grub/asmstub.c: Include . (grub_stage2) [HAVE_LIBCURSES]: If USE_CURSES is true, ignore the signal SIGWINCH. Reported by Christian Hudon . 2001-11-29 Yoshinori K. Okuji 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 * 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 * 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 . 2001-10-27 Yoshinori K. Okuji JFS and XFS support is added. From Serguei Tzukanov : * 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 * 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 * configure.in: Explicitly call _AM_DEPENDENCIES(CC) for the benefit of older Autoconfs. 2001-10-13 Yoshinori K. Okuji * 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 Don't use get_diskinfo_floppy. Reported by Ben Liblit . * 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 Based on a patch from Jeremy Katz : * 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 From Jason Thomas : * util/grub-install.in (convert): Add support for DAC960. From Adrian Phillips : * lib/device.c (get_dac960_disk_name): New function. (init_device_map) [__linux__]: Add support for DAC960. 2001-10-11 Jochen Hoenicke * 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 * 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 . 2001-09-24 Jochen Hoenicke * 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 From Derrik Pates : * 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 * util/grub-md5-crypt.in: Prefix backquotes with backslashes in strings. From Fernando Silveira. 2001-08-02 Gordon Matzigkeit * stage2/common.c (init_bios_info): Ignore zero-length memory ranges. From Derrik Pates . 2001-07-26 Jochen Hoenicke * 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 2001-07-13 OKUJI Yoshinori * util/grub-install.in (convert): Recognize the naming scheme for Linux devfs floppy devices. Reported by Jason Thomas . 2001-07-07 OKUJI Yoshinori * netboot/compile: New file. This was also missing... How many ``compile''s does automake want? 2001-07-07 OKUJI Yoshinori From Jan Zerebecki : * acinclude.m4 (grub_DEFINE_FILE): Escape double-quotations as well. 2001-07-05 OKUJI Yoshinori * configure.in (AM_INIT_AUTOMAKE): Set the version number to 0.90. 2001-07-05 OKUJI Yoshinori Ughh! I forgot to add this file to the CVS. * docs/compile: New file. 2001-07-05 OKUJI Yoshinori * docs/grub.texi: Updated. 2001-07-05 OKUJI Yoshinori * 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 * 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 From Julien Bordet : * stage2/i386-elf.h (Elf32_Shdr): New type. * stage2/boot.c (load_image): Added ELF symbol loading support. 2001-06-22 OKUJI Yoshinori * 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 VSTa filesystem support is added. From Kristoffer Brånemyr : * 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 From Thierry Laronde : * 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 * docs/grub.texi: Update the location of the CVS repository [/home/cvs -> /cvsroot/grub]. * README: Likewise. 2001-06-19 OKUJI Yoshinori * 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. . 2001-05-30 OKUJI Yoshinori * docs/grub.texi: Fix some typos. Reported by Florian Hatat . 2001-05-29 Pavel Roskin * configure.in (AC_OUTPUT): Remove debian/Makefile. 2001-05-28 Gordon Matzigkeit * Makefile.am (SUBDIRS): Remove reference to debian directory. Packaging is no longer done by the GRUB team. 2001-05-03 Gordon Matzigkeit * stage1/stage1.S (nt_magic): Explicitly reserve space for the NT magic number. 2001-05-25 Klaus Reichl * 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 * stage2/shared.h (ENTRY): Remove unnecessary `##'. 2001-05-03 Jochen Hoenicke * grub/asmstub.c (biosdisk): Work around a bug in linux's ez remapping. Problem reported by Ben Byer . 2001-03-28 Gordon Matzigkeit * 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 From Bodo Rueskamp : * stage2/boot.c (load_initrd): Avoid the last 64kb for Linux 2.2.x bug. 2001-03-03 OKUJI Yoshinori * docs/multiboot.texi (History): Written. 2001-02-28 OKUJI Yoshinori From HASEGAWA Tomoki : * 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 From Thierry Laronde : * 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 . 2001-02-28 OKUJI Yoshinori * 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 * 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 Added hercules support based on a patch by Frank Mehnert . I translated his assembly code into C, and separated hercules from the normal console. * configure.in (--disable-hercules): New option. * grub/asmstub.c: Include . (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 . [!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 From "Treutwein; Bernhard" : * docs/grub.texi (DOS/Windows): Improved the readability. 2001-02-11 OKUJI Yoshinori * docs/grub.texi (Command-line and menu commands): Renamed to ... (General commands): ... this. 2001-02-08 OKUJI Yoshinori * 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 . 2001-02-08 OKUJI Yoshinori * 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 From Erik Schoenfelder : * stage2/shared.h (LINUX_INITRD_MAX_ADDRESS): Changed from 0x3C000000 to 0x38000000. 2001-02-03 OKUJI Yoshinori * 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 * 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 Make savedefault workable even with Stage 1.5. Reported by Thierry Laronde . * 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 * 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 From Danilo Godec : * 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 From Bernhard Treutwein : * docs/grub-new.texi (DOS/Windows): Made more readable. 2001-01-27 OKUJI Yoshinori * docs/multiboot.texi: Start reorganizing Multiboot Specification. 2001-01-15 OKUJI Yoshinori From Thierry Laronde : * 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 From Thierry Laronde : * util/grub-md5-crypt.in (prefix): New variable. (exec_prefix): Likewise. (sbindir): Likewise. 2001-01-12 OKUJI Yoshinori * 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 * 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 * 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 * 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 * 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 . 2001-01-07 OKUJI Yoshinori * 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 * 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 . 2000-12-22 OKUJI Yoshinori * 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 From Cedric Ware : * 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 * 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 * 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 * docs/prog-ref.texi (Partition types): Rewrite the footnotes. Suggested by Ralf.Medow@t-online.de (Ralf Medow). 2000-12-14 OKUJI Yoshinori From Erik Schoenfelder : * util/grub-install.in (convert): Revised the fix for floppy device handling. 2000-12-14 OKUJI Yoshinori From HORIKAWA Kazunori : * 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 * 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 . 2000-12-09 OKUJI Yoshinori From Leendert Meyer : * util/grub-install.in (convert): If a floppy device is specified, remove everything from $tmp_part. 2000-12-09 OKUJI Yoshinori * lib/device.c [__linux__] (write_to_partition): Use strcpy instead of strcat, to overwrite "/disc". Reported by Thiago Macieira . 2000-12-05 Jochen Hoenicke * 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 . 2000-11-27 Jochen Hoenicke * 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 * 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 * 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 . 2000-11-22 OKUJI Yoshinori From Vesa Jaaskelainen : * 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 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 * 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 From Jan Fricke : * stage2/asm.S [!STAGE1_5] (set_vbe_mode): Add a missing `$' prefix. 2000-11-11 OKUJI Yoshinori * 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 * 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 * docs/user-ref.texi (Features): Update the URL of grub/98. 2000-11-03 OKUJI Yoshinori 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 * docs/help2man: Copied from help2man-1.23. 2000-10-29 OKUJI Yoshinori * stage2/asm.S [STAGE1_5]: Don't include setjmp.S or apm.S. 2000-10-27 OKUJI Yoshinori * lib/device.c (read_device_map): Don't parse a line, if it is empty. Reported by Holger Bauer . 2000-10-25 Jochen Hoenicke * 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 * 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 * 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 * docs/multiboot.texi: Upgraded to 0.6.92. (Boot information format): Re-designed the graphics table. 2000-10-22 OKUJI Yoshinori * docs/tutorial.texi: Miscellaneous updates. * docs/user-ref.texi: Likewise. * docs/appendices.texi: Likewise. 2000-10-22 OKUJI Yoshinori * 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 From Matthias Granberry : * util/grub-install.in (convert): Added backslashes into continuous lines. 2000-10-21 OKUJI Yoshinori * 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 * docs/user-ref.texi: Fixed several typos and some inappropriate texinfo commands, and update the descriptions about some commands. 2000-10-20 OKUJI Yoshinori * stage2/builtins.c (displayapm_func): New function. (builtin_displayapm): New variable. (builtin_table): Added a pointer to BUILTIN_DISPLAYAPM. 2000-10-20 OKUJI Yoshinori APM BIOS table support is added, based on a patch by Matt Yourst . * 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 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 * stage2/Makefile.am (noinst_HEADERS): Added md5.h. Reported by Volker Augustin . 2000-10-17 OKUJI Yoshinori * configure.in (--disable-md5password): Renamed to ... (--disable-md5-password): ... this. Just for my preference. 2000-10-17 Jochen Hoenicke 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 * 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 * 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 . 2000-10-16 OKUJI Yoshinori 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 * 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 From Roderich Schupp: * lib/device.c: Include . [__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 From Roderich Schupp : * util/grub-install.in (convert): Added support for "native" devfs device names. 2000-10-14 OKUJI Yoshinori * 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 * 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 * 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 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 * 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 . 2000-10-10 OKUJI Yoshinori From Daniel Pittman : * 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 * 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 * stage2/builtins.c (find_func): Clear ERRNUM after the last call of next_partition, because it always sets ERRNUM. Reported by Thierry Laronde . 2000-10-07 OKUJI Yoshinori * lib/device.c [__linux__] (write_to_partition): Open DEV with O_RDWR instead of O_ORONLY. 2000-10-06 Alessandro Rubini * 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 * 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 * 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 * docs/grub.texi: Added an entry for the chapter "Serial terminal". * docs/tutorial.texi (Serial terminal): New chapter. 2000-10-04 Gordon Matzigkeit * 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 * 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 * 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 * lib/device.c [__linux__]: Don't include . [__linux__ && !CDROM_GET_CAPABILITY] (CDROM_GET_CAPABILITY): Defined as 0x5331. 2000-10-01 OKUJI Yoshinori * 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 * 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 * 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 Added two new commands, "partnew" and "parttype", based on the patch by Stefan Ondrejicka : * 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 * 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 * 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 * configure.in (--enable-serial): Changed to ... (--disable-serial): ... this. Now the serial support is enabled by default. 2000-09-27 OKUJI Yoshinori * 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 * 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 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 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 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 * 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 From Alessandro Rubini: * configure.in (CPPFLAGS): Added -malign-jumps=1, -malign-loops=1 and -malign-functions=1. 2000-09-07 OKUJI Yoshinori From Hal Snyder : * 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 * 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 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 * 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 Add support for "boot previously booted entry by default", based on the patch by Mike Meyer , 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 * 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 and Pixel . 2000-09-05 OKUJI Yoshinori From Alessandro Rubini : * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 . 2000-08-30 OKUJI Yoshinori * 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 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 * 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 * 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 * 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 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 * stage2/char_io.c (translate_keycode) [SUPPORT_SERIAL]: Don't drain the input buffer, since that was irritating. 2000-08-26 OKUJI Yoshinori 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 * 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 * stage2/builtins.c [GRUB_UTIL]: Include stdio.h before shared.h. Reported by Mathieu Chouquet-Stringer . 2000-08-21 OKUJI Yoshinori * 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 * 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 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 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 . * 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 * 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 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 * 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 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 * docs/tutorial.texi: Minor fixes. 2000-08-10 OKUJI Yoshinori * 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 * 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 * 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 * 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 * grub/asmstub.c (biosdisk) [__linux__]: The first argument for _llseek renamed from "seeked_fd" to "filedes". 2000-07-30 OKUJI Yoshinori * docs/appendices.texi (FAQ): Added the answer for the separate boot partition problem. 2000-07-30 OKUJI Yoshinori Update the network support to Etherboot-4.6.4. From Daniel Wagner : * 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 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 * stage2/fsys_reiserfs.c (block_read): Changed the variable "len" to "j_len" (it shadowed a parameter). 2000-07-29 OKUJI Yoshinori * 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 * 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 * stage2/asm.S (check_int13_extensions): Fixed the effect of the --force-lba switch in stage2/stage1_5. 2000-07-25 Jochen Hoenicke * 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 * 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 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 * docs/tutorial.texi: Fix some syntax errors and ambiguous sentences. Suggested by M. Meiarashi . 2000-07-14 Khimenko Victor * 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 * lib/device.c: Include errno.h. Reported by Thierry DELHAISE . 2000-07-12 OKUJI Yoshinori 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 * stage2/Makefile.am (libgrub_a_CFLAGS): Added -I$(top_srcdir)/lib. * stage2/builtins.c [GRUB_UTIL]: Include device.h. 2000-07-12 OKUJI Yoshinori 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 * 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 * 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 * 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 * docs/tutorial.texi: Fixed some typos and syntax errors. * docs/user-ref.texi: Likewise. 2000-06-21 OKUJI Yoshinori * 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 * docs/mdate-sh: Moved to ... * mdate-sh: ... here. * docs/texinfo.tex: Moved to ... * texinfo.tex: ... here. 2000-06-09 OKUJI Yoshinori * 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 * docs/appendices.texi (FAQ): Added an question about Linux's `mem=' option and the answer. 2000-06-17 OKUJI Yoshinori * stage2/boot.c (load_image): Pass a mem option to Linux, only if SRC has no substring "mem=". 2000-06-17 OKUJI Yoshinori * stage2/compile: Removed. * netboot/compile: Likewise. * compile: New file. Copied from Automake. 2000-06-16 OKUJI Yoshinori * stage2/boot.c (load_image): Don't remove the vga option after parsing it. Suggested by Tim Riker. 2000-06-15 OKUJI Yoshinori * stage2/asm.S (grub_halt): Use jmp instead of jc, if INT 15 AX=5307h fails. 2000-06-15 OKUJI Yoshinori * 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 * 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 * docs/tutorial.texi (GNU/Linux): Added a caution about the "mem=" option. 2000-06-11 OKUJI Yoshinori * 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 * 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 * 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 * 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 * 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 * 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 * 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 From Chip Salzenberg: * stage2/cmdline.c (enter_cmdline) [SUPPORT_DISKLESS]: Redisplay network configuration after clearing screen, before first prompt. * stage2/cmdline.c: Include instead of "shared.h". [SUPPORT_DISKLESS]: Include . 2000-06-01 OKUJI Yoshinori * 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 * 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 * stage2/shared.h (grub_memmove): Prototype to use void *. * stage2/char_io.c (grub_memmove): Define likewise. 2000-05-30 Gordon Matzigkeit * docs/user-ref.texi (Stage2 errors): Update error messages. 2000-05-29 Pavel Roskin * 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 * 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 Based on a patch by Neal H Walfield : * 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 * 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 Add diskless support, mostly based on patches by Christoph Plattner , but also based on a patch by Chip Salzenberg 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 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 * 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 * 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 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 * 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 * 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 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 * util/grub-install.in: If the program `cp' fails, exit with the status code 1. Suggested by Pavel Roskin. 2000-05-13 OKUJI Yoshinori From Pixel : * 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 * 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 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 * stage1/stage1.S (message): Use lodsb instead of incw and movb. From Andrew Clausen . * 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 * stage2/builtins.c (setup_func): Use SECTOR_BITS instead of SECTOR_SIZE to compute BLOCKSIZE. 2000-04-26 OKUJI Yoshinori * netboot/depca.c: Copied from Etherboot-4.6.0. 2000-04-23 OKUJI Yoshinori 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 * 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 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 . [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 . (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 . (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 * 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 * 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 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 * util/grub-install.in (root_device): Append `/' to ${rootdir}, since ROOTDIR may be empty. Reported by Satoshi Nagayasu . 2000-04-15 Jochen Hoenicke * 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 * 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 * 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 . 2000-04-09 OKUJI Yoshinori * 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 * stage2/builtins.c (kernel_func): Added missing ``size'' arguments into `grub_memcmp's. Reported by Christoph Plattner . From Torsten Duwe : * 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 for CDROM_GET_CAPABILITY. [__FreeBSD__ || __NetBSD__ || __OpenBSD__]: Include 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 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 * 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 . 2000-04-02 OKUJI Yoshinori * 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 Suggested by Neal H Walfield : * 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 : * 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 : * grub.texi: Several awkward English sentences are fixed. * tutorial.texi: Likewise. * user-ref.texi: Likewise. * appendices.texi: Likewise. 2000-03-27 OKUJI Yoshinori * 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 * 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 * netboot/Makefile.am (EXTRA_libdrivers_a_SOURCES): 3c89x0.h -> cs89x0.h. Just a typo. 2000-03-10 Gordon Matzigkeit * debian/rules: Strip mbchk. * debian/postinst: Fix up /usr/doc symlink creation. 2000-03-01 OKUJI Yoshinori * 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 * stage2/builtins.c (color_func): Return 1 if safe_parse_maxint returns zero instead of non-zero. Reported by Magnus Holmberg . 2000-02-29 OKUJI Yoshinori * grub/asmstub.c [__linux__]: Include for the macro MAJOR. From Kalle Olavi Niemitalo . 2000-02-27 OKUJI Yoshinori * docs/tutorial.texi (Network): New chapter. 2000-02-26 OKUJI Yoshinori * 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 * 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 * stage2/disk_io.c [!STAGE1_5] (print_fsys_type): Mask CURRENT_SLICE with 0xFF when printing the partition type. * grub/asmstub.c [__linux__]: Include 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 * 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 * 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 * docs/user-ref.texi (Command-line-specific commands): Added a description about "cmp". * docs/appendices.texi (Reporting bugs): Rewritten. 2000-02-20 OKUJI Yoshinori 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 * 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 * 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 * 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 * 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 * 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 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 * 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 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 From Per Lundberg : * docs/multiboot.texi: Added graphics support. 2000-02-10 OKUJI Yoshinori * 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 * 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 even if __FreeBSD__ is undefined. 2000-02-09 OKUJI Yoshinori 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 * grub/asmstub.c (biosdisk) [__linux__]: Use _llseek when __GLIBC_MINOR__ is less than 1 even if __GLIBC__ is 2. Reported by Goran Koruga . * 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 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 * 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 . 2000-02-03 OKUJI Yoshinori * 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 . * 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 * 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 * 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 * docs/prog-ref.texi (LBA mode disk I/O): Added a footnote about a buggy BIOS. 2000-01-11 OKUJI Yoshinori * 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 * 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." . * 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 * 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 * 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 * docs/multiboot.texi (Boot information format): Added the descriptions about the fields "config_table" and "boot_loader_name". 1999-12-31 OKUJI Yoshinori * 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 * 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 * 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 * 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 . 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 . 1999-12-06 Gordon Matzigkeit * README (DEVELOPERS): Change CVS location to subversions. 1999-11-30 OKUJI Yoshinori * 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 . 1999-11-19 Gordon Matzigkeit * 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 * 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 * 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 * 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 * 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 * 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 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 * 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 From Pavel Roskin: * stage1/stage1.S (lba_mode): Jump to chs_mode if INT 13 AH=42h fails. 1999-11-12 OKUJI Yoshinori 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 * 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 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 * 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 * 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 * grub/asmstub.c (grub_putchar) [HAVE_LIBCURSES]: Do not call wrefresh. This was just an accident. Sorry. Reported by Alan McLean : * 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 * 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 * 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 * debian/rules (binary-arch): Compress man pages. Strip the grub shell. Install examples. 1999-11-03 OKUJI Yoshinori * 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 * 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 . * stage2/builtins.c (device_func) [GRUB_UTIL]: Call nul_terminate before calling check_device. 1999-11-02 OKUJI Yoshinori * 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 . * 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 * 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 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 and . [__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 * 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 * 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 * 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 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 * 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 * 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 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 * 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 * 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 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 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 * 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 * 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 * 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 From Michael Hohmuth : * 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 * 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 * 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 * docs/user-ref.texi: New file. * docs/Makefile.am (UNFINISHED_MANUALS): Added user-red.texi. 1999-10-21 OKUJI Yoshinori 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 * 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 * stage2/char_io.c (memcheck): Fix the checks: "<=" -> "<". Reported by Mike Hicks . 1999-10-19 OKUJI Yoshinori * 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 * docs/Makefile.am (UNFINISHED_MANUALS): New variable. (EXTRA_DIST): Added $(UNFINISHED_MANUALS). * docs/new-grub.texi: New file. 1999-10-19 OKUJI Yoshinori * 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 * 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 * 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 * 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 * 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 * 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 * multiboot.texi: Rename Multiboot Standard to Multiboot Specification and upgrade the version to 0.7. Many cleanups are done. 1999-10-15 OKUJI Yoshinori * 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 * configure.in: Check for opendisk in libutil. * grub/asmstub.c [__FreeBSD__ || __NetBSD__]: Include . [HAVE_OPENDISK]: Include . [__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 * 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 * 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 * 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 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 * 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 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 * 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 * 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 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 * 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 * stage2/builtins.c (boot_func): Pass MBI.CMDLINE instead of ARG to bsd_boot. 1999-10-03 OKUJI Yoshinori * 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 * 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 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 * stage2/disk_io.c (set_bootdev): Mask 0x7F instead of 0x79 of the device number. 1999-10-01 OKUJI Yoshinori * 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 * 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 * 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 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 * 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 * 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 * 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 * 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 * 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 * acinclude.m4 (grub_CHECK_END_SYMBOL): Add a missing double-quote. Reported by Johannes Kroeger . 1999-09-14 Gordon Matzigkeit * 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 * 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 . 1999-09-23 OKUJI Yoshinori * 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 * 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 * 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 * 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 * 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 * 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 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 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 * 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 * 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 * 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 * 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 * 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 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 * 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 * 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 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 * 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 * grub/asmstub.c [__linux__]: On GLibc 2.0 and newer use lseek, don't include and define BLKFLSBUF if needed. 1999-09-14 OKUJI Yoshinori 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 * 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 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 * 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 * 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 * 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 * 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 . 1999-09-12 OKUJI Yoshinori * 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 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 * 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 * 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 * 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 * 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 * stage2/builtins.c (configfile_func): New function. (builtin_configfile): New variable. (builtin_table): Added the pointer to BUILTIN_CONFIGFILE. 1999-09-06 OKUJI Yoshinori 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 * stage2/builtins.c (testload_func): Fix the typos: 0x2000000 -> 0x200000 and 0x3000000 -> 0x300000. 1999-09-06 OKUJI Yoshinori From Hisazumi Kenji : * 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 * 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 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 * 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 * stage2/boot.c (load_image): Use PHDR->P_PADDR instead of PHDR->P_VADDR. Reported by Ramon van Handel . 1999-09-03 OKUJI Yoshinori * docs/help2man: Upgraded to 1.013. * docs/grub.8: Regenerated. 1999-09-02 Pavel Roskin * stage2/cmdline.c (enter_cmdline) [GRUB_UTIL]: Add a space in the LBA warning message. 1999-09-02 OKUJI Yoshinori 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 * 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 * 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 * 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 From Edward Killips : * 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 From Pavel Roskin : * 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 * 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 * stage2/fsys_fat.c (fat_create_blocklist): Return 1 for the root directory on FAT12 and FAT16. 1999-08-27 OKUJI Yoshinori * 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 * 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 From Klaus Reichl : * 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 From Jochen Hoenicke : * 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 * stage2/fsys_ffs.c (ffs_mount): Do not shift the fs type FS_BSDFFS. Reported by Takehiro Suzuki . * stage2/fsys_fat.c (fat_mount): Do not shift the fs type FS_MSDOS. 1999-08-13 OKUJI Yoshinori 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 * 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 * 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 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 * 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 * stage2/stage2.c (run_menu): Terminate the string PASSWORD before checking if ENTERED is identical to PASSWORD. Reported by Mark Lundeberg . 1999-08-08 OKUJI Yoshinori * 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 * 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 * stage2/boot.c (load_image): Use RAW_ADDR macro when loading an a.out kernel. 1999-08-04 OKUJI Yoshinori * 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 * boot.c (load_image): Fix a strcmp test. Reported by Pavel Roskin . 1999-08-03 OKUJI Yoshinori From "Dan J. Walters" : * 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 From Pavel Roskin : * 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 From Pavel Roskin : * 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 * 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 * stage2/bios.c (get_diskinfo): When DRIVE is a floppy drive, try standard probe routine at first. Reported by Peter Astrand . * grub/main.c (main): Call printf instead of grub_printf. Reported by Klaus Reichl . 1999-07-15 OKUJI Yoshinori * 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 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 * 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 * 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 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 * stage2/boot.c (load_image): When removing "vga=...", memmove the length of VGA_END plus one. 1999-07-12 OKUJI Yoshinori * 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 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 * 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 * 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 * 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 . 1999-06-27 OKUJI Yoshinori * 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 * 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 * 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 * 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 * 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 Build process is cleaned up. Stage 2 and Stage 1.5's are all built in the directory stage2. From Pavel Roskin : * 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 * stage1/stage1.S: Call testb instead of andb when checking if the drive is a floppy. 1999-06-23 OKUJI Yoshinori * 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 . * 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 * 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 * shared_src/Makefile.am (EXTRA_DIST): Add bios.c. Reported by Pavel Roskin . 1999-06-21 OKUJI Yoshinori * 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 From Alexander K. Hudek : * 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 Color-menu support based on Peter Astrand '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 * 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 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 * 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 * 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 Reported from Klaus Reichl : * 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 * grub/asmstub.c (grub_stage2): Fix a memory leak that FP is not closed. 1999-05-25 OKUJI Yoshinori * 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 * 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 * acinclude.m4 (grub_ASM_EXT_C): Do not overrun the command shift. Reported by Pavel Roskin . 1999-05-14 OKUJI Yoshinori * docs/Makefile.am (info_TEXINFOS): Added multiboot.texi. * docs/multiboot.texi: New file. From Kunihiro Ishiguro. 1999-05-12 OKUJI Yoshinori * grub/asmstub.c: Include . Reported by Kunihiro Ishiguro . 1999-05-11 OKUJI Yoshinori Reported by Brian Brunswick : * 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 : * 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 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 * debian/rules (build): Install into /lib instead of /share. 1999-05-03 OKUJI Yoshinori 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 * shared_src/asm.S (biosdisk_standard): Pop %ebp correctly, reported by Pavel Roskin . 1999-04-25 OKUJI Yoshinori * docs/menu.lst: Rewritten, so that it contains up-to-date information and FAQish configuration examples. 1999-04-09 OKUJI Yoshinori * shared_src/asm.S (get_diskinfo_floppy): Correct the number of heads and the one of cylinders. 1999-04-06 OKUJI Yoshinori * 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 * 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 * 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 * shared_src/stage2.c (print_entries): Correctly assign MENU_ENTRIES the entries starting from FIRST. 1999-03-27 Gordon Matzigkeit * 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 * grub/asmstub.c (set_attrib): Use inch and addch, instead of chgat, because chgat doesn't work as expected. 1999-03-26 OKUJI Yoshinori * 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 * 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 * 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 * 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 * shared_src/shared.h (geometry_t): Delete typedef, until we actually use it. 1999-03-16 OKUJI Yoshinori * 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 * 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 * 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 * 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 * 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 * shared_src/asm.S (biosdisk): Compute location of disk_address_packet correctly. From OKUJI Yoshinori. 1999-03-08 Gordon Matzigkeit * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * shared_src/asm.S: Fix typo that called interrupt 0xd (decimal 13) instead of 0x13. 1999-01-31 Gordon Matzigkeit * 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 * 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. grub-0.97/INSTALL0000644000076500007650000002267310237276303010411 00000000000000-*- 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 . * GNU Make For now, the Makefiles produced by Automake depends on GNU Make. See the web page . * 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 , 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 . * 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 . 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. grub-0.97/NEWS0000644000076500007650000006412210237275376010063 00000000000000NEWS - 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 , for more details. * The appendix "FAQ" in the manual is removed. See the GNU GRUB FAQ on the web 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. grub-0.97/THANKS0000644000076500007650000001121710237273307010264 00000000000000GRUB 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 Adrian Phillips Alban Crequy Alessandro Rubini Alexander K. Hudek Alexander Langer Alfred M. Szmidt Andrew Clausen Andrew Walrond Ben Liblit Bernhard Treutwein Bodo Rueskamp . Boji Tony Kannanthanam Bradford Hovinen Brian Brunswick Bryan Ford Cedric Ware Chip Salzenberg Christian Jones Christoph Plattner Damian Ivereigh David Weinehall Dan J. Walters Daniel Farrell Daniel Pittman Daniel Wagner Danilo Godec Dennis Kitzman Derrik Pates Edmund GRIMLEY EVANS Eduard Guzovsky Edward Killips Egmont Koblinger Eric Hanchrow Erik Schoenfelder Eugene Doudine Florian Hatat Frank Mehnert Gary Poppitz Goran Koruga Hal Snyder HASEGAWA Tomoki Heikki Vatiainen Heiko Schroeder Henrik Nordstrom Herbert Nachtnebel Hidetoshi Nishimaki Hisazumi Kenji HORIKAWA Kazunori Ilguiz Latypov Jan Fricke Jan Zerebecki Jason Thomas Jean-Jacques Michel Jeremy Katz Jochen Hoenicke Johannes Kroeger John Goerzen John Tobey Josip Rodin Julien Bordet Julien Perrot Kalle Olavi Niemitalo Karsten Scheibler KB Sriram Khimenko Victor Klaus Reichl Kristoffer Branemyr Kunihiro Ishiguro Leendert Meyer Leonid Lisovskiy M. Meiarashi Mark Kettenis Mark Lundeberg Matt Perry Matt Yourst Matthias Granberry Matthias Kretschmer Michael Hohmuth Michael Sullivan Mike Meyer Miles Bader NATORI Shin Neal H Walfield Neelkanth Natu OKUJI Yoshinori Pavel Roskin Per Lundberg Peter Astrand Ralf Medow Ramon van Handel Robert Millan Roderich Schupp Rogelio M. Serrano Jr. Sergey Matveychuk Serguei Tzukanov Stefan Ondrejicka Stephen Early Steven Dick Sven Wegener Takehiro Suzuki Taketo Kabe Thierry DELHAISE Thierry Laronde Thomas Schweikle Thomas Schwinge Tilmann Bubeck Timothy Baldwin Torsten Duwe Uwe Dannowski VaX#n8 Vesa Jaaskelainen Yedidyah Bar-David Yury V. Umanets Yuri Zaporogets grub-0.97/TODO0000644000076500007650000000672010000475332010032 00000000000000-*- 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 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. grub-0.97/compile0000755000076500007650000000715710237276235010742 00000000000000#! /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 . # # This program is free software; you can redistribute 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 or send patches to # . 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 . 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: grub-0.97/config.guess0000755000076500007650000012470210237276240011674 00000000000000#! /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 . # Please send patches to . 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 ." 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 /* 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 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 #include 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 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 #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' /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 echo i586-unisys-sysv4 exit 0 ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # 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 < # include #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 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 # 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 < 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: grub-0.97/config.sub0000755000076500007650000007537310237276240011350 00000000000000#! /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 . 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 ." 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: grub-0.97/depcomp0000755000076500007650000003554510237276237010745 00000000000000#! /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 . 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 . 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: grub-0.97/install-sh0000755000076500007650000002201710237276231011354 00000000000000#!/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: grub-0.97/missing0000755000076500007650000002453310237276231010754 00000000000000#! /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 , 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 ." 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: grub-0.97/mkinstalldirs0000755000076500007650000000653510237276240012165 00000000000000#! /bin/sh # mkinstalldirs --- make directory hierarchy scriptversion=2004-02-15.20 # Original author: Noah Friedman # Created: 1993-05-16 # Public domain. # # This file is maintained in Automake, please report # bugs to or send patches to # . 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 ." # 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: grub-0.97/BUGS0000644000076500007650000000026607703000156010030 00000000000000See 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) grub-0.97/MAINTENANCE0000644000076500007650000000544210000215242010777 00000000000000-*- 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 grub-0.97/netboot/0000777000076500007650000000000010237300262011074 500000000000000grub-0.97/netboot/Makefile.am0000644000076500007650000001700407703000141013043 00000000000000# For and . 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 grub-0.97/netboot/Makefile.in0000644000076500007650000023706410237276233013103 00000000000000# 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 and . 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: grub-0.97/netboot/cards.h0000644000076500007650000001074207703000141012256 00000000000000#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 */ grub-0.97/netboot/config.c0000644000076500007650000004730207703000141012424 00000000000000/* * 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 #include #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 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 #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); } grub-0.97/netboot/etherboot.h0000644000076500007650000003106407703000141013155 00000000000000/* * 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 /* 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 #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 */ grub-0.97/netboot/fsys_tftp.c0000644000076500007650000002657610037472100013214 00000000000000/* * 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 #define GRUB 1 #include #include 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 ("\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); } grub-0.97/netboot/linux-asm-io.h0000644000076500007650000001323607703000141013505 00000000000000#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 grub-0.97/netboot/linux-asm-string.h0000644000076500007650000001637407703000141014412 00000000000000/* * 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 #include /* #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 ("\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 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; } } grub-0.97/netboot/misc.c0000644000076500007650000001240407703000141012105 00000000000000/* * 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 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; } grub-0.97/netboot/nic.h0000644000076500007650000000147207703000142011734 00000000000000 /* * This program is free software; you can redistribute 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 */ grub-0.97/netboot/osdep.h0000644000076500007650000000427007703000142012274 00000000000000#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: */ grub-0.97/netboot/pci.c0000644000076500007650000003176207703000142011736 00000000000000/* ** 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); } } grub-0.97/netboot/pci.h0000644000076500007650000001655107703000142011742 00000000000000#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 */ grub-0.97/netboot/timer.c0000644000076500007650000000642607703000142012302 00000000000000/* 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 */ grub-0.97/netboot/timer.h0000644000076500007650000000272307703000142012303 00000000000000/* 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 */ grub-0.97/netboot/3c509.c0000644000076500007650000003714007703000141011721 00000000000000/************************************************************************** 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= 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: */ grub-0.97/netboot/3c509.h0000644000076500007650000002716607703000141011735 00000000000000/* * 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: */ grub-0.97/netboot/3c595.c0000644000076500007650000003005107703000141011720 00000000000000/* * 3c595.c -- 3COM 3C595 Fast Etherlink III PCI driver for etherboot * * Copyright (C) 2000 Shusuke Nisiyama * 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 * */ /* #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 < 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 <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: */ grub-0.97/netboot/3c595.h0000644000076500007650000003307007703000141011731 00000000000000/* * 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 * 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: */ grub-0.97/netboot/3c90x.c0000644000076500007650000007501407703000141012026 00000000000000/* * 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;inode_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; } grub-0.97/netboot/cs89x0.c0000644000076500007650000004425307703000141012217 00000000000000/* 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 * 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 * 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 * 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 * Synched with Russel Nelson's current code (v1.00) * 2 Thu Nov 12 18:00:00 1996 Markus Gutschke * Cleaned up some of the code and tried to optimize the code size. * 1.5 Sun Nov 10 16:30:00 1996 Markus Gutschke * 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; inode_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: */ grub-0.97/netboot/cs89x0.h0000644000076500007650000003714607703000141012227 00000000000000/* 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: */ grub-0.97/netboot/davicom.c0000644000076500007650000004754607703000141012613 00000000000000/* 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; inode_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= 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; inode_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; } grub-0.97/netboot/depca.c0000644000076500007650000006675207703000141012245 00000000000000/* 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 . 0.383 22-feb-95 Fix for conflict with VESA SCSI reported by 0.384 17-mar-95 Fix a ring full bug reported by 0.385 3-apr-95 Fix a recognition bug reported by 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 0.41 26-Jun-95 Added verify_area() calls in depca_ioctl() from suggestion by 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 . Add new multicasting code. 0.421 22-Apr-96 Fix alloc_device() bug 0.422 29-Apr-96 Fix depca_hw_init() bug 0.423 7-Jun-96 Fix module load bug 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 0.45 3-Nov-98 Added support for MCA EtherWORKS (DE210/DE212) cards by 0.451 5-Nov-98 Fixed mca stuff cuz I'm a dummy. 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 ========================================================================= */ #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); } grub-0.97/netboot/eepro.c0000644000076500007650000004372507703000141012276 00000000000000/************************************************************************** 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) /* 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); } grub-0.97/netboot/eepro100.c0000644000076500007650000004707707703000141012523 00000000000000/* * 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 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;inode_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;inode_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 grub-0.97/netboot/epic100.c0000644000076500007650000003120607703000141012314 00000000000000/* 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); } grub-0.97/netboot/epic100.h0000644000076500007650000001625207703000141012325 00000000000000#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_ */ grub-0.97/netboot/fa311.c0000644000076500007650000003064107703000141011770 00000000000000/* 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; } grub-0.97/netboot/i82586.c0000644000076500007650000006266607703000141012036 00000000000000/************************************************************************** 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 grub-0.97/netboot/lance.c0000644000076500007650000004311307703000141012235 00000000000000/************************************************************************** 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; irx_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; } grub-0.97/netboot/natsemi.c0000644000076500007650000004777007703000142012631 00000000000000/* -*- 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); } grub-0.97/netboot/ni5010.c0000644000076500007650000003416007703000142012072 00000000000000/************************************************************************** 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); } grub-0.97/netboot/ns8390.c0000644000076500007650000006324007703000142012123 00000000000000/************************************************************************** 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; inode_addr[i], eth_nic_base+D8390_P1_PAR0+i); for (i=0; iflags) ? 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; inode_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; inode_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; inode_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: */ grub-0.97/netboot/ns8390.h0000644000076500007650000001757507703000142012142 00000000000000/************************************************************************** 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: */ grub-0.97/netboot/otulip.c0000644000076500007650000002722407703000142012475 00000000000000/* 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;xnode_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; } grub-0.97/netboot/otulip.h0000644000076500007650000000417007703000142012475 00000000000000/* 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 */ }; grub-0.97/netboot/rtl8139.c0000644000076500007650000003642207703000142012307 00000000000000/* 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<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 */; } grub-0.97/netboot/sis900.c0000644000076500007650000006675007703000142012217 00000000000000/* -*- 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, ®); 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<= 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<= 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); } grub-0.97/netboot/sis900.h0000644000076500007650000002423207703000142012211 00000000000000/* -*- 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; grub-0.97/netboot/sk_g16.c0000644000076500007650000007705507703000142012262 00000000000000/************************************************************************** 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 ***************************************************************************/ /*- * 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 grub-0.97/netboot/sk_g16.h0000644000076500007650000001141507703000142012253 00000000000000/*- * * 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 */ grub-0.97/netboot/smc9000.c0000644000076500007650000003613207703000142012252 00000000000000 /*------------------------------------------------------------------------ * smc9000.c * This is a Etherboot driver for SMC's 9000 series of Ethernet cards. * * Copyright (C) 1998 Daniel Engström * Based on the Linux SMC9000 driver, smc9194.c by Eric Stahlman * 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. * * "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 * Daniel Engström * * 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); } grub-0.97/netboot/smc9000.h0000644000076500007650000001361707703000142012262 00000000000000/*------------------------------------------------------------------------ * 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 * Erik Stahlman * * 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_ */ grub-0.97/netboot/tiara.c0000644000076500007650000001656507703000142012267 00000000000000/************************************************************************** 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); } grub-0.97/netboot/tlan.c0000644000076500007650000033644507703000142012127 00000000000000/************************************************************************** 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 * New Maintainer * ********************************************************************/ #include #include #include #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 : TLan_PciProbe() now uses * new PCI BIOS interface. * Alan Cox : Fixed the out of memory * handling. * * Torben Mathiasen 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 . * - 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 * Denis Beaudoin * 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 #include "tlan.h" #include #include #include #include #include #include #include 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 "); 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<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 grub-0.97/netboot/tulip.c0000644000076500007650000021443607703000142012321 00000000000000/* -*- 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; } grub-0.97/netboot/via-rhine.c0000644000076500007650000007520407703000142013044 00000000000000/* 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 */ grub-0.97/netboot/w89c840.c0000644000076500007650000007307607703000142012215 00000000000000/* * Etherboot - BOOTP/TFTP Bootstrap Program * * w89c840.c -- This file implements the winbond-840 driver for etherboot. * */ /* * Adapted by Igor V. Kovalenko * -- * OR * -- * 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 '%'<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 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 */ 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;inode_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; } grub-0.97/netboot/README.netboot0000644000076500007650000000777207703000141013353 00000000000000You 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 . 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. grub-0.97/netboot/3c90x.txt0000644000076500007650000003405607703000141012424 00000000000000 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 .... 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 , 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.] grub-0.97/netboot/cs89x0.txt0000644000076500007650000000155707703000141012614 00000000000000Permission 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 for providing an evaluation NIC and for sponsoring the development of this driver. Randall Sears Deva Bodas Andreas Kraemer 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 for writing the Linux device driver for the CS89x0 chipset. Russel's code is very well designed and simplified my job a lot. grub-0.97/netboot/sis900.txt0000644000076500007650000000551207703000142012601 00000000000000How 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. grub-0.97/netboot/tulip.txt0000644000076500007650000000440107703000142012703 00000000000000This 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/ grub-0.97/stage2/0000777000076500007650000000000010237300264010611 500000000000000grub-0.97/stage2/apic.h0000644000076500007650000000361307703000160011611 00000000000000/* * * * Author: Erich Boleyn 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 */ grub-0.97/stage2/defs.h0000644000076500007650000000547307703000160011624 00000000000000/* * 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 grub-0.97/stage2/dir.h0000644000076500007650000001213507703000160011452 00000000000000 /* * 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 * 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_ */ grub-0.97/stage2/disk_inode.h0000644000076500007650000000735207703000160013011 00000000000000/* * 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_ */ grub-0.97/stage2/disk_inode_ffs.h0000644000076500007650000000654307703000160013650 00000000000000/* * 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_ */ grub-0.97/stage2/fat.h0000644000076500007650000000647707703000160011462 00000000000000/* * 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))) grub-0.97/stage2/filesys.h0000644000076500007650000001016410051217713012356 00000000000000/* 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]; grub-0.97/stage2/freebsd.h0000644000076500007650000000736207703000160012314 00000000000000 /* * 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; }; grub-0.97/stage2/fs.h0000644000076500007650000004454207703000160011313 00000000000000/* * 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) grub-0.97/stage2/hercules.h0000644000076500007650000000216307703000161012507 00000000000000/* 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 */ grub-0.97/stage2/i386-elf.h0000644000076500007650000001441607703000161012136 00000000000000/* * 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 grub-0.97/stage2/imgact_aout.h0000644000076500007650000001354207703000161013174 00000000000000 /*- * 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_ */ grub-0.97/stage2/iso9660.h0000644000076500007650000001237310031322636012022 00000000000000/* * ISO 9660 filesystem backend for GRUB (GRand Unified Bootloader) * including Rock Ridge Extensions support * * Copyright (C) 1998, 1999 Kousuke Takai * * This program is free software; you can redistribute 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<= 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_ */ grub-0.97/stage2/mb_header.h0000644000076500007650000000526707703000161012613 00000000000000/* * 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 grub-0.97/stage2/mb_info.h0000644000076500007650000001175307703000161012313 00000000000000/* * 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 grub-0.97/stage2/md5.h0000644000076500007650000000252307703000161011362 00000000000000/* 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) grub-0.97/stage2/nbi.h0000644000076500007650000000223607703000161011446 00000000000000/* 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 */ grub-0.97/stage2/pc_slice.h0000644000076500007650000002004007703000161012450 00000000000000/* * 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 */ grub-0.97/stage2/serial.h0000644000076500007650000000471507703000161012161 00000000000000/* 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 */ grub-0.97/stage2/shared.h0000644000076500007650000006762210065066151012164 00000000000000/* 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 /* 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 #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 #elif defined(HAVE_NCURSES_H) # include #elif defined(HAVE_CURSES_H) # include #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 # 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 */ grub-0.97/stage2/smp-imps.h0000644000076500007650000001231210200234666012444 00000000000000/* * * * Author: Erich Boleyn 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 */ grub-0.97/stage2/term.h0000644000076500007650000001003007703000161011634 00000000000000/* 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 */ grub-0.97/stage2/terminfo.h0000644000076500007650000000323110000207620012506 00000000000000/* 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 */ grub-0.97/stage2/tparm.h0000644000076500007650000000200307703000161012011 00000000000000/* 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 */ grub-0.97/stage2/ufs2.h0000644000076500007650000004524210065027526011572 00000000000000/* * 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_ */ grub-0.97/stage2/vstafs.h0000644000076500007650000000364307703000161012207 00000000000000/* * 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 */ grub-0.97/stage2/xfs.h0000644000076500007650000004303410002556106011500 00000000000000/* 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 */ grub-0.97/stage2/Makefile.am0000644000076500007650000002256610200235017012565 00000000000000# 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 . 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 $< $@ grub-0.97/stage2/Makefile.in0000644000076500007650000120561210237276237012615 00000000000000# 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 . 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: grub-0.97/stage2/boot.c0000644000076500007650000006471310032256610011645 00000000000000/* 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); } } grub-0.97/stage2/builtins.c0000644000076500007650000034523710204470177012545 00000000000000/* 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 #endif #include #include #include #ifdef SUPPORT_NETBOOT # define GRUB 1 # include #endif #ifdef SUPPORT_SERIAL # include # include #endif #ifdef GRUB_UTIL # include #else /* ! GRUB_UTIL */ # include # include #endif /* ! GRUB_UTIL */ #ifdef USE_MD5_PASSWORDS # include #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; /* 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 (§or, &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 break; /* Try the next. */ arg = skip_to (0, arg); } 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; } /* Copy the command-line to MB_CMDLINE. */ grub_memmove (mb_cmdline, arg, len + 1); 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] 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." }; /* 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_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 }; grub-0.97/stage2/char_io.c0000644000076500007650000006533410177765713012331 00000000000000/* 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 #include #ifdef SUPPORT_HERCULES # include #endif #ifdef SUPPORT_SERIAL # include #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 grub-0.97/stage2/cmdline.c0000644000076500007650000001454110110240725012304 00000000000000/* 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 #ifdef SUPPORT_DISKLESS # define GRUB 1 # include #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); } } grub-0.97/stage2/common.c0000644000076500007650000002331710031325410012157 00000000000000/* 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 #ifdef SUPPORT_DISKLESS # define GRUB 1 # include #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 (); } grub-0.97/stage2/disk_io.c0000644000076500007650000011677010054151314012323 00000000000000/* 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 #include #ifdef SUPPORT_NETBOOT # define GRUB 1 # include #endif #ifdef GRUB_UTIL # include #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, ¤t_partition, ¤t_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 *) ¤t_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 *) ¤t_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)) (); } grub-0.97/stage2/fsys_ext2fs.c0000644000076500007650000005312710105467246013170 00000000000000/* * 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 */ grub-0.97/stage2/fsys_fat.c0000644000076500007650000002772710215611260012523 00000000000000/* * 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 */ grub-0.97/stage2/fsys_ffs.c0000644000076500007650000001660507703000160012517 00000000000000/* * 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 */ grub-0.97/stage2/fsys_iso9660.c0000644000076500007650000002531410050141347013057 00000000000000/* * ISO 9660 filesystem backend for GRUB (GRand Unified Bootloader) * including Rock Ridge Extensions support * * Copyright (C) 1998, 1999 Kousuke Takai * * This program is free software; you can redistribute 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 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 */ grub-0.97/stage2/fsys_jfs.c0000644000076500007650000002223607703000160012520 00000000000000/* 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 */ grub-0.97/stage2/fsys_minix.c0000644000076500007650000003274507703000161013071 00000000000000/* * 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<. 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 */ grub-0.97/stage2/fsys_reiserfs.c0000644000076500007650000011154610014761206013567 00000000000000/* 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 */ grub-0.97/stage2/fsys_ufs2.c0000644000076500007650000001763210065027360012627 00000000000000/* * 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 */ grub-0.97/stage2/fsys_vstafs.c0000644000076500007650000001242407703000161013243 00000000000000/* * 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 */ grub-0.97/stage2/fsys_xfs.c0000644000076500007650000003341310237273133012545 00000000000000/* 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 */ grub-0.97/stage2/gunzip.c0000644000076500007650000010414007703000161012202 00000000000000/* * 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())<>=(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 */ grub-0.97/stage2/md5.c0000644000076500007650000002236207703000161011360 00000000000000/* 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 #ifndef TEST # include #endif #ifdef TEST # include # 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 grub-0.97/stage2/serial.c0000644000076500007650000002035610024400071012145 00000000000000/* 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 #include #include #include /* 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 */ grub-0.97/stage2/stage2.c0000644000076500007650000005615710217063275012102 00000000000000/* * 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 #include grub_jmp_buf restart_env; #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS) # if defined(PRESET_MENU_STRING) static const char *preset_menu = PRESET_MENU_STRING; # 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); } } } grub-0.97/stage2/terminfo.c0000644000076500007650000001317510000207270012512 00000000000000/* 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 #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)); } grub-0.97/stage2/tparm.c0000644000076500007650000004052507703000161012017 00000000000000/**************************************************************************** * 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 2002 **********************************************************************/ /**************************************************************************** * Author: Zeyd M. Ben-Halim 1992,1995 * * and: Eric S. Raymond * ****************************************************************************/ /* * 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; } grub-0.97/stage2/asm.S0000644000076500007650000012227510065067772011457 00000000000000/* * 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 */ grub-0.97/stage2/bios.c0000644000076500007650000002252110031326374011631 00000000000000/* 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; } grub-0.97/stage2/console.c0000644000076500007650000000372707703000160012340 00000000000000/* 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 #include /* 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); } grub-0.97/stage2/hercules.c0000644000076500007650000001002507703000161012476 00000000000000/* 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 #include #include /* 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 */ grub-0.97/stage2/smp-imps.c0000644000076500007650000004314310200234660012437 00000000000000/* * 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. */ /* * * * Author: Erich Boleyn 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; } grub-0.97/stage2/start.S0000644000076500007650000002157207703000161012012 00000000000000/* * 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 #ifndef STAGE1_5 #include #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!!! */ grub-0.97/stage2/stage1_5.c0000644000076500007650000000327507703000161012305 00000000000000/* * 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 (); } grub-0.97/stage2/start_eltorito.S0000644000076500007650000001675110031324134013733 00000000000000/* * 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!!! */ grub-0.97/stage2/nbloader.S0000644000076500007650000000514507703000161012441 00000000000000/* * 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 #include .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 grub-0.97/stage2/pxeloader.S0000644000076500007650000000231407703000161012631 00000000000000/* * 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 grub-0.97/stage2/setjmp.S0000644000076500007650000000527107703000161012155 00000000000000/* * 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.... */ grub-0.97/stage2/apm.S0000644000076500007650000000565307703000160011433 00000000000000/* * 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 grub-0.97/stage2/size_test0000755000076500007650000000303110051217154012460 00000000000000#!/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 # 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 grub-0.97/stage1/0000777000076500007650000000000010237300264010610 500000000000000grub-0.97/stage1/Makefile.am0000644000076500007650000000060510075737670012600 00000000000000pkglibdir = $(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 $< $@ grub-0.97/stage1/Makefile.in0000644000076500007650000003201410237276234012602 00000000000000# 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: grub-0.97/stage1/stage1.S0000644000076500007650000002323010204467627012047 00000000000000/* -*-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 /* * 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 grub-0.97/stage1/stage1.h0000644000076500007650000000502110204467703012065 00000000000000/* * 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 */ grub-0.97/lib/0000777000076500007650000000000010237300264010172 500000000000000grub-0.97/lib/Makefile.am0000644000076500007650000000026107703000140012133 00000000000000noinst_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 grub-0.97/lib/Makefile.in0000644000076500007650000003136610237276233012174 00000000000000# 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: grub-0.97/lib/getopt.c0000644000076500007650000007264407703000141011564 00000000000000/* 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 . Ditto for AIX 3.2 and . */ #ifndef _NO_PROTO # define _NO_PROTO #endif #ifdef HAVE_CONFIG_H # include #endif #if !defined __STDC__ || !__STDC__ /* This is a separate conditional since some stdc systems reject `defined (const)'. */ # ifndef const # define const # endif #endif #include /* 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 # 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 # include #endif /* GNU C library. */ #ifdef VMS # include # if HAVE_STRING_H - 0 # include # endif #endif #ifndef _ /* This is for other GNU distributions with internationalized messages. When compiling libc, the _ macro is predefined. */ # ifdef HAVE_LIBINTL_H # include # 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 # define my_index strchr #else # if HAVE_STRING_H # include # else # include # 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 */ grub-0.97/lib/getopt1.c0000644000076500007650000001071207703000141011631 00000000000000/* 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 #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 /* 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 #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 #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 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 */ grub-0.97/lib/getopt.h0000644000076500007650000001075707703000141011566 00000000000000/* 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 */ grub-0.97/lib/device.c0000644000076500007650000005276010221637121011521 00000000000000/* 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 #include #include #include #include #include #include #include #include #include #include #include #ifdef __linux__ # if !defined(__GLIBC__) || \ ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))) /* Maybe libc doesn't have large file support. */ # include /* _llseek */ # endif /* (GLIBC < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR < 1)) */ # include /* 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 # ifndef __FreeBSD_kernel_version # define __FreeBSD_kernel_version __FreeBSD_version # endif /* Runtime detection of kernel */ # include 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 /* ioctl */ # include # include /* CDIOCCLRDEBUG */ # if defined(__FreeBSD_kernel__) # include # if __FreeBSD_kernel_version >= 500040 # include # endif # endif /* __FreeBSD_kernel__ */ #endif /* __FreeBSD_kernel__ || __NetBSD__ || __OpenBSD__ */ #ifdef HAVE_OPENDISK # include #endif /* HAVE_OPENDISK */ #define WITHOUT_LIBC_STUBS 1 #include #include /* 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, §or_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/cdp. 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__ */ grub-0.97/lib/device.h0000644000076500007650000000333610054151264011524 00000000000000/* 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 */ grub-0.97/grub/0000777000076500007650000000000010237300264010363 500000000000000grub-0.97/grub/Makefile.am0000644000076500007650000000113510200235073012326 00000000000000sbin_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) grub-0.97/grub/Makefile.in0000644000076500007650000003407010237276232012357 00000000000000# 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: grub-0.97/grub/main.c0000644000076500007650000001531207703000140011363 00000000000000/* 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 #include #include #include #include #include #include #define WITHOUT_LIBC_STUBS 1 #include #include 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 .\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 ()); } grub-0.97/grub/asmstub.c0000644000076500007650000006274710204730332012136 00000000000000/* 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __linux__ # include /* ioctl */ # if !defined(__GLIBC__) || \ ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 1))) /* Maybe libc doesn't have large file support. */ # include /* _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 #include #include #include /* 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; } grub-0.97/docs/0000777000076500007650000000000010237300266010356 500000000000000grub-0.97/docs/internals.texi0000644000076500007650000003220610123647131013166 00000000000000@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 grub-0.97/docs/boot.S.texi0000644000076500007650000000434207744533155012352 00000000000000/* @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 .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 grub-0.97/docs/kernel.c.texi0000644000076500007650000001666010145232442012675 00000000000000/* @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 /* @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; @} @} @} @} grub-0.97/docs/multiboot.h.texi0000644000076500007650000000624707703000140013432 00000000000000/* @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} */ grub-0.97/docs/Makefile.am0000644000076500007650000000403007703000137012321 00000000000000info_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 grub-0.97/docs/Makefile.in0000644000076500007650000006556610237276232012366 00000000000000# 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: grub-0.97/docs/stamp-vti0000644000076500007650000000013010237300265012132 00000000000000@set UPDATED 8 May 2005 @set UPDATED-MONTH May 2005 @set EDITION 0.97 @set VERSION 0.97 grub-0.97/docs/version.texi0000644000076500007650000000013010237300265012643 00000000000000@set UPDATED 8 May 2005 @set UPDATED-MONTH May 2005 @set EDITION 0.97 @set VERSION 0.97 grub-0.97/docs/mdate-sh0000755000076500007650000001147310237276232011735 00000000000000#!/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 , 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 or send patches to # . 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 . 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: grub-0.97/docs/texinfo.tex0000644000076500007650000067302710237276232012514 00000000000000% 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 `\^^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 . % \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 to achieve this: TeX expands \the only once, % simply yielding the contents of . (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 \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{...} % If we want to allow any 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'{'#1'}'{#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\ }} \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 % 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 grub-0.97/docs/boot.S0000644000076500007650000000346407703000137011366 00000000000000/* 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 .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 grub-0.97/docs/kernel.c0000644000076500007650000001537310145232442011725 00000000000000/* 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 /* 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; } } } } grub-0.97/docs/multiboot.h0000644000076500007650000000602207703000140012451 00000000000000/* 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 */ grub-0.97/docs/grub.texi0000644000076500007650000040241310237300257012130 00000000000000\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 </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. grub-0.97/docs/multiboot.texi0000644000076500007650000013416507703000140013205 00000000000000\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 Copyright @copyright{} 1995, 96 Erich Stefan Boleyn 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 Copyright @copyright{} 1995, 96 Erich Stefan Boleyn 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 grub-0.97/docs/menu.lst0000644000076500007650000000313010050141345011751 00000000000000# # 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 grub-0.97/docs/grub.80000644000076500007650000000276510237277030011336 00000000000000.\" 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 . .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. grub-0.97/docs/mbchk.10000644000076500007650000000150510237277030011443 00000000000000.\" 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 . .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. grub-0.97/docs/grub-install.80000644000076500007650000000251310237277030012771 00000000000000.\" 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 . .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. grub-0.97/docs/grub-md5-crypt.80000644000076500007650000000144710237277030013154 00000000000000.\" 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 . .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. grub-0.97/docs/grub-terminfo.80000644000076500007650000000140410237277030013144 00000000000000.\" 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 . .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. grub-0.97/docs/help2man0000755000076500007650000002660307703000140011725 00000000000000#!/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 # 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 my $help_info = <. 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 () { # [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: # # # # {GNU,Free} # ({GNU,Free} ) # - {GNU,Free} # # 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} .= < ${texi}.new mv -f ${texi}.new ${dir}/${texi} grub-0.97/docs/grub.info0000644000076500007650000050051410237300265012112 00000000000000This 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 -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 , 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

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: Move forward one character. Move back one character. Move to the start of the line. Move the the end of the line. Delete the character underneath the cursor. Delete the character to the left of the cursor. Kill the text from the current cursor position to the end of the line. Kill backward from the cursor to the beginning of the line. Yank the killed text back into the buffer at the cursor. Move up through the history list. 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 key (or ) will display a listing of the available commands, and if the cursor is after the first word, the `' 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 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 (which operates exactly like the non-config-file version of GRUB, but allows one to return to the menu if desired by pressing ) or to edit any of the "boot entries" by pressing . If you protect the menu interface with a password (*note Security::), all you can do is choose an entry by pressing , or press

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 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 , GRUB replaces the line in question in the boot entry with the changes (unless it was aborted via , in which case the changes are thrown away). If you want to add a new line to the menu entry, press if adding a line after the current line or press if before the current line. To delete a line, hit the key . 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 . 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 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 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 `' 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 `--' 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 `--' 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 . 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 </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 , 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 . 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 ***** [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 grub-0.97/docs/multiboot.info0000644000076500007650000017264710177031367013214 00000000000000This 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 Copyright (C) 1995, 96 Erich Stefan Boleyn 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 .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 /* 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 , 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 ***** [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