blob: ce80499f93c37e9ec9f35fa937f1ea8cb340700c [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).
3
4To build, one should be able to run "make" in the main directory. The
5resulting file "out/rom.bin" contains the processed bios image.
6
7The code has been successfully compiled with gcc 4.1.2 and gas
82.17.50.0.18.
9
10
11Overview of files:
12
13The src/ directory contains the bios source code. The post.c code is
14compiled in 32bit mode. The output.c code is compiled twice - once in
1516bit mode and once in 32bit mode. The remaining c files are compiled
16in 16bit mode.
17
18The tools/ directory contains helper utilities for manipulating and
19building the final rom.
20
21The out/ directory is created by the build process - it contains all
22temporary and final files.
23
24
25Build overview:
26
27The 16bit code is compiled via gcc to assembler (file out/blob.16.s).
28The gcc "-fwhole-program" option is used to optimize the process so
29that gcc can efficiently compile and discard unneeded code.
30
31This resulting assembler code is pulled into romlayout.S. The gas
32option ".code16gcc" is used prior to including the gcc generated
33assembler - this option enables gcc to be used to generate valid 16
34bit code. The romlayout.S also defines all the mandatory bios visible
35memory locations.
36
37The post code (post.c) is written in 32bits. The 16bit post vector
38(in romlayout.S) transitions the cpu into 32 bit mode before calling
39the initialization code in post.c.
40
41In the last step, the compiled 32 bit code is merged into the 16 bit
42code so that one binary file contains both. Currently, both 16bit and
4332bit code will be located in the 64K block at segment 0xf000.
44
45
46GCC 16 bit limitations:
47
48Although the 16bit code is compiled with gcc, developers need to be
49aware of the environment. In particular, global variables _must_ be
50treated specially.
51
52The code has full access to stack variables and general purpose
53registers. The entry code in romlayout.S will push the original
54registers on the stack before calling the C code and then pop them off
55(including any required changes) before returning from the interrupt.
56Changes to CS, DS, and ES segment registers in C code is also safe.
57Changes to other segment registers (SS, FS, GS) need to be restored
58manually.
59
60Stack variables (and pointers to stack variables) work as they
61normally do in standard C code.
62
63However, variables stored outside the stack need to be accessed via
64the GET_VAR and SET_VAR macros. This is due to the 16bit segment
65nature of the X86 cpu when it is in "real mode". The C entry code
66will set DS and SS to point to the stack segment. Variables not on
67the stack need to be accessed via an explicit segment register.
68Global constant definitions (those in 0xf000) can be accessed via the
69CS segment register. Any other access requires altering one of the
70other segment registers (usually ES) and then accessing the variable
71via that segment register.