/* * \brief Core main program * \author Norman Feske * \date 2006-07-12 */ /* * Copyright (C) 2006-2017 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU Affero General Public License version 3. */ /* Genode includes */ #include #include #include #include #include #include #include #include #include /* base-internal includes */ #include /* core includes */ #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Genode; /*************************************** ** 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; /* * Register signal-source entrypoint at core-local signal-transmitter back * end */ static bool signal_transmitter_initialized; if (!signal_transmitter_initialized) signal_transmitter_initialized = (init_core_signal_transmitter(_env.signal_ep()), true); return _env; } Env_deprecated *Genode::env_deprecated() { return &core_env(); } Platform &Genode::platform_specific() { static Platform _platform; return _platform; } Platform_generic &Genode::platform() { return platform_specific(); } Thread_capability Genode::main_thread_cap() { return Thread_capability(); } /** * Dummy implementation for core that has no parent to ask for resources */ void Genode::init_parent_resource_requests(Genode::Env &) {}; /**************** ** Core child ** ****************/ class Core_child : public Child_policy { private: Registry &_services; Capability _core_pd_cap; Pd_session &_core_pd; Capability _core_cpu_cap; Cpu_session &_core_cpu; Cap_quota const _cap_quota; Ram_quota const _ram_quota; Child _child; public: /** * Constructor */ Core_child(Registry &services, Region_map &local_rm, Pd_session &core_pd, Capability core_pd_cap, Cpu_session &core_cpu, Capability core_cpu_cap, Cap_quota cap_quota, Ram_quota ram_quota, Rpc_entrypoint &ep) : _services(services), _core_pd_cap (core_pd_cap), _core_pd (core_pd), _core_cpu_cap(core_cpu_cap), _core_cpu(core_cpu), _cap_quota(Child::effective_quota(cap_quota)), _ram_quota(Child::effective_quota(ram_quota)), _child(local_rm, ep, *this) { } /**************************** ** Child-policy interface ** ****************************/ Name name() const override { return "init"; } Route resolve_session_request(Service::Name const &name, Session_label const &label) override { Service *service = nullptr; _services.for_each([&] (Service &s) { if (!service && s.name() == name) service = &s; }); if (!service) throw Service_denied(); return Route { .service = *service, .label = label, .diag = Session::Diag() }; } void init(Pd_session &session, Capability cap) override { session.ref_account(_core_pd_cap); _core_pd.transfer_quota(cap, _cap_quota); _core_pd.transfer_quota(cap, _ram_quota); } void init(Cpu_session &session, Capability cap) override { session.ref_account(_core_cpu_cap); _core_cpu.transfer_quota(cap, Cpu_session::quota_lim_upscale(100, 100)); } Pd_session &ref_pd() override { return _core_pd; } Pd_session_capability ref_pd_cap() const override { return _core_pd_cap; } size_t session_alloc_batch_size() const override { return 128; } }; /**************** ** 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. */ void Genode::init_signal_thread(Env &) { } void Genode::destroy_signal_thread() { } /******************* ** Trace support ** *******************/ Trace::Source_registry &Trace::sources() { static Trace::Source_registry inst; return inst; } /*************** ** Core main ** ***************/ namespace Genode { extern bool inhibit_tracing; extern char const *version_string; } int main() { /** * Disable tracing within core because it is currently not fully implemented. */ inhibit_tracing = true; log("Genode ", Genode::version_string); static Trace::Policy_registry trace_policies; static Rpc_entrypoint &ep = core_env().entrypoint(); static Ram_allocator &core_ram_alloc = core_env().ram_allocator(); static Region_map &local_rm = core_env().local_rm(); Pd_session &core_pd = *core_env().pd_session(); Capability core_pd_cap = core_env().pd_session_cap(); static Registry services; /* * Allocate session meta data on distinct dataspaces to enable independent * destruction (to enable quota trading) of session component objects. */ static Sliced_heap sliced_heap(core_ram_alloc, local_rm); /* * Factory for creating RPC capabilities within core */ static Rpc_cap_factory rpc_cap_factory(sliced_heap); static Pager_entrypoint pager_ep(rpc_cap_factory); static Rom_root rom_root (ep, ep, platform().rom_fs(), sliced_heap); static Rm_root rm_root (ep, sliced_heap, pager_ep); static Cpu_root cpu_root (core_ram_alloc, local_rm, ep, ep, pager_ep, sliced_heap, Trace::sources()); static Pd_root pd_root (ep, core_env().signal_ep(), pager_ep, platform().ram_alloc(), local_rm, sliced_heap, platform_specific().core_mem_alloc()); static Log_root log_root (ep, sliced_heap); static Io_mem_root io_mem_root (ep, ep, platform().io_mem_alloc(), platform().ram_alloc(), sliced_heap); static Irq_root irq_root (*core_env().pd_session(), platform().irq_alloc(), sliced_heap); static Trace::Root trace_root (core_ram_alloc, local_rm, ep, sliced_heap, Trace::sources(), trace_policies); static Core_service rom_service (services, rom_root); static Core_service rm_service (services, rm_root); static Core_service cpu_service (services, cpu_root); static Core_service pd_service (services, pd_root); static Core_service log_service (services, log_root); static Core_service io_mem_service (services, io_mem_root); static Core_service irq_service (services, irq_root); static Core_service trace_service (services, trace_root); /* make platform-specific services known to service pool */ platform_add_local_services(ep, sliced_heap, services); size_t const avail_ram_quota = core_pd.avail_ram().value; size_t const avail_cap_quota = core_pd.avail_caps().value; size_t const preserved_ram_quota = 224*1024; size_t const preserved_cap_quota = 1000; if (avail_ram_quota < preserved_ram_quota) { error("core preservation exceeds platform RAM limit"); return -1; } if (avail_cap_quota < preserved_cap_quota) { error("core preservation exceeds platform cap quota limit"); return -1; } Ram_quota const init_ram_quota { avail_ram_quota - preserved_ram_quota }; Cap_quota const init_cap_quota { avail_cap_quota - preserved_cap_quota }; /* CPU session representing core */ static Cpu_session_component core_cpu(core_ram_alloc, local_rm, ep, ep, pager_ep, sliced_heap, Trace::sources(), "label=\"core\"", Affinity(), Cpu_session::QUOTA_LIMIT); Cpu_session_capability core_cpu_cap = ep.manage(&core_cpu); log("", init_ram_quota.value / (1024*1024), " MiB RAM and ", init_cap_quota, " caps " "assigned to init"); static Reconstructible init(services, local_rm, core_pd, core_pd_cap, core_cpu, core_cpu_cap, init_cap_quota, init_ram_quota, ep); platform().wait_for_exit(); init.destruct(); return 0; }