blob: 1e61e2f32c68e48f43736ab74213f5c951a06fb2 [file] [log] [blame]
Kevin O'Connorf076a3e2008-02-25 22:25:15 -05001This code implements an X86 legacy bios. It is intended to be
2compiled using standard gnu tools (eg, gas and gcc).
Kevin O'Connor8744e152013-10-14 21:52:28 -04004To build for QEMU, one should be able to run "make" in the main
5directory. The resulting file "out/bios.bin" contains the processed
6bios image. To build for coreboot, please see the coreboot wiki. To
7build for CSM, please see README.CSM.
Kevin O'Connorf076a3e2008-02-25 22:25:15 -05008
Kevin O'Connor838f08f2008-03-30 11:07:42 -04009
10Testing of images:
12To test the bios under bochs, one will need to instruct bochs to use
13the new bios image. Use the 'romimage' option - for example:
Kevin O'Connor59fead62008-05-10 15:49:20 -040015bochs -q 'floppya: 1_44=myfdimage.img' 'romimage: file=out/bios.bin'
Kevin O'Connor838f08f2008-03-30 11:07:42 -040016
17To test under qemu, one will need to create a directory with all the
18bios images and then overwrite the main bios image. For example:
20cp /usr/share/qemu/*.bin mybiosdir/
Kevin O'Connor59fead62008-05-10 15:49:20 -040021cp out/bios.bin mybiosdir/
Kevin O'Connorac467be2013-03-17 10:29:06 -040022cp out/*.aml mybiosdir/
Kevin O'Connor838f08f2008-03-30 11:07:42 -040023
24Once this is setup, one can instruct qemu to use the newly created
25directory for rom images. For example:
27qemu -L mybiosdir/ -fda myfdimage.img
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050030Overview of files:
Kevin O'Connor838f08f2008-03-30 11:07:42 -040032The src/ directory contains the bios source code. Several of the
33files are compiled twice - once for 16bit mode and once for 32bit
Kevin O'Connor0942e7f2009-06-15 22:27:01 -040034mode. (The build system will remove code that is not needed for a
35particular mode.)
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050036
Kevin O'Connor1c787112013-09-13 16:29:11 -040037The vgasrc/ directory contains code for VGA BIOS implementations.
38This code is separate from the main BIOS code in the src/ directory.
39It produces a VGA BIOS rom in out/vgabios.bin. The VGA BIOS code is
40always compiled in 16bit mode.
42The scripts/ directory contains helper utilities for manipulating and
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050043building the final rom.
45The out/ directory is created by the build process - it contains all
46temporary and final files.
49Build overview:
Kevin O'Connor0afee522009-02-05 20:32:41 -050051The 16bit code is compiled via gcc to assembler (file out/ccode.16.s).
Kevin O'Connor0942e7f2009-06-15 22:27:01 -040052The gcc "-fwhole-program" and "-ffunction-sections -fdata-sections"
53options are used to optimize the process so that gcc can efficiently
54compile and discard unneeded code. (In the code, one can use the
Kevin O'Connor0fdf1932011-10-04 21:12:28 -040055macros 'VISIBLE16' and 'VISIBLE32FLAT' to instruct a symbol to be
Kevin O'Connor0942e7f2009-06-15 22:27:01 -040056outputted in 16bit and 32bit mode respectively.)
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050057
58This resulting assembler code is pulled into romlayout.S. The gas
59option ".code16gcc" is used prior to including the gcc generated
Kevin O'Connor838f08f2008-03-30 11:07:42 -040060assembler - this option enables gcc to generate valid 16 bit code.
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050061
Kevin O'Connor0fdf1932011-10-04 21:12:28 -040062The post code (post.c) is entered, via the function handle_post(), in
6332bit mode. The 16bit post vector (in romlayout.S) transitions the
64cpu into 32 bit mode before calling the post.c code.
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050065
Kevin O'Connor838f08f2008-03-30 11:07:42 -040066In the last step of compilation, the 32 bit code is merged into the 16
67bit code so that one binary file contains both. Currently, both 16bit
Kevin O'Connor0fdf1932011-10-04 21:12:28 -040068and 32bit code will be located in the memory at 0xe0000-0xfffff.
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050069
71GCC 16 bit limitations:
73Although the 16bit code is compiled with gcc, developers need to be
74aware of the environment. In particular, global variables _must_ be
75treated specially.
77The code has full access to stack variables and general purpose
78registers. The entry code in romlayout.S will push the original
79registers on the stack before calling the C code and then pop them off
80(including any required changes) before returning from the interrupt.
81Changes to CS, DS, and ES segment registers in C code is also safe.
82Changes to other segment registers (SS, FS, GS) need to be restored
85Stack variables (and pointers to stack variables) work as they
86normally do in standard C code.
88However, variables stored outside the stack need to be accessed via
Kevin O'Connor838f08f2008-03-30 11:07:42 -040089the GET_VAR and SET_VAR macros (or one of the helper macros described
90below). This is due to the 16bit segment nature of the X86 cpu when
91it is in "real mode". The C entry code will set DS and SS to point to
92the stack segment. Variables not on the stack need to be accessed via
Kevin O'Connor0afee522009-02-05 20:32:41 -050093an explicit segment register. Any other access requires altering one
94of the other segment registers (usually ES) and then accessing the
95variable via that segment register.
Kevin O'Connor838f08f2008-03-30 11:07:42 -040096
97There are three low-level ways to access a remote variable:
Kevin O'Connor0afee522009-02-05 20:32:41 -050098GET/SET_VAR, GET/SET_FARVAR, and GET/SET_FLATPTR. The first set takes
Kevin O'Connor838f08f2008-03-30 11:07:42 -040099an explicit segment descriptor (eg, "CS") and offset. The second set
Kevin O'Connor0afee522009-02-05 20:32:41 -0500100will take a segment id and offset, set ES to the segment id, and then
Kevin O'Connor838f08f2008-03-30 11:07:42 -0400101make the access via the ES segment. The last method is similar to the
Kevin O'Connor0afee522009-02-05 20:32:41 -0500102second, except it takes a pointer that would be valid in 32-bit flat
103mode instead of a segment/offset pair.
Kevin O'Connor838f08f2008-03-30 11:07:42 -0400104
Kevin O'Connor0afee522009-02-05 20:32:41 -0500105Most BIOS variables are stored in global variables, the "BDA", or
106"EBDA" memory areas. Because this is common, three sets of helper
Kevin O'Connorc21dce32013-10-26 11:56:24 -0400107macros (GET_GLOBAL, GET/SET_BDA, and GET/SET_EBDA) are available to
108simplify these accesses. Also, an area in the 0xc0000-0xf0000 memory
109range is made available for internal BIOS run-time variables that are
110marked with the VARLOW attribute. These variables can then be
111accessed with the GET/SET_LOW macros.
Kevin O'Connor0afee522009-02-05 20:32:41 -0500112
113Global variables defined in the C code can be read in 16bit mode if
Kevin O'Connor14b255b2013-07-14 14:40:19 -0400114the variable declaration is marked with VAR16, VARFSEG, or VAR16FIXED.
115The GET_GLOBAL macro will then allow read access to the variable.
116Global variables are stored in the 0xf000 segment. Because the
117f-segment is marked read-only during run-time, the 16bit code is not
Kevin O'Connorc21dce32013-10-26 11:56:24 -0400118permitted to change the value of 16bit variables. Code running in
11932bit mode can not access variables with VAR16, but can access
120variables marked with VARFSEG, VARLOW, VAR16FIXED, or with no marking
121at all. The 32bit code can use the GET_GLOBAL macros, but they are
122not required.
Kevin O'Connor838f08f2008-03-30 11:07:42 -0400123
125GCC 16 bit stack limitations:
127Another limitation of gcc is its use of 32-bit temporaries. Gcc will
128allocate 32-bits of space for every variable - even if that variable
129is only defined as a 'u8' or 'u16'. If one is not careful, using too
130much stack space can break old DOS applications.
132There does not appear to be explicit documentation on the minimum
133stack space available for bios calls. However, Freedos has been
Kevin O'Connor0bb2a442008-04-01 21:09:05 -0400134observed to call into the bios with less than 150 bytes available.
Kevin O'Connor838f08f2008-03-30 11:07:42 -0400135
136Note that the post code and boot code (irq 18/19) do not have a stack
Kevin O'Connor0afee522009-02-05 20:32:41 -0500137limitation because the entry points for these functions transition the
138cpu to 32bit mode and reset the stack to a known state. Only the
139general purpose 16-bit service entry points are affected.
Kevin O'Connor838f08f2008-03-30 11:07:42 -0400140
141There are some ways to reduce stack usage: making sure functions are
142tail-recursive often helps, reducing the number of parameters passed
143to functions often helps, sometimes reordering variable declarations
144helps, inlining of functions can sometimes help, and passing of packed
Kevin O'Connor0afee522009-02-05 20:32:41 -0500145structures can also help. It is also possible to transition to/from
146an extra stack stored in the EBDA using the stack_hop helper function.
Kevin O'Connor838f08f2008-03-30 11:07:42 -0400147
Kevin O'Connor0bb2a442008-04-01 21:09:05 -0400148Some useful stats: the overhead for the entry to a bios handler that
Kevin O'Connor0942e7f2009-06-15 22:27:01 -0400149takes a 'struct bregs' is 42 bytes of stack space (6 bytes from
150interrupt insn, 32 bytes to store registers, and 4 bytes for call
Kevin O'Connor0bb2a442008-04-01 21:09:05 -0400151insn). An entry to an ISR handler without args takes 30 bytes (6 + 20
152+ 4).
Kevin O'Connor838f08f2008-03-30 11:07:42 -0400154
155Debugging the bios:
157The bios will output information messages to a special debug port.
Kevin O'Connor0fdf1932011-10-04 21:12:28 -0400158Under qemu, one can view these messages by adding '-chardev
159stdio,id=seabios -device isa-debugcon,iobase=0x402,chardev=seabios' to
160the qemu command line. Once this is done, one should see status
161messages on the console.
Kevin O'Connor838f08f2008-03-30 11:07:42 -0400162
163The gdb-server mechanism of qemu is also useful. One can use gdb with
164qemu to debug system images. To use this, add '-s -S' to the qemu
165command line. For example:
167qemu -L mybiosdir/ -fda myfdimage.img -s -S
169Then, in another session, run gdb with either out/rom16.o (to debug
170bios 16bit code) or out/rom32.o (to debug bios 32bit code). For
173gdb out/rom16.o
175Once in gdb, use the command "target remote localhost:1234" to have
176gdb connect to qemu. See the qemu documentation for more information
177on using gdb and qemu in this mode. Note that gdb seems to get
178breakpoints confused when the cpu is in 16-bit real mode. This makes
179stepping through the program difficult (though 'step instruction'
180still works). Also, one may need to set 16bit break points at both
181the cpu address and memory address (eg, break *0x1234 ; break