diff --git a/repos/base-hw/lib/mk/core-hw.inc b/repos/base-hw/lib/mk/core-hw.inc
index a875b20eb8..98657c1581 100644
--- a/repos/base-hw/lib/mk/core-hw.inc
+++ b/repos/base-hw/lib/mk/core-hw.inc
@@ -58,7 +58,6 @@ SRC_CC += kernel/object.cc
SRC_CC += kernel/signal_receiver.cc
SRC_CC += kernel/thread.cc
SRC_CC += kernel/timer.cc
-SRC_CC += init_main_thread.cc
SRC_CC += capability.cc
SRC_CC += stack_area_addr.cc
SRC_CC += heartbeat.cc
diff --git a/repos/base-hw/recipes/src/base-hw_content.inc b/repos/base-hw/recipes/src/base-hw_content.inc
index 38ab511db0..84f8e3a367 100644
--- a/repos/base-hw/recipes/src/base-hw_content.inc
+++ b/repos/base-hw/recipes/src/base-hw_content.inc
@@ -121,7 +121,7 @@ SRC_LIB_TIMEOUT += duration.cc \
timer_connection.cc \
timer_connection_time.cc
-SRC_LIB_STARTUP += init_main_thread.cc _main.cc \
+SRC_LIB_STARTUP += _main.cc \
$(addprefix spec/,${call selected_content,SRC_LIB_STARTUP_SPECS})
SRC_CORE += $(notdir $(wildcard $(BASE_HW_DIR)/src/core/*.cc)) \
diff --git a/repos/base/lib/mk/startup.inc b/repos/base/lib/mk/startup.inc
index f76e595c25..f9d1b874d4 100644
--- a/repos/base/lib/mk/startup.inc
+++ b/repos/base/lib/mk/startup.inc
@@ -1,5 +1,5 @@
SRC_S += crt0.s
-SRC_CC += _main.cc init_main_thread.cc
+SRC_CC += _main.cc
REP_INC_DIR += src/include
vpath %.cc $(BASE_DIR)/src/lib/startup
diff --git a/repos/base/src/lib/startup/_main.cc b/repos/base/src/lib/startup/_main.cc
index ca6baf6a5c..09d72a5acf 100644
--- a/repos/base/src/lib/startup/_main.cc
+++ b/repos/base/src/lib/startup/_main.cc
@@ -4,28 +4,117 @@
* \author Christian Prochaska
* \author Norman Feske
* \date 2006-04-12
- *
- * The startup code calls constructors for static objects before calling
- * main(). Furthermore, this file contains the support of exit handlers
- * and destructors.
*/
/*
- * Copyright (C) 2006-2017 Genode Labs GmbH
+ * 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
#include
+#include
#include
/* platform-specific local helper functions */
-#include
+#include
#include
+using namespace Genode;
+
+
+addr_t init_main_thread_result;
+
+enum { MAIN_THREAD_STACK_SIZE = 16*1024 };
+
+
+/**
+ * Satisfy crt0.s in static programs, LDSO overrides this symbol
+ */
+extern "C" void init_rtld() __attribute__((weak));
+void init_rtld()
+{
+ /* init cxa guard mechanism before any local static variables are used */
+ init_cxx_guard();
+}
+
+
+/**
+ * Lower bound of the stack, solely used for sanity checking
+ */
+extern unsigned char __initial_stack_base[];
+
+
+/**
+ * The first thread in a program
+ */
+struct Main_thread : Thread
+{
+ Main_thread()
+ :
+ Thread(Weight::DEFAULT_WEIGHT, "main", MAIN_THREAD_STACK_SIZE, Type::MAIN)
+ { }
+
+ /**********************
+ ** Thread interface **
+ **********************/
+
+ void entry() override { }
+};
+
+
+Main_thread * main_thread()
+{
+ static Main_thread s { };
+ return &s;
+}
+
+
+/**
+ * Create a thread object for the main thread
+ *
+ * \return stack pointer of the new environment via init_main_thread_result
+ *
+ * This function must be called only once per program and before the _main
+ * function. It can be called as soon as a temporary environment provides
+ * some stack space and inter-process communication. At this stage, global
+ * static objects are not registered for implicit destruction at program exit.
+ */
+extern "C" void init_main_thread()
+{
+ prepare_init_main_thread();
+
+ init_platform();
+
+ /* create a thread object for the main thread */
+ main_thread();
+
+ /**
+ * The new stack pointer enables the caller to switch from its current
+ * environment to the those that the thread object provides.
+ */
+ addr_t const sp = reinterpret_cast(main_thread()->stack_top());
+ init_main_thread_result = sp;
+
+ /*
+ * Sanity check for the usage of the initial stack
+ *
+ * Because the initial stack is located in the BSS, it is zero-initialized.
+ * We check that the stack still contains zeros at its lower boundary after
+ * executing all the initialization code.
+ */
+ enum { STACK_PAD = 256U };
+ for (unsigned i = 0; i < STACK_PAD; i++) {
+ if (__initial_stack_base[i] == 0)
+ continue;
+
+ error("initial stack overflow detected");
+ for (;;);
+ }
+}
+
void * __dso_handle = 0;
@@ -47,11 +136,6 @@ int genode_argc = 1;
char **genode_envp = 0;
-/******************************************************
- ** C entry function called by the crt0 startup code **
- ******************************************************/
-
-
namespace Genode {
/*
diff --git a/repos/base/src/lib/startup/init_main_thread.cc b/repos/base/src/lib/startup/init_main_thread.cc
deleted file mode 100644
index a3d6f954ff..0000000000
--- a/repos/base/src/lib/startup/init_main_thread.cc
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * \brief Setup the thread environment of a programs first thread
- * \author Christian Helmuth
- * \author Christian Prochaska
- * \author Martin Stein
- * \date 2013-12-04
- */
-
-/*
- * Copyright (C) 2013-2017 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
-#include
-#include
-
-/* base-internal includes */
-#include
-
-using namespace Genode;
-
-
-addr_t init_main_thread_result;
-
-namespace Genode { extern Region_map * env_stack_area_region_map; }
-
-enum { MAIN_THREAD_STACK_SIZE = 16*1024 };
-
-
-/**
- * Satisfy crt0.s in static programs, LDSO overrides this symbol
- */
-extern "C" void init_rtld() __attribute__((weak));
-void init_rtld()
-{
- /* init cxa guard mechanism before any local static variables are used */
- init_cxx_guard();
-}
-
-
-/**
- * Lower bound of the stack, solely used for sanity checking
- */
-extern unsigned char __initial_stack_base[];
-
-
-/**
- * The first thread in a program
- */
-struct Main_thread : Thread
-{
- Main_thread()
- :
- Thread(Weight::DEFAULT_WEIGHT, "main", MAIN_THREAD_STACK_SIZE, Type::MAIN)
- { }
-
- /**********************
- ** Thread interface **
- **********************/
-
- void entry() override { }
-};
-
-
-Main_thread * main_thread()
-{
- static Main_thread s { };
- return &s;
-}
-
-
-/**
- * Create a thread object for the main thread
- *
- * \return stack pointer of the new environment via init_main_thread_result
- *
- * This function must be called only once per program and before the _main
- * function. It can be called as soon as a temporary environment provides
- * some stack space and inter-process communication. At this stage, global
- * static objects are not registered for implicit destruction at program exit.
- */
-extern "C" void init_main_thread()
-{
- prepare_init_main_thread();
-
- init_platform();
-
- /* create a thread object for the main thread */
- main_thread();
-
- /**
- * The new stack pointer enables the caller to switch from its current
- * environment to the those that the thread object provides.
- */
- addr_t const sp = reinterpret_cast(main_thread()->stack_top());
- init_main_thread_result = sp;
-
- /*
- * Sanity check for the usage of the initial stack
- *
- * Because the initial stack is located in the BSS, it is zero-initialized.
- * We check that the stack still contains zeros at its lower boundary after
- * executing all the initialization code.
- */
- enum { STACK_PAD = 256U };
- for (unsigned i = 0; i < STACK_PAD; i++) {
- if (__initial_stack_base[i] == 0)
- continue;
-
- error("initial stack overflow detected");
- for (;;);
- }
-}