From 7f61d9a84a289ca469be7063c278673ea542b583 Mon Sep 17 00:00:00 2001 From: Menno Valkema Date: Mon, 27 Jun 2016 09:43:40 +0200 Subject: [PATCH] Added fesrv port Fixes #18 --- ports/fesrv.hash | 1 + ports/fesrv.port | 11 ++ run/fesrv.run | 57 +++++++++++ src/app/fesrv/README | 79 +++++++++++++++ src/app/fesrv/linux_syscalls.cc | 69 +++++++++++++ src/app/fesrv/main.cc | 141 ++++++++++++++++++++++++++ src/app/fesrv/patches/fesrv.patch | 162 ++++++++++++++++++++++++++++++ src/app/fesrv/target.mk | 30 ++++++ 8 files changed, 550 insertions(+) create mode 100644 ports/fesrv.hash create mode 100644 ports/fesrv.port create mode 100644 run/fesrv.run create mode 100644 src/app/fesrv/README create mode 100644 src/app/fesrv/linux_syscalls.cc create mode 100644 src/app/fesrv/main.cc create mode 100644 src/app/fesrv/patches/fesrv.patch create mode 100644 src/app/fesrv/target.mk diff --git a/ports/fesrv.hash b/ports/fesrv.hash new file mode 100644 index 0000000..0559a13 --- /dev/null +++ b/ports/fesrv.hash @@ -0,0 +1 @@ +f3880fddb60b77e7af5bc03abfef751db0e1faf6 diff --git a/ports/fesrv.port b/ports/fesrv.port new file mode 100644 index 0000000..e03103a --- /dev/null +++ b/ports/fesrv.port @@ -0,0 +1,11 @@ +LICENSE := BSD +VERSION := ceb56f29aacf1ff8a9997e9a57b855936ba00fd6 +DOWNLOADS := riscv-fesrv.git + +URL(riscv-fesrv) := https://github.com/riscv/riscv-fesvr.git +REV(riscv-fesrv) := ceb56f29aacf1ff8a9997e9a57b855936ba00fd6 + +DIR(riscv-fesrv) := src/app/fesrv + +PATCHES := src/app/fesrv/patches/*.patch +PATCH_OPT := -N -p1 -d ${DIR(riscv-fesrv)} diff --git a/run/fesrv.run b/run/fesrv.run new file mode 100644 index 0000000..2230a62 --- /dev/null +++ b/run/fesrv.run @@ -0,0 +1,57 @@ +# +# Build +# + +build { core init app/fesrv } + +create_boot_directory + +# +# Generate config +# + +install_config { + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} + +# +# Boot image +# + +build_boot_image { core init fesrv riscv-image.elf libm.lib.so stdcxx.lib.so libc.lib.so ld.lib.so } + +append qemu_args " -nographic " + +run_genode_until forever diff --git a/src/app/fesrv/README b/src/app/fesrv/README new file mode 100644 index 0000000..a2a8f9f --- /dev/null +++ b/src/app/fesrv/README @@ -0,0 +1,79 @@ +Introduction +############ + +Fesrv is a port of the RISCV frontend server, which transports elf +images to the RISCV core for execution. + +This document describes how to connect to the zedboard and configure +uboot for use with tftp. Assuming a riscv elf image exists, it shows +the steps to load this on the RISCV using through the Genode port of +fesrv runnnig no the zedboard arm core. + +Thus there are 2 cpu's: an ARM and a RISCV. The RISCV should be loaded +through the ARM core. Therefore an Genode image (uImage) for the ARM +core should be created, which then loads a second image to the +RISCV. The image is loaded on the RISCV using our port of the fesrv +port. + +Preparation +########### + +This document assumes you have a Zedboard which boots with a Riscv +image configured at the FPGA. + +Connect the to the uart of the zedboard and open a terminal using picocom: + +! $ sudo picocom -i -f h -b 115200 /dev/ttyACM0 + +This has been tested with the following version of uBoot: + +! U-Boot 2014.07-01982-gf634657-dirty (Sep 29 2014 - 14:52:40) +! arm-xilinx-linux-gnueabi-gcc (Sourcery CodeBench Lite 2013.11-53) 4.8.1 +! GNU ld (Sourcery CodeBench Lite 2013.11-53) 2.23.52.20130912 + + +Uboot environment variables should be set as follows at the uBoot prompt: + +! > env set bootcmd="tftpboot 0x3000000 uImage ;bootm 0x3000000" +! > env save + +And boot with the command below (or reset the zedboard). + +! > boot + +The directory where the resulting ARM uImage that should be copied +should be exposed via TFTP. This could be the +build/hw_zedboard/var/run/hello + +With atftp this could be done as follows: + +! $ sudo atftpd --mcast-switch-client -v --no-fork --daemon --logfile - build/hw_zedboard/var/run/hello/ + +Usage +##### + +Create a riscv compatible elf image, with the code that should run on +the RISCV core. Let's call this image riscv-image.elf. This image +should be kept on disc and is included later on in the +buildprocess. + +Now handle the build of the Arm zedboard image: + +! $ git clone +! $ cd +! $ cd repos +! $ git clone git@turing:fesrv.git +! $ cd .. +! $ ./tool/create_builddir hw_zedboard +! $ cd build/hw_zedboard +! $ echo 'REPOSITORIES += $(GENODE_DIR)/repos/fesrv' >> etc/build.conf +! $ echo 'RUN_OPT += --include image/uboot' >> etc/build.conf +! $ cd ../.. +! $ for port in fesrv stdcxx libc; do ./tool/ports/prepare_port $port; done +! $ cd build/hw_zedboard +! $ cp bin/ +! $ make run/fesrv + +Optionally you can modify repos/fesrv/run/fesrv.run according to +needs, or use bits and pieces fo the fesrv.run within the project at +hand. diff --git a/src/app/fesrv/linux_syscalls.cc b/src/app/fesrv/linux_syscalls.cc new file mode 100644 index 0000000..6e0d86c --- /dev/null +++ b/src/app/fesrv/linux_syscalls.cc @@ -0,0 +1,69 @@ +/// +/// \file linux_syscalls.cc +/// \author Menno Valkema +/// \date 2016-05-17 +/// +/// \brief Dummy implementation of nonexistend linux system calls +/// + +/// +/// Copyright (c) 2016, Cyber Security Labs B.V. +/// All rights reserved. +/// +/// Redistribution and use in source and binary forms, with or without +/// modification, are permitted provided that the following conditions are met: +/// 1. Redistributions of source code must retain the above copyright +/// notice, this list of conditions and the following disclaimer. +/// 2. Redistributions in binary form must reproduce the above copyright +/// notice, this list of conditions and the following disclaimer in the +/// documentation and/or other materials provided with the distribution. +/// 3. All advertising materials mentioning features or use of this software +/// must display the following acknowledgement: +/// This product includes software developed by the Cyber Security Labs B.V.. +/// 4. Neither the name of Cyber Security Labs B.V. nor the +/// names of its contributors may be used to endorse or promote products +/// derived from this software without specific prior written permission. +/// +/// THIS SOFTWARE IS PROVIDED BY CYBER SECURITY LABS B.V. ''AS IS'' AND ANY +/// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +/// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +/// DISCLAIMED. IN NO EVENT SHALL CYBER SECURITY LABS B.V. BE LIABLE FOR ANY +/// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +/// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +/// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +/// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +/// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/// + +#include +#include +#include + +int openat( int dirfd, const char *pathname, int flags , ... ) +{ + return open( pathname, flags ); +} + + +int faccessat( int dirfd, const char *pathname, int mode, int flags ) +{ + return access( pathname, mode ); +} + + +int linkat( int olddirfd, const char *oldpath, + int newdirfd, const char *newpath, int flags ) +{ + return link( oldpath, newpath ); +} + +int unlinkat( int dirfd, const char *pathname, int flags ) +{ + return unlink( pathname ); +} + +int mkdirat( int dirfd, const char *pathname, mode_t mode ) +{ + return mkdir( pathname, mode ); +} diff --git a/src/app/fesrv/main.cc b/src/app/fesrv/main.cc new file mode 100644 index 0000000..fc27f90 --- /dev/null +++ b/src/app/fesrv/main.cc @@ -0,0 +1,141 @@ +/// +/// \file main.cc +/// \author Menno Valkema +/// \date 2016-05-17 +/// +/// \brief Genode fesrv component. Port of https://github.com/riscv/riscv-fesvr +/// + +/// +/// Copyright (c) 2016, Cyber Security Labs B.V. +/// All rights reserved. +/// +/// Redistribution and use in source and binary forms, with or without +/// modification, are permitted provided that the following conditions are met: +/// 1. Redistributions of source code must retain the above copyright +/// notice, this list of conditions and the following disclaimer. +/// 2. Redistributions in binary form must reproduce the above copyright +/// notice, this list of conditions and the following disclaimer in the +/// documentation and/or other materials provided with the distribution. +/// 3. All advertising materials mentioning features or use of this software +/// must display the following acknowledgement: +/// This product includes software developed by the Cyber Security Labs B.V.. +/// 4. Neither the name of Cyber Security Labs B.V. nor the +/// names of its contributors may be used to endorse or promote products +/// derived from this software without specific prior written permission. +/// +/// THIS SOFTWARE IS PROVIDED BY Cyber Security Labs B.V. ''AS IS'' AND ANY +/// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +/// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +/// DISCLAIMED. IN NO EVENT SHALL Cyber Security Labs B.V. BE LIABLE FOR ANY +/// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +/// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +/// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +/// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +/// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +/// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/// + +#include "htif.h" + +#include +#include + +#include +#include + +#define read_reg(r) (dev_vaddr[r]) +#define write_reg(r, v) (dev_vaddr[r] = v) + +class Htif_zedboard_genode : public htif_t +{ + public: + Htif_zedboard_genode( std::string image = "image.elf" ): + htif_t( std::vector( { image } ) ), + _io_mem_dataspace( DEV_PADDR, 2 * sizeof( uintptr_t ), true ), + dev_vaddr( _io_mem_dataspace.local_addr() ) + + { + write_reg( 31, 0 ); // reset + } + protected: + ssize_t read( void *buf, size_t max_size ) + { + uint32_t *x = ( uint32_t * )buf; + assert( max_size >= sizeof( *x ) ); + + uintptr_t c = read_reg( 0 ); + uint32_t count = 0; + + if ( c > 0 ) + { + for ( count=0; count= sizeof( *x ) ); + + for ( uint32_t i = 0; i < size/sizeof( *x ); i++ ) + { + write_reg( 0, x[i] ); + } + + return size; + } + + size_t chunk_max_size() { return 64; } + size_t chunk_align() { return 64; } + uint32_t mem_mb() { return 256; } + uint32_t num_cores() { return 1; } + + private: + Genode::Attached_io_mem_dataspace _io_mem_dataspace; + volatile uintptr_t *dev_vaddr; + + const static uintptr_t DEV_PADDR = 0x43C00000; +}; + +static const std::string image_name() +{ + static const size_t LEN = 128; + char buf[LEN]; + Genode::memset( buf, 0, LEN ); + + try + { + Genode::config()->xml_node().sub_node( "fesrv" ).attribute( "image" ).value( + buf, LEN - 1 ); + } + catch ( ... ) + { + throw std::runtime_error( "elf-image not configured" ); + } + + return std::string( buf ); +} + +int main() +{ + try + { + auto image = image_name(); + Htif_zedboard_genode htif( image ); + PINF( "Initialized Htif_zedboard with %s", image.c_str() ); + htif.run(); + } + catch ( const std::runtime_error &e ) + { + PERR( "Caught runtime error: %s", e.what() ); + } + catch ( ... ) + { + PERR( "Unknown error occured" ); + } +} diff --git a/src/app/fesrv/patches/fesrv.patch b/src/app/fesrv/patches/fesrv.patch new file mode 100644 index 0000000..c9baca7 --- /dev/null +++ b/src/app/fesrv/patches/fesrv.patch @@ -0,0 +1,162 @@ +diff --git a/fesvr/device.cc b/fesvr/device.cc +index 7179ce0..118ef71 100644 +--- a/fesvr/device.cc ++++ b/fesvr/device.cc +@@ -11,6 +11,8 @@ + #include + using namespace std::placeholders; + ++#include ++ + device_t::device_t() + : command_handlers(command_t::MAX_COMMANDS), + command_names(command_t::MAX_COMMANDS) +@@ -69,7 +71,7 @@ void bcd_t::handle_read(command_t cmd) + + void bcd_t::handle_write(command_t cmd) + { +- canonical_terminal_t::write(cmd.payload()); ++ Genode::printf("%c",(char)cmd.payload()); + cmd.respond(0x100 | (uint8_t)cmd.payload()); + } + +diff --git a/fesvr/htif.cc b/fesvr/htif.cc +index 7e101ad..d8cca9d 100644 +--- a/fesvr/htif.cc ++++ b/fesvr/htif.cc +@@ -11,7 +11,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -30,40 +29,11 @@ + # define TARGET_DIR "/" TARGET_ARCH "/bin/" + #endif + +-static volatile bool signal_exit = false; +-static void handle_signal(int sig) +-{ +- if (sig == SIGABRT || signal_exit) // someone set up us the bomb! +- exit(-1); +- signal_exit = true; +- signal(sig, &handle_signal); +-} +- +-void htif_t::set_chroot(const char* where) +-{ +- char buf1[PATH_MAX], buf2[PATH_MAX]; +- +- if (getcwd(buf1, sizeof(buf1)) == NULL +- || chdir(where) != 0 +- || getcwd(buf2, sizeof(buf2)) == NULL +- || chdir(buf1) != 0) +- { +- printf("could not chroot to %s\n", chroot.c_str()); +- exit(-1); +- } +- +- chroot = buf2; +-} +- + htif_t::htif_t(const std::vector& args) + : exitcode(0), mem(this), seqno(1), started(false), stopped(false), +- _mem_mb(0), _num_cores(0), sig_addr(0), sig_len(0), ++ _mem_mb(0), _num_cores(0), sig_addr(0), sig_len(0), + syscall_proxy(this) + { +- signal(SIGINT, &handle_signal); +- signal(SIGTERM, &handle_signal); +- signal(SIGABRT, &handle_signal); // we still want to call static destructors +- + size_t i; + for (i = 0; i < args.size(); i++) + if (args[i].length() && args[i][0] != '-' && args[i][0] != '+') +@@ -82,8 +52,6 @@ htif_t::htif_t(const std::vector& args) + dynamic_devices.push_back(new disk_t(arg.c_str() + strlen("+disk="))); + else if (arg.find("+signature=") == 0) + sig_file = arg.c_str() + strlen("+signature="); +- else if (arg.find("+chroot=") == 0) +- set_chroot(arg.substr(strlen("+chroot=")).c_str()); + } + + device_list.register_device(&syscall_proxy); +@@ -169,7 +137,6 @@ void htif_t::load_program() + if (access(test_path.c_str(), F_OK) == 0) + path = test_path; + } +- + if (path.empty()) + throw std::runtime_error("could not open " + targs[0]); + +@@ -199,9 +166,9 @@ void htif_t::stop() + std::vector buf(sig_len); + mem.read(sig_addr, sig_len, &buf[0]); + +- std::ofstream sigs(sig_file); +- assert(sigs && "can't open signature file!"); +- sigs << std::setfill('0') << std::hex; ++ std::ofstream sigs(sig_file); ++ assert(sigs && "can't open signature file!"); ++ sigs << std::setfill('0') << std::hex; + + const addr_t incr = 16; + assert(sig_len % incr == 0); +@@ -293,7 +260,7 @@ int htif_t::run() + for (size_t i = 0; i < num_cores(); i++) + fromhost_callbacks.push_back(std::bind(enq_func, &fromhost[i], std::placeholders::_1)); + +- while (!signal_exit && exitcode == 0) ++ while ( exitcode == 0) + { + for (uint32_t coreid = 0; coreid < num_cores(); coreid++) + { +diff --git a/fesvr/htif.h b/fesvr/htif.h +index ace4503..9fcbbf6 100644 +--- a/fesvr/htif.h ++++ b/fesvr/htif.h +@@ -70,7 +70,6 @@ class htif_t + virtual packet_t read_packet(seqno_t expected_seqno); + virtual void write_packet(const packet_t& packet); + +- void set_chroot(const char* where); + const std::vector& target_args() { return targs; } + + friend class memif_t; +diff --git a/fesvr/htif_eth.cc b/fesvr/htif_eth.cc +index 3a9de7d..19028e4 100644 +--- a/fesvr/htif_eth.cc ++++ b/fesvr/htif_eth.cc +@@ -181,8 +181,6 @@ htif_eth_t::~htif_eth_t() + + ssize_t htif_eth_t::read(void* buf, size_t max_size) + { +- ssize_t bytes; +- + for(int timeouts = 0; timeouts < 3; ) + { + #ifdef __linux__ +@@ -277,4 +275,5 @@ ssize_t htif_eth_t::write(const void* buf, size_t size) + else + return ::write(sock, (char*)ð_packet, size); + #endif ++ return 0; + } +diff --git a/fesvr/syscall.cc b/fesvr/syscall.cc +index dc73360..cf16c58 100644 +--- a/fesvr/syscall.cc ++++ b/fesvr/syscall.cc +@@ -71,10 +71,7 @@ syscall_t::syscall_t(htif_t* htif) + + register_command(0, std::bind(&syscall_t::handle_syscall, this, _1), "syscall"); + +- int stdin_fd = dup(0), stdout_fd0 = dup(1), stdout_fd1 = dup(1); +- if (stdin_fd < 0 || stdout_fd0 < 0 || stdout_fd1 < 0) +- throw std::runtime_error("could not dup stdin/stdout"); +- ++ int stdin_fd =0, stdout_fd0 = 1, stdout_fd1 = 1; + fds.alloc(stdin_fd); // stdin -> stdin + fds.alloc(stdout_fd0); // stdout -> stdout + fds.alloc(stdout_fd1); // stderr -> stdout diff --git a/src/app/fesrv/target.mk b/src/app/fesrv/target.mk new file mode 100644 index 0000000..38c1dba --- /dev/null +++ b/src/app/fesrv/target.mk @@ -0,0 +1,30 @@ +FESRV_SRC = $(call select_from_ports,fesrv)/src/app/fesrv/fesvr/ + +SRC_CC = main.cc \ + linux_syscalls.cc \ + context.cc \ + device.cc \ + dummy.cc \ + elfloader.cc \ + htif.cc \ + htif_eth.cc \ + htif_hexwriter.cc \ + htif_rs232.cc \ + htif_zedboard.cc \ + memif.cc \ + option_parser.cc \ + packet.cc \ + rfb.cc \ + syscall.cc \ + term.cc + +TARGET = fesrv +LIBS = stdcxx +INC_DIR += $(FESRV_SRC) + +# Some defines to keep the fesrv compilation process happy +CC_OPT += -DPREFIX=\"\" -DTARGET_ARCH=\"\" -DTARGET_DIR=\"\" + +vpath %.cc $(FESRV_SRC) + +