Enhance tools/layoutrom.py code so that it can detect which sections are used from the "32bit flat" runtime code. All other "32bit flat" sections can then be assured to be initialization code only.
This is in preparation for relocating the 32bit initialization code. --- src/post.c | 2 +- src/stacks.c | 4 +- src/types.h | 10 ++++++-- tools/layoutrom.py | 53 +++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 60 insertions(+), 9 deletions(-)
diff --git a/src/post.c b/src/post.c index 5d0e2cb..6cd94ce 100644 --- a/src/post.c +++ b/src/post.c @@ -178,7 +178,7 @@ init_hw(void) }
// Main setup code. -static void +void VISIBLE32INIT post(void) { // Detect and init ram. diff --git a/src/stacks.c b/src/stacks.c index f5feeeb..dade3af 100644 --- a/src/stacks.c +++ b/src/stacks.c @@ -1,6 +1,6 @@ // Code for manipulating stack locations. // -// Copyright (C) 2009 Kevin O'Connor kevin@koconnor.net +// Copyright (C) 2009-2010 Kevin O'Connor kevin@koconnor.net // // This file may be distributed under the terms of the GNU LGPLv3 license.
@@ -383,7 +383,7 @@ wait_preempt(void) extern void yield_preempt(void); #if MODESEGMENT == 0 // Try to execute 32bit threads. -void VISIBLE32FLAT +void VISIBLE32INIT yield_preempt(void) { PreemptCount++; diff --git a/src/types.h b/src/types.h index 5083941..7d610ec 100644 --- a/src/types.h +++ b/src/types.h @@ -1,6 +1,6 @@ // Basic type definitions for X86 cpus. // -// Copyright (C) 2008,2009 Kevin O'Connor kevin@koconnor.net +// Copyright (C) 2008-2010 Kevin O'Connor kevin@koconnor.net // // This file may be distributed under the terms of the GNU LGPLv3 license. #ifndef __TYPES_H @@ -45,6 +45,8 @@ extern void __force_link_error__only_in_16bit(void) __noreturn; # define VISIBLE16 __VISIBLE // Notes a function as externally visible in the 32bit flat code chunk. # define VISIBLE32FLAT __section(".discard.func32flat." UNIQSEC) noinline __weak +// Notes a 32bit flat function that will only be called during init. +# define VISIBLE32INIT VISIBLE32FLAT // Notes a function as externally visible in the 32bit segmented code chunk. # define VISIBLE32SEG __section(".discard.func32seg." UNIQSEC) noinline __weak // Designate a variable as (only) visible to 16bit code. @@ -70,6 +72,7 @@ extern void __force_link_error__only_in_16bit(void) __noreturn; #elif MODESEGMENT == 1 # define VISIBLE16 __section(".discard.func16." UNIQSEC) noinline __weak # define VISIBLE32FLAT __section(".discard.func32flat." UNIQSEC) noinline __weak +# define VISIBLE32INIT VISIBLE32FLAT # define VISIBLE32SEG __VISIBLE # define VAR16 __section(".discard.var16." UNIQSEC) # define VAR16VISIBLE VAR16 __VISIBLE __weak @@ -84,14 +87,15 @@ extern void __force_link_error__only_in_16bit(void) __noreturn; # define ASSERT32FLAT() __force_link_error__only_in_32bit_flat() #else # define VISIBLE16 __section(".discard.func16." UNIQSEC) noinline __weak -# define VISIBLE32FLAT __VISIBLE +# define VISIBLE32FLAT __section(".text.runtime." UNIQSEC) __VISIBLE +# define VISIBLE32INIT __section(".text.init." UNIQSEC) __VISIBLE # define VISIBLE32SEG __section(".discard.func32seg." UNIQSEC) noinline __weak # define VAR16 __section(".discard.var16." UNIQSEC) # define VAR16VISIBLE VAR16 __VISIBLE __weak # define VAR16EXPORT VAR16VISIBLE # define VAR16FIXED(addr) VAR16VISIBLE # define VAR32SEG __section(".discard.var32seg." UNIQSEC) -# define VAR32FLATVISIBLE __VISIBLE +# define VAR32FLATVISIBLE __section(".data.runtime." UNIQSEC) __VISIBLE # define ASM16(code) # define ASM32FLAT(code) __ASM(code) # define ASSERT16() __force_link_error__only_in_16bit() diff --git a/tools/layoutrom.py b/tools/layoutrom.py index ac6fd14..ca8cb3c 100755 --- a/tools/layoutrom.py +++ b/tools/layoutrom.py @@ -140,9 +140,9 @@ def fitSections(sections, fillsections): return firstfixed
# Return the subset of sections with a given name prefix -def getSectionsPrefix(sections, fileid, prefix): +def getSectionsPrefix(sections, category, prefix): return [section for section in sections - if section.fileid == fileid and section.name.startswith(prefix)] + if section.category == category and section.name.startswith(prefix)]
def doLayout(sections): # Determine 16bit positions @@ -176,13 +176,25 @@ def doLayout(sections): textsections + rodatasections + datasections + bsssections , code32seg_start + BUILD_BIOS_ADDR, 16)
+ # Determine 32flat init positions + textsections = getSectionsPrefix(sections, '32init', '.text.') + rodatasections = getSectionsPrefix(sections, '32init', '.rodata') + datasections = getSectionsPrefix(sections, '32init', '.data.') + bsssections = getSectionsPrefix(sections, '32init', '.bss.') + + code32init_start = setSectionsStart( + textsections + rodatasections + datasections + bsssections + , code32flat_start, 16) + # Print statistics size16 = BUILD_BIOS_SIZE - code16_start size32seg = code16_start - code32seg_start size32flat = code32seg_start + BUILD_BIOS_ADDR - code32flat_start + size32init = code32flat_start - code32init_start print "16bit size: %d" % size16 print "32bit segmented size: %d" % size32seg print "32bit flat size: %d" % size32flat + print "32bit flat init size: %d" % size32init
###################################################################### @@ -271,6 +283,11 @@ def writeLinkerScripts(sections, entrysym, out16, out32seg, out32flat): """ % (entrysym.name, entrysym.section.finalloc + entrysym.offset + BUILD_BIOS_ADDR, code32flat_start) + + outRelSections(getSectionsPrefix(sections32flat, '32init', '') + , 'code32flat_start') + + """ + code32init_end = ABSOLUTE(.) ; +""" + outRelSections(getSectionsPrefix(sections32flat, '32flat', '') , 'code32flat_start') + """ @@ -293,6 +310,33 @@ PHDRS
###################################################################### +# Detection of init code +###################################################################### + +def markRuntime(section, sections): + if (section is None or not section.keep or section.category is not None + or '.init.' in section.name or section.fileid != '32flat'): + return + section.category = '32flat' + # Recursively mark all sections this section points to + for reloc in section.relocs: + markRuntime(reloc.symbol.section, sections) + +def findInit(sections): + # Recursively find and mark all "runtime" sections. + for section in sections: + if '.runtime.' in section.name or '.export.' in section.name: + markRuntime(section, sections) + for section in sections: + if section.category is not None: + continue + if section.fileid == '32flat': + section.category = '32init' + else: + section.category = section.fileid + + +###################################################################### # Section garbage collection ######################################################################
@@ -347,7 +391,7 @@ def gc(info16, info32seg, info32flat):
class Section: name = size = alignment = fileid = relocs = None - finalloc = keep = None + finalloc = category = keep = None class Reloc: offset = type = symbol = None class Symbol: @@ -437,6 +481,9 @@ def main(): # Figure out which sections to keep. sections = gc(info16, info32seg, info32flat)
+ # Separate 32bit flat into runtime and init parts + findInit(sections) + # Determine the final memory locations of each kept section. # locsX = [(addr, sectioninfo), ...] doLayout(sections)