diff --git a/ChangeLog b/ChangeLog
index b76fe38..24271a4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2009-08-19 Vladimir Serbinenko
+
+ Import multiboot specification
+
+ * docs/kernel.c: New file.
+ * docs/multiboot.h: Likewise.
+ * docs/multiboot.texi: Likewise.
+ * docs/src2texi: Likewise.
+ * conf/common.rmk (SRC2TEXI): New variable.
+ (MULTIBOOT_TEXI): Likewise.
+ (%.c.texi): New target.
+ (%.h.texi): Likewise.
+ (%.S.texi): Likewise.
+ (multiboot.dvi): Likewise.
+ (multiboot.html): Likewise.
+ (multiboot.info): Likewise.
+ (multiboot.info.bz2): Likewise.
+
2009-08-17 Michal Suchanek
VBE cleanup.
diff --git a/conf/common.rmk b/conf/common.rmk
index b0d3785..314e6b4 100644
--- a/conf/common.rmk
+++ b/conf/common.rmk
@@ -1,5 +1,32 @@
# -*- makefile -*-
+SRC2TEXI=src2texi
+MULTIBOOT_TEXI=docs/multiboot.texi docs/multiboot.h.texi docs/kernel.c.texi docs/boot.S.texi
+
+%.c.texi: %.c $(srcdir)/docs/$(SRC2TEXI)
+ $(SHELL) $(srcdir)/docs/$(SRC2TEXI) $(srcdir)/docs $< $@
+
+%.h.texi: %.h $(srcdir)/docs/$(SRC2TEXI)
+ $(SHELL) $(srcdir)/docs/$(SRC2TEXI) $(srcdir)/docs $< $@
+
+%.S.texi: %.S $(srcdir)/docs/$(SRC2TEXI)
+ $(SHELL) $(srcdir)/docs/$(SRC2TEXI) $(srcdir)/docs $< $@
+
+multiboot.dvi: $(MULTIBOOT_TEXI)
+ texi2dvi -o $@ $<
+
+multiboot.pdf: $(MULTIBOOT_TEXI)
+ texi2pdf -o $@ $<
+
+multiboot.html: $(MULTIBOOT_TEXI)
+ texi2html -o $@ $<
+
+multiboot.info: $(MULTIBOOT_TEXI)
+ makeinfo -o $@ $<
+
+multiboot.info.bz2: multiboot.info
+ bzip2 < $< > $@
+
# For grub-mkelfimage.
bin_UTILITIES += grub-mkelfimage
grub_mkelfimage_SOURCES = util/elf/grub-mkimage.c util/misc.c \
diff --git a/docs/boot.S b/docs/boot.S
new file mode 100644
index 0000000..4db6a00
--- /dev/null
+++ b/docs/boot.S
@@ -0,0 +1,79 @@
+/* boot.S - bootstrap the kernel */
+/* Copyright (C) 1999, 2001 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#define ASM 1
+#include
+
+ .text
+
+ .globl start, _start
+start:
+_start:
+ jmp multiboot_entry
+
+ /* Align 32 bits boundary. */
+ .align 4
+
+ /* Multiboot header. */
+multiboot_header:
+ /* magic */
+ .long MULTIBOOT_HEADER_MAGIC
+ /* flags */
+ .long MULTIBOOT_HEADER_FLAGS
+ /* checksum */
+ .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
+#ifndef __ELF__
+ /* header_addr */
+ .long multiboot_header
+ /* load_addr */
+ .long _start
+ /* load_end_addr */
+ .long _edata
+ /* bss_end_addr */
+ .long _end
+ /* entry_addr */
+ .long multiboot_entry
+#endif /* ! __ELF__ */
+
+multiboot_entry:
+ /* Initialize the stack pointer. */
+ movl $(stack + STACK_SIZE), %esp
+
+ /* Reset EFLAGS. */
+ pushl $0
+ popf
+
+ /* Push the pointer to the Multiboot information structure. */
+ pushl %ebx
+ /* Push the magic value. */
+ pushl %eax
+
+ /* Now enter the C main function... */
+ call EXT_C(cmain)
+
+ /* Halt. */
+ pushl $halt_message
+ call EXT_C(printf)
+
+loop: hlt
+ jmp loop
+
+halt_message:
+ .asciz "Halted."
+
+ /* Our stack area. */
+ .comm stack, STACK_SIZE
diff --git a/docs/kernel.c b/docs/kernel.c
new file mode 100644
index 0000000..af0def9
--- /dev/null
+++ b/docs/kernel.c
@@ -0,0 +1,284 @@
+/* kernel.c - the C part of the kernel */
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include
+
+/* Macros. */
+
+/* Check if the bit BIT in FLAGS is set. */
+#define CHECK_FLAG(flags,bit) ((flags) & (1 << (bit)))
+
+/* Some screen stuff. */
+/* The number of columns. */
+#define COLUMNS 80
+/* The number of lines. */
+#define LINES 24
+/* The attribute of an character. */
+#define ATTRIBUTE 7
+/* The video memory address. */
+#define VIDEO 0xB8000
+
+/* Variables. */
+/* Save the X position. */
+static int xpos;
+/* Save the Y position. */
+static int ypos;
+/* Point to the video memory. */
+static volatile unsigned char *video;
+
+/* Forward declarations. */
+void cmain (unsigned long magic, unsigned long addr);
+static void cls (void);
+static void itoa (char *buf, int base, int d);
+static void putchar (int c);
+void printf (const char *format, ...);
+
+/* Check if MAGIC is valid and print the Multiboot information structure
+ pointed by ADDR. */
+void
+cmain (unsigned long magic, unsigned long addr)
+{
+ multiboot_info_t *mbi;
+
+ /* Clear the screen. */
+ cls ();
+
+ /* Am I booted by a Multiboot-compliant boot loader? */
+ if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
+ {
+ printf ("Invalid magic number: 0x%x\n", (unsigned) magic);
+ return;
+ }
+
+ /* Set MBI to the address of the Multiboot information structure. */
+ mbi = (multiboot_info_t *) addr;
+
+ /* Print out the flags. */
+ printf ("flags = 0x%x\n", (unsigned) mbi->flags);
+
+ /* Are mem_* valid? */
+ if (CHECK_FLAG (mbi->flags, 0))
+ printf ("mem_lower = %uKB, mem_upper = %uKB\n",
+ (unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper);
+
+ /* Is boot_device valid? */
+ if (CHECK_FLAG (mbi->flags, 1))
+ printf ("boot_device = 0x%x\n", (unsigned) mbi->boot_device);
+
+ /* Is the command line passed? */
+ if (CHECK_FLAG (mbi->flags, 2))
+ printf ("cmdline = %s\n", (char *) mbi->cmdline);
+
+ /* Are mods_* valid? */
+ if (CHECK_FLAG (mbi->flags, 3))
+ {
+ module_t *mod;
+ int i;
+
+ printf ("mods_count = %d, mods_addr = 0x%x\n",
+ (int) mbi->mods_count, (int) mbi->mods_addr);
+ for (i = 0, mod = (module_t *) mbi->mods_addr;
+ i < mbi->mods_count;
+ i++, mod++)
+ printf (" mod_start = 0x%x, mod_end = 0x%x, string = %s\n",
+ (unsigned) mod->mod_start,
+ (unsigned) mod->mod_end,
+ (char *) mod->string);
+ }
+
+ /* Bits 4 and 5 are mutually exclusive! */
+ if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5))
+ {
+ printf ("Both bits 4 and 5 are set.\n");
+ return;
+ }
+
+ /* Is the symbol table of a.out valid? */
+ if (CHECK_FLAG (mbi->flags, 4))
+ {
+ aout_symbol_table_t *aout_sym = &(mbi->u.aout_sym);
+
+ printf ("aout_symbol_table: tabsize = 0x%0x, "
+ "strsize = 0x%x, addr = 0x%x\n",
+ (unsigned) aout_sym->tabsize,
+ (unsigned) aout_sym->strsize,
+ (unsigned) aout_sym->addr);
+ }
+
+ /* Is the section header table of ELF valid? */
+ if (CHECK_FLAG (mbi->flags, 5))
+ {
+ elf_section_header_table_t *elf_sec = &(mbi->u.elf_sec);
+
+ printf ("elf_sec: num = %u, size = 0x%x,"
+ " addr = 0x%x, shndx = 0x%x\n",
+ (unsigned) elf_sec->num, (unsigned) elf_sec->size,
+ (unsigned) elf_sec->addr, (unsigned) elf_sec->shndx);
+ }
+
+ /* Are mmap_* valid? */
+ if (CHECK_FLAG (mbi->flags, 6))
+ {
+ memory_map_t *mmap;
+
+ printf ("mmap_addr = 0x%x, mmap_length = 0x%x\n",
+ (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length);
+ for (mmap = (memory_map_t *) mbi->mmap_addr;
+ (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
+ mmap = (memory_map_t *) ((unsigned long) mmap
+ + mmap->size + sizeof (mmap->size)))
+ printf (" size = 0x%x, base_addr = 0x%x%x,"
+ " length = 0x%x%x, type = 0x%x\n",
+ (unsigned) mmap->size,
+ (unsigned) mmap->base_addr_high,
+ (unsigned) mmap->base_addr_low,
+ (unsigned) mmap->length_high,
+ (unsigned) mmap->length_low,
+ (unsigned) mmap->type);
+ }
+}
+
+/* Clear the screen and initialize VIDEO, XPOS and YPOS. */
+static void
+cls (void)
+{
+ int i;
+
+ video = (unsigned char *) VIDEO;
+
+ for (i = 0; i < COLUMNS * LINES * 2; i++)
+ *(video + i) = 0;
+
+ xpos = 0;
+ ypos = 0;
+}
+
+/* Convert the integer D to a string and save the string in BUF. If
+ BASE is equal to 'd', interpret that D is decimal, and if BASE is
+ equal to 'x', interpret that D is hexadecimal. */
+static void
+itoa (char *buf, int base, int d)
+{
+ char *p = buf;
+ char *p1, *p2;
+ unsigned long ud = d;
+ int divisor = 10;
+
+ /* If %d is specified and D is minus, put `-' in the head. */
+ if (base == 'd' && d < 0)
+ {
+ *p++ = '-';
+ buf++;
+ ud = -d;
+ }
+ else if (base == 'x')
+ divisor = 16;
+
+ /* Divide UD by DIVISOR until UD == 0. */
+ do
+ {
+ int remainder = ud % divisor;
+
+ *p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10;
+ }
+ while (ud /= divisor);
+
+ /* Terminate BUF. */
+ *p = 0;
+
+ /* Reverse BUF. */
+ p1 = buf;
+ p2 = p - 1;
+ while (p1 < p2)
+ {
+ char tmp = *p1;
+ *p1 = *p2;
+ *p2 = tmp;
+ p1++;
+ p2--;
+ }
+}
+
+/* Put the character C on the screen. */
+static void
+putchar (int c)
+{
+ if (c == '\n' || c == '\r')
+ {
+ newline:
+ xpos = 0;
+ ypos++;
+ if (ypos >= LINES)
+ ypos = 0;
+ return;
+ }
+
+ *(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF;
+ *(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE;
+
+ xpos++;
+ if (xpos >= COLUMNS)
+ goto newline;
+}
+
+/* Format a string and print it on the screen, just like the libc
+ function printf. */
+void
+printf (const char *format, ...)
+{
+ char **arg = (char **) &format;
+ int c;
+ char buf[20];
+
+ arg++;
+
+ while ((c = *format++) != 0)
+ {
+ if (c != '%')
+ putchar (c);
+ else
+ {
+ char *p;
+
+ c = *format++;
+ switch (c)
+ {
+ case 'd':
+ case 'u':
+ case 'x':
+ itoa (buf, c, *((int *) arg++));
+ p = buf;
+ goto string;
+ break;
+
+ case 's':
+ p = *arg++;
+ if (! p)
+ p = "(null)";
+
+ string:
+ while (*p)
+ putchar (*p++);
+ break;
+
+ default:
+ putchar (*((int *) arg++));
+ break;
+ }
+ }
+ }
+}
diff --git a/docs/multiboot.h b/docs/multiboot.h
new file mode 100644
index 0000000..df79225
--- /dev/null
+++ b/docs/multiboot.h
@@ -0,0 +1,119 @@
+/* multiboot.h - the header for Multiboot */
+/* Copyright (C) 1999, 2001 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Macros. */
+
+/* The magic number for the Multiboot header. */
+#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
+
+/* The flags for the Multiboot header. */
+#ifdef __ELF__
+# define MULTIBOOT_HEADER_FLAGS 0x00000003
+#else
+# define MULTIBOOT_HEADER_FLAGS 0x00010003
+#endif
+
+/* The magic number passed by a Multiboot-compliant boot loader. */
+#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002
+
+/* The size of our stack (16KB). */
+#define STACK_SIZE 0x4000
+
+/* C symbol format. HAVE_ASM_USCORE is defined by configure. */
+#ifdef HAVE_ASM_USCORE
+# define EXT_C(sym) _ ## sym
+#else
+# define EXT_C(sym) sym
+#endif
+
+#ifndef ASM
+/* Do not include here in boot.S. */
+
+/* Types. */
+
+/* The Multiboot header. */
+typedef struct multiboot_header
+{
+ unsigned long magic;
+ unsigned long flags;
+ unsigned long checksum;
+ unsigned long header_addr;
+ unsigned long load_addr;
+ unsigned long load_end_addr;
+ unsigned long bss_end_addr;
+ unsigned long entry_addr;
+} multiboot_header_t;
+
+/* The symbol table for a.out. */
+typedef struct aout_symbol_table
+{
+ unsigned long tabsize;
+ unsigned long strsize;
+ unsigned long addr;
+ unsigned long reserved;
+} aout_symbol_table_t;
+
+/* The section header table for ELF. */
+typedef struct elf_section_header_table
+{
+ unsigned long num;
+ unsigned long size;
+ unsigned long addr;
+ unsigned long shndx;
+} elf_section_header_table_t;
+
+/* The Multiboot information. */
+typedef struct multiboot_info
+{
+ unsigned long flags;
+ unsigned long mem_lower;
+ unsigned long mem_upper;
+ unsigned long boot_device;
+ unsigned long cmdline;
+ unsigned long mods_count;
+ unsigned long mods_addr;
+ union
+ {
+ aout_symbol_table_t aout_sym;
+ elf_section_header_table_t elf_sec;
+ } u;
+ unsigned long mmap_length;
+ unsigned long mmap_addr;
+} multiboot_info_t;
+
+/* The module structure. */
+typedef struct module
+{
+ unsigned long mod_start;
+ unsigned long mod_end;
+ unsigned long string;
+ unsigned long reserved;
+} module_t;
+
+/* The memory map. Be careful that the offset 0 is base_addr_low
+ but no size. */
+typedef struct memory_map
+{
+ unsigned long size;
+ unsigned long base_addr_low;
+ unsigned long base_addr_high;
+ unsigned long length_low;
+ unsigned long length_high;
+ unsigned long type;
+} memory_map_t;
+
+#endif /* ! ASM */
diff --git a/docs/multiboot.texi b/docs/multiboot.texi
new file mode 100644
index 0000000..c069fae
--- /dev/null
+++ b/docs/multiboot.texi
@@ -0,0 +1,1234 @@
+\input texinfo @c -*-texinfo-*-
address@hidden %**start of header
address@hidden multiboot.info
address@hidden VERSION 0.6.95
address@hidden Multiboot Specification version @value{VERSION}
address@hidden Unify all our little indices for now.
address@hidden fn cp
address@hidden vr cp
address@hidden ky cp
address@hidden pg cp
address@hidden tp cp
address@hidden %**end of header
+
address@hidden separate
address@hidden 3
address@hidden
+
address@hidden
+Copyright @copyright{} 1995,96 Bryan Ford
+
+Copyright @copyright{} 1995,96 Erich Stefan Boleyn
+
+Copyright @copyright{} 1999,2000,2001,2002,2005,2006 Free Software Foundation, Inc.
+
address@hidden
+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.
+
address@hidden
+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).
address@hidden 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.
address@hidden quotation
address@hidden copying
+
address@hidden Kernel
address@hidden
+* Multiboot Specification: (multiboot). Multiboot Specification.
address@hidden direntry
+
address@hidden
address@hidden 10
address@hidden The Multiboot Specification version @value{VERSION}
address@hidden Yoshinori K. Okuji, Bryan Ford, Erich Stefan Boleyn, Kunihiro Ishiguro
address@hidden
address@hidden 0pt plus 1filll
address@hidden
address@hidden titlepage
+
address@hidden
address@hidden double
+
address@hidden
address@hidden Top
address@hidden Multiboot Specification
+
+This file documents Multiboot Specification, the proposal for the boot
+sequence standard. This edition documents version @value{VERSION}.
+
address@hidden
address@hidden ifnottex
+
address@hidden
+* Overview::
+* Terminology::
+* Specification::
+* Examples::
+* History::
+* Index::
address@hidden menu
+
+
address@hidden Overview
address@hidden Introduction to Multiboot Specification
+
+This chapter describes some rough information on the Multiboot
+Specification. Note that this is not a part of the specification itself.
+
address@hidden
+* Motivation::
+* Architecture::
+* Operating systems::
+* Boot sources::
+* Boot-time configuration::
+* Convenience to operating systems::
+* Boot modules::
address@hidden menu
+
+
address@hidden Motivation
address@hidden The background of Multiboot Specification
+
+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
address@hidden 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.
+
+
address@hidden Architecture
address@hidden The target 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.
+
+
address@hidden Operating systems
address@hidden The target 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.
+
+
address@hidden Boot sources
address@hidden 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{blocklists} (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.
+
+
address@hidden Boot-time configuration
address@hidden Configure an operating system at boot-time
+
+It is often necessary for one reason or another for the user to be able
+to provide some configuration information to an 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.
+
+
address@hidden Convenience to operating systems
address@hidden How to make OS development easier
+
+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 required to create OS images in a @emph{special} file
+format. If this means shifting some work from the operating system to
+a 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 OS images always contain a magic
address@hidden 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.
+
+
address@hidden Boot modules
address@hidden 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.
+
+
address@hidden Terminology
address@hidden The definitions of terms used through the specification
+
address@hidden @dfn
address@hidden must
+We use the term @dfn{must}, when any boot loader or OS image needs to
+follow a rule --- otherwise, the boot loader or OS image is @emph{not}
+Multiboot-compliant.
+
address@hidden should
+We use the term @dfn{should}, when any boot loader or OS image is
+recommended to follow a rule, but it doesn't need to follow the rule.
+
address@hidden may
+We use the term @dfn{may}, when any boot loader or OS image is allowed
+to follow a rule.
+
address@hidden boot loader
+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 an operating
+system --- must follow the rules specified in this document in order
+to be @dfn{Multiboot-compliant}; earlier boot loader stages may be
+designed in whatever way is most convenient.
+
address@hidden OS image
+The initial binary image that a boot loader loads into memory and
+transfers control to start an operating system. The OS image is
+typically an executable containing the operating system kernel.
+
address@hidden boot module
+Other auxiliary files that a boot loader loads into memory along with
+an OS image, but does not interpret in any way other than passing their
+locations to the operating system when it is invoked.
+
address@hidden Multiboot-compliant
+A boot loader or an OS image which follows the rules defined as
address@hidden is Multiboot-compliant. When this specification specifies a
+rule as @dfn{should} or @dfn{may}, a Multiboot-complaint boot loader/OS
+image doesn't need to follow the rule.
+
address@hidden u8
+The type of unsigned 8-bit data.
+
address@hidden u16
+The type of unsigned 16-bit data. Because the target architecture is
+little-endian, u16 is coded in little-endian.
+
address@hidden u32
+The type of unsigned 32-bit data. Because the target architecture is
+little-endian, u32 is coded in little-endian.
+
address@hidden u64
+The type of unsigned 64-bit data. Because the target architecture is
+little-endian, u64 is coded in little-endian.
address@hidden table
+
+
address@hidden Specification
address@hidden The exact definitions of Multiboot Specification
+
+There are three main aspects of a boot loader/OS image interface:
+
address@hidden
address@hidden
+The format of an OS image as seen by a boot loader.
+
address@hidden
+The state of a machine when a boot loader starts an operating
+system.
+
address@hidden
+The format of information passed by a boot loader to an operating
+system.
address@hidden enumerate
+
address@hidden
+* OS image format::
+* Machine state::
+* Boot information format::
address@hidden menu
+
+
address@hidden OS image format
address@hidden OS image format
+
+An OS image may be 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
address@hidden's I/O region or other reserved areas, and of course it should
+not use shared libraries or other fancy features.
+
+An OS image must contain an additional header called @dfn{Multiboot
+header}, besides the headers of the format used by the OS image. The
+Multiboot header must be contained completely within the first 8192
+bytes of the OS image, and must be longword (32-bit) aligned. In
+general, it should come @emph{as early as possible}, and may be
+embedded in the beginning of the text segment after the @emph{real}
+executable header.
+
address@hidden
+* Header layout:: The layout of Multiboot header
+* Header magic fields:: The magic fields of Multiboot header
+* Header address fields::
+* Header graphics fields::
address@hidden menu
+
+
address@hidden Header layout
address@hidden The layout of Multiboot header
+
+The layout of the Multiboot header must be as follows:
+
address@hidden @columnfractions .1 .1 .2 .5
address@hidden Offset @tab Type @tab Field Name @tab Note
address@hidden 0 @tab u32 @tab magic @tab required
address@hidden 4 @tab u32 @tab flags @tab required
address@hidden 8 @tab u32 @tab checksum @tab required
address@hidden 12 @tab u32 @tab header_addr @tab if flags[16] is set
address@hidden 16 @tab u32 @tab load_addr @tab if flags[16] is set
address@hidden 20 @tab u32 @tab load_end_addr @tab if flags[16] is set
address@hidden 24 @tab u32 @tab bss_end_addr @tab if flags[16] is set
address@hidden 28 @tab u32 @tab entry_addr @tab if flags[16] is set
address@hidden 32 @tab u32 @tab mode_type @tab if flags[2] is set
address@hidden 36 @tab u32 @tab width @tab if flags[2] is set
address@hidden 40 @tab u32 @tab height @tab if flags[2] is set
address@hidden 44 @tab u32 @tab depth @tab if flags[2] is set
address@hidden multitable
+
+The fields @samp{magic}, @samp{flags} and @samp{checksum} are defined in
address@hidden magic fields}, the fields @samp{header_addr},
address@hidden, @samp{load_end_addr}, @samp{bss_end_addr} and
address@hidden are defined in @ref{Header address fields}, and the
+fields @samp{mode_type}, @samp{width}, @samp{height} and @samp{depth} are
+defined in @ref{Header graphics fields}.
+
+
address@hidden Header magic fields
address@hidden The magic fields of Multiboot header
+
address@hidden @samp
address@hidden magic
+The field @samp{magic} is the magic number identifying the header,
+which must be the hexadecimal value @code{0x1BADB002}.
+
address@hidden flags
+The field @samp{flags} specifies features that the OS image requests or
+requires of an 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 may 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
+boot loader is capable of passing a memory map (the @samp{mmap_*} fields)
+and one exists, then it may be included as well.
+
+If bit 2 in the @samp{flags} word is set, information about the video
+mode table (@pxref{Boot information format}) must be available to the
+kernel.
+
+If bit 16 in the @samp{flags} word is set, then the fields at offsets
+12-28 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.
+
address@hidden checksum
+The field @samp{checksum} is a 32-bit unsigned value which, when added
+to the other magic fields (i.e. @samp{magic} and @samp{flags}), must
+have a 32-bit unsigned sum of zero.
address@hidden table
+
+
address@hidden Header address fields
address@hidden The address fields of Multiboot header
+
+All of the address fields enabled by flag bit 16 are physical addresses.
+The meaning of each is as follows:
+
address@hidden @code
address@hidden 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.
+
address@hidden 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.
+
address@hidden 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.
+If this field is zero, the boot loader assumes that the text and data
+segments occupy the whole OS image file.
+
address@hidden 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. If this field is zero, the boot loader
+assumes that no bss segment is present.
+
address@hidden entry_addr
+The physical address to which the boot loader should jump in order to
+start running the operating system.
address@hidden table
+
+
address@hidden Header graphics fields
address@hidden The graphics fields of Multiboot header
+
+All of the graphics fields are enabled by flag bit 2. They specify the
+preferred graphics mode. Note that that is only a @emph{recommended}
+mode by the OS image. If the mode exists, the boot loader should set
+it, when the user doesn't specify a mode explicitly. Otherwise, the
+boot loader should fall back to a similar mode, if available.
+
+The meaning of each is as follows:
+
address@hidden @code
address@hidden mode_type
+Contains @samp{0} for linear graphics mode or @samp{1} for
+EGA-standard text mode. Everything else is reserved for future
+expansion. Note that the boot loader may set a text mode, even if this
+field contains @samp{0}.
+
address@hidden width
+Contains the number of the columns. This is specified in pixels in a
+graphics mode, and in characters in a text mode. The value zero
+indicates that the OS image has no preference.
+
address@hidden height
+Contains the number of the lines. This is specified in pixels in a
+graphics mode, and in characters in a text mode. The value zero
+indicates that the OS image has no preference.
+
address@hidden depth
+Contains the number of bits per pixel in a graphics mode, and zero in
+a text mode. The value zero indicates that the OS image has no
+preference.
address@hidden table
+
+
address@hidden Machine state
address@hidden Machine state
+
+When the boot loader invokes the 32-bit operating system, the machine
+must have the following state:
+
address@hidden @samp
address@hidden EAX
+Must contain the magic value @samp{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).
+
address@hidden EBX
+Must contain the 32-bit physical address of the Multiboot
+information structure provided by the boot loader (@pxref{Boot
+information format}).
+
address@hidden CS
+Must be a 32-bit read/execute code segment with an offset of @samp{0}
+and a limit of @samp{0xFFFFFFFF}. The exact value is undefined.
+
address@hidden DS
address@hidden ES
address@hidden FS
address@hidden GS
address@hidden SS
+Must be a 32-bit read/write data segment with an offset of @samp{0}
+and a limit of @samp{0xFFFFFFFF}. The exact values are all undefined.
+
address@hidden A20 gate
+Must be enabled.
+
address@hidden CR0
+Bit 31 (PG) must be cleared. Bit 0 (PE) must be set. Other bits are
+all undefined.
+
address@hidden EFLAGS
+Bit 17 (VM) must be cleared. Bit 9 (IF) must be cleared. Other bits
+are all undefined.
address@hidden table
+
+All other processor registers and flag bits are undefined. This
+includes, in particular:
+
address@hidden @samp
address@hidden ESP
+The OS image must create its own stack as soon as it needs one.
+
address@hidden GDTR
+Even though the segment registers are set up as described above, the
address@hidden may be invalid, so the OS image must not load any segment
+registers (even just reloading the same values!) until it sets up its
+own @samp{GDT}.
+
address@hidden IDTR
+The OS image must leave interrupts disabled until it sets up its own
address@hidden
address@hidden table
+
+However, other machine state should be left by the boot loader in
address@hidden 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
address@hidden programmed with the normal @sc{bios}/DOS values, even if it
+changed them during the switch to 32-bit mode.
+
+
address@hidden Boot information format
address@hidden Boot information format
+
+FIXME: Split this chapter like the chapter ``OS image 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:
+
address@hidden
address@hidden
+ +-------------------+
+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_length | (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)
+ +-------------------+
+72 | vbe_control_info | (present if flags[11] is set)
+76 | vbe_mode_info |
+80 | vbe_mode |
+82 | vbe_interface_seg |
+84 | vbe_interface_off |
+86 | vbe_interface_len |
+ +-------------------+
address@hidden group
address@hidden 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
address@hidden 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
address@hidden field is laid out in four one-byte subfields as
+follows:
+
address@hidden
address@hidden
++-------+-------+-------+-------+
+| part3 | part2 | part1 | drive |
++-------+-------+-------+-------+
address@hidden group
address@hidden example
+
+The first byte contains the @sc{bios} drive number as understood by the
address@hidden 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
address@hidden 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
address@hidden 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:
+
address@hidden
address@hidden
+ +-------------------+
+0 | mod_start |
+4 | mod_end |
+ +-------------------+
+8 | string |
+ +-------------------+
+12 | reserved (0) |
+ +-------------------+
address@hidden group
address@hidden 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.
+
address@hidden:} 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:
+
address@hidden
address@hidden
+ +-------------------+
+28 | tabsize |
+32 | strsize |
+36 | addr |
+40 | reserved (0) |
+ +-------------------+
address@hidden group
address@hidden 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:
+
address@hidden
address@hidden
+ +-------------------+
+28 | num |
+32 | size |
+36 | addr |
+40 | shndx |
+ +-------------------+
address@hidden group
address@hidden 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
address@hidden may be 0, indicating no symbols, even if bit 5 in the
address@hidden 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):
+
address@hidden
address@hidden
+ +-------------------+
+-4 | size |
+ +-------------------+
+0 | base_addr_low |
+4 | base_addr_high |
+8 | length_low |
+12 | length_high |
+16 | type |
+ +-------------------+
address@hidden group
address@hidden 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
address@hidden 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 size of drive structures. @samp{drives_addr}
+is the address, and @samp{drives_length} is the total size of drive
+structures. Note that @samp{drives_length} may be zero. Each drive
+structure is formatted as follows:
+
address@hidden
address@hidden
+ +-------------------+
+0 | size |
+ +-------------------+
+4 | drive_number |
+ +-------------------+
+5 | drive_mode |
+ +-------------------+
+6 | drive_cylinders |
+8 | drive_heads |
+9 | drive_sectors |
+ +-------------------+
+10 - xx | drive_ports |
+ +-------------------+
address@hidden group
address@hidden example
+
+The @samp{size} field specifies the size of this structure. The size
+varies, depending on the number of ports. Note that the size may not be
+equal to (10 + 2 * the number of ports), because of an alignment.
+
+The @samp{drive_number} field contains the BIOS drive number. The
address@hidden field represents the access mode used by the boot
+loader. Currently, the following modes are defined:
+
address@hidden @samp
address@hidden 0
+CHS mode (traditional cylinder/head/sector addressing mode).
+
address@hidden 1
+LBA mode (Logical Block Addressing mode).
address@hidden table
+
+The three fields, @samp{drive_cylinders}, @samp{drive_heads} and
address@hidden, indicate the geometry of the drive detected by the
address@hidden @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 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).
+
+If bit 8 in the @samp{flags} is set, then the @samp{config_table} field
+is valid, and indicates the address of the @sc{rom} configuration table
+returned by the @dfn{GET CONFIGURATION} @sc{bios} call. If the @sc{bios}
+call fails, then the size of the table must be @emph{zero}.
+
+If bit 9 in the @samp{flags} is set, the @samp{boot_loader_name} field
+is valid, and contains the physical address of the name of a boot
+loader booting the kernel. The name is a normal C-style zero-terminated
+string.
+
+If bit 10 in the @samp{flags} is set, the @samp{apm_table} field is
+valid, and contains the physical address of an @sc{apm} table defined as
+below:
+
address@hidden
address@hidden
+ +----------------------+
+0 | version |
+2 | cseg |
+4 | offset |
+8 | cseg_16 |
+10 | dseg |
+12 | flags |
+14 | cseg_len |
+16 | cseg_16_len |
+18 | dseg_len |
+ +----------------------+
address@hidden group
address@hidden example
+
+The fields @samp{version}, @samp{cseg}, @samp{offset}, @samp{cseg_16},
address@hidden, @samp{flags}, @samp{cseg_len}, @samp{cseg_16_len},
address@hidden indicate the version number, the protected mode 32-bit
+code segment, the offset of the entry point, the protected mode 16-bit
+code segment, the protected mode 16-bit data segment, the flags, the
+length of the protected mode 32-bit code segment, the length of the
+protected mode 16-bit code segment, and the length of the protected mode
+16-bit data segment, respectively. Only the field @samp{offset} is 4
+bytes, and the others are 2 bytes. See
address@hidden://www.microsoft.com/hwdev/busbios/amp_12.htm, Advanced Power
+Management (APM) BIOS Interface Specification}, for more information.
+
+If bit 11 in the @samp{flags} is set, the graphics table is available.
+This must only be done if the kernel has indicated in the
address@hidden Header} that it accepts a graphics mode.
+
+The fields @samp{vbe_control_info} and @samp{vbe_mode_info} contain
+the physical addresses of @sc{vbe} control information returned by the
address@hidden Function 00h and @sc{vbe} mode information returned by the
address@hidden Function 01h, respectively.
+
+The field @samp{vbe_mode} indicates current video mode in the format
+specified in @sc{vbe} 3.0.
+
+The rest fields @samp{vbe_interface_seg}, @samp{vbe_interface_off}, and
address@hidden contain the table of a protected mode interface
+defined in @sc{vbe} 2.0+. If this information is not available, those
+fields contain zero. Note that @sc{vbe} 3.0 defines another protected
+mode interface which is incompatible with the old one. If you want to
+use the new protected mode interface, you will have to find the table
+yourself.
+
+The fields for the graphics table are designed for @sc{vbe}, but
+Multiboot boot loaders may simulate @sc{vbe} on address@hidden modes, as
+if they were @sc{vbe} modes.
+
+
address@hidden Examples
address@hidden Examples
+
address@hidden:} The following items are not part of the specification
+document, but are included for prospective operating system and boot
+loader writers.
+
address@hidden
+* Notes on PC::
+* BIOS device mapping techniques::
+* Example OS code::
+* Example boot loader code::
address@hidden menu
+
+
address@hidden Notes on PC
address@hidden 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
address@hidden 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
address@hidden 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
address@hidden interface, passing along any extra data to be interpreted by
+the operating system as desired.
+
+
address@hidden BIOS device mapping techniques
address@hidden 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.
+
address@hidden
+* Data comparison technique::
+* I/O restriction technique::
address@hidden menu
+
+
address@hidden Data comparison technique
address@hidden 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:
+
address@hidden
address@hidden
+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).
+
address@hidden
+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).
address@hidden enumerate
+
+
address@hidden I/O restriction technique
address@hidden 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:
+
address@hidden
address@hidden
+Create a @dfn{clean @sc{bios} virtual machine}.
+
address@hidden
+Set the I/O permission map for the I/O area claimed by the device driver
+to no permissions (neither read nor write).
+
address@hidden
+Access each device.
+
address@hidden
+Record which devices succeed, and those which try to access the
address@hidden I/O areas (hopefully, this will be an @dfn{xor}
+situation).
address@hidden 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
address@hidden numbers, but they pretty much always count from the lowest
+logically numbered devices on the controller.
+
+
address@hidden Example OS code
address@hidden 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
address@hidden in the GRUB distribution.
+
+The kernel @file{kernel} consists of only three files: @file{boot.S},
address@hidden and @file{multiboot.h}. The assembly source
address@hidden 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
address@hidden 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
address@hidden defines some macros, such as the magic number for the
+Multiboot header, the Multiboot header structure and the Multiboot
+information structure.
+
address@hidden
+* multiboot.h::
+* boot.S::
+* kernel.c::
+* Other Multiboot kernels::
address@hidden menu
+
+
address@hidden multiboot.h
address@hidden multiboot.h
+
+This is the source code in the file @file{multiboot.h}:
+
address@hidden
address@hidden multiboot.h.texi
address@hidden example
+
+
address@hidden boot.S
address@hidden boot.S
+
+In the file @file{boot.S}:
+
address@hidden
address@hidden boot.S.texi
address@hidden example
+
+
address@hidden kernel.c
address@hidden kernel.c
+
+And, in the file @file{kernel.c}:
+
address@hidden
address@hidden kernel.c.texi
address@hidden example
+
+
address@hidden Other Multiboot kernels
address@hidden 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
address@hidden://www.cs.utah.edu/projects/flux/oskit/}, which provides a
+library supporting the specification.
+
+
address@hidden Example boot loader code
address@hidden 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:
+
address@hidden://alpha.gnu.org/gnu/grub}
+
+See the webpage @url{http://www.gnu.org/software/grub/grub.html}, for
+more information.
+
+
address@hidden History
address@hidden The change log of this specification
+
address@hidden @asis
address@hidden 0.7
address@hidden @bullet
address@hidden
address@hidden Standard} is renamed to @dfn{Multiboot Specification}.
+
address@hidden
+Graphics fields are added to Multiboot header.
+
address@hidden
+BIOS drive information, BIOS configuration table, the name of a boot
+loader, APM information, and graphics information are added to Multiboot
+information.
+
address@hidden
+Rewritten in Texinfo format.
+
address@hidden
+Rewritten, using more strict words.
+
address@hidden
+The maintainer changes to the GNU GRUB maintainer team
address@hidden@@gnu.org}, from Bryan Ford and Erich Stefan Boleyn.
+
address@hidden
+The byte order of the @samp{boot_device} in Multiboot information is
+reversed. This was a mistake.
+
address@hidden
+The offset of the address fields were wrong.
+
address@hidden
+The format is adapted to a newer Texinfo, and the version number is
+specified more explicitly in the title.
address@hidden itemize
+
address@hidden 0.6
address@hidden @bullet
address@hidden
+A few wording changes.
+
address@hidden
+Header checksum.
+
address@hidden
+Classification of machine state passed to an operating system.
address@hidden itemize
+
address@hidden 0.5
address@hidden @bullet
address@hidden
+Name change.
address@hidden itemize
+
address@hidden 0.4
address@hidden @bullet
address@hidden
+Major changes plus HTMLification.
address@hidden itemize
address@hidden table
+
+
address@hidden Index
address@hidden Index
+
address@hidden cp
+
address@hidden
address@hidden
diff --git a/docs/src2texi b/docs/src2texi
new file mode 100644
index 0000000..10786d9
--- /dev/null
+++ b/docs/src2texi
@@ -0,0 +1,16 @@
+#! /bin/sh
+#
+# Convert a source file to a TeXinfo file. Stolen from glibc.
+#
+# Usage: src2texi SRCDIR SRC TEXI
+
+dir=$1
+src=`basename $2`
+texi=`basename $3`
+
+sed -e 's,[{}],@&,g' \
+ -e 's,/\*\(@.*\)\*/,\1,g' \
+ -e 's,/\* *,/* @r{,g' -e 's, *\*/,} */,' \
+ -e 's/\(@[a-z][a-z]*\)@{\([^}]*\)@}/\1{\2}/g' \
+ ${dir}/${src} | expand > ${texi}.new
+mv -f ${texi}.new ${dir}/${texi}