Add NOVA tests
parent
484d036057
commit
9096313d6c
@ -0,0 +1,191 @@
|
||||
# SPDX-FileCopyrightText: Emery Hemingway
|
||||
#
|
||||
# SPDX-License-Identifier: LicenseRef-Hippocratic-1.1
|
||||
|
||||
{ testPkgs, hostPkgs, lib }:
|
||||
|
||||
let
|
||||
testDriver = with hostPkgs;
|
||||
stdenv.mkDerivation {
|
||||
name = "nova-genode-test-driver";
|
||||
|
||||
buildInputs = [ makeWrapper expect ];
|
||||
|
||||
dontUnpack = true;
|
||||
|
||||
preferLocalBuild = true;
|
||||
|
||||
installPhase = ''
|
||||
install -Dm555 ${./nova-test-driver.exp} $out/bin/genode-test-driver
|
||||
wrapProgram $out/bin/genode-test-driver \
|
||||
--prefix PATH : "${lib.makeBinPath [ expect coreutils ]}"
|
||||
'';
|
||||
};
|
||||
|
||||
runTests = driver:
|
||||
hostPkgs.stdenv.mkDerivation {
|
||||
name = "test-run-${driver.testName}";
|
||||
|
||||
buildCommand = ''
|
||||
mkdir -p $out/nix-support
|
||||
|
||||
${driver}/bin/genode-test-driver | tee $out/log
|
||||
|
||||
touch $out/nix-support
|
||||
echo "report testlog $out log" >> $out/nix-support/hydra-build-products
|
||||
'';
|
||||
};
|
||||
|
||||
makeTest = { testScript, testConfig, name ? "unamed", ... }@t:
|
||||
let
|
||||
|
||||
baseSetup = with testPkgs;
|
||||
|
||||
''
|
||||
global modules
|
||||
set HOSTLD ${buildPackages.binutils}/bin/x86_64-unknown-genode-elf-ld
|
||||
|
||||
file link -s timer ${genode.base-nova}/bin/nova_timer_drv
|
||||
file link -s ld.lib.so ${depot.base-nova}/lib/ld.lib.so
|
||||
file link -s core-nova.o ${depot.base-nova}/lib/core-nova.o
|
||||
file link -s init ${genode.os}/bin/init
|
||||
file link -s config ${./driver-config.xml}
|
||||
file link -s test.config $env(testConfig)
|
||||
|
||||
set modules {
|
||||
timer
|
||||
ld.lib.so
|
||||
init
|
||||
config
|
||||
test.config
|
||||
}
|
||||
|
||||
set qemu_mem 64
|
||||
|
||||
##
|
||||
# Link core image containing given modules
|
||||
#
|
||||
proc build_core {lib modules target} {
|
||||
global env
|
||||
|
||||
# generate assembly code aggregating the modules data
|
||||
set asm_src [generate_boot_modules_asm $modules]
|
||||
|
||||
# compile the boot modules into one object file
|
||||
exec $env(CC) -c -x assembler -o boot_modules.o - << $asm_src
|
||||
|
||||
# link final image
|
||||
global HOSTLD
|
||||
exec $HOSTLD -nostdlib \
|
||||
-T${./genode.ld} \
|
||||
-T${./nova-bss.ld} \
|
||||
-z max-page-size=0x1000 \
|
||||
-Ttext=0x100000 -gc-sections \
|
||||
--whole-archive \
|
||||
$lib boot_modules.o --no-whole-archive \
|
||||
-o $target
|
||||
}
|
||||
|
||||
proc build_iso {target} {
|
||||
# TODO: take our own build of NOVA
|
||||
file mkdir boot/syslinux
|
||||
file copy ${nova}/hypervisor-x86_64 boot/hypervisor
|
||||
file copy ${./nova-isolinux.cfg} boot/syslinux/isolinux.cfg
|
||||
file copy ${hostPkgs.syslinux}/share/syslinux/isolinux.bin boot/syslinux/isolinux.bin
|
||||
file copy ${hostPkgs.syslinux}/share/syslinux/ldlinux.c32 boot/syslinux/ldlinux.c32
|
||||
file copy ${hostPkgs.syslinux}/share/syslinux/libcom32.c32 boot/syslinux/libcom32.c32
|
||||
file copy ${hostPkgs.syslinux}/share/syslinux/mboot.c32 boot/syslinux/mboot.c32
|
||||
|
||||
exec chmod +w boot/syslinux/isolinux.bin
|
||||
catch { exec ${hostPkgs.cdrkit}/bin/mkisofs -o $target \
|
||||
-b syslinux/isolinux.bin -c syslinux/boot.cat \
|
||||
-no-emul-boot -boot-load-size 4 -boot-info-table \
|
||||
-iso-level 2 \
|
||||
boot
|
||||
}
|
||||
puts "built ISO?"
|
||||
}
|
||||
|
||||
##
|
||||
# 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 -1 }
|
||||
timeout { puts stderr "Error: Test execution timed out"; exit -1 }
|
||||
}
|
||||
set output $expect_out(buffer)
|
||||
}
|
||||
|
||||
|
||||
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 env modules qemu_mem
|
||||
file mkdir boot
|
||||
build_core core-nova.o $modules boot/image.elf
|
||||
|
||||
set out $env(out)
|
||||
build_iso $out/test.iso
|
||||
|
||||
global spawn_id
|
||||
spawn ${hostPkgs.qemu_test}/bin/qemu-system-x86_64 -cdrom $out/test.iso -nographic -m $qemu_mem
|
||||
wait_for_output $wait_for_re $timeout_value $spawn_id
|
||||
}
|
||||
'';
|
||||
|
||||
driver = with hostPkgs;
|
||||
buildPackages.runCommand "genode-test-driver-${name}" {
|
||||
buildInputs = [ makeWrapper expect ];
|
||||
inherit baseSetup testConfig testScript;
|
||||
preferLocalBuild = true;
|
||||
testName = name;
|
||||
} ''
|
||||
mkdir -p $out/bin
|
||||
echo "$testConfig" > $out/test.config
|
||||
echo "$testScript" > $out/test-script
|
||||
echo "$baseSetup" > $out/base-setup
|
||||
ln -s ${testDriver}/bin/genode-test-driver $out/bin/
|
||||
wrapProgram $out/bin/genode-test-driver \
|
||||
--run "export testConfig=\"$testConfig\"" \
|
||||
--run "export testScript=\"\$(cat $out/test-script)\"" \
|
||||
--run "export baseSetup=\"\$(cat $out/base-setup)\"" \
|
||||
'';
|
||||
|
||||
passMeta = drv:
|
||||
drv
|
||||
// lib.optionalAttrs (t ? meta) { meta = (drv.meta or { }) // t.meta; };
|
||||
|
||||
test = passMeta (runTests driver);
|
||||
|
||||
in test // { inherit driver test; };
|
||||
|
||||
in {
|
||||
callTest = path: args:
|
||||
makeTest (import path ({
|
||||
pkgs = testPkgs;
|
||||
inherit lib;
|
||||
} // args));
|
||||
}
|
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* \brief Linker script for Genode programs
|
||||
* \author Christian Helmuth
|
||||
* \date 2006-04-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
ro PT_LOAD;
|
||||
rw PT_LOAD;
|
||||
boot PT_LOAD FLAGS(4);
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
/* begin of program image (link address) */
|
||||
_prog_img_beg = .;
|
||||
|
||||
/* put entry code at the start of the text segment / raw binary */
|
||||
KEEP (*(.text.crt0))
|
||||
|
||||
*(.init)
|
||||
*(.text .text.* .gnu.linkonce.t.*)
|
||||
*(.fini)
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
|
||||
. = ALIGN(0x08);
|
||||
|
||||
_ctors_start = .;
|
||||
KEEP (*(.ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.init_array)) /* list of constructors specific for ARM eabi */
|
||||
_ctors_end = .;
|
||||
_dtors_start = .;
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
_dtors_end = .;
|
||||
} : ro = 0x0
|
||||
|
||||
/* Linux: exception section for uaccess mechanism */
|
||||
__ex_table : { *(__ex_table) }
|
||||
|
||||
.eh_frame_hdr : { *(.eh_frame_hdr) }
|
||||
__eh_frame_hdr_start = SIZEOF(.eh_frame_hdr) > 0 ? ADDR(.eh_frame_hdr) : 0;
|
||||
__eh_frame_hdr_end = SIZEOF(.eh_frame_hdr) > 0 ? . : 0;
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
|
||||
.data : {
|
||||
/*
|
||||
* Leave space for parent capability parameters at start of data
|
||||
* section. The protection domain creator is reponsible for storing
|
||||
* sane values here.
|
||||
*/
|
||||
_parent_cap = .;
|
||||
_parent_cap_thread_id = .;
|
||||
LONG(0xffffffff);
|
||||
_parent_cap_local_name = .;
|
||||
LONG(0xffffffff);
|
||||
LONG(0xffffffff);
|
||||
LONG(0xffffffff);
|
||||
LONG(0xffffffff);
|
||||
LONG(0xffffffff);
|
||||
LONG(0xffffffff);
|
||||
LONG(0xffffffff);
|
||||
|
||||
/*
|
||||
* Platform-specific entry for Fiasco.OC.
|
||||
*
|
||||
* PIC-code compiled for Fiasco.OC, needs some PIC-compatible
|
||||
* way to enter the kernel, the fixed address of the kernel
|
||||
* entry code address needs to be found here.
|
||||
*/
|
||||
__l4sys_invoke_indirect = .;
|
||||
LONG(0xeacff000);
|
||||
|
||||
*(.data .gnu.linkonce.d.*)
|
||||
|
||||
/* include all data subsections except those of the boot modules */
|
||||
*(EXCLUDE_FILE (*boot_modules.o) .data.*)
|
||||
} : rw
|
||||
|
||||
/* exception frames for C++ */
|
||||
.eh_frame : {
|
||||
__eh_frame_start__ = .;
|
||||
__eh_frame_start = .;
|
||||
KEEP (*(.eh_frame))
|
||||
__eh_frame_end = .;
|
||||
LONG(0)
|
||||
} : rw
|
||||
|
||||
.gcc_except_table : {
|
||||
KEEP(*(.gcc_except_table))
|
||||
KEEP(*(.gcc_except_table.*))
|
||||
}
|
||||
|
||||
.dynamic : { *(.dynamic) }
|
||||
|
||||
/* .ARM.exidx is sorted, so has to go in its own output section */
|
||||
__exidx_start = .;
|
||||
.ARM.exidx : {
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
}
|
||||
__exidx_end = .;
|
||||
|
||||
.ARM.extab : {
|
||||
*(.ARM.extab*)
|
||||
} : rw
|
||||
|
||||
.bss : {
|
||||
_bss_start = ALIGN(4);
|
||||
*(.bss .bss.* .gnu.linkonce.b.* COMMON)
|
||||
}
|
||||
_bss_end = ALIGN(4);
|
||||
|
||||
/* separate location for the binaries of the boot modules */
|
||||
.data.boot_modules_binaries : { *(.data.boot_modules_binaries) } : boot
|
||||
|
||||
/* end of program image -- must be after last section */
|
||||
_prog_img_end = .;
|
||||
|
||||
/DISCARD/ : {
|
||||
*(.note)
|
||||
*(.note.ABI-tag)
|
||||
*(.comment)
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
SECTIONS
|
||||
{
|
||||
.data : {
|
||||
*(.bss .bss.* .gnu.linkonce.b.* COMMON)
|
||||
} : rw
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
SERIAL
|
||||
DEFAULT 0
|
||||
LABEL 0
|
||||
KERNEL mboot.c32
|
||||
APPEND /hypervisor iommu novpid serial --- /image.elf
|
@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env expect
|
||||
|
||||
##
|
||||
# Generate assembly code aggregating boot-module data from specified files.
|
||||
#
|
||||
proc generate_boot_modules_asm {modules} {
|
||||
|
||||
# architecture dependent definitions
|
||||
set address_type ".quad"
|
||||
|
||||
# header
|
||||
set asm_src {}
|
||||
append asm_src ".set MIN_PAGE_SIZE_LOG2, 12\n"
|
||||
append asm_src ".set DATA_ACCESS_ALIGNM_LOG2, 3\n"
|
||||
append asm_src "\n"
|
||||
append asm_src ".section .data\n"
|
||||
append asm_src "\n"
|
||||
append asm_src ".p2align DATA_ACCESS_ALIGNM_LOG2\n"
|
||||
append asm_src ".global _boot_modules_headers_begin\n"
|
||||
append asm_src "_boot_modules_headers_begin:\n"
|
||||
append asm_src "\n"
|
||||
|
||||
# module list
|
||||
set i 0
|
||||
foreach module $modules {
|
||||
incr i
|
||||
append asm_src "${address_type} _boot_module_${i}_name\n"
|
||||
append asm_src "${address_type} _boot_module_${i}_begin\n"
|
||||
append asm_src "${address_type} _boot_module_${i}_end -"
|
||||
append asm_src " _boot_module_${i}_begin\n"
|
||||
append asm_src "\n"
|
||||
}
|
||||
append asm_src ".global _boot_modules_headers_end\n"
|
||||
append asm_src "_boot_modules_headers_end:\n"
|
||||
append asm_src "\n"
|
||||
|
||||
# module names
|
||||
set i 0
|
||||
foreach module $modules {
|
||||
incr i
|
||||
append asm_src ".p2align DATA_ACCESS_ALIGNM_LOG2\n"
|
||||
append asm_src "_boot_module_${i}_name:\n"
|
||||
append asm_src ".string \"${module}\"\n"
|
||||
append asm_src ".byte 0\n"
|
||||
append asm_src "\n"
|
||||
}
|
||||
|
||||
# header end
|
||||
append asm_src ".section .data.boot_modules_binaries\n"
|
||||
append asm_src "\n"
|
||||
append asm_src ".global _boot_modules_binaries_begin\n"
|
||||
append asm_src "_boot_modules_binaries_begin:\n"
|
||||
append asm_src "\n"
|
||||
|
||||
# module data
|
||||
set i 0
|
||||
foreach module $modules {
|
||||
incr i
|
||||
append asm_src ".p2align MIN_PAGE_SIZE_LOG2\n"
|
||||
append asm_src "_boot_module_${i}_begin:\n"
|
||||
append asm_src ".incbin \"${module}\"\n"
|
||||
append asm_src "_boot_module_${i}_end:\n"
|
||||
append asm_src "\n"
|
||||
}
|
||||
|
||||
append asm_src ".p2align MIN_PAGE_SIZE_LOG2\n"
|
||||
append asm_src ".global _boot_modules_binaries_end\n"
|
||||
append asm_src "_boot_modules_binaries_end:\n"
|
||||
|
||||
return $asm_src
|
||||
}
|
||||
|
||||
eval $env(baseSetup)
|
||||
|
||||
eval $env(testScript)
|
Loading…
Reference in New Issue