mirror of
https://github.com/genodelabs/genode.git
synced 2025-02-20 09:46:20 +00:00
base: setup thread object for main thread in CRT0
For a main thread a thread object is created by the CRT0 before _main gets called so that _main can already run in a generic environment that, e.g., catches stack overflows as a page-fault instead of corrupting the BSS. Additionally dynamic programs have only one CRT0 - the one of the LDSO - which does the initialization for both LDSO and program. ref #989
This commit is contained in:
parent
ba8e61653f
commit
0b64328944
@ -6,7 +6,7 @@
|
||||
|
||||
LIBS += cxx l4 startup
|
||||
|
||||
SRC_CC += cap_copy.cc main_bootstrap.cc
|
||||
SRC_CC += cap_copy.cc
|
||||
SRC_CC += ipc/ipc.cc ipc/pager.cc ipc/ipc_marshal_cap.cc
|
||||
SRC_CC += pager/pager.cc pager/common.cc
|
||||
SRC_CC += avl_tree/avl_tree.cc
|
||||
@ -28,7 +28,6 @@ INC_DIR += $(REP_DIR)/src/base/lock
|
||||
INC_DIR += $(BASE_DIR)/src/base/thread
|
||||
INC_DIR += $(REP_DIR)/include/codezero/dummies
|
||||
|
||||
vpath main_bootstrap.cc $(REP_DIR)/src/platform
|
||||
vpath cap_copy.cc $(BASE_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
vpath cap_copy.cc $(BASE_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Thread bootstrap code
|
||||
* \author Christian Prochaska
|
||||
* \author Martin Stein
|
||||
* \date 2013-02-15
|
||||
*/
|
||||
|
||||
@ -13,13 +14,83 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/env.h>
|
||||
#include <util/string.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
Genode::Native_thread_id main_thread_tid;
|
||||
Codezero::l4_mutex main_thread_running_lock;
|
||||
|
||||
|
||||
/*****************************
|
||||
** Startup library support **
|
||||
*****************************/
|
||||
|
||||
void prepare_init_main_thread()
|
||||
{
|
||||
/* initialize codezero environment */
|
||||
Codezero::__l4_init();
|
||||
|
||||
/* provide kernel identification of thread through temporary environment */
|
||||
main_thread_tid = Codezero::thread_myself();
|
||||
}
|
||||
|
||||
void prepare_reinit_main_thread() { prepare_init_main_thread(); }
|
||||
|
||||
|
||||
/****************************
|
||||
** Codezero libl4 support **
|
||||
****************************/
|
||||
|
||||
/*
|
||||
* Unfortunately, the function 'exregs_print_registers' in 'exregs.c' refers to
|
||||
* 'memset'. Because we do not want to link core against a C library, we have to
|
||||
* resolve this function here.
|
||||
*/
|
||||
extern "C" void *memset(void *s, int c, Genode::size_t n) __attribute__((weak));
|
||||
extern "C" void *memset(void *s, int c, Genode::size_t n)
|
||||
{
|
||||
return Genode::memset(s, c, n);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Same problem as for 'memset'. The 'printf' symbol is referenced from
|
||||
* 'mutex.c' and 'exregs.c' of Codezero's libl4.
|
||||
*/
|
||||
extern "C" int printf(const char *format, ...) __attribute__((weak));
|
||||
extern "C" int printf(const char *format, ...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
Genode::vprintf(format, list);
|
||||
va_end(list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** Thread_base **
|
||||
*****************/
|
||||
|
||||
void Genode::Thread_base::_thread_bootstrap()
|
||||
{
|
||||
Codezero::l4_mutex_init(utcb()->running_lock());
|
||||
Codezero::l4_mutex_lock(utcb()->running_lock()); /* block on first mutex lock */
|
||||
}
|
||||
|
||||
|
||||
void Genode::Thread_base::_init_platform_thread(Type type)
|
||||
{
|
||||
if (type == NORMAL) { return; }
|
||||
|
||||
/* adjust values whose computation differs for a main thread */
|
||||
_tid.l4id = main_thread_tid;
|
||||
_thread_cap = Genode::env()->parent()->main_thread_cap();
|
||||
|
||||
/* get first mutex lock (normally done by _thread_bootstrap) */
|
||||
Codezero::l4_mutex_init(utcb()->running_lock());
|
||||
Codezero::l4_mutex_lock(utcb()->running_lock());
|
||||
}
|
||||
|
@ -39,9 +39,6 @@ void Thread_base::_thread_start()
|
||||
** Thread base **
|
||||
*****************/
|
||||
|
||||
void Thread_base::_init_platform_thread() { }
|
||||
|
||||
|
||||
void Thread_base::_deinit_platform_thread()
|
||||
{
|
||||
env()->cpu_session()->kill_thread(_thread_cap);
|
||||
|
@ -27,10 +27,6 @@ enum { verbose_thread_start = true };
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread() { }
|
||||
|
||||
|
||||
void Thread_base::_deinit_platform_thread() { }
|
||||
|
||||
|
||||
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* \brief Platform-specific helper functions for the _main() function
|
||||
* \author Norman Feske
|
||||
* \author Christian Helmuth
|
||||
* \date 2009-10-02
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/stdint.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/thread.h>
|
||||
#include <util/string.h>
|
||||
|
||||
/* Codezero includes */
|
||||
#include <codezero/syscalls.h>
|
||||
|
||||
|
||||
/****************************
|
||||
** Codezero libl4 support **
|
||||
****************************/
|
||||
|
||||
/*
|
||||
* Unfortunately, the function 'exregs_print_registers' in 'exregs.c' refers to
|
||||
* 'memset'. Because we do not want to link core against a C library, we have to
|
||||
* resolve this function here.
|
||||
*/
|
||||
extern "C" void *memset(void *s, int c, Genode::size_t n) __attribute__((weak));
|
||||
extern "C" void *memset(void *s, int c, Genode::size_t n)
|
||||
{
|
||||
return Genode::memset(s, c, n);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Same problem as for 'memset'. The 'printf' symbol is referenced from
|
||||
* 'mutex.c' and 'exregs.c' of Codezero's libl4.
|
||||
*/
|
||||
extern "C" int printf(const char *format, ...) __attribute__((weak));
|
||||
extern "C" int printf(const char *format, ...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
Genode::vprintf(format, list);
|
||||
va_end(list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**************************
|
||||
** Startup-code helpers **
|
||||
**************************/
|
||||
|
||||
namespace Genode { void platform_main_bootstrap(); }
|
||||
|
||||
|
||||
Genode::Native_thread_id main_thread_tid;
|
||||
Codezero::l4_mutex main_thread_running_lock;
|
||||
|
||||
|
||||
void Genode::platform_main_bootstrap()
|
||||
{
|
||||
static struct Bootstrap
|
||||
{
|
||||
Bootstrap()
|
||||
{
|
||||
Codezero::__l4_init();
|
||||
|
||||
main_thread_tid = Codezero::thread_myself();
|
||||
|
||||
Codezero::l4_mutex_init(&main_thread_running_lock);
|
||||
Codezero::l4_mutex_lock(&main_thread_running_lock); /* block on first mutex lock */
|
||||
}
|
||||
} bootstrap;
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
|
||||
LIBS += cxx startup
|
||||
|
||||
SRC_CC += cap_copy.cc main_bootstrap.cc
|
||||
SRC_CC += cap_copy.cc
|
||||
SRC_CC += ipc/ipc.cc ipc/pager.cc ipc/ipc_marshal_cap.cc
|
||||
SRC_CC += pager/pager.cc pager/common.cc
|
||||
SRC_CC += avl_tree/avl_tree.cc
|
||||
@ -20,12 +20,11 @@ SRC_CC += elf/elf_binary.cc
|
||||
SRC_CC += lock/lock.cc
|
||||
SRC_CC += signal/signal.cc signal/common.cc
|
||||
SRC_CC += server/server.cc server/common.cc
|
||||
SRC_CC += thread/thread.cc thread/thread_bootstrap_empty.cc thread/trace.cc
|
||||
SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/base/lock
|
||||
INC_DIR += $(BASE_DIR)/src/base/thread
|
||||
|
||||
vpath main_bootstrap.cc $(REP_DIR)/src/platform
|
||||
vpath cap_copy.cc $(BASE_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
vpath cap_copy.cc $(BASE_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
|
41
base-fiasco/src/base/thread/thread_bootstrap.cc
Normal file
41
base-fiasco/src/base/thread/thread_bootstrap.cc
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* \brief Platform specific thread initialization
|
||||
* \author Martin Stein
|
||||
* \date 2014-01-06
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/env.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/*****************************
|
||||
** Startup library support **
|
||||
*****************************/
|
||||
|
||||
void prepare_init_main_thread() { }
|
||||
|
||||
void prepare_reinit_main_thread() { }
|
||||
|
||||
|
||||
/*****************
|
||||
** Thread_base **
|
||||
*****************/
|
||||
|
||||
void Thread_base::_thread_bootstrap() { }
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread(Type type)
|
||||
{
|
||||
if (type == NORMAL) { return; }
|
||||
_thread_cap = Genode::env()->parent()->main_thread_cap();
|
||||
}
|
@ -53,9 +53,6 @@ void Thread_base::cancel_blocking()
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread() { }
|
||||
|
||||
|
||||
void Thread_base::_deinit_platform_thread()
|
||||
{
|
||||
/* destruct platform thread */
|
||||
|
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* \brief Platform-specific helper functions for the _main() function
|
||||
* \author Christian Prochaska
|
||||
* \date 2009-08-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
namespace Genode { void platform_main_bootstrap() { /* dummy */ } }
|
@ -17,6 +17,7 @@
|
||||
#include <base/cap_map.h>
|
||||
#include <base/native_types.h>
|
||||
#include <util/assert.h>
|
||||
#include <util/construct_at.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
@ -124,6 +125,11 @@ namespace Genode {
|
||||
|
||||
bool static_idx(Cap_index *idx) {
|
||||
return ((T*)idx) < &_indices[START_IDX]; }
|
||||
|
||||
void reinit()
|
||||
{
|
||||
construct_at<Cap_index_allocator_tpl<T, SZ> >(this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -146,6 +146,11 @@ namespace Genode
|
||||
* \param idx pointer to the Cap_index object in question
|
||||
*/
|
||||
virtual bool static_idx(Cap_index *idx) = 0;
|
||||
|
||||
/**
|
||||
* Redo construction of the object
|
||||
*/
|
||||
virtual void reinit() = 0;
|
||||
};
|
||||
|
||||
|
||||
@ -196,7 +201,9 @@ namespace Genode
|
||||
* to save entries in the capability space, and prevent leaks of
|
||||
* them.
|
||||
*/
|
||||
class Capability_map : Noncopyable
|
||||
class Capability_map
|
||||
:
|
||||
private Noncopyable
|
||||
{
|
||||
private:
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
LIBS += cxx syscall startup
|
||||
|
||||
SRC_CC += main_bootstrap.cc
|
||||
SRC_CC += ipc/ipc.cc ipc/pager.cc
|
||||
SRC_CC += pager/pager.cc pager/common.cc
|
||||
SRC_CC += avl_tree/avl_tree.cc
|
||||
@ -27,8 +26,7 @@ INC_DIR += $(REP_DIR)/src/base/lock
|
||||
INC_DIR += $(BASE_DIR)/src/base/lock
|
||||
INC_DIR += $(BASE_DIR)/src/base/thread
|
||||
|
||||
vpath main_bootstrap.cc $(REP_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
|
||||
# vi: set ft=make :
|
||||
|
@ -51,24 +51,35 @@ addr_t Thread_base::Context_allocator::addr_to_base(void *addr)
|
||||
|
||||
size_t Thread_base::Context_allocator::base_to_idx(addr_t base)
|
||||
{
|
||||
return (base - Native_config::context_area_virtual_base()) /
|
||||
Native_config::context_virtual_size();
|
||||
/* the first context isn't managed through the indices */
|
||||
return ((base - Native_config::context_area_virtual_base()) /
|
||||
Native_config::context_virtual_size()) - 1;
|
||||
}
|
||||
|
||||
|
||||
addr_t Thread_base::Context_allocator::idx_to_base(size_t idx)
|
||||
{
|
||||
/* the first context isn't managed through the indices */
|
||||
return Native_config::context_area_virtual_base() +
|
||||
Native_config::context_virtual_size() +
|
||||
idx * Native_config::context_virtual_size();
|
||||
}
|
||||
|
||||
|
||||
Thread_base::Context *Thread_base::Context_allocator::alloc(Thread_base *thread_base)
|
||||
Thread_base::Context *
|
||||
Thread_base::Context_allocator::alloc(Thread_base *thread_base, bool main_thread)
|
||||
{
|
||||
Lock::Guard _lock_guard(_threads_lock);
|
||||
|
||||
try {
|
||||
return base_to_context(idx_to_base(_alloc.alloc()));
|
||||
addr_t base;
|
||||
if (main_thread) {
|
||||
/* the main-thread context isn't managed by '_alloc' */
|
||||
base = Native_config::context_area_virtual_base();
|
||||
} else {
|
||||
/* contexts besides main-thread context are managed by '_alloc' */
|
||||
base = idx_to_base(_alloc.alloc());
|
||||
}
|
||||
return base_to_context(base);
|
||||
} catch(Bit_allocator<MAX_THREADS>::Out_of_indices) {
|
||||
return 0;
|
||||
}
|
||||
@ -78,8 +89,13 @@ Thread_base::Context *Thread_base::Context_allocator::alloc(Thread_base *thread_
|
||||
void Thread_base::Context_allocator::free(Context *context)
|
||||
{
|
||||
Lock::Guard _lock_guard(_threads_lock);
|
||||
addr_t const base = addr_to_base(context);
|
||||
|
||||
_alloc.free(base_to_idx(addr_to_base(context)));
|
||||
/* the main-thread context isn't managed by '_alloc' */
|
||||
if (base == Native_config::context_area_virtual_base()) { return; }
|
||||
|
||||
/* contexts besides main-thread context are managed by '_alloc' */
|
||||
_alloc.free(base_to_idx(base));
|
||||
}
|
||||
|
||||
|
||||
@ -94,7 +110,8 @@ Thread_base::Context_allocator *Thread_base::_context_allocator()
|
||||
}
|
||||
|
||||
|
||||
Thread_base::Context *Thread_base::_alloc_context(size_t stack_size)
|
||||
Thread_base::Context *
|
||||
Thread_base::_alloc_context(size_t stack_size, bool main_thread)
|
||||
{
|
||||
/*
|
||||
* Synchronize context list when creating new threads from multiple threads
|
||||
@ -105,7 +122,7 @@ Thread_base::Context *Thread_base::_alloc_context(size_t stack_size)
|
||||
Lock::Guard _lock_guard(alloc_lock);
|
||||
|
||||
/* allocate thread context */
|
||||
Context *context = _context_allocator()->alloc(this);
|
||||
Context *context = _context_allocator()->alloc(this, main_thread);
|
||||
if (!context)
|
||||
throw Context_alloc_failed();
|
||||
|
||||
@ -201,7 +218,7 @@ void Thread_base::join()
|
||||
|
||||
void* Thread_base::alloc_secondary_stack(char const *name, size_t stack_size)
|
||||
{
|
||||
Context *context = _alloc_context(stack_size);
|
||||
Context *context = _alloc_context(stack_size, false);
|
||||
strncpy(context->name, name, sizeof(context->name));
|
||||
return (void *)context->stack_top();
|
||||
}
|
||||
@ -214,13 +231,14 @@ void Thread_base::free_secondary_stack(void* stack_addr)
|
||||
}
|
||||
|
||||
|
||||
Thread_base::Thread_base(const char *name, size_t stack_size)
|
||||
Thread_base::Thread_base(const char *name, size_t stack_size, Type const type)
|
||||
:
|
||||
_context(_alloc_context(stack_size)),
|
||||
_context(type == REINITIALIZED_MAIN ?
|
||||
_context : _alloc_context(stack_size, type == MAIN)),
|
||||
_join_lock(Lock::LOCKED)
|
||||
{
|
||||
strncpy(_context->name, name, sizeof(_context->name));
|
||||
_init_platform_thread();
|
||||
_init_platform_thread(type);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Fiasco.OC specific thread bootstrap code
|
||||
* \author Stefan Kalkowski
|
||||
* \author Martin Stein
|
||||
* \date 2011-01-20
|
||||
*/
|
||||
|
||||
@ -11,9 +12,38 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/construct_at.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
|
||||
/*****************************
|
||||
** Startup library support **
|
||||
*****************************/
|
||||
|
||||
void prepare_init_main_thread()
|
||||
{
|
||||
using namespace Genode;
|
||||
enum { THREAD_CAP_ID = 1 };
|
||||
Cap_index * ci(cap_map()->insert(THREAD_CAP_ID, Fiasco::MAIN_THREAD_CAP));
|
||||
Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE] = (unsigned long)ci;
|
||||
Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_THREAD_OBJ] = 0;
|
||||
}
|
||||
|
||||
|
||||
void prepare_reinit_main_thread()
|
||||
{
|
||||
using namespace Genode;
|
||||
construct_at<Capability_map>(cap_map());
|
||||
cap_idx_alloc()->reinit();
|
||||
prepare_init_main_thread();
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** Thread_base **
|
||||
*****************/
|
||||
|
||||
void Genode::Thread_base::_thread_bootstrap() { }
|
||||
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
* \brief Fiasco-specific implementation of the non-core startup Thread API
|
||||
* \author Norman Feske
|
||||
* \author Stefan Kalkowski
|
||||
* \author Martin Stein
|
||||
* \date 2010-01-19
|
||||
*/
|
||||
|
||||
@ -38,15 +39,26 @@ void Thread_base::_deinit_platform_thread()
|
||||
}
|
||||
|
||||
|
||||
void Genode::Thread_base::_init_platform_thread()
|
||||
void Thread_base::_init_platform_thread(Type type)
|
||||
{
|
||||
/* create thread at core */
|
||||
char buf[48];
|
||||
name(buf, sizeof(buf));
|
||||
_thread_cap = env()->cpu_session()->create_thread(buf);
|
||||
if (type == NORMAL)
|
||||
{
|
||||
/* create thread at core */
|
||||
char buf[48];
|
||||
name(buf, sizeof(buf));
|
||||
_thread_cap = env()->cpu_session()->create_thread(buf);
|
||||
|
||||
/* assign thread to protection domain */
|
||||
env()->pd_session()->bind_thread(_thread_cap);
|
||||
/* assign thread to protection domain */
|
||||
env()->pd_session()->bind_thread(_thread_cap);
|
||||
return;
|
||||
}
|
||||
/* adjust values whose computation differs for a main thread */
|
||||
_tid = Fiasco::MAIN_THREAD_CAP;
|
||||
_thread_cap = env()->parent()->main_thread_cap();
|
||||
|
||||
/* make thread object known to the Fiasco environment */
|
||||
addr_t const t = (addr_t)this;
|
||||
Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_THREAD_OBJ] = t;
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,7 +35,7 @@ void Thread_base::_deinit_platform_thread()
|
||||
}
|
||||
|
||||
|
||||
void Genode::Thread_base::_init_platform_thread() { }
|
||||
void Thread_base::_init_platform_thread(Type) { }
|
||||
|
||||
|
||||
void Thread_base::start()
|
||||
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* \brief Platform-specific helper functions for the _main() function
|
||||
* \author Christian Prochaska
|
||||
* \author Christian Helmuth
|
||||
* \date 2009-08-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/stdint.h>
|
||||
#include <base/native_types.h>
|
||||
#include <base/cap_map.h>
|
||||
|
||||
namespace Fiasco {
|
||||
#include <l4/sys/utcb.h>
|
||||
}
|
||||
|
||||
|
||||
namespace Genode { void platform_main_bootstrap(); }
|
||||
|
||||
|
||||
void Genode::platform_main_bootstrap()
|
||||
{
|
||||
static struct Bootstrap
|
||||
{
|
||||
enum { MAIN_THREAD_CAP_ID = 1 };
|
||||
|
||||
Bootstrap()
|
||||
{
|
||||
Cap_index *i(cap_map()->insert(MAIN_THREAD_CAP_ID, Fiasco::MAIN_THREAD_CAP));
|
||||
Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_BADGE] = (unsigned long) i;
|
||||
Fiasco::l4_utcb_tcr()->user[Fiasco::UTCB_TCR_THREAD_OBJ] = 0;
|
||||
}
|
||||
} bootstrap;
|
||||
}
|
@ -6,7 +6,6 @@
|
||||
|
||||
LIBS += cxx kernel_interface
|
||||
|
||||
SRC_CC += main_bootstrap.cc
|
||||
SRC_CC += ipc.cc ipc/ipc_marshal_cap.cc
|
||||
SRC_CC += avl_tree/avl_tree.cc
|
||||
SRC_CC += allocator/slab.cc
|
||||
@ -21,10 +20,9 @@ SRC_CC += signal/signal.cc signal/common.cc
|
||||
SRC_CC += server/server.cc server/common.cc
|
||||
SRC_CC += thread/thread_bootstrap.cc thread/trace.cc
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/base/lock
|
||||
INC_DIR += $(REP_DIR)/src/base/lock
|
||||
INC_DIR += $(BASE_DIR)/src/base/lock
|
||||
INC_DIR += $(BASE_DIR)/src/base/thread
|
||||
|
||||
vpath main_bootstrap.cc $(REP_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* \brief Thread bootstrap code
|
||||
* \author Christian Prochaska
|
||||
* \brief Thread initialization
|
||||
* \author Martin stein
|
||||
* \date 2013-02-15
|
||||
*/
|
||||
|
||||
@ -13,13 +13,82 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/env.h>
|
||||
|
||||
/* base-hw includes */
|
||||
#include <kernel/interface.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
void Genode::Thread_base::_thread_bootstrap()
|
||||
Ram_dataspace_capability _main_thread_utcb_ds;
|
||||
|
||||
Native_thread_id _main_thread_id;
|
||||
|
||||
namespace Genode { Rm_session * env_context_area_rm_session(); }
|
||||
|
||||
|
||||
/**************************
|
||||
** Native types support **
|
||||
**************************/
|
||||
|
||||
Native_thread_id Genode::thread_get_my_native_id()
|
||||
{
|
||||
Thread_base * const t = Thread_base::myself();
|
||||
return t ? t->tid().thread_id : _main_thread_id;
|
||||
}
|
||||
|
||||
|
||||
/*****************************
|
||||
** Startup library support **
|
||||
*****************************/
|
||||
|
||||
void prepare_init_main_thread()
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
/*
|
||||
* Make data from the startup info persistantly available by copying it
|
||||
* before the UTCB gets polluted by the following function calls.
|
||||
*/
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
_main_thread_id = utcb->start_info()->thread_id();
|
||||
_main_thread_utcb_ds =
|
||||
reinterpret_cap_cast<Ram_dataspace>(utcb->start_info()->utcb_ds());
|
||||
}
|
||||
|
||||
|
||||
void prepare_reinit_main_thread() { prepare_init_main_thread(); }
|
||||
|
||||
|
||||
/*****************
|
||||
** Thread_base **
|
||||
*****************/
|
||||
|
||||
void Thread_base::_thread_bootstrap()
|
||||
{
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
_tid.thread_id = utcb->start_info()->thread_id();
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread(Type type)
|
||||
{
|
||||
/* nothing platform specific to do if this is not a special thread */
|
||||
if (type == NORMAL) { return; }
|
||||
|
||||
/* if we got reinitialized we have to get rid of the old UTCB */
|
||||
size_t const utcb_size = sizeof(Native_utcb);
|
||||
addr_t const context_area = Native_config::context_area_virtual_base();
|
||||
addr_t const utcb_new = (addr_t)&_context->utcb - context_area;
|
||||
Rm_session * const rm = env_context_area_rm_session();
|
||||
if (type == REINITIALIZED_MAIN) { rm->detach(utcb_new); }
|
||||
|
||||
/* remap initial main-thread UTCB according to context-area spec */
|
||||
try { rm->attach_at(_main_thread_utcb_ds, utcb_new, utcb_size); }
|
||||
catch(...) {
|
||||
PERR("failed to re-map UTCB");
|
||||
while (1) ;
|
||||
}
|
||||
/* adjust initial object state in case of a main thread */
|
||||
tid().thread_id = _main_thread_id;
|
||||
}
|
||||
|
@ -26,9 +26,6 @@ namespace Genode { Rm_session * env_context_area_rm_session(); }
|
||||
** Thread_base **
|
||||
*****************/
|
||||
|
||||
void Thread_base::_init_platform_thread() { }
|
||||
|
||||
|
||||
Native_utcb * Thread_base::utcb()
|
||||
{
|
||||
if (this) { return &_context->utcb; }
|
||||
|
@ -60,11 +60,6 @@
|
||||
/* catch erroneous kernel return */
|
||||
3: b 3b
|
||||
|
||||
/* handle for dynamic symbol objects */
|
||||
.align 3
|
||||
.global __dso_handle
|
||||
__dso_handle: .long 0
|
||||
|
||||
.section .bss
|
||||
|
||||
/* kernel stack */
|
||||
|
@ -41,6 +41,7 @@ using namespace Kernel;
|
||||
|
||||
/* get core configuration */
|
||||
extern Genode::Native_utcb * _main_thread_utcb;
|
||||
extern Genode::Native_thread_id _main_thread_id;
|
||||
extern int _kernel_stack_high;
|
||||
extern "C" void CORE_MAIN();
|
||||
|
||||
@ -249,6 +250,7 @@ extern "C" void kernel()
|
||||
/* start thread with stack pointer at the top of stack */
|
||||
static Native_utcb utcb;
|
||||
static Thread t(Priority::MAX, "core");
|
||||
_main_thread_id = t.id();
|
||||
_main_thread_utcb = &utcb;
|
||||
_main_thread_utcb->start_info()->init(t.id(), Genode::Native_capability());
|
||||
t.ip = (addr_t)CORE_MAIN;;
|
||||
|
@ -53,7 +53,7 @@ void Thread_base::_thread_start()
|
||||
}
|
||||
|
||||
|
||||
Thread_base::Thread_base(const char * const label, size_t const stack_size)
|
||||
Thread_base::Thread_base(const char * const label, size_t const stack_size, Type)
|
||||
{
|
||||
_tid.platform_thread = new (platform()->core_mem_alloc())
|
||||
Platform_thread(stack_size, Kernel::core_id(), label);
|
||||
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* \brief Platform-specific helper functions for the _main() function
|
||||
* \author Martin Stein
|
||||
* \author Christian Helmuth
|
||||
* \date 2010-09-13
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/native_types.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
namespace Genode { void platform_main_bootstrap(); }
|
||||
|
||||
Native_thread_id _main_thread_id;
|
||||
|
||||
|
||||
Native_thread_id Genode::thread_get_my_native_id()
|
||||
{
|
||||
Thread_base * const t = Thread_base::myself();
|
||||
return t ? t->tid().thread_id : _main_thread_id;
|
||||
}
|
||||
|
||||
|
||||
void Genode::platform_main_bootstrap()
|
||||
{
|
||||
/* go save against multiple calls e.g. for programs with dynamic linker */
|
||||
static bool main_thread_id_valid = 0;
|
||||
if (!main_thread_id_valid) {
|
||||
Native_utcb * const utcb = Thread_base::myself()->utcb();
|
||||
_main_thread_id = utcb->start_info()->thread_id();
|
||||
main_thread_id_valid = 1;
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@
|
||||
#ifndef _INCLUDE__RM_SESSION__CLIENT_H_
|
||||
#define _INCLUDE__RM_SESSION__CLIENT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <rm_session/capability.h>
|
||||
|
||||
namespace Genode {
|
||||
@ -22,6 +23,8 @@ namespace Genode {
|
||||
{
|
||||
Rm_session_capability const _cap;
|
||||
|
||||
typedef Rm_session Rpc_interface;
|
||||
|
||||
/**
|
||||
* Return pointer to locally implemented RM session
|
||||
*
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
LIBS += syscall
|
||||
|
||||
SRC_CC += main_bootstrap.cc
|
||||
SRC_CC += ipc/ipc.cc
|
||||
SRC_CC += avl_tree/avl_tree.cc
|
||||
SRC_CC += allocator/slab.cc
|
||||
@ -20,7 +19,7 @@ SRC_CC += lock/lock.cc
|
||||
SRC_CC += env/rm_session_mmap.cc env/debug.cc
|
||||
SRC_CC += signal/signal.cc signal/common.cc
|
||||
SRC_CC += server/server.cc server/common.cc
|
||||
SRC_CC += thread/trace.cc
|
||||
SRC_CC += thread/trace.cc thread/thread_env.cc
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/base/lock $(BASE_DIR)/src/base/lock
|
||||
INC_DIR += $(REP_DIR)/src/base/ipc
|
||||
@ -28,6 +27,5 @@ INC_DIR += $(REP_DIR)/src/base/env $(BASE_DIR)/src/base/env
|
||||
INC_DIR += $(REP_DIR)/src/platform $(BASE_DIR)/src/platform
|
||||
INC_DIR += $(BASE_DIR)/src/base/thread
|
||||
|
||||
vpath main_bootstrap.cc $(REP_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
|
4
base-linux/src/base/env/platform_env.cc
vendored
4
base-linux/src/base/env/platform_env.cc
vendored
@ -154,6 +154,10 @@ Platform_env::Local_parent &Platform_env::_parent()
|
||||
}
|
||||
|
||||
|
||||
void Platform_env::reinit(Native_capability::Dst, long) { }
|
||||
void Platform_env::reinit_main_thread(Rm_session_capability &) { }
|
||||
|
||||
|
||||
Platform_env::Platform_env()
|
||||
:
|
||||
Platform_env_base(static_cap_cast<Ram_session>(_parent().session("Env::ram_session", "")),
|
||||
|
14
base-linux/src/base/env/platform_env.h
vendored
14
base-linux/src/base/env/platform_env.h
vendored
@ -432,13 +432,15 @@ namespace Genode {
|
||||
*/
|
||||
~Platform_env() { _parent().exit(0); }
|
||||
|
||||
/**
|
||||
* Reload parent capability and reinitialize environment resources
|
||||
/*
|
||||
* Support functions for implementing fork on Noux.
|
||||
*
|
||||
* Not supported on Linux.
|
||||
*
|
||||
* See the documentation in 'base/src/base/env/platform_env.h'
|
||||
*/
|
||||
void reload_parent_cap(Capability<Parent>::Dst, long)
|
||||
{
|
||||
/* not supported on Linux */
|
||||
}
|
||||
void reinit(Native_capability::Dst, long);
|
||||
void reinit_main_thread(Rm_session_capability &);
|
||||
|
||||
|
||||
/*************************************
|
||||
|
49
base-linux/src/base/thread/thread_env.cc
Normal file
49
base-linux/src/base/thread/thread_env.cc
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* \brief Thread-environment support common to all programs
|
||||
* \author Martin Stein
|
||||
* \date 2013-12-13
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/stdint.h>
|
||||
#include <base/env.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern addr_t * __initial_sp;
|
||||
|
||||
/*
|
||||
* Define 'lx_environ' pointer.
|
||||
*/
|
||||
char **lx_environ;
|
||||
|
||||
/**
|
||||
* Natively aligned memory location used in the lock implementation
|
||||
*/
|
||||
int main_thread_futex_counter __attribute__((aligned(sizeof(addr_t))));
|
||||
|
||||
|
||||
/*****************************
|
||||
** Startup library support **
|
||||
*****************************/
|
||||
|
||||
void prepare_init_main_thread()
|
||||
{
|
||||
/*
|
||||
* Initialize the 'lx_environ' pointer
|
||||
*
|
||||
* environ = &argv[argc + 1]
|
||||
* __initial_sp[0] = argc (always 1 in Genode)
|
||||
* __initial_sp[1] = argv[0]
|
||||
* __initial_sp[2] = NULL
|
||||
* __initial_sp[3] = environ
|
||||
*/
|
||||
lx_environ = (char**)&__initial_sp[3];
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Implementation of the Thread API via Linux threads
|
||||
* \author Norman Feske
|
||||
* \author Martin Stein
|
||||
* \date 2006-06-13
|
||||
*/
|
||||
|
||||
@ -23,6 +24,7 @@
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern int main_thread_futex_counter;
|
||||
|
||||
static void empty_signal_handler(int) { }
|
||||
|
||||
@ -67,9 +69,16 @@ void Thread_base::_thread_start()
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread()
|
||||
void Thread_base::_init_platform_thread(Type type)
|
||||
{
|
||||
_thread_cap = env()->cpu_session()->create_thread(_context->name);
|
||||
/* for normal threads create an object at the CPU session */
|
||||
if (type == NORMAL) {
|
||||
_thread_cap = env()->cpu_session()->create_thread(_context->name);
|
||||
return;
|
||||
}
|
||||
/* adjust initial object state for main threads */
|
||||
tid().futex_counter = main_thread_futex_counter;
|
||||
_thread_cap = env()->parent()->main_thread_cap();
|
||||
}
|
||||
|
||||
|
||||
|
@ -46,7 +46,7 @@ void Thread_base::_thread_start()
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread() { }
|
||||
void Thread_base::_init_platform_thread(Type) { }
|
||||
|
||||
|
||||
void Thread_base::_deinit_platform_thread() { }
|
||||
|
@ -401,7 +401,7 @@ void Thread_base::join()
|
||||
}
|
||||
|
||||
|
||||
Thread_base::Thread_base(const char *name, size_t stack_size)
|
||||
Thread_base::Thread_base(const char *name, size_t stack_size, Type)
|
||||
{
|
||||
_tid.meta_data = new (env()->heap()) Thread_meta_data_created(this);
|
||||
|
||||
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* \brief Platform-specific helper functions for the _main() function
|
||||
* \author Christian Prochaska
|
||||
* \author Christian Helmuth
|
||||
* \date 2009-08-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <base/thread.h>
|
||||
#include <linux_syscalls.h>
|
||||
|
||||
|
||||
namespace Genode { void platform_main_bootstrap(); }
|
||||
|
||||
|
||||
/*
|
||||
* Define 'lx_environ' pointer.
|
||||
*/
|
||||
char **lx_environ;
|
||||
|
||||
|
||||
/**
|
||||
* Natively aligned memory location used in the lock implementation
|
||||
*/
|
||||
int main_thread_futex_counter __attribute__((aligned(sizeof(Genode::addr_t))));
|
||||
|
||||
|
||||
/**
|
||||
* Initial value of SP register (in crt0)
|
||||
*/
|
||||
extern Genode::addr_t *__initial_sp;
|
||||
|
||||
|
||||
/**
|
||||
* Platform-specific bootstrap
|
||||
*/
|
||||
void Genode::platform_main_bootstrap()
|
||||
{
|
||||
static struct Bootstrap
|
||||
{
|
||||
Bootstrap()
|
||||
{
|
||||
/*
|
||||
* Initialize the 'lx_environ' pointer
|
||||
*
|
||||
* environ = &argv[argc + 1]
|
||||
* __initial_sp[0] = argc (always 1 in Genode)
|
||||
* __initial_sp[1] = argv[0]
|
||||
* __initial_sp[2] = NULL
|
||||
* __initial_sp[3] = environ
|
||||
*/
|
||||
lx_environ = (char**)&__initial_sp[3];
|
||||
}
|
||||
} bootstrap;
|
||||
}
|
@ -102,7 +102,7 @@ namespace Genode {
|
||||
};
|
||||
|
||||
|
||||
class Capability_map : Noncopyable
|
||||
class Capability_map : private Noncopyable
|
||||
{
|
||||
private:
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
|
||||
LIBS += cxx startup
|
||||
|
||||
SRC_CC += main_bootstrap.cc
|
||||
SRC_CC += ipc/ipc.cc ipc/pager.cc
|
||||
SRC_CC += avl_tree/avl_tree.cc
|
||||
SRC_CC += allocator/slab.cc
|
||||
@ -26,8 +25,7 @@ INC_DIR += $(REP_DIR)/src/base/lock
|
||||
INC_DIR += $(BASE_DIR)/src/base/lock
|
||||
INC_DIR += $(BASE_DIR)/src/base/thread
|
||||
|
||||
vpath main_bootstrap.cc $(REP_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
|
||||
# vi: set ft=make :
|
||||
|
@ -7,8 +7,7 @@
|
||||
LIBS += base-common
|
||||
|
||||
SRC_CC += console/log_console.cc
|
||||
SRC_CC += env/env.cc env/main_thread.cc \
|
||||
env/context_area.cc env/reinitialize.cc
|
||||
SRC_CC += env/env.cc env/context_area.cc env/reinitialize.cc
|
||||
SRC_CC += thread/thread_nova.cc
|
||||
|
||||
INC_DIR += $(BASE_DIR)/src/base/env
|
||||
|
31
base-nova/src/base/env/main_thread.cc
vendored
31
base-nova/src/base/env/main_thread.cc
vendored
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* \brief Information about the main thread
|
||||
* \author Norman Feske
|
||||
* \author Alexander Boettcher
|
||||
* \date 2010-01-19
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/native_types.h>
|
||||
|
||||
/* NOVA includes */
|
||||
#include <nova/syscalls.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
Native_utcb *main_thread_utcb()
|
||||
{
|
||||
return reinterpret_cast<Native_utcb *>(
|
||||
Native_config::context_area_virtual_base() +
|
||||
Native_config::context_area_virtual_size() - Nova::PAGE_SIZE_BYTE);
|
||||
}
|
||||
|
||||
|
||||
addr_t main_thread_running_semaphore() { return Nova::SM_SEL_EC; }
|
@ -1,6 +1,8 @@
|
||||
/*
|
||||
* \brief Thread-context specific part of the thread library
|
||||
* \author Norman Feske
|
||||
* \author Alexander Boettcher
|
||||
* \author Martin Stein
|
||||
* \date 2010-01-19
|
||||
*
|
||||
* This part of the thread library is required by the IPC framework
|
||||
@ -14,13 +16,98 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/construct_at.h>
|
||||
#include <base/env.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
/* base-nova includes */
|
||||
#include <base/cap_map.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern addr_t __initial_sp;
|
||||
|
||||
Native_utcb *main_thread_utcb();
|
||||
|
||||
/*******************
|
||||
** local helpers **
|
||||
*******************/
|
||||
|
||||
Native_utcb * main_thread_utcb()
|
||||
{
|
||||
using namespace Genode;
|
||||
return reinterpret_cast<Native_utcb *>(
|
||||
Native_config::context_area_virtual_base() +
|
||||
Native_config::context_virtual_size() - Nova::PAGE_SIZE_BYTE);
|
||||
}
|
||||
|
||||
|
||||
addr_t main_thread_running_semaphore() { return Nova::SM_SEL_EC; }
|
||||
|
||||
|
||||
class Initial_cap_range : public Cap_range
|
||||
{
|
||||
private:
|
||||
|
||||
enum { CAP_RANGE_START = 4096 };
|
||||
|
||||
public:
|
||||
|
||||
Initial_cap_range() : Cap_range(CAP_RANGE_START) { }
|
||||
};
|
||||
|
||||
|
||||
Initial_cap_range * initial_cap_range()
|
||||
{
|
||||
static Initial_cap_range s;
|
||||
return &s;
|
||||
}
|
||||
|
||||
|
||||
/*****************************
|
||||
** Startup library support **
|
||||
*****************************/
|
||||
|
||||
void prepare_init_main_thread()
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
cap_map()->insert(initial_cap_range());
|
||||
|
||||
/* for Core we can't perform the following code so early */
|
||||
if (!__initial_sp) {
|
||||
|
||||
enum { CAP_RANGES = 16 };
|
||||
|
||||
unsigned index = initial_cap_range()->base() +
|
||||
initial_cap_range()->elements();
|
||||
|
||||
static char local[CAP_RANGES][sizeof(Cap_range)];
|
||||
|
||||
for (unsigned i = 0; i < CAP_RANGES; i++) {
|
||||
|
||||
Cap_range * range = reinterpret_cast<Cap_range *>(local[i]);
|
||||
*range = Cap_range(index);
|
||||
|
||||
cap_map()->insert(range);
|
||||
|
||||
index = range->base() + range->elements();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void prepare_reinit_main_thread()
|
||||
{
|
||||
using namespace Genode;
|
||||
construct_at<Capability_map>(cap_map());
|
||||
construct_at<Initial_cap_range>(initial_cap_range());
|
||||
prepare_init_main_thread();
|
||||
}
|
||||
|
||||
|
||||
/*****************
|
||||
** Thread_base **
|
||||
*****************/
|
||||
|
||||
Native_utcb *Thread_base::utcb()
|
||||
{
|
||||
@ -34,5 +121,3 @@ Native_utcb *Thread_base::utcb()
|
||||
|
||||
return &_context->utcb;
|
||||
}
|
||||
|
||||
|
||||
|
@ -66,7 +66,7 @@ void Thread_base::_thread_start()
|
||||
** Thread base **
|
||||
*****************/
|
||||
|
||||
void Thread_base::_init_platform_thread()
|
||||
void Thread_base::_init_platform_thread(Type type)
|
||||
{
|
||||
using namespace Nova;
|
||||
|
||||
@ -74,7 +74,15 @@ void Thread_base::_init_platform_thread()
|
||||
* Allocate capability selectors for the thread's execution context,
|
||||
* running semaphore and exception handler portals.
|
||||
*/
|
||||
_tid.ec_sel = Native_thread::INVALID_INDEX;
|
||||
_tid.ec_sel = Native_thread::INVALID_INDEX;
|
||||
|
||||
/* for main threads the member initialization differs */
|
||||
if (type == MAIN || type == REINITIALIZED_MAIN) {
|
||||
_thread_cap = env()->parent()->main_thread_cap();
|
||||
_tid.exc_pt_sel = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
_tid.exc_pt_sel = cap_map()->insert(NUM_INITIAL_PT_LOG2);
|
||||
if (_tid.exc_pt_sel == Native_thread::INVALID_INDEX)
|
||||
throw Cpu_session::Thread_creation_failed();
|
||||
|
@ -106,7 +106,7 @@ int Platform_thread::start(void *ip, void *sp)
|
||||
|
||||
if (!is_vcpu()) {
|
||||
pd_utcb = Native_config::context_area_virtual_base() +
|
||||
Native_config::context_area_virtual_size() - get_page_size();
|
||||
Native_config::context_virtual_size() - get_page_size();
|
||||
|
||||
addr_t remap_src[] = { _pd->parent_pt_sel() };
|
||||
addr_t remap_dst[] = { PT_SEL_PARENT };
|
||||
|
@ -27,7 +27,6 @@ SRC_CC = main.cc \
|
||||
signal_source_component.cc \
|
||||
trace_session_component.cc \
|
||||
core_rm_session.cc \
|
||||
main_thread.cc \
|
||||
context_area.cc \
|
||||
echo.cc \
|
||||
dump_alloc.cc \
|
||||
@ -59,5 +58,4 @@ vpath platform_services.cc $(GEN_CORE_DIR)/x86
|
||||
vpath context_area.cc $(GEN_CORE_DIR)
|
||||
vpath core_printf.cc $(BASE_DIR)/src/base/console
|
||||
vpath %.cc $(REP_DIR)/src/core
|
||||
vpath main_thread.cc $(REP_DIR)/src/base/env
|
||||
vpath pager.cc $(REP_DIR)/src/base/pager
|
||||
|
@ -27,7 +27,7 @@
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread()
|
||||
void Thread_base::_init_platform_thread(Type type)
|
||||
{
|
||||
/*
|
||||
* This function is called for constructing server activations and pager
|
||||
@ -36,6 +36,20 @@ void Thread_base::_init_platform_thread()
|
||||
*/
|
||||
using namespace Nova;
|
||||
|
||||
if (type == MAIN)
|
||||
{
|
||||
/* set EC selector according to NOVA spec */
|
||||
_tid.ec_sel = Platform_pd::pd_core_sel() + 1;
|
||||
|
||||
/*
|
||||
* Exception base of first thread in core is 0. We have to set
|
||||
* it here so that Thread_base code finds the semaphore of the
|
||||
* main thread.
|
||||
*/
|
||||
_tid.exc_pt_sel = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
_tid.ec_sel = cap_map()->insert(1);
|
||||
_tid.exc_pt_sel = cap_map()->insert(NUM_INITIAL_PT_LOG2);
|
||||
addr_t pd_sel = Platform_pd::pd_core_sel();
|
||||
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* \brief Platform-specific helper functions for the _main() function
|
||||
* \author Norman Feske
|
||||
* \author Sebastian Sumpf
|
||||
* \date 2009-12-28
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <base/cap_map.h>
|
||||
#include <base/env.h>
|
||||
|
||||
#include <base/printf.h>
|
||||
|
||||
namespace Genode { void platform_main_bootstrap(); }
|
||||
|
||||
enum { CAP_RANGE_START = 4096 };
|
||||
|
||||
Genode::Cap_range * initial_range()
|
||||
{
|
||||
static Genode::Cap_range range(CAP_RANGE_START);
|
||||
return ⦥
|
||||
}
|
||||
|
||||
extern "C" Genode::addr_t __initial_sp;
|
||||
|
||||
void Genode::platform_main_bootstrap()
|
||||
{
|
||||
static struct Bootstrap
|
||||
{
|
||||
Bootstrap()
|
||||
{
|
||||
cap_map()->insert(initial_range());
|
||||
|
||||
/* for Core we can't perform the following code so early */
|
||||
if (__initial_sp)
|
||||
return;
|
||||
|
||||
unsigned index = initial_range()->base() + initial_range()->elements();
|
||||
|
||||
/*
|
||||
printf("initial selector range [0x%8lx:0x%8lx)\n",
|
||||
initial_range()->base(), initial_range()->base() +
|
||||
initial_range()->elements());
|
||||
*/
|
||||
|
||||
for (unsigned i = 0; i < 16; i++) {
|
||||
|
||||
Ram_dataspace_capability ds = env()->ram_session()->alloc(4096);
|
||||
addr_t local = env()->rm_session()->attach(ds);
|
||||
|
||||
Cap_range * range = reinterpret_cast<Cap_range *>(local);
|
||||
*range = Cap_range(index);
|
||||
|
||||
cap_map()->insert(range);
|
||||
|
||||
/*
|
||||
printf("add cap selector range [0x%8lx:0x%8lx)\n",
|
||||
range->base(), range->base() + range->elements());
|
||||
*/
|
||||
|
||||
index = range->base() + range->elements();
|
||||
}
|
||||
}
|
||||
} bootstrap;
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
|
||||
LIBS += cxx startup
|
||||
|
||||
SRC_CC += cap_copy.cc main_bootstrap.cc
|
||||
SRC_CC += cap_copy.cc
|
||||
SRC_CC += ipc/ipc.cc ipc/pager.cc ipc/ipc_marshal_cap.cc
|
||||
SRC_CC += pager/pager.cc pager/common.cc
|
||||
SRC_CC += avl_tree/avl_tree.cc
|
||||
@ -25,7 +25,6 @@ SRC_CC += thread/thread.cc thread/thread_bootstrap.cc thread/trace.cc
|
||||
INC_DIR += $(REP_DIR)/src/base/lock
|
||||
INC_DIR += $(BASE_DIR)/src/base/thread
|
||||
|
||||
vpath main_bootstrap.cc $(REP_DIR)/src/platform
|
||||
vpath cap_copy.cc $(BASE_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
vpath cap_copy.cc $(BASE_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Default thread bootstrap code
|
||||
* \author Norman Feske
|
||||
* \author Martin Stein
|
||||
* \date 2009-04-02
|
||||
*/
|
||||
|
||||
@ -11,19 +12,74 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
|
||||
namespace Okl4 { extern "C" {
|
||||
#include <l4/utcb.h>
|
||||
#include <l4/thread.h>
|
||||
} }
|
||||
|
||||
namespace Okl4 {
|
||||
extern L4_Word_t copy_uregister_to_utcb(void);
|
||||
/* OKL4 includes */
|
||||
namespace Okl4
|
||||
{
|
||||
extern "C" {
|
||||
#include <l4/utcb.h>
|
||||
#include <l4/thread.h>
|
||||
}
|
||||
}
|
||||
|
||||
Genode::Native_thread_id main_thread_tid;
|
||||
|
||||
|
||||
/*******************
|
||||
** local helpers **
|
||||
*******************/
|
||||
|
||||
namespace Okl4
|
||||
{
|
||||
/*
|
||||
* Read global thread ID from user-defined handle and store it
|
||||
* into a designated UTCB entry.
|
||||
*/
|
||||
L4_Word_t copy_uregister_to_utcb()
|
||||
{
|
||||
using namespace Okl4;
|
||||
|
||||
L4_Word_t my_global_id = L4_UserDefinedHandle();
|
||||
__L4_TCR_Set_ThreadWord(Genode::UTCB_TCR_THREAD_WORD_MYSELF,
|
||||
my_global_id);
|
||||
return my_global_id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************
|
||||
** Startup library support **
|
||||
*****************************/
|
||||
|
||||
void prepare_init_main_thread()
|
||||
{
|
||||
/* copy thread ID to utcb */
|
||||
main_thread_tid.raw = Okl4::copy_uregister_to_utcb();
|
||||
|
||||
/* adjust main-thread ID if this is the main thread of core */
|
||||
if (main_thread_tid.raw == 0) {
|
||||
main_thread_tid.raw = Okl4::L4_rootserver.raw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void prepare_reinit_main_thread() { prepare_init_main_thread(); }
|
||||
|
||||
|
||||
/*****************
|
||||
** Thread_base **
|
||||
*****************/
|
||||
|
||||
void Genode::Thread_base::_thread_bootstrap()
|
||||
{
|
||||
_tid.l4id.raw = Okl4::copy_uregister_to_utcb();
|
||||
}
|
||||
|
||||
|
||||
void Genode::Thread_base::_init_platform_thread(Type type)
|
||||
{
|
||||
if (type == NORMAL) { return; }
|
||||
_tid.l4id.raw = main_thread_tid.raw;
|
||||
}
|
||||
|
@ -50,9 +50,6 @@ void Thread_base::cancel_blocking()
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread() { }
|
||||
|
||||
|
||||
void Thread_base::_deinit_platform_thread()
|
||||
{
|
||||
/* destruct platform thread */
|
||||
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* \brief Platform-specific helper functions for the _main() function
|
||||
* \author Christian Prochaska
|
||||
* \author Christian Helmuth
|
||||
* \date 2009-08-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/native_types.h>
|
||||
|
||||
/* OKL4-specific includes and definitions */
|
||||
namespace Okl4 { extern "C" {
|
||||
#include <l4/utcb.h>
|
||||
#include <l4/thread.h>
|
||||
} }
|
||||
|
||||
|
||||
namespace Okl4 {
|
||||
|
||||
/*
|
||||
* Read global thread ID from user-defined handle and store it
|
||||
* into a designated UTCB entry.
|
||||
*/
|
||||
L4_Word_t copy_uregister_to_utcb()
|
||||
{
|
||||
using namespace Okl4;
|
||||
|
||||
L4_Word_t my_global_id = L4_UserDefinedHandle();
|
||||
__L4_TCR_Set_ThreadWord(Genode::UTCB_TCR_THREAD_WORD_MYSELF,
|
||||
my_global_id);
|
||||
return my_global_id;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace Genode { void platform_main_bootstrap(); }
|
||||
|
||||
|
||||
Genode::Native_thread_id main_thread_tid;
|
||||
|
||||
|
||||
void Genode::platform_main_bootstrap()
|
||||
{
|
||||
static struct Bootstrap
|
||||
{
|
||||
Bootstrap()
|
||||
{
|
||||
/* copy thread ID to utcb */
|
||||
main_thread_tid.raw = Okl4::copy_uregister_to_utcb();
|
||||
|
||||
if (main_thread_tid.raw == 0) /* core */
|
||||
main_thread_tid.raw = Okl4::L4_rootserver.raw;
|
||||
}
|
||||
} bootstrap;
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
|
||||
LIBS += cxx startup
|
||||
|
||||
SRC_CC += cap_copy.cc main_bootstrap.cc
|
||||
SRC_CC += cap_copy.cc
|
||||
SRC_CC += ipc/ipc.cc ipc/pager.cc ipc/ipc_marshal_cap.cc
|
||||
SRC_CC += pager/pager.cc pager/common.cc
|
||||
SRC_CC += avl_tree/avl_tree.cc
|
||||
@ -25,7 +25,6 @@ SRC_CC += thread/thread.cc thread/trace.cc thread/thread_bootstrap.cc
|
||||
INC_DIR += $(REP_DIR)/src/base/lock
|
||||
INC_DIR += $(BASE_DIR)/src/base/thread
|
||||
|
||||
vpath main_bootstrap.cc $(REP_DIR)/src/platform
|
||||
vpath cap_copy.cc $(BASE_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
vpath cap_copy.cc $(BASE_DIR)/src/platform
|
||||
vpath %.cc $(REP_DIR)/src/base
|
||||
vpath %.cc $(BASE_DIR)/src/base
|
||||
|
@ -15,11 +15,38 @@
|
||||
#include <base/thread.h>
|
||||
|
||||
/* Pistachio includes */
|
||||
namespace Pistachio {
|
||||
#include <l4/thread.h>
|
||||
namespace Pistachio
|
||||
{
|
||||
#include <l4/thread.h>
|
||||
}
|
||||
|
||||
Genode::Native_thread_id main_thread_tid;
|
||||
|
||||
|
||||
/*****************************
|
||||
** Startup library support **
|
||||
*****************************/
|
||||
|
||||
void prepare_init_main_thread()
|
||||
{
|
||||
main_thread_tid = Pistachio::L4_Myself();
|
||||
}
|
||||
|
||||
void prepare_reinit_main_thread() { prepare_init_main_thread(); }
|
||||
|
||||
|
||||
/*****************
|
||||
** Thread_base **
|
||||
*****************/
|
||||
|
||||
void Genode::Thread_base::_thread_bootstrap()
|
||||
{
|
||||
_tid.l4id = Pistachio::L4_Myself();
|
||||
}
|
||||
|
||||
|
||||
void Genode::Thread_base::_init_platform_thread(Type type)
|
||||
{
|
||||
if (type == NORMAL) { return; }
|
||||
_tid.l4id = main_thread_tid;
|
||||
}
|
||||
|
@ -53,9 +53,6 @@ void Thread_base::cancel_blocking()
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread() { }
|
||||
|
||||
|
||||
void Thread_base::_deinit_platform_thread()
|
||||
{
|
||||
/* destruct platform thread */
|
||||
|
@ -1,36 +0,0 @@
|
||||
/*
|
||||
* \brief Platform-specific helper functions for the _main() function
|
||||
* \author Christian Prochaska
|
||||
* \author Christian Helmuth
|
||||
* \date 2009-08-05
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/native_types.h>
|
||||
|
||||
/* Pistachio includes */
|
||||
namespace Pistachio {
|
||||
#include <l4/thread.h>
|
||||
}
|
||||
|
||||
|
||||
namespace Genode { void platform_main_bootstrap(); }
|
||||
|
||||
|
||||
Genode::Native_thread_id main_thread_tid;
|
||||
|
||||
|
||||
void Genode::platform_main_bootstrap()
|
||||
{
|
||||
static struct Bootstrap
|
||||
{
|
||||
Bootstrap() { main_thread_tid = Pistachio::L4_Myself(); }
|
||||
} bootstrap;
|
||||
}
|
@ -73,20 +73,6 @@ namespace Genode {
|
||||
* Heap backed by the ram_session of the environment.
|
||||
*/
|
||||
virtual Allocator *heap() = 0;
|
||||
|
||||
/**
|
||||
* Reload parent capability and reinitialize environment resources
|
||||
*
|
||||
* This function is solely used for implementing fork semantics.
|
||||
* After forking a process, the new child process is executed
|
||||
* within a copy of the address space of the forking process.
|
||||
* Thereby, the new process inherits the original 'env' object of
|
||||
* the forking process, which is meaningless in the context of the
|
||||
* new process. By calling this function, the new process is able
|
||||
* to reinitialize its 'env' with meaningful capabilities obtained
|
||||
* via its updated parent capability.
|
||||
*/
|
||||
virtual void reload_parent_cap(Capability<Parent>::Dst, long) = 0;
|
||||
};
|
||||
|
||||
extern Env *env();
|
||||
|
@ -185,11 +185,13 @@ namespace Genode {
|
||||
/**
|
||||
* Allocate thread context for specified thread
|
||||
*
|
||||
* \param thread thread for which to allocate the new context
|
||||
* \return virtual address of new thread context, or
|
||||
* 0 if the allocation failed
|
||||
* \param thread thread for which to allocate the new context
|
||||
* \param main_thread wether to alloc for the main thread
|
||||
*
|
||||
* \return virtual address of new thread context, or
|
||||
* 0 if the allocation failed
|
||||
*/
|
||||
Context *alloc(Thread_base *thread);
|
||||
Context *alloc(Thread_base *thread, bool main_thread);
|
||||
|
||||
/**
|
||||
* Release thread context
|
||||
@ -224,8 +226,11 @@ namespace Genode {
|
||||
|
||||
/**
|
||||
* Allocate and locally attach a new thread context
|
||||
*
|
||||
* \param stack_size size of this threads stack
|
||||
* \param main_thread wether this is the main thread
|
||||
*/
|
||||
Context *_alloc_context(size_t stack_size);
|
||||
Context *_alloc_context(size_t stack_size, bool main_thread);
|
||||
|
||||
/**
|
||||
* Detach and release thread context of the thread
|
||||
@ -246,11 +251,6 @@ namespace Genode {
|
||||
*/
|
||||
static void _thread_start();
|
||||
|
||||
/**
|
||||
* Hook for platform-specific constructor supplements
|
||||
*/
|
||||
void _init_platform_thread();
|
||||
|
||||
/**
|
||||
* Hook for platform-specific destructor supplements
|
||||
*/
|
||||
@ -285,6 +285,14 @@ namespace Genode {
|
||||
*/
|
||||
Genode::Lock _join_lock;
|
||||
|
||||
/**
|
||||
* Thread type
|
||||
*
|
||||
* Some threads need special treatment at construction. This enum
|
||||
* is solely used to distinguish them at construction.
|
||||
*/
|
||||
enum Type { NORMAL, MAIN, REINITIALIZED_MAIN };
|
||||
|
||||
private:
|
||||
|
||||
Trace::Logger _trace_logger;
|
||||
@ -296,6 +304,13 @@ namespace Genode {
|
||||
*/
|
||||
static Trace::Logger *_logger();
|
||||
|
||||
/**
|
||||
* Hook for platform-specific constructor supplements
|
||||
*
|
||||
* \param main_thread wether this is the main thread
|
||||
*/
|
||||
void _init_platform_thread(Type type);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
@ -303,6 +318,7 @@ namespace Genode {
|
||||
*
|
||||
* \param name thread name for debugging
|
||||
* \param stack_size stack size
|
||||
* \param type enables selection of special construction
|
||||
*
|
||||
* \throw Stack_too_large
|
||||
* \throw Stack_alloc_failed
|
||||
@ -313,8 +329,14 @@ namespace Genode {
|
||||
* stack size is internally used by the framework for storing
|
||||
* thread-context information such as the thread's name (see
|
||||
* 'struct Context').
|
||||
*
|
||||
* FIXME: With type = Forked_main_thread the whole
|
||||
* Context::_alloc_context call gets skipped but we should
|
||||
* at least set Context::ds_cap in a way that it references
|
||||
* the dataspace of the already attached stack.
|
||||
*/
|
||||
Thread_base(const char *name, size_t stack_size);
|
||||
Thread_base(const char *name, size_t stack_size,
|
||||
Type type = NORMAL);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
@ -448,9 +470,10 @@ namespace Genode {
|
||||
* Constructor
|
||||
*
|
||||
* \param name thread name (for debugging)
|
||||
* \param type enables selection of special construction
|
||||
*/
|
||||
explicit Thread(const char *name)
|
||||
: Thread_base(name, STACK_SIZE) { }
|
||||
explicit Thread(const char *name, Type type = NORMAL)
|
||||
: Thread_base(name, STACK_SIZE, type) { }
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
SRC_S += crt0.s
|
||||
SRC_CC += _main.cc
|
||||
SRC_CC += init_main_thread.cc
|
||||
|
||||
REP_INC_DIR += src/platform
|
||||
|
||||
LIBS += syscall
|
||||
|
||||
vpath _main.cc $(BASE_DIR)/src/platform
|
||||
vpath init_main_thread.cc $(BASE_DIR)/src/platform
|
||||
|
@ -84,6 +84,15 @@ LIBS += $(BASE_LIBS)
|
||||
else
|
||||
LIBS := $(filter-out $(BASE_LIBS),$(LIBS))
|
||||
LIBS += $(DYNAMIC_LINKER)
|
||||
|
||||
#
|
||||
# Ensure that startup_dyn is build for the dynamic programs that depend on a
|
||||
# shared library. They add it to their dependencies as replacement for the
|
||||
# static-case startup as soon as they recognize that they are dynamic.
|
||||
# The current library in contrast filters-out startup_dyn from its
|
||||
# dependencies before they get merged.
|
||||
#
|
||||
LIBS += startup_dyn
|
||||
endif
|
||||
|
||||
|
||||
|
@ -125,9 +125,15 @@ $(LIB_A): $(OBJECTS)
|
||||
$(VERBOSE)$(AR) -rc $@ $(OBJECTS)
|
||||
|
||||
#
|
||||
# Prevent linkage of startup code against shared libraries except for ld.lib.so
|
||||
# Prevent linkage of startup_dyn as we added it only in order that it gets
|
||||
# build for the dynamic programs.
|
||||
#
|
||||
ifdef SHARED_LIB
|
||||
override DEPS := $(filter-out startup_dyn.lib,$(DEPS))
|
||||
|
||||
#
|
||||
# Prevent linkage of startup code against shared libraries except for ld.lib.so
|
||||
#
|
||||
ifneq ($(LIB),ld)
|
||||
override DEPS := $(filter-out startup.lib,$(DEPS))
|
||||
endif
|
||||
|
@ -120,9 +120,13 @@ LD_CMD += -Wl,--dynamic-linker=$(DYNAMIC_LINKER).lib.so \
|
||||
-Wl,--eh-frame-hdr
|
||||
|
||||
#
|
||||
# Filter out the base libraries since they will be provided by the ldso.library
|
||||
# Filter out the base libraries since they will be provided by the LDSO
|
||||
# library and the startup library as the CRT0 part of program startup is
|
||||
# done by LDSO already. As replacement for the startup library startup_dyn
|
||||
# is used. The startup_dyn build is triggered by any shared library without
|
||||
# merging it to the library.
|
||||
#
|
||||
FILTER_DEPS := $(filter-out $(BASE_LIBS),$(DEPS:.lib=))
|
||||
FILTER_DEPS := $(filter-out $(BASE_LIBS) startup,$(DEPS:.lib=)) startup_dyn
|
||||
SHARED_LIBS += $(LIB_CACHE_DIR)/$(DYNAMIC_LINKER)/$(DYNAMIC_LINKER).lib.so
|
||||
|
||||
#
|
||||
|
30
base/src/base/env/platform_env.h
vendored
30
base/src/base/env/platform_env.h
vendored
@ -23,7 +23,7 @@
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
#include <base/env.h>
|
||||
#include <base/heap.h>
|
||||
#include <base/heap.h>
|
||||
|
||||
/* local includes */
|
||||
#include <platform_env_common.h>
|
||||
@ -36,7 +36,9 @@ namespace Genode {
|
||||
}
|
||||
|
||||
|
||||
struct Genode::Expanding_rm_session_client : Upgradeable_client<Genode::Rm_session_client>
|
||||
struct Genode::Expanding_rm_session_client
|
||||
:
|
||||
Upgradeable_client<Genode::Rm_session_client>
|
||||
{
|
||||
Expanding_rm_session_client(Rm_session_capability cap)
|
||||
: Upgradeable_client<Genode::Rm_session_client>(cap) { }
|
||||
@ -139,7 +141,29 @@ class Genode::Platform_env : public Genode::Env, public Emergency_ram_reserve
|
||||
_emergency_ram_ds(_resources.ram.alloc(_emergency_ram_size()))
|
||||
{ }
|
||||
|
||||
void reload_parent_cap(Native_capability::Dst, long);
|
||||
/**
|
||||
* Reload parent capability and reinitialize environment resources
|
||||
*
|
||||
* This function is solely used for implementing fork semantics.
|
||||
* After forking a process, the new child process is executed
|
||||
* within a copy of the address space of the forking process.
|
||||
* Thereby, the new process inherits the original 'env' object of
|
||||
* the forking process, which is meaningless in the context of the
|
||||
* new process. By calling this function, the new process is able
|
||||
* to reinitialize its 'env' with meaningful capabilities obtained
|
||||
* via its updated parent capability.
|
||||
*/
|
||||
void reinit(Native_capability::Dst, long);
|
||||
|
||||
/**
|
||||
* Reinitialize main-thread object
|
||||
*
|
||||
* \param context_area_rm new RM session of the context area
|
||||
*
|
||||
* This function is solely used for implementing fork semantics
|
||||
* as provided by the Noux environment.
|
||||
*/
|
||||
void reinit_main_thread(Rm_session_capability &);
|
||||
|
||||
|
||||
/*************************************
|
||||
|
55
base/src/base/env/reinitialize.cc
vendored
55
base/src/base/env/reinitialize.cc
vendored
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Environment reinitialization
|
||||
* \author Norman Feske
|
||||
* \author Martin Stein
|
||||
* \date 2012-02-16
|
||||
*/
|
||||
|
||||
@ -11,12 +12,28 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* env includes */
|
||||
#include <platform_env.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/construct_at.h>
|
||||
#include <base/crt0.h>
|
||||
#include <rm_session/connection.h>
|
||||
|
||||
void prepare_reinit_main_thread();
|
||||
|
||||
void reinit_main_thread();
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
extern bool inhibit_tracing;
|
||||
|
||||
Rm_session * env_context_area_rm_session();
|
||||
}
|
||||
|
||||
|
||||
void Genode::Platform_env::reload_parent_cap(Native_capability::Dst dst,
|
||||
long local_name)
|
||||
void Genode::Platform_env::reinit(Native_capability::Dst dst,
|
||||
long local_name)
|
||||
{
|
||||
/*
|
||||
* This function is unused during the normal operation of Genode. It is
|
||||
@ -32,21 +49,26 @@ void Genode::Platform_env::reload_parent_cap(Native_capability::Dst dst,
|
||||
* provided by the actual parent.
|
||||
*/
|
||||
|
||||
/* avoid RPCs by the tracing framework as long as we have no valid env */
|
||||
inhibit_tracing = true;
|
||||
|
||||
/* do platform specific preparation */
|
||||
prepare_reinit_main_thread();
|
||||
|
||||
/*
|
||||
* Patch new parent capability into the original location as specified by
|
||||
* the linker script.
|
||||
*/
|
||||
Native_capability::Raw *raw = (Native_capability::Raw *)(&_parent_cap);
|
||||
|
||||
raw->dst = dst;
|
||||
raw->local_name = local_name;
|
||||
raw->dst = dst;
|
||||
raw->local_name = local_name;
|
||||
|
||||
/*
|
||||
* Re-initialize 'Platform_env' members
|
||||
*/
|
||||
static_cast<Parent_client &>(_parent_client) = Parent_client(Genode::parent_cap());
|
||||
|
||||
_resources = Resources(_parent_client);
|
||||
Expanding_parent_client * const p = &_parent_client;
|
||||
construct_at<Expanding_parent_client>(p, parent_cap(), *this);
|
||||
construct_at<Resources>(&_resources, _parent_client);
|
||||
|
||||
/*
|
||||
* Keep information about dynamically allocated memory but use the new
|
||||
@ -57,3 +79,20 @@ void Genode::Platform_env::reload_parent_cap(Native_capability::Dst dst,
|
||||
*/
|
||||
_heap.reassign_resources(&_resources.ram, &_resources.rm);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Genode::Platform_env::
|
||||
reinit_main_thread(Rm_session_capability & context_area_rm)
|
||||
{
|
||||
/* reinitialize context area RM session */
|
||||
Rm_session * const rms = env_context_area_rm_session();
|
||||
Rm_session_client * const rmc = dynamic_cast<Rm_session_client *>(rms);
|
||||
construct_at<Rm_session_client>(rmc, context_area_rm);
|
||||
|
||||
/* re-enable tracing */
|
||||
inhibit_tracing = false;
|
||||
|
||||
/* reinitialize main-thread object */
|
||||
::reinit_main_thread();
|
||||
}
|
||||
|
@ -51,24 +51,34 @@ addr_t Thread_base::Context_allocator::addr_to_base(void *addr)
|
||||
|
||||
size_t Thread_base::Context_allocator::base_to_idx(addr_t base)
|
||||
{
|
||||
return (base - Native_config::context_area_virtual_base()) /
|
||||
Native_config::context_virtual_size();
|
||||
/* the first context isn't managed through the indices */
|
||||
return ((base - Native_config::context_area_virtual_base()) /
|
||||
Native_config::context_virtual_size()) - 1;
|
||||
}
|
||||
|
||||
|
||||
addr_t Thread_base::Context_allocator::idx_to_base(size_t idx)
|
||||
{
|
||||
/* the first context isn't managed through the indices */
|
||||
return Native_config::context_area_virtual_base() +
|
||||
idx * Native_config::context_virtual_size();
|
||||
(idx + 1) * Native_config::context_virtual_size();
|
||||
}
|
||||
|
||||
|
||||
Thread_base::Context *Thread_base::Context_allocator::alloc(Thread_base *thread_base)
|
||||
Thread_base::Context *
|
||||
Thread_base::Context_allocator::alloc(Thread_base *thread_base, bool main_thread)
|
||||
{
|
||||
Lock::Guard _lock_guard(_threads_lock);
|
||||
|
||||
try {
|
||||
return base_to_context(idx_to_base(_alloc.alloc()));
|
||||
addr_t base;
|
||||
if (main_thread) {
|
||||
/* the main-thread context isn't managed by '_alloc' */
|
||||
base = Native_config::context_area_virtual_base();
|
||||
} else {
|
||||
/* contexts besides main-thread context are managed by '_alloc' */
|
||||
base = idx_to_base(_alloc.alloc());
|
||||
}
|
||||
return base_to_context(base);
|
||||
} catch(Bit_allocator<MAX_THREADS>::Out_of_indices) {
|
||||
return 0;
|
||||
}
|
||||
@ -78,8 +88,13 @@ Thread_base::Context *Thread_base::Context_allocator::alloc(Thread_base *thread_
|
||||
void Thread_base::Context_allocator::free(Context *context)
|
||||
{
|
||||
Lock::Guard _lock_guard(_threads_lock);
|
||||
addr_t const base = addr_to_base(context);
|
||||
|
||||
_alloc.free(base_to_idx(addr_to_base(context)));
|
||||
/* the main-thread context isn't managed by '_alloc' */
|
||||
if (base == Native_config::context_area_virtual_base()) { return; }
|
||||
|
||||
/* contexts besides main-thread context are managed by '_alloc' */
|
||||
_alloc.free(base_to_idx(base));
|
||||
}
|
||||
|
||||
|
||||
@ -94,7 +109,8 @@ Thread_base::Context_allocator *Thread_base::_context_allocator()
|
||||
}
|
||||
|
||||
|
||||
Thread_base::Context *Thread_base::_alloc_context(size_t stack_size)
|
||||
Thread_base::Context *
|
||||
Thread_base::_alloc_context(size_t stack_size, bool main_thread)
|
||||
{
|
||||
/*
|
||||
* Synchronize context list when creating new threads from multiple threads
|
||||
@ -105,7 +121,7 @@ Thread_base::Context *Thread_base::_alloc_context(size_t stack_size)
|
||||
Lock::Guard _lock_guard(alloc_lock);
|
||||
|
||||
/* allocate thread context */
|
||||
Context *context = _context_allocator()->alloc(this);
|
||||
Context *context = _context_allocator()->alloc(this, main_thread);
|
||||
if (!context)
|
||||
throw Context_alloc_failed();
|
||||
|
||||
@ -213,7 +229,7 @@ void Thread_base::join()
|
||||
|
||||
void* Thread_base::alloc_secondary_stack(char const *name, size_t stack_size)
|
||||
{
|
||||
Context *context = _alloc_context(stack_size);
|
||||
Context *context = _alloc_context(stack_size, false);
|
||||
strncpy(context->name, name, sizeof(context->name));
|
||||
return (void *)context->stack_top();
|
||||
}
|
||||
@ -226,13 +242,14 @@ void Thread_base::free_secondary_stack(void* stack_addr)
|
||||
}
|
||||
|
||||
|
||||
Thread_base::Thread_base(const char *name, size_t stack_size)
|
||||
Thread_base::Thread_base(const char *name, size_t stack_size, Type type)
|
||||
:
|
||||
_context(_alloc_context(stack_size)),
|
||||
_context(type == REINITIALIZED_MAIN ?
|
||||
_context : _alloc_context(stack_size, type == MAIN)),
|
||||
_join_lock(Lock::LOCKED)
|
||||
{
|
||||
strncpy(_context->name, name, sizeof(_context->name));
|
||||
_init_platform_thread();
|
||||
_init_platform_thread(type);
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,9 +36,6 @@ void Thread_base::_thread_start()
|
||||
** Thread base **
|
||||
*****************/
|
||||
|
||||
void Thread_base::_init_platform_thread() { }
|
||||
|
||||
|
||||
void Thread_base::_deinit_platform_thread()
|
||||
{
|
||||
env()->cpu_session()->kill_thread(_thread_cap);
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <base/env.h>
|
||||
#include <base/heap.h>
|
||||
#include <ram_session/client.h>
|
||||
#include <rm_session/capability.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform.h>
|
||||
@ -174,7 +175,9 @@ namespace Genode {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void reload_parent_cap(Capability<Parent>::Dst, long) { }
|
||||
void reinit(Capability<Parent>::Dst, long) { }
|
||||
|
||||
void reinit_main_thread(Rm_session_capability &) { }
|
||||
};
|
||||
|
||||
|
||||
|
@ -31,13 +31,8 @@
|
||||
using namespace Genode;
|
||||
|
||||
extern int main(int argc, char **argv, char **envp);
|
||||
extern void init_exception_handling(); /* implemented in base/cxx */
|
||||
|
||||
namespace Genode {
|
||||
Rm_session *env_context_area_rm_session();
|
||||
void platform_main_bootstrap();
|
||||
}
|
||||
|
||||
namespace Genode { Rm_session *env_context_area_rm_session(); }
|
||||
|
||||
enum { ATEXIT_SIZE = 256 };
|
||||
|
||||
@ -46,6 +41,8 @@ enum { ATEXIT_SIZE = 256 };
|
||||
** C++ stuff **
|
||||
***************/
|
||||
|
||||
void * __dso_handle = 0;
|
||||
|
||||
enum Atexit_fn_type { ATEXIT_FN_EMPTY, ATEXIT_FN_STD, ATEXIT_FN_CXA };
|
||||
|
||||
struct atexit_fn
|
||||
@ -229,11 +226,6 @@ namespace Genode { extern bool inhibit_tracing; }
|
||||
*/
|
||||
extern "C" int _main()
|
||||
{
|
||||
platform_main_bootstrap();
|
||||
|
||||
/* call env() explicitly to setup the environment */
|
||||
(void*)env();
|
||||
|
||||
/*
|
||||
* Allow exit handlers to be registered.
|
||||
*
|
||||
@ -244,34 +236,6 @@ extern "C" int _main()
|
||||
*/
|
||||
atexit_enable();
|
||||
|
||||
/* initialize exception handling */
|
||||
init_exception_handling();
|
||||
|
||||
/*
|
||||
* We create the thread-context area as early as possible to prevent other
|
||||
* mappings from occupying the predefined virtual-memory region.
|
||||
*/
|
||||
env_context_area_rm_session();
|
||||
|
||||
/*
|
||||
* Trigger first exception. This step has two purposes.
|
||||
* First, it enables us to detect problems related to exception handling as
|
||||
* early as possible. If there are problems with the C++ support library,
|
||||
* it is much easier to debug them at this early stage. Otherwise problems
|
||||
* with half-working exception handling cause subtle failures that are hard
|
||||
* to interpret.
|
||||
*
|
||||
* Second, the C++ support library allocates data structures lazily on the
|
||||
* first occurrence of an exception. This allocation traverses into
|
||||
* Genode's heap and, in some corner cases, consumes several KB of stack.
|
||||
* This is usually not a problem when the first exception is triggered from
|
||||
* the main thread but it becomes an issue when the first exception is
|
||||
* thrown from the context of a thread with a specially tailored (and
|
||||
* otherwise sufficient) stack size. By throwing an exception here, we
|
||||
* mitigate this issue by eagerly performing those allocations.
|
||||
*/
|
||||
try { throw 1; } catch (...) { }
|
||||
|
||||
/* call constructors for static objects */
|
||||
void (**func)();
|
||||
for (func = &_ctors_end; func != &_ctors_start; (*--func)());
|
||||
|
@ -1,6 +1,7 @@
|
||||
/**
|
||||
* \brief Startup code for Genode applications on ARM
|
||||
* \author Norman Feske
|
||||
* \author Martin Stein
|
||||
* \date 2007-04-28
|
||||
*/
|
||||
|
||||
@ -11,34 +12,58 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/*--- .text (program code) -------------------------*/
|
||||
|
||||
/**************************
|
||||
** .text (program code) **
|
||||
**************************/
|
||||
|
||||
.section ".text.crt0"
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
/* program entry-point */
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
ldr r4, .initial_sp
|
||||
/* make initial value of some registers available to higher-level code */
|
||||
ldr r4, =__initial_sp
|
||||
str sp, [r4]
|
||||
|
||||
ldr sp, .stack_high
|
||||
b _main
|
||||
/*
|
||||
* Install initial temporary environment that is replaced later by the
|
||||
* environment that init_main_thread creates.
|
||||
*/
|
||||
ldr sp, =_stack_high
|
||||
|
||||
.initial_sp: .word __initial_sp
|
||||
.stack_high: .word _stack_high
|
||||
/* create proper environment for main thread */
|
||||
bl init_main_thread
|
||||
|
||||
.globl __dso_handle
|
||||
__dso_handle: .long 0
|
||||
/* apply environment that was created by init_main_thread */
|
||||
ldr sp, =init_main_thread_result
|
||||
ldr sp, [sp]
|
||||
|
||||
/* jump into init C code instead of calling it as it should never return */
|
||||
b _main
|
||||
|
||||
|
||||
/*********************************
|
||||
** .bss (non-initialized data) **
|
||||
*********************************/
|
||||
|
||||
/*--- .bss (non-initialized data) ------------------*/
|
||||
.section ".bss"
|
||||
|
||||
/* stack of the temporary initial environment */
|
||||
.p2align 4
|
||||
.globl _stack_low
|
||||
_stack_low:
|
||||
.space 128*1024
|
||||
.globl _stack_high
|
||||
_stack_high:
|
||||
.global _stack_low
|
||||
_stack_low:
|
||||
.space 128 * 1024
|
||||
.global _stack_high
|
||||
_stack_high:
|
||||
|
||||
/* initial value of the SP register */
|
||||
.globl __initial_sp
|
||||
__initial_sp: .space 4
|
||||
.global __initial_sp
|
||||
__initial_sp:
|
||||
.space 4
|
||||
|
||||
/* return value of init_main_thread */
|
||||
.global init_main_thread_result
|
||||
init_main_thread_result:
|
||||
.space 4
|
||||
|
130
base/src/platform/init_main_thread.cc
Normal file
130
base/src/platform/init_main_thread.cc
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* \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 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/construct_at.h>
|
||||
#include <base/env.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern addr_t init_main_thread_result;
|
||||
|
||||
extern void init_exception_handling();
|
||||
|
||||
namespace Genode { Rm_session * env_context_area_rm_session(); }
|
||||
|
||||
void prepare_init_main_thread();
|
||||
|
||||
enum { MAIN_THREAD_STACK_SIZE = 16UL * 1024 * sizeof(Genode::addr_t) };
|
||||
|
||||
/**
|
||||
* The first thread in a program
|
||||
*/
|
||||
class Main_thread : public Thread<MAIN_THREAD_STACK_SIZE>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param reinit wether this is called for reinitialization
|
||||
*/
|
||||
Main_thread(bool reinit)
|
||||
:
|
||||
Thread("main", reinit ? REINITIALIZED_MAIN : MAIN)
|
||||
{ }
|
||||
|
||||
/**********************
|
||||
** Thread interface **
|
||||
**********************/
|
||||
|
||||
void entry() { }
|
||||
};
|
||||
|
||||
|
||||
Main_thread * main_thread()
|
||||
{
|
||||
static Main_thread s(false);
|
||||
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()
|
||||
{
|
||||
/* do platform specific preparation */
|
||||
prepare_init_main_thread();
|
||||
|
||||
/*
|
||||
* Explicitly setup program environment at this point to ensure that its
|
||||
* destructor won't be registered for the atexit routine.
|
||||
*/
|
||||
(void*)env();
|
||||
|
||||
/* initialize exception handling */
|
||||
init_exception_handling();
|
||||
|
||||
/*
|
||||
* We create the thread-context area as early as possible to prevent other
|
||||
* mappings from occupying the predefined virtual-memory region.
|
||||
*/
|
||||
env_context_area_rm_session();
|
||||
|
||||
/*
|
||||
* Trigger first exception. This step has two purposes.
|
||||
* First, it enables us to detect problems related to exception handling as
|
||||
* early as possible. If there are problems with the C++ support library,
|
||||
* it is much easier to debug them at this early stage. Otherwise problems
|
||||
* with half-working exception handling cause subtle failures that are hard
|
||||
* to interpret.
|
||||
*
|
||||
* Second, the C++ support library allocates data structures lazily on the
|
||||
* first occurrence of an exception. This allocation traverses into
|
||||
* Genode's heap and, in some corner cases, consumes several KB of stack.
|
||||
* This is usually not a problem when the first exception is triggered from
|
||||
* the main thread but it becomes an issue when the first exception is
|
||||
* thrown from the context of a thread with a specially tailored (and
|
||||
* otherwise sufficient) stack size. By throwing an exception here, we
|
||||
* mitigate this issue by eagerly performing those allocations.
|
||||
*/
|
||||
try { throw 1; } catch (...) { }
|
||||
|
||||
/* 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 sp = reinterpret_cast<addr_t>(main_thread()->stack_top());
|
||||
init_main_thread_result = sp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reinitialize main-thread object according to a reinitialized environment
|
||||
*/
|
||||
void reinit_main_thread() { construct_at<Main_thread>(main_thread(), true); }
|
@ -1,6 +1,7 @@
|
||||
/**
|
||||
* \brief Startup code for Genode applications
|
||||
* \author Christian Helmuth
|
||||
* \author Martin Stein
|
||||
* \date 2009-08-12
|
||||
*/
|
||||
|
||||
@ -11,53 +12,79 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/*--- .text (program code) -------------------------*/
|
||||
.text
|
||||
.global _start
|
||||
|
||||
_start:
|
||||
/**************************
|
||||
** .text (program code) **
|
||||
**************************/
|
||||
|
||||
.text
|
||||
|
||||
/* program entry-point */
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
/* make initial value of some registers available to higher-level code */
|
||||
mov %esp, __initial_sp
|
||||
mov %eax, __initial_ax
|
||||
mov %edi, __initial_di
|
||||
|
||||
/* XXX Switch to our own stack. */
|
||||
/*
|
||||
* Install initial temporary environment that is replaced later by the
|
||||
* environment that init_main_thread creates.
|
||||
*/
|
||||
leal _stack_high, %esp
|
||||
|
||||
/* Clear the base pointer so that stack backtraces will work. */
|
||||
/* create proper environment for the main thread */
|
||||
call init_main_thread
|
||||
|
||||
/* apply environment that was created by init_main_thread */
|
||||
movl init_main_thread_result, %esp
|
||||
|
||||
/* clear the base pointer in order that stack backtraces will work */
|
||||
xor %ebp,%ebp
|
||||
|
||||
/* Jump into init C code */
|
||||
call _main
|
||||
/* jump into init C code instead of calling it as it should never return */
|
||||
jmp _main
|
||||
|
||||
/* We should never get here since _main does not return */
|
||||
1: int $3
|
||||
jmp 2f
|
||||
.ascii "_main() returned."
|
||||
2: jmp 1b
|
||||
|
||||
.globl __dso_handle
|
||||
__dso_handle: .long 0
|
||||
/**********************************
|
||||
** .eh_frame (exception frames) **
|
||||
**********************************/
|
||||
|
||||
/*--- .eh_frame (exception frames) -----------------*/
|
||||
/*
|
||||
.section .eh_frame,"aw"
|
||||
.section .eh_frame,"aw"
|
||||
|
||||
.global __EH_FRAME_BEGIN__
|
||||
__EH_FRAME_BEGIN__:
|
||||
__EH_FRAME_BEGIN__:
|
||||
*/
|
||||
|
||||
/*--- .bss (non-initialized data) ------------------*/
|
||||
.bss
|
||||
|
||||
/*********************************
|
||||
** .bss (non-initialized data) **
|
||||
*********************************/
|
||||
|
||||
.bss
|
||||
|
||||
/* stack of the temporary initial environment */
|
||||
.p2align 4
|
||||
.global _stack_low
|
||||
_stack_low:
|
||||
.space 64*1024
|
||||
_stack_low:
|
||||
.space 64 * 1024
|
||||
.global _stack_high
|
||||
_stack_high:
|
||||
_stack_high:
|
||||
|
||||
/* initial value of the ESP, EAX and EDI register */
|
||||
.globl __initial_sp
|
||||
.globl __initial_ax
|
||||
.globl __initial_di
|
||||
__initial_sp: .space 4
|
||||
__initial_ax: .space 4
|
||||
__initial_di: .space 4
|
||||
.global __initial_sp
|
||||
__initial_sp:
|
||||
.space 4
|
||||
.global __initial_ax
|
||||
__initial_ax:
|
||||
.space 4
|
||||
.global __initial_di
|
||||
__initial_di:
|
||||
.space 4
|
||||
|
||||
/* return value of init_main_thread */
|
||||
.global init_main_thread_result
|
||||
init_main_thread_result:
|
||||
.space 4
|
||||
|
@ -1,6 +1,7 @@
|
||||
/**
|
||||
* \brief Startup code for Genode 64Bit applications
|
||||
* \author Sebastian Sumpf
|
||||
* \author Martin Stein
|
||||
* \date 2011-05-11
|
||||
*/
|
||||
|
||||
@ -11,60 +12,90 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/*--- .text (program code) -------------------------*/
|
||||
.text
|
||||
|
||||
/**************************
|
||||
** .text (program code) **
|
||||
**************************/
|
||||
|
||||
.text
|
||||
|
||||
/* program entry-point */
|
||||
.global _start
|
||||
_start:
|
||||
|
||||
_start:
|
||||
|
||||
/* make initial value of some registers available to higher-level code */
|
||||
movq __initial_ax@GOTPCREL(%rip), %rbx
|
||||
movq %rax, (%rbx)
|
||||
|
||||
movq __initial_di@GOTPCREL(%rip), %rbx
|
||||
movq %rdi, (%rbx)
|
||||
|
||||
movq __initial_sp@GOTPCREL(%rip), %rax
|
||||
movq %rsp, (%rax)
|
||||
|
||||
/* XXX Switch to our own stack. */
|
||||
/*
|
||||
* Install initial temporary environment that is replaced later by the
|
||||
* environment that init_main_thread creates.
|
||||
*/
|
||||
leaq _stack_high@GOTPCREL(%rip),%rax
|
||||
movq (%rax), %rsp
|
||||
|
||||
/* Clear the base pointer so that stack backtraces will work. */
|
||||
xorq %rbp,%rbp
|
||||
/* create proper environment for the main thread */
|
||||
call init_main_thread
|
||||
|
||||
/* Jump into init C code */
|
||||
call _main
|
||||
/* apply environment that was created by init_main_thread */
|
||||
movq init_main_thread_result@GOTPCREL(%rip), %rax
|
||||
movq (%rax), %rsp
|
||||
|
||||
/* We should never get here since _main does not return */
|
||||
1: int $3
|
||||
jmp 2f
|
||||
.ascii "_main() returned."
|
||||
2: jmp 1b
|
||||
/* clear the base pointer in order that stack backtraces will work */
|
||||
xorq %rbp, %rbp
|
||||
|
||||
.globl __dso_handle
|
||||
__dso_handle: .quad 0
|
||||
/*
|
||||
* We jump into initial C code instead of calling it as it should never
|
||||
* return on the one hand and because the alignment of the stack pointer
|
||||
* that init_main_thread returned expects a jump at the other hand. The
|
||||
* latter matters because GCC expects the initial stack pointer to be
|
||||
* aligned to 16 byte for at least the handling of floating points.
|
||||
*/
|
||||
jmp _main
|
||||
|
||||
|
||||
/**********************************
|
||||
** .eh_frame (exception frames) **
|
||||
**********************************/
|
||||
|
||||
/*--- .eh_frame (exception frames) -----------------*/
|
||||
/*
|
||||
.section .eh_frame,"aw"
|
||||
.section .eh_frame,"aw"
|
||||
|
||||
.global __EH_FRAME_BEGIN__
|
||||
__EH_FRAME_BEGIN__:
|
||||
__EH_FRAME_BEGIN__:
|
||||
*/
|
||||
|
||||
/*--- .bss (non-initialized data) ------------------*/
|
||||
.bss
|
||||
|
||||
/*********************************
|
||||
** .bss (non-initialized data) **
|
||||
*********************************/
|
||||
|
||||
.bss
|
||||
|
||||
/* stack of the temporary initial environment */
|
||||
.p2align 8
|
||||
.global _stack_low
|
||||
_stack_low:
|
||||
.space 64*1024
|
||||
_stack_low:
|
||||
.space 64 * 1024
|
||||
.global _stack_high
|
||||
_stack_high:
|
||||
_stack_high:
|
||||
|
||||
/* initial value of the RSP, RAX and RDI register */
|
||||
.globl __initial_sp
|
||||
__initial_sp:
|
||||
.space 8
|
||||
.globl __initial_ax
|
||||
__initial_ax:
|
||||
.space 8
|
||||
.globl __initial_di
|
||||
__initial_sp: .space 8
|
||||
__initial_ax: .space 8
|
||||
__initial_di: .space 8
|
||||
__initial_di:
|
||||
.space 8
|
||||
|
||||
/* return value of init_main_thread */
|
||||
.globl init_main_thread_result
|
||||
init_main_thread_result:
|
||||
.space 8
|
||||
|
@ -7,8 +7,6 @@ INC_DIR += $(REP_DIR)/src/lib/ffat/contrib
|
||||
SRC_C = ff.c ccsbcs.c
|
||||
SRC_CC = diskio_block.cc
|
||||
|
||||
LIBS = base
|
||||
|
||||
vpath % $(REP_DIR)/src/lib/ffat/
|
||||
vpath % $(REP_DIR)/contrib/ff007e/src
|
||||
vpath % $(REP_DIR)/contrib/ff007e/src/option
|
||||
|
5
os/lib/mk/startup_dyn.mk
Normal file
5
os/lib/mk/startup_dyn.mk
Normal file
@ -0,0 +1,5 @@
|
||||
SRC_CC += _main.cc
|
||||
|
||||
REP_INC_DIR += src/platform
|
||||
|
||||
vpath _main.cc $(BASE_DIR)/src/platform
|
@ -1,6 +1,7 @@
|
||||
/**
|
||||
* \brief Startup code for Genode applications on ARM
|
||||
* \author Norman Feske
|
||||
* \author Martin Stein
|
||||
* \date 2007-04-28
|
||||
*/
|
||||
|
||||
@ -11,19 +12,40 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/*--- .text (program code) -------------------------*/
|
||||
|
||||
/**************************
|
||||
** .text (program code) **
|
||||
**************************/
|
||||
|
||||
.section ".text.crt0"
|
||||
|
||||
/* linker entry-point */
|
||||
.globl _start_ldso
|
||||
_start_ldso:
|
||||
_start_ldso:
|
||||
|
||||
ldr r2, .initial_sp
|
||||
/* make initial value of some registers available to higher-level code */
|
||||
ldr r2, =__initial_sp
|
||||
str sp, [r2]
|
||||
|
||||
ldr sp, .stack_high
|
||||
/*
|
||||
* Install initial temporary environment that is replaced later by the
|
||||
* environment that init_main_thread creates.
|
||||
*/
|
||||
ldr sp, =_stack_high
|
||||
|
||||
/* let init_rtld relocate linker */
|
||||
bl init_rtld
|
||||
b _main
|
||||
|
||||
.initial_sp: .word __initial_sp
|
||||
.stack_high: .word _stack_high
|
||||
/* create proper environment for the main thread */
|
||||
bl init_main_thread
|
||||
|
||||
/* apply environment that was created by init_main_thread */
|
||||
ldr sp, =init_main_thread_result
|
||||
ldr sp, [sp]
|
||||
|
||||
/* call init C code */
|
||||
bl _main
|
||||
|
||||
/* this should never be reached since _main should never return */
|
||||
_catch_main_return:
|
||||
b _catch_main_return
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Call main function (ARM specific)
|
||||
* \author Sebastian Sumpf <Sebastian.Sumpf@genode-labs.com>
|
||||
* \author Martin Stein
|
||||
* \date 2011-05-05
|
||||
*/
|
||||
|
||||
@ -13,20 +14,32 @@
|
||||
#ifndef _ARM__CALL_MAIN_H_
|
||||
#define _ARM__CALL_MAIN_H_
|
||||
|
||||
/**
|
||||
* Restore SP from initial sp and jump to entry function
|
||||
*/
|
||||
void call_main(void (*func)(void))
|
||||
{
|
||||
extern long __initial_sp;
|
||||
void * my_stack_top();
|
||||
void set_program_var(const char *, const void *);
|
||||
|
||||
asm volatile ("mov %%sp, %0;"
|
||||
"bx %1;"
|
||||
:
|
||||
: "r" (__initial_sp),
|
||||
"r" (func)
|
||||
: "memory"
|
||||
);
|
||||
extern void * __initial_sp;
|
||||
|
||||
/**
|
||||
* Call program _main with the environment that its CRT0 would have created
|
||||
*
|
||||
* \param _main_fp pointer to _main function of dynamic program
|
||||
*/
|
||||
void call_main(void (*_main_fp)(void))
|
||||
{
|
||||
/* make initial value of some registers available to dynamic program */
|
||||
set_program_var("__initial_sp", __initial_sp);
|
||||
|
||||
/*
|
||||
* We could also do a call but that would enable the the program main to
|
||||
* return to LDSO wich isn't desired. This means also that not resetting
|
||||
* the SP to stack top as we do would waste stack memory for dead LDSO
|
||||
* frames.
|
||||
*/
|
||||
asm volatile ("mov sp, %[sp];"
|
||||
"bx %[ip];"
|
||||
:: [sp] "r" (my_stack_top()),
|
||||
[ip] "r" (_main_fp)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#endif /* _ARM__CALL_MAIN_H_ */
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Call main function (X86 specific)
|
||||
* \author Sebastian Sumpf <Sebastian.Sumpf@genode-labs.com>
|
||||
* \author Martin Stein
|
||||
* \date 2011-05-02
|
||||
*/
|
||||
|
||||
@ -13,20 +14,37 @@
|
||||
#ifndef _X86_32__CALL_MAIN_H_
|
||||
#define _X86_32__CALL_MAIN_H_
|
||||
|
||||
/**
|
||||
* Restore SP from initial sp and jump to entry function
|
||||
*/
|
||||
void call_main(void (*func)(void))
|
||||
{
|
||||
extern long __initial_sp;
|
||||
void * my_stack_top();
|
||||
void set_program_var(const char *, const void *);
|
||||
|
||||
asm volatile ("mov %0, %%esp;"
|
||||
"jmp *%1;"
|
||||
:
|
||||
: "r" (__initial_sp),
|
||||
"r" (func)
|
||||
: "memory"
|
||||
);
|
||||
extern void * __initial_sp;
|
||||
extern void * __initial_ax;
|
||||
extern void * __initial_di;
|
||||
|
||||
/**
|
||||
* Call program _main with the environment that its CRT0 would have created
|
||||
*
|
||||
* \param _main_fp pointer to _main function of dynamic program
|
||||
*/
|
||||
void call_main(void (*_main_fp)(void))
|
||||
{
|
||||
/* make initial value of some registers available to dynamic program */
|
||||
set_program_var("__initial_sp", __initial_sp);
|
||||
set_program_var("__initial_ax", __initial_ax);
|
||||
set_program_var("__initial_di", __initial_di);
|
||||
|
||||
/*
|
||||
* We could also do a call but that would enable the the program main to
|
||||
* return to LDSO wich isn't desired. This means also that not resetting
|
||||
* the SP to stack top as we do would waste stack memory for dead LDSO
|
||||
* frames.
|
||||
*/
|
||||
asm volatile ("mov %[sp], %%esp;"
|
||||
"xor %%ebp, %%ebp;"
|
||||
"jmp *%[ip];"
|
||||
:: [sp] "r" (my_stack_top()),
|
||||
[ip] "r" (_main_fp)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#endif /* _X86_32__CALL_MAIN_H_ */
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* \brief Call main function (X86 64 bit specific)
|
||||
* \author Sebastian Sumpf <Sebastian.Sumpf@genode-labs.com>
|
||||
* \author Martin Stein
|
||||
* \date 2011-05-011
|
||||
*/
|
||||
|
||||
@ -13,20 +14,37 @@
|
||||
#ifndef _X86_64__CALL_MAIN_H_
|
||||
#define _X86_64__CALL_MAIN_H_
|
||||
|
||||
/**
|
||||
* Restore SP from initial sp and jump to entry function
|
||||
*/
|
||||
void call_main(void (*func)(void))
|
||||
{
|
||||
extern long __initial_sp;
|
||||
void * my_stack_top();
|
||||
void set_program_var(const char *, const void *);
|
||||
|
||||
asm volatile ("movq %0, %%rsp;"
|
||||
"jmpq *%1;"
|
||||
:
|
||||
: "r" (__initial_sp),
|
||||
"r" (func)
|
||||
: "memory"
|
||||
);
|
||||
extern void * __initial_sp;
|
||||
extern void * __initial_ax;
|
||||
extern void * __initial_di;
|
||||
|
||||
/**
|
||||
* Call program _main with the environment that its CRT0 would have created
|
||||
*
|
||||
* \param _main_fp pointer to _main function of dynamic program
|
||||
*/
|
||||
void call_main(void (*_main_fp)(void))
|
||||
{
|
||||
/* make initial value of some registers available to dynamic program */
|
||||
set_program_var("__initial_sp", __initial_sp);
|
||||
set_program_var("__initial_ax", __initial_ax);
|
||||
set_program_var("__initial_di", __initial_di);
|
||||
|
||||
/*
|
||||
* We could also do a call but that would enable the the program main to
|
||||
* return to LDSO wich isn't desired. This means also that not resetting
|
||||
* the SP to stack top as we do would waste stack memory for dead LDSO
|
||||
* frames.
|
||||
*/
|
||||
asm volatile ("movq %[sp], %%rsp;"
|
||||
"xorq %%rbp, %%rbp;"
|
||||
"jmpq *%[ip];"
|
||||
:: [sp] "r" (my_stack_top()),
|
||||
[ip] "r" (_main_fp)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
#endif /* _X86_64__CALL_MAIN_H_ */
|
||||
|
@ -7,7 +7,7 @@ SRC_S = rtld_start.S
|
||||
SRC_C = reloc.c rtld.c map_object.c xmalloc.c debug.c main.c \
|
||||
ldso_types.c rtld_dummies.c platform.c
|
||||
SRC_CC = stdio.cc stdlib.cc file.cc err.cc string.cc lock.cc \
|
||||
test.cc environ.cc
|
||||
test.cc environ.cc thread.cc
|
||||
|
||||
INC_DIR += $(DIR)/ \
|
||||
$(DIR)/contrib \
|
||||
|
24
os/src/lib/ldso/thread.cc
Normal file
24
os/src/lib/ldso/thread.cc
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* \brief Thread related C helpers
|
||||
* \author Martin Stein
|
||||
* \date 2013-12-13
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
|
||||
|
||||
/**
|
||||
* Return top end of the stack of the calling thread
|
||||
*/
|
||||
extern "C" void * my_stack_top()
|
||||
{
|
||||
return Genode::Thread_base::myself()->stack_top();
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
* \brief Startup code for ld.lib.so (x86-32)
|
||||
* \author Christian Helmuth
|
||||
* \author Sebastian Sumpf
|
||||
* \author Martin Stein
|
||||
* \date 2011-05-03
|
||||
*/
|
||||
|
||||
@ -12,39 +13,60 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/*--- .text (program code) -------------------------*/
|
||||
.text
|
||||
|
||||
/**************************
|
||||
** .text (program code) **
|
||||
**************************/
|
||||
|
||||
.text
|
||||
|
||||
/* linker entry-point */
|
||||
.global _start_ldso
|
||||
_start_ldso:
|
||||
|
||||
_start_ldso:
|
||||
|
||||
/* initialize GOT pointer in EBX */
|
||||
3:
|
||||
/* The follwing statement causes a text relocation which will be ignored by
|
||||
* ldso itself, this is necessary since we don't have a valid stack pointer at
|
||||
* this moment so a 'call' in order to retrieve our IP and thus calculate the
|
||||
* GOT-position in the traditional manner is not possible on x86
|
||||
/*
|
||||
* Initialize GOT pointer in EBX.
|
||||
*
|
||||
* The follwing statement causes a text relocation which will be ignored
|
||||
* by ldso itself, this is necessary since we don't have a valid stack
|
||||
* pointer at this moment so a 'call' in order to retrieve our IP and thus
|
||||
* calculate the GOT-position in the traditional manner is not possible on
|
||||
* x86.
|
||||
*/
|
||||
3:
|
||||
movl $., %ebx
|
||||
addl $_GLOBAL_OFFSET_TABLE_ + (. - 3b) , %ebx
|
||||
|
||||
/* make initial value of some registers available to higher-level code */
|
||||
movl %esp, __initial_sp@GOTOFF(%ebx)
|
||||
movl %eax, __initial_ax@GOTOFF(%ebx)
|
||||
movl %edi, __initial_di@GOTOFF(%ebx)
|
||||
|
||||
/* XXX Switch to our own stack. */
|
||||
/*
|
||||
* Install initial temporary environment that is replaced later by the
|
||||
* environment that init_main_thread creates.
|
||||
*/
|
||||
leal _stack_high@GOTOFF(%ebx), %esp
|
||||
|
||||
/* relocate ldso */
|
||||
/* let init_rtld relocate LDSO */
|
||||
call init_rtld
|
||||
|
||||
/* Clear the base pointer so that stack backtraces will work. */
|
||||
/* create proper environment for the main thread */
|
||||
call init_main_thread
|
||||
|
||||
/* apply environment that was created by init_main_thread */
|
||||
movl init_main_thread_result, %esp
|
||||
|
||||
/* clear the base pointer so that stack backtraces will work */
|
||||
xor %ebp,%ebp
|
||||
|
||||
/* Jump into init C code */
|
||||
/* jump into init C code */
|
||||
call _main
|
||||
|
||||
/* We should never get here since _main does not return */
|
||||
1: int $3
|
||||
/* we should never get here since _main does not return */
|
||||
1:
|
||||
int $3
|
||||
jmp 2f
|
||||
.ascii "_main() returned."
|
||||
2: jmp 1b
|
||||
|
||||
2:
|
||||
jmp 1b
|
||||
|
@ -2,6 +2,7 @@
|
||||
* \brief Startup code for ldso 64Bit version
|
||||
* \author Christian Helmuth
|
||||
* \author Sebastian Sumpf
|
||||
* \author Martin Stein
|
||||
* \date 2011-05-10
|
||||
*/
|
||||
|
||||
@ -12,32 +13,55 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/*--- .text (program code) -------------------------*/
|
||||
.text
|
||||
|
||||
/**************************
|
||||
** .text (program code) **
|
||||
**************************/
|
||||
|
||||
.text
|
||||
|
||||
/* linker entry-point */
|
||||
.globl _start_ldso
|
||||
_start_ldso:
|
||||
_start_ldso:
|
||||
|
||||
/* initialize GLOBAL OFFSET TABLE */
|
||||
/* initialize global offset table */
|
||||
leaq _GLOBAL_OFFSET_TABLE_(%rip),%r15
|
||||
|
||||
|
||||
/* make initial value of some registers available to higher-level code */
|
||||
movq __initial_ax@GOTPCREL(%rip), %rbx
|
||||
movq %rax, (%rbx)
|
||||
movq __initial_di@GOTPCREL(%rip), %rbx
|
||||
movq %rdi, (%rbx)
|
||||
movq __initial_sp@GOTPCREL(%rip), %rax
|
||||
movq %rsp, (%rax)
|
||||
|
||||
/* XXX Switch to our own stack. */
|
||||
/*
|
||||
* Install initial temporary environment that is replaced later by the
|
||||
* environment that init_main_thread creates.
|
||||
*/
|
||||
leaq _stack_high@GOTPCREL(%rip),%rax
|
||||
movq (%rax), %rsp
|
||||
|
||||
/* let init_rtld relocate LDSO */
|
||||
call init_rtld
|
||||
|
||||
/* Clear the base pointer so that stack backtraces will work. */
|
||||
/* create proper environment for the main thread */
|
||||
call init_main_thread
|
||||
|
||||
/* apply environment that was created by init_main_thread */
|
||||
movq init_main_thread_result@GOTPCREL(%rip), %rax
|
||||
movq (%rax), %rsp
|
||||
|
||||
/* clear the base pointer so that stack backtraces will work */
|
||||
xorq %rbp,%rbp
|
||||
|
||||
/* Jump into init C code */
|
||||
/* jump into init C code */
|
||||
call _main
|
||||
|
||||
/* We should never get here since _main does not return */
|
||||
1: int $3
|
||||
/* we should never get here since _main does not return */
|
||||
1:
|
||||
int $3
|
||||
jmp 2f
|
||||
.ascii "_main() returned."
|
||||
2: jmp 1b
|
||||
2:
|
||||
jmp 1b
|
||||
|
@ -11,7 +11,12 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
ENTRY(_start)
|
||||
|
||||
/*
|
||||
* Program doesn't need to startup with CRT0 as LDSO has done this
|
||||
* initialization during its own CRT0 already.
|
||||
*/
|
||||
ENTRY(_main)
|
||||
|
||||
PHDRS
|
||||
{
|
||||
|
@ -4,6 +4,8 @@ LIBS += libc
|
||||
|
||||
REP_INC_DIR += src/lib/libc
|
||||
|
||||
INC_DIR += $(BASE_DIR)/src/base/env/
|
||||
|
||||
vpath %.cc $(REP_DIR)/src/lib/libc_noux
|
||||
|
||||
SHARED_LIB = yes
|
||||
|
@ -12,12 +12,14 @@
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/construct_at.h>
|
||||
#include <util/misc_math.h>
|
||||
#include <util/arg_string.h>
|
||||
#include <base/printf.h>
|
||||
#include <rom_session/connection.h>
|
||||
#include <base/sleep.h>
|
||||
#include <dataspace/client.h>
|
||||
#include <platform_env.h>
|
||||
|
||||
/* noux includes */
|
||||
#include <noux_session/connection.h>
|
||||
@ -60,9 +62,6 @@ enum { verbose = false };
|
||||
enum { verbose_signals = false };
|
||||
|
||||
|
||||
void *operator new (size_t, void *ptr) { return ptr; }
|
||||
|
||||
|
||||
class Noux_connection
|
||||
{
|
||||
private:
|
||||
@ -79,13 +78,6 @@ class Noux_connection
|
||||
|
||||
Noux_connection() : _sysio(_obtain_sysio()) { }
|
||||
|
||||
void reconnect()
|
||||
{
|
||||
new (&_connection) Noux_connection;
|
||||
Genode::env()->rm_session()->detach(_sysio);
|
||||
_sysio = _obtain_sysio();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the capability of the local context-area RM session
|
||||
*/
|
||||
@ -495,11 +487,22 @@ extern "C" void stdout_reconnect(); /* provided by 'log_console.cc' */
|
||||
*/
|
||||
extern "C" void fork_trampoline()
|
||||
{
|
||||
Genode::env()->reload_parent_cap(new_parent.dst, new_parent.local_name);
|
||||
/* reinitialize environment */
|
||||
using namespace Genode;
|
||||
Platform_env * const platform_env = dynamic_cast<Platform_env *>(env());
|
||||
platform_env->reinit(new_parent.dst, new_parent.local_name);
|
||||
|
||||
/* reinitialize standard-output connection */
|
||||
stdout_reconnect();
|
||||
noux_connection()->reconnect();
|
||||
|
||||
/* reinitialize noux connection */
|
||||
construct_at<Noux_connection>(noux_connection());
|
||||
|
||||
/* reinitialize main-thread object which implies reinit of context area */
|
||||
auto context_area_rm = noux_connection()->context_area_rm_session();
|
||||
platform_env->reinit_main_thread(context_area_rm);
|
||||
|
||||
/* apply processor state that the forker had when he did the fork */
|
||||
longjmp(fork_jmp_buf, 1);
|
||||
}
|
||||
|
||||
@ -507,7 +510,7 @@ extern "C" void fork_trampoline()
|
||||
extern "C" pid_t fork(void)
|
||||
{
|
||||
/* stack used for executing 'fork_trampoline' */
|
||||
enum { STACK_SIZE = 1024 };
|
||||
enum { STACK_SIZE = 8 * 1024 };
|
||||
static long stack[STACK_SIZE];
|
||||
|
||||
if (setjmp(fork_jmp_buf)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user