diff --git a/run/fdt.run b/run/fdt.run
new file mode 100644
index 0000000..38dc947
--- /dev/null
+++ b/run/fdt.run
@@ -0,0 +1,35 @@
+build "core init test/fdt"
+
+create_boot_directory
+
+install_config {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
+build_boot_image {
+ core init timer test-fdt
+ ld.lib.so fdt.lib.so
+ tree.dtb
+}
+
+append qemu_args " -nographic "
+
+run_genode_until "child .* exited with exit value 0.*\n" 30
diff --git a/src/test/fdt/main.cc b/src/test/fdt/main.cc
new file mode 100644
index 0000000..84615eb
--- /dev/null
+++ b/src/test/fdt/main.cc
@@ -0,0 +1,100 @@
+/**
+ * \brief Test basic libfdt functionality
+ * \author Sebastian Sumpf
+ * \date 2019-08-09
+ */
+
+/*
+ * Copyright (C) 2019 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.
+ */
+
+extern "C" {
+#include
+}
+
+#include
+#include
+#include
+
+using namespace Genode;
+
+enum { MAX_FDT = 128*1024 };
+static char fdt[MAX_FDT];
+
+
+static void memory(int offset)
+{
+ log("Address cells: ", fdt_address_cells(fdt, offset));
+ log("Size cells ", fdt_size_cells(fdt, offset));
+ log("Reg subnode offset: ", fdt_subnode_offset(fdt, offset, "reg"));
+
+ int pr_off;
+ fdt_for_each_property_offset(pr_off, fdt, offset) {
+
+ int len;
+ struct fdt_property const *pr = fdt_get_property_by_offset(fdt, pr_off, &len);
+ log("Property length: ", len);
+ log("name '", fdt_get_string(fdt, host_to_big_endian(pr->nameoff), nullptr), "' ",
+ " tag: ", Hex(host_to_big_endian(pr->tag)),
+ " length: ", host_to_big_endian(pr->len),
+ " name offset: ", Hex(host_to_big_endian(pr->nameoff)));
+
+ if (strcmp(fdt_get_string(fdt, host_to_big_endian(pr->nameoff), nullptr), "reg") != 0) continue;
+ unsigned *data = (unsigned *)pr->data;
+ log("Poperty: ", pr, " data at ", data);
+ for (int i = 0; i < 4; i++) {
+ log("[", i, "] data: ", Hex(host_to_big_endian(data[i])));
+ }
+
+ log("Set property");
+ data[3] = host_to_big_endian(0xb0000000);
+
+ for (int i = 0; i < 4; i++) {
+ log("[", i, "] data: ", Hex(host_to_big_endian(data[i])));
+ }
+ }
+}
+
+
+void Component::construct(Genode::Env &env)
+{
+ Attached_rom_dataspace dtb { env, "tree.dtb" };
+
+ log("Opened 'tree.dtb'");
+ Genode::memcpy(fdt, dtb.local_addr(), dtb.size());
+
+ log("Copied ", dtb.size(), " bytes");
+ log("Tree is ", fdt_check_header(fdt) == 0 ? "valid" : "corrupted");
+
+ int offset = fdt_next_node(fdt, -1, nullptr);
+ int last_offset = offset;
+ while (offset >= 0) {
+ char const *name = fdt_get_name(fdt, offset, nullptr);
+ log("node: ", name);
+
+ if (strcmp(name, "memory", 6) == 0) {
+ warning("Found memory");
+ memory(offset);
+ }
+
+ if (strcmp(name, "ethernet", 8) == 0) {
+ warning("Deleting ethernet");
+ fdt_del_node(fdt, offset);
+ offset = last_offset;
+ }
+
+ if (strcmp(name, "audio-codec", 11) == 0) {
+ warning("Deleting audio's 'compatible' porpery");
+ fdt_delprop(fdt, offset,"compatible");
+ }
+
+ last_offset = offset;
+ offset = fdt_next_node(fdt, offset, nullptr);
+ }
+
+ fdt_pack(fdt);
+ warning("Total size after pack: ", fdt_totalsize(fdt), " bytes");
+}
diff --git a/src/test/fdt/target.mk b/src/test/fdt/target.mk
new file mode 100644
index 0000000..e2060b4
--- /dev/null
+++ b/src/test/fdt/target.mk
@@ -0,0 +1,5 @@
+SRC_CC = main.cc
+TARGET = test-fdt
+LIBS = base fdt
+
+CC_CXX_WARN_STRICT =