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)
+
+