2004-06-20 Yoshinori K. Okuji <okuji@enbug.org>
This is a big change on saving a default entry. This change makes it possible to set up a quite robust system using GRUB. Now we do not use the second sector of Stage 2 to store an entry number but use the file /boot/grub/default. This file must be generated by grub-set-default, although this file is plain-text. * util/grub-set-default.in: New file. * util/grub-install.in (grub_set_default): New variable. Use /grub instead of /boot/grub on OpenBSD as well as NetBSD. Run grub-set-default to make a default file. * util/Makefile.am (sbin_SCRIPTS): Added grub-set-default. * stage2/stage2.c (run_menu): Change the fallback handling to support multiple fallback entries. (cmain): Likewise. Also, get a saved entry from a default file if possible, before reading a config file. * stage2/shared.h (DEFAULT_FILE_BUF): New macro. (DEFAULT_FILE_BUFLEN): Likewise. (CMDLINE_BUF): Set to DEFAULT_FILE_BUF + DEFAULT_FILE_BUFLEN. (MENU_BUFLEN): Set to 0x8000 + PASSWORD_BUF - MENU_BUF. (fallback_entry): Removed. (fallback_entries): Declared. (fallback_entryno): Likewise. (MAX_FALLBACK_ENTRIES): New macro. * stage2/cmdline.c (run_script): Use FALLBACK_ENTRYNO instead of FALLBACK_ENTRY. * stage2/builtins.c (fallback_entry): Removed. (fallback_entryno): New variable. (fallback_entries): Likewise. (init_config): Initialize FALLBACK_ENTRYNO and FALLBACK_ENTRIES. (fallback_func): Rewritten completely. (savedefault_func): Likewise. * docs/grub.texi (grub-set-default): New direntry. (Installation): Describe grub-set-default for manual installations. (Making your system robust): New section. (Booting once-only): New subsection. (Booting fallback systems): Likewise. (fallback): Describe multiple fallback entries. (savedefault): Describe an optional argument. (Invoking grub-set-default): New chapter. (Future): Replaced with a description about GRUB 2. * configure.ac (AC_CONFIG_FILES): Added util/grub-set-default.
This commit is contained in:
parent
e15e075464
commit
5b5f6dc772
16 changed files with 705 additions and 98 deletions
54
ChangeLog
54
ChangeLog
|
@ -1,3 +1,57 @@
|
||||||
|
2004-06-20 Yoshinori K. Okuji <okuji@enbug.org>
|
||||||
|
|
||||||
|
This is a big change on saving a default entry. This change
|
||||||
|
makes it possible to set up a quite robust system using GRUB.
|
||||||
|
Now we do not use the second sector of Stage 2 to store an
|
||||||
|
entry number but use the file /boot/grub/default. This file
|
||||||
|
must be generated by grub-set-default, although this file is
|
||||||
|
plain-text.
|
||||||
|
|
||||||
|
* util/grub-set-default.in: New file.
|
||||||
|
|
||||||
|
* util/grub-install.in (grub_set_default): New variable.
|
||||||
|
Use /grub instead of /boot/grub on OpenBSD as well as NetBSD.
|
||||||
|
Run grub-set-default to make a default file.
|
||||||
|
|
||||||
|
* util/Makefile.am (sbin_SCRIPTS): Added grub-set-default.
|
||||||
|
|
||||||
|
* stage2/stage2.c (run_menu): Change the fallback handling to
|
||||||
|
support multiple fallback entries.
|
||||||
|
(cmain): Likewise. Also, get a saved entry from a default file
|
||||||
|
if possible, before reading a config file.
|
||||||
|
|
||||||
|
* stage2/shared.h (DEFAULT_FILE_BUF): New macro.
|
||||||
|
(DEFAULT_FILE_BUFLEN): Likewise.
|
||||||
|
(CMDLINE_BUF): Set to DEFAULT_FILE_BUF + DEFAULT_FILE_BUFLEN.
|
||||||
|
(MENU_BUFLEN): Set to 0x8000 + PASSWORD_BUF - MENU_BUF.
|
||||||
|
(fallback_entry): Removed.
|
||||||
|
(fallback_entries): Declared.
|
||||||
|
(fallback_entryno): Likewise.
|
||||||
|
(MAX_FALLBACK_ENTRIES): New macro.
|
||||||
|
|
||||||
|
* stage2/cmdline.c (run_script): Use FALLBACK_ENTRYNO instead of
|
||||||
|
FALLBACK_ENTRY.
|
||||||
|
|
||||||
|
* stage2/builtins.c (fallback_entry): Removed.
|
||||||
|
(fallback_entryno): New variable.
|
||||||
|
(fallback_entries): Likewise.
|
||||||
|
(init_config): Initialize FALLBACK_ENTRYNO and FALLBACK_ENTRIES.
|
||||||
|
(fallback_func): Rewritten completely.
|
||||||
|
(savedefault_func): Likewise.
|
||||||
|
|
||||||
|
* docs/grub.texi (grub-set-default): New direntry.
|
||||||
|
(Installation): Describe grub-set-default for manual
|
||||||
|
installations.
|
||||||
|
(Making your system robust): New section.
|
||||||
|
(Booting once-only): New subsection.
|
||||||
|
(Booting fallback systems): Likewise.
|
||||||
|
(fallback): Describe multiple fallback entries.
|
||||||
|
(savedefault): Describe an optional argument.
|
||||||
|
(Invoking grub-set-default): New chapter.
|
||||||
|
(Future): Replaced with a description about GRUB 2.
|
||||||
|
|
||||||
|
* configure.ac (AC_CONFIG_FILES): Added util/grub-set-default.
|
||||||
|
|
||||||
2004-06-19 Yoshinori K. Okuji <okuji@enbug.org>
|
2004-06-19 Yoshinori K. Okuji <okuji@enbug.org>
|
||||||
|
|
||||||
* stage2/ufs2.h (int8_t): Renamed to ...
|
* stage2/ufs2.h (int8_t): Renamed to ...
|
||||||
|
|
7
NEWS
7
NEWS
|
@ -1,5 +1,12 @@
|
||||||
NEWS - list of user-visible changes between releases of GRUB
|
NEWS - list of user-visible changes between releases of GRUB
|
||||||
|
|
||||||
|
New:
|
||||||
|
* The command "fallback" supports mutiple fallback entries.
|
||||||
|
* The command "savedefault" supports an optional argument which
|
||||||
|
is the number of next boot entry or the special keyword `fallback'.
|
||||||
|
* New utility "grub-set-default".
|
||||||
|
* New section "Making your system robust" in the manual.
|
||||||
|
|
||||||
New in 0.95 - 2004-06-13:
|
New in 0.95 - 2004-06-13:
|
||||||
* Add support for ReiserFS 3.
|
* Add support for ReiserFS 3.
|
||||||
* Fix support for FreeBSD 5.
|
* Fix support for FreeBSD 5.
|
||||||
|
|
3
configure
vendored
3
configure
vendored
|
@ -6109,7 +6109,7 @@ CCASFLAGS='$(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ac_config_files="$ac_config_files Makefile stage1/Makefile stage2/Makefile docs/Makefile lib/Makefile util/Makefile grub/Makefile netboot/Makefile util/grub-image util/grub-install util/grub-md5-crypt util/grub-terminfo"
|
ac_config_files="$ac_config_files Makefile stage1/Makefile stage2/Makefile docs/Makefile lib/Makefile util/Makefile grub/Makefile netboot/Makefile util/grub-image util/grub-install util/grub-md5-crypt util/grub-terminfo util/grub-set-default"
|
||||||
|
|
||||||
cat >confcache <<\_ACEOF
|
cat >confcache <<\_ACEOF
|
||||||
# This file is a shell script that caches the results of configure
|
# This file is a shell script that caches the results of configure
|
||||||
|
@ -6728,6 +6728,7 @@ do
|
||||||
"util/grub-install" ) CONFIG_FILES="$CONFIG_FILES util/grub-install" ;;
|
"util/grub-install" ) CONFIG_FILES="$CONFIG_FILES util/grub-install" ;;
|
||||||
"util/grub-md5-crypt" ) CONFIG_FILES="$CONFIG_FILES util/grub-md5-crypt" ;;
|
"util/grub-md5-crypt" ) CONFIG_FILES="$CONFIG_FILES util/grub-md5-crypt" ;;
|
||||||
"util/grub-terminfo" ) CONFIG_FILES="$CONFIG_FILES util/grub-terminfo" ;;
|
"util/grub-terminfo" ) CONFIG_FILES="$CONFIG_FILES util/grub-terminfo" ;;
|
||||||
|
"util/grub-set-default" ) CONFIG_FILES="$CONFIG_FILES util/grub-set-default" ;;
|
||||||
"depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
|
"depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
|
||||||
"config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
|
"config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
|
||||||
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
|
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
|
||||||
|
|
|
@ -666,5 +666,5 @@ AC_CONFIG_FILES([Makefile stage1/Makefile stage2/Makefile \
|
||||||
docs/Makefile lib/Makefile util/Makefile \
|
docs/Makefile lib/Makefile util/Makefile \
|
||||||
grub/Makefile netboot/Makefile util/grub-image \
|
grub/Makefile netboot/Makefile util/grub-image \
|
||||||
util/grub-install util/grub-md5-crypt \
|
util/grub-install util/grub-md5-crypt \
|
||||||
util/grub-terminfo])
|
util/grub-terminfo util/grub-set-default])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
|
302
docs/grub.texi
302
docs/grub.texi
|
@ -27,6 +27,8 @@
|
||||||
* grub-terminfo: (grub)Invoking grub-terminfo. Generate a terminfo
|
* grub-terminfo: (grub)Invoking grub-terminfo. Generate a terminfo
|
||||||
command from a
|
command from a
|
||||||
terminfo name
|
terminfo name
|
||||||
|
* grub-set-default: (grub)Invoking grub-set-default. Set a default boot
|
||||||
|
entry
|
||||||
* mbchk: (grub)Invoking mbchk. Check for the format of a Multiboot kernel
|
* mbchk: (grub)Invoking mbchk. Check for the format of a Multiboot kernel
|
||||||
@end direntry
|
@end direntry
|
||||||
|
|
||||||
|
@ -113,6 +115,7 @@ This edition documents version @value{VERSION}.
|
||||||
* Invoking grub-install:: How to use the GRUB installer
|
* Invoking grub-install:: How to use the GRUB installer
|
||||||
* Invoking grub-md5-crypt:: How to generate a cryptic password
|
* Invoking grub-md5-crypt:: How to generate a cryptic password
|
||||||
* Invoking grub-terminfo:: How to generate a terminfo command
|
* Invoking grub-terminfo:: How to generate a terminfo command
|
||||||
|
* Invoking grub-set-default:: How to set a default boot entry
|
||||||
* Invoking mbchk:: How to use the Multiboot checker
|
* Invoking mbchk:: How to use the Multiboot checker
|
||||||
* Obtaining and Building GRUB:: How to obtain and build GRUB
|
* Obtaining and Building GRUB:: How to obtain and build GRUB
|
||||||
* Reporting bugs:: Where you should send a bug report
|
* Reporting bugs:: Where you should send a bug report
|
||||||
|
@ -475,11 +478,14 @@ if, by any chance, your hard drive becomes unusable (unbootable).
|
||||||
GRUB comes with boot images, which are normally put in the directory
|
GRUB comes with boot images, which are normally put in the directory
|
||||||
@file{/usr/share/grub/i386-pc}. If you do not use grub-install, then
|
@file{/usr/share/grub/i386-pc}. If you do not use grub-install, then
|
||||||
you need to copy the files @file{stage1}, @file{stage2}, and
|
you need to copy the files @file{stage1}, @file{stage2}, and
|
||||||
@file{*stage1_5} to the directory @file{/boot/grub}. Hereafter, the
|
@file{*stage1_5} to the directory @file{/boot/grub}, and run the
|
||||||
directory where GRUB images are initially placed (normally
|
@command{grub-set-default} (@pxref{Invoking grub-set-default}) if you
|
||||||
@file{/usr/share/grub/i386-pc}) will be called the @dfn{image
|
intend to use @samp{default saved} (@pxref{default}) in your
|
||||||
directory}, and the directory where the boot loader needs to find them
|
configuration file. Hereafter, the directory where GRUB images are
|
||||||
(usually @file{/boot/grub}) will be called the @dfn{boot directory}.
|
initially placed (normally @file{/usr/share/grub/i386-pc}) will be
|
||||||
|
called the @dfn{image directory}, and the directory where the boot
|
||||||
|
loader needs to find them (usually @file{/boot/grub}) will be called
|
||||||
|
the @dfn{boot directory}.
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Creating a GRUB boot floppy::
|
* Creating a GRUB boot floppy::
|
||||||
|
@ -734,6 +740,7 @@ magic.
|
||||||
@menu
|
@menu
|
||||||
* General boot methods:: How to boot OSes with GRUB generally
|
* General boot methods:: How to boot OSes with GRUB generally
|
||||||
* OS-specific notes:: Notes on some operating systems
|
* OS-specific notes:: Notes on some operating systems
|
||||||
|
* Making your system robust:: How to make your system robust
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@ -1068,6 +1075,184 @@ grub> @kbd{boot}
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
|
||||||
|
@node Making your system robust
|
||||||
|
@section How to make your system robust
|
||||||
|
|
||||||
|
When you test a new kernel or a new OS, it is important to make sure
|
||||||
|
that your computer can boot even if the new system is unbootable. This
|
||||||
|
is crucial especially if you maintain servers or remote systems. To
|
||||||
|
accomplish this goal, you need to set up two things:
|
||||||
|
|
||||||
|
@enumerate
|
||||||
|
@item
|
||||||
|
You must maintain a system which is always bootable. For instance, if
|
||||||
|
you test a new kernel, you need to keep a working kernel in a
|
||||||
|
different place. And, it would sometimes be very nice to even have a
|
||||||
|
complete copy of a working system in a different partition or disk.
|
||||||
|
|
||||||
|
@item
|
||||||
|
You must direct GRUB to boot a working system when the new system
|
||||||
|
fails. This is possible with the @dfn{fallback} system in GRUB.
|
||||||
|
@end enumerate
|
||||||
|
|
||||||
|
The former requirement is very specific to each OS, so this
|
||||||
|
documentation does not cover that topic. It is better to consult some
|
||||||
|
backup tools.
|
||||||
|
|
||||||
|
So let's see the GRUB part. There are two possibilities: one of them
|
||||||
|
is quite simple but not very robust, and the other is a bit complex to
|
||||||
|
set up but probably the best solution to make sure that your system
|
||||||
|
can start as long as GRUB itself is bootable.
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Booting once-only::
|
||||||
|
* Booting fallback systems::
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Booting once-only
|
||||||
|
@subsection Booting once-only
|
||||||
|
|
||||||
|
You can teach GRUB to boot an entry only at next boot time. Suppose
|
||||||
|
that your have an old kernel @file{old_kernel} and a new kernel
|
||||||
|
@file{new_kernel}. You know that @file{old_kernel} can boot
|
||||||
|
your system correctly, and you want to test @file{new_kernel}.
|
||||||
|
|
||||||
|
To ensure that your system will go back to the old kernel even if the
|
||||||
|
new kernel fails (e.g. it panics), you can specify that GRUB should
|
||||||
|
try the new kernel only once and boot the old kernel after that.
|
||||||
|
|
||||||
|
First, modify your configuration file. Here is an example:
|
||||||
|
|
||||||
|
@group
|
||||||
|
@example
|
||||||
|
default saved # This is important!!!
|
||||||
|
timeout 10
|
||||||
|
|
||||||
|
title the old kernel
|
||||||
|
root (hd0,0)
|
||||||
|
kernel /old_kernel
|
||||||
|
savedefault
|
||||||
|
|
||||||
|
title the new kernel
|
||||||
|
root (hd0,0)
|
||||||
|
kernel /new_kernel
|
||||||
|
savedefault 0 # This is important!!!
|
||||||
|
@end example
|
||||||
|
@end group
|
||||||
|
|
||||||
|
Note that this configuration file uses @samp{default saved}
|
||||||
|
(@pxref{default}) at the head and @samp{savedefault 0}
|
||||||
|
(@pxref{savedefault}) in the entry for the new kernel. This means
|
||||||
|
that GRUB boots a saved entry by default, and booting the entry for the
|
||||||
|
new kernel saves @samp{0} as the saved entry.
|
||||||
|
|
||||||
|
With this configuration file, after all, GRUB always tries to boot the
|
||||||
|
old kernel after it booted the new one, because @samp{0} is the entry
|
||||||
|
of @code{the old kernel}.
|
||||||
|
|
||||||
|
The next step is to tell GRUB to boot the new kernel at next boot
|
||||||
|
time. For this, execute @command{grub-set-default} (@pxref{Invoking
|
||||||
|
grub-set-default}):
|
||||||
|
|
||||||
|
@example
|
||||||
|
# @kbd{grub-set-default 1}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
This command sets the saved entry to @samp{1}, that is, to the new
|
||||||
|
kernel.
|
||||||
|
|
||||||
|
This method is useful, but still not very robust, because GRUB stops
|
||||||
|
booting, if there is any error in the boot entry, such that the new
|
||||||
|
kernel has an invalid executable format. Thus, it it even better to
|
||||||
|
use the @dfn{fallback} mechanism of GRUB. Look at next subsection for
|
||||||
|
this feature.
|
||||||
|
|
||||||
|
|
||||||
|
@node Booting fallback systems
|
||||||
|
@subsection Booting fallback systems
|
||||||
|
|
||||||
|
GRUB supports a fallback mechanism of booting one or more other
|
||||||
|
entries if a default boot entry fails. You can specify multiple
|
||||||
|
fallback entries if you wish.
|
||||||
|
|
||||||
|
Suppose that you have three systems, @samp{A}, @samp{B} and
|
||||||
|
@samp{C}. @samp{A} is a system which you want to boot by
|
||||||
|
default. @samp{B} is a backup system which is supposed to boot
|
||||||
|
safely. @samp{C} is another backup system which is used in case where
|
||||||
|
@samp{B} is broken.
|
||||||
|
|
||||||
|
Then you may want GRUB to boot the first system which is bootable
|
||||||
|
among @samp{A}, @samp{B} and @samp{C}. A configuration file can be
|
||||||
|
written in this way:
|
||||||
|
|
||||||
|
@group
|
||||||
|
@example
|
||||||
|
default saved # This is important!!!
|
||||||
|
timeout 10
|
||||||
|
fallback 1 2 # This is important!!!
|
||||||
|
|
||||||
|
title A
|
||||||
|
root (hd0,0)
|
||||||
|
kernel /kernel
|
||||||
|
savedefault fallback # This is important!!!
|
||||||
|
|
||||||
|
title B
|
||||||
|
root (hd1,0)
|
||||||
|
kernel /kernel
|
||||||
|
savedefault fallback # This is important!!!
|
||||||
|
|
||||||
|
title C
|
||||||
|
root (hd2,0)
|
||||||
|
kernel /kernel
|
||||||
|
savedefault
|
||||||
|
@end example
|
||||||
|
@end group
|
||||||
|
|
||||||
|
Note that @samp{default saved} (@pxref{default}), @samp{fallback 1 2}
|
||||||
|
and @samp{savedefault fallback} are used. GRUB will boot a saved entry
|
||||||
|
by default and save a fallback entry as next boot entry with this
|
||||||
|
configuration.
|
||||||
|
|
||||||
|
When GRUB tries to boot @samp{A}, GRUB saves @samp{1} as next boot
|
||||||
|
entry, because the command @command{fallback} specifies that @samp{1}
|
||||||
|
is the first fallback entry. The entry @samp{1} is @samp{B}, so GRUB
|
||||||
|
will try to boot @samp{B} at next boot time.
|
||||||
|
|
||||||
|
Likewise, when GRUB tries to boot @samp{B}, GRUB saves @samp{2} as
|
||||||
|
next boot entry, because @command{fallback} specifies @samp{2} as next
|
||||||
|
fallback entry. This makes sure that GRUB will boot @samp{C} after
|
||||||
|
booting @samp{B}.
|
||||||
|
|
||||||
|
It is noteworthy that GRUB uses fallback entries both when GRUB
|
||||||
|
itself fails in booting an entry and when @samp{A} or @samp{B} fails
|
||||||
|
in starting up your system. So this solution ensures that your system
|
||||||
|
is started even if GRUB cannot find your kernel or if your kernel
|
||||||
|
panics.
|
||||||
|
|
||||||
|
However, you need to run @command{grub-set-default} (@pxref{Invoking
|
||||||
|
grub-set-default}) when @samp{A} starts correctly or you fix @samp{A}
|
||||||
|
after it crashes, since GRUB always sets next boot entry to a fallback
|
||||||
|
entry. You should run this command in a startup script such as
|
||||||
|
@file{rc.local} to boot @samp{A} by default:
|
||||||
|
|
||||||
|
@example
|
||||||
|
# @kbd{grub-set-default 0}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
where @samp{0} is the number of the boot entry for the system
|
||||||
|
@samp{A}.
|
||||||
|
|
||||||
|
If you want to see what is current default entry, you can look at the
|
||||||
|
file @file{/boot/grub/default} (or @file{/grub/default} in
|
||||||
|
some systems). Because this file is plain-text, you can just
|
||||||
|
@command{cat} this file. But it is strongly recommended @strong{not to
|
||||||
|
modify this file directly}, because GRUB may fail in saving a default
|
||||||
|
entry in this file, if you change this file in an unintended
|
||||||
|
manner. Therefore, you should use @command{grub-set-default} when you
|
||||||
|
need to change the default entry.
|
||||||
|
|
||||||
|
|
||||||
@node Configuration
|
@node Configuration
|
||||||
@chapter Configuration
|
@chapter Configuration
|
||||||
|
|
||||||
|
@ -1952,12 +2137,13 @@ default entry is the entry saved with the command
|
||||||
@node fallback
|
@node fallback
|
||||||
@subsection fallback
|
@subsection fallback
|
||||||
|
|
||||||
@deffn Command fallback num
|
@deffn Command fallback num...
|
||||||
Go into unattended boot mode: if the default boot entry has any errors,
|
Go into unattended boot mode: if the default boot entry has any errors,
|
||||||
instead of waiting for the user to do something, immediately start
|
instead of waiting for the user to do something, immediately start
|
||||||
over using the @var{num} entry (same numbering as the @code{default}
|
over using the @var{num} entry (same numbering as the @code{default}
|
||||||
command (@pxref{default})). This obviously won't help if the machine was
|
command (@pxref{default})). This obviously won't help if the machine was
|
||||||
rebooted by a kernel that GRUB loaded.
|
rebooted by a kernel that GRUB loaded. You can specify multiple
|
||||||
|
fallback entry numbers.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@ -2962,8 +3148,9 @@ derived from attempting the mount will @emph{not} work correctly.
|
||||||
@node savedefault
|
@node savedefault
|
||||||
@subsection savedefault
|
@subsection savedefault
|
||||||
|
|
||||||
@deffn Command savedefault
|
@deffn Command savedefault num
|
||||||
Save the current menu entry as a default entry. Here is an example:
|
Save the current menu entry or @var{num} if specified as a default
|
||||||
|
entry. Here is an example:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
@group
|
@group
|
||||||
|
@ -2984,7 +3171,13 @@ savedefault
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
With this configuration, GRUB will choose the entry booted previously as
|
With this configuration, GRUB will choose the entry booted previously as
|
||||||
the default entry. See also @ref{default}.
|
the default entry.
|
||||||
|
|
||||||
|
You can specify @samp{fallback} instead of a number. Then, next
|
||||||
|
fallback entry is saved. Next fallback entry is chosen from fallback
|
||||||
|
entries. Normally, this will be the first entry in fallback ones.
|
||||||
|
|
||||||
|
See also @ref{default} and @ref{Invoking grub-set-default}.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
|
|
||||||
|
@ -3559,6 +3752,68 @@ You must specify one argument to this command. For example:
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
|
||||||
|
@node Invoking grub-set-default
|
||||||
|
@chapter Invoking grub-set-default
|
||||||
|
|
||||||
|
The program @command{grub-set-default} sets the default boot entry for
|
||||||
|
GRUB. This automatically creates a file named @file{default} under
|
||||||
|
your GRUB directory (i.e. @file{/boot/grub}), if it is not
|
||||||
|
present. This file is used to determine the default boot entry when
|
||||||
|
GRUB boots up your system when you use @samp{default saved} in your
|
||||||
|
configuration file (@pxref{default}), and to save next default boot
|
||||||
|
entry when you use @samp{savedefault} in a boot entry
|
||||||
|
(@pxref{savedefault}).
|
||||||
|
|
||||||
|
@command{grub-set-default} accepts the following options:
|
||||||
|
|
||||||
|
@table @option
|
||||||
|
@item --help
|
||||||
|
Print a summary of the command-line options and exit.
|
||||||
|
|
||||||
|
@item --version
|
||||||
|
Print the version information and exit.
|
||||||
|
|
||||||
|
@item --root-directory=@var{dir}
|
||||||
|
Use the directory @var{dir} instead of the root directory
|
||||||
|
(i.e. @file{/}) to define the location of the default file. This
|
||||||
|
is useful when you mount a disk which is used for another system.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
You must specify a single argument to @command{grub-set-default}. This
|
||||||
|
argument is normally the number of a default boot entry. For example,
|
||||||
|
if you have this configuration file:
|
||||||
|
|
||||||
|
@group
|
||||||
|
@example
|
||||||
|
default saved
|
||||||
|
timeout 10
|
||||||
|
|
||||||
|
title GNU/Hurd
|
||||||
|
root (hd0,0)
|
||||||
|
...
|
||||||
|
|
||||||
|
title GNU/Linux
|
||||||
|
root (hd0,1)
|
||||||
|
...
|
||||||
|
@end example
|
||||||
|
@end group
|
||||||
|
|
||||||
|
and if you want to set the next default boot entry to GNU/Linux, you
|
||||||
|
may execute this command:
|
||||||
|
|
||||||
|
@example
|
||||||
|
@kbd{grub-set-default 1}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Because the entry for GNU/Linux is @samp{1}. Note that entries are
|
||||||
|
counted from zero. So, if you want to specify GNU/Hurd here, then you
|
||||||
|
should specify @samp{0}.
|
||||||
|
|
||||||
|
This feature is very useful if you want to test a new kernel or to
|
||||||
|
make your system quite robust. @xref{Making your system robust}, for
|
||||||
|
more hints about how to set up a robust system.
|
||||||
|
|
||||||
|
|
||||||
@node Invoking mbchk
|
@node Invoking mbchk
|
||||||
@chapter Invoking mbchk
|
@chapter Invoking mbchk
|
||||||
|
|
||||||
|
@ -3695,27 +3950,12 @@ Once we get your report, we will try to fix the bugs.
|
||||||
@node Future
|
@node Future
|
||||||
@chapter Where GRUB will go
|
@chapter Where GRUB will go
|
||||||
|
|
||||||
Here are some ideas of what might happen in the future:
|
We started the next generation of GRUB, GRUB 2. This will include
|
||||||
|
internationalization, dynamic module loading, real memory management,
|
||||||
@itemize @bullet
|
multiple architecture support, a scripting language, and many other
|
||||||
@item
|
nice feature. If you are interested in the development of GRUB 2, take
|
||||||
Support dynamic loading.
|
a look at @uref{http://www.gnu.org/software/grub/grub.html, the
|
||||||
|
homepage}.
|
||||||
@item
|
|
||||||
Add real memory management.
|
|
||||||
|
|
||||||
@item
|
|
||||||
Add a real scripting language.
|
|
||||||
|
|
||||||
@item
|
|
||||||
Support internationalization.
|
|
||||||
|
|
||||||
@item
|
|
||||||
Support other architectures than i386-pc.
|
|
||||||
@end itemize
|
|
||||||
|
|
||||||
See the file @file{TODO} in the source distribution, for more
|
|
||||||
information.
|
|
||||||
|
|
||||||
|
|
||||||
@c Separate the programming guide.
|
@c Separate the programming guide.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@set UPDATED 11 May 2004
|
@set UPDATED 20 June 2004
|
||||||
@set UPDATED-MONTH May 2004
|
@set UPDATED-MONTH June 2004
|
||||||
@set EDITION 0.95
|
@set EDITION 0.95
|
||||||
@set VERSION 0.95
|
@set VERSION 0.95
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@set UPDATED 11 May 2004
|
@set UPDATED 20 June 2004
|
||||||
@set UPDATED-MONTH May 2004
|
@set UPDATED-MONTH June 2004
|
||||||
@set EDITION 0.95
|
@set EDITION 0.95
|
||||||
@set VERSION 0.95
|
@set VERSION 0.95
|
||||||
|
|
|
@ -87,6 +87,7 @@ ENTRY(main)
|
||||||
|
|
||||||
VARIABLE(install_partition)
|
VARIABLE(install_partition)
|
||||||
.long 0xFFFFFF
|
.long 0xFFFFFF
|
||||||
|
/* This variable is here only because of a historical reason. */
|
||||||
VARIABLE(saved_entryno)
|
VARIABLE(saved_entryno)
|
||||||
.long 0
|
.long 0
|
||||||
VARIABLE(stage2_id)
|
VARIABLE(stage2_id)
|
||||||
|
|
|
@ -59,7 +59,8 @@ int debug = 0;
|
||||||
/* The default entry. */
|
/* The default entry. */
|
||||||
int default_entry = 0;
|
int default_entry = 0;
|
||||||
/* The fallback entry. */
|
/* The fallback entry. */
|
||||||
int fallback_entry = -1;
|
int fallback_entryno;
|
||||||
|
int fallback_entries[MAX_FALLBACK_ENTRIES];
|
||||||
/* The number of current entry. */
|
/* The number of current entry. */
|
||||||
int current_entryno;
|
int current_entryno;
|
||||||
/* The address for Multiboot command-line buffer. */
|
/* The address for Multiboot command-line buffer. */
|
||||||
|
@ -97,7 +98,8 @@ init_config (void)
|
||||||
{
|
{
|
||||||
default_entry = 0;
|
default_entry = 0;
|
||||||
password = 0;
|
password = 0;
|
||||||
fallback_entry = -1;
|
fallback_entryno = -1;
|
||||||
|
fallback_entries[0] = -1;
|
||||||
grub_timeout = -1;
|
grub_timeout = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1143,9 +1145,35 @@ static struct builtin builtin_embed =
|
||||||
static int
|
static int
|
||||||
fallback_func (char *arg, int flags)
|
fallback_func (char *arg, int flags)
|
||||||
{
|
{
|
||||||
if (! safe_parse_maxint (&arg, &fallback_entry))
|
int i = 0;
|
||||||
|
|
||||||
|
while (*arg)
|
||||||
|
{
|
||||||
|
int entry;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
if (! safe_parse_maxint (&arg, &entry))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
/* Remove duplications to prevent infinite looping. */
|
||||||
|
for (j = 0; j < i; j++)
|
||||||
|
if (entry == fallback_entries[j])
|
||||||
|
break;
|
||||||
|
if (j != i)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
fallback_entries[i++] = entry;
|
||||||
|
if (i == MAX_FALLBACK_ENTRIES)
|
||||||
|
break;
|
||||||
|
|
||||||
|
arg = skip_to (0, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i < MAX_FALLBACK_ENTRIES)
|
||||||
|
fallback_entries[i] = -1;
|
||||||
|
|
||||||
|
fallback_entryno = (i == 0) ? -1 : 0;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1155,7 +1183,7 @@ static struct builtin builtin_fallback =
|
||||||
fallback_func,
|
fallback_func,
|
||||||
BUILTIN_MENU,
|
BUILTIN_MENU,
|
||||||
#if 0
|
#if 0
|
||||||
"fallback NUM",
|
"fallback NUM...",
|
||||||
"Go into unattended boot mode: if the default boot entry has any"
|
"Go into unattended boot mode: if the default boot entry has any"
|
||||||
" errors, instead of waiting for the user to do anything, it"
|
" errors, instead of waiting for the user to do anything, it"
|
||||||
" immediately starts over using the NUM entry (same numbering as the"
|
" immediately starts over using the NUM entry (same numbering as the"
|
||||||
|
@ -3185,8 +3213,29 @@ static int
|
||||||
savedefault_func (char *arg, int flags)
|
savedefault_func (char *arg, int flags)
|
||||||
{
|
{
|
||||||
#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
|
#if !defined(SUPPORT_DISKLESS) && !defined(GRUB_UTIL)
|
||||||
char buffer[512];
|
unsigned long tmp_drive = saved_drive;
|
||||||
int *entryno_ptr;
|
unsigned long tmp_partition = saved_partition;
|
||||||
|
char *default_file = (char *) DEFAULT_FILE_BUF;
|
||||||
|
char buf[10];
|
||||||
|
char sect[SECTOR_SIZE];
|
||||||
|
int entryno;
|
||||||
|
int sector_count = 0;
|
||||||
|
int saved_sectors[2];
|
||||||
|
int saved_offsets[2];
|
||||||
|
int saved_lengths[2];
|
||||||
|
|
||||||
|
/* Save sector information about at most two sectors. */
|
||||||
|
auto void disk_read_savesect_func (int sector, int offset, int length);
|
||||||
|
void disk_read_savesect_func (int sector, int offset, int length)
|
||||||
|
{
|
||||||
|
if (sector_count < 2)
|
||||||
|
{
|
||||||
|
saved_sectors[sector_count] = sector;
|
||||||
|
saved_offsets[sector_count] = offset;
|
||||||
|
saved_lengths[sector_count] = length;
|
||||||
|
}
|
||||||
|
sector_count++;
|
||||||
|
}
|
||||||
|
|
||||||
/* This command is only useful when you boot an entry from the menu
|
/* This command is only useful when you boot an entry from the menu
|
||||||
interface. */
|
interface. */
|
||||||
|
@ -3196,45 +3245,109 @@ savedefault_func (char *arg, int flags)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the geometry of the boot drive (i.e. the disk which contains
|
/* Determine a saved entry number. */
|
||||||
this stage2). */
|
if (*arg)
|
||||||
if (get_diskinfo (boot_drive, &buf_geom))
|
|
||||||
{
|
{
|
||||||
errnum = ERR_NO_DISK;
|
if (grub_memcmp (arg, "fallback", sizeof ("fallback") - 1) == 0)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_FALLBACK_ENTRIES; i++)
|
||||||
|
{
|
||||||
|
if (fallback_entries[i] < 0)
|
||||||
|
break;
|
||||||
|
if (fallback_entries[i] == current_entryno)
|
||||||
|
{
|
||||||
|
index = i + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index >= MAX_FALLBACK_ENTRIES || fallback_entries[index] < 0)
|
||||||
|
{
|
||||||
|
/* This is the last. */
|
||||||
|
errnum = ERR_BAD_ARGUMENT;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load the second sector of this stage2. */
|
entryno = fallback_entries[index];
|
||||||
if (! rawread (boot_drive, install_second_sector, 0, SECTOR_SIZE, buffer))
|
}
|
||||||
{
|
else if (! safe_parse_maxint (&arg, &entryno))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
entryno = current_entryno;
|
||||||
|
|
||||||
/* Sanity check. */
|
/* Open the default file. */
|
||||||
if (buffer[STAGE2_STAGE2_ID] != STAGE2_ID_STAGE2
|
saved_drive = boot_drive;
|
||||||
|| *((short *) (buffer + STAGE2_VER_MAJ_OFFS)) != COMPAT_VERSION)
|
saved_partition = install_partition;
|
||||||
|
if (grub_open (default_file))
|
||||||
{
|
{
|
||||||
errnum = ERR_BAD_VERSION;
|
int len;
|
||||||
return 1;
|
|
||||||
|
disk_read_hook = disk_read_savesect_func;
|
||||||
|
len = grub_read (buf, sizeof (buf));
|
||||||
|
disk_read_hook = 0;
|
||||||
|
grub_close ();
|
||||||
|
|
||||||
|
if (len != sizeof (buf))
|
||||||
|
{
|
||||||
|
/* This is too small. Do not modify the file manually, please! */
|
||||||
|
errnum = ERR_READ;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
entryno_ptr = (int *) (buffer + STAGE2_SAVED_ENTRYNO);
|
if (sector_count > 2)
|
||||||
|
|
||||||
/* Check if the saved entry number differs from current entry number. */
|
|
||||||
if (*entryno_ptr != current_entryno)
|
|
||||||
{
|
{
|
||||||
/* Overwrite the saved entry number. */
|
/* Is this possible?! Too fragmented! */
|
||||||
*entryno_ptr = current_entryno;
|
errnum = ERR_FSYS_CORRUPT;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* Save the image in the disk. */
|
/* Set up a string to be written. */
|
||||||
if (! rawwrite (boot_drive, install_second_sector, buffer))
|
grub_memset (buf, '\n', sizeof (buf));
|
||||||
return 1;
|
grub_sprintf (buf, "%d", entryno);
|
||||||
|
|
||||||
|
if (saved_lengths[0] < sizeof (buf))
|
||||||
|
{
|
||||||
|
/* The file is anchored to another file and the first few bytes
|
||||||
|
are spanned in two sectors. Uggh... */
|
||||||
|
if (! rawread (current_drive, saved_sectors[0], 0, SECTOR_SIZE,
|
||||||
|
sect))
|
||||||
|
goto fail;
|
||||||
|
grub_memmove (sect + saved_offsets[0], buf, saved_lengths[0]);
|
||||||
|
if (! rawwrite (current_drive, saved_sectors[0], sect))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (! rawread (current_drive, saved_sectors[1], 0, SECTOR_SIZE,
|
||||||
|
sect))
|
||||||
|
goto fail;
|
||||||
|
grub_memmove (sect + saved_offsets[1],
|
||||||
|
buf + saved_lengths[0],
|
||||||
|
sizeof (buf) - saved_lengths[0]);
|
||||||
|
if (! rawwrite (current_drive, saved_sectors[1], sect))
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This is a simple case. It fits into a single sector. */
|
||||||
|
if (! rawread (current_drive, saved_sectors[0], 0, SECTOR_SIZE,
|
||||||
|
sect))
|
||||||
|
goto fail;
|
||||||
|
grub_memmove (sect + saved_offsets[0], buf, sizeof (buf));
|
||||||
|
if (! rawwrite (current_drive, saved_sectors[0], sect))
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
/* Clear the cache. */
|
/* Clear the cache. */
|
||||||
buf_track = -1;
|
buf_track = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
fail:
|
||||||
|
saved_drive = tmp_drive;
|
||||||
|
saved_partition = tmp_partition;
|
||||||
|
return errnum;
|
||||||
#else /* ! SUPPORT_DISKLESS && ! GRUB_UTIL */
|
#else /* ! SUPPORT_DISKLESS && ! GRUB_UTIL */
|
||||||
errnum = ERR_UNRECOGNIZED;
|
errnum = ERR_UNRECOGNIZED;
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -3246,8 +3359,10 @@ static struct builtin builtin_savedefault =
|
||||||
"savedefault",
|
"savedefault",
|
||||||
savedefault_func,
|
savedefault_func,
|
||||||
BUILTIN_CMDLINE,
|
BUILTIN_CMDLINE,
|
||||||
"savedefault",
|
"savedefault [NUM | `fallback']",
|
||||||
"Save the current entry as the default boot entry."
|
"Save the current entry as the default boot entry if no argument is"
|
||||||
|
" specified. If a number is specified, this number is saved. If"
|
||||||
|
" `fallback' is used, next fallback entry is saved."
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -201,7 +201,7 @@ run_script (char *script, char *heap)
|
||||||
|
|
||||||
/* If a fallback entry is defined, don't prompt a user's
|
/* If a fallback entry is defined, don't prompt a user's
|
||||||
intervention. */
|
intervention. */
|
||||||
if (fallback_entry < 0)
|
if (fallback_entryno >= 0)
|
||||||
{
|
{
|
||||||
grub_printf ("\nPress any key to continue...");
|
grub_printf ("\nPress any key to continue...");
|
||||||
(void) getkey ();
|
(void) getkey ();
|
||||||
|
|
|
@ -97,8 +97,12 @@ extern char *grub_scratch_mem;
|
||||||
#define PASSWORD_BUF RAW_ADDR (0x78000)
|
#define PASSWORD_BUF RAW_ADDR (0x78000)
|
||||||
#define PASSWORD_BUFLEN 0x200
|
#define PASSWORD_BUFLEN 0x200
|
||||||
|
|
||||||
|
/* THe buffer for the filename of "/boot/grub/default". */
|
||||||
|
#define DEFAULT_FILE_BUF (PASSWORD_BUF + PASSWORD_BUFLEN)
|
||||||
|
#define DEFAULT_FILE_BUFLEN 0x60
|
||||||
|
|
||||||
/* The buffer for the command-line. */
|
/* The buffer for the command-line. */
|
||||||
#define CMDLINE_BUF (PASSWORD_BUF + PASSWORD_BUFLEN)
|
#define CMDLINE_BUF (DEFAULT_FILE_BUF + DEFAULT_FILE_BUFLEN)
|
||||||
#define CMDLINE_BUFLEN MAX_CMDLINE
|
#define CMDLINE_BUFLEN MAX_CMDLINE
|
||||||
|
|
||||||
/* The kill buffer for the command-line. */
|
/* The kill buffer for the command-line. */
|
||||||
|
@ -120,7 +124,7 @@ extern char *grub_scratch_mem;
|
||||||
|
|
||||||
/* The buffer for the menu entries. */
|
/* The buffer for the menu entries. */
|
||||||
#define MENU_BUF (UNIQUE_BUF + UNIQUE_BUFLEN)
|
#define MENU_BUF (UNIQUE_BUF + UNIQUE_BUFLEN)
|
||||||
#define MENU_BUFLEN (0x8000 + PASSWORD_BUF - UNIQUE_BUF)
|
#define MENU_BUFLEN (0x8000 + PASSWORD_BUF - MENU_BUF)
|
||||||
|
|
||||||
/* The size of the drive map. */
|
/* The size of the drive map. */
|
||||||
#define DRIVE_MAP_SIZE 8
|
#define DRIVE_MAP_SIZE 8
|
||||||
|
@ -585,7 +589,9 @@ extern void assign_device_name (int drive, const char *device);
|
||||||
|
|
||||||
#ifndef STAGE1_5
|
#ifndef STAGE1_5
|
||||||
/* GUI interface variables. */
|
/* GUI interface variables. */
|
||||||
extern int fallback_entry;
|
# define MAX_FALLBACK_ENTRIES 8
|
||||||
|
extern int fallback_entries[MAX_FALLBACK_ENTRIES];
|
||||||
|
extern int fallback_entryno;
|
||||||
extern int default_entry;
|
extern int default_entry;
|
||||||
extern int current_entryno;
|
extern int current_entryno;
|
||||||
|
|
||||||
|
|
|
@ -390,7 +390,7 @@ restart:
|
||||||
gotoxy (3, 22);
|
gotoxy (3, 22);
|
||||||
printf (" ");
|
printf (" ");
|
||||||
grub_timeout = -1;
|
grub_timeout = -1;
|
||||||
fallback_entry = -1;
|
fallback_entryno = -1;
|
||||||
if (! (current_term->flags & TERM_DUMB))
|
if (! (current_term->flags & TERM_DUMB))
|
||||||
gotoxy (74, 4 + entryno);
|
gotoxy (74, 4 + entryno);
|
||||||
}
|
}
|
||||||
|
@ -731,15 +731,18 @@ restart:
|
||||||
|
|
||||||
if (run_script (cur_entry, heap))
|
if (run_script (cur_entry, heap))
|
||||||
{
|
{
|
||||||
if (fallback_entry < 0)
|
if (fallback_entryno >= 0)
|
||||||
break;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
cur_entry = NULL;
|
cur_entry = NULL;
|
||||||
first_entry = 0;
|
first_entry = 0;
|
||||||
entryno = fallback_entry;
|
entryno = fallback_entries[fallback_entryno];
|
||||||
fallback_entry = -1;
|
fallback_entryno++;
|
||||||
|
if (fallback_entryno >= MAX_FALLBACK_ENTRIES
|
||||||
|
|| fallback_entries[fallback_entryno] < 0)
|
||||||
|
fallback_entryno = -1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
@ -864,6 +867,36 @@ cmain (void)
|
||||||
if (use_config_file)
|
if (use_config_file)
|
||||||
#endif /* GRUB_UTIL */
|
#endif /* GRUB_UTIL */
|
||||||
{
|
{
|
||||||
|
char *default_file = (char *) DEFAULT_FILE_BUF;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Get a saved default entry if possible. */
|
||||||
|
saved_entryno = 0;
|
||||||
|
grub_strncat (default_file, config_file, DEFAULT_FILE_BUFLEN);
|
||||||
|
for (i = grub_strlen(default_file); i >= 0; i--)
|
||||||
|
if (default_file[i] == '/')
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
grub_strncat (default_file + i, "default", DEFAULT_FILE_BUFLEN - i);
|
||||||
|
if (grub_open (default_file))
|
||||||
|
{
|
||||||
|
char buf[10]; /* This is good enough. */
|
||||||
|
char *p = buf;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = grub_read (buf, sizeof (buf));
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
buf[sizeof (buf) - 1] = 0;
|
||||||
|
safe_parse_maxint (&p, &saved_entryno);
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_close ();
|
||||||
|
}
|
||||||
|
errnum = ERR_NONE;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* STATE 0: Before any title command.
|
/* STATE 0: Before any title command.
|
||||||
|
@ -970,15 +1003,41 @@ cmain (void)
|
||||||
menu_len);
|
menu_len);
|
||||||
menu_entries = config_entries + config_len;
|
menu_entries = config_entries + config_len;
|
||||||
|
|
||||||
|
/* Make sure that all fallback entries are valid. */
|
||||||
|
if (fallback_entryno >= 0)
|
||||||
|
{
|
||||||
|
for (i = 0; i < MAX_FALLBACK_ENTRIES; i++)
|
||||||
|
{
|
||||||
|
if (fallback_entries[i] < 0)
|
||||||
|
break;
|
||||||
|
if (fallback_entries[i] >= num_entries)
|
||||||
|
{
|
||||||
|
grub_memmove (fallback_entries + i,
|
||||||
|
fallback_entries + i + 1,
|
||||||
|
((MAX_FALLBACK_ENTRIES - i - 1)
|
||||||
|
* sizeof (int)));
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fallback_entries[0] < 0)
|
||||||
|
fallback_entryno = -1;
|
||||||
|
}
|
||||||
/* Check if the default entry is present. Otherwise reset
|
/* Check if the default entry is present. Otherwise reset
|
||||||
it to fallback if fallback is valid, or to DEFAULT_ENTRY
|
it to fallback if fallback is valid, or to DEFAULT_ENTRY
|
||||||
if not. */
|
if not. */
|
||||||
if (default_entry >= num_entries)
|
if (default_entry >= num_entries)
|
||||||
{
|
{
|
||||||
if (fallback_entry < 0 || fallback_entry >= num_entries)
|
if (fallback_entryno >= 0)
|
||||||
default_entry = 0;
|
{
|
||||||
|
default_entry = fallback_entries[0];
|
||||||
|
fallback_entryno++;
|
||||||
|
if (fallback_entryno >= MAX_FALLBACK_ENTRIES
|
||||||
|
|| fallback_entries[fallback_entryno] < 0)
|
||||||
|
fallback_entryno = -1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
default_entry = fallback_entry;
|
default_entry = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_preset)
|
if (is_preset)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
bin_PROGRAMS = mbchk
|
bin_PROGRAMS = mbchk
|
||||||
sbin_SCRIPTS = grub-install grub-md5-crypt grub-terminfo
|
sbin_SCRIPTS = grub-install grub-md5-crypt grub-terminfo \
|
||||||
|
grub-set-default
|
||||||
noinst_SCRIPTS = grub-image mkbimage
|
noinst_SCRIPTS = grub-image mkbimage
|
||||||
|
|
||||||
EXTRA_DIST = mkbimage
|
EXTRA_DIST = mkbimage
|
||||||
|
|
|
@ -42,7 +42,8 @@ bin_PROGRAMS = mbchk$(EXEEXT)
|
||||||
subdir = util
|
subdir = util
|
||||||
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
|
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
|
||||||
$(srcdir)/grub-image.in $(srcdir)/grub-install.in \
|
$(srcdir)/grub-image.in $(srcdir)/grub-install.in \
|
||||||
$(srcdir)/grub-md5-crypt.in $(srcdir)/grub-terminfo.in
|
$(srcdir)/grub-md5-crypt.in $(srcdir)/grub-set-default.in \
|
||||||
|
$(srcdir)/grub-terminfo.in
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
|
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
|
||||||
$(top_srcdir)/configure.ac
|
$(top_srcdir)/configure.ac
|
||||||
|
@ -51,7 +52,7 @@ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||||
CONFIG_HEADER = $(top_builddir)/config.h
|
CONFIG_HEADER = $(top_builddir)/config.h
|
||||||
CONFIG_CLEAN_FILES = grub-image grub-install grub-md5-crypt \
|
CONFIG_CLEAN_FILES = grub-image grub-install grub-md5-crypt \
|
||||||
grub-terminfo
|
grub-terminfo grub-set-default
|
||||||
am__installdirs = $(DESTDIR)$(bindir) $(DESTDIR)$(sbindir)
|
am__installdirs = $(DESTDIR)$(bindir) $(DESTDIR)$(sbindir)
|
||||||
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
|
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
|
||||||
PROGRAMS = $(bin_PROGRAMS)
|
PROGRAMS = $(bin_PROGRAMS)
|
||||||
|
@ -180,7 +181,9 @@ sbindir = @sbindir@
|
||||||
sharedstatedir = @sharedstatedir@
|
sharedstatedir = @sharedstatedir@
|
||||||
sysconfdir = @sysconfdir@
|
sysconfdir = @sysconfdir@
|
||||||
target_alias = @target_alias@
|
target_alias = @target_alias@
|
||||||
sbin_SCRIPTS = grub-install grub-md5-crypt grub-terminfo
|
sbin_SCRIPTS = grub-install grub-md5-crypt grub-terminfo \
|
||||||
|
grub-set-default
|
||||||
|
|
||||||
noinst_SCRIPTS = grub-image mkbimage
|
noinst_SCRIPTS = grub-image mkbimage
|
||||||
EXTRA_DIST = mkbimage
|
EXTRA_DIST = mkbimage
|
||||||
|
|
||||||
|
@ -229,6 +232,8 @@ grub-md5-crypt: $(top_builddir)/config.status $(srcdir)/grub-md5-crypt.in
|
||||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
|
||||||
grub-terminfo: $(top_builddir)/config.status $(srcdir)/grub-terminfo.in
|
grub-terminfo: $(top_builddir)/config.status $(srcdir)/grub-terminfo.in
|
||||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
|
||||||
|
grub-set-default: $(top_builddir)/config.status $(srcdir)/grub-set-default.in
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
|
||||||
install-binPROGRAMS: $(bin_PROGRAMS)
|
install-binPROGRAMS: $(bin_PROGRAMS)
|
||||||
@$(NORMAL_INSTALL)
|
@$(NORMAL_INSTALL)
|
||||||
$(mkdir_p) $(DESTDIR)$(bindir)
|
$(mkdir_p) $(DESTDIR)$(bindir)
|
||||||
|
|
|
@ -30,6 +30,7 @@ host_vendor=@host_vendor@
|
||||||
pkgdatadir=${datadir}/${PACKAGE}/${host_cpu}-${host_vendor}
|
pkgdatadir=${datadir}/${PACKAGE}/${host_cpu}-${host_vendor}
|
||||||
|
|
||||||
grub_shell=${sbindir}/grub
|
grub_shell=${sbindir}/grub
|
||||||
|
grub_set_default=${sbindir}/grub-set-default
|
||||||
log_file=/tmp/grub-install.log.$$
|
log_file=/tmp/grub-install.log.$$
|
||||||
img_file=/tmp/grub-install.img.$$
|
img_file=/tmp/grub-install.img.$$
|
||||||
rootdir=
|
rootdir=
|
||||||
|
@ -273,8 +274,8 @@ fi
|
||||||
|
|
||||||
# Initialize these directories here, since ROOTDIR was initialized.
|
# Initialize these directories here, since ROOTDIR was initialized.
|
||||||
case "$host_os" in
|
case "$host_os" in
|
||||||
netbsd*)
|
netbsd* | openbsd*)
|
||||||
# Because /boot is used for the boot block in NetBSD, use /grub
|
# Because /boot is used for the boot block in NetBSD and OpenBSD, use /grub
|
||||||
# instead of /boot/grub.
|
# instead of /boot/grub.
|
||||||
grub_prefix=/grub
|
grub_prefix=/grub
|
||||||
bootdir=${rootdir}
|
bootdir=${rootdir}
|
||||||
|
@ -410,6 +411,9 @@ for file in \
|
||||||
cp -f $file ${grubdir} || exit 1
|
cp -f $file ${grubdir} || exit 1
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# Make a default file.
|
||||||
|
${grub_set_default} --root-directory=${rootdir} default
|
||||||
|
|
||||||
# Make sure that GRUB reads the same images as the host OS.
|
# Make sure that GRUB reads the same images as the host OS.
|
||||||
test -n "$mkimg" && img_file=`$mkimg`
|
test -n "$mkimg" && img_file=`$mkimg`
|
||||||
test -n "$mklog" && log_file=`$mklog`
|
test -n "$mklog" && log_file=`$mklog`
|
||||||
|
|
114
util/grub-set-default.in
Normal file
114
util/grub-set-default.in
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
# Set a default boot entry for GRUB
|
||||||
|
# Copyright (C) 2004 Free Software Foundation, Inc.
|
||||||
|
#
|
||||||
|
# This file is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful, but
|
||||||
|
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
# General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
# Initialize some variables.
|
||||||
|
PACKAGE=@PACKAGE@
|
||||||
|
VERSION=@VERSION@
|
||||||
|
|
||||||
|
rootdir=
|
||||||
|
entry=
|
||||||
|
|
||||||
|
# Usage: usage
|
||||||
|
# Print the usage.
|
||||||
|
usage () {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: grub-set-default [OPTION] entry
|
||||||
|
Set the default boot entry for GRUB.
|
||||||
|
|
||||||
|
-h, --help print this message and exit
|
||||||
|
-v, --version print the version information and exit
|
||||||
|
--root-directory=DIR Use the directory DIR instead of the root directory
|
||||||
|
|
||||||
|
ENTRY is a number or the special keyword \`default'.
|
||||||
|
|
||||||
|
Report bugs to <bug-grub@gnu.org>.
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check the arguments.
|
||||||
|
for option in "$@"; do
|
||||||
|
case "$option" in
|
||||||
|
-h | --help)
|
||||||
|
usage
|
||||||
|
exit 0 ;;
|
||||||
|
-v | --version)
|
||||||
|
echo "grub-set-default (GNU GRUB ${VERSION})"
|
||||||
|
exit 0 ;;
|
||||||
|
--root-directory=*)
|
||||||
|
rootdir=`echo "$option" | sed 's/--root-directory=//'` ;;
|
||||||
|
-*)
|
||||||
|
echo "Unrecognized option \`$option'" 1>&2
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if test "x$entry" != x; then
|
||||||
|
echo "More than one entries?" 1>&2
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# We don't care about what the user specified actually.
|
||||||
|
entry="${option}" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if test "x$entry" = x; then
|
||||||
|
echo "entry not specified." 1>&2
|
||||||
|
usage
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Determine the GRUB directory. This is different among OSes.
|
||||||
|
grubdir=${rootdir}/boot/grub
|
||||||
|
if test -d ${grubdir}; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
grubdir=${rootdir}/grub
|
||||||
|
if test -d ${grubdir}; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
echo "No GRUB directory found under ${rootdir}/" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
file=${grubdir}/default
|
||||||
|
if test -f ${file}; then
|
||||||
|
chmod 0600 ${file}
|
||||||
|
rm -f ${file}
|
||||||
|
fi
|
||||||
|
cat <<EOF > $file
|
||||||
|
$entry
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# WARNING: If you want to edit this file directly, do not remove any line
|
||||||
|
# from this file, including this warning. Using `grub-set-default' is
|
||||||
|
# strongly recommended.
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Bye.
|
||||||
|
exit 0
|
Loading…
Add table
Add a link
Reference in a new issue