blob: 66003be2f64cbe40ec8280c37e2dbf74cb6053b5 [file] [log] [blame] [raw]
\input texinfo @c -*-texinfo-*-
@setfilename multiboot.info
@syncodeindex fn cp
@syncodeindex vr cp
@syncodeindex ky cp
@syncodeindex pg cp
@syncodeindex tp cp
@dircategory Kernel
@direntry
* Multiboot Specification: (multiboot). Multiboot Specification.
@end direntry
@ifinfo
Copyright @copyright{} 1995, 96 Bryan Ford <baford@@cs.utah.edu>
Copyright @copyright{} 1995, 96 Erich Stefan Boleyn <erich@@uruk.org>
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
@settitle Multiboot Specification
@titlepage
@finalout
@title The Multiboot Specification
@author Bryan Ford
@author Erich Stefan Boleyn
@author Kunihiro Ishiguro
@author OKUJI Yoshinori
@page
@vskip 0pt plus 1filll
Copyright @copyright{} 1995, 96 Bryan Ford <baford@@cs.utah.edu>
Copyright @copyright{} 1995, 96 Erich Stefan Boleyn <erich@@uruk.org>
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
@ifnottex
@node Top
@top Multiboot Specification
This file documents Multiboot Specification, the proposal for the boot
sequence standard. This edition documents version 0.7.
@end ifnottex
@menu
* Motivation::
* Terminology::
* Scope and requirements::
* Details::
* Examples::
* Index::
@detailmenu
--- The Detailed Node Listing ---
Scope and Requirements
* Architecture::
* Operating systems::
* Boot sources::
* Boot-time configuration::
* Convenience to the operating system::
* Boot modules::
Details
* OS image format::
* Machine state::
* Boot information format::
Examples
* Notes on PC::
* BIOS device mapping techniques::
* Example OS code::
* Example boot loader code::
@end detailmenu
@end menu
@node Motivation
@chapter Motivation
Every operating system ever created tends to have its own boot loader.
Installing a new operating system on a machine generally involves
installing a whole new set of boot mechanisms, each with completely
different install-time and boot-time user interfaces. Getting multiple
operating systems to coexist reliably on one machine through typical
@dfn{chaining} mechanisms can be a nightmare. There is little or no
choice of boot loaders for a particular operating system --- if the one
that comes with the operating system doesn't do exactly what you want,
or doesn't work on your machine, you're screwed.
While we may not be able to fix this problem in existing commercial
operating systems, it shouldn't be too difficult for a few people in the
free operating system communities to put their heads together and solve
this problem for the popular free operating systems. That's what this
specification aims for. Basically, it specifies an interface between a
boot loader and a operating system, such that any complying boot loader
should be able to load any complying operating system. This
specification does @emph{not} specify how boot loaders should work ---
only how they must interface with the operating system being loaded.
@node Terminology
@chapter Terminology
Throughout this document, the term @dfn{boot loader} means whatever
program or set of programs loads the image of the final operating system
to be run on the machine. The boot loader may itself consist of several
stages, but that is an implementation detail not relevant to this
specification. Only the @emph{final} stage of the boot loader --- the
stage that eventually transfers control to the operating system ---
needs to follow the rules specified in this document in order to be
@dfn{MultiBoot compliant}; earlier boot loader stages can be designed in
whatever way is most convenient.
The term @dfn{OS image} is used to refer to the initial binary image
that the boot loader loads into memory and transfers control to start
the operating system. The OS image is typically an executable containing
the operating system kernel.
The term @dfn{boot module} refers to other auxiliary files that the boot
loader loads into memory along with the OS image, but does not interpret
in any way other than passing their locations to the operating system
when it is invoked.
@node Scope and requirements
@chapter Scope and requirements
@menu
* Architecture::
* Operating systems::
* Boot sources::
* Boot-time configuration::
* Convenience to the operating system::
* Boot modules::
@end menu
@node Architecture
@section Architecture
This specification is primarily targeted at @sc{pc}, since they are the
most common and have the largest variety of operating systems and boot
loaders. However, to the extent that certain other architectures may
need a boot specification and do not have one already, a variation of
this specification, stripped of the x86-specific details, could be
adopted for them as well.
@node Operating systems
@section Operating systems
This specification is targeted toward free 32-bit operating systems
that can be fairly easily modified to support the specification without
going through lots of bureaucratic rigmarole. The particular free
operating systems that this specification is being primarily designed
for are Linux, FreeBSD, NetBSD, Mach, and VSTa. It is hoped that other
emerging free operating systems will adopt it from the start, and thus
immediately be able to take advantage of existing boot loaders. It would
be nice if commercial operating system vendors eventually adopted this
specification as well, but that's probably a pipe dream.
@node Boot sources
@section Boot sources
It should be possible to write compliant boot loaders that load the OS
image from a variety of sources, including floppy disk, hard disk, and
across a network.
Disk-based boot loaders may use a variety of techniques to find the
relevant OS image and boot module data on disk, such as by
interpretation of specific file systems (e.g. the BSD/Mach boot loader),
using precalculated @dfn{block lists} (e.g. LILO), loading from a
special @dfn{boot partition} (e.g. OS/2), or even loading from within
another operating system (e.g. the VSTa boot code, which loads from
DOS). Similarly, network-based boot loaders could use a variety of
network hardware and protocols.
It is hoped that boot loaders will be created that support multiple
loading mechanisms, increasing their portability, robustness, and
user-friendliness.
@node Boot-time configuration
@section Boot-time configuration
It is often necessary for one reason or another for the user to be able
to provide some configuration information to the operating system
dynamically at boot time. While this specification should not dictate
how this configuration information is obtained by the boot loader, it
should provide a standard means for the boot loader to pass such
information to the operating system.
@node Convenience to the operating system
@section Convenience to the operating system
OS images should be easy to generate. Ideally, an OS image should simply
be an ordinary 32-bit executable file in whatever file format the
operating system normally uses. It should be possible to @code{nm} or
disassemble OS images just like normal executables. Specialized tools
should not be needed to create OS images in a @emph{special} file
format. If this means shifting some work from the operating system to
the boot loader, that is probably appropriate, because all the memory
consumed by the boot loader will typically be made available again after
the boot process is created, whereas every bit of code in the OS image
typically has to remain in memory forever. The operating system should
not have to worry about getting into 32-bit mode initially, because mode
switching code generally needs to be in the boot loader anyway in order
to load operating system data above the 1MB boundary, and forcing the
operating system to do this makes creation of OS images much more
difficult.
Unfortunately, there is a horrendous variety of executable file formats
even among free Unix-like @sc{pc}-based operating systems --- generally
a different format for each operating system. Most of the relevant free
operating systems use some variant of a.out format, but some are moving
to @sc{elf}. It is highly desirable for boot loaders not to have to be
able to interpret all the different types of executable file formats in
existence in order to load the OS image --- otherwise the boot loader
effectively becomes operating system specific again.
This specification adopts a compromise solution to this
problem. Multiboot compliant boot images always contain a magic
@dfn{Multiboot header} (@pxref{OS image format}), which allows the boot
loader to load the image without having to understand numerous a.out
variants or other executable formats. This magic header does not need to
be at the very beginning of the executable file, so kernel images can
still conform to the local a.out format variant in addition to being
Multiboot compliant.
@node Boot modules
@section Boot modules
Many modern operating system kernels, such as those of VSTa and Mach, do
not by themselves contain enough mechanism to get the system fully
operational: they require the presence of additional software modules at
boot time in order to access devices, mount file systems, etc. While
these additional modules could be embedded in the main OS image along
with the kernel itself, and the resulting image be split apart manually
by the operating system when it receives control, it is often more
flexible, more space-efficient, and more convenient to the operating
system and user if the boot loader can load these additional modules
independently in the first place.
Thus, this specification should provide a standard method for a boot
loader to indicate to the operating system what auxiliary boot modules
were loaded, and where they can be found. Boot loaders don't have to
support multiple boot modules, but they are strongly encouraged to,
because some operating systems will be unable to boot without them.
@node Details
@chapter Details
There are three main aspects of the boot loader/OS image interface:
@enumerate
@item
The format of the OS image as seen by the boot loader.
@item
The state of the machine when the boot loader starts the operating
system.
@item
The format of the information passed by the boot loader to the operating
system.
@end enumerate
@menu
* OS image format::
* Machine state::
* Boot information format::
@end menu
@node OS image format
@section OS image format
An OS image is generally just an ordinary 32-bit executable file in the
standard format for that particular operating system, except that it may
be linked at a non-default load address to avoid loading on top of the
@sc{pc}'s I/O region or other reserved areas, and of course it can't use
shared libraries or other fancy features.
Unfortunately, the exact meaning of the text, data, bss, and entry
fields of a.out headers tends to vary widely between different
executable flavors, and it is sometimes very difficult to distinguish
one flavor from another (e.g. Linux @sc{zmagic} executables and Mach
@sc{zmagic} executables). Furthermore, there is no simple, reliable way
of determining at what address in memory the text segment is supposed to
start. Therefore, this specification requires that an additional header,
known as a @dfn{Multiboot header}, appear somewhere near the beginning
of the executable file. In general it should come @emph{as early as
possible}, and is typically embedded in the beginning of the text
segment after the @emph{real} executable header. It @emph{must} be
contained completely within the first 8192 bytes of the executable file,
and must be longword (32-bit) aligned. These rules allow the boot loader
to find and synchronize with the text segment in the a.out file without
knowing beforehand the details of the a.out variant. The layout of the
header is as follows:
@example
@group
+-------------------+
0 | magic: 0x1BADB002 | (required)
4 | flags | (required)
8 | checksum | (required)
+-------------------+
12 | header_addr | (present if flags[16] is set)
16 | load_addr | (present if flags[16] is set)
20 | load_end_addr | (present if flags[16] is set)
24 | bss_end_addr | (present if flags[16] is set)
28 | entry_addr | (present if flags[16] is set)
+-------------------+
@end group
@end example
All fields are in little-endian byte order, of course. The first field
is the magic number identifying the header, which must be the hex value
0x1BADB002.
The @samp{flags} field specifies features that the OS image requests or
requires of the boot loader. Bits 0-15 indicate requirements; if the
boot loader sees any of these bits set but doesn't understand the flag
or can't fulfill the requirements it indicates for some reason, it must
notify the user and fail to load the OS image. Bits 16-31 indicate
optional features; if any bits in this range are set but the boot loader
doesn't understand them, it can simply ignore them and proceed as
usual. Naturally, all as-yet-undefined bits in the @samp{flags} word
must be set to zero in OS images. This way, the @samp{flags} fields
serves for version control as well as simple feature selection.
If bit 0 in the @samp{flags} word is set, then all boot modules loaded
along with the operating system must be aligned on page (4KB)
boundaries. Some operating systems expect to be able to map the pages
containing boot modules directly into a paged address space during
startup, and thus need the boot modules to be page-aligned.
If bit 1 in the @samp{flags} word is set, then information on available
memory via at least the @samp{mem_*} fields of the Multiboot information
structure (@pxref{Boot information format}) must be included. If the
bootloader is capable of passing a memory map (the @samp{mmap_*} fields)
and one exists, then it must be included as well.
If bit 16 in the @samp{flags} word is set, then the fields at offsets
8-24 in the Multiboot header are valid, and the boot loader should use
them instead of the fields in the actual executable header to calculate
where to load the OS image. This information does not need to be
provided if the kernel image is in @sc{elf} format, but it @emph{must}
be provided if the images is in a.out format or in some other
format. Compliant boot loaders must be able to load images that either
are in @sc{elf} format or contain the load address information embedded
in the Multiboot header; they may also directly support other executable
formats, such as particular a.out variants, but are not required to.
All of the address fields enabled by flag bit 16 are physical addresses.
The meaning of each is as follows:
@table @code
@item header_addr
Contains the address corresponding to the beginning of the Multiboot
header --- the physical memory location at which the magic value is
supposed to be loaded. This field serves to @dfn{synchronize} the
mapping between OS image offsets and physical memory addresses.
@item load_addr
Contains the physical address of the beginning of the text segment. The
offset in the OS image file at which to start loading is defined by the
offset at which the header was found, minus (header_addr -
load_addr). load_addr must be less than or equal to header_addr.
@item load_end_addr
Contains the physical address of the end of the data
segment. (load_end_addr - load_addr) specifies how much data to load.
This implies that the text and data segments must be consecutive in the
OS image; this is true for existing a.out executable formats.
@item bss_end_addr
Contains the physical address of the end of the bss segment. The boot
loader initializes this area to zero, and reserves the memory it
occupies to avoid placing boot modules and other data relevant to the
operating system in that area.
@item entry_addr
The physical address to which the boot loader should jump in order to
start running the operating system.
@end table
The checksum is a 32-bit unsigned value which, when added to
the other required fields, must have a 32-bit unsigned sum of zero.
@node Machine state
@section Machine state
When the boot loader invokes the 32-bit operating system, the machine
must have the following state:
@itemize @bullet
@item
@code{CS} must be a 32-bit read/execute code segment with an offset of 0
and a limit of 0xFFFFFFFF.
@item
@code{DS}, @code{ES}, @code{FS}, @code{GS}, and @code{SS} must be a
32-bit read/write data segment with an offset of 0 and a limit of
0xFFFFFFFF.
@item
The address 20 line must be usable for standard linear 32-bit addressing
of memory (in standard @sc{pc} hardware, it is wired to 0 at bootup,
forcing addresses in the 1-2 MB range to be mapped to the 0-1 MB range,
3-4 is mapped to 2-3, etc.).
@item
Paging must be turned off.
@item
The processor interrupt flag must be turned off.
@item
@code{EAX} must contain the magic value 0x2BADB002; the presence of this
value indicates to the operating system that it was loaded by a
Multiboot-compliant boot loader (e.g. as opposed to another type of boot
loader that the operating system can also be loaded from).
@item
@code{EBX} must contain the 32-bit physical address of the Multiboot
information structure provided by the boot loader (@pxref{Boot
information format}).
@end itemize
All other processor registers and flag bits are undefined. This
includes, in particular:
@itemize @bullet
@item
@code{ESP}: the 32-bit operating system must create its own stack as
soon as it needs one.
@item
@code{GDTR}: Even though the segment registers are set up as described
above, the @code{GDTR} may be invalid, so the operating system must not
load any segment registers (even just reloading the same values!) until
it sets up its own @code{GDT}.
@item
@code{IDTR}: The operating system must leave interrupts disabled until
it sets up its own @code{IDT}.
@end itemize
However, other machine state should be left by the boot loader in
@dfn{normal working order}, i.e. as initialized by the @sc{bios} (or
DOS, if that's what the boot loader runs from). In other words, the
operating system should be able to make @sc{bios} calls and such after
being loaded, as long as it does not overwrite the @sc{bios} data
structures before doing so. Also, the boot loader must leave the
@sc{pic} programmed with the normal @sc{bios}/DOS values, even if it
changed them during the switch to 32-bit mode.
@node Boot information format
@section Boot information format
Upon entry to the operating system, the @code{EBX} register contains the
physical address of a @dfn{Multiboot information} data structure,
through which the boot loader communicates vital information to the
operating system. The operating system can use or ignore any parts of
the structure as it chooses; all information passed by the boot loader
is advisory only.
The Multiboot information structure and its related substructures may be
placed anywhere in memory by the boot loader (with the exception of the
memory reserved for the kernel and boot modules, of course). It is the
operating system's responsibility to avoid overwriting this memory until
it is done using it.
The format of the Multiboot information structure (as defined so far)
follows:
@example
@group
+-------------------+
0 | flags | (required)
+-------------------+
4 | mem_lower | (present if flags[0] is set)
8 | mem_upper | (present if flags[0] is set)
+-------------------+
12 | boot_device | (present if flags[1] is set)
+-------------------+
16 | cmdline | (present if flags[2] is set)
+-------------------+
20 | mods_count | (present if flags[3] is set)
24 | mods_addr | (present if flags[3] is set)
+-------------------+
28 - 40 | syms | (present if flags[4] or
| | flags[5] is set)
+-------------------+
44 | mmap_length | (present if flags[6] is set)
48 | mmap_addr | (present if flags[6] is set)
+-------------------+
@end group
@end example
The first longword indicates the presence and validity of other fields
in the Multiboot information structure. All as-yet-undefined bits must
be set to zero by the boot loader. Any set bits that the operating
system does not understand should be ignored. Thus, the @samp{flags}
field also functions as a version indicator, allowing the Multiboot
information structure to be expanded in the future without breaking
anything.
If bit 0 in the @samp{flags} word is set, then the @samp{mem_*} fields
are valid. @samp{mem_lower} and @samp{mem_upper} indicate the amount of
lower and upper memory, respectively, in kilobytes. Lower memory starts
at address 0, and upper memory starts at address 1 megabyte. The maximum
possible value for lower memory is 640 kilobytes. The value returned for
upper memory is maximally the address of the first upper memory hole
minus 1 megabyte. It is not guaranteed to be this value.
If bit 1 in the @samp{flags} word is set, then the @samp{boot_device}
field is valid, and indicates which @sc{bios} disk device the boot
loader loaded the OS image from. If the OS image was not loaded from a
@sc{bios} disk, then this field must not be present (bit 3 must be
clear). The operating system may use this field as a hint for
determining its own @dfn{root} device, but is not required to. The
@samp{boot_device} field is laid out in four one-byte subfields as
follows:
@example
@group
+-------+-------+-------+-------+
| drive | part1 | part2 | part3 |
+-------+-------+-------+-------+
@end group
@end example
The first byte contains the @sc{bios} drive number as understood by the
@sc{bios} INT 0x13 low-level disk interface: e.g. 0x00 for the first
floppy disk or 0x80 for the first hard disk.
The three remaining bytes specify the boot partition. @samp{part1}
specifies the @dfn{top-level} partition number, @samp{part2} specifies a
@dfn{sub-partition} in the top-level partition, etc. Partition numbers
always start from zero. Unused partition bytes must be set to 0xFF. For
example, if the disk is partitioned using a simple one-level DOS
partitioning scheme, then @samp{part1} contains the DOS partition
number, and @samp{part2} and @samp{part3} are both 0xFF. As another
example, if a disk is partitioned first into DOS partitions, and then
one of those DOS partitions is subdivided into several BSD partitions
using BSD's @dfn{disklabel} strategy, then @samp{part1} contains the DOS
partition number, @samp{part2} contains the BSD sub-partition within
that DOS partition, and @samp{part3} is 0xFF.
DOS extended partitions are indicated as partition numbers starting from
4 and increasing, rather than as nested sub-partitions, even though the
underlying disk layout of extended partitions is hierarchical in
nature. For example, if the boot loader boots from the second extended
partition on a disk partitioned in conventional DOS style, then
@samp{part1} will be 5, and @samp{part2} and @samp{part3} will both be
0xFF.
If bit 2 of the @samp{flags} longword is set, the @samp{cmdline} field
is valid, and contains the physical address of the command line to
be passed to the kernel. The command line is a normal C-style
zero-terminated string.
If bit 3 of the @samp{flags} is set, then the @samp{mods} fields
indicate to the kernel what boot modules were loaded along with the
kernel image, and where they can be found. @samp{mods_count} contains
the number of modules loaded; @samp{mods_addr} contains the physical
address of the first module structure. @samp{mods_count} may be zero,
indicating no boot modules were loaded, even if bit 1 of @samp{flags} is
set. Each module structure is formatted as follows:
@example
@group
+-------------------+
0 | mod_start |
4 | mod_end |
+-------------------+
8 | string |
+-------------------+
12 | reserved (0) |
+-------------------+
@end group
@end example
The first two fields contain the start and end addresses of the boot
module itself. The @samp{string} field provides an arbitrary string to
be associated with that particular boot module; it is a zero-terminated
ASCII string, just like the kernel command line. The @samp{string} field
may be 0 if there is no string associated with the module. Typically the
string might be a command line (e.g. if the operating system treats boot
modules as executable programs), or a pathname (e.g. if the operating
system treats boot modules as files in a file system), but its exact use
is specific to the operating system. The @samp{reserved} field must be
set to 0 by the boot loader and ignored by the operating system.
@strong{Caution:} Bits 4 & 5 are mutually exclusive.
If bit 4 in the @samp{flags} word is set, then the following fields in
the Multiboot information structure starting at byte 28 are valid:
@example
@group
+-------------------+
28 | tabsize |
32 | strsize |
36 | addr |
40 | reserved (0) |
+-------------------+
@end group
@end example
These indicate where the symbol table from an a.out kernel image can be
found. @samp{addr} is the physical address of the size (4-byte unsigned
long) of an array of a.out format @dfn{nlist} structures, followed
immediately by the array itself, then the size (4-byte unsigned long) of
a set of zero-terminated @sc{ascii} strings (plus sizeof(unsigned long) in
this case), and finally the set of strings itself. @samp{tabsize} is
equal to its size parameter (found at the beginning of the symbol
section), and @samp{strsize} is equal to its size parameter (found at
the beginning of the string section) of the following string table to
which the symbol table refers. Note that @samp{tabsize} may be 0,
indicating no symbols, even if bit 4 in the @samp{flags} word is set.
If bit 5 in the @samp{flags} word is set, then the following fields in
the Multiboot information structure starting at byte 28 are valid:
@example
@group
+-------------------+
28 | num |
32 | size |
36 | addr |
40 | shndx |
+-------------------+
@end group
@end example
These indicate where the section header table from an ELF kernel is, the
size of each entry, number of entries, and the string table used as the
index of names. They correspond to the @samp{shdr_*} entries
(@samp{shdr_num}, etc.) in the Executable and Linkable Format (@sc{elf})
specification in the program header. All sections are loaded, and the
physical address fields of the @sc{elf} section header then refer to where
the sections are in memory (refer to the i386 @sc{elf} documentation for
details as to how to read the section header(s)). Note that
@samp{shdr_num} may be 0, indicating no symbols, even if bit 5 in the
@samp{flags} word is set.
If bit 6 in the @samp{flags} word is set, then the @samp{mmap_*} fields
are valid, and indicate the address and length of a buffer containing a
memory map of the machine provided by the @sc{bios}. @samp{mmap_addr} is
the address, and @samp{mmap_length} is the total size of the buffer. The
buffer consists of one or more of the following size/structure pairs
(@samp{size} is really used for skipping to the next pair):
@example
@group
+-------------------+
-4 | size |
+-------------------+
0 | base_addr_low |
4 | base_addr_high |
8 | length_low |
12 | length_high |
16 | type |
+-------------------+
@end group
@end example
where @samp{size} is the size of the associated structure in bytes, which
can be greater than the minimum of 20 bytes. @samp{base_addr_low} is the
lower 32 bits of the starting address, and @samp{base_addr_high} is the
upper 32 bits, for a total of a 64-bit starting address. @samp{length_low}
is the lower 32 bits of the size of the memory region in bytes, and
@samp{length_high} is the upper 32 bits, for a total of a 64-bit
length. @samp{type} is the variety of address range represented, where a
value of 1 indicates available @sc{ram}, and all other values currently
indicated a reserved area.
The map provided is guaranteed to list all standard @sc{ram} that should
be available for normal use.
@node Examples
@chapter Examples
@strong{Caution:} The following items are not part of the specification
document, but are included for prospective operating system and boot
loader writers.
@menu
* Notes on PC::
* BIOS device mapping techniques::
* Example OS code::
* Example boot loader code::
@end menu
@node Notes on PC
@section Notes on PC
In reference to bit 0 of the @samp{flags} parameter in the Multiboot
information structure, if the bootloader in question uses older
@sc{bios} interfaces, or the newest ones are not available (see
description about bit 6), then a maximum of either 15 or 63 megabytes of
memory may be reported. It is @emph{highly} recommended that boot
loaders perform a thorough memory probe.
In reference to bit 1 of the @samp{flags} parameter in the Multiboot
information structure, it is recognized that determination of which
@sc{bios} drive maps to which device driver in an operating system is
non-trivial, at best. Many kludges have been made to various operating
systems instead of solving this problem, most of them breaking under
many conditions. To encourage the use of general-purpose solutions to
this problem, there are 2 @sc{bios} device mapping techniques
(@pxref{BIOS device mapping techniques}).
In reference to bit 6 of the @samp{flags} parameter in the Multiboot
information structure, it is important to note that the data structure
used there (starting with @samp{BaseAddrLow}) is the data returned by
the INT 15h, AX=E820h --- Query System Address Map call. See @xref{Query
System Address Map, , Query System Address Map, grub.info, The GRUB
Manual}, for more information. The interface here is meant to allow a
boot loader to work unmodified with any reasonable extensions of the
@sc{bios} interface, passing along any extra data to be interpreted by
the operating system as desired.
@node BIOS device mapping techniques
@section BIOS device mapping techniques
Both of these techniques should be usable from any PC operating system,
and neither require any special support in the drivers themselves. This
section will be flushed out into detailed explanations, particularly for
the I/O restriction technique.
The general rule is that the data comparison technique is the quick and
dirty solution. It works most of the time, but doesn't cover all the
bases, and is relatively simple.
The I/O restriction technique is much more complex, but it has potential
to solve the problem under all conditions, plus allow access of the
remaining @sc{bios} devices when not all of them have operating system
drivers.
@menu
* Data comparison technique::
* I/O restriction technique::
@end menu
@node Data comparison technique
@subsection Data comparison technique
Before activating @emph{any} of the device drivers, gather enough data
from similar sectors on each of the disks such that each one can be
uniquely identified.
After activating the device drivers, compare data from the drives using
the operating system drivers. This should hopefully be sufficient to
provide such a mapping.
Problems:
@enumerate
@item
The data on some @sc{bios} devices might be identical (so the part
reading the drives from the @sc{bios} should have some mechanism to give
up).
@item
There might be extra drives not accessible from the @sc{bios} which are
identical to some drive used by the @sc{bios} (so it should be capable
of giving up there as well).
@end enumerate
@node I/O restriction technique
@subsection I/O restriction technique
This first step may be unnecessary, but first create copy-on-write
mappings for the device drivers writing into @sc{pc} @sc{ram}. Keep the
original copies for the @dfn{clean @sc{bios} virtual machine} to be
created later.
For each device driver brought online, determine which @sc{bios} devices
become inaccessible by:
@enumerate
@item
Create a @dfn{clean @sc{bios} virtual machine}.
@item
Set the I/O permission map for the I/O area claimed by the device driver
to no permissions (neither read nor write).
@item
Access each device.
@item
Record which devices succeed, and those which try to access the
@dfn{restricted} I/O areas (hopefully, this will be an @dfn{xor}
situation).
@end enumerate
For each device driver, given how many of the @sc{bios} devices were
subsumed by it (there should be no gaps in this list), it should be easy
to determine which devices on the controller these are.
In general, you have at most 2 disks from each controller given
@sc{bios} numbers, but they pretty much always count from the lowest
logically numbered devices on the controller.
@node Example OS code
@section Example OS code
In this distribution, the example Multiboot kernel @file{kernel} is
included. The kernel just prints out the Multiboot information structure
on the screen, so you can make use of the kernel to test a
Multiboot-compliant boot loader and for reference to how to implement a
Multiboot kernel. The source files can be found under the directory
@file{docs} in the GRUB distribution.
The kernel @file{kernel} consists of only three files: @file{boot.S},
@file{kernel.c} and @file{multiboot.h}. The assembly source
@file{boot.S} is written in GAS (@pxref{Top, , GNU assembler, as.info,
The GNU assembler}), and contains the Multiboot information structure to
comply with the specification. When a Multiboot-compliant boot loader
loads and execute it, it initialize the stack pointer and @code{EFLAGS},
and then call the function @code{cmain} defined in @file{kernel.c}. If
@code{cmain} returns to the callee, then it shows a message to inform
the user of the halt state and stops forever until you push the reset
key. The file @file{kernel.c} contains the function @code{cmain},
which checks if the magic number passed by the boot loader is valid and
so on, and some functions to print messages on the screen. The file
@file{multiboot.h} defines some macros, such as the magic number for the
Multiboot header, the Multiboot header structure and the Multiboot
information structure.
@menu
* multiboot.h::
* boot.S::
* kernel.c::
* Other Multiboot kernels::
@end menu
@node multiboot.h
@subsection multiboot.h
This is the source code in the file @file{multiboot.h}:
@example
@include multiboot.h.texi
@end example
@node boot.S
@subsection boot.S
In the file @file{boot.S}:
@example
@include boot.S.texi
@end example
@node kernel.c
@subsection kernel.c
And, in the file @file{kernel.c}:
@example
@include kernel.c.texi
@end example
@node Other Multiboot kernels
@subsection Other Multiboot kernels
Other useful information should be available in Multiboot kernels, such
as GNU Mach and Fiasco @url{http://os.inf.tu-dresden.de/fiasco/}. And,
it is worth mentioning the OSKit
@url{http://www.cs.utah.edu/projects/flux/oskit/}, which provides a
library supporting the specification.
@node Example boot loader code
@section Example boot loader code
The GNU GRUB (@pxref{Top, , GRUB, grub.info, The GRUB manual}) project
@url{http://www.gnu.org/software/grub/grub.en.html} is a full
Multiboot-compliant boot loader, supporting all required and optional
features present in this specification. A public release has not been
made, but the test release is available in
@url{ftp://alpha.gnu.org/gnu/hurd/src/}.
@node Index
@unnumbered Index
@printindex cp
@contents
@bye