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