mirror of
https://git.savannah.gnu.org/git/grub.git
synced 2026-10-22 07:12:39 +00:00
2963 lines
95 KiB
Plaintext
2963 lines
95 KiB
Plaintext
\input texinfo @c -*-texinfo-*-
|
|
@setfilename grub.info
|
|
@include version.texi
|
|
|
|
@c Unify all our little indices for now.
|
|
@syncodeindex fn cp
|
|
@syncodeindex vr cp
|
|
@syncodeindex ky cp
|
|
@syncodeindex pg cp
|
|
@syncodeindex tp cp
|
|
|
|
@dircategory Kernel
|
|
@direntry
|
|
* GRUB: (grub). The GRand Unified Bootloader.
|
|
@end direntry
|
|
|
|
@ifinfo
|
|
Copyright @copyright{} 1996 Erich Boleyn
|
|
Copyright @copyright{} 1999 Free Software Foundation, Inc.
|
|
|
|
Permission is granted to make and distribute verbatim copies of
|
|
this manual provided the copyright notice and this permission notice
|
|
are preserved on all copies.
|
|
|
|
@ignore
|
|
Permission is granted to process this file through TeX and print the
|
|
results, provided the printed document carries a copying permission
|
|
notice identical to this one except for the removal of this paragraph
|
|
(this paragraph not being relevant to the printed manual).
|
|
|
|
@end ignore
|
|
|
|
Permission is granted to copy and distribute modified versions of this
|
|
manual under the conditions for verbatim copying, provided also that
|
|
the entire resulting derived work is distributed under the terms of a
|
|
permission notice identical to this one.
|
|
|
|
Permission is granted to copy and distribute translations of this manual
|
|
into another language, under the above conditions for modified versions.
|
|
@end ifinfo
|
|
|
|
@c @setchapternewpage odd
|
|
@settitle GRUB Manual
|
|
@titlepage
|
|
@finalout
|
|
@title The GRUB Manual
|
|
@author Gordon Matzigkeit
|
|
@author OKUJI Yoshinori
|
|
@page
|
|
|
|
@vskip 0pt plus 1filll
|
|
Copyright @copyright{} 1996 Erich Boleyn
|
|
Copyright @copyright{} 1999 Free Software Foundation, Inc.
|
|
|
|
Permission is granted to make and distribute verbatim copies of
|
|
this manual provided the copyright notice and this permission notice
|
|
are preserved on all copies.
|
|
|
|
Permission is granted to copy and distribute modified versions of this
|
|
manual under the conditions for verbatim copying, provided also that
|
|
the entire resulting derived work is distributed under the terms of a
|
|
permission notice identical to this one.
|
|
|
|
Permission is granted to copy and distribute translations of this manual
|
|
into another language, under the above conditions for modified versions.
|
|
@end titlepage
|
|
|
|
@c The Top node should not appear in TeX.
|
|
@ifnottex
|
|
|
|
@node Top
|
|
@top GRUB
|
|
|
|
This file documents GNU GRUB, the Grand Unified Bootloader. This
|
|
edition documents version @value{VERSION}.
|
|
@end ifnottex
|
|
|
|
|
|
@menu
|
|
* Introduction:: Capturing the spirit of GRUB.
|
|
* Installing:: How to install GRUB on your computer.
|
|
* Using:: Booting your operating system.
|
|
* Filesystems:: Filesystem syntax and semantics.
|
|
* Troubleshooting:: Error messages produced by GRUB.
|
|
* The grub shell:: The @command{grub} command.
|
|
* Hacking:: Implementation details.
|
|
* Index:: Index.
|
|
|
|
@detailmenu
|
|
--- The Detailed Node Listing ---
|
|
|
|
Introduction
|
|
|
|
* History:: From maggot to house fly.
|
|
* Features:: How GRUB is different.
|
|
* Role of a bootloader:: Judging a system by its bootloader.
|
|
|
|
How to install GRUB on your computer
|
|
|
|
* Boot floppy:: Creating a GRUB boot floppy.
|
|
* Automated install:: Installation via @code{install}.
|
|
|
|
Booting your operating system
|
|
|
|
* Command line:: The flexible command-line interface.
|
|
* Menu:: The simple menu interface.
|
|
* Menu entry editor:: Editing a menu entry.
|
|
* Commands:: The list of available commands.
|
|
|
|
Filesystem syntax and semantics
|
|
|
|
* Device syntax:: How to specify devices.
|
|
* Filename syntax:: How to specify files.
|
|
|
|
Error messages reported by GRUB
|
|
|
|
* Stage1 errors:: Errors reported by the Stage 1.
|
|
* Stage1.5 errors:: Errors reported by the Stage 1.5.
|
|
* Stage2 errors:: Errors reported by the Stage 2.
|
|
|
|
The @command{grub} command
|
|
|
|
* Basic usage:: How to use the grub shell.
|
|
* Installation under UNIX:: How to install GRUB via @command{grub}.
|
|
|
|
Implementation details
|
|
|
|
* Memory map:: The memory map of the various
|
|
components.
|
|
* Embedded data:: Embedded variables in GRUB.
|
|
* Memory detection:: How to detect all installed @sc{ram}.
|
|
* Low-level disk I/O:: INT 13H disk I/O interrupts.
|
|
* MBR:: The structure of Master Boot Record.
|
|
* Partition table:: The format of partition table.
|
|
* Filesystem interface:: The generic interface for the fs code.
|
|
|
|
@end detailmenu
|
|
@end menu
|
|
|
|
|
|
@node Introduction
|
|
@chapter Introduction
|
|
|
|
Briefly, a @dfn{bootloader} is the first software program that runs when
|
|
a computer starts. It is responsible for loading and transferring
|
|
control to the operating system @dfn{kernel} software (such as the Linux
|
|
or GNU Hurd kernel). The kernel, in turn, initializes the rest of the
|
|
operating system (usually GNU).
|
|
|
|
@menu
|
|
* History:: From maggot to house fly.
|
|
* Features:: How GRUB is different.
|
|
* Role of a bootloader:: Judging a system by its bootloader.
|
|
@end menu
|
|
|
|
|
|
@node History
|
|
@section History of GRUB
|
|
|
|
GRUB originated in 1995 when Erich Boleyn was trying to boot the GNU
|
|
Hurd with the University of Utah's Mach 4 microkernel (now known as GNU
|
|
Mach). Erich and Brian Ford designed the Multiboot Standard
|
|
(@pxref{Top, Multiboot Standard, Motivation, multiboot, The Multiboot
|
|
Standard}), because they were determined not to add to the large number
|
|
of mutually-incompatible PC boot methods.
|
|
|
|
Erich then began modifying the FreeBSD bootloader so that it would
|
|
understand Multiboot. He soon realized that it would be a lot easier
|
|
to write his own bootloader from scratch than to keep working on the
|
|
FreeBSD bootloader, and so GRUB was born.
|
|
|
|
Erich added many features to GRUB, but other priorities prevented him
|
|
from keeping up with the demands of its quickly-expanding user base. In
|
|
1999, Gordon Matzigkeit and OKUJI Yoshinori adopted GRUB as an official
|
|
GNU package, and opened its development by making the latest sources
|
|
available via anonymous CVS.@footnote{The repository is
|
|
@code{:pserver:anoncvs@@anoncvs.gnu.org:/gd/gnu/anoncvsroot}, module
|
|
@code{grub}. Just hit return when prompted for a password.}
|
|
|
|
|
|
@node Features
|
|
@section GRUB features
|
|
|
|
The primary requirement for GRUB is that it be compliant with the
|
|
@dfn{Multiboot Standard}, which is described in @ref{Top, Multiboot
|
|
Standard, Motivation, multiboot, The Multiboot Standard}.
|
|
|
|
The other goals, listed in approximate order of importance, are:
|
|
|
|
@itemize @bullet{}
|
|
@item
|
|
Basic functions must be straightforward for end-users.
|
|
|
|
@item
|
|
Rich functionality to support kernel experts and designers.
|
|
|
|
@item
|
|
Backward compatibility for booting FreeBSD, NetBSD, OpenBSD, and
|
|
Linux. Proprietary kernels (such as DOS, Windows NT, and OS/2) are
|
|
supported via a chain-loading function.
|
|
@end itemize
|
|
|
|
Except for specific compatibility modes (chain-loading and the Linux
|
|
@dfn{piggyback} format), all kernels will be started in much the same
|
|
state as in the Multiboot Standard. Only kernels loaded at 1 megabyte
|
|
or above are presently supported. Any attempt to load below that
|
|
boundary will simply result in immediate failure and an error message
|
|
reporting the problem.
|
|
|
|
In addition to the requirements above, GRUB has the following features
|
|
(note that the Multiboot Standard doesn't require all the features that
|
|
GRUB supports):
|
|
|
|
@table @asis
|
|
@item Multiple Executable Formats
|
|
Supports many of the @dfn{a.out} variants plus @dfn{ELF}. Symbol
|
|
tables are also loaded.
|
|
|
|
@item Supports Non-Multiboot Kernels
|
|
Supports many of the various free 32-bit kernels that lack Multiboot
|
|
compliance (primarily FreeBSD, NetBSD, OpenBSD, and
|
|
Linux). Chain-loading of other bootloaders is also supported.
|
|
|
|
@item Loads Multiples Modules
|
|
GRUB fully supports the Multiboot feature of loading multiple modules.
|
|
|
|
@item Configuration File
|
|
Supports a human-readable text configuration file with preset boot
|
|
commands. The list of commands (@pxref{Commands}) are a superset of
|
|
those supported on the command line. An example command file is provided
|
|
in @file{docs/menu.lst} in the source tree.
|
|
|
|
@item Menu Interface
|
|
A menu interface listing the preset boot commands, with a programmable
|
|
timeout, is available. There is no fixed limit on the number of boot
|
|
entries, and the current implementation has space for several hundred.
|
|
|
|
@item Flexible Command Line Interface
|
|
A fairly flexible command line interface, accessible from the menu,
|
|
is available to edit any preset commands, or write a new boot command
|
|
set from scratch. If no command file is present, GRUB drops to
|
|
the command line.
|
|
|
|
The list of commands (@pxref{Commands}) are a subset of those supported
|
|
for command files. Editing commands closely resemble the Bash command
|
|
line (@pxref{Command Line Editing, Bash, Command Line Editing, features,
|
|
Bash Features}), with @key{TAB}-completion of commands, devices,
|
|
partitions, and files in a directory depending on context.
|
|
|
|
@item Multiple Filesystem Types
|
|
Supports multiple filesystem types transparently, plus a useful explicit
|
|
blocklist notation. The currently supported filesystem types are
|
|
@dfn{BSD FFS}, @dfn{DOS FAT16 and FAT32}, @dfn{Minix fs}, and
|
|
@dfn{Linux ext2fs}. @xref{Filesystems}, for more information.
|
|
|
|
@item Decompression Support
|
|
Can decompress files which were compressed by
|
|
@command{gzip}. This function is both automatic and transparent to the
|
|
user (i.e. all functions operate upon the uncompressed contents
|
|
of the specified files). This greatly
|
|
reduces file size and loading time, a particularly major
|
|
benefit for floppies.@footnote{There are a few pathological cases
|
|
where loading a very badly organized ELF kernel might take
|
|
longer, but in practice this never happens.}
|
|
|
|
It is conceivable that some kernel modules should be loaded in a
|
|
compressed state, so a different module-loading command can be specified
|
|
to avoid uncompressing the modules.
|
|
|
|
@item Access Data on Any Installed Device
|
|
Supports reading data from any or all floppy or hard disk(s) recognized
|
|
by the BIOS, independent of the setting of the root partition.
|
|
|
|
@item Independent of Drive Geometry Translation
|
|
Unlike many other bootloaders, GRUB makes the particular drive
|
|
translation irrelevant. A drive installed and running
|
|
with one translation may be converted to another translation without any
|
|
adverse effects or changes in GRUB's configuration.
|
|
|
|
@item Detects All Installed @sc{ram}
|
|
GRUB can generally find all the installed @sc{ram} on a PC-compatible
|
|
machine. It uses an advanced BIOS query technique for finding all
|
|
memory regions (@pxref{Memory detection}). As described on the Multiboot
|
|
Standard (@pxref{Top, Multiboot Standard, Motivation, multiboot, The
|
|
Multiboot Standard}), not all kernels make use of this information, but
|
|
GRUB provides it for those who do.
|
|
|
|
@item Supports Logical Block Address Mode
|
|
In traditional disk calls (called @dfn{CHS mode}), there is a geometry
|
|
translation problem, that is, the BIOS cannot access over 1024
|
|
cylinders, so the accessible space is limited to at least 508 MB and to
|
|
at most 8GB. GRUB can't universally solve this problem, as there is no
|
|
standard interface used in all machines. However, some newer machines
|
|
have the a new interface, Logical Block Address (@dfn{LBA}) mode. GRUB
|
|
automatically detects if LBA mode is available and uses it if
|
|
available. In LBA mode, GRUB can access the entire disk.
|
|
@end table
|
|
|
|
Future directions might include an internal programming language for
|
|
supporting richer sets of boot options with control statements (which
|
|
would make GRUB its own kind of kernel). Support for non-PC hardware
|
|
architectures is also planned.@footnote{There is already a port to the
|
|
NEC PC-98xx series. See
|
|
@url{http://www.kuis.kyoto-u.ac.jp/~kmc/proj/linux98/arch/i386/boot/grub98/},
|
|
for more information.}
|
|
|
|
|
|
@node Role of a bootloader
|
|
@section The role of a bootloader
|
|
|
|
The following is a quotation from Gordon Matzigkeit, a GRUB fanatic:
|
|
|
|
@quotation
|
|
Some people like to acknowledge both the operating system and kernel when
|
|
they talk about their computers, so they might say they use
|
|
``GNU/Linux'' or ``GNU/Hurd''. Other people seem to think that the
|
|
kernel is the most important part of the system, so they like to call
|
|
their GNU operating systems ``Linux systems.''
|
|
|
|
I, personally, believe that this is a grave injustice, because the
|
|
@emph{bootloader} is the most important software of all. I used to
|
|
refer to the above systems as either ``LILO''@footnote{The LInux LOader,
|
|
a bootloader that everybody uses, but nobody likes.} or ``GRUB''
|
|
systems.
|
|
|
|
Unfortunately, nobody ever understood what I was talking about; now I
|
|
just use the word ``GNU'' as a pseudonym for GRUB.
|
|
|
|
So, if you ever hear people talking about their alleged ``GNU'' systems,
|
|
remember that they are actually paying homage to the best bootloader
|
|
around@dots{} GRUB!
|
|
@end quotation
|
|
|
|
We, the GRUB maintainers, do not (usually) encourage Gordon's level of
|
|
fanaticism, but it helps to remember that bootloaders deserve
|
|
recognition. We hope that you enjoy using GNU GRUB as much as we did
|
|
writing it.
|
|
|
|
|
|
@node Installing
|
|
@chapter How to install GRUB on your computer
|
|
|
|
Due to the nature of a @dfn{bootloader}, you need to install GRUB on
|
|
bootable media, such as a floppy disk. The installation can be performed
|
|
by @code{dd} or @code{rawrite} for a boot floppy, or the @code{install}
|
|
command at the GRUB command line (@pxref{Using}).
|
|
|
|
@menu
|
|
* Boot floppy:: Creating a GRUB boot floppy.
|
|
* Automated install:: Installation via @code{install}.
|
|
@end menu
|
|
|
|
|
|
@node Boot floppy
|
|
@section Creating a GRUB boot floppy
|
|
|
|
@quotation
|
|
@strong{Caution:} This procedure will destroy any data currently stored
|
|
on the floppy.
|
|
@end quotation
|
|
|
|
If you install GRUB using this method, it will only have access to the
|
|
command line interface, since there is no filesystem in which to find a
|
|
configuration file. If you want to use the menu interface, see
|
|
@ref{Automated install}.
|
|
|
|
Under an UNIX-like operating system, such as GNU, use @code{dd} as
|
|
follows, where @file{/lib/grub/i386-pc} is the GRUB install directory
|
|
and @file{/dev/fd0} is the floppy device:
|
|
|
|
@example
|
|
$ cd /lib/grub/i386-pc
|
|
$ dd if=stage1 of=/dev/fd0 bs=512 count=1
|
|
1+0 records in
|
|
1+0 records out
|
|
$ dd if=stage2 of=/dev/fd0 bs=512 seek=1
|
|
67+1 records in
|
|
67+1 records out
|
|
$
|
|
@end example
|
|
|
|
Under DOS-based systems, such as Windows, use @code{copy} and
|
|
@code{rawrite}:
|
|
|
|
@example
|
|
copy /b stage1 + stage2 grub.raw
|
|
rawrite grub.raw a:
|
|
@end example
|
|
|
|
@code{rawrite} is available as a part of the installation tools that
|
|
come with many GNU and GNU/Linux distributions.
|
|
|
|
|
|
@node Automated install
|
|
@section Installation via the @code{install} command
|
|
|
|
@quotation
|
|
@strong{Caution:} Installing GRUB's stage1 in this manner will erase the
|
|
normal boot-sector used by an OS. GRUB can boot GNU Mach, Linux,
|
|
FreeBSD, NetBSD, and OpenBSD directly, so this may be
|
|
desired. Generally, it is a good idea to back up the first sector of the
|
|
partition on which you are installing GRUB's stage1. This isn't as
|
|
important if you are installing GRUB on the first sector of a hard disk,
|
|
since it's easy to reinitialize it (by running @code{FDISK /MBR} from DOS).
|
|
@end quotation
|
|
|
|
GRUB has a command called @code{install} which is described in
|
|
@xref{Using}. The purpose of this section is to give examples and
|
|
describe how to use the command in different situations.
|
|
|
|
First, make a GRUB boot floppy (@pxref{Boot floppy}). This is simply a
|
|
way to get the process started easily; any bootable copy of the same
|
|
version GRUB will work fine.
|
|
|
|
Then, make a @file{/boot/grub} directory (@file{\boot\grub} under DOS)
|
|
in the @dfn{install partition}. Place the GRUB @file{stage2} file, any
|
|
optional @file{stage1.5} files, and the configuration file
|
|
(@file{menu.lst}) in that directory.
|
|
|
|
Now figure out how to use the @code{install} command appropriately, and
|
|
you're done!
|
|
|
|
Examples of how to use the @code{install} command:
|
|
|
|
@itemize @bullet
|
|
@item
|
|
@strong{Make a hard disk bootable with GRUB's stage2 on PC partition
|
|
number 2:} Make a directory in the partition called @file{/boot/grub},
|
|
place the @file{stage2} (and if desired, the @file{menu.lst}
|
|
configuration file), then run the following command at GRUB's command
|
|
line (after booting from the GRUB floppy):
|
|
|
|
@example
|
|
install (fd0)+1 (hd0) (hd0,1)/boot/grub/stage2 p
|
|
@end example
|
|
|
|
This tells GRUB to grab the first sector of the floppy and use it as the
|
|
stage1, create a blocklist using the file @file{/boot/grub/stage2} on
|
|
the first hard disk (partition number 2), merge them together, set the
|
|
load address correctly for a stage2 (0x8000), save the @dfn{install
|
|
partition} in the first sector of the stage2 (the @samp{p} at the end),
|
|
then write the result to the first sector of the hard disk.
|
|
|
|
@item
|
|
@strong{Same as above, but place the stage1 on the floppy, then have
|
|
it start the stage2 on the hard disk:} The difference here is you're
|
|
telling GRUB's stage1 to read from the first hard disk no matter where
|
|
the stage1 was loaded from:
|
|
|
|
@example
|
|
install (fd0)+1 d (fd0) (hd0,1)/boot/grub/stage2 p
|
|
@end example
|
|
|
|
By default, GRUB loads the stage2 from the disk where the stage1 was
|
|
installed. The @samp{d} option near the beginning of this command line
|
|
forces GRUB to load the stage2 from the disk where it was installed.
|
|
Also, the @dfn{destination device} is changed to place the finished
|
|
stage1 on the floppy disk.
|
|
|
|
@item
|
|
@strong{Same as above, but place the stage1.5 in the first cylinder of
|
|
the hard disk, and load the stage2 via the stage1.5:} Each of Stage 1.5s
|
|
supports only one filesystem, so choose a stage1.5 that supports the
|
|
filesystem where stage2 is located. Here it is assumed that the
|
|
filesystem is ext2fs.
|
|
|
|
First, copy @file{e2fs_stage1_5} to the first sector after the MBR
|
|
(@pxref{MBR}):
|
|
|
|
@example
|
|
dd if=stage2/e2fs_stage1_5 of=/dev/hda bs=512 seek=1
|
|
@end example
|
|
|
|
Second, specify the stage1.5 argument in blocklist format (we assume
|
|
that the size of e2fs_stage1_5 is less than 10KB):
|
|
|
|
@example
|
|
install (fd0)+1 (hd0) (hd0)1+20 p (hd0,1)/boot/grub/stage2
|
|
@end example
|
|
|
|
@item
|
|
@strong{Installing from an @emph{install directory} to the second hard
|
|
disk:} Here we're loading the stage1 from a file on the first hard disk,
|
|
installing stage2 from the first BSD @samp{a} partition on the second
|
|
hard disk, and setting the stage2's @dfn{configuration file} to
|
|
@file{(hd1,a)/grubdir/configfile}:
|
|
|
|
@example
|
|
install (hd0,1)/boot/grub/stage1 (hd1) (hd1,a)/boot/grub/stage2 p /grubdir/configfile
|
|
@end example
|
|
@end itemize
|
|
|
|
You can automate these steps by using a GRUB floppy with a filesystem
|
|
and a configuration file which contains entries such as:
|
|
|
|
@example
|
|
# Start of entry:
|
|
title GNU/Linux installation
|
|
|
|
# Installation command:
|
|
install (fd0)+1 (hd0) (hd0,1)/boot/grub/stage2 p
|
|
|
|
# Actually boot here:
|
|
root (hd0,1)
|
|
kernel /zImage root=/dev/hda2
|
|
@end example
|
|
|
|
@dots{} then have the install script continue from there after boot of
|
|
the OS.
|
|
|
|
|
|
@node Using
|
|
@chapter Booting your operating system
|
|
|
|
GRUB has both a simple menu interface for choosing preset entries from a
|
|
configuration file, and a highly flexible command line for performing
|
|
any desired combination of boot commands.
|
|
|
|
GRUB looks for its configuration file as soon as it is loaded. If one
|
|
is found, then the full menu interface is activated using whatever
|
|
entries were found in the file. If you choose the `command line' menu
|
|
option, or if the configuration file was not found, then GRUB drops to
|
|
the command line interface.
|
|
|
|
@menu
|
|
* Command line:: The flexible command line interface.
|
|
* Menu:: The simple menu interface.
|
|
* Menu entry editor:: Editing a menu entry.
|
|
* Commands:: The list of available commands.
|
|
@end menu
|
|
|
|
|
|
@node Command line
|
|
@section The flexible command line interface
|
|
|
|
The command line interface provides a prompt and after it an editable
|
|
text area much like a command line in Unix or DOS. Each command is
|
|
immediately executed after it is entered @footnote{However, this
|
|
behavior will be changed in the future version, in a user-invisible
|
|
way.}. The commands are a subset of those available in the configuration
|
|
file, used with exactly the same syntax.
|
|
|
|
Cursor movement and editing of the text on the line can be done via a
|
|
subset of the functions available in the BASH shell:
|
|
|
|
@table @key
|
|
@item C-f
|
|
@itemx PC left key
|
|
Move forward one character.
|
|
|
|
@item C-b
|
|
@itemx PC right key
|
|
Move back one character.
|
|
|
|
@item C-a
|
|
@itemx HOME
|
|
Move to the start of the line.
|
|
|
|
@item C-e
|
|
@itemx END
|
|
Move the the end of the line.
|
|
|
|
@item C-d
|
|
@itemx DEL
|
|
Delete the character underneath the cursor.
|
|
|
|
@item C-h
|
|
@itemx BS
|
|
Delete the character to the left of the cursor.
|
|
|
|
@item C-k
|
|
Kill the text from the current cursor position to the end of the line.
|
|
|
|
@item C-u
|
|
Kill backward from the cursor to the beginning of the line.
|
|
|
|
@item C-y
|
|
Yank the killed text back into the buffer at the cursor.
|
|
|
|
@item C-p
|
|
@itemx PC up key
|
|
Move up through the history list.
|
|
|
|
@item C-n
|
|
@itemx PC down key
|
|
Move down through the history list.
|
|
@end table
|
|
|
|
When typing commands interactively, if the cursor is within or before
|
|
the first word in the command-line, pressing the @key{TAB} key (or
|
|
@key{C-i}) will display a listing of the available commands, and if the
|
|
cursor is after the first word, the @key{TAB} will provide a completion
|
|
listing of disks, partitions, and filenames depending on the context.
|
|
|
|
|
|
@node Menu
|
|
@section The simple menu interface
|
|
|
|
The menu interface is quite easy to use. Its commands are both
|
|
reasonably intuitive and described on screen.
|
|
|
|
Basically, the menu interface provides a list of @dfn{boot entries} to
|
|
the user to choose from. Use the arrow keys to select the entry of
|
|
choice, then press @key{RET} to run it. An optional timeout is
|
|
available to boot the default entry (the first one if not set), which is
|
|
aborted by pressing any key.
|
|
|
|
Commands are available to enter a bare command line by pressing @key{c}
|
|
(which operates exactly like the non-config-file version of GRUB, but
|
|
allows one to return to the menu if desired by pressing @key{ESC}) or to
|
|
edit any of the @dfn{boot entries} by pressing @key{e}.
|
|
|
|
|
|
@node Menu entry editor
|
|
@section Editing a menu entry
|
|
|
|
The menu entry editor looks much like the main menu interface, but the
|
|
lines in the menu are individual commands in the selected entry instead
|
|
of entry names.
|
|
|
|
If an @key{ESC} is pressed in the editor, it aborts all the changes made
|
|
to the configuration entry and returns to the main menu interface.
|
|
|
|
When a particular line is selected, the editor places the user at a
|
|
special version of the GRUB command line to edit that line. When the
|
|
user hits @key{RET}, GRUB replaces the line in question in the boot
|
|
entry with the changes (unless it was aborted via @key{ESC},
|
|
in which case the changes are thrown away).
|
|
|
|
|
|
@node Commands
|
|
@section The list of available commands
|
|
|
|
In this section, we list the available commands, both in the
|
|
configuration file and in the command line.
|
|
|
|
The configuration file should follow these rules:
|
|
|
|
@enumerate
|
|
@item
|
|
The configuration-file-specific commands have to be used before any
|
|
others.
|
|
|
|
@item
|
|
A multiboot kernel must be loaded before any modules.
|
|
|
|
@item
|
|
A kernel must be loaded before either the configuration file entry ends,
|
|
or any @samp{boot} command is issued.
|
|
@end enumerate
|
|
|
|
The semantics are as follows:
|
|
|
|
@itemize @bullet
|
|
@item
|
|
The files @emph{must} be in plain-text format.
|
|
|
|
@item
|
|
@samp{#} at the beginning of a line in a configuration file means it is
|
|
only a comment.
|
|
|
|
@item
|
|
Options are separated by spaces.
|
|
|
|
@item
|
|
All numbers can be either decimal or hexadecimal. A hexadecimal number
|
|
must be preceded by @samp{0x}, and is case-insensitive.
|
|
|
|
@item
|
|
Extra options or text at the end of the line is ignored unless otherwise
|
|
specified.
|
|
|
|
@item
|
|
Bad commands are added to the current entry, except before entries
|
|
start, where they are ignored.
|
|
@end itemize
|
|
|
|
Commands usable in configuration files only.
|
|
|
|
@table @code
|
|
@item default @var{num}
|
|
Set the default entry to entry number @var{num} (if not specified, it is
|
|
0, the first entry).
|
|
|
|
@item fallback @var{num}
|
|
Go into unattended boot mode: if the default boot entry has any errors,
|
|
instead of waiting for the user to do anything, it immediately starts
|
|
over using the @var{num} entry (same numbering as the @code{default}
|
|
command). This obviously won't help if the machine was rebooted by a
|
|
kernel that GRUB loaded.
|
|
|
|
@item password @var{passwd} @var{new-config-file}
|
|
Disable all interactive editing control (menu entry editor and
|
|
command line). If the password @var{passwd} is entered, it loads the
|
|
@var{new-config-file} as a new config file and restarts the GRUB Stage
|
|
2.
|
|
|
|
@item timeout @var{sec}
|
|
Set a timeout, in @var{sec} seconds, before automatically booting the
|
|
default entry (normally the first entry defined).
|
|
|
|
@item title @var{name}@dots{}
|
|
Start a new boot entry, and set its name to the contents of the rest of
|
|
the line, starting with the first non-space character.
|
|
@end table
|
|
|
|
Commands usable both interactively and in configuration files:
|
|
|
|
@table @code
|
|
@item boot
|
|
This boots the OS/chain-loader which has been loaded. Only necessary if
|
|
running the fully interactive command line (it is implicit at the end of
|
|
a config-file entry).
|
|
|
|
@item cat @var{file}
|
|
Display the contents of the file @var{file}.
|
|
|
|
@item color @var{normal} [@var{highlight}]
|
|
Change the menu colors. The color @var{normal} is used for most
|
|
lines in the menu, and the color @var{highlight} is used to highlight the
|
|
line where the cursor points. If you omit @var{highlight}, then the
|
|
inverted color of @var{normal} is used for the highlighted line.
|
|
The format of a color is @code{@var{fg}/@var{bg}}. @var{fg} and @var{bg}
|
|
are symbolic color names. A symbolic color name must be one of these:
|
|
|
|
@itemize @bullet
|
|
@item
|
|
black
|
|
|
|
@item
|
|
blue
|
|
|
|
@item
|
|
green
|
|
|
|
@item
|
|
cyan
|
|
|
|
@item
|
|
red
|
|
|
|
@item
|
|
magenta
|
|
|
|
@item
|
|
brown
|
|
|
|
@item
|
|
light-gray
|
|
|
|
@strong{These below can be specified only for the foreground.}
|
|
|
|
@item
|
|
dark-gray
|
|
|
|
@item
|
|
light-blue
|
|
|
|
@item
|
|
light-green
|
|
|
|
@item
|
|
light-cyan
|
|
|
|
@item
|
|
light-red
|
|
|
|
@item
|
|
light-magenta
|
|
|
|
@item
|
|
yellow
|
|
|
|
@item
|
|
white
|
|
@end itemize
|
|
|
|
But only the first eight names can be used for @var{bg}. You can prefix
|
|
@code{blink-} to @var{fg} if you want a blinking foreground color.
|
|
|
|
This command can be used in the configuration file and on the command
|
|
line, so you may write something like this in your configuration file:
|
|
|
|
@example
|
|
# Set default colors.
|
|
color light-gray/blue black/light-gray
|
|
|
|
# Change the colors.
|
|
title OS-BS like
|
|
color magenta/blue black/magenta
|
|
@end example
|
|
|
|
@item chainloader @var{file}
|
|
Load @var{file} as a chain-loader. Like any other file loaded by the
|
|
filesystem code, it can use the blocklist notation to grab the first
|
|
sector of the current partition with @samp{+1}.
|
|
|
|
@item configfile @var{file}
|
|
Load @var{file} as the configuration file.
|
|
|
|
@item device @var{drive} @var{file}
|
|
In the grub shell, specify the file @var{file} as the actual drive for a
|
|
@sc{bios} drive @var{drive}. You can use this command to create a disk
|
|
image and to fix the drives guessed by GRUB when GRUB fails to determine
|
|
them correctly, like this:
|
|
|
|
@example
|
|
grub> device (fd0) /floppy-image
|
|
grub> device (hd0) /dev/sd0
|
|
@end example
|
|
|
|
This command is just ignored in Stage 2.
|
|
|
|
@item displaymem
|
|
Display what GRUB thinks the system address space map of the machine is,
|
|
including all regions of physical @sc{ram} installed. GRUB's
|
|
@dfn{upper/lower memory} display uses the standard BIOS interface for
|
|
the available memory in the first megabyte, or @dfn{lower memory}, and a
|
|
synthesized number from various BIOS interfaces of the memory starting
|
|
at 1MB and going up to the first chipset hole for @dfn{upper memory}
|
|
(the standard PC @dfn{upper memory} interface is limited to reporting a
|
|
maximum of 64MB).
|
|
|
|
@item fstest
|
|
Toggle filesystem test mode.
|
|
|
|
Filesystem test mode, when turned on, prints out data corresponding to
|
|
all the device reads and what values are being sent to the low-level
|
|
routines. The format is @samp{<@var{partition-offset-sector},
|
|
@var{byte-offset}, @var{byte-length}>} for high-level reads inside a
|
|
partition, and @samp{[@var{disk-offset-sector}]} for low-level sector
|
|
requests from the disk.
|
|
|
|
Filesystem test mode is turned off by any use of the @command{install}
|
|
or @command{testload} commands.
|
|
|
|
@item geometry @var{drive} [@var{cylinder} @var{head} @var{sector} [@var{total_sector}]]
|
|
Print the information for the drive @var{drive}. In the grub shell, you
|
|
can set the geometry of the drive arbitrarily. The number of the
|
|
cylinders, the one of the heads, the one of the sectors and the one of
|
|
the total sectors are set to CYLINDER, HEAD, SECTOR and TOTAL_SECTOR,
|
|
respectively. If you omit TOTAL_SECTOR, then it will be calculated
|
|
based on the C/H/S values automatically.
|
|
|
|
@item help [@var{pattern} @dots{}]
|
|
Display helpful information about builtin commands. If you do not
|
|
specify @var{pattern}, this command lists the short documents of all
|
|
available commands, and, if you specify one or more @var{pattern}s, it
|
|
displays long documents of the commands which match @var{pattern}.
|
|
|
|
@item hide @var{partition}
|
|
Hide @var{partition} by setting the @dfn{hidden} bit in its partition
|
|
type code.
|
|
|
|
@item impsprobe
|
|
Probe the Intel Multiprocessor Specification 1.1 or 1.4 configuration
|
|
table and boot the various CPUs which are found into a tight loop.
|
|
|
|
@item initrd @var{file} @dots{}
|
|
Load an initial ramdisk for a Linux format boot image and set the
|
|
appropriate parameters in the Linux setup area in memory.
|
|
|
|
@item install @var{stage1-file} [d] @var{dest-device} @var{file} [@var{addr}] [p] [@var{config-file}]
|
|
This command is fairly complex, and for detailed examples one should
|
|
look at @ref{Automated install}. In short, it will perform a full
|
|
install presuming the stage2 or stage1.5@footnote{They're loaded the
|
|
same way, so we will refer to the stage1.5 as a stage2 from now on.}
|
|
is in its final install location.
|
|
|
|
In slightly more detail, it will load @var{stage1-file}, validate that
|
|
it is a GRUB stage1 of the right version number, install a blocklist for
|
|
loading @var{file} as a stage2. If the option @samp{d} is present, the
|
|
stage1 will always look for the actual disk @var{file} was installed on,
|
|
rather than using the booting drive. The stage2 will be loaded at
|
|
address @var{addr}, which must be @samp{0x8000} for a true stage2, and
|
|
@samp{0x2000} for a stage1.5. If @var{addr} is not present, GRUB will
|
|
determine the address automatically. It then writes the completed stage1
|
|
to the first block of the device @var{dest-dev}. If the options @samp{p}
|
|
or @var{config-file} are present, then it reads the first block of
|
|
stage2, modifies it with the values of the partition @var{file} was
|
|
found on (for @samp{p}) or places the string @var{config-file} into the
|
|
area telling the stage2 where to look for a configuration file at boot
|
|
time. This command preserves the DOS BPB (and for hard disks, the
|
|
partition table) of the sector the stage1 is to be installed into.
|
|
|
|
@item kernel @var{file} @dots{}
|
|
Attempt to load the primary boot image (Multiboot a.out or @sc{elf},
|
|
Linux zImage or bzImage, FreeBSD a.out, or NetBSD a.out) from
|
|
@var{file}. The rest of the line is passed verbatim as the @dfn{kernel
|
|
command line}. Any modules must be reloaded after using this command.
|
|
|
|
@item makeactive
|
|
Set the active partition on the root disk to GRUB's root partition.
|
|
This command is limited to @emph{primary} PC partitions on a hard disk.
|
|
|
|
@item module @var{file} @dots{}
|
|
Load a boot module @var{file} for a Multiboot format boot image (no
|
|
interpretation of the file contents are made, so that user of this
|
|
command must know what the kernel in question expects). The rest of the
|
|
line is passed as the @dfn{module command line}, like the
|
|
@command{kernel} command.
|
|
|
|
@item modulenounzip @var{file} @dots{}
|
|
The same as @command{module}, except that automatic decompression is
|
|
disabled.
|
|
|
|
@item pause @var{message}@dots{}
|
|
Print the @var{message}, then wait until a key is pressed. Note that
|
|
placing @key{^G} (ASCII code 7) in the message will cause the speaker to
|
|
emit the standard beep sound, which is useful when prompting the user to
|
|
change floppies.
|
|
|
|
@item quit
|
|
Exit from the GRUB shell @command{grub} (@pxref{The grub shell}). This
|
|
command is ignored in the native Stage 2.
|
|
|
|
@item read @var{addr}
|
|
Read a 32-bit value from memory at address @var{addr} and
|
|
display it in hex format.
|
|
|
|
@item root @var{device} [@var{hdbias}]
|
|
Set the current @dfn{root partition} to the device @var{device}, then
|
|
attempt to mount it to get the partition size (for passing the partition
|
|
descriptor in @code{ES:ESI}, used by some chain-loaded bootloaders), the
|
|
BSD drive-type (for booting BSD kernels using their native boot format),
|
|
and correctly determine the PC partition where a BSD sub-partition is
|
|
located. The optional @var{hdbias} parameter is a number to tell a BSD
|
|
kernel how many BIOS drive numbers are on controllers before the current
|
|
one. For example, if there is an IDE disk and a SCSI disk, and your
|
|
FreeBSD root partition is on the SCSI disk, then use a @samp{1} for
|
|
@var{hdbias}.
|
|
|
|
@item rootnoverify @var{device} [@var{hdbias}]
|
|
Similar to @command{root}, but don't attempt to mount the
|
|
partition. This is useful for when an OS is outside of the area of the
|
|
disk that GRUB can read, but setting the correct root partition is still
|
|
desired. Note that the items mentioned in @command{root} above which
|
|
derived from attempting the mount will @emph{not} work correctly.
|
|
|
|
@item testload @var{file}
|
|
Read the entire contents of @var{file} in several different ways and
|
|
compares them, to test the filesystem code. The output is somewhat
|
|
cryptic , but if no errors are reported and the final @samp{i=@var{X},
|
|
filepos=@var{Y}} reading has @var{X} and @var{Y} equal, then it is
|
|
definitely consistent, and very likely works correctly subject to a
|
|
consistent offset error. If this test succeeds, then a good next step is
|
|
to try loading a kernel.
|
|
|
|
@item unhide @var{partition}
|
|
Unhide @var{partition} by clearing the @dfn{hidden} bit in its partition
|
|
type code.
|
|
|
|
@item uppermem @var{kbytes}
|
|
Force GRUB to assume that only @var{kbytes} kilobytes of upper memory
|
|
are installed. Any system address range maps are discarded.
|
|
|
|
@strong{Caution:} This should be used with great caution, and should
|
|
only be necessary on some old machines. GRUB's BIOS probe can pick up
|
|
all @sc{ram} on all new machines the author has ever heard of. It can
|
|
also be used for debugging purposes to lie to an OS.
|
|
@end table
|
|
|
|
|
|
@node Filesystems
|
|
@chapter Filesystem syntax and semantics
|
|
|
|
GRUB uses a special syntax for specifying disk drives which can be
|
|
accessed by BIOS. Because of BIOS limitations, GRUB cannot distinguish
|
|
between IDE, ESDI, SCSI, or others. You must know yourself which BIOS
|
|
device is equivalent to which OS device.
|
|
|
|
@menu
|
|
* Device syntax:: How to specify devices.
|
|
* Filename syntax:: How to specify files.
|
|
@end menu
|
|
|
|
|
|
@node Device syntax
|
|
@section How to specify devices
|
|
|
|
The device syntax is like this:
|
|
|
|
@example
|
|
@code{(@var{bios-device}[,@var{part-num}][,@var{bsd-subpart-letter}])}
|
|
@end example
|
|
|
|
@samp{[]} means the parameter is optional. @var{bios-device} should be
|
|
either @samp{fd} or @samp{hd} followed by a digit, like @samp{fd0}.
|
|
But you can also set @var{bios-device} to a hexadecimal or a decimal,
|
|
which is a BIOS drive number, so the following are equivalent:
|
|
|
|
@example
|
|
(hd0)
|
|
(0x80)
|
|
(128)
|
|
@end example
|
|
|
|
@var{part-num} represents the partition number of @var{bios-device},
|
|
starting from zero, and @var{bsd-subpart-letter} represents the BSD
|
|
disklabel subpartition, such as @samp{a} or @samp{e}.
|
|
|
|
A shortcut for specifying BSD subpartitions is
|
|
@code{(@var{bios-device},@var{bsd-subpart-letter})}, in this case, GRUB
|
|
searches for the first PC partition containing a BSD disklabel, then
|
|
finds the subpartition @var{bsd-subpart-letter}. Here is an example:
|
|
|
|
@example
|
|
(hd0,a)
|
|
@end example
|
|
|
|
|
|
@node Filename syntax
|
|
@section How to specify files
|
|
|
|
There are two ways to specify files, by @dfn{absolute filename} and by
|
|
@dfn{blocklist}.
|
|
|
|
An absolute filename resembles a Unix absolute filename, using @samp{/}
|
|
for the directory separator (not @samp{\} as in DOS). One example of an
|
|
absolute filename is @samp{/boot/grub/menu.lst}.
|
|
|
|
A blocklist is used for specifying a file that doesn't appear in the
|
|
filesystem, like a chainloader. The syntax is
|
|
@code{[@var{offset}]+@var{length}[,[@var{offset}]+@var{length}]@dots{}}.
|
|
Here is an example:
|
|
|
|
@example
|
|
@code{0+100,200+1,300+300}
|
|
@end example
|
|
|
|
This represents that GRUB should read blocks 0 through 99, block 200,
|
|
and blocks 300 through 600. If you omit an offset, then GRUB assumes
|
|
the offset is zero.
|
|
|
|
|
|
@node Troubleshooting
|
|
@chapter Error messages reported by GRUB
|
|
|
|
This chapter describes error messages reported by GRUB when you
|
|
encounter trouble.
|
|
|
|
@menu
|
|
* Stage1 errors:: Errors reported by the Stage 1.
|
|
* Stage1.5 errors:: Errors reported by the Stage 1.5.
|
|
* Stage2 errors:: Errors reported by the Stage 2.
|
|
@end menu
|
|
|
|
|
|
@node Stage1 errors
|
|
@section Errors reported by the Stage 1
|
|
|
|
The general way that the Stage 1 handles errors is to print an error
|
|
string and then halt. Pressing @kbd{@key{CTRL}-@key{ALT}-@key{DEL}} will
|
|
reboot.
|
|
|
|
The following is a comprehensive list of error messages for the Stage 1:
|
|
|
|
@table @asis
|
|
@item Hard Disk Error
|
|
The stage2 or stage1.5 is being read from a hard disk, and the attempt
|
|
to determine the size and geometry of the hard disk failed.
|
|
|
|
@item Floppy Error
|
|
The stage2 or stage1.5 is being read from a floppy disk, and the attempt
|
|
to determine the size and geometry of the floppy disk failed. It's listed
|
|
as a separate error since the probe sequence is different than for hard
|
|
disks.
|
|
|
|
@item Read Error
|
|
A disk read error happened while trying to read the stage2 or stage1.5.
|
|
|
|
@item Geom Error
|
|
The location of the stage2 or stage1.5 is not in the portion of the disk
|
|
supported directly by the BIOS read calls. This could occur because the
|
|
BIOS translated geometry has been changed by the user or the disk is
|
|
moved to another machine or controller after installation, or GRUB was
|
|
not installed using itself (if it was, the Stage 2 version of this error
|
|
would have been seen during that process and it would not have completed
|
|
the install).
|
|
@end table
|
|
|
|
@c FIXME: Gord stopped here
|
|
|
|
@node Stage1.5 errors
|
|
@section Errors reported by the Stage 1.5
|
|
|
|
The general way that the Stage 1.5 handles errors is to print an error
|
|
number in the form @code{Error: @var{num}} and then halt. Pressing
|
|
@kbd{@key{CTRL}-@key{ALT}-@key{DEL}} will reboot.
|
|
|
|
The error numbers correspond to the @ref{Stage2 errors} in the listed
|
|
sequence.
|
|
|
|
|
|
@node Stage2 errors
|
|
@section Errors reported by the Stage 2
|
|
|
|
The general way that the Stage 2 handles errors is to abort the
|
|
operation in question, print an error string, then (if possible) either
|
|
continue based on the fact that an error occurred or wait for the user to
|
|
deal with the error.
|
|
|
|
The following is a comprehensive list of error messages for the Stage 2
|
|
(error numbers for the Stage 1.5 are listed before the colon in each
|
|
description):
|
|
|
|
@table @asis
|
|
@item 1 : Bad filename (must be absolute filename or blocklist)
|
|
This error is returned if a filename is requested which doesn't fit the
|
|
syntax/rules listed in the @ref{Filesystems}.
|
|
|
|
@item 2 : Bad file or directory type
|
|
This error is returned if a file requested is not a regular file, but
|
|
something like a symbolic link, directory, or FIFO.
|
|
|
|
@item 3 : Bad or corrupt data while decompressing file
|
|
This error is returned the run-length decompression code gets an
|
|
internal error. This is usually from a corrupt file.
|
|
|
|
@item 4 : Bad or incompatible header on compressed file
|
|
This error is returned if the file header for a supposedly compressed
|
|
file is bad.
|
|
|
|
@item 5 : Partition table invalid or corrupt
|
|
This error s returned if the sanity checks on the integrity of the
|
|
partition table fail. This is a bad sign.
|
|
|
|
@item 6 : Bad or corrupt version of stage1/stage2
|
|
This error is returned if the install command is pointed to incompatible
|
|
or corrupt versions of the stage1 or stage2. It can't detect corruption
|
|
in general, but this is a sanity check on the version numbers, which
|
|
should be correct.
|
|
|
|
@item 7 : Loading below 1MB is not supported
|
|
This error is returned if the lowest address in a kernel is below the
|
|
1MB boundary. The Linux zImage format is a special case and can be
|
|
handled since it has a fixed loading address and maximum size.
|
|
|
|
@item 8 : Cannot boot without kernel loaded
|
|
This error is returned if GRUB is told to execute the boot sequence
|
|
without having a kernel to start.
|
|
|
|
@item 9 : Unknown boot failure
|
|
This error is returned if the boot attempt did not succeed for reasons
|
|
which are unknown.
|
|
|
|
@item 10 : Unsupported Multiboot features requested
|
|
This error is returned when the Multiboot features word in the Multiboot
|
|
header requires a feature that is not recognized. The point of this is
|
|
that the kernel requires special handling which GRUB is likely unable to
|
|
provide.
|
|
|
|
@item 11 : Device string unrecognizable
|
|
This error is returned if a device string was expected, and the string
|
|
encountered didn't fit the syntax/rules listed in the @ref{Filesystems}.
|
|
|
|
@item 12 : Invalid device requested
|
|
This error is returned if a device string is recognizable but does not
|
|
fall under the other device errors.
|
|
|
|
@item 13 : Invalid or unsupported executable format
|
|
This error is returned if the kernel image being loaded is not
|
|
recognized as Multiboot or one of the supported native formats (Linux
|
|
zImage or bzImage, FreeBSD, or NetBSD).
|
|
|
|
@item 14 : Filesystem compatibility error, can't read whole file
|
|
Some of the filesystem reading code in GRUB has limits on the length of
|
|
the files it can read. This error is returned when the user runs into
|
|
such a limit.
|
|
|
|
@item 15 : File not found
|
|
This error is returned if the specified filename cannot be found, but
|
|
everything else (like the disk/partition info) is OK.
|
|
|
|
@item 16 : Inconsistent filesystem structure
|
|
This error is returned by the filesystem code to denote an internal
|
|
error caused by the sanity checks of the filesystem structure on disk
|
|
not matching what it expects. This is usually caused by a corrupt
|
|
filesystem or bugs in the code handling it in GRUB.
|
|
|
|
@item 17 : Cannot mount selected partition
|
|
This error is returned if the partition requested exists, but the
|
|
filesystem type cannot be recognized by GRUB.
|
|
|
|
@item 18 : Selected cylinder exceeds maximum supported by BIOS
|
|
This error is returned when a read is attempted at a linear block
|
|
address beyond the end of the BIOS translated area. This generally
|
|
happens if your disk is larger than the BIOS can handle (512MB for
|
|
(E)IDE disks on older machines or larger than 8GB in general).
|
|
|
|
@item 19 : Must load Linux kernel before initrd
|
|
This error is returned if the initrd command is used before loading a
|
|
Linux kernel. Similar to the above error, it only makes sense in that
|
|
case anyway.
|
|
|
|
@item 20 : Must load Multiboot kernel before modules
|
|
This error is returned if the module load command is used before loading
|
|
a Multiboot kernel. It only makes sense in this case anyway, as GRUB has
|
|
no idea how to communicate the presence of location of such modules to a
|
|
non-Multiboot-aware kernel.
|
|
|
|
@item 21 : Selected disk does not exist
|
|
This error is returned if the device part of a device- or full filename
|
|
refers to a disk or BIOS device that is not present or not recognized by
|
|
the BIOS in the system.
|
|
|
|
@item 22 : No such partition
|
|
This error is returned if a partition is requested in the device part of
|
|
a device- or full filename which isn't on the selected disk.
|
|
|
|
@item 23 : Error while parsing number
|
|
This error is returned if GRUB was expecting to read a number and
|
|
encountered bad data.
|
|
|
|
@item 24 : Attempt to access block outside partition
|
|
This error is returned if a linear block address is outside of the disk
|
|
partition. This generally happens because of a corrupt filesystem on the
|
|
disk or a bug in the code handling it in GRUB (it's a great debugging
|
|
tool).
|
|
|
|
@item 25 : Disk read error
|
|
This error is returned if there is a disk read error when trying to
|
|
probe or read data from a particular disk.
|
|
|
|
@item 26 : Too many symbolic links
|
|
This error is returned if the link count is beyond the maximum
|
|
(currently 5), possibly the symbolic links are looped.
|
|
|
|
@item 27 : Unrecognized command
|
|
This error is returned if an unrecognized command is entered into the
|
|
command line or in a boot sequence section of a configuration file and
|
|
that entry is selected.
|
|
|
|
@item 28 : Selected item won't fit into memory
|
|
This error is returned if a kernel, module, or raw file load command is
|
|
either trying to load its data such that it won't fit into memory or it
|
|
is simply too big.
|
|
|
|
@item 29 : Disk write error
|
|
This error is returned if there is a disk write error when trying to
|
|
write to a particular disk. This would generally only occur during an
|
|
install of set active partition command.
|
|
@end table
|
|
|
|
|
|
@node The grub shell
|
|
@chapter The command @command{grub}
|
|
|
|
This chapter documents the grub shell @command{grub}.
|
|
|
|
@menu
|
|
* Basic usage:: How to use the grub shell.
|
|
* Installation under UNIX:: How to install GRUB via @command{grub}.
|
|
@end menu
|
|
|
|
|
|
@node Basic usage
|
|
@section Introduction into the grub shell
|
|
|
|
You can use the command @command{grub} for installing GRUB under your
|
|
operating systems and for a testbed when you add a new feature into GRUB
|
|
or when fix a bug. @command{grub} is almost the same as Stage 2, and, in
|
|
fact, it shares the source code with Stage 2 and you can use the same
|
|
commands in @command{grub}. It is emulated by replacing BIOS calls with
|
|
UNIX system calls and libc functions.
|
|
|
|
The command @command{grub} accepts the following options:
|
|
|
|
@table @code
|
|
@item --help
|
|
Print a summary of the command line options and exit.
|
|
|
|
@item --version
|
|
Print the version number of GRUB and exit.
|
|
|
|
@item --verbose
|
|
Print some verbose messages for debugging purpose.
|
|
|
|
@item --config-file=@var{file}
|
|
Read the configuration file @var{file} instead of
|
|
@file{/boot/grub/menu.lst}. The format is the same as the normal GRUB
|
|
syntax. See @ref{Filesystems}, for more information.
|
|
|
|
@item --boot-drive=@var{drive}
|
|
Set the stage2 @var{boot_drive} to @var{drive}. This argument should be
|
|
an integer (decimal, octal or hexadecimal).
|
|
|
|
@item --install-partition=@var{par}
|
|
Set the stage2 @var{install_partition} to @var{par}. This argument
|
|
should be an integer (decimal, octal or hexadecimal).
|
|
|
|
@item --no-config-file
|
|
Do not use the configuration file even if it can be read.
|
|
|
|
@item --no-curses
|
|
Do not use the curses interface even if it is available.
|
|
|
|
@item --batch
|
|
This option has the same meaning as @samp{--no-config-file --no-curses}.
|
|
|
|
@item --read-only
|
|
Disable writing to any disk.
|
|
|
|
@item --hold
|
|
Wait until a debugger will attach. This option is useful when you want
|
|
to debug the startup code.
|
|
@end table
|
|
|
|
|
|
@node Installation under UNIX
|
|
@section How to install GRUB via @command{grub}
|
|
|
|
The installation procedure is the same as under the @dfn{native} Stage
|
|
2. See @ref{Automated install} for more information. The command
|
|
@command{grub}-specific information is described here.
|
|
|
|
What you should be careful about is @dfn{buffer cache}. @command{grub}
|
|
makes use of raw devices instead of filesystems that your operating
|
|
systems serve, so there exists a potential problem that some cache
|
|
inconsistency may corrupt your filesystems. What we recommend is:
|
|
|
|
@itemize @bullet
|
|
@item
|
|
If you can unmount drives to which GRUB may write any amount of data,
|
|
unmount them before running @command{grub}.
|
|
|
|
@item
|
|
If a drive cannot be unmounted but can be mounted with the read-only
|
|
flag, mount it in read-only mode. That should be secure.
|
|
|
|
@item
|
|
If a drive must be mounted with the read-write flag, make sure that any
|
|
activity is not being done on it during running the command
|
|
@command{grub}.
|
|
|
|
@item
|
|
Reboot your operating system as soon as possible. Probably that is not
|
|
required if you follow these rules above, but reboot is the most secure
|
|
way.
|
|
@end itemize
|
|
|
|
In addition, enter the command @command{quit} when you finish the
|
|
installation. That is @emph{very important} because @command{quit} makes
|
|
the buffer cache consistent. Do not push @key{C-c}.
|
|
|
|
If you want to install GRUB non-interactively, specify @samp{--batch}
|
|
option in the command line. This is a simple example:
|
|
|
|
@example
|
|
#!/bin/sh
|
|
|
|
/sbin/grub --batch <<EOT 1>/dev/null 2>/dev/null
|
|
root (hd0,0)
|
|
install /boot/grub/stage1 (hd0) /boot/grub/stage2 p
|
|
quit
|
|
EOT
|
|
@end example
|
|
|
|
|
|
@node Hacking
|
|
@chapter Implementation details
|
|
|
|
This chapter describes the GRUB internals so that developers can
|
|
understand the implementation and start to hack GRUB. Of course, the
|
|
source code has the complete information, so refer to it when you are
|
|
not satisfied with this documentation.
|
|
|
|
@menu
|
|
* Memory map:: The memory map of the various
|
|
components.
|
|
* Embedded data:: Embedded variables in GRUB.
|
|
* Memory detection:: How to detect all installed @sc{ram}.
|
|
* Low-level disk I/O:: INT 13H disk I/O interrupts.
|
|
* MBR:: The structure of Master Boot Record.
|
|
* Partition table:: The format of partition table.
|
|
* Filesystem interface:: The generic interface for the fs code.
|
|
@end menu
|
|
|
|
|
|
@node Memory map
|
|
@section The memory map of various components
|
|
|
|
GRUB is broken into 2 distinct components, or @dfn{stages}, which are
|
|
loaded at different times in the boot process. The Stage 1 has to know
|
|
where to find Stage 2, and the Stage 2 has to know where to find its
|
|
configuration file (if Stage 2 doesn't have a configuration file, it
|
|
drops into the command line interface and waits for a user command).
|
|
|
|
Here is the memory map of the various components
|
|
@footnote{Currently GRUB does not use the extended memory for itself,
|
|
since it is used to load an operating system. But we are planning to use
|
|
it for GRUB itself in the future by @dfn{lazy loading}. Ask okuji for
|
|
more information.}:
|
|
|
|
@table @asis
|
|
@item 0 to 4K-1
|
|
Interrupt & BIOS area
|
|
|
|
@item down from 8K-1
|
|
16-bit stack area
|
|
|
|
@item 8K to (ebss1.5)
|
|
Stage 1.5 (optionally) loaded here by Stage 1
|
|
|
|
@item 0x7c00 to 0x7dff
|
|
Stage 1 loaded here by the BIOS
|
|
|
|
@item 0x7e00 to 0x7e08
|
|
Scratch space used by Stage 1
|
|
|
|
@item 32K to (ebss2)
|
|
Stage 2 loaded here by Stage 1.5 or Stage 1
|
|
|
|
@item (middle area)
|
|
Heap used for random memory allocation
|
|
|
|
@item down from 416K-1
|
|
32-bit stack area
|
|
|
|
@item 416K to 448K-1
|
|
Filesystem info buffer (when reading a filesystem)
|
|
|
|
@item 448K to 479.5K-1
|
|
BIOS track read buffer
|
|
|
|
@item 479.5K to 480K-1
|
|
512 byte fixed SCRATCH area
|
|
|
|
@item 480K to 511K-1
|
|
General storage heap
|
|
@end table
|
|
|
|
|
|
@node Embedded data
|
|
@section Embedded variables in GRUB
|
|
|
|
GRUB's stage1 and stage2 have embedded variables whose locations are
|
|
well-defined, so that the installation can patch the binary file
|
|
directly without recompilation of the modules.
|
|
|
|
In stage1, these are defined (The number in the parenthesis of each
|
|
entry is an offset number):
|
|
|
|
@table @asis
|
|
@item @dfn{major version} (0x1bc)
|
|
This is the major version byte (should be 2).
|
|
|
|
@item @dfn{minor version} (0x1bd)
|
|
This is the minor version byte (should be 1).
|
|
|
|
@item @dfn{stage2 start address} (0x1b8)
|
|
This is the data for the @code{ljmp} command to the starting address of
|
|
the component loaded by the stage1. The format is two 2-byte words: the
|
|
first is the IP, and the second is the CS segment register (remember,
|
|
we're in x86 real-mode@dots{} 16-bit instruction pointer and segment
|
|
registers shifted left by 4bits).
|
|
|
|
A @dfn{stage1.5} should be loaded at address 0x2000, and a @dfn{stage2}
|
|
should be loaded at address 0x8000. Both use a CS of 0.
|
|
|
|
@item @dfn{firstlist} (0x1b05)
|
|
This is the @emph{ending} address of the blocklist data area.
|
|
|
|
The trick here is that it is actually read backward, and the first
|
|
8-byte blocklist is not read here, but after the pointer is decremented
|
|
8 bytes, then after reading it, it decrements again, reads, decrements,
|
|
reads, etc. until it is finished. The terminating condition is when the
|
|
number of sectors to be read in the next blocklist is 0.
|
|
|
|
The format of a blocklist can be seen from the example in the code just
|
|
before the @code{firstlist} label. (note that it is always from the
|
|
beginning of the disk, and @emph{not} relative to the partition
|
|
boundaries)
|
|
|
|
@item @dfn{loading drive} (0x1b05)
|
|
This is the BIOS drive number to load the blocklists from. If the number
|
|
is 0xff, then load from the booting drive.
|
|
@end table
|
|
|
|
In stage1.5 and stage2 (these are all defined at the beginning of
|
|
@file{shared_src/asm.S}):
|
|
|
|
@table @asis
|
|
@item @dfn{major version} (0x6)
|
|
This is the major version byte (should be 2).
|
|
|
|
@item @dfn{minor version} (0x7)
|
|
This is the minor version byte (should be 0).
|
|
|
|
@item @dfn{install_partition} (0x8)
|
|
This is an unsigned long representing the partition on the currently
|
|
booted disk which GRUB should expect to find it's data files and treat
|
|
as the default root partition.
|
|
|
|
The format of is exactly the same as the @dfn{partition} part (the
|
|
@dfn{disk} part is ignored) of the data passed to an OS by a
|
|
Multiboot-compliant bootloader in the @dfn{boot_device} data element,
|
|
with one exception.
|
|
|
|
The exception is that if the first level of disk partitioning is left as
|
|
0xFF (decimal 255, which is marked as no partitioning being used), but
|
|
the second level does have a partition number, it looks for the first
|
|
BSD-style PC partition, and finds the numbered BSD sub-partition in it.
|
|
The default @dfn{install_partition} 0xFF00FF, would then find the first
|
|
BSD-style PC partition, and use the @samp{a} partition in it, and
|
|
0xFF01FF would use the @samp{b} partition, etc.
|
|
|
|
If an explicit first-level partition is given, then no search is
|
|
performed, and it will expect that the BSD-style PC partition is in the
|
|
appropriate location, else a @samp{no such partition} error will be
|
|
returned.
|
|
|
|
If a @dfn{stage1.5} is being used, it will pass its own
|
|
@dfn{install_partition} to any @dfn{stage2} it loads, therefore
|
|
overwriting the one present in the @dfn{stage2}.
|
|
|
|
@item @dfn{stage2_id} (0xc)
|
|
This is the @dfn{stage1.5} or @dfn{stage2} identifier.
|
|
|
|
@item @dfn{version_string} (0xd)
|
|
This is the @dfn{stage1.5} or @dfn{stage2} version string. It isn't
|
|
meant to be changed, simply easy to find.
|
|
|
|
@item @dfn{config_file} (after the terminating zero of @dfn{version_string})
|
|
This is the location, using the GRUB filesystem syntax, of the config
|
|
file. It will, by default, look in the @dfn{install_partition} of the
|
|
disk GRUB was loaded from, though one can use any valid GRUB filesystem
|
|
string, up to and including making it look on other disks.
|
|
|
|
The bootloader itself doesn't search for the end of
|
|
@dfn{version_string}, it simply knows where @dfn{config_file} is, so the
|
|
beginning of the string cannot be moved after compile-time. This should
|
|
be OK, since the @dfn{version_string} is meant to be static.
|
|
|
|
The code of stage2 starts again at offset 0x70, so @dfn{config_file}
|
|
string obviously can't go past there. Also, remember to terminate the
|
|
string with a 0.
|
|
@end table
|
|
|
|
|
|
@node Memory detection
|
|
@section How to detect all installed @sc{ram}
|
|
|
|
There are three BIOS calls which return the information of installed
|
|
@sc{ram}. GRUB uses these calls to detect all installed @sc{ram} and
|
|
which address range should be treated by operating systems.
|
|
|
|
@menu
|
|
* Query System Address Map:: INT 15H, AX=E820h interrupt call.
|
|
* Get Large Memory Size:: INT 15H, AX=E801h interrupt call.
|
|
* Get Extended Memory Size:: INT 15H, AX=88h interrupt call.
|
|
@end menu
|
|
|
|
|
|
@node Query System Address Map
|
|
@subsection INT 15H, AX=E820h interrupt call
|
|
|
|
Real mode only.
|
|
|
|
This call returns a memory map of all the installed @sc{ram}, and of
|
|
physical memory ranges reserved by the BIOS. The address map is returned
|
|
by making successive calls to this API, each returning one "run" of
|
|
physical address information. Each run has a type which dictates how
|
|
this run of physical address range should be treated by the operating
|
|
system.
|
|
|
|
If the information returned from INT 15h, AX=E820h in some way differs
|
|
from INT 15h, AX=E801h (@pxref{Get Large Memory Size}) or INT 15h AH=88h
|
|
(@pxref{Get Extended Memory Size}), then the information returned from
|
|
E820h supersedes what is returned from these older interfaces. This
|
|
allows the BIOS to return whatever information it wishes to for
|
|
compatibility reasons.
|
|
|
|
Input:
|
|
|
|
@multitable @columnfractions .15 .25 .6
|
|
@item @code{EAX} @tab Function Code @tab E820h
|
|
|
|
@item @code{EBX} @tab Continuation @tab Contains the @dfn{continuation
|
|
value} to get the next run of physical memory. This is the value
|
|
returned by a previous call to this routine. If this is the first call,
|
|
@code{EBX} must contain zero.
|
|
|
|
@item @code{ES:DI} @tab Buffer Pointer @tab Pointer to an Address Range
|
|
Descriptor structure which the BIOS is to fill in.
|
|
|
|
@item @code{ECX} @tab Buffer Size @tab The length in bytes of the
|
|
structure passed to the BIOS. The BIOS will fill in at most @code{ECX}
|
|
bytes of the structure or however much of the structure the BIOS
|
|
implements. The minimum size which must be supported by both the BIOS
|
|
and the caller is 20 bytes. Future implementations may extend this
|
|
structure.
|
|
|
|
@item @code{EDX} @tab Signature @tab @samp{SMAP} - Used by the BIOS to
|
|
verify the caller is requesting the system map information to be
|
|
returned in @code{ES:DI}.
|
|
@end multitable
|
|
|
|
Output:
|
|
|
|
@multitable @columnfractions 0.15 0.25 0.6
|
|
@item @code{CF} @tab Carry Flag @tab Non-Carry - indicates no error
|
|
|
|
@item @code{EAX} @tab Signature @tab @samp{SMAP} - Signature to verify
|
|
correct BIOS revision.
|
|
|
|
@item @code{ES:DI} @tab Buffer Pointer @tab Returned Address Range
|
|
Descriptor pointer. Same value as on input.
|
|
|
|
@item @code{ECX} @tab Buffer Size @tab Number of bytes returned by the
|
|
BIOS in the address range descriptor. The minimum size structure
|
|
returned by the BIOS is 20 bytes.
|
|
|
|
@item @code{EBX} @tab Continuation @tab Contains the continuation value
|
|
to get the next address descriptor. The actual significance of the
|
|
continuation value is up to the discretion of the BIOS. The caller must
|
|
pass the continuation value unchanged as input to the next iteration of
|
|
the E820h call in order to get the next Address Range Descriptor. A
|
|
return value of zero means that this is the last descriptor. Note that
|
|
the BIOS indicate that the last valid descriptor has been returned by
|
|
either returning a zero as the continuation value, or by returning
|
|
carry.
|
|
@end multitable
|
|
|
|
The Address Range Descriptor Structure is:
|
|
|
|
@multitable @columnfractions 0.25 0.3 0.45
|
|
@item Offset in Bytes @tab Name @tab Description
|
|
|
|
@item 0 @tab @dfn{BaseAddrLow} @tab Low 32 Bits of Base Address
|
|
|
|
@item 4 @tab @dfn{BaseAddrHigh} @tab High 32 Bits of Base Address
|
|
|
|
@item 8 @tab @dfn{LengthLow} @tab Low 32 Bits of Length in Bytes
|
|
|
|
@item 12 @tab @dfn{LengthHigh} @tab High 32 Bits of Length in Bytes
|
|
|
|
@item 16 @tab @dfn{Type} @tab Address type of this range
|
|
@end multitable
|
|
|
|
The @dfn{BaseAddrLow} and @dfn{BaseAddrHigh} together are the 64 bit
|
|
@dfn{BaseAddress} of this range. The @dfn{BaseAddress} is the physical
|
|
address of the start of the range being specified.
|
|
|
|
The @dfn{LengthLow} and @dfn{LengthHigh} together are the 64 bit
|
|
@dfn{Length} of this range. The @dfn{Length} is the physical contiguous
|
|
length in bytes of a range being specified.
|
|
|
|
The @dfn{Type} field describes the usage of the described address range
|
|
as defined in the table below:
|
|
|
|
@multitable @columnfractions 0.1 0.35 0.55
|
|
@item Value @tab Mnemonic @tab Description
|
|
|
|
@item 1 @tab @dfn{AddressRangeMemory} @tab This run is available
|
|
@sc{ram} usable by the operating system.
|
|
|
|
@item 2 @tab @dfn{AddressRangeReserved} @tab This run of addresses is in
|
|
use or reserved by the system, and must not be used by the operating
|
|
system.
|
|
|
|
@item Other @tab @dfn{Undefined} @tab Undefined - Reserved for future
|
|
use. Any range of this type must be treated by the OS as if the type
|
|
returned was @dfn{AddressRangeReserved}.
|
|
@end multitable
|
|
|
|
The BIOS can use the @dfn{AddressRangeReserved} address range type to
|
|
block out various addresses as @emph{not suitable} for use by a
|
|
programmable device.
|
|
|
|
Some of the reasons a BIOS would do this are:
|
|
|
|
@itemize @bullet
|
|
@item
|
|
The address range contains system @sc{rom}.
|
|
|
|
@item
|
|
The address range contains @sc{ram} in use by the @sc{rom}.
|
|
|
|
@item
|
|
The address range is in use by a memory mapped system device.
|
|
|
|
@item
|
|
The address range is for whatever reason are unsuitable for a
|
|
standard device to use as a device memory space.
|
|
@end itemize
|
|
|
|
Here is the list of assumptions and limitations:
|
|
|
|
@enumerate
|
|
@item
|
|
The BIOS will return address ranges describing base board memory and ISA
|
|
or PCI memory that is contiguous with that base board memory.
|
|
|
|
@item
|
|
The BIOS @emph{will not} return a range description for the memory
|
|
mapping of PCI devices. ISA Option @sc{rom}'s, and ISA plug & play
|
|
cards. This is because the OS has mechanisms available to detect them.
|
|
|
|
@item
|
|
The BIOS will return chipset defined address holes that are not being
|
|
used by devices as reserved.
|
|
|
|
@item
|
|
Address ranges defined for base board memory mapped I/O devices (for
|
|
example APICs) will be returned as reserved.
|
|
|
|
@item
|
|
All occurrences of the system BIOS will be mapped as reserved. This
|
|
includes the area below 1 MB, at 16 MB (if present) and at end of the
|
|
address space (4 GB).
|
|
|
|
@item
|
|
Standard PC address ranges will not be reported. Example video memory at
|
|
A0000 to BFFFF physical will not be described by this function. The
|
|
range from E0000 to EFFFF is base board specific and will be reported as
|
|
suits the bas board.
|
|
|
|
@item
|
|
All of lower memory is reported as normal memory. It is OS's
|
|
responsibility to handle standard @sc{ram} locations reserved for
|
|
specific uses, for example: the interrupt vector table (0:0) and the
|
|
BIOS data area (40:0).
|
|
@end enumerate
|
|
|
|
Here we explain an example address map. This sample address map
|
|
describes a machine which has 128 MB @sc{ram}, 640K of base memory and
|
|
127 MB extended. The base memory has 639K available for the user and 1K
|
|
for an extended BIOS data area. There is a 4 MB Linear Frame Buffer
|
|
(LFB) based at 12 MB. The memory hole created by the chipset is from 8
|
|
M to 16 M. There are memory mapped APIC devices in the system. The IO
|
|
Unit is at FEC00000 and the Local Unit is at FEE00000. The system BIOS
|
|
is remapped to 4G - 64K.
|
|
|
|
Note that the 639K endpoint of the first memory range is also the base
|
|
memory size reported in the BIOS data segment at 40:13.
|
|
|
|
Key to types: @dfn{ARM} is AddressRangeMemory, @dfn{ARR} is
|
|
AddressRangeReserved.
|
|
|
|
@multitable @columnfractions 0.15 0.1 0.1 0.65
|
|
@item Base (Hex) @tab Length @tab Type @tab Description
|
|
|
|
@item 0000 0000 @tab 639K @tab ARM @tab Available Base memory -
|
|
typically the same value as is returned via the INT 12 function.
|
|
|
|
@item 0009 FC00 @tab 1K @tab ARR @tab Memory reserved for use by the
|
|
BIOS(s). This area typically includes the Extended BIOS data area.
|
|
|
|
@item 000F 0000 @tab 64K @tab ARR @tab System BIOS.
|
|
|
|
@item 0010 0000 @tab 7M @tab ARM @tab Extended memory, this is not
|
|
limited to the 64MB address range.
|
|
|
|
@item 0080 0000 @tab 8M @tab ARR @tab Chipset memory hole required to
|
|
support the LFB mapping at 12 MB.
|
|
|
|
@item 0100 0000 @tab 120M @tab ARM @tab Base board @sc{ram} relocated
|
|
above a chipset memory hole.
|
|
|
|
@item FE00 0000 @tab 4K @tab ARR @tab IO APIC memory mapped I/O at
|
|
FEC00000. Note the range of addresses required for an APIC device may
|
|
vary from base OEM to OEM.
|
|
|
|
@item FEE0 0000 @tab 4K @tab ARR @tab Local APIC memory mapped I/O at
|
|
FEE00000.
|
|
|
|
@item FFFF 0000 @tab 64K @tab ARR @tab Remapped System BIOS at end of
|
|
address space.
|
|
@end multitable
|
|
|
|
The following code segment is intended to describe the algorithm needed
|
|
when calling the Query System Address Map function. It is an
|
|
implementation example and uses non standard mechanisms.
|
|
|
|
@example
|
|
E820Present = FALSE;
|
|
Regs.ebx = 0;
|
|
do
|
|
@{
|
|
Regs.eax = 0xE820;
|
|
Regs.es = SEGMENT (&Descriptor);
|
|
Regs.di = OFFSET (&Descriptor);
|
|
Regs.ecx = sizeof (Descriptor);
|
|
Regs.edx = 'SMAP';
|
|
|
|
_int (0x15, Regs);
|
|
|
|
if ((Regs.eflags & EFLAGS_CARRY) || Regs.eax != 'SMAP')
|
|
@{
|
|
break;
|
|
@}
|
|
|
|
if (Regs.ecx < 20 || Regs.ecx > sizeof (Descriptor))
|
|
@{
|
|
/* bug in bios - all returned descriptors must be at
|
|
least 20 bytes long, and can not be larger than
|
|
the input buffer. */
|
|
break;
|
|
@}
|
|
|
|
E820Present = TRUE;
|
|
.
|
|
.
|
|
.
|
|
Add address range Descriptor.BaseAddress through
|
|
Descriptor.BaseAddress + Descriptor.Length
|
|
as type Descriptor.Type
|
|
.
|
|
.
|
|
.
|
|
@}
|
|
while (Regs.ebx != 0);
|
|
|
|
if (! E820Present)
|
|
@{
|
|
.
|
|
.
|
|
.
|
|
call INT 15H, AX E801h and/or INT 15H, AH=88h to obtain old style
|
|
memory information
|
|
.
|
|
.
|
|
.
|
|
@}
|
|
@end example
|
|
|
|
|
|
@node Get Large Memory Size
|
|
@subsection INT 15H, AX=E801h interrupt call
|
|
|
|
Real mode only.
|
|
|
|
Originally defined for EISA servers, this interface is capable of
|
|
reporting up to 4 GB of @sc{ram}. While not nearly as flexible as
|
|
E820h, it is present in many more systems.
|
|
|
|
Input:
|
|
|
|
@multitable @columnfractions 0.15 0.25 0.6
|
|
@item @code{AX} @tab Function Code @tab E801h.
|
|
@end multitable
|
|
|
|
Output:
|
|
|
|
@multitable @columnfractions 0.15 0.25 0.6
|
|
@item @code{CF} @tab Carry Flag @tab Non-Carry - indicates no error.
|
|
|
|
@item @code{AX} @tab Extended 1 @tab Number of contiguous KB between 1
|
|
and 16 MB, maximum 0x3C00 = 15 MB.
|
|
|
|
@item @code{BX} @tab Extended 2 @tab Number of contiguous 64KB blocks
|
|
between 16 MB and 4GB.
|
|
|
|
@item @code{CX} @tab Configured 1 @tab Number of contiguous KB between 1
|
|
and 16 MB, maximum 0x3c00 = 15 MB.
|
|
|
|
@item @code{DX} @tab Configured 2 @tab Number of contiguous 64KB blocks
|
|
between 16 MB and 4 GB.
|
|
@end multitable
|
|
|
|
Not sure what this difference between the @dfn{Extended} and
|
|
@dfn{Configured} numbers are, but they appear to be identical, as
|
|
reported from the BIOS.
|
|
|
|
It is possible for a machine using this interface to report a memory
|
|
hole just under 16 MB (Count 1 is less than 15 MB, but Count 2 is
|
|
non-zero).
|
|
|
|
|
|
@node Get Extended Memory Size
|
|
@subsection INT 15H, AX=88h interrupt call
|
|
|
|
Real mode only.
|
|
|
|
This interface is quite primitive. It returns a single value for
|
|
contiguous memory above 1 MB. The biggest limitation is that the value
|
|
returned is a 16-bit value, in KB, so it has a maximum saturation of
|
|
just under 64 MB even presuming it returns as much as it can. On some
|
|
systems, it won't return anything above the 16 MB boundary.
|
|
|
|
The one useful point is that it works on every PC available.
|
|
|
|
Input:
|
|
|
|
@multitable @columnfractions 0.15 0.25 0.6
|
|
@item @code{AH} @tab Function Code @tab 88h
|
|
@end multitable
|
|
|
|
Output:
|
|
|
|
@multitable @columnfractions 0.15 0.25 0.6
|
|
@item @code{CF} @tab Carry Flag @tab Non-Carry - indicates no error.
|
|
|
|
@item @code{AX} @tab Memory Count @tab Number of contiguous KB above 1
|
|
MB.
|
|
@end multitable
|
|
|
|
|
|
@node Low-level disk I/O
|
|
@section INT 13H disk I/O interrupts
|
|
|
|
In the PC world, living with the BIOS disk interface is definitely a
|
|
nightmare. This section documents how awful the chaos is and how GRUB
|
|
deals with the BIOS disks.
|
|
|
|
@menu
|
|
* CHS Translation:: CHS addressing and LBA addressing.
|
|
* CHS mode disk I/O:: INT 13H, AH=0xh interrupt call.
|
|
* LBA mode disk I/O:: INT 13H, AH=4xh interrupt call.
|
|
@end menu
|
|
|
|
|
|
@node CHS Translation
|
|
@subsection CHS addressing and LBA addressing
|
|
|
|
CHS --- Cylinder/Head/Sector --- is the traditional way to address
|
|
sectors on a disk. There are at least two types of CHS addressing; the
|
|
CHS that is used at the INT 13H interface and the CHS that is used at
|
|
the ATA device interface. In the MFM/RLL/ESDI and early ATA days the CHS
|
|
used at the INT 13H interface was the same as the CHS used at the device
|
|
interface.
|
|
|
|
Today we have CHS translating BIOS types that can use one CHS at the INT
|
|
13H interface and a different CHS at the device interface. These two
|
|
types of CHS will be called the logical CHS or @dfn{L-CHS} and the
|
|
physical CHS or @dfn{P-CHS} in this section. L-CHS is the CHS used at
|
|
the INT 13H interface and P-CHS is the CHS used at the device interface.
|
|
|
|
The L-CHS used at the INT 13 interface allows up to 256 heads, up to
|
|
1024 cylinders and up to 63 sectors. This allows support of up to 8GB
|
|
drives. This scheme started with either ESDI or SCSI adapters many years
|
|
ago.
|
|
|
|
The P-CHS used at the device interface allows up to 16 heads up to 65535
|
|
cylinders, and up to 63 sectors. This allows access to 2^28 sectors
|
|
(136GB) on an ATA device. When a P-CHS is used at the INT 13H interface
|
|
it is limited to 1024 cylinders, 16 heads and 63 sectors. This is where
|
|
the old 528MB limit originated.
|
|
|
|
LBA --- Logical Block Address --- is another way of addressing sectors
|
|
that uses a simple numbering scheme starting with zero as the address of
|
|
the first sector on a device. The ATA standard requires that cylinder 0,
|
|
head 0, sector 1 address the same sector as addressed by LBA 0. LBA
|
|
addressing can be used at the ATA interface if the ATA device supports
|
|
it. LBA addressing is also used at the INT 13H interface by the AH=4xH
|
|
read/write calls.
|
|
|
|
ATA devices may also support LBA at the device interface. LBA allows
|
|
access to approximately 2^28 sectors (137GB) on an ATA device.
|
|
|
|
A SCSI host adapter can convert a L-CHS directly to an LBA used in the
|
|
SCSI read/write commands. On a PC today, SCSI is also limited to 8GB
|
|
when CHS addressing is used at the INT 13H interface.
|
|
|
|
First, all OS's that want to be co-resident with another OS (and that is
|
|
all of the PC based OS's that I know of) @emph{must} use INT 13H to
|
|
determine the capacity of a hard disk. And that capacity information
|
|
@emph{must} be determined in L-CHS mode. Why is this? Because:
|
|
|
|
@enumerate
|
|
@item
|
|
FDISK and the partition tables are really L-CHS based.
|
|
|
|
@item
|
|
MS/PC DOS uses INT 13H AH=02H and AH=03H to read and write the disk and
|
|
these BIOS calls are L-CHS based.
|
|
|
|
@item
|
|
The boot processing done by the BIOS is all L-CHS based.
|
|
@end enumerate
|
|
|
|
During the boot processing, all of the disk read accesses are done in
|
|
L-CHS mode via INT 13H and this includes loading the first of the OS's
|
|
kernel code or boot manager's code.
|
|
|
|
Second, because there can be multiple BIOS types in any one system, each
|
|
drive may be under the control of a different type of BIOS. For example,
|
|
drive 80H (the first hard drive) could be controlled by the original
|
|
system BIOS, drive 81H (the second drive) could be controlled by a
|
|
option @sc{rom} BIOS and drive 82H (the third drive) could be controlled
|
|
by a software driver. Also, be aware that each drive could be a
|
|
different type, for example, drive 80H could be an MFM drive, drive 81H
|
|
could be an ATA drive, drive 82H could be a SCSI drive.
|
|
|
|
Third, not all OS's understand or use BIOS drive numbers greater than
|
|
81H. Even if there is INT 13H support for drives 82H or greater, the OS
|
|
may not use that support.
|
|
|
|
Fourth, the BIOS INT 13H configuration calls are:
|
|
|
|
@table @asis
|
|
@item AH=08H, Get Drive Parameters
|
|
This call is restricted to drives up to 528MB without CHS translation
|
|
and to drives up to 8GB with CHS translation. For older BIOS with no
|
|
support for >1024 cylinders or >528MB, this call returns the same CHS as
|
|
is used at the ATA interface (the P-CHS). For newer BIOS's that do
|
|
support >1024 cylinders or >528MB, this call returns a translated CHS
|
|
(the L-CHS). The CHS returned by this call is used by FDISK to build
|
|
partition records.
|
|
|
|
@item AH=41H, Get BIOS Extensions Support
|
|
This call is used to determine if the IBM/Microsoft Extensions or if the
|
|
Phoenix Enhanced INT 13H calls are supported for the BIOS drive number.
|
|
|
|
@item AH=48H, Extended Get Drive Parameters
|
|
This call is used to determine the CHS geometries, LBA information and
|
|
other data about the BIOS drive number.
|
|
@end table
|
|
|
|
An ATA disk must implement both CHS and LBA addressing and must at any
|
|
given time support only one P-CHS at the device interface. And, the
|
|
drive must maintain a strict relationship between the sector addressing
|
|
in CHS mode and LBA mode. Quoting @cite{the ATA-2 document}:
|
|
|
|
@example
|
|
@group
|
|
LBA = ( (cylinder * heads_per_cylinder + heads )
|
|
* sectors_per_track ) + sector - 1
|
|
|
|
where heads_per_cylinder and sectors_per_track are the current
|
|
translation mode values.
|
|
@end group
|
|
@end example
|
|
|
|
This algorithm can also be used by a BIOS or an OS to convert a L-CHS to
|
|
an LBA.
|
|
|
|
This algorithm can be reversed such that an LBA can be converted to a
|
|
CHS:
|
|
|
|
@example
|
|
@group
|
|
cylinder = LBA / (heads_per_cylinder * sectors_per_track)
|
|
temp = LBA % (heads_per_cylinder * sectors_per_track)
|
|
head = temp / sectors_per_track
|
|
sector = temp % sectors_per_track + 1
|
|
@end group
|
|
@end example
|
|
|
|
While most OS's compute disk addresses in an LBA scheme, an OS like DOS
|
|
must convert that LBA to a CHS in order to call INT 13H.
|
|
|
|
The basic problem is that there is no requirement that a CHS translating
|
|
BIOS followed these rules. There are many other algorithms that can be
|
|
implemented to perform a similar function. Today, there are at least two
|
|
popular implementations: the Phoenix implementation (described above) and
|
|
the non-Phoenix implementations. Because a protected mode OS that does
|
|
not want to use INT 13H must implement the same CHS translation
|
|
algorithm. If it doesn't, your data gets scrambled.
|
|
|
|
In the perfect world of tomorrow, maybe only LBA will be used. But today
|
|
we are faced with the following problems:
|
|
|
|
@itemize @bullet
|
|
@item
|
|
Some drives >528MB don't implement LBA.
|
|
|
|
@item
|
|
Some drives are optimized for CHS and may have lower performance when
|
|
given commands in LBA mode. Don't forget that LBA is something new for
|
|
the ATA disk designers who have worked very hard for many years to
|
|
optimize CHS address handling. And not all drive designs require the use
|
|
of LBA internally.
|
|
|
|
@item
|
|
The L-CHS to LBA conversion is more complex and slower than the bit
|
|
shifting L-CHS to P-CHS conversion.
|
|
|
|
@item
|
|
DOS, FDISK and the MBR are still CHS based --- they use the CHS returned
|
|
by INT 13H AH=08H. Any OS that can be installed on the same disk with
|
|
DOS must understand CHS addressing.
|
|
|
|
@item
|
|
The BIOS boot processing and loading of the first OS kernel code is done
|
|
in CHS mode --- the CHS returned by INT 13H AH=08H is used.
|
|
|
|
@item
|
|
Microsoft has said that their OS's will not use any disk capacity that
|
|
can not also be accessed by INT 13H AH=0xH.
|
|
@end itemize
|
|
|
|
These are difficult problems to overcome in today's industry
|
|
environment. The result: chaos.
|
|
|
|
|
|
@node CHS mode disk I/O
|
|
@subsection INT 13H, AH=0xh interrupt call
|
|
|
|
Real mode only. These functions are the traditional CHS mode disk
|
|
interface. GRUB calls them only if LBA mode is not available.
|
|
|
|
INT 13H, AH=02h reads sectors into memory.
|
|
|
|
Input:
|
|
|
|
@multitable @columnfractions .15 .85
|
|
@item @code{AH} @tab 02h
|
|
|
|
@item @code{AL} @tab The number of sectors to read (must be non-zero).
|
|
|
|
@item @code{CH} @tab Low 8 bits of cylinder number.
|
|
|
|
@item @code{CL} @tab Sector number in bits 0-5, and high 2 bits of
|
|
cylinder number in bits 6-7.
|
|
|
|
@item @code{DH} @tab Head number.
|
|
|
|
@item @code{DL} @tab Drive number (bit 7 set for hard disk).
|
|
|
|
@item @code{ES:BX} @tab Data buffer.
|
|
@end multitable
|
|
|
|
Output:
|
|
|
|
@multitable @columnfractions .15 .85
|
|
@item @code{CF} @tab Set on error.
|
|
|
|
@item @code{AH} @tab Status.
|
|
|
|
@item @code{AL} @tab The number of sectors transferred (only valid if CF
|
|
set for some BIOSes).
|
|
@end multitable
|
|
|
|
INT 13H, AH=03h writes disk sectors.
|
|
|
|
Input:
|
|
|
|
@multitable @columnfractions .15 .85
|
|
@item @code{AH} @tab 03h
|
|
|
|
@item @code{AL} @tab The number of sectors to write (must be non-zero).
|
|
|
|
@item @code{CH} @tab Low 8 bits of cylinder number.
|
|
|
|
@item @code{CL} @tab Sector number in bits 0-5, and high 2 bits of
|
|
cylinder number in bits 6-7.
|
|
|
|
@item @code{DH} @tab Head number.
|
|
|
|
@item @code{DL} @tab Drive number (bit 7 set for hard disk).
|
|
|
|
@item @code{ES:BX} @tab Data buffer.
|
|
@end multitable
|
|
|
|
Output:
|
|
|
|
@multitable @columnfractions .15 .85
|
|
@item @code{CF} @tab Set on error.
|
|
|
|
@item @code{AH} @tab Status.
|
|
|
|
@item @code{AL} @tab The number of sectors transferred (only valid if CF
|
|
set for some BIOSes).
|
|
@end multitable
|
|
|
|
INT 13H, AH=08h returns drive parameters. For systems predating the IBM
|
|
PC/AT, this call is only valid for hard disks.
|
|
|
|
Input:
|
|
|
|
@multitable @columnfractions .15 .85
|
|
@item @code{AH} @tab 08h
|
|
|
|
@item @code{DL} @tab Drive number (bit 7 set for hard disk).
|
|
@end multitable
|
|
|
|
Output:
|
|
|
|
@multitable @columnfractions .15 .85
|
|
@item @code{CF} @tab Set on error.
|
|
|
|
@item @code{AH} @tab 0.
|
|
|
|
@item @code{AL} @tab 0 on at least some BIOSes.
|
|
|
|
@item @code{BL} @tab Drive type (AT/PS2 floppies only).
|
|
|
|
@item @code{CH} @tab Low 8 bits of maximum cylinder number.
|
|
|
|
@item @code{CL} @tab Maximum sector number in bits 0-5, and high 2 bits
|
|
of maximum cylinder number in bits 6-7.
|
|
|
|
@item @code{DH} @tab Maximum head number.
|
|
|
|
@item @code{DL} @tab The number of drives.
|
|
|
|
@item @code{ES:DI} @tab Drive parameter table (floppies only).
|
|
@end multitable
|
|
|
|
GRUB does not use this call for floppies, but attempts to read the first
|
|
sector from the last head of the last cylinder to determine the maximum
|
|
head number and the maximum cylinder number.
|
|
|
|
|
|
@node LBA mode disk I/O
|
|
@subsection INT 13H, AH=4xh interrupt call
|
|
|
|
Real mode only. These functions are IBM/MS INT 13 Extensions to support
|
|
LBA mode. GRUB uses them if available so that it can read/write over 8GB
|
|
area.
|
|
|
|
INT 13, AH=41h checks if LBA is supported.
|
|
|
|
Input:
|
|
|
|
@multitable @columnfractions 0.15 0.85
|
|
@item @code{AH} @tab 41h.
|
|
|
|
@item @code{BX} @tab 55AAh.
|
|
|
|
@item @code{DL} @tab Drive number.
|
|
@end multitable
|
|
|
|
Output:
|
|
|
|
@multitable @columnfractions 0.15 0.85
|
|
@item @code{CF} @tab Set on error.
|
|
|
|
@item @code{AH} @tab Major version of extensions (01h for 1.x, 20h for
|
|
2.0 / EDD-1.0, 21h for 2.1 / EDD-1.1 and 30h for EDD-3.0) if successful,
|
|
otherwise 01h (the error code of @dfn{invalid function}).
|
|
|
|
@item @code{BX} @tab AA55h if installed.
|
|
|
|
@item @code{AL} @tab Internal use.
|
|
|
|
@item @code{CX} @tab API subset support bitmap (see below).
|
|
|
|
@item @code{DH} @tab Extension version.
|
|
@end multitable
|
|
|
|
The bitfields for the API subset support bitmap are:
|
|
|
|
@multitable @columnfractions 0.15 0.85
|
|
@item Bit(s) @tab Description
|
|
|
|
@item 0 @tab Extended disk access functions (AH=42h-44h, 47h, 48h)
|
|
supported.
|
|
|
|
@item 1 @tab Removable drive controller functions (AH=45h, 46h, 48h,
|
|
49h, INT 15H, AH=52h) supported.
|
|
|
|
@item 2 @tab Enhanced disk drive (EDD) functions (AH=48h, 4Eh)
|
|
supported.
|
|
|
|
@item 3-15 @tab Reserved (0).
|
|
@end multitable
|
|
|
|
INT 13, AH=42h reads sectors into memory.
|
|
|
|
Input:
|
|
|
|
@multitable @columnfractions .15 .85
|
|
@item @code{AH} @tab 42h.
|
|
|
|
@item @code{DL} @tab Drive number.
|
|
|
|
@item @code{DS:SI} @tab Disk Address Packet (see below).
|
|
@end multitable
|
|
|
|
Output:
|
|
|
|
@multitable @columnfractions .15 .85
|
|
@item @code{CF} @tab Set on error.
|
|
|
|
@item @code{AH} @tab 0 if successful, otherwise error code.
|
|
@end multitable
|
|
|
|
The format of @dfn{Disk Address Packet} is:
|
|
|
|
@multitable @columnfractions 0.15 0.15 0.7
|
|
@item Offset (hex) @tab Size (byte) @tab Description
|
|
|
|
@item 00 @tab 1 @tab 10h (The size of packet).
|
|
|
|
@item 01 @tab 1 @tab Reserved (0).
|
|
|
|
@item 02 @tab 2 @tab The number of blocks to transfer (max 007F for
|
|
Phoenix EDD).
|
|
|
|
@item 04 @tab 4 @tab Transfer buffer (SEGMENT:OFFSET).
|
|
|
|
@item 08 @tab 8 @tab Starting absolute block number.
|
|
@end multitable
|
|
|
|
INT 13, AH=43h writes disk sectors.
|
|
|
|
Input:
|
|
|
|
@multitable @columnfractions 0.15 0.85
|
|
@item @code{AH} @tab 43h.
|
|
|
|
@item @code{AL} @tab Write flags (In version 1.0 and 2.0, bit 0 is the
|
|
flag for @dfn{verify write} and other bits are reserved (0). In version
|
|
2.1, 00h and 01h indicates @dfn{write without verify}, and 02h indicates
|
|
@dfn{write with verify}.
|
|
|
|
@item @code{DL} @tab Drive number.
|
|
|
|
@item @code{DS:SI} @tab Disk Address Packet (see above).
|
|
@end multitable
|
|
|
|
Output:
|
|
|
|
@multitable @columnfractions 0.15 0.85
|
|
@item @code{CF} @tab Set on error.
|
|
|
|
@item @code{AH} @tab 0 if successful, otherwise error code.
|
|
@end multitable
|
|
|
|
INT 13, AH=48h returns drive parameters. GRUB only makes use of the
|
|
total number of sectors, and ignore the CHS information, because only
|
|
L-CHS makes sense. @xref{CHS Translation}, for more information.
|
|
|
|
Input:
|
|
|
|
@multitable @columnfractions 0.15 0.85
|
|
@item @code{AH} @tab 48h.
|
|
|
|
@item @code{DL} @tab Drive number.
|
|
|
|
@item @code{DS:SI} @tab Buffer for drive parameters (see below).
|
|
@end multitable
|
|
|
|
Output:
|
|
|
|
@multitable @columnfractions 0.15 0.85
|
|
@item @code{CF} @tab Set on error.
|
|
|
|
@item @code{AH} @tab 0 if successful, otherwise error code.
|
|
@end multitable
|
|
|
|
The format of drive parameters is:
|
|
|
|
@multitable @columnfractions 0.25 0.15 0.6
|
|
@item Offset (hex) @tab Size (byte) @tab Description
|
|
|
|
@item 00 @tab 2 @tab The size of buffer. Before calling this function,
|
|
set to the maximum buffer size, at least 1Ah. The size actually filled
|
|
is returned (1Ah for version 1.0, 1Eh for 2.x and 42h for 3.0).
|
|
|
|
@item 02 @tab 2 @tab Information flags (see below).
|
|
|
|
@item 04 @tab 4 @tab The number of physical cylinders.
|
|
|
|
@item 08 @tab 4 @tab The number of physical heads.
|
|
|
|
@item 0C @tab 4 @tab The number of physical sectors per track.
|
|
|
|
@item 10 @tab 8 @tab The total number of sectors.
|
|
|
|
@item 18 @tab 2 @tab The bytes per sector.
|
|
|
|
@comment Add an empty row for readability...
|
|
@item @tab @tab
|
|
|
|
@item @strong{v2.0 and later} @tab @tab
|
|
|
|
@item 1A @tab 4 @tab EDD configuration parameters.
|
|
|
|
@comment Add an empty row for readability...
|
|
@item @tab @tab
|
|
|
|
@item @strong{v3.0} @tab @tab
|
|
|
|
@item 1E @tab 2 @tab Signature BEDD to indicate presence of Device Path
|
|
information.
|
|
|
|
@item 20 @tab 1 @tab The length of Device Path information, including
|
|
signature and this byte (24h for version 3.0).
|
|
|
|
@item 21 @tab 3 @tab Reserved (0).
|
|
|
|
@item 24 @tab 4 @tab ASCIZ name of host bus (@samp{ISA} or @samp{PCI}).
|
|
|
|
@item 28 @tab 8 @tab ASCIZ name of interface type (@samp{ATA},
|
|
@samp{ATAPI}, @samp{SCSI}, @samp{USB}, @samp{1394} or @samp{FIBRE}).
|
|
|
|
@item 30 @tab 8 @tab Interface Path.
|
|
|
|
@item 38 @tab 8 @tab Device Path.
|
|
|
|
@item 40 @tab 1 @tab Reserved (0).
|
|
|
|
@item 41 @tab 1 @tab Checksum of bytes 1Eh-40h (2's complement of sum,
|
|
which makes the 8 bit sum of bytes 1Eh-41h equal to 00h).
|
|
@end multitable
|
|
|
|
The information flags are:
|
|
|
|
@multitable @columnfractions 0.15 0.85
|
|
@item Bit(s) @tab Description
|
|
|
|
@item 0 @tab DMA boundary errors handles transparently.
|
|
|
|
@item 1 @tab CHS information is valid.
|
|
|
|
@item 2 @tab Removable drive.
|
|
|
|
@item 3 @tab Write with verify supported.
|
|
|
|
@item 4 @tab Drive has change-line support (required if drive is
|
|
removable).
|
|
|
|
@item 5 @tab Drive can be locked (required if drive is removable).
|
|
|
|
@item 6 @tab CHS information set to maximum supported values, not
|
|
current media.
|
|
|
|
@item 7-15 @tab Reserved (0).
|
|
@end multitable
|
|
|
|
|
|
@node MBR
|
|
@section The structure of Master Boot Record
|
|
|
|
A Master Boot Record (@dfn{MBR}) is the sector at cylinder 0, head 0,
|
|
sector 1 of a hard disk. A MBR-like structure must be created in each of
|
|
partitions by the FDISK program.
|
|
|
|
At the completion of your system's Power On Self Test (@dfn{POST}), INT
|
|
19H is called. Usually INT 19 tries to read a boot sector from the first
|
|
floppy drive@footnote{Which drive is read first depends on your BIOS
|
|
settings.}. If a boot sector is found on the floppy disk, that boot
|
|
sector is read into memory at location 0000:7C00 and INT 19H jumps to
|
|
memory location 0000:7C00. However, if no boot sector is found on the
|
|
first floppy drive, INT 19H tries to read the MBR from the first hard
|
|
drive. If an MBR is found it is read into memory at location 0000:7C00
|
|
and INT 19H jumps to memory location 0000:7C00. The small program in the
|
|
MBR will attempt to locate an active (bootable) partition in its
|
|
partition table@footnote{This behavior is DOS MBR's, and GRUB ignores
|
|
the active flag.}. The small program in the boot sector must locate the
|
|
first part of the operating system's kernel loader program (or perhaps
|
|
the kernel itself or perhaps a @dfn{boot manager program}) and read that
|
|
into memory.
|
|
|
|
INT 19H is also called when the @key{CTRL}-@key{ALT}-@key{DEL} keys are
|
|
used. On most systems, @key{CTRL}-@key{ALT}-@key{DEL} causes an short
|
|
version of the POST to be executed before INT 19H is called.
|
|
|
|
The stuff is:
|
|
|
|
@table @asis
|
|
@item Offset 0000
|
|
The address where the MBR code starts.
|
|
|
|
@item Offset 01BE
|
|
The address where the partition table starts (@pxref{Partition table}).
|
|
|
|
@item Offset 01FE
|
|
The signature, AA55.
|
|
@end table
|
|
|
|
However, the first 62 bytes of a boot sector are known as the BIOS
|
|
Parameter Block (@dfn{BPB}), so GRUB cannot use these bytes for its own
|
|
purpose.
|
|
|
|
If an active partition is found, that partition's boot record is read
|
|
into 0000:7C00 and the MBR code jumps to 0000:7C00 with @code{SI}
|
|
pointing to the partition table entry that describes the partition being
|
|
booted. The boot record program uses this data to determine the drive
|
|
being booted from and the location of the partition on the disk.
|
|
|
|
The first byte of an active partition table entry is 80. This byte is
|
|
loaded into the @code{DL} register before INT 13H is called to read the
|
|
boot sector. When INT 13H is called, @code{DL} is the BIOS device
|
|
number. Because of this, the boot sector read by this MBR program can
|
|
only be read from BIOS device number 80 (the first hard disk). This is
|
|
one of the reasons why it is usually not possible to boot from any other
|
|
hard disk.
|
|
|
|
|
|
@node Partition table
|
|
@section The format of partition table
|
|
|
|
@menu
|
|
* Partition basics:: Overview the partition table.
|
|
* Partition types:: The list of the @dfn{type} code.
|
|
* Partition entry format:: The format of the table entry.
|
|
* Partition table rules:: Some basic rules for Partition table.
|
|
@end menu
|
|
|
|
|
|
@node Partition basics
|
|
@subsection Overview the partition table
|
|
|
|
FDISK creates all partition records (sectors). The primary purpose of a
|
|
partition record is to hold a partition table. The rules for how FDISK
|
|
works are unwritten but so far most FDISK programs seem to follow the
|
|
same basic idea.
|
|
|
|
First, all partition table records (sectors) have the same format. This
|
|
includes the partition table record at cylinder 0, head 0, sector 1 --
|
|
what is known as the Master Boot Record (MBR). The last 66 bytes of a
|
|
partition table record contain a partition table and a 2 byte
|
|
signature. The first 446 bytes of these sectors usually contain a
|
|
program but only the program in the MBR is ever executed (so extended
|
|
partition table records could contain something other than a program in
|
|
the first 466 bytes). For more information, see @ref{MBR}.
|
|
|
|
Second, extended partitions are @emph{nested} inside one another and
|
|
extended partition table records form a @dfn{linked list}. I will
|
|
attempt to show this in a diagram at @ref{Partition entry format}.
|
|
|
|
Each partition table entry is 16 bytes and contains things like the
|
|
start and end location of a partition in CHS, the start in LBA, the size
|
|
in sectors, the partition @dfn{type} and the @dfn{active} flag. Older
|
|
versions of FDISK may compute incorrect LBA or size values. And when
|
|
your computer boots itself, only the CHS fields of the partition table
|
|
entries are used (another reason LBA doesn't solve the >528MB
|
|
problem). The CHS fields in the partition tables are in L-CHS format,
|
|
see @ref{CHS Translation}.
|
|
|
|
|
|
@node Partition types
|
|
@subsection The list of the @dfn{type} code
|
|
|
|
There is no central clearing house to assign the codes used in the one
|
|
byte @dfn{type} field. But codes are assigned (or used) to define most
|
|
every type of file system that anyone has ever implemented on the x86
|
|
PC: 12-bit FAT, 16-bit FAT, HPFS, NTFS, etc. Plus, an extended partition
|
|
also has a unique type code.
|
|
|
|
In the FDISK program @samp{sfdisk}, the following list is assumed:
|
|
|
|
@table @asis
|
|
@item 00
|
|
Empty
|
|
|
|
@item 01
|
|
DOS 12-bit FAT
|
|
|
|
@item 02
|
|
XENIX /
|
|
|
|
@item 03
|
|
XENIX /usr
|
|
|
|
@item 04
|
|
DOS 16-bit FAT <32M
|
|
|
|
@item 05
|
|
DOS Extended
|
|
|
|
@item 06
|
|
DOS 16-bit FAT >=32M
|
|
|
|
@item 07
|
|
HPFS / NTFS
|
|
|
|
@item 08
|
|
AIX boot or SplitDrive
|
|
|
|
@item 09
|
|
AIX data or Coherent
|
|
|
|
@item 0A
|
|
OS/2 Boot Manager
|
|
|
|
@item 0B
|
|
Windows95 FAT32
|
|
|
|
@item 0C
|
|
Windows95 FAT32 (LBA)
|
|
|
|
@item 0E
|
|
Windows95 FAT16 (LBA)
|
|
|
|
@item 0F
|
|
Windows95 Extended (LBA)
|
|
|
|
@item 10
|
|
OPUS
|
|
|
|
@item 11
|
|
Hidden DOS FAT12
|
|
|
|
@item 12
|
|
Compaq diagnostics
|
|
|
|
@item 14
|
|
Hidden DOS FAT16
|
|
|
|
@item 16
|
|
Hidden DOS FAT16 (big)
|
|
|
|
@item 17
|
|
Hidden HPFS/NTFS
|
|
|
|
@item 18
|
|
AST Windows swapfile
|
|
|
|
@item 24
|
|
NEC DOS
|
|
|
|
@item 3C
|
|
PartitionMagic recovery
|
|
|
|
@item 40
|
|
Venix 80286
|
|
|
|
@item 41
|
|
Linux/MINIX (sharing disk with DRDOS)
|
|
|
|
@item 42
|
|
SFS or Linux swap (sharing disk with DRDOS)
|
|
|
|
@item 43
|
|
Linux native (sharing disk with DRDOS)
|
|
|
|
@item 50
|
|
DM (disk manager)
|
|
|
|
@item 51
|
|
DM6 Aux1 (or Novell)
|
|
|
|
@item 52
|
|
CP/M or Microsoft SysV/AT
|
|
|
|
@item 53
|
|
DM6 Aux3
|
|
|
|
@item 54
|
|
DM6
|
|
|
|
@item 55
|
|
EZ-Drive (disk manager)
|
|
|
|
@item 56
|
|
Golden Bow (disk manager)
|
|
|
|
@item 5C
|
|
Priam Edisk (disk manager)
|
|
|
|
@item 61
|
|
SpeedStor
|
|
|
|
@item 63
|
|
GNU Hurd or Mach or Sys V/386 (such as ISC UNIX)@footnote{But the reason
|
|
why they decided that 63 means GNU Hurd is not known. Do not use 63 for
|
|
GNU Hurd.}
|
|
|
|
@item 64
|
|
Novell Netware 286
|
|
|
|
@item 65
|
|
Novell Netware 386
|
|
|
|
@item 70
|
|
DiskSecure Multi-Boot
|
|
|
|
@item 75
|
|
PC/IX
|
|
|
|
@item 77
|
|
QNX4.x
|
|
|
|
@item 78
|
|
QNX4.x 2nd part
|
|
|
|
@item 79
|
|
QNX4.x 3rd part
|
|
|
|
@item 80
|
|
MINIX until 1.4a
|
|
|
|
@item 81
|
|
MINIX / old Linux
|
|
|
|
@item 82
|
|
Linux swap
|
|
|
|
@item 83
|
|
Linux native@footnote{This is not true. Use 83 for ext2fs even if the
|
|
owner OS is GNU/Hurd.}
|
|
|
|
@item 84
|
|
OS/2 hidden C: drive
|
|
|
|
@item 85
|
|
Linux extended
|
|
|
|
@item 86
|
|
NTFS volume set
|
|
|
|
@item 87
|
|
NTFS volume set
|
|
|
|
@item 93
|
|
Amoeba
|
|
|
|
@item 94
|
|
Amoeba BBT
|
|
|
|
@item A0
|
|
IBM Thinkpad hibernation
|
|
|
|
@item A5
|
|
BSD/386
|
|
|
|
@item A7
|
|
NeXTSTEP 486
|
|
|
|
@item B7
|
|
BSDI fs
|
|
|
|
@item B8
|
|
BSDI swap
|
|
|
|
@item C1
|
|
DRDOS/sec (FAT-12)
|
|
|
|
@item C4
|
|
DRDOS/sec (FAT-16, < 32M)
|
|
|
|
@item C6
|
|
DRDOS/sec (FAT-16, >= 32M)
|
|
|
|
@item C7
|
|
Syrinx
|
|
|
|
@item DB
|
|
CP/M or Concurrent CP/M or Concurrent DOS or CTOS
|
|
|
|
@item E1
|
|
DOS access or SpeedStor 12-bit FAT extended partition
|
|
|
|
@item E3
|
|
DOS R/O or SpeedStor
|
|
|
|
@item E4
|
|
SpeedStor 16-bit FAT extended partition < 1024 cyl.
|
|
|
|
@item F1
|
|
SpeedStor
|
|
|
|
@item F2
|
|
DOS 3.3+ secondary
|
|
|
|
@item F4
|
|
SpeedStor large partition
|
|
|
|
@item FE
|
|
SpeedStor >1024 cyl. or LANstep
|
|
|
|
@item FF
|
|
Xenix Bad Block Table
|
|
@end table
|
|
|
|
@node Partition entry format
|
|
@subsection The format of the table entry
|
|
|
|
The 16 bytes of a partition table entry are used as follows:
|
|
|
|
@example
|
|
@group
|
|
+--- Bit 7 is the active partition flag, bits 6-0 are zero.
|
|
|
|
|
| +--- Starting CHS in INT 13 call format.
|
|
| |
|
|
| | +--- Partition type byte.
|
|
| | |
|
|
| | | +--- Ending CHS in INT 13 call format.
|
|
| | | |
|
|
| | | | +-- Starting LBA.
|
|
| | | | |
|
|
| | | | | +-- Size in sectors.
|
|
| | | | | |
|
|
v <--+---> v <--+--> v v
|
|
|
|
0 1 2 3 4 5 6 7 8 9 A B C D E F
|
|
DH DL CH CL TB DL CH CL LBA..... SIZE....
|
|
|
|
80 01 01 00 06 0e be 94 3e000000 0c610900 1st entry
|
|
|
|
00 00 81 95 05 0e fe 7d 4a610900 724e0300 2nd entry
|
|
|
|
00 00 00 00 00 00 00 00 00000000 00000000 3rd entry
|
|
|
|
00 00 00 00 00 00 00 00 00000000 00000000 4th entry
|
|
@end group
|
|
@end example
|
|
|
|
Bytes 0-3 are used by the small program in the Master Boot Record to
|
|
read the first sector of an active partition into memory. The @dfn{DH},
|
|
@dfn{DL}, @dfn{CH} and @dfn{CL} above show which x86 register is loaded
|
|
when the MBR program calls INT 13H AH=02h to read the active partition's
|
|
boot sector. For more information, see @ref{MBR}.
|
|
|
|
These entries define the following partitions:
|
|
|
|
@enumerate
|
|
@item
|
|
The first partition, a primary partition DOS FAT, starts at CHS 0H,1H,1H
|
|
(LBA 3EH) and ends at CHS 294H,EH,3EH with a size of 9610CH sectors.
|
|
|
|
@item
|
|
The second partition, an extended partition, starts at CHS 295H,0H,1H
|
|
(LBA 9614AH) and ends at CHS 37DH,EH,3EH with a size of 34E72H sectors.
|
|
|
|
@item
|
|
The third and fourth table entries are unused.
|
|
@end enumerate
|
|
|
|
|
|
@node Partition table rules
|
|
@subsection Some basic rules for Partition table.
|
|
|
|
Keep in mind that there are @emph{no} written rules and @emph{no}
|
|
industry standards on how FDISK should work but here are some basic
|
|
rules that seem to be followed by most versions of FDISK:
|
|
|
|
@enumerate
|
|
@item
|
|
In the MBR there can be 0-4 @dfn{primary} partitions, OR, 0-3 primary
|
|
partitions and 0-1 extended partition entry.
|
|
|
|
@item
|
|
In an extended partition there can be 0-1 @dfn{secondary} partition
|
|
entries and 0-1 extended partition entries.
|
|
|
|
@item
|
|
Only 1 primary partition in the MBR can be marked @dfn{active} at any
|
|
given time.
|
|
|
|
@item
|
|
In most versions of FDISK, the first sector of a partition will be
|
|
aligned such that it is at head 0, sector 1 of a cylinder. This means
|
|
that there may be unused sectors on the track(s) prior to the first
|
|
sector of a partition and that there may be unused sectors following a
|
|
partition table sector.
|
|
|
|
For example, most new versions of FDISK start the first partition
|
|
(primary or extended) at cylinder 0, head 1, sector 0. This leaves the
|
|
sectors at cylinder 0, head 0, sectors 2...n as unused sectors. This
|
|
same layout may be seen on the first track of an extended partition.
|
|
See example 2 below.
|
|
|
|
Also note that software drivers like Ontrack's Disk Manager depend on
|
|
these unused sectors because these drivers will @dfn{hide} their code
|
|
there (in cylinder 0, head 0, sectors 2...n). This is also a good place
|
|
for boot sector virus programs to hang out.
|
|
|
|
@item
|
|
The partition table entries (slots) can be used in any order. Some
|
|
versions of FDISK fill the table from the bottom up and some versions of
|
|
FDISK fill the table from the top down. Deleting a partition can leave
|
|
an unused entry (slot) in the middle of a table.
|
|
|
|
@item
|
|
And then there is the @dfn{hack} that some newer OS's (OS/2 and Linux)
|
|
use in order to place a partition spanning or passed cylinder 1024 on a
|
|
system that does not have a CHS translating BIOS. These systems create a
|
|
partition table entry with the partition's starting and ending CHS
|
|
information set to all FFH. The starting and ending LBA information is
|
|
used to describe the location of the partition. The LBA can be converted
|
|
back to a CHS --- most likely a CHS with more than 1024 cylinders. Since
|
|
such a CHS can't be used by the system BIOS, these partitions can not be
|
|
booted or accessed until the OS's kernel and hard disk device drivers
|
|
are loaded. It is not known if the systems using this @dfn{hack} follow
|
|
the same rules for the creation of these type of partitions.
|
|
@end enumerate
|
|
|
|
There are @emph{no} written rules as to how an OS scans the partition
|
|
table entries so each OS can have a different method. For DOS, this
|
|
means that different versions could assign different drive letters to
|
|
the same FAT file system partitions.
|
|
|
|
|
|
@node Filesystem interface
|
|
@section The generic interface for the fs code
|
|
|
|
For any particular partition, it is presumed that only one of the
|
|
@dfn{normal} filesystems such as FAT, FFS, or ext2fs can be used, so
|
|
there is a switch table managed by the functions in
|
|
@file{disk_io.c}. The notation is that you can only @dfn{mount} one at a
|
|
time.
|
|
|
|
The blocklist filesystem has a special place in the system. In addition
|
|
to the @dfn{normal} filesystem (or even without one mounted), you can
|
|
access disk blocks directly (in the indicated partition) via the
|
|
blocklist notation. Using the blocklist filesystem doesn't effect any
|
|
other filesystem mounts.
|
|
|
|
The variables which can be read by the filesystem backend are:
|
|
|
|
@vtable @code
|
|
@item current_drive
|
|
Contain the current BIOS drive number (numbered from 0, if a floppy,
|
|
and numbered from 0x80, if a hard disk).
|
|
|
|
@item current_slice
|
|
Contain the current partition length, in sectors.
|
|
|
|
@item print_possibilities
|
|
True when the @code{dir} function should print the possible completions
|
|
of a file, and false when it should try to actually open a file of that
|
|
name.
|
|
|
|
@item FSYS_BUF
|
|
Point to a filesystem buffer which is 32K in size, to use in any way
|
|
which the filesystem backend desires.
|
|
@end vtable
|
|
|
|
The variables which need to be written by a filesystem backend are:
|
|
|
|
@vtable @code
|
|
@item filepos
|
|
Should be the current position in the file.
|
|
|
|
@strong{Caution:} the value of @var{filepos} can be changed out from
|
|
under the filesystem code in the current implementation. Don't depend on
|
|
it being the same for later calls into the back-end code!
|
|
|
|
@item filemax
|
|
Should be the length of the file.
|
|
|
|
@item disk_read_func
|
|
Should be set to the value of @samp{disk_read_hook} @emph{only} during
|
|
reading of data for the file, not any other fs data, inodes, FAT tables,
|
|
whatever, then set to @code{NULL} at all other times (it will be
|
|
@code{NULL} by default). If this isn't done correctly, then the
|
|
@command{testload} and @command{install} commands won't work
|
|
correctly.
|
|
@end vtable
|
|
|
|
The functions expected to be used by the filesystem backend are:
|
|
|
|
@ftable @code
|
|
@item devread
|
|
Only read sectors from within a partition. Sector 0 is the first sector
|
|
in the partition.
|
|
|
|
@item grub_read
|
|
If the backend uses the blocklist code (like the FAT filesystem backend
|
|
does), then @code{grub_read} can be used, after setting @var{block_file}
|
|
to 1.
|
|
@end ftable
|
|
|
|
The functions expected to be defined by the filesystem backend are
|
|
described at least moderately in the file @file{filesys.h}. Their usage
|
|
is fairly evident from their use in the functions in @file{disk_io.c},
|
|
look for the use of the @var{fsys_table} array.
|
|
|
|
@strong{Caution:} The semantics are such that then @samp{mount}ing the
|
|
filesystem, presume the filesystem buffer @var{FSYS_BUF} is corrupted,
|
|
and (re-)load all important contents. When opening and reading a file,
|
|
presume that the data from the @samp{mount} is available, and doesn't
|
|
get corrupted by the open/read (i.e. multiple opens and/or reads will be
|
|
done with only one mount if in the same filesystem).
|
|
|
|
|
|
@node Index
|
|
@unnumbered Index
|
|
|
|
@c Currently, we use only the Concept Index.
|
|
@printindex cp
|
|
|
|
@contents
|
|
@bye
|