|  | \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 |