mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 21:27:56 +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)
|
||||
$(VERBOSE)test -f "$(RUN_SCRIPT)" || (echo "Error: No run script for $*"; exit -1)
|
||||
$(VERBOSE)$(GENODE_DIR)/tool/run --genode-dir $(GENODE_DIR) \
|
||||
--name $* \
|
||||
--specs "$(SPECS)" \
|
||||
--repositories "$(REPOSITORIES)" \
|
||||
--cross-dev-prefix "$(CROSS_DEV_PREFIX)" \
|
||||
--qemu-args "$(QEMU_OPT)" \
|
||||
--include $(RUN_ENV) $(RUN_OPT) \
|
||||
--include $(RUN_SCRIPT)
|
||||
$(VERBOSE)$(GENODE_DIR)/tool/run/run --genode-dir $(GENODE_DIR) \
|
||||
--name $* \
|
||||
--specs "$(SPECS)" \
|
||||
--repositories "$(REPOSITORIES)" \
|
||||
--cross-dev-prefix "$(CROSS_DEV_PREFIX)" \
|
||||
--qemu-args "$(QEMU_OPT)" \
|
||||
$(RUN_OPT) \
|
||||
--include $(RUN_ENV) \
|
||||
--include $(RUN_SCRIPT)
|
||||
|
||||
##
|
||||
## 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 ##
|
||||
##################################
|
||||
|
||||
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} {
|
||||
##
|
||||
# Populate boot directory with binaries on codezero
|
||||
#
|
||||
proc run_boot_dir {binaries} {
|
||||
|
||||
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)
|
||||
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'.
|
||||
#
|
||||
|
||||
##
|
||||
# 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
|
||||
#
|
||||
@ -83,20 +75,6 @@ proc reset_target { {spawn_id_arg -1} } {
|
||||
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} {
|
||||
|
||||
@ -108,10 +86,6 @@ proc copy_and_strip_binaries {binaries} {
|
||||
catch {
|
||||
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 "
|
||||
|
||||
proc build_boot_image_x86 {binaries} {
|
||||
proc run_boot_dir_x86 {binaries} {
|
||||
|
||||
global fiasco_serial_esc_arg
|
||||
|
||||
exec mkdir -p [run_dir]/fiasco
|
||||
|
||||
copy_and_strip_binaries $binaries
|
||||
|
||||
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]/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
|
||||
#
|
||||
# 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 Fiasco.OC"
|
||||
puts $fh " kernel /boot/bender"
|
||||
puts $fh " module /fiasco/bootstrap -modaddr=0x01100000"
|
||||
puts $fh " module /fiasco/fiasco $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_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"
|
||||
#
|
||||
# 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 Fiasco.OC"
|
||||
puts $fh " kernel /boot/bender"
|
||||
puts $fh " module /fiasco/bootstrap -modaddr=0x01100000"
|
||||
puts $fh " module /fiasco/fiasco $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
|
||||
}
|
||||
|
||||
#
|
||||
# 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 fiasco_serial_esc_arg
|
||||
@ -249,53 +223,27 @@ proc build_boot_image_arm {binaries} {
|
||||
}
|
||||
|
||||
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"
|
||||
|
||||
# set symbolic link to image.elf file in TFTP directory for PXE boot
|
||||
if {[info exists ::env(PXE_TFTP_DIR_BASE)] &&
|
||||
[info exists ::env(PXE_TFTP_DIR_OFFSET)]} {
|
||||
exec ln -sf "[pwd]/[run_dir]/image.elf" "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)"
|
||||
if {[regexp "uboot" $run_target]} {
|
||||
exec ln -sf "[pwd]/[run_dir]/uImage" "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)/uImage"
|
||||
if {[have_include "load/tftp"]} {
|
||||
set tftp_base_dir [load_tftp_base_dir]
|
||||
set tftp_offset_dir [load_tftp_offset_dir]
|
||||
|
||||
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] }
|
||||
if {[have_spec arm]} { return [build_boot_image_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
|
||||
##
|
||||
# Populate boot directory with binaries on fiasco.OC
|
||||
#
|
||||
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] }
|
||||
}
|
@ -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
|
||||
#
|
||||
proc clean_boot_modules { } {
|
||||
exec rm -rf boot_modules.s var/libcache/boot_modules/boot_modules.o }
|
||||
|
||||
|
||||
##########################
|
||||
## 'tool/run' interface ##
|
||||
##########################
|
||||
|
||||
proc build {targets} {
|
||||
|
||||
# skip targets that shall not be build
|
||||
if {[get_cmd_switch --skip-build]} return
|
||||
|
||||
# handle false remnants of previous builds
|
||||
proc run_boot_dir_hook { } {
|
||||
clean_boot_modules
|
||||
|
||||
#
|
||||
# Build all remaining targets.
|
||||
# Core is build with a dummy boot-modules file first.
|
||||
#
|
||||
regsub -all {\s\s+} $targets " " targets
|
||||
set timeout 10000
|
||||
set pid [eval "spawn make $targets"]
|
||||
expect { eof { } }
|
||||
if {[lindex [wait $pid] end] != 0} {
|
||||
puts stderr "Error: Genode build failed"
|
||||
exit -1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
proc create_boot_directory { } {
|
||||
|
||||
exec rm -rf [run_dir]
|
||||
exec mkdir -p [run_dir]/genode
|
||||
}
|
||||
|
||||
|
||||
proc build_boot_image {binaries {core_type core}} {
|
||||
##
|
||||
# Populate boot directory with binaries on hw
|
||||
#
|
||||
proc run_boot_dir {binaries {core_type core}} {
|
||||
if {$core_type == "test"} {
|
||||
set core_bin "test-[run_name]"
|
||||
set core_target "test/[run_name]"
|
||||
@ -90,7 +51,7 @@ proc build_boot_image {binaries {core_type core}} {
|
||||
exec echo -e \
|
||||
"/**" \
|
||||
"\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 /* core includes */" \
|
||||
@ -176,15 +137,14 @@ proc build_boot_image {binaries {core_type core}} {
|
||||
exec cp -L bin/$core_bin $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
|
||||
if {[info exists ::env(PXE_TFTP_DIR_BASE)] &&
|
||||
[info exists ::env(PXE_TFTP_DIR_OFFSET)]} {
|
||||
exec ln -sf "[pwd]/$elf_img" "$::env(PXE_TFTP_DIR_BASE)$::env(PXE_TFTP_DIR_OFFSET)"
|
||||
if {[have_include "load/tftp"]} {
|
||||
exec ln -sf [pwd]/$elf_img [load_tftp_base_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)"
|
||||
if {[have_include "image/uboot"]} {
|
||||
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 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
|
||||
#
|
||||
proc base_okl4_dir {} { return [repository_contains mk/spec-okl4.mk] }
|
||||
|
||||
|
||||
##
|
||||
# Read the location of the OKL4 directory from 'etc/okl4.conf'
|
||||
#
|
||||
@ -37,6 +22,7 @@ proc okl4_dir { } {
|
||||
return $_okl4_dir
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Return the location of the OKL4 kernel
|
||||
#
|
||||
@ -45,6 +31,7 @@ proc okl4 { } {
|
||||
return bin/kernel
|
||||
}
|
||||
|
||||
|
||||
##
|
||||
# Return whether okl4 kernel is provided from the outside
|
||||
#
|
||||
@ -53,15 +40,6 @@ proc okl4_external { } {
|
||||
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 {
|
||||
<machine>
|
||||
@ -122,7 +100,11 @@ set weaver_xml_template {
|
||||
<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
|
||||
|
||||
#
|
||||
@ -179,86 +161,50 @@ proc build_boot_image {binaries} {
|
||||
#
|
||||
exec rm -r [run_dir]/genode
|
||||
|
||||
#
|
||||
# Install GRUB
|
||||
#
|
||||
install_iso_bootloader_to_run_dir
|
||||
if {[have_include "image/iso"] || [have_include "image/disk"]} {
|
||||
#
|
||||
# Install GRUB
|
||||
#
|
||||
install_iso_bootloader_to_run_dir
|
||||
|
||||
#
|
||||
# Install PXE bootloader pulsar
|
||||
#
|
||||
install_pxe_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 "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"
|
||||
#
|
||||
# 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 "hiddenmenu"
|
||||
puts $fh "\ntitle Genode on OKL4"
|
||||
puts $fh " kernel /boot/bender"
|
||||
puts $fh " module /image.elf"
|
||||
puts $fh " vbeset 0x117"
|
||||
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
|
||||
|
||||
#
|
||||
# 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"]
|
||||
# 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_tftp_config
|
||||
}
|
||||
}
|
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