diff --git a/config/cml/container_ruleset.template b/config/cml/container_ruleset.template index f36d698..870b914 100644 --- a/config/cml/container_ruleset.template +++ b/config/cml/container_ruleset.template @@ -2,6 +2,7 @@ symbols CONT%(cn)d_TYPE_LINUX 'Linux Container' CONT%(cn)d_TYPE_BARE 'Bare Container' CONT%(cn)d_TYPE_POSIX 'Codezero POSIX Services' +CONT%(cn)d_TYPE_TEST 'Test Container' CONT%(cn)d_OPT_NAME 'Container Name' CONT%(cn)d_PHYSMEM_REGIONS 'Container %(cn)d Number of Physical Regions' @@ -116,10 +117,11 @@ default CONT%(cn)d_VIRT4_END from 0x0 default CONT%(cn)d_VIRT5_START from 0x0 default CONT%(cn)d_VIRT5_END from 0x0 -default CONT%(cn)d_OPT_NAME from (CONT%(cn)d_TYPE_LINUX==y) ? "linux%(cn)d" : ((CONT%(cn)d_TYPE_BARE==y) ? "bare%(cn)d" : "posix%(cn)d") +default CONT%(cn)d_OPT_NAME from (CONT%(cn)d_TYPE_LINUX==y) ? "linux%(cn)d" : ((CONT%(cn)d_TYPE_BARE==y) ? "bare%(cn)d" : ((CONT%(cn)d_TYPE_TEST==y) ? "test%(cn)d" : "posix%(cn)d")) when CONT%(cn)d_TYPE_LINUX==y suppress cont%(cn)d_bare_pager_params cont%(cn)d_posix_pager_params when CONT%(cn)d_TYPE_BARE==y suppress cont%(cn)d_linux_pager_params cont%(cn)d_posix_pager_params +when CONT%(cn)d_TYPE_TEST==y suppress cont%(cn)d_linux_pager_params cont%(cn)d_posix_pager_params when CONT%(cn)d_TYPE_POSIX==y suppress cont%(cn)d_linux_pager_params symbols @@ -192,6 +194,7 @@ choices container%(cn)d_type CONT%(cn)d_TYPE_LINUX CONT%(cn)d_TYPE_BARE CONT%(cn)d_TYPE_POSIX + CONT%(cn)d_TYPE_TEST default CONT%(cn)d_TYPE_BARE menu cont%(cn)d_menu diff --git a/config/configuration.py b/config/configuration.py index 8eb5d06..2ac59d1 100644 --- a/config/configuration.py +++ b/config/configuration.py @@ -151,6 +151,8 @@ class configuration: self.containers[id].type = "posix" elif param2 == "BARE": self.containers[id].type = "bare" + elif param2 == "TEST": + self.containers[id].type = "test" # Extract parameters for containers def get_container_parameters(self, name, val): diff --git a/config/projpaths.py b/config/projpaths.py index 60cdd49..d2af30d 100644 --- a/config/projpaths.py +++ b/config/projpaths.py @@ -30,6 +30,8 @@ LINUX_ATAGSDIR = join(LINUXDIR, 'atags') POSIXDIR = join(PROJROOT, 'conts/posix') POSIX_BOOTDESCDIR = join(POSIXDIR, 'bootdesc') +TESTDIR = join(PROJROOT, 'conts/test') + projpaths = { \ 'LINUX_ATAGSDIR' : LINUX_ATAGSDIR, \ 'LINUX_ROOTFSDIR' : LINUX_ROOTFSDIR, \ diff --git a/conts/test/SConscript b/conts/test/SConscript new file mode 100644 index 0000000..4f5e381 --- /dev/null +++ b/conts/test/SConscript @@ -0,0 +1,44 @@ + +Import('config', 'env', 'contid') + +import os, sys +from config.projpaths import * + +arch = config.arch + +sys.path.append('../../') +from config.lib import * + +container = next((c for c in config.containers if int(c.id) == int(contid)), None) + +CONTAINER_INCLUDE = join(BUILDDIR, 'cont' + str(contid) + '/test' + '/include') + +def generate_linker_script(target, source, env): + with open(source[0].path, 'r') as lds_in: + linker_script = lds_in.read() + with open(target[0].path, 'w+') as lds_out: + assert container.pager_vma != 0 + assert container.pager_lma != 0 + lds_out.write(linker_script % (conv_hex(container.pager_vma), conv_hex(container.pager_lma))) + +def generate_container_h(target, source, env): + with open(source[0].path, 'r') as fin: + str = fin.read() + with open(target[0].path, 'w+') as fout: + # Make any manipulations here + fout.write(str % (container.name, container.id, container.id)) + +linker_lds = Command('include/linker.lds', 'include/linker.lds.in', generate_linker_script) + +container_h = Command('include/container.h', 'include/container.h.in', generate_container_h) + +src = [Glob('*.[cS]') + Glob('src/*.[cS]')] + +env.Append(LINKFLAGS = ['-T' + linker_lds[0].path, '-u_start']) +env.Append(CPPPATH = [CONTAINER_INCLUDE]) + +objs = env.Object(src) +prog = env.Program('main.elf', objs) +Depends(linker_lds, CML2_CONFIG_H) +Depends(prog, linker_lds) + diff --git a/conts/test/SConstruct b/conts/test/SConstruct new file mode 100644 index 0000000..af97623 --- /dev/null +++ b/conts/test/SConstruct @@ -0,0 +1,56 @@ +# -*- mode: python; coding: utf-8; -*- +# +# Codezero -- Virtualization microkernel for embedded systems. +# +# Copyright © 2009 B Labs Ltd +# +import os, shelve, sys +from os.path import * + +PROJRELROOT = '../../' + +sys.path.append(PROJRELROOT) + +from config.projpaths import * +from config.configuration import * +from config.lib import * + +config = configuration_retrieve() +arch = config.arch + + +LIBL4_RELDIR = 'conts/libl4' +KERNEL_INCLUDE = join(PROJROOT, 'include') +LIBL4_DIR = join(PROJROOT, LIBL4_RELDIR) +LIBL4_INCLUDE = join(LIBL4_DIR, 'include') +LIBL4_LIBPATH = join(BUILDDIR, LIBL4_RELDIR) + +# Locally important paths are here +LIBC_RELDIR = 'conts/libc' +LIBC_DIR = join(PROJROOT, LIBC_RELDIR) +LIBC_LIBPATH = join(BUILDDIR, LIBC_RELDIR) +LIBC_INCLUDE = [join(LIBC_DIR, 'include'), \ + join(LIBC_DIR, 'include/arch' + '/' + arch)] + + +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', '-mcpu=arm926ej-s', '-nostdlib', '-ffreestanding', \ + '-std=gnu99', '-Wall', '-Werror'], + LINKFLAGS = ['-nostdlib'], + ASFLAGS = ['-D__ASSEMBLY__'], + PROGSUFFIX = '.elf', # The suffix to use for final executable + ENV = {'PATH' : os.environ['PATH']}, # Inherit shell path + LIBS = ['gcc', 'libl4', 'c-userspace', 'gcc', 'c-userspace'], # libgcc.a - This is required for division routines. + CPPPATH = ["#include", KERNEL_INCLUDE, LIBL4_INCLUDE, LIBC_INCLUDE], + LIBPATH = [LIBL4_LIBPATH, LIBC_LIBPATH], + CPPFLAGS = '-include l4/config.h -include l4/macros.h -include l4/types.h') + + +contid = ARGUMENTS.get('cont', '0') + +SConscript('SConscript', \ + exports = { 'config' : config, 'env' : env, 'contid' : contid }, duplicate = 0, \ + variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/test')) + diff --git a/conts/test/container.c b/conts/test/container.c new file mode 100644 index 0000000..7bcbf9e --- /dev/null +++ b/conts/test/container.c @@ -0,0 +1,21 @@ +/* + * Container entry point for pager + * + * Copyright (C) 2007-2009 B Labs Ltd. + */ + +#include +#include + + +void main(void); + +void __container_init(void) +{ + /* Generic L4 initialisation */ + __l4_init(); + + /* Entry to main */ + main(); +} + diff --git a/conts/test/hello.c b/conts/test/hello.c new file mode 100644 index 0000000..054adc9 --- /dev/null +++ b/conts/test/hello.c @@ -0,0 +1,13 @@ +/* + * Autogenerated hello world print function + */ + +#include +#include + +int print_hello_world(void) +{ + printf("%s: Hello world from %s!\n", __CONTAINER__, __CONTAINER_NAME__); + return 0; +} + diff --git a/conts/test/include/container.h.in b/conts/test/include/container.h.in new file mode 100644 index 0000000..5015fd6 --- /dev/null +++ b/conts/test/include/container.h.in @@ -0,0 +1,13 @@ +/* + * Autogenerated definitions for this container. + */ +#ifndef __CONTAINER_H__ +#define __CONTAINER_H__ + + +#define __CONTAINER_NAME__ "%s" +#define __CONTAINER_ID__ %d +#define __CONTAINER__ "cont%d" + + +#endif /* __CONTAINER_H__ */ diff --git a/conts/test/include/linker.lds.in b/conts/test/include/linker.lds.in new file mode 100644 index 0000000..ab525c4 --- /dev/null +++ b/conts/test/include/linker.lds.in @@ -0,0 +1,26 @@ +/* + * Example working linker script for this container. + * + * Copyright (C) 2009 B Labs Ltd. + */ + +vma_start = %s; +lma_start = %s; +offset = vma_start - lma_start; + +ENTRY(_start) + +SECTIONS +{ + . = vma_start; + .text : AT (ADDR(.text) - offset) { *(.text.head) *(.text) } + .rodata : AT (ADDR(.rodata) - offset) { *(.rodata) } + .rodata1 : AT (ADDR(.rodata1) - offset) { *(.rodata1) } + + . = ALIGN(4K); + .data : AT (ADDR(.data) - offset) { *(.data) } + .bss : AT (ADDR(.bss) - offset) { *(.bss) } + . += 0x1000; + . = ALIGN(8); + __stack = .; +} diff --git a/conts/test/main.c b/conts/test/main.c new file mode 100644 index 0000000..d2d8ed6 --- /dev/null +++ b/conts/test/main.c @@ -0,0 +1,16 @@ +/* + * Main function for this container + */ +#include +#include +#include + +extern int print_hello_world(void); + +int main(void) +{ + print_hello_world(); + + return 0; +} + diff --git a/scripts/conts/containers.py b/scripts/conts/containers.py index e0bce4a..4207cc8 100755 --- a/scripts/conts/containers.py +++ b/scripts/conts/containers.py @@ -63,6 +63,21 @@ def build_posix_container(projpaths, container): container_packer = DefaultContainerPacker(container, images) return container_packer.pack_container() +# We simply use SCons to figure all this out from container.id +# Builds the test container. +def build_test_container(projpaths, container): + images = [] + cwd = os.getcwd() + os.chdir(TESTDIR) + print '\nBuilding the Test Container...' + scons_cmd = 'scons ' + 'cont=' + str(container.id) + print "Issuing scons command: %s" % scons_cmd + os.system(scons_cmd) + builddir = source_to_builddir(TESTDIR, container.id) + os.path.walk(builddir, glob_by_walk, ['*.elf', images]) + container_packer = DefaultContainerPacker(container, images) + return container_packer.pack_container() + # This simply calls SCons on a given container, and collects # all images with .elf extension, instead of using whole classes # for building and packing. @@ -89,6 +104,8 @@ def build_all_containers(): cont_images.append(build_default_container(projpaths, container)) elif container.type == 'posix': cont_images.append(build_posix_container(projpaths, container)) + elif container.type == 'test': + cont_images.append(build_test_container(projpaths, container)) else: print "Error: Don't know how to build " + \ "container of type: %s" % (container.type)