diff --git a/repos/base-tukija/lib/mk/core-tukija.inc b/repos/base-tukija/lib/mk/core-tukija.inc
index 5c56cf8fdf..761cc50f58 100644
--- a/repos/base-tukija/lib/mk/core-tukija.inc
+++ b/repos/base-tukija/lib/mk/core-tukija.inc
@@ -52,7 +52,7 @@ INC_DIR += $(REP_DIR)/src/core/include \
include $(GEN_CORE_DIR)/version.inc
-vpath main.cc $(GEN_CORE_DIR)
+vpath main.cc $(REP_DIR)/src/core
vpath pd_session_component.cc $(GEN_CORE_DIR)
vpath rom_session_component.cc $(GEN_CORE_DIR)
vpath core_log.cc $(GEN_CORE_DIR)
diff --git a/repos/base-tukija/src/core/include/core_child.h b/repos/base-tukija/src/core/include/core_child.h
new file mode 100644
index 0000000000..33fd432024
--- /dev/null
+++ b/repos/base-tukija/src/core/include/core_child.h
@@ -0,0 +1,113 @@
+/*
+ * \brief Child policy for the init component
+ * \author Norman Feske
+ * \date 2024-12-17
+ */
+
+/*
+ * Copyright (C) 2016-2024 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.
+ */
+
+#ifndef _CORE__INCLUDE__CORE_CHILD_H_
+#define _CORE__INCLUDE__CORE_CHILD_H_
+
+/* Genode includes */
+#include
+#include
+
+/* core includes */
+#include
+
+namespace Core { class Core_child; }
+
+
+class Core::Core_child : public Child_policy
+{
+ private:
+
+ Registry &_services;
+ Rpc_entrypoint &_ep;
+ Region_map &_core_rm;
+ Ram_allocator &_core_ram;
+ Core_account &_core_account;
+
+ Capability _core_cpu_cap;
+ Cpu_session &_core_cpu;
+
+ Cap_quota const _cap_quota;
+ Ram_quota const _ram_quota;
+
+ Id_space _server_ids { };
+
+ Child _child { _core_rm, _ep, *this };
+
+ public:
+
+ Core_child(Registry &services, Rpc_entrypoint &ep,
+ Region_map &core_rm, Ram_allocator &core_ram,
+ Core_account &core_account,
+ Cpu_session &core_cpu, Capability core_cpu_cap,
+ Cap_quota cap_quota, Ram_quota ram_quota)
+ :
+ _services(services), _ep(ep), _core_rm(core_rm), _core_ram(core_ram),
+ _core_account(core_account),
+ _core_cpu_cap(core_cpu_cap), _core_cpu(core_cpu),
+ _cap_quota(Child::effective_quota(cap_quota)),
+ _ram_quota(Child::effective_quota(ram_quota))
+ { }
+
+
+ /****************************
+ ** Child-policy interface **
+ ****************************/
+
+ Name name() const override { return "hoitaja"; }
+
+ Route resolve_session_request(Service::Name const &name,
+ Session_label const &label,
+ Session::Diag const diag) override
+ {
+ Service *service = nullptr;
+ _services.for_each([&] (Service &s) {
+ if (!service && s.name() == name)
+ service = &s; });
+
+ if (!service)
+ throw Service_denied();
+
+ return Route { .service = *service,
+ .label = label,
+ .diag = diag };
+ }
+
+ void init(Pd_session &, Capability cap) override
+ {
+ _ep.apply(cap, [&] (Pd_session_component *pd_ptr) {
+ if (pd_ptr)
+ pd_ptr->ref_accounts(_core_account.ram_account,
+ _core_account.cap_account); });
+
+ _core_account.transfer_quota(cap, _cap_quota);
+ _core_account.transfer_quota(cap, _ram_quota);
+ }
+
+ void init(Cpu_session &session, Capability cap) override
+ {
+ session.ref_account(_core_cpu_cap);
+ _core_cpu.transfer_quota(cap, Cpu_session::quota_lim_upscale(100, 100));
+ }
+
+ Ram_allocator &session_md_ram() override { return _core_ram; }
+
+ Pd_account &ref_account() override { return _core_account; }
+ Capability ref_account_cap() const override { return _core_account.cap(); }
+
+ size_t session_alloc_batch_size() const override { return 128; }
+
+ Id_space &server_id_space() override { return _server_ids; }
+};
+
+#endif /* _CORE__INCLUDE__CORE_CHILD_H_ */
diff --git a/repos/base-tukija/src/core/main.cc b/repos/base-tukija/src/core/main.cc
new file mode 100644
index 0000000000..0fba36d174
--- /dev/null
+++ b/repos/base-tukija/src/core/main.cc
@@ -0,0 +1,192 @@
+/*
+ * \brief Core main program
+ * \author Norman Feske
+ * \date 2006-07-12
+ */
+
+/*
+ * Copyright (C) 2006-2023 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.
+ */
+
+/* Genode includes */
+#include
+
+/* base-internal includes */
+#include
+
+/* core includes */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+Core::Platform &Core::platform_specific()
+{
+ static Platform _platform;
+ return _platform;
+}
+
+
+Core::Platform_generic &Core::platform() { return platform_specific(); }
+
+
+Core::Trace::Source_registry &Core::Trace::sources()
+{
+ static Source_registry inst;
+ return inst;
+}
+
+
+namespace Genode { extern char const *version_string; }
+
+
+struct Genode::Platform { };
+
+
+/*
+ * Executed on the initial stack
+ */
+Genode::Platform &Genode::init_platform()
+{
+ init_stack_area();
+
+ static Platform platform { };
+ return platform;
+}
+
+
+/*
+ * Executed on a stack located within the stack area
+ */
+void Genode::bootstrap_component(Genode::Platform &)
+{
+ using namespace Core;
+
+ Range_allocator &ram_ranges = Core::platform().ram_alloc();
+ Rom_fs &rom_modules = Core::platform().rom_fs();
+ Range_allocator &io_mem_ranges = Core::platform().io_mem_alloc();
+ Range_allocator &io_port_ranges = Core::platform().io_port_alloc();
+ Range_allocator &irq_ranges = Core::platform().irq_alloc();
+ Allocator &core_alloc = platform_specific().core_mem_alloc();
+
+ Ram_quota const avail_ram { ram_ranges.avail() };
+ Cap_quota const avail_caps { Core::platform().max_caps() };
+
+ static constexpr size_t STACK_SIZE = 20 * 1024;
+
+ static Rpc_entrypoint ep { nullptr, STACK_SIZE, "entrypoint", Affinity::Location() };
+
+ static Core::Core_account core_account { ep, avail_ram, avail_caps };
+
+ static Ram_dataspace_factory core_ram {
+ ep, ram_ranges, Ram_dataspace_factory::any_phys_range(), core_alloc };
+
+ static Core_region_map core_rm { ep };
+
+ static Rpc_entrypoint &signal_ep = core_signal_ep(ep);
+
+ init_exception_handling(core_ram, core_rm);
+ init_core_signal_transmitter(signal_ep);
+ init_page_fault_handling(ep);
+
+ /* disable tracing within core because it is not fully implemented */
+ inhibit_tracing = true;
+
+ log("Genode ", Genode::version_string);
+
+ static Core::Trace::Policy_registry trace_policies;
+
+ static Registry services;
+
+ /*
+ * Allocate session meta data on distinct dataspaces to enable independent
+ * destruction (to enable quota trading) of session component objects.
+ */
+ static Sliced_heap sliced_heap { core_ram, core_rm };
+
+ /*
+ * Factory for creating RPC capabilities within core
+ */
+ static Rpc_cap_factory rpc_cap_factory { sliced_heap };
+
+ static Pager_entrypoint pager_ep(rpc_cap_factory);
+
+ using Trace_root = Core::Trace::Root;
+ using Trace_session_component = Core::Trace::Session_component;
+
+ static Core::System_control &system_control = init_system_control(sliced_heap, ep);
+
+ static Rom_root rom_root (ep, ep, rom_modules, sliced_heap);
+ static Rm_root rm_root (ep, sliced_heap, core_ram, core_rm, pager_ep);
+ static Cpu_root cpu_root (core_ram, core_rm, ep, ep, pager_ep,
+ sliced_heap, Core::Trace::sources());
+ static Pd_root pd_root (ep, signal_ep, pager_ep, ram_ranges, core_rm, sliced_heap,
+ platform_specific().core_mem_alloc(),
+ system_control);
+ static Log_root log_root (ep, sliced_heap);
+ static Io_mem_root io_mem_root (ep, ep, io_mem_ranges, ram_ranges, sliced_heap);
+ static Irq_root irq_root (irq_ranges, sliced_heap);
+ static Trace_root trace_root (core_ram, core_rm, ep, sliced_heap,
+ Core::Trace::sources(), trace_policies);
+
+ static Core_service rom_service (services, rom_root);
+ static Core_service rm_service (services, rm_root);
+ static Core_service cpu_service (services, cpu_root);
+ static Core_service pd_service (services, pd_root);
+ static Core_service log_service (services, log_root);
+ static Core_service io_mem_service (services, io_mem_root);
+ static Core_service irq_service (services, irq_root);
+ static Core_service trace_service (services, trace_root);
+
+ /* make platform-specific services known to service pool */
+ platform_add_local_services(ep, sliced_heap, services, Core::Trace::sources(),
+ core_ram, core_rm, io_port_ranges);
+
+ if (!core_account.ram_account.try_withdraw({ 224*1024 })) {
+ error("core preservation exceeds available RAM");
+ return;
+ }
+
+ if (!core_account.cap_account.try_withdraw({ 1000 })) {
+ error("core preservation exceeds available caps");
+ return;
+ }
+
+ Ram_quota const init_ram_quota = core_account.ram_account.avail();
+ Cap_quota const init_cap_quota = core_account.cap_account.avail();
+
+ /* CPU session representing core */
+ static Cpu_session_component
+ core_cpu(ep,
+ Session::Resources{{Cpu_session::RAM_QUOTA},
+ {Cpu_session::CAP_QUOTA}},
+ "core", Session::Diag{false},
+ core_ram, core_rm, ep, pager_ep, Core::Trace::sources(), "",
+ Affinity::unrestricted(), Cpu_session::QUOTA_LIMIT);
+
+ log(init_ram_quota.value / (1024*1024), " MiB RAM and ",
+ init_cap_quota, " caps assigned to init");
+
+ static Reconstructible
+ init(services, ep, core_rm, core_ram, core_account,
+ core_cpu, core_cpu.cap(), init_cap_quota, init_ram_quota);
+
+ Core::platform().wait_for_exit();
+
+ init.destruct();
+}