Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit f076a3e
Showing
27 changed files
with
3,974 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
# Legacy Bios build system | ||
# | ||
# Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net> | ||
# | ||
# This file may be distributed under the terms of the GNU GPLv3 license. | ||
|
||
# Output directory | ||
OUT=out/ | ||
|
||
# Source files | ||
SRC16=floppy.c disk.c system.c clock.c serial.c kbd.c output.c boot.c | ||
SRC32=post.c output.c | ||
|
||
# Default compiler flags (note -march=armv4 is needed for 16 bit insns) | ||
CFLAGS = -Wall -Os -MD -m32 -march=i386 -mregparm=2 -ffreestanding | ||
CFLAGS16 = -Wall -Os -MD -m32 -DMODE16 -march=i386 -mregparm=2 -ffreestanding -fno-jump-tables | ||
|
||
all: $(OUT) $(OUT)rom.bin | ||
|
||
# Run with "make V=1" to see the actual compile commands | ||
ifdef V | ||
Q= | ||
else | ||
Q=@ | ||
endif | ||
|
||
.PHONY : all FORCE | ||
|
||
vpath %.c src | ||
vpath %.S src | ||
|
||
################ Build rules | ||
$(OUT)%.proc.16.s: $(OUT)%.16.s | ||
@echo " Moving data sections to text in $<" | ||
$(Q)sed 's/\t.section\t.rodata.*// ; s/\t.data//' < $< > $@ | ||
|
||
$(OUT)%.16.s: %.c | ||
@echo " Generating assembler for $<" | ||
$(Q)$(CC) $(CFLAGS16) -fwhole-program -S -combine -c $< -o $@ | ||
|
||
$(OUT)%.lds: %.lds.S | ||
@echo " Precompiling $<" | ||
$(Q)$(CPP) -P $< -o $@ | ||
|
||
$(OUT)%.bin: $(OUT)%.o | ||
@echo " Extracting binary $@" | ||
$(Q)objcopy -O binary $< $@ | ||
|
||
$(OUT)%.offset.auto.h: $(OUT)%.o | ||
@echo " Generating symbol offset header $@" | ||
$(Q)nm $< | ./tools/defsyms.py > $@ | ||
|
||
$(OUT)blob.16.s: | ||
@echo " Generating whole program assembler $@" | ||
$(Q)$(CC) $(CFLAGS16) -fwhole-program -S -combine -c $(addprefix src/, $(SRC16)) -o $@ | ||
|
||
$(OUT)romlayout16.o: romlayout.S $(OUT)blob.proc.16.s $(OUT)font.proc.16.s $(OUT)cbt.proc.16.s | ||
@echo " Generating 16bit layout of $@" | ||
$(Q)$(CC) $(CFLAGS16) -c $< -o $@ | ||
|
||
$(OUT)rom16.o: $(OUT)romlayout16.o | ||
@echo " Linking $@" | ||
$(Q)ld -melf_i386 -Ttext 0 $< -o $@ | ||
|
||
$(OUT)rom16.bin: $(OUT)rom16.o | ||
@echo " Extracting binary $@" | ||
$(Q)objcopy -O binary $< $@ | ||
|
||
$(OUT)romlayout32.o: $(OUT)rom16.offset.auto.h | ||
@echo " Compiling whole program $@" | ||
$(Q)$(CC) $(CFLAGS) -fwhole-program -combine -c $(addprefix src/, $(SRC32)) -o $@ | ||
|
||
$(OUT)rom32.o: $(OUT)romlayout32.o $(OUT)rombios32.lds | ||
@echo " Linking $@" | ||
$(Q)ld -T $(OUT)rombios32.lds $< -o $@ | ||
|
||
$(OUT)rom.bin: $(OUT)rom16.bin $(OUT)rom32.bin $(OUT)rom16.offset.auto.h $(OUT)rom32.offset.auto.h | ||
@echo " Building $@" | ||
$(Q)./tools/buildrom.py | ||
|
||
####### Generic rules | ||
clean: | ||
rm -rf $(OUT) | ||
|
||
$(OUT): | ||
mkdir $@ | ||
|
||
-include $(OUT)*.d |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
This code implements an X86 legacy bios. It is intended to be | ||
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. | ||
|
||
The code has been successfully compiled with gcc 4.1.2 and gas | ||
2.17.50.0.18. | ||
|
||
|
||
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 tools/ directory contains helper utilities for manipulating and | ||
building the final rom. | ||
|
||
The out/ directory is created by the build process - it contains all | ||
temporary and final files. | ||
|
||
|
||
Build overview: | ||
|
||
The 16bit code is compiled via gcc to assembler (file out/blob.16.s). | ||
The gcc "-fwhole-program" option is used to optimize the process so | ||
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 | ||
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. | ||
|
||
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. | ||
|
||
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. | ||
|
||
|
||
GCC 16 bit limitations: | ||
|
||
Although the 16bit code is compiled with gcc, developers need to be | ||
aware of the environment. In particular, global variables _must_ be | ||
treated specially. | ||
|
||
The code has full access to stack variables and general purpose | ||
registers. The entry code in romlayout.S will push the original | ||
registers on the stack before calling the C code and then pop them off | ||
(including any required changes) before returning from the interrupt. | ||
Changes to CS, DS, and ES segment registers in C code is also safe. | ||
Changes to other segment registers (SS, FS, GS) need to be restored | ||
manually. | ||
|
||
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 | ||
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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
Make header files work with either 32bit or 16bit code. | ||
|
||
Fix makefiles so that they rebuild the required files automatically. | ||
|
||
Make sure gdt/idt tables are properly aligned | ||
|
||
Cleanup setting of ES on GET/SET_BDA | ||
|
||
Make sure inline assembly isn't preventing inlining of calling | ||
functions. | ||
|
||
Convert remaining parts of rombios.c to new code. | ||
|
||
Convert rombios32 and apm bios stuff to new code. | ||
|
||
Allow one to select adding 32 bit code to 0xf000 or in a separate | ||
location. | ||
|
||
Try generating bios tables at compile time. | ||
|
||
Move e820 map generation to post time (just have e820 code copy pre | ||
made tables back to user). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,184 @@ | ||
// Variable layouts of bios. | ||
// | ||
// Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net> | ||
// | ||
// This file may be distributed under the terms of the GNU GPLv3 license. | ||
|
||
#include "types.h" // u8 | ||
#include "farptr.h" // SET_SEG | ||
|
||
|
||
/**************************************************************** | ||
* Bios Data Area (BDA) | ||
****************************************************************/ | ||
|
||
struct ivec { | ||
u16 offset; | ||
u16 seg; | ||
}; | ||
|
||
struct bios_data_area_s { | ||
// 00:00 | ||
struct ivec ivecs[256]; | ||
// 30:00 | ||
// u8 stack[256]; | ||
// 40:00 | ||
u16 port_com1, port_com2, port_com3, port_com4; | ||
u16 port_lpt1, port_lpt2, port_lpt3; | ||
u16 ebda_seg; | ||
// 40:10 | ||
u16 equipment_list_flags; | ||
u8 pad1; | ||
u16 mem_size_kb; | ||
u8 pad2; | ||
u8 ps2_ctrl_flag; | ||
u16 kbd_flag; | ||
u8 alt_keypad; | ||
u16 kbd_buf_head; | ||
u16 kbd_buf_tail; | ||
// 40:1e | ||
u8 kbd_buf[32]; | ||
u8 floppy_recalibration_status; | ||
u8 floppy_motor_status; | ||
// 40:40 | ||
u8 floppy_motor_counter; | ||
u8 floppy_last_status; | ||
u8 floppy_return_status[7]; | ||
u8 other1[0x7]; | ||
// 40:50 | ||
u8 other2[0x1c]; | ||
// 40:6c | ||
u32 timer_counter; | ||
// 40:70 | ||
u8 timer_rollover; | ||
u8 other4[0x0f]; | ||
// 40:80 | ||
u16 kbd_buf_start_offset; | ||
u16 kbd_buf_end_offset; | ||
u8 other5[7]; | ||
u8 floppy_last_data_rate; | ||
u8 other6[3]; | ||
u8 floppy_harddisk_info; | ||
// 40:90 | ||
u8 floppy_media_state[4]; | ||
u8 floppy_track0; | ||
u8 floppy_track1; | ||
u8 kbd_mode; | ||
u8 kbd_led; | ||
u32 ptr_user_wait_complete_flag; | ||
u32 user_wait_timeout; | ||
// 40:A0 | ||
u8 rtc_wait_flag; | ||
} __attribute__((packed)); | ||
|
||
// BDA floppy_recalibration_status bitdefs | ||
#define FRS_TIMEOUT (1<<7) | ||
|
||
// BDA rtc_wait_flag bitdefs | ||
#define RWS_WAIT_PENDING (1<<0) | ||
#define RWS_WAIT_ELAPSED (1<<7) | ||
|
||
// BDA floppy_media_state bitdefs | ||
#define FMS_DRIVE_STATE_MASK (0x07) | ||
#define FMS_MEDIA_DRIVE_ESTABLISHED (1<<4) | ||
#define FMS_DOUBLE_STEPPING (1<<5) | ||
#define FMS_DATA_RATE_MASK (0xc0) | ||
|
||
// Accessor functions | ||
#define GET_BDA(var) ({ \ | ||
SET_SEG(ES, 0x0000); \ | ||
GET_VAR(ES, ((struct bios_data_area_s *)0)->var); }) | ||
#define SET_BDA(var, val) do { \ | ||
SET_SEG(ES, 0x0000); \ | ||
SET_VAR(ES, ((struct bios_data_area_s *)0)->var, val); \ | ||
} while (0) | ||
#define CLEARBITS_BDA(var, val) do { \ | ||
typeof(((struct bios_data_area_s *)0)->var) __val = GET_BDA(var); \ | ||
SET_BDA(var, (__val & ~(val))); \ | ||
} while (0) | ||
#define SETBITS_BDA(var, val) do { \ | ||
typeof(((struct bios_data_area_s *)0)->var) __val = GET_BDA(var); \ | ||
SET_BDA(var, (__val | (val))); \ | ||
} while (0) | ||
|
||
|
||
/**************************************************************** | ||
* Extended Bios Data Area (EBDA) | ||
****************************************************************/ | ||
|
||
struct extended_bios_data_area_s { | ||
u8 size; | ||
u8 other1[0x3c]; | ||
|
||
// FDPT - Can be splitted in data members if needed | ||
u8 fdpt0[0x10]; | ||
u8 fdpt1[0x10]; | ||
|
||
u8 other2[0xC4]; | ||
|
||
// ATA Driver data | ||
//ata_t ata; | ||
|
||
#if BX_ELTORITO_BOOT | ||
// El Torito Emulation data | ||
cdemu_t cdemu; | ||
#endif // BX_ELTORITO_BOOT | ||
}; | ||
|
||
|
||
/**************************************************************** | ||
* Extended Bios Data Area (EBDA) | ||
****************************************************************/ | ||
|
||
#define UREG(ER, R, RH, RL) union { u32 ER; struct { u16 R; u16 R ## _hi; }; struct { u8 RL; u8 RH; u8 R ## _hilo; u8 R ## _hihi; }; } | ||
|
||
struct bregs { | ||
u16 ds; | ||
u16 es; | ||
UREG(edi, di, di_hi, di_lo); | ||
UREG(esi, si, si_hi, si_lo); | ||
UREG(ebp, bp, bp_hi, bp_lo); | ||
UREG(esp, sp, sp_hi, sp_lo); | ||
UREG(ebx, bx, bh, bl); | ||
UREG(edx, dx, dh, dl); | ||
UREG(ecx, cx, ch, cl); | ||
UREG(eax, ax, ah, al); | ||
u16 ip; | ||
u16 cs; | ||
u16 flags; | ||
} __attribute__((packed)); | ||
|
||
// bregs flags bitdefs | ||
#define F_CF (1<<9) | ||
|
||
static inline void | ||
set_cf(struct bregs *regs, int cond) | ||
{ | ||
if (cond) | ||
regs->flags |= F_CF; | ||
else | ||
regs->flags &= ~F_CF; | ||
} | ||
|
||
|
||
/**************************************************************** | ||
* Bios Config Table | ||
****************************************************************/ | ||
|
||
struct bios_config_table_s { | ||
// XXX | ||
u8 x; | ||
}; | ||
|
||
extern struct bios_config_table_s BIOS_CONFIG_TABLE; | ||
|
||
|
||
/**************************************************************** | ||
* Memory layout info | ||
****************************************************************/ | ||
|
||
#define SEG_BIOS 0xf000 | ||
|
||
#define EBDA_SEG 0x9FC0 | ||
#define EBDA_SIZE 1 // In KiB | ||
#define BASE_MEM_IN_K (640 - EBDA_SIZE) |
Oops, something went wrong.