From 711ddc64ac67b7971aa151c6695e98e31dc4c404 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Sat, 17 Jan 2009 15:17:34 -0500 Subject: [PATCH 1/1] Try to automatically fit sections into open spaces in the fixed area. Enhance layoutrom.py script to find and locate sections into fixed area. Have layoutrom.py create output file instead of using redirect from make. Don't use freespace2 for bios tables in f segment - freespace in fixed area is now automatically filled. Change checkrom script to test final_code16_end instead of _start - this improves catching of alignment errors. Don't align gdt to 8 bytes - it causes whole section to be aligned, which causes entry point to be misaligned. Explicitly reserve space for variables in fixed area so that the space for them is not auto-filled. --- Makefile | 2 +- src/memmap.c | 10 ++-- src/rombios.lds.S | 2 +- src/rombios16.lds.S | 1 + src/romlayout.S | 9 ++-- tools/checkrom.py | 10 ++-- tools/layoutrom.py | 109 +++++++++++++++++++++++++++++++++++--------- 7 files changed, 104 insertions(+), 39 deletions(-) diff --git a/Makefile b/Makefile index 424dd0b..f69ed83 100644 --- a/Makefile +++ b/Makefile @@ -107,7 +107,7 @@ $(OUT)rom32.o: $(OUT)ccode32.o $(OUT)rombios32.lds $(OUT)romlayout.lds: $(OUT)romlayout16.o @echo " Building layout information $@" - $(Q)$(OBJDUMP) -h $< | ./tools/layoutrom.py > $@ + $(Q)$(OBJDUMP) -h $< | ./tools/layoutrom.py $@ $(OUT)rombios16.lds: $(OUT)romlayout.lds diff --git a/src/memmap.c b/src/memmap.c index 372ec52..01b00d8 100644 --- a/src/memmap.c +++ b/src/memmap.c @@ -123,7 +123,7 @@ add_e820(u64 start, u64 size, u32 type) } // Symbols defined in romlayout.S -extern char freespace2_start, freespace2_end; +extern char freespace1_start, freespace1_end; u32 bios_table_cur_addr, bios_table_end_addr; @@ -131,8 +131,8 @@ u32 bios_table_cur_addr, bios_table_end_addr; void memmap_setup() { - bios_table_cur_addr = (u32)&freespace2_start; - bios_table_end_addr = (u32)&freespace2_end; + bios_table_cur_addr = (u32)&freespace1_start; + bios_table_end_addr = (u32)&freespace1_end; dprintf(1, "bios_table_addr: 0x%08x end=0x%08x\n", bios_table_cur_addr, bios_table_end_addr); @@ -155,8 +155,8 @@ memmap_finalize() dprintf(1, "final bios_table_addr: 0x%08x (used %d%%)\n" , bios_table_cur_addr - , (100 * (bios_table_cur_addr - (u32)&freespace2_start) - / ((u32)&freespace2_end - (u32)&freespace2_start))); + , (100 * (bios_table_cur_addr - (u32)&freespace1_start) + / ((u32)&freespace1_end - (u32)&freespace1_start))); if (bios_table_cur_addr > bios_table_end_addr) BX_PANIC("bios_table_end_addr overflow!\n"); } diff --git a/src/rombios.lds.S b/src/rombios.lds.S index c17d0f0..61a04c4 100644 --- a/src/rombios.lds.S +++ b/src/rombios.lds.S @@ -15,8 +15,8 @@ SECTIONS *(.text) . = code16_start ; - final_code16_start = . ; *(.text16) + final_code16_end = . ; } /DISCARD/ : { *(.discard*) } } diff --git a/src/rombios16.lds.S b/src/rombios16.lds.S index 074d5f1..61de421 100644 --- a/src/rombios16.lds.S +++ b/src/rombios16.lds.S @@ -11,6 +11,7 @@ OUTPUT_ARCH("i386") SECTIONS { . = ( _code32_code32_end - BUILD_BIOS_ADDR ) ; + . = ALIGN(16) ; code16_start = . ; .text16 : { diff --git a/src/romlayout.S b/src/romlayout.S index 4db9dfe..e8cc9b4 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -487,7 +487,7 @@ rombios32_gdt_48: .word (rombios32_gdt_end - rombios32_gdt) .long (BUILD_BIOS_ADDR + rombios32_gdt) - .balign 8 + //.balign 8 .type rombios32_gdt, @object rombios32_gdt: .word 0, 0, 0, 0 @@ -520,6 +520,7 @@ entry_13_official: .type __fdpt, @object __fdpt: // XXX - Fixed Disk Parameter Table + .space 16 ORG 0xe6f2 .global entry_19_official @@ -534,6 +535,7 @@ entry_19_official: .type __brgt, @object __brgt: // XXX - Baud Rate Generator Table + .space 16 ORG 0xe739 IRQ_ENTRY_ARG 14 @@ -571,11 +573,7 @@ __int1d: // XXX - INT 1D - SYSTEM DATA - VIDEO PARAMETER TABLES .space 0x58 - .global freespace2_start, freespace2_end -freespace2_start: - ORG 0xf841 -freespace2_end: .global entry_12_official entry_12_official: jmp entry_12 @@ -626,6 +624,7 @@ entry_18: ORG 0xfef3 __initvector: // XXX - Initial Interrupt Vector Offsets Loaded by POST + .space 13 ORG 0xff00 .type __copyright, @object diff --git a/tools/checkrom.py b/tools/checkrom.py index 6b5f1e9..d03c794 100755 --- a/tools/checkrom.py +++ b/tools/checkrom.py @@ -17,24 +17,22 @@ def main(): except: pass - c16s = syms['code16_start'] + 0xf0000 - c32s = syms['final_code16_start'] - if c16s != c32s: + c16e = syms['code16_end'] + 0xf0000 + f16e = syms['final_code16_end'] + if c16e != f16e: print "Error! 16bit code moved during linking (0x%x vs 0x%x)" % ( - c32s, c16s) + c16e, f16e) sys.exit(1) sizefree = syms['freespace1_end'] - syms['freespace1_start'] size16 = syms['code16_end'] - syms['code16_start'] - sizefree size32 = syms['code32_end'] - syms['code32_start'] totalc = size16+size32 - tablefree = syms['freespace2_end'] - syms['freespace2_start'] print "16bit size: %d" % size16 print "32bit size: %d" % size32 print "Total size: %d Free space: %d Percent used: %.1f%%" % ( totalc, sizefree , (totalc / float(size16+size32+sizefree)) * 100.0) - print "BIOS table space: %d" % tablefree if __name__ == '__main__': main() diff --git a/tools/layoutrom.py b/tools/layoutrom.py index f1fe0e1..592893b 100755 --- a/tools/layoutrom.py +++ b/tools/layoutrom.py @@ -8,61 +8,128 @@ import sys def main(): - # Read in section names and sizes + # Get output name + outname = sys.argv[1] - # sections = [(idx, name, size, align), ...] + # Read in section names and sizes + # sections = [(size, align, name), ...] sections = [] for line in sys.stdin.readlines(): try: idx, name, size, vma, lma, fileoff, align = line.split() if align[:3] != '2**': continue - sections.append(( - int(idx), name, int(size, 16), int(align[3:]))) + sections.append((int(size, 16), 2**int(align[3:]), name)) except: pass - # fixedsections = [(addr, sectioninfo), ...] - fixedsections = [] + doLayout(sections, outname) + +def alignpos(pos, alignbytes): + mask = alignbytes - 1 + return (pos + mask) & ~mask + +def doLayout(sections, outname): textsections = [] rodatasections = [] datasections = [] + # fixedsections = [(addr, sectioninfo, extasectionslist), ...] + fixedsections = [] + # canrelocate = [(sectioninfo, list), ...] + canrelocate = [] # Find desired sections. for section in sections: - name = section[1] + size, align, name = section if name[:11] == '.fixedaddr.': addr = int(name[11:], 16) - fixedsections.append((addr, section)) + fixedsections.append((addr, section, [])) + if align != 1: + print "Error: Fixed section %s has non-zero alignment (%d)" % ( + name, align) + sys.exit(1) if name[:6] == '.text.': textsections.append(section) + canrelocate.append((section, textsections)) if name[:17] == '.rodata.__func__.' or name == '.rodata.str1.1': rodatasections.append(section) + #canrelocate.append((section, rodatasections)) if name[:8] == '.data16.': datasections.append(section) + #canrelocate.append((section, datasections)) + + # Find freespace in fixed address area + fixedsections.sort() + # fixedAddr = [(freespace, sectioninfo), ...] + fixedAddr = [] + for i in range(len(fixedsections)): + fixedsectioninfo = fixedsections[i] + addr, section, extrasectionslist = fixedsectioninfo + if i == len(fixedsections) - 1: + nextaddr = 0x10000 + else: + nextaddr = fixedsections[i+1][0] + avail = nextaddr - addr - section[0] + fixedAddr.append((avail, fixedsectioninfo)) + + # Attempt to fit other sections into fixed area + fixedAddr.sort() + canrelocate.sort() + for freespace, fixedsectioninfo in fixedAddr: + fixedaddr, fixedsection, extrasections = fixedsectioninfo + addpos = fixedaddr + fixedsection[0] + nextfixedaddr = addpos + freespace +# print "Filling section %x uses %d, next=%x, available=%d" % ( +# fixedaddr, fixedsection[0], nextfixedaddr, freespace) + while 1: + canfit = None + for fixedaddrinfo in canrelocate: + fitsection, inlist = fixedaddrinfo + fitnextaddr = alignpos(addpos, fitsection[1]) + fitsection[0] +# print "Test %s - %x vs %x" % ( +# fitsection[2], fitnextaddr, nextfixedaddr) + if fitnextaddr > nextfixedaddr: + # Can't fit. + break + canfit = (fitnextaddr, fixedaddrinfo) + if canfit is None: + break + # Found a section that can fit. + fitnextaddr, fixedaddrinfo = canfit + canrelocate.remove(fixedaddrinfo) + fitsection, inlist = fixedaddrinfo + inlist.remove(fitsection) + extrasections.append(fitsection) + addpos = fitnextaddr +# print " Adding %s (size %d align %d)" % ( +# fitsection[2], fitsection[0], fitsection[1]) # Write regular sections + output = open(outname, 'wb') for section in textsections: - name = section[1] - sys.stdout.write("*(%s)\n" % (name,)) - sys.stdout.write("code16_rodata = . ;\n") + name = section[2] + output.write("*(%s)\n" % (name,)) + output.write("code16_rodata = . ;\n") for section in rodatasections: - name = section[1] - sys.stdout.write("*(%s)\n" % (name,)) + name = section[2] + output.write("*(%s)\n" % (name,)) for section in datasections: - name = section[1] - sys.stdout.write("*(%s)\n" % (name,)) + name = section[2] + output.write("*(%s)\n" % (name,)) # Write fixed sections - sys.stdout.write("freespace1_start = . ;\n") + output.write("freespace1_start = . ;\n") first = 1 - for addr, section in fixedsections: - name = section[1] - sys.stdout.write(". = ( 0x%x - code16_start ) ;\n" % (addr,)) + for addr, section, extrasections in fixedsections: + name = section[2] + output.write(". = ( 0x%x - code16_start ) ;\n" % (addr,)) if first: first = 0 - sys.stdout.write("freespace1_end = . ;\n") - sys.stdout.write("*(%s)\n" % (name,)) + output.write("freespace1_end = . ;\n") + output.write("*(%s)\n" % (name,)) + for extrasection in extrasections: + name = extrasection[2] + output.write("*(%s)\n" % (name,)) if __name__ == '__main__': main() -- 2.25.1