diff options
Diffstat (limited to '')
-rw-r--r-- | doc/Makefile | 5 | ||||
-rw-r--r-- | doc/linux-i386-boot.txt | 438 | ||||
-rw-r--r-- | doc/linux-i386-zero-page.txt | 78 | ||||
-rw-r--r-- | doc/multiboot.html | 664 | ||||
-rw-r--r-- | doc/nbi-spec.txt | 660 |
5 files changed, 1845 insertions, 0 deletions
diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..3442e09 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,5 @@ +dist += doc/Makefile \ + doc/linux-i386-boot.txt \ + doc/linux-i386-zero-page.txt \ + doc/multiboot.html \ + doc/nbi-spec.txt diff --git a/doc/linux-i386-boot.txt b/doc/linux-i386-boot.txt new file mode 100644 index 0000000..afa6d12 --- /dev/null +++ b/doc/linux-i386-boot.txt @@ -0,0 +1,438 @@ + THE LINUX/I386 BOOT PROTOCOL + ---------------------------- + + H. Peter Anvin <hpa@zytor.com> + Last update 2002-01-01 + +On the i386 platform, the Linux kernel uses a rather complicated boot +convention. This has evolved partially due to historical aspects, as +well as the desire in the early days to have the kernel itself be a +bootable image, the complicated PC memory model and due to changed +expectations in the PC industry caused by the effective demise of +real-mode DOS as a mainstream operating system. + +Currently, four versions of the Linux/i386 boot protocol exist. + +Old kernels: zImage/Image support only. Some very early kernels + may not even support a command line. + +Protocol 2.00: (Kernel 1.3.73) Added bzImage and initrd support, as + well as a formalized way to communicate between the + boot loader and the kernel. setup.S made relocatable, + although the traditional setup area still assumed + writable. + +Protocol 2.01: (Kernel 1.3.76) Added a heap overrun warning. + +Protocol 2.02: (Kernel 2.4.0-test3-pre3) New command line protocol. + Lower the conventional memory ceiling. No overwrite + of the traditional setup area, thus making booting + safe for systems which use the EBDA from SMM or 32-bit + BIOS entry points. zImage deprecated but still + supported. + +Protocol 2.03: (Kernel 2.4.18-pre1) Explicitly makes the highest possible + initrd address available to the bootloader. + + +**** MEMORY LAYOUT + +The traditional memory map for the kernel loader, used for Image or +zImage kernels, typically looks like: + + | | +0A0000 +------------------------+ + | Reserved for BIOS | Do not use. Reserved for BIOS EBDA. +09A000 +------------------------+ + | Stack/heap/cmdline | For use by the kernel real-mode code. +098000 +------------------------+ + | Kernel setup | The kernel real-mode code. +090200 +------------------------+ + | Kernel boot sector | The kernel legacy boot sector. +090000 +------------------------+ + | Protected-mode kernel | The bulk of the kernel image. +010000 +------------------------+ + | Boot loader | <- Boot sector entry point 0000:7C00 +001000 +------------------------+ + | Reserved for MBR/BIOS | +000800 +------------------------+ + | Typically used by MBR | +000600 +------------------------+ + | BIOS use only | +000000 +------------------------+ + + +When using bzImage, the protected-mode kernel was relocated to +0x100000 ("high memory"), and the kernel real-mode block (boot sector, +setup, and stack/heap) was made relocatable to any address between +0x10000 and end of low memory. Unfortunately, in protocols 2.00 and +2.01 the command line is still required to live in the 0x9XXXX memory +range, and that memory range is still overwritten by the early kernel. +The 2.02 protocol resolves that problem. + +It is desirable to keep the "memory ceiling" -- the highest point in +low memory touched by the boot loader -- as low as possible, since +some newer BIOSes have begun to allocate some rather large amounts of +memory, called the Extended BIOS Data Area, near the top of low +memory. The boot loader should use the "INT 12h" BIOS call to verify +how much low memory is available. + +Unfortunately, if INT 12h reports that the amount of memory is too +low, there is usually nothing the boot loader can do but to report an +error to the user. The boot loader should therefore be designed to +take up as little space in low memory as it reasonably can. For +zImage or old bzImage kernels, which need data written into the +0x90000 segment, the boot loader should make sure not to use memory +above the 0x9A000 point; too many BIOSes will break above that point. + + +**** THE REAL-MODE KERNEL HEADER + +In the following text, and anywhere in the kernel boot sequence, "a +sector" refers to 512 bytes. It is independent of the actual sector +size of the underlying medium. + +The first step in loading a Linux kernel should be to load the +real-mode code (boot sector and setup code) and then examine the +following header at offset 0x01f1. The real-mode code can total up to +32K, although the boot loader may choose to load only the first two +sectors (1K) and then examine the bootup sector size. + +The header looks like: + +Offset Proto Name Meaning +/Size + +01F1/1 ALL setup_sects The size of the setup in sectors +01F2/2 ALL root_flags If set, the root is mounted readonly +01F4/2 ALL syssize DO NOT USE - for bootsect.S use only +01F6/2 ALL swap_dev DO NOT USE - obsolete +01F8/2 ALL ram_size DO NOT USE - for bootsect.S use only +01FA/2 ALL vid_mode Video mode control +01FC/2 ALL root_dev Default root device number +01FE/2 ALL boot_flag 0xAA55 magic number +0200/2 2.00+ jump Jump instruction +0202/4 2.00+ header Magic signature "HdrS" +0206/2 2.00+ version Boot protocol version supported +0208/4 2.00+ realmode_swtch Boot loader hook (see below) +020C/2 2.00+ start_sys The load-low segment (0x1000) (obsolete) +020E/2 2.00+ kernel_version Pointer to kernel version string +0210/1 2.00+ type_of_loader Boot loader identifier +0211/1 2.00+ loadflags Boot protocol option flags +0212/2 2.00+ setup_move_size Move to high memory size (used with hooks) +0214/4 2.00+ code32_start Boot loader hook (see below) +0218/4 2.00+ ramdisk_image initrd load address (set by boot loader) +021C/4 2.00+ ramdisk_size initrd size (set by boot loader) +0220/4 2.00+ bootsect_kludge DO NOT USE - for bootsect.S use only +0224/2 2.01+ heap_end_ptr Free memory after setup end +0226/2 N/A pad1 Unused +0228/4 2.02+ cmd_line_ptr 32-bit pointer to the kernel command line +022C/4 2.03+ initrd_addr_max Highest legal initrd address + +For backwards compatibility, if the setup_sects field contains 0, the +real value is 4. + +If the "HdrS" (0x53726448) magic number is not found at offset 0x202, +the boot protocol version is "old". Loading an old kernel, the +following parameters should be assumed: + + Image type = zImage + initrd not supported + Real-mode kernel must be located at 0x90000. + +Otherwise, the "version" field contains the protocol version, +e.g. protocol version 2.01 will contain 0x0201 in this field. When +setting fields in the header, you must make sure only to set fields +supported by the protocol version in use. + +The "kernel_version" field, if set to a nonzero value, contains a +pointer to a null-terminated human-readable kernel version number +string, less 0x200. This can be used to display the kernel version to +the user. This value should be less than (0x200*setup_sects). For +example, if this value is set to 0x1c00, the kernel version number +string can be found at offset 0x1e00 in the kernel file. This is a +valid value if and only if the "setup_sects" field contains the value +14 or higher. + +Most boot loaders will simply load the kernel at its target address +directly. Such boot loaders do not need to worry about filling in +most of the fields in the header. The following fields should be +filled out, however: + + vid_mode: + Please see the section on SPECIAL COMMAND LINE OPTIONS. + + type_of_loader: + If your boot loader has an assigned id (see table below), enter + 0xTV here, where T is an identifier for the boot loader and V is + a version number. Otherwise, enter 0xFF here. + + Assigned boot loader ids: + 0 LILO + 1 Loadlin + 2 bootsect-loader + 3 SYSLINUX + 4 EtherBoot + + Please contact <hpa@zytor.com> if you need a bootloader ID + value assigned. + + loadflags, heap_end_ptr: + If the protocol version is 2.01 or higher, enter the + offset limit of the setup heap into heap_end_ptr and set the + 0x80 bit (CAN_USE_HEAP) of loadflags. heap_end_ptr appears to + be relative to the start of setup (offset 0x0200). + + setup_move_size: + When using protocol 2.00 or 2.01, if the real mode + kernel is not loaded at 0x90000, it gets moved there later in + the loading sequence. Fill in this field if you want + additional data (such as the kernel command line) moved in + addition to the real-mode kernel itself. + + ramdisk_image, ramdisk_size: + If your boot loader has loaded an initial ramdisk (initrd), + set ramdisk_image to the 32-bit pointer to the ramdisk data + and the ramdisk_size to the size of the ramdisk data. + + The initrd should typically be located as high in memory as + possible, as it may otherwise get overwritten by the early + kernel initialization sequence. However, it must never be + located above the address specified in the initrd_addr_max + field. The initrd should be at least 4K page aligned. + + cmd_line_ptr: + If the protocol version is 2.02 or higher, this is a 32-bit + pointer to the kernel command line. The kernel command line + can be located anywhere between the end of setup and 0xA0000. + Fill in this field even if your boot loader does not support a + command line, in which case you can point this to an empty + string (or better yet, to the string "auto".) If this field + is left at zero, the kernel will assume that your boot loader + does not support the 2.02+ protocol. + + ramdisk_max: + The maximum address that may be occupied by the initrd + contents. For boot protocols 2.02 or earlier, this field is + not present, and the maximum address is 0x37FFFFFF. (This + address is defined as the address of the highest safe byte, so + if your ramdisk is exactly 131072 bytes long and this field is + 0x37FFFFFF, you can start your ramdisk at 0x37FE0000.) + + +**** THE KERNEL COMMAND LINE + +The kernel command line has become an important way for the boot +loader to communicate with the kernel. Some of its options are also +relevant to the boot loader itself, see "special command line options" +below. + +The kernel command line is a null-terminated string up to 255 +characters long, plus the final null. + +If the boot protocol version is 2.02 or later, the address of the +kernel command line is given by the header field cmd_line_ptr (see +above.) + +If the protocol version is *not* 2.02 or higher, the kernel +command line is entered using the following protocol: + + At offset 0x0020 (word), "cmd_line_magic", enter the magic + number 0xA33F. + + At offset 0x0022 (word), "cmd_line_offset", enter the offset + of the kernel command line (relative to the start of the + real-mode kernel). + + The kernel command line *must* be within the memory region + covered by setup_move_size, so you may need to adjust this + field. + + +**** SAMPLE BOOT CONFIGURATION + +As a sample configuration, assume the following layout of the real +mode segment: + + 0x0000-0x7FFF Real mode kernel + 0x8000-0x8FFF Stack and heap + 0x9000-0x90FF Kernel command line + +Such a boot loader should enter the following fields in the header: + + unsigned long base_ptr; /* base address for real-mode segment */ + + if ( setup_sects == 0 ) { + setup_sects = 4; + } + + if ( protocol >= 0x0200 ) { + type_of_loader = <type code>; + if ( loading_initrd ) { + ramdisk_image = <initrd_address>; + ramdisk_size = <initrd_size>; + } + if ( protocol >= 0x0201 ) { + heap_end_ptr = 0x9000 - 0x200; + loadflags |= 0x80; /* CAN_USE_HEAP */ + } + if ( protocol >= 0x0202 ) { + cmd_line_ptr = base_ptr + 0x9000; + } else { + cmd_line_magic = 0xA33F; + cmd_line_offset = 0x9000; + setup_move_size = 0x9100; + } + } else { + /* Very old kernel */ + + cmd_line_magic = 0xA33F; + cmd_line_offset = 0x9000; + + /* A very old kernel MUST have its real-mode code + loaded at 0x90000 */ + + if ( base_ptr != 0x90000 ) { + /* Copy the real-mode kernel */ + memcpy(0x90000, base_ptr, (setup_sects+1)*512); + /* Copy the command line */ + memcpy(0x99000, base_ptr+0x9000, 256); + + base_ptr = 0x90000; /* Relocated */ + } + + /* It is recommended to clear memory up to the 32K mark */ + memset(0x90000 + (setup_sects+1)*512, 0, + (64-(setup_sects+1))*512); + } + + +**** LOADING THE REST OF THE KERNEL + +The non-real-mode kernel starts at offset (setup_sects+1)*512 in the +kernel file (again, if setup_sects == 0 the real value is 4.) It +should be loaded at address 0x10000 for Image/zImage kernels and +0x100000 for bzImage kernels. + +The kernel is a bzImage kernel if the protocol >= 2.00 and the 0x01 +bit (LOAD_HIGH) in the loadflags field is set: + + is_bzImage = (protocol >= 0x0200) && (loadflags & 0x01); + load_address = is_bzImage ? 0x100000 : 0x10000; + +Note that Image/zImage kernels can be up to 512K in size, and thus use +the entire 0x10000-0x90000 range of memory. This means it is pretty +much a requirement for these kernels to load the real-mode part at +0x90000. bzImage kernels allow much more flexibility. + + +**** SPECIAL COMMAND LINE OPTIONS + +If the command line provided by the boot loader is entered by the +user, the user may expect the following command line options to work. +They should normally not be deleted from the kernel command line even +though not all of them are actually meaningful to the kernel. Boot +loader authors who need additional command line options for the boot +loader itself should get them registered in +Documentation/kernel-parameters.txt to make sure they will not +conflict with actual kernel options now or in the future. + + vga=<mode> + <mode> here is either an integer (in C notation, either + decimal, octal, or hexadecimal) or one of the strings + "normal" (meaning 0xFFFF), "ext" (meaning 0xFFFE) or "ask" + (meaning 0xFFFD). This value should be entered into the + vid_mode field, as it is used by the kernel before the command + line is parsed. + + mem=<size> + <size> is an integer in C notation optionally followed by K, M + or G (meaning << 10, << 20 or << 30). This specifies the end + of memory to the kernel. This affects the possible placement + of an initrd, since an initrd should be placed near end of + memory. Note that this is an option to *both* the kernel and + the bootloader! + + initrd=<file> + An initrd should be loaded. The meaning of <file> is + obviously bootloader-dependent, and some boot loaders + (e.g. LILO) do not have such a command. + +In addition, some boot loaders add the following options to the +user-specified command line: + + BOOT_IMAGE=<file> + The boot image which was loaded. Again, the meaning of <file> + is obviously bootloader-dependent. + + auto + The kernel was booted without explicit user intervention. + +If these options are added by the boot loader, it is highly +recommended that they are located *first*, before the user-specified +or configuration-specified command line. Otherwise, "init=/bin/sh" +gets confused by the "auto" option. + + +**** RUNNING THE KERNEL + +The kernel is started by jumping to the kernel entry point, which is +located at *segment* offset 0x20 from the start of the real mode +kernel. This means that if you loaded your real-mode kernel code at +0x90000, the kernel entry point is 9020:0000. + +At entry, ds = es = ss should point to the start of the real-mode +kernel code (0x9000 if the code is loaded at 0x90000), sp should be +set up properly, normally pointing to the top of the heap, and +interrupts should be disabled. Furthermore, to guard against bugs in +the kernel, it is recommended that the boot loader sets fs = gs = ds = +es = ss. + +In our example from above, we would do: + + /* Note: in the case of the "old" kernel protocol, base_ptr must + be == 0x90000 at this point; see the previous sample code */ + + seg = base_ptr >> 4; + + cli(); /* Enter with interrupts disabled! */ + + /* Set up the real-mode kernel stack */ + _SS = seg; + _SP = 0x9000; /* Load SP immediately after loading SS! */ + + _DS = _ES = _FS = _GS = seg; + jmp_far(seg+0x20, 0); /* Run the kernel */ + +If your boot sector accesses a floppy drive, it is recommended to +switch off the floppy motor before running the kernel, since the +kernel boot leaves interrupts off and thus the motor will not be +switched off, especially if the loaded kernel has the floppy driver as +a demand-loaded module! + + +**** ADVANCED BOOT TIME HOOKS + +If the boot loader runs in a particularly hostile environment (such as +LOADLIN, which runs under DOS) it may be impossible to follow the +standard memory location requirements. Such a boot loader may use the +following hooks that, if set, are invoked by the kernel at the +appropriate time. The use of these hooks should probably be +considered an absolutely last resort! + +IMPORTANT: All the hooks are required to preserve %esp, %ebp, %esi and +%edi across invocation. + + realmode_swtch: + A 16-bit real mode far subroutine invoked immediately before + entering protected mode. The default routine disables NMI, so + your routine should probably do so, too. + + code32_start: + A 32-bit flat-mode routine *jumped* to immediately after the + transition to protected mode, but before the kernel is + uncompressed. No segments, except CS, are set up; you should + set them up to KERNEL_DS (0x18) yourself. + + After completing your hook, you should jump to the address + that was in this field before your boot loader overwrote it. diff --git a/doc/linux-i386-zero-page.txt b/doc/linux-i386-zero-page.txt new file mode 100644 index 0000000..e2582a6 --- /dev/null +++ b/doc/linux-i386-zero-page.txt @@ -0,0 +1,78 @@ +Summary of boot_params layout (kernel point of view) + ( collected by Hans Lermen and Martin Mares ) + +The contents of boot_params are used to pass parameters from the +16-bit realmode code of the kernel to the 32-bit part. References/settings +to it mainly are in: + + arch/i386/boot/setup.S + arch/i386/boot/video.S + arch/i386/kernel/head.S + arch/i386/kernel/setup.c + + +Offset Type Description +------ ---- ----------- + 0 32 bytes struct screen_info, SCREEN_INFO + ATTENTION, overlaps the following !!! + 2 unsigned short EXT_MEM_K, extended memory size in Kb (from int 0x15) + 0x20 unsigned short CL_MAGIC, commandline magic number (=0xA33F) + 0x22 unsigned short CL_OFFSET, commandline offset + Address of commandline is calculated: + 0x90000 + contents of CL_OFFSET + (only taken, when CL_MAGIC = 0xA33F) + 0x40 20 bytes struct apm_bios_info, APM_BIOS_INFO + 0x60 16 bytes Intel SpeedStep (IST) BIOS support information + 0x80 16 bytes hd0-disk-parameter from intvector 0x41 + 0x90 16 bytes hd1-disk-parameter from intvector 0x46 + + 0xa0 16 bytes System description table truncated to 16 bytes. + ( struct sys_desc_table_struct ) + 0xb0 - 0x1c3 Free. Add more parameters here if you really need them. + +0x1c4 unsigned long EFI system table pointer +0x1c8 unsigned long EFI memory descriptor size +0x1cc unsigned long EFI memory descriptor version +0x1d0 unsigned long EFI memory descriptor map pointer +0x1d4 unsigned long EFI memory descriptor map size +0x1e0 unsigned long ALT_MEM_K, alternative mem check, in Kb +0x1e8 char number of entries in E820MAP (below) +0x1e9 unsigned char number of entries in EDDBUF (below) +0x1ea unsigned char number of entries in EDD_MBR_SIG_BUFFER (below) +0x1f1 char size of setup.S, number of sectors +0x1f2 unsigned short MOUNT_ROOT_RDONLY (if !=0) +0x1f4 unsigned short size of compressed kernel-part in the + (b)zImage-file (in 16 byte units, rounded up) +0x1f6 unsigned short swap_dev (unused AFAIK) +0x1f8 unsigned short RAMDISK_FLAGS +0x1fa unsigned short VGA-Mode (old one) +0x1fc unsigned short ORIG_ROOT_DEV (high=Major, low=minor) +0x1ff char AUX_DEVICE_INFO + +0x200 short jump to start of setup code aka "reserved" field. +0x202 4 bytes Signature for SETUP-header, ="HdrS" +0x206 unsigned short Version number of header format + Current version is 0x0201... +0x208 8 bytes (used by setup.S for communication with boot loaders, + look there) +0x210 char LOADER_TYPE, = 0, old one + else it is set by the loader: + 0xTV: T=0 for LILO + 1 for Loadlin + 2 for bootsect-loader + 3 for SYSLINUX + 4 for ETHERBOOT + V = version +0x211 char loadflags: + bit0 = 1: kernel is loaded high (bzImage) + bit7 = 1: Heap and pointer (see below) set by boot + loader. +0x212 unsigned short (setup.S) +0x214 unsigned long KERNEL_START, where the loader started the kernel +0x218 unsigned long INITRD_START, address of loaded ramdisk image +0x21c unsigned long INITRD_SIZE, size in bytes of ramdisk image +0x220 4 bytes (setup.S) +0x224 unsigned short setup.S heap end pointer +0x290 - 0x2cf EDD_MBR_SIG_BUFFER (edd.S) +0x2d0 - 0x600 E820MAP +0xd00 - 0xeec EDDBUF (edd.S) for edd data diff --git a/doc/multiboot.html b/doc/multiboot.html new file mode 100644 index 0000000..bd41444 --- /dev/null +++ b/doc/multiboot.html @@ -0,0 +1,664 @@ +<HTML> + +<HEAD> +<TITLE>Multiboot Standard</TITLE> +</HEAD> + +<BODY> + +<CENTER><H1>Multiboot Standard</H1></CENTER> +<CENTER><H3>Version 0.6</H3></CENTER> + +<HR> + +<H2>Contents</H2> + +<UL> +<LI> <A HREF="#motivation">Motivation</A> +<LI> <A HREF="#terminology">Terminology</A> +<LI> <A HREF="#scope">Scope and Requirements</A> +<LI> <A HREF="#details">Details</A> +<LI> <A HREF="#author">Authors</A> +<LI> <B>NOTE: The following items are not part of the standards document, +but are included for prospective OS and bootloader writers.</B> +<LI> <A HREF="#notes">Notes on PCs</A> +<LI> <A HREF="#example_os">Example OS Code</A> +<LI> <A HREF="#example_boot">Example Bootloader Code</A> +</UL> + +<HR> + +<H2><A NAME="motivation">Motivation</A></H2> + +Every OS ever created tends to have its own boot loader. Installing a new +OS 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 "chaining" mechanisms can be a nightmare. There is +little or no choice of boot loaders for a particular operating system - if +the one that comes with the OS doesn't do exactly what you want, or doesn't +work on your machine, you're screwed.<P> + +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 OS communities to put their heads together and solve this problem for +the popular free operating systems. That's what this standard 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 standard does NOT specify how boot +loaders should work - only how they must interface with the OS being +loaded.<P> + +<HR> + +<H2><A NAME="terminology">Terminology</A></H2> + +Throughout this document, the term "boot loader" means whatever program or +set of programs loads the image of the final operating system to be run on +the machine. The boot loader may itself consist of several stages, but +that is an implementation detail not relevant to this standard. Only the +"final" stage of the boot loader - the stage that eventually transfers +control to the OS - needs to follow the rules specified in this document +in order to be "MultiBoot compliant"; earlier boot loader stages can be +designed in whatever way is most convenient.<P> + +The term "OS image" is used to refer to the initial binary image that the +boot loader loads into memory and transfers control to to start the OS. +The OS image is typically an executable containing the OS kernel.<P> + +The term "boot module" refers to other auxiliary files that the boot loader +loads into memory along with the OS image, but does not interpret in any +way other than passing their locations to the OS when it is invoked.<P> + +<HR> + +<H2><A NAME="scope">Scope and Requirements</A></H2> + +<H3>Architectures</H3> + +This standard is primarily targetted at PC's, since they are the most +common and have the largest variety of OS's and boot loaders. However, to +the extent that certain other architectures may need a boot standard and do +not have one already, a variation of this standard, stripped of the +x86-specific details, could be adopted for them as well.<P> + +<H3>Operating systems</H3> + +This standard is targetted toward free 32-bit operating systems that can be +fairly easily modified to support the standard without going through lots of +bureaucratic rigmarole. The particular free OS's that this standard is +being primarily designed for are Linux, FreeBSD, NetBSD, Mach, and VSTa. +It is hoped that other emerging free OS's 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 standard as well, but that's probably a pipe dream.<P> + +<H3>Boot sources</H3> + +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.<P> + +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 "block lists" (e.g. LILO), loading from a special "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.<P> + +It is hoped that boot loaders will be created that support multiple loading +mechanisms, increasing their portability, robustness, and +user-friendliness.<P> + +<H3>Boot-time configuration</H3> + +It is often necessary for one reason or another for the user to be able to +provide some configuration information to the OS dynamically at boot time. +While this standard 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 OS.<P> + +<H3>Convenience to the OS</H3> + +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 OS +normally uses. It should be possible to 'nm' or disassemble OS images just +like normal executables. Specialized tools should not be needed to create +OS images in a "special" file format. If this means shifting some work +from the OS to the boot loader, that is probably appropriate, because all +the memory consumed by the boot loader will typically be made available +again after the boot process is created, whereas every bit of code in the +OS image typically has to remain in memory forever. The OS 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 OS +data above the 1MB boundary, and forcing the OS to do this makes creation +of OS images much more difficult.<P> + +Unfortunately, there is a horrendous variety of executable file formats +even among free Unix-like PC-based OS's - generally a different format for +each OS. Most of the relevant free OS's use some variant of a.out format, +but some are moving to 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 OS-specific again.<P> + +This standard adopts a compromise solution to this problem. +MultiBoot compliant boot images always either (a) are in ELF format, or (b) +contain a "magic MultiBoot header", described below, 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.<P> + +<H3>Boot modules</H3> + +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 OS +when it receives control, it is often more flexible, more space-efficient, +and more convenient to the OS and user if the boot loader can load these +additional modules independently in the first place.<P> + +Thus, this standard should provide a standard method for a boot loader to +indicate to the OS 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 OS's will be unable to +boot without them.<P> + +<HR> + +<H2><A NAME="details">Details</H2> + +There are three main aspects of the boot-loader/OS image interface this +standard must specify:<P> + +<UL> +<LI>The format of the OS image as seen by the boot loader. +<LI>The state of the machine when the boot loader starts the OS. +<LI>The format of the information passed by the boot loader to the OS. +</UL> + +<H3>OS Image Format</H3> + +An OS image is generally just an ordinary 32-bit executable file in the +standard format for that particular OS, except that it may be linked at a +non-default load address to avoid loading on top of the PC's I/O region +or other reserved areas, and of course it can't use shared libraries or +other fancy features. Initially, only images in a.out format are +supported; ELF support will probably later be specified in the standard.<P> + +Unfortunately, the exact meaning of the text, data, bss, and entry fields +of a.out headers tends to vary widely between different executable flavors, +and it is sometimes very difficult to distinguish one flavor from another +(e.g. Linux ZMAGIC executables and Mach ZMAGIC executables). Furthermore, +there is no simple, reliable way of determining at what address in memory +the text segment is supposed to start. Therefore, this standard requires +that an additional header, known as a 'multiboot_header', appear somewhere +near the beginning of the executable file. In general it should come "as +early as possible", and is typically embedded in the beginning of the text +segment after the "real" executable header. It _must_ be contained +completely within the first 8192 bytes of the executable file, and must be +longword (32-bit) aligned. These rules allow the boot loader to find and +synchronize with the text segment in the a.out file without knowing +beforehand the details of the a.out variant. The layout of the header is +as follows:<P> + +<pre> + +-------------------+ +0 | magic: 0x1BADB002 | (required) +4 | flags | (required) +8 | checksum | (required) + +-------------------+ +8 | header_addr | (present if flags[16] is set) +12 | load_addr | (present if flags[16] is set) +16 | load_end_addr | (present if flags[16] is set) +20 | bss_end_addr | (present if flags[16] is set) +24 | entry_addr | (present if flags[16] is set) + +-------------------+ +</pre> + +All fields are in little-endian byte order, of course. The first field is +the magic number identifying the header, which must be the hex value +0x1BADB002.<P> + +The flags field specifies features that the OS image requests or requires +of the boot loader. Bits 0-15 indicate requirements; if the boot loader +sees any of these bits set but doesn't understand the flag or can't fulfill +the requirements it indicates for some reason, it must notify the user and +fail to load the OS image. Bits 16-31 indicate optional features; if any +bits in this range are set but the boot loader doesn't understand them, it +can simply ignore them and proceed as usual. Naturally, all +as-yet-undefined bits in the flags word must be set to zero in OS +images. This way, the flags fields serves for version control as well as +simple feature selection.<P> + +If bit 0 in the flags word is set, then all boot modules loaded along with +the OS must be aligned on page (4KB) boundaries. Some OS's 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.<P> + +If bit 1 in the flags word is set, then information on available memory +via at least the 'mem_*' fields of the multiboot_info structure defined +below must be included. If the bootloader is capable of passing a memory +map (the 'mmap_*' fields) and one exists, then it must be included as +well.<P> + +If bit 16 in the flags word is set, then the fields at offsets 8-24 in the +multiboot_header are valid, and the boot loader should use them instead of +the fields in the actual executable header to calculate where to load the +OS image. This information does not need to be provided if the kernel +image is in ELF format, but it should 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 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.<P> + +All of the address fields enabled by flag bit 16 are physical addresses. +The meaning of each is as follows:<P> + +<UL> +<LI><B>header_addr</B> -- 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 "synchronize" +the mapping between OS image offsets and physical memory addresses. +<LI><B>load_addr</B> -- 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. +<LI><B>load_end_addr</B> -- 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. +<LI><B>bss_end_addr</B> -- 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 OS in that area. +<LI><B>entry</B> -- The physical address to which the boot loader should +jump in order to start running the OS. +</UL> + +The checksum is a 32-bit unsigned value which, when added to +the other required fields, must have a 32-bit unsigned sum of zero.<P> + +<H3>Machine State</H3> + +When the boot loader invokes the 32-bit operating system, +the machine must have the following state:<P> + +<UL> +<LI>CS must be a 32-bit read/execute code segment with an offset of 0 +and a limit of 0xffffffff. +<LI>DS, ES, FS, GS, and SS must be a 32-bit read/write data segment with +an offset of 0 and a limit of 0xffffffff. +<LI>The address 20 line must be usable for standard linear 32-bit +addressing of memory (in standard PC hardware, it is wired to +0 at bootup, forcing addresses in the 1-2 MB range to be mapped to the +0-1 MB range, 3-4 is mapped to 2-3, etc.). +<LI>Paging must be turned off. +<LI>The processor interrupt flag must be turned off. +<LI>EAX must contain the magic value 0x2BADB002; the presence of this value +indicates to the OS that it was loaded by a MultiBoot-compliant boot +loader (e.g. as opposed to another type of boot loader that the OS can +also be loaded from). +<LI>EBX must contain the 32-bit physical address of the multiboot_info +structure provided by the boot loader (see below). +</UL> + +All other processor registers and flag bits are undefined. This includes, +in particular:<P> + +<UL> +<LI>ESP: the 32-bit OS must create its own stack as soon as it needs one. +<LI>GDTR: Even though the segment registers are set up as described above, +the GDTR may be invalid, so the OS must not load any segment registers +(even just reloading the same values!) until it sets up its own GDT. +<LI>IDTR: The OS must leave interrupts disabled until it sets up its own IDT. +</UL> + +However, other machine state should be left by the boot loader in "normal +working order", i.e. as initialized by the BIOS (or DOS, if that's what +the boot loader runs from). In other words, the OS should be able to make +BIOS calls and such after being loaded, as long as it does not overwrite +the BIOS data structures before doing so. Also, the boot loader must leave +the PIC programmed with the normal BIOS/DOS values, even if it changed them +during the switch to 32-bit mode.<P> + +<H3>Boot Information Format</H3> + +Upon entry to the OS, the EBX register contains the physical address of +a 'multiboot_info' data structure, through which the boot loader +communicates vital information to the OS. The OS can use or ignore any +parts of the structure as it chooses; all information passed by the boot +loader is advisory only.<P> + +The multiboot_info 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 OS's +responsibility to avoid overwriting this memory until it is done using it.<P> + +The format of the multiboot_info structure (as defined so far) follows:<P> + +<pre> + +-------------------+ +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) + +-------------------+ +</pre> + +The first longword indicates the presence and validity of other fields in +the multiboot_info structure. All as-yet-undefined bits must be set to +zero by the boot loader. Any set bits that the OS does not understand +should be ignored. Thus, the flags field also functions as a version +indicator, allowing the multiboot_info structure to be expanded in the +future without breaking anything.<P> + +If bit 0 in the multiboot_info.flags word is set, then the 'mem_*' fields +are valid. 'mem_lower' and '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.<P> + +If bit 1 in the multiboot_info.flags word is set, then the 'boot_device' +field is valid, and indicates which BIOS disk device the boot loader loaded +the OS from. If the OS was not loaded from a BIOS disk, then this field +must not be present (bit 3 must be clear). The OS may use this field as a +hint for determining its own "root" device, but is not required to. The +boot_device field is layed out in four one-byte subfields as follows:<P> + +<pre> + +-------+-------+-------+-------+ + | drive | part1 | part2 | part3 | + +-------+-------+-------+-------+ +</pre> + +The first byte contains the BIOS drive number as understood by the BIOS +INT 0x13 low-level disk interface: e.g. 0x00 for the first floppy disk or +0x80 for the first hard disk.<P> + +The three remaining bytes specify the boot partition. 'part1' specifies +the "top-level" partition number, 'part2' specifies a "sub-partition" in +the top-level partition, etc. Partition numbers always start from zero. +Unused partition bytes must be set to 0xFF. For example, if the disk is +partitioned using a simple one-level DOS partitioning scheme, then 'part1' +contains the DOS partition number, and 'part2' and 'part3' are both zero. +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 "disklabel" strategy, then 'part1' contains the DOS partition +number, 'part2' contains the BSD sub-partition within that DOS partition, +and 'part3' is 0xFF.<P> + +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 'part1' will be 5, +and 'part2' and 'part3' will both be 0xFF.<P> + +If bit 2 of the flags longword is set, the 'cmdline' field is valid, and +contains the physical address of the the command line to be passed to the +kernel. The command line is a normal C-style null-terminated string.<P> + +If bit 3 of the flags is set, then the 'mods' fields indicate to the kernel +what boot modules were loaded along with the kernel image, and where they +can be found. 'mods_count' contains the number of modules loaded; +'mods_addr' contains the physical address of the first module structure. +'mods_count' may be zero, indicating no boot modules were loaded, even if +bit 1 of 'flags' is set. Each module structure is formatted as follows:<P> + +<pre> + +-------------------+ +0 | mod_start | +4 | mod_end | + +-------------------+ +8 | string | + +-------------------+ +12 | reserved (0) | + +-------------------+ +</pre> + +The first two fields contain the start and end addresses of the boot module +itself. The 'string' field provides an arbitrary string to be associated +with that particular boot module; it is a null-terminated ASCII string, +just like the kernel command line. The '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 OS treats boot modules as executable programs), +or a pathname (e.g. if the OS treats boot modules as files in a file +system), but its exact use is specific to the OS. The 'reserved' field +must be set to 0 by the boot loader and ignored by the OS.<P> + +NOTE: Bits 4 & 5 are mutually exclusive.<P> + +If bit 4 in the multiboot_info.flags word is set, then the following +fields in the multiboot_info structure starting at byte 28 are valid:<P> + +<pre> + +-------------------+ +28 | tabsize | +32 | strsize | +36 | addr | +40 | reserved (0) | + +-------------------+ +</pre> + +These indicate where the symbol table from an a.out kernel image can be +found. 'addr' is the physical address of the size (4-byte unsigned +long) of an array of a.out-format 'nlist' structures, followed immediately +by the array itself, then the size (4-byte unsigned long) of a set of +null-terminated ASCII strings (plus sizeof(unsigned long) in this case), +and finally the set of strings itself. 'tabsize' is equal to it's size +parameter (found at the beginning of the symbol section), and 'strsize' +is equal to it's size parameter (found at the beginning of the string section) +of the following string table to which the symbol table refers. Note that +'tabsize' may be 0, indicating no symbols, even if bit 4 in the flags +word is set.<P> + +If bit 5 in the multiboot_info.flags word is set, then the following +fields in the multiboot_info structure starting at byte 28 are valid:<P> + +<pre> + +-------------------+ +28 | num | +32 | size | +36 | addr | +40 | shndx | + +-------------------+ +</pre> + +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 'shdr_*' entries ('shdr_num', etc.) +in the Executable and Linkable Format (ELF) specification in the program +header. All sections are loaded, and the physical address fields +of the elf section header then refer to where the sections are in memory +(refer to the i386 ELF documentation for details as to how to read the +section header(s)). Note that 'shdr_num' may be 0, indicating no symbols, +even if bit 5 in the flags word is set.<P> + +If bit 6 in the multiboot_info.flags word is set, then the 'mmap_*' fields +are valid, and indicate the address and length of a buffer containing a +memory map of the machine provided by the BIOS. 'mmap_addr' is the address, +and 'mmap_length' is the total size of the buffer. The buffer consists of +one or more of the following size/structure pairs ('size' is really used +for skipping to the next pair):<P> + +<pre> + +-------------------+ +-4 | size | + +-------------------+ +0 | BaseAddrLow | +4 | BaseAddrHigh | +8 | LengthLow | +12 | LengthHigh | +16 | Type | + +-------------------+ +</pre> + +where 'size' is the size of the associated structure in bytes, which can +be greater than the minimum of 20 bytes. 'BaseAddrLow' is the lower 32 +bits of the starting address, and 'BaseAddrHigh' is the upper 32 bits, +for a total of a 64-bit starting address. 'LengthLow' is the lower 32 bits +of the size of the memory region in bytes, and 'LengthHigh' is the upper 32 +bits, for a total of a 64-bit length. 'Type' is the variety of address +range represented, where a value of 1 indicates available RAM, and all +other values currently indicated a reserved area.<P> + +The map provided is guaranteed to list all standard RAM that should +be available for normal use.<P> + +<HR> + +<H2><A NAME="author">Authors</A></H2> + +<pre> +Bryan Ford +Computer Systems Laboratory +University of Utah +Salt Lake City, UT 84112 +(801) 581-4280 +baford@cs.utah.edu + +Erich Stefan Boleyn +924 S.W. 16th Ave, #202 +Portland, OR, USA 97205 +(503) 226-0741 +erich@uruk.org +</pre> + +We would also like to thank the many other people have provided comments, +ideas, information, and other forms of support for our work.<P> + +<H3>Revision History</H3> + +<pre> +Version 0.6 3/29/96 (a few wording changes, header checksum, and + clarification of machine state passed to the OS) +Version 0.5 2/23/96 (name change) +Version 0.4 2/1/96 (major changes plus HTMLification) +Version 0.3 12/23/95 +Version 0.2 10/22/95 +Version 0.1 6/26/95 +</pre> + +<HR> + +<H2><A NAME="notes">Notes on PCs</A></H2> + +In reference to bit 0 of the multiboot_info.flags parameter, +if the bootloader +in question uses older BIOS interfaces, or the newest ones are not +available (see description about bit 6), then a maximum of either +15 or 63 megabytes of memory may be reported. It is HIGHLY recommended +that bootloaders perform a thorough memory probe.<P> + +In reference to bit 1 of the multiboot_info.flags parameter, it is +recognized that determination of which BIOS drive maps to which +OS-level device-driver is non-trivial, at best. Many kludges have +been made to various OSes instead of solving this problem, most of +them breaking under many conditions. To encourage the use of +general-purpose solutions to this problem, here are 2 +<A HREF=bios_mapping.txt>BIOS Device Mapping Techniques</A>.<P> + +In reference to bit 6 of the multiboot_info.flags parameter, it is +important to note that the data structure used there +(starting with 'BaseAddrLow') is the data returned by the +<A HREF=mem64mb.html>INT 15h, AX=E820h +- Query System Address Map</A> call. More information +on reserved memory regions is defined on that web page. +The interface here is meant to allow a bootloader to +work unmodified with any reasonable extensions of the BIOS interface, +passing along any extra data to be interpreted by the OS as desired.<P> + +<HR> + +<H2><A NAME="example_os">Example OS Code</A> (from Bryan Ford)</H2> + +EDITOR'S NOTE: These examples are relevant to the Proposal version 0.5, +which is basically identical except for the multiboot OS header, which was +missing the checksum. A patch to bring Mach4 UK22 up to version 0.6 is +available in the GRUB FTP area mentioned in the +<A HREF="#example_boot">Example Bootloader Code</A> section below.<P> + +The Mach 4 distribution, available by anonymous FTP from +flux.cs.utah.edu:/flux, contains a C header file that defines the +MultiBoot data structures described above; anyone is welcome to rip it +out and use it for other boot loaders and OS's:<P> + +<pre> + mach4-i386/include/mach/machine/multiboot.h +</pre> + +This distribution also contains code implementing a "Linux boot adaptor", +which collects a MultiBoot-compliant OS image and an optional set of boot +modules, compresses them, and packages them into a single traditional Linux +boot image that can be loaded from LILO or other Linux boot loaders. There +is also a corresponding "BSD boot adaptor" which can be used to wrap a +MultiBoot kernel and set of modules and produce an image that can be loaded +from the FreeBSD and NetBSD boot loaders. All of this code can be used as-is +or as a basis for other boot loaders. These are the directories of primary +relevance:<P> + +<pre> + mach4-i386/boot + mach4-i386/boot/bsd + mach4-i386/boot/linux +</pre> + +The Mach kernel itself in this distribution contains code that demonstrates +how to create a compliant OS. The following files are of primary +relevance:<P> + +<pre> + mach4-i386/kernel/i386at/boothdr.S + mach4-i386/kernel/i386at/model_dep.c +</pre> + +Finally, I have created patches against the Linux 1.2.2 and FreeBSD 2.0 +kernels, in order to make them compliant with this proposed standard. +These patches are available in kahlua.cs.utah.edu:/private/boot.<P> + +<HR> + +<H2><A NAME"example_boot">Example Bootloader Code</A> (from Erich Boleyn)</H2> + +The <A HREF=http://www.uruk.org/grub/>GRUB</A> bootloader project +will be fully +Multiboot-compliant, supporting all required and optional +features present in this standard.<P> + +A final release has not been made, but both the GRUB beta release +(which is quite stable) and a patch for Multiboot version 0.6 for +Mach4 UK22 are available in the GRUB +<A HREF=ftp://ftp.uruk.org/public/grub/>public release</A> +area.<P> + +<HR> + +<A HREF=mailto:erich@uruk.org><I>erich@uruk.org</I></A><P> + +</BODY> +</HTML> + diff --git a/doc/nbi-spec.txt b/doc/nbi-spec.txt new file mode 100644 index 0000000..320f025 --- /dev/null +++ b/doc/nbi-spec.txt @@ -0,0 +1,660 @@ + Draft Net Boot Image Proposal 0.3 + Jamie Honan and Gero Kuhlmann, gero@minix.han.de + June 15, 1997 + + This is the specification of the "tagged image" format + ______________________________________________________________________ + + Table of Contents + + + 1. Note + + 2. Preamble - the why + + 3. The target + + 4. Net Boot Process Description. + + 5. Image Format with Initial Magic Number. + + 6. Boot prom entry points. + + 7. Example of a boot image. + + 8. Terms + + 9. References + + + + ______________________________________________________________________ + + 11.. NNoottee + + + In order to provide more functionality to the boot rom code I changed + Jamie's draft a little bit. All my changes are preceded and followed + by ((ggkk)). + + + + Gero Kuhlmann + + + 22.. PPrreeaammbbllee -- tthhee wwhhyy + + + Whilst researching what other boot proms do (at least those + implementing TCP/IP protocols) it is clear that each 'does their own + thing' in terms of what they expect in a boot image. + + + + If we could all agree on working toward an open standard, O/S + suppliers and boot rom suppliers can build their products to this + norm, and be confident that they will work with each other. + + + + This is a description of how I will implement the boot rom for Linux. + I believe it to be flexible enough for any OS that will be loaded + when a PC boots from a network in the TCP/IP environment. + + + + + It would be good if this could be turned into some form of standard. + + + + This is very much a first draft. I am inviting comment. + + + + The ideas presented here should be independant of any implementation. + In the end, where there is a conflict between the final of this draft, + and an implementation, this description should prevail. + + + + The terms I use are defined at the end. + + + + ((ggkk))IMPORTANT NOTE: The scope of this document starts at the point + where the net boot process gains control from the BIOS, to where the + booted image reaches a state from which there is no return to the net + boot program possible.((ggkk)) + + + 33.. TThhee ttaarrggeett + + + The target is to have a PC retrieve a boot image from a network in the + TCP/IP environment. + + + + ((ggkk))The boot may take place from a network adaptor rom, from a boot + floppy.((ggkk)) + + + 44.. NNeett BBoooott PPrroocceessss DDeessccrriippttiioonn.. + + + ((ggkk))The net boot process is started as a result of the PC boot + process. The net boot program can reside on a rom, e.g. on an adaptor + card, or in ram as a result of reading off disk.((ggkk)) + + + + The boot process may execute in any mode (e.g. 8086, 80386) it + desires. When it jumps to the start location in the boot image, it + must be in 8086 mode and be capable of going into any mode supported + by the underlying processor. + + + + The image cannot be loaded into address spaces below 10000h, or + between A0000h through FFFFFh, or between 98000h through 9FFFFh. + ((ggkk))Only when the image is not going to return to the boot process, + all the memory is available to it once it has been started, so it can + relocate parts of itself to these areas.((ggkk)) + + + + The boot process must be capable of loading the image into all other + memory locations. Specifically, where the machine supports this, this + means memory over 100000h. + + + + The net boot process must execute the bootp protocol, followed by the + tftp protocol, as defined in the relevant rfc's. + + + + The file name used in the tftp protocol must be that given by the + bootp record. + + + + If less than 512 bytes are loaded, the net boot process attempts to + display on the screen any ascii data at the start of the image. The + net boot process then exits in the normal manner. For a boot prom, + this will allow normal disk booting. ((ggkk))Reference to DOS deleted.((ggkk)) + + + + When the first 512 bytes have been loaded, the boot process checks for + an initial magic number, which is defined later. If this number is + present, the net process continues loading under the control of the + image format. The image, which is described later, tells the net boot + process where to put this record and all subsequent data. + + + + If no initial magic number is present the net boot process checks for + a second magic number at offset 510. If the magic number 510 = 55h, + 511 = AAh, then the net process continues. If this second magic number + is not present, then the net boot process terminates the tftp + protocol, displays an error message and exits in the normal manner. + + + + If no initial magic number is present and the second one is, the net + boot process relocates the 512 bytes to location 7c00h. The net boot + process continues to load any further image data to 10000h up. This + data can overwrite the first 512 boot bytes. If the image reaches + 98000h, then any further data is continued to be loaded above 100000h. + When all the data has been loaded, the net boot process jumps to + location 0:7c00. + + + + ((ggkk))When the net boot program calls the image, it places 2 far + pointers onto the stack, in standard intel order (e.g. segment:offset + representation). The first far pointer which immediately follows the + return address on the stack, points to the loaded boot image header. + The second far pointer which is placed above the first one, shows to + the memory area where the net boot process saved the bootp reply. + + + + If the boot image is flagged as being returnable to the boot process, + the boot program has to provide the boot image with interrupt vector + 78h. It's an interface to services provided by the net boot program + (see below for further description). + + + + If the boot image is not flagged as being returnable to the boot + process, before the boot image is called, the boot program has to set + the system into a state in which it was before the net boot process + has started.((ggkk)) + + + + 55.. IImmaaggee FFoorrmmaatt wwiitthh IInniittiiaall MMaaggiicc NNuummbbeerr.. + + + The first 512 bytes of the image file contain the image header, and + image loading information records. This contains all the information + needed by the net boot process as to where data is to be loaded. + + The magic number (in time-honoured tradition (well why not?)) is: + + + ______________________________________________________________________ + 0 = 36h + 1 = 13h + 2 = 03h + 3 = 1Bh + ______________________________________________________________________ + + + + Apart from the two magic numbers, all words and double words are in PC + native endian. + + + + Including the initial magic number the header record is: + + + ______________________________________________________________________ + +---------------------+ + | | + | Initial Magic No. | 4 bytes + +---------------------+ + | | + | Flags and length | double word + +---------------------+ + | | + | Location Address | double word in ds:bx format + +---------------------+ + | | + | Execute Address | double word in cs:ip format + +---------------------+ + ______________________________________________________________________ + + + + The Location address is where to place the 512 bytes. The net boot + process does this before loading the rest of the image. The location + address cannot be one of the reserved locations mentioned above, but + must be an address lower than 100000h. + + + + The rest of the image must not overwrite these initial 512 bytes, + placed at the required location. The writing of data by the net boot + process into these 512 bytes is deprecated. These 512 bytes must be + available for the image to interogate once it is loaded and running. + + + + The execute address is the location in cs:ip of the initial + instruction once the full image has been loaded. This must be lower + than 100000h, since the initial instructions will be executed in 8086 + mode. When the jump (actaully a far call) is made to the boot image, + the stack contains a far return address, with a far pointer parameter + above that, pointing to the location of this header. + + The flags and length field is broken up in the following way: + + + + Bits 0 to 3 (lowest 4 bits) define the length of the non vendor header + in double words. Currently the value is 4. + + + + Bits 4 to 7 define the length required by the vendor extra information + in double words. A value of zero indicates no extra vendor + information. + + + + ((ggkk))Bit 8 is set if the boot image can return to the net boot process + after execution. If this bit is not set the boot image does never + return to the net boot process, and the net boot program has to set + the system into a clean state before calling the boot image. + + + + Bits 9 to 31 are reserved for future use and must be set to zero.((ggkk)) + + + + After this header, and any vendor header, come the image loading + information records. These specify where data is to be loaded, how + long it is, and communicates to the loaded image what sort of data it + is. + + + + The format of each image loading information record is : + + + + ______________________________________________________________________ + +---------------------+ + | Flags, tags and | double word + | lengths | + +---------------------+ + | | + | Load Address | double word + +---------------------+ + | | + | Image Length | double word + +---------------------+ + | | + | Memory Length | double word + +---------------------+ + ______________________________________________________________________ + + + + Each image loading information record follows the previous, or the + header. + + + + The memory length, image length and load address fields are unsigned + 32 numbers. They do not have the segment:offset format used by the + 8086. + + + + The flags, tags and lengths field is broken up as follows: + + + + Bits 0 to 3 (lowest 4 bits) are the length of the non vendor part of + this header in double words. Currently this value is 4. + + + + Bits 4 to 7 indicate the length of any vendor information, in double + words. + + + + Bits 8 to 15 are for vendor's tags. The vendor tag is a private number + that the loaded image can use to determine what sort of image is at + this particular location. + + + + Bits 16 to 23 are for future expansion and should be set to zero. + + + + Bits 24 to 31 are for flags, which are defined later. + + + + Vendors may place further information after this information record, + and before the next. Each information record may have a different + vendor length. + + + + There are two restrictions on vendor information. + + + + One is that the header and all information records that the net boot + process is to use fall within the first 512 bytes. + + + + The second restriction is that the net boot process must ignore all + vendor additions. The net boot process may not overwrite vendor + supplied information, or other undefined data in the initial 512 + bytes. + + + + The flags are used to modify the load address field, and to indicate + that this is the last information record that the net boot process + should use. + + + + Bit 24 works in conjunction with bit 25 to specify the meaning of the + load address. + + + + + + + + + ______________________________________________________________________ + B24 B25 + + 0 0 load address is an absolute 32 number + + 1 0 add the load address to the location one past the last byte + of the memory area required by the last image loaded. + If the first image, then add to 512 plus the location + where the 512 bytes were placed + + 0 1 subtract the load address from the one past the + last writeable location in memory. Thus 1 would + be the last location one could write in memory. + + 1 1 load address is subtracted from the start of + the last image loaded. If the first image, then + subtract from the start of where the 512 bytes were + placed + ______________________________________________________________________ + + + + (For convenience bit 24 is byte 0 of the flag field) + + + + Bit 26 is the end marker for the net boot process. It is set when this + is the last information record the net boot process should look at. + More records may be present, but the net boot process will not look at + them. (Vendors can continue information records out past the 512 + boundary for private use in this manner). + + + + The image length tells the net boot process how many bytes are to be + loaded. Zero is a valid value. This can be used to mark memory areas + such as shared memory for interprocessor communication, flash eproms, + data in eproms. + + + + The image length can also be different from the memory length. This + allows decompression programs to fluff up the kernel image. It also + allows a file system to be larger then the loaded file system image. + + + + Bits 27 through 31 are not defined as yet and must be set to zero + until they are. + + + 66.. BBoooott pprroomm eennttrryy ppooiinnttss.. + + + ((ggkk))As mentioned above the net boot process has to provide interrupt + 78h as an entry point in case, the returnable flag (bit 9 of the flags + field in the image header) of the boot image has been set. When + calling this interface interrupt, the caller has to load the AH + register with a value indicating the type of operation requested: + + + + + + + + ______________________________________________________________________ + 00h - Installation check + Input: none + Output: AX - returns the value 474Bh + BX - flags indicating what further services are + provided by the net boot program: + Bit 0 - packet driver interface (see below) + Bits 1 to 15 are unused and have to be zero + + 01h - Cleanup and terminate the boot process services. This will + also remove the services provided by interrupt 87h. + Input: none + Output: none + ______________________________________________________________________ + + + + + + Further functions are not yet defined. These functions are only + available to boot images which have the first magic number at the + beginning of the image header, and have the returnable flag set in the + flags field. + + + + In order to provide compatibility with net boot programs written to + match an earlier version of this document, the loaded image should + check for the existence of interrupt 78h by looking at it's vector. If + that's 0:0, or if it does not return a proper magic ID after calling + the installation check function, the boot image has to assume that the + net boot program does not support this services interrupt. + + + + If the bit 0 of register BX of function 00h is set, the boot program + has to provide a packet driver <http://www.crynwr.com> interface at + interrupt 79h as described in the packet driver interface standard, + version 1.09, published by FTP Software, Inc., which is not repeated + here. It serves as an interface to the system's network card. It is + important to note that the net boot process has to provide a clean + packet driver interface without any handles being defined when the + boot image gets started. It is expected that the boot image sets up + it's own TCP/IP or other network's stack on top of this packet driver + interface. When the boot image returns to the net boot process, it + has to return a clean packet driver interface as well, without any + handles being defined.((ggkk)) + + + 77.. EExxaammppllee ooff aa bboooott iimmaaggee.. + + + Here is an example of how the boot image would look for Linux: + + + + + + + + + + + + + + ______________________________________________________________________ + 0x1B031336, /* magic number */ + 0x4, /* length of header is 16 bytes, no vendor info */ + 0x90000000, /* location in ds:bx format */ + 0x90000200, /* execute address in cs:ip format */ + + /* 2048 setup.S bytes */ + 0x4, /* flags, not end, absolute address, 16 bytes this + record, no vendor info */ + 0x90200, /* load address - note format */ + 0x800, /* 4 8 512 byte blocks for linux */ + 0x800, + + /* kernel image */ + 0x4, /* flags, not end, absolute address, 16 bytes this + record, no vendor info */ + 0x10000, /* load address - note format */ + 0x80000, /* 512K (this could be shorter */ + 0x80000, + + /* ramdisk for root file system */ + 0x04000004, /* flags = last, absolute address, 16 bytes this + record, no vendor info *// + 0x100000, /* load address - in extended memory */ + 0x80000, /* 512K for instance */ + 0x80000, + + /* Then follows linux specific information */ + ______________________________________________________________________ + + + + + 88.. TTeerrmmss + + + When I say 'the net boot process', I mean the act of loading the image + into memory, setting up any tables, up until the jump to the required + location in the image. + + + + The net booting program executes the net boot process. The net boot + program may be a rom, but not neccassarily. It is a set of + instructions and data residing on the booting machine. + + + + The image, or boot image, consists of the data loaded by the net boot + process. + + + + When I say 'the PC boot process', I mean the general PC rom bios boot + process, the setting up of hardware, the scanning for adaptor roms, + the execution of adaptor roms, the loading in of the initial boot + track. The PC boot process will include the net boot process, if one + is present. + + + + When I say client, I mean the PC booting up. + + + + + When I say 'image host', I mean the host where the boot image is + comming from. This may not have the same architecture as the client. + + + + The bootp protocol is defined in RFC951 and RFC1084. The tftp protocol + is defined in RFC783. These are available on many sites. See Comer + 1991 for details on how to obtain them. + + + + A bootp server is the machine that answers the bootp request. It is + not neccessarily the image host. + + + + "Can" and "may" means doesn't have to, but is allowed to and might. + "Must" means just that. "Cannot" means must not. + + + 99.. RReeffeerreenncceess + + + Comer, D.E. 1991, Internetworking with TCP/IP Vol I: Principles, + Protocols, and Architecture Second Edition, Prentice Hall, Englewood + Cliffs, N.J., 1991 + + + + Stevens, W.R 1990, Unix Network Programming, Prentice Hall, Englewood + Cliffs, N.J., 1990 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + |