# -*- mode: python; coding: utf-8; -*- # # Codezero -- a microkernel for embedded systems. # # P.S : This file is called from PROJROOT directory, # so all paths are given relative to PROJROOT. # # Copyright © 2009 B Labs Ltd import os, sys from os.path import join sys.path.append(os.getcwd()) from scripts.config.configuration import * from scripts.config.projpaths import * from scripts.loader.generate_loader_asm import * config = configuration_retrieve() arch = config.arch gcc_arch_flag = config.gcc_arch_flag symbols = config.all variant = 'baremetal' # Locally important paths are here LIBC_PATH = 'loader/libs/c' LIBC_LIBPATH = join(BUILDDIR, LIBC_PATH) LIBC_INCPATH = ['#' + join(LIBC_PATH, 'include'), '#' + join(LIBC_PATH, 'include/arch/' + arch)] LIBELF_PATH = 'loader/libs/elf' LIBELF_LIBPATH = join(BUILDDIR, LIBELF_PATH) LIBELF_INCPATH = '#' + join(LIBELF_PATH, 'include') env = Environment(CC = config.toolchain_kernel + 'gcc', AR = config.toolchain_kernel + 'ar', RANLIB = config.toolchain_kernel + 'ranlib', # 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', '-march=' + gcc_arch_flag], LINKFLAGS = ['-nostdlib', '-T' + join(BUILDDIR, 'loader/linker.lds'), '-u_start'], ASFLAGS = ['-D__ASSEMBLY__'], PROGSUFFIX = '.elf', ENV = {'PATH' : os.environ['PATH']}, LIBS = ['gcc', 'elf', 'libdev-baremetal', 'c-baremetal', 'gcc'], LIBPATH = [LIBDEV_BAREMETAL_LIBPATH, LIBELF_LIBPATH, LIBC_LIBPATH], CPPPATH = [KERNEL_HEADERS, LIBDEV_INCLUDE, LIBC_INCPATH, LIBELF_INCPATH], CPPFLAGS = '-include l4/config.h -include l4/macros.h \ -include l4/types.h -D__KERNEL__') libdev_builddir = join(join(BUILDDIR, LIBDEV_RELDIR), 'sys-' + variant) objs = SConscript(join(LIBDEV_RELDIR, 'SConscript'), duplicate = 0, exports = { 'env' : env, 'type' : variant, 'build_dir' : libdev_builddir}, variant_dir = join(BUILDDIR, LIBDEV_RELDIR)) objs += SConscript('loader/libs/c/SConscript', duplicate = 0, exports = { 'env' : env, 'type' : variant}, variant_dir = join(BUILDDIR, 'loader/libs/c')) objs += SConscript('loader/libs/elf/SConscript', duplicate = 0, exports = { 'env' : env }, variant_dir = join(BUILDDIR, 'loader/libs/elf')) objs += SConscript('loader/SConscript', duplicate = 0, exports = { 'env' : env }, variant_dir = join(BUILDDIR, 'loader')) # # Find the LMA for FINAL_ELF # Let size of physical memory hole needed for FINAL_ELF be 16MB # and default LMA = 32MB, # FIXME: default LMA = get_kernel_end_address() # def find_loader_load_address(target, source, env): # Start/end addresses of various physical memory regions defined array_start = [] array_end = [] for sym, val in symbols: if re.search("(PHYS)([0-9]){1,4}(_START)", sym): array_start.append(int(val, 0)) elif re.search("(PHYS)([0-9]){1,4}(_END)", sym): array_end.append(int(val, 0)) array_start.sort() array_end.sort() mem_needed = 0x1000000 loadaddr = 0x1000000 for index, end in enumerate(array_end): loadaddr = end if (index+1) >= len(array_start): # Reached end of start_array break else: start = array_start[index+1] if start - end >= mem_needed: break # Create target file with open(source[1].path, 'r') as input: buffer = input.read() #print '\nLoad address for FINAL_ELF: ' + str(conv_hex(loadaddr)) with open(target[0].path, 'w+') as output: output.write(buffer % str(loadaddr)) return None def ksym_to_loader(target, source, env): generate_ksym_to_loader(target[0].path, source[0].path) def gen_loader_images_S(target, source, env): generate_image_S(target[0].path, source) # Builders loader_image_S = Builder(action = gen_loader_images_S) env.Append(BUILDERS = {'IMAGE_S' : loader_image_S}) env.IMAGE_S(join(BUILDDIR, 'loader/images.S'), [KERNEL_ELF, join(BUILDDIR, 'conts/containers.elf')]) objs += env.Object(join(BUILDDIR, 'loader/images.S')) loader_ksyms = Builder(action = ksym_to_loader) env.Append(BUILDERS = {'LOADER_KSYSM' : loader_ksyms}) env.LOADER_KSYSM(join(BUILDDIR, 'loader/ksyms.S'), [KERNEL_ELF]) objs += env.Object(join(BUILDDIR, 'loader/ksyms.S')) lma_lds = Builder(action = find_loader_load_address) env.Append(BUILDERS = {'LMA_LDS' : lma_lds}) env.LMA_LDS(join(BUILDDIR, 'loader/linker.lds'), [KERNEL_ELF, 'loader/linker.lds.in']) final_elf = env.Program(FINAL_ELF, objs) Depends(objs,join(BUILDDIR, 'conts/containers.elf')) Depends(objs,join(BUILDDIR, 'kernel.elf')) Depends(final_elf, join(BUILDDIR, 'loader/linker.lds'))