aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2009-01-17 15:17:34 -0500
committerKevin O'Connor <kevin@koconnor.net>2009-01-17 15:17:34 -0500
commit711ddc64ac67b7971aa151c6695e98e31dc4c404 (patch)
treef02d647c9e8f007ec28acb08a1a22730ce759ddc /tools
parent202024a27b171700f95717a6ef9c23bcf04d9fc1 (diff)
downloadseabios-711ddc64ac67b7971aa151c6695e98e31dc4c404.tar.gz
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.
Diffstat (limited to 'tools')
-rwxr-xr-xtools/checkrom.py10
-rwxr-xr-xtools/layoutrom.py109
2 files changed, 92 insertions, 27 deletions
diff --git a/tools/checkrom.py b/tools/checkrom.py
index 6b5f1e9f..d03c794c 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 f1fe0e10..592893b6 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()