mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-05 13:34:11 +00:00
run: modularize run tool
This commit is contained in:
parent
febca1b827
commit
c706b1c0a7
@ -1,201 +0,0 @@
|
|||||||
#
|
|
||||||
# \brief Fiasco-specific test-environment supplements
|
|
||||||
# \author Norman Feske
|
|
||||||
# \author Christian Helmuth
|
|
||||||
# \date 2010-08-26
|
|
||||||
#
|
|
||||||
# This file is meant to be used as '--include' argument for 'tool/run'.
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Install files needed to boot via PXE
|
|
||||||
#
|
|
||||||
proc install_pxe_bootloader_to_run_dir { } {
|
|
||||||
exec cp [genode_dir]/tool/boot/pulsar [run_dir]/boot/pulsar
|
|
||||||
exec cp [genode_dir]/tool/boot/bender [run_dir]/boot/bender
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Read the location of the Fiasco user directory from 'etc/fiasco.conf'
|
|
||||||
#
|
|
||||||
proc l4_dir { } {
|
|
||||||
global _l4_dir
|
|
||||||
|
|
||||||
if {![info exists _l4_dir]} {
|
|
||||||
if {[file exists etc/fiasco.conf]} {
|
|
||||||
set _l4_dir [exec sed -n "/^L4_BUILD_DIR/s/^.*=\\s*//p" etc/fiasco.conf]
|
|
||||||
if {[file exists $_l4_dir]} { return $_l4_dir }
|
|
||||||
}
|
|
||||||
|
|
||||||
set _l4_dir "[pwd]/l4"
|
|
||||||
if {![file exists $_l4_dir]} {
|
|
||||||
puts -nonewline stderr "Error: Could neither find the L4 build directory "
|
|
||||||
puts -nonewline stderr "within '<genode-build-dir>/l4' nor at a location "
|
|
||||||
puts -nonewline stderr "specified via 'L4_BUILD_DIR = <l4v2-build-dir>' "
|
|
||||||
puts stderr "in <genode-build-dir>/etc/fiasco.conf'."
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $_l4_dir
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Return whether the l4-buid-directory is provided from the outside
|
|
||||||
#
|
|
||||||
proc l4_dir_external { } {
|
|
||||||
if {[l4_dir] == "[pwd]/l4"} { return 0 }
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Return the location of the Fiasco kernel
|
|
||||||
#
|
|
||||||
proc fiasco { } {
|
|
||||||
return [kernel_location_from_config_file etc/fiasco.conf [pwd]/kernel/fiasco/fiasco]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Return whether fiasco kernel is provided from the outside
|
|
||||||
#
|
|
||||||
proc fiasco_external { } {
|
|
||||||
if {[fiasco] == "[pwd]/kernel/fiasco/fiasco"} { return 0 }
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
##################################
|
|
||||||
## Test framework API functions ##
|
|
||||||
##################################
|
|
||||||
|
|
||||||
proc create_boot_directory { } {
|
|
||||||
exec rm -rf [run_dir]
|
|
||||||
exec mkdir -p [run_dir]/genode
|
|
||||||
exec mkdir -p [run_dir]/fiasco
|
|
||||||
}
|
|
||||||
|
|
||||||
proc bin_dir { } {
|
|
||||||
if {[have_spec x86_32]} { return "[l4_dir]/bin/x86_586" }
|
|
||||||
|
|
||||||
puts stderr "Error: Cannot determine bin directory"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
set fiasco_serial_esc_arg "-serial_esc "
|
|
||||||
|
|
||||||
proc build_boot_image {binaries} {
|
|
||||||
|
|
||||||
global fiasco_serial_esc_arg
|
|
||||||
|
|
||||||
#
|
|
||||||
# Collect contents of the ISO image
|
|
||||||
#
|
|
||||||
copy_and_strip_genode_binaries_to_run_dir $binaries
|
|
||||||
|
|
||||||
if {![fiasco_external]} { build { kernel } }
|
|
||||||
if {![l4_dir_external]} { build { bootstrap sigma0 } }
|
|
||||||
|
|
||||||
# assert existence of the L4 build directory
|
|
||||||
l4_dir
|
|
||||||
|
|
||||||
puts "using fiasco kernel [fiasco]"
|
|
||||||
exec cp [fiasco] [run_dir]/fiasco/fiasco
|
|
||||||
puts "using sigma0/bootstrap at [l4_dir]"
|
|
||||||
exec cp [bin_dir]/l4v2/sigma0 [run_dir]/fiasco
|
|
||||||
exec cp [bin_dir]/bootstrap [run_dir]/fiasco
|
|
||||||
|
|
||||||
install_iso_bootloader_to_run_dir
|
|
||||||
|
|
||||||
#
|
|
||||||
# Generate grub config file
|
|
||||||
#
|
|
||||||
# The core binary is part of the 'binaries' list but it must
|
|
||||||
# appear right after 'sigma0' as boot module. Hence the special case.
|
|
||||||
#
|
|
||||||
set fh [open "[run_dir]/boot/grub/menu.lst" "WRONLY CREAT TRUNC"]
|
|
||||||
puts $fh "timeout 0"
|
|
||||||
puts $fh "default 0"
|
|
||||||
puts $fh "\ntitle Genode on L4/Fiasco"
|
|
||||||
puts $fh " kernel /boot/bender"
|
|
||||||
puts $fh " module /fiasco/bootstrap -serial -modaddr=0x02000000"
|
|
||||||
puts $fh " module /fiasco/fiasco -serial -jdb_cmd=JH $fiasco_serial_esc_arg"
|
|
||||||
puts $fh " module /fiasco/sigma0"
|
|
||||||
puts $fh " module /genode/core"
|
|
||||||
puts $fh " module /genode/config"
|
|
||||||
foreach binary $binaries {
|
|
||||||
if {$binary != "core"} {
|
|
||||||
puts $fh " module /genode/$binary" } }
|
|
||||||
puts $fh " vbeset 0x117 506070"
|
|
||||||
close $fh
|
|
||||||
|
|
||||||
#
|
|
||||||
# Install PXE bootloader pulsar
|
|
||||||
#
|
|
||||||
install_pxe_bootloader_to_run_dir
|
|
||||||
|
|
||||||
create_iso_image_from_run_dir
|
|
||||||
create_disk_image_from_run_dir
|
|
||||||
|
|
||||||
#
|
|
||||||
# Generate pulsar config file
|
|
||||||
#
|
|
||||||
set fh [open "[run_dir]/config-52-54-00-12-34-56" "WRONLY CREAT TRUNC"]
|
|
||||||
puts $fh " exec /boot/bender"
|
|
||||||
puts $fh " load /fiasco/bootstrap -serial -modaddr=0x02000000"
|
|
||||||
puts $fh " load /fiasco/fiasco -serial -serial_esc -jdb_cmd=JH"
|
|
||||||
puts $fh " load /fiasco/sigma0"
|
|
||||||
puts $fh " load /genode/core"
|
|
||||||
puts $fh " load /genode/config"
|
|
||||||
foreach binary $binaries {
|
|
||||||
if {$binary != "core"} {
|
|
||||||
puts $fh " load /genode/$binary" } }
|
|
||||||
close $fh
|
|
||||||
|
|
||||||
#
|
|
||||||
# Generate pulsar config file pointing to the config file above.
|
|
||||||
#
|
|
||||||
if {[info exists ::env(PXE_TFTP_DIR_BASE)] && [info exists ::env(PXE_TFTP_DIR_OFFSET)]} {
|
|
||||||
exec ln -nfs "[pwd]" "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)"
|
|
||||||
|
|
||||||
set tftp_base ""
|
|
||||||
if {[get_cmd_switch --tftp-absolute]} {
|
|
||||||
set tftp_base $::env(PXE_TFTP_DIR_BASE)
|
|
||||||
}
|
|
||||||
|
|
||||||
set fh [open "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)/config-00-00-00-00-00-00" "WRONLY CREAT TRUNC"]
|
|
||||||
puts $fh " root $tftp_base$::env(PXE_TFTP_DIR_OFFSET)/[run_dir]"
|
|
||||||
puts $fh " config config-52-54-00-12-34-56"
|
|
||||||
close $fh
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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_amt_available]} {
|
|
||||||
spawn_amt $wait_for_re $timeout_value
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if {[is_qemu_available]} {
|
|
||||||
spawn_qemu $wait_for_re $timeout_value
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
global run_target
|
|
||||||
puts stderr "Error: Can't execute automatically on target '$run_target'"
|
|
||||||
exit -1
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
#
|
|
||||||
# \brief Environment for executing Genode on Linux
|
|
||||||
# \author Norman Feske
|
|
||||||
# \date 2010-08-16
|
|
||||||
#
|
|
||||||
# For the documentation of the implemented API functions,
|
|
||||||
# please refer to the comments in 'tool/run'.
|
|
||||||
#
|
|
||||||
|
|
||||||
proc create_boot_directory { } {
|
|
||||||
exec rm -rf [run_dir]
|
|
||||||
exec mkdir -p [run_dir]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
proc install_config {config} {
|
|
||||||
set fh [open "[run_dir]/config" "WRONLY CREAT TRUNC"]
|
|
||||||
puts $fh $config
|
|
||||||
close $fh
|
|
||||||
|
|
||||||
check_xml_syntax [run_dir]/config
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
proc build_boot_image {binaries} {
|
|
||||||
foreach binary $binaries {
|
|
||||||
exec ln -sf ../../../bin/$binary [run_dir] }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
global spawn_id
|
|
||||||
|
|
||||||
set orig_pwd [pwd]
|
|
||||||
cd [run_dir]
|
|
||||||
spawn ./core
|
|
||||||
wait_for_output $wait_for_re $timeout_value $spawn_id
|
|
||||||
cd $orig_pwd
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Umount a directory that was bind-mounted beforehand
|
|
||||||
#
|
|
||||||
# This function is used by chroot-related tests, e.g., 'os/run/chroot.run',
|
|
||||||
# 'os/run/chroot_loader.run'.
|
|
||||||
#
|
|
||||||
proc umount_and_rmdir { path } {
|
|
||||||
|
|
||||||
puts "umounting $path"
|
|
||||||
|
|
||||||
#
|
|
||||||
# Invoke umount until it returns an error. Apparently, the unmounting
|
|
||||||
# of bind-mounted mount points does not always take immediate effect
|
|
||||||
# (regardless of the -l option).
|
|
||||||
#
|
|
||||||
while {1} {
|
|
||||||
if {[catch { exec sudo umount -l $path }]} { break; }
|
|
||||||
sleep 0.25
|
|
||||||
}
|
|
||||||
|
|
||||||
catch { exec rmdir -p $path }
|
|
||||||
}
|
|
||||||
|
|
@ -1,144 +0,0 @@
|
|||||||
#
|
|
||||||
# \brief NOVA-specific test-environment supplements
|
|
||||||
# \author Norman Feske
|
|
||||||
# \date 2010-08-31
|
|
||||||
#
|
|
||||||
# This file is meant to be used as '--include' argument for 'tool/run'.
|
|
||||||
#
|
|
||||||
|
|
||||||
##
|
|
||||||
# Install files needed to boot via PXE
|
|
||||||
#
|
|
||||||
proc install_pxe_bootloader_to_run_dir { } {
|
|
||||||
exec cp [genode_dir]/tool/boot/pulsar [run_dir]/boot/pulsar
|
|
||||||
exec cp [genode_dir]/tool/boot/bender [run_dir]/boot/bender
|
|
||||||
}
|
|
||||||
|
|
||||||
##
|
|
||||||
# Read the location of the NOVA kernel directory from 'etc/nova.conf'
|
|
||||||
#
|
|
||||||
proc nova_kernel { } {
|
|
||||||
global _nova_kernel
|
|
||||||
|
|
||||||
if {![info exists _nova_kernel]} {
|
|
||||||
if {[file exists etc/nova.conf]} {
|
|
||||||
set _nova_kernel [exec sed -n "/^NOVA_KERNEL/s/^.*=\\s*//p" etc/nova.conf]
|
|
||||||
} else {
|
|
||||||
set _nova_kernel "[pwd]/kernel/hypervisor"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $_nova_kernel
|
|
||||||
}
|
|
||||||
|
|
||||||
##
|
|
||||||
# Return whether nova is provided from the outside
|
|
||||||
#
|
|
||||||
proc nova_external { } {
|
|
||||||
if {[nova_kernel] == "[pwd]/kernel/hypervisor"} { return 0 }
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
##################################
|
|
||||||
## Test framework API functions ##
|
|
||||||
##################################
|
|
||||||
|
|
||||||
proc create_boot_directory { } {
|
|
||||||
exec rm -rf [run_dir]
|
|
||||||
exec mkdir -p [run_dir]/genode
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
proc build_boot_image {binaries} {
|
|
||||||
|
|
||||||
#
|
|
||||||
# Collect contents of the ISO image
|
|
||||||
#
|
|
||||||
copy_and_strip_genode_binaries_to_run_dir $binaries
|
|
||||||
|
|
||||||
if {![nova_external] && ![file exists [nova_kernel]]} { build { kernel } }
|
|
||||||
|
|
||||||
puts "using NOVA kernel at [nova_kernel]"
|
|
||||||
exec [cross_dev_prefix]objcopy -O elf32-i386 [nova_kernel] [run_dir]/hypervisor
|
|
||||||
|
|
||||||
install_iso_bootloader_to_run_dir
|
|
||||||
|
|
||||||
#
|
|
||||||
# The core binary is part of the 'binaries' list but it must
|
|
||||||
# appear right after 'sigma0' as boot module. Hence the special case.
|
|
||||||
#
|
|
||||||
# Generate grub config file
|
|
||||||
#
|
|
||||||
set fh [open "[run_dir]/boot/grub/menu.lst" "WRONLY CREAT TRUNC"]
|
|
||||||
puts $fh "timeout 0"
|
|
||||||
puts $fh "default 0"
|
|
||||||
puts $fh "\ntitle Genode on NOVA"
|
|
||||||
puts $fh " kernel /boot/bender"
|
|
||||||
puts $fh " module /hypervisor iommu serial novpid"
|
|
||||||
puts $fh " module /genode/core"
|
|
||||||
puts $fh " module /genode/config"
|
|
||||||
foreach binary $binaries {
|
|
||||||
if {$binary != "core"} {
|
|
||||||
puts $fh " module /genode/$binary" } }
|
|
||||||
close $fh
|
|
||||||
|
|
||||||
install_pxe_bootloader_to_run_dir
|
|
||||||
create_iso_image_from_run_dir
|
|
||||||
create_disk_image_from_run_dir
|
|
||||||
|
|
||||||
#
|
|
||||||
# Generate pulsar config file
|
|
||||||
#
|
|
||||||
set fh [open "[run_dir]/config-52-54-00-12-34-56" "WRONLY CREAT TRUNC"]
|
|
||||||
puts $fh " exec /boot/bender"
|
|
||||||
puts $fh " load /hypervisor iommu serial novpid"
|
|
||||||
puts $fh " load /genode/core"
|
|
||||||
puts $fh " load /genode/config"
|
|
||||||
foreach binary $binaries {
|
|
||||||
if {$binary != "core"} {
|
|
||||||
puts $fh " load /genode/$binary" } }
|
|
||||||
close $fh
|
|
||||||
|
|
||||||
#
|
|
||||||
# Generate pulsar config file pointing to the config file above.
|
|
||||||
#
|
|
||||||
if {[info exists ::env(PXE_TFTP_DIR_BASE)] && [info exists ::env(PXE_TFTP_DIR_OFFSET)]} {
|
|
||||||
exec ln -nfs "[pwd]" "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)"
|
|
||||||
|
|
||||||
set tftp_base ""
|
|
||||||
if {[get_cmd_switch --tftp-absolute]} {
|
|
||||||
set tftp_base $::env(PXE_TFTP_DIR_BASE)
|
|
||||||
}
|
|
||||||
|
|
||||||
set fh [open "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)/config-00-00-00-00-00-00" "WRONLY CREAT TRUNC"]
|
|
||||||
puts $fh " root $tftp_base$::env(PXE_TFTP_DIR_OFFSET)/[run_dir]"
|
|
||||||
puts $fh " config config-52-54-00-12-34-56"
|
|
||||||
close $fh
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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_amt_available]} {
|
|
||||||
spawn_amt $wait_for_re $timeout_value
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if {[is_serial_available]} {
|
|
||||||
spawn_serial $wait_for_re $timeout_value "NOVA Microhypervisor"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if {[is_qemu_available]} {
|
|
||||||
spawn_qemu $wait_for_re $timeout_value
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,179 +0,0 @@
|
|||||||
#
|
|
||||||
# \brief Pistachio-specific test-environment supplements
|
|
||||||
# \author Norman Feske
|
|
||||||
# \date 2010-08-25
|
|
||||||
#
|
|
||||||
# This file is meant to be used as '--include' argument for 'tool/run'.
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Install files needed to boot via PXE
|
|
||||||
#
|
|
||||||
proc install_pxe_bootloader_to_run_dir { } {
|
|
||||||
exec cp [genode_dir]/tool/boot/pulsar [run_dir]/boot/pulsar
|
|
||||||
exec cp [genode_dir]/tool/boot/bender [run_dir]/boot/bender
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Read the location of the Pistachio user directory from 'etc/pistachio.conf'
|
|
||||||
#
|
|
||||||
proc pistachio_user_dir { } {
|
|
||||||
global _pistachio_user_dir
|
|
||||||
|
|
||||||
if {![info exists _pistachio_user_dir]} {
|
|
||||||
if {[file exists etc/pistachio.conf]} {
|
|
||||||
set _pistachio_user_dir [exec sed -n "/^PISTACHIO_USER_BUILD_DIR/s/^.*=\\s*//p" etc/pistachio.conf]
|
|
||||||
} else {
|
|
||||||
set _pistachio_user_dir "[pwd]/l4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $_pistachio_user_dir
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Read the location of the Pistachio kernel directory from 'etc/pistachio.conf'
|
|
||||||
# or return a good heuristic
|
|
||||||
#
|
|
||||||
proc pistachio_kernel { } {
|
|
||||||
global _pistachio_kernel
|
|
||||||
|
|
||||||
if {![info exists _pistachio_kernel]} {
|
|
||||||
if {[file exists etc/pistachio.conf]} {
|
|
||||||
set _pistachio_kernel [exec sed -n "/^PISTACHIO_KERNEL/s/^.*=\\s*//p" etc/pistachio.conf]
|
|
||||||
if {$_pistachio_kernel == ""} {
|
|
||||||
set _pistachio_kernel [file dirname [file dirname [pistachio_user_dir]]]/kernel/build/x86-kernel
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
set _pistachio_kernel "[pwd]/bin/kernel"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $_pistachio_kernel
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# Return whether the kernel is provided from the outside
|
|
||||||
#
|
|
||||||
proc kernel_external { } {
|
|
||||||
if {[pistachio_kernel] == "[pwd]/bin/kernel"} { return 0 }
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
##################################
|
|
||||||
## Test framework API functions ##
|
|
||||||
##################################
|
|
||||||
|
|
||||||
proc create_boot_directory { } {
|
|
||||||
exec rm -rf [run_dir]
|
|
||||||
exec mkdir -p [run_dir]/genode
|
|
||||||
exec mkdir -p [run_dir]/pistachio
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
proc build_boot_image {binaries} {
|
|
||||||
|
|
||||||
#
|
|
||||||
# Collect contents of the ISO image
|
|
||||||
#
|
|
||||||
copy_and_strip_genode_binaries_to_run_dir $binaries
|
|
||||||
|
|
||||||
if {![kernel_external] && ![file exists [pistachio_kernel]]} { build { kernel } }
|
|
||||||
|
|
||||||
exec cp [pistachio_kernel] [run_dir]/pistachio/kernel
|
|
||||||
exec cp [pistachio_user_dir]/serv/sigma0/sigma0 [run_dir]/pistachio
|
|
||||||
exec cp [pistachio_user_dir]/util/kickstart/kickstart [run_dir]/pistachio
|
|
||||||
|
|
||||||
install_iso_bootloader_to_run_dir
|
|
||||||
|
|
||||||
#
|
|
||||||
# Generate grub config file
|
|
||||||
#
|
|
||||||
# The core binary is part of the 'binaries' list but it must
|
|
||||||
# appear right after 'sigma0' as boot module. Hence the special case.
|
|
||||||
#
|
|
||||||
set fh [open "[run_dir]/boot/grub/menu.lst" "WRONLY CREAT TRUNC"]
|
|
||||||
puts $fh "timeout 0"
|
|
||||||
puts $fh "default 0"
|
|
||||||
puts $fh "\ntitle Genode on L4ka::Pistachio"
|
|
||||||
puts $fh " kernel /pistachio/kickstart"
|
|
||||||
puts $fh " module /pistachio/kernel"
|
|
||||||
puts $fh " module /pistachio/sigma0"
|
|
||||||
puts $fh " module /genode/core"
|
|
||||||
puts $fh " module /genode/config"
|
|
||||||
foreach binary $binaries {
|
|
||||||
if {$binary != "core"} {
|
|
||||||
puts $fh " module /genode/$binary" } }
|
|
||||||
close $fh
|
|
||||||
|
|
||||||
#
|
|
||||||
# Install PXE bootloader pulsar
|
|
||||||
#
|
|
||||||
install_pxe_bootloader_to_run_dir
|
|
||||||
|
|
||||||
create_iso_image_from_run_dir
|
|
||||||
create_disk_image_from_run_dir
|
|
||||||
|
|
||||||
#
|
|
||||||
# Generate pulsar config file
|
|
||||||
#
|
|
||||||
set fh [open "[run_dir]/config-52-54-00-12-34-56" "WRONLY CREAT TRUNC"]
|
|
||||||
puts $fh " exec /boot/bender"
|
|
||||||
puts $fh " load /pistachio/kickstart"
|
|
||||||
puts $fh " load /pistachio/kernel"
|
|
||||||
puts $fh " load /pistachio/sigma0"
|
|
||||||
puts $fh " load /genode/core"
|
|
||||||
puts $fh " load /genode/config"
|
|
||||||
puts $fh " load /genode/config"
|
|
||||||
foreach binary $binaries {
|
|
||||||
if {$binary != "core"} {
|
|
||||||
puts $fh " load /genode/$binary" } }
|
|
||||||
close $fh
|
|
||||||
|
|
||||||
#
|
|
||||||
# Generate pulsar config file pointing to the config file above.
|
|
||||||
#
|
|
||||||
if {[info exists ::env(PXE_TFTP_DIR_BASE)] && [info exists ::env(PXE_TFTP_DIR_OFFSET)]} {
|
|
||||||
exec ln -nfs "[pwd]" "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)"
|
|
||||||
|
|
||||||
set tftp_base ""
|
|
||||||
if {[get_cmd_switch --tftp-absolute]} {
|
|
||||||
set tftp_base $::env(PXE_TFTP_DIR_BASE)
|
|
||||||
}
|
|
||||||
|
|
||||||
set fh [open "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)/config-00-00-00-00-00-00" "WRONLY CREAT TRUNC"]
|
|
||||||
puts $fh " root $tftp_base$::env(PXE_TFTP_DIR_OFFSET)/[run_dir]"
|
|
||||||
puts $fh " config config-52-54-00-12-34-56"
|
|
||||||
close $fh
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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_amt_available]} {
|
|
||||||
spawn_amt $wait_for_re $timeout_value
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if {[is_qemu_available]} {
|
|
||||||
spawn_qemu $wait_for_re $timeout_value
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
global run_target
|
|
||||||
puts stderr "Error: Can't execute automatically on target '$run_target'"
|
|
||||||
exit -1
|
|
||||||
}
|
|
@ -238,14 +238,15 @@ RUN_SCRIPT = $(call select_from_repositories,run/$*.run)
|
|||||||
|
|
||||||
run/%: $(call select_from_repositories,run/%.run) $(RUN_ENV)
|
run/%: $(call select_from_repositories,run/%.run) $(RUN_ENV)
|
||||||
$(VERBOSE)test -f "$(RUN_SCRIPT)" || (echo "Error: No run script for $*"; exit -1)
|
$(VERBOSE)test -f "$(RUN_SCRIPT)" || (echo "Error: No run script for $*"; exit -1)
|
||||||
$(VERBOSE)$(GENODE_DIR)/tool/run --genode-dir $(GENODE_DIR) \
|
$(VERBOSE)$(GENODE_DIR)/tool/run/run --genode-dir $(GENODE_DIR) \
|
||||||
--name $* \
|
--name $* \
|
||||||
--specs "$(SPECS)" \
|
--specs "$(SPECS)" \
|
||||||
--repositories "$(REPOSITORIES)" \
|
--repositories "$(REPOSITORIES)" \
|
||||||
--cross-dev-prefix "$(CROSS_DEV_PREFIX)" \
|
--cross-dev-prefix "$(CROSS_DEV_PREFIX)" \
|
||||||
--qemu-args "$(QEMU_OPT)" \
|
--qemu-args "$(QEMU_OPT)" \
|
||||||
--include $(RUN_ENV) $(RUN_OPT) \
|
$(RUN_OPT) \
|
||||||
--include $(RUN_SCRIPT)
|
--include $(RUN_ENV) \
|
||||||
|
--include $(RUN_SCRIPT)
|
||||||
|
|
||||||
##
|
##
|
||||||
## Clean rules
|
## Clean rules
|
||||||
|
141
tool/run/README
Normal file
141
tool/run/README
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
|
||||||
|
|
||||||
|
===================
|
||||||
|
The Genode run tool
|
||||||
|
===================
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
############
|
||||||
|
|
||||||
|
The run tool is used to configure, build, and execute so-called run scripts.
|
||||||
|
These run scripts include a scenario or test-case of Genode components and
|
||||||
|
subsystems. Its core functionality is split into various modules to accommodate
|
||||||
|
a variety of different execution environments. These modules provide the
|
||||||
|
implementation of a given step in the sequence of execution of a run script.
|
||||||
|
These steps are:
|
||||||
|
|
||||||
|
* Building the corresponding components
|
||||||
|
* Wrapping the components in a format suitable for execution
|
||||||
|
* Preparing the target systems
|
||||||
|
* Executing the scenario
|
||||||
|
* Collecting any output
|
||||||
|
|
||||||
|
After the run script was executed successfully, the run tool will print the
|
||||||
|
string 'Run script execution successful.". This message can be used to check
|
||||||
|
for the successful completion of the run script when doing automated testing.
|
||||||
|
|
||||||
|
The categories of modules are formed by existing requirements such as automated
|
||||||
|
testing on a variety of different hardware platforms and are based
|
||||||
|
on the above-named steps:
|
||||||
|
|
||||||
|
:boot_dir:
|
||||||
|
These modules contain the functionality to populate the boot directory
|
||||||
|
and are specific to each kernel. It is mandatory to always include the
|
||||||
|
module corresponding to the used kernel.
|
||||||
|
|
||||||
|
:image modules:
|
||||||
|
These modules are used to wrap up all components used by the run script
|
||||||
|
in a specific format and thereby to prepare them for execution.
|
||||||
|
Depending on the used kernel, there are different formats. With these
|
||||||
|
modules, the creation of ISO and disk images is also handled.
|
||||||
|
|
||||||
|
:load modules:
|
||||||
|
These modules handle the way the components are transfered to the
|
||||||
|
target system. Depending on the used kernel there are various options
|
||||||
|
to pass on the components. Loading from TFTP or via JTAG is handled
|
||||||
|
by the modules of this category.
|
||||||
|
|
||||||
|
:log modules:
|
||||||
|
These modules handle how the output of a currently executed run script
|
||||||
|
is captured.
|
||||||
|
|
||||||
|
:power_on modules:
|
||||||
|
These modules are used for bringing the target system into an defined
|
||||||
|
state, e.g., by starting or rebooting the system.
|
||||||
|
|
||||||
|
:power_off modules:
|
||||||
|
These modules are used for turning the target system off after the
|
||||||
|
execution of a run script.
|
||||||
|
|
||||||
|
When executing a run script, only one module of each category must be used.
|
||||||
|
|
||||||
|
|
||||||
|
Usage
|
||||||
|
#####
|
||||||
|
|
||||||
|
To execute a run script a combination of modules may be used. The combination
|
||||||
|
is controlled via the RUN_OPT variable used by the build framework. Here are a
|
||||||
|
few common exemplary combinations:
|
||||||
|
|
||||||
|
Executing NOVA in Qemu:
|
||||||
|
|
||||||
|
!RUN_OPT = --include boot_dir/nova \
|
||||||
|
! --include exec/qemu --include log/qemu --include image/iso
|
||||||
|
|
||||||
|
Executing NOVA on a real x86 machine using AMT for resetting the target system
|
||||||
|
and for capturing the serial output while loading the files via TFTP:
|
||||||
|
|
||||||
|
!RUN_OPT = --include boot_dir/nova \
|
||||||
|
! --include power_on/amt --power-on-amt-host 10.23.42.13 \
|
||||||
|
! --power-on-amt-password 'foo!' \
|
||||||
|
! --include load/tftp --load-tftp-base-dir /var/lib/tftpboot \
|
||||||
|
! --load-tftp-offset-dir /x86 \
|
||||||
|
! --include log/amt --log-amt-host 10.23.42.13 \
|
||||||
|
! --log-amt-password 'foo!'
|
||||||
|
|
||||||
|
Executing fiasco.OC on a real x86 machine using AMT for resetting, USB serial
|
||||||
|
for output while loading the files via TFTP:
|
||||||
|
|
||||||
|
!RUN_OPT = --include boot_dir/foc \
|
||||||
|
! --include power_on/amt --amt-host 10.23.42.13 --amt-password 'foo!' \
|
||||||
|
! --include load/tftp --tftp-base-dir /var/lib/tftpboot \
|
||||||
|
! --tftp-offset-dir /x86 \
|
||||||
|
! --include log/serial --serial-cmd 'picocom -b 115200 /dev/ttyUSB0'
|
||||||
|
|
||||||
|
Executing hw on a rpi using powerplug to reset the hardware, JTAG to load the
|
||||||
|
image and USB serial to capture the output:
|
||||||
|
|
||||||
|
!RUN_OPT = --include boot_dir/hw \
|
||||||
|
! --include power_on/powerplug --power-on-powerplug-ip 10.23.42.5 \
|
||||||
|
! --power-on-powerplug-user admin \
|
||||||
|
! --power-on-powerplug-password secret \
|
||||||
|
! --power-on-powerplug-port 1
|
||||||
|
! --include power_off/powerplug --power-off-powerplug-ip 10.23.42.5 \
|
||||||
|
! --power-off-powerplug-user admin \
|
||||||
|
! --power-off-powerplug-password secret \
|
||||||
|
! --power-off-powerplug-port 1
|
||||||
|
! --include load/jtag \
|
||||||
|
! --load-jtag-debugger /usr/share/openocd/scripts/interface/flyswatter2.cfg \
|
||||||
|
! --load-jtag-board /usr/share/openocd/scripts/interface/raspberrypi.cfg \
|
||||||
|
! --include log/serial --log-serial-cmd 'picocom -b 115200 /dev/ttyUSB0'
|
||||||
|
|
||||||
|
|
||||||
|
Module overview
|
||||||
|
###############
|
||||||
|
|
||||||
|
A module consist of a expect/TCL source file located in one of the existing
|
||||||
|
directories of a category. It is named implicitly by its location and the
|
||||||
|
name of the source file, e.g. 'image/iso' is the name of the image module
|
||||||
|
that creates an ISO image.
|
||||||
|
|
||||||
|
The source file contains one mandatory procedure:
|
||||||
|
|
||||||
|
* run_<module> { <module-args> }
|
||||||
|
The procedure is called if the step at hand is executed by the
|
||||||
|
run tool. If its execution was successful, it returns true and
|
||||||
|
otherwise false. Certain modules may also call exit on failure.
|
||||||
|
|
||||||
|
A module may have arguments, which are by convention prefixed with the name
|
||||||
|
of the source file, e.g. 'power_on/amt' may have an argument called
|
||||||
|
'--power-on-amt-host'. If the argument passes on a value the value must be
|
||||||
|
made accessible by calling an equally named procedure, e.g.
|
||||||
|
'--power-on-amt-host' becomes 'proc amt_host { }'.
|
||||||
|
Thereby a run script or a run environment can access the value of the argument
|
||||||
|
in a defined way without the use of a global variable by using
|
||||||
|
'[power_on_amt_host]'. Also arguments without a value may be queried in this
|
||||||
|
way. '--image-uboot-gzip' becomes '[image_uboot_use_gzip]'.
|
||||||
|
In addition to these procedures, a module may have any number of public
|
||||||
|
procedures. They may be used after the presence of the particular module that
|
||||||
|
contains them is verified. For this reason the run tool provides a procedure
|
||||||
|
called 'have_include', that performs this check. For example the presence of
|
||||||
|
the 'load/tftp' module is checked by calling '[have_include "load/tftp"]'.
|
28
tool/run/amt.inc
Normal file
28
tool/run/amt.inc
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
##
|
||||||
|
# Check whether AMT support is available
|
||||||
|
#
|
||||||
|
proc is_amt_available { {host "" } {password "" } } {
|
||||||
|
if {![have_spec x86]} { return false }
|
||||||
|
|
||||||
|
#
|
||||||
|
# Exit execution if parameter are not set rather returning
|
||||||
|
# false because we cannot recover anyway.
|
||||||
|
#
|
||||||
|
if {[string compare $host ""] == 0} {
|
||||||
|
puts "Aborting, AMT host not specified."
|
||||||
|
exit -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if {[string compare $password ""] == 0} {
|
||||||
|
puts "Aborting, AMT password not set."
|
||||||
|
exit -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if {[have_installed amtterm] &&
|
||||||
|
[expr [have_installed amttool] || [have_installed wsman] ] } {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
puts "No support for Intel's AMT detected."
|
||||||
|
return false
|
||||||
|
}
|
@ -1,10 +1,3 @@
|
|||||||
#
|
|
||||||
# \brief Codezero-specific test-environment supplements
|
|
||||||
# \author Norman Feske
|
|
||||||
# \date 2011-08-05
|
|
||||||
#
|
|
||||||
# This file is meant to be used as '--include' argument for 'tool/run'.
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
@ -34,21 +27,10 @@ proc exec_sh { command } {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
##################################
|
##
|
||||||
## Test framework API functions ##
|
# Populate boot directory with binaries on codezero
|
||||||
##################################
|
#
|
||||||
|
proc run_boot_dir {binaries} {
|
||||||
proc create_boot_directory { } {
|
|
||||||
|
|
||||||
# create only intermediate directries hosting the run directory
|
|
||||||
exec mkdir -p [run_dir]
|
|
||||||
exec rm -rf [run_dir]
|
|
||||||
|
|
||||||
exec mkdir -p [run_dir]/genode
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
proc build_boot_image {binaries} {
|
|
||||||
|
|
||||||
if {![file exists kernel]} { build kernel }
|
if {![file exists kernel]} { build kernel }
|
||||||
|
|
||||||
@ -81,26 +63,3 @@ proc build_boot_image {binaries} {
|
|||||||
# copy result to [run_dir]/image.elf (to be picked up by spawn_qemu)
|
# copy result to [run_dir]/image.elf (to be picked up by spawn_qemu)
|
||||||
exec_sh "cp [kernel_dir]/build/final.elf [run_dir]/image.elf"
|
exec_sh "cp [kernel_dir]/build/final.elf [run_dir]/image.elf"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
global run_target
|
|
||||||
puts stderr "Error: Can't execute automatically on target '$run_target'"
|
|
||||||
exit -1
|
|
||||||
}
|
|
142
tool/run/boot_dir/fiasco
Normal file
142
tool/run/boot_dir/fiasco
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
##
|
||||||
|
# Read the location of the Fiasco user directory from 'etc/fiasco.conf'
|
||||||
|
#
|
||||||
|
proc l4_dir { } {
|
||||||
|
global _l4_dir
|
||||||
|
|
||||||
|
if {![info exists _l4_dir]} {
|
||||||
|
if {[file exists etc/fiasco.conf]} {
|
||||||
|
set _l4_dir [exec sed -n "/^L4_BUILD_DIR/s/^.*=\\s*//p" etc/fiasco.conf]
|
||||||
|
if {[file exists $_l4_dir]} { return $_l4_dir }
|
||||||
|
}
|
||||||
|
|
||||||
|
set _l4_dir "[pwd]/l4"
|
||||||
|
if {![file exists $_l4_dir]} {
|
||||||
|
puts -nonewline stderr "Error: Could neither find the L4 build directory "
|
||||||
|
puts -nonewline stderr "within '<genode-build-dir>/l4' nor at a location "
|
||||||
|
puts -nonewline stderr "specified via 'L4_BUILD_DIR = <l4v2-build-dir>' "
|
||||||
|
puts stderr "in <genode-build-dir>/etc/fiasco.conf'."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $_l4_dir
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Return whether the l4-buid-directory is provided from the outside
|
||||||
|
#
|
||||||
|
proc l4_dir_external { } {
|
||||||
|
if {[l4_dir] == "[pwd]/l4"} { return 0 }
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Return the location of the Fiasco kernel
|
||||||
|
#
|
||||||
|
proc fiasco { } {
|
||||||
|
return [kernel_location_from_config_file etc/fiasco.conf [pwd]/kernel/fiasco/fiasco]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Return whether fiasco kernel is provided from the outside
|
||||||
|
#
|
||||||
|
proc fiasco_external { } {
|
||||||
|
if {[fiasco] == "[pwd]/kernel/fiasco/fiasco"} { return 0 }
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
proc bin_dir { } {
|
||||||
|
if {[have_spec x86_32]} { return "[l4_dir]/bin/x86_586" }
|
||||||
|
|
||||||
|
puts stderr "Error: Cannot determine bin directory"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
set fiasco_serial_esc_arg "-serial_esc "
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Populate boot directory with binaries on fiasco
|
||||||
|
#
|
||||||
|
proc run_boot_dir {binaries} {
|
||||||
|
|
||||||
|
global fiasco_serial_esc_arg
|
||||||
|
|
||||||
|
exec mkdir -p [run_dir]/fiasco
|
||||||
|
|
||||||
|
#
|
||||||
|
# Collect contents of the ISO image
|
||||||
|
#
|
||||||
|
copy_and_strip_genode_binaries_to_run_dir $binaries
|
||||||
|
|
||||||
|
if {![fiasco_external]} { build { kernel } }
|
||||||
|
if {![l4_dir_external]} { build { bootstrap sigma0 } }
|
||||||
|
|
||||||
|
# assert existence of the L4 build directory
|
||||||
|
l4_dir
|
||||||
|
|
||||||
|
puts "using fiasco kernel [fiasco]"
|
||||||
|
exec cp [fiasco] [run_dir]/fiasco/fiasco
|
||||||
|
puts "using sigma0/bootstrap at [l4_dir]"
|
||||||
|
exec cp [bin_dir]/l4v2/sigma0 [run_dir]/fiasco
|
||||||
|
exec cp [bin_dir]/bootstrap [run_dir]/fiasco
|
||||||
|
|
||||||
|
if {[have_include "image/iso"] || [have_include "image/disk"]} {
|
||||||
|
#
|
||||||
|
# Install isolinux/GRUB files and bender
|
||||||
|
#
|
||||||
|
install_iso_bootloader_to_run_dir
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate GRUB config file
|
||||||
|
#
|
||||||
|
# The core binary is part of the 'binaries' list but it must
|
||||||
|
# appear right after 'sigma0' as boot module. Hence the special case.
|
||||||
|
#
|
||||||
|
set fh [open "[run_dir]/boot/grub/menu.lst" "WRONLY CREAT TRUNC"]
|
||||||
|
puts $fh "timeout 0"
|
||||||
|
puts $fh "default 0"
|
||||||
|
puts $fh "\ntitle Genode on L4/Fiasco"
|
||||||
|
puts $fh " kernel /boot/bender"
|
||||||
|
puts $fh " module /fiasco/bootstrap -serial -modaddr=0x02000000"
|
||||||
|
puts $fh " module /fiasco/fiasco -serial -jdb_cmd=JH $fiasco_serial_esc_arg"
|
||||||
|
puts $fh " module /fiasco/sigma0"
|
||||||
|
puts $fh " module /genode/core"
|
||||||
|
puts $fh " module /genode/config"
|
||||||
|
foreach binary $binaries {
|
||||||
|
if {$binary != "core"} {
|
||||||
|
puts $fh " module /genode/$binary" } }
|
||||||
|
puts $fh " vbeset 0x117 506070"
|
||||||
|
close $fh
|
||||||
|
}
|
||||||
|
|
||||||
|
run_image
|
||||||
|
|
||||||
|
if {[have_include "load/tftp"]} {
|
||||||
|
#
|
||||||
|
# Install PXE bootloader pulsar
|
||||||
|
#
|
||||||
|
install_pxe_bootloader_to_run_dir
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate pulsar config file
|
||||||
|
#
|
||||||
|
set fh [open "[run_dir]/config-52-54-00-12-34-56" "WRONLY CREAT TRUNC"]
|
||||||
|
puts $fh " exec /boot/bender"
|
||||||
|
puts $fh " load /fiasco/bootstrap -serial -modaddr=0x02000000"
|
||||||
|
puts $fh " load /fiasco/fiasco -serial -serial_esc -jdb_cmd=JH"
|
||||||
|
puts $fh " load /fiasco/sigma0"
|
||||||
|
puts $fh " load /genode/core"
|
||||||
|
puts $fh " load /genode/config"
|
||||||
|
foreach binary $binaries {
|
||||||
|
if {$binary != "core"} {
|
||||||
|
puts $fh " load /genode/$binary" } }
|
||||||
|
close $fh
|
||||||
|
|
||||||
|
generate_tftp_config
|
||||||
|
}
|
||||||
|
}
|
@ -6,14 +6,6 @@
|
|||||||
# This file is meant to be used as '--include' argument for 'tool/run'.
|
# This file is meant to be used as '--include' argument for 'tool/run'.
|
||||||
#
|
#
|
||||||
|
|
||||||
##
|
|
||||||
# Install files needed to boot via PXE
|
|
||||||
#
|
|
||||||
proc install_pxe_bootloader_to_run_dir { } {
|
|
||||||
exec cp [genode_dir]/tool/boot/pulsar [run_dir]/boot/pulsar
|
|
||||||
exec cp [genode_dir]/tool/boot/bender [run_dir]/boot/bender
|
|
||||||
}
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Return the location of the Fiasco.OC user directory
|
# Return the location of the Fiasco.OC user directory
|
||||||
#
|
#
|
||||||
@ -83,20 +75,6 @@ proc reset_target { {spawn_id_arg -1} } {
|
|||||||
send -i $spawn_id_arg "\033^^"
|
send -i $spawn_id_arg "\033^^"
|
||||||
}
|
}
|
||||||
|
|
||||||
##################################
|
|
||||||
## Test framework API functions ##
|
|
||||||
##################################
|
|
||||||
|
|
||||||
proc create_boot_directory { } {
|
|
||||||
exec rm -rf [run_dir]
|
|
||||||
exec mkdir -p [run_dir]/genode
|
|
||||||
|
|
||||||
if {[have_spec x86]} {
|
|
||||||
exec mkdir -p [run_dir]/fiasco
|
|
||||||
exec mkdir -p [run_dir]/boot/grub
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
proc copy_and_strip_binaries {binaries} {
|
proc copy_and_strip_binaries {binaries} {
|
||||||
|
|
||||||
@ -108,10 +86,6 @@ proc copy_and_strip_binaries {binaries} {
|
|||||||
catch {
|
catch {
|
||||||
exec [cross_dev_prefix]strip [run_dir]/genode/$binary }
|
exec [cross_dev_prefix]strip [run_dir]/genode/$binary }
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
|
||||||
# Generate config file for bootstrap
|
|
||||||
#
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -126,10 +100,12 @@ proc bin_dir { } {
|
|||||||
|
|
||||||
set fiasco_serial_esc_arg "-serial_esc "
|
set fiasco_serial_esc_arg "-serial_esc "
|
||||||
|
|
||||||
proc build_boot_image_x86 {binaries} {
|
proc run_boot_dir_x86 {binaries} {
|
||||||
|
|
||||||
global fiasco_serial_esc_arg
|
global fiasco_serial_esc_arg
|
||||||
|
|
||||||
|
exec mkdir -p [run_dir]/fiasco
|
||||||
|
|
||||||
copy_and_strip_binaries $binaries
|
copy_and_strip_binaries $binaries
|
||||||
|
|
||||||
set foc_targets { }
|
set foc_targets { }
|
||||||
@ -149,69 +125,67 @@ proc build_boot_image_x86 {binaries} {
|
|||||||
exec cp [bin_dir]/l4f/sigma0 [run_dir]/fiasco
|
exec cp [bin_dir]/l4f/sigma0 [run_dir]/fiasco
|
||||||
exec cp [bin_dir]/bootstrap [run_dir]/fiasco
|
exec cp [bin_dir]/bootstrap [run_dir]/fiasco
|
||||||
|
|
||||||
install_iso_bootloader_to_run_dir
|
if {[have_include "image/iso"] || [have_include "image/disk"]} {
|
||||||
|
#
|
||||||
|
# Install isolinux/GRUB files and bender
|
||||||
|
#
|
||||||
|
install_iso_bootloader_to_run_dir
|
||||||
|
|
||||||
#
|
#
|
||||||
# Generate grub config file
|
# Generate grub config file
|
||||||
#
|
#
|
||||||
# The core binary is part of the 'binaries' list but it must
|
# The core binary is part of the 'binaries' list but it must
|
||||||
# appear right after 'sigma0' as boot module. Hence the special case.
|
# appear right after 'sigma0' as boot module. Hence the special case.
|
||||||
#
|
#
|
||||||
set fh [open "[run_dir]/boot/grub/menu.lst" "WRONLY CREAT TRUNC"]
|
set fh [open "[run_dir]/boot/grub/menu.lst" "WRONLY CREAT TRUNC"]
|
||||||
puts $fh "timeout 0"
|
puts $fh "timeout 0"
|
||||||
puts $fh "default 0"
|
puts $fh "default 0"
|
||||||
puts $fh "\ntitle Genode on Fiasco.OC"
|
puts $fh "\ntitle Genode on Fiasco.OC"
|
||||||
puts $fh " kernel /boot/bender"
|
puts $fh " kernel /boot/bender"
|
||||||
puts $fh " module /fiasco/bootstrap -modaddr=0x01100000"
|
puts $fh " module /fiasco/bootstrap -modaddr=0x01100000"
|
||||||
puts $fh " module /fiasco/fiasco $fiasco_serial_esc_arg"
|
puts $fh " module /fiasco/fiasco $fiasco_serial_esc_arg"
|
||||||
puts $fh " module /fiasco/sigma0"
|
puts $fh " module /fiasco/sigma0"
|
||||||
puts $fh " module /genode/core"
|
puts $fh " module /genode/core"
|
||||||
puts $fh " module /genode/config"
|
puts $fh " module /genode/config"
|
||||||
foreach binary $binaries {
|
foreach binary $binaries {
|
||||||
if {$binary != "core"} {
|
if {$binary != "core"} {
|
||||||
puts $fh " module /genode/$binary" } }
|
puts $fh " module /genode/$binary" } }
|
||||||
puts $fh " vbeset 0x117 506070"
|
puts $fh " vbeset 0x117 506070"
|
||||||
close $fh
|
|
||||||
|
|
||||||
install_pxe_bootloader_to_run_dir
|
|
||||||
create_iso_image_from_run_dir
|
|
||||||
create_disk_image_from_run_dir
|
|
||||||
|
|
||||||
#
|
|
||||||
# Generate pulsar config file
|
|
||||||
#
|
|
||||||
set fh [open "[run_dir]/config-52-54-00-12-34-56" "WRONLY CREAT TRUNC"]
|
|
||||||
puts $fh " exec /boot/bender"
|
|
||||||
puts $fh " load /fiasco/bootstrap -modaddr=0x01100000"
|
|
||||||
puts $fh " load /fiasco/fiasco -serial_esc"
|
|
||||||
puts $fh " load /fiasco/sigma0"
|
|
||||||
puts $fh " load /genode/core"
|
|
||||||
puts $fh " load /genode/config"
|
|
||||||
foreach binary $binaries {
|
|
||||||
if {$binary != "core"} {
|
|
||||||
puts $fh " load /genode/$binary" } }
|
|
||||||
close $fh
|
|
||||||
|
|
||||||
#
|
|
||||||
# Generate pulsar config file pointing to the config file above.
|
|
||||||
#
|
|
||||||
if {[info exists ::env(PXE_TFTP_DIR_BASE)] && [info exists ::env(PXE_TFTP_DIR_OFFSET)]} {
|
|
||||||
exec ln -nfs "[pwd]" "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)"
|
|
||||||
|
|
||||||
set tftp_base ""
|
|
||||||
if {[get_cmd_switch --tftp-absolute]} {
|
|
||||||
set tftp_base $::env(PXE_TFTP_DIR_BASE)
|
|
||||||
}
|
|
||||||
|
|
||||||
set fh [open "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)/config-00-00-00-00-00-00" "WRONLY CREAT TRUNC"]
|
|
||||||
puts $fh " root $tftp_base$::env(PXE_TFTP_DIR_OFFSET)/[run_dir]"
|
|
||||||
puts $fh " config config-52-54-00-12-34-56"
|
|
||||||
close $fh
|
close $fh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build image
|
||||||
|
#
|
||||||
|
run_image
|
||||||
|
|
||||||
|
if {[have_include "load/tftp"]} {
|
||||||
|
#
|
||||||
|
# Install PXE bootloader pulsar
|
||||||
|
#
|
||||||
|
install_pxe_bootloader_to_run_dir
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate pulsar config file
|
||||||
|
#
|
||||||
|
set fh [open "[run_dir]/config-52-54-00-12-34-56" "WRONLY CREAT TRUNC"]
|
||||||
|
puts $fh " exec /boot/bender"
|
||||||
|
puts $fh " load /fiasco/bootstrap -modaddr=0x01100000"
|
||||||
|
puts $fh " load /fiasco/fiasco -serial_esc"
|
||||||
|
puts $fh " load /fiasco/sigma0"
|
||||||
|
puts $fh " load /genode/core"
|
||||||
|
puts $fh " load /genode/config"
|
||||||
|
foreach binary $binaries {
|
||||||
|
if {$binary != "core"} {
|
||||||
|
puts $fh " load /genode/$binary" } }
|
||||||
|
close $fh
|
||||||
|
|
||||||
|
generate_tftp_config
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
proc build_boot_image_arm {binaries} {
|
proc run_boot_dir_arm {binaries} {
|
||||||
|
|
||||||
global run_target
|
global run_target
|
||||||
global fiasco_serial_esc_arg
|
global fiasco_serial_esc_arg
|
||||||
@ -249,53 +223,27 @@ proc build_boot_image_arm {binaries} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
exec cp [bin_dir]/bootstrap.elf [run_dir]/image.elf
|
exec cp [bin_dir]/bootstrap.elf [run_dir]/image.elf
|
||||||
build_uboot_image [run_dir]/image.elf
|
run_image [run_dir]/image.elf
|
||||||
|
|
||||||
puts "\nboot image: [run_dir]/image.elf\n"
|
puts "\nboot image: [run_dir]/image.elf\n"
|
||||||
|
|
||||||
# set symbolic link to image.elf file in TFTP directory for PXE boot
|
# set symbolic link to image.elf file in TFTP directory for PXE boot
|
||||||
if {[info exists ::env(PXE_TFTP_DIR_BASE)] &&
|
if {[have_include "load/tftp"]} {
|
||||||
[info exists ::env(PXE_TFTP_DIR_OFFSET)]} {
|
set tftp_base_dir [load_tftp_base_dir]
|
||||||
exec ln -sf "[pwd]/[run_dir]/image.elf" "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)"
|
set tftp_offset_dir [load_tftp_offset_dir]
|
||||||
if {[regexp "uboot" $run_target]} {
|
|
||||||
exec ln -sf "[pwd]/[run_dir]/uImage" "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)/uImage"
|
exec ln -sf [pwd]/[run_dir]/image.elf $tftp_base_dir$tftp_offset_dir
|
||||||
|
if {[have_include "image/uboot"]} {
|
||||||
|
exec ln -sf [pwd]/[run_dir]/uImage $tftp_base_dir$tftp_offset_dir/uImage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
proc build_boot_image {binaries} {
|
##
|
||||||
if {[have_spec x86]} { return [build_boot_image_x86 $binaries] }
|
# Populate boot directory with binaries on fiasco.OC
|
||||||
if {[have_spec arm]} { return [build_boot_image_arm $binaries] }
|
#
|
||||||
}
|
proc run_boot_dir {binaries} {
|
||||||
|
if {[have_spec x86]} { return [run_boot_dir_x86 $binaries] }
|
||||||
|
if {[have_spec arm]} { return [run_boot_dir_arm $binaries] }
|
||||||
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_amt_available]} {
|
|
||||||
spawn_amt $wait_for_re $timeout_value
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if {[is_qemu_available]} {
|
|
||||||
spawn_qemu $wait_for_re $timeout_value
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if {[is_serial_available]} {
|
|
||||||
spawn_serial $wait_for_re $timeout_value "L4 Bootstrapper"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
global run_target
|
|
||||||
puts stderr "Error: Can't execute automatically on target '$run_target'"
|
|
||||||
exit -1
|
|
||||||
}
|
}
|
@ -1,58 +1,19 @@
|
|||||||
#!/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
|
# Ensure that the next Genode build includes no target specific boot modules
|
||||||
#
|
#
|
||||||
proc clean_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 var/libcache/boot_modules/boot_modules.o }
|
||||||
|
|
||||||
|
|
||||||
##########################
|
proc run_boot_dir_hook { } {
|
||||||
## '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
|
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 { } {
|
##
|
||||||
|
# Populate boot directory with binaries on hw
|
||||||
exec rm -rf [run_dir]
|
#
|
||||||
exec mkdir -p [run_dir]/genode
|
proc run_boot_dir {binaries {core_type core}} {
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
proc build_boot_image {binaries {core_type core}} {
|
|
||||||
if {$core_type == "test"} {
|
if {$core_type == "test"} {
|
||||||
set core_bin "test-[run_name]"
|
set core_bin "test-[run_name]"
|
||||||
set core_target "test/[run_name]"
|
set core_target "test/[run_name]"
|
||||||
@ -90,7 +51,7 @@ proc build_boot_image {binaries {core_type core}} {
|
|||||||
exec echo -e \
|
exec echo -e \
|
||||||
"/**" \
|
"/**" \
|
||||||
"\n * This file was automatically generated by the procedure" \
|
"\n * This file was automatically generated by the procedure" \
|
||||||
"\n * 'build_boot_image' in 'base-hw/run/env'." \
|
"\n * 'run_boot_dir' in 'base-hw/run/env'." \
|
||||||
"\n */" \
|
"\n */" \
|
||||||
"\n" \
|
"\n" \
|
||||||
"\n /* core includes */" \
|
"\n /* core includes */" \
|
||||||
@ -176,15 +137,14 @@ proc build_boot_image {binaries {core_type core}} {
|
|||||||
exec cp -L bin/$core_bin $elf_img
|
exec cp -L bin/$core_bin $elf_img
|
||||||
exec [cross_dev_prefix]strip $elf_img
|
exec [cross_dev_prefix]strip $elf_img
|
||||||
|
|
||||||
build_uboot_image $elf_img
|
run_image $elf_img
|
||||||
|
|
||||||
# set symbolic link to image.elf file in TFTP directory for PXE boot
|
# set symbolic link to image.elf file in TFTP directory for PXE boot
|
||||||
if {[info exists ::env(PXE_TFTP_DIR_BASE)] &&
|
if {[have_include "load/tftp"]} {
|
||||||
[info exists ::env(PXE_TFTP_DIR_OFFSET)]} {
|
exec ln -sf [pwd]/$elf_img [load_tftp_base_dir][load_tftp_offset_dir]
|
||||||
exec ln -sf "[pwd]/$elf_img" "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)"
|
|
||||||
|
|
||||||
if {[regexp "uboot" $run_target]} {
|
if {[have_include "image/uboot"]} {
|
||||||
exec ln -sf "[pwd]/[run_dir]/uImage" "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)"
|
exec ln -sf [pwd]/[run_dir]/uImage [load_tftp_base_dir][load_tftp_offset_dir]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,31 +152,3 @@ proc build_boot_image {binaries {core_type core}} {
|
|||||||
exec cp $core_target/$core_bin.standalone bin/$core_bin
|
exec cp $core_target/$core_bin.standalone bin/$core_bin
|
||||||
exec rm $core_target/$core_bin.standalone
|
exec rm $core_target/$core_bin.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 "kernel initialized"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
global run_target
|
|
||||||
puts stderr "Error: Can't execute automatically on target '$run_target'"
|
|
||||||
exit -1
|
|
||||||
}
|
|
||||||
|
|
7
tool/run/boot_dir/linux
Normal file
7
tool/run/boot_dir/linux
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
##
|
||||||
|
# Populate boot directory with binaries on Linux
|
||||||
|
#
|
||||||
|
proc run_boot_dir {binaries} {
|
||||||
|
foreach binary $binaries {
|
||||||
|
exec ln -sf ../../../../bin/$binary [run_dir]/genode }
|
||||||
|
}
|
90
tool/run/boot_dir/nova
Normal file
90
tool/run/boot_dir/nova
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
##
|
||||||
|
# Read the location of the NOVA kernel directory from 'etc/nova.conf'
|
||||||
|
#
|
||||||
|
proc nova_kernel { } {
|
||||||
|
global _nova_kernel
|
||||||
|
|
||||||
|
if {![info exists _nova_kernel]} {
|
||||||
|
if {[file exists etc/nova.conf]} {
|
||||||
|
set _nova_kernel [exec sed -n "/^NOVA_KERNEL/s/^.*=\\s*//p" etc/nova.conf]
|
||||||
|
} else {
|
||||||
|
set _nova_kernel "[pwd]/kernel/hypervisor"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $_nova_kernel
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Return whether nova is provided from the outside
|
||||||
|
#
|
||||||
|
proc nova_external { } {
|
||||||
|
if {[nova_kernel] == "[pwd]/kernel/hypervisor"} { return 0 }
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Populate directory with binaries on NOVA
|
||||||
|
#
|
||||||
|
proc run_boot_dir {binaries} {
|
||||||
|
#
|
||||||
|
# Collect contents of the ISO image
|
||||||
|
#
|
||||||
|
copy_and_strip_genode_binaries_to_run_dir $binaries
|
||||||
|
|
||||||
|
if {![nova_external] && ![file exists [nova_kernel]]} { build { kernel } }
|
||||||
|
|
||||||
|
puts "using NOVA kernel at [nova_kernel]"
|
||||||
|
exec [cross_dev_prefix]objcopy -O elf32-i386 [nova_kernel] [run_dir]/hypervisor
|
||||||
|
|
||||||
|
if {[have_include "image/iso"] || [have_include "image/disk"]} {
|
||||||
|
#
|
||||||
|
# Install isolinux/GRUB files and bender
|
||||||
|
#
|
||||||
|
install_iso_bootloader_to_run_dir
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate GRUB config file
|
||||||
|
#
|
||||||
|
set fh [open "[run_dir]/boot/grub/menu.lst" "WRONLY CREAT TRUNC"]
|
||||||
|
puts $fh "timeout 0"
|
||||||
|
puts $fh "default 0"
|
||||||
|
puts $fh "\ntitle Genode on NOVA"
|
||||||
|
puts $fh " kernel /boot/bender"
|
||||||
|
puts $fh " module /hypervisor iommu serial novpid"
|
||||||
|
puts $fh " module /genode/core"
|
||||||
|
puts $fh " module /genode/config"
|
||||||
|
foreach binary $binaries {
|
||||||
|
if {$binary != "core"} {
|
||||||
|
puts $fh " module /genode/$binary" } }
|
||||||
|
close $fh
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build image
|
||||||
|
#
|
||||||
|
run_image
|
||||||
|
|
||||||
|
if {[have_include "load/tftp"]} {
|
||||||
|
#
|
||||||
|
# Install PXE bootloader pulsar
|
||||||
|
#
|
||||||
|
install_pxe_bootloader_to_run_dir
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate pulsar config file
|
||||||
|
#
|
||||||
|
set fh [open "[run_dir]/config-52-54-00-12-34-56" "WRONLY CREAT TRUNC"]
|
||||||
|
puts $fh " exec /boot/bender"
|
||||||
|
puts $fh " load /hypervisor iommu serial novpid"
|
||||||
|
puts $fh " load /genode/core"
|
||||||
|
puts $fh " load /genode/config"
|
||||||
|
foreach binary $binaries {
|
||||||
|
if {$binary != "core"} {
|
||||||
|
puts $fh " load /genode/$binary" } }
|
||||||
|
close $fh
|
||||||
|
|
||||||
|
generate_tftp_config
|
||||||
|
}
|
||||||
|
}
|
@ -1,24 +1,9 @@
|
|||||||
#
|
|
||||||
# \brief OKL4-specific test-environment supplements
|
|
||||||
# \author Norman Feske
|
|
||||||
# \date 2010-08-16
|
|
||||||
#
|
|
||||||
# This file is meant to be used as '--include' argument for 'tool/run'.
|
|
||||||
#
|
|
||||||
|
|
||||||
##
|
|
||||||
# Install files needed to boot via PXE
|
|
||||||
#
|
|
||||||
proc install_pxe_bootloader_to_run_dir { } {
|
|
||||||
exec cp [genode_dir]/tool/boot/pulsar [run_dir]/boot/pulsar
|
|
||||||
exec cp [genode_dir]/tool/boot/bender [run_dir]/boot/bender
|
|
||||||
}
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Get the base-okl4 repository
|
# Get the base-okl4 repository
|
||||||
#
|
#
|
||||||
proc base_okl4_dir {} { return [repository_contains mk/spec-okl4.mk] }
|
proc base_okl4_dir {} { return [repository_contains mk/spec-okl4.mk] }
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Read the location of the OKL4 directory from 'etc/okl4.conf'
|
# Read the location of the OKL4 directory from 'etc/okl4.conf'
|
||||||
#
|
#
|
||||||
@ -37,6 +22,7 @@ proc okl4_dir { } {
|
|||||||
return $_okl4_dir
|
return $_okl4_dir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Return the location of the OKL4 kernel
|
# Return the location of the OKL4 kernel
|
||||||
#
|
#
|
||||||
@ -45,6 +31,7 @@ proc okl4 { } {
|
|||||||
return bin/kernel
|
return bin/kernel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Return whether okl4 kernel is provided from the outside
|
# Return whether okl4 kernel is provided from the outside
|
||||||
#
|
#
|
||||||
@ -53,15 +40,6 @@ proc okl4_external { } {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
##################################
|
|
||||||
## Test framework API functions ##
|
|
||||||
##################################
|
|
||||||
|
|
||||||
proc create_boot_directory { } {
|
|
||||||
exec rm -rf [run_dir]
|
|
||||||
exec mkdir -p [run_dir]/genode
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
set weaver_xml_template {
|
set weaver_xml_template {
|
||||||
<machine>
|
<machine>
|
||||||
@ -122,7 +100,11 @@ set weaver_xml_template {
|
|||||||
<rootprogram file="core" virtpool="virtual" physpool="physical" />
|
<rootprogram file="core" virtpool="virtual" physpool="physical" />
|
||||||
}
|
}
|
||||||
|
|
||||||
proc build_boot_image {binaries} {
|
|
||||||
|
##
|
||||||
|
# Populate directory with binaries on OKL4
|
||||||
|
#
|
||||||
|
proc run_boot_dir {binaries} {
|
||||||
global weaver_xml_template
|
global weaver_xml_template
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -179,86 +161,50 @@ proc build_boot_image {binaries} {
|
|||||||
#
|
#
|
||||||
exec rm -r [run_dir]/genode
|
exec rm -r [run_dir]/genode
|
||||||
|
|
||||||
#
|
if {[have_include "image/iso"] || [have_include "image/disk"]} {
|
||||||
# Install GRUB
|
#
|
||||||
#
|
# Install GRUB
|
||||||
install_iso_bootloader_to_run_dir
|
#
|
||||||
|
install_iso_bootloader_to_run_dir
|
||||||
|
|
||||||
#
|
#
|
||||||
# Install PXE bootloader pulsar
|
# Generate grub config file
|
||||||
#
|
#
|
||||||
install_pxe_bootloader_to_run_dir
|
# The core binary is part of the 'binaries' list but it must
|
||||||
|
# appear right after 'sigma0' as boot module. Hence the special case.
|
||||||
#
|
#
|
||||||
# Generate grub config file
|
set fh [open "[run_dir]/boot/grub/menu.lst" "WRONLY CREAT TRUNC"]
|
||||||
#
|
puts $fh "timeout 0"
|
||||||
# The core binary is part of the 'binaries' list but it must
|
puts $fh "default 0"
|
||||||
# appear right after 'sigma0' as boot module. Hence the special case.
|
puts $fh "hiddenmenu"
|
||||||
#
|
puts $fh "\ntitle Genode on OKL4"
|
||||||
set fh [open "[run_dir]/boot/grub/menu.lst" "WRONLY CREAT TRUNC"]
|
puts $fh " kernel /boot/bender"
|
||||||
puts $fh "timeout 0"
|
puts $fh " module /image.elf"
|
||||||
puts $fh "default 0"
|
puts $fh " vbeset 0x117"
|
||||||
puts $fh "hiddenmenu"
|
|
||||||
puts $fh "\ntitle Genode on OKL4"
|
|
||||||
puts $fh " kernel /boot/bender"
|
|
||||||
puts $fh " module /image.elf"
|
|
||||||
puts $fh " vbeset 0x117"
|
|
||||||
close $fh
|
|
||||||
|
|
||||||
create_iso_image_from_run_dir
|
|
||||||
create_disk_image_from_run_dir
|
|
||||||
|
|
||||||
#
|
|
||||||
# Generate pulsar config file
|
|
||||||
#
|
|
||||||
set fh [open "[run_dir]/config-52-54-00-12-34-56" "WRONLY CREAT TRUNC"]
|
|
||||||
# load okl4 at 256M to avoid overwritting binary, adjust by need
|
|
||||||
puts $fh " addr 0x10000000"
|
|
||||||
puts $fh " exec /boot/bender"
|
|
||||||
puts $fh " load /image.elf"
|
|
||||||
close $fh
|
|
||||||
|
|
||||||
#
|
|
||||||
# Generate pulsar config file pointing to the config file above.
|
|
||||||
#
|
|
||||||
if {[info exists ::env(PXE_TFTP_DIR_BASE)] && [info exists ::env(PXE_TFTP_DIR_OFFSET)]} {
|
|
||||||
exec ln -nfs "[pwd]" "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)"
|
|
||||||
|
|
||||||
set tftp_base ""
|
|
||||||
if {[get_cmd_switch --tftp-absolute]} {
|
|
||||||
set tftp_base $::env(PXE_TFTP_DIR_BASE)
|
|
||||||
}
|
|
||||||
|
|
||||||
set fh [open "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)/config-00-00-00-00-00-00" "WRONLY CREAT TRUNC"]
|
|
||||||
puts $fh " root $tftp_base$::env(PXE_TFTP_DIR_OFFSET)/[run_dir]"
|
|
||||||
puts $fh " config config-52-54-00-12-34-56"
|
|
||||||
close $fh
|
close $fh
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
#
|
||||||
|
# Build image
|
||||||
proc run_genode_until {{wait_for_re forever} {timeout_value 0} {running_spawn_id -1}} {
|
#
|
||||||
#
|
run_image
|
||||||
# If a running_spawn_id is specified, wait for the expected output
|
|
||||||
#
|
if {[have_include "load/tftp"]} {
|
||||||
if {$running_spawn_id != -1} {
|
#
|
||||||
wait_for_output $wait_for_re $timeout_value $running_spawn_id
|
# Install PXE bootloader pulsar
|
||||||
return
|
#
|
||||||
}
|
install_pxe_bootloader_to_run_dir
|
||||||
|
|
||||||
#
|
#
|
||||||
# Try to use one of the supported backends for running the scripts
|
# Generate pulsar config file
|
||||||
#
|
#
|
||||||
if {[is_amt_available]} {
|
set fh [open "[run_dir]/config-52-54-00-12-34-56" "WRONLY CREAT TRUNC"]
|
||||||
spawn_amt $wait_for_re $timeout_value
|
# load okl4 at 256M to avoid overwritting binary, adjust by need
|
||||||
return
|
puts $fh " addr 0x10000000"
|
||||||
}
|
puts $fh " exec /boot/bender"
|
||||||
if {[is_qemu_available]} {
|
puts $fh " load /image.elf"
|
||||||
spawn_qemu $wait_for_re $timeout_value
|
close $fh
|
||||||
return
|
|
||||||
}
|
generate_tftp_config
|
||||||
|
}
|
||||||
global run_target
|
|
||||||
puts stderr "Error: Can't execute automatically on target '$run_target'"
|
|
||||||
exit -1
|
|
||||||
}
|
}
|
140
tool/run/boot_dir/pistachio
Normal file
140
tool/run/boot_dir/pistachio
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
#
|
||||||
|
# \brief Pistachio-specific test-environment supplements
|
||||||
|
# \author Norman Feske
|
||||||
|
# \date 2010-08-25
|
||||||
|
#
|
||||||
|
# This file is meant to be used as '--include' argument for 'tool/run'.
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Install files needed to boot via PXE
|
||||||
|
#
|
||||||
|
proc install_pxe_bootloader_to_run_dir { } {
|
||||||
|
exec cp [genode_dir]/tool/boot/pulsar [run_dir]/boot/pulsar
|
||||||
|
exec cp [genode_dir]/tool/boot/bender [run_dir]/boot/bender
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Read the location of the Pistachio user directory from 'etc/pistachio.conf'
|
||||||
|
#
|
||||||
|
proc pistachio_user_dir { } {
|
||||||
|
global _pistachio_user_dir
|
||||||
|
|
||||||
|
if {![info exists _pistachio_user_dir]} {
|
||||||
|
if {[file exists etc/pistachio.conf]} {
|
||||||
|
set _pistachio_user_dir [exec sed -n "/^PISTACHIO_USER_BUILD_DIR/s/^.*=\\s*//p" etc/pistachio.conf]
|
||||||
|
} else {
|
||||||
|
set _pistachio_user_dir "[pwd]/l4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $_pistachio_user_dir
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Read the location of the Pistachio kernel directory from 'etc/pistachio.conf'
|
||||||
|
# or return a good heuristic
|
||||||
|
#
|
||||||
|
proc pistachio_kernel { } {
|
||||||
|
global _pistachio_kernel
|
||||||
|
|
||||||
|
if {![info exists _pistachio_kernel]} {
|
||||||
|
if {[file exists etc/pistachio.conf]} {
|
||||||
|
set _pistachio_kernel [exec sed -n "/^PISTACHIO_KERNEL/s/^.*=\\s*//p" etc/pistachio.conf]
|
||||||
|
if {$_pistachio_kernel == ""} {
|
||||||
|
set _pistachio_kernel [file dirname [file dirname [pistachio_user_dir]]]/kernel/build/x86-kernel
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
set _pistachio_kernel "[pwd]/bin/kernel"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $_pistachio_kernel
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Return whether the kernel is provided from the outside
|
||||||
|
#
|
||||||
|
proc kernel_external { } {
|
||||||
|
if {[pistachio_kernel] == "[pwd]/bin/kernel"} { return 0 }
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Populdate boot directory with binaries on pistachio
|
||||||
|
#
|
||||||
|
proc run_boot_dir {binaries} {
|
||||||
|
|
||||||
|
exec mkdir -p [run_dir]/pistachio
|
||||||
|
|
||||||
|
#
|
||||||
|
# Collect contents of the ISO image
|
||||||
|
#
|
||||||
|
copy_and_strip_genode_binaries_to_run_dir $binaries
|
||||||
|
|
||||||
|
if {![kernel_external] && ![file exists [pistachio_kernel]]} { build { kernel } }
|
||||||
|
|
||||||
|
exec cp [pistachio_kernel] [run_dir]/pistachio/kernel
|
||||||
|
exec cp [pistachio_user_dir]/serv/sigma0/sigma0 [run_dir]/pistachio
|
||||||
|
exec cp [pistachio_user_dir]/util/kickstart/kickstart [run_dir]/pistachio
|
||||||
|
|
||||||
|
if {[have_include "image/iso"] || [have_include "image/disk"]} {
|
||||||
|
#
|
||||||
|
# Install isolinux/GRUB files and bender
|
||||||
|
#
|
||||||
|
install_iso_bootloader_to_run_dir
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate grub config file
|
||||||
|
#
|
||||||
|
# The core binary is part of the 'binaries' list but it must
|
||||||
|
# appear right after 'sigma0' as boot module. Hence the special case.
|
||||||
|
#
|
||||||
|
set fh [open "[run_dir]/boot/grub/menu.lst" "WRONLY CREAT TRUNC"]
|
||||||
|
puts $fh "timeout 0"
|
||||||
|
puts $fh "default 0"
|
||||||
|
puts $fh "\ntitle Genode on L4ka::Pistachio"
|
||||||
|
puts $fh " kernel /pistachio/kickstart"
|
||||||
|
puts $fh " module /pistachio/kernel"
|
||||||
|
puts $fh " module /pistachio/sigma0"
|
||||||
|
puts $fh " module /genode/core"
|
||||||
|
puts $fh " module /genode/config"
|
||||||
|
foreach binary $binaries {
|
||||||
|
if {$binary != "core"} {
|
||||||
|
puts $fh " module /genode/$binary" } }
|
||||||
|
close $fh
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build image
|
||||||
|
#
|
||||||
|
run_image
|
||||||
|
|
||||||
|
if {[have_include "load/tftp"]} {
|
||||||
|
#
|
||||||
|
# Install PXE bootloader pulsar
|
||||||
|
#
|
||||||
|
install_pxe_bootloader_to_run_dir
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate pulsar config file
|
||||||
|
#
|
||||||
|
set fh [open "[run_dir]/config-52-54-00-12-34-56" "WRONLY CREAT TRUNC"]
|
||||||
|
puts $fh " exec /boot/bender"
|
||||||
|
puts $fh " load /pistachio/kickstart"
|
||||||
|
puts $fh " load /pistachio/kernel"
|
||||||
|
puts $fh " load /pistachio/sigma0"
|
||||||
|
puts $fh " load /genode/core"
|
||||||
|
puts $fh " load /genode/config"
|
||||||
|
puts $fh " load /genode/config"
|
||||||
|
foreach binary $binaries {
|
||||||
|
if {$binary != "core"} {
|
||||||
|
puts $fh " load /genode/$binary" } }
|
||||||
|
close $fh
|
||||||
|
|
||||||
|
generate_tftp_config
|
||||||
|
}
|
||||||
|
}
|
49
tool/run/image/disk
Normal file
49
tool/run/image/disk
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
##
|
||||||
|
# Create disk image with contents of the run directory
|
||||||
|
#
|
||||||
|
# \param --image-disk-size disk size in MiB
|
||||||
|
#
|
||||||
|
|
||||||
|
source [genode_dir]/tool/run/iso.inc
|
||||||
|
|
||||||
|
|
||||||
|
proc image_disk_size { } { return [get_cmd_arg --image-disk-size 0] }
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Create disk image with the content of the run directory
|
||||||
|
#
|
||||||
|
proc run_image { {unused ""} } {
|
||||||
|
|
||||||
|
requires_installation_of parted
|
||||||
|
requires_installation_of resize2fs
|
||||||
|
requires_installation_of fallocate
|
||||||
|
|
||||||
|
set grub_img "[genode_dir]/tool/grub2-head.img"
|
||||||
|
set disk_img "[run_dir].img"
|
||||||
|
set part1_img "[run_dir]-part1.img"
|
||||||
|
set run_size [expr [regsub {\s.*} [exec du -sm [run_dir]] {}] + 4]
|
||||||
|
if {[image_disk_size] > 0} {
|
||||||
|
set disk_size [image_disk_size]
|
||||||
|
} else {
|
||||||
|
set disk_size $run_size
|
||||||
|
}
|
||||||
|
set part1_size [expr $disk_size - 1]MiB
|
||||||
|
|
||||||
|
# extract and resize partition image
|
||||||
|
exec dd if=$grub_img of=$part1_img bs=1M skip=1 2>/dev/null
|
||||||
|
exec fallocate -l $part1_size $part1_img
|
||||||
|
exec resize2fs $part1_img 2>/dev/null
|
||||||
|
|
||||||
|
# populate partition with binaries
|
||||||
|
exec [genode_dir]/tool/rump -F ext2fs -p [run_dir] $part1_img
|
||||||
|
|
||||||
|
# merge final image from GRUB2 head and partition
|
||||||
|
exec dd if=$grub_img of=$disk_img status=noxfer bs=1M count=1 2>/dev/null
|
||||||
|
exec dd if=$part1_img of=$disk_img status=noxfer bs=1M seek=1 2>/dev/null
|
||||||
|
exec parted -s $disk_img -- rm 1 mkpart primary 2048s -1s set 1 boot on
|
||||||
|
|
||||||
|
exec rm -f $part1_img
|
||||||
|
|
||||||
|
puts "Created image file $disk_img ($disk_size MiB)"
|
||||||
|
}
|
20
tool/run/image/iso
Normal file
20
tool/run/image/iso
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
source [genode_dir]/tool/run/iso.inc
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Create ISO image with the content of the run directory
|
||||||
|
#
|
||||||
|
proc run_image { {unused ""} } {
|
||||||
|
|
||||||
|
puts "creating ISO image..."
|
||||||
|
exec rm -f "[run_dir].iso"
|
||||||
|
|
||||||
|
#
|
||||||
|
# The 'create_iso' writes diagnostics to stderr, which are interpreted as
|
||||||
|
# execution failure by expect unless '-ignorestderr' is set on 'exec'.
|
||||||
|
#
|
||||||
|
if {[catch {exec -ignorestderr [genode_dir]/tool/create_iso iso ISO=[run_dir]} ]} {
|
||||||
|
puts stderr "Error: ISO image creation failed"
|
||||||
|
exit -5
|
||||||
|
}
|
||||||
|
}
|
47
tool/run/image/uboot
Normal file
47
tool/run/image/uboot
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
##
|
||||||
|
# Build U-boot bootloader specific uImage
|
||||||
|
#
|
||||||
|
# \param --image-uboot-no-gzip do not gzip the uImage
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Check if the uImage should be gzipped
|
||||||
|
#
|
||||||
|
proc image_uboot_use_no_gzip { } { return [get_cmd_switch --image-uboot-no-gzip] }
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Build U-boot bootloader specific uImage
|
||||||
|
#
|
||||||
|
# \param elf_img ELF binary to build uImage from
|
||||||
|
#
|
||||||
|
proc run_image {elf_img} {
|
||||||
|
# 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]
|
||||||
|
|
||||||
|
set bin_img "[run_dir]/image.bin"
|
||||||
|
exec [cross_dev_prefix]objcopy -O binary $elf_img $bin_img
|
||||||
|
|
||||||
|
set use_gzip [expr ![image_uboot_use_no_gzip]]
|
||||||
|
set compress_type none
|
||||||
|
set bin_ext ""
|
||||||
|
|
||||||
|
# compress ELF
|
||||||
|
if $use_gzip {
|
||||||
|
exec gzip --best --force $bin_img
|
||||||
|
set bin_ext .gz
|
||||||
|
set compress_type gzip
|
||||||
|
}
|
||||||
|
|
||||||
|
# create uImage
|
||||||
|
set uboot_img [run_dir]/uImage
|
||||||
|
exec mkimage -A arm -O linux -T kernel -C $compress_type -a $load_addr \
|
||||||
|
-e $entrypoint -d $bin_img$bin_ext $uboot_img
|
||||||
|
exec rm -rf $bin_img$bin_ext
|
||||||
|
}
|
20
tool/run/iso.inc
Normal file
20
tool/run/iso.inc
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
##
|
||||||
|
# Install files needed to create a bootable ISO image
|
||||||
|
#
|
||||||
|
# The ISO boot concept uses isolinux to load GRUB, which in turn loads Genode.
|
||||||
|
# This way we can make use of isolinux' support for booting ISO images from a
|
||||||
|
# USB stick.
|
||||||
|
#
|
||||||
|
proc install_iso_bootloader_to_run_dir { } {
|
||||||
|
puts "install bootloader"
|
||||||
|
|
||||||
|
exec mkdir -p [run_dir]/boot/isolinux
|
||||||
|
exec cp [genode_dir]/tool/boot/chain.c32 [run_dir]/boot/isolinux
|
||||||
|
exec cp [genode_dir]/tool/boot/isolinux.bin [run_dir]/boot/isolinux
|
||||||
|
exec cp [genode_dir]/tool/boot/isolinux.cfg [run_dir]/boot/isolinux
|
||||||
|
|
||||||
|
exec mkdir -p [run_dir]/boot/grub
|
||||||
|
exec cp [genode_dir]/tool/boot/stage2_eltorito [run_dir]/boot/grub
|
||||||
|
|
||||||
|
exec cp [genode_dir]/tool/boot/bender [run_dir]/boot/bender
|
||||||
|
}
|
7
tool/run/load.inc
Normal file
7
tool/run/load.inc
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
##
|
||||||
|
# Get the spawn_id of the load process
|
||||||
|
#
|
||||||
|
proc load_spawn_id { } {
|
||||||
|
global load_spawn_id
|
||||||
|
return $load_spawn_id
|
||||||
|
}
|
52
tool/run/load/jtag
Normal file
52
tool/run/load/jtag
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
##
|
||||||
|
# Load image to target hardware via JTAG
|
||||||
|
#
|
||||||
|
# \param --load-jtag-debugger Debugger used
|
||||||
|
# \param --load-jtag-board Set the used board
|
||||||
|
#
|
||||||
|
|
||||||
|
source [genode_dir]/tool/run/load.inc
|
||||||
|
|
||||||
|
|
||||||
|
proc load_jtag_debugger { } { return [get_cmd_arg --load-jtag-debugger 1] }
|
||||||
|
|
||||||
|
|
||||||
|
proc load_jtag_board { } { return [get_cmd_arg --load-jtag-board 1] }
|
||||||
|
|
||||||
|
|
||||||
|
proc run_load { } {
|
||||||
|
global load_spawn_id
|
||||||
|
|
||||||
|
if {![have_spec arm] || ![have_installed openocd]} {
|
||||||
|
puts "No support for JTAG detected."
|
||||||
|
exit -1
|
||||||
|
}
|
||||||
|
|
||||||
|
set debugger [load_jtag_debugger]
|
||||||
|
set board [load_jtag_board]
|
||||||
|
set elf_img "[run_dir]/image.elf"
|
||||||
|
|
||||||
|
# sleep a bit, board might need some time to come up
|
||||||
|
sleep 8
|
||||||
|
|
||||||
|
# parse ELF entrypoint
|
||||||
|
set entrypoint [exec [cross_dev_prefix]readelf -h $elf_img | \
|
||||||
|
grep "Entry point address: " | \
|
||||||
|
sed -e "s/.*Entry point address: *//"]
|
||||||
|
|
||||||
|
eval spawn openocd -f $debugger -f $board -c init -c halt \
|
||||||
|
-c \"load_image $elf_img\" -c \"resume $entrypoint\"
|
||||||
|
set load_spawn_id $spawn_id
|
||||||
|
set timeout 360
|
||||||
|
expect {
|
||||||
|
"downloaded" { return true; }
|
||||||
|
eof {
|
||||||
|
puts stderr "openocd command process died unexpectedly";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
timeout {
|
||||||
|
puts stderr "Loading timed out";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
64
tool/run/load/tftp
Normal file
64
tool/run/load/tftp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
##
|
||||||
|
# Load files needed by the scenario via TFTP
|
||||||
|
#
|
||||||
|
# \param --load-tftp-base-dir base directory of TFTP
|
||||||
|
# \param --load-tftp-offset-dir offset directory within TFTP
|
||||||
|
# \param --load-tftp-absolute path is absolute, i.e. /base_dir/offset_dir
|
||||||
|
# instead of only /offset_dir is used
|
||||||
|
#
|
||||||
|
|
||||||
|
source [genode_dir]/tool/run/load.inc
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# The files are loaded implicitly via TFTP to the target machine
|
||||||
|
#
|
||||||
|
proc run_load { } {
|
||||||
|
global load_spawn_id
|
||||||
|
set load_spawn_id -1
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
proc load_tftp_base_dir { } { return [get_cmd_arg --load-tftp-base-dir ""] }
|
||||||
|
|
||||||
|
|
||||||
|
proc load_tftp_offset_dir { } { return [get_cmd_arg --load-tftp-offset-dir ""] }
|
||||||
|
|
||||||
|
|
||||||
|
proc load_tftp_use_absolute { } { return [get_cmd_switch --load-tftp-absolute] }
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Install files needed to boot via PXE
|
||||||
|
#
|
||||||
|
proc install_pxe_bootloader_to_run_dir { } {
|
||||||
|
exec mkdir -p [run_dir]/boot
|
||||||
|
exec cp [genode_dir]/tool/boot/pulsar [run_dir]/boot/pulsar
|
||||||
|
exec cp [genode_dir]/tool/boot/bender [run_dir]/boot/bender
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Generate pulsar config file used for loading files from TFTP
|
||||||
|
#
|
||||||
|
proc generate_tftp_config { } {
|
||||||
|
set tftp_base_dir [load_tftp_base_dir]
|
||||||
|
set tftp_offset_dir [load_tftp_offset_dir]
|
||||||
|
|
||||||
|
if {[string length $tftp_base_dir] > 0 && [string length $tftp_offset_dir] > 0} {
|
||||||
|
exec ln -nfs "[pwd]" "$tftp_base_dir$tftp_offset_dir"
|
||||||
|
|
||||||
|
set tftp_base ""
|
||||||
|
if {[load_tftp_use_absolute]} {
|
||||||
|
set tftp_base $tftp_base_dir
|
||||||
|
}
|
||||||
|
|
||||||
|
set fh [open "$tftp_base_dir$tftp_offset_dir/config-00-00-00-00-00-00" "WRONLY CREAT TRUNC"]
|
||||||
|
puts $fh " root $tftp_base$tftp_offset_dir/[run_dir]"
|
||||||
|
puts $fh " config config-52-54-00-12-34-56"
|
||||||
|
close $fh
|
||||||
|
} else {
|
||||||
|
puts "Warning, TFTP base directory or TFTP offset directory not set."
|
||||||
|
}
|
||||||
|
}
|
7
tool/run/log.inc
Normal file
7
tool/run/log.inc
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
##
|
||||||
|
# Get the spawn_id of the output process
|
||||||
|
#
|
||||||
|
proc output_spawn_id { } {
|
||||||
|
global output_spawn_id
|
||||||
|
return $output_spawn_id
|
||||||
|
}
|
70
tool/run/log/amt
Normal file
70
tool/run/log/amt
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
##
|
||||||
|
# Get output of the target machine via Intel AMT's SoL feature
|
||||||
|
#
|
||||||
|
# \param --amt-host IP address of target machine
|
||||||
|
# \param --amt-password AMT password for target machine
|
||||||
|
#
|
||||||
|
|
||||||
|
source [genode_dir]/tool/run/log.inc
|
||||||
|
source [genode_dir]/tool/run/amt.inc
|
||||||
|
|
||||||
|
|
||||||
|
proc log_amt_host { } {
|
||||||
|
return [get_cmd_arg_first --log-amt-host ""]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
proc log_amt_password { } {
|
||||||
|
return [get_cmd_arg_first --log-amt-password ""]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Log output of the test machine using Intel's AMT
|
||||||
|
#
|
||||||
|
proc run_log { wait_for_re timeout_value } {
|
||||||
|
global output_spawn_id
|
||||||
|
|
||||||
|
if {![is_amt_available [log_amt_host] [log_amt_password]]} {
|
||||||
|
set exit_result 1
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# grab output
|
||||||
|
#
|
||||||
|
set amtterm "amtterm -u admin -p [log_amt_password] -v [log_amt_host]"
|
||||||
|
if {$wait_for_re == "forever"} {
|
||||||
|
set timeout -1
|
||||||
|
} else {
|
||||||
|
set timeout [expr $timeout_value + 30]
|
||||||
|
}
|
||||||
|
set exit_result 1
|
||||||
|
|
||||||
|
while { $exit_result != 0 } {
|
||||||
|
set time_start [ clock seconds ]
|
||||||
|
eval spawn $amtterm
|
||||||
|
set output_spawn_id $spawn_id
|
||||||
|
expect {
|
||||||
|
-i $output_spawn_id -re $wait_for_re { break }
|
||||||
|
eof { continue }
|
||||||
|
timeout { puts "Error: Test execution timed out"; exit -2 }
|
||||||
|
}
|
||||||
|
catch wait result
|
||||||
|
set time_end [ clock seconds ]
|
||||||
|
if {[expr $time_end - $time_start] <= 1} {
|
||||||
|
incr timeout -1
|
||||||
|
} else {
|
||||||
|
incr timeout [expr -1 * ($time_end - $time_start)]
|
||||||
|
}
|
||||||
|
if {$timeout < 0} {
|
||||||
|
set timeout 0
|
||||||
|
}
|
||||||
|
set exit_result [lindex $result 3]
|
||||||
|
}
|
||||||
|
|
||||||
|
global output
|
||||||
|
set output $expect_out(buffer)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
11
tool/run/log/linux
Normal file
11
tool/run/log/linux
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
source [genode_dir]/tool/run/log.inc
|
||||||
|
|
||||||
|
proc run_log { wait_for_re timeout_value } {
|
||||||
|
global linux_spawn_id
|
||||||
|
global output_spawn_id
|
||||||
|
|
||||||
|
set output_spawn_id $linux_spawn_id
|
||||||
|
|
||||||
|
wait_for_output $wait_for_re $timeout_value $linux_spawn_id
|
||||||
|
return true
|
||||||
|
}
|
17
tool/run/log/qemu
Normal file
17
tool/run/log/qemu
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
##
|
||||||
|
# Capture the output of a scenario executed via Qemu
|
||||||
|
#
|
||||||
|
|
||||||
|
source [genode_dir]/tool/run/log.inc
|
||||||
|
source [genode_dir]/tool/run/qemu.inc
|
||||||
|
|
||||||
|
|
||||||
|
proc run_log { wait_for_re timeout_value } {
|
||||||
|
global qemu_spawn_id
|
||||||
|
global output_spawn_id
|
||||||
|
|
||||||
|
set output_spawn_id $qemu_spawn_id
|
||||||
|
|
||||||
|
wait_for_output $wait_for_re $timeout_value $qemu_spawn_id
|
||||||
|
return true;
|
||||||
|
}
|
42
tool/run/log/serial
Normal file
42
tool/run/log/serial
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
##
|
||||||
|
# Get the output of the target machine via serial connection
|
||||||
|
#
|
||||||
|
# \param --log-serial-cmd Cmd that is executed to capture the output
|
||||||
|
#
|
||||||
|
|
||||||
|
source [genode_dir]/tool/run/log.inc
|
||||||
|
|
||||||
|
|
||||||
|
set default_serial_cmd "picocom -b 115200 /dev/ttyUSB0"
|
||||||
|
|
||||||
|
|
||||||
|
proc log_serial_cmd { } {
|
||||||
|
global default_serial_cmd
|
||||||
|
return [get_cmd_arg --log-serial-cmd $default_serial_cmd]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Log output of the test machine via serial device
|
||||||
|
#
|
||||||
|
proc run_log { wait_for_re timeout_value } {
|
||||||
|
global output_spawn_id
|
||||||
|
|
||||||
|
set timeout 210
|
||||||
|
while {true} {
|
||||||
|
eval spawn [log_serial_cmd]
|
||||||
|
set output_spawn_id $spawn_id
|
||||||
|
expect {
|
||||||
|
"Genode \[0-9]\[0-9]\.\[0-9]\[0-9]" {
|
||||||
|
wait_for_output $wait_for_re $timeout_value $output_spawn_id;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
eof { continue; }
|
||||||
|
timeout {
|
||||||
|
puts stderr "Boot process timed out";
|
||||||
|
close;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
45
tool/run/power_off/powerplug
Normal file
45
tool/run/power_off/powerplug
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
##
|
||||||
|
# Reset the target machine via powerplug
|
||||||
|
#
|
||||||
|
# \param --power-off-powerplug-ip IP address of powerplug device
|
||||||
|
# \param --power-off-powerplug-user user for powerplug device
|
||||||
|
# \param --power-off-powerplug-password password for powerplug device
|
||||||
|
# \param --power-off-powerplug-port target port of powerplug device
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
source [genode_dir]/tool/run/powerplug.inc
|
||||||
|
|
||||||
|
|
||||||
|
proc power_off_powerplug_ip { } {
|
||||||
|
return [get_cmd_arg_first --power-off-powerplug-ip 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
proc power_off_powerplug_user { } {
|
||||||
|
return [get_cmd_arg_first --power-off-powerplug-user 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
proc power_off_powerplug_password { } {
|
||||||
|
return [get_cmd_arg_first --power-off-powerplug-password 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
proc power_off_powerplug_port { } {
|
||||||
|
return [get_cmd_arg_first --power-off-powerplug-port 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
proc run_power_off { } {
|
||||||
|
set server_ip [power_off_powerplug_ip]
|
||||||
|
set user_name [power_off_powerplug_user]
|
||||||
|
set password [power_off_powerplug_password]
|
||||||
|
set power_port [power_off_powerplug_port]
|
||||||
|
|
||||||
|
set connection_id [power_plug_connect $server_ip $user_name $password]
|
||||||
|
|
||||||
|
puts "switch port $power_port off"
|
||||||
|
send -i $connection_id "port $power_port 0\n"
|
||||||
|
expect -i $connection_id "250 OK"
|
||||||
|
}
|
131
tool/run/power_on/amt
Normal file
131
tool/run/power_on/amt
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
##
|
||||||
|
# Reset the target machine via Intel AMT
|
||||||
|
#
|
||||||
|
# \param --power-on-amt-host IP address of target machine
|
||||||
|
# \param --power-on-amt-password AMT password for target machine
|
||||||
|
#
|
||||||
|
|
||||||
|
source [genode_dir]/tool/run/amt.inc
|
||||||
|
|
||||||
|
|
||||||
|
proc power_on_amt_host { } {
|
||||||
|
return [get_cmd_arg_first --power-on-amt-host ""]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
proc power_on_amt_password { } {
|
||||||
|
return [get_cmd_arg_first --power-on-amt-password ""]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Reset via Intel AMT (works up to version smaller Intel AMT 9)
|
||||||
|
#
|
||||||
|
proc amt_reset_soap_eoi { } {
|
||||||
|
set timeout 20
|
||||||
|
set exit_result 1
|
||||||
|
|
||||||
|
#
|
||||||
|
# amttool expects in the environment variable AMT_PASSWORD the password
|
||||||
|
#
|
||||||
|
set ::env(AMT_PASSWORD) [power_on_amt_password]
|
||||||
|
|
||||||
|
while { $exit_result != 0 } {
|
||||||
|
set try_again 0
|
||||||
|
set time_start [ clock seconds ]
|
||||||
|
spawn amttool [power_on_amt_host] reset
|
||||||
|
expect {
|
||||||
|
"host" { send "y\r"; }
|
||||||
|
eof { puts "Error: amttool died unexpectedly"; exit -4 }
|
||||||
|
timeout { puts "Error: amttool timed out"; exit -5 }
|
||||||
|
}
|
||||||
|
expect {
|
||||||
|
"result: pt_status: success" { break }
|
||||||
|
eof { set try_again 1 }
|
||||||
|
timeout { puts "Error: amttool timed out"; exit -6 }
|
||||||
|
}
|
||||||
|
catch wait result
|
||||||
|
set time_end [ clock seconds ]
|
||||||
|
if {[expr $time_end - $time_start] <= 1} {
|
||||||
|
incr timeout -1
|
||||||
|
} else {
|
||||||
|
incr timeout [expr -1 * ($time_end - $time_start)]
|
||||||
|
}
|
||||||
|
if {$timeout < 0} {
|
||||||
|
set timeout 0
|
||||||
|
}
|
||||||
|
if {$try_again != 0 } {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
set exit_result [lindex $result 3]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Reset via Intel AMT wsman protocol
|
||||||
|
#
|
||||||
|
proc amt_reset_wsman { } {
|
||||||
|
set xml_request "amt-reset-wsman.xml"
|
||||||
|
|
||||||
|
set fh [open $xml_request "WRONLY CREAT TRUNC"]
|
||||||
|
|
||||||
|
puts $fh {
|
||||||
|
<!-- poweron - 2, poweroff - 8, reset - 5 -->
|
||||||
|
<p:RequestPowerStateChange_INPUT xmlns:p="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_PowerManagementService">
|
||||||
|
<p:PowerState>5</p:PowerState>
|
||||||
|
<p:ManagedElement xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing"
|
||||||
|
xmlns:wsman="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd">
|
||||||
|
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</wsa:Address>
|
||||||
|
<wsa:ReferenceParameters>
|
||||||
|
<wsman:ResourceURI>http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ComputerSystem</wsman:ResourceURI>
|
||||||
|
<wsman:SelectorSet>
|
||||||
|
<wsman:Selector Name="CreationClassName">CIM_ComputerSystem</wsman:Selector>
|
||||||
|
<wsman:Selector Name="Name">ManagedSystem</wsman:Selector>
|
||||||
|
</wsman:SelectorSet>
|
||||||
|
</wsa:ReferenceParameters>
|
||||||
|
</p:ManagedElement>
|
||||||
|
</p:RequestPowerStateChange_INPUT>
|
||||||
|
}
|
||||||
|
|
||||||
|
close $fh
|
||||||
|
|
||||||
|
exec wsman invoke -a RequestPowerStateChange -J $xml_request \
|
||||||
|
"http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_PowerManagementService?SystemCreationClassName=\"CIM_ComputerSystem\",SystemName=\"Intel(r) AMT\",CreationClassName=\"CIM_PowerManagementService\",Name=\"Intel(r) AMT Power Management Service\"" \
|
||||||
|
--port 16992 -h [power_on_amt_host] --username admin -p [power_on_amt_password] -V -v
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Reset the test machine using Intel's AMT
|
||||||
|
#
|
||||||
|
proc run_power_on { } {
|
||||||
|
if {![is_amt_available [power_on_amt_host] [power_on_amt_password]]} {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# amttool and wsman are supported for reset
|
||||||
|
#
|
||||||
|
set amt_tool [get_cmd_arg --amt-tool "default"]
|
||||||
|
|
||||||
|
#
|
||||||
|
# reset the box
|
||||||
|
#
|
||||||
|
if {[have_installed wsman] &&
|
||||||
|
( $amt_tool == "wsman" || $amt_tool == "default") } {
|
||||||
|
amt_reset_wsman
|
||||||
|
} else {
|
||||||
|
if {[have_installed amttool] &&
|
||||||
|
($amt_tool == "amttool" || $amt_tool == "default") } {
|
||||||
|
amt_reset_soap_eoi
|
||||||
|
} else {
|
||||||
|
puts stderr "specified tool \"$amt_tool\" for using Intel AMT is unknown or is not installed"
|
||||||
|
exit -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep 5
|
||||||
|
return true
|
||||||
|
}
|
37
tool/run/power_on/linux
Normal file
37
tool/run/power_on/linux
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
##
|
||||||
|
# Execute scenario on Linux
|
||||||
|
#
|
||||||
|
proc run_power_on { } {
|
||||||
|
global linux_spawn_id
|
||||||
|
global linux_orig_pwd
|
||||||
|
|
||||||
|
set linux_orig_pwd [pwd]
|
||||||
|
cd [run_dir]/genode
|
||||||
|
eval spawn ./core
|
||||||
|
set linux_spawn_id $spawn_id
|
||||||
|
cd $linux_orig_pwd
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Umount a directory that was bind-mounted beforehand
|
||||||
|
#
|
||||||
|
# This function is used by chroot-related tests, e.g., 'os/run/chroot.run',
|
||||||
|
# 'os/run/chroot_loader.run'.
|
||||||
|
#
|
||||||
|
proc umount_and_rmdir { path } {
|
||||||
|
|
||||||
|
puts "umounting $path"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Invoke umount until it returns an error. Apparently, the unmounting
|
||||||
|
# of bind-mounted mount points does not always take immediate effect
|
||||||
|
# (regardless of the -l option).
|
||||||
|
#
|
||||||
|
while {1} {
|
||||||
|
if {[catch { exec sudo umount -l $path }]} { break; }
|
||||||
|
sleep 0.25
|
||||||
|
}
|
||||||
|
|
||||||
|
catch { exec rmdir -p $path }
|
||||||
|
}
|
54
tool/run/power_on/powerplug
Normal file
54
tool/run/power_on/powerplug
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
##
|
||||||
|
# Reset the target machine via powerplug
|
||||||
|
#
|
||||||
|
# \param --power-on-powerplug-ip IP address of powerplug device
|
||||||
|
# \param --power-on-powerplug-user user for powerplug device
|
||||||
|
# \param --power-on-powerplug-password password for powerplug device
|
||||||
|
# \param --power-on-powerplug-port target port of powerplug device
|
||||||
|
#
|
||||||
|
|
||||||
|
source [genode_dir]/tool/run/powerplug.inc
|
||||||
|
|
||||||
|
|
||||||
|
proc power_on_powerplug_ip { } {
|
||||||
|
return [get_cmd_arg_first --power-on-powerplug-ip 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
proc power_on_powerplug_user { } {
|
||||||
|
return [get_cmd_arg_first --power-on-powerplug-user 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
proc power_on_powerplug_password { } {
|
||||||
|
return [get_cmd_arg_first --power-on-powerplug-password 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
proc power_on_powerplug_port { } {
|
||||||
|
return [get_cmd_arg_first --power-on-powerplug-port 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
proc run_power_on { } {
|
||||||
|
set server_ip [power_on_powerplug_ip]
|
||||||
|
set user_name [power_on_powerplug_user]
|
||||||
|
set password [power_on_powerplug_password]
|
||||||
|
set power_port [power_on_powerplug_port]
|
||||||
|
|
||||||
|
set connection_id [power_plug_connect $server_ip $user_name $password]
|
||||||
|
|
||||||
|
send -i $connection_id "port $power_port\n"
|
||||||
|
expect -i $connection_id -re {250 [0-9]+.*\n}
|
||||||
|
regexp -all {[0-9]+} $expect_out(0,string) power_status
|
||||||
|
if {!$power_status} {
|
||||||
|
puts "port $power_port is off - switching it on"
|
||||||
|
send -i $connection_id "port $power_port 1\n"
|
||||||
|
expect -i $connection_id "250 OK"
|
||||||
|
} else {
|
||||||
|
puts "port $power_port is on - reset port"
|
||||||
|
send -i $connection_id "port $power_port int\n"
|
||||||
|
expect -i $connection_id "250 OK"
|
||||||
|
}
|
||||||
|
}
|
78
tool/run/power_on/qemu
Normal file
78
tool/run/power_on/qemu
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
##
|
||||||
|
# Reset the target machine or rather run the scenario with Qemu
|
||||||
|
#
|
||||||
|
|
||||||
|
source [genode_dir]/tool/run/qemu.inc
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Execute scenario using Qemu
|
||||||
|
#
|
||||||
|
proc run_power_on { } {
|
||||||
|
global qemu_args
|
||||||
|
global qemu
|
||||||
|
global qemu_spawn_id
|
||||||
|
|
||||||
|
#
|
||||||
|
# Back out on platforms w/o Qemu support
|
||||||
|
#
|
||||||
|
if {![is_qemu_available]} { return 0 }
|
||||||
|
|
||||||
|
if {[have_spec x86_32]} { set qemu "qemu-system-i386" }
|
||||||
|
if {[have_spec x86_64]} { set qemu "qemu-system-x86_64" }
|
||||||
|
if {[have_spec arm]} { set qemu "qemu-system-arm" }
|
||||||
|
|
||||||
|
#
|
||||||
|
# Only the x86_64 variant of Qemu provides the emulation of hardware
|
||||||
|
# virtualization features used by NOVA. So let's always stick to this
|
||||||
|
# variant of Qemu when working with NOVA even when operating in 32bit.
|
||||||
|
#
|
||||||
|
if {[have_spec nova]} { set qemu "qemu-system-x86_64" }
|
||||||
|
|
||||||
|
#
|
||||||
|
# Redirect serial output to stdio, but only in graphics mode and no
|
||||||
|
# explicit configuration of serial interfaces is specified in the run
|
||||||
|
# script. The 'mon' prefix enables the access to the qemu console.
|
||||||
|
#
|
||||||
|
if {![regexp -- {-nographic} $qemu_args dummy] &&
|
||||||
|
![regexp -- {-serial} $qemu_args dummy]} {
|
||||||
|
append qemu_args " -serial mon:stdio " }
|
||||||
|
|
||||||
|
# tweak emulated platform for specific platforms
|
||||||
|
if {[have_spec platform_pbxa9]} {
|
||||||
|
#
|
||||||
|
# For PBXA9 qemu adjusts provided RAM chips to the -m arg. Thus we
|
||||||
|
# filter user values and force value that enables all chips that Genode
|
||||||
|
# expects to be available. Not doing so leads to inexplicable errors.
|
||||||
|
#
|
||||||
|
regsub -all {\-m ([0-9])+} $qemu_args "" qemu_args
|
||||||
|
append qemu_args " -m 768"
|
||||||
|
append qemu_args " -M realview-pbx-a9"
|
||||||
|
}
|
||||||
|
if {[have_spec platform_vpb926]} { append qemu_args " -M versatilepb -m 128 " }
|
||||||
|
if {[have_spec platform_vea9x4]} { append qemu_args " -M vexpress-a9 -cpu cortex-a9 -m 256 " }
|
||||||
|
|
||||||
|
# on x86, we support booting via pxe or iso/disk image
|
||||||
|
if {[have_spec x86]} {
|
||||||
|
if {[have_include "load/tftp"]} {
|
||||||
|
append qemu_args " -boot n -tftp [run_dir] -bootp boot/pulsar -no-reboot -no-shutdown "
|
||||||
|
} else {
|
||||||
|
if {[have_include "image/iso"]} {
|
||||||
|
append qemu_args " -cdrom [run_dir].iso "
|
||||||
|
} else {
|
||||||
|
if {[have_include "image/disk"]} {
|
||||||
|
append qemu_args " -hda [run_dir].img "
|
||||||
|
} else {
|
||||||
|
puts "Aborting, cannot execute Qemu without a ISO or disk image"
|
||||||
|
exit -4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# on ARM, we supply the boot image as kernel
|
||||||
|
if {[have_spec arm]} { append qemu_args " -kernel [run_dir]/image.elf " }
|
||||||
|
|
||||||
|
eval spawn $qemu $qemu_args
|
||||||
|
set qemu_spawn_id $spawn_id
|
||||||
|
}
|
9
tool/run/powerplug.inc
Normal file
9
tool/run/powerplug.inc
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
proc power_plug_connect { server_ip user_name password } {
|
||||||
|
spawn telnet $server_ip 1234
|
||||||
|
set connection_id $spawn_id
|
||||||
|
expect -i $connection_id "KSHELL V1.*"
|
||||||
|
send -i $connection_id "login $user_name $password\n"
|
||||||
|
expect -i $connection_id "250 OK"
|
||||||
|
|
||||||
|
return $connection_id
|
||||||
|
}
|
33
tool/run/qemu.inc
Normal file
33
tool/run/qemu.inc
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
set qemu_spawn_id ""
|
||||||
|
set qemu_args [get_cmd_arg --qemu-args ""]
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Enable run scripts to extend 'qemu_arg' via 'append' without bothering
|
||||||
|
# about the required whitespace in front of the custom arguments.
|
||||||
|
#
|
||||||
|
append qemu_args " "
|
||||||
|
|
||||||
|
|
||||||
|
proc qemu_args { } {
|
||||||
|
global qemu_args
|
||||||
|
return $qemu_args
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Check whether Qemu support is available
|
||||||
|
#
|
||||||
|
# XXX should by removed in favor of [have_include "exec/qemu"]
|
||||||
|
#
|
||||||
|
proc is_qemu_available { } {
|
||||||
|
if {[have_spec linux]} { return false }
|
||||||
|
|
||||||
|
if {[have_spec platform_panda]
|
||||||
|
|| [have_spec platform_arndale]
|
||||||
|
|| [have_spec platform_rpi]} {
|
||||||
|
puts stderr "skipping execution because platform is not supported by qemu"
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
663
tool/run/run
Executable file
663
tool/run/run
Executable file
@ -0,0 +1,663 @@
|
|||||||
|
#!/usr/bin/expect
|
||||||
|
|
||||||
|
#
|
||||||
|
# \brief Framework for running automated tests
|
||||||
|
# \author Norman Feske
|
||||||
|
# \date 2010-03-16
|
||||||
|
#
|
||||||
|
# Usage: run --name <run_name> --include <run_script> ...
|
||||||
|
#
|
||||||
|
# The '--name' argument is used for as name for the boot-image and
|
||||||
|
# temporary directories. The files includes via the '--include'
|
||||||
|
# argument provide platform-specific additions/refinements to the
|
||||||
|
# test framework as well as the actual test steps.
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Remove leading and trailing whitespace from string
|
||||||
|
#
|
||||||
|
proc strip_whitespace {string} {
|
||||||
|
regsub -all {^\s+} $string "" string
|
||||||
|
regsub -all {\s+$} $string "" string
|
||||||
|
return $string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Check if the specified spec requirement is satisfied
|
||||||
|
#
|
||||||
|
proc assert_spec {spec} {
|
||||||
|
global specs
|
||||||
|
if {[lsearch $specs $spec] == -1} {
|
||||||
|
puts stderr "Test requires '$spec'"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Build genode targets specified as space-separated strings
|
||||||
|
#
|
||||||
|
# If the build process fails, this procedure will exit the program with
|
||||||
|
# the error code -4.
|
||||||
|
#
|
||||||
|
proc build {targets} {
|
||||||
|
|
||||||
|
if {[get_cmd_switch --skip-build]} return
|
||||||
|
|
||||||
|
if {[info exists run_boot_dir_hook]} {
|
||||||
|
run_boot_dir_hook
|
||||||
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Create a fresh boot directory
|
||||||
|
#
|
||||||
|
proc create_boot_directory { } {
|
||||||
|
exec rm -rf [run_dir]
|
||||||
|
exec mkdir -p [run_dir]
|
||||||
|
exec mkdir -p [run_dir]/genode
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Append string to variable only if 'condition' is satisfied
|
||||||
|
#
|
||||||
|
proc append_if {condition var string} {
|
||||||
|
upvar $var up_var
|
||||||
|
if {$condition} { append up_var $string }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Append element to list only if 'condition' is satisfied
|
||||||
|
#
|
||||||
|
proc lappend_if {condition var string} {
|
||||||
|
upvar $var up_var
|
||||||
|
if {$condition} { lappend up_var $string }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Check syntax of specified XML file using xmllint
|
||||||
|
#
|
||||||
|
proc check_xml_syntax {xml_file} {
|
||||||
|
|
||||||
|
if {![have_installed xmllint]} {
|
||||||
|
puts "Warning: Cannot validate config syntax (please install xmllint)"
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if {[catch {exec xmllint --noout $xml_file} result]} {
|
||||||
|
puts stderr $result
|
||||||
|
puts stderr "Error: Invalid XML syntax in $xml_file"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Install content of specfied variable as init config file
|
||||||
|
#
|
||||||
|
proc install_config {config} {
|
||||||
|
set fh [open "[run_dir]/genode/config" "WRONLY CREAT TRUNC"]
|
||||||
|
puts $fh $config
|
||||||
|
close $fh
|
||||||
|
|
||||||
|
check_xml_syntax [run_dir]/genode/config
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Integrate specified binaries into boot image
|
||||||
|
#
|
||||||
|
# \param binaries space-separated list of file names located within the
|
||||||
|
# '<build-dir>/bin/' directory
|
||||||
|
#
|
||||||
|
proc build_boot_image {binaries} {
|
||||||
|
run_boot_dir $binaries
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Execute Genode
|
||||||
|
#
|
||||||
|
# \param wait_for_re regular expression that matches the test completion
|
||||||
|
# \param timeout_value timeout in seconds
|
||||||
|
# \param spawn_id spawn_id of a already running and spawned process
|
||||||
|
# spawn_id may be a list of spawned processes if needed
|
||||||
|
# \global output contains the core output (modified)
|
||||||
|
#
|
||||||
|
# If the function is called without any argument, Genode is executed in
|
||||||
|
# interactive mode.
|
||||||
|
#
|
||||||
|
# If the test execution times out, this procedure will exit the program with
|
||||||
|
# the error code -2.
|
||||||
|
#
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
set retry 3
|
||||||
|
while { $retry != 0 } {
|
||||||
|
|
||||||
|
run_power_on
|
||||||
|
|
||||||
|
if {![run_load]} {
|
||||||
|
puts "Load step failed, retry."
|
||||||
|
|
||||||
|
# kill the spawned load process if there is one
|
||||||
|
if {[load_spawn_id] != -1} {
|
||||||
|
set pid [exp_pid -i [load_spawn_id]]
|
||||||
|
exec kill -9 $pid
|
||||||
|
}
|
||||||
|
|
||||||
|
incr retry -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if {![run_log $wait_for_re $timeout_value]} {
|
||||||
|
puts "Log step failed, retry."
|
||||||
|
incr retry -1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
puts stderr "Boot process failed 3 times in series. I give up!";
|
||||||
|
exit -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Remove color information from output
|
||||||
|
#
|
||||||
|
proc filter_out_color_escape_sequences { } {
|
||||||
|
global output
|
||||||
|
regsub -all {\e\[.*?m} $output "" output
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Remove superfluous empty lines and unify line endings from output
|
||||||
|
#
|
||||||
|
proc trim_lines { } {
|
||||||
|
global output
|
||||||
|
regsub -all {[\r\n]+} $output "\n" output
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Filter output based on the specified pattern
|
||||||
|
#
|
||||||
|
# Only those lines that match the pattern are preserved.
|
||||||
|
#
|
||||||
|
proc grep_output {pattern} {
|
||||||
|
global output
|
||||||
|
|
||||||
|
filter_out_color_escape_sequences
|
||||||
|
|
||||||
|
trim_lines
|
||||||
|
|
||||||
|
set output_list [split $output "\n"]
|
||||||
|
set filtered ""
|
||||||
|
foreach line $output_list {
|
||||||
|
if {[regexp $pattern $line]} {
|
||||||
|
append filtered "$line\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set output $filtered
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Unify known variations that appear in the test output
|
||||||
|
#
|
||||||
|
# \global output test output (modified)
|
||||||
|
#
|
||||||
|
proc unify_output {pattern replacement} {
|
||||||
|
global output
|
||||||
|
regsub -all $pattern $output $replacement output
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Compare output against expected output line by line
|
||||||
|
#
|
||||||
|
# \param good expected test output
|
||||||
|
# \global output test output
|
||||||
|
#
|
||||||
|
# This procedure will exit the program with the error code -1 if the
|
||||||
|
# comparison fails.
|
||||||
|
#
|
||||||
|
proc compare_output_to { good } {
|
||||||
|
global output
|
||||||
|
set output_list [split [strip_whitespace $output] "\n"]
|
||||||
|
set good_list [split [strip_whitespace $good] "\n"]
|
||||||
|
|
||||||
|
set i 0
|
||||||
|
set mismatch_cnt 0
|
||||||
|
foreach good_line $good_list {
|
||||||
|
set output_line [strip_whitespace [lindex $output_list $i]]
|
||||||
|
set good_line [strip_whitespace $good_line]
|
||||||
|
|
||||||
|
if {$output_line != $good_line} {
|
||||||
|
puts ""
|
||||||
|
puts stderr "Line $i of output is unexpected"
|
||||||
|
puts stderr " expected: '$good_line'"
|
||||||
|
puts stderr " got: '$output_line'"
|
||||||
|
incr mismatch_cnt
|
||||||
|
}
|
||||||
|
incr i
|
||||||
|
}
|
||||||
|
|
||||||
|
#
|
||||||
|
# if $good is empty the foreach-loop isn't entered
|
||||||
|
# so we've to check for it separately
|
||||||
|
#
|
||||||
|
if {![llength $good_list] && [llength $output_list]} {
|
||||||
|
foreach output_line $output_list {
|
||||||
|
set output_line [strip_whitespace $output_line]
|
||||||
|
puts ""
|
||||||
|
puts stderr "Line $i of output is unexpected"
|
||||||
|
puts stderr " got: '$output_line'"
|
||||||
|
incr mismatch_cnt
|
||||||
|
incr i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if {$mismatch_cnt > 0} {
|
||||||
|
puts "Error: Test failed, $mismatch_cnt unexpected lines of output"
|
||||||
|
exit -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Return true if command-line switch was specified
|
||||||
|
#
|
||||||
|
proc get_cmd_switch { arg_name } {
|
||||||
|
global argv
|
||||||
|
return [expr [lsearch $argv $arg_name] >= 0]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Return command-line argument value
|
||||||
|
#
|
||||||
|
# If a argument name is specified multiple times, a
|
||||||
|
# list of argument values is returned.
|
||||||
|
#
|
||||||
|
proc get_cmd_arg { arg_name default_value } {
|
||||||
|
global argv
|
||||||
|
|
||||||
|
# find argument name in argv list
|
||||||
|
set arg_idx_list [lsearch -all $argv $arg_name]
|
||||||
|
|
||||||
|
if {[llength $arg_idx_list] == 0} { return $default_value }
|
||||||
|
|
||||||
|
set result {}
|
||||||
|
foreach arg_idx $arg_idx_list {
|
||||||
|
set next_idx [expr $arg_idx + 1]
|
||||||
|
|
||||||
|
# stop if argv ends with the argument name
|
||||||
|
if {$next_idx >= [llength $argv]} continue
|
||||||
|
|
||||||
|
# return list element following the argument name
|
||||||
|
lappend result [lindex $argv $next_idx]
|
||||||
|
}
|
||||||
|
|
||||||
|
# if argument occurred only once, return its value
|
||||||
|
if {[llength $result] == 1} { return [lindex $result 0] }
|
||||||
|
|
||||||
|
# if argument occurred multiple times, contain list of arguments
|
||||||
|
return $result
|
||||||
|
}
|
||||||
|
|
||||||
|
##
|
||||||
|
# Return command-line argument value
|
||||||
|
#
|
||||||
|
# If a argument name is specified multiple times, return only the
|
||||||
|
# first match.
|
||||||
|
#
|
||||||
|
proc get_cmd_arg_first { arg_name default_value } {
|
||||||
|
global argv
|
||||||
|
|
||||||
|
set arg_idx [lsearch $argv $arg_name]
|
||||||
|
|
||||||
|
if {$arg_idx == -1} { return $default_value }
|
||||||
|
|
||||||
|
return [lindex $argv [expr $arg_idx + 1]]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Read command-line arguments
|
||||||
|
#
|
||||||
|
|
||||||
|
set run_name [get_cmd_arg --name "noname"]
|
||||||
|
set genode_dir [get_cmd_arg --genode-dir ""]
|
||||||
|
set cross_dev_prefix [get_cmd_arg --cross-dev-prefix ""]
|
||||||
|
set specs [get_cmd_arg --specs ""]
|
||||||
|
set repositories [get_cmd_arg --repositories ""]
|
||||||
|
|
||||||
|
|
||||||
|
# accessor functions for command-line arguments
|
||||||
|
proc run_name { } { global run_name; return $run_name }
|
||||||
|
proc run_dir { } { global run_name; return var/run/$run_name }
|
||||||
|
proc genode_dir { } { global genode_dir; return $genode_dir }
|
||||||
|
proc cross_dev_prefix { } { global cross_dev_prefix; return $cross_dev_prefix }
|
||||||
|
|
||||||
|
# set expect match-buffer size
|
||||||
|
match_max -d 20000
|
||||||
|
|
||||||
|
##
|
||||||
|
# Return true if spec value is set for the build
|
||||||
|
#
|
||||||
|
proc have_spec {spec} { global specs; return [expr [lsearch $specs $spec] != -1] }
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Return true if specified program is installed
|
||||||
|
#
|
||||||
|
proc have_installed {program} {
|
||||||
|
if {[catch { exec which $program }]} { return false; }
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Return true if specified program is installed on the host platform
|
||||||
|
#
|
||||||
|
proc requires_installation_of {program} {
|
||||||
|
if {![have_installed $program]} {
|
||||||
|
puts "Run script aborted because $program is not installed"; exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Return first repository containing the given path
|
||||||
|
#
|
||||||
|
proc repository_contains {path} {
|
||||||
|
global repositories;
|
||||||
|
foreach i $repositories {
|
||||||
|
if {[file exists $i/$path]} { return $i }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## Utilities for performing steps that are the same on several platforms
|
||||||
|
##
|
||||||
|
|
||||||
|
##
|
||||||
|
# Read kernel location from build-directory configuration
|
||||||
|
#
|
||||||
|
# If config file does not exist or if there is no 'KERNEL' declaration in the
|
||||||
|
# config file, the function returns 'default_location'. If the config file
|
||||||
|
# points to a non-existing kernel image, the function aborts with the exit
|
||||||
|
# value -6.
|
||||||
|
#
|
||||||
|
proc kernel_location_from_config_file { config_file default_location } {
|
||||||
|
global _kernel
|
||||||
|
|
||||||
|
if {![info exists _kernel]} {
|
||||||
|
if {[file exists $config_file]} {
|
||||||
|
set _kernel [exec sed -n "/^KERNEL/s/^.*=\\s*//p" $config_file]
|
||||||
|
|
||||||
|
# check if the regular expression matched
|
||||||
|
if {$_kernel != ""} {
|
||||||
|
if {[file exists $_kernel]} {
|
||||||
|
return $_kernel
|
||||||
|
} else {
|
||||||
|
puts stderr "Error: kernel specified in '$config_file' does not exist"
|
||||||
|
exit -6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# try to fall back to version hosted with the Genode build directory
|
||||||
|
set _kernel $default_location
|
||||||
|
}
|
||||||
|
return $_kernel
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Copy the specified binaries from the 'bin/' directory to the run
|
||||||
|
# directory and try to strip executables.
|
||||||
|
#
|
||||||
|
proc copy_and_strip_genode_binaries_to_run_dir { binaries } {
|
||||||
|
|
||||||
|
foreach binary $binaries {
|
||||||
|
exec cp bin/$binary [run_dir]/genode
|
||||||
|
catch {
|
||||||
|
exec [cross_dev_prefix]strip [run_dir]/genode/$binary || true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Wait for a specific output of a already running spawned process
|
||||||
|
#
|
||||||
|
proc wait_for_output { wait_for_re timeout_value running_spawn_id } {
|
||||||
|
global output
|
||||||
|
|
||||||
|
if {$wait_for_re == "forever"} {
|
||||||
|
set timeout -1
|
||||||
|
interact {
|
||||||
|
\003 {
|
||||||
|
send_user "Expect: 'interact' received 'strg+c' and was cancelled\n";
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
-i $running_spawn_id
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
set timeout $timeout_value
|
||||||
|
}
|
||||||
|
|
||||||
|
expect {
|
||||||
|
-i $running_spawn_id -re $wait_for_re { }
|
||||||
|
eof { puts stderr "Error: Spawned process died unexpectedly"; exit -3 }
|
||||||
|
timeout { puts stderr "Error: Test execution timed out"; exit -2 }
|
||||||
|
}
|
||||||
|
set output $expect_out(buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## Fall-back implementations of all run module procedures
|
||||||
|
##
|
||||||
|
|
||||||
|
##
|
||||||
|
# Dummy boot_dir maodule
|
||||||
|
proc run_boot_dir { } { return true; }
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Dummy image build module
|
||||||
|
#
|
||||||
|
proc run_image { {image "" } } { return true; }
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Dummy load module
|
||||||
|
#
|
||||||
|
proc run_load { } { return true; }
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Dummy output module
|
||||||
|
#
|
||||||
|
# XXX explain why exit 0 is appropiate
|
||||||
|
#
|
||||||
|
proc run_log { wait_for_re timeout_value } { exit 0 }
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Dummy power_on module
|
||||||
|
#
|
||||||
|
proc run_power_on { } { return true; }
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Dummy power_off module
|
||||||
|
#
|
||||||
|
proc run_power_off { } { return true; }
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Check if a specific file is included
|
||||||
|
#
|
||||||
|
proc have_include { name } {
|
||||||
|
global include_list
|
||||||
|
foreach element $include_list {
|
||||||
|
if {[string equal $element $name]} {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Override the exit procedure
|
||||||
|
#
|
||||||
|
# We have to override the exit procedure to make sure that a loaded
|
||||||
|
# run_power_off procedure is in any case execute when stopping the
|
||||||
|
# execution of the run tool.
|
||||||
|
#
|
||||||
|
rename exit real_exit
|
||||||
|
proc exit {{status 0}} {
|
||||||
|
run_power_off
|
||||||
|
|
||||||
|
real_exit $status
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Determine terminal program
|
||||||
|
#
|
||||||
|
proc terminal { } {
|
||||||
|
global env
|
||||||
|
if {[info exists env(COLORTERM)]} {
|
||||||
|
return $env(COLORTERM)
|
||||||
|
}
|
||||||
|
return $env(TERM)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Determine GDB executable installed at the host
|
||||||
|
#
|
||||||
|
proc gdb { } {
|
||||||
|
if {[have_installed "[cross_dev_prefix]gdb"]} {
|
||||||
|
return "[cross_dev_prefix]gdb" }
|
||||||
|
|
||||||
|
if {[have_installed gdb]} {
|
||||||
|
return "gdb" }
|
||||||
|
|
||||||
|
requires_installation_of gdb
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Check if a shell command is installed
|
||||||
|
#
|
||||||
|
# \param command name of the command to search
|
||||||
|
#
|
||||||
|
# \return absolute path of command if found, or exists if not
|
||||||
|
#
|
||||||
|
proc check_installed {command} {
|
||||||
|
if { [catch {set path [exec which $command]}] == 0} {
|
||||||
|
return $path
|
||||||
|
}
|
||||||
|
|
||||||
|
set dir { /sbin /usr/sbin /usr/local/bin }
|
||||||
|
|
||||||
|
foreach location $dir {
|
||||||
|
append location / $command
|
||||||
|
|
||||||
|
if { [file exists $location] == 1} {
|
||||||
|
return $location
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
puts stderr "Error: '$command' command could be not found. Please make sure to install the"
|
||||||
|
puts stderr " packet containing '$command', or make it available in your PATH variable.\n"
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
## Execution of run scripts
|
||||||
|
##
|
||||||
|
|
||||||
|
|
||||||
|
set include_list { }
|
||||||
|
|
||||||
|
|
||||||
|
##
|
||||||
|
# Read and execute files specified as '--include' arguments
|
||||||
|
#
|
||||||
|
# Out of convenience run modules may be included by using a relative path.
|
||||||
|
#
|
||||||
|
foreach include_name [get_cmd_arg --include ""] {
|
||||||
|
# first check if the include name is absolute
|
||||||
|
if {[string first "/" $include_name] == 0} {
|
||||||
|
puts "including $include_name"
|
||||||
|
lappend include_list $include_name
|
||||||
|
source $include_name
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
# if it is relative, check run modules
|
||||||
|
set run_path [genode_dir]/tool/run
|
||||||
|
set dir { etc }
|
||||||
|
lappend dir $run_path
|
||||||
|
|
||||||
|
set found 0
|
||||||
|
foreach location $dir {
|
||||||
|
set include_file $location/$include_name
|
||||||
|
if {[file exists $include_file] == 1} {
|
||||||
|
puts "including $include_file"
|
||||||
|
lappend include_list $include_name
|
||||||
|
source $include_file
|
||||||
|
|
||||||
|
set found 1
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if {!$found} {
|
||||||
|
puts stderr "Aborting, could not load '$include_file'"
|
||||||
|
exit -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
puts "\nRun script execution successful."
|
||||||
|
exit 0
|
Loading…
Reference in New Issue
Block a user