Annotation of qemu/roms/ipxe/src/arch/i386/README.i386, revision 1.1.1.1

1.1       root        1: Etherboot/NILO i386 initialisation path and external call interface
                      2: ===================================================================
                      3: 
                      4: 1. Background
                      5: 
                      6: GCC compiles 32-bit code.  It is capable of producing
                      7: position-independent code, but the resulting binary is about 25%
                      8: bigger than the corresponding fixed-position code.  Since one main use
                      9: of Etherboot is as firmware to be burned into an EPROM, code size must
                     10: be kept as small as possible.
                     11: 
                     12: This means that we want to compile fixed-position code with GCC, and
                     13: link it to have a predetermined start address.  The problem then is
                     14: that we must know the address that the code will be loaded to when it
                     15: runs.  There are several ways to solve this:
                     16: 
                     17: 1. Pick an address, link the code with this start address, then make
                     18:    sure that the code gets loaded at that location.  This is
                     19:    problematic, because we may pick an address that we later end up
                     20:    wanting to use to load the operating system that we're booting.
                     21: 
                     22: 2. Pick an address, link the code with this start address, then set up
                     23:    virtual addressing so that the virtual addresses match the
                     24:    link-time addresses regardless of the real physical address that
                     25:    the code is loaded to.  This enables us to relocate Etherboot to
                     26:    the top of high memory, where it will be out of the way of any
                     27:    loading operating system.
                     28: 
                     29: 3. Link the code with a text start address of zero and a data start
                     30:    address also of zero.  Use 16-bit real mode and the
                     31:    quasi-position-independence it gives you via segment addressing.
                     32:    Doing this requires that we generate 16-bit code, rather than
                     33:    32-bit code, and restricts us to a maximum of 64kB in each segment.
                     34: 
                     35: There are other possible approaches (e.g. including a relocation table
                     36: and code that performs standard dynamic relocation), but the three
                     37: options listed above are probably the best available.
                     38: 
                     39: Etherboot can be invoked in a variety of ways (ROM, floppy, as a PXE
                     40: NBP, etc).  Several of these ways involve control being passed to
                     41: Etherboot with the CPU in 16-bit real mode.  Some will involve the CPU
                     42: being in 32-bit protected mode, and there's an outside chance that
                     43: some may involve the CPU being in 16-bit protected mode.  We will
                     44: almost certainly have to effect a CPU mode change in order to reach
                     45: the mode we want to be in to execute the C code.
                     46: 
                     47: Additionally, Etherboot may wish to call external routines, such as
                     48: BIOS interrupts, which must be called in 16-bit real mode.  When
                     49: providing a PXE API, Etherboot must provide a mechanism for external
                     50: code to call it from 16-bit real mode.
                     51: 
                     52: Not all i386 builds of Etherboot will want to make real-mode calls.
                     53: For example, when built for LinuxBIOS rather than the standard PCBIOS,
                     54: no real-mode calls are necessary.
                     55: 
                     56: For the ultimate in PXE compatibility, we may want to build Etherboot
                     57: to run permanently in real mode.
                     58: 
                     59: There is a wide variety of potential combinations of mode switches
                     60: that we may wish to implement.  There are additional complications,
                     61: such as the inability to access a high-memory stack when running in
                     62: real mode.
                     63: 
                     64: 2. Transition libraries
                     65: 
                     66: To handle all these various combinations of mode switches, we have
                     67: several "transition" libraries in Etherboot.  We also have the concept
                     68: of an "internal" and an "external" environment.  The internal
                     69: environment is the environment within which we can execute C code.
                     70: The external environment is the environment of whatever external code
                     71: we're trying to interface to, such as the system BIOS or a PXE NBP.
                     72: 
                     73: As well as having a separate addressing scheme, the internal
                     74: environment also has a separate stack.
                     75: 
                     76: The transition libraries are:
                     77: 
                     78: a) librm
                     79: 
                     80: librm handles transitions between an external 16-bit real-mode
                     81: environment and an internal 32-bit protected-mode environment with
                     82: virtual addresses.
                     83: 
                     84: b) libkir
                     85: 
                     86: libkir handles transitions between an external 16-bit real-mode (or
                     87: 16:16 or 16:32 protected-mode) environment and an internal 16-bit
                     88: real-mode (or 16:16 protected-mode) environment.
                     89: 
                     90: c) libpm
                     91: 
                     92: libpm handles transitions between an external 32-bit protected-mode
                     93: environment with flat physical addresses and an internal 32-bit
                     94: protected-mode environment with virtual addresses.
                     95: 
                     96: The transition libraries handle the transitions required when
                     97: Etherboot is started up for the first time, the transitions required
                     98: to execute any external code, and the transitions required when
                     99: Etherboot exits (if it exits).  When Etherboot provides a PXE API,
                    100: they also handle the transitions required when a PXE client makes a
                    101: PXE API call to Etherboot.
                    102: 
                    103: Etherboot may use multiple transition libraries.  For example, an
                    104: Etherboot ELF image does not require librm for its initial transitions
                    105: from prefix to runtime, but may require librm for calling external
                    106: real-mode functions.
                    107: 
                    108: 3. Setup and initialisation
                    109: 
                    110: Etherboot is conceptually divided into the prefix, the decompressor,
                    111: and the runtime image.  (For non-compressed images, the decompressor
                    112: is a no-op.)  The complete image comprises all three parts and is
                    113: distinct from the runtime image, which exclude the prefix and the
                    114: decompressor.
                    115: 
                    116: The prefix does several tasks:
                    117: 
                    118:   Load the complete image into memory.  (For example, the floppy
                    119:   prefix issues BIOS calls to load the remainder of the complete image
                    120:   from the floppy disk into RAM, and the ISA ROM prefix copies the ROM
                    121:   contents into RAM for faster access.)
                    122: 
                    123:   Call the decompressor, if the runtime image is compressed.  This
                    124:   decompresses the runtime image.
                    125: 
                    126:   Call the runtime image's setup() routine.  This is a routine
                    127:   implemented in assembly code which sets up the internal environment
                    128:   so that C code can execute.
                    129: 
                    130:   Call the runtime image's arch_initialise() routine.  This is a
                    131:   routine implemented in C which does some basic startup tasks, such
                    132:   as initialising the console device, obtaining a memory map and
                    133:   relocating the runtime image to high memory.
                    134: 
                    135:   Call the runtime image's arch_main() routine.  This records the exit
                    136:   mechanism requested by the prefix and calls main().  (The prefix
                    137:   needs to register an exit mechanism because by the time main()
                    138:   returns, the memory occupied by the prefix has most likely been
                    139:   overwritten.)
                    140: 
                    141: When acting as a PXE ROM, the ROM prefix contains an UNDI loader
                    142: routine in addition to its usual code.  The UNDI loader performs a
                    143: similar sequence of steps:
                    144: 
                    145:   Load the complete image into memory.
                    146: 
                    147:   Call the decompressor.
                    148: 
                    149:   Call the runtime image's setup() routine.
                    150: 
                    151:   Call the runtime image's arch_initialise() routine.
                    152: 
                    153:   Call the runtime image's install_pxe_stack() routine.
                    154: 
                    155:   Return to caller.
                    156: 
                    157: The runtime image's setup() routine will perform the following steps:
                    158: 
                    159:   Switch to the internal environment using an appropriate transition
                    160:   library.  This will record the parameters of the external
                    161:   environment.
                    162: 
                    163:   Set up the internal environment: load a stack, and set up a GDT for
                    164:   virtual addressing if virtual addressing is to be used.
                    165: 
                    166:   Switch back to the external environment using the transition
                    167:   library.  This will record the parameters of the internal
                    168:   environment.
                    169: 
                    170: Once the setup() routine has returned, the internal environment has been
                    171: set up ready for C code to run.  The prefix can call C routines using
                    172: a function from the transition library.
                    173: 
                    174: The runtime image's arch_initialise() routine will perform the
                    175: following steps:
                    176: 
                    177:   Zero the bss
                    178: 
                    179:   Initialise the console device(s) and print a welcome message.
                    180: 
                    181:   Obtain a memory map via the INT 15,E820 BIOS call or suitable
                    182:   fallback mechanism. [not done if libkir is being used]
                    183: 
                    184:   Relocate the runtime image to the top of high memory. [not done if
                    185:   libkir is being used]
                    186: 
                    187:   Install librm to base memory. [done only if librm is being used]
                    188: 
                    189:   Call initialise().
                    190: 
                    191:   Return to the prefix, setting registers to indicate to the prefix
                    192:   the new location of the transition library, if applicable.  Which
                    193:   registers these are is specific to the transition library being
                    194:   used.
                    195: 
                    196: Once the arch_initialise() routine has returned, the prefix will
                    197: probably call arch_main().

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.