mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-18 07:08:18 +00:00
Move server API concept to base framework
This commit introduces the new `Component` interface in the form of the headers base/component.h and base/entrypoint.h. The os/server.h API has become merely a compatibilty wrapper and will eventually be removed. The same holds true for os/signal_rpc_dispatcher.h. The mechanism has moved to base/signal.h and is now called 'Signal_handler'. Since the patch shuffles headers around, please do a 'make clean' in the build directory. Issue #1832
This commit is contained in:
committed by
Christian Helmuth
parent
4ac7127f89
commit
051e84c4b4
@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/env.h>
|
||||
#include <base/component.h>
|
||||
#include <base/printf.h>
|
||||
#include <os/config.h>
|
||||
#include <util/list.h>
|
||||
@ -35,13 +35,6 @@ namespace Linker {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Genode args to the 'main' function
|
||||
*/
|
||||
extern char **genode_argv;
|
||||
extern int genode_argc;
|
||||
extern char **genode_envp;
|
||||
|
||||
static Binary *binary = 0;
|
||||
bool Linker::bind_now = false;
|
||||
Link_map *Link_map::first;
|
||||
@ -364,7 +357,7 @@ struct Linker::Binary : Root_object, Elf_object
|
||||
return 0;
|
||||
}
|
||||
|
||||
int call_entry_point()
|
||||
void call_entry_point(Genode::Environment &env)
|
||||
{
|
||||
/* call static construtors and register destructors */
|
||||
Func * const ctors_start = (Func *)lookup_symbol("_ctors_start");
|
||||
@ -375,11 +368,13 @@ struct Linker::Binary : Root_object, Elf_object
|
||||
Func * const dtors_end = (Func *)lookup_symbol("_dtors_end");
|
||||
for (Func * dtor = dtors_start; dtor != dtors_end; genode_atexit(*dtor++));
|
||||
|
||||
/* call main function of the program */
|
||||
typedef int (*Main)(int, char **, char **);
|
||||
Main const main = reinterpret_cast<Main>(_file->entry);
|
||||
/* call component entry point */
|
||||
/* XXX the function type for call_component_construct() is a candidate
|
||||
* for a base-internal header */
|
||||
typedef void (*Entry)(Genode::Environment &);
|
||||
Entry const entry = reinterpret_cast<Entry>(_file->entry);
|
||||
|
||||
return main(genode_argc, genode_argv, genode_envp);
|
||||
entry(env);
|
||||
}
|
||||
|
||||
void relocate() override
|
||||
@ -558,7 +553,12 @@ static void dump_loaded()
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
Genode::size_t Component::stack_size() { return 16*1024*sizeof(long); }
|
||||
char const * Component::name() { return "ep"; }
|
||||
|
||||
struct Failed_to_load_program { };
|
||||
|
||||
void Component::construct(Genode::Environment &env)
|
||||
{
|
||||
/* load program headers of linker now */
|
||||
if (!Ld::linker()->file())
|
||||
@ -575,7 +575,7 @@ int main()
|
||||
binary = new(Genode::env()->heap()) Binary();
|
||||
} catch (...) {
|
||||
PERR("LD: Failed to load program");
|
||||
return -1;
|
||||
throw Failed_to_load_program();
|
||||
}
|
||||
|
||||
/* print loaded object information */
|
||||
@ -592,6 +592,5 @@ int main()
|
||||
Link_map::dump();
|
||||
|
||||
/* start binary */
|
||||
return binary->call_entry_point();
|
||||
binary->call_entry_point(env);
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
* \brief Startup code
|
||||
* \author Christian Helmuth
|
||||
* \author Christian Prochaska
|
||||
* \author Norman Feske
|
||||
* \date 2006-04-12
|
||||
*
|
||||
* The startup code calls constructors for static objects before calling
|
||||
@ -12,7 +13,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2013 Genode Labs GmbH
|
||||
* Copyright (C) 2006-2016 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.
|
||||
@ -22,16 +23,13 @@
|
||||
#include <base/env.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/component.h>
|
||||
|
||||
/* platform-specific local helper functions */
|
||||
#include <startup/internal/_main_parent_cap.h>
|
||||
#include <base/internal/crt0.h>
|
||||
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
extern int main(int argc, char **argv, char **envp);
|
||||
|
||||
enum { ATEXIT_SIZE = 256 };
|
||||
|
||||
|
||||
@ -64,9 +62,9 @@ static struct atexit
|
||||
} _atexit;
|
||||
|
||||
|
||||
static Lock &atexit_lock()
|
||||
static Genode::Lock &atexit_lock()
|
||||
{
|
||||
static Lock _atexit_lock;
|
||||
static Genode::Lock _atexit_lock;
|
||||
return _atexit_lock;
|
||||
}
|
||||
|
||||
@ -79,7 +77,7 @@ static void atexit_enable()
|
||||
|
||||
static int atexit_register(struct atexit_fn *fn)
|
||||
{
|
||||
Lock::Guard atexit_lock_guard(atexit_lock());
|
||||
Genode::Lock::Guard atexit_lock_guard(atexit_lock());
|
||||
|
||||
if (!_atexit.enabled)
|
||||
return 0;
|
||||
@ -188,10 +186,10 @@ void genode_exit(int status)
|
||||
for (func = &_dtors_start; func != &_dtors_end; (*func++)());
|
||||
|
||||
/* inform parent about the exit status */
|
||||
env()->parent()->exit(status);
|
||||
Genode::env()->parent()->exit(status);
|
||||
|
||||
/* wait for destruction by the parent */
|
||||
sleep_forever();
|
||||
Genode::sleep_forever();
|
||||
}
|
||||
|
||||
|
||||
@ -213,15 +211,28 @@ int genode_argc = 1;
|
||||
char **genode_envp = 0;
|
||||
|
||||
|
||||
namespace Genode { extern bool inhibit_tracing; }
|
||||
/******************************************************
|
||||
** C entry function called by the crt0 startup code **
|
||||
******************************************************/
|
||||
|
||||
|
||||
namespace Genode {
|
||||
|
||||
/*
|
||||
* To be called from the context of the initial entrypoiny before
|
||||
* passing control to the 'Component::construct' function.
|
||||
*/
|
||||
void call_global_static_constructors()
|
||||
{
|
||||
void (**func)();
|
||||
for (func = &_ctors_end; func != &_ctors_start; (*--func)());
|
||||
}
|
||||
|
||||
/* XXX move to base-internal header */
|
||||
extern void bootstrap_component();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* C entry function called by the crt0 startup code
|
||||
*
|
||||
* Note, _main is executed twice when starting dynamic programs: in ld.lib.so
|
||||
* and also in the loaded binary.
|
||||
*/
|
||||
extern "C" int _main()
|
||||
{
|
||||
/*
|
||||
@ -234,20 +245,8 @@ extern "C" int _main()
|
||||
*/
|
||||
atexit_enable();
|
||||
|
||||
/* call constructors for static objects */
|
||||
void (**func)();
|
||||
for (func = &_ctors_end; func != &_ctors_start; (*--func)());
|
||||
Genode::bootstrap_component();
|
||||
|
||||
/* now, it is save to call printf */
|
||||
|
||||
/* enable tracing support */
|
||||
inhibit_tracing = false;
|
||||
|
||||
/* call real main function */
|
||||
int ret = main(genode_argc, genode_argv, genode_envp);
|
||||
|
||||
genode_exit(ret);
|
||||
|
||||
/* not reached */
|
||||
return ret;
|
||||
/* never reached */
|
||||
return 0;
|
||||
}
|
||||
|
98
repos/base/src/lib/startup/component_construct.cc
Normal file
98
repos/base/src/lib/startup/component_construct.cc
Normal file
@ -0,0 +1,98 @@
|
||||
/*
|
||||
* \brief Startup code for component construction
|
||||
* \author Christian Helmuth
|
||||
* \date 2016-01-21
|
||||
*
|
||||
* The component construction code is used by the startup library, which is
|
||||
* linked to static binaries and ld.lib.so. The code is also used by the
|
||||
* component_entry_point static library, which is linked to all dynamic
|
||||
* executables to make the fallback implementation and the
|
||||
* call_component_construct-hook function pointer available to these binaries.
|
||||
*
|
||||
* Note, for dynamic binaries we can't refer to the default implementation in
|
||||
* ld.lib.so as it is a component itself implementing the Component functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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/component.h>
|
||||
|
||||
|
||||
namespace Genode {
|
||||
|
||||
/*
|
||||
* Hook for intercepting the call of the 'Component::construct' method. By
|
||||
* hooking this function pointer in a library constructor, the libc is able
|
||||
* to create a task context for the component code. This context is
|
||||
* scheduled by the libc in a cooperative fashion, i.e. when the
|
||||
* component's entrypoint is activated.
|
||||
*/
|
||||
|
||||
extern void (*call_component_construct)(Genode::Environment &) __attribute__((weak));
|
||||
}
|
||||
|
||||
static void default_component_construct(Genode::Environment &env)
|
||||
{
|
||||
Component::construct(env);
|
||||
}
|
||||
|
||||
void (*Genode::call_component_construct)(Genode::Environment &) = &default_component_construct;
|
||||
|
||||
|
||||
/****************************************************
|
||||
** Fallback implementation of Component interface **
|
||||
****************************************************/
|
||||
|
||||
extern void genode_exit(int status);
|
||||
|
||||
static int exit_status;
|
||||
|
||||
static void exit_on_suspended() { genode_exit(exit_status); }
|
||||
|
||||
/*
|
||||
* Regular components provide the 'Component' interface as defined in
|
||||
* base/component.h. This fallback accommodates legacy components that lack the
|
||||
* implementation of this interface but come with a main function.
|
||||
*/
|
||||
|
||||
/*
|
||||
* XXX these symbols reside in the startup library - candidate for
|
||||
* base-internal header?
|
||||
*/
|
||||
extern char **genode_argv;
|
||||
extern int genode_argc;
|
||||
extern char **genode_envp;
|
||||
|
||||
extern int main(int argc, char **argv, char **envp);
|
||||
|
||||
void Component::construct(Genode::Environment &env) __attribute__((weak));
|
||||
void Component::construct(Genode::Environment &env)
|
||||
{
|
||||
/* call real main function */
|
||||
exit_status = main(genode_argc, genode_argv, genode_envp);
|
||||
|
||||
/* trigger suspend in the entry point */
|
||||
env.ep().schedule_suspend(exit_on_suspended, nullptr);
|
||||
|
||||
/* return to entrypoint and exit via exit_on_suspended() */
|
||||
}
|
||||
|
||||
|
||||
Genode::size_t Component::stack_size() __attribute__((weak));
|
||||
Genode::size_t Component::stack_size()
|
||||
{
|
||||
return 16UL * 1024 * sizeof(Genode::addr_t);
|
||||
}
|
||||
|
||||
|
||||
char const *Component::name() __attribute__((weak));
|
||||
char const *Component::name()
|
||||
{
|
||||
return "ep";
|
||||
}
|
32
repos/base/src/lib/startup/component_entry_point.cc
Normal file
32
repos/base/src/lib/startup/component_entry_point.cc
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* \brief Component entry point for dynamic executables
|
||||
* \author Christian Helmuth
|
||||
* \date 2016-01-21
|
||||
*
|
||||
* The ELF entry point of dynamic binaries is set to component_entry_point(),
|
||||
* which calls the call_component_construct-hook function pointer.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016 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/component.h>
|
||||
|
||||
|
||||
/* FIXME move to base-internal header */
|
||||
namespace Genode {
|
||||
extern void (*call_component_construct)(Environment &);
|
||||
}
|
||||
|
||||
namespace Genode {
|
||||
|
||||
void component_entry_point(Genode::Environment &env)
|
||||
{
|
||||
call_component_construct(env);
|
||||
}
|
||||
}
|
@ -25,7 +25,7 @@ addr_t init_main_thread_result;
|
||||
|
||||
extern void init_exception_handling();
|
||||
|
||||
namespace Genode { Rm_session * env_stack_area_rm_session(); }
|
||||
namespace Genode { extern Rm_session * const env_stack_area_rm_session; }
|
||||
|
||||
void prepare_init_main_thread();
|
||||
|
||||
@ -93,12 +93,6 @@ extern "C" void init_main_thread()
|
||||
/* 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_stack_area_rm_session();
|
||||
|
||||
/*
|
||||
* Trigger first exception. This step has two purposes.
|
||||
* First, it enables us to detect problems related to exception handling as
|
||||
|
Reference in New Issue
Block a user