This series updates the build (and layoutrom.py in particular) to be more flexible in section layouts. Prior to this series, only code compiled in the 16bit mode pass could be placed at a fixed address in the f-segment. After this change, the build can more easily place sections from any compile pass.
Most of the series consists of minor cleanups to layoutrom.py to make the above happen. Patch 4 is an unrelated minor feature enhancement.
Otherwise, patches 7 and 10 are where the real changes occur.
-Kevin
Kevin O'Connor (10): build: Remove unused function getSectionsStart() from layoutrom.py. build: Extract section visiting logic in layoutrom.py. build: Refactor layoutrom.py gc() function. build: Use customized entry point for each type of build. build: Refactor findInit() function. build: Rework getRelocs() to use a hash instead of categories in layoutrom.py build: Keep segmented sections separate until final link step. build: Use fileid instead of category to write sections in layoutrom.py. build: Only export needed fields in LayoutInfo in layoutrom.py. build: Get fixed address variables from 32bit compile pass (not 16bit)
Makefile | 13 +- scripts/layoutrom.py | 426 ++++++++++++++++++++++++--------------------------- src/entryfuncs.S | 6 - src/font.c | 2 +- src/misc.c | 18 +-- src/romlayout.S | 4 +- src/types.h | 8 +- 7 files changed, 224 insertions(+), 253 deletions(-)
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- scripts/layoutrom.py | 5 ----- 1 file changed, 5 deletions(-)
diff --git a/scripts/layoutrom.py b/scripts/layoutrom.py index b325406..28e7d0c 100755 --- a/scripts/layoutrom.py +++ b/scripts/layoutrom.py @@ -343,11 +343,6 @@ def getRelocs(sections, type=None, category=None, notcategory=None): out.append(section.finalloc + reloc.offset) return out
-# Return the start address and minimum alignment for a set of sections -def getSectionsStart(sections, defaddr=0): - return min([section.finalloc for section in sections - if section.finalloc is not None] or [defaddr]) - # Output the linker scripts for all required sections. def writeLinkerScripts(li, out16, out32seg, out32flat): # Write 16bit linker script
Extract out the logic that visits all reachable sections into new function findReachable().
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- scripts/layoutrom.py | 117 ++++++++++++++++++++++++++------------------------- 1 file changed, 60 insertions(+), 57 deletions(-)
diff --git a/scripts/layoutrom.py b/scripts/layoutrom.py index 28e7d0c..a4eba89 100755 --- a/scripts/layoutrom.py +++ b/scripts/layoutrom.py @@ -449,29 +449,42 @@ PHDRS # Detection of init code ######################################################################
-def markRuntime(section, sections, chain=[]): - if (section is None or not section.keep or section.category is not None +# Visit all sections reachable from a given set of start sections +def findReachable(anchorsections, checkreloc, data): + anchorsections = dict([(section, []) for section in anchorsections]) + pending = list(anchorsections) + while pending: + section = pending.pop() + for reloc in section.relocs: + chain = anchorsections[section] + [section.name] + if not checkreloc(reloc, section, data, chain): + continue + nextsection = reloc.symbol.section + if nextsection not in anchorsections: + anchorsections[nextsection] = chain + pending.append(nextsection) + return anchorsections + +def checkRuntime(reloc, rsection, data, chain): + section = reloc.symbol.section + if (section is None or not section.keep or '.init.' in section.name or section.fileid != '32flat'): - return + return 0 if '.data.varinit.' in section.name: print("ERROR: %s is VARVERIFY32INIT but used from %s" % ( section.name, chain)) sys.exit(1) - section.category = '32flat' - # Recursively mark all sections this section points to - for reloc in section.relocs: - markRuntime(reloc.symbol.section, sections, chain + [section.name]) + return 1
def findInit(sections): # Recursively find and mark all "runtime" sections. - for section in sections: + anchorsections = [ + section for section in sections if ('.data.varlow.' in section.name or '.data.varfseg.' in section.name - or '.runtime.' in section.name or '.export.' in section.name): - markRuntime(section, sections) + or '.runtime.' in section.name or '.export.' in section.name)] + runtimesections = findReachable(anchorsections, checkRuntime, None) for section in sections: - if section.category is not None: - continue - if section.fileid == '32flat': + if section.fileid == '32flat' and section not in runtimesections: section.category = '32init' else: section.category = section.fileid @@ -481,65 +494,55 @@ def findInit(sections): # Section garbage collection ######################################################################
-CFUNCPREFIX = [('_cfunc16_', 0), ('_cfunc32seg_', 1), ('_cfunc32flat_', 2)] - # Find and keep the section associated with a symbol (if available). -def keepsymbol(reloc, infos, pos, isxref): +def checkKeepSym(reloc, syms, fileid, isxref): symbolname = reloc.symbolname - mustbecfunc = 0 - for symprefix, needpos in CFUNCPREFIX: - if symbolname.startswith(symprefix): - if needpos != pos: - return -1 - symbolname = symbolname[len(symprefix):] - mustbecfunc = 1 - break - symbol = infos[pos][1].get(symbolname) + mustbecfunc = symbolname.startswith('_cfunc') + if mustbecfunc: + symprefix = '_cfunc' + fileid + '_' + if not symbolname.startswith(symprefix): + return 0 + symbolname = symbolname[len(symprefix):] + symbol = syms.get(symbolname) if (symbol is None or symbol.section is None or symbol.section.name.startswith('.discard.')): - return -1 + return 0 isdestcfunc = (symbol.section.name.startswith('.text.') and not symbol.section.name.startswith('.text.asm.')) if ((mustbecfunc and not isdestcfunc) or (not mustbecfunc and isdestcfunc and isxref)): - return -1 + return 0
reloc.symbol = symbol - keepsection(symbol.section, infos, pos) + return 1 + +# Resolve a relocation and check if it should be kept in the final binary. +def checkKeep(reloc, section, infos, chain): + ret = checkKeepSym(reloc, infos[section.fileid][1], section.fileid, 0) + if ret: + return ret + # Not in primary sections - it may be a cross 16/32 reference + for fileid in ('16', '32seg', '32flat'): + if fileid != section.fileid: + ret = checkKeepSym(reloc, infos[fileid][1], fileid, 1) + if ret: + return ret return 0
-# Note required section, and recursively set all referenced sections -# as required. -def keepsection(section, infos, pos=0): - if section.keep: - # Already kept - nothing to do. - return - section.keep = 1 - # Keep all sections that this section points to - for reloc in section.relocs: - ret = keepsymbol(reloc, infos, pos, 0) - if not ret: - continue - # Not in primary sections - it may be a cross 16/32 reference - ret = keepsymbol(reloc, infos, (pos+1)%3, 1) - if not ret: - continue - ret = keepsymbol(reloc, infos, (pos+2)%3, 1) - if not ret: - continue - # Determine which sections are actually referenced and need to be # placed into the output file. def gc(info16, info32seg, info32flat): - # infos = ((sections16, symbols16), (sect32seg, sym32seg) - # , (sect32flat, sym32flat)) - infos = (info16, info32seg, info32flat) - # Start by keeping sections that are globally visible. - for section in info16[0]: - if section.name.startswith('.fixedaddr.') or '.export.' in section.name: - keepsection(section, infos) - return [section for section in info16[0]+info32seg[0]+info32flat[0] - if section.keep] + anchorsections = [section for section in info16[0] + if (section.name.startswith('.fixedaddr.') + or '.export.' in section.name)] + infos = {'16': info16, '32seg': info32seg, '32flat': info32flat} + keepsections = findReachable(anchorsections, checkKeep, infos) + sections = [] + for section in info16[0] + info32seg[0] + info32flat[0]: + if section in keepsections: + section.keep = 1 + sections.append(section) + return sections
######################################################################
Eliminate the per-section 'keep' variable - the list of sections that will be emitted is sufficient to track that state.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- scripts/layoutrom.py | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-)
diff --git a/scripts/layoutrom.py b/scripts/layoutrom.py index a4eba89..1fae72d 100755 --- a/scripts/layoutrom.py +++ b/scripts/layoutrom.py @@ -467,8 +467,7 @@ def findReachable(anchorsections, checkreloc, data):
def checkRuntime(reloc, rsection, data, chain): section = reloc.symbol.section - if (section is None or not section.keep - or '.init.' in section.name or section.fileid != '32flat'): + if section is None or '.init.' in section.name or section.fileid != '32flat': return 0 if '.data.varinit.' in section.name: print("ERROR: %s is VARVERIFY32INIT but used from %s" % ( @@ -517,33 +516,18 @@ def checkKeepSym(reloc, syms, fileid, isxref): return 1
# Resolve a relocation and check if it should be kept in the final binary. -def checkKeep(reloc, section, infos, chain): - ret = checkKeepSym(reloc, infos[section.fileid][1], section.fileid, 0) +def checkKeep(reloc, section, symbols, chain): + ret = checkKeepSym(reloc, symbols[section.fileid], section.fileid, 0) if ret: return ret # Not in primary sections - it may be a cross 16/32 reference for fileid in ('16', '32seg', '32flat'): if fileid != section.fileid: - ret = checkKeepSym(reloc, infos[fileid][1], fileid, 1) + ret = checkKeepSym(reloc, symbols[fileid], fileid, 1) if ret: return ret return 0
-# Determine which sections are actually referenced and need to be -# placed into the output file. -def gc(info16, info32seg, info32flat): - anchorsections = [section for section in info16[0] - if (section.name.startswith('.fixedaddr.') - or '.export.' in section.name)] - infos = {'16': info16, '32seg': info32seg, '32flat': info32flat} - keepsections = findReachable(anchorsections, checkKeep, infos) - sections = [] - for section in info16[0] + info32seg[0] + info32flat[0]: - if section in keepsections: - section.keep = 1 - sections.append(section) - return sections -
###################################################################### # Startup and input parsing @@ -551,7 +535,7 @@ def gc(info16, info32seg, info32flat):
class Section: name = size = alignment = fileid = relocs = None - finalloc = finalsegloc = category = keep = None + finalloc = finalsegloc = category = None class Reloc: offset = type = symbolname = symbol = None class Symbol: @@ -674,7 +658,13 @@ def main(): config = scanconfig(cfgfile)
# Figure out which sections to keep. - sections = gc(info16, info32seg, info32flat) + allsections = info16[0] + info32seg[0] + info32flat[0] + symbols = {'16': info16[1], '32seg': info32seg[1], '32flat': info32flat[1]} + anchorsections = [section for section in info16[0] + if (section.name.startswith('.fixedaddr.') + or '.export.' in section.name)] + keepsections = findReachable(anchorsections, checkKeep, symbols) + sections = [section for section in allsections if section in keepsections]
# Separate 32bit flat into runtime and init parts findInit(sections) @@ -686,15 +676,15 @@ def main(): section.category = '32fseg'
# Determine the final memory locations of each kept section. - genreloc = '_reloc_abs_start' in info32flat[1] + genreloc = '_reloc_abs_start' in symbols['32flat'] li = doLayout(sections, config, genreloc)
# Exported symbols - li.exportsyms = [symbol for symbol in info16[1].values() + li.exportsyms = [symbol for symbol in symbols['16'].values() if (symbol.section is not None and '.export.' in symbol.section.name and symbol.name != symbol.section.name)] - li.varlowsyms = [symbol for symbol in info32flat[1].values() + li.varlowsyms = [symbol for symbol in symbols['32flat'].values() if (symbol.section is not None and symbol.section.finalloc is not None and '.data.varlow.' in symbol.section.name
Set an appropriate elf entry point (entry_elf, entry_csm, reset_vector) for each type of build (coreboot, csm, qemu). Use that entry point when determining which sections to keep.
Also, remove the '.export.' mechanism to keep a section in the final binary - it is no longer used.
This allows the build to slightly reduce the overall size as entry_elf is no longer needed on non-coreboot builds and entry_csm is no longer needed on non-csm builds.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- scripts/layoutrom.py | 27 +++++++++++++++------------ src/entryfuncs.S | 6 ------ src/romlayout.S | 4 ++-- 3 files changed, 17 insertions(+), 20 deletions(-)
diff --git a/scripts/layoutrom.py b/scripts/layoutrom.py index 1fae72d..7c96cd3 100755 --- a/scripts/layoutrom.py +++ b/scripts/layoutrom.py @@ -166,7 +166,7 @@ class LayoutInfo: zonefseg_start = zonefseg_end = None final_readonly_start = None zonelow_base = final_sec32low_start = None - exportsyms = varlowsyms = None + varlowsyms = entrysym = None
# Determine final memory addresses for sections def doLayout(sections, config, genreloc): @@ -394,7 +394,7 @@ def writeLinkerScripts(li, out16, out32seg, out32flat): sec32all_start -= numrelocs * 4 out = outXRefs(li.sections32low, exportsyms=li.varlowsyms , forcedelta=li.final_sec32low_start-li.sec32low_start) - out += outXRefs(sections32all, exportsyms=li.exportsyms) + """ + out += outXRefs(sections32all, exportsyms=[li.entrysym]) + """ _reloc_min_align = 0x%x ; zonefseg_start = 0x%x ; zonefseg_end = 0x%x ; @@ -434,12 +434,12 @@ def writeLinkerScripts(li, out16, out32seg, out32flat): li.sec32seg_start, li.sec16_start) out = COMMONHEADER + out + COMMONTRAILER + """ -ENTRY(entry_elf) +ENTRY(%s) PHDRS { text PT_LOAD AT ( code32flat_start ) ; } -""" +""" % (li.entrysym.name,) outfile = open(out32flat, 'w') outfile.write(out) outfile.close() @@ -480,7 +480,7 @@ def findInit(sections): anchorsections = [ section for section in sections if ('.data.varlow.' in section.name or '.data.varfseg.' in section.name - or '.runtime.' in section.name or '.export.' in section.name)] + or '.runtime.' in section.name)] runtimesections = findReachable(anchorsections, checkRuntime, None) for section in sections: if section.fileid == '32flat' and section not in runtimesections: @@ -660,9 +660,15 @@ def main(): # Figure out which sections to keep. allsections = info16[0] + info32seg[0] + info32flat[0] symbols = {'16': info16[1], '32seg': info32seg[1], '32flat': info32flat[1]} - anchorsections = [section for section in info16[0] - if (section.name.startswith('.fixedaddr.') - or '.export.' in section.name)] + if config.get('CONFIG_COREBOOT'): + entrysym = symbols['16'].get('entry_elf') + elif config.get('CONFIG_CSM'): + entrysym = symbols['16'].get('entry_csm') + else: + entrysym = symbols['16'].get('reset_vector') + anchorsections = [entrysym.section] + [ + section for section in info16[0] + if section.name.startswith('.fixedaddr.')] keepsections = findReachable(anchorsections, checkKeep, symbols) sections = [section for section in allsections if section in keepsections]
@@ -680,15 +686,12 @@ def main(): li = doLayout(sections, config, genreloc)
# Exported symbols - li.exportsyms = [symbol for symbol in symbols['16'].values() - if (symbol.section is not None - and '.export.' in symbol.section.name - and symbol.name != symbol.section.name)] li.varlowsyms = [symbol for symbol in symbols['32flat'].values() if (symbol.section is not None and symbol.section.finalloc is not None and '.data.varlow.' in symbol.section.name and symbol.name != symbol.section.name)] + li.entrysym = entrysym
# Write out linker script files. writeLinkerScripts(li, out16, out32seg, out32flat) diff --git a/src/entryfuncs.S b/src/entryfuncs.S index ea6f990..679b1fc 100644 --- a/src/entryfuncs.S +++ b/src/entryfuncs.S @@ -149,9 +149,3 @@ .section .text.asm.\func .global \func .endm - - // Declare an exported function - .macro EXPORTFUNC func - .section .text.asm.export.\func - .global \func - .endm diff --git a/src/romlayout.S b/src/romlayout.S index 8071963..a931b32 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -440,7 +440,7 @@ entry_bios32: lretl
// 32bit elf entry point - EXPORTFUNC entry_elf + DECLFUNC entry_elf entry_elf: cli cld @@ -458,7 +458,7 @@ entry_elf: .code16
// UEFI Compatibility Support Module (CSM) entry point - EXPORTFUNC entry_csm + DECLFUNC entry_csm entry_csm: // Backup register state pushfw
Push findInit() into main() and unify the category setting code.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- scripts/layoutrom.py | 46 ++++++++++++++++++---------------------------- 1 file changed, 18 insertions(+), 28 deletions(-)
diff --git a/scripts/layoutrom.py b/scripts/layoutrom.py index 7c96cd3..a935b3d 100755 --- a/scripts/layoutrom.py +++ b/scripts/layoutrom.py @@ -446,7 +446,7 @@ PHDRS
###################################################################### -# Detection of init code +# Detection of unused sections and init sections ######################################################################
# Visit all sections reachable from a given set of start sections @@ -465,9 +465,10 @@ def findReachable(anchorsections, checkreloc, data): pending.append(nextsection) return anchorsections
+# Find "runtime" sections (ie, not init only sections). def checkRuntime(reloc, rsection, data, chain): section = reloc.symbol.section - if section is None or '.init.' in section.name or section.fileid != '32flat': + if section is None or '.init.' in section.name: return 0 if '.data.varinit.' in section.name: print("ERROR: %s is VARVERIFY32INIT but used from %s" % ( @@ -475,24 +476,6 @@ def checkRuntime(reloc, rsection, data, chain): sys.exit(1) return 1
-def findInit(sections): - # Recursively find and mark all "runtime" sections. - anchorsections = [ - section for section in sections - if ('.data.varlow.' in section.name or '.data.varfseg.' in section.name - or '.runtime.' in section.name)] - runtimesections = findReachable(anchorsections, checkRuntime, None) - for section in sections: - if section.fileid == '32flat' and section not in runtimesections: - section.category = '32init' - else: - section.category = section.fileid - - -###################################################################### -# Section garbage collection -###################################################################### - # Find and keep the section associated with a symbol (if available). def checkKeepSym(reloc, syms, fileid, isxref): symbolname = reloc.symbolname @@ -672,14 +655,21 @@ def main(): keepsections = findReachable(anchorsections, checkKeep, symbols) sections = [section for section in allsections if section in keepsections]
- # Separate 32bit flat into runtime and init parts - findInit(sections) - - # Note "low memory" and "fseg memory" parts - for section in getSectionsPrefix(sections, '.data.varlow.'): - section.category = '32low' - for section in getSectionsPrefix(sections, '.data.varfseg.'): - section.category = '32fseg' + # Separate 32bit flat into runtime, init, and special variable parts + anchorsections = [ + section for section in sections + if ('.data.varlow.' in section.name or '.data.varfseg.' in section.name + or '.runtime.' in section.name)] + runtimesections = findReachable(anchorsections, checkRuntime, None) + for section in sections: + if section.name.startswith('.data.varlow.'): + section.category = '32low' + elif section.name.startswith('.data.varfseg.'): + section.category = '32fseg' + elif section.fileid == '32flat' and section not in runtimesections: + section.category = '32init' + else: + section.category = section.fileid
# Determine the final memory locations of each kept section. genreloc = '_reloc_abs_start' in symbols['32flat']
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- scripts/layoutrom.py | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-)
diff --git a/scripts/layoutrom.py b/scripts/layoutrom.py index a935b3d..3eca823 100755 --- a/scripts/layoutrom.py +++ b/scripts/layoutrom.py @@ -329,19 +329,13 @@ def strRelocs(outname, outrel, relocs): for pos in relocs]) + " %s_end = ABSOLUTE(.) ;\n" % (outname,))
-# Find all relocations in the given sections with the given attributes -def getRelocs(sections, type=None, category=None, notcategory=None): - out = [] - for section in sections: - for reloc in section.relocs: - if reloc.symbol.section is None: - continue - destcategory = reloc.symbol.section.category - if ((type is None or reloc.type == type) - and (category is None or destcategory == category) - and (notcategory is None or destcategory != notcategory)): - out.append(section.finalloc + reloc.offset) - return out +# Find relocations to the given sections +def getRelocs(sections, tosection, type=None): + return [section.finalloc + reloc.offset + for section in sections + for reloc in section.relocs + if (reloc.symbol.section in tosection + and (type is None or reloc.type == type))]
# Output the linker scripts for all required sections. def writeLinkerScripts(li, out16, out32seg, out32flat): @@ -380,13 +374,13 @@ def writeLinkerScripts(li, out16, out32seg, out32flat): relocstr = "" if li.genreloc: # Generate relocations - absrelocs = getRelocs( - li.sections32init, type='R_386_32', category='32init') - relrelocs = getRelocs( - li.sections32init, type='R_386_PC32', notcategory='32init') - initrelocs = getRelocs( + initsections = dict([(s, 1) for s in li.sections32init]) + noninitsections = dict([(s, 1) for s in ( li.sections32flat + li.sections32low + li.sections16 - + li.sections32seg + li.sections32fseg, category='32init') + + li.sections32seg + li.sections32fseg)]) + absrelocs = getRelocs(initsections, initsections, type='R_386_32') + relrelocs = getRelocs(initsections, noninitsections, type='R_386_PC32') + initrelocs = getRelocs(noninitsections, initsections) relocstr = (strRelocs("_reloc_abs", "code32init_start", absrelocs) + strRelocs("_reloc_rel", "code32init_start", relrelocs) + strRelocs("_reloc_init", "code32flat_start", initrelocs))
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- Makefile | 2 +- scripts/layoutrom.py | 52 ++++++++++++++++++++-------------------------------- 2 files changed, 21 insertions(+), 33 deletions(-)
diff --git a/Makefile b/Makefile index d788ffe..e095601 100644 --- a/Makefile +++ b/Makefile @@ -57,7 +57,7 @@ COMMONCFLAGS := -I$(OUT) -Isrc -Os -MD -g \ -m32 -march=i386 -mregparm=3 -mpreferred-stack-boundary=2 \ -minline-all-stringops \ -freg-struct-return -ffreestanding -fno-delete-null-pointer-checks \ - -ffunction-sections -fdata-sections -fno-common + -ffunction-sections -fdata-sections -fno-common -fno-merge-constants COMMONCFLAGS += $(call cc-option,$(CC),-nopie,) COMMONCFLAGS += $(call cc-option,$(CC),-fno-stack-protector,) COMMONCFLAGS += $(call cc-option,$(CC),-fno-stack-protector-all,) diff --git a/scripts/layoutrom.py b/scripts/layoutrom.py index 3eca823..20ffbe0 100755 --- a/scripts/layoutrom.py +++ b/scripts/layoutrom.py @@ -175,10 +175,7 @@ def doLayout(sections, config, genreloc): # Determine 16bit positions li.sections16 = getSectionsCategory(sections, '16') textsections = getSectionsPrefix(li.sections16, '.text.') - rodatasections = ( - getSectionsPrefix(li.sections16, '.rodata.str1.1') - + getSectionsPrefix(li.sections16, '.rodata.__func__.') - + getSectionsPrefix(li.sections16, '.rodata.__PRETTY_FUNCTION__.')) + rodatasections = getSectionsPrefix(li.sections16, '.rodata') datasections = getSectionsPrefix(li.sections16, '.data16.') fixedsections = getSectionsPrefix(li.sections16, '.fixedaddr.')
@@ -191,10 +188,7 @@ def doLayout(sections, config, genreloc): # Determine 32seg positions li.sections32seg = getSectionsCategory(sections, '32seg') textsections = getSectionsPrefix(li.sections32seg, '.text.') - rodatasections = ( - getSectionsPrefix(li.sections32seg, '.rodata.str1.1') - + getSectionsPrefix(li.sections32seg, '.rodata.__func__.') - + getSectionsPrefix(li.sections32seg, '.rodata.__PRETTY_FUNCTION__.')) + rodatasections = getSectionsPrefix(li.sections32seg, '.rodata') datasections = getSectionsPrefix(li.sections32seg, '.data32seg.')
li.sec32seg_start, li.sec32seg_align = setSectionsStart( @@ -305,6 +299,16 @@ def outXRefs(sections, useseg=0, exportsyms=[], forcedelta=0): out += "%s = 0x%x ;\n" % (symbolname, loc + forcedelta + symbol.offset) return out
+# Write LD script includes for the given sections +def outSections(sections, useseg=0): + out = "" + for section in sections: + loc = section.finalloc + if useseg: + loc = section.finalsegloc + out += "%s 0x%x : { *(%s) }\n" % (section.name, loc, section.name) + return out + # Write LD script includes for the given sections using relative offsets def outRelSections(sections, startsym, useseg=0): sections = [(section.finalloc, section) for section in sections @@ -316,9 +320,9 @@ def outRelSections(sections, startsym, useseg=0): if useseg: loc = section.finalsegloc out += ". = ( 0x%x - %s ) ;\n" % (loc, startsym) - if section.name == '.rodata.str1.1': - out += "_rodata = . ;\n" - out += "*(%s)\n" % (section.name,) + if section.name in ('.rodata.str1.1', '.rodata'): + out += "_rodata%s = . ;\n" % (section.fileid,) + out += "*%s.*(%s)\n" % (section.fileid, section.name) return out
# Build linker script output for a list of relocations. @@ -344,26 +348,17 @@ def writeLinkerScripts(li, out16, out32seg, out32flat): zonelow_base = 0x%x ; _zonelow_seg = 0x%x ;
- code16_start = 0x%x ; - .text16 code16_start : { %s - } """ % (li.zonelow_base, int(li.zonelow_base / 16), - li.sec16_start - BUILD_BIOS_ADDR, - outRelSections(li.sections16, 'code16_start', useseg=1)) + outSections(li.sections16, useseg=1)) outfile = open(out16, 'w') outfile.write(COMMONHEADER + out + COMMONTRAILER) outfile.close()
# Write 32seg linker script - out = outXRefs(li.sections32seg, useseg=1) + """ - code32seg_start = 0x%x ; - .text32seg code32seg_start : { -%s - } -""" % (li.sec32seg_start - BUILD_BIOS_ADDR, - outRelSections(li.sections32seg, 'code32seg_start', useseg=1)) + out = (outXRefs(li.sections32seg, useseg=1) + + outSections(li.sections32seg, useseg=1)) outfile = open(out32seg, 'w') outfile.write(COMMONHEADER + out + COMMONTRAILER) outfile.close() @@ -406,11 +401,6 @@ def writeLinkerScripts(li, out16, out32seg, out32flat): %s code32init_end = ABSOLUTE(.) ; %s -%s - . = ( 0x%x - code32flat_start ) ; - *(.text32seg) - . = ( 0x%x - code32flat_start ) ; - *(.text16) code32flat_end = ABSOLUTE(.) ; } :text """ % (li.sec32init_align, @@ -423,10 +413,8 @@ def writeLinkerScripts(li, out16, out32seg, out32flat): relocstr, outRelSections(li.sections32low, 'code32flat_start'), outRelSections(li.sections32init, 'code32flat_start'), - outRelSections(li.sections32flat, 'code32flat_start'), - outRelSections(li.sections32fseg, 'code32flat_start'), - li.sec32seg_start, - li.sec16_start) + outRelSections(li.sections32flat + li.sections32fseg + + li.sections32seg + li.sections16, 'code32flat_start')) out = COMMONHEADER + out + COMMONTRAILER + """ ENTRY(%s) PHDRS
The 'category' really determines the memory location while the 'fileid' determines which link stage the section is in. So, use 'fileid' when writing the linker scripts.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- scripts/layoutrom.py | 49 ++++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 21 deletions(-)
diff --git a/scripts/layoutrom.py b/scripts/layoutrom.py index 20ffbe0..0b88768 100755 --- a/scripts/layoutrom.py +++ b/scripts/layoutrom.py @@ -149,6 +149,10 @@ def fitSections(sections, fillsections): def getSectionsCategory(sections, category): return [section for section in sections if section.category == category]
+# Return the subset of sections with a given fileid +def getSectionsFileid(sections, fileid): + return [section for section in sections if section.fileid == fileid] + # Return the subset of sections with a given name prefix def getSectionsPrefix(sections, prefix): return [section for section in sections @@ -156,6 +160,7 @@ def getSectionsPrefix(sections, prefix):
# The sections (and associated information) to be placed in output rom class LayoutInfo: + sections = None genreloc = None sections16 = sec16_start = sec16_align = None sections32seg = sec32seg_start = sec32seg_align = None @@ -171,6 +176,7 @@ class LayoutInfo: # Determine final memory addresses for sections def doLayout(sections, config, genreloc): li = LayoutInfo() + li.sections = sections li.genreloc = genreloc # Determine 16bit positions li.sections16 = getSectionsCategory(sections, '16') @@ -344,35 +350,36 @@ def getRelocs(sections, tosection, type=None): # Output the linker scripts for all required sections. def writeLinkerScripts(li, out16, out32seg, out32flat): # Write 16bit linker script - out = outXRefs(li.sections16, useseg=1) + """ + filesections16 = getSectionsFileid(li.sections, '16') + out = outXRefs(filesections16, useseg=1) + """ zonelow_base = 0x%x ; _zonelow_seg = 0x%x ;
%s """ % (li.zonelow_base, int(li.zonelow_base / 16), - outSections(li.sections16, useseg=1)) + outSections(filesections16, useseg=1)) outfile = open(out16, 'w') outfile.write(COMMONHEADER + out + COMMONTRAILER) outfile.close()
# Write 32seg linker script - out = (outXRefs(li.sections32seg, useseg=1) - + outSections(li.sections32seg, useseg=1)) + filesections32seg = getSectionsFileid(li.sections, '32seg') + out = (outXRefs(filesections32seg, useseg=1) + + outSections(filesections32seg, useseg=1)) outfile = open(out32seg, 'w') outfile.write(COMMONHEADER + out + COMMONTRAILER) outfile.close()
# Write 32flat linker script - sections32all = (li.sections32flat + li.sections32init + li.sections32fseg) sec32all_start = li.sec32low_start relocstr = "" if li.genreloc: # Generate relocations - initsections = dict([(s, 1) for s in li.sections32init]) - noninitsections = dict([(s, 1) for s in ( - li.sections32flat + li.sections32low + li.sections16 - + li.sections32seg + li.sections32fseg)]) + initsections = dict([ + (s, 1) for s in getSectionsCategory(li.sections, '32init')]) + noninitsections = dict([(s, 1) for s in li.sections + if s not in initsections]) absrelocs = getRelocs(initsections, initsections, type='R_386_32') relrelocs = getRelocs(initsections, noninitsections, type='R_386_PC32') initrelocs = getRelocs(noninitsections, initsections) @@ -381,25 +388,24 @@ def writeLinkerScripts(li, out16, out32seg, out32flat): + strRelocs("_reloc_init", "code32flat_start", initrelocs)) numrelocs = len(absrelocs + relrelocs + initrelocs) sec32all_start -= numrelocs * 4 - out = outXRefs(li.sections32low, exportsyms=li.varlowsyms + filesections32flat = getSectionsFileid(li.sections, '32flat') + out = outXRefs([], exportsyms=li.varlowsyms , forcedelta=li.final_sec32low_start-li.sec32low_start) - out += outXRefs(sections32all, exportsyms=[li.entrysym]) + """ + out += outXRefs(filesections32flat, exportsyms=[li.entrysym]) + """ _reloc_min_align = 0x%x ; zonefseg_start = 0x%x ; zonefseg_end = 0x%x ; zonelow_base = 0x%x ; final_varlow_start = 0x%x ; final_readonly_start = 0x%x ; + varlow_start = 0x%x ; + varlow_end = 0x%x ; + code32init_start = 0x%x ; + code32init_end = 0x%x ;
code32flat_start = 0x%x ; .text code32flat_start : { %s - varlow_start = ABSOLUTE(.) ; -%s - varlow_end = ABSOLUTE(.) ; - code32init_start = ABSOLUTE(.) ; -%s - code32init_end = ABSOLUTE(.) ; %s code32flat_end = ABSOLUTE(.) ; } :text @@ -409,12 +415,13 @@ def writeLinkerScripts(li, out16, out32seg, out32flat): li.zonelow_base, li.final_sec32low_start, li.final_readonly_start, + li.sec32low_start, + li.sec32init_start, + li.sec32init_start, + li.sec32flat_start, sec32all_start, relocstr, - outRelSections(li.sections32low, 'code32flat_start'), - outRelSections(li.sections32init, 'code32flat_start'), - outRelSections(li.sections32flat + li.sections32fseg - + li.sections32seg + li.sections16, 'code32flat_start')) + outRelSections(li.sections, 'code32flat_start')) out = COMMONHEADER + out + COMMONTRAILER + """ ENTRY(%s) PHDRS
A number of fields were exported from the layout info that weren't used. Don't bother exporting them.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- scripts/layoutrom.py | 130 ++++++++++++++++++++++++++------------------------- 1 file changed, 67 insertions(+), 63 deletions(-)
diff --git a/scripts/layoutrom.py b/scripts/layoutrom.py index 0b88768..ba557e6 100755 --- a/scripts/layoutrom.py +++ b/scripts/layoutrom.py @@ -162,15 +162,11 @@ def getSectionsPrefix(sections, prefix): class LayoutInfo: sections = None genreloc = None - sections16 = sec16_start = sec16_align = None - sections32seg = sec32seg_start = sec32seg_align = None - sections32flat = sec32flat_start = sec32flat_align = None - sections32init = sec32init_start = sec32init_align = None - sections32low = sec32low_start = sec32low_align = None - sections32fseg = sec32fseg_start = sec32fseg_align = None + sec32init_start = sec32init_end = sec32init_align = None + sec32low_start = sec32low_end = None + zonelow_base = final_sec32low_start = None zonefseg_start = zonefseg_end = None final_readonly_start = None - zonelow_base = final_sec32low_start = None varlowsyms = entrysym = None
# Determine final memory addresses for sections @@ -179,101 +175,109 @@ def doLayout(sections, config, genreloc): li.sections = sections li.genreloc = genreloc # Determine 16bit positions - li.sections16 = getSectionsCategory(sections, '16') - textsections = getSectionsPrefix(li.sections16, '.text.') - rodatasections = getSectionsPrefix(li.sections16, '.rodata') - datasections = getSectionsPrefix(li.sections16, '.data16.') - fixedsections = getSectionsPrefix(li.sections16, '.fixedaddr.') + sections16 = getSectionsCategory(sections, '16') + textsections = getSectionsPrefix(sections16, '.text.') + rodatasections = getSectionsPrefix(sections16, '.rodata') + datasections = getSectionsPrefix(sections16, '.data16.') + fixedsections = getSectionsPrefix(sections16, '.fixedaddr.')
firstfixed = fitSections(fixedsections, textsections) remsections = [s for s in textsections+rodatasections+datasections if s.finalloc is None] - li.sec16_start, li.sec16_align = setSectionsStart( + sec16_start, sec16_align = setSectionsStart( remsections, firstfixed, segoffset=BUILD_BIOS_ADDR)
# Determine 32seg positions - li.sections32seg = getSectionsCategory(sections, '32seg') - textsections = getSectionsPrefix(li.sections32seg, '.text.') - rodatasections = getSectionsPrefix(li.sections32seg, '.rodata') - datasections = getSectionsPrefix(li.sections32seg, '.data32seg.') + sections32seg = getSectionsCategory(sections, '32seg') + textsections = getSectionsPrefix(sections32seg, '.text.') + rodatasections = getSectionsPrefix(sections32seg, '.rodata') + datasections = getSectionsPrefix(sections32seg, '.data32seg.')
- li.sec32seg_start, li.sec32seg_align = setSectionsStart( - textsections + rodatasections + datasections, li.sec16_start + sec32seg_start, sec32seg_align = setSectionsStart( + textsections + rodatasections + datasections, sec16_start , segoffset=BUILD_BIOS_ADDR)
# Determine "fseg memory" data positions - li.sections32fseg = getSectionsCategory(sections, '32fseg') + sections32fseg = getSectionsCategory(sections, '32fseg')
- li.sec32fseg_start, li.sec32fseg_align = setSectionsStart( - li.sections32fseg, li.sec32seg_start, 16 + sec32fseg_start, sec32fseg_align = setSectionsStart( + sections32fseg, sec32seg_start, 16 , segoffset=BUILD_BIOS_ADDR)
# Determine 32flat runtime positions - li.sections32flat = getSectionsCategory(sections, '32flat') - textsections = getSectionsPrefix(li.sections32flat, '.text.') - rodatasections = getSectionsPrefix(li.sections32flat, '.rodata') - datasections = getSectionsPrefix(li.sections32flat, '.data.') - bsssections = getSectionsPrefix(li.sections32flat, '.bss.') + sections32flat = getSectionsCategory(sections, '32flat') + textsections = getSectionsPrefix(sections32flat, '.text.') + rodatasections = getSectionsPrefix(sections32flat, '.rodata') + datasections = getSectionsPrefix(sections32flat, '.data.') + bsssections = getSectionsPrefix(sections32flat, '.bss.')
- li.sec32flat_start, li.sec32flat_align = setSectionsStart( + sec32flat_start, sec32flat_align = setSectionsStart( textsections + rodatasections + datasections + bsssections - , li.sec32fseg_start, 16) + , sec32fseg_start, 16)
# Determine 32flat init positions - li.sections32init = getSectionsCategory(sections, '32init') - init32_textsections = getSectionsPrefix(li.sections32init, '.text.') - init32_rodatasections = getSectionsPrefix(li.sections32init, '.rodata') - init32_datasections = getSectionsPrefix(li.sections32init, '.data.') - init32_bsssections = getSectionsPrefix(li.sections32init, '.bss.') + sections32init = getSectionsCategory(sections, '32init') + init32_textsections = getSectionsPrefix(sections32init, '.text.') + init32_rodatasections = getSectionsPrefix(sections32init, '.rodata') + init32_datasections = getSectionsPrefix(sections32init, '.data.') + init32_bsssections = getSectionsPrefix(sections32init, '.bss.')
- li.sec32init_start, li.sec32init_align = setSectionsStart( + sec32init_start, sec32init_align = setSectionsStart( init32_textsections + init32_rodatasections + init32_datasections + init32_bsssections - , li.sec32flat_start, 16) + , sec32flat_start, 16)
# Determine location of ZoneFSeg memory. - li.zonefseg_end = li.sec32flat_start + zonefseg_end = sec32flat_start if not genreloc: - li.zonefseg_end = li.sec32init_start - li.zonefseg_start = BUILD_BIOS_ADDR - if li.zonefseg_start + BUILD_MIN_BIOSTABLE > li.zonefseg_end: + zonefseg_end = sec32init_start + zonefseg_start = BUILD_BIOS_ADDR + if zonefseg_start + BUILD_MIN_BIOSTABLE > zonefseg_end: # Not enough ZoneFSeg space - force a minimum space. - li.zonefseg_end = li.sec32fseg_start - li.zonefseg_start = li.zonefseg_end - BUILD_MIN_BIOSTABLE - li.sec32flat_start, li.sec32flat_align = setSectionsStart( + zonefseg_end = sec32fseg_start + zonefseg_start = zonefseg_end - BUILD_MIN_BIOSTABLE + sec32flat_start, sec32flat_align = setSectionsStart( textsections + rodatasections + datasections + bsssections - , li.zonefseg_start, 16) - li.sec32init_start, li.sec32init_align = setSectionsStart( + , zonefseg_start, 16) + sec32init_start, sec32init_align = setSectionsStart( init32_textsections + init32_rodatasections + init32_datasections + init32_bsssections - , li.sec32flat_start, 16) - li.final_readonly_start = min(BUILD_BIOS_ADDR, li.sec32flat_start) + , sec32flat_start, 16) + li.sec32init_start = sec32init_start + li.sec32init_end = sec32flat_start + li.sec32init_align = sec32init_align + final_readonly_start = min(BUILD_BIOS_ADDR, sec32flat_start) if not genreloc: - li.final_readonly_start = min(BUILD_BIOS_ADDR, li.sec32init_start) + final_readonly_start = min(BUILD_BIOS_ADDR, sec32init_start) + li.zonefseg_start = zonefseg_start + li.zonefseg_end = zonefseg_end + li.final_readonly_start = final_readonly_start
# Determine "low memory" data positions - li.sections32low = getSectionsCategory(sections, '32low') - sec32low_end = li.sec32init_start + sections32low = getSectionsCategory(sections, '32low') + sec32low_end = sec32init_start if config.get('CONFIG_MALLOC_UPPERMEMORY'): - final_sec32low_end = li.final_readonly_start + final_sec32low_end = final_readonly_start zonelow_base = final_sec32low_end - 64*1024 - li.zonelow_base = max(BUILD_ROM_START, alignpos(zonelow_base, 2*1024)) + zonelow_base = max(BUILD_ROM_START, alignpos(zonelow_base, 2*1024)) else: final_sec32low_end = BUILD_LOWRAM_END - li.zonelow_base = final_sec32low_end - 64*1024 + zonelow_base = final_sec32low_end - 64*1024 relocdelta = final_sec32low_end - sec32low_end li.sec32low_start, li.sec32low_align = setSectionsStart( - li.sections32low, sec32low_end, 16 - , segoffset=li.zonelow_base - relocdelta) + sections32low, sec32low_end, 16 + , segoffset=zonelow_base - relocdelta) + li.sec32low_end = sec32low_end + li.zonelow_base = zonelow_base li.final_sec32low_start = li.sec32low_start + relocdelta
# Print statistics - size16 = BUILD_BIOS_ADDR + BUILD_BIOS_SIZE - li.sec16_start - size32seg = li.sec16_start - li.sec32seg_start - size32fseg = li.sec32seg_start - li.sec32fseg_start - size32flat = li.sec32fseg_start - li.sec32flat_start - size32init = li.sec32flat_start - li.sec32init_start - sizelow = sec32low_end - li.sec32low_start + size16 = BUILD_BIOS_ADDR + BUILD_BIOS_SIZE - sec16_start + size32seg = sec16_start - sec32seg_start + size32fseg = sec32seg_start - sec32fseg_start + size32flat = sec32fseg_start - sec32flat_start + size32init = sec32flat_start - sec32init_start + sizelow = li.sec32low_end - li.sec32low_start print("16bit size: %d" % size16) print("32bit segmented size: %d" % size32seg) print("32bit flat size: %d" % size32flat) @@ -416,9 +420,9 @@ def writeLinkerScripts(li, out16, out32seg, out32flat): li.final_sec32low_start, li.final_readonly_start, li.sec32low_start, + li.sec32low_end, li.sec32init_start, - li.sec32init_start, - li.sec32flat_start, + li.sec32init_end, sec32all_start, relocstr, outRelSections(li.sections, 'code32flat_start'))
Update the layoutrom.py build script so that fixed address sections can come from the 32bit compiled C code. Update the C code so that all VAR16FIXED variables instead use the new VARFSEGFIXED which is defined in 32bit mode.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- Makefile | 11 ++++++----- scripts/layoutrom.py | 8 +++++--- src/font.c | 2 +- src/misc.c | 18 +++++++++--------- src/types.h | 8 ++++---- 5 files changed, 25 insertions(+), 22 deletions(-)
diff --git a/Makefile b/Makefile index e095601..e492f80 100644 --- a/Makefile +++ b/Makefile @@ -27,17 +27,18 @@ IASL:=iasl LD32BIT_FLAG:=-melf_i386
# Source files -SRCBOTH=misc.c stacks.c output.c string.c x86.c block.c cdrom.c mouse.c kbd.c \ - serial.c clock.c resume.c pnpbios.c vgahooks.c pcibios.c apm.c \ +SRCBOTH=misc.c stacks.c output.c string.c x86.c block.c cdrom.c \ + system.c disk.c mouse.c kbd.c serial.c clock.c resume.c \ + pnpbios.c vgahooks.c pcibios.c apm.c \ hw/pci.c hw/timer.c hw/rtc.c hw/dma.c hw/pic.c hw/ps2port.c hw/serialio.c \ hw/usb.c hw/usb-uhci.c hw/usb-ohci.c hw/usb-ehci.c \ hw/usb-hid.c hw/usb-msc.c hw/usb-uas.c \ hw/blockcmd.c hw/floppy.c hw/ata.c hw/ramdisk.c \ hw/virtio-ring.c hw/virtio-pci.c hw/virtio-blk.c hw/virtio-scsi.c \ hw/lsi-scsi.c hw/esp-scsi.c hw/megasas.c -SRC16=$(SRCBOTH) system.c disk.c font.c -SRC32FLAT=$(SRCBOTH) post.c memmap.c malloc.c pmm.c romfile.c optionroms.c \ - boot.c bootsplash.c jpeg.c bmp.c \ +SRC16=$(SRCBOTH) +SRC32FLAT=$(SRCBOTH) post.c memmap.c malloc.c romfile.c optionroms.c \ + pmm.c font.c boot.c bootsplash.c jpeg.c bmp.c \ hw/ahci.c hw/pvscsi.c hw/usb-xhci.c hw/usb-hub.c \ fw/coreboot.c fw/lzmadecode.c fw/csm.c fw/biostables.c \ fw/paravirt.c fw/shadow.c fw/pciinit.c fw/smm.c fw/smp.c fw/mtrr.c fw/xen.c \ diff --git a/scripts/layoutrom.py b/scripts/layoutrom.py index ba557e6..bd90706 100755 --- a/scripts/layoutrom.py +++ b/scripts/layoutrom.py @@ -179,7 +179,7 @@ def doLayout(sections, config, genreloc): textsections = getSectionsPrefix(sections16, '.text.') rodatasections = getSectionsPrefix(sections16, '.rodata') datasections = getSectionsPrefix(sections16, '.data16.') - fixedsections = getSectionsPrefix(sections16, '.fixedaddr.') + fixedsections = getSectionsCategory(sections, 'fixed')
firstfixed = fitSections(fixedsections, textsections) remsections = [s for s in textsections+rodatasections+datasections @@ -643,7 +643,7 @@ def main(): else: entrysym = symbols['16'].get('reset_vector') anchorsections = [entrysym.section] + [ - section for section in info16[0] + section for section in allsections if section.name.startswith('.fixedaddr.')] keepsections = findReachable(anchorsections, checkKeep, symbols) sections = [section for section in allsections if section in keepsections] @@ -652,13 +652,15 @@ def main(): anchorsections = [ section for section in sections if ('.data.varlow.' in section.name or '.data.varfseg.' in section.name - or '.runtime.' in section.name)] + or '.fixedaddr.' in section.name or '.runtime.' in section.name)] runtimesections = findReachable(anchorsections, checkRuntime, None) for section in sections: if section.name.startswith('.data.varlow.'): section.category = '32low' elif section.name.startswith('.data.varfseg.'): section.category = '32fseg' + elif section.name.startswith('.fixedaddr.'): + section.category = 'fixed' elif section.fileid == '32flat' and section not in runtimesections: section.category = '32init' else: diff --git a/src/font.c b/src/font.c index 3f8662f..67e5d46 100644 --- a/src/font.c +++ b/src/font.c @@ -7,7 +7,7 @@ * found at ftp://ftp.simtel.net/pub/simtelnet/msdos/screen/fntcol16.zip * This font is public domain */ -u8 vgafont8[128*8] VAR16FIXED(0xfa6e) = { +u8 vgafont8[128*8] VARFSEGFIXED(0xfa6e) = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, 0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e, diff --git a/src/misc.c b/src/misc.c index 889064a..8caaf31 100644 --- a/src/misc.c +++ b/src/misc.c @@ -117,7 +117,7 @@ handle_75(void) // INT 16/AH=09h (keyboard functionality) supported #define CBT_F2_INT1609 (1<<6)
-struct bios_config_table_s BIOS_CONFIG_TABLE VAR16FIXED(0xe6f5) = { +struct bios_config_table_s BIOS_CONFIG_TABLE VARFSEGFIXED(0xe6f5) = { .size = sizeof(BIOS_CONFIG_TABLE) - 2, .model = BUILD_MODEL_ID, .submodel = BUILD_SUBMODEL_ID, @@ -182,22 +182,22 @@ struct descloc_s rombios32_gdt_48 VARFSEG = { ****************************************************************/
// BIOS build date -char BiosDate[] VAR16FIXED(0xfff5) = "06/23/99"; +char BiosDate[] VARFSEGFIXED(0xfff5) = "06/23/99";
-u8 BiosModelId VAR16FIXED(0xfffe) = BUILD_MODEL_ID; +u8 BiosModelId VARFSEGFIXED(0xfffe) = BUILD_MODEL_ID;
-u8 BiosChecksum VAR16FIXED(0xffff); +u8 BiosChecksum VARFSEGFIXED(0xffff);
-struct floppy_dbt_s diskette_param_table VAR16FIXED(0xefc7); +struct floppy_dbt_s diskette_param_table VARFSEGFIXED(0xefc7);
// Old Fixed Disk Parameter Table (newer tables are in the ebda). -struct fdpt_s OldFDPT VAR16FIXED(0xe401); +struct fdpt_s OldFDPT VARFSEGFIXED(0xe401);
// XXX - Baud Rate Generator Table -u8 BaudTable[16] VAR16FIXED(0xe729); +u8 BaudTable[16] VARFSEGFIXED(0xe729);
// XXX - Initial Interrupt Vector Offsets Loaded by POST -u8 InitVectors[13] VAR16FIXED(0xfef3); +u8 InitVectors[13] VARFSEGFIXED(0xfef3);
// XXX - INT 1D - SYSTEM DATA - VIDEO PARAMETER TABLES -u8 VideoParams[88] VAR16FIXED(0xf0a4); +u8 VideoParams[88] VARFSEGFIXED(0xf0a4); diff --git a/src/types.h b/src/types.h index 3466b3a..097372c 100644 --- a/src/types.h +++ b/src/types.h @@ -62,14 +62,14 @@ extern void __force_link_error__only_in_16bit(void) __noreturn; # define VISIBLE32SEG // Designate a variable as (only) visible to 16bit code. # define VAR16 __section(".data16." UNIQSEC) -// Designate a variable at a specific 16bit address -# define VAR16FIXED(addr) __aligned(1) __VISIBLE __section(".fixedaddr." __stringify(addr)) // Designate a variable as (only) visible to 32bit segmented code. # define VAR32SEG __section(".discard.var32seg." UNIQSEC) // Designate a variable as visible and located in the e-segment. # define VARLOW __section(".discard.varlow." UNIQSEC) __VISIBLE __weak // Designate a variable as visible and located in the f-segment. # define VARFSEG __section(".discard.varfseg." UNIQSEC) __VISIBLE __weak +// Designate a variable at a specific address in the f-segment. +# define VARFSEGFIXED(addr) __section(".discard.varfixed." UNIQSEC) __VISIBLE __weak // Verify a variable is only accessable via 32bit "init" functions # define VARVERIFY32INIT __section(".discard.varinit." UNIQSEC) // Designate top-level assembler as 16bit only. @@ -86,10 +86,10 @@ extern void __force_link_error__only_in_16bit(void) __noreturn; # define VISIBLE32INIT # define VISIBLE32SEG __VISIBLE # define VAR16 __section(".discard.var16." UNIQSEC) -# define VAR16FIXED(addr) VAR16 __VISIBLE __weak # define VAR32SEG __section(".data32seg." UNIQSEC) # define VARLOW __section(".discard.varlow." UNIQSEC) __VISIBLE __weak # define VARFSEG __section(".discard.varfseg." UNIQSEC) __VISIBLE __weak +# define VARFSEGFIXED(addr) __section(".discard.varfixed." UNIQSEC) __VISIBLE __weak # define VARVERIFY32INIT __section(".discard.varinit." UNIQSEC) # define ASM16(code) # define ASM32FLAT(code) @@ -102,10 +102,10 @@ extern void __force_link_error__only_in_16bit(void) __noreturn; # define VISIBLE32INIT __section(".text.init." UNIQSEC) __VISIBLE # define VISIBLE32SEG # define VAR16 __section(".discard.var16." UNIQSEC) -# define VAR16FIXED(addr) VAR16 __VISIBLE __weak # define VAR32SEG __section(".discard.var32seg." UNIQSEC) # define VARLOW __section(".data.varlow." UNIQSEC) __VISIBLE __weak # define VARFSEG __section(".data.varfseg." UNIQSEC) __VISIBLE +# define VARFSEGFIXED(addr) __section(".fixedaddr." __stringify(addr)) __VISIBLE __aligned(1) # define VARVERIFY32INIT __section(".data.varinit." UNIQSEC) # define ASM16(code) # define ASM32FLAT(code) __ASM(code)
On Wed, Jun 11, 2014 at 03:20:03PM -0400, Kevin O'Connor wrote:
This series updates the build (and layoutrom.py in particular) to be more flexible in section layouts. Prior to this series, only code compiled in the 16bit mode pass could be placed at a fixed address in the f-segment. After this change, the build can more easily place sections from any compile pass.
Most of the series consists of minor cleanups to layoutrom.py to make the above happen. Patch 4 is an unrelated minor feature enhancement.
Otherwise, patches 7 and 10 are where the real changes occur.
FYI, I have pushed this series.
-Kevin