ALT Linux Bugzilla
– Attachment 2557 Details for
Bug 14795
Ругань при установке grub-0.97-alt3
New bug
|
Search
|
[?]
|
Help
Register
|
Log In
[x]
|
Forgot Password
Login:
[x]
|
EN
|
RU
[patch]
workaround for 'line 7 - to many arguments...' error
grub-0.97-alt3.patch (text/plain), 118.46 KB, created by
Mike
on 2008-04-09 21:30:31 MSD
(
hide
)
Description:
workaround for 'line 7 - to many arguments...' error
Filename:
MIME Type:
Creator:
Mike
Created:
2008-04-09 21:30:31 MSD
Size:
118.46 KB
patch
obsolete
> .gear/rules | 2 + > .../tags/607d849b5fb32b41822516380089de50078ed12b | 6 + > .gear/tags/list | 1 + > Makefile.am | 1 + > configure.ac | 3 +- > docs/grub-install.8 | 2 + > docs/grub.texi | 61 ++- > grub.spec | 323 +++++++ > grub/asmstub.c | 52 +- > grub/main.c | 2 +- > grubonce | 57 ++ > lib/device.c | 269 ++++++- > netboot/config.c | 12 + > netboot/fsys_tftp.c | 4 +- > netboot/i82586.c | 2 +- > netboot/main.c | 4 +- > netboot/pci.h | 4 + > stage1/Makefile.am | 2 +- > stage1/stage1.S | 11 +- > stage2/Makefile.am | 2 +- > stage2/asm.S | 371 ++++++++- > stage2/boot.c | 7 +- > stage2/builtins.c | 148 +++- > stage2/disk_io.c | 39 +- > stage2/filesys.h | 40 +- > stage2/fsys_ext2fs.c | 39 +- > stage2/fsys_fat.c | 26 +- > stage2/fsys_ffs.c | 20 +- > stage2/fsys_iso9660.c | 14 +- > stage2/fsys_jfs.c | 14 +- > stage2/fsys_minix.c | 28 +- > stage2/fsys_reiserfs.c | 18 +- > stage2/fsys_ufs2.c | 16 +- > stage2/fsys_vstafs.c | 17 +- > stage2/fsys_xfs.c | 13 +- > stage2/iso9660.h | 4 +- > stage2/pc_slice.h | 2 + > stage2/shared.h | 60 ++- > stage2/stage2.c | 896 +++++++++++++++++++- > util/grub-install.in | 278 +++++-- > util/grub-md5-crypt.in | 2 +- > util/mbchk.c | 4 +- > 42 files changed, 2534 insertions(+), 342 deletions(-) > >diff --git a/.gear/rules b/.gear/rules >new file mode 100644 >index 0000000..f78a96e >--- /dev/null >+++ b/.gear/rules >@@ -0,0 +1,2 @@ >+tar: @name@-@version@:. >+diff: @name@-@version@:. . >diff --git a/.gear/tags/607d849b5fb32b41822516380089de50078ed12b b/.gear/tags/607d849b5fb32b41822516380089de50078ed12b >new file mode 100644 >index 0000000..c6739e7 >--- /dev/null >+++ b/.gear/tags/607d849b5fb32b41822516380089de50078ed12b >@@ -0,0 +1,6 @@ >+object bc19bc026c057091d3ff25c0312afd200a153ef8 >+type commit >+tag grub-0.97 >+tagger Alexey I. Froloff <raorn@altlinux.org> 1202825111 +0300 >+ >+grub 0.97 >diff --git a/.gear/tags/list b/.gear/tags/list >new file mode 100644 >index 0000000..b403ab4 >--- /dev/null >+++ b/.gear/tags/list >@@ -0,0 +1 @@ >+607d849b5fb32b41822516380089de50078ed12b grub-0.97 >diff --git a/Makefile.am b/Makefile.am >index 63a9a4f..202a9d1 100644 >--- a/Makefile.am >+++ b/Makefile.am >@@ -2,3 +2,4 @@ > AUTOMAKE_OPTIONS = 1.7 gnu > SUBDIRS = netboot stage2 stage1 lib grub util docs > EXTRA_DIST = BUGS MAINTENANCE >+pkgdatadir=$(datadir) >diff --git a/configure.ac b/configure.ac >index bb9e1d9..dfd5cc6 100644 >--- a/configure.ac >+++ b/configure.ac >@@ -60,8 +60,7 @@ AC_PROG_CC > _AM_DEPENDENCIES(CC) > > dnl Because recent automake complains about AS, set it here. >-CCAS="$CC" >-AC_SUBST(CCAS) >+AM_PROG_AS > > AC_ARG_WITH(binutils, > [ --with-binutils=DIR search the directory DIR to find binutils]) >diff --git a/docs/grub-install.8 b/docs/grub-install.8 >index ac588a3..accff22 100644 >--- a/docs/grub-install.8 >+++ b/docs/grub-install.8 >@@ -30,6 +30,8 @@ BIOS > .TP > \fB\-\-recheck\fR > probe a device map even if it already exists >+ >+This option is unreliable and its use is strongly discouraged. > .PP > INSTALL_DEVICE can be a GRUB device name or a system device filename. > .PP >diff --git a/docs/grub.texi b/docs/grub.texi >index 51d330a..18e3736 100644 >--- a/docs/grub.texi >+++ b/docs/grub.texi >@@ -2118,8 +2118,10 @@ These commands can only be used in the menu: > * default:: Set the default entry > * fallback:: Set the fallback entry > * hiddenmenu:: Hide the menu interface >+* gfxmenu:: Use graphical menu interface > * timeout:: Set the timeout > * title:: Start a menu entry >+* wildcard:: Define a wildcard boot entry > @end menu > > >@@ -2150,6 +2152,15 @@ fallback entry numbers. > @end deffn > > >+@node gfxmenu >+@subsection gfxmenu >+ >+@deffn Command gfxmenu file >+Use the graphical menu interface. The graphics data are taken from >+@var{file} and must be created using 'mkbootmsg' from the gfxboot package. >+@end deffn >+ >+ > @node hiddenmenu > @subsection hiddenmenu > >@@ -2180,6 +2191,42 @@ the line, starting with the first non-space character. > @end deffn > > >+@node wildcard >+@subsection wildcard >+ >+@deffn Command wildcard pathname >+Treat this boot entry as a wildcard entry: The >+wildcard, title, kernel, and initrd commands (see @ref{Menu-specific >+commands} and @ref{Command-line and menu entry commands}) each have an >+asterisk (*) in their value. A filename match is performed on the >+@var{pathname} of the wildcard command. For each match, the entire boot >+entry is duplicated. The part of the filename whcih matches the asterisk >+in the wildcard command replaces the asterisks in the title, kernel, and >+initrd commands. For example, with the files vmlinuz-2.6.5-1 and >+vmlinuz-2.6.8-8 below (hd0,7)/boot, the following entry in the stage 2 >+configuration file: >+ >+@example >+title Linux-* >+ wildcard (hd0,7)/boot/vmlinuz-* >+ kernel (hd0,7)/boot/vmlinuz-* root=/dev/hda8 >+ initrd (hd0,7)/boot/initrd-* >+@end example >+ >+would expand as follows: >+ >+@example >+title Linux-2.6.5-1 >+ wildcard (hd0,7)/boot/vmlinuz-2.6.5-1 >+ kernel (hd0,7)/boot/vmlinuz-2.6.5-1 root=/dev/hda8 >+ initrd (hd0,7)/boot/initrd-2.6.5-1 >+title Linux-2.6.8-8 >+ wildcard (hd0,7)/boot/vmlinuz-2.6.8-8 >+ kernel (hd0,7)/boot/vmlinuz-2.6.8-8 root=/dev/hda8 >+ initrd (hd0,7)/boot/initrd-2.6.8-8 >+@end example >+@end deffn >+ > @node General commands > @section The list of general commands > >@@ -2909,7 +2956,7 @@ appropriate parameters in the Linux setup area in memory. See also > @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] >+@deffn Command install [@option{--force-lba[=off]}] [@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. >@@ -2956,6 +3003,13 @@ HP Vectra XU 6/200 BIOS version GG.06.11 > 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. >+On the other hand there is at least one known BIOS that does the opposite, >+it claims to support LBA and then fails to provide it. Iff you have an >+Adaptec 2940 with BIOS revision 1.21 ( newer ones just work and older ones >+don't make the false claim ), or otherwise experience grub hanging >+after stage1, you can try to use the option @option{--force-lba=off}, >+as long as all disk blocks involved in booting reside >+within the first 1024 cylinders. > > @strong{Caution3:} You must specify the option @option{--stage2} in the > grub shell, if you cannot unmount the filesystem where your stage2 file >@@ -3702,8 +3756,9 @@ Use @var{file} as the grub shell. You can append arbitrary options to > > @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. >+exists. >+ >+This option is unreliable and its use is strongly discouraged. > @end table > > >diff --git a/grub.spec b/grub.spec >new file mode 100644 >index 0000000..5b6b68a >--- /dev/null >+++ b/grub.spec >@@ -0,0 +1,323 @@ >+Name: grub >+Version: 0.97 >+Release: alt3 >+ >+Summary: GRand Unified Bootloader >+Group: System/Kernel and hardware >+License: GPL >+URL: http://www.gnu.org/software/grub/grub.en.html >+ >+ExclusiveArch: %ix86 >+ >+Packager: Sir Raorn <raorn@altlinux.ru> >+ >+Source: ftp://alpha.gnu.org/gnu/grub/%name-%version.tar >+Patch: %name-%version-%release.patch >+ >+Provides: %name-doc = %version, %name-graph = %version >+Obsoletes: %name-doc, %name-graph >+ >+# Automatically added by buildreq on Mon Feb 25 2008 >+BuildRequires: libncurses-devel tetex-latex >+ >+##BuildRequires: libncurses-devel reiser4progs-minimal-devel tetex-latex >+ >+%package utils >+Group: System/Kernel and hardware >+Summary: Additional utilites for %name >+ >+%description >+GNU GRUB is a multiboot boot loader. It was derived from GRUB. It is an >+attempt to produce a boot loader for IBM PC-compatible machines that >+has both the ability to be friendly to beginning or otherwise >+nontechnically interested users and the flexibility to help experts in >+diverse environments. It is compatible with Free/Net/OpenBSD and Linux. >+It supports Win 9x/NT and OS/2 via chainloaders. It has a menu >+interface and a command line interface. >+It implements the Multiboot standard, which allows for flexible loading >+of multiple boot images (needed for modular kernels such as the GNU >+Hurd). >+ >+%description utils >+Additional utilites for %name >+ >+%prep >+%setup >+%patch -p1 >+ >+%build >+%autoreconf >+ >+%define _optlevel s >+%add_optflags -DNDEBUG -W -Wall -Wpointer-arith >+%add_optflags -fno-stack-protector -fno-strict-aliasing -minline-all-stringops >+%ifarch x86_64 >+ %add_optflags -m32 -fno-asynchronous-unwind-tables >+%endif >+%configure \ >+ --bindir=/bin --sbindir=/sbin \ >+ --disable-auto-linux-mem-opt --enable-diskless \ >+ --enable-{3c50{3,7},3c5{0,2}9,3c595,3c90x,cs89x0,davicom,depca,eepro{,100},epic100} \ >+ --enable-{exos205,lance,ne,ne2100,ni{50,52,65}00,ns8390} \ >+ --enable-{rtl8139,sk-g16,smc9000,tiara,tulip,via-rhine,w89c840,wd} >+%make_build >+(cd stage2; mv nbgrub pxegrub ..) >+mv stage2/stage2{,.netboot} >+%make_build clean >+%configure \ >+ --bindir=/bin --sbindir=/sbin \ >+ --prefix=/usr --infodir=%{_infodir} --mandir=%{_mandir} --datadir=%{_datadir} \ >+ --libexecdir=%{_libexecdir} \ >+ --disable-auto-linux-mem-opt >+%make_build >+%make_build -C docs dvi >+ >+%install >+%make_install DESTDIR=%buildroot install >+mkdir -p %buildroot/boot/grub/pictures >+ln -sfn . %buildroot/boot/boot >+install -p {nb,pxe}grub stage2/stage2{,.netboot} %buildroot/boot/grub >+install -m755 -p grubonce %buildroot/sbin >+mv %buildroot%_libexecdir/grub/* %buildroot/boot/grub >+rm -rf %buildroot%_libexecdir/grub >+ln -sfn ../../boot/grub %buildroot%_libexecdir >+ >+%post >+if [ -x /usr/sbin/detectloader -a -f /proc/partitions ]; then >+ LOADER=$(/usr/sbin/detectloader) >+ if [ "$LOADER" = "GRUB" ]; then >+ if [ -f /boot/grub/install.sh ]; then >+ # Old grub installation >+ sh /boot/grub/install.sh > /dev/null >+ elif [ -s /etc/sysconfig/grub -a grep -q quit /etc/sysconfig/grub 1>/dev/null 2>/dev/null ]; then >+ # This file should be created by (future) alterator-grub >+ /sbin/grub --batch < /etc/sysconfig/grub > /dev/null >+ else >+ cat <<EOF >&2 >+Please install GRUB manually. >+EOF >+ fi >+ fi >+fi >+ >+%install_info %name.info >+%install_info multiboot.info >+ >+%preun >+%uninstall_info %name.info >+%uninstall_info multiboot.info >+ >+ >+%files >+%doc BUGS NEWS TODO README THANKS AUTHORS INSTALL ChangeLog COPYING docs/menu.lst >+%dir /boot/grub >+%dir /boot/boot >+/boot/grub/*stage* >+/boot/grub/nbgrub >+/boot/grub/pxegrub >+%_infodir/* >+%_mandir/*/* >+/sbin/* >+/bin/* >+%exclude /sbin/grub-terminfo >+%dir %_libexecdir/grub >+ >+%files utils >+/sbin/grub-terminfo >+ >+%changelog >+* Thu Feb 28 2008 Sir Raorn <raorn@altlinux.ru> 0.97-alt3 >+- Resurrected from orphaned >+- Removed ReiserFS4 support >+- Updated gfxboot support from SuSE >+- mdraid/dmraid support in grub-install(8) from Fedora >+- All binaries moved to /bin and /sbin >+- Wildcard menu.lst entries support from SuSE >+ >+* Tue May 30 2006 Andriy Stepanov <stanv@altlinux.ru> 0.97-alt2 >+- Add support for reiser4 FS >+ >+* Wed May 24 2006 Andriy Stepanov <stanv@altlinux.ru> 0.97-alt1 >+- Switch to new version. Dual plain grub and with PXE support. >+ >+* Wed Oct 20 2004 Stanislav Ievlev <inger@altlinux.org> 0.95-alt1 >+- 0.95 >+ >+* Tue Mar 09 2004 Stanislav Ievlev <inger@altlinux.org> 0.94-alt1 >+- 0.94 >+ >+* Wed Jan 14 2004 Stanislav Ievlev <inger@altlinux.org> 0.93-alt2 >+- fix building with gcc3.3 >+ >+* Tue Apr 08 2003 Stanislav Ievlev <inger@altlinux.ru> 0.93-alt1 >+- removed patches for old graphics support >+- removed grub-splashes too >+- patch (nodeprecatedflags) removed >+- dump patch turned off >+- new grub-terminfo utility placed into grub-utils subpackage (to avoid deps on termutils-devel) >+ >+* Fri Feb 07 2003 Stanislav Ievlev <inger@altlinux.ru> 0.92-alt3.1 >+- removed old graphics support >+- removed grub-graph package (now obsolete) >+ >+* Mon Feb 03 2003 Rider <rider@altlinux.ru> 0.92-alt3 >+- GFX menu support from SuSE >+ >+* Sun Oct 6 2002 Ivan Zakharyaschev <imz@altlinux.ru> 0.92-alt2 >+- try to fix graph menu cursor clearing passed items: keypressclear patch >+ modified -- now it refreshes the screen multiple times >+ (not only the first time) >+ >+* Mon Apr 01 2002 Stanislav Ievlev <inger@altlinux.ru> 0.91-alt5 >+- Added patch to fix meminfo displaying >+ >+* Fri Feb 15 2002 Stanislav Ievlev <inger@altlinux.ru> 0.91-alt4 >+- fixed grub-install >+ >+* Mon Feb 04 2002 Stanislav Ievlev <inger@altlinux.ru> 0.91-alt3 >+- real dump terminal fix and some other patches from grub-bug mailing list >+ >+ >+* Wed Jan 30 2002 Stanislav Ievlev <inger@altlinux.ru> 0.91-alt2 >+- added temporary hack for the DUMB_TERMINAL mode >+ >+* Tue Jan 29 2002 Stanislav Ievlev <inger@altlinux.ru> 0.91-alt1 >+- 0.91 >+- all mandrake patches removed >+ >+* Fri Nov 16 2001 Stanislav Ievlev <inger@altlinux.ru> 0.90-alt8 >+- Added latest XFS+JFS patches >+- Added some RH patches >+ >+* Wed Nov 14 2001 Dmitry V. Levin <ldv@alt-linux.org> 0.90-alt7 >+- Moved rebootin utility to bootloader-utils package. >+ >+* Wed Aug 22 2001 Stanislav Ievlev <inger@altlinux.ru> 0.90-alt6 >+- New image and new package (graph). >+ >+* Wed Aug 15 2001 Stanislav Ievlev <inger@altlinux.ru> 0.90-alt5 >+- Added first picture ( Junior ;) ). >+ >+* Mon Aug 13 2001 Stanislav Ievlev <inger@altlinux.ru> 0.90-alt4 >+- Added patch for JFS support >+ >+* Wed Aug 08 2001 Stanislav Ievlev <inger@altlinux.ru> 0.90-alt3 >+- Removed Mandrake's builtins. We don't need it >+- Added vga16 support. >+- We don't need previous hack now. All works. >+ Problem was: some bad function set errnum nonzero. >+ >+* Thu Aug 02 2001 Stanislav Ievlev <inger@altlinux.ru> 0.90-alt2 >+- Temporary hack: memcheck() function doesn't work. >+ >+* Thu Jul 26 2001 Stanislav Ievlev <inger@altlinux.ru> 0.90-alt1 >+- 0.90. Little changes from previous snapshot >+ >+* Thu Jun 28 2001 Stanislav Ievlev <inger@altlinux.ru> 0.5.96.1-ipl5mdk >+- Update to CVS at 20010530 >+ >+* Mon May 28 2001 Stanislav Ievlev <inger@altlinux.ru> 0.5.96.1-ipl4mdk >+- New patches from Mandrake >+ >+* Mon Dec 18 2000 AEN <aen@logic.ru> >+- adopted for RE >+ >+* Mon Dec 11 2000 Pixel <pixel@mandrakesoft.com> 0.5.96.1-2mdk >+- add a call to /boot/grub/install.sh if needed >+ >+* Sat Dec 9 2000 Pixel <pixel@mandrakesoft.com> 0.5.96.1-1mdk >+- new version >+ * patch fixbiosbug-nbsectors no more needed (unless you define NO_BUGGY_BIOS_IN_THE_WORLD) >+ >+* Thu Aug 24 2000 Pixel <pixel@mandrakesoft.com> 0.5.95-7mdk >+- %%uninstall_info is fixed, yeepee :) >+ >+* Tue Aug 22 2000 Pixel <pixel@mandrakesoft.com> 0.5.95-6mdk >+- fixbiosbug-nbsectors for some Geom Errors (warly's case) >+ >+* Wed Aug 16 2000 Pixel <pixel@mandrakesoft.com> 0.5.95-5mdk >+- fix erroneous remove_info macro (sillyme) >+ >+* Mon Aug 07 2000 Frederic Lepied <flepied@mandrakesoft.com> 0.5.95-4mdk >+- automatically added BuildRequires >+ >+* Fri Jul 21 2000 Pixel <pixel@mandrakesoft.com> 0.5.95-3mdk >+- macroization, BM >+ >+* Wed Jul 12 2000 Pixel <pixel@mandrakesoft.com> 0.5.95-2mdk >+- add a patch for ezbios nonsense >+ >+* Mon Jul 3 2000 Pixel <pixel@mandrakesoft.com> 0.5.95-1mdk >+- new version >+ >+* Sat May 20 2000 Pixel <pixel@mandrakesoft.com> 0.5.94-14mdk >+- add rebootin command (use altconfigfile cmd in menu.lst) >+- add altconfigfile (read once) >+ >+* Mon May 8 2000 Pixel <pixel@mandrakesoft.com> 0.5.94-12mdk >+- add reiserfs handling (missing symlink handling though) >+ >+* Wed May 3 2000 Pixel <pixel@mandrakesoft.com> 0.5.94-11mdk >+- fix for linux-extended extended partition >+ >+* Tue May 2 2000 Pixel <pixel@mandrakesoft.com> 0.5.94-10mdk >+- fix case of not found keytable >+ >+* Tue Apr 18 2000 Pixel <pixel@mandrakesoft.com> 0.5.94-9mdk >+- remove a patch from caldera >+ >+* Sun Apr 16 2000 Pixel <pixel@mandrakesoft.com> 0.5.94-8mdk >+- nicer menu >+- don't add automatic mem= if one is given >+ >+* Tue Apr 4 2000 Pixel <pixel@mandrakesoft.com> 0.5.94-7mdk >+- fix install path >+ >+* Mon Apr 3 2000 Pixel <pixel@mandrakesoft.com> 0.5.94-6mdk >+- integrate patches from caldera >+ >+* Fri Mar 31 2000 Pixel <pixel@mandrakesoft.com> 0.5.94-5mdk >+- re-rebuild >+ >+* Wed Mar 29 2000 Pixel <pixel@mandrakesoft.com> 0.5.94-4mdk >+- big patch (i18n & look) >+ >+* Sat Mar 25 2000 Pixel <pixel@mandrakesoft.com> 0.5.94-3mdk >+- split printable doc and some more to have smaller package (keep mainly info in >+main package, very good one) >+- cleanup install-info in %% post scripts >+ >+* Fri Mar 24 2000 Pixel <pixel@mandrakesoft.com> 0.5.94-2mdk >+- remove unneeded patch >+- use of %% { ix86 } >+ >+* Wed Mar 22 2000 Pixel <pixel@mandrakesoft.com> 0.5.94-1mdk >+- remove now unneeded --disable-gunzip >+- added option --disable-lba-support-bitmap-check >+- patch for *very* buggy bioses (tells grub every hd is gigantic) >+- new version >+ >+* Mon Mar 13 2000 Pixel <pixel@mandrakesoft.com> 0.5.93.1-7mdk >+- configure with --disable-gunzip >+(so that initrd is not gunzip'ed and fits in memory, that's the kernel's job anyway) >+ >+* Wed Mar 1 2000 Pixel <pixel@mandrakesoft.com> 0.5.93.1-6mdk >+- remove no-device-check (was stupid) >+- replace by something better (option --devices) >+ >+* Tue Feb 29 2000 Pixel <pixel@mandrakesoft.com> 0.5.93.1-5mdk >+- add option no-device-check for grub binary (mainly for non-interactive use) >+ >+* Sun Jan 16 2000 Chmouel Boudjnah <chmouel@mandrakesoft.com> 0.5.93.1-4mdk >+- Add Exclusivearch. >+ >+* Tue Jan 4 2000 Chmouel Boudjnah <chmouel@mandrakesoft.com> 0.5.93.1-3mdk >+- Add install_grub_on_floppy script (thnks b.bodin). >+- Add dvi docs (tknks b.bodin). >+ >+* Mon Jan 3 2000 Chmouel Boudjnah <chmouel@mandrakesoft.com> 0.5.93.1-2mdk >+- Add %%packager (thnks rpmlint). >+- Remove CFLAGS. >+ >+* Mon Jan 3 2000 Chmouel Boudjnah <chmouel@mandrakesoft.com> >+- First spec file for Mandrake distribution based on debian version. >diff --git a/grub/asmstub.c b/grub/asmstub.c >index ab95b4b..56280b9 100644 >--- a/grub/asmstub.c >+++ b/grub/asmstub.c >@@ -43,6 +43,8 @@ int grub_stage2 (void); > #include <termios.h> > #include <signal.h> > >+#include <sys/mman.h> >+ > #ifdef __linux__ > # include <sys/ioctl.h> /* ioctl */ > # if !defined(__GLIBC__) || \ >@@ -142,14 +144,30 @@ grub_stage2 (void) > } > > assert (grub_scratch_mem == 0); >- scratch = malloc (0x100000 + EXTENDED_MEMSIZE + 15); >+#ifdef MAP_32BIT >+#define MY_MAP_SET MAP_PRIVATE | MAP_GROWSDOWN | MAP_ANONYMOUS | MAP_32BIT >+#else >+#define MY_MAP_SET MAP_PRIVATE | MAP_GROWSDOWN | MAP_ANONYMOUS >+#endif >+ scratch = mmap(NULL, >+ 0x100000 + EXTENDED_MEMSIZE + 15, >+ PROT_EXEC | PROT_READ | PROT_WRITE, >+ MY_MAP_SET, >+ -1, >+ 0); >+ > 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)); >+ disks = mmap(NULL, >+ NUM_DISKS * sizeof (*disks), >+ PROT_EXEC | PROT_READ | PROT_WRITE, >+ MY_MAP_SET, >+ -1, >+ 0); > assert (disks); > /* Initialize DISKS. */ > for (i = 0; i < NUM_DISKS; i++) >@@ -215,9 +233,9 @@ grub_stage2 (void) > /* Release memory. */ > restore_device_map (device_map); > device_map = 0; >- free (disks); >+ munmap(disks, NUM_DISKS * sizeof (*disks)); > disks = 0; >- free (scratch); >+ munmap(scratch, 0x100000 + EXTENDED_MEMSIZE + 15); > grub_scratch_mem = 0; > > if (serial_device) >@@ -480,6 +498,32 @@ set_vbe_mode (int mode_number) > return 0; > } > >+/* graphical menu functions . */ >+int >+gfx_init (gfx_data_t *gfx_data) >+{ >+ return 0; >+} >+ >+int >+gfx_done (gfx_data_t *gfx_data) >+{ >+ return 0; >+} >+ >+int >+gfx_input (gfx_data_t *gfx_data, int *menu_entry) >+{ >+ return 0; >+} >+ >+int >+gfx_setup_menu (gfx_data_t *gfx_data) >+{ >+ return 0; >+} >+ >+ > /* low-level timing info */ > int > getrtsecs (void) >diff --git a/grub/main.c b/grub/main.c >index dfe847e..c9476fd 100644 >--- a/grub/main.c >+++ b/grub/main.c >@@ -44,7 +44,7 @@ int use_curses = 0; > int verbose = 0; > int read_only = 0; > int floppy_disks = 1; >-char *device_map_file = 0; >+char *device_map_file = "/boot/grub/device.map"; > static int default_boot_drive; > static int default_install_partition; > static char *default_config_file; >diff --git a/grubonce b/grubonce >new file mode 100755 >index 0000000..84df31d >--- /dev/null >+++ b/grubonce >@@ -0,0 +1,57 @@ >+#!/usr/bin/perl >+ >+# Keep this sort of configurable for the future. >+$GRUBDIR="/boot/grub"; >+ >+# Parse the menu file, and see if we can get a match for a maybe given arg. >+open(MENU, "<$GRUBDIR/menu.lst") || die "no menu.lst in $GRUBDIR"; >+$gotit = 0; >+$titleno = -1; >+$global_default = undef; >+while(<MENU>) { >+ m,\s*default\s+(.+), && $titleno == -1 && ($global_default = $1); >+ next unless m,\s*title\s+(.*),i; >+ $title_name = $1; >+ $titleno++; >+ >+ if (@ARGV > 0) { >+ # Argument may be entirely numerical, in which case it is an index, >+ # or a perl RE that leads to the first title matching. >+ if (( $ARGV[0] =~ m,^[0-9]+$, && $titleno eq $ARGV[0] ) || >+ ( $ARGV[0] !~ m,^[0-9]+$, && $title_name =~ m,$ARGV[0],i) ) { >+ $gotit = 1; >+ last; >+ } >+ } else { >+ print "$titleno: $title_name\n"; >+ } >+} >+close(MENU); >+ >+print "Warning: you haven't set a global default!\n" if !defined($global_default); >+ >+# Without a command line argument, we have now listet the titles and are done. >+exit 0 if @ARGV < 1; >+ >+# Else the user wants to write the default file. We have better found a match! >+if ($gotit > 0) { >+ print "Warning: your global default is 'saved'; changing default permanently!" >+ if $global_default eq "saved"; >+ >+ print "Using entry #$titleno: $title_name\n"; >+ >+ # set the magic one-time flag >+ $titleno |= 0x4000; >+ >+ open(DEFFILE, ">$GRUBDIR/default") || >+ die "Cannot open default file for writing"; >+ $buf = $titleno . "\0" . "\n" x 9; >+ syswrite(DEFFILE, $buf, 10); >+ close(DEFFILE); >+ >+ exit 0; >+} else { >+ print $ARGV[0] . " not found in $GRUBDIR/menu.lst\n"; >+ exit 1; >+} >+ >diff --git a/lib/device.c b/lib/device.c >index d0663b3..ddd4687 100644 >--- a/lib/device.c >+++ b/lib/device.c >@@ -131,6 +131,122 @@ get_kfreebsd_version () > #include <shared.h> > #include <device.h> > >+#if defined(__linux__) >+/* The 2.6 kernel has removed all of the geometry handling for IDE drives >+ * that did fixups for LBA, etc. This means that the geometry we get >+ * with the ioctl has a good chance of being wrong. So, we get to >+ * also know about partition tables and try to read what the geometry >+ * is there. *grumble* Very closely based on code from cfdisk >+ */ >+static void get_kernel_geometry(int fd, int *cyl, int *heads, int *sectors) { >+ struct hd_geometry hdg; >+ >+ if (ioctl (fd, HDIO_GETGEO, &hdg)) >+ return; >+ >+ *cyl = hdg.cylinders; >+ *heads = hdg.heads; >+ *sectors = hdg.sectors; >+} >+ >+struct partition { >+ unsigned char boot_ind; /* 0x80 - active */ >+ unsigned char head; /* starting head */ >+ unsigned char sector; /* starting sector */ >+ unsigned char cyl; /* starting cylinder */ >+ unsigned char sys_ind; /* What partition type */ >+ unsigned char end_head; /* end head */ >+ unsigned char end_sector; /* end sector */ >+ unsigned char end_cyl; /* end cylinder */ >+ unsigned char start4[4]; /* starting sector counting from 0 */ >+ unsigned char size4[4]; /* nr of sectors in partition */ >+}; >+ >+#define ALIGNMENT 2 >+typedef union { >+ struct { >+ unsigned char align[ALIGNMENT]; >+ unsigned char b[SECTOR_SIZE]; >+ } c; >+ struct { >+ unsigned char align[ALIGNMENT]; >+ unsigned char buffer[0x1BE]; >+ struct partition part[4]; >+ unsigned char magicflag[2]; >+ } p; >+} partition_table; >+ >+#define PART_TABLE_FLAG0 0x55 >+#define PART_TABLE_FLAG1 0xAA >+ >+static void >+get_partition_table_geometry(partition_table *bufp, int *cyl, int *heads, >+ int *sectors) { >+ struct partition *p; >+ int i,h,s,hh,ss; >+ int first = 1; >+ int bad = 0; >+ >+ if (bufp->p.magicflag[0] != PART_TABLE_FLAG0 || >+ bufp->p.magicflag[1] != PART_TABLE_FLAG1) { >+ /* Matthew Wilcox: slightly friendlier version of >+ fatal(_("Bad signature on partition table"), 3); >+ */ >+ fprintf(stderr, "Unknown partition table signature\n"); >+ return; >+ } >+ >+ hh = ss = 0; >+ for (i=0; i<4; i++) { >+ p = &(bufp->p.part[i]); >+ if (p->sys_ind != 0) { >+ h = p->end_head + 1; >+ s = (p->end_sector & 077); >+ if (first) { >+ hh = h; >+ ss = s; >+ first = 0; >+ } else if (hh != h || ss != s) >+ bad = 1; >+ } >+ } >+ >+ if (!first && !bad) { >+ *heads = hh; >+ *sectors = ss; >+ } >+} >+ >+static void get_linux_geometry (int fd, struct geometry *geom) { >+ int kern_cyl = 0, kern_head = 0, kern_sectors = 0; >+ int pt_cyl = 0, pt_head = 0, pt_sectors = 0; >+ partition_table bufp; >+ >+ get_kernel_geometry(fd, &kern_cyl, &kern_head, &kern_sectors); >+ >+ if (read(fd, bufp.c.b, SECTOR_SIZE) == SECTOR_SIZE) { >+ get_partition_table_geometry(&bufp, &pt_cyl, &pt_head, &pt_sectors); >+ } else { >+ fprintf(stderr, "Unable to read partition table: %s\n", strerror(errno)); >+ } >+ >+ if (pt_head && pt_sectors) { >+ int cyl_size; >+ >+ geom->heads = pt_head; >+ geom->sectors = pt_sectors; >+ cyl_size = pt_head * pt_sectors; >+ geom->cylinders = geom->total_sectors/cyl_size; >+ } else { >+ geom->heads = kern_head; >+ geom->sectors = kern_sectors; >+ geom->cylinders = kern_cyl; >+ } >+ >+ return; >+} >+#endif >+ > /* Get the geometry of a drive DRIVE. */ > void > get_drive_geometry (struct geometry *geom, char **map, int drive) >@@ -151,20 +267,16 @@ get_drive_geometry (struct geometry *geom, char **map, int drive) > #if defined(__linux__) > /* Linux */ > { >- struct hd_geometry hdg; > unsigned long nr; > >- if (ioctl (fd, HDIO_GETGEO, &hdg)) >- goto fail; >- > if (ioctl (fd, BLKGETSIZE, &nr)) > goto fail; >- >- /* Got the geometry, so save it. */ >- geom->cylinders = hdg.cylinders; >- geom->heads = hdg.heads; >- geom->sectors = hdg.sectors; >+ > geom->total_sectors = nr; >+ get_linux_geometry(fd, geom); >+ >+ if (!geom->heads && !geom->cylinders && !geom->sectors) >+ goto fail; > > goto success; > } >@@ -403,10 +515,27 @@ get_dac960_disk_name (char *name, int controller, int drive) > } > > static void >+get_cciss_disk_name (char * name, int controller, int drive) >+{ >+ sprintf (name, "/dev/cciss/c%dd%d", controller, drive); >+} >+ >+static void >+get_cpqarray_disk_name (char * name, int controller, int drive) >+{ >+ sprintf (name, "/dev/ida/c%dd%d", controller, drive); >+} >+static void > get_ataraid_disk_name (char *name, int unit) > { > sprintf (name, "/dev/ataraid/d%c", unit + '0'); > } >+ >+static void >+get_i2o_disk_name (char *name, int unit) >+{ >+ sprintf (name, "/dev/i2o/hd%c", unit + 'a'); >+} > #endif > > /* Check if DEVICE can be read. If an error occurs, return zero, >@@ -515,6 +644,7 @@ read_device_map (FILE *fp, char **map, const char *map_file) > probing devices. */ > char buf[1024]; /* XXX */ > int line_number = 0; >+ int retval = 0; /* default to failure */ > > while (fgets (buf, sizeof (buf), fp)) > { >@@ -541,14 +671,14 @@ read_device_map (FILE *fp, char **map, const char *map_file) > if (*ptr != '(') > { > show_error (line_number, "No open parenthesis found"); >- return 0; >+ continue; > } > > ptr++; > if ((*ptr != 'f' && *ptr != 'h') || *(ptr + 1) != 'd') > { > show_error (line_number, "Bad drive name"); >- return 0; >+ continue; > } > > if (*ptr == 'f') >@@ -559,7 +689,7 @@ read_device_map (FILE *fp, char **map, const char *map_file) > if (drive < 0) > { > show_error (line_number, "Bad device number"); >- return 0; >+ continue; > } > else if (drive > 127) > { >@@ -575,7 +705,7 @@ read_device_map (FILE *fp, char **map, const char *map_file) > if (*ptr != ')') > { > show_error (line_number, "No close parenthesis found"); >- return 0; >+ continue; > } > > ptr++; >@@ -586,7 +716,7 @@ read_device_map (FILE *fp, char **map, const char *map_file) > if (! *ptr) > { > show_error (line_number, "No filename found"); >- return 0; >+ continue; > } > > /* Terminate the filename. */ >@@ -604,9 +734,11 @@ read_device_map (FILE *fp, char **map, const char *map_file) > > map[drive] = strdup (ptr); > assert (map[drive]); >+ >+ retval = 1; /* at least 1 drive configured successfully */ > } > >- return 1; >+ return retval; > } > > /* Initialize the device map MAP. *MAP will be allocated from the heap >@@ -782,7 +914,7 @@ init_device_map (char ***map, const char *map_file, int floppy_disks) > > for (controller = 0; controller < 8; controller++) > { >- for (drive = 0; drive < 15; drive++) >+ for (drive = 0; drive < 32; drive++) > { > char name[24]; > >@@ -801,6 +933,90 @@ init_device_map (char ***map, const char *map_file, int floppy_disks) > } > } > } >+ >+ /* I2O disks. */ >+ for (i = 0; i < 8; i++) >+ { >+ char name[16]; >+ >+ get_i2o_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__ */ >+ >+#ifdef __linux__ >+ /* This is for cciss - we have >+ /dev/cciss/c<controller>d<logical drive>p<partition>. >+ >+ cciss driver currently supports up to 8 controllers, 16 logical >+ drives, and 7 partitions. */ >+ { >+ int controller, drive; >+ >+ for (controller = 0; controller < 8; controller++) >+ { >+ for (drive = 0; drive < 16; drive++) >+ { >+ char name[24]; >+ >+ get_cciss_disk_name (name, controller, drive); >+ if (check_device (name)) >+ { >+ (*map)[num_hd + 0x80] = strdup (name); >+ assert ((*map)[num_hd + 0x80]); >+ >+ /* If the device map file is opened, write the map. */ >+ if (fp) >+ fprintf (fp, "(hd%d)\t%s\n", num_hd, name); >+ >+ num_hd++; >+ } >+ } >+ } >+ } >+#endif /* __linux__ */ >+ >+#ifdef __linux__ >+ /* This is for cpqarray - we have >+ /dev/ida/c<controller>d<logical drive>p<partition>. >+ >+ cpqarray driver currently supports up to 8 controllers, 16 logical >+ drives, and 15 partitions. */ >+ { >+ int controller, drive; >+ >+ for (controller = 0; controller < 8; controller++) >+ { >+ for (drive = 0; drive < 15; drive++) >+ { >+ char name[24]; >+ >+ get_cpqarray_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. */ >@@ -831,9 +1047,11 @@ int > is_disk_device (char **map, int drive) > { > struct stat st; >+ int retval; > > assert (map[drive] != 0); >- assert (stat (map[drive], &st) == 0); >+ retval = stat (map[drive], &st); >+ assert (retval == 0); > /* For now, disk devices under Linux are all block devices. */ > return S_ISBLK (st.st_mode); > } >@@ -843,7 +1061,7 @@ write_to_partition (char **map, int drive, int partition, > int sector, int size, const char *buf) > { > char dev[PATH_MAX]; /* XXX */ >- int fd; >+ int fd, len, pnum; > > if ((partition & 0x00FF00) != 0x00FF00) > { >@@ -861,7 +1079,20 @@ write_to_partition (char **map, int drive, int partition, > if (strcmp (dev + strlen(dev) - 5, "/disc") == 0) > strcpy (dev + strlen(dev) - 5, "/part"); > } >- sprintf (dev + strlen(dev), "%d", ((partition >> 16) & 0xFF) + 1); >+ >+ len = strlen(dev); >+ pnum = ((partition >> 16) & 0xFF); >+ if (strncmp (dev, "/dev/disk/by-id/", 16) == 0) >+ { >+ sprintf (dev + len, "-part%d", pnum + 1); >+ } >+ else if (isdigit(dev[len-1])) >+ { >+ /* It is obviously some RAID disk: "/dev/<dsk>/c0d0" . "p1" */ >+ sprintf (dev + len, "p%d", pnum + 1); >+ } >+ else >+ sprintf (dev + len, "%d", pnum + 1); > > /* Open the partition. */ > fd = open (dev, O_RDWR); >diff --git a/netboot/config.c b/netboot/config.c >index 3949a67..009e6cd 100644 >--- a/netboot/config.c >+++ b/netboot/config.c >@@ -122,6 +122,14 @@ static struct pci_device pci_nic_list[] = > "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_ID1031, >+ "Intel EtherExpressPro100 ID1031", 0, 0, 0, 0}, >+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1039, >+ "Intel EtherExpressPro100 ID1039", 0, 0, 0, 0}, >+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID103B, >+ "Intel 82801BD PRO/100 VM", 0, 0, 0, 0}, >+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1050, >+ "Intel EtherExpressPro100 82555 10/100", 0, 0, 0, 0}, > { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82562, > "Intel EtherExpressPro100 82562EM", 0, 0, 0, 0}, > #endif >@@ -281,6 +289,10 @@ static struct pci_dispatch_table PCI_NIC[] = > { 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_ID1031, eepro100_probe }, >+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1039, eepro100_probe }, >+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID103B, eepro100_probe }, >+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ID1050, eepro100_probe }, > { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82562, eepro100_probe }, > # endif /* INCLUDE_EEPRO100 */ > # ifdef INCLUDE_EPIC100 >diff --git a/netboot/fsys_tftp.c b/netboot/fsys_tftp.c >index b0233e8..c2140a4 100644 >--- a/netboot/fsys_tftp.c >+++ b/netboot/fsys_tftp.c >@@ -409,7 +409,7 @@ tftp_read (char *addr, int size) > /* Check if the file DIRNAME really exists. Get the size and save it in > FILEMAX. */ > int >-tftp_dir (char *dirname) >+tftp_dir (char *dirname, void (*handle)(char *)) > { > int ch; > >@@ -418,7 +418,7 @@ tftp_dir (char *dirname) > #endif > > /* In TFTP, there is no way to know what files exist. */ >- if (print_possibilities) >+ if (handle) > return 1; > > /* Don't know the size yet. */ >diff --git a/netboot/i82586.c b/netboot/i82586.c >index 15540c2..f8ec3fa 100644 >--- a/netboot/i82586.c >+++ b/netboot/i82586.c >@@ -735,7 +735,7 @@ static unsigned char exos_i186_init[] = > static int exos205_probe2(void) > { > unsigned short i; >- unsigned short shmem[10]; >+ unsigned short shmem[10] = { 0,0,0,0,0,0,0,0,0,0 }; > > /* Fix the ISCP address and base. */ > init_words[3] = scb_base; >diff --git a/netboot/main.c b/netboot/main.c >index 82759b6..abd9212 100644 >--- a/netboot/main.c >+++ b/netboot/main.c >@@ -54,9 +54,9 @@ struct rom_info rom; > > static int vendorext_isvalid; > static unsigned long netmask; >-static struct bootpd_t bootp_data; >+struct bootpd_t bootp_data; > static unsigned long xid; >-static unsigned char *end_of_rfc1533 = NULL; >+unsigned char *end_of_rfc1533 = NULL; > > #ifndef NO_DHCP_SUPPORT > #endif /* NO_DHCP_SUPPORT */ >diff --git a/netboot/pci.h b/netboot/pci.h >index a99dc14..cacd8de 100644 >--- a/netboot/pci.h >+++ b/netboot/pci.h >@@ -129,6 +129,10 @@ __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory") > #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_ID1031 0x1031 >+#define PCI_DEVICE_ID_INTEL_ID1039 0x1039 >+#define PCI_DEVICE_ID_INTEL_ID103B 0x103B >+#define PCI_DEVICE_ID_INTEL_ID1050 0x1050 > #define PCI_DEVICE_ID_INTEL_82562 0x2449 > #define PCI_VENDOR_ID_AMD 0x1022 > #define PCI_DEVICE_ID_AMD_LANCE 0x2000 >diff --git a/stage1/Makefile.am b/stage1/Makefile.am >index 0afc285..16e076a 100644 >--- a/stage1/Makefile.am >+++ b/stage1/Makefile.am >@@ -1,4 +1,4 @@ >-pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor) >+pkglibdir = /usr/lib/grub > nodist_pkglib_DATA = stage1 > > CLEANFILES = $(nodist_pkglib_DATA) >diff --git a/stage1/stage1.S b/stage1/stage1.S >index 985963d..886633f 100644 >--- a/stage1/stage1.S >+++ b/stage1/stage1.S >@@ -69,9 +69,12 @@ mode: > .byte 0 > disk_address_packet: > sectors: >- .long 0 >+ .byte 0 >+ .ascii "GRU" > heads: >- .long 0 >+ .ascii "B" >+ .byte 0 >+ .word 0 > cylinders: > .word 0 > sector_start: >@@ -177,7 +180,11 @@ real_start: > /* 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 >+ /* check if LBA is forced OFF 0x80 <= %al <= 0xff */ >+ js chs_mode >+ /* or forced ON 0x01 <= %al <= 0x7f */ > jnz lba_mode >+ /* otherwise trust BIOS int's result */ > andw $1, %cx > jz chs_mode > >diff --git a/stage2/Makefile.am b/stage2/Makefile.am >index f8e6d42..33e1231 100644 >--- a/stage2/Makefile.am >+++ b/stage2/Makefile.am >@@ -27,7 +27,7 @@ libgrub_a_CFLAGS = $(GRUB_CFLAGS) -I$(top_srcdir)/lib \ > -DUSE_MD5_PASSWORDS=1 -DSUPPORT_SERIAL=1 -DSUPPORT_HERCULES=1 > > # Stage 2 and Stage 1.5's. >-pkglibdir = $(libdir)/$(PACKAGE)/$(host_cpu)-$(host_vendor) >+pkglibdir = /usr/lib/grub > > EXTRA_PROGRAMS = nbloader.exec pxeloader.exec diskless.exec > >diff --git a/stage2/asm.S b/stage2/asm.S >index 34b6e7d..e2b07c0 100644 >--- a/stage2/asm.S >+++ b/stage2/asm.S >@@ -1091,7 +1091,11 @@ ENTRY(check_int13_extensions) > /* check if AH=0x42 is supported if FORCE_LBA is zero */ > movb EXT_C(force_lba), %al > testb %al, %al >+ /* check if LBA is forced OFF 0x80 <= %al <= 0xff */ >+ js 1f >+ /* or forced ON 0x01 <= %al <= 0x7f */ > jnz 2f >+ /* otherwise trust BIOS int's result */ > andw $1, %cx > jnz 2f > >@@ -1610,48 +1614,369 @@ ENTRY(set_vbe_mode) > popl %ebp > ret > >+ >+/* >+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >+ * >+ * graphical menu functions >+ * >+ */ >+ >+/* >+ * int gfx_init (gfx_data_t *gfx_data) >+ * >+ * init gfx things >+ * >+ * return vales: >+ * 0: ok >+ * 1: failed >+ * sets gfx_data->ok >+ */ >+ >+ENTRY(gfx_init) >+ pushl %ebp >+ movl %esp, %ebp >+ >+ pushl %edi >+ pushl %esi >+ pushl %ebx >+ >+ movl 8(%ebp),%edx >+ movl %edx,%edi >+ leal gfx_ofs_sys_cfg(%edx),%esi >+ andl $0xf,%edi >+ shrl $4,%edx >+ >+ pushl %ebp >+ >+ call EXT_C(prot_to_real) >+ .code16 >+ >+ pushw %ds >+ movw %dx,%ds >+ >+ lcall *gfx_ofs_jmp_table + 4 * 0 (%di) >+ >+ sbbl %ebx,%ebx >+ negl %ebx >+ >+ popw %ds >+ >+ DATA32 call EXT_C(real_to_prot) >+ .code32 >+ >+ popl %ebp >+ >+ movl %ebx,%eax >+ xorl $1,%ebx >+ movl 8(%ebp),%edx >+ movl %ebx,gfx_ofs_ok(%edx) >+ >+ popl %ebx >+ popl %esi >+ popl %edi >+ >+ popl %ebp >+ ret >+ >+ >+/* >+ * int gfx_done (gfx_data_t *gfx_data) >+ * >+ * shut down gfx things >+ * >+ * return vales: >+ * always 0 >+ * sets gfx_data->ok >+ */ >+ >+ENTRY(gfx_done) >+ pushl %ebp >+ movl %esp, %ebp >+ >+ pushl %edi >+ pushl %esi >+ pushl %ebx >+ >+ movl 8(%ebp),%edx >+ movl %edx,%ebx >+ andl $0xf,%ebx >+ shrl $4,%edx >+ >+ pushl %ebp >+ >+ call EXT_C(prot_to_real) >+ .code16 >+ >+ pushw %ds >+ >+ movw %dx,%ds >+ >+ lcall *gfx_ofs_jmp_table + 4 * 1 (%bx) >+ >+ popw %ds >+ >+ DATA32 call EXT_C(real_to_prot) >+ .code32 >+ >+ popl %ebp >+ >+ xorl %eax,%eax >+ movl 8(%ebp),%edx >+ movl %eax,gfx_ofs_ok(%edx) >+ >+ popl %ebx >+ popl %esi >+ popl %edi >+ >+ popl %ebp >+ ret >+ >+ >+/* >+ * int gfx_input (gfx_data_t *gfx_data, int *menu_entry) >+ * >+ * let user enter a command line >+ * >+ * uses gfx_data->cmdline as buffer >+ * >+ * return values: >+ * 1: abort >+ * 2: boot >+ * menu_entry: selected entry >+ */ >+ >+ENTRY(gfx_input) >+ pushl %ebp >+ movl %esp, %ebp >+ >+ pushl %edi >+ pushl %esi >+ pushl %ebx >+ >+ movl 8(%ebp),%edx >+ movl %edx,%ebx >+ leal gfx_ofs_sys_cfg(%edx),%esi >+ andl $0xf,%ebx >+ shrl $4,%edx >+ >+ pushl %ebp >+ >+ call EXT_C(prot_to_real) >+ .code16 >+ >+ pushw %ds >+ >+ movw %dx,%ds >+ >+ movl gfx_ofs_cmdline(%bx),%edi >+ movl gfx_ofs_cmdline_len(%bx),%ecx >+ movl gfx_ofs_timeout(%bx),%eax >+ imull $18,%eax >+ >+ lcall *gfx_ofs_jmp_table + 4 * 2 (%bx) >+ >+ movl %eax,%ecx >+ >+ popw %ds >+ >+ DATA32 call EXT_C(real_to_prot) >+ .code32 >+ >+ popl %ebp >+ >+ movl 12(%ebp),%edx >+ movl %ebx,(%edx) >+ >+ movl %ecx,%eax >+ >+ popl %ebx >+ popl %esi >+ popl %edi >+ >+ popl %ebp >+ ret >+ >+ >+/* >+ * int gfx_setup_menu (gfx_data_t *gfx_data) >+ * >+ * draw boot menu >+ * >+ * return values: >+ * always 0 >+ */ >+ >+/* menu entry descriptor */ >+#define menu_entries 0 >+#define menu_default 2 /* seg:ofs */ >+#define menu_ent_list 6 /* seg:ofs */ >+#define menu_ent_size 10 >+#define menu_arg_list 12 /* seg:ofs */ >+#define menu_arg_size 16 >+#define sizeof_menu_desc 18 >+ >+ENTRY(gfx_setup_menu) >+ pushl %ebp >+ movl %esp, %ebp >+ >+ pushl %edi >+ pushl %esi >+ pushl %ebx >+ >+ movl 8(%ebp),%edx >+ movl %edx,%ebx >+ andl $0xf,%ebx >+ shrl $4,%edx >+ >+ call EXT_C(prot_to_real) >+ .code16 >+ >+ pushw %ds >+ >+ movw %dx,%ds >+ shll $4,%edx >+ >+ subw $sizeof_menu_desc,%sp >+ movw %esp,%ebp >+ >+ movl gfx_ofs_menu_entries(%bx),%eax >+ movw %ax,menu_entries(%bp) >+ >+ movl gfx_ofs_menu_default_entry(%bx),%eax >+ subl %edx,%eax >+ movw %ax,menu_default(%bp) >+ movw %ds,menu_default+2(%bp) >+ >+ movl gfx_ofs_menu_list(%bx),%eax >+ subl %edx,%eax >+ movw %ax,menu_ent_list(%bp) >+ movw %ds,menu_ent_list+2(%bp) >+ >+ movl gfx_ofs_menu_entry_len(%bx),%eax >+ movw %ax,menu_ent_size(%bp) >+ >+ movl gfx_ofs_args_list(%bx),%eax >+ subl %edx,%eax >+ movw %ax,menu_arg_list(%bp) >+ movw %ds,menu_arg_list+2(%bp) >+ >+ movl gfx_ofs_args_entry_len(%bx),%eax >+ movw %ax,menu_arg_size(%bp) >+ >+ movl %ss,%esi >+ shll $4,%esi >+ addl %ebp,%esi >+ >+ lcall %ds: *gfx_ofs_jmp_table + 4 * 3 (%bx) >+ >+ addw $sizeof_menu_desc,%sp >+ >+ popw %ds >+ >+ DATA32 call EXT_C(real_to_prot) >+ .code32 >+ >+ xorl %eax,%eax >+ >+ popl %ebx >+ popl %esi >+ popl %edi >+ >+ popl %ebp >+ ret >+ >+ >+/* >+ * >+ * end graphics stuff >+ * >+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - >+ */ >+ > > /* > * 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. :-( >+ * Try to disable the A20 gate by all means. (The argument is ignored) >+ * On success (the memory world is free), a -1 is returned, 0 on failure. >+ * It may also eat any keystrokes in the keyboard buffer. :-( > */ > > ENTRY(gateA20) >+ pushl %ebx >+ pushl %edx >+ call testA20 >+ jnz 1f >+ call A20_BIOS >+ call testA20 >+ jnz 1f >+ call A20_PORT92 >+ call testA20 >+ jnz 1f >+ call A20_KBDCTL >+ call testA20 >+ jnz 1f >+ movl $0,%eax >+ jmp 2f >+1: movl $-1,%eax >+2: popl %edx >+ popl %ebx >+ ret >+ >+testA20: >+ movl 0x500,%eax >+ movl 0x100500,%ebx >+ notl %eax >+ movl %eax,0x100500 >+ cmpl %eax,0x500 >+ pushfl >+ movl %ebx,0x100500 >+ notl %eax >+ movl %eax,0x500 >+ popfl >+ ret >+ >+A20_BIOS: > /* 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 >+ movw $0x2401, %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 */ >+ >+A20_PORT92: >+ /* >+ * try to switch gateA20 using PORT92, the "Fast A20 and Init" >+ * register >+ */ >+ mov $0x92, %dx >+ inb %dx, %al >+ /* skip the port92 code if it's unimplemented (read returns 0xff) */ >+ cmpb $0xff, %al >+ jz 6f >+ >+ /* set bit1, the ALT_A20_GATE bit */ >+ orb $2, %al >+/* and $0xfd, %al */ >+ >+ /* clear the INIT_NOW bit; don't accidently reset the machine */ >+ and $0xfe, %al >+ outb %al, %dx >+6: ret >+ >+ >+A20_KBDCTL: >+ /* use keyboard controller */ > pushl %eax > > call gloop1 >@@ -1665,11 +1990,7 @@ gloopint1: > jnz gloopint1 > > movb $KB_OUTPUT_MASK, %al >- cmpb $0, 0x8(%esp) >- jz gdoit >- > orb $KB_A20_ENABLE, %al >-gdoit: > outb $K_RDWR > > call gloop1 >diff --git a/stage2/boot.c b/stage2/boot.c >index 4185d23..4616572 100644 >--- a/stage2/boot.c >+++ b/stage2/boot.c >@@ -824,8 +824,11 @@ load_initrd (char *initrd) > moveto = (mbi.mem_upper + 0x400) << 10; > > moveto = (moveto - len) & 0xfffff000; >- max_addr = (lh->header == LINUX_MAGIC_SIGNATURE && lh->version >= 0x0203 >- ? lh->initrd_addr_max : LINUX_INITRD_MAX_ADDRESS); >+ max_addr = LINUX_INITRD_MAX_ADDRESS; >+ if (lh->header == LINUX_MAGIC_SIGNATURE && >+ lh->version >= 0x0203 && >+ lh->initrd_addr_max < max_addr) >+ max_addr = lh->initrd_addr_max; > if (moveto + len >= max_addr) > moveto = (max_addr - len) & 0xfffff000; > >diff --git a/stage2/builtins.c b/stage2/builtins.c >index 3e08a86..4761af4 100644 >--- a/stage2/builtins.c >+++ b/stage2/builtins.c >@@ -63,6 +63,8 @@ int fallback_entryno; > int fallback_entries[MAX_FALLBACK_ENTRIES]; > /* The number of current entry. */ > int current_entryno; >+/* graphics file */ >+char graphics_file[64]; > /* The address for Multiboot command-line buffer. */ > static char *mb_cmdline; > /* The password. */ >@@ -455,6 +457,10 @@ chainloader_func (char *arg, int flags) > *((unsigned long *) (BOOTSEC_LOCATION + BOOTSEC_BPB_HIDDEN_SECTORS)) > = part_start; > >+ /* if a new device was specified, make sure DX is passed correctly */ >+ if ('(' == *file) >+ set_device(file); >+ > errnum = ERR_NONE; > > return 0; >@@ -766,11 +772,11 @@ static int > default_func (char *arg, int flags) > { > #ifndef SUPPORT_DISKLESS >- if (grub_strcmp (arg, "saved") == 0) >+ if (grub_strcmp (arg, "saved") == 0 || (saved_entryno & 0x4000)) > { >- default_entry = saved_entryno; >- return 0; >+ default_entry = saved_entryno & 0x3fff; > } >+ else > #endif /* SUPPORT_DISKLESS */ > > if (! safe_parse_maxint (&arg, &default_entry)) >@@ -791,6 +797,22 @@ static struct builtin builtin_default = > #endif > }; > >+#ifndef SUPPORT_DISKLESS >+static int savedefault_func (char *arg, int flags); >+void __savedefault_once_reset() >+{ >+ if (saved_entryno & 0x4000) >+ { >+ int saved_current_entryno = current_entryno; >+ grub_timeout = 0; >+ current_entryno = default_entry; >+ savedefault_func("\0", BUILTIN_SCRIPT); >+ current_entryno = saved_current_entryno; >+ saved_entryno &= 0x3fff; >+ } >+} >+#endif /* SUPPORT_DISKLESS */ >+ > > #ifdef GRUB_UTIL > /* device */ >@@ -1331,6 +1353,26 @@ static struct builtin builtin_fstest = > }; > > >+/* graphics */ >+static int >+gfxmenu_func (char *arg, int flags) >+{ >+ memmove(graphics_file, arg, sizeof graphics_file - 1); >+ graphics_file[sizeof graphics_file - 1] = 0; >+ >+ return 0; >+} >+ >+static struct builtin builtin_gfxmenu = >+{ >+ "gfxmenu", >+ gfxmenu_func, >+ BUILTIN_MENU | BUILTIN_HELP_LIST, >+ "gfxmenu FILE", >+ "Use the graphical menu from FILE." >+}; >+ >+ > /* geometry */ > static int > geometry_func (char *arg, int flags) >@@ -1834,7 +1876,12 @@ install_func (char *arg, int flags) > /* First, check the GNU-style long option. */ > while (1) > { >- if (grub_memcmp ("--force-lba", arg, sizeof ("--force-lba") - 1) == 0) >+ if (grub_memcmp ("--force-lba=off", arg, sizeof ("--force-lba=off") - 1) == 0) >+ { >+ is_force_lba = 0xff; >+ arg = skip_to (0, arg); >+ } >+ else if (grub_memcmp ("--force-lba", arg, sizeof ("--force-lba") - 1) == 0) > { > is_force_lba = 1; > arg = skip_to (0, arg); >@@ -1842,9 +1889,23 @@ install_func (char *arg, int flags) > #ifdef GRUB_UTIL > else if (grub_memcmp ("--stage2=", arg, sizeof ("--stage2=") - 1) == 0) > { >+ int fd; > stage2_os_file = arg + sizeof ("--stage2=") - 1; > arg = skip_to (0, arg); > nul_terminate (stage2_os_file); >+ >+#if defined(__linux__) && defined (FSYS_REISERFS) >+ if ((fd=open(stage2_os_file, O_RDONLY)) >= 0) >+ { >+ struct statfs buf; >+ /* see if the file sits on a reiserfs, >+ and try do defragment it if so. */ >+ fstatfs(fd, &buf); >+ if (buf.f_type == REISERFS_SUPER_MAGIC) >+ ioctl (fd, REISERFS_IOC_UNPACK, 1); >+ } >+#endif /* __linux__ && FSYS_REISERFS */ >+ > } > #endif /* GRUB_UTIL */ > else >@@ -2263,7 +2324,7 @@ 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 [--stage2=STAGE2_FILE] [--force-lba[=off]] 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" >@@ -2276,8 +2337,9 @@ static struct builtin builtin_install = > " 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." >+ " for LBA mode, `--force-lba=off' will disable it completely. If the" >+ " option `--stage2' is specified, rewrite the Stage 2 via your OS's" >+ " filesystem instead of the raw device." > }; > > >@@ -3890,7 +3952,12 @@ setup_func (char *arg, int flags) > /* Check if the user specifies --force-lba. */ > while (1) > { >- if (grub_memcmp ("--force-lba", arg, sizeof ("--force-lba") - 1) == 0) >+ if (grub_memcmp ("--force-lba=off", arg, sizeof ("--force-lba=off") - 1) == 0) >+ { >+ is_force_lba = 0xff; >+ arg = skip_to (0, arg); >+ } >+ else if (grub_memcmp ("--force-lba", arg, sizeof ("--force-lba") - 1) == 0) > { > is_force_lba = 1; > arg = skip_to (0, arg); >@@ -4011,6 +4078,9 @@ setup_func (char *arg, int flags) > } > } > >+ /* force buffer cache invalidation after embedding */ >+ buf_drive = -1; >+ > /* Construct a string that is used by the command "install" as its > arguments. */ > sprint_device (installed_drive, installed_partition); >@@ -4018,7 +4088,9 @@ setup_func (char *arg, int flags) > #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 " : "", >+ is_force_lba ? >+ (is_force_lba == 0xff ? "--force-lba=off " : "--force-lba ") >+ : "", > stage2_arg? stage2_arg : "", > stage2_arg? " " : "", > stage1, >@@ -4071,17 +4143,18 @@ 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]", >+ "setup [--prefix=DIR] [--stage2=STAGE2_FILE] [--force-lba[=off]] 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." >+ " doesn't work in LBA mode, specify the option `--force-lba'. If the" >+ " BIOS claims to support LBA mode but really doesn't, use" >+ " `--force-lba=off'. 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." > }; > > >@@ -4186,7 +4259,7 @@ terminal_func (char *arg, int flags) > > /* If multiple terminals are specified, wait until the user pushes any > key on one of the terminals. */ >- if (term_bitmap & ~(1 << default_term)) >+ if ((term_bitmap & ~(1 << default_term)) && !(saved_entryno & 0x4000)) > { > int time1, time2 = -1; > >@@ -4792,6 +4865,49 @@ static struct builtin builtin_vbeprobe = > }; > > >+/* wildcard */ >+ static int >+wildcard_func (char *arg, int flags) >+{ >+#ifdef DEBUG_WILDCARD >+ char *w = wildcard (arg); >+ >+ if (w) >+ { >+ while (*w) >+ { >+ grub_printf("%s ", w); >+ w += strlen (w) + 1; >+ } >+ grub_printf("\n"); >+ return 1; >+ } >+ else >+ print_error(); >+#endif >+ >+ /* This special command is interpreted in the config file parser. */ >+ return 0; >+} >+ >+static struct builtin builtin_wildcard = >+ { >+ "wildcard", >+ wildcard_func, >+#ifndef DEBUG_WILDCARD >+ BUILTIN_MENU, >+#else >+ BUILTIN_CMDLINE | BUILTIN_MENU | BUILTIN_HELP_LIST, >+ "wildcard GLOB", >+ "Declare this menu entry as a wildcard entry. GLOB is a path containing" >+ " one asterisk. All files matching this expression are looked up; the" >+ " menu entry is duplicated for each match with asterisks in other" >+ " commands replaced by the string matching the asterisk in the wildcard" >+ " command." >+#endif >+}; >+ >+ > /* The table of builtin commands. Sorted in dictionary order. */ > struct builtin *builtin_table[] = > { >@@ -4823,6 +4939,7 @@ struct builtin *builtin_table[] = > &builtin_find, > &builtin_fstest, > &builtin_geometry, >+ &builtin_gfxmenu, > &builtin_halt, > &builtin_help, > &builtin_hiddenmenu, >@@ -4880,5 +4997,6 @@ struct builtin *builtin_table[] = > &builtin_unhide, > &builtin_uppermem, > &builtin_vbeprobe, >+ &builtin_wildcard, > 0 > }; >diff --git a/stage2/disk_io.c b/stage2/disk_io.c >index b9bc526..605c213 100644 >--- a/stage2/disk_io.c >+++ b/stage2/disk_io.c >@@ -36,7 +36,6 @@ 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; >@@ -128,7 +127,7 @@ int filepos; > int filemax; > > static inline unsigned long >-log2 (unsigned long word) >+grub_log2 (unsigned long word) > { > asm volatile ("bsfl %1,%0" > : "=r" (word) >@@ -140,7 +139,7 @@ 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); >+ int sector_size_bits = grub_log2 (buf_geom.sector_size); > > if (byte_len <= 0) > return 1; >@@ -163,7 +162,7 @@ rawread (int drive, int sector, int byte_offset, int byte_len, char *buf) > } > buf_drive = drive; > buf_track = -1; >- sector_size_bits = log2 (buf_geom.sector_size); >+ sector_size_bits = grub_log2 (buf_geom.sector_size); > } > > /* Make sure that SECTOR is valid. */ >@@ -1479,7 +1478,7 @@ print_completions (int is_filename, int is_completion) > if (! is_completion) > grub_printf (" Possible files are:"); > >- dir (buf); >+ dir (buf, print_a_completion); > > if (is_completion && *unique_string) > { >@@ -1498,7 +1497,7 @@ print_completions (int is_filename, int is_completion) > *ptr = '/'; > *(ptr + 1) = 0; > >- dir (buf); >+ dir (buf, print_a_completion); > > /* Restore the original unique value. */ > unique = 1; >@@ -1626,12 +1625,7 @@ grub_open (char *filename) > 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)) >+ if (!errnum && (*(fsys_table[fsys_type].dir_func)) (filename, NULL)) > { > #ifndef NO_DECOMPRESSION > return gunzip_test_header (); >@@ -1752,7 +1746,7 @@ grub_seek (int offset) > } > > int >-dir (char *dirname) >+dir (char *dirname, void (*handle)(char *)) > { > #ifndef NO_DECOMPRESSION > compressed_file = 0; >@@ -1761,19 +1755,18 @@ dir (char *dirname) > if (!(dirname = setup_part (dirname))) > return 0; > >+ errnum = 0; > if (*dirname != '/') > errnum = ERR_BAD_FILENAME; >- >- if (fsys_type == NUM_FSYS) >+ else 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); >+ else >+ { >+ fsys_table[fsys_type].dir_func (dirname, handle); >+ if (errnum == ERR_FILE_NOT_FOUND) >+ errnum = 0; >+ } >+ return errnum == 0; > } > #endif /* STAGE1_5 */ > >diff --git a/stage2/filesys.h b/stage2/filesys.h >index bbad8b9..9241103 100644 >--- a/stage2/filesys.h >+++ b/stage2/filesys.h >@@ -24,7 +24,7 @@ > #define FSYS_FFS_NUM 1 > int ffs_mount (void); > int ffs_read (char *buf, int len); >-int ffs_dir (char *dirname); >+int ffs_dir (char *dirname, void (*handle)(char *)); > int ffs_embed (int *start_sector, int needed_sectors); > #else > #define FSYS_FFS_NUM 0 >@@ -34,7 +34,7 @@ int ffs_embed (int *start_sector, int needed_sectors); > #define FSYS_UFS2_NUM 1 > int ufs2_mount (void); > int ufs2_read (char *buf, int len); >-int ufs2_dir (char *dirname); >+int ufs2_dir (char *dirname, void (*handle)(char *)); > int ufs2_embed (int *start_sector, int needed_sectors); > #else > #define FSYS_UFS2_NUM 0 >@@ -44,7 +44,7 @@ int ufs2_embed (int *start_sector, int needed_sectors); > #define FSYS_FAT_NUM 1 > int fat_mount (void); > int fat_read (char *buf, int len); >-int fat_dir (char *dirname); >+int fat_dir (char *dirname, void (*handle)(char *)); > #else > #define FSYS_FAT_NUM 0 > #endif >@@ -53,7 +53,7 @@ int fat_dir (char *dirname); > #define FSYS_EXT2FS_NUM 1 > int ext2fs_mount (void); > int ext2fs_read (char *buf, int len); >-int ext2fs_dir (char *dirname); >+int ext2fs_dir (char *dirname, void (*handle)(char *)); > #else > #define FSYS_EXT2FS_NUM 0 > #endif >@@ -62,7 +62,7 @@ int ext2fs_dir (char *dirname); > #define FSYS_MINIX_NUM 1 > int minix_mount (void); > int minix_read (char *buf, int len); >-int minix_dir (char *dirname); >+int minix_dir (char *dirname, void (*handle)(char *)); > #else > #define FSYS_MINIX_NUM 0 > #endif >@@ -71,8 +71,18 @@ int minix_dir (char *dirname); > #define FSYS_REISERFS_NUM 1 > int reiserfs_mount (void); > int reiserfs_read (char *buf, int len); >-int reiserfs_dir (char *dirname); >+int reiserfs_dir (char *dirname, void (*handle)(char *)); > int reiserfs_embed (int *start_sector, int needed_sectors); >+#if defined(__linux__) && defined (GRUB_UTIL) >+#include <sys/types.h> >+#include <sys/stat.h> >+#include <sys/ioctl.h> >+#include <sys/statfs.h> >+#include <fcntl.h> >+/* from <linux/reiserfs_fs.h> */ >+#define REISERFS_SUPER_MAGIC 0x52654973 >+#define REISERFS_IOC_UNPACK _IOW(0xCD,1,long) >+#endif > #else > #define FSYS_REISERFS_NUM 0 > #endif >@@ -81,7 +91,7 @@ int reiserfs_embed (int *start_sector, int needed_sectors); > #define FSYS_VSTAFS_NUM 1 > int vstafs_mount (void); > int vstafs_read (char *buf, int len); >-int vstafs_dir (char *dirname); >+int vstafs_dir (char *dirname, void (*handle)(char *)); > #else > #define FSYS_VSTAFS_NUM 0 > #endif >@@ -90,7 +100,7 @@ int vstafs_dir (char *dirname); > #define FSYS_JFS_NUM 1 > int jfs_mount (void); > int jfs_read (char *buf, int len); >-int jfs_dir (char *dirname); >+int jfs_dir (char *dirname, void (*handle)(char *)); > int jfs_embed (int *start_sector, int needed_sectors); > #else > #define FSYS_JFS_NUM 0 >@@ -100,7 +110,7 @@ int jfs_embed (int *start_sector, int needed_sectors); > #define FSYS_XFS_NUM 1 > int xfs_mount (void); > int xfs_read (char *buf, int len); >-int xfs_dir (char *dirname); >+int xfs_dir (char *dirname, void (*handle)(char *)); > #else > #define FSYS_XFS_NUM 0 > #endif >@@ -109,7 +119,7 @@ int xfs_dir (char *dirname); > #define FSYS_TFTP_NUM 1 > int tftp_mount (void); > int tftp_read (char *buf, int len); >-int tftp_dir (char *dirname); >+int tftp_dir (char *dirname, void (*handle)(char *)); > void tftp_close (void); > #else > #define FSYS_TFTP_NUM 0 >@@ -119,7 +129,7 @@ void tftp_close (void); > #define FSYS_ISO9660_NUM 1 > int iso9660_mount (void); > int iso9660_read (char *buf, int len); >-int iso9660_dir (char *dirname); >+int iso9660_dir (char *dirname, void (*handle)(char *)); > #else > #define FSYS_ISO9660_NUM 0 > #endif >@@ -150,16 +160,10 @@ struct fsys_entry > char *name; > int (*mount_func) (void); > int (*read_func) (char *buf, int len); >- int (*dir_func) (char *dirname); >+ int (*dir_func) (char *dirname, void (*print_one)(char *)); > void (*close_func) (void); > int (*embed_func) (int *start_sector, int needed_sectors); > }; > >-#ifdef STAGE1_5 >-# define print_possibilities 0 >-#else >-extern int print_possibilities; >-#endif >- > extern int fsmax; > extern struct fsys_entry fsys_table[NUM_FSYS + 1]; >diff --git a/stage2/fsys_ext2fs.c b/stage2/fsys_ext2fs.c >index 560048f..6d46f8f 100644 >--- a/stage2/fsys_ext2fs.c >+++ b/stage2/fsys_ext2fs.c >@@ -193,7 +193,7 @@ struct ext2_dir_entry > > > /* ext2/super.c */ >-#define log2(n) ffz(~(n)) >+#define grub_log2(n) ffz(~(n)) > > #define EXT2_SUPER_MAGIC 0xEF53 /* include/linux/ext2_fs.h */ > #define EXT2_ROOT_INO 2 /* include/linux/ext2_fs.h */ >@@ -216,7 +216,7 @@ struct ext2_dir_entry > > /* 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))) >+#define EXT2_ADDR_PER_BLOCK_BITS(s) (grub_log2(EXT2_ADDR_PER_BLOCK(s))) > > /* linux/ext2_fs.h */ > #define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) >@@ -257,6 +257,8 @@ ext2fs_mount (void) > if ((((current_drive & 0x80) || (current_slice != 0)) > && (current_slice != PC_SLICE_TYPE_EXT2FS) > && (current_slice != PC_SLICE_TYPE_LINUX_RAID) >+ && (current_slice != PC_SLICE_TYPE_ZEN) >+ && (current_slice != PC_SLICE_TYPE_ZEN_DISABLED) > && (! 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)) >@@ -495,7 +497,7 @@ int ext2_is_fast_symlink (void) > * side effects: messes up GROUP_DESC buffer area > */ > int >-ext2fs_dir (char *dirname) >+ext2fs_dir (char *dirname, void (*handle)(char *)) > { > int current_ino = EXT2_ROOT_INO; /* start at the root */ > int updir_ino = current_ino; /* the parent of the current directory */ >@@ -521,7 +523,6 @@ ext2fs_dir (char *dirname) > #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 >@@ -537,7 +538,7 @@ ext2fs_dir (char *dirname) > > /* look up an inode */ > group_id = (current_ino - 1) / (SUPERBLOCK->s_inodes_per_group); >- group_desc = group_id >> log2 (EXT2_DESC_PER_BLOCK (SUPERBLOCK)); >+ group_desc = group_id >> grub_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, >@@ -553,7 +554,7 @@ ext2fs_dir (char *dirname) > 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))); >+ >> grub_log2 (EXT2_BLOCK_SIZE (SUPERBLOCK) / sizeof (struct ext2_inode))); > #ifdef E2DEBUG > printf ("inode table fsblock=%d\n", ino_blk); > #endif /* E2DEBUG */ >@@ -713,18 +714,9 @@ ext2fs_dir (char *dirname) > 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); >+ errnum = ERR_FILE_NOT_FOUND; >+ *rest = ch; >+ return 0; > } > > /* else, find the (logical) block component of our location */ >@@ -765,20 +757,15 @@ ext2fs_dir (char *dirname) > 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); >- } >+ if (handle && ch != '/' && (!*dirname || str_chk <= 0)) >+ handle (dp->name); > # endif > > dp->name[dp->name_len] = saved_c; > } > > } >- while (!dp->inode || (str_chk || (print_possibilities && ch != '/'))); >+ while (!dp->inode || (str_chk || (handle && ch != '/'))); > > current_ino = dp->inode; > *(dirname = rest) = ch; >diff --git a/stage2/fsys_fat.c b/stage2/fsys_fat.c >index f40e658..1a62fcf 100644 >--- a/stage2/fsys_fat.c >+++ b/stage2/fsys_fat.c >@@ -55,7 +55,7 @@ struct fat_superblock > #define FAT_CACHE_SIZE 2048 > > static __inline__ unsigned long >-log2 (unsigned long word) >+grub_log2 (unsigned long word) > { > __asm__ ("bsfl %1,%0" > : "=r" (word) >@@ -84,9 +84,9 @@ fat_mount (void) > if (bpb.sects_per_clust == 0) > return 0; > >- FAT_SUPER->sectsize_bits = log2 (FAT_CVT_U16 (bpb.bytes_per_sect)); >+ FAT_SUPER->sectsize_bits = grub_log2 (FAT_CVT_U16 (bpb.bytes_per_sect)); > FAT_SUPER->clustsize_bits >- = FAT_SUPER->sectsize_bits + log2 (bpb.sects_per_clust); >+ = FAT_SUPER->sectsize_bits + grub_log2 (bpb.sects_per_clust); > > /* Fill in info about super block */ > FAT_SUPER->num_sectors = FAT_CVT_U16 (bpb.short_sectors) >@@ -289,7 +289,7 @@ fat_read (char *buf, int len) > } > > int >-fat_dir (char *dirname) >+fat_dir (char *dirname, void (*handle)(char *)) > { > char *rest, ch, dir_buf[FAT_DIRENTRY_LENGTH]; > char *filename = (char *) NAME_BUF; >@@ -345,7 +345,7 @@ fat_dir (char *dirname) > *rest = 0; > > # ifndef STAGE1_5 >- if (print_possibilities && ch != '/') >+ if (handle && ch != '/') > do_possibilities = 1; > # endif > >@@ -356,16 +356,6 @@ fat_dir (char *dirname) > { > 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; > } >@@ -460,11 +450,7 @@ fat_dir (char *dirname) > { > print_filename: > if (substring (dirname, filename) <= 0) >- { >- if (print_possibilities > 0) >- print_possibilities = -print_possibilities; >- print_a_completion (filename); >- } >+ handle (filename); > continue; > } > # endif /* STAGE1_5 */ >diff --git a/stage2/fsys_ffs.c b/stage2/fsys_ffs.c >index 6e2300f..c0d0fa6 100644 >--- a/stage2/fsys_ffs.c >+++ b/stage2/fsys_ffs.c >@@ -180,7 +180,7 @@ ffs_read (char *buf, int len) > > > int >-ffs_dir (char *dirname) >+ffs_dir (char *dirname, void (*handle)(char *)) > { > char *rest, ch; > int block, off, loc, map, ino = ROOTINO; >@@ -236,13 +236,6 @@ loop: > { > 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; >@@ -267,18 +260,13 @@ loop: > loc += dp->d_reclen; > > #ifndef STAGE1_5 >- if (dp->d_ino && print_possibilities && ch != '/' >+ if (dp->d_ino && handle && ch != '/' > && (!*dirname || substring (dirname, dp->d_name) <= 0)) >- { >- if (print_possibilities > 0) >- print_possibilities = -print_possibilities; >- >- print_a_completion (dp->d_name); >- } >+ handle (dp->d_name); > #endif /* STAGE1_5 */ > } > while (!dp->d_ino || (substring (dirname, dp->d_name) != 0 >- || (print_possibilities && ch != '/'))); >+ || (handle && ch != '/'))); > > /* only get here if we have a matching directory entry */ > >diff --git a/stage2/fsys_iso9660.c b/stage2/fsys_iso9660.c >index 90e4aa8..e314f28 100644 >--- a/stage2/fsys_iso9660.c >+++ b/stage2/fsys_iso9660.c >@@ -57,7 +57,7 @@ struct iso_inode_info { > > > static inline unsigned long >-log2 (unsigned long word) >+grub_log2 (unsigned long word) > { > asm volatile ("bsfl %1,%0" > : "=r" (word) >@@ -68,7 +68,7 @@ log2 (unsigned long 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); >+ unsigned short sector_size_lg2 = grub_log2(buf_geom.sector_size); > > /* > * We have to use own devread() function since BIOS return wrong geometry >@@ -133,7 +133,7 @@ iso9660_mount (void) > } > > int >-iso9660_dir (char *dirname) >+iso9660_dir (char *dirname, void (*handle)(char *)) > { > struct iso_directory_record *idr; > RR_ptr_t rr_ptr; >@@ -346,7 +346,7 @@ iso9660_dir (char *dirname) > if (name_len >= pathlen > && !memcmp(name, dirname, pathlen)) > { >- if (dirname[pathlen] == '/' || !print_possibilities) >+ if (dirname[pathlen] == '/' || !handle) > { > /* > * DIRNAME is directory component of pathname, >@@ -377,11 +377,9 @@ iso9660_dir (char *dirname) > 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); >+ handle (NAME_BUF); > #endif > } > } >@@ -390,7 +388,7 @@ iso9660_dir (char *dirname) > size -= ISO_SECTOR_SIZE; > } /* size>0 */ > >- if (dirname[pathlen] == '/' || print_possibilities >= 0) >+ if (dirname[pathlen] == '/' || handle) > { > errnum = ERR_FILE_NOT_FOUND; > return 0; >diff --git a/stage2/fsys_jfs.c b/stage2/fsys_jfs.c >index 307f836..1619d29 100644 >--- a/stage2/fsys_jfs.c >+++ b/stage2/fsys_jfs.c >@@ -270,7 +270,7 @@ jfs_read (char *buf, int len) > } > > int >-jfs_dir (char *dirname) >+jfs_dir (char *dirname, void (*handle)(char *)) > { > char *ptr, *rest, ch; > ldtentry_t *de; >@@ -357,12 +357,9 @@ jfs_dir (char *dirname) > > 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 >+ if (handle && ch != '/' && cmp <= 0) >+ handle (namebuf); >+ else > #endif > if (cmp == 0) { > parent_inum = inum; >@@ -372,9 +369,6 @@ jfs_dir (char *dirname) > } > de = next_dentry (); > if (de == NULL) { >- if (print_possibilities < 0) >- return 1; >- > errnum = ERR_FILE_NOT_FOUND; > *rest = ch; > return 0; >diff --git a/stage2/fsys_minix.c b/stage2/fsys_minix.c >index 5c76796..b86b2b4 100644 >--- a/stage2/fsys_minix.c >+++ b/stage2/fsys_minix.c >@@ -294,7 +294,7 @@ minix_read (char *buf, int len) > inode of the file we were trying to look up > side effects: none yet */ > int >-minix_dir (char *dirname) >+minix_dir (char *dirname, void (*handle)(char *)) > { > int current_ino = MINIX_ROOT_INO; /* start at the root */ > int updir_ino = current_ino; /* the parent of the current directory */ >@@ -457,18 +457,9 @@ minix_dir (char *dirname) > 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); >+ errnum = ERR_FILE_NOT_FOUND; >+ *rest = ch; >+ return 0; > } > > /* else, find the (logical) block component of our location */ >@@ -510,20 +501,15 @@ minix_dir (char *dirname) > 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); >- } >+ if (handle && ch != '/' && (!*dirname || str_chk <= 0)) >+ handle (dp->name); > # endif > > dp->name[namelen] = saved_c; > } > > } >- while (!dp->inode || (str_chk || (print_possibilities && ch != '/'))); >+ while (!dp->inode || (str_chk || (handle && ch != '/'))); > > current_ino = dp->inode; > *(dirname = rest) = ch; >diff --git a/stage2/fsys_reiserfs.c b/stage2/fsys_reiserfs.c >index 93ec5f8..7a6f8fc 100644 >--- a/stage2/fsys_reiserfs.c >+++ b/stage2/fsys_reiserfs.c >@@ -367,7 +367,7 @@ struct fsys_reiser_info > > > static __inline__ unsigned long >-log2 (unsigned long word) >+grub_log2 (unsigned long word) > { > __asm__ ("bsfl %1,%0" > : "=r" (word) >@@ -609,7 +609,7 @@ reiserfs_mount (void) > > INFO->version = super.s_version; > INFO->blocksize = super.s_blocksize; >- INFO->fullblocksize_shift = log2 (super.s_blocksize); >+ INFO->fullblocksize_shift = grub_log2 (super.s_blocksize); > INFO->blocksize_shift = INFO->fullblocksize_shift - SECTOR_BITS; > INFO->cached_slots = > (FSYSREISER_CACHE_SIZE >> INFO->fullblocksize_shift) - 1; >@@ -991,7 +991,7 @@ reiserfs_read (char *buf, int len) > * the size of the file. > */ > int >-reiserfs_dir (char *dirname) >+reiserfs_dir (char *dirname, void (*handle)(char *)) > { > struct reiserfs_de_head *de_head; > char *rest, ch; >@@ -1123,7 +1123,7 @@ reiserfs_dir (char *dirname) > *rest = 0; > > # ifndef STAGE1_5 >- if (print_possibilities && ch != '/') >+ if (handle && ch != '/') > do_possibilities = 1; > # endif /* ! STAGE1_5 */ > >@@ -1170,10 +1170,8 @@ reiserfs_dir (char *dirname) > { > if (cmp <= 0) > { >- if (print_possibilities > 0) >- print_possibilities = -print_possibilities; > *name_end = 0; >- print_a_completion (filename); >+ handle (filename); > *name_end = tmp; > } > } >@@ -1189,12 +1187,6 @@ reiserfs_dir (char *dirname) > num_entries--; > } > } >- >-# ifndef STAGE1_5 >- if (print_possibilities < 0) >- return 1; >-# endif /* ! STAGE1_5 */ >- > errnum = ERR_FILE_NOT_FOUND; > *rest = ch; > return 0; >diff --git a/stage2/fsys_ufs2.c b/stage2/fsys_ufs2.c >index 3b64313..ffb8a79 100644 >--- a/stage2/fsys_ufs2.c >+++ b/stage2/fsys_ufs2.c >@@ -204,7 +204,7 @@ ufs2_read (char *buf, int len) > } > > int >-ufs2_dir (char *dirname) >+ufs2_dir (char *dirname, void (*handle)(char *)) > { > char *rest, ch; > int block, off, loc, ino = ROOTINO; >@@ -261,9 +261,6 @@ loop: > { > if (loc >= INODE_UFS2->di_size) > { >- if (print_possibilities < 0) >- return 1; >- > errnum = ERR_FILE_NOT_FOUND; > *rest = ch; > return 0; >@@ -288,18 +285,13 @@ loop: > loc += dp->d_reclen; > > #ifndef STAGE1_5 >- if (dp->d_ino && print_possibilities && ch != '/' >+ if (dp->d_ino && handle && ch != '/' > && (!*dirname || substring (dirname, dp->d_name) <= 0)) >- { >- if (print_possibilities > 0) >- print_possibilities = -print_possibilities; >- >- print_a_completion (dp->d_name); >- } >+ handle (dp->d_name); > #endif /* STAGE1_5 */ > } > while (!dp->d_ino || (substring (dirname, dp->d_name) != 0 >- || (print_possibilities && ch != '/'))); >+ || (handle && ch != '/'))); > > /* only get here if we have a matching directory entry */ > >diff --git a/stage2/fsys_vstafs.c b/stage2/fsys_vstafs.c >index a116717..834849b 100644 >--- a/stage2/fsys_vstafs.c >+++ b/stage2/fsys_vstafs.c >@@ -115,7 +115,7 @@ vstafs_nextdir (void) > } > > int >-vstafs_dir (char *dirname) >+vstafs_dir (char *dirname, void (*handle)(char *)) > { > char *fn, ch; > struct dir_entry *d; >@@ -146,14 +146,9 @@ vstafs_dir (char *dirname) > continue; > > #ifndef STAGE1_5 >- if (print_possibilities && ch != '/' >+ if (handle && ch != '/' > && (! *dirname || strcmp (dirname, d->name) <= 0)) >- { >- if (print_possibilities > 0) >- print_possibilities = -print_possibilities; >- >- printf (" %s", d->name); >- } >+ handle(d->name); > #endif > if (! grub_strcmp (dirname, d->name)) > { >@@ -168,12 +163,6 @@ vstafs_dir (char *dirname) > *(dirname = fn) = ch; > if (! d) > { >- if (print_possibilities < 0) >- { >- putchar ('\n'); >- return 1; >- } >- > errnum = ERR_FILE_NOT_FOUND; > return 0; > } >diff --git a/stage2/fsys_xfs.c b/stage2/fsys_xfs.c >index 76c4c13..266fcaa 100644 >--- a/stage2/fsys_xfs.c >+++ b/stage2/fsys_xfs.c >@@ -534,7 +534,7 @@ xfs_read (char *buf, int len) > } > > int >-xfs_dir (char *dirname) >+xfs_dir (char *dirname, void (*handle)(char *)) > { > xfs_ino_t ino, parent_ino, new_ino; > xfs_fsize_t di_size; >@@ -595,11 +595,9 @@ xfs_dir (char *dirname) > 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 >+ if (handle && ch != '/' && cmp <= 0) >+ handle (name); >+ else > #endif > if (cmp == 0) { > parent_ino = ino; >@@ -610,9 +608,6 @@ xfs_dir (char *dirname) > } > name = next_dentry (&new_ino); > if (name == NULL) { >- if (print_possibilities < 0) >- return 1; >- > errnum = ERR_FILE_NOT_FOUND; > *rest = ch; > return 0; >diff --git a/stage2/iso9660.h b/stage2/iso9660.h >index 4a6a8cc..c311ecf 100644 >--- a/stage2/iso9660.h >+++ b/stage2/iso9660.h >@@ -73,11 +73,11 @@ typedef union { > > typedef struct __iso_16bit { > u_int16_t l, b; >-} iso_16bit_t __attribute__ ((packed)); >+} iso_16bit_t; > > typedef struct __iso_32bit { > u_int32_t l, b; >-} iso_32bit_t __attribute__ ((packed)); >+} iso_32bit_t; > > typedef u_int8_t iso_date_t[7]; > >diff --git a/stage2/pc_slice.h b/stage2/pc_slice.h >index a38d97f..9fb0df8 100644 >--- a/stage2/pc_slice.h >+++ b/stage2/pc_slice.h >@@ -114,6 +114,8 @@ > #define PC_SLICE_TYPE_EXT2FS 0x83 > #define PC_SLICE_TYPE_LINUX_EXTENDED 0x85 > #define PC_SLICE_TYPE_VSTAFS 0x9e >+#define PC_SLICE_TYPE_ZEN 0xbc >+#define PC_SLICE_TYPE_ZEN_DISABLED 0xbd > #define PC_SLICE_TYPE_DELL_UTIL 0xde > #define PC_SLICE_TYPE_LINUX_RAID 0xfd > >diff --git a/stage2/shared.h b/stage2/shared.h >index 77eef11..4dea4b7 100644 >--- a/stage2/shared.h >+++ b/stage2/shared.h >@@ -174,8 +174,8 @@ extern char *grub_scratch_mem; > > #define BOOTSEC_LOCATION RAW_ADDR (0x7C00) > #define BOOTSEC_SIGNATURE 0xAA55 >-#define BOOTSEC_BPB_OFFSET 0x3 >-#define BOOTSEC_BPB_LENGTH 0x3B >+#define BOOTSEC_BPB_OFFSET 0xA >+#define BOOTSEC_BPB_LENGTH 0x34 > #define BOOTSEC_BPB_SYSTEM_ID 0x3 > #define BOOTSEC_BPB_HIDDEN_SECTORS 0x1C > #define BOOTSEC_PART_OFFSET 0x1BE >@@ -374,6 +374,22 @@ extern char *grub_scratch_mem; > #endif /* WITHOUT_LIBC_STUBS */ > > >+/* see typedef gfx_data_t below */ >+#define gfx_ofs_ok 0x00 >+#define gfx_ofs_code_seg 0x04 >+#define gfx_ofs_jmp_table 0x08 >+#define gfx_ofs_sys_cfg 0x38 >+#define gfx_ofs_cmdline 0x6c >+#define gfx_ofs_cmdline_len 0x70 >+#define gfx_ofs_menu_list 0x74 >+#define gfx_ofs_menu_default_entry 0x78 >+#define gfx_ofs_menu_entries 0x7c >+#define gfx_ofs_menu_entry_len 0x80 >+#define gfx_ofs_args_list 0x84 >+#define gfx_ofs_args_entry_len 0x88 >+#define gfx_ofs_timeout 0x8c >+ >+ > #ifndef ASM_FILE > /* > * Below this should be ONLY defines and other constructs for C code. >@@ -595,6 +611,38 @@ extern int fallback_entryno; > extern int default_entry; > extern int current_entryno; > >+ >+/* >+ * graphics menu stuff >+ * >+ * Note: gfx_data and all data referred to in it must lie within a 64k area. >+ */ >+typedef struct { >+ unsigned ok; /* set while we're in graphics mode */ >+ unsigned code_seg; /* code segment of binary graphics code */ >+ unsigned jmp_table[12]; /* link to graphics functions */ >+ unsigned char sys_cfg[52]; /* sys_cfg[0]: identifies boot loader (grub == 2) */ >+ char *cmdline; /* command line returned by gfx_input() */ >+ unsigned cmdline_len; /* length of the above */ >+ char *menu_list; /* list of menu entries, each of fixed length (menu_entry_len) */ >+ char *menu_default_entry; /* the default entry */ >+ unsigned menu_entries; /* number of entries in menu_list */ >+ unsigned menu_entry_len; /* one entry */ >+ char *args_list; /* same structure as menu_list, menu_entries entries */ >+ unsigned args_entry_len; /* one entry */ >+ unsigned timeout; /* in seconds (0: no timeout) */ >+} __attribute__ ((packed)) gfx_data_t; >+ >+extern gfx_data_t *graphics_data; >+ >+/* pointer to graphics image data */ >+extern char graphics_file[64]; >+ >+int gfx_init(gfx_data_t *gfx_data); >+int gfx_done(gfx_data_t *gfx_data); >+int gfx_input(gfx_data_t *gfx_data, int *menu_entry); >+int gfx_setup_menu(gfx_data_t *gfx_data); >+ > /* The constants for password types. */ > typedef enum > { >@@ -956,9 +1004,11 @@ 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); >+/* List the contents of DIRECTORY. */ >+int dir (char *dirname, void (*handle)(char *)); >+ >+/* Wildcard expand the last pathname component of GLOB. */ >+char *wildcard (char *glob, int *len); > > int set_bootdev (int hdbias); > >diff --git a/stage2/stage2.c b/stage2/stage2.c >index 4dbf6f5..128c044 100644 >--- a/stage2/stage2.c >+++ b/stage2/stage2.c >@@ -22,6 +22,8 @@ > > grub_jmp_buf restart_env; > >+gfx_data_t *graphics_data; >+ > #if defined(PRESET_MENU_STRING) || defined(SUPPORT_DISKLESS) > > # if defined(PRESET_MENU_STRING) >@@ -234,6 +236,8 @@ run_menu (char *menu_entries, char *config_entries, int num_entries, > int c, time1, time2 = -1, first_entry = 0; > char *cur_entry = 0; > >+ cls(); >+ > /* > * Main loop for menu UI. > */ >@@ -261,14 +265,16 @@ restart: > /* Get current time. */ > while ((time1 = getrtsecs ()) == 0xFF) > ; >+ grub_printf("\rPress any key to enter the menu\n\n\n"); > > while (1) > { > /* Check if ESC is pressed. */ >- if (checkkey () != -1 && ASCII_CHAR (getkey ()) == '\e') >+ if (checkkey () != -1) > { > grub_timeout = -1; > show_menu = 1; >+ getkey (); > break; > } > >@@ -287,7 +293,8 @@ restart: > grub_timeout--; > > /* Print a message. */ >- grub_printf ("\rPress `ESC' to enter the menu... %d ", >+ grub_printf ("\rBooting %s in %d seconds...", >+ get_entry(menu_entries, first_entry + entryno, 0), > grub_timeout); > } > } >@@ -310,6 +317,12 @@ restart: > > if (! auth && password) > { >+ if (*graphics_file) >+ { >+ printf ("\ >+ WARNING: graphical menu doesn\'t work\ >+ in conjunction with the password feature\n" ); >+ } > printf ("\ > Press enter to boot the selected OS or \'p\' to enter a\n\ > password to unlock the next set of features."); >@@ -319,7 +332,8 @@ restart: > 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."); >+ commands before booting, \'a\' to modify the kernel arguments\n\ >+ before booting, or \'c\' for a command-line."); > else > printf ("\ > Press \'b\' to boot, \'e\' to edit the selected command in the\n\ >@@ -697,6 +711,87 @@ restart: > enter_cmdline (heap, 0); > goto restart; > } >+ if (config_entries && c == 'a') >+ { >+ int new_num_entries = 0, i = 0, j; >+ char *new_heap; >+ char * entries; >+ char * entry_copy; >+ char * append_line; >+ char * start; >+ >+ entry_copy = new_heap = heap; >+ cur_entry = get_entry (config_entries, first_entry + entryno, >+ 1); >+ >+ 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; >+ >+ new_heap = heap + NEW_HEAPSIZE + 1; >+ >+ entries = entry_copy; >+ while (*entries) >+ { >+ if ((strstr(entries, "kernel") == entries) && >+ isspace(entries[6])) >+ break; >+ >+ while (*entries) entries++; >+ entries++; >+ } >+ >+ if (!*entries) >+ goto restart; >+ >+ start = entries + 6; >+ >+ /* skip the white space */ >+ while (*start && isspace(*start)) start++; >+ /* skip the kernel name */ >+ while (*start && !isspace(*start)) start++; >+ /* skip the white space */ >+ while (*start && isspace(*start)) start++; >+ >+ append_line = new_heap; >+ grub_strcpy(append_line, start); >+ >+ cls(); >+ print_cmdline_message (0); >+ >+ if (get_cmdline(PACKAGE " append> ", >+ append_line, NEW_HEAPSIZE + 1, >+ 0, 1)) >+ goto restart; >+ >+ /* have new args; append_line points to the >+ new args and start points to the old >+ args */ >+ >+ i = grub_strlen(start); >+ j = grub_strlen(append_line); >+ >+ /* align rest of commands properly */ >+ memmove (start + j, start + i, >+ ((int) append_line) - ((int) start) - (i > j ? i : j)); >+ >+ /* copy command to correct area */ >+ memmove (start, append_line, j); >+ >+ /* set up this entry to boot */ >+ config_entries = NULL; >+ cur_entry = entry_copy; >+ heap = new_heap; >+ >+ break; >+ } > #ifdef GRUB_UTIL > if (c == 'q') > { >@@ -753,6 +848,496 @@ restart: > } > > >+ >+#if 0 >+/* for debugging */ >+static void hexdump(unsigned char *buf, unsigned len) >+{ >+ int i, j = 0; >+ char s[17]; >+ unsigned addr = (unsigned) buf; >+ >+ s[16] = 0; >+ while(len--) { >+ i = buf[j]; >+ i = i & 0xff; >+ s[j & 15] = (i >= 0x20 && i <= 0x7e) ? i : '.'; >+ if(!(j & 15)) { >+ printf("%x ", j + addr); >+ } >+ if(!(j & 7) && (j & 15)) printf(" "); >+ /* stupid grub_printf */ >+ printf("%x", (i >> 4) & 0x0f); >+ printf("%x ", i & 0x0f); >+ if(!(++j & 15)) { >+ printf(" %s\n", s); >+ } >+ } >+ >+ if(j & 15) { >+ s[j & 15] = 0; >+ if(!(j & 8)) printf(" "); >+ i = 1 + 3 * (16 - (j & 15)); >+ while(i--) printf(" "); >+ printf("%s\n", s); >+ } >+} >+#endif >+ >+ >+/* kernel + (grub-)module options */ >+#define GFX_CMD_BUF_SIZE 512 >+ >+/* command line separator char */ >+#define GFX_CMD_SEP 1 >+ >+/* >+ * Go through config entry and find kernel args, if any. >+ * Put things into buf and return it. >+ */ >+static char *get_kernel_args(char *cfg, char *buf) >+{ >+ int i, j; >+ char *s, *t = "", *p, *t2; >+ >+ *(p = buf) = 0; >+ >+ for(j = 0; ; j++) { >+ s = get_entry(cfg, j, 0); >+ if(!*s) break; >+ if( >+ (!memcmp(s, "kernel", 6) || !memcmp(s, "module", 6)) && >+ (s[6] == ' ' || s[6] == '\t') >+ ) { >+ t = skip_to(0, s); >+ t2 = s[0] == 'm' ? strstr(t, "initrd") : NULL; >+ if(*t) t = skip_to(0, t); >+ if(t2 && t2 < t) break; /* module is likely a normal initrd -> skip */ >+ i = strlen(t); >+ if(p - buf + i > GFX_CMD_BUF_SIZE - 2) break; >+ *p++ = GFX_CMD_SEP; >+ strcpy(p, t); >+ p += i; >+ >+ continue; >+ } >+ } >+ >+ if(*buf) buf++; /* skip initial separator char */ >+ >+ return buf; >+} >+ >+ >+/* >+ * Check header and return code start offset. >+ */ >+static unsigned magic_ok(unsigned char *buf) >+{ >+ if( >+ *(unsigned *) buf == 0x0b2d97f00 && /* magic id */ >+ (buf[4] == 8) /* version 8 */ >+ ) { >+ return *(unsigned *) (buf + 8); >+ } >+ >+ return 0; >+} >+ >+ >+/* >+ * Search cpio archive for gfx file. >+ */ >+static unsigned find_file(unsigned char *buf, unsigned len, unsigned *gfx_file_start, unsigned *file_len) >+{ >+ unsigned i, fname_len, code_start = 0; >+ >+ *gfx_file_start = 0; >+ >+ for(i = 0; i < len;) { >+ if((len - i) >= 0x1a && (buf[i] + (buf[i + 1] << 8)) == 0x71c7) { >+ fname_len = *(unsigned short *) (buf + i + 20); >+ *file_len = *(unsigned short *) (buf + i + 24) + (*(unsigned short *) (buf + i + 22) << 16); >+ i += 26 + fname_len; >+ i = ((i + 1) & ~1); >+ if((code_start = magic_ok(buf + i))) { >+ *gfx_file_start = i; >+ return code_start; >+ } >+ i += *file_len; >+ i = ((i + 1) & ~1); >+ } >+ else { >+ break; >+ } >+ } >+ >+ return code_start; >+} >+ >+static inline unsigned char * stack_ptr(void) >+{ >+ unsigned char * u; >+ >+ asm("movl %%esp, %0" : "=r" (u)); >+ >+ return u; >+} >+ >+static void sleep(int delay) >+{ >+ int tick, last_tick = currticks(); >+ >+ delay *= 18; >+ >+ while(delay--) { >+ while((tick = currticks()) == last_tick) { } >+ last_tick = tick; >+ } >+} >+ >+static void wait_for_key() >+{ >+ printf("Press a key to continue..."); >+ getkey(); >+ printf("\r \r"); >+} >+ >+ >+/* >+ * Leave that much space on the heap. Everything else goes to the graphics >+ * functions. >+ * >+ * 0x2000 is _not_ enough >+ */ >+#define MIN_HEAP_SIZE 0x4000 >+#define MIN_GFX_FREE 0x1000 >+ >+#define SC_BOOTLOADER 0 >+#define SC_FAILSAFE 3 >+#define SC_SYSCONFIG_SIZE 4 >+#define SC_BOOTLOADER_SEG 8 >+#define SC_XMEM_0 24 >+#define SC_XMEM_1 26 >+#define SC_XMEM_2 28 >+#define SC_XMEM_3 30 >+#define SC_FILE 32 >+#define SC_ARCHIVE_START 36 >+#define SC_ARCHIVE_END 40 >+#define SC_MEM0_START 44 >+#define SC_MEM0_END 48 >+ >+/* >+ * Does normally not return. >+ */ >+static void >+run_graphics_menu (char *menu_entries, char *config_entries, int num_entries, >+ char *heap, int entryno) >+{ >+ unsigned char *buf, *buf_ext; >+ unsigned buf_size, buf_ext_size, code_start, file_start; >+ char *s, *t, *t2, *cfg, *new_config, *p; >+ char *saved_heap; >+ int i, j, max_len, gfx_file_size, verbose; >+ int selected_entry; >+ gfx_data_t *gfx_data; >+ char *cmd_buf; >+ unsigned mem0_start, mem0_end, file_len; >+ >+ /* >+ * check gfx_data_t struct offsets for consistency; gcc will optimize away >+ * the whole block >+ */ >+ >+ /* dummy function to make ld fail */ >+ { >+ extern void wrong_struct_size(void); >+ #define gfx_ofs_check(a) if(gfx_ofs_##a != (char *) &gfx_data->a - (char *) gfx_data) wrong_struct_size(); >+ gfx_ofs_check(ok); >+ gfx_ofs_check(code_seg); >+ gfx_ofs_check(jmp_table); >+ gfx_ofs_check(sys_cfg); >+ gfx_ofs_check(cmdline); >+ gfx_ofs_check(cmdline_len); >+ gfx_ofs_check(menu_list); >+ gfx_ofs_check(menu_default_entry); >+ gfx_ofs_check(menu_entries); >+ gfx_ofs_check(menu_entry_len); >+ gfx_ofs_check(args_list); >+ gfx_ofs_check(args_entry_len); >+ gfx_ofs_check(timeout); >+ #undef gfx_ofs_check >+ } >+ >+ if(!num_entries) return; >+ >+ graphics_data = gfx_data = (gfx_data_t *) heap; >+ heap += sizeof *gfx_data; >+ memset(gfx_data, 0, sizeof *gfx_data); >+ >+ gfx_data->sys_cfg[SC_BOOTLOADER] = 2; /* bootloader: grub */ >+ gfx_data->sys_cfg[SC_SYSCONFIG_SIZE] = 52; /* config data size */ >+ *(unsigned short *) (gfx_data->sys_cfg + SC_BOOTLOADER_SEG) = (unsigned) gfx_data >> 4; /* segment */ >+ gfx_data->sys_cfg[SC_XMEM_0] = 0x21; /* 1MB @ 2MB */ >+ gfx_data->sys_cfg[SC_XMEM_1] = 0x41; /* 1MB @ 4MB */ >+ verbose = (*(unsigned char *) 0x417) & 3 ? 1 : 0; /* SHIFT pressed */ >+ gfx_data->sys_cfg[SC_FAILSAFE] = verbose; >+ >+ gfx_data->timeout = grub_timeout >= 0 ? grub_timeout : 0; >+ >+ >+ /* setup command line edit buffer */ >+ >+ gfx_data->cmdline_len = 256; >+ >+ gfx_data->cmdline = heap; >+ heap += gfx_data->cmdline_len; >+ memset(gfx_data->cmdline, 0, gfx_data->cmdline_len); >+ >+ cmd_buf = heap; >+ heap += GFX_CMD_BUF_SIZE; >+ >+ /* setup menu entries */ >+ >+ for(i = max_len = 0; i < num_entries; i++) { >+ j = strlen(get_entry(menu_entries, i, 0)); >+ if(j > max_len) max_len = j; >+ } >+ >+ if(!max_len) return; >+ >+ gfx_data->menu_entry_len = max_len + 1; >+ gfx_data->menu_entries = num_entries; >+ >+ gfx_data->menu_list = heap; >+ heap += gfx_data->menu_entry_len * gfx_data->menu_entries; >+ >+ memset(gfx_data->menu_list, 0, gfx_data->menu_entry_len * gfx_data->menu_entries); >+ >+ for(i = 0; i < (int) gfx_data->menu_entries; i++) { >+ strcpy(gfx_data->menu_list + i * gfx_data->menu_entry_len, get_entry(menu_entries, i, 0)); >+ } >+ >+ gfx_data->menu_default_entry = gfx_data->menu_list + entryno * gfx_data->menu_entry_len; >+ >+ >+ /* setup list of kernel args */ >+ >+ for(i = max_len = 0; i < num_entries; i++) { >+ s = get_kernel_args(get_entry(config_entries, i, 1), cmd_buf); >+ j = strlen(s); >+ if(j > max_len) max_len = j; >+ } >+ >+ gfx_data->args_entry_len = max_len + 1; >+ >+ gfx_data->args_list = heap; >+ heap += gfx_data->args_entry_len * gfx_data->menu_entries; >+ >+ memset(gfx_data->args_list, 0, gfx_data->args_entry_len * gfx_data->menu_entries); >+ >+ for(i = 0; i < (int) gfx_data->menu_entries; i++) { >+ strcpy(gfx_data->args_list + i* gfx_data->args_entry_len, get_kernel_args(get_entry(config_entries, i, 1), cmd_buf)); >+ } >+ >+ >+ /* go back here when we no longer need the graphics data */ >+ saved_heap = heap; >+ >+ >+ /* get memory area to be used by graphics functions */ >+ >+ /* use 1MB starting at 2MB as file buffer */ >+ buf_ext = (unsigned char *) (2 << 20); >+ buf_ext_size = 1 << 20; >+ >+ /* must be 16-byte aligned */ >+ buf = (unsigned char *) (((unsigned) heap + 0xf) & ~0xf); >+ >+ buf_size = stack_ptr() - buf - MIN_HEAP_SIZE; >+ buf_size &= ~0xf; >+ >+ mem0_start = (unsigned) buf; >+ mem0_end = mem0_start + buf_size; >+ >+ if(verbose) { >+ printf("low memory 0x%x - 0x%x (%d bytes)\n", mem0_start, mem0_end, buf_size); >+ wait_for_key(); >+ } >+ >+ heap += buf_size; >+ >+ /* read the file */ >+ >+ if(!grub_open(graphics_file)) { >+ printf("%s: file not found\n", graphics_file); >+ sleep(5); >+ heap = saved_heap; >+ return; >+ } >+ >+ gfx_file_size = grub_read(buf_ext, buf_ext_size); >+ >+ grub_close(); >+ >+ if(gfx_file_size <= 0) { >+ printf("%s: read error\n", graphics_file); >+ sleep(5); >+ heap = saved_heap; >+ return; >+ } >+ >+ if(verbose) { >+ printf("%s: %d bytes (%d bytes left)\n", graphics_file, gfx_file_size, buf_ext_size - gfx_file_size); >+ wait_for_key(); >+ } >+ >+ /* locate file inside cpio archive */ >+ if(!(code_start = find_file(buf_ext, gfx_file_size, &file_start, &file_len))) { >+ printf("%s: invalid file format\n", graphics_file); >+ sleep(5); >+ heap = saved_heap; >+ return; >+ } >+ >+ if(verbose) { >+ printf("init: start 0x%x, len %d; code offset 0x%x\n", file_start, file_len, code_start); >+ wait_for_key(); >+ } >+ >+ if(file_len - code_start + MIN_GFX_FREE > buf_size) { >+ printf("not enough free memory: %d extra bytes need\n", file_len - code_start + MIN_GFX_FREE - buf_size); >+ sleep(5); >+ heap = saved_heap; >+ return; >+ } >+ >+ memcpy((void *) buf, (void *) (buf_ext + file_start + code_start), file_len - code_start); >+ >+ mem0_start += file_len - code_start; >+ mem0_start = (mem0_start + 3) & ~3; /* align */ >+ >+ /* init interface to graphics functions */ >+ >+ *(unsigned *) (gfx_data->sys_cfg + SC_FILE) = (unsigned) buf_ext + file_start; >+ *(unsigned *) (gfx_data->sys_cfg + SC_ARCHIVE_START) = (unsigned) buf_ext; >+ *(unsigned *) (gfx_data->sys_cfg + SC_ARCHIVE_END) = (unsigned) buf_ext + gfx_file_size; >+ *(unsigned *) (gfx_data->sys_cfg + SC_MEM0_START) = mem0_start; >+ *(unsigned *) (gfx_data->sys_cfg + SC_MEM0_END) = mem0_end; >+ >+ gfx_data->code_seg = (unsigned) buf >> 4; >+ >+ if(verbose) { >+ printf("init 0x%x, archive 0x%x - 0x%x, low mem 0x%x - 0x%x\ncode seg 0x%x\n", >+ (unsigned) buf_ext + file_start, >+ (unsigned) buf_ext, (unsigned) buf_ext + gfx_file_size, >+ mem0_start, mem0_end, gfx_data->code_seg >+ ); >+ wait_for_key(); >+ } >+ >+ for(i = 0; (unsigned) i < sizeof gfx_data->jmp_table / sizeof *gfx_data->jmp_table; i++) { >+ gfx_data->jmp_table[i] = (gfx_data->code_seg << 16) + ((unsigned short *) buf)[i]; >+ } >+ >+ if(verbose) { >+ for(i = 0; i < 12; i++) { >+ printf("%d: 0x%x\n", i, gfx_data->jmp_table[i]); >+ } >+ >+ for(i = 0; i < gfx_data->menu_entries; i++) { >+ printf("\"%s\" -- \"%s\"\n", >+ gfx_data->menu_list + i * gfx_data->menu_entry_len, >+ gfx_data->args_list + i * gfx_data->args_entry_len >+ ); >+ } >+ >+ printf("default: \"%s\"\n", gfx_data->menu_default_entry); >+ wait_for_key(); >+ } >+ >+ /* switch to graphics mode */ >+ >+ if(gfx_init(gfx_data)) { >+ printf("graphics initialization failed\n"); >+ sleep(5); >+ heap = saved_heap; >+ return; >+ } >+ >+ gfx_setup_menu(gfx_data); >+ >+ i = gfx_input(gfx_data, &selected_entry); >+ >+ /* ESC -> show text menu */ >+ if(i == 1) { >+ gfx_done(gfx_data); >+ grub_timeout = -1; >+ >+ heap = saved_heap; >+ return; >+ } >+ >+ gfx_done(gfx_data); >+ >+ heap = saved_heap; /* free most of the graphics data */ >+ >+ // printf("cmdline: >%s<, entry = %d\n", gfx_data->cmdline, selected_entry); >+ >+ if(selected_entry < 0 || selected_entry > num_entries) return; >+ >+ /* for 'savedefault' */ >+ current_entryno = selected_entry; >+ >+ >+ /* create new config with modified kernel option */ >+ >+ cfg = get_entry(config_entries, selected_entry, 1); >+ >+ new_config = heap; >+ >+ for(p = gfx_data->cmdline, i = 0; ; i++) { >+ s = get_entry(cfg, i, 0); >+ if(!*s) { >+ if(!i) *heap++ = 0; >+ *heap++ = 0; >+ break; >+ } >+ /* note: must match get_kernel_args() */ >+ if( >+ (!memcmp(s, "kernel", 6) || !memcmp(s, "module", 6)) && >+ (s[6] == ' ' || s[6] == '\t') >+ ) { >+ t = skip_to(0, s); >+ t2 = s[0] == 'm' ? strstr(t, "initrd") : NULL; >+ if(*t) t = skip_to(0, t); >+ if(t2 && t2 < t) { /* module is likely a normal initrd -> skip */ >+ strcpy(heap, s); >+ heap += strlen(s) + 1; >+ continue; >+ } >+ memmove(heap, s, t - s); >+ heap += t - s; >+ *heap++ = ' '; >+ while(*p && *p != GFX_CMD_SEP) *heap++ = *p++; >+ *heap++ = 0; >+ if(*p == GFX_CMD_SEP) p++; >+ } >+ else { >+ strcpy(heap, s); >+ heap += strlen(s) + 1; >+ } >+ } >+ >+ *heap++ = 0; >+ >+ // hexdump(new_config, heap - new_config); >+ // getkey(); >+ >+ run_script(new_config, heap); >+} >+ >+ > static int > get_line_from_config (char *cmdline, int maxlen, int read_from_file) > { >@@ -827,6 +1412,195 @@ get_line_from_config (char *cmdline, int maxlen, int read_from_file) > return pos; > } > >+extern void __savedefault_once_reset(); >+ >+char *wildcard_prefix, *wildcard_suffix; >+char wildcard_matches[1024], *end_wildcard_matches; >+ >+static void wildcard_handler(char *name); >+ >+/* Match one directory entry against the current wildcard. If the entry >+ matches, store it in WILDCARD_MATCHES. Silently ignore entries that >+ don't fit into WILDCARD_MATCHES anymore. */ >+static void >+wildcard_handler(char *name) >+{ >+ char *n = name, *p = wildcard_prefix; >+ >+ while (*p && *p == *n) >+ { >+ p++; >+ n++; >+ } >+ if (*p) >+ return; /* prefix mismatch */ >+ >+ p = name + grub_strlen (name) - grub_strlen (wildcard_suffix); >+ /* [n .. p) is the part matching the asterisk */ >+ >+ if (p < n || grub_strcmp (p, wildcard_suffix) != 0) >+ return; /* suffix mismatch */ >+ >+ /* store this match */ >+ if (p - n + 1 > sizeof (wildcard_matches) - >+ (end_wildcard_matches - wildcard_matches)) >+ return; /* out of space */ >+ while (n < p) >+ *end_wildcard_matches++ = *n++; >+ *end_wildcard_matches++ = 0; >+} >+ >+/* Wildcard expand the GLOB argument. Return NULL upon failure, or >+ a list of 0-terminated expansions, terminated by a zero-length string. */ >+char * >+wildcard (char *glob, int *len) >+{ >+ char path[128], *p; >+ int ret; >+ >+ end_wildcard_matches = wildcard_matches; >+ if (grub_strlen (glob) + 1 > sizeof (path)) { >+ errnum = ERR_FILELENGTH; >+ return NULL; /* cannot handle pathnames this long */ >+ } >+ grub_strcpy (path, glob); >+ p = path; >+ while (*p) >+ p++; >+ wildcard_suffix = p; >+ while (p > path && *p != '/') >+ p--; >+ if (*p != '/') >+ { >+ errnum = ERR_BAD_FILETYPE; >+ return NULL; /* Cannot wildcard device names */ >+ } >+ *(++p) = 0; >+ wildcard_prefix = glob + (p - path); >+ for (p = wildcard_prefix;; p++) >+ { >+ if (*p == 0) >+ { >+ /* We cannot do exact matches: this cannot be represented in the >+ result list. */ >+ return NULL; >+ } >+ else if (*p == '*') >+ { >+ *p++ = 0; >+ wildcard_suffix = p; >+ break; >+ } >+ } >+ >+ ret = dir (path, wildcard_handler); >+ /* restore original argument */ >+ wildcard_prefix[grub_strlen (wildcard_prefix)] = '*'; >+ if (!ret) >+ return NULL; >+ *len = end_wildcard_matches - wildcard_matches; >+ return wildcard_matches; >+} >+ >+#define skip(str) ((str) + grub_strlen (str) + 1) >+ >+static void inplace_sort (char *str, int len); >+ >+static void >+inplace_sort (char *str, int len) >+{ >+ int m, n = 0; >+ char *s, *t; >+ >+ /* we use x as temporary storage */ >+ char *x = str + len; >+ >+ for (s = str; s < x; s = skip (s)) >+ n++; >+ >+ for (; n >= 2; n--) >+ { >+ s = str; >+ t = skip (s); >+ >+ for (m = n; m >= 2; m--) >+ { >+ if (grub_strcmp (s, t) > 0) >+ { >+ int ls = skip (s) - s; >+ int lt = skip (t) - t; >+ >+ memcpy (x, s, ls); >+ grub_memmove (s + ls, s + lt, t - (s + ls)); >+ memcpy (s, t, lt); >+ t = t + lt - ls; >+ memcpy (t, x, ls); >+ } >+ s = t; >+ t = skip (t); >+ } >+ } >+} >+ >+#undef skip >+ >+static int this_config_len (const char *config); >+static int >+this_config_len (const char *config) >+{ >+ const char *c = config; >+ while (*c) >+ { >+ while (*c) >+ c++; >+ c++; >+ } >+ c++; >+ return c - config; >+} >+ >+static const char * expand_asterisks (const char *str, int *len, >+ const char *subst); >+ >+/* Expand all asterisks (*) in a menu entry or commands section with its >+ substitution. Use a backslash as escape character. */ >+static const char * >+expand_asterisks (const char *str, int *len, const char *subst) >+{ >+ static char buffer[1024]; >+ char *b = buffer, escaped = 0; >+ const char *end = str + *len; >+ >+ while (str < end) >+ { >+ if (*str == '*' && !escaped) >+ { >+ if (b - buffer + grub_strlen (subst) > sizeof (buffer)) >+ { >+ errnum = ERR_FILELENGTH; >+ return NULL; >+ } >+ grub_strcpy (b, subst); >+ b += grub_strlen (subst); >+ } >+ else if (*str == '\\' && !escaped) >+ escaped = 1; >+ else >+ { >+ escaped = 0; >+ if (b - buffer + 1 > sizeof (buffer)) >+ { >+ errnum = ERR_FILELENGTH; >+ return NULL; >+ } >+ *b++ = *str; >+ } >+ str++; >+ } >+ *len = b - buffer; >+ >+ return buffer; >+} > > /* This is the starting function in C. */ > void >@@ -848,6 +1622,97 @@ cmain (void) > init_config (); > } > >+ auto void expand_wildcard_entries (void); >+ void expand_wildcard_entries (void) >+ { >+ char *config_entry = config_entries; >+ char *menu_entry = menu_entries; >+ >+ while (*menu_entry) >+ { >+ char *command = config_entry; >+ >+ do >+ { >+ char *c = command; >+ const char *w = "wildcard"; >+ >+ while (*w && *c == *w) >+ { >+ c++; >+ w++; >+ } >+ if (*w == 0 && (*c == ' ' || *c == '\t' || *c == '=')) >+ { >+ int len, wlen; >+ >+ /* This is a wildcard command. Advance to the argument. */ >+ while (*c == ' ' || *c == '\t' || *c == '=') >+ c++; >+ >+ /* Expand wildcard entry. */ >+ w = wildcard (c, &wlen); >+ if (w) >+ inplace_sort (w, wlen); >+ >+ /* Remove the wildcard command from the command section; >+ it has no meaning beyond the wildcard expansion just >+ performed. */ >+ len = grub_strlen (command) + 1; >+ grub_memmove (command, command + len, >+ config_len - (command - config_entries)); >+ config_len -= len; >+ >+ while (w && wlen) >+ { >+ /* Insert expansion before the wildcard entry in the >+ list of entry names. */ >+ len = grub_strlen (menu_entry) + 1; >+ const char *x = expand_asterisks (menu_entry, &len, w); >+ grub_memmove (menu_entry + len, menu_entry, >+ menu_len - (menu_entry - menu_entries)); >+ memcpy (menu_entry, x, len); >+ menu_entry += len; >+ menu_len += len; >+ >+ /* Insert expansion before the wildcard command section >+ in the list of command sections. */ >+ len = this_config_len (config_entry); >+ x = expand_asterisks (config_entry, &len, w); >+ grub_memmove (config_entry + len, config_entry, >+ config_len - (config_entry - >+ config_entries)); >+ memcpy (config_entry, x, len); >+ config_entry += len; >+ config_len += len; >+ >+ num_entries++; >+ wlen -= grub_strlen (w) + 1; >+ w += grub_strlen (w) + 1; >+ } >+ >+ /* Remove the wildcard command section; it has just >+ been expanded. */ >+ len = grub_strlen (menu_entry) + 1; >+ grub_memmove (menu_entry, menu_entry + len, >+ menu_len - (menu_entry - menu_entries)); >+ menu_len -= len; >+ >+ len = this_config_len(config_entry); >+ grub_memmove (config_entry, config_entry + len, >+ config_len - (config_entry - config_entries)); >+ config_len -= len; >+ >+ num_entries--; >+ } >+ command += grub_strlen (command) + 1; >+ } >+ while (*command); >+ menu_entry += grub_strlen (menu_entry) + 1; >+ config_entry += this_config_len(config_entry); >+ } >+ } >+ > /* Initialize the environment for restarting Stage 2. */ > grub_setjmp (restart_env); > >@@ -999,8 +1864,16 @@ cmain (void) > config_len = prev_config_len; > } > >+ if (is_preset) >+ close_preset_menu (); >+ else >+ grub_close (); >+ > menu_entries[menu_len++] = 0; > config_entries[config_len++] = 0; >+ >+ expand_wildcard_entries(); >+ > grub_memmove (config_entries + config_len, menu_entries, > menu_len); > menu_entries = config_entries + config_len; >@@ -1042,14 +1915,12 @@ cmain (void) > default_entry = 0; > } > >- if (is_preset) >- close_preset_menu (); >- else >- grub_close (); > } > while (is_preset); > } >- >+#ifndef SUPPORT_DISKLESS >+ __savedefault_once_reset(); >+#endif > if (! num_entries) > { > /* If no acceptable config file, goto command-line, starting >@@ -1059,9 +1930,12 @@ cmain (void) > } > else > { >- /* Run menu interface. */ >- run_menu (menu_entries, config_entries, num_entries, >- menu_entries + menu_len, default_entry); >+ if (*graphics_file && !password && show_menu && grub_timeout) >+ { >+ run_graphics_menu(menu_entries, config_entries, num_entries,menu_entries + menu_len, default_entry); >+ } >+ /* Run menu interface. */ >+ run_menu (menu_entries, config_entries, num_entries, menu_entries + menu_len, default_entry); > } > } > } >diff --git a/util/grub-install.in b/util/grub-install.in >index 2e598b0..ffa9f90 100644 >--- a/util/grub-install.in >+++ b/util/grub-install.in >@@ -27,15 +27,17 @@ VERSION=@VERSION@ > host_cpu=@host_cpu@ > host_os=@host_os@ > host_vendor=@host_vendor@ >-pkglibdir=${libdir}/${PACKAGE}/${host_cpu}-${host_vendor} >+pkglibdir=${libdir}/${PACKAGE}/ > > grub_shell=${sbindir}/grub >+mdadm=${sbindir}/mdadm > grub_set_default=${sbindir}/grub-set-default > log_file=/tmp/grub-install.log.$$ > img_file=/tmp/grub-install.img.$$ > rootdir= > grub_prefix=/boot/grub > >+install_drives= > install_device= > no_floppy= > force_lba= >@@ -70,6 +72,8 @@ Install GRUB on your drive. > --force-lba force GRUB to use LBA mode even for a buggy > BIOS > --recheck probe a device map even if it already exists >+ This flag is unreliable and its use is >+ strongly discouraged. > > INSTALL_DEVICE can be a GRUB device name or a system device filename. > >@@ -96,17 +100,26 @@ convert () { > # 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%' \ >+ tmp_disk=`echo "$1" | grep -v '/mapper/control$' | >+ grep -v '/mapper/[[:alnum:]]\+-[[:alnum:]]\+$' | uniq | >+ 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%\(c[0-7]d[0-9]*\).*$%\1%' \ >+ -e 's%\(/mapper/[[:alpha:]]\+[[:digit:]]\+\)p[[:digit:]]\+$%\1%' \ >+ -e 's%\(/mapper/[[:alpha:]]\+_[[:alpha:]]\+\)[[:digit:]]\+$%\1%'` >+ tmp_part=`echo "$1" | grep -v '/mapper/control$' | >+ grep -v '/mapper/[[:alnum:]]\+-[[:alnum:]]\+$' | uniq | >+ 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%%'` >+ -e 's%.*c[0-7]d[0-9]*p%%' \ >+ -e 's%.*/mapper/[[:alpha:]]\+[[:digit:]]\+p\([[:digit:]]\+\)$%\1%' \ >+ -e 's%.*/mapper/[[:alpha:]]\+_[[:alpha:]]\+\([[:digit:]]\+\)$%\1%' | >+ grep -v '.*/mapper/.*'` > ;; > gnu*) > tmp_disk=`echo "$1" | sed 's%\([sh]d[0-9]*\).*%\1%'` >@@ -211,23 +224,135 @@ resolve_symlink () { > echo "$tmp_fname" > } > >+# Usage: is_raid1_device devicename >+# Returns 0 if devicename is a raid1 md device, 1 if it is not. >+is_raid1_device () { >+ case "$host_os" in >+ linux*) >+ level=`$mdadm --query --detail $1 2>/dev/null | \ >+ awk '/Raid Level :/ {print $4}'` >+ if [ "$level" = "raid1" ]; then >+ return 0 >+ fi >+ ;; >+ esac >+ return 1 >+} >+ >+# Usage: find_real_devs device >+# Returns space separated list of devices for linux if device is >+# a raid1 device. In all other cases, the provided value is returned. >+find_real_devs () { >+ source_device=$1 >+ case "$host_os" in >+ linux*) >+ if is_raid1_device $source_device ; then >+ list="" >+ for device in `$mdadm --query --detail "${source_device}" | \ >+ awk '/\/dev\/[^(md)]/ {print $7}'` ; do >+ list="$list $device" >+ done >+ echo $list >+ return 0 >+ fi >+ ;; >+ esac >+ echo $source_device >+ return 0 >+} >+ >+# Usage: stat_device file >+# Find major:minor of a device node. >+stat_device() { >+ majmin=`stat -c "%t:%T" "$1" 2>/dev/null` >+ if test -z "$majmin"; then >+ echo "Could not find device for $1" 2>&1 >+ exit 1 >+ fi >+ >+ echo "$majmin" >+} >+ >+# Usage: find_mapper_device file >+# Find a file in /dev/mapper with the same major:minor as the specified node. >+find_mapper_device() { >+ if [ -b "$1" ]; then >+ dev="$1" >+ else >+ mntpnt=`echo "$1" | sed 's,/,\\\\/,g'` >+ dev=`awk '($2 ~ /'$mntpnt'/) { print $1 }' /etc/mtab` >+ fi >+ if test -z "$dev"; then >+ echo "Could not find device for $1" 2>&1 >+ exit 1 >+ fi >+ >+ majmin=`stat_device $dev` >+ for x in /dev/mapper/* ; do >+ devmajmin=`stat_device "$x"` >+ if [ "$majmin" == "$devmajmin" ]; then >+ echo "$x" >+ return 0 >+ fi >+ done >+ return 1 >+} >+ > # 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'` >+ tmp_fname=`df $1/ | awk '/\/dev\/|LABEL=|UUID=/{ print $1 }'` >+ >+ if echo "$tmp_fname" | grep -q LABEL= ; then >+ label=`echo "$tmp_fname" | sed -e s/.*=//` >+ tmp_fname=`readlink -f /dev/disk/by-label/$label` >+ fi >+ if echo "$tmp_fname" | grep -q UUID= ; then >+ uuid=`echo "$tmp_fname" | sed -e s/.*=//` >+ tmp_fname=`readlink -f /dev/disk/by-uuid/$uuid` >+ fi > > if test -z "$tmp_fname"; then > echo "Could not find device for $1" 2>&1 > exit 1 > fi > >- tmp_fname=`resolve_symlink $tmp_fname` >+ ret_fname=`resolve_symlink $tmp_fname` >+ tmp_fname=`find_mapper_device $ret_fname` >+ if test -n "$tmp_fname"; then >+ ret_fname="$tmp_fname" >+ fi > >- echo "$tmp_fname" >+ echo "$ret_fname" >+ return 0 > } > >+ >+dump_boot_block () { >+ sync >+ $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file >+dump ${root_drive}${tmp} ${img_file} >+quit >+EOF >+} >+ >+ >+install_boot_block () { >+ # Before all invocations of the grub shell, call sync to make sure >+ # the raw device is in sync with any bufferring in filesystems. >+ sync >+ >+ # Now perform the installation. >+ $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >>$log_file >+root $1 >+setup $force_lba --stage2=$grubdir/stage2 --prefix=$grub_prefix $2 >+quit >+EOF >+} >+ >+ > # Check the arguments. > for option in "$@"; do > case "$option" in >@@ -293,6 +418,14 @@ esac > grubdir=${bootdir}/grub > device_map=${grubdir}/device.map > >+if [ "$recheck" == "yes" ]; then >+ if grep 'mapper' ${device_map} >/dev/null; then >+ echo 'grub-install does not support reprobing of device.map when' 1>&2 >+ echo 'using a device-mapper based boot device.' 1>&2 >+ exit 1 >+ fi >+fi >+ > # Check if GRUB is installed. > # This is necessary, because the user can specify "grub --read-only". > set $grub_shell dummy >@@ -326,7 +459,7 @@ 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 >+ mv $device_map ${device_map}.backup > fi > > # Create the device map file if it is not present. >@@ -336,6 +469,10 @@ else > # Create a safe temporary file. > test -n "$mklog" && log_file=`$mklog` > >+ # Before all invocations of the grub shell, call sync to make sure >+ # the raw device is in sync with any bufferring in filesystems. >+ sync >+ > $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file > quit > EOF >@@ -351,7 +488,22 @@ fi > 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 >+ echo "The drive $tmp is defined multiple times in the new device map." 1>&2 >+ if test $recheck = yes; then >+ echo "Reverting to backed up copy." 1>&2 >+ mv ${device_map}.backup $device_map >+ fi >+ exit 1 >+fi >+ >+# Make sure device.map has at least one hd device >+grep -q "^(hd[0-9]\+)" $device_map >+if [ "x$?" != "x0" ]; then >+ echo "No suitable drive was found in the generated device map." 1>&2 >+ if test $recheck = yes; then >+ echo "Reverting to backed up copy." 1>&2 >+ mv ${device_map}.backup $device_map >+ fi > exit 1 > fi > >@@ -359,23 +511,34 @@ fi > 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 >+ for install_drive in `find_real_devs $install_device` ; do >+ install_drive=`convert $install_drive` >+ if is_raid1_device $install_device; then >+ install_drive=`echo $install_drive | sed 's/,[0-9]*)/)/'` >+ fi >+ if [ "x$install_drive" = "x" ]; then >+ exit 1 >+ fi >+ install_drives="${install_drives} ${install_drive}" >+ done >+ unset install_drive >+ >+ if test "x$install_drives" = x ; then > exit 1 > fi ;; > \([hf]d[0-9]*\)) >- install_drive="$install_device" ;; >+ install_drives="$install_device" ;; > [hf]d[0-9]*) > # The GRUB format with no parenthesis. >- install_drive="($install_device)" ;; >+ install_drives="($install_device)" ;; > *) > echo "Format of install_device not recognized." 1>&2 > usage > exit 1 ;; > esac > >+unset install_device >+ > # Get the root drive. > root_device=`find_device ${rootdir}` > bootdir_device=`find_device ${bootdir}` >@@ -387,14 +550,7 @@ if test "x$root_device" != "x$bootdir_device"; then > 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. >+# 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 >@@ -406,14 +562,19 @@ 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 >+# FHS says that /usr/share is used for architecture independent data, >+# so all stage-files are directly installed to /usr/lib/grub. >+# Therefor this part is no longer needed. >+# <--cut_here--> >+## 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 >+# <--uncut--> > > # Make a default file. > ${grub_set_default} --root-directory=${rootdir} default >@@ -422,25 +583,33 @@ ${grub_set_default} --root-directory=${rootdir} default > test -n "$mkimg" && img_file=`$mkimg` > test -n "$mklog" && log_file=`$mklog` > >+# There's not a real root device, so just pick the first >+if is_raid1_device $root_device ; then >+ root_device=`find_real_devs $root_device | awk '{print $1}'` >+fi >+ >+# Convert the root deviceto a GRUB drive. >+root_drive=`convert "$root_device"` >+if [ "x$root_drive" = x ]; then >+ exit 1 >+fi >+ > for file in ${grubdir}/stage1 ${grubdir}/stage2 ${grubdir}/*stage1_5; do > count=5 > tmp=`echo $file | sed "s|^${grubdir}|${grub_prefix}|"` > while test $count -gt 0; do >- $grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file >-dump ${root_drive}${tmp} ${img_file} >-quit >-EOF >- if grep "Error [0-9]*: " $log_file >/dev/null; then >- : >- elif cmp $file $img_file >/dev/null; then >- break >- fi >- sleep 1 >- count=`expr $count - 1` >+ dump_boot_block $root_drive $img_file >+ 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 >+ echo "The file $file not read correctly." 1>&2 >+ exit 1 > fi > done > >@@ -450,17 +619,22 @@ rm -f $log_file > # Create a safe temporary file. > test -n "$mklog" && log_file=`$mklog` > >-# Now perform the installation. >-$grub_shell --batch $no_floppy --device-map=$device_map <<EOF >$log_file >-root $root_drive >-setup $force_lba --stage2=$grubdir/stage2 --prefix=$grub_prefix $install_drive >-quit >-EOF >+for install_drive in $install_drives; do >+ # Convert the root deviceto a GRUB drive. >+ root_drive=`convert "$root_device"` >+ if [ "x$root_drive" = x ]; then >+ exit 1 >+ fi >+ install_boot_block $root_drive $install_drive >+done > >-if grep "Error [0-9]*: " $log_file >/dev/null || test $debug = yes; then >+if grep "Error [0-9]*: " $log_file >/dev/null ; then > cat $log_file 1>&2 > exit 1 > fi >+if test $debug = yes; then >+ cat $log_file 1>&2 >+fi > > rm -f $log_file > >diff --git a/util/grub-md5-crypt.in b/util/grub-md5-crypt.in >index c030c87..e327676 100644 >--- a/util/grub-md5-crypt.in >+++ b/util/grub-md5-crypt.in >@@ -88,7 +88,7 @@ if test "x$password" != "x$password2"; then > fi > > # Run the grub shell. >-$grub_shell --batch --device-map=/dev/null <<EOF \ >+$grub_shell --batch <<EOF \ > | grep "^Encrypted: " | sed 's/^Encrypted: //' > md5crypt > $password >diff --git a/util/mbchk.c b/util/mbchk.c >index fd71858..41572fc 100644 >--- a/util/mbchk.c >+++ b/util/mbchk.c >@@ -59,7 +59,9 @@ check_multiboot (const char *filename, FILE *fp) > int i; > char buf[8192]; > >- if (fread (buf, 1, 8192, fp) < 0) >+ fread (buf, 1, 8192, fp); >+ >+ if (ferror(fp)) > { > fprintf (stderr, "%s: Read error.\n", filename); > return 0;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 14795
: 2557