diff --git a/include/solo5/stdint.h b/include/solo5/stdint.h
new file mode 100644
index 0000000..21f3045
--- /dev/null
+++ b/include/solo5/stdint.h
@@ -0,0 +1,12 @@
+#include
+
+typedef genode_uint8_t uint8_t;
+typedef genode_int8_t int8_t;
+typedef genode_uint16_t uint16_t;
+typedef genode_int16_t int16_t;
+typedef genode_uint32_t uint32_t;
+typedef genode_int32_t int32_t;
+typedef genode_uint64_t uint64_t;
+typedef genode_int64_t int64_t;
+typedef unsigned long uintptr_t;
+typedef unsigned long size_t;
diff --git a/lib/import/import-solo5.mk b/lib/import/import-solo5.mk
new file mode 100644
index 0000000..7c45aaf
--- /dev/null
+++ b/lib/import/import-solo5.mk
@@ -0,0 +1,4 @@
+REQUIRES += 64bit
+
+INC_DIR += $(call select_from_repositories,include/solo5)
+INC_DIR += $(call select_from_ports,solo5)/include/solo5
diff --git a/lib/mk/solo5.mk b/lib/mk/solo5.mk
new file mode 100644
index 0000000..ac84bba
--- /dev/null
+++ b/lib/mk/solo5.mk
@@ -0,0 +1,23 @@
+REQUIRES += 64bit
+
+SHARED_LIB = yes
+
+CC_OPT += -D__SOLO5_BINDINGS__ -Drestrict=__restrict__
+
+# GCC 8 complains about a mismatch of the 'log()' function declaration.
+# Since the solo5 'log()' function is unrelated to the builtin function,
+# we disable the error message.
+CC_OPT += -Wno-builtin-declaration-mismatch
+
+SRC_CC = bindings.cc
+
+SOLO5_PORT_DIR := $(call select_from_ports,solo5)
+
+INC_DIR += $(SOLO5_PORT_DIR)/src/lib/solo5/bindings
+INC_DIR += $(SOLO5_PORT_DIR)/include/solo5
+INC_DIR += $(REP_DIR)/include/solo5
+
+vpath bindings.cc $(SOLO5_PORT_DIR)/src/lib/solo5/bindings/genode
+
+# ignore warning about use of deprecated Xml_node API
+CC_CXX_WARN_STRICT :=
diff --git a/lib/symbols/solo5 b/lib/symbols/solo5
new file mode 100644
index 0000000..61ca6cd
--- /dev/null
+++ b/lib/symbols/solo5
@@ -0,0 +1,13 @@
+solo5_abort T
+solo5_app_main U
+solo5_block_info T
+solo5_block_read T
+solo5_block_write T
+solo5_clock_monotonic T
+solo5_clock_wall T
+solo5_console_write T
+solo5_exit T
+solo5_net_info T
+solo5_net_read T
+solo5_net_write T
+solo5_yield T
diff --git a/ports/solo5.hash b/ports/solo5.hash
new file mode 100644
index 0000000..d1a8dd0
--- /dev/null
+++ b/ports/solo5.hash
@@ -0,0 +1 @@
+55dd4fb026c0d4a7cc192c8228e4a6344f5781ef
diff --git a/ports/solo5.port b/ports/solo5.port
new file mode 100644
index 0000000..f2320e7
--- /dev/null
+++ b/ports/solo5.port
@@ -0,0 +1,11 @@
+LICENSE := ISC
+VERSION := HEAD
+DOWNLOADS := solo5.archive
+
+REV := 7dca1a677f548ea0bc911a209f34ceb55d8f10fd
+URL(solo5) := https://genode.org/files/solo5-$(REV).tar.gz
+SHA(solo5) := 87a8e8e047bc6fffe0384f1cbb2bfde1e4c88c545287899be29444ec9a4d6b95
+DIR(solo5) := src/lib/solo5
+
+DIRS := include/solo5
+DIR_CONTENT(include/solo5) = src/lib/solo5/include/solo5/solo5.h
diff --git a/recipes/api/solo5/content.mk b/recipes/api/solo5/content.mk
new file mode 100644
index 0000000..e0161a9
--- /dev/null
+++ b/recipes/api/solo5/content.mk
@@ -0,0 +1,16 @@
+MIRROR_FROM_REP_DIR = lib/import/import-solo5.mk lib/symbols/solo5
+
+content: $(MIRROR_FROM_REP_DIR) include/solo5 LICENSE
+
+PORT_DIR := $(call port_dir,$(REP_DIR)/ports/solo5)/src/lib/solo5
+
+include/solo5:
+ mkdir -p $@
+ cp -r $(PORT_DIR)/include/solo5/* $@
+ cp -r $(REP_DIR)/include/solo5/* $@
+
+$(MIRROR_FROM_REP_DIR):
+ $(mirror_from_rep_dir)
+
+LICENSE:
+ cp $(PORT_DIR)/$@ $@
diff --git a/recipes/api/solo5/hash b/recipes/api/solo5/hash
new file mode 100644
index 0000000..c8f37cf
--- /dev/null
+++ b/recipes/api/solo5/hash
@@ -0,0 +1 @@
+2019-05-05 8f54bd69a92ed4e090124d69a6a3b92689b39536
diff --git a/recipes/pkg/test-solo5/README b/recipes/pkg/test-solo5/README
new file mode 100644
index 0000000..e14cb9c
--- /dev/null
+++ b/recipes/pkg/test-solo5/README
@@ -0,0 +1 @@
+Test of the Solo5 unikernel middleware.
diff --git a/recipes/pkg/test-solo5/archives b/recipes/pkg/test-solo5/archives
new file mode 100644
index 0000000..8380a1d
--- /dev/null
+++ b/recipes/pkg/test-solo5/archives
@@ -0,0 +1,8 @@
+_/src/init
+_/src/nic_loopback
+_/src/vfs_block
+_/src/sequence
+_/src/solo5
+_/src/test-solo5
+_/src/vfs
+_/src/vfs_import
diff --git a/recipes/pkg/test-solo5/hash b/recipes/pkg/test-solo5/hash
new file mode 100644
index 0000000..48dcae3
--- /dev/null
+++ b/recipes/pkg/test-solo5/hash
@@ -0,0 +1 @@
+2020-06-18-b 32b32ac1918d2a2aebb7636e6faae4ea958b5eeb
diff --git a/recipes/pkg/test-solo5/runtime b/recipes/pkg/test-solo5/runtime
new file mode 100644
index 0000000..4d30b71
--- /dev/null
+++ b/recipes/pkg/test-solo5/runtime
@@ -0,0 +1,79 @@
+
+
+
+
+
+ [init] child "test" exited with exit value 0
+
+ Error:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/recipes/src/solo5/api b/recipes/src/solo5/api
new file mode 100644
index 0000000..19e0c9e
--- /dev/null
+++ b/recipes/src/solo5/api
@@ -0,0 +1 @@
+solo5
diff --git a/recipes/src/solo5/content.mk b/recipes/src/solo5/content.mk
new file mode 100644
index 0000000..f80fed7
--- /dev/null
+++ b/recipes/src/solo5/content.mk
@@ -0,0 +1,20 @@
+PORT_DIR_SOLO5 := $(call port_dir,$(REP_DIR)/ports/solo5)
+
+SRC_DIR = src/lib/solo5
+
+MIRROR_FROM_REP_DIR = \
+ include/solo5 \
+ lib/import/import-solo5.mk \
+ lib/mk/solo5.mk \
+
+content: $(SRC_DIR) $(MIRROR_FROM_REP_DIR)
+
+$(SRC_DIR):
+ mkdir -p $@
+ cp -r $(PORT_DIR_SOLO5)/$@/* $@/
+ cp -r $(PORT_DIR_SOLO5)/include/solo5/* $@/bindings
+ cp $(PORT_DIR_SOLO5)/$@/LICENSE .
+ echo 'LIBS=solo5' > $@/target.mk
+
+$(MIRROR_FROM_REP_DIR):
+ $(mirror_from_rep_dir)
diff --git a/recipes/src/solo5/hash b/recipes/src/solo5/hash
new file mode 100644
index 0000000..0b421c1
--- /dev/null
+++ b/recipes/src/solo5/hash
@@ -0,0 +1 @@
+2020-05-26 b3a592352ce08a4c62cd8abb6718ddee44b0b184
diff --git a/recipes/src/solo5/used_apis b/recipes/src/solo5/used_apis
new file mode 100644
index 0000000..f26a4f0
--- /dev/null
+++ b/recipes/src/solo5/used_apis
@@ -0,0 +1,7 @@
+base
+os
+block_session
+nic_session
+rtc_session
+timer_session
+solo5
diff --git a/recipes/src/test-solo5/content.mk b/recipes/src/test-solo5/content.mk
new file mode 100644
index 0000000..f2772bf
--- /dev/null
+++ b/recipes/src/test-solo5/content.mk
@@ -0,0 +1,19 @@
+MIRROR_FROM_REP_DIR := src/test/solo5
+
+PORT_DIR := $(call port_dir,$(REP_DIR)/ports/solo5)
+
+content: $(MIRROR_FROM_REP_DIR) src/lib/solo5/tests src/lib/solo5/bindings LICENSE
+
+src/lib/solo5/bindings: $(PORT_DIR)
+ mkdir -p $@
+ cp $(PORT_DIR)/$@/*.c $@
+
+src/lib/solo5/tests: $(PORT_DIR)
+ mkdir -p $@
+ cp -r $(PORT_DIR)/$@/test_* $@
+
+$(MIRROR_FROM_REP_DIR):
+ $(mirror_from_rep_dir)
+
+LICENSE:
+ cp $(PORT_DIR)/src/lib/solo5/LICENSE $@
diff --git a/recipes/src/test-solo5/hash b/recipes/src/test-solo5/hash
new file mode 100644
index 0000000..0621a47
--- /dev/null
+++ b/recipes/src/test-solo5/hash
@@ -0,0 +1 @@
+2020-05-26 827f99e63057492c51a8f7c2cf86f23ba35d840e
diff --git a/recipes/src/test-solo5/used_apis b/recipes/src/test-solo5/used_apis
new file mode 100644
index 0000000..e134d1f
--- /dev/null
+++ b/recipes/src/test-solo5/used_apis
@@ -0,0 +1,2 @@
+base
+solo5
diff --git a/run/mirage_net.run b/run/mirage_net.run
new file mode 100644
index 0000000..f4c00ba
--- /dev/null
+++ b/run/mirage_net.run
@@ -0,0 +1,105 @@
+if {![have_spec x86_64]} {
+ puts "\nSolo5 requires a 64bit architecture\n"
+ exit 0
+}
+
+if {![file exists bin/mirage]} {
+ puts ""
+ puts "A mirage image must be provided at 'bin/mirage' to execute this scenario."
+ puts ""
+ exit 1
+}
+
+if {[have_spec linux]} {
+ puts ""
+ puts "This scenario is not available for the Linux platform."
+ puts ""
+ exit 1
+}
+
+create_boot_directory
+
+import_from_depot \
+ [depot_user]/src/[base_src] \
+ [depot_user]/src/init \
+ [depot_user]/src/rtc_drv \
+
+source ${genode_dir}/repos/base/run/platform_drv.inc
+
+set build_components {
+ drivers/nic
+ drivers/rtc
+ lib/solo5
+}
+
+append_platform_drv_build_components
+
+build $build_components
+
+append config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+
+append_platform_drv_config
+
+append config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+install_config $config
+
+set boot_modules {
+ mirage
+ rtc_drv
+ ipxe_nic_drv
+ solo5.lib.so
+}
+
+# platform-specific modules
+append_platform_drv_boot_modules
+
+build_boot_image $boot_modules
+
+append qemu_args " -nographic "
+
+proc qemu_nic_model {} {
+ if [have_spec x86] { return e1000 }
+ if [have_spec lan9118] { return lan9118 }
+ if [have_spec zynq] { return cadence_gem }
+ return nic_model_missing
+}
+
+append qemu_args " -netdev user,id=net0 "
+append qemu_args " -net nic,model=[qemu_nic_model],netdev=net0 "
+
+run_genode_until forever
diff --git a/run/mirage_pretty.run b/run/mirage_pretty.run
new file mode 100644
index 0000000..fd3af8d
--- /dev/null
+++ b/run/mirage_pretty.run
@@ -0,0 +1,140 @@
+if {![have_spec x86_64]} {
+ puts "\nSolo5 requires a 64bit architecture\n"
+ exit 0
+}
+
+if {![file exists bin/mirage]} {
+ puts ""
+ puts "A mirage image must be provided at 'bin/mirage' to execute this scenario."
+ puts ""
+ exit 1
+}
+
+if {[have_spec linux]} {
+ puts ""
+ puts "This scenario is not available for Linux."
+ puts ""
+ exit 1
+}
+
+create_boot_directory
+
+import_from_depot \
+ [depot_user]/src/[base_src] \
+ [depot_user]/src/init \
+ [depot_user]/src/ipxe_nic_drv \
+ [depot_user]/src/rtc_drv \
+ [depot_user]/pkg/terminal
+
+source ${genode_dir}/repos/base/run/platform_drv.inc
+
+set build_components {
+ app/log_core
+ drivers/framebuffer
+ drivers/input/dummy
+ lib/solo5
+ server/terminal_log
+}
+
+append_platform_drv_build_components
+
+build $build_components
+
+set fb_drv "vesa_fb_drv"
+
+if {[have_include "image/uefi"]} {
+ set fb_drv "fb_boot_drv"
+}
+
+append config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+
+append_platform_drv_config
+
+append config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+install_config $config
+
+append boot_modules {
+ dummy_input_drv
+ log_core
+ terminal_log
+ mirage
+ solo5.lib.so
+}
+
+append boot_modules " $fb_drv"
+
+# platform-specific modules
+append_platform_drv_boot_modules
+
+build_boot_image $boot_modules
+
+append qemu_args " -netdev user,id=net0 "
+append qemu_args " -net nic,model=e1000,netdev=net0 "
+
+run_genode_until forever
diff --git a/run/solo5.run b/run/solo5.run
new file mode 100644
index 0000000..030b817
--- /dev/null
+++ b/run/solo5.run
@@ -0,0 +1,116 @@
+if {![have_spec x86_64]} {
+ puts "\nTest requires x86_64\n"
+ exit 0
+}
+
+if {[have_spec linux]} {
+ puts "\nRun script is not supported on this platform\n"
+ exit 0
+}
+
+create_boot_directory
+
+import_from_depot \
+ [depot_user]/src/[base_src] \
+ [depot_user]/src/init \
+ [depot_user]/src/nic_loopback \
+ [depot_user]/src/vfs_block \
+ [depot_user]/src/rtc_drv \
+ [depot_user]/src/sequence \
+ [depot_user]/src/vfs \
+ [depot_user]/src/vfs_import
+
+append config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+
+if { ![get_cmd_switch --autopilot] || ![have_include "power_on/qemu"] } {
+ append config {
+
+
+ }
+}
+
+append config {
+
+
+
+}
+
+install_config $config
+
+build {
+ test/solo5
+}
+
+build_boot_image {
+ solo5.lib.so
+ solo5-test_blk
+ solo5-test_fpu
+ solo5-test_globals
+ solo5-test_hello
+ solo5-test_quiet
+ solo5-test_time
+}
+
+append qemu_args " -nographic "
+
+run_genode_until {child "test" exited with exit value 0} 40
diff --git a/run/solo5_ping.run b/run/solo5_ping.run
new file mode 100644
index 0000000..1218371
--- /dev/null
+++ b/run/solo5_ping.run
@@ -0,0 +1,122 @@
+if {![have_spec x86_64]} {
+ puts "\nTest requires x86_64\n"
+ exit 0
+}
+
+if {[have_spec linux]} {
+ puts "\nRun script is not supported on this platform\n"
+ exit 0
+}
+
+create_boot_directory
+
+import_from_depot \
+ [depot_user]/src/[base_src] \
+ [depot_user]/src/init \
+ [depot_user]/src/rtc_drv \
+
+source ${genode_dir}/repos/base/run/platform_drv.inc
+
+append config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ }
+
+append_platform_drv_config
+
+append config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+install_config $config
+
+append build_components {
+ app/ping
+ drivers/nic
+ server/nic_bridge
+ test/solo5/ping_serve
+}
+
+append_platform_drv_build_components
+build $build_components
+
+append boot_modules {
+ nic_bridge
+ ping
+ ipxe_nic_drv
+ solo5-test_ping_serve
+ solo5.lib.so
+}
+
+append_platform_drv_boot_modules
+build_boot_image $boot_modules
+
+append qemu_args " -nographic "
+
+run_genode_until {child "ping" exited with exit value 0} 60
diff --git a/run/solo5_ssp.run b/run/solo5_ssp.run
new file mode 100644
index 0000000..fdd82be
--- /dev/null
+++ b/run/solo5_ssp.run
@@ -0,0 +1,51 @@
+if {![have_spec x86_64]} {
+ puts "\nTest requires x86_64\n"
+ exit 0
+}
+
+create_boot_directory
+
+import_from_depot \
+ [depot_user]/src/[base_src] \
+ [depot_user]/src/init \
+
+append config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+install_config $config
+
+build {
+ test/solo5
+}
+
+build_boot_image {
+ solo5.lib.so
+ solo5-test_ssp
+}
+
+append qemu_args " -nographic "
+
+run_genode_until {Error: stack protector check failed} 20
diff --git a/src/lib/solo5/target.mk b/src/lib/solo5/target.mk
new file mode 100644
index 0000000..ee186f1
--- /dev/null
+++ b/src/lib/solo5/target.mk
@@ -0,0 +1,2 @@
+TARGET = dummy-solo5
+LIBS = solo5
diff --git a/src/test/solo5/abort/target.mk b/src/test/solo5/abort/target.mk
new file mode 100644
index 0000000..c52248b
--- /dev/null
+++ b/src/test/solo5/abort/target.mk
@@ -0,0 +1 @@
+include $(REP_DIR)/src/test/solo5/test.inc
diff --git a/src/test/solo5/blk/target.mk b/src/test/solo5/blk/target.mk
new file mode 100644
index 0000000..c52248b
--- /dev/null
+++ b/src/test/solo5/blk/target.mk
@@ -0,0 +1 @@
+include $(REP_DIR)/src/test/solo5/test.inc
diff --git a/src/test/solo5/exception/target.mk b/src/test/solo5/exception/target.mk
new file mode 100644
index 0000000..c52248b
--- /dev/null
+++ b/src/test/solo5/exception/target.mk
@@ -0,0 +1 @@
+include $(REP_DIR)/src/test/solo5/test.inc
diff --git a/src/test/solo5/fpu/target.mk b/src/test/solo5/fpu/target.mk
new file mode 100644
index 0000000..c52248b
--- /dev/null
+++ b/src/test/solo5/fpu/target.mk
@@ -0,0 +1 @@
+include $(REP_DIR)/src/test/solo5/test.inc
diff --git a/src/test/solo5/globals/target.mk b/src/test/solo5/globals/target.mk
new file mode 100644
index 0000000..c52248b
--- /dev/null
+++ b/src/test/solo5/globals/target.mk
@@ -0,0 +1 @@
+include $(REP_DIR)/src/test/solo5/test.inc
diff --git a/src/test/solo5/hello/target.mk b/src/test/solo5/hello/target.mk
new file mode 100644
index 0000000..c52248b
--- /dev/null
+++ b/src/test/solo5/hello/target.mk
@@ -0,0 +1 @@
+include $(REP_DIR)/src/test/solo5/test.inc
diff --git a/src/test/solo5/ping_serve/target.mk b/src/test/solo5/ping_serve/target.mk
new file mode 100644
index 0000000..c52248b
--- /dev/null
+++ b/src/test/solo5/ping_serve/target.mk
@@ -0,0 +1 @@
+include $(REP_DIR)/src/test/solo5/test.inc
diff --git a/src/test/solo5/quiet/target.mk b/src/test/solo5/quiet/target.mk
new file mode 100644
index 0000000..c52248b
--- /dev/null
+++ b/src/test/solo5/quiet/target.mk
@@ -0,0 +1 @@
+include $(REP_DIR)/src/test/solo5/test.inc
diff --git a/src/test/solo5/ssp/target.mk b/src/test/solo5/ssp/target.mk
new file mode 100644
index 0000000..c52248b
--- /dev/null
+++ b/src/test/solo5/ssp/target.mk
@@ -0,0 +1 @@
+include $(REP_DIR)/src/test/solo5/test.inc
diff --git a/src/test/solo5/test.inc b/src/test/solo5/test.inc
new file mode 100644
index 0000000..d7deb0e
--- /dev/null
+++ b/src/test/solo5/test.inc
@@ -0,0 +1,10 @@
+TEST_NAME := test_$(subst $(REP_DIR)/src/test/solo5/,,$(PRG_DIR))
+TARGET = solo5-$(TEST_NAME)
+
+LIBS += base solo5
+
+CC_OPT += -fstack-protector-strong
+
+SRC_C += $(TEST_NAME).c
+
+vpath %.c $(call select_from_ports,solo5)/src/lib/solo5/tests/$(TEST_NAME)
diff --git a/src/test/solo5/time/target.mk b/src/test/solo5/time/target.mk
new file mode 100644
index 0000000..c52248b
--- /dev/null
+++ b/src/test/solo5/time/target.mk
@@ -0,0 +1 @@
+include $(REP_DIR)/src/test/solo5/test.inc