diff --git a/.gitignore b/.gitignore
index 378eac2..916f4b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,6 @@
build
+*~
+.sconsign.dblite
+*.pyc
+config.log
+crt0.o
diff --git a/SConstruct b/SConstruct
index d94da0d..60f239c 100644
--- a/SConstruct
+++ b/SConstruct
@@ -1,459 +1,304 @@
+# -*- mode: python; coding: utf-8; -*-
+
+# Codezero -- a microkernel for embedded systems.
#
-# Almost enough mechanism to build a toy OS
+# Copyright © 2009 B Labs Ltd
#
-# Copyright (C) 2007 Bahadir Balban
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
+
+# To support Python 2.5 we need the following, which seems to do no harm in Python 2.6. Only if Python 2.6
+# is the floor version supported can be dispensed with.
+
+from __future__ import with_statement
+
import os
-import sys
-import shutil
-from string import split
-from os.path import join
-from os import sys
-import glob
-
-# The root directory of the repository where this file resides:
-project_root = os.getcwd()
-source_root = os.path.join(project_root, 'src')
-headers_root = os.path.join(project_root, 'include')
-project_tools_root = os.path.join(project_root, 'tools')
-cml2_tools_root = os.path.join(project_tools_root, 'cml2-tools')
-config_h = os.path.join(headers_root, "l4/config.h")
-
-# Make sure python modules can be imported from tools and cml-tools
-sys.path.append(project_tools_root)
-sys.path.append(cml2_tools_root)
-
-import cml2header
-import cmlconfigure
-
-# The linker script to link the final executable
-linker_script = join(headers_root, 'l4/arch/arm/linker.lds')
-
-# Environment to build sources
-#env = None
-
-###########################################
-# #
-# ARM kernel build environment #
-# #
-###########################################
-
-kernel_env = Environment(CC = 'arm-none-eabi-gcc',
- # We don't use -nostdinc because sometimes we need standard headers,
- # such as stdarg.h e.g. for variable args, as in printk().
- CCFLAGS = ['-g', '-mcpu=arm926ej-s', '-nostdlib', '-ffreestanding', \
- '-std=gnu99', '-Wall', '-Werror'],
- LINKFLAGS = ['-nostdlib', '-T' + linker_script],
- ASFLAGS = ['-D__ASSEMBLY__'],
- PROGSUFFIX = '.axf', # The suffix to use for final executable
- ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
- LIBS = 'gcc', # libgcc.a - This is required for division routines.
- CPPPATH = headers_root,
- CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h -D__KERNEL__')
-
-#########################################
-# #
-# TEST BUILDING ENVIRONMENT #
-# #
-#########################################
-
-# The purpose of test build is somewhat similar to regression/unit
-# testing. There are individual tests for each interesting
-# function/module (e.g. memory allocator layers). For each individual
-# test only the relevant sources' SConscript files are picked up.
-# So we don't build a whole kernel, but many little individual tests.
-tests_env = Environment(CC = 'gcc -m32',
- CCFLAGS = ['-g', '-std=gnu99', '-Wall', '-Werror'],
- ENV = {'PATH' : os.environ['PATH']},
- LIBS = 'gcc',
- CPPPATH = '#include',
- CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h -D__KERNEL__')
-
-# Dictionary mappings for configuration symbols to directories of
-# sources that relate to those symbols.
-arch_to_dir = { 'ARCH_ARM' : 'arm', \
- 'ARCH_TEST' : 'tests' }
-plat_to_dir = { 'ARM_PLATFORM_PB926' : 'pb926', \
- 'TEST_PLATFORM' : 'tests' }
-subarch_to_dir = { 'ARM_SUBARCH_V5' : 'v5', \
- 'TEST_SUBARCH' : 'tests' }
-driver_to_dir = { 'DRIVER_UART_PL011' : 'uart/pl011', \
- 'DRIVER_TIMER_SP804' : 'timer/sp804', \
- 'DRIVER_IRQCTRL_PL190' : 'irq/pl190' }
-
-arch_to_env = { 'arm' : kernel_env, \
- 'tests' : tests_env }
-
-def kprocess_config_symbols(config_symbols):
- '''
- Checks configuration symbols and discovers the directories with
- SConscripts that needs to be compiled for those symbols.
- Also derives symbols and adds them to CPPFLAGS.
- '''
- archdir = None
- subarchdir = None
- platdir = None
- driversdirs = []
- for sym in config_symbols:
- for arch in arch_to_dir:
- if sym == arch:
- archdir = arch_to_dir[arch]
- env = arch_to_env[arch]
- Export('env')
- if arch == 'ARCH_TEST':
- env.Append(CPPFLAGS = '-DSUBARCH_TEST ')
- env.Append(CPPFLAGS = '-DPLATFORM_TEST ')
- subarchdir = "tests"
- platdir = "tests"
- for subarch in subarch_to_dir:
- if sym == subarch:
- subarchdir = subarch_to_dir[subarch]
- for plat in plat_to_dir:
- if sym == plat:
- platdir = plat_to_dir[plat]
- for driver in driver_to_dir:
- if sym == driver:
- # There can me multiple drivers, so making a list.
- driversdirs.append(driver_to_dir[driver])
- if archdir == None:
- print "Error: No config symbol found for architecture"
- sys.exit()
- if subarchdir == None:
- print "Error: No config symbol found for subarchitecture"
- sys.exit()
- if platdir == None:
- print "Error: No config symbol found for platform"
- sys.exit()
-
- # Update config.h with derived values. Unfortunately CML2 does not handle
- # derived symbols well yet. This can be fixed in the future.
- f = open(config_h, "a")
- f.seek(0, 2)
- f.write("/* Symbols derived from this file by SConstruct\process_config_symbols() */")
- f.write("\n#define __ARCH__\t\t%s\n" % archdir)
- f.write("#define __PLATFORM__\t\t%s\n" % platdir)
- f.write("#define __SUBARCH__\t\t%s\n\n" % subarchdir)
- f.close()
- return archdir, subarchdir, platdir, driversdirs
-def process_config_symbols(config_symbols):
- '''
- Checks configuration symbols and discovers the directories with
- SConscripts that needs to be compiled for those symbols.
- '''
- archdir = None
- subarchdir = None
- platdir = None
- driversdirs = []
- for sym,val in config_symbols:
- if sym == "__ARCH__":
- archdir = val
- env = arch_to_env[val]
- Export('env')
- if sym == "__PLATFORM__":
- platdir = val
- if sym == "__SUBARCH__":
- subarchdir = val
- for driver in driver_to_dir:
- if sym == driver:
- # There can me multiple drivers, so making a list.
- driversdirs.append(driver_to_dir[driver])
- if archdir == None:
- print "Error: No config symbol found for architecture"
- sys.exit()
- if subarchdir == None:
- print "Error: No config symbol found for subarchitecture"
- sys.exit()
- if platdir == None:
- print "Error: No config symbol found for platform"
- sys.exit()
+includeDirectory = 'include'
+toolsDirectory = 'tools'
+cml2ToolsDirectory = toolsDirectory + '/cml2-tools'
+buildDirectory = 'build'
- return archdir, subarchdir, platdir, driversdirs
+cml2CompileRulesFile = buildDirectory + '/cml2Rules.out'
+cml2ConfigPropertiesFile = buildDirectory + '/cml2Config.out'
+cml2ConfigHeaderFile = buildDirectory + '/cml2Config.h'
-def gather_config_symbols(header_file):
- '''
- Gathers configuration symbols from config.h to be used in the build. This
- is particularly used for determining what sources to build. Each Sconscript
- has the option to select sources to build based on the symbols imported to it.
- '''
- if not os.path.exists(header_file):
- print "\n\%s does not exist. "\
- "Please run: `scons configure' first\n\n" % header_file
- sys.exit()
- f = open(header_file)
- config_symbols = []
- while True:
- line = f.readline()
- if line == "":
- break
- str_parts = split(line)
- if len(str_parts) > 0:
- if str_parts[0] == "#define":
- config_symbols.append((str_parts[1], str_parts[2]))
- f.close()
- Export('config_symbols')
- return config_symbols
+# The choice of which parts of the kernel to compile and include in the build depends on the configuration
+# which is managed using CML2. CML2 uses a base configuration file (currently #configs/arm.cml) to drive
+# an interaction with the user which results in a trio of files that specify the user choice.
+#
+# cml2RulesFile is the pickled version of the source configuration driver.
+#
+# cml2Config.out is a properties type representation of the user selected configuration data.
+#
+# cml2Config.h is a C include file representation of the user selected configuration data derived from
+# cml2Config.out, it is essential for the compilation of the C code of the kernel and the tasks.
+#
+# Since the DAG for building the kernel relies on the information from the configuration split the build
+# into two distinct phases as Autotools and Waf do, configure then build. Achieve this by partitioning the
+# SCons DAG building in two depending on the command line.
-def gather_sconscripts(config_symbols):
- "Gather all SConscripts to be compiled depending on configuration symbols"
- arch, subarch, plat, drivers = process_config_symbols(config_symbols)
- dirpath = []
- allpaths = []
+if 'configure' in COMMAND_LINE_TARGETS :
- # Paths for the SConscripts: sc_ etc. glob.glob is useful in that
- # it returns `None' for non-existing paths.
- sc_generic = glob.glob("src/generic/SConscript")
- sc_api = glob.glob("src/api/SConscript")
- sc_lib = glob.glob("src/lib/SConscript")
- sc_platform = glob.glob("src/platform/" + plat + "/SConscript")
- sc_arch = glob.glob("src/arch/" + arch + "/SConscript")
- sc_glue = glob.glob("src/glue/" + arch + "/SConscript")
- sc_subarch = glob.glob("src/arch/" + arch + "/" + subarch + "/SConscript")
- sc_drivers = []
- for driver in drivers:
- sc_drivers.append("src/drivers/" + driver + "/SConscript")
- #print "\nSConscripts collected for this build:"
- for dirpath in [sc_generic, sc_api, sc_lib, sc_platform, sc_arch, sc_subarch, sc_glue]:
- for path in dirpath:
- # print path
- allpaths.append(join(os.getcwd(), path[:-11]))
- for drvpath in sc_drivers:
- allpaths.append(join(os.getcwd(), drvpath[:-11]))
- return allpaths
+ def performCML2Configuration(target, source, env):
+ if not os.path.isdir(buildDirectory) : os.mkdir(buildDirectory)
+ os.system(cml2ToolsDirectory + '/cmlcompile.py -o ' + cml2CompileRulesFile + ' ' + source[0].path)
+ os.system(cml2ToolsDirectory + '/cmlconfigure.py -c -o ' + cml2ConfigPropertiesFile + ' ' + cml2CompileRulesFile)
+ os.system(toolsDirectory + '/cml2header.py -o ' + cml2ConfigHeaderFile + ' -i ' + cml2ConfigPropertiesFile)
-def gather_kernel_build_paths(scons_script_path_list):
- '''
- Takes the list of all SConscript files, and returns the list of
- corresponding build directories for each SConscript file.
- '''
- build_path_list = []
- for path in scons_script_path_list:
- build_path_list.append('build' + path)
- return build_path_list
+ if len ( COMMAND_LINE_TARGETS ) != 1:
+ print '#### Warning####: configure is part of the command line, all the other targets are being ignored as this is a configure step.'
+ Command('configure', ['#configs/arm.cml'], performCML2Configuration)
+ Clean('configure', buildDirectory)
-def declare_kernel_build_paths(script_paths):
- '''
- Gathers all SConscript files and their corresponding
- distinct build directories. Declares the association
- to the scons build system.
- '''
- # Get all the script and corresponding build paths
- build_paths = gather_kernel_build_paths(script_paths)
- script_paths.sort()
- build_paths.sort()
+else :
- # Declare build paths
- for script_path, build_path in zip(script_paths, build_paths):
-# print "Sources in " + script_path + " will be built in: " + build_path
- BuildDir(build_path, script_path)
+ if not os.path.exists(cml2ConfigPropertiesFile):
+ print "####\n#### Configuration has not been undertaken, please run 'scons configure'.\n####"
+ Exit()
- return build_paths
+########## Create the base environment and process the configuration ########################
-def build_and_gather(bpath_list):
- '''
- Given a SConscript build path list, declares all
- SConscript files and builds them, gathers and
- returns the resulting object files.
- '''
- obj_list = []
- for path in bpath_list:
-# print "Building files in: " + path
- o = SConscript(path + '/' + 'SConscript')
- obj_list.append(o)
- return obj_list
+ def processCML2Config():
+ configItems = {}
+ with file(cml2ConfigPropertiesFile) as configFile:
+ for line in configFile:
+ item = line.split('=')
+ if len(item) == 2:
+ configItems[item[0].strip()] = (item[1].strip() == 'y')
+ return configItems
+
+ baseEnvironment = Environment(tools = ['gnulink', 'gcc', 'gas', 'ar'],
+ ENV = {'PATH': os.environ['PATH']},
+ configFiles = ('#' + cml2CompileRulesFile, '#' + cml2ConfigPropertiesFile, '#' + cml2ConfigHeaderFile))
-def determine_target(config_symbols):
- if "ARCH_TEST" in config_symbols:
- target = "tests"
- else:
- target = "kernel"
- return target
+ kernelSConscriptPaths = ['generic', 'api', 'lib']
-def build_kernel_objs(config_symbols):
- "Builds the final kernel executable."
- # Declare builddir <--> SConscript association
- script_paths = gather_sconscripts(config_symbols)
- build_paths = declare_kernel_build_paths(script_paths)
- # Declare Sconscript files, build and gather objects.
- objs = build_and_gather(build_paths)
- return objs
+ # It is assumed that the C code is assuming that the configuration file will be found at l4/config.h so create it there.
+ #
+ # Kernel code include config.h in a different way to all the other bits of code.
+ #
+ # TODO: Decide if this is an issue or not.
-#################################################################
-# Kernel and Test Targets #
-# Executes python functions and compiles the kernel. #
-#################################################################
+ configuration = Configure(baseEnvironment, config_h = buildDirectory + '/l4/config.h')
+ configData = processCML2Config()
+ arch = None
+ platform = None
+ subarch = None
+ for key, value in configData.items():
+ if value:
+ items = key.split('_')
+ if items[0] == 'ARCH':
+ arch = items[1].lower()
+ for key, value in configData.items():
+ if value:
+ items = key.split('_')
+ if items[0] == arch.upper():
+ if items[1] == 'PLATFORM':
+ platform = items[2].lower()
+ if items[1] == 'SUBARCH':
+ subarch = items[2].lower()
+ if items[0] == 'DRIVER':
+ kernelSConscriptPaths.append('drivers/' + ('irq' if items[1] == 'IRQCTRL' else items[1].lower()) + '/' + items[2].lower())
+ configuration.Define('__ARCH__', arch)
+ configuration.Define('__PLATFORM__', platform)
+ configuration.Define('__SUBARCH__', subarch)
+ kernelSConscriptPaths += [
+ 'arch/' + arch,
+ 'glue/' + arch,
+ 'platform/' + platform,
+ 'arch/' + arch + '/' + subarch]
+ configuration.env['ARCH'] = arch
+ configuration.env['PLATFORM'] = platform
+ configuration.env['SUBARCH'] = subarch
+ baseEnvironment = configuration.Finish()
-# Unfortunately the build system is imperative rather than declarative,
-# and this is the entry point. This inconvenience is due to the fact that
-# it is not easily possible in SCons to produce a target list dynamically,
-# which, is generated by the `configure' target.
+########## Build the libraries ########################
-if "build" in COMMAND_LINE_TARGETS:
- config_symbols = gather_config_symbols(config_h)
- target = determine_target(config_symbols)
- if target == "kernel":
- built_objs = build_kernel_objs(config_symbols)
- kernel_target = kernel_env.Program('build/start', built_objs)
- kernel_env.Alias('build', kernel_target)
- elif target == "tests":
- built_objs = build_kernel_objs(config_symbols)
- tests_target = tests_env.Program('build/tests', built_objs)
- tests_env.Alias('build', tests_target)
- else:
- print "Invalid or unknown target.\n"
+ libraryEnvironment = baseEnvironment.Clone(
+ CC = 'arm-none-linux-gnueabi-gcc',
+ CCFLAGS = ['-g', '-nostdinc', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
+ LINKFLAGS = ['-nostdlib'],
+ LIBS = ['gcc'],
+ ARCH = arch,
+ PLATFORM = platform)
-#################################################################
-# The Configuration Targets: #
-# Executes python functions/commands to configure the kernel. #
-#################################################################
-# Configuration Build Details: #
-# ---------------------------- #
-# 1) Compiles the ruleset for given architecture/platform. #
-# 2) Invokes the CML2 kernel configurator using the given #
-# ruleset. #
-# 3) Configurator output is translated into a header file. #
-# #
-# For more information on this see the cml2 manual. Recap: #
-# The cml file defines the rules (i.e. option a and b #
-# implies c etc.) The compiler converts it to a pickled #
-# form. The configurator reads it and brings up a UI menu. #
-# Saving the selections results in a configuration file, #
-# which in turn is converted to a header file includable #
-# by the C sources. #
-#################################################################
+ libs = {}
+ crts = {}
+ for variant in ['baremetal', 'userspace']:
+ (libs[variant], crts[variant]) = SConscript('libs/c/SConscript', variant_dir = buildDirectory + '/lib/c/' + variant, duplicate = 0, exports = {'environment': libraryEnvironment, 'variant': variant})
+ Depends((libs[variant], crts[variant]), libraryEnvironment['configFiles'])
-def cml_configure(target, source, env):
+ baseEnvironment['baremetal_libc'] = libs['baremetal']
+ baseEnvironment['baremetal_crt0'] = crts['baremetal']
+ baseEnvironment['userspace_libc'] = libs['userspace']
+ baseEnvironment['userspace_crt0'] = crts['userspace']
- default_target = 'config.out'
- default_source = 'rules.out'
+ libelf = SConscript('libs/elf/SConscript', variant_dir = buildDirectory + '/lib/elf', duplicate = 0, exports = {'environment': libraryEnvironment})
+ Depends(libelf, libraryEnvironment['configFiles'])
- target = str(target[0])
- source = str(source[0])
- # Strangely, cmlconfigure.py's command line option parsing is fairly broken
- # if you specify an input or output file a combination of things can happen,
- # so we supply no options, and move the defaults ifile= ./rules.out
- # ofile=./config.out around to match with supplied target/source arguments.
+ Alias('libs', crts.values() + libs.values() + [libelf])
- # Move source to where cmlconfigure.py expects to find it.
- print "Moving", source, "to", default_source
- shutil.move(source, default_source)
- cml2_configure_cmd = cml2_tools_root + '/cmlconfigure.py -c'
- os.system(cml2_configure_cmd)
+########## Build the kernel ########################
- # Move target file to where the build system expects to find it.
- print "Moving", default_target, "to", target
- shutil.move(default_target, target)
- print "Moving", default_source, "back to", source
- shutil.move(default_source, source)
- return None
+ kernelEnvironment = baseEnvironment.Clone(
+ CC = 'arm-none-eabi-gcc',
+ # We don't use -nostdinc because sometimes we need standard headers, such as stdarg.h e.g. for variable
+ # args, as in printk().
+ CCFLAGS = ['-mcpu=arm926ej-s', '-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
+ LINKFLAGS = ['-nostdlib', '-T' + includeDirectory + '/l4/arch/' + arch + '/mylink.lds'],
+ ASFLAGS = ['-D__ASSEMBLY__'],
+ PROGSUFFIX = '.axf',
+ LIBS = ['gcc'],
+ CPPPATH = ['#' + buildDirectory, '#' + buildDirectory + '/l4', '#' + includeDirectory, '#' + includeDirectory + '/l4'],
-def cml_compile(target, source, env):
- # Same here, this always produces a default file.
- default_target = "rules.out"
+ ####
+ #### TODO: Why are these files forcibly included, why not just leave it up to the C code to include things?
+ ####
- target = str(target[0])
- source = str(source[0])
+ CPPFLAGS = ['-include', 'config.h', '-include', 'cml2Config.h', '-include', 'macros.h', '-include', 'types.h', '-D__KERNEL__'])
+
+ kernelComponents = []
+ for scriptPath in ['src/' + path for path in kernelSConscriptPaths]:
+ kernelComponents.append(SConscript(scriptPath + '/SConscript', variant_dir = buildDirectory + '/' + scriptPath, duplicate = 0, exports = {'environment': kernelEnvironment}))
+ startAxf = kernelEnvironment.Program(buildDirectory + '/start.axf', kernelComponents)
+ Depends(kernelComponents + [startAxf], kernelEnvironment['configFiles'])
+
+ Alias('kernel', startAxf)
- cml2_compile_cmd = cml2_tools_root + '/cmlcompile.py < ' + source + ' > ' + target
- os.system(cml2_compile_cmd)
+########## Build the task libraries ########################
- print "Moving " + default_target + " to " + target
- shutil.move(default_target, target)
- return None
+ taskSupportLibraryEnvironment = baseEnvironment.Clone(
+ CC = 'arm-none-linux-gnueabi-gcc',
+ CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
+ LINKFLAGS = ['-nostdlib'],
+ ASFLAGS = ['-D__ASSEMBLY__'],
+ LIBS = ['gcc'],
+ CPPPATH = ['#' + buildDirectory, '#' + buildDirectory + '/l4', '#' + includeDirectory])
-def derive_symbols(config_header):
- '''
- Reads target header (config.h), derives symbols, and appends them to the same file.
- Normally CML2 should do this on-the-fly but, doesn't so this function explicitly
- does it here.
- '''
- archdir = None
- subarchdir = None
- platdir = None
- driversdirs = []
+ taskLibraryNames = [f.name for f in Glob('tasks/lib*')]
- config_symbols = gather_config_symbols(config_header)
- for sym,val in config_symbols:
- for arch in arch_to_dir:
- if sym == arch:
- archdir = arch_to_dir[arch]
- if arch == "ARCH_TEST":
- # These are derived from ARCH_TEST, but don't need to be written,
- # because they are unused. Instead, __ARCH__ test etc. are derived
- # from these and written to config.h because those are used by the
- # build system. IOW these are transitional symbols.
- config_symbols.append(("TEST_SUBARCH","1"))
- config_symbols.append(("TEST_PLATFORM","1"))
- for subarch in subarch_to_dir:
- if sym == subarch:
- subarchdir = subarch_to_dir[subarch]
- for plat in plat_to_dir:
- if sym == plat:
- platdir = plat_to_dir[plat]
- for driver in driver_to_dir:
- if sym == driver:
- # There can me multiple drivers, so making a list.
- driversdirs.append(driver_to_dir[driver])
- if archdir == None:
- print "Error: No config symbol found for architecture"
- sys.exit()
- if subarchdir == None:
- print "Error: No config symbol found for subarchitecture"
- sys.exit()
- if platdir == None:
- print "Error: No config symbol found for platform"
- sys.exit()
+ taskLibraries = []
+ for library in taskLibraryNames:
+ taskLibraries.append(SConscript('tasks/' + library + '/SConscript', variant_dir = buildDirectory + '/tasks/' + library, duplicate = 0, exports = {'environment': taskSupportLibraryEnvironment}))
- # Update config.h with derived values. Unfortunately CML2 does not handle
- # derived symbols well yet. This can be fixed in the future.
- f = open(config_h, "a")
- f.seek(0, 2)
- f.write("/* Symbols derived from this file by SConstruct\derive_symbols() */")
- f.write("\n#define __ARCH__\t\t%s\n" % archdir)
- f.write("#define __PLATFORM__\t\t%s\n" % platdir)
- f.write("#define __SUBARCH__\t\t%s\n\n" % subarchdir)
+ Depends(taskLibraries, taskSupportLibraryEnvironment['configFiles'])
- f.close()
+ Alias ('tasklibs', taskLibraries)
+########## Build the tasks ########################
-def cml_config2header(target, source, env):
- '''
- Translate the output of cml2 configurator to a C header file,
- to be included by the kernel.
- '''
- target = str(target[0])
- source = str(source[0])
- config_translator = cml2header.cml2header_translator()
- if config_translator.translate(source, target) < 0:
- print 'Configuration translation failed.'
- ##
- ## CML2 is incapable of deriving symbols. Hence, derived
- ## symbols are handled here.
- derive_symbols(target)
+ def buildTask(programName, sources, environment, previousImage, extraCppPath=None):
+ e = environment.Clone()
+ e.Append(LINKFLAGS=['-Ttasks/' + programName + '/include/linker.lds'])
+ e.Append(LIBPATH=['#build/tasks/' + programName, '#build/lib/c/userspace/crt/sys-userspace/arch-arm'])
+ if extraCppPath: e.Append(CPPPATH=extraCppPath)
+ objects = e.StaticObject(sources)
+ Depends(objects, e['configFiles'])
+ program = e.Program(programName, objects + ['#' + e['userspace_crt0'][0].name])
+ physicalBaseLinkerScript = Command('include/physical_base.lds', previousImage, 'tools/pyelf/readelf.py --first-free-page ' + previousImage[0].path + ' >> $TARGET')
+ Depends(program, [physicalBaseLinkerScript, e['userspace_crt0']])
+ return program
-# `hash' ('#') is a shorthand meaning `relative to
-# the root directory'. But this only works for
-# well-defined variables, not all paths, and only
-# if we use a relative build directory for sources.
-# Individual Build commands for configuration targets
+ tasksEnvironment = baseEnvironment.Clone(
+ CC = 'arm-none-linux-gnueabi-gcc',
+ CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
+ LINKFLAGS = ['-nostdlib'],
+ ASFLAGS = ['-D__ASSEMBLY__'],
+ LIBS = [libs['userspace']] + taskLibraries + ['gcc', libs['userspace']], #### TODO: Why have the userspace C library twice?
+ PROGSUFFIX = '.axf',
+ CPPDEFINES = ['__USERSPACE__'],
+ CPPPATH = ['#' + buildDirectory, '#' + buildDirectory + '/l4', '#' + includeDirectory, 'include', '#tasks/libl4/include', '#tasks/libmem', '#tasks/libposix/include'],
+ buildTask = buildTask)
-cml_compiled_target = kernel_env.Command('#build/rules.out', '#configs/arm.cml', cml_compile)
-cml_configured_target = kernel_env.Command('#build/config.out', '#build/rules.out', cml_configure)
-cml_translated_target = kernel_env.Command(config_h, '#build/config.out', cml_config2header)
+####
+#### TODO: Why doe the linker require crt0.o to be in the current directory and named as such. Is it
+#### because of the text in the linker script?
+####
-if "configure" in COMMAND_LINE_TARGETS:
- # This ensures each time `scons configure' is typed, a configuration occurs.
- # Otherwise the build system would think target is up-to-date and do nothing.
- kernel_env.AlwaysBuild(cml_compiled_target)
- kernel_env.AlwaysBuild(cml_configured_target)
- kernel_env.AlwaysBuild(cml_translated_target)
+ userspaceRuntime = Command(crts['userspace'][0].name, crts['userspace'][0], 'ln -s $SOURCE.path $TARGET')
-# Commandline aliases for each individual configuration targets
-kernel_env.Alias('cmlcompile', cml_compiled_target)
-kernel_env.Alias('cmlconfigure', cml_configured_target)
-kernel_env.Alias('cmltranslate', cml_translated_target)
+ execfile('tasks/taskOrder.py')
+ imageOrderData = [(taskName, []) for taskName in taskOrder]
+ imageOrderData[0][1].append(startAxf)
+ tasks = []
+ for i in range(len(imageOrderData)):
+ taskName = imageOrderData[i][0]
+ dependency = imageOrderData[i][1]
+ program = SConscript('tasks/' + taskName + '/SConscript', variant_dir = buildDirectory + '/tasks/' + taskName, duplicate = 0, exports = {'environment': tasksEnvironment, 'previousImage': dependency[0]})
+ Depends(program, userspaceRuntime)
+ tasks.append(program)
+ if i < len(imageOrderData) - 1:
+ imageOrderData[i+1][1].append(program)
+ Depends(tasks, tasksEnvironment['configFiles'])
-# Below alias is enough to trigger all config dependency tree.
-kernel_env.Alias('configure', cml_translated_target)
+ Alias ('tasks', tasks)
+########## Create the boot description ########################
+
+ taskName = 'bootdesc'
+
+ bootdescEnvironment = baseEnvironment.Clone(
+ CC = 'arm-none-linux-gnueabi-gcc',
+ CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
+ LINKFLAGS = ['-nostdlib', '-Ttasks/' + taskName + '/linker.lds'],
+ ASFLAGS = ['-D__ASSEMBLY__'],
+ PROGSUFFIX = '.axf',
+ LIBS = ['gcc'],
+ CPPPATH = ['#' + includeDirectory])
+
+ bootdesc = SConscript('tasks/' + taskName + '/SConscript', variant_dir = buildDirectory + '/tasks/' + taskName, duplicate = 0, exports = {'environment': bootdescEnvironment, 'images': [startAxf] + tasks})
+
+ Alias('bootdesc', bootdesc)
+
+########## Do the packing / create loadable ########################
+
+ loaderEnvironment = baseEnvironment.Clone(
+ CC = 'arm-none-linux-gnueabi-gcc',
+ CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
+ LINKFLAGS = ['-nostdlib', '-T' + buildDirectory + '/loader/linker.lds'],
+ PROGSUFFIX = '.axf',
+ LIBS = [libelf, libs['baremetal'], 'gcc', libs['baremetal']],
+ CPPPATH = ['#libs/elf/include', '#' + buildDirectory + '/loader'])
+
+ #### TODO: Fix the tasks data structure so as to avoid all the assumptions.
+
+ loader = SConscript('loader/SConscript', variant_dir = buildDirectory + '/loader', duplicate = 0, exports = {'environment': loaderEnvironment, 'images':[startAxf, bootdesc] + tasks})
+
+ Alias('final', loader)
+
+########## Other rules. ########################
+
+ Default(crts.values() + libs.values() + [libelf, startAxf] + tasks + bootdesc + loader)
+
+ Clean('.', [buildDirectory])
+
+########## Be helpful ########################
+
+Help('''
+Explicit targets are:
+
+ configure -- configure the build area ready for a build.
+
+ libs -- build the support library.
+ kernel -- build the kernel.
+ tasklibs -- build all the support libraries for the tasks.
+ tasks -- build all the tasks.
+ bootdesc -- build the tasks and the boot descriptor.
+ final -- build the loadable.
+
+The default target is to compile everything and to do a final link.
+
+Compilation can only be undertaken after a configuration.
+''')
diff --git a/buildall.sh b/buildall.sh
deleted file mode 100755
index b1bb158..0000000
--- a/buildall.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/bash
-
-rm -rf build
-
-echo -e "\n--- Building External Libs --- "
-cd libs/c
-scons
-cd ../elf
-scons
-cd ../..
-echo -e "\n--- Building kernel --- "
-scons configure
-scons build
-cd tasks
-echo -e "\n--- Building libraries --- "
-cd libmem
-scons
-cd ../libl4
-scons
-cd ../libposix
-scons
-echo -e "\n--- Building tasks --- "
-cd ../mm0
-scons
-cd ../fs0
-scons
-cd ../test0
-scons
-echo -e "\n--- Building bootdesc ---"
-cd ../bootdesc
-scons
-cd ../..
-echo -e "\n--- Packing all up ---"
-./packer.sh
-echo -e "\n--- Build Completed ---\n"
diff --git a/libs/c/SConscript b/libs/c/SConscript
new file mode 100644
index 0000000..109ce42
--- /dev/null
+++ b/libs/c/SConscript
@@ -0,0 +1,41 @@
+# -*- mode: python; coding: utf-8; -*-
+
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
+
+Import('environment', 'variant')
+
+source = \
+ Glob('src/*.c') + \
+ Glob('src/sys-' + variant + '/*.c') + \
+ Glob('src/sys-' + variant + '/arch-' + environment['ARCH'] + '/*.c') + \
+ Glob('src/sys-' + variant + '/arch-' + environment['ARCH'] + '/plat-' + environment['PLATFORM'] + '/*.c') + \
+ Glob('src/arch-' + environment['ARCH'] + '/*.c') + \
+ Glob('src/arch-' + environment['ARCH'] + '/*.S')
+
+e = environment.Clone()
+e.Append(CPPPATH = ['include', 'include/sys-' + variant + '/arch-' + environment['ARCH']])
+
+objects = e.StaticObject(source)
+Depends (objects, e['configFiles'])
+
+result = (
+ e.StaticLibrary('c-' + variant, objects),
+ e.StaticObject('crt/sys-' + variant + '/arch-' + e['ARCH'] + '/crt0.S')
+ )
+
+Return('result')
diff --git a/libs/c/SConstruct b/libs/c/SConstruct
deleted file mode 100644
index 8e04519..0000000
--- a/libs/c/SConstruct
+++ /dev/null
@@ -1,76 +0,0 @@
-Import("*")
-import os
-import glob
-from os.path import join
-
-arch = "arm"
-platform = "pb926"
-
-variant1 = "userspace"
-variant2 = "baremetal"
-
-builddir_var1 = join("build", variant1)
-builddir_var2 = join("build", variant2)
-crt0bdir_var1 = join("build", "crt")
-crt0bdir_var2 = join("build", "crt")
-
-BuildDir(builddir_var1, "src")
-BuildDir(builddir_var2, "src")
-BuildDir(crt0bdir_var1, "crt")
-BuildDir(crt0bdir_var2, "crt")
-
-headers_var1 = ["#include", "#include/sys-%s/arch-%s" % (variant1, arch)]
-headers_var2 = ["#include", "#include/sys-%s/arch-%s" % (variant2, arch)]
-
-env_var1 = Environment(CC = 'arm-none-linux-gnueabi-gcc',
- CCFLAGS = ['-g', '-nostdinc', '-nostdlib', '-ffreestanding'],
- LINKFLAGS = ['-nostdlib'],
- ENV = {'PATH' : os.environ['PATH']},
- LIBS = 'gcc',
- CPPPATH = headers_var1)
-
-env_var2 = Environment(CC = 'arm-none-linux-gnueabi-gcc',
- CCFLAGS = ['-g', '-nostdinc', '-nostdlib', '-ffreestanding'],
- LINKFLAGS = ['-nostdlib'],
- ENV = {'PATH' : os.environ['PATH']},
- LIBS = 'gcc',
- CPPPATH = headers_var2)
-
-def src_glob(src_base, src_paths, builddir):
- """Src glob is used to find source files easily e.g: src_glob("src/*.c"),
- the reason we can't just use glob is due to the way SCons handles out
- of directory builds."""
- search = os.path.join(src_base, src_paths)
- dir = os.path.dirname(search)
- if dir != "":
- dir = dir + os.sep
- src_path = Dir('.').srcnode().abspath
- files = glob.glob(src_path + os.sep + search)
- files = map(os.path.basename, files)
- ret_files = []
- for file in files:
- ret_files.append(builddir + dir[len(src_base):] + file)
- return ret_files
-
-src_var1 = src_glob("src", "*.c", builddir_var1) + \
- src_glob("src", "sys-%s/*.c" % variant1, builddir_var1) + \
- src_glob("src", "sys-%s/arch-%s/*.c" % (variant1, arch), builddir_var1) + \
- src_glob("src", "sys-%s/arch-%s/plat-%s/*.c" % (variant1, arch, platform), builddir_var1) + \
- src_glob("src", "arch-%s/*.S" % arch, builddir_var1) + \
- src_glob("src", "arch-%s/*.c" % arch, builddir_var1)
-
-src_var2 = src_glob("src", "*.c", builddir_var2) + \
- src_glob("src", "sys-%s/*.c" % variant2, builddir_var2) + \
- src_glob("src", "sys-%s/arch-%s/*.c" % (variant2, arch), builddir_var2) + \
- src_glob("src", "sys-%s/arch-%s/plat-%s/*.c" % (variant2, arch, platform), builddir_var2) + \
- src_glob("src", "arch-%s/*.S" % arch, builddir_var2) + \
- src_glob("src", "arch-%s/*.c" % arch, builddir_var2)
-
-crt_var1 = env_var1.StaticObject(src_glob("crt", \
- "sys-%s/arch-%s/crt0.S" % (variant1, arch), crt0bdir_var1), ASFLAGS=env_var1["CCFLAGS"])
-
-crt_var2 = env_var2.StaticObject(src_glob("crt", \
- "sys-%s/arch-%s/crt0.S" % (variant2, arch), crt0bdir_var2), ASFLAGS=env_var2["CCFLAGS"])
-
-libc_var1 = env_var1.StaticLibrary(join("build",variant1) + "/c-" + variant1, src_var1)
-libc_var2 = env_var2.StaticLibrary(join("build",variant2) + "/c-" + variant2, src_var2)
diff --git a/libs/elf/SConscript b/libs/elf/SConscript
new file mode 100644
index 0000000..5bc3a3f
--- /dev/null
+++ b/libs/elf/SConscript
@@ -0,0 +1,29 @@
+# -*- mode: python; coding: utf-8; -*-
+
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
+
+Import('environment')
+
+e = environment.Clone()
+e.Append(CPPPATH = ['include', '#libs/c/include', '#libs/c/include/arch/' + e['ARCH']])
+
+objects = e.StaticObject(Glob('src/*.c'))
+Depends(objects, e['configFiles'])
+library = e.StaticLibrary('elf', objects)
+
+Return('library')
diff --git a/libs/elf/SConstruct b/libs/elf/SConstruct
deleted file mode 100644
index d12a63a..0000000
--- a/libs/elf/SConstruct
+++ /dev/null
@@ -1,42 +0,0 @@
-Import("*")
-import os
-import glob
-
-libs = ["gcc"]
-
-arch = 'arm'
-
-# C library information
-clibvariant = "baremetal"
-clibroot = os.getcwd() + '/../c'
-clibpath = os.getcwd() + clibroot + '/build/' + clibvariant
-cincpath = [clibroot + '/include', clibroot + '/include/arch/%s' % arch]
-
-env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
- CCFLAGS = ['-g', '-nostdinc', '-nostdlib', '-ffreestanding'],
- LINKFLAGS = ['-nostdlib'],
- ENV = {'PATH' : os.environ['PATH']},
- LIBS = ['gcc','c-' + clibvariant],
- LIBPATH = clibpath,
- CPPPATH = ['#include'] + cincpath)
-
-
-def src_glob(search):
- """Src glob is used to find source files easily e.g: src_glob("src/*.c"),
- the reason we can't just use glob is due to the way SCons handles out
- of directory builds."""
- dir = os.path.dirname(search)
- if dir != "":
- dir = dir + os.sep
- src_path = Dir('.').srcnode().abspath
- files = glob.glob(src_path + os.sep + search)
- files = map(os.path.basename, files)
- ret_files = []
- for file in files:
- ret_files.append(dir + file)
- return ret_files
-
-src = src_glob("src/*.c")
-
-libelf = env.StaticLibrary('elf', src)
-
diff --git a/loader/SConscript b/loader/SConscript
new file mode 100644
index 0000000..6057769
--- /dev/null
+++ b/loader/SConscript
@@ -0,0 +1,117 @@
+# -*- mode: python; coding: utf-8; -*-
+
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
+
+import os.path
+import subprocess
+
+Import('environment', 'images')
+
+def ksymToLds(target, source, env):
+ symbols = ['break_virtual']
+ with open(target[0].path, 'w') as asmFile:
+ asmFile.write('''
+/*
+ * %s autogenerated from %s
+ *
+ * This file is included by the loader sources so that any
+ * kernel symbol address can be known in advance and stopped
+ * at by debuggers before virtual memory is enabled.
+ */
+''' % (target[0].name, source[0].name))
+ for symbol in symbols:
+ process = subprocess.Popen('arm-none-eabi-objdump -d ' + source[0].path + ' | grep "<' + symbol + '>"', shell=True, stdout=subprocess.PIPE)
+ assert process.wait() == 0
+ address, name = process.stdout.read().split()
+ assert '<' + symbol + '>:' == name
+ asmFile.write( '''
+.section .text
+.align 4
+.global %s
+.type %s, function
+.equ %s, %s
+''' % (symbol, symbol, symbol, (hex(int(address, 16) - 0xf0000000))))
+
+def createKernelSFile(target, source, env):
+ with open(target[0].path, 'w') as asmFile:
+ asmFile.write('''
+/* This file defines kernel symbols extracted from the kernel image in their physical address */
+.include "%s"
+
+.section .kernel
+
+.incbin "%s"
+
+''' % (source[0].path , source[1].path))
+ for image in source[2:]:
+ asmFile.write('''
+.align 4
+.section .%s
+.incbin "%s"
+''' % (os.path.splitext(image.name)[0], image.path))
+
+def createMainC(target, source, env):
+ with open(source[0].path) as inFile:
+ with open(target[0].path, 'w') as outFile:
+ externs = ''
+ declarations = ''
+ loads = ''
+ for item in source[1:]:
+ name = os.path.splitext(item.name)[0]
+ if name == 'start' : name = 'kernel'
+ externs += '''
+extern char _start_%s[];
+extern char _end_%s[];
+''' % (name, name)
+ declarations += ' void *%s_entry = NULL;\n' % (name,)
+ loads += '''
+ printf("Loading the %s...\\n");
+ load_image(&%s_entry, _start_%s, _end_%s);
+''' %(name, name, name, name)
+ text = inFile.read()
+ text = text.replace('__EXTERNAL_SYMBOLS_EDIT_MARKER__', externs)
+ text = text.replace('__DECLARATIONS_EDIT_MARKER__', declarations)
+ text = text.replace('__LOAD_STATEMENTS_EDIT_MARKER__', loads)
+ outFile.write(text)
+
+def createLinkerScript(target, source, env):
+ with open(source[0].path) as inFile:
+ with open(target[0].path, 'w') as outFile:
+ linkerItems = ''
+ for item in source[1:]:
+ name = os.path.splitext(item.name)[0]
+ if name == 'start' : name = 'kernel'
+ linkerItems += '''
+ _start_%s = .;
+ *(.%s)
+ _end_%s = .;
+''' % (name, name, name)
+ outFile.write(inFile.read().replace('__LINKER_ITEMS_EDIT_MARKER__', linkerItems))
+
+startAxfS = Command('start.axf.S', images[0], ksymToLds)
+kernelS = Command('kernel.S', [startAxfS] + images, createKernelSFile) # Order of dependencies is crucial here.
+mainC = Command('main.c', ['main.c.in'] + images, createMainC)
+linkerScript = Command('linker.lds', ['linker.lds.in'] + images, createLinkerScript)
+
+objects = environment.Object(['arch.c' , kernelS, startAxfS, mainC])
+Depends(objects, environment['configFiles'])
+Depends(objects, images)
+program = environment.Program('final', objects + [environment['baremetal_crt0']])
+Depends(program, linkerScript)
+
+Return('program')
diff --git a/loader/SConstruct b/loader/SConstruct
deleted file mode 100644
index ca595d5..0000000
--- a/loader/SConstruct
+++ /dev/null
@@ -1,51 +0,0 @@
-Import("*")
-import os
-import glob
-from os.path import join
-
-arch = 'arm'
-clibvariant = 'baremetal'
-# C library information
-clibroot = join(os.getcwd(), '../libs/c')
-clibpath = join(join(clibroot, 'build'), clibvariant)
-cincpath = [join(clibroot, 'include'), join(clibroot,'include/arch/%s' % arch)]
-crt0objpath = join(clibroot, 'build/crt/sys-%s/arch-%s/crt0.o' % (clibvariant, arch))
-clibname = "c-" + clibvariant
-
-# Elf library information
-elflibpath = os.getcwd() + '/../libs/elf'
-elfincpath = [elflibpath + '/include']
-
-env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
- CCFLAGS = ['-g', '-nostdlib', '-ffreestanding'],
- LINKFLAGS = ['-nostdlib', '-Tmylink.lds'],
- ENV = {'PATH' : os.environ['PATH']},
- PROGSUFFIX = '.axf',
- LIBS = ['elf', clibname, 'gcc', clibname], # Note there's a dependency order here.
- # Left libs depend on libs on their right.
- CPPPATH = ['#'] + cincpath + elfincpath)
-
-env.Append(LIBPATH = [clibpath, elflibpath])
-
-def src_glob(search):
- """Src glob is used to find source files easily e.g: src_glob("src/*.c"),
- the reason we can't just use glob is due to the way SCons handles out
- of directory builds."""
- dir = os.path.dirname(search)
- if dir != "":
- dir = dir + os.sep
- src_path = Dir('.').srcnode().abspath
- files = glob.glob(src_path + os.sep + search)
- files = map(os.path.basename, files)
- ret_files = []
- for file in files:
- ret_files.append(dir + file)
- return ret_files
-
-src = src_glob("*.c")
-src += src_glob("*.S")
-
-obj_list = env.Object(src)
-loader = env.Program("final", obj_list + [crt0objpath])
-
-
diff --git a/loader/kernel.S b/loader/kernel.S
deleted file mode 100644
index ebbece2..0000000
--- a/loader/kernel.S
+++ /dev/null
@@ -1,25 +0,0 @@
-
-/* This file defines kernel symbols extracted from the kernel image in their physical address */
-.include "start.axf.S"
-
-.section .kernel
-
-.incbin "start.axf"
-
-.align 4
-.section .bootdesc
-.incbin "bootdesc.axf"
-
-.align 4
-.section .mm0
-.incbin "mm0.axf"
-
-.align 4
-.section .fs0
-.incbin "fs0.axf"
-
-.align 4
-.section .test0
-.incbin "test0.axf"
-
-.align 4
diff --git a/loader/mylink.lds b/loader/linker.lds.in
similarity index 54%
rename from loader/mylink.lds
rename to loader/linker.lds.in
index c2b8a15..5e6da93 100644
--- a/loader/mylink.lds
+++ b/loader/linker.lds.in
@@ -1,3 +1,11 @@
+/****
+ **** Template for generating a linker.lds. Edit markers have replaced some items in the original file
+ ****
+ **** Copyright © 2009 B Labs Ltd
+ ****
+ **** Author: Russel Winder.
+ ****/
+
/*
* Simple linker script for userspace or svc tasks.
*
@@ -13,21 +21,7 @@ SECTIONS
.rodata1 : { *(.rodata1) }
.data :
{
- _start_kernel = .;
- *(.kernel)
- _end_kernel = .;
- _start_bootdesc = .;
- *(.bootdesc)
- _end_bootdesc = .;
- _start_mm0 = .;
- *(.mm0)
- _end_mm0 = .;
- _start_fs0 = .;
- *(.fs0)
- _end_fs0 = .;
- _start_test0 = .;
- *(.test0)
- _end_test0 = .;
+__LINKER_ITEMS_EDIT_MARKER__
*(.data)
}
.got : { *(.got) *(.got.plt) }
diff --git a/loader/main.c b/loader/main.c.in
similarity index 91%
rename from loader/main.c
rename to loader/main.c.in
index 91f4425..6231d64 100644
--- a/loader/main.c
+++ b/loader/main.c.in
@@ -1,3 +1,11 @@
+/****
+ **** Template for generating a main.c. Edit markers have replaced some items in the original file
+ ****
+ **** Copyright © 2009 B Labs Ltd
+ ****
+ **** Author: Russel Winder.
+ ****/
+
/*******************************************************************************
* Filename: src/main.c *
* Description: Elf-loader - ELF file kernel/application bootstraper, main *
@@ -95,17 +103,10 @@
* Extern symbols *
*****************/
-/* These symbols are defined by the linker scripts. */
-extern char _start_kernel[];
-extern char _end_kernel[];
-extern char _start_mm0[];
-extern char _end_mm0[];
-extern char _start_fs0[];
-extern char _end_fs0[];
-extern char _start_test0[];
-extern char _end_test0[];
-extern char _start_bootdesc[];
-extern char _end_bootdesc[];
+/* Variable declarations added here for symbols defined by the linker scripts. */
+
+__EXTERNAL_SYMBOLS_EDIT_MARKER__
+
/* This is a kernel symbol exported to loader's linker script from kernel build */
extern char bkpt_phys_to_virt[];
@@ -118,29 +119,17 @@ static void load_image(void **entry, char *start, char *end);
int
main(void)
{
- void *kernel_entry = NULL;
- void *mm0_entry = NULL;
- void *fs0_entry = NULL;
- void *test0_entry = NULL;
- void *bootdesc_entry = NULL;
+ /* Declarations added here.*/
+
+__DECLARATIONS_EDIT_MARKER__
+
arch_init();
printf("elf-loader:\tStarted\n");
- printf("Loading the kernel...\n");
- load_image(&kernel_entry, _start_kernel, _end_kernel);
+ /* Loader statements added here. */
- printf("Loading the bootdesc\n");
- load_image(&bootdesc_entry, _start_bootdesc, _end_bootdesc);
-
- printf("Loading mm0\n");
- load_image(&mm0_entry, _start_mm0, _end_mm0);
-
- printf("Loading fs0\n");
- load_image(&fs0_entry, _start_fs0, _end_fs0);
-
- printf("Loading test0\n");
- load_image(&test0_entry, _start_test0, _end_test0);
+__LOAD_STATEMENTS_EDIT_MARKER__
printf("elf-loader:\tkernel entry point is %p\n", kernel_entry);
arch_start_kernel(kernel_entry);
diff --git a/loader/todo.txt b/loader/todo.txt
deleted file mode 100644
index 8aafc72..0000000
--- a/loader/todo.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-
-TODO:
-1) The build system could auto-copy all images to here,
-then autogenerate kernel.S from these images.
-Then autogenerate a function that loads all given images in main.c
-
-This would allow you to, say, build a custom combination of images
-and not worry about how they will be loaded.
diff --git a/packer.sh b/packer.sh
deleted file mode 100755
index d901017..0000000
--- a/packer.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-
-#Export symbols from kernel to loader's linker script
-#Debuggers can use these symbols as a stop point for loading ksymtab before mmu is on.
-./tools/ksym_to_lds.py
-
-cp build/start.axf loader/
-cp tasks/mm0/mm0.axf loader/
-cp tasks/fs0/fs0.axf loader/
-cp tasks/test0/test0.axf loader/
-cp tasks/bootdesc/bootdesc.axf loader/
-cd loader
-scons -c
-scons
-cp final.axf ../build
-
-if [ -n "$SAMBA_DIR" ]
-then
- cp final.axf $SAMBA_DIR
- cp start.axf $SAMBA_DIR
-fi
-cd ../build
-arm-none-eabi-objdump -d start.axf > start.txt
diff --git a/src/api/SConscript b/src/api/SConscript
index 71ca539..7646bb9 100644
--- a/src/api/SConscript
+++ b/src/api/SConscript
@@ -1,10 +1,24 @@
-# Inherit global environment
-Import('env')
-Import('config_symbols')
+# -*- mode: python; coding: utf-8; -*-
-# The set of source files associated with this SConscript file.
-src_local = ['kip.c', 'syscall.c', 'thread.c', 'ipc.c', 'space.c', 'mutex.c', 'capability.c']
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
-obj = env.Object(src_local)
+Import('environment')
-Return('obj')
+objects = environment.Object(Glob('*.c'))
+
+Return('objects')
diff --git a/src/arch/arm/SConscript b/src/arch/arm/SConscript
index 57bc74f..1aaa68a 100644
--- a/src/arch/arm/SConscript
+++ b/src/arch/arm/SConscript
@@ -1,10 +1,24 @@
+# -*- mode: python; coding: utf-8; -*-
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
-# Inherit global environment
-Import('env')
+Import('environment')
-# The set of source files associated with this SConscript file.
-src_local = ['head.S', 'vectors.S', 'syscall.S', 'exception.c']
-obj = env.Object(src_local)
+objects = environment.Object(Glob('*.c') + Glob('*.S'))
-Return('obj')
+Return('objects')
diff --git a/src/arch/arm/v5/SConscript b/src/arch/arm/v5/SConscript
index 4fd282a..1aaa68a 100644
--- a/src/arch/arm/v5/SConscript
+++ b/src/arch/arm/v5/SConscript
@@ -1,10 +1,24 @@
+# -*- mode: python; coding: utf-8; -*-
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
-# Inherit global environment
-Import('env')
+Import('environment')
-# The set of source files associated with this SConscript file.
-src_local = ['mm.c', 'mmu_ops.S', 'mutex.S']
+objects = environment.Object(Glob('*.c') + Glob('*.S'))
-obj = env.Object(src_local)
-Return('obj')
+Return('objects')
diff --git a/src/arch/arm/v6/SConscript b/src/arch/arm/v6/SConscript
new file mode 100644
index 0000000..1aaa68a
--- /dev/null
+++ b/src/arch/arm/v6/SConscript
@@ -0,0 +1,24 @@
+# -*- mode: python; coding: utf-8; -*-
+
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
+
+Import('environment')
+
+objects = environment.Object(Glob('*.c') + Glob('*.S'))
+
+Return('objects')
diff --git a/src/arch/tests/SConscript b/src/arch/tests/SConscript
deleted file mode 100644
index 23f0d20..0000000
--- a/src/arch/tests/SConscript
+++ /dev/null
@@ -1,9 +0,0 @@
-
-# Inherit global environment
-Import('env')
-
-# The set of source files associated with this SConscript file.
-src_local = ['linker.c']
-
-obj = env.Object(src_local)
-Return('obj')
diff --git a/src/drivers/irq/pl190/SConscript b/src/drivers/irq/pl190/SConscript
index 4c5a0f1..7646bb9 100644
--- a/src/drivers/irq/pl190/SConscript
+++ b/src/drivers/irq/pl190/SConscript
@@ -1,10 +1,24 @@
+# -*- mode: python; coding: utf-8; -*-
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
-# Inherit global environment
-Import('env')
+Import('environment')
-# The set of source files associated with this SConscript file.
-src_local = ['pl190_vic.c']
+objects = environment.Object(Glob('*.c'))
-obj = env.Object(src_local)
-Return('obj')
+Return('objects')
diff --git a/src/drivers/timer/sp804/SConscript b/src/drivers/timer/sp804/SConscript
index bb0402b..7646bb9 100644
--- a/src/drivers/timer/sp804/SConscript
+++ b/src/drivers/timer/sp804/SConscript
@@ -1,10 +1,24 @@
+# -*- mode: python; coding: utf-8; -*-
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
-# Inherit global environment
-Import('env')
+Import('environment')
-# The set of source files associated with this SConscript file.
-src_local = ['sp804_timer.c']
+objects = environment.Object(Glob('*.c'))
-obj = env.Object(src_local)
-Return('obj')
+Return('objects')
diff --git a/src/drivers/uart/pl011/SConscript b/src/drivers/uart/pl011/SConscript
index 3de3d3e..7646bb9 100644
--- a/src/drivers/uart/pl011/SConscript
+++ b/src/drivers/uart/pl011/SConscript
@@ -1,10 +1,24 @@
+# -*- mode: python; coding: utf-8; -*-
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
-# Inherit global environment
-Import('env')
+Import('environment')
-# The set of source files associated with this SConscript file.
-src_local = ['pl011_uart.c']
+objects = environment.Object(Glob('*.c'))
-obj = env.Object(src_local)
-Return('obj')
+Return('objects')
diff --git a/src/generic/SConscript b/src/generic/SConscript
index 826baca..7646bb9 100644
--- a/src/generic/SConscript
+++ b/src/generic/SConscript
@@ -1,10 +1,24 @@
+# -*- mode: python; coding: utf-8; -*-
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
-# Inherit global environment
-Import('env')
+Import('environment')
-# The set of source files associated with this SConscript file.
-src_local = ['irq.c', 'scheduler.c', 'time.c', 'tcb.c', 'space.c', 'bootm.c', 'resource.c', 'container.c', 'capability.c']
+objects = environment.Object(Glob('*.c'))
-obj = env.Object(src_local)
-Return('obj')
+Return('objects')
diff --git a/src/glue/arm/SConscript b/src/glue/arm/SConscript
index 0dcde26..7646bb9 100644
--- a/src/glue/arm/SConscript
+++ b/src/glue/arm/SConscript
@@ -1,10 +1,24 @@
+# -*- mode: python; coding: utf-8; -*-
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
-# Inherit global environment
-Import('env')
+Import('environment')
-# The set of source files associated with this SConscript file.
-src_local = ['init.c', 'memory.c', 'systable.c']
+objects = environment.Object(Glob('*.c'))
-obj = env.Object(src_local)
-Return('obj')
+Return('objects')
diff --git a/src/glue/tests/SConscript b/src/glue/tests/SConscript
deleted file mode 100644
index a5c3b82..0000000
--- a/src/glue/tests/SConscript
+++ /dev/null
@@ -1,9 +0,0 @@
-
-# Inherit global environment
-Import('env')
-
-# The set of source files associated with this SConscript file.
-src_local = ['main.c', 'test_kmalloc.c', 'test_memcache.c', 'test_allocpage.c', 'test_alloc_generic.c', 'debug.c', 'memory.c', 'clz.c']
-
-obj = env.Object(src_local)
-Return('obj')
diff --git a/src/lib/SConscript b/src/lib/SConscript
index 98c4869..7646bb9 100644
--- a/src/lib/SConscript
+++ b/src/lib/SConscript
@@ -1,12 +1,24 @@
+# -*- mode: python; coding: utf-8; -*-
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
-# Inherit global environment
-Import('env')
-Import('config_symbols')
-# The set of source files associated with this SConscript file.
-src_local = ['printk.c', 'putc.c', 'string.c', 'bit.c', 'wait.c', 'mutex.c', 'idpool.c', 'memcache.c']
-if "ARCH_TEST" not in config_symbols:
- obj = env.Object(src_local)
-else:
- obj = []
-Return('obj')
+Import('environment')
+
+objects = environment.Object(Glob('*.c'))
+
+Return('objects')
diff --git a/src/platform/pb926/SConscript b/src/platform/pb926/SConscript
index cd867bf..1aaa68a 100644
--- a/src/platform/pb926/SConscript
+++ b/src/platform/pb926/SConscript
@@ -1,10 +1,24 @@
+# -*- mode: python; coding: utf-8; -*-
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
-# Inherit global environment
-Import('env')
+Import('environment')
-# The set of source files associated with this SConscript file.
-src_local = ['printascii.S','platform.c', 'uart.c', 'timer.c', 'irq.c']
+objects = environment.Object(Glob('*.c') + Glob('*.S'))
-obj = env.Object(src_local)
-Return('obj')
+Return('objects')
diff --git a/src/platform/tests/SConscript b/src/platform/tests/SConscript
deleted file mode 100644
index ad1dc3c..0000000
--- a/src/platform/tests/SConscript
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-# Inherit global environment
-Import('env')
-
-# The set of source files associated with this SConscript file.
-src_local = ['offsets.c']
-
-obj = env.Object(src_local)
-Return('obj')
diff --git a/tasks/bootdesc/.gitignore b/tasks/bootdesc/.gitignore
deleted file mode 100644
index 1af9725..0000000
--- a/tasks/bootdesc/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*.txt
-bootdesc.c.append
diff --git a/tasks/bootdesc/SConscript b/tasks/bootdesc/SConscript
new file mode 100644
index 0000000..748a5ec
--- /dev/null
+++ b/tasks/bootdesc/SConscript
@@ -0,0 +1,91 @@
+# -*- mode: python; coding: utf-8; -*-
+
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
+
+import os.path
+import subprocess
+import shutil
+
+Import('environment', 'images')
+
+bootdescTemplate = \
+'''
+/* This file is autogenerated, do not edit by hand. */
+
+/* Supervisor task at load time. */
+struct svc_image {
+ char name[16];
+ unsigned int phys_start;
+ unsigned int phys_end;
+} __attribute__((__packed__));
+
+/* Supervisor task descriptor at load time */
+struct bootdesc {
+ int desc_size;
+ int total_images;
+ struct svc_image images[];
+} __attribute__((__packed__));
+
+struct bootdesc bootdesc = {
+ .desc_size = sizeof(struct bootdesc) + sizeof(struct svc_image) * %s,
+ .total_images = %s,
+ .images = {
+%s
+ },
+};
+'''
+
+imageTemplate = \
+''' [%s] = {
+ .name = "%s",
+ .phys_start = %s,
+ .phys_end = %s,
+ },
+'''
+
+def generateLocationData(image):
+ process = subprocess.Popen('tools/pyelf/readelf.py --lma-start-end ' + image.path, shell=True, stdout=subprocess.PIPE)
+ assert process.wait() == 0
+ return (process.stdout.readline().strip(), process.stdout.readline().strip().split()[1], process.stdout.readline().strip().split()[1])
+
+def generateBootdesc(target, source, env):
+ '''
+ Extracts name, start, end information from the kernel and each svc task.
+ Uses this information to produce bootdesc.c
+ '''
+ with open(target[0].path, 'w' ) as f:
+ imagesString = ''
+ numberOfImages = len(source) - 1
+ for index in range(1, len(source)):
+ imagesString += imageTemplate % ((index - 1,) + generateLocationData(source[index]))
+ f.write(bootdescTemplate % (numberOfImages, numberOfImages, imagesString))
+
+def relocateBootdesc(target, source, env):
+ name, start, end = generateLocationData(source[1])
+ process = subprocess.Popen(executable='arm-none-linux-gnueabi-objcopy', args=(
+ '--adjust-section-vma .data=' + end,
+ source[0].path))
+ assert process.wait() == 0
+ shutil.copyfile(source[0].path, target[0].path)
+
+bootdescSource = environment.Command('bootdesc.c', images, generateBootdesc)
+objects = environment.Object(bootdescSource)
+Depends(objects, environment['configFiles'])
+bootdesc = environment.Command('bootdesc.axf', environment.Program('bootdesc_intermediate', objects) + [images[0]] , relocateBootdesc)
+
+Return('bootdesc')
diff --git a/tasks/bootdesc/SConstruct b/tasks/bootdesc/SConstruct
deleted file mode 100644
index ccf9152..0000000
--- a/tasks/bootdesc/SConstruct
+++ /dev/null
@@ -1,124 +0,0 @@
-#
-# Build script to autogenerate a bootdesc image
-#
-# Copyright (C) 2007 Bahadir Balban
-#
-import os
-import sys
-import shutil
-from os.path import join
-
-# The root directory of the repository where this file resides:
-project_root = "../.."
-tools_root = "../../tools"
-
-kernel = join(project_root, "build/start.axf")
-mm0 = join(project_root, "tasks/mm0/mm0.axf")
-fs0 = join(project_root, "tasks/fs0/fs0.axf")
-test0 = join(project_root, "tasks/test0/test0.axf")
-#test1 = join(project_root, "tasks/test1/test1.axf")
-#blkdev0 = join(project_root, "tasks/fsbin/blkdev0.axf")
-
-images = [kernel, mm0, fs0, test0]
-autogen_templ = "bootdesc.c.append"
-
-def get_image_name_start_end(image, target):
- '''
- Using readelf.py utility, extracts name, start, end triplet from an arm-elf image.
- '''
- rest, name = os.path.split(image)
- if name[-4] == ".":
- name = name[:-4]
- os.system(join(tools_root, "pyelf/readelf.py --lma-start-end " + \
- image + " > " + target))
-
-bootdesc_template = \
-'''
-struct bootdesc bootdesc = {
- .desc_size = sizeof(struct bootdesc) + sizeof(struct svc_image) * %s,
- .total_images = %s,
- .images = {
-%s
- },
-};
-'''
-
-images_template = \
-''' [%s] = {
- .name = "%s",
- .phys_start = %s,
- .phys_end = %s,
- },
-'''
-
-images_template_end = \
-'''
- },
-'''
-
-def generate_bootdesc(source, target, env):
- '''
- Extracts name, start, end information from the kernel and each svc task.
- Uses this information to produce bootdesc.c
- '''
- source.sort()
- images = []
- images_string = ""
- for node in source:
- if str(node)[-4:] == ".axf":
- rest, imgname = os.path.split(str(node))
- images.append((str(node), imgname[:-4]))
- elif str(node) [-6:] == ".templ":
- # Static template that has type definitions.
- #rest, original_template = os.path.split(str(node))
- original_template = str(node)
- index = 0
- for imgpath, imgname in images:
- get_image_name_start_end(imgpath, imgname + ".txt")
- if imgname != "start":
- f = open(imgname + ".txt", "r")
- svc_name = f.readline()[:-1]
- [start, startval] = str.split(f.readline()[:-1])
- [end, endval] = str.split(f.readline()[:-1])
- f.close()
- images_string += images_template % (str(index), svc_name, \
- hex(int(startval, 16)), hex(int(endval, 16)))
- index += 1
-
- # Autogenerated template with actual data.
- autogen_template = open(autogen_templ, "w+")
- autogen_template.write(bootdesc_template % (str(index), str(index), images_string))
- autogen_template.close()
-
- os.system("cat " + original_template + " > " + str(target[0]))
- os.system("cat " + autogen_templ + " >> " + str(target[0]))
-
-# Relocate to end of mm0 instead of end of kernel
-def relocate_bootdesc(source, target, env):
- f = open("mm0.txt", "r")
- kernel_name = f.readline()[:-1]
- [start, startval] = str.split(f.readline()[:-1])
- [end, endval] = str.split(f.readline()[:-1])
- os.system("arm-none-linux-gnueabi-objcopy --adjust-section-vma .data=" + \
- hex(int(endval,16)) + " " + str(source[0]))
- os.system("mv " + str(source[0]) + " " + str(target[0]))
-# The kernel build environment:
-env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
- # We don't use -nostdinc because sometimes we need standard headers,
- # such as stdarg.h e.g. for variable args, as in printk().
- CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
- LINKFLAGS = ['-nostdlib','-Tlinker.lds'],
- ASFLAGS = ['-D__ASSEMBLY__'],
- PROGSUFFIX = '.axf', # The suffix to use for final executable
- ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
- LIBS = 'gcc', # libgcc.a - This is required for division routines.
- CPPPATH = '#include') # `hash' ('#') is a shorthand meaning `relative to
- # the root directory'. But this only works for
- # well-defined variables, not all paths, and only
- # if we use a relative build directory for sources.
-
-bootdesc_src = env.Command("bootdesc.c", ["bootdesc.c.templ"] + images, generate_bootdesc)
-objs = env.Object('bootdesc.c')
-bootdesc = env.Program('bootdesc_data', objs)
-bootdesc_relocated = env.Command("bootdesc.axf", "bootdesc_data.axf", relocate_bootdesc)
-env.Depends(bootdesc_relocated, bootdesc)
diff --git a/tasks/bootdesc/bootdesc.c.templ b/tasks/bootdesc/bootdesc.c.templ
deleted file mode 100644
index 0b6aa49..0000000
--- a/tasks/bootdesc/bootdesc.c.templ
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-/* Supervisor task at load time. */
-struct svc_image {
- char name[16];
- unsigned int phys_start;
- unsigned int phys_end;
-} __attribute__((__packed__));
-
-/* Supervisor task descriptor at load time */
-struct bootdesc {
- int desc_size;
- int total_images;
- struct svc_image images[];
-} __attribute__((__packed__));
-
diff --git a/tasks/fs0/SConscript b/tasks/fs0/SConscript
new file mode 100644
index 0000000..10c9c26
--- /dev/null
+++ b/tasks/fs0/SConscript
@@ -0,0 +1,24 @@
+# -*- mode: python; coding: utf-8; -*-
+
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
+
+Import('environment', 'previousImage')
+
+program = environment['buildTask']('fs0', Glob('*.c') + [Glob(directory + '/*.c') for directory in [ 'src', 'src/lib', 'src/lib/elf', 'src/memfs']], environment, previousImage)
+
+Return('program')
diff --git a/tasks/fs0/SConstruct b/tasks/fs0/SConstruct
deleted file mode 100644
index 6c6b1e3..0000000
--- a/tasks/fs0/SConstruct
+++ /dev/null
@@ -1,75 +0,0 @@
-#
-# User space application build script
-#
-# Copyright (C) 2007 Bahadir Balban
-#
-import os
-import sys
-import shutil
-from os.path import join
-from glob import glob
-
-task_name = "fs0"
-
-# The root directory of the repository where this file resides:
-project_root = "../.."
-tools_root = join(project_root, "tools")
-prev_image = join(project_root, "tasks/mm0/mm0.axf")
-libs_path = join(project_root, "libs")
-ld_script = "include/linker.lds"
-physical_base_ld_script = "include/physical_base.lds"
-
-# libc paths:
-libc_variant = "userspace"
-libc_libpath = join(libs_path, "c/build/%s" % libc_variant)
-libc_incpath = join(libc_libpath, "include")
-libc_crt0 = join(libs_path, "c/build/crt/sys-userspace/arch-arm/crt0.o")
-libc_name = "c-%s" % libc_variant
-
-#libmem paths:
-libmem_path = "../libmem"
-libmem_incpath = "../libmem"
-
-# libl4 paths:
-libl4_path = "../libl4"
-libl4_incpath1 = join(libl4_path, "include")
-
-# libposix paths:
-libposix_path = "../libposix"
-libposix_incpath = join(libposix_path, "include")
-
-# kernel paths:
-kernel_incpath = join(project_root, "include")
-
-# If crt0 is in its library path, it becomes hard to link with it.
-# For instance the linker script must use an absolute path for it.
-def copy_crt0(source, target, env):
- os.system("cp " + str(source[0]) + " " + str(target[0]))
-
-def get_physical_base(source, target, env):
- os.system(join(tools_root, "pyelf/readelf.py --first-free-page " + \
- prev_image + " >> " + physical_base_ld_script))
-
-# The kernel build environment:
-env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
- # We don't use -nostdinc because sometimes we need standard headers,
- # such as stdarg.h e.g. for variable args, as in printk().
- CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
- LINKFLAGS = ['-nostdlib', '-T' + ld_script, "-L" + libc_libpath, "-L" + libl4_path,\
- "-L" + libmem_path, "-L" + libposix_path],
- ASFLAGS = ['-D__ASSEMBLY__'],
- PROGSUFFIX = '.axf', # The suffix to use for final executable
- ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
- LIBS = [libc_name, 'gcc', 'libmc', 'libl4', 'gcc', libc_name, "posix"],
- CPPFLAGS = "-D__USERSPACE__",
- CPPPATH = ['#include', libl4_incpath1, kernel_incpath, libc_incpath, \
- libposix_incpath, libmem_incpath])
-
-src = [glob("src/*.c"), glob("*.c"), glob("src/arch/arm/*.c"), glob("src/memfs/*.c"), glob("src/lib/*.c")]
-objs = env.Object(src)
-physical_base = env.Command(physical_base_ld_script, prev_image, get_physical_base)
-crt0_copied = env.Command("crt0.o", libc_crt0, copy_crt0)
-
-task = env.Program(task_name, objs + [crt0_copied])
-env.Alias(task_name, task)
-env.Depends(task, physical_base)
diff --git a/tasks/libl4/SConscript b/tasks/libl4/SConscript
new file mode 100644
index 0000000..abaa43b
--- /dev/null
+++ b/tasks/libl4/SConscript
@@ -0,0 +1,33 @@
+# -*- mode: python; coding: utf-8; -*-
+
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
+
+Import('environment')
+
+e = environment.Clone()
+e.Append(CPPPATH = ['include'])
+
+# TODO: There are errors in this code that -Werror gives problems with.
+
+e['CCFLAGS'] = ['-g', '-nostdlib', '-Wall', '-ffreestanding', '-std=gnu99']
+
+objects = e.StaticObject(Glob('src/*.c') + Glob('src/' + e['ARCH'] + '/*.[cS]'))
+Depends(objects, e['configFiles'])
+library = e.StaticLibrary('l4', objects)
+
+Return('library')
diff --git a/tasks/libl4/SConstruct b/tasks/libl4/SConstruct
deleted file mode 100644
index 7a5de7f..0000000
--- a/tasks/libl4/SConstruct
+++ /dev/null
@@ -1,84 +0,0 @@
-#
-# Copyright (C) 2007 Bahadir Balban
-#
-
-import os
-import glob
-import sys
-from os.path import join
-from string import split
-
-# libposix paths:
-libposix_libpath = "../libposix"
-libposix_incpath = "../libposix/include/posix"
-
-project_root = "../.."
-kernel_headers = join(project_root, "include")
-config_h = join(project_root, "include/l4/config.h")
-
-env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
- CCFLAGS = ['-g', '-nostdlib', '-ffreestanding'],
- LINKFLAGS = ['-nostdlib'],
- ASFLAGS = ['-D__ASSEMBLY__'],
- ENV = {'PATH' : os.environ['PATH']},
- LIBS = 'gcc',
- CPPPATH = ['#include', libposix_incpath])
-
-
-def extract_arch_subarch_plat(config_header):
- '''
- From the autogenerated kernel config.h, extracts platform, archictecture,
- subarchitecture information. This is used to include the relevant headers
- from the kernel directories.
- '''
- arch = None
- subarch = None
- plat = None
-
- if not os.path.exists(config_header):
- print "\n\nconfig.h does not exist. "\
- "Please run: `scons configure' first\n\n"
- sys.exit()
- f = open(config_h, "r")
- while True:
- line = f.readline()
- if line == "":
- break
- parts = split(line)
- if len(parts) > 0:
- if parts[0] == "#define":
- if parts[1] == "__ARCH__":
- arch = parts[2]
- elif parts[1] == "__PLATFORM__":
- plat = parts[2]
- elif parts[1] == "__SUBARCH__":
- subarch = parts[2]
- f.close()
- if arch == None:
- print "Error: No config symbol found for architecture"
- sys.exit()
- if subarch == None:
- print "Error: No config symbol found for subarchitecture"
- sys.exit()
- if plat == None:
- print "Error: No config symbol found for platform"
- sys.exit()
- return arch, subarch, plat
-
-def create_symlinks(arch):
- if not os.path.exists("include/l4lib/arch"):
- os.system("ln -s %s %s" % ("arch-" + arch, "include/l4lib/arch"))
-
-arch, subarch, plat = extract_arch_subarch_plat(config_h)
-
-create_symlinks(arch) # Creates symlinks to architecture specific directories.
-
-headers = ["#include", "#include/libl4/arch", kernel_headers]
-
-env.Append(CPPPATH = headers)
-
-src = glob.glob("src/*.c") + glob.glob("src/%s/*.[cS]" % arch)
-
-libl4 = env.StaticLibrary('l4', src)
-
-
diff --git a/tasks/libmem/SConscript b/tasks/libmem/SConscript
new file mode 100644
index 0000000..432bf0a
--- /dev/null
+++ b/tasks/libmem/SConscript
@@ -0,0 +1,39 @@
+# -*- mode: python; coding: utf-8; -*-
+
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
+
+Import('environment')
+
+e = environment.Clone()
+e.Append(CPPPATH = ['#tasks/libl4/include' , '.' ])
+
+mmObjects = e.StaticObject(Glob('mm/*.c'))
+Depends(mmObjects, e['configFiles'])
+mmLibrary = e.StaticLibrary('mm', mmObjects)
+
+kmObjects = e.StaticObject(Glob('kmalloc/*.c'))
+Depends(kmObjects, e['configFiles'])
+kmLibrary = e.StaticLibrary('km', kmObjects)
+
+mcObjects = e.StaticObject(Glob('memcache/*.c'))
+Depends(mcObjects, e['configFiles'])
+mcLibrary = e.StaticLibrary('mc', mcObjects)
+
+libraries = (mmLibrary, kmLibrary, mcLibrary)
+
+Return('libraries')
diff --git a/tasks/libmem/SConstruct b/tasks/libmem/SConstruct
deleted file mode 100644
index 5a32b21..0000000
--- a/tasks/libmem/SConstruct
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Copyright (C) 2007 Bahadir Balban
-#
-
-import os
-import glob
-import sys
-from os.path import join
-from string import split
-
-project_root = "../.."
-headers_root = join(project_root, "include/l4")
-config_h = join(headers_root, "config.h")
-
-#libl4 paths
-libl4_headers = join(project_root, "tasks/libl4/include")
-libl4_libpath = join(project_root, "tasks/libl4")
-
-mm = "mm"
-kmalloc = "kmalloc"
-memcache = "memcache"
-tests = "tests"
-
-mm_dir = mm
-kmalloc_dir = kmalloc
-memcache_dir = memcache
-tests_dir = tests
-
-test_env = Environment(CC = 'gcc -m32',
- CCFLAGS = ['-g', '-std=gnu99', '-Wall', '-Werror'],
- ENV = {'PATH' : os.environ['PATH']},
- LIBS = ['gcc', 'mm', 'km', 'mc'],
- LIBPATH = ['#'],
- CPPPATH = ['#include', join(project_root, "include"), "#", libl4_headers])
-
-
-env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
- CCFLAGS = ['-g', '-nostdlib', '-Wall', '-Werror', '-ffreestanding', '-std=gnu99'],
- LINKFLAGS = ['-nostdlib'],
- ENV = {'PATH' : os.environ['PATH']},
- LIBS = 'gcc',
- CPPPATH = [join(project_root, "include"), "#", libl4_headers])
-
-if os.path.exists(config_h) is False:
- print "\nThis build requires a valid kernel configuration header."
- print "Please run `scons configure' in the kernel root directory."
- print "Choose the `tests' target to build memory allocator tests,"
- print "or any other target for real use.\n"
- sys.exit()
-
-mm_src = glob.glob("%s/*.c" % mm_dir)
-kmalloc_src = glob.glob("%s/*.c" % kmalloc_dir)
-memcache_src = glob.glob("%s/*.c" % memcache_dir)
-tests_src = glob.glob ("%s/*.c" % tests_dir)
-
-if "tests" in COMMAND_LINE_TARGETS:
- print "WARNING!!! Did you configure the kernel with test target first???"
- libmm = test_env.StaticLibrary(mm, mm_src)
- libkmalloc = test_env.StaticLibrary("km", kmalloc_src)
- libmemcache = test_env.StaticLibrary("mc", memcache_src)
- test_prog = test_env.Program("test", tests_src)
- env.Alias("tests", test_prog)
-else:
- libmm = env.StaticLibrary(mm, mm_src)
- libkmalloc = env.StaticLibrary("km", kmalloc_src)
- libmemcache = env.StaticLibrary("mc", memcache_src)
-
diff --git a/tasks/libmem/tests/SConscript b/tasks/libmem/tests/SConscript
deleted file mode 100644
index a5c3b82..0000000
--- a/tasks/libmem/tests/SConscript
+++ /dev/null
@@ -1,9 +0,0 @@
-
-# Inherit global environment
-Import('env')
-
-# The set of source files associated with this SConscript file.
-src_local = ['main.c', 'test_kmalloc.c', 'test_memcache.c', 'test_allocpage.c', 'test_alloc_generic.c', 'debug.c', 'memory.c', 'clz.c']
-
-obj = env.Object(src_local)
-Return('obj')
diff --git a/tasks/libposix/SConscript b/tasks/libposix/SConscript
new file mode 100644
index 0000000..e56940c
--- /dev/null
+++ b/tasks/libposix/SConscript
@@ -0,0 +1,33 @@
+# -*- mode: python; coding: utf-8; -*-
+
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
+
+Import('environment')
+
+e = environment.Clone()
+e.Append(CPPPATH = ['include', 'include/posix', '#tasks/libl4/include'])
+
+# TODO: There are errors in this code that -Werror gives problems with.
+
+e['CCFLAGS'] = ['-g', '-nostdlib', '-Wall', '-ffreestanding', '-std=gnu99']
+
+objects = e.StaticObject(Glob('*.c'))
+Depends(objects, e['configFiles'])
+library = e.StaticLibrary('posix', objects)
+
+Return('library')
diff --git a/tasks/libposix/SConstruct b/tasks/libposix/SConstruct
deleted file mode 100644
index 352c734..0000000
--- a/tasks/libposix/SConstruct
+++ /dev/null
@@ -1,74 +0,0 @@
-#
-# Copyright (C) 2007 Bahadir Balban
-#
-
-import os
-import glob
-import sys
-from os.path import join
-from string import split
-
-project_root = "../.."
-kernel_headers = join(project_root, "include")
-l4lib_headers = join(project_root, "tasks/libl4/include")
-config_h = join(project_root, "include/l4/config.h")
-
-env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
- CCFLAGS = ['-g', '-std=gnu99', '-nostdlib', '-ffreestanding'],
- LINKFLAGS = ['-nostdlib'],
- CPPPATH = ['#include'],
- ENV = {'PATH' : os.environ['PATH']},
- LIBS = 'gcc')
-
-
-def extract_arch_subarch_plat(config_header):
- '''
- From the autogenerated kernel config.h, extracts platform, archictecture,
- subarchitecture information. This is used to include the relevant headers
- from the kernel directories.
- '''
- arch = None
- subarch = None
- plat = None
-
- if not os.path.exists(config_header):
- print "\n\nconfig.h does not exist. "\
- "Please run: `scons configure' first\n\n"
- sys.exit()
- f = open(config_h, "r")
- while True:
- line = f.readline()
- if line == "":
- break
- parts = split(line)
- if len(parts) > 0:
- if parts[0] == "#define":
- if parts[1] == "__ARCH__":
- arch = parts[2]
- elif parts[1] == "__PLATFORM__":
- plat = parts[2]
- elif parts[1] == "__SUBARCH__":
- subarch = parts[2]
- f.close()
- if arch == None:
- print "Error: No config symbol found for architecture"
- sys.exit()
- if subarch == None:
- print "Error: No config symbol found for subarchitecture"
- sys.exit()
- if plat == None:
- print "Error: No config symbol found for platform"
- sys.exit()
- return arch, subarch, plat
-
-arch, subarch, plat = extract_arch_subarch_plat(config_h)
-
-headers = ["#include/posix", l4lib_headers, kernel_headers]
-
-env.Append(CPPPATH = headers)
-
-src = glob.glob("src/*.c") + glob.glob("*.c")
-
-libposix = env.StaticLibrary('posix', src)
-
-
diff --git a/tasks/mm0/SConscript b/tasks/mm0/SConscript
new file mode 100644
index 0000000..5c1ca07
--- /dev/null
+++ b/tasks/mm0/SConscript
@@ -0,0 +1,24 @@
+# -*- mode: python; coding: utf-8; -*-
+
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
+
+Import('environment', 'previousImage')
+
+program = environment['buildTask']('mm0', Glob('*.c') + [Glob(directory + '/*.c') for directory in [ 'src', 'src/lib', 'src/lib/elf', 'src/arch-' + environment['ARCH']]], environment, previousImage)
+
+Return('program')
diff --git a/tasks/mm0/SConstruct b/tasks/mm0/SConstruct
deleted file mode 100644
index 7ea96a6..0000000
--- a/tasks/mm0/SConstruct
+++ /dev/null
@@ -1,136 +0,0 @@
-#
-# User space application build script
-#
-# Copyright (C) 2007 Bahadir Balban
-#
-import os
-import sys
-import shutil
-from string import split
-from os.path import join
-from glob import glob
-
-task_name = "mm0"
-
-# The root directory of the repository where this file resides:
-project_root = "../.."
-tools_root = join(project_root, "tools")
-prev_image = join(project_root, "build/start.axf")
-libs_path = join(project_root, "libs")
-ld_script = "include/linker.lds"
-physical_base_ld_script = "include/physical_base.lds"
-
-# libc paths:
-libc_variant = "userspace"
-libc_libpath = join(libs_path, "c/build/%s" % libc_variant)
-libc_incpath = join(libc_libpath, "include")
-libc_crt0 = join(libs_path, "c/build/crt/sys-userspace/arch-arm/crt0.o")
-libc_name = "c-%s" % libc_variant
-
-# libl4 paths:
-libl4_path = "../libl4"
-libl4_incpath = join(libl4_path, "include")
-
-# libposix paths:
-libposix_path = "../libposix"
-libposix_incpath = join(libposix_path, "include")
-
-#libmem paths:
-libmem_path = "../libmem"
-libmem_incpath = "../libmem"
-
-# kernel paths:
-kernel_incpath = join(project_root, "include")
-
-# Kernel config header.
-config_h = join(project_root, "include/l4/config.h")
-
-
-# If crt0 is in its library path, it becomes hard to link with it.
-# For instance the linker script must use an absolute path for it.
-def copy_crt0(source, target, env):
- os.system("cp " + str(source[0]) + " " + str(target[0]))
-
-def get_physical_base(source, target, env):
- os.system(join(tools_root, "pyelf/readelf.py --first-free-page " + \
- prev_image +" >> " + physical_base_ld_script))
-
-# The kernel build environment:
-env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
- # We don't use -nostdinc because sometimes we need standard headers,
- # such as stdarg.h e.g. for variable args, as in printk().
- CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror' ],
- LINKFLAGS = ['-nostdlib', '-T' + ld_script, "-L" + libc_libpath, "-L" + libl4_path, \
- "-L" + libposix_path, "-L" + libmem_path],
- ASFLAGS = ['-D__ASSEMBLY__'],
- PROGSUFFIX = '.axf', # The suffix to use for final executable
- ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
- LIBS = [libc_name, 'libl4', 'libmm', 'libmc', 'libkm', 'libposix', \
- 'gcc', libc_name], # libgcc.a - This is required for division routines.
- CPPFLAGS = "-D__USERSPACE__",
- CPPPATH = ['#include', libl4_incpath, libc_incpath, kernel_incpath, \
- libmem_incpath, libposix_incpath])
-
-def extract_arch_subarch_plat(config_header):
- '''
- From the autogenerated kernel config.h, extracts platform, archictecture,
- subarchitecture information. This is used to include the relevant headers
- from the kernel directories.
- '''
- arch = None
- subarch = None
- plat = None
-
- if not os.path.exists(config_header):
- print "\n\nconfig.h does not exist. "\
- "Please run: `scons configure' first\n\n"
- sys.exit()
- f = open(config_h, "r")
- while True:
- line = f.readline()
- if line == "":
- break
- parts = split(line)
- if len(parts) > 0:
- if parts[0] == "#define":
- if parts[1] == "__ARCH__":
- arch = parts[2]
- elif parts[1] == "__PLATFORM__":
- plat = parts[2]
- elif parts[1] == "__SUBARCH__":
- subarch = parts[2]
- f.close()
- if arch == None:
- print "Error: No config symbol found for architecture"
- sys.exit()
- if subarch == None:
- print "Error: No config symbol found for subarchitecture"
- sys.exit()
- if plat == None:
- print "Error: No config symbol found for platform"
- sys.exit()
- return arch, subarch, plat
-
-def create_symlinks(arch):
- arch_path = "include/arch"
- arch_path2 ="src/arch"
- if os.path.exists(arch_path):
- os.system("rm %s" % (arch_path))
- os.system("ln -s %s %s" % ("arch-" + arch, arch_path))
- if os.path.exists(arch_path2):
- os.system("rm %s" % (arch_path2))
- os.system("ln -s %s %s" % ("arch-" + arch, arch_path2))
-
-arch, subarch, plat = extract_arch_subarch_plat(config_h)
-
-create_symlinks(arch) # Creates symlinks to architecture specific directories.
-
-src = [glob("src/*.c"), glob("src/lib/*.c"), glob("src/lib/elf/*.c"), glob("*.c"), glob("src/arch/*.c")]
-objs = env.Object(src)
-physical_base = env.Command(physical_base_ld_script, prev_image, get_physical_base)
-crt0_copied = env.Command("crt0.o", libc_crt0, copy_crt0)
-
-task = env.Program(task_name, objs + [crt0_copied])
-env.Alias(task_name, task)
-env.Depends(task, physical_base)
-
diff --git a/tasks/taskOrder.py b/tasks/taskOrder.py
new file mode 100644
index 0000000..b6550ec
--- /dev/null
+++ b/tasks/taskOrder.py
@@ -0,0 +1,22 @@
+# -*- mode: python; coding: utf-8; -*-
+
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
+
+# A sequence determining the order of tasks in the packing.
+
+taskOrder = ('mm0', 'fs0', 'test0')
diff --git a/tasks/test0/SConscript b/tasks/test0/SConscript
new file mode 100644
index 0000000..68267ef
--- /dev/null
+++ b/tasks/test0/SConscript
@@ -0,0 +1,24 @@
+# -*- mode: python; coding: utf-8; -*-
+
+# Codezero -- a microkernel for embedded systems.
+#
+# Copyright © 2009 B Labs Ltd
+#
+# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
+# General Public License as published by the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
+# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+# License for more details.
+#
+# You should have received a copy of the GNU General Public License along with this program. If not, see
+# .
+#
+# Author: Russel Winder
+
+Import('environment', 'previousImage')
+
+program = environment['buildTask']('test0', Glob('*.c') + Glob('src/*.c'), environment, previousImage, ['#tasks/libposix/include/posix'])
+
+Return('program')
diff --git a/tasks/test0/SConstruct b/tasks/test0/SConstruct
deleted file mode 100644
index 8be9ec7..0000000
--- a/tasks/test0/SConstruct
+++ /dev/null
@@ -1,109 +0,0 @@
-#
-# User space application build script
-#
-# Copyright (C) 2007 Bahadir Balban
-#
-import os
-import sys
-import shutil
-from os.path import join
-from glob import glob
-
-task_name = "test0"
-
-# The root directory of the repository where this file resides:
-project_root = "../.."
-tools_root = join(project_root, "tools")
-prev_image = join(project_root, "tasks/fs0/fs0.axf")
-libs_path = join(project_root, "libs")
-ld_script = "include/linker.lds"
-physical_base_ld_script = "include/physical_base.lds"
-
-# Libc situation:
-# Libposix has uClibc (and therefore posix) headers.
-# NICTA libc implements printf for us for now.
-# Libposix implements posix calls for us, e.g. mmap.
-# In conclusion nicta libc and libposix complement each other
-# they should not clash. In future libposix will be part of uclibc
-# and uclibc will be used.
-
-# libc paths:
-libc_variant = "userspace"
-libc_libpath = join(libs_path, "c/build/%s" % libc_variant)
-libc_incpath = join(libc_libpath, "include")
-libc_crt0 = join(libs_path, "c/build/crt/sys-userspace/arch-arm/crt0.o")
-libc_name = "c-%s" % libc_variant
-
-# libposix paths:
-libposix_libpath = "../libposix"
-libposix_incpath = "../libposix/include/posix"
-
-# libl4 paths:
-libl4_path = "../libl4"
-libl4_incpath = join(libl4_path, "include")
-
-# kernel paths:
-kernel_incpath = join(project_root, "include")
-
-# If crt0 is in its library path, it becomes hard to link with it.
-# For instance the linker script must use an absolute path for it.
-def copy_crt0(source, target, env):
- os.system("cp " + str(source[0]) + " " + str(target[0]))
-
-def get_physical_base(source, target, env):
- os.system(join(tools_root, "pyelf/readelf.py --first-free-page " + \
- prev_image + " >> " + physical_base_ld_script))
-
-# The kernel build environment:
-env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
- # We don't use -nostdinc because sometimes we need standard headers,
- # such as stdarg.h e.g. for variable args, as in printk().
- CCFLAGS = ['-g', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
- LINKFLAGS = ['-nostdlib', '-T' + ld_script, "-L" + libc_libpath, "-L" + libl4_path, \
- '-L' + libposix_libpath],
- ASFLAGS = ['-D__ASSEMBLY__'],
- PROGSUFFIX = '.axf', # The suffix to use for final executable
- ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
- LIBS = [libc_name, 'gcc', libc_name, 'libl4', 'libposix', libc_name],
- CPPFLAGS = "-D__USERSPACE__",
- CPPPATH = ['#include', libl4_incpath, libposix_incpath, kernel_incpath])
-
-
-test_exec_ld_script = "include/test_exec_linker.lds"
-# The kernel build environment:
-test_exec_env = Environment(CC = 'arm-none-linux-gnueabi-gcc',
- # We don't use -nostdinc because sometimes we need standard headers,
- # such as stdarg.h e.g. for variable args, as in printk().
- CCFLAGS = ['-O3', '-nostdlib', '-ffreestanding', '-std=gnu99', '-Wall', '-Werror'],
- LINKFLAGS = ['-nostdlib', '-T' + test_exec_ld_script, "-L" + libc_libpath, "-L" + libl4_path, \
- '-L' + libposix_libpath],
- ASFLAGS = ['-D__ASSEMBLY__'],
- PROGSUFFIX = '.axf', # The suffix to use for final executable
- ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path
- LIBS = [libc_name, 'gcc', libc_name, 'libl4', 'libposix', libc_name],
- CPPFLAGS = "-D__USERSPACE__",
- CPPPATH = ['#include', libl4_incpath, libposix_incpath, kernel_incpath])
-
-src = [glob("src/*.c"), glob("*.c"), glob("*.S"), glob("src/arch/arm/*.c"), glob("../libcont/*.c")]
-objs = env.Object(src)
-physical_base = env.Command(physical_base_ld_script, prev_image, get_physical_base)
-crt0_copied = env.Command("crt0.o", libc_crt0, copy_crt0)
-
-test_exec_src = [glob("src/test_exec/*.c")]
-test_exec_objs = test_exec_env.Object(test_exec_src)
-test_exec_name = "test_exec"
-test_exec = test_exec_env.Program(test_exec_name, test_exec_objs + [crt0_copied])
-test_exec_env.Alias(test_exec_name, test_exec)
-
-env.Depends(objs, test_exec)
-task = env.Program(task_name, objs + [crt0_copied])
-env.Alias(task_name, task)
-
-# I find this to be a BUG related to SCons. SCons is still good compared to
-# notoriously horrible makefiles, but it could have been better.
-# if test_exec doesn't depend on physical_base, test_exec is compiled but
-# task complains that physical_base is not there. However we already declared
-# its dependency below.
-
-env.Depends(test_exec, physical_base)
-env.Depends(task, physical_base)
diff --git a/tools/ksym_to_lds.py b/tools/ksym_to_lds.py
deleted file mode 100755
index c4325cb..0000000
--- a/tools/ksym_to_lds.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/python
-import os
-import sys
-from string import atoi
-from os import popen2
-from os.path import join
-
-symbols = ['break_virtual']
-builddir = "build"
-loaderdir = "loader"
-image = "start.axf"
-imgpath = join(builddir, image)
-asmfile = join(loaderdir, image) + ".S"
-symfile = "ksyms"
-asmheader = \
-'''
-/*
- * %s autogenerated from %s
- *
- * This file is included by the loader sources so that any
- * kernel symbol address can be known in advance and stopped
- * at by debuggers before virtual memory is enabled.
- */
-'''
-
-asmcontent = \
-'''
-
-.section .text
-.align 4
-.global %s;
-.type %s, function;
-.equ %s, %s
-
-'''
-def virt_to_phys(addr):
- return hex(int(addr, 16) - 0xF0000000)[:-1]
-
-def ksym_to_lds():
- asm = open(asmfile, "w+")
- asm.write(asmheader % (asmfile, imgpath))
- cmd = "arm-none-eabi-objdump -d " + imgpath + " | grep " + "\\<" + symbols[0] + "\\>" + " > " + symfile
- os.system(cmd)
- kf = open(symfile, "r")
- #child_out, child_in = popen2(cmd)
- while True:
- line = kf.readline()
- if len(line) is 0:
- break
- addr, sym = line.split()
- sym = sym[1:-2]
- addr = "0x" + addr
- addr = virt_to_phys(addr)
- if sym in symbols:
- print "Adding " + sym + " from " + imgpath + " to " + asmfile + " in physical"
- asm.write(asmcontent % (sym, sym, sym, addr))
- asm.close()
- kf.close()
- cmd = "rm -rf " + symfile
- os.system(cmd)
-if __name__ == "__main__":
- ksym_to_lds()
-