Avoid runtime relocation of 16bit "low" mem - calculate at build instead.

Some 16bit accesses to "low" mem variables use 16bit relocations
instead of the normal 32bit relocations.  This causes build problems
if the "low" mem sections move more than 64K during relocation.

The final location of the "low" memory can be determined during the
build, so link the 16bit code with the final post-reloc location of
the "low" mem variables instead.  This eliminates the need to do these
runtime relocations on the 16bit code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
diff --git a/tools/layoutrom.py b/tools/layoutrom.py
index 74b410f..7a7d08c 100755
--- a/tools/layoutrom.py
+++ b/tools/layoutrom.py
@@ -48,8 +48,6 @@
         totspace = alignpos(totspace, section.align) + section.size
     startaddr = (endaddr - totspace) / minalign * minalign
     curaddr = startaddr
-    # out = [(addr, sectioninfo), ...]
-    out = []
     for section in sections:
         curaddr = alignpos(curaddr, section.align)
         section.finalloc = curaddr
@@ -159,7 +157,7 @@
     sections32flat = sec32flat_start = sec32flat_align = None
     sections32init = sec32init_start = sec32init_align = None
     sections32low = sec32low_start = sec32low_align = None
-    datalow_base = None
+    datalow_base = final_sec32low_start = None
 
 # Determine final memory addresses for sections
 def doLayout(sections, genreloc):
@@ -219,13 +217,17 @@
     li.sections32low = getSectionsCategory(sections, '32low')
     if genreloc:
         sec32low_top = li.sec32init_start
-        datalow_base = min(BUILD_BIOS_ADDR, li.sec32flat_start) - 64*1024
+        final_sec32low_top = min(BUILD_BIOS_ADDR, li.sec32flat_start)
     else:
         sec32low_top = min(BUILD_BIOS_ADDR, li.sec32init_start)
-        datalow_base = sec32low_top - 64*1024
+        final_sec32low_top = sec32low_top
+    relocdelta = final_sec32low_top - sec32low_top
+    datalow_base = final_sec32low_top - 64*1024
     li.datalow_base = max(BUILD_ROM_START, alignpos(datalow_base, 2*1024))
     li.sec32low_start, li.sec32low_align = setSectionsStart(
-        li.sections32low, sec32low_top, 16, segoffset=li.datalow_base)
+        li.sections32low, sec32low_top, 16
+        , segoffset=li.datalow_base - relocdelta)
+    li.final_sec32low_start = li.sec32low_start + relocdelta
 
     # Print statistics
     size16 = BUILD_BIOS_ADDR + BUILD_BIOS_SIZE - li.sec16_start
@@ -311,7 +313,7 @@
 def writeLinkerScripts(li, entrysym, genreloc, out16, out32seg, out32flat):
     # Write 16bit linker script
     out = outXRefs(li.sections16, useseg=1) + """
-    _datalow_base = 0x%x ;
+    datalow_base = 0x%x ;
     _datalow_seg = 0x%x ;
 
     code16_start = 0x%x ;
@@ -352,8 +354,7 @@
         initrelocs = getRelocs(
             li.sections32flat + li.sections32low + li.sections16
             + li.sections32seg, category='32init')
-        lowrelocs = getRelocs(
-            li.sections16 + li.sections32seg + sections32all, category='32low')
+        lowrelocs = getRelocs(sections32all, category='32low')
         relocstr = (strRelocs("_reloc_abs", "code32init_start", absrelocs)
                     + strRelocs("_reloc_rel", "code32init_start", relrelocs)
                     + strRelocs("_reloc_init", "code32flat_start", initrelocs)
@@ -363,8 +364,8 @@
     out = outXRefs(sections32all) + """
     %s = 0x%x ;
     _reloc_min_align = 0x%x ;
-    _datalow_base = 0x%x ;
-    _datalow_min_align = 0x%x ;
+    datalow_base = 0x%x ;
+    final_datalow_start = 0x%x ;
 
     code32flat_start = 0x%x ;
     .text code32flat_start : {
@@ -385,7 +386,7 @@
 """ % (entrysym.name, entrysympos,
        li.sec32init_align,
        li.datalow_base,
-       li.sec32low_align,
+       li.final_sec32low_start,
        sec32all_start,
        relocstr,
        outRelSections(li.sections32low, 'code32flat_start'),