mirror of
https://github.com/drasko/codezero.git
synced 2026-01-12 02:43:15 +01:00
Bootdesc building working
This commit is contained in:
@@ -26,9 +26,14 @@ LINUXDIR = join(PROJROOT, 'conts/linux')
|
||||
LINUX_KERNELDIR = join(LINUXDIR, 'linux-2.6.28.10')
|
||||
LINUX_ROOTFSDIR = join(LINUXDIR, 'rootfs')
|
||||
|
||||
POSIXDIR = join(PROJROOT, 'conts/posix')
|
||||
POSIX_BOOTDESCDIR = join(POSIXDIR, 'bootdesc')
|
||||
|
||||
projpaths = { \
|
||||
'LINUX_ROOTFSDIR' : LINUX_ROOTFSDIR, \
|
||||
'LINUX_KERNELDIR' : LINUX_KERNELDIR, \
|
||||
'LINUXDIR' : LINUXDIR, \
|
||||
'BUILDDIR' : BUILDDIR, \
|
||||
'POSIXDIR' : POSIXDIR, \
|
||||
'POSIX_BOOTDESCDIR' : POSIX_BOOTDESCDIR
|
||||
}
|
||||
|
||||
@@ -76,18 +76,27 @@ fs0 = SConscript('fs0/SConscript', \
|
||||
|
||||
test0_env = env.Clone()
|
||||
test0_env.Replace(CPPPATH = ['include', KERNEL_INCLUDE, LIBL4_INCLUDE, LIBMEM_INCLUDE])
|
||||
#test0_env.Replace(CPPPATH = [LIBPOSIX_INCLUDE_USERSPACE, 'include', LIBC_INCLUDE, KERNEL_INCLUDE, LIBL4_INCLUDE, LIBMEM_INCLUDE])
|
||||
#test0_env.Append(CCFLAGS = '-nostdinc')
|
||||
test0 = SConscript('test0/SConscript', \
|
||||
exports = { 'config' : config, 'environment' : test0_env, 'contid' : contid}, duplicate = 0, \
|
||||
variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/posix' + '/test0'))
|
||||
|
||||
images = [mm0, fs0, test0]
|
||||
bootdesc_env = env.Clone()
|
||||
bootdesc_env['bootdesc_dir'] = 'bootdesc'
|
||||
|
||||
bootdesc = SConscript('bootdesc/SConscript', \
|
||||
exports = { 'config' : config, 'environment' : bootdesc_env, \
|
||||
'contid' : contid, 'images' : images }, duplicate = 0, \
|
||||
variant_dir = join(BUILDDIR, 'cont' + str(contid) + '/posix' + '/bootdesc'))
|
||||
|
||||
Depends(fs0, libposix)
|
||||
Depends(test0, libposix)
|
||||
Depends(bootdesc, [fs0, test0, mm0])
|
||||
|
||||
Alias('libposix', libposix)
|
||||
Alias('mm0', mm0)
|
||||
Alias('fs0', fs0)
|
||||
Alias('test0', test0)
|
||||
Alias('bootdesc', bootdesc)
|
||||
|
||||
Default([mm0, fs0, libposix, test0])
|
||||
Default([mm0, fs0, libposix, test0, bootdesc])
|
||||
|
||||
@@ -3,31 +3,26 @@
|
||||
# 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
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# Author: Russel Winder
|
||||
|
||||
import os.path
|
||||
import subprocess
|
||||
import shutil
|
||||
import sys, subprocess, shutil
|
||||
from os.path import *
|
||||
|
||||
Import('environment', 'images')
|
||||
Import('config', 'environment', 'images')
|
||||
|
||||
e = environment.Clone()
|
||||
e.Append(LINKFLAGS = ['-T' + e['posixServicesDirectory'] + '/bootdesc/linker.lds'])
|
||||
e.Append(CPPPATH = ['#' + e['includeDirectory']])
|
||||
e.Append(LINKFLAGS = ['-T' + e['bootdesc_dir'] + '/linker.lds'])
|
||||
#e.Append(LINKFLAGS = ['-T' + '/linker.lds'])
|
||||
|
||||
bootdescTemplate = \
|
||||
PROJRELROOT = '../../../../'
|
||||
|
||||
sys.path.append(os.path.abspath(PROJRELROOT))
|
||||
|
||||
from config.projpaths import *
|
||||
from config.configuration import *
|
||||
from tools.pyelf import elf
|
||||
|
||||
bootdesc_template = \
|
||||
'''
|
||||
/* This file is autogenerated, do not edit by hand. */
|
||||
|
||||
@@ -54,7 +49,7 @@ struct bootdesc bootdesc = {
|
||||
};
|
||||
'''
|
||||
|
||||
imageTemplate = \
|
||||
image_template = \
|
||||
''' [%s] = {
|
||||
.name = "%s",
|
||||
.phys_start = %s,
|
||||
@@ -62,36 +57,49 @@ imageTemplate = \
|
||||
},
|
||||
'''
|
||||
|
||||
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 conv_hex(val):
|
||||
hexval = hex(val)
|
||||
if hexval[-1:] == 'L':
|
||||
hexval = hexval[:-1]
|
||||
return hexval
|
||||
|
||||
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 image_lma_start_end(img):
|
||||
elffile = elf.ElfFile.from_file(img)
|
||||
paddr_first = 0
|
||||
paddr_start = 0
|
||||
paddr_end = 0
|
||||
for pheader in elffile.pheaders:
|
||||
x = pheader.ai
|
||||
if str(x.p_type) != "LOAD":
|
||||
continue
|
||||
if paddr_first == 0:
|
||||
paddr_first = 1
|
||||
paddr_start = x.p_paddr.value
|
||||
if paddr_start > x.p_paddr.value:
|
||||
paddr_start = x.p_paddr.value
|
||||
if paddr_end < x.p_paddr + x.p_memsz:
|
||||
paddr_end = x.p_paddr + x.p_memsz
|
||||
return paddr_start, paddr_end
|
||||
|
||||
def relocateBootdesc(target, source, env):
|
||||
name, start, end = generateLocationData(source[1])
|
||||
print "arm-none-linux-gnueabi-objcopy" + " --adjust-section-vma .data=" + end + " " + source[0].path
|
||||
# process = subprocess.Popen(executable='arm-none-linux-gnueabi-objcopy', args=(
|
||||
# '--adjust-section-vma .data=' + end,
|
||||
# source[0].path))
|
||||
# assert process.wait() == 0
|
||||
os.system("arm-none-linux-gnueabi-objcopy --adjust-section-vma .data=" + end + " " + source[0].path)
|
||||
shutil.copyfile(source[0].path, target[0].path)
|
||||
def generate_bootdesc(target, source, env):
|
||||
with open(target[0].path, 'w+' ) as f:
|
||||
images_string = ''
|
||||
for index in range(len(source)):
|
||||
start, end = image_lma_start_end(source[index].path)
|
||||
images_string += image_template % (str(index), basename(source[index].path), conv_hex(start), conv_hex(end))
|
||||
f.write(bootdesc_template % (len(source), len(source), images_string))
|
||||
|
||||
objects = e.Object(e.Command('bootdesc.c', images, generateBootdesc))
|
||||
Depends(objects, e['configFiles'])
|
||||
bootdesc = e.Command('bootdesc.axf', e.Program('bootdesc_intermediate', objects) + [images[1]] , relocateBootdesc)
|
||||
Depends(bootdesc, e['configFiles'])
|
||||
def relocate_bootdesc(target, source, env):
|
||||
bootdesc_raw = source[0]
|
||||
images = source[1:]
|
||||
mm0 = images[0]
|
||||
start, end = image_lma_start_end(mm0.path)
|
||||
print "arm-none-linux-gnueabi-objcopy --adjust-section-vma .data=" + conv_hex(end) + " " + bootdesc_raw.path
|
||||
os.system("arm-none-linux-gnueabi-objcopy --adjust-section-vma .data=" + conv_hex(end) + " " + bootdesc_raw.path)
|
||||
shutil.copyfile(bootdesc_raw.path, target[0].path)
|
||||
|
||||
bootdesc_c = e.Command('bootdesc.c', images, generate_bootdesc)
|
||||
bootdesc_raw = e.Program('bootdesc_raw.elf', bootdesc_c)
|
||||
bootdesc = e.Command('bootdesc.elf', [bootdesc_raw, images], relocate_bootdesc)
|
||||
|
||||
Return('bootdesc')
|
||||
|
||||
@@ -8,116 +8,16 @@ import sys
|
||||
import shutil
|
||||
from os.path import join
|
||||
|
||||
# The root directory of the repository where this file resides:
|
||||
project_root = "../.."
|
||||
tools_root = "../../tools"
|
||||
builddir = ARGUMENTS.get('builddir', 'build/conts/posix')
|
||||
|
||||
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.
|
||||
PROGSUFFIX = '.elf',
|
||||
ENV = {'PATH' : os.environ['PATH']},
|
||||
LIBS = 'gcc',
|
||||
CPPPATH = '#include')
|
||||
|
||||
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)
|
||||
bootdesc = env.Program(join(builddir, 'bootdesc.elf'), join(builddir, 'bootdesc.c'))
|
||||
Default(bootdesc)
|
||||
|
||||
@@ -30,6 +30,9 @@ def build_linux_container(projpaths, container):
|
||||
rootfs_builder)
|
||||
return linux_container_packer.pack_container()
|
||||
|
||||
def build_posix_container(projpaths, container):
|
||||
posix_builder = PosixBuilder(projpaths, container)
|
||||
posix_builder.build_posix()
|
||||
|
||||
def glob_by_walk(arg, dirname, names):
|
||||
ext, imglist = arg
|
||||
@@ -61,6 +64,8 @@ def build_all_containers():
|
||||
cont_images.append(build_linux_container(projpaths, container))
|
||||
elif container.type == 'bare':
|
||||
cont_images.append(build_default_container(projpaths, container))
|
||||
elif container.type == 'posix':
|
||||
cont_images.append(build_posix_container(projpaths, container))
|
||||
else:
|
||||
print "Error: Don't know how to build " + \
|
||||
"container of type: %s" % (container.type)
|
||||
|
||||
@@ -58,71 +58,6 @@ def main():
|
||||
print "Afterburn:"
|
||||
for burn in burns:
|
||||
print " ", burn
|
||||
if options.lma_boundary:
|
||||
paddr_first = 0
|
||||
paddr_start = 0
|
||||
paddr_end = 0
|
||||
for pheader in elffile.pheaders:
|
||||
x = pheader.ai
|
||||
if str(x.p_type) != "LOAD":
|
||||
continue
|
||||
# First time assign the first p_paddr.
|
||||
if paddr_first == 0:
|
||||
paddr_first = 1
|
||||
paddr_start = x.p_paddr.value
|
||||
# Then if new paddr is lesser, reassign start.
|
||||
if paddr_start > x.p_paddr.value:
|
||||
paddr_start = x.p_paddr.value
|
||||
# If end of segment is greater, reassign end.
|
||||
if paddr_end < x.p_paddr + x.p_memsz:
|
||||
paddr_end = x.p_paddr + x.p_memsz
|
||||
rest, image_name = path.split(args[0])
|
||||
if image_name[-4] == ".":
|
||||
image_name = image_name[:-4]
|
||||
print image_name
|
||||
if hex(paddr_start)[-1] == "L":
|
||||
print "image_start " + hex(paddr_start)[:-1]
|
||||
else:
|
||||
print "image_start " + hex(paddr_start)
|
||||
if hex(paddr_end)[-1] == "L":
|
||||
print "image_end " + hex(paddr_end)[:-1]
|
||||
else:
|
||||
print "image_end " + hex(paddr_end)
|
||||
|
||||
if options.ffpage:
|
||||
paddr_max = 0
|
||||
p_align = 0
|
||||
for pheader in elffile.pheaders:
|
||||
x = pheader.ai
|
||||
if str(x.p_type) == "LOAD":
|
||||
paddr = x.p_paddr + x.p_memsz
|
||||
p_align = x.p_align
|
||||
if paddr > paddr_max:
|
||||
paddr_max = paddr
|
||||
|
||||
print "/*\n" + \
|
||||
" * The next free p_align'ed LMA base address\n" + \
|
||||
" *\n" + \
|
||||
" * p_align = " + hex(p_align.value) + "\n" + \
|
||||
" *\n" + \
|
||||
" * Recap from ELF spec: p_align: Loadable process segments must have\n" + \
|
||||
" * congruent values for p_vaddr and p_offset, modulo the page size. \n" + \
|
||||
" * This member gives the value to which the segments are aligned in \n" + \
|
||||
" * memory and in the file. Values 0 and 1 mean that no alignment is \n" + \
|
||||
" * required. Otherwise, p_align should be a positive, integral power\n" + \
|
||||
" * of 2, and p_addr should equal p_offset, modulo p_align. \n" + \
|
||||
" * This essentially means next available address must be aligned at\n" + \
|
||||
" * p_align, rather than the page_size, which one (well, I) would \n" + \
|
||||
" * normally expect. \n" + \
|
||||
" */\n"
|
||||
paddr_aligned = paddr_max & ~(p_align.value - 1)
|
||||
if paddr_max & (p_align.value - 1):
|
||||
paddr_aligned += p_align.value
|
||||
if hex(paddr_aligned)[-1] == "L":
|
||||
print "physical_base = " + hex(paddr_aligned)[:-1] + ";"
|
||||
else:
|
||||
print "physical_base = " + hex(paddr_aligned) + ";"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user