mirror of
https://git.savannah.gnu.org/git/grub.git
synced 2026-10-23 23:59:22 +00:00
1021 lines
39 KiB
Plaintext
1021 lines
39 KiB
Plaintext
\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)
|
|
+-------------------+
|
|
52 | drives_count | (present if flags[7] is set)
|
|
56 | drives_addr | (present if flags[7] is set)
|
|
+-------------------+
|
|
60 | config_table | (present if flags[8] is set)
|
|
+-------------------+
|
|
64 | boot_loader_name | (present if flags[9] is set)
|
|
+-------------------+
|
|
68 - ?? | apm_table | (present if flags[10] 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.
|
|
|
|
If bit 7 in the @samp{flags} is set, then the @samp{drives_*} fields
|
|
are valid, and indicate the address of the physical address of the first
|
|
drive structure and the number of drive structures. @samp{drives_addr}
|
|
is the address, and @samp{drives_count} is the
|
|
number. @samp{drives_count} may be zero. Each drive structure is
|
|
formatted as follows:
|
|
|
|
@example
|
|
@group
|
|
+-------------------+
|
|
0 | drive_number |
|
|
+-------------------+
|
|
1 | drive_mode |
|
|
+-------------------+
|
|
2 | drive_cylinders |
|
|
4 | drive_heads |
|
|
5 | drive_sectors |
|
|
+-------------------+
|
|
6 | drive_ports |
|
|
+-------------------+
|
|
10 | reserved (0) |
|
|
+-------------------+
|
|
@end group
|
|
@end example
|
|
|
|
The @samp{drive_number} field contains the BIOS drive number. The
|
|
@samp{drive_mode} field represents the access mode used by the boot
|
|
loader. Currently, the following modes are defined:
|
|
|
|
@table @samp
|
|
@item 0
|
|
CHS mode (traditional cylinder/head/sector addressing mode).
|
|
|
|
@item 1
|
|
LBA mode (Logical Block Addressing mode).
|
|
@end table
|
|
|
|
The three fields, @samp{drive_cylinders}, @samp{drive_heads} and
|
|
@samp{drive_sectors}, indicate the geometry of the drive detected by the
|
|
@sc{bios}. @samp{drive_cylinders} contains the number of the
|
|
cylinders. @samp{drive_heads} contains the number of the
|
|
heads. @samp{drive_sectors} contains the number of the sectors per
|
|
track.
|
|
|
|
The @samp{drive_ports} field contains the physical address of the array
|
|
of the I/O ports used for the drive in the @sc{bios} code. The array
|
|
consists of zero or more unsigned two-bytes integers, and is terminated
|
|
with zero. Note that the array may contain any number of I/O ports that
|
|
are not related to the drive actually (such as @sc{dma} controller's
|
|
ports).
|
|
|
|
The last field @samp{reserved} is reserved for future use, and must be
|
|
zero. The size is four bytes.
|
|
|
|
@c I'll write the descriptions about config_table, boot_loader_name and
|
|
@c apm_tabel. Just wait for a while. - okuji
|
|
|
|
|
|
@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
|
|
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 from:
|
|
|
|
@url{ftp://alpha.gnu.org/gnu/hurd/src/}
|
|
|
|
See the webpage @url{http://www.gnu.org/software/grub/grub.html}, for
|
|
more information.
|
|
|
|
|
|
@node Index
|
|
@unnumbered Index
|
|
|
|
@printindex cp
|
|
|
|
@contents
|
|
@bye
|