Annotation of qemu/roms/ipxe/src/arch/i386/README.i386, revision 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.