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() -