2011-12-22 16:19:25 +01:00
|
|
|
/*
|
|
|
|
* \brief Core main program
|
|
|
|
* \author Norman Feske
|
|
|
|
* \date 2006-07-12
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2013-01-10 21:44:47 +01:00
|
|
|
* Copyright (C) 2006-2013 Genode Labs GmbH
|
2011-12-22 16:19:25 +01:00
|
|
|
*
|
|
|
|
* 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/snprintf.h>
|
|
|
|
#include <base/sleep.h>
|
|
|
|
#include <base/service.h>
|
|
|
|
#include <base/child.h>
|
2016-05-03 16:31:17 +02:00
|
|
|
#include <base/log.h>
|
2015-05-05 08:50:16 +02:00
|
|
|
#include <rm_session/connection.h>
|
|
|
|
#include <pd_session/connection.h>
|
2011-12-22 16:19:25 +01:00
|
|
|
#include <rom_session/connection.h>
|
|
|
|
#include <cpu_session/connection.h>
|
|
|
|
|
2016-05-04 12:27:17 +02:00
|
|
|
/* base-internal includes */
|
|
|
|
#include <base/internal/globals.h>
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
/* core includes */
|
|
|
|
#include <platform.h>
|
|
|
|
#include <core_env.h>
|
|
|
|
#include <ram_root.h>
|
|
|
|
#include <rom_root.h>
|
|
|
|
#include <rm_root.h>
|
|
|
|
#include <cpu_root.h>
|
|
|
|
#include <pd_root.h>
|
|
|
|
#include <log_root.h>
|
|
|
|
#include <io_mem_root.h>
|
|
|
|
#include <irq_root.h>
|
2013-08-10 03:44:55 +02:00
|
|
|
#include <trace/root.h>
|
2012-10-02 13:11:58 +02:00
|
|
|
#include <platform_services.h>
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
using namespace Genode;
|
|
|
|
|
|
|
|
|
|
|
|
/* pool of provided core services */
|
|
|
|
static Service_registry local_services;
|
|
|
|
|
|
|
|
|
|
|
|
/***************************************
|
|
|
|
** Core environment/platform support **
|
|
|
|
***************************************/
|
|
|
|
|
|
|
|
Core_env * Genode::core_env()
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Make sure to initialize the platform before constructing the core
|
|
|
|
* environment.
|
|
|
|
*/
|
|
|
|
platform();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* By placing the environment as static object here, we ensure that its
|
|
|
|
* constructor gets called when this function is used the first time.
|
|
|
|
*/
|
|
|
|
static Core_env _env;
|
|
|
|
return &_env;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2016-04-27 22:11:38 +02:00
|
|
|
Env_deprecated * Genode::env() {
|
2011-12-22 16:19:25 +01:00
|
|
|
return core_env(); }
|
|
|
|
|
|
|
|
|
|
|
|
Platform *Genode::platform_specific()
|
|
|
|
{
|
|
|
|
static Platform _platform;
|
|
|
|
return &_platform;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Platform_generic *Genode::platform() { return platform_specific(); }
|
|
|
|
|
|
|
|
|
|
|
|
/*************************
|
|
|
|
** Core parent support **
|
|
|
|
*************************/
|
|
|
|
|
|
|
|
Session_capability Core_parent::session(Parent::Service_name const &name,
|
2013-08-07 23:10:28 +02:00
|
|
|
Parent::Session_args const &args,
|
|
|
|
Affinity const &affinity)
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
|
|
|
Service *service = local_services.find(name.string());
|
|
|
|
|
|
|
|
if (service)
|
2013-08-07 23:10:28 +02:00
|
|
|
return service->session(args.string(), affinity);
|
2011-12-22 16:19:25 +01:00
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
warning("service_name=\"", name.string(), "\" args=\"", args.string(), "\" not handled");
|
2011-12-22 16:19:25 +01:00
|
|
|
return Session_capability();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/****************
|
|
|
|
** Core child **
|
|
|
|
****************/
|
|
|
|
|
|
|
|
class Core_child : public Child_policy
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Entry point used for serving the parent interface
|
|
|
|
*/
|
|
|
|
Rpc_entrypoint _entrypoint;
|
2014-05-21 16:12:00 +02:00
|
|
|
enum { STACK_SIZE = 2 * 1024 * sizeof(Genode::addr_t)};
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2013-01-30 17:00:00 +01:00
|
|
|
Service_registry &_local_services;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2016-04-27 16:04:58 +02:00
|
|
|
/*
|
|
|
|
* Dynamic linker, does not need to be valid because init is statically
|
|
|
|
* linked
|
|
|
|
*/
|
|
|
|
Dataspace_capability _ldso_ds;
|
|
|
|
|
|
|
|
Pd_session_client _pd;
|
|
|
|
Ram_session_client _ram;
|
|
|
|
Cpu_session_client _cpu;
|
|
|
|
|
2016-07-20 08:41:52 +02:00
|
|
|
Child::Initial_thread _initial_thread { _cpu, _pd, "init_main" };
|
2016-05-10 18:05:38 +02:00
|
|
|
|
2016-04-20 21:12:57 +02:00
|
|
|
Region_map_client _address_space;
|
|
|
|
|
2013-01-30 17:00:00 +01:00
|
|
|
Child _child;
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*/
|
2015-05-05 08:50:16 +02:00
|
|
|
Core_child(Dataspace_capability elf_ds, Pd_session_capability pd,
|
2016-01-19 20:24:22 +01:00
|
|
|
Ram_session_capability ram,
|
2016-04-15 15:19:22 +02:00
|
|
|
Cpu_session_capability cpu,
|
2015-05-05 08:50:16 +02:00
|
|
|
Service_registry &services)
|
2011-12-22 16:19:25 +01:00
|
|
|
:
|
2016-07-20 08:41:52 +02:00
|
|
|
_entrypoint(nullptr, STACK_SIZE, "init_child", false),
|
2013-01-30 17:00:00 +01:00
|
|
|
_local_services(services),
|
2016-04-27 16:04:58 +02:00
|
|
|
_pd(pd), _ram(ram), _cpu(cpu),
|
2016-04-20 21:12:57 +02:00
|
|
|
_address_space(Pd_session_client(pd).address_space()),
|
2016-05-10 18:05:38 +02:00
|
|
|
_child(elf_ds, _ldso_ds, _pd, _pd, _ram, _ram, _cpu, _initial_thread,
|
2016-04-27 16:04:58 +02:00
|
|
|
*env()->rm_session(), _address_space, _entrypoint, *this,
|
2015-05-05 08:50:16 +02:00
|
|
|
*_local_services.find(Pd_session::service_name()),
|
2013-01-30 17:00:00 +01:00
|
|
|
*_local_services.find(Ram_session::service_name()),
|
2016-04-15 15:19:22 +02:00
|
|
|
*_local_services.find(Cpu_session::service_name()))
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
|
|
|
_entrypoint.activate();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/****************************
|
|
|
|
** Child-policy interface **
|
|
|
|
****************************/
|
|
|
|
|
2013-05-08 11:10:35 +02:00
|
|
|
void filter_session_args(const char *, char *args,
|
|
|
|
Genode::size_t args_len)
|
|
|
|
{
|
|
|
|
using namespace Genode;
|
|
|
|
|
|
|
|
char label_buf[Parent::Session_args::MAX_SIZE];
|
|
|
|
Arg_string::find_arg(args, "label").string(label_buf, sizeof(label_buf), "");
|
|
|
|
|
|
|
|
char value_buf[Parent::Session_args::MAX_SIZE];
|
|
|
|
Genode::snprintf(value_buf, sizeof(value_buf),
|
|
|
|
"\"%s%s%s\"",
|
|
|
|
"init",
|
|
|
|
Genode::strcmp(label_buf, "") == 0 ? "" : " -> ",
|
|
|
|
label_buf);
|
|
|
|
|
|
|
|
Arg_string::set_arg(args, args_len, "label", value_buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
const char *name() const { return "init"; }
|
|
|
|
|
|
|
|
Service *resolve_session_request(const char *service, const char *)
|
|
|
|
{
|
2013-01-30 17:00:00 +01:00
|
|
|
return _local_services.find(service);
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-12-23 15:22:33 +01:00
|
|
|
/****************
|
|
|
|
** Signal API **
|
|
|
|
****************/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* In contrast to the 'Platform_env' used by non-core components, core disables
|
|
|
|
* the signal thread but overriding 'Genode::init_signal_thread' with a dummy.
|
|
|
|
* Within core, the signal thread is not needed as core is never supposed to
|
|
|
|
* receive any signals. Otherwise, the signal thread would be the only
|
|
|
|
* non-entrypoint thread within core, which would be a problem on NOVA where
|
|
|
|
* the creation of regular threads within core is unsupported.
|
|
|
|
*/
|
|
|
|
|
2016-05-04 12:27:17 +02:00
|
|
|
namespace Genode { void init_signal_thread(Env &) { } }
|
2015-12-23 15:22:33 +01:00
|
|
|
|
|
|
|
|
2015-06-16 20:39:09 +02:00
|
|
|
/*******************
|
|
|
|
** Trace support **
|
|
|
|
*******************/
|
|
|
|
|
|
|
|
Trace::Source_registry &Trace::sources()
|
|
|
|
{
|
|
|
|
static Trace::Source_registry inst;
|
|
|
|
return inst;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
/***************
|
|
|
|
** Core main **
|
|
|
|
***************/
|
|
|
|
|
2014-04-11 13:59:18 +02:00
|
|
|
namespace Genode {
|
|
|
|
extern bool inhibit_tracing;
|
|
|
|
extern char const *version_string;
|
|
|
|
}
|
2013-08-09 20:48:32 +02:00
|
|
|
|
2015-12-23 15:22:33 +01:00
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
int main()
|
|
|
|
{
|
2013-08-09 20:48:32 +02:00
|
|
|
/**
|
|
|
|
* Disable tracing within core because it is currently not fully implemented.
|
|
|
|
*/
|
|
|
|
inhibit_tracing = true;
|
|
|
|
|
2016-05-03 16:31:17 +02:00
|
|
|
log("Genode ", Genode::version_string);
|
2014-03-18 16:23:52 +01:00
|
|
|
|
2013-08-10 03:44:55 +02:00
|
|
|
static Trace::Policy_registry trace_policies;
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
/*
|
|
|
|
* Initialize root interfaces for our services
|
|
|
|
*/
|
|
|
|
Rpc_entrypoint *e = core_env()->entrypoint();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocate session meta data on distinct dataspaces to enable independent
|
|
|
|
* destruction (to enable quota trading) of session component objects.
|
|
|
|
*/
|
|
|
|
static Sliced_heap sliced_heap(env()->ram_session(), env()->rm_session());
|
|
|
|
|
2016-01-19 20:24:22 +01:00
|
|
|
/*
|
|
|
|
* Factory for creating RPC capabilities within core
|
|
|
|
*/
|
|
|
|
static Rpc_cap_factory rpc_cap_factory(sliced_heap);
|
|
|
|
|
2016-04-15 15:19:22 +02:00
|
|
|
static Pager_entrypoint pager_ep(rpc_cap_factory);
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
static Ram_root ram_root (e, e, platform()->ram_alloc(), &sliced_heap);
|
|
|
|
static Rom_root rom_root (e, e, platform()->rom_fs(), &sliced_heap);
|
2016-04-15 15:19:22 +02:00
|
|
|
static Rm_root rm_root (e, &sliced_heap, pager_ep);
|
|
|
|
static Cpu_root cpu_root (e, e, &pager_ep, &sliced_heap,
|
2015-06-16 20:39:09 +02:00
|
|
|
Trace::sources());
|
2016-04-15 15:19:22 +02:00
|
|
|
static Pd_root pd_root (e, e, pager_ep, &sliced_heap);
|
2011-12-22 16:19:25 +01:00
|
|
|
static Log_root log_root (e, &sliced_heap);
|
|
|
|
static Io_mem_root io_mem_root (e, e, platform()->io_mem_alloc(),
|
|
|
|
platform()->ram_alloc(), &sliced_heap);
|
2016-01-19 20:24:22 +01:00
|
|
|
static Irq_root irq_root (core_env()->pd_session(),
|
2015-06-09 12:42:39 +02:00
|
|
|
platform()->irq_alloc(), &sliced_heap);
|
2015-06-16 20:39:09 +02:00
|
|
|
static Trace::Root trace_root (e, &sliced_heap, Trace::sources(), trace_policies);
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Play our role as parent of init and declare our services.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static Local_service ls[] = {
|
|
|
|
Local_service(Rom_session::service_name(), &rom_root),
|
|
|
|
Local_service(Ram_session::service_name(), &ram_root),
|
|
|
|
Local_service(Rm_session::service_name(), &rm_root),
|
|
|
|
Local_service(Cpu_session::service_name(), &cpu_root),
|
|
|
|
Local_service(Pd_session::service_name(), &pd_root),
|
|
|
|
Local_service(Log_session::service_name(), &log_root),
|
|
|
|
Local_service(Io_mem_session::service_name(), &io_mem_root),
|
|
|
|
Local_service(Irq_session::service_name(), &irq_root),
|
2013-08-10 03:44:55 +02:00
|
|
|
Local_service(Trace::Session::service_name(), &trace_root)
|
2011-12-22 16:19:25 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/* make our local services known to service pool */
|
|
|
|
for (unsigned i = 0; i < sizeof(ls) / sizeof(Local_service); i++)
|
|
|
|
local_services.insert(&ls[i]);
|
|
|
|
|
2012-10-02 13:11:58 +02:00
|
|
|
/* make platform-specific services known to service pool */
|
|
|
|
platform_add_local_services(e, &sliced_heap, &local_services);
|
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
/* obtain ROM session with init binary */
|
|
|
|
Rom_session_capability init_rom_session_cap;
|
|
|
|
try {
|
|
|
|
static Rom_connection rom("init");
|
|
|
|
init_rom_session_cap = rom.cap(); }
|
|
|
|
catch (...) {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
error("ROM module \"init\" not present"); }
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
/* create ram session for init and transfer some of our own quota */
|
|
|
|
Ram_session_capability init_ram_session_cap
|
2013-08-07 23:10:28 +02:00
|
|
|
= static_cap_cast<Ram_session>(ram_root.session("ram_quota=32K", Affinity()));
|
2011-12-22 16:19:25 +01:00
|
|
|
Ram_session_client(init_ram_session_cap).ref_account(env()->ram_session_cap());
|
|
|
|
|
2014-10-16 11:15:46 +02:00
|
|
|
/* create CPU session for init and transfer all of the CPU quota to it */
|
|
|
|
static Cpu_session_component
|
2016-04-15 15:19:22 +02:00
|
|
|
cpu(e, e, &pager_ep, &sliced_heap, Trace::sources(),
|
2015-03-27 14:05:55 +01:00
|
|
|
"label=\"core\"", Affinity(), Cpu_session::QUOTA_LIMIT);
|
2014-10-16 11:15:46 +02:00
|
|
|
Cpu_session_capability cpu_cap = core_env()->entrypoint()->manage(&cpu);
|
2013-03-28 12:58:10 +01:00
|
|
|
Cpu_connection init_cpu("init");
|
2014-10-16 11:15:46 +02:00
|
|
|
init_cpu.ref_account(cpu_cap);
|
2015-03-27 14:05:55 +01:00
|
|
|
cpu.transfer_quota(init_cpu, Cpu_session::quota_lim_upscale(100, 100));
|
2014-10-16 11:15:46 +02:00
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
/* transfer all left memory to init, but leave some memory left for core */
|
|
|
|
/* NOTE: exception objects thrown in core components are currently allocated on
|
|
|
|
core's heap and not accounted by the component's meta data allocator */
|
2016-01-24 20:58:14 +01:00
|
|
|
Genode::size_t init_quota = platform()->ram_alloc()->avail() - 224*1024;
|
2011-12-22 16:19:25 +01:00
|
|
|
env()->ram_session()->transfer_quota(init_ram_session_cap, init_quota);
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 19:07:09 +02:00
|
|
|
log("", init_quota / (1024*1024), " MiB RAM assigned to init");
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2015-05-05 08:50:16 +02:00
|
|
|
Pd_connection init_pd("init");
|
2011-12-22 16:19:25 +01:00
|
|
|
Core_child *init = new (env()->heap())
|
|
|
|
Core_child(Rom_session_client(init_rom_session_cap).dataspace(),
|
2016-04-15 15:19:22 +02:00
|
|
|
init_pd, init_ram_session_cap, init_cpu.cap(),
|
2016-01-19 20:24:22 +01:00
|
|
|
local_services);
|
2011-12-22 16:19:25 +01:00
|
|
|
|
|
|
|
platform()->wait_for_exit();
|
|
|
|
|
|
|
|
destroy(env()->heap(), init);
|
|
|
|
|
|
|
|
rom_root.close(init_rom_session_cap);
|
|
|
|
ram_root.close(init_ram_session_cap);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|