mirror of
https://github.com/genodelabs/genode.git
synced 2025-03-22 20:15:20 +00:00
parent
60fbbc1fd1
commit
5d8a43dd08
300
base-hw/run/env
300
base-hw/run/env
@ -1,146 +1,32 @@
|
|||||||
#!/usr/bin/expect
|
#!/usr/bin/expect
|
||||||
|
|
||||||
#
|
#
|
||||||
# \brief Implementation of the interface provided by 'tool/run'
|
# \brief Implementation of the 'tool/run' interface
|
||||||
# \author Martin Stein
|
# \author Martin Stein
|
||||||
# \date 2011-12-16
|
# \date 2011-12-16
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
######################
|
###############
|
||||||
## Utility routines ##
|
## Utilities ##
|
||||||
######################
|
###############
|
||||||
|
|
||||||
#
|
|
||||||
# Build an assembly file that enables the creation of a single boot image
|
|
||||||
#
|
|
||||||
# \param file targeted file
|
|
||||||
# \parem binaries targeted boot modules, must reside in '[run_dir]/genode/'
|
|
||||||
#
|
|
||||||
# This 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.
|
|
||||||
#
|
|
||||||
proc boot_modules_arm {{file} {binaries}} {
|
|
||||||
|
|
||||||
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 * 'boot_modules_arm' in '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:" > $file
|
|
||||||
|
|
||||||
# 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" >> $file
|
|
||||||
incr i
|
|
||||||
}
|
|
||||||
|
|
||||||
# end boot module headers
|
|
||||||
exec echo -e \
|
|
||||||
"\n.global _boot_module_headers_end" \
|
|
||||||
"\n_boot_module_headers_end:" \
|
|
||||||
"\n" >> $file
|
|
||||||
|
|
||||||
# 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" >> $file
|
|
||||||
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" >> $file
|
|
||||||
incr i
|
|
||||||
}
|
|
||||||
|
|
||||||
# end boot-modules file
|
|
||||||
exec echo -e \
|
|
||||||
".global _boot_modules_end" \
|
|
||||||
"\n_boot_modules_end:" >> $file
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Ensure that the next Genode build includes no target specific boot modules
|
# Ensure that the next Genode build includes no target specific boot modules
|
||||||
#
|
#
|
||||||
proc disable_specific_boot_modules { } {
|
proc clean_boot_modules { } {
|
||||||
|
exec rm -rf boot_modules.s var/libcache/boot_modules/boot_modules.o }
|
||||||
exec rm -rf boot_modules.s
|
|
||||||
exec rm -rf var/libcache/boot_modules/boot_modules.o
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Ensure that the next Genode build includes target specific boot modules
|
# Get target argument
|
||||||
#
|
#
|
||||||
proc enable_specific_boot_modules {file} {
|
proc target { } { return [get_cmd_arg --target "qemu"] }
|
||||||
|
|
||||||
exec rm -rf boot_modules.s
|
|
||||||
exec ln -s $file boot_modules.s
|
|
||||||
exec rm -rf var/libcache/boot_modules/boot_modules.o
|
|
||||||
exec find . -type f -name "core" -delete
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#
|
##########################
|
||||||
# Apply the boot modules file 'file' to the core image
|
## 'tool/run' interface ##
|
||||||
#
|
##########################
|
||||||
proc apply_boot_modules_to_core {file} {
|
|
||||||
|
|
||||||
# recompile 'core', with specific boot modules
|
|
||||||
puts "Building single boot image"
|
|
||||||
set timeout 10000
|
|
||||||
enable_specific_boot_modules $file
|
|
||||||
set pid [eval "spawn make core"]
|
|
||||||
expect { eof { } }
|
|
||||||
if {[lindex [wait $pid] end] != 0} {
|
|
||||||
puts "Error: Genode build failed"
|
|
||||||
exit -4
|
|
||||||
}
|
|
||||||
|
|
||||||
# clean up for subsequent builds
|
|
||||||
disable_specific_boot_modules
|
|
||||||
puts "Single boot image built"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
######################################
|
|
||||||
## Interface supplied by 'tool/run' ##
|
|
||||||
######################################
|
|
||||||
|
|
||||||
proc build {targets} {
|
proc build {targets} {
|
||||||
|
|
||||||
@ -148,22 +34,20 @@ proc build {targets} {
|
|||||||
if {[get_cmd_switch --skip-build]} return
|
if {[get_cmd_switch --skip-build]} return
|
||||||
|
|
||||||
# handle false remnants of previous builds
|
# handle false remnants of previous builds
|
||||||
disable_specific_boot_modules
|
clean_boot_modules
|
||||||
|
|
||||||
#
|
#
|
||||||
# Build all remaining targets.
|
# Build all remaining targets.
|
||||||
# Core is build with a dummy boot-modules file first.
|
# Core is build with a dummy boot-modules file first.
|
||||||
#
|
#
|
||||||
regsub -all {\s\s+} $targets " " targets
|
regsub -all {\s\s+} $targets " " targets
|
||||||
puts "building targets: $targets"
|
|
||||||
set timeout 10000
|
set timeout 10000
|
||||||
set pid [eval "spawn make $targets"]
|
set pid [eval "spawn make $targets"]
|
||||||
expect { eof { } }
|
expect { eof { } }
|
||||||
if {[lindex [wait $pid] end] != 0} {
|
if {[lindex [wait $pid] end] != 0} {
|
||||||
puts "Error: Genode build failed"
|
puts stderr "Error: Genode build failed"
|
||||||
exit -4
|
exit -1
|
||||||
}
|
}
|
||||||
puts "genode build completed"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -176,49 +60,157 @@ proc create_boot_directory { } {
|
|||||||
|
|
||||||
proc build_boot_image {binaries} {
|
proc build_boot_image {binaries} {
|
||||||
|
|
||||||
# create additional stripped version of any binary
|
# strip binaries
|
||||||
copy_and_strip_genode_binaries_to_run_dir $binaries
|
copy_and_strip_genode_binaries_to_run_dir $binaries
|
||||||
|
|
||||||
# append init configuration if existent to the binaries
|
# append init config
|
||||||
if {[file exists "[run_dir]/genode/config"] == 1} {
|
if {[file exists "[run_dir]/genode/config"] == 1} {
|
||||||
append binaries " config"
|
append binaries " config"
|
||||||
}
|
}
|
||||||
|
|
||||||
# create scenario-specific 'boot_modules.s' of all given binaries
|
#
|
||||||
|
# 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"
|
set boot_modules "[run_dir]/boot_modules.s"
|
||||||
if { [have_spec {arm}] } {
|
if { [have_spec {arm}] } {
|
||||||
boot_modules_arm $boot_modules $binaries
|
|
||||||
puts "Boot_modules: ${boot_modules}"
|
set load_store_align_l2 2
|
||||||
exec cp ${boot_modules} /tmp/
|
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
|
||||||
|
|
||||||
# preserve stand-alone core for debugging
|
# recompile core with boot modules
|
||||||
exec cp -L bin/core core/core.standalone
|
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"
|
||||||
|
|
||||||
# apply the new 'boot_modules.s' to 'core' to create single boot image
|
# offer ELF image
|
||||||
apply_boot_modules_to_core $boot_modules
|
set elf_img "[run_dir]/image.elf"
|
||||||
exec cp -L bin/core [run_dir]/image.elf
|
exec cp -L bin/core $elf_img
|
||||||
exec [cross_dev_prefix]strip [run_dir]/image.elf
|
exec [cross_dev_prefix]strip $elf_img
|
||||||
|
|
||||||
# remove stripped binaries and retrieve stand-alone core
|
# target specific ops
|
||||||
exec cp core/core.standalone bin/core
|
if {[target] == "uboot"} {
|
||||||
exec rm core/core.standalone
|
|
||||||
exec rm -r [run_dir]/genode
|
# 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
|
||||||
|
}
|
||||||
|
# retrieve stand-alone core
|
||||||
|
exec mv core/core.standalone bin/core
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
proc run_genode_until {{wait_for_re forever} {timeout_value 0}} {
|
proc run_genode_until {{wait_for_re forever} {timeout_value 0}} {
|
||||||
|
|
||||||
# get the targeted method of execution, the default is 'qemu'
|
if {[target] == "qemu"} { spawn_qemu $wait_for_re $timeout_value
|
||||||
set image [run_dir]/image.elf
|
|
||||||
set target [get_cmd_arg --target "qemu"]
|
|
||||||
|
|
||||||
# try to execute image according to the targeted method of execution
|
|
||||||
if { $target == "qemu" } {
|
|
||||||
spawn_qemu $wait_for_re $timeout_value
|
|
||||||
} else {
|
} else {
|
||||||
puts stderr "Error: Target '${target}' is not supported"
|
puts stderr "Error: Can't execute automatically on target '$target'"
|
||||||
puts stderr " Supported targets are: 'qemu'"; exit -3
|
puts stderr " Target might be: 'qemu'"
|
||||||
|
exit -1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user