#!/usr/bin/expect # # \brief Implementation of the interface provided by 'tool/run' # \author Martin Stein # \date 2011-12-16 # ###################### ## Utility routines ## ###################### # # 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 # proc disable_specific_boot_modules { } { 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 # proc enable_specific_boot_modules {file} { 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 # 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} { # skip targets that shall not be build if {[get_cmd_switch --skip-build]} return # handle false remnants of previous builds disable_specific_boot_modules # # Build all remaining targets. # Core is build with a dummy boot-modules file first. # regsub -all {\s\s+} $targets " " targets puts "building targets: $targets" set timeout 10000 set pid [eval "spawn make $targets"] expect { eof { } } if {[lindex [wait $pid] end] != 0} { puts "Error: Genode build failed" exit -4 } puts "genode build completed" } proc create_boot_directory { } { exec rm -rf [run_dir] exec mkdir -p [run_dir]/genode } proc build_boot_image {binaries} { # create additional stripped version of any binary copy_and_strip_genode_binaries_to_run_dir $binaries # append init configuration if existent to the binaries if {[file exists "[run_dir]/genode/config"] == 1} { append binaries " config" } # create scenario-specific 'boot_modules.s' of all given binaries set boot_modules "[run_dir]/boot_modules.s" if { [have_spec {arm}] } { boot_modules_arm $boot_modules $binaries puts "Boot_modules: ${boot_modules}" exec cp ${boot_modules} /tmp/ } # preserve stand-alone core for debugging exec cp -L bin/core core/core.standalone # apply the new 'boot_modules.s' to 'core' to create single boot image apply_boot_modules_to_core $boot_modules exec cp -L bin/core [run_dir]/image.elf exec [cross_dev_prefix]strip [run_dir]/image.elf # remove stripped binaries and retrieve stand-alone core exec cp core/core.standalone bin/core exec rm core/core.standalone exec rm -r [run_dir]/genode } proc run_genode_until {{wait_for_re forever} {timeout_value 0}} { # get the targeted method of execution, the default is 'qemu' 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 { puts stderr "Error: Target '${target}' is not supported" puts stderr " Supported targets are: 'qemu'"; exit -3 } }