genode/base-hw/run/env
Stefan Kalkowski e717ad656f base-hw: preserve symbolic link bin/core
In this case "mv A B" works slightly different than "cp A B; rm A" as
symbolic links come into play. The statements should copy the contents
of A into the symboliv link at B (preserving it as is) and remove A. The
mv would replace the link B by the binary A.

Fixes #805.
2013-07-12 15:23:33 +02:00

241 lines
6.1 KiB
Plaintext

#!/usr/bin/expect
#
# \brief Implementation of the 'tool/run' interface
# \author Martin Stein
# \date 2011-12-16
#
###############
## Utilities ##
###############
#
# Ensure that the next Genode build includes no target specific boot modules
#
proc clean_boot_modules { } {
exec rm -rf boot_modules.s var/libcache/boot_modules/boot_modules.o }
##########################
## 'tool/run' interface ##
##########################
proc build {targets} {
# skip targets that shall not be build
if {[get_cmd_switch --skip-build]} return
# handle false remnants of previous builds
clean_boot_modules
#
# Build all remaining targets.
# Core is build with a dummy boot-modules file first.
#
regsub -all {\s\s+} $targets " " targets
set timeout 10000
set pid [eval "spawn make $targets"]
expect { eof { } }
if {[lindex [wait $pid] end] != 0} {
puts stderr "Error: Genode build failed"
exit -1
}
}
proc create_boot_directory { } {
exec rm -rf [run_dir]
exec mkdir -p [run_dir]/genode
}
proc build_boot_image {binaries} {
global run_target
# strip binaries
copy_and_strip_genode_binaries_to_run_dir $binaries
# append init config
if {[file exists "[run_dir]/genode/config"] == 1} {
append binaries " config"
}
#
# Compose a platform specific assembly file 'boot_modules.s', that
# enables the creation of a single boot image. The file rawly includes
# all binaries given in 'binaries', minus 'core', if given, plus 'config',
# if available. It also provides a simple file system, that enables Genode
# to access these BLOBs. To build a single image this file is simply
# linked against core. To build core stand-alone this file is substituted
# by a dummy version. 'boot_modules.s' must be composed on demand, because
# it depends on the individual run scenario.
#
set boot_modules "[run_dir]/boot_modules.s"
if { [have_spec {arm}] } {
set load_store_align_l2 2
set min_page_align_l2 12
# introduce boot module headers
exec echo -e \
"/**" \
"\n * This file was automatically generated by the procedure" \
"\n * 'build_boot_image' in 'base-hw/run/env'." \
"\n */" \
"\n" \
"\n.section .data" \
"\n" \
"\n.p2align ${load_store_align_l2}" \
"\n.global _boot_modules_begin" \
"\n_boot_modules_begin:" \
"\n.string \"GROM\"" \
"\n" \
"\n.p2align ${load_store_align_l2}" \
"\n.global _boot_module_headers_begin" \
"\n_boot_module_headers_begin:" > $boot_modules
# generate header for each boot module except core
set i 1
foreach binary $binaries {
if {$binary == "core"} { continue }
exec echo -e \
"\n.long mod${i}_name" \
"\n.long mod${i}_start" \
"\n.long mod${i}_end - mod${i}_start" >> $boot_modules
incr i
}
# end boot module headers
exec echo -e \
"\n.global _boot_module_headers_end" \
"\n_boot_module_headers_end:" \
"\n" >> $boot_modules
# generate name string for each module except core
set i 1
foreach binary $binaries {
if {$binary == "core"} { continue }
exec echo -e \
".p2align ${load_store_align_l2}" \
"\nmod${i}_name:" \
"\n.string \"${binary}\"" \
"\n.byte 0" \
"\n" >> $boot_modules
incr i
}
# include raw data of modules consecutively but page aligned
set i 1
foreach binary $binaries {
if {$binary == "core"} { continue }
exec echo -e \
".p2align ${min_page_align_l2}" \
"\nmod${i}_start:" \
"\n.incbin \"[run_dir]/genode/${binary}\"" \
"\nmod${i}_end:" \
"\n" >> $boot_modules
incr i
}
# end boot-modules file
exec echo -e \
".global _boot_modules_end" \
"\n_boot_modules_end:" >> $boot_modules
} else {
puts stderr "Error: Unknown architecture"
puts stderr " SPEC must contain one of: 'arm'"
exit -1
}
clean_boot_modules
exec ln -s $boot_modules boot_modules.s
# recompile core with boot modules
exec cp -L bin/core core/core.standalone
exec find . -type f -name "core" -delete
set timeout 10000
set pid [eval "spawn make core"]
expect { eof { } }
if {[lindex [wait $pid] end] != 0} {
clean_boot_modules
puts stderr "Error: Genode build failed"
exit -1
}
clean_boot_modules
exec rm -rf "[run_dir]/genode"
# offer ELF image
set elf_img "[run_dir]/image.elf"
exec cp -L bin/core $elf_img
exec [cross_dev_prefix]strip $elf_img
# target specific ops
if {[regexp "uboot" $run_target]} {
# parse ELF entrypoint and load address
set entrypoint [exec [cross_dev_prefix]readelf -h $elf_img | \
grep "Entry point address: " | \
sed -e "s/.*Entry point address: *//"]
set load_addr [exec [cross_dev_prefix]readelf -l $elf_img | \
grep -m 1 "LOAD"]
set load_addr [lindex [regexp -inline -all -- {\S+} $load_addr] 3]
# compress ELF
set bin_img "[run_dir]/image.bin"
exec [cross_dev_prefix]objcopy -O binary $elf_img $bin_img
exec gzip --best --force $bin_img
# create compressed uImage
set uboot_img [run_dir]/uImage
exec mkimage -A arm -O linux -T kernel -C gzip -a $load_addr \
-e $entrypoint -d $bin_img.gz $uboot_img
exec rm -rf $bin_img.gz
}
# set symbolic link to image.elf file in TFTP directory for PXE boot
if {[info exists ::env(PXE_TFTP_DIR_BASE)] &&
[info exists ::env(PXE_TFTP_DIR_OFFSET)]} {
exec ln -sf "[pwd]/$elf_img" "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)"
if {[regexp "uboot" $run_target]} {
exec ln -sf "[pwd]/[run_dir]/uImage" "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)"
}
}
# retrieve stand-alone core
exec cp core/core.standalone bin/core
exec rm core/core.standalone
}
proc run_genode_until {{wait_for_re forever} {timeout_value 0} {running_spawn_id -1}} {
#
# If a running_spawn_id is specified, wait for the expected output
#
if {$running_spawn_id != -1} {
wait_for_output $wait_for_re $timeout_value $running_spawn_id
return
}
#
# Try to use one of the supported backends for running the scripts
#
if {[is_qemu_available]} {
spawn_qemu $wait_for_re $timeout_value
return
}
if {[is_serial_available]} {
spawn_serial $wait_for_re $timeout_value
return
}
global run_target
puts stderr "Error: Can't execute automatically on target '$run_target'"
exit -1
}