Update README file with more information on using the bios. master origin/HEAD origin/master rel-0.2.0
authorKevin O'Connor <kevin@koconnor.net>
Sun, 30 Mar 2008 15:07:42 +0000 (11:07 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Sun, 30 Mar 2008 15:07:42 +0000 (11:07 -0400)
README

diff --git a/README b/README
index ce80499..0ca5f1b 100644 (file)
--- a/README
+++ b/README
@@ -4,16 +4,57 @@ compiled using standard gnu tools (eg, gas and gcc).
 To build, one should be able to run "make" in the main directory.  The
 resulting file "out/rom.bin" contains the processed bios image.
 
 To build, one should be able to run "make" in the main directory.  The
 resulting file "out/rom.bin" contains the processed bios image.
 
-The code has been successfully compiled with gcc 4.1.2 and gas
-2.17.50.0.18.
+The build requires gcc v4.1 or later.  Some buggy versions of gcc have
+issues with the '-combine' compiler option - in particular, recent
+versions of Ubuntu are affected.  One can use "make AVOIDCOMBINE=1" to
+get around this.
+
+
+Testing of images:
+
+To test the bios under bochs, one will need to instruct bochs to use
+the new bios image.  Use the 'romimage' option - for example:
+
+bochs -q 'floppya: 1_44=myfdimage.img' 'romimage: file=out/rom.bin'
+
+To test under qemu, one will need to create a directory with all the
+bios images and then overwrite the main bios image.  For example:
+
+cp /usr/share/qemu/*.bin mybiosdir/
+cp out/rom.bin mybiosdir/bios.bin
+
+Once this is setup, one can instruct qemu to use the newly created
+directory for rom images.  For example:
+
+qemu -L mybiosdir/ -fda myfdimage.img
+
+
+The following payloads have been tested:
+
+Freedos - see http://www.freedos.org/ .  Useful tests include: booting
+from installation cdrom, installing to hard drive and floppy, making
+sure hard drive and floppy boots then work.  It is also useful to take
+the bootable floppy and hard-drive images, write them to an el-torito
+bootable cdrom using the Linux mkisofs utility, and then boot those
+cdrom images.
+
+Linux - useful hard drive image available from
+http://fabrice.bellard.free.fr/qemu/linux-0.2.img.bz2 .  It is also
+useful to test standard distribution bootup and live cdroms.
+
+NetBSD - useful hard drive image available from
+http://nopid.free.fr/small.ffs.bz2 .  It is also useful to test
+standard distribution installation cdroms.
 
 
 Overview of files:
 
 
 
 Overview of files:
 
-The src/ directory contains the bios source code.  The post.c code is
-compiled in 32bit mode.  The output.c code is compiled twice - once in
-16bit mode and once in 32bit mode.  The remaining c files are compiled
-in 16bit mode.
+The src/ directory contains the bios source code.  Several of the
+files are compiled twice - once for 16bit mode and once for 32bit
+mode.  The gcc compile option '-fwhole-program' is used to remove code
+that is not needed for a particular mode.  (In the code, one can use
+the macros 'VISIBLE16' and 'VISIBLE32' to instruct a symbol to be
+outputted in 16bit and 32bit mode respectively.)
 
 The tools/ directory contains helper utilities for manipulating and
 building the final rom.
 
 The tools/ directory contains helper utilities for manipulating and
 building the final rom.
@@ -30,17 +71,17 @@ that gcc can efficiently compile and discard unneeded code.
 
 This resulting assembler code is pulled into romlayout.S.  The gas
 option ".code16gcc" is used prior to including the gcc generated
 
 This resulting assembler code is pulled into romlayout.S.  The gas
 option ".code16gcc" is used prior to including the gcc generated
-assembler - this option enables gcc to be used to generate valid 16
-bit code.  The romlayout.S also defines all the mandatory bios visible
-memory locations.
+assembler - this option enables gcc to generate valid 16 bit code.
+The romlayout.S also defines all the mandatory bios visible memory
+locations.
 
 
-The post code (post.c) is written in 32bits.  The 16bit post vector
-(in romlayout.S) transitions the cpu into 32 bit mode before calling
-the initialization code in post.c.
+The post code (post.c) is entered, via the function _start(), in 32bit
+mode.  The 16bit post vector (in romlayout.S) transitions the cpu into
+32 bit mode before calling the post.c code.
 
 
-In the last step, the compiled 32 bit code is merged into the 16 bit
-code so that one binary file contains both.  Currently, both 16bit and
-32bit code will be located in the 64K block at segment 0xf000.
+In the last step of compilation, the 32 bit code is merged into the 16
+bit code so that one binary file contains both.  Currently, both 16bit
+and 32bit code will be located in the 64K block at segment 0xf000.
 
 
 GCC 16 bit limitations:
 
 
 GCC 16 bit limitations:
@@ -61,11 +102,76 @@ Stack variables (and pointers to stack variables) work as they
 normally do in standard C code.
 
 However, variables stored outside the stack need to be accessed via
 normally do in standard C code.
 
 However, variables stored outside the stack need to be accessed via
-the GET_VAR and SET_VAR macros.  This is due to the 16bit segment
-nature of the X86 cpu when it is in "real mode".  The C entry code
-will set DS and SS to point to the stack segment.  Variables not on
-the stack need to be accessed via an explicit segment register.
-Global constant definitions (those in 0xf000) can be accessed via the
-CS segment register.  Any other access requires altering one of the
-other segment registers (usually ES) and then accessing the variable
-via that segment register.
+the GET_VAR and SET_VAR macros (or one of the helper macros described
+below).  This is due to the 16bit segment nature of the X86 cpu when
+it is in "real mode".  The C entry code will set DS and SS to point to
+the stack segment.  Variables not on the stack need to be accessed via
+an explicit segment register.  Global constants (loaded into 0xf000)
+can be accessed via the CS segment register.  Any other access
+requires altering one of the other segment registers (usually ES) and
+then accessing the variable via that segment register.
+
+There are three low-level ways to access a remote variable:
+GET/SET_VAR, GET/SET_FARVAR, and GET/SET_FARPTR.  The first set takes
+an explicit segment descriptor (eg, "CS") and offset.  The second set
+will take a segment id and offset, set ES to the segment, and then
+make the access via the ES segment.  The last method is similar to the
+second, except it takes a pointer that would be valid in 32-bit mode
+instead of a segment/offset pair.
+
+Most BIOS variables are stored in the "BDA" or "EBDA" memory areas.
+Because this is common, two sets of helper macros (GET/SET_BDA and
+GET/SET_EBDA) are available to simplify these accesses.
+
+
+GCC 16 bit stack limitations:
+
+Another limitation of gcc is its use of 32-bit temporaries.  Gcc will
+allocate 32-bits of space for every variable - even if that variable
+is only defined as a 'u8' or 'u16'.  If one is not careful, using too
+much stack space can break old DOS applications.
+
+There does not appear to be explicit documentation on the minimum
+stack space available for bios calls.  However, Freedos has been
+observed to call into the bios with less than 150 bytes of stack space
+available.
+
+Note that the post code and boot code (irq 18/19) do not have a stack
+limitation because the entry points for these functions reset the
+stack to a known state.  Only the general purpose 16-bit service entry
+points are affected.
+
+There are some ways to reduce stack usage: making sure functions are
+tail-recursive often helps, reducing the number of parameters passed
+to functions often helps, sometimes reordering variable declarations
+helps, inlining of functions can sometimes help, and passing of packed
+structures can also help.
+
+
+Debugging the bios:
+
+The bios will output information messages to a special debug port.
+Under qemu, one can view these messages by enabling the '#define
+DEBUG_BIOS' definition in 'qemu/hw/pc.c'.  Once this is done (and qemu
+is recompiled), one should see status messages on the console.
+
+The gdb-server mechanism of qemu is also useful.  One can use gdb with
+qemu to debug system images.  To use this, add '-s -S' to the qemu
+command line.  For example:
+
+qemu -L mybiosdir/ -fda myfdimage.img -s -S
+
+Then, in another session, run gdb with either out/rom16.o (to debug
+bios 16bit code) or out/rom32.o (to debug bios 32bit code).  For
+example:
+
+gdb out/rom16.o
+
+Once in gdb, use the command "target remote localhost:1234" to have
+gdb connect to qemu.  See the qemu documentation for more information
+on using gdb and qemu in this mode.  Note that gdb seems to get
+breakpoints confused when the cpu is in 16-bit real mode.  This makes
+stepping through the program difficult (though 'step instruction'
+still works).  Also, one may need to set 16bit break points at both
+the cpu address and memory address (eg, break *0x1234 ; break
+*0xf1234).