# # 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])) def relocate_bootdesc(source, target, env): f = open("start.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)