Home | History | Annotate | Download | only in docs
      1 This is ../../docs/multiboot.info, produced by makeinfo version 4.7
      2 from ../../docs/multiboot.texi.
      3 
      4 INFO-DIR-SECTION Kernel
      5 START-INFO-DIR-ENTRY
      6 * Multiboot Specification: (multiboot).		Multiboot Specification.
      7 END-INFO-DIR-ENTRY
      8 
      9    Copyright (C) 1995, 96 Bryan Ford <baford (a] cs.utah.edu> Copyright (C)
     10 1995, 96 Erich Stefan Boleyn <erich (a] uruk.org> Copyright (C) 1999, 2000,
     11 2001, 2002 Free Software Foundation, Inc.
     12 
     13    Permission is granted to make and distribute verbatim copies of this
     14 manual provided the copyright notice and this permission notice are
     15 preserved on all copies.
     16 
     17    Permission is granted to copy and distribute modified versions of
     18 this manual under the conditions for verbatim copying, provided also
     19 that the entire resulting derived work is distributed under the terms
     20 of a permission notice identical to this one.
     21 
     22    Permission is granted to copy and distribute translations of this
     23 manual into another language, under the above conditions for modified
     24 versions.
     25 
     26 
     27 File: multiboot.info,  Node: Top,  Next: Overview,  Up: (dir)
     28 
     29 Multiboot Specification
     30 ***********************
     31 
     32 This file documents Multiboot Specification, the proposal for the boot
     33 sequence standard. This edition documents version 0.6.93.
     34 
     35 * Menu:
     36 
     37 * Overview::
     38 * Terminology::
     39 * Specification::
     40 * Examples::
     41 * History::
     42 * Index::
     43 
     44 
     45 File: multiboot.info,  Node: Overview,  Next: Terminology,  Prev: Top,  Up: Top
     46 
     47 1 Introduction to Multiboot Specification
     48 *****************************************
     49 
     50 This chapter describes some rough information on the Multiboot
     51 Specification. Note that this is not a part of the specification itself.
     52 
     53 * Menu:
     54 
     55 * Motivation::
     56 * Architecture::
     57 * Operating systems::
     58 * Boot sources::
     59 * Boot-time configuration::
     60 * Convenience to operating systems::
     61 * Boot modules::
     62 
     63 
     64 File: multiboot.info,  Node: Motivation,  Next: Architecture,  Up: Overview
     65 
     66 1.1 The background of Multiboot Specification
     67 =============================================
     68 
     69 Every operating system ever created tends to have its own boot loader.
     70 Installing a new operating system on a machine generally involves
     71 installing a whole new set of boot mechanisms, each with completely
     72 different install-time and boot-time user interfaces. Getting multiple
     73 operating systems to coexist reliably on one machine through typical
     74 "chaining" mechanisms can be a nightmare. There is little or no choice
     75 of boot loaders for a particular operating system -- if the one that
     76 comes with the operating system doesn't do exactly what you want, or
     77 doesn't work on your machine, you're screwed.
     78 
     79    While we may not be able to fix this problem in existing commercial
     80 operating systems, it shouldn't be too difficult for a few people in the
     81 free operating system communities to put their heads together and solve
     82 this problem for the popular free operating systems. That's what this
     83 specification aims for. Basically, it specifies an interface between a
     84 boot loader and a operating system, such that any complying boot loader
     85 should be able to load any complying operating system. This
     86 specification does _not_ specify how boot loaders should work -- only
     87 how they must interface with the operating system being loaded.
     88 
     89 
     90 File: multiboot.info,  Node: Architecture,  Next: Operating systems,  Prev: Motivation,  Up: Overview
     91 
     92 1.2 The target architecture
     93 ===========================
     94 
     95 This specification is primarily targeted at PC, since they are the most
     96 common and have the largest variety of operating systems and boot
     97 loaders. However, to the extent that certain other architectures may
     98 need a boot specification and do not have one already, a variation of
     99 this specification, stripped of the x86-specific details, could be
    100 adopted for them as well.
    101 
    102 
    103 File: multiboot.info,  Node: Operating systems,  Next: Boot sources,  Prev: Architecture,  Up: Overview
    104 
    105 1.3 The target operating systems
    106 ================================
    107 
    108 This specification is targeted toward free 32-bit operating systems
    109 that can be fairly easily modified to support the specification without
    110 going through lots of bureaucratic rigmarole. The particular free
    111 operating systems that this specification is being primarily designed
    112 for are Linux, FreeBSD, NetBSD, Mach, and VSTa. It is hoped that other
    113 emerging free operating systems will adopt it from the start, and thus
    114 immediately be able to take advantage of existing boot loaders. It would
    115 be nice if commercial operating system vendors eventually adopted this
    116 specification as well, but that's probably a pipe dream.
    117 
    118 
    119 File: multiboot.info,  Node: Boot sources,  Next: Boot-time configuration,  Prev: Operating systems,  Up: Overview
    120 
    121 1.4 Boot sources
    122 ================
    123 
    124 It should be possible to write compliant boot loaders that load the OS
    125 image from a variety of sources, including floppy disk, hard disk, and
    126 across a network.
    127 
    128    Disk-based boot loaders may use a variety of techniques to find the
    129 relevant OS image and boot module data on disk, such as by
    130 interpretation of specific file systems (e.g. the BSD/Mach boot loader),
    131 using precalculated "block lists" (e.g. LILO), loading from a special
    132 "boot partition" (e.g. OS/2), or even loading from within another
    133 operating system (e.g. the VSTa boot code, which loads from DOS).
    134 Similarly, network-based boot loaders could use a variety of network
    135 hardware and protocols.
    136 
    137    It is hoped that boot loaders will be created that support multiple
    138 loading mechanisms, increasing their portability, robustness, and
    139 user-friendliness.
    140 
    141 
    142 File: multiboot.info,  Node: Boot-time configuration,  Next: Convenience to operating systems,  Prev: Boot sources,  Up: Overview
    143 
    144 1.5 Configure an operating system at boot-time
    145 ==============================================
    146 
    147 It is often necessary for one reason or another for the user to be able
    148 to provide some configuration information to an operating system
    149 dynamically at boot time. While this specification should not dictate
    150 how this configuration information is obtained by the boot loader, it
    151 should provide a standard means for the boot loader to pass such
    152 information to the operating system.
    153 
    154 
    155 File: multiboot.info,  Node: Convenience to operating systems,  Next: Boot modules,  Prev: Boot-time configuration,  Up: Overview
    156 
    157 1.6 How to make OS development easier
    158 =====================================
    159 
    160 OS images should be easy to generate. Ideally, an OS image should simply
    161 be an ordinary 32-bit executable file in whatever file format the
    162 operating system normally uses. It should be possible to `nm' or
    163 disassemble OS images just like normal executables. Specialized tools
    164 should not be required to create OS images in a _special_ file format.
    165 If this means shifting some work from the operating system to a boot
    166 loader, that is probably appropriate, because all the memory consumed
    167 by the boot loader will typically be made available again after the
    168 boot process is created, whereas every bit of code in the OS image
    169 typically has to remain in memory forever. The operating system should
    170 not have to worry about getting into 32-bit mode initially, because mode
    171 switching code generally needs to be in the boot loader anyway in order
    172 to load operating system data above the 1MB boundary, and forcing the
    173 operating system to do this makes creation of OS images much more
    174 difficult.
    175 
    176    Unfortunately, there is a horrendous variety of executable file
    177 formats even among free Unix-like PC-based operating systems --
    178 generally a different format for each operating system. Most of the
    179 relevant free operating systems use some variant of a.out format, but
    180 some are moving to ELF. It is highly desirable for boot loaders not to
    181 have to be able to interpret all the different types of executable file
    182 formats in existence in order to load the OS image -- otherwise the
    183 boot loader effectively becomes operating system specific again.
    184 
    185    This specification adopts a compromise solution to this problem.
    186 Multiboot-compliant OS images always contain a magic "Multiboot header"
    187 (*note OS image format::), which allows the boot loader to load the
    188 image without having to understand numerous a.out variants or other
    189 executable formats. This magic header does not need to be at the very
    190 beginning of the executable file, so kernel images can still conform to
    191 the local a.out format variant in addition to being Multiboot-compliant.
    192 
    193 
    194 File: multiboot.info,  Node: Boot modules,  Prev: Convenience to operating systems,  Up: Overview
    195 
    196 1.7 Boot modules
    197 ================
    198 
    199 Many modern operating system kernels, such as those of VSTa and Mach, do
    200 not by themselves contain enough mechanism to get the system fully
    201 operational: they require the presence of additional software modules at
    202 boot time in order to access devices, mount file systems, etc. While
    203 these additional modules could be embedded in the main OS image along
    204 with the kernel itself, and the resulting image be split apart manually
    205 by the operating system when it receives control, it is often more
    206 flexible, more space-efficient, and more convenient to the operating
    207 system and user if the boot loader can load these additional modules
    208 independently in the first place.
    209 
    210    Thus, this specification should provide a standard method for a boot
    211 loader to indicate to the operating system what auxiliary boot modules
    212 were loaded, and where they can be found. Boot loaders don't have to
    213 support multiple boot modules, but they are strongly encouraged to,
    214 because some operating systems will be unable to boot without them.
    215 
    216 
    217 File: multiboot.info,  Node: Terminology,  Next: Specification,  Prev: Overview,  Up: Top
    218 
    219 2 The definitions of terms used through the specification
    220 *********************************************************
    221 
    222 "must"
    223      We use the term "must", when any boot loader or OS image needs to
    224      follow a rule -- otherwise, the boot loader or OS image is _not_
    225      Multiboot-compliant.
    226 
    227 "should"
    228      We use the term "should", when any boot loader or OS image is
    229      recommended to follow a rule, but it doesn't need to follow the
    230      rule.
    231 
    232 "may"
    233      We use the term "may", when any boot loader or OS image is allowed
    234      to follow a rule.
    235 
    236 "boot loader"
    237      Whatever program or set of programs loads the image of the final
    238      operating system to be run on the machine. The boot loader may
    239      itself consist of several stages, but that is an implementation
    240      detail not relevant to this specification. Only the _final_ stage
    241      of the boot loader -- the stage that eventually transfers control
    242      to an operating system -- must follow the rules specified in this
    243      document in order to be "Multiboot-compliant"; earlier boot loader
    244      stages may be designed in whatever way is most convenient.
    245 
    246 "OS image"
    247      The initial binary image that a boot loader loads into memory and
    248      transfers control to start an operating system. The OS image is
    249      typically an executable containing the operating system kernel.
    250 
    251 "boot module"
    252      Other auxiliary files that a boot loader loads into memory along
    253      with an OS image, but does not interpret in any way other than
    254      passing their locations to the operating system when it is invoked.
    255 
    256 "Multiboot-compliant"
    257      A boot loader or an OS image which follows the rules defined as
    258      "must" is Multiboot-compliant. When this specification specifies a
    259      rule as "should" or "may", a Multiboot-complaint boot loader/OS
    260      image doesn't need to follow the rule.
    261 
    262 "u8"
    263      The type of unsigned 8-bit data.
    264 
    265 "u16"
    266      The type of unsigned 16-bit data. Because the target architecture
    267      is little-endian, u16 is coded in little-endian.
    268 
    269 "u32"
    270      The type of unsigned 32-bit data. Because the target architecture
    271      is little-endian, u32 is coded in little-endian.
    272 
    273 "u64"
    274      The type of unsigned 64-bit data. Because the target architecture
    275      is little-endian, u64 is coded in little-endian.
    276 
    277 
    278 File: multiboot.info,  Node: Specification,  Next: Examples,  Prev: Terminology,  Up: Top
    279 
    280 3 The exact definitions of Multiboot Specification
    281 **************************************************
    282 
    283 There are three main aspects of a boot loader/OS image interface:
    284 
    285   1. The format of an OS image as seen by a boot loader.
    286 
    287   2. The state of a machine when a boot loader starts an operating
    288      system.
    289 
    290   3. The format of information passed by a boot loader to an operating
    291      system.
    292 
    293 * Menu:
    294 
    295 * OS image format::
    296 * Machine state::
    297 * Boot information format::
    298 
    299 
    300 File: multiboot.info,  Node: OS image format,  Next: Machine state,  Up: Specification
    301 
    302 3.1 OS image format
    303 ===================
    304 
    305 An OS image may be an ordinary 32-bit executable file in the standard
    306 format for that particular operating system, except that it may be
    307 linked at a non-default load address to avoid loading on top of the
    308 PC's I/O region or other reserved areas, and of course it should not
    309 use shared libraries or other fancy features.
    310 
    311    An OS image must contain an additional header called "Multiboot
    312 header", besides the headers of the format used by the OS image. The
    313 Multiboot header must be contained completely within the first 8192
    314 bytes of the OS image, and must be longword (32-bit) aligned. In
    315 general, it should come _as early as possible_, and may be embedded in
    316 the beginning of the text segment after the _real_ executable header.
    317 
    318 * Menu:
    319 
    320 * Header layout::               The layout of Multiboot header
    321 * Header magic fields::         The magic fields of Multiboot header
    322 * Header address fields::
    323 * Header graphics fields::
    324 
    325 
    326 File: multiboot.info,  Node: Header layout,  Next: Header magic fields,  Up: OS image format
    327 
    328 3.1.1 The layout of Multiboot header
    329 ------------------------------------
    330 
    331 The layout of the Multiboot header must be as follows:
    332 
    333 Offset  Type    Field Name     Note
    334 0       u32     magic          required
    335 4       u32     flags          required
    336 8       u32     checksum       required
    337 12      u32     header_addr    if flags[16] is set
    338 16      u32     load_addr      if flags[16] is set
    339 20      u32     load_end_addr  if flags[16] is set
    340 24      u32     bss_end_addr   if flags[16] is set
    341 28      u32     entry_addr     if flags[16] is set
    342 32      u32     mode_type      if flags[2] is set
    343 36      u32     width          if flags[2] is set
    344 40      u32     height         if flags[2] is set
    345 44      u32     depth          if flags[2] is set
    346 
    347    The fields `magic', `flags' and `checksum' are defined in *Note
    348 Header magic fields::, the fields `header_addr', `load_addr',
    349 `load_end_addr', `bss_end_addr' and `entry_addr' are defined in *Note
    350 Header address fields::, and the fields `mode_type', `width', `height'
    351 and `depth' are defind in *Note Header graphics fields::.
    352 
    353 
    354 File: multiboot.info,  Node: Header magic fields,  Next: Header address fields,  Prev: Header layout,  Up: OS image format
    355 
    356 3.1.2 The magic fields of Multiboot header
    357 ------------------------------------------
    358 
    359 `magic'
    360      The field `magic' is the magic number identifying the header,
    361      which must be the hexadecimal value `0x1BADB002'.
    362 
    363 `flags'
    364      The field `flags' specifies features that the OS image requests or
    365      requires of an boot loader. Bits 0-15 indicate requirements; if the
    366      boot loader sees any of these bits set but doesn't understand the
    367      flag or can't fulfill the requirements it indicates for some
    368      reason, it must notify the user and fail to load the OS image.
    369      Bits 16-31 indicate optional features; if any bits in this range
    370      are set but the boot loader doesn't understand them, it may simply
    371      ignore them and proceed as usual. Naturally, all as-yet-undefined
    372      bits in the `flags' word must be set to zero in OS images. This
    373      way, the `flags' fields serves for version control as well as
    374      simple feature selection.
    375 
    376      If bit 0 in the `flags' word is set, then all boot modules loaded
    377      along with the operating system must be aligned on page (4KB)
    378      boundaries. Some operating systems expect to be able to map the
    379      pages containing boot modules directly into a paged address space
    380      during startup, and thus need the boot modules to be page-aligned.
    381 
    382      If bit 1 in the `flags' word is set, then information on available
    383      memory via at least the `mem_*' fields of the Multiboot information
    384      structure (*note Boot information format::) must be included. If
    385      the boot loader is capable of passing a memory map (the `mmap_*'
    386      fields) and one exists, then it may be included as well.
    387 
    388      If bit 2 in the `flags' word is set, information about the video
    389      mode table (*note Boot information format::) must be available to
    390      the kernel.
    391 
    392      If bit 16 in the `flags' word is set, then the fields at offsets
    393      8-24 in the Multiboot header are valid, and the boot loader should
    394      use them instead of the fields in the actual executable header to
    395      calculate where to load the OS image. This information does not
    396      need to be provided if the kernel image is in ELF format, but it
    397      _must_ be provided if the images is in a.out format or in some
    398      other format. Compliant boot loaders must be able to load images
    399      that either are in ELF format or contain the load address
    400      information embedded in the Multiboot header; they may also
    401      directly support other executable formats, such as particular
    402      a.out variants, but are not required to.
    403 
    404 `checksum'
    405      The field `checksum' is a 32-bit unsigned value which, when added
    406      to the other magic fields (i.e. `magic' and `flags'), must have a
    407      32-bit unsigned sum of zero.
    408 
    409 
    410 File: multiboot.info,  Node: Header address fields,  Next: Header graphics fields,  Prev: Header magic fields,  Up: OS image format
    411 
    412 3.1.3 The address fields of Multiboot header
    413 --------------------------------------------
    414 
    415 All of the address fields enabled by flag bit 16 are physical addresses.
    416 The meaning of each is as follows:
    417 
    418 `header_addr'
    419      Contains the address corresponding to the beginning of the
    420      Multiboot header -- the physical memory location at which the
    421      magic value is supposed to be loaded. This field serves to
    422      "synchronize" the mapping between OS image offsets and physical
    423      memory addresses.
    424 
    425 `load_addr'
    426      Contains the physical address of the beginning of the text
    427      segment. The offset in the OS image file at which to start loading
    428      is defined by the offset at which the header was found, minus
    429      (header_addr - load_addr). load_addr must be less than or equal to
    430      header_addr.
    431 
    432 `load_end_addr'
    433      Contains the physical address of the end of the data segment.
    434      (load_end_addr - load_addr) specifies how much data to load.  This
    435      implies that the text and data segments must be consecutive in the
    436      OS image; this is true for existing a.out executable formats.  If
    437      this field is zero, the boot loader assumes that the text and data
    438      segments occupy the whole OS image file.
    439 
    440 `bss_end_addr'
    441      Contains the physical address of the end of the bss segment. The
    442      boot loader initializes this area to zero, and reserves the memory
    443      it occupies to avoid placing boot modules and other data relevant
    444      to the operating system in that area. If this field is zero, the
    445      boot loader assumes that no bss segment is present.
    446 
    447 `entry_addr'
    448      The physical address to which the boot loader should jump in order
    449      to start running the operating system.
    450 
    451 
    452 File: multiboot.info,  Node: Header graphics fields,  Prev: Header address fields,  Up: OS image format
    453 
    454 3.1.4 The graphics fields of Multiboot header
    455 ---------------------------------------------
    456 
    457 All of the graphics fields are enabled by flag bit 2. They specify the
    458 preferred graphics mode. Note that that is only a _recommended_ mode by
    459 the OS image. If the mode exists, the boot loader should set it, when
    460 the user doesn't specify a mode explicitly. Otherwise, the boot loader
    461 should fall back to a similar mode, if available.
    462 
    463    The meaning of each is as follows:
    464 
    465 `mode_type'
    466      Contains `0' for linear graphics mode or `1' for EGA-standard text
    467      mode. Everything else is reserved for future expansion. Note that
    468      the boot loader may set a text mode, even if this field contains
    469      `0'.
    470 
    471 `width'
    472      Contains the number of the columns. This is specified in pixels in
    473      a graphics mode, and in characters in a text mode. The value zero
    474      indicates that the OS image has no preference.
    475 
    476 `height'
    477      Contains the number of the lines. This is specified in pixels in a
    478      graphics mode, and in characters in a text mode. The value zero
    479      indicates that the OS image has no preference.
    480 
    481 `depth'
    482      Contains the number of bits per pixel in a graphics mode, and zero
    483      in a text mode. The value zero indicates that the OS image has no
    484      preference.
    485 
    486 
    487 File: multiboot.info,  Node: Machine state,  Next: Boot information format,  Prev: OS image format,  Up: Specification
    488 
    489 3.2 Machine state
    490 =================
    491 
    492 When the boot loader invokes the 32-bit operating system, the machine
    493 must have the following state:
    494 
    495 `EAX'
    496      Must contain the magic value `0x2BADB002'; the presence of this
    497      value indicates to the operating system that it was loaded by a
    498      Multiboot-compliant boot loader (e.g. as opposed to another type of
    499      boot loader that the operating system can also be loaded from).
    500 
    501 `EBX'
    502      Must contain the 32-bit physical address of the Multiboot
    503      information structure provided by the boot loader (*note Boot
    504      information format::).
    505 
    506 `CS'
    507      Must be a 32-bit read/execute code segment with an offset of `0'
    508      and a limit of `0xFFFFFFFF'. The exact value is undefined.
    509 
    510 `DS'
    511 `ES'
    512 `FS'
    513 `GS'
    514 `SS'
    515      Must be a 32-bit read/write data segment with an offset of `0' and
    516      a limit of `0xFFFFFFFF'. The exact values are all undefined.
    517 
    518 `A20 gate'
    519      Must be enabled.
    520 
    521 `CR0'
    522      Bit 31 (PG) must be cleared. Bit 0 (PE) must be set. Other bits are
    523      all undefined.
    524 
    525 `EFLAGS'
    526      Bit 17 (VM) must be cleared. Bit 9 (IF) must be cleared. Other bits
    527      are all undefined.
    528 
    529    All other processor registers and flag bits are undefined. This
    530 includes, in particular:
    531 
    532 `ESP'
    533      The OS image must create its own stack as soon as it needs one.
    534 
    535 `GDTR'
    536      Even though the segment registers are set up as described above,
    537      the `GDTR' may be invalid, so the OS image must not load any
    538      segment registers (even just reloading the same values!) until it
    539      sets up its own `GDT'.
    540 
    541 `IDTR'
    542      The OS image must leave interrupts disabled until it sets up its
    543      own `IDT'.
    544 
    545    However, other machine state should be left by the boot loader in
    546 "normal working order", i.e. as initialized by the BIOS (or DOS, if
    547 that's what the boot loader runs from). In other words, the operating
    548 system should be able to make BIOS calls and such after being loaded,
    549 as long as it does not overwrite the BIOS data structures before doing
    550 so. Also, the boot loader must leave the PIC programmed with the normal
    551 BIOS/DOS values, even if it changed them during the switch to 32-bit
    552 mode.
    553 
    554 
    555 File: multiboot.info,  Node: Boot information format,  Prev: Machine state,  Up: Specification
    556 
    557 3.3 Boot information format
    558 ===========================
    559 
    560 FIXME: Split this chapter like the chapter "OS image format".
    561 
    562    Upon entry to the operating system, the `EBX' register contains the
    563 physical address of a "Multiboot information" data structure, through
    564 which the boot loader communicates vital information to the operating
    565 system. The operating system can use or ignore any parts of the
    566 structure as it chooses; all information passed by the boot loader is
    567 advisory only.
    568 
    569    The Multiboot information structure and its related substructures
    570 may be placed anywhere in memory by the boot loader (with the exception
    571 of the memory reserved for the kernel and boot modules, of course). It
    572 is the operating system's responsibility to avoid overwriting this
    573 memory until it is done using it.
    574 
    575    The format of the Multiboot information structure (as defined so far)
    576 follows:
    577 
    578              +-------------------+
    579      0       | flags             |    (required)
    580              +-------------------+
    581      4       | mem_lower         |    (present if flags[0] is set)
    582      8       | mem_upper         |    (present if flags[0] is set)
    583              +-------------------+
    584      12      | boot_device       |    (present if flags[1] is set)
    585              +-------------------+
    586      16      | cmdline           |    (present if flags[2] is set)
    587              +-------------------+
    588      20      | mods_count        |    (present if flags[3] is set)
    589      24      | mods_addr         |    (present if flags[3] is set)
    590              +-------------------+
    591      28 - 40 | syms              |    (present if flags[4] or
    592              |                   |                flags[5] is set)
    593              +-------------------+
    594      44      | mmap_length       |    (present if flags[6] is set)
    595      48      | mmap_addr         |    (present if flags[6] is set)
    596              +-------------------+
    597      52      | drives_length     |    (present if flags[7] is set)
    598      56      | drives_addr       |    (present if flags[7] is set)
    599              +-------------------+
    600      60      | config_table      |    (present if flags[8] is set)
    601              +-------------------+
    602      64      | boot_loader_name  |    (present if flags[9] is set)
    603              +-------------------+
    604      68      | apm_table         |    (present if flags[10] is set)
    605              +-------------------+
    606      72      | vbe_control_info  |    (present if flags[11] is set)
    607      76      | vbe_mode_info     |
    608      80      | vbe_mode          |
    609      82      | vbe_interface_seg |
    610      84      | vbe_interface_off |
    611      86      | vbe_interface_len |
    612              +-------------------+
    613 
    614    The first longword indicates the presence and validity of other
    615 fields in the Multiboot information structure. All as-yet-undefined
    616 bits must be set to zero by the boot loader. Any set bits that the
    617 operating system does not understand should be ignored. Thus, the
    618 `flags' field also functions as a version indicator, allowing the
    619 Multiboot information structure to be expanded in the future without
    620 breaking anything.
    621 
    622    If bit 0 in the `flags' word is set, then the `mem_*' fields are
    623 valid. `mem_lower' and `mem_upper' indicate the amount of lower and
    624 upper memory, respectively, in kilobytes. Lower memory starts at
    625 address 0, and upper memory starts at address 1 megabyte. The maximum
    626 possible value for lower memory is 640 kilobytes. The value returned for
    627 upper memory is maximally the address of the first upper memory hole
    628 minus 1 megabyte. It is not guaranteed to be this value.
    629 
    630    If bit 1 in the `flags' word is set, then the `boot_device' field is
    631 valid, and indicates which BIOS disk device the boot loader loaded the
    632 OS image from. If the OS image was not loaded from a BIOS disk, then
    633 this field must not be present (bit 3 must be clear). The operating
    634 system may use this field as a hint for determining its own "root"
    635 device, but is not required to. The `boot_device' field is laid out in
    636 four one-byte subfields as follows:
    637 
    638      +-------+-------+-------+-------+
    639      | drive | part1 | part2 | part3 |
    640      +-------+-------+-------+-------+
    641 
    642    The first byte contains the BIOS drive number as understood by the
    643 BIOS INT 0x13 low-level disk interface: e.g. 0x00 for the first floppy
    644 disk or 0x80 for the first hard disk.
    645 
    646    The three remaining bytes specify the boot partition. `part1'
    647 specifies the "top-level" partition number, `part2' specifies a
    648 "sub-partition" in the top-level partition, etc. Partition numbers
    649 always start from zero. Unused partition bytes must be set to 0xFF. For
    650 example, if the disk is partitioned using a simple one-level DOS
    651 partitioning scheme, then `part1' contains the DOS partition number,
    652 and `part2' and `part3' are both 0xFF. As another example, if a disk is
    653 partitioned first into DOS partitions, and then one of those DOS
    654 partitions is subdivided into several BSD partitions using BSD's
    655 "disklabel" strategy, then `part1' contains the DOS partition number,
    656 `part2' contains the BSD sub-partition within that DOS partition, and
    657 `part3' is 0xFF.
    658 
    659    DOS extended partitions are indicated as partition numbers starting
    660 from 4 and increasing, rather than as nested sub-partitions, even
    661 though the underlying disk layout of extended partitions is
    662 hierarchical in nature. For example, if the boot loader boots from the
    663 second extended partition on a disk partitioned in conventional DOS
    664 style, then `part1' will be 5, and `part2' and `part3' will both be
    665 0xFF.
    666 
    667    If bit 2 of the `flags' longword is set, the `cmdline' field is
    668 valid, and contains the physical address of the command line to be
    669 passed to the kernel. The command line is a normal C-style
    670 zero-terminated string.
    671 
    672    If bit 3 of the `flags' is set, then the `mods' fields indicate to
    673 the kernel what boot modules were loaded along with the kernel image,
    674 and where they can be found. `mods_count' contains the number of
    675 modules loaded; `mods_addr' contains the physical address of the first
    676 module structure. `mods_count' may be zero, indicating no boot modules
    677 were loaded, even if bit 1 of `flags' is set. Each module structure is
    678 formatted as follows:
    679 
    680              +-------------------+
    681      0       | mod_start         |
    682      4       | mod_end           |
    683              +-------------------+
    684      8       | string            |
    685              +-------------------+
    686      12      | reserved (0)      |
    687              +-------------------+
    688 
    689    The first two fields contain the start and end addresses of the boot
    690 module itself. The `string' field provides an arbitrary string to be
    691 associated with that particular boot module; it is a zero-terminated
    692 ASCII string, just like the kernel command line. The `string' field may
    693 be 0 if there is no string associated with the module. Typically the
    694 string might be a command line (e.g. if the operating system treats boot
    695 modules as executable programs), or a pathname (e.g. if the operating
    696 system treats boot modules as files in a file system), but its exact use
    697 is specific to the operating system. The `reserved' field must be set
    698 to 0 by the boot loader and ignored by the operating system.
    699 
    700    *Caution:* Bits 4 & 5 are mutually exclusive.
    701 
    702    If bit 4 in the `flags' word is set, then the following fields in
    703 the Multiboot information structure starting at byte 28 are valid:
    704 
    705              +-------------------+
    706      28      | tabsize           |
    707      32      | strsize           |
    708      36      | addr              |
    709      40      | reserved (0)      |
    710              +-------------------+
    711 
    712    These indicate where the symbol table from an a.out kernel image can
    713 be found. `addr' is the physical address of the size (4-byte unsigned
    714 long) of an array of a.out format "nlist" structures, followed
    715 immediately by the array itself, then the size (4-byte unsigned long) of
    716 a set of zero-terminated ASCII strings (plus sizeof(unsigned long) in
    717 this case), and finally the set of strings itself. `tabsize' is equal
    718 to its size parameter (found at the beginning of the symbol section),
    719 and `strsize' is equal to its size parameter (found at the beginning of
    720 the string section) of the following string table to which the symbol
    721 table refers. Note that `tabsize' may be 0, indicating no symbols, even
    722 if bit 4 in the `flags' word is set.
    723 
    724    If bit 5 in the `flags' word is set, then the following fields in
    725 the Multiboot information structure starting at byte 28 are valid:
    726 
    727              +-------------------+
    728      28      | num               |
    729      32      | size              |
    730      36      | addr              |
    731      40      | shndx             |
    732              +-------------------+
    733 
    734    These indicate where the section header table from an ELF kernel is,
    735 the size of each entry, number of entries, and the string table used as
    736 the index of names. They correspond to the `shdr_*' entries
    737 (`shdr_num', etc.) in the Executable and Linkable Format (ELF)
    738 specification in the program header. All sections are loaded, and the
    739 physical address fields of the ELF section header then refer to where
    740 the sections are in memory (refer to the i386 ELF documentation for
    741 details as to how to read the section header(s)). Note that `shdr_num'
    742 may be 0, indicating no symbols, even if bit 5 in the `flags' word is
    743 set.
    744 
    745    If bit 6 in the `flags' word is set, then the `mmap_*' fields are
    746 valid, and indicate the address and length of a buffer containing a
    747 memory map of the machine provided by the BIOS. `mmap_addr' is the
    748 address, and `mmap_length' is the total size of the buffer. The buffer
    749 consists of one or more of the following size/structure pairs (`size'
    750 is really used for skipping to the next pair):
    751 
    752              +-------------------+
    753      -4      | size              |
    754              +-------------------+
    755      0       | base_addr_low     |
    756      4       | base_addr_high    |
    757      8       | length_low        |
    758      12      | length_high       |
    759      16      | type              |
    760              +-------------------+
    761 
    762    where `size' is the size of the associated structure in bytes, which
    763 can be greater than the minimum of 20 bytes. `base_addr_low' is the
    764 lower 32 bits of the starting address, and `base_addr_high' is the
    765 upper 32 bits, for a total of a 64-bit starting address. `length_low'
    766 is the lower 32 bits of the size of the memory region in bytes, and
    767 `length_high' is the upper 32 bits, for a total of a 64-bit length.
    768 `type' is the variety of address range represented, where a value of 1
    769 indicates available RAM, and all other values currently indicated a
    770 reserved area.
    771 
    772    The map provided is guaranteed to list all standard RAM that should
    773 be available for normal use.
    774 
    775    If bit 7 in the `flags' is set, then the `drives_*' fields are
    776 valid, and indicate the address of the physical address of the first
    777 drive structure and the size of drive structures. `drives_addr' is the
    778 address, and `drives_length' is the total size of drive structures.
    779 Note that `drives_length' may be zero. Each drive structure is
    780 formatted as follows:
    781 
    782              +-------------------+
    783      0       | size              |
    784              +-------------------+
    785      4       | drive_number      |
    786              +-------------------+
    787      5       | drive_mode        |
    788              +-------------------+
    789      6       | drive_cylinders   |
    790      8       | drive_heads       |
    791      9       | drive_sectors     |
    792              +-------------------+
    793      10 - xx | drive_ports       |
    794              +-------------------+
    795 
    796    The `size' field specifies the size of this structure. The size
    797 varies, depending on the number of ports. Note that the size may not be
    798 equal to (10 + 2 * the number of ports), because of an alignment.
    799 
    800    The `drive_number' field contains the BIOS drive number. The
    801 `drive_mode' field represents the access mode used by the boot loader.
    802 Currently, the following modes are defined:
    803 
    804 `0'
    805      CHS mode (traditional cylinder/head/sector addressing mode).
    806 
    807 `1'
    808      LBA mode (Logical Block Addressing mode).
    809 
    810    The three fields, `drive_cylinders', `drive_heads' and
    811 `drive_sectors', indicate the geometry of the drive detected by the
    812 BIOS. `drive_cylinders' contains the number of the cylinders.
    813 `drive_heads' contains the number of the heads. `drive_sectors'
    814 contains the number of the sectors per track.
    815 
    816    The `drive_ports' field contains the array of the I/O ports used for
    817 the drive in the BIOS code. The array consists of zero or more unsigned
    818 two-bytes integers, and is terminated with zero. Note that the array
    819 may contain any number of I/O ports that are not related to the drive
    820 actually (such as DMA controller's ports).
    821 
    822    If bit 8 in the `flags' is set, then the `config_table' field is
    823 valid, and indicates the address of the ROM configuration table
    824 returned by the "GET CONFIGURATION" BIOS call. If the BIOS call fails,
    825 then the size of the table must be _zero_.
    826 
    827    If bit 9 in the `flags' is set, the `boot_loader_name' field is
    828 valid, and contains the physical address of the name of a boot loader
    829 booting the kernel. The name is a normal C-style zero-terminated string.
    830 
    831    If bit 10 in the `flags' is set, the `apm_table' field is valid, and
    832 contains the physical address of an APM table defined as below:
    833 
    834              +----------------------+
    835      0       | version              |
    836      2       | cseg                 |
    837      4       | offset               |
    838      8       | cseg_16              |
    839      10      | dseg                 |
    840      12      | flags                |
    841      14      | cseg_len             |
    842      16      | cseg_16_len          |
    843      18      | dseg_len             |
    844              +----------------------+
    845 
    846    The fields `version', `cseg', `offset', `cseg_16', `dseg', `flags',
    847 `cseg_len', `cseg_16_len', `dseg_len' indicate the version number, the
    848 protected mode 32-bit code segment, the offset of the entry point, the
    849 protected mode 16-bit code segment, the protected mode 16-bit data
    850 segment, the flags, the length of the protected mode 32-bit code
    851 segment, the length of the protected mode 16-bit code segment, and the
    852 length of the protected mode 16-bit data segment, respectively. Only
    853 the field `offset' is 4 bytes, and the others are 2 bytes. See Advanced
    854 Power Management (APM) BIOS Interface Specification
    855 (http://www.microsoft.com/hwdev/busbios/amp_12.htm), for more
    856 information.
    857 
    858    If bit 11 in the `flags' is set, the graphics table is available.
    859 This must only be done if the kernel has indicated in the `Multiboot
    860 Header' that it accepts a graphics mode.
    861 
    862    The fields `vbe_control_info' and `vbe_mode_info' contain the
    863 physical addresses of VBE control information returned by the VBE
    864 Function 00h and VBE mode information returned by the VBE Function 01h,
    865 respectively.
    866 
    867    The field `vbe_mode' indicates current video mode in the format
    868 specified in VBE 3.0.
    869 
    870    The rest fields `vbe_interface_seg', `vbe_interface_off', and
    871 `vbe_interface_len' contain the table of a protected mode interface
    872 defined in VBE 2.0+. If this information is not available, those fields
    873 contain zero. Note that VBE 3.0 defines another protected mode
    874 interface which is incompatible with the old one. If you want to use
    875 the new protected mode interface, you will have to find the table
    876 yourself.
    877 
    878    The fields for the graphics table are designed for VBE, but
    879 Multiboot boot loaders may simulate VBE on non-VBE modes, as if they
    880 were VBE modes.
    881 
    882 
    883 File: multiboot.info,  Node: Examples,  Next: History,  Prev: Specification,  Up: Top
    884 
    885 4 Examples
    886 **********
    887 
    888 *Caution:* The following items are not part of the specification
    889 document, but are included for prospective operating system and boot
    890 loader writers.
    891 
    892 * Menu:
    893 
    894 * Notes on PC::
    895 * BIOS device mapping techniques::
    896 * Example OS code::
    897 * Example boot loader code::
    898 
    899 
    900 File: multiboot.info,  Node: Notes on PC,  Next: BIOS device mapping techniques,  Up: Examples
    901 
    902 4.1 Notes on PC
    903 ===============
    904 
    905 In reference to bit 0 of the `flags' parameter in the Multiboot
    906 information structure, if the bootloader in question uses older BIOS
    907 interfaces, or the newest ones are not available (see description about
    908 bit 6), then a maximum of either 15 or 63 megabytes of memory may be
    909 reported. It is _highly_ recommended that boot loaders perform a
    910 thorough memory probe.
    911 
    912    In reference to bit 1 of the `flags' parameter in the Multiboot
    913 information structure, it is recognized that determination of which
    914 BIOS drive maps to which device driver in an operating system is
    915 non-trivial, at best. Many kludges have been made to various operating
    916 systems instead of solving this problem, most of them breaking under
    917 many conditions. To encourage the use of general-purpose solutions to
    918 this problem, there are 2 BIOS device mapping techniques (*note BIOS
    919 device mapping techniques::).
    920 
    921    In reference to bit 6 of the `flags' parameter in the Multiboot
    922 information structure, it is important to note that the data structure
    923 used there (starting with `BaseAddrLow') is the data returned by the
    924 INT 15h, AX=E820h -- Query System Address Map call. See *Note Query
    925 System Address Map: (grub.info)Query System Address Map, for more
    926 information. The interface here is meant to allow a boot loader to work
    927 unmodified with any reasonable extensions of the BIOS interface,
    928 passing along any extra data to be interpreted by the operating system
    929 as desired.
    930 
    931 
    932 File: multiboot.info,  Node: BIOS device mapping techniques,  Next: Example OS code,  Prev: Notes on PC,  Up: Examples
    933 
    934 4.2 BIOS device mapping techniques
    935 ==================================
    936 
    937 Both of these techniques should be usable from any PC operating system,
    938 and neither require any special support in the drivers themselves. This
    939 section will be flushed out into detailed explanations, particularly for
    940 the I/O restriction technique.
    941 
    942    The general rule is that the data comparison technique is the quick
    943 and dirty solution. It works most of the time, but doesn't cover all the
    944 bases, and is relatively simple.
    945 
    946    The I/O restriction technique is much more complex, but it has
    947 potential to solve the problem under all conditions, plus allow access
    948 of the remaining BIOS devices when not all of them have operating system
    949 drivers.
    950 
    951 * Menu:
    952 
    953 * Data comparison technique::
    954 * I/O restriction technique::
    955 
    956 
    957 File: multiboot.info,  Node: Data comparison technique,  Next: I/O restriction technique,  Up: BIOS device mapping techniques
    958 
    959 4.2.1 Data comparison technique
    960 -------------------------------
    961 
    962 Before activating _any_ of the device drivers, gather enough data from
    963 similar sectors on each of the disks such that each one can be uniquely
    964 identified.
    965 
    966    After activating the device drivers, compare data from the drives
    967 using the operating system drivers. This should hopefully be sufficient
    968 to provide such a mapping.
    969 
    970    Problems:
    971 
    972   1. The data on some BIOS devices might be identical (so the part
    973      reading the drives from the BIOS should have some mechanism to give
    974      up).
    975 
    976   2. There might be extra drives not accessible from the BIOS which are
    977      identical to some drive used by the BIOS (so it should be capable
    978      of giving up there as well).
    979 
    980 
    981 File: multiboot.info,  Node: I/O restriction technique,  Prev: Data comparison technique,  Up: BIOS device mapping techniques
    982 
    983 4.2.2 I/O restriction technique
    984 -------------------------------
    985 
    986 This first step may be unnecessary, but first create copy-on-write
    987 mappings for the device drivers writing into PC RAM. Keep the original
    988 copies for the "clean BIOS virtual machine" to be created later.
    989 
    990    For each device driver brought online, determine which BIOS devices
    991 become inaccessible by:
    992 
    993   1. Create a "clean BIOS virtual machine".
    994 
    995   2. Set the I/O permission map for the I/O area claimed by the device
    996      driver to no permissions (neither read nor write).
    997 
    998   3. Access each device.
    999 
   1000   4. Record which devices succeed, and those which try to access the
   1001      "restricted" I/O areas (hopefully, this will be an "xor"
   1002      situation).
   1003 
   1004    For each device driver, given how many of the BIOS devices were
   1005 subsumed by it (there should be no gaps in this list), it should be easy
   1006 to determine which devices on the controller these are.
   1007 
   1008    In general, you have at most 2 disks from each controller given BIOS
   1009 numbers, but they pretty much always count from the lowest logically
   1010 numbered devices on the controller.
   1011 
   1012 
   1013 File: multiboot.info,  Node: Example OS code,  Next: Example boot loader code,  Prev: BIOS device mapping techniques,  Up: Examples
   1014 
   1015 4.3 Example OS code
   1016 ===================
   1017 
   1018 In this distribution, the example Multiboot kernel `kernel' is
   1019 included. The kernel just prints out the Multiboot information structure
   1020 on the screen, so you can make use of the kernel to test a
   1021 Multiboot-compliant boot loader and for reference to how to implement a
   1022 Multiboot kernel. The source files can be found under the directory
   1023 `docs' in the GRUB distribution.
   1024 
   1025    The kernel `kernel' consists of only three files: `boot.S',
   1026 `kernel.c' and `multiboot.h'. The assembly source `boot.S' is written
   1027 in GAS (*note GNU assembler: (as.info)Top.), and contains the Multiboot
   1028 information structure to comply with the specification. When a
   1029 Multiboot-compliant boot loader loads and execute it, it initialize the
   1030 stack pointer and `EFLAGS', and then call the function `cmain' defined
   1031 in `kernel.c'. If `cmain' returns to the callee, then it shows a
   1032 message to inform the user of the halt state and stops forever until
   1033 you push the reset key. The file `kernel.c' contains the function
   1034 `cmain', which checks if the magic number passed by the boot loader is
   1035 valid and so on, and some functions to print messages on the screen.
   1036 The file `multiboot.h' defines some macros, such as the magic number
   1037 for the Multiboot header, the Multiboot header structure and the
   1038 Multiboot information structure.
   1039 
   1040 * Menu:
   1041 
   1042 * multiboot.h::
   1043 * boot.S::
   1044 * kernel.c::
   1045 * Other Multiboot kernels::
   1046 
   1047 
   1048 File: multiboot.info,  Node: multiboot.h,  Next: boot.S,  Up: Example OS code
   1049 
   1050 4.3.1 multiboot.h
   1051 -----------------
   1052 
   1053 This is the source code in the file `multiboot.h':
   1054 
   1055      /* multiboot.h - the header for Multiboot */
   1056      /* Copyright (C) 1999, 2001  Free Software Foundation, Inc.
   1057 
   1058         This program is free software; you can redistribute it and/or modify
   1059         it under the terms of the GNU General Public License as published by
   1060         the Free Software Foundation; either version 2 of the License, or
   1061         (at your option) any later version.
   1062 
   1063         This program is distributed in the hope that it will be useful,
   1064         but WITHOUT ANY WARRANTY; without even the implied warranty of
   1065         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   1066         GNU General Public License for more details.
   1067 
   1068         You should have received a copy of the GNU General Public License
   1069         along with this program; if not, write to the Free Software
   1070         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
   1071 
   1072      /* Macros. */
   1073 
   1074      /* The magic number for the Multiboot header. */
   1075      #define MULTIBOOT_HEADER_MAGIC          0x1BADB002
   1076 
   1077      /* The flags for the Multiboot header. */
   1078      #ifdef __ELF__
   1079      # define MULTIBOOT_HEADER_FLAGS         0x00000003
   1080      #else
   1081      # define MULTIBOOT_HEADER_FLAGS         0x00010003
   1082      #endif
   1083 
   1084      /* The magic number passed by a Multiboot-compliant boot loader. */
   1085      #define MULTIBOOT_BOOTLOADER_MAGIC      0x2BADB002
   1086 
   1087      /* The size of our stack (16KB). */
   1088      #define STACK_SIZE                      0x4000
   1089 
   1090      /* C symbol format. HAVE_ASM_USCORE is defined by configure. */
   1091      #ifdef HAVE_ASM_USCORE
   1092      # define EXT_C(sym)                     _ ## sym
   1093      #else
   1094      # define EXT_C(sym)                     sym
   1095      #endif
   1096 
   1097      #ifndef ASM
   1098      /* Do not include here in boot.S. */
   1099 
   1100      /* Types. */
   1101 
   1102      /* The Multiboot header. */
   1103      typedef struct multiboot_header
   1104      {
   1105        unsigned long magic;
   1106        unsigned long flags;
   1107        unsigned long checksum;
   1108        unsigned long header_addr;
   1109        unsigned long load_addr;
   1110        unsigned long load_end_addr;
   1111        unsigned long bss_end_addr;
   1112        unsigned long entry_addr;
   1113      } multiboot_header_t;
   1114 
   1115      /* The symbol table for a.out. */
   1116      typedef struct aout_symbol_table
   1117      {
   1118        unsigned long tabsize;
   1119        unsigned long strsize;
   1120        unsigned long addr;
   1121        unsigned long reserved;
   1122      } aout_symbol_table_t;
   1123 
   1124      /* The section header table for ELF. */
   1125      typedef struct elf_section_header_table
   1126      {
   1127        unsigned long num;
   1128        unsigned long size;
   1129        unsigned long addr;
   1130        unsigned long shndx;
   1131      } elf_section_header_table_t;
   1132 
   1133      /* The Multiboot information. */
   1134      typedef struct multiboot_info
   1135      {
   1136        unsigned long flags;
   1137        unsigned long mem_lower;
   1138        unsigned long mem_upper;
   1139        unsigned long boot_device;
   1140        unsigned long cmdline;
   1141        unsigned long mods_count;
   1142        unsigned long mods_addr;
   1143        union
   1144        {
   1145          aout_symbol_table_t aout_sym;
   1146          elf_section_header_table_t elf_sec;
   1147        } u;
   1148        unsigned long mmap_length;
   1149        unsigned long mmap_addr;
   1150      } multiboot_info_t;
   1151 
   1152      /* The module structure. */
   1153      typedef struct module
   1154      {
   1155        unsigned long mod_start;
   1156        unsigned long mod_end;
   1157        unsigned long string;
   1158        unsigned long reserved;
   1159      } module_t;
   1160 
   1161      /* The memory map. Be careful that the offset 0 is base_addr_low
   1162         but no size. */
   1163      typedef struct memory_map
   1164      {
   1165        unsigned long size;
   1166        unsigned long base_addr_low;
   1167        unsigned long base_addr_high;
   1168        unsigned long length_low;
   1169        unsigned long length_high;
   1170        unsigned long type;
   1171      } memory_map_t;
   1172 
   1173      #endif /* ! ASM */
   1174 
   1175 
   1176 File: multiboot.info,  Node: boot.S,  Next: kernel.c,  Prev: multiboot.h,  Up: Example OS code
   1177 
   1178 4.3.2 boot.S
   1179 ------------
   1180 
   1181 In the file `boot.S':
   1182 
   1183      /* boot.S - bootstrap the kernel */
   1184      /* Copyright (C) 1999, 2001  Free Software Foundation, Inc.
   1185 
   1186         This program is free software; you can redistribute it and/or modify
   1187         it under the terms of the GNU General Public License as published by
   1188         the Free Software Foundation; either version 2 of the License, or
   1189         (at your option) any later version.
   1190 
   1191         This program is distributed in the hope that it will be useful,
   1192         but WITHOUT ANY WARRANTY; without even the implied warranty of
   1193         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   1194         GNU General Public License for more details.
   1195 
   1196         You should have received a copy of the GNU General Public License
   1197         along with this program; if not, write to the Free Software
   1198         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
   1199 
   1200      #define ASM     1
   1201      #include <multiboot.h>
   1202 
   1203              .text
   1204 
   1205              .globl  start, _start
   1206      start:
   1207      _start:
   1208              jmp     multiboot_entry
   1209 
   1210              /* Align 32 bits boundary. */
   1211              .align  4
   1212 
   1213              /* Multiboot header. */
   1214      multiboot_header:
   1215              /* magic */
   1216              .long   MULTIBOOT_HEADER_MAGIC
   1217              /* flags */
   1218              .long   MULTIBOOT_HEADER_FLAGS
   1219              /* checksum */
   1220              .long   -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)
   1221      #ifndef __ELF__
   1222              /* header_addr */
   1223              .long   multiboot_header
   1224              /* load_addr */
   1225              .long   _start
   1226              /* load_end_addr */
   1227              .long   _edata
   1228              /* bss_end_addr */
   1229              .long   _end
   1230              /* entry_addr */
   1231              .long   multiboot_entry
   1232      #endif /* ! __ELF__ */
   1233 
   1234      multiboot_entry:
   1235              /* Initialize the stack pointer. */
   1236              movl    $(stack + STACK_SIZE), %esp
   1237 
   1238              /* Reset EFLAGS. */
   1239              pushl   $0
   1240              popf
   1241 
   1242              /* Push the pointer to the Multiboot information structure. */
   1243              pushl   %ebx
   1244              /* Push the magic value. */
   1245              pushl   %eax
   1246 
   1247              /* Now enter the C main function... */
   1248              call    EXT_C(cmain)
   1249 
   1250              /* Halt. */
   1251              pushl   $halt_message
   1252              call    EXT_C(printf)
   1253 
   1254      loop:   hlt
   1255              jmp     loop
   1256 
   1257      halt_message:
   1258              .asciz  "Halted."
   1259 
   1260              /* Our stack area. */
   1261              .comm   stack, STACK_SIZE
   1262 
   1263 
   1264 File: multiboot.info,  Node: kernel.c,  Next: Other Multiboot kernels,  Prev: boot.S,  Up: Example OS code
   1265 
   1266 4.3.3 kernel.c
   1267 --------------
   1268 
   1269 And, in the file `kernel.c':
   1270 
   1271      /* kernel.c - the C part of the kernel */
   1272      /* Copyright (C) 1999  Free Software Foundation, Inc.
   1273 
   1274         This program is free software; you can redistribute it and/or modify
   1275         it under the terms of the GNU General Public License as published by
   1276         the Free Software Foundation; either version 2 of the License, or
   1277         (at your option) any later version.
   1278 
   1279         This program is distributed in the hope that it will be useful,
   1280         but WITHOUT ANY WARRANTY; without even the implied warranty of
   1281         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   1282         GNU General Public License for more details.
   1283 
   1284         You should have received a copy of the GNU General Public License
   1285         along with this program; if not, write to the Free Software
   1286         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
   1287 
   1288      #include <multiboot.h>
   1289 
   1290      /* Macros. */
   1291 
   1292      /* Check if the bit BIT in FLAGS is set. */
   1293      #define CHECK_FLAG(flags,bit)   ((flags) & (1 << (bit)))
   1294 
   1295      /* Some screen stuff. */
   1296      /* The number of columns. */
   1297      #define COLUMNS                 80
   1298      /* The number of lines. */
   1299      #define LINES                   24
   1300      /* The attribute of an character. */
   1301      #define ATTRIBUTE               7
   1302      /* The video memory address. */
   1303      #define VIDEO                   0xB8000
   1304 
   1305      /* Variables. */
   1306      /* Save the X position. */
   1307      static int xpos;
   1308      /* Save the Y position. */
   1309      static int ypos;
   1310      /* Point to the video memory. */
   1311      static volatile unsigned char *video;
   1312 
   1313      /* Forward declarations. */
   1314      void cmain (unsigned long magic, unsigned long addr);
   1315      static void cls (void);
   1316      static void itoa (char *buf, int base, int d);
   1317      static void putchar (int c);
   1318      void printf (const char *format, ...);
   1319 
   1320      /* Check if MAGIC is valid and print the Multiboot information structure
   1321         pointed by ADDR. */
   1322      void
   1323      cmain (unsigned long magic, unsigned long addr)
   1324      {
   1325        multiboot_info_t *mbi;
   1326 
   1327        /* Clear the screen. */
   1328        cls ();
   1329 
   1330        /* Am I booted by a Multiboot-compliant boot loader? */
   1331        if (magic != MULTIBOOT_BOOTLOADER_MAGIC)
   1332          {
   1333            printf ("Invalid magic number: 0x%x\n", (unsigned) magic);
   1334            return;
   1335          }
   1336 
   1337        /* Set MBI to the address of the Multiboot information structure. */
   1338        mbi = (multiboot_info_t *) addr;
   1339 
   1340        /* Print out the flags. */
   1341        printf ("flags = 0x%x\n", (unsigned) mbi->flags);
   1342 
   1343        /* Are mem_* valid? */
   1344        if (CHECK_FLAG (mbi->flags, 0))
   1345          printf ("mem_lower = %uKB, mem_upper = %uKB\n",
   1346                  (unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper);
   1347 
   1348        /* Is boot_device valid? */
   1349        if (CHECK_FLAG (mbi->flags, 1))
   1350          printf ("boot_device = 0x%x\n", (unsigned) mbi->boot_device);
   1351 
   1352        /* Is the command line passed? */
   1353        if (CHECK_FLAG (mbi->flags, 2))
   1354          printf ("cmdline = %s\n", (char *) mbi->cmdline);
   1355 
   1356        /* Are mods_* valid? */
   1357        if (CHECK_FLAG (mbi->flags, 3))
   1358          {
   1359            module_t *mod;
   1360            int i;
   1361 
   1362            printf ("mods_count = %d, mods_addr = 0x%x\n",
   1363                    (int) mbi->mods_count, (int) mbi->mods_addr);
   1364            for (i = 0, mod = (module_t *) mbi->mods_addr;
   1365                 i < mbi->mods_count;
   1366                 i++, mod++)
   1367              printf (" mod_start = 0x%x, mod_end = 0x%x, string = %s\n",
   1368                      (unsigned) mod->mod_start,
   1369                      (unsigned) mod->mod_end,
   1370                      (char *) mod->string);
   1371          }
   1372 
   1373        /* Bits 4 and 5 are mutually exclusive! */
   1374        if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5))
   1375          {
   1376            printf ("Both bits 4 and 5 are set.\n");
   1377            return;
   1378          }
   1379 
   1380        /* Is the symbol table of a.out valid? */
   1381        if (CHECK_FLAG (mbi->flags, 4))
   1382          {
   1383            aout_symbol_table_t *aout_sym = &(mbi->u.aout_sym);
   1384 
   1385            printf ("aout_symbol_table: tabsize = 0x%0x, "
   1386                    "strsize = 0x%x, addr = 0x%x\n",
   1387                    (unsigned) aout_sym->tabsize,
   1388                    (unsigned) aout_sym->strsize,
   1389                    (unsigned) aout_sym->addr);
   1390          }
   1391 
   1392        /* Is the section header table of ELF valid? */
   1393        if (CHECK_FLAG (mbi->flags, 5))
   1394          {
   1395            elf_section_header_table_t *elf_sec = &(mbi->u.elf_sec);
   1396 
   1397            printf ("elf_sec: num = %u, size = 0x%x,"
   1398                    " addr = 0x%x, shndx = 0x%x\n",
   1399                    (unsigned) elf_sec->num, (unsigned) elf_sec->size,
   1400                    (unsigned) elf_sec->addr, (unsigned) elf_sec->shndx);
   1401          }
   1402 
   1403        /* Are mmap_* valid? */
   1404        if (CHECK_FLAG (mbi->flags, 6))
   1405          {
   1406            memory_map_t *mmap;
   1407 
   1408            printf ("mmap_addr = 0x%x, mmap_length = 0x%x\n",
   1409                    (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length);
   1410            for (mmap = (memory_map_t *) mbi->mmap_addr;
   1411                 (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length;
   1412                 mmap = (memory_map_t *) ((unsigned long) mmap
   1413                                          + mmap->size + sizeof (mmap->size)))
   1414              printf (" size = 0x%x, base_addr = 0x%x%x,"
   1415                      " length = 0x%x%x, type = 0x%x\n",
   1416                      (unsigned) mmap->size,
   1417                      (unsigned) mmap->base_addr_high,
   1418                      (unsigned) mmap->base_addr_low,
   1419                      (unsigned) mmap->length_high,
   1420                      (unsigned) mmap->length_low,
   1421                      (unsigned) mmap->type);
   1422          }
   1423      }
   1424 
   1425      /* Clear the screen and initialize VIDEO, XPOS and YPOS. */
   1426      static void
   1427      cls (void)
   1428      {
   1429        int i;
   1430 
   1431        video = (unsigned char *) VIDEO;
   1432 
   1433        for (i = 0; i < COLUMNS * LINES * 2; i++)
   1434          *(video + i) = 0;
   1435 
   1436        xpos = 0;
   1437        ypos = 0;
   1438      }
   1439 
   1440      /* Convert the integer D to a string and save the string in BUF. If
   1441         BASE is equal to 'd', interpret that D is decimal, and if BASE is
   1442         equal to 'x', interpret that D is hexadecimal. */
   1443      static void
   1444      itoa (char *buf, int base, int d)
   1445      {
   1446        char *p = buf;
   1447        char *p1, *p2;
   1448        unsigned long ud = d;
   1449        int divisor = 10;
   1450 
   1451        /* If %d is specified and D is minus, put `-' in the head. */
   1452        if (base == 'd' && d < 0)
   1453          {
   1454            *p++ = '-';
   1455            buf++;
   1456            ud = -d;
   1457          }
   1458        else if (base == 'x')
   1459          divisor = 16;
   1460 
   1461        /* Divide UD by DIVISOR until UD == 0. */
   1462        do
   1463          {
   1464            int remainder = ud % divisor;
   1465 
   1466            *p++ = (remainder < 10) ? remainder + '0' : remainder + 'a' - 10;
   1467          }
   1468        while (ud /= divisor);
   1469 
   1470        /* Terminate BUF. */
   1471        *p = 0;
   1472 
   1473        /* Reverse BUF. */
   1474        p1 = buf;
   1475        p2 = p - 1;
   1476        while (p1 < p2)
   1477          {
   1478            char tmp = *p1;
   1479            *p1 = *p2;
   1480            *p2 = tmp;
   1481            p1++;
   1482            p2--;
   1483          }
   1484      }
   1485 
   1486      /* Put the character C on the screen. */
   1487      static void
   1488      putchar (int c)
   1489      {
   1490        if (c == '\n' || c == '\r')
   1491          {
   1492          newline:
   1493            xpos = 0;
   1494            ypos++;
   1495            if (ypos >= LINES)
   1496              ypos = 0;
   1497            return;
   1498          }
   1499 
   1500        *(video + (xpos + ypos * COLUMNS) * 2) = c & 0xFF;
   1501        *(video + (xpos + ypos * COLUMNS) * 2 + 1) = ATTRIBUTE;
   1502 
   1503        xpos++;
   1504        if (xpos >= COLUMNS)
   1505          goto newline;
   1506      }
   1507 
   1508      /* Format a string and print it on the screen, just like the libc
   1509         function printf. */
   1510      void
   1511      printf (const char *format, ...)
   1512      {
   1513        char **arg = (char **) &format;
   1514        int c;
   1515        char buf[20];
   1516 
   1517        arg++;
   1518 
   1519        while ((c = *format++) != 0)
   1520          {
   1521            if (c != '%')
   1522              putchar (c);
   1523            else
   1524              {
   1525                char *p;
   1526 
   1527                c = *format++;
   1528                switch (c)
   1529                  {
   1530                  case 'd':
   1531                  case 'u':
   1532                  case 'x':
   1533                    itoa (buf, c, *((int *) arg++));
   1534                    p = buf;
   1535                    goto string;
   1536                    break;
   1537 
   1538                  case 's':
   1539                    p = *arg++;
   1540                    if (! p)
   1541                      p = "(null)";
   1542 
   1543                  string:
   1544                    while (*p)
   1545                      putchar (*p++);
   1546                    break;
   1547 
   1548                  default:
   1549                    putchar (*((int *) arg++));
   1550                    break;
   1551                  }
   1552              }
   1553          }
   1554      }
   1555 
   1556 
   1557 File: multiboot.info,  Node: Other Multiboot kernels,  Prev: kernel.c,  Up: Example OS code
   1558 
   1559 4.3.4 Other Multiboot kernels
   1560 -----------------------------
   1561 
   1562 Other useful information should be available in Multiboot kernels, such
   1563 as GNU Mach and Fiasco `http://os.inf.tu-dresden.de/fiasco/'. And, it
   1564 is worth mentioning the OSKit
   1565 `http://www.cs.utah.edu/projects/flux/oskit/', which provides a library
   1566 supporting the specification.
   1567 
   1568 
   1569 File: multiboot.info,  Node: Example boot loader code,  Prev: Example OS code,  Up: Examples
   1570 
   1571 4.4 Example boot loader code
   1572 ============================
   1573 
   1574 The GNU GRUB (*note GRUB: (grub.info)Top.) project is a full
   1575 Multiboot-compliant boot loader, supporting all required and optional
   1576 features present in this specification. A public release has not been
   1577 made, but the test release is available from:
   1578 
   1579    `ftp://alpha.gnu.org/gnu/grub'
   1580 
   1581    See the webpage `http://www.gnu.org/software/grub/grub.html', for
   1582 more information.
   1583 
   1584 
   1585 File: multiboot.info,  Node: History,  Next: Index,  Prev: Examples,  Up: Top
   1586 
   1587 5 The change log of this specification
   1588 **************************************
   1589 
   1590 0.7
   1591         * "Multiboot Standard" is renamed to "Multiboot Specification".
   1592 
   1593         * Graphics fields are added to Multiboot header.
   1594 
   1595         * BIOS drive information, BIOS configuration table, the name of
   1596           a boot loader, APM information, and graphics information are
   1597           added to Multiboot information.
   1598 
   1599         * Rewritten in Texinfo format.
   1600 
   1601         * Rewritten, using more strict words.
   1602 
   1603         * The maintainer changes to the GNU GRUB maintainer team
   1604           <bug-grub (a] gnu.org>, from Bryan Ford and Erich Stefan Boleyn.
   1605 
   1606 0.6
   1607         * A few wording changes.
   1608 
   1609         * Header checksum.
   1610 
   1611         * Clasification of machine state passed to an operating system.
   1612 
   1613 0.5
   1614         * Name change.
   1615 
   1616 0.4
   1617         * Major changes plus HTMLification.
   1618 
   1619 
   1620 File: multiboot.info,  Node: Index,  Prev: History,  Up: Top
   1621 
   1622 Index
   1623 *****
   1624 
   1625 [index]
   1626 * Menu:
   1627 
   1628 
   1629 Tag Table:
   1630 Node: Top990
   1631 Node: Overview1326
   1632 Node: Motivation1794
   1633 Node: Architecture3191
   1634 Node: Operating systems3724
   1635 Node: Boot sources4518
   1636 Node: Boot-time configuration5488
   1637 Node: Convenience to operating systems6096
   1638 Node: Boot modules8327
   1639 Node: Terminology9476
   1640 Node: Specification11855
   1641 Node: OS image format12418
   1642 Node: Header layout13476
   1643 Node: Header magic fields14644
   1644 Node: Header address fields17505
   1645 Node: Header graphics fields19351
   1646 Node: Machine state20737
   1647 Node: Boot information format22997
   1648 Node: Examples38368
   1649 Node: Notes on PC38741
   1650 Node: BIOS device mapping techniques40307
   1651 Node: Data comparison technique41217
   1652 Node: I/O restriction technique42079
   1653 Node: Example OS code43296
   1654 Node: multiboot.h44838
   1655 Node: boot.S48662
   1656 Node: kernel.c51286
   1657 Node: Other Multiboot kernels60013
   1658 Node: Example boot loader code60444
   1659 Node: History60970
   1660 Node: Index61891
   1661 
   1662 End Tag Table
   1663