@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: ; $(call whole-compile, $(CFLAGS16) -S, $(addprefix src/, $(SRC16)),$@)
@echo " Generating 16bit layout of $@"
$(Q)$(CC) $(CFLAGS16) -c $< -o $@
-$(OUT)rom16.o: $(OUT)romlayout16.o $(OUT)rombios16.lds
- @echo " Linking $@"
- $(Q)ld -T $(OUT)rombios16.lds $< -o $@.16
- $(Q)objcopy --change-addresses 0xf0000 $@.16 $@
+$(OUT)romlayout32.o: ; $(call whole-compile, $(CFLAGS), $(addprefix src/, $(SRC32)),$@)
+
+$(OUT)rom32.notreloc.o: $(OUT)romlayout32.o $(OUT)rombios32.lds
+ @echo " Linking (no relocs) $@"
+ $(Q)ld -r -T $(OUT)rombios32.lds $< -o $@.raw
+ $(Q)objcopy --prefix-symbols=_code32_ $@.raw $@
-$(OUT)romlayout32.o: $(OUT)rom16.offset.auto.h ; $(call whole-compile, $(CFLAGS), $(addprefix src/, $(SRC32)),$@)
+$(OUT)rom16.o: $(OUT)romlayout16.o $(OUT)rom32.notreloc.o $(OUT)rombios16.lds
+ @echo " Linking $@"
+ $(Q)ld -T $(OUT)rombios16.lds -R $(OUT)rom32.notreloc.o $< -o $@
-$(OUT)rom32.o: $(OUT)romlayout32.o $(OUT)rombios32.lds
+$(OUT)rom32.o: $(OUT)rom16.o $(OUT)romlayout32.o $(OUT)rombios32.lds
@echo " Linking $@"
- $(Q)ld -T $(OUT)rombios32.lds $< -o $@
+ $(Q)ld -T $(OUT)rombios32.lds $(OUT)rom16.o $(OUT)romlayout32.o -o $@
+ $(Q)nm $@ | ./tools/checkrom.py
+
+$(OUT)bios.bin.elf: $(OUT)rom32.o
+ @echo " Stripping $<"
+ $(Q)strip $< -o $@
+
+$(OUT)bios.bin: $(OUT)bios.bin.elf
+ @echo " Extracting binary $@"
+ $(Q)objcopy -O binary $< $@
-$(OUT)bios.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:
void
memmap_setup()
{
- bios_table_cur_addr = OFFSET_freespace2_start;
- bios_table_end_addr = OFFSET_freespace2_end;
+ // Symbols defined in romlayout.S
+ extern char freespace2_start, freespace2_end;
+
+ bios_table_cur_addr = (u32)&freespace2_start;
+ bios_table_end_addr = (u32)&freespace2_end;
dprintf(1, "bios_table_addr: 0x%08x end=0x%08x\n",
bios_table_cur_addr, bios_table_end_addr);
}
// This file may be distributed under the terms of the GNU GPLv3 license.
#include "ioport.h" // PORT_*
-#include "../out/rom16.offset.auto.h" // OFFSET_*
#include "config.h" // CONFIG_*
#include "cmos.h" // CMOS_*
#include "util.h" // memset
#define ebda ((struct extended_bios_data_area_s *)MAKE_FARPTR(SEG_EBDA, 0))
static void
-set_irq(int vector, u32 loc)
+set_irq(int vector, void *loc)
{
SET_BDA(ivecs[vector].seg, SEG_BIOS);
- SET_BDA(ivecs[vector].offset, loc - BUILD_BIOS_ADDR);
+ SET_BDA(ivecs[vector].offset, (u32)loc - BUILD_BIOS_ADDR);
}
+// Symbols defined in romlayout.S
+extern void dummy_iret_handler();
+extern void entry_08();
+extern void entry_09();
+extern void entry_hwirq();
+extern void entry_0e();
+extern void entry_10();
+extern void entry_11();
+extern void entry_12();
+extern void entry_13();
+extern void entry_14();
+extern void entry_15();
+extern void entry_16();
+extern void entry_17();
+extern void entry_18();
+extern void entry_19();
+extern void entry_1a();
+extern void entry_1c();
+extern void entry_40();
+extern void entry_70();
+extern void entry_74();
+extern void entry_75();
+extern void entry_76();
+
static void
init_bda()
{
int i;
for (i=0; i<256; i++)
- set_irq(i, OFFSET_dummy_iret_handler);
-
- set_irq(0x08, OFFSET_entry_08);
- set_irq(0x09, OFFSET_entry_09);
- //set_irq(0x0a, OFFSET_entry_hwirq);
- //set_irq(0x0b, OFFSET_entry_hwirq);
- //set_irq(0x0c, OFFSET_entry_hwirq);
- //set_irq(0x0d, OFFSET_entry_hwirq);
- set_irq(0x0e, OFFSET_entry_0e);
- //set_irq(0x0f, OFFSET_entry_hwirq);
- set_irq(0x10, OFFSET_entry_10);
- set_irq(0x11, OFFSET_entry_11);
- set_irq(0x12, OFFSET_entry_12);
- set_irq(0x13, OFFSET_entry_13);
- set_irq(0x14, OFFSET_entry_14);
- set_irq(0x15, OFFSET_entry_15);
- set_irq(0x16, OFFSET_entry_16);
- set_irq(0x17, OFFSET_entry_17);
- set_irq(0x18, OFFSET_entry_18);
- set_irq(0x19, OFFSET_entry_19);
- set_irq(0x1a, OFFSET_entry_1a);
- set_irq(0x1c, OFFSET_entry_1c);
- set_irq(0x40, OFFSET_entry_40);
- set_irq(0x70, OFFSET_entry_70);
- //set_irq(0x71, OFFSET_entry_hwirq);
- //set_irq(0x72, OFFSET_entry_hwirq);
- //set_irq(0x73, OFFSET_entry_hwirq);
- set_irq(0x74, OFFSET_entry_74);
- set_irq(0x75, OFFSET_entry_75);
- set_irq(0x76, OFFSET_entry_76);
- //set_irq(0x77, OFFSET_entry_hwirq);
+ set_irq(i, &dummy_iret_handler);
+
+ set_irq(0x08, &entry_08);
+ set_irq(0x09, &entry_09);
+ //set_irq(0x0a, &entry_hwirq);
+ //set_irq(0x0b, &entry_hwirq);
+ //set_irq(0x0c, &entry_hwirq);
+ //set_irq(0x0d, &entry_hwirq);
+ set_irq(0x0e, &entry_0e);
+ //set_irq(0x0f, &entry_hwirq);
+ set_irq(0x10, &entry_10);
+ set_irq(0x11, &entry_11);
+ set_irq(0x12, &entry_12);
+ set_irq(0x13, &entry_13);
+ set_irq(0x14, &entry_14);
+ set_irq(0x15, &entry_15);
+ set_irq(0x16, &entry_16);
+ set_irq(0x17, &entry_17);
+ set_irq(0x18, &entry_18);
+ set_irq(0x19, &entry_19);
+ set_irq(0x1a, &entry_1a);
+ set_irq(0x1c, &entry_1c);
+ set_irq(0x40, &entry_40);
+ set_irq(0x70, &entry_70);
+ //set_irq(0x71, &entry_hwirq);
+ //set_irq(0x72, &entry_hwirq);
+ //set_irq(0x73, &entry_hwirq);
+ set_irq(0x74, &entry_74);
+ set_irq(0x75, &entry_75);
+ set_irq(0x76, &entry_76);
+ //set_irq(0x77, &entry_hwirq);
// set vector 0x79 to zero
// this is used by 'gardian angel' protection system
SET_BDA(ivecs[0x79].seg, 0);
SET_BDA(ivecs[0x79].offset, 0);
- set_irq(0x1E, OFFSET_diskette_param_table2);
+ set_irq(0x1E, &diskette_param_table2);
}
static void
memset(&br, 0, sizeof(br));
br.es = SEG_BIOS;
// starts 1 past for alignment
- br.di = OFFSET_pnp_string - BUILD_BIOS_ADDR + 1;
+ extern char pnp_string[];
+ br.di = (u32)pnp_string - BUILD_BIOS_ADDR + 1;
br.cs = seg;
br.ip = offset;
call16(&br);
interactive_bootmenu();
// Setup bios checksum.
- *(u8*)OFFSET_bios_checksum = -checksum((u8*)BUILD_BIOS_ADDR
- , BUILD_BIOS_SIZE - 1);
+ extern char bios_checksum;
+ bios_checksum = -checksum((u8*)BUILD_BIOS_ADDR, BUILD_BIOS_SIZE - 1);
// Prep for boot process.
make_bios_readonly();
call16_int(0x19, &br);
}
+// Ughh - some older gcc compilers have a bug which causes VISIBLE32
+// functions to not be exported as a global variable - force _start
+// to be global here.
+asm(".global _start");
+
// Externally visible 32bit entry point.
asm(
".global post32\n"
"post32:\n"
"cli\n"
"cld\n"
- "lidtl " __stringify(OFFSET_pmode_IDT_info) "\n"
- "lgdtl " __stringify(OFFSET_rombios32_gdt_48) "\n"
+ "lidtl pmode_IDT_info\n"
+ "lgdtl rombios32_gdt_48\n"
"movl $" __stringify(BUILD_STACK_ADDR) ", %esp\n"
"ljmp $0x10, $_start\n"
);
// Linker definitions for 16bit code
//
// Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
-// Copyright (C) 2002 MandrakeSoft S.A.
//
// This file may be distributed under the terms of the GNU GPLv3 license.
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH("i386")
-ENTRY(post16);
SECTIONS
{
- . = 0;
- .text : {
+ .text16 ( _code32_code16_start - BUILD_BIOS_ADDR ) : {
*(.text)
- *(.rodata)
- *(.rodata.*)
+ *(.rodata*)
*(.data)
- bios16c_end = .;
- . = BUILD_START_FIXED;
- *(.text.fixed.addr)
}
- /DISCARD/ : { *(.stab)
- *(.stabstr)
- *(.comment)
- *(.note)
- }
+ .text16.fixed.addr BUILD_START_FIXED : {
+ *(.text.fixed.addr)
+ }
}
-// Linker definitions for 32bit code
+// Linker definitions for 16 and 32 bit code
//
// Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
-// Copyright (C) 2002 MandrakeSoft S.A.
//
// This file may be distributed under the terms of the GNU GPLv3 license.
#include "config.h"
-#include "../out/rom16.offset.auto.h"
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH("i386")
ENTRY(post32);
SECTIONS
{
- . = OFFSET_bios16c_end;
- . = ALIGN(16);
- _text32_start = . ;
- .text : { *(.text) }
- .rodata : { *(.rodata) }
- .data : { *(.data) }
- . = BUILD_BSS_ADDR;
- __bss_start = . ;
- .bss : { *(.bss) *(COMMON) }
- __bss_end = . ;
- __call16_from32 = OFFSET___call16_from32;
- /DISCARD/ : { *(.stab)
- *(.stabstr)
- *(.comment)
- *(.note)
- }
+ .text BUILD_BIOS_ADDR : {
+ code32_start = . ;
+ *(.text)
+ *(.rodata*)
+ *(.data)
+ code32_end = . ;
+
+ . = ALIGN(16) ;
+ code16_start = . ;
+ *(.text16)
+ code16_end = . ;
+ freespace1_start = . ;
+
+ . = BUILD_START_FIXED ;
+ freespace1_end = . ;
+ *(.text16.fixed.addr)
+ }
+
+ .bss BUILD_BSS_ADDR : {
+ __bss_start = . ;
+ *(.bss)
+ *(COMMON)
+ __bss_end = . ;
+ }
}
****************************************************************/
ORG 0xe05b
- .globl post16
post16:
// init the stack pointer
RESET_STACK
- // Set entry point of rombios32 code - the actual address
- // is altered later in the build process.
- .globl set_entry32
-set_entry32:
- pushl $0xf0000000
+ pushl $_code32__start
cld
// Call a 16bit function from 32bit mode.
// %eax = address of struct bregs
// Clobbers: all gp registers, flags, stack registers, cr0, idt/gdt
- .globl __call16_from32
+ .global __call16_from32
__call16_from32:
pushl %eax
// Call a 16bit function from 16bit mode with a specified cpu register state
// %eax = address of struct bregs
// Clobbers: all gp registers, es
- .globl __call16
+ .global __call16
__call16:
// Save eax
pushl %eax
// APM trampolines
- .globl apm16protected_entry
+ .global apm16protected_entry
apm16protected_entry:
pushfw // save flags
pushl %eax // dummy
lretw
.code32
- .globl apm32protected_entry
+ .global apm32protected_entry
apm32protected_entry:
pushfw
pushw %cs // Setup for long jump to 16bit mode
// Set base to f0000 to correspond to beginning of BIOS,
// in case I actually define an IDT later
// Set limit to 0
+ .global pmode_IDT_info
pmode_IDT_info:
.word 0x0000 // limit 15:00
.long 0xf0000 // base 16:47
.word 0x03ff // limit 15:00
.long 0 // base 16:47
+ .global rombios32_gdt_48
rombios32_gdt_48:
.word 0x30
.word rombios32_gdt
// Define an entry point for an interrupt (no args passed).
.macro IRQ_ENTRY num
- .globl entry_\num
+ .global entry_\num
entry_\num :
cli // In case something far-calls instead of using "int"
ENTRY handle_\num
// Define an entry point for an interrupt (can read/modify args).
.macro IRQ_ENTRY_ARG num
- .globl entry_\num
+ .global entry_\num
entry_\num :
cli // In case something far-calls instead of using "int"
ENTRY_ARG handle_\num
IRQ_ENTRY 75
// int 18/19 are special - they reset the stack and do not return.
- .globl entry_19
+ .global entry_19
entry_19:
RESET_STACK
ENTRY handle_19
- .globl entry_18
+ .global entry_18
entry_18:
RESET_STACK
ENTRY handle_18
// IRQ trampolines
.macro IRQ_TRAMPOLINE num
- .globl irq_trampoline_0x\num
+ .global irq_trampoline_0x\num
irq_trampoline_0x\num :
int $0x\num
lretw
// XXX int 1D
iretw
- .globl freespace2_start, freespace2_end
+ .global freespace2_start, freespace2_end
freespace2_start:
ORG 0xf841
.ascii "(c) 2002 MandrakeSoft S.A. Written by Kevin Lawton & the Bochs team."
ORG 0xff53
- .globl dummy_iret_handler
+ .global dummy_iret_handler
dummy_iret_handler:
iretw
ORG 0xfffe
.byte CONFIG_MODEL_ID
- .globl bios_checksum
+ .global bios_checksum
bios_checksum:
.byte 0x00
}
asm(
- ".globl smp_ap_boot_code_start\n"
- ".globl smp_ap_boot_code_end\n"
+ ".global smp_ap_boot_code_start\n"
+ ".global smp_ap_boot_code_end\n"
" .code16\n"
"smp_ap_boot_code_start:\n"
struct bregs;
inline void call16(struct bregs *callregs);
inline void __call16_int(struct bregs *callregs, u16 offset);
-#ifdef MODE16
#define call16_int(nr, callregs) do { \
extern void irq_trampoline_ ##nr (); \
__call16_int((callregs), (u32)&irq_trampoline_ ##nr ); \
} while (0)
-#else
-#include "../out/rom16.offset.auto.h"
-#define call16_int(nr, callregs) \
- __call16_int((callregs), OFFSET_irq_trampoline_ ##nr - BUILD_BIOS_ADDR)
-#endif
// output.c
void debug_serial_setup();
+++ /dev/null
-#!/usr/bin/env python
-# Script to merge a rom32.bin file into a rom16.bin file.
-#
-# Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
-#
-# This file may be distributed under the terms of the GNU GPLv3 license.
-
-import sys
-import struct
-import os
-
-ROM16='out/rom16.bin'
-ROM32='out/rom32.bin'
-OFFSETS16='out/rom16.offset.auto.h'
-OFFSETS32='out/rom32.offset.auto.h'
-OUT='out/bios.bin'
-
-def align(v, a):
- return (v + a - 1) // a * a
-
-def scanconfig(file):
- f = open(file, 'rb')
- opts = {}
- for l in f.readlines():
- parts = l.split()
- if len(parts) != 3:
- continue
- if parts[0] != '#define':
- continue
- opts[parts[1]] = parts[2]
- return opts
-
-def alteraddr(data, offset, ptr):
- rel = struct.pack("<i", ptr)
- return data[:offset] + rel + data[offset+4:]
-
-
-def main():
- # Read in files
- f = open(ROM16, 'rb')
- data16 = f.read()
- f = open(ROM32, 'rb')
- data32 = f.read()
-
- if len(data16) != 65536:
- print "16bit code is not 65536 bytes long"
- sys.exit(1)
-
- # Get config options
- o16 = scanconfig(OFFSETS16)
- o32 = scanconfig(OFFSETS32)
-
- # Inject 32bit code
- spos = align(int(o16['OFFSET_bios16c_end'], 16), 16)
- epos = int(o16['OFFSET_post16'], 16)
- size32 = len(data32)
- freespace = epos - spos
- if size32 > freespace:
- print "32bit code too large (%d vs %d)" % (size32, freespace)
- sys.exit(1)
- spos -= 0xf0000
- if data16[spos:spos+size32] != '\0'*size32:
- print "Non zero data in 16bit freespace (0x%x to 0x%x)" % (
- spos, spos+size32)
- sys.exit(1)
- outrom = data16[:spos] + data32 + data16[spos+size32:]
-
- # Fixup initial jump to 32 bit code
- jmppos = int(o16['OFFSET_set_entry32'], 16) - 0xf0000
- start32 = int(o32['OFFSET__start'], 16)
- outrom = alteraddr(outrom, jmppos+2, start32)
-
- print "Writing output rom %s" % OUT
- print " 16bit C-code size: %d" % spos
- print " 32bit C-code size: %d" % size32
- print " Total C-code size: %d" % (spos+size32)
-
- # Write output rom
- f = open(OUT, 'wb')
- f.write(outrom)
- f.close()
-
- # Build elf file with 32bit entry point
- os.system(
- "ld -melf_i386 -e %s -Tdata 0xf0000 -b binary %s -o %s" % (
- int(o32['OFFSET_post32'], 16), OUT, OUT+".elf"))
-
-if __name__ == '__main__':
- main()
--- /dev/null
+#!/usr/bin/env python
+# Script to check a bios image and report info on it.
+#
+# Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
+#
+# This file may be distributed under the terms of the GNU GPLv3 license.
+
+import sys
+
+def main():
+ # Read in symbols (that are valid)
+ syms = {}
+ for line in sys.stdin.readlines():
+ try:
+ addr, type, sym = line.split()
+ syms[sym] = int(addr, 16)
+ except:
+ pass
+
+ if syms['code16_start'] != syms['_code32_code16_start']:
+ print "Error! 16bit code moved during linking"
+ sys.exit(1)
+
+ size16 = syms['code16_end'] - syms['code16_start']
+ size32 = syms['code32_end'] - syms['code32_start']
+ sizefree = syms['freespace1_end'] - syms['freespace1_start']
+ print "16bit C-code size: %d" % size16
+ print "32bit C-code size: %d" % size32
+ print "Total C-code size: %d" % (size16+size32)
+ print "Free C-code space: %d" % sizefree
+
+if __name__ == '__main__':
+ main()
+++ /dev/null
-#!/usr/bin/env python
-# Simple script to convert the output from 'nm' to a C style header
-# file with defined offsets.
-#
-# Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
-#
-# This file may be distributed under the terms of the GNU GPLv3 license.
-
-import sys
-import string
-
-def printUsage():
- print "Usage:\n %s <output file>" % (sys.argv[0],)
- sys.exit(1)
-
-def main():
- if len(sys.argv) != 2:
- printUsage()
- # Find symbols (that are valid)
- syms = []
- lines = sys.stdin.readlines()
- for line in lines:
- addr, type, sym = line.split()
- if type not in 'Tt':
- # Only interested in global symbols in text segment
- continue
- for c in sym:
- if c not in string.letters + string.digits + '_':
- break
- else:
- syms.append((sym, addr))
- # Build guard string
- guardstr = ''
- for c in sys.argv[1]:
- if c not in string.letters + string.digits + '_':
- guardstr += '_'
- else:
- guardstr += c
- # Generate header
- f = open(sys.argv[1], 'wb')
- f.write("""
-#ifndef __OFFSET_AUTO_H__%s
-#define __OFFSET_AUTO_H__%s
-// Auto generated file - please see defsyms.py.
-// This file contains symbol offsets of a compiled binary.
-
-""" % (guardstr, guardstr))
- for sym, addr in syms:
- f.write("#define OFFSET_%s 0x%s\n" % (sym, addr))
- f.write("""
-#endif // __OFFSET_AUTO_H__%s
-""" % (guardstr,))
-
-if __name__ == '__main__':
- main()