// 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
# 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.
#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
# 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()
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
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
######################################################################
""" % (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')
+ """
output.close()
+######################################################################
+# 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
######################################################################
class Section:
name = size = alignment = fileid = relocs = None
- finalloc = keep = None
+ finalloc = category = keep = None
class Reloc:
offset = type = symbol = None
class Symbol:
# 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)