Annotation of qemu/roms/seabios/README, revision 1.1

1.1     ! root        1: This code implements an X86 legacy bios.  It is intended to be
        !             2: compiled using standard gnu tools (eg, gas and gcc).
        !             3: 
        !             4: To build, one should be able to run "make" in the main directory.  The
        !             5: resulting file "out/bios.bin" contains the processed bios image.
        !             6: 
        !             7: 
        !             8: Testing of images:
        !             9: 
        !            10: To test the bios under bochs, one will need to instruct bochs to use
        !            11: the new bios image.  Use the 'romimage' option - for example:
        !            12: 
        !            13: bochs -q 'floppya: 1_44=myfdimage.img' 'romimage: file=out/bios.bin'
        !            14: 
        !            15: To test under qemu, one will need to create a directory with all the
        !            16: bios images and then overwrite the main bios image.  For example:
        !            17: 
        !            18: cp /usr/share/qemu/*.bin mybiosdir/
        !            19: cp out/bios.bin mybiosdir/
        !            20: 
        !            21: Once this is setup, one can instruct qemu to use the newly created
        !            22: directory for rom images.  For example:
        !            23: 
        !            24: qemu -L mybiosdir/ -fda myfdimage.img
        !            25: 
        !            26: 
        !            27: The following payloads have been tested:
        !            28: 
        !            29: Freedos - see http://www.freedos.org/ .  Useful tests include: booting
        !            30: from installation cdrom, installing to hard drive and floppy, making
        !            31: sure hard drive and floppy boots then work.  It is also useful to take
        !            32: the bootable floppy and hard-drive images, write them to an el-torito
        !            33: bootable cdrom using the Linux mkisofs utility, and then boot those
        !            34: cdrom images.
        !            35: 
        !            36: Linux - useful hard drive image available from
        !            37: http://fabrice.bellard.free.fr/qemu/linux-0.2.img.bz2 .  It is also
        !            38: useful to test standard distribution bootup and live cdroms.
        !            39: 
        !            40: NetBSD - useful hard drive image available from
        !            41: http://nopid.free.fr/small.ffs.bz2 .  It is also useful to test
        !            42: standard distribution installation cdroms.
        !            43: 
        !            44: 
        !            45: Overview of files:
        !            46: 
        !            47: The src/ directory contains the bios source code.  Several of the
        !            48: files are compiled twice - once for 16bit mode and once for 32bit
        !            49: mode.  (The build system will remove code that is not needed for a
        !            50: particular mode.)
        !            51: 
        !            52: The tools/ directory contains helper utilities for manipulating and
        !            53: building the final rom.
        !            54: 
        !            55: The out/ directory is created by the build process - it contains all
        !            56: temporary and final files.
        !            57: 
        !            58: 
        !            59: Build overview:
        !            60: 
        !            61: The 16bit code is compiled via gcc to assembler (file out/ccode.16.s).
        !            62: The gcc "-fwhole-program" and "-ffunction-sections -fdata-sections"
        !            63: options are used to optimize the process so that gcc can efficiently
        !            64: compile and discard unneeded code.  (In the code, one can use the
        !            65: macros 'VISIBLE16' and 'VISIBLE32' to instruct a symbol to be
        !            66: outputted in 16bit and 32bit mode respectively.)
        !            67: 
        !            68: This resulting assembler code is pulled into romlayout.S.  The gas
        !            69: option ".code16gcc" is used prior to including the gcc generated
        !            70: assembler - this option enables gcc to generate valid 16 bit code.
        !            71: 
        !            72: The post code (post.c) is entered, via the function _start(), in 32bit
        !            73: mode.  The 16bit post vector (in romlayout.S) transitions the cpu into
        !            74: 32 bit mode before calling the post.c code.
        !            75: 
        !            76: In the last step of compilation, the 32 bit code is merged into the 16
        !            77: bit code so that one binary file contains both.  Currently, both 16bit
        !            78: and 32bit code will be located in the 64K block at segment 0xf000.
        !            79: 
        !            80: 
        !            81: GCC 16 bit limitations:
        !            82: 
        !            83: Although the 16bit code is compiled with gcc, developers need to be
        !            84: aware of the environment.  In particular, global variables _must_ be
        !            85: treated specially.
        !            86: 
        !            87: The code has full access to stack variables and general purpose
        !            88: registers.  The entry code in romlayout.S will push the original
        !            89: registers on the stack before calling the C code and then pop them off
        !            90: (including any required changes) before returning from the interrupt.
        !            91: Changes to CS, DS, and ES segment registers in C code is also safe.
        !            92: Changes to other segment registers (SS, FS, GS) need to be restored
        !            93: manually.
        !            94: 
        !            95: Stack variables (and pointers to stack variables) work as they
        !            96: normally do in standard C code.
        !            97: 
        !            98: However, variables stored outside the stack need to be accessed via
        !            99: the GET_VAR and SET_VAR macros (or one of the helper macros described
        !           100: below).  This is due to the 16bit segment nature of the X86 cpu when
        !           101: it is in "real mode".  The C entry code will set DS and SS to point to
        !           102: the stack segment.  Variables not on the stack need to be accessed via
        !           103: an explicit segment register.  Any other access requires altering one
        !           104: of the other segment registers (usually ES) and then accessing the
        !           105: variable via that segment register.
        !           106: 
        !           107: There are three low-level ways to access a remote variable:
        !           108: GET/SET_VAR, GET/SET_FARVAR, and GET/SET_FLATPTR.  The first set takes
        !           109: an explicit segment descriptor (eg, "CS") and offset.  The second set
        !           110: will take a segment id and offset, set ES to the segment id, and then
        !           111: make the access via the ES segment.  The last method is similar to the
        !           112: second, except it takes a pointer that would be valid in 32-bit flat
        !           113: mode instead of a segment/offset pair.
        !           114: 
        !           115: Most BIOS variables are stored in global variables, the "BDA", or
        !           116: "EBDA" memory areas.  Because this is common, three sets of helper
        !           117: macros (GET/SET_GLOBAL, GET/SET_BDA, and GET/SET_EBDA) are available
        !           118: to simplify these accesses.
        !           119: 
        !           120: Global variables defined in the C code can be read in 16bit mode if
        !           121: the variable declaration is marked with VAR16, VAR16VISIBLE,
        !           122: VAR16EXPORT, or VAR16FIXED.  The GET_GLOBAL macro will then allow read
        !           123: access to the variable.  Global variables are stored in the 0xf000
        !           124: segment, and their values are persistent across soft resets.  Because
        !           125: the f-segment is marked read-only during run-time, the 16bit code is
        !           126: not permitted to change the value of 16bit variables (use of the
        !           127: SET_GLOBAL macro from 16bit mode will cause a link error).  Code
        !           128: running in 32bit mode can not access variables with VAR16, but can
        !           129: access variables marked with VAR16VISIBLE, VAR16EXPORT, VAR16FIXED, or
        !           130: with no marking at all.  The 32bit code can use the GET/SET_GLOBAL
        !           131: macros, but they are not required.
        !           132: 
        !           133: 
        !           134: GCC 16 bit stack limitations:
        !           135: 
        !           136: Another limitation of gcc is its use of 32-bit temporaries.  Gcc will
        !           137: allocate 32-bits of space for every variable - even if that variable
        !           138: is only defined as a 'u8' or 'u16'.  If one is not careful, using too
        !           139: much stack space can break old DOS applications.
        !           140: 
        !           141: There does not appear to be explicit documentation on the minimum
        !           142: stack space available for bios calls.  However, Freedos has been
        !           143: observed to call into the bios with less than 150 bytes available.
        !           144: 
        !           145: Note that the post code and boot code (irq 18/19) do not have a stack
        !           146: limitation because the entry points for these functions transition the
        !           147: cpu to 32bit mode and reset the stack to a known state.  Only the
        !           148: general purpose 16-bit service entry points are affected.
        !           149: 
        !           150: There are some ways to reduce stack usage: making sure functions are
        !           151: tail-recursive often helps, reducing the number of parameters passed
        !           152: to functions often helps, sometimes reordering variable declarations
        !           153: helps, inlining of functions can sometimes help, and passing of packed
        !           154: structures can also help.  It is also possible to transition to/from
        !           155: an extra stack stored in the EBDA using the stack_hop helper function.
        !           156: 
        !           157: Some useful stats: the overhead for the entry to a bios handler that
        !           158: takes a 'struct bregs' is 42 bytes of stack space (6 bytes from
        !           159: interrupt insn, 32 bytes to store registers, and 4 bytes for call
        !           160: insn).  An entry to an ISR handler without args takes 30 bytes (6 + 20
        !           161: + 4).
        !           162: 
        !           163: 
        !           164: Debugging the bios:
        !           165: 
        !           166: The bios will output information messages to a special debug port.
        !           167: Under qemu, one can view these messages by enabling the '#define
        !           168: DEBUG_BIOS' definition in 'qemu/hw/pc.c'.  Once this is done (and qemu
        !           169: is recompiled), one should see status messages on the console.
        !           170: 
        !           171: The gdb-server mechanism of qemu is also useful.  One can use gdb with
        !           172: qemu to debug system images.  To use this, add '-s -S' to the qemu
        !           173: command line.  For example:
        !           174: 
        !           175: qemu -L mybiosdir/ -fda myfdimage.img -s -S
        !           176: 
        !           177: Then, in another session, run gdb with either out/rom16.o (to debug
        !           178: bios 16bit code) or out/rom32.o (to debug bios 32bit code).  For
        !           179: example:
        !           180: 
        !           181: gdb out/rom16.o
        !           182: 
        !           183: Once in gdb, use the command "target remote localhost:1234" to have
        !           184: gdb connect to qemu.  See the qemu documentation for more information
        !           185: on using gdb and qemu in this mode.  Note that gdb seems to get
        !           186: breakpoints confused when the cpu is in 16-bit real mode.  This makes
        !           187: stepping through the program difficult (though 'step instruction'
        !           188: still works).  Also, one may need to set 16bit break points at both
        !           189: the cpu address and memory address (eg, break *0x1234 ; break
        !           190: *0xf1234).

unix.superglobalmegacorp.com

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