mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-16 22:28:18 +00:00
Adapt high-level components to new parent API
This patch adjusts the various users of the 'Child' API to the changes on the account of the new non-blocking parent interface. It also removes the use of the no-longer-available 'Connection::KEEP_OPEN' feature. With the adjustment, we took the opportunity to redesign several components to fit the non-blocking execution model much better, in particular the demo applications. Issue #2120
This commit is contained in:
committed by
Christian Helmuth
parent
8bafb9d41b
commit
b44f0554bd
@ -24,12 +24,10 @@
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Nitpicker"/></provides>
|
||||
<config>
|
||||
<domain name="pointer" layer="1" xray="no" origin="pointer" />
|
||||
<domain name="" layer="2" />
|
||||
<policy label="pointer" domain="pointer"/>
|
||||
<policy label="" domain=""/>
|
||||
<global-key name="KEY_F1" operation="kill" />
|
||||
<global-key name="KEY_F2" operation="xray" />
|
||||
<domain name="pointer" layer="1" label="no" content="client" xray="no" origin="pointer" />
|
||||
<domain name="default" layer="2" label="no" content="client" hover="always" focus="click" />
|
||||
<policy label="pointer" domain="pointer"/>
|
||||
<default-policy domain="default"/>
|
||||
</config>
|
||||
</start>
|
||||
<start name="pointer">
|
||||
|
@ -25,73 +25,68 @@
|
||||
|
||||
#include <util/arg_string.h>
|
||||
|
||||
#include "cpu_root.h"
|
||||
#include "genode_child_resources.h"
|
||||
#include "cpu_session_component.h"
|
||||
#include "pd_session_component.h"
|
||||
#include "ram_root.h"
|
||||
#include "rom.h"
|
||||
|
||||
|
||||
namespace Gdb_monitor { class App_child; }
|
||||
|
||||
class Gdb_monitor::App_child : public Child_policy,
|
||||
public Init::Child_policy_enforce_labeling
|
||||
class Gdb_monitor::App_child : public Child_policy
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Genode::Registered<Genode::Parent_service> Parent_service;
|
||||
typedef Genode::Registry<Parent_service> Parent_services;
|
||||
|
||||
private:
|
||||
|
||||
enum { STACK_SIZE = 4*1024*sizeof(long) };
|
||||
|
||||
const char *_unique_name;
|
||||
Init::Child_policy_enforce_labeling _labeling_policy;
|
||||
|
||||
Genode::Dataspace_capability _elf_ds;
|
||||
Genode::Dataspace_capability _ldso_ds;
|
||||
Genode::Env &_env;
|
||||
|
||||
Rpc_entrypoint _entrypoint;
|
||||
Genode::Ram_session_capability _ref_ram_cap { _env.ram_session_cap() };
|
||||
Genode::Ram_session_client _ref_ram { _ref_ram_cap };
|
||||
|
||||
Service_registry *_parent_services;
|
||||
Service_registry _local_services;
|
||||
const char *_unique_name;
|
||||
|
||||
Genode::Rpc_entrypoint *_root_ep;
|
||||
Genode::Dataspace_capability _elf_ds;
|
||||
|
||||
Init::Child_config _child_config;
|
||||
Genode::Region_map &_rm;
|
||||
|
||||
Genode::size_t _ram_quota;
|
||||
|
||||
Rpc_entrypoint _entrypoint;
|
||||
|
||||
Parent_services _parent_services;
|
||||
|
||||
Init::Child_config _child_config;
|
||||
|
||||
Init::Child_policy_provide_rom_file _binary_policy;
|
||||
Init::Child_policy_provide_rom_file _config_policy;
|
||||
|
||||
Genode_child_resources _genode_child_resources;
|
||||
Genode_child_resources _genode_child_resources;
|
||||
|
||||
Signal_dispatcher<App_child> _unresolved_page_fault_dispatcher;
|
||||
Signal_dispatcher<App_child> _unresolved_page_fault_dispatcher;
|
||||
|
||||
Dataspace_pool _managed_ds_map;
|
||||
Dataspace_pool _managed_ds_map;
|
||||
|
||||
Pd_session_component _pd {_unique_name, _entrypoint, _managed_ds_map};
|
||||
Pd_session_component _pd {_unique_name, _entrypoint, _managed_ds_map};
|
||||
Pd_service::Single_session_factory _pd_factory { _pd };
|
||||
Pd_service _pd_service { _pd_factory };
|
||||
|
||||
Cpu_root _cpu_root;
|
||||
Cpu_session_client _cpu_session;
|
||||
Local_cpu_factory _cpu_factory;
|
||||
Cpu_service _cpu_service { _cpu_factory };
|
||||
|
||||
Ram_session_client _ram_session;
|
||||
Local_rom_factory _rom_factory;
|
||||
Rom_service _rom_service { _rom_factory };
|
||||
|
||||
Region_map_client _address_space { _pd.address_space() };
|
||||
|
||||
Child::Initial_thread _initial_thread;
|
||||
|
||||
Parent_service _parent_pd_service { "" };
|
||||
Parent_service _parent_ram_service { "" };
|
||||
Parent_service _parent_cpu_service { "" };
|
||||
|
||||
Child *_child;
|
||||
|
||||
Rom_service _rom_service;
|
||||
|
||||
|
||||
Cpu_session_capability _get_cpu_session_cap()
|
||||
{
|
||||
_entrypoint.manage(&_cpu_root);
|
||||
char args[64];
|
||||
Genode::snprintf(args, sizeof(args), "ram_quota=64K, label=\"%s\"", _unique_name);
|
||||
return static_cap_cast<Cpu_session>(_cpu_root.session(args, Affinity()));
|
||||
}
|
||||
Child *_child;
|
||||
|
||||
/* FIXME */
|
||||
#if 0
|
||||
/**
|
||||
* Proxy for a service provided by the child
|
||||
*/
|
||||
@ -229,12 +224,23 @@ class Gdb_monitor::App_child : public Child_policy,
|
||||
child_ram.transfer_quota(env()->ram_session_cap(), ram_quota);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
void _dispatch_unresolved_page_fault(unsigned)
|
||||
{
|
||||
_genode_child_resources.cpu_session_component()->handle_unresolved_page_fault();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static Genode::Service *_find_service(Genode::Registry<T> &services,
|
||||
Genode::Service::Name const &name)
|
||||
{
|
||||
Genode::Service *service = nullptr;
|
||||
services.for_each([&] (T &s) {
|
||||
if (!service && (s.name() == name))
|
||||
service = &s; });
|
||||
return service;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
@ -244,38 +250,30 @@ class Gdb_monitor::App_child : public Child_policy,
|
||||
* services provided by the child and announced
|
||||
* towards the parent of GDB monitor
|
||||
*/
|
||||
App_child(const char *unique_name,
|
||||
Genode::Dataspace_capability elf_ds,
|
||||
Genode::Dataspace_capability ldso_ds,
|
||||
Genode::Ram_session_capability ram_session,
|
||||
Genode::Cap_session *cap_session,
|
||||
Service_registry *parent_services,
|
||||
Genode::Rpc_entrypoint *root_ep,
|
||||
App_child(Genode::Env &env,
|
||||
const char *unique_name,
|
||||
Genode::Pd_session &pd,
|
||||
Genode::Region_map &rm,
|
||||
Genode::size_t ram_quota,
|
||||
Signal_receiver *signal_receiver,
|
||||
Xml_node target_node)
|
||||
: Init::Child_policy_enforce_labeling(unique_name),
|
||||
: _labeling_policy(unique_name),
|
||||
_env(env),
|
||||
_unique_name(unique_name),
|
||||
_elf_ds(elf_ds),
|
||||
_ldso_ds(ldso_ds),
|
||||
_entrypoint(cap_session, STACK_SIZE, "GDB monitor entrypoint name"),
|
||||
_parent_services(parent_services),
|
||||
_root_ep(root_ep),
|
||||
_child_config(ram_session, target_node),
|
||||
_binary_policy("binary", elf_ds, &_entrypoint),
|
||||
_rm(rm),
|
||||
_ram_quota(ram_quota),
|
||||
_entrypoint(&pd, STACK_SIZE, "GDB monitor entrypoint"),
|
||||
_child_config(env.ram(), rm, target_node),
|
||||
_config_policy("config", _child_config.dataspace(), &_entrypoint),
|
||||
_unresolved_page_fault_dispatcher(*signal_receiver,
|
||||
*this,
|
||||
&App_child::_dispatch_unresolved_page_fault),
|
||||
_cpu_root(&_entrypoint, &_entrypoint, env()->heap(), _pd.core_pd_cap(),
|
||||
signal_receiver, &_genode_child_resources),
|
||||
_cpu_session(_get_cpu_session_cap()),
|
||||
_ram_session(ram_session),
|
||||
_initial_thread(_cpu_session, _pd.cap(), unique_name),
|
||||
_rom_service(&_entrypoint, env()->heap())
|
||||
_cpu_factory(_env, _entrypoint, Genode::env()->heap(), _pd.core_pd_cap(),
|
||||
signal_receiver, &_genode_child_resources),
|
||||
_rom_factory(env, _entrypoint)
|
||||
{
|
||||
_genode_child_resources.region_map_component(&_pd.region_map());
|
||||
_pd.region_map().fault_handler(_unresolved_page_fault_dispatcher);
|
||||
_local_services.insert(&_rom_service);
|
||||
}
|
||||
|
||||
~App_child()
|
||||
@ -290,68 +288,72 @@ class Gdb_monitor::App_child : public Child_policy,
|
||||
|
||||
void start()
|
||||
{
|
||||
_child = new (env()->heap()) Child(_elf_ds,
|
||||
_ldso_ds,
|
||||
_pd.cap(),
|
||||
_pd,
|
||||
_ram_session,
|
||||
_ram_session,
|
||||
_cpu_session,
|
||||
_initial_thread,
|
||||
*Genode::env()->rm_session(),
|
||||
_address_space,
|
||||
_entrypoint,
|
||||
*this);
|
||||
_child = new (env()->heap()) Child(_rm, _entrypoint, *this);
|
||||
}
|
||||
|
||||
/****************************
|
||||
** Child-policy interface **
|
||||
****************************/
|
||||
|
||||
const char *name() const { return _unique_name; }
|
||||
Name name() const override { return _unique_name; }
|
||||
|
||||
void filter_session_args(const char *, char *args, Genode::size_t args_len)
|
||||
Genode::Ram_session &ref_ram() override { return _ref_ram; }
|
||||
|
||||
Genode::Ram_session_capability ref_ram_cap() const override { return _ref_ram_cap; }
|
||||
|
||||
void init(Genode::Ram_session &session,
|
||||
Genode::Ram_session_capability cap) override
|
||||
{
|
||||
Init::Child_policy_enforce_labeling::filter_session_args(0, args, args_len);
|
||||
session.ref_account(_ref_ram_cap);
|
||||
_ref_ram.transfer_quota(cap, _ram_quota);
|
||||
}
|
||||
|
||||
Service *resolve_session_request(const char *service_name,
|
||||
const char *args)
|
||||
void filter_session_args(Service::Name const&, char *args, Genode::size_t args_len) override
|
||||
{
|
||||
Service *service = 0;
|
||||
_labeling_policy.filter_session_args(0, args, args_len);
|
||||
}
|
||||
|
||||
/* check for binary file request */
|
||||
if ((service = _binary_policy.resolve_session_request(service_name, args)))
|
||||
return service;
|
||||
Service &resolve_session_request(Genode::Service::Name const &service_name,
|
||||
Genode::Session_state::Args const &args) override
|
||||
{
|
||||
Service *service = nullptr;
|
||||
|
||||
/* check for config file request */
|
||||
if ((service = _config_policy.resolve_session_request(service_name, args)))
|
||||
return service;
|
||||
if ((service = _config_policy.resolve_session_request(service_name.string(), args.string())))
|
||||
return *service;
|
||||
|
||||
service = _local_services.find(service_name);
|
||||
if (service)
|
||||
return service;
|
||||
if (service_name == "CPU")
|
||||
return _cpu_service;
|
||||
|
||||
service = _parent_services->find(service_name);
|
||||
if (!service) {
|
||||
service = new (env()->heap()) Parent_service(service_name);
|
||||
_parent_services->insert(service);
|
||||
}
|
||||
if (service_name == "PD")
|
||||
return _pd_service;
|
||||
|
||||
return service;
|
||||
if (service_name == "ROM")
|
||||
return _rom_service;
|
||||
|
||||
service = _find_service(_parent_services, service_name);
|
||||
if (!service)
|
||||
service = new (env()->heap()) Parent_service(_parent_services, _env, service_name);
|
||||
|
||||
if (!service)
|
||||
throw Parent::Service_denied();
|
||||
|
||||
return *service;
|
||||
}
|
||||
|
||||
bool announce_service(const char *name,
|
||||
Root_capability root,
|
||||
Allocator *alloc,
|
||||
Server *server)
|
||||
// XXX adjust to API change, need to serve a "session_requests" rom
|
||||
// to the child
|
||||
void announce_service(Service::Name const &name) override
|
||||
{
|
||||
/* FIXME */
|
||||
#if 0
|
||||
/* create and announce proxy for the child's root interface */
|
||||
Child_service_root *r = new (alloc)
|
||||
Child_service_root(_ram_session, root);
|
||||
|
||||
Genode::env()->parent()->announce(name, _root_ep->manage(r));
|
||||
return true;
|
||||
#else
|
||||
Genode::warning(__PRETTY_FUNCTION__, ": not implemented");
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,78 +0,0 @@
|
||||
/*
|
||||
* \brief CPU root interface
|
||||
* \author Christian Helmuth
|
||||
* \date 2006-07-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _CPU_ROOT_H_
|
||||
#define _CPU_ROOT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <root/component.h>
|
||||
|
||||
/* core includes */
|
||||
#include <cpu_session_component.h>
|
||||
|
||||
/* GDB monitor includes */
|
||||
#include "genode_child_resources.h"
|
||||
|
||||
namespace Gdb_monitor { class Cpu_root; }
|
||||
|
||||
class Gdb_monitor::Cpu_root : public Root_component<Cpu_session_component>
|
||||
{
|
||||
private:
|
||||
|
||||
Rpc_entrypoint *_thread_ep;
|
||||
Allocator *_md_alloc;
|
||||
Pd_session_capability _core_pd;
|
||||
Genode::Signal_receiver *_signal_receiver;
|
||||
Genode_child_resources *_genode_child_resources;
|
||||
|
||||
protected:
|
||||
|
||||
Cpu_session_component *_create_session(const char *args)
|
||||
{
|
||||
Cpu_session_component *cpu_session_component =
|
||||
new (md_alloc())
|
||||
Cpu_session_component(_thread_ep,
|
||||
_md_alloc,
|
||||
_core_pd,
|
||||
_signal_receiver,
|
||||
args);
|
||||
_genode_child_resources->cpu_session_component(cpu_session_component);
|
||||
return cpu_session_component;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param session_ep entry point for managing cpu session objects
|
||||
* \param thread_ep entry point for managing threads
|
||||
* \param md_alloc meta data allocator to be used by root component
|
||||
*/
|
||||
Cpu_root(Rpc_entrypoint *session_ep,
|
||||
Rpc_entrypoint *thread_ep,
|
||||
Allocator *md_alloc,
|
||||
Pd_session_capability core_pd,
|
||||
Genode::Signal_receiver *signal_receiver,
|
||||
Genode_child_resources *genode_child_resources)
|
||||
:
|
||||
Root_component<Cpu_session_component>(session_ep, md_alloc),
|
||||
_thread_ep(thread_ep),
|
||||
_md_alloc(md_alloc),
|
||||
_core_pd(core_pd),
|
||||
_signal_receiver(signal_receiver),
|
||||
_genode_child_resources(genode_child_resources)
|
||||
{ }
|
||||
};
|
||||
|
||||
#endif /* _CPU_ROOT_H_ */
|
@ -36,7 +36,7 @@ Cpu_session &Cpu_session_component::parent_cpu_session()
|
||||
|
||||
Rpc_entrypoint &Cpu_session_component::thread_ep()
|
||||
{
|
||||
return *_thread_ep;
|
||||
return _ep;
|
||||
}
|
||||
|
||||
|
||||
@ -299,18 +299,22 @@ Capability<Cpu_session::Native_cpu> Cpu_session_component::native_cpu()
|
||||
}
|
||||
|
||||
|
||||
Cpu_session_component::Cpu_session_component(Rpc_entrypoint *thread_ep,
|
||||
Cpu_session_component::Cpu_session_component(Genode::Env &env,
|
||||
Rpc_entrypoint &ep,
|
||||
Allocator *md_alloc,
|
||||
Pd_session_capability core_pd,
|
||||
Signal_receiver *exception_signal_receiver,
|
||||
const char *args)
|
||||
: _thread_ep(thread_ep),
|
||||
const char *args,
|
||||
Affinity const &affinity)
|
||||
: _env(env),
|
||||
_ep(ep),
|
||||
_md_alloc(md_alloc),
|
||||
_core_pd(core_pd),
|
||||
_parent_cpu_session(env()->parent()->session<Cpu_session>(args)),
|
||||
_parent_cpu_session(env.session<Cpu_session>(_id_space_element.id(), args, affinity)),
|
||||
_exception_signal_receiver(exception_signal_receiver),
|
||||
_native_cpu_cap(_setup_native_cpu())
|
||||
{
|
||||
_ep.manage(this);
|
||||
}
|
||||
|
||||
|
||||
@ -323,6 +327,8 @@ Cpu_session_component::~Cpu_session_component()
|
||||
}
|
||||
|
||||
_cleanup_native_cpu();
|
||||
|
||||
_ep.dissolve(this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -16,43 +16,59 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/allocator.h>
|
||||
#include <base/env.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <base/service.h>
|
||||
#include <base/thread.h>
|
||||
#include <base/printf.h>
|
||||
#include <cpu_session/client.h>
|
||||
#include <parent/parent.h>
|
||||
#include <pd_session/capability.h>
|
||||
|
||||
/* GDB monitor includes */
|
||||
#include "append_list.h"
|
||||
#include "genode_child_resources.h"
|
||||
|
||||
namespace Gdb_monitor
|
||||
{
|
||||
class Cpu_session_component;
|
||||
class Cpu_thread_component;
|
||||
class Local_cpu_factory;
|
||||
|
||||
typedef Genode::Local_service<Cpu_session_component> Cpu_service;
|
||||
|
||||
using namespace Genode;
|
||||
}
|
||||
|
||||
|
||||
class Gdb_monitor::Cpu_session_component : public Rpc_object<Cpu_session>
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
Rpc_entrypoint *_thread_ep;
|
||||
Allocator *_md_alloc;
|
||||
Genode::Env &_env;
|
||||
|
||||
Pd_session_capability _core_pd;
|
||||
Genode::Parent::Client _parent_client;
|
||||
|
||||
Id_space<Parent::Client>::Element const _id_space_element
|
||||
{ _parent_client, _env.id_space() };
|
||||
|
||||
Cpu_session_client _parent_cpu_session;
|
||||
Signal_receiver *_exception_signal_receiver;
|
||||
Rpc_entrypoint &_ep;
|
||||
Allocator *_md_alloc;
|
||||
|
||||
Append_list<Cpu_thread_component> _thread_list;
|
||||
Pd_session_capability _core_pd;
|
||||
|
||||
bool _stop_new_threads = true;
|
||||
Lock _stop_new_threads_lock;
|
||||
Cpu_session_client _parent_cpu_session;
|
||||
Signal_receiver *_exception_signal_receiver;
|
||||
|
||||
Capability<Cpu_session::Native_cpu> _native_cpu_cap;
|
||||
Append_list<Cpu_thread_component> _thread_list;
|
||||
|
||||
Capability<Cpu_session::Native_cpu> _setup_native_cpu();
|
||||
bool _stop_new_threads = true;
|
||||
Lock _stop_new_threads_lock;
|
||||
|
||||
Capability<Cpu_session::Native_cpu> _native_cpu_cap;
|
||||
|
||||
Capability<Cpu_session::Native_cpu> _setup_native_cpu();
|
||||
void _cleanup_native_cpu();
|
||||
|
||||
public:
|
||||
@ -60,11 +76,13 @@ class Gdb_monitor::Cpu_session_component : public Rpc_object<Cpu_session>
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Cpu_session_component(Rpc_entrypoint *thread_ep,
|
||||
Allocator *md_alloc,
|
||||
Pd_session_capability core_pd,
|
||||
Signal_receiver *exception_signal_receiver,
|
||||
const char *args);
|
||||
Cpu_session_component(Genode::Env &env,
|
||||
Rpc_entrypoint &ep,
|
||||
Allocator *md_alloc,
|
||||
Pd_session_capability core_pd,
|
||||
Signal_receiver *exception_signal_receiver,
|
||||
const char *args,
|
||||
Affinity const &affinity);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
@ -109,4 +127,59 @@ class Gdb_monitor::Cpu_session_component : public Rpc_object<Cpu_session>
|
||||
Capability<Native_cpu> native_cpu() override;
|
||||
};
|
||||
|
||||
|
||||
class Gdb_monitor::Local_cpu_factory : public Cpu_service::Factory
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env &_env;
|
||||
Genode::Rpc_entrypoint &_ep;
|
||||
|
||||
Allocator *_md_alloc;
|
||||
Pd_session_capability _core_pd;
|
||||
Genode::Signal_receiver *_signal_receiver;
|
||||
Genode_child_resources *_genode_child_resources;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Local_cpu_factory(Genode::Env &env, Genode::Rpc_entrypoint &ep,
|
||||
Allocator *md_alloc,
|
||||
Pd_session_capability core_pd,
|
||||
Genode::Signal_receiver *signal_receiver,
|
||||
Genode_child_resources *genode_child_resources)
|
||||
: _env(env), _ep(ep),
|
||||
_md_alloc(md_alloc),
|
||||
_core_pd(core_pd),
|
||||
_signal_receiver(signal_receiver),
|
||||
_genode_child_resources(genode_child_resources)
|
||||
{ }
|
||||
|
||||
/***********************
|
||||
** Factory interface **
|
||||
***********************/
|
||||
|
||||
Cpu_session_component &create(Args const &args, Affinity affinity) override
|
||||
{
|
||||
Cpu_session_component *cpu_session_component =
|
||||
new (_md_alloc)
|
||||
Cpu_session_component(_env,
|
||||
_ep,
|
||||
_md_alloc,
|
||||
_core_pd,
|
||||
_signal_receiver,
|
||||
args.string(),
|
||||
affinity);
|
||||
_genode_child_resources->cpu_session_component(cpu_session_component);
|
||||
return *cpu_session_component;
|
||||
}
|
||||
|
||||
void upgrade(Cpu_session_component &, Args const &) override { }
|
||||
|
||||
void destroy(Cpu_session_component &session) override
|
||||
{
|
||||
Genode::destroy(env()->heap(), &session);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _CPU_SESSION_COMPONENT_H_ */
|
||||
|
@ -46,6 +46,8 @@ int linux_detach_one_lwp (struct inferior_list_entry *entry, void *args);
|
||||
|
||||
static bool verbose = false;
|
||||
|
||||
Genode::Env *genode_env;
|
||||
|
||||
static int _new_thread_pipe[2];
|
||||
|
||||
/*
|
||||
@ -273,16 +275,6 @@ extern "C" int fork()
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* look for dynamic linker */
|
||||
|
||||
Dataspace_capability ldso_cap;
|
||||
try {
|
||||
Rom_connection ldso_rom("ld.lib.so");
|
||||
ldso_cap = clone_rom(ldso_rom.dataspace());
|
||||
} catch (...) {
|
||||
warning("ld.lib.so not found");
|
||||
}
|
||||
|
||||
/* extract target filename from config file */
|
||||
|
||||
static char filename[32] = "";
|
||||
@ -319,34 +311,6 @@ extern "C" int fork()
|
||||
Number_of_bytes ram_quota = env()->ram_session()->avail() - preserved_ram_quota;
|
||||
|
||||
/* start the application */
|
||||
char *unique_name = filename;
|
||||
Capability<Rom_dataspace> file_cap;
|
||||
try {
|
||||
static Rom_connection rom(prefixed_label(Session_label(Cstring(unique_name)),
|
||||
Session_label(Cstring(filename))).string());
|
||||
file_cap = rom.dataspace();
|
||||
} catch (Rom_connection::Rom_connection_failed) {
|
||||
error("could not access ROM module \"", Cstring(filename), "\"");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* copy ELF image to writable dataspace */
|
||||
Genode::size_t elf_size = Dataspace_client(file_cap).size();
|
||||
Dataspace_capability elf_cap = clone_rom(file_cap);
|
||||
|
||||
/* create ram session for child with some of our own quota */
|
||||
static Ram_connection ram;
|
||||
ram.ref_account(env()->ram_session_cap());
|
||||
env()->ram_session()->transfer_quota(ram.cap(), (Genode::size_t)ram_quota - elf_size);
|
||||
|
||||
/* cap session for allocating capabilities for parent interfaces */
|
||||
static Cap_connection cap_session;
|
||||
|
||||
static Service_registry parent_services;
|
||||
|
||||
enum { CHILD_ROOT_EP_STACK = 1024*sizeof(addr_t) };
|
||||
static Rpc_entrypoint child_root_ep(&cap_session, CHILD_ROOT_EP_STACK,
|
||||
"child_root_ep");
|
||||
|
||||
static Signal_receiver signal_receiver;
|
||||
|
||||
@ -354,19 +318,22 @@ extern "C" int fork()
|
||||
signal_handler_thread(&signal_receiver);
|
||||
signal_handler_thread.start();
|
||||
|
||||
App_child *child = new (env()->heap()) App_child(unique_name,
|
||||
elf_cap,
|
||||
ldso_cap,
|
||||
ram.cap(),
|
||||
&cap_session,
|
||||
&parent_services,
|
||||
&child_root_ep,
|
||||
App_child *child = new (env()->heap()) App_child(*genode_env,
|
||||
filename,
|
||||
genode_env->pd(),
|
||||
genode_env->rm(),
|
||||
ram_quota,
|
||||
&signal_receiver,
|
||||
target_node);
|
||||
|
||||
_genode_child_resources = child->genode_child_resources();
|
||||
|
||||
child->start();
|
||||
try {
|
||||
child->start();
|
||||
} catch (...) {
|
||||
Genode::error("Could not start child process");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return GENODE_MAIN_LWPID;
|
||||
}
|
||||
|
@ -14,10 +14,12 @@
|
||||
#ifndef _GENODE_CHILD_RESOURCES_H_
|
||||
#define _GENODE_CHILD_RESOURCES_H_
|
||||
|
||||
#include "cpu_session_component.h"
|
||||
#include "region_map_component.h"
|
||||
|
||||
namespace Gdb_monitor { class Genode_child_resources; }
|
||||
namespace Gdb_monitor {
|
||||
class Cpu_session_component;
|
||||
class Genode_child_resources;
|
||||
}
|
||||
|
||||
class Gdb_monitor::Genode_child_resources
|
||||
{
|
||||
|
@ -11,6 +11,7 @@
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <base/component.h>
|
||||
|
||||
/*
|
||||
* Suppress messages of libc dummy functions
|
||||
@ -30,10 +31,14 @@ extern "C" const char host_name[] = "";
|
||||
|
||||
extern "C" int gdbserver_main(int argc, const char *argv[]);
|
||||
|
||||
int main()
|
||||
extern Genode::Env *genode_env;
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
genode_env = &env;
|
||||
|
||||
int argc = 3;
|
||||
const char *argv[] = { "gdbserver", "/dev/terminal", "target", 0 };
|
||||
|
||||
return gdbserver_main(argc, argv);
|
||||
gdbserver_main(argc, argv);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
namespace Gdb_monitor {
|
||||
class Pd_session_component;
|
||||
typedef Genode::Local_service<Pd_session_component> Pd_service;
|
||||
using namespace Genode;
|
||||
}
|
||||
|
||||
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* \brief RAM root interface
|
||||
* \author Norman Feske
|
||||
* \date 2006-05-30
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _RAM_ROOT_H_
|
||||
#define _RAM_ROOT_H_
|
||||
|
||||
#include <root/component.h>
|
||||
|
||||
#include "ram_session_component.h"
|
||||
|
||||
namespace Gdb_monitor { class Ram_root; }
|
||||
|
||||
class Gdb_monitor::Ram_root : public Root_component<Ram_session_component>
|
||||
{
|
||||
protected:
|
||||
|
||||
Ram_session_component *_create_session(const char *args)
|
||||
{
|
||||
return new (md_alloc())
|
||||
Ram_session_component(args);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param session_ep entry point for managing ram session objects
|
||||
* \param md_alloc meta-data allocator to be used by root component
|
||||
*/
|
||||
Ram_root(Rpc_entrypoint *session_ep,
|
||||
Allocator *md_alloc)
|
||||
: Root_component<Ram_session_component>(session_ep, md_alloc)
|
||||
{ }
|
||||
};
|
||||
|
||||
#endif /* _RAM_ROOT_H_ */
|
@ -20,8 +20,10 @@
|
||||
using namespace Genode;
|
||||
using namespace Gdb_monitor;
|
||||
|
||||
Ram_session_component::Ram_session_component(const char *args)
|
||||
: _parent_ram_session(env()->parent()->session<Ram_session>(args))
|
||||
Ram_session_component::Ram_session_component(Genode::Env &env, const char *args,
|
||||
Affinity const &affinity)
|
||||
: _env(env),
|
||||
_parent_ram_session(_env.session<Ram_session>(_id_space_element.id(), args, affinity))
|
||||
{ }
|
||||
|
||||
|
||||
|
@ -28,6 +28,13 @@ class Gdb_monitor::Ram_session_component : public Rpc_object<Ram_session>
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env &_env;
|
||||
|
||||
Genode::Parent::Client _parent_client;
|
||||
|
||||
Id_space<Parent::Client>::Element const _id_space_element
|
||||
{ _parent_client, _env.id_space() };
|
||||
|
||||
Genode::Ram_session_client _parent_ram_session;
|
||||
|
||||
public:
|
||||
@ -35,7 +42,8 @@ class Gdb_monitor::Ram_session_component : public Rpc_object<Ram_session>
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Ram_session_component(const char *args);
|
||||
Ram_session_component(Genode::Env &env, const char *args,
|
||||
Affinity const &affinity);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
|
@ -25,8 +25,9 @@
|
||||
namespace Gdb_monitor
|
||||
{
|
||||
class Rom_session_component;
|
||||
class Rom_root;
|
||||
class Rom_service;
|
||||
class Local_rom_factory;
|
||||
typedef Genode::Local_service<Rom_session_component> Rom_service;
|
||||
|
||||
using namespace Genode;
|
||||
}
|
||||
|
||||
@ -65,68 +66,68 @@ class Gdb_monitor::Rom_session_component : public Rpc_object<Rom_session>
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Rpc_entrypoint &_ep;
|
||||
|
||||
Capability<Ram_dataspace> _clone_cap;
|
||||
|
||||
public:
|
||||
|
||||
Rom_session_component(char const *filename)
|
||||
: _clone_cap(clone_rom(Rom_connection(filename).dataspace()))
|
||||
{ }
|
||||
Rom_session_component(Genode::Rpc_entrypoint &ep, char const *filename)
|
||||
: _ep(ep),
|
||||
_clone_cap(clone_rom(Rom_connection(filename).dataspace()))
|
||||
{ _ep.manage(this); }
|
||||
|
||||
~Rom_session_component() { env()->ram_session()->free(_clone_cap); }
|
||||
~Rom_session_component()
|
||||
{
|
||||
env()->ram_session()->free(_clone_cap);
|
||||
_ep.dissolve(this);
|
||||
}
|
||||
|
||||
Capability<Rom_dataspace> dataspace()
|
||||
/***************************
|
||||
** ROM session interface **
|
||||
***************************/
|
||||
|
||||
Rom_dataspace_capability dataspace() override
|
||||
{
|
||||
return static_cap_cast<Rom_dataspace>(
|
||||
static_cap_cast<Dataspace>(_clone_cap));
|
||||
}
|
||||
|
||||
void release() { }
|
||||
|
||||
void sigh(Genode::Signal_context_capability) { }
|
||||
void sigh(Genode::Signal_context_capability) override { }
|
||||
};
|
||||
|
||||
|
||||
class Gdb_monitor::Rom_root : public Root_component<Rom_session_component>
|
||||
{
|
||||
protected:
|
||||
|
||||
Rom_session_component *_create_session(char const *args)
|
||||
{
|
||||
Session_label const label = label_from_args(args);
|
||||
|
||||
return new (md_alloc())
|
||||
Rom_session_component(label.last_element().string());
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Rom_root(Rpc_entrypoint *session_ep,
|
||||
Allocator *md_alloc)
|
||||
: Root_component<Rom_session_component>(session_ep, md_alloc)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
class Gdb_monitor::Rom_service : public Service
|
||||
class Gdb_monitor::Local_rom_factory : public Rom_service::Factory
|
||||
{
|
||||
private:
|
||||
|
||||
Rom_root _root;
|
||||
Genode::Env &_env;
|
||||
Genode::Rpc_entrypoint &_ep;
|
||||
|
||||
public:
|
||||
|
||||
Rom_service(Rpc_entrypoint *entrypoint,
|
||||
Allocator *md_alloc)
|
||||
: Service("ROM"), _root(entrypoint, md_alloc)
|
||||
{ }
|
||||
Local_rom_factory(Genode::Env &env, Genode::Rpc_entrypoint &ep)
|
||||
: _env(env), _ep(ep) { }
|
||||
|
||||
Capability<Session> session(char const *args, Affinity const &affinity) {
|
||||
return _root.session(args, affinity); }
|
||||
/***********************
|
||||
** Factory interface **
|
||||
***********************/
|
||||
|
||||
void upgrade(Capability<Session>, char const *) { }
|
||||
Rom_session_component &create(Args const &args, Affinity) override
|
||||
{
|
||||
Session_label const label = label_from_args(args.string());
|
||||
|
||||
void close(Capability<Session> cap) { _root.close(cap); }
|
||||
return *new (env()->heap())
|
||||
Rom_session_component(_ep, label.last_element().string());
|
||||
}
|
||||
|
||||
void upgrade(Rom_session_component &, Args const &) override { }
|
||||
|
||||
void destroy(Rom_session_component &session) override
|
||||
{
|
||||
Genode::destroy(env()->heap(), &session);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif /* _ROM_H_ */
|
||||
|
@ -32,8 +32,8 @@
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/component.h>
|
||||
#include <util/touch.h>
|
||||
#include <base/sleep.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <util/misc_math.h>
|
||||
#include <rom_session/connection.h>
|
||||
@ -699,7 +699,7 @@ class Vcpu_dispatcher : public Vcpu_handler,
|
||||
|
||||
|
||||
Vcpu_dispatcher(Genode::Lock &vcpu_lock,
|
||||
Genode::Cap_connection &cap_connection,
|
||||
Genode::Env &env,
|
||||
VCpu *unsynchronized_vcpu,
|
||||
Guest_memory &guest_memory,
|
||||
Synced_motherboard &motherboard,
|
||||
@ -709,7 +709,7 @@ class Vcpu_dispatcher : public Vcpu_handler,
|
||||
Genode::Cpu_session *cpu_session,
|
||||
Genode::Affinity::Location &location)
|
||||
:
|
||||
Vcpu_handler(STACK_SIZE, cap_connection, cpu_session, location),
|
||||
Vcpu_handler(env, STACK_SIZE, cpu_session, location),
|
||||
_vcpu(vcpu_lock, unsynchronized_vcpu),
|
||||
_vcpu_thread(vcpu_thread),
|
||||
_guest_memory(guest_memory),
|
||||
@ -849,9 +849,9 @@ class Machine : public StaticReceiver<Machine>
|
||||
{
|
||||
private:
|
||||
|
||||
Genode::Env &_env;;
|
||||
Genode::Rom_connection _hip_rom;
|
||||
Hip * const _hip;
|
||||
Genode::Cap_connection _cap;
|
||||
Clock _clock;
|
||||
Genode::Lock _motherboard_lock;
|
||||
Motherboard _unsynchronized_motherboard;
|
||||
@ -955,7 +955,7 @@ class Machine : public StaticReceiver<Machine>
|
||||
|
||||
Vcpu_dispatcher *vcpu_dispatcher =
|
||||
new Vcpu_dispatcher(_motherboard_lock,
|
||||
_cap,
|
||||
_env,
|
||||
msg.vcpu,
|
||||
_guest_memory,
|
||||
_motherboard,
|
||||
@ -1246,10 +1246,11 @@ class Machine : public StaticReceiver<Machine>
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Machine(Boot_module_provider &boot_modules, Guest_memory &guest_memory,
|
||||
bool colocate)
|
||||
Machine(Genode::Env &env, Boot_module_provider &boot_modules,
|
||||
Guest_memory &guest_memory, bool colocate)
|
||||
:
|
||||
_hip_rom("hypervisor_info_page"),
|
||||
_env(env),
|
||||
_hip_rom(_env, "hypervisor_info_page"),
|
||||
_hip(Genode::env()->rm_session()->attach(_hip_rom.dataspace())),
|
||||
_clock(_hip->tsc_freq*1000),
|
||||
_motherboard_lock(Genode::Lock::LOCKED),
|
||||
@ -1403,7 +1404,7 @@ extern unsigned long _prog_img_beg; /* begin of program image (link address) */
|
||||
extern unsigned long _prog_img_end; /* end of program image */
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
Genode::addr_t fb_size = 4*1024*1024;
|
||||
Genode::addr_t vm_size;
|
||||
@ -1434,7 +1435,7 @@ int main(int argc, char **argv)
|
||||
Genode::Xml_node node = Genode::config()->xml_node().sub_node("machine").sub_node("vga");
|
||||
Genode::Xml_node::Attribute arg = node.attribute("fb_size");
|
||||
|
||||
unsigned long val;
|
||||
unsigned long val = 0;
|
||||
arg.value(&val);
|
||||
fb_size = val*1024;
|
||||
} catch (...) { }
|
||||
@ -1484,7 +1485,8 @@ int main(int argc, char **argv)
|
||||
!guest_memory.backing_store_fb_local_base()) {
|
||||
PERR("Not enough space left for %s - exit",
|
||||
guest_memory.backing_store_local_base() ? "framebuffer" : "VMM");
|
||||
return 1;
|
||||
env.parent().exit(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
Genode::printf("\n--- Setup VM ---\n");
|
||||
@ -1493,17 +1495,17 @@ int main(int argc, char **argv)
|
||||
boot_modules(Genode::config()->xml_node().sub_node("multiboot"));
|
||||
|
||||
/* create the PC machine based on the configuration given */
|
||||
static Machine machine(boot_modules, guest_memory, colocate);
|
||||
static Machine machine(env, boot_modules, guest_memory, colocate);
|
||||
|
||||
/* create console thread */
|
||||
Vancouver_console vcon(machine.motherboard(), fb_size, guest_memory.fb_ds());
|
||||
static Vancouver_console vcon(machine.motherboard(), fb_size, guest_memory.fb_ds());
|
||||
|
||||
vcon.register_host_operations(machine.unsynchronized_motherboard());
|
||||
|
||||
/* create disk thread */
|
||||
Vancouver_disk vdisk(machine.motherboard(),
|
||||
guest_memory.backing_store_local_base(),
|
||||
guest_memory.backing_store_size());
|
||||
static Vancouver_disk vdisk(machine.motherboard(),
|
||||
guest_memory.backing_store_local_base(),
|
||||
guest_memory.backing_store_size());
|
||||
|
||||
vdisk.register_host_operations(machine.unsynchronized_motherboard());
|
||||
|
||||
@ -1512,7 +1514,4 @@ int main(int argc, char **argv)
|
||||
Genode::printf("\n--- Booting VM ---\n");
|
||||
|
||||
machine.boot();
|
||||
|
||||
Genode::sleep_forever();
|
||||
return 0;
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ Gdb_monitor::Cpu_session_component::_setup_native_cpu()
|
||||
void Gdb_monitor::Cpu_session_component::_cleanup_native_cpu()
|
||||
{
|
||||
Native_cpu_component *native_cpu_component = nullptr;
|
||||
_thread_ep->apply(_native_cpu_cap, [&] (Native_cpu_component *c) { native_cpu_component = c; });
|
||||
_ep.apply(_native_cpu_cap, [&] (Native_cpu_component *c) { native_cpu_component = c; });
|
||||
|
||||
if (!native_cpu_component) return;
|
||||
|
||||
|
@ -71,7 +71,7 @@ Gdb_monitor::Cpu_session_component::_setup_native_cpu()
|
||||
void Gdb_monitor::Cpu_session_component::_cleanup_native_cpu()
|
||||
{
|
||||
Native_cpu_component *native_cpu_component = nullptr;
|
||||
_thread_ep->apply(_native_cpu_cap, [&] (Native_cpu_component *c) { native_cpu_component = c; });
|
||||
_ep.apply(_native_cpu_cap, [&] (Native_cpu_component *c) { native_cpu_component = c; });
|
||||
|
||||
if (!native_cpu_component) return;
|
||||
|
||||
|
@ -16,8 +16,7 @@
|
||||
#include <util/misc_math.h>
|
||||
#include <util/arg_string.h>
|
||||
#include <base/log.h>
|
||||
#include <os/config.h>
|
||||
#include <rom_session/connection.h>
|
||||
#include <base/attached_rom_dataspace.h>
|
||||
#include <base/sleep.h>
|
||||
#include <dataspace/client.h>
|
||||
#include <region_map/client.h>
|
||||
@ -89,17 +88,11 @@ class Noux_connection
|
||||
private:
|
||||
|
||||
Noux::Connection _connection;
|
||||
Noux::Sysio *_sysio;
|
||||
|
||||
Noux::Sysio *_obtain_sysio()
|
||||
{
|
||||
return Genode::env()->rm_session()->attach(_connection.sysio_dataspace());
|
||||
}
|
||||
Genode::Attached_dataspace _sysio_ds { _connection.sysio_dataspace() };
|
||||
|
||||
public:
|
||||
|
||||
Noux_connection() : _sysio(_obtain_sysio()) { }
|
||||
|
||||
/**
|
||||
* Return the capability of the local stack-area region map
|
||||
*
|
||||
@ -111,7 +104,26 @@ class Noux_connection
|
||||
}
|
||||
|
||||
Noux::Session *session() { return &_connection; }
|
||||
Noux::Sysio *sysio() { return _sysio; }
|
||||
Noux::Sysio *sysio() { return _sysio_ds.local_addr<Noux::Sysio>(); }
|
||||
|
||||
void reconnect()
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
/*
|
||||
* Release Id_space<Parent::Client>::Element of the local ID space.
|
||||
*/
|
||||
_connection.discard_session_id();
|
||||
|
||||
/*
|
||||
* Obtain new noux connection. Note that we cannot reconstruct
|
||||
* the connection via a 'Volatile_object' because this would
|
||||
* result in an inconsistent referernce count when attempting
|
||||
* to destruct the session capability in the just-cleared
|
||||
* capability space.
|
||||
*/
|
||||
construct_at<Noux_connection>(this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -532,12 +544,8 @@ extern "C" void fork_trampoline()
|
||||
/* reinitialize standard-output connection */
|
||||
stdout_reconnect();
|
||||
|
||||
/* reinitialize config */
|
||||
Genode::Config *config = Genode::config();
|
||||
construct_at<Genode::Config>(config);
|
||||
|
||||
/* reinitialize noux connection */
|
||||
construct_at<Noux_connection>(noux_connection());
|
||||
noux_connection()->reconnect();
|
||||
|
||||
/* reinitialize main-thread object which implies reinit of stack area */
|
||||
auto stack_area_rm = noux_connection()->stack_area_region_map(in_stack_area);
|
||||
@ -2229,14 +2237,14 @@ void init_libc_noux(void)
|
||||
sigemptyset(&signal_mask);
|
||||
|
||||
/* copy command-line arguments from 'args' ROM dataspace */
|
||||
Genode::Rom_connection args_rom("args");
|
||||
char *args = (char *)Genode::env()->rm_session()->
|
||||
attach(args_rom.dataspace());
|
||||
|
||||
enum { MAX_ARGS = 256, ARG_BUF_SIZE = 4096 };
|
||||
enum { MAX_ARGS = 256, ARG_BUF_SIZE = 4096UL };
|
||||
static char *argv[MAX_ARGS];
|
||||
static char arg_buf[ARG_BUF_SIZE];
|
||||
Genode::memcpy(arg_buf, args, ARG_BUF_SIZE);
|
||||
{
|
||||
Genode::Attached_rom_dataspace ds("args");
|
||||
Genode::memcpy(arg_buf, ds.local_addr<char>(),
|
||||
Genode::min((size_t)ARG_BUF_SIZE, ds.size()));
|
||||
}
|
||||
|
||||
int argc = 0;
|
||||
for (unsigned i = 0; arg_buf[i] && (i < ARG_BUF_SIZE - 2); ) {
|
||||
@ -2252,7 +2260,7 @@ void init_libc_noux(void)
|
||||
}
|
||||
|
||||
argv[argc] = &arg_buf[i];
|
||||
i += Genode::strlen(&args[i]) + 1; /* skip null-termination */
|
||||
i += Genode::strlen(&arg_buf[i]) + 1; /* skip null-termination */
|
||||
argc++;
|
||||
}
|
||||
|
||||
@ -2264,12 +2272,15 @@ void init_libc_noux(void)
|
||||
* Make environment variables from 'env' ROM dataspace available to libc's
|
||||
* 'environ'.
|
||||
*/
|
||||
Genode::Rom_connection env_rom("env");
|
||||
Genode::Dataspace_capability env_ds = env_rom.dataspace();
|
||||
char *env_string = (char *)Genode::env()->rm_session()->attach(env_ds);
|
||||
|
||||
enum { ENV_MAX_ENTRIES = 128 };
|
||||
enum { ENV_MAX_ENTRIES = 128, ENV_BUF_SIZE = 8*1024 };
|
||||
static char *env_array[ENV_MAX_ENTRIES];
|
||||
static char env_buf[ENV_BUF_SIZE];
|
||||
{
|
||||
Genode::Attached_rom_dataspace ds("env");
|
||||
Genode::memcpy(env_buf, ds.local_addr<char>(),
|
||||
Genode::min((size_t)ENV_BUF_SIZE, ds.size()));
|
||||
}
|
||||
char *env_string = &env_buf[0];
|
||||
|
||||
unsigned num_entries = 0; /* index within 'env_array' */
|
||||
|
||||
|
@ -38,8 +38,6 @@
|
||||
#include <interrupt_handler.h>
|
||||
#include <kill_broadcaster.h>
|
||||
#include <parent_execve.h>
|
||||
#include <local_cpu_service.h>
|
||||
#include <local_pd_service.h>
|
||||
#include <local_rom_service.h>
|
||||
|
||||
namespace Noux {
|
||||
@ -87,11 +85,6 @@ namespace Noux {
|
||||
*/
|
||||
Io_receptor_registry *io_receptor_registry();
|
||||
|
||||
/**
|
||||
* Return ELF binary of dynamic linker
|
||||
*/
|
||||
Dataspace_capability ldso_ds_cap();
|
||||
|
||||
/*
|
||||
* Return lock for protecting the signal queue
|
||||
*/
|
||||
@ -135,67 +128,77 @@ namespace Noux {
|
||||
{
|
||||
private:
|
||||
|
||||
Child_policy::Name const _name;
|
||||
|
||||
Parent_exit *_parent_exit;
|
||||
Kill_broadcaster &_kill_broadcaster;
|
||||
Parent_execve &_parent_execve;
|
||||
|
||||
Signal_receiver *_sig_rec;
|
||||
Signal_receiver &_sig_rec;
|
||||
|
||||
Vfs::Dir_file_system &_root_dir;
|
||||
|
||||
Allocator *_alloc;
|
||||
Destruct_queue &_destruct_queue;
|
||||
Destruct_dispatcher _destruct_dispatcher;
|
||||
Signal_context_capability _destruct_context_cap;
|
||||
Destruct_dispatcher _destruct_dispatcher { _destruct_queue, this };
|
||||
Signal_context_capability _destruct_context_cap =
|
||||
_sig_rec.manage(&_destruct_dispatcher);
|
||||
|
||||
Cap_session * const _cap_session;
|
||||
Pd_session &_env_pd_session; /* used for creating 'Rpc_entrypoint' */
|
||||
|
||||
enum { STACK_SIZE = 5*1024*sizeof(long) };
|
||||
Rpc_entrypoint _entrypoint;
|
||||
/**
|
||||
* Entrypoint used to serve the RPC interfaces of the
|
||||
* locally-provided services
|
||||
*/
|
||||
enum { STACK_SIZE = 8*1024*sizeof(long) };
|
||||
Rpc_entrypoint _ep { &_env_pd_session, STACK_SIZE, "noux_process", false };
|
||||
|
||||
Ram_session &_ref_ram;
|
||||
Ram_session_capability const _ref_ram_cap;
|
||||
|
||||
/**
|
||||
* Registry of dataspaces owned by the Noux process
|
||||
*/
|
||||
Dataspace_registry _ds_registry;
|
||||
|
||||
Pd_session_component _pd;
|
||||
/**
|
||||
* Locally-provided PD service
|
||||
*/
|
||||
typedef Local_service<Pd_session_component> Pd_service;
|
||||
Pd_session_component _pd { _ep, _name, _ds_registry };
|
||||
Pd_service::Single_session_factory _pd_factory { _pd };
|
||||
Pd_service _pd_service { _pd_factory };
|
||||
|
||||
/**
|
||||
* Resources assigned to the child
|
||||
* Locally-provided RAM service
|
||||
*/
|
||||
struct Resources
|
||||
{
|
||||
/**
|
||||
* Entrypoint used to serve the RPC interfaces of the
|
||||
* locally-provided services
|
||||
*/
|
||||
Rpc_entrypoint &ep;
|
||||
typedef Local_service<Ram_session_component> Ram_service;
|
||||
Ram_session_component _ram { _ep, _ds_registry };
|
||||
Ram_service::Single_session_factory _ram_factory { _ram };
|
||||
Ram_service _ram_service { _ram_factory };
|
||||
|
||||
/**
|
||||
* Locally-provided services for accessing platform resources
|
||||
*/
|
||||
Ram_session_component ram;
|
||||
Cpu_session_component cpu;
|
||||
/**
|
||||
* Locally-provided CPU service
|
||||
*/
|
||||
typedef Local_service<Cpu_session_component> Cpu_service;
|
||||
Cpu_session_component _cpu { _ep, _name, false };
|
||||
Cpu_service::Single_session_factory _cpu_factory { _cpu };
|
||||
Cpu_service _cpu_service { _cpu_factory };
|
||||
|
||||
Resources(char const *label, Rpc_entrypoint &ep,
|
||||
Dataspace_registry &ds_registry,
|
||||
Pd_session_capability core_pd_cap, bool forked)
|
||||
:
|
||||
ep(ep), ram(ds_registry), cpu(label, core_pd_cap, forked)
|
||||
{
|
||||
ep.manage(&ram);
|
||||
ep.manage(&cpu);
|
||||
}
|
||||
/*
|
||||
* Locally-provided Noux service
|
||||
*/
|
||||
Session_capability const _noux_session_cap =
|
||||
Session_capability(_ep.manage(this));
|
||||
|
||||
~Resources()
|
||||
{
|
||||
ep.dissolve(&ram);
|
||||
ep.dissolve(&cpu);
|
||||
}
|
||||
typedef Local_service<Rpc_object<Session> > Noux_service;
|
||||
Noux_service::Single_session_factory _noux_factory { *this };
|
||||
Noux_service _noux_service { _noux_factory };
|
||||
|
||||
} _resources;
|
||||
|
||||
Genode::Child::Initial_thread _initial_thread;
|
||||
|
||||
Region_map_client _address_space { _pd.address_space() };
|
||||
/*
|
||||
* Locally-provided ROM service
|
||||
*/
|
||||
Local_rom_factory _rom_factory { _ep, _root_dir, _ds_registry };
|
||||
Local_rom_service _rom_service { _rom_factory };
|
||||
|
||||
/**
|
||||
* Command line arguments
|
||||
@ -210,61 +213,26 @@ namespace Noux {
|
||||
/*
|
||||
* Child configuration
|
||||
*/
|
||||
Child_config _config;
|
||||
|
||||
/**
|
||||
* ELF binary handling
|
||||
*/
|
||||
struct Elf
|
||||
{
|
||||
enum { NAME_MAX_LEN = 128 };
|
||||
char _name[NAME_MAX_LEN];
|
||||
|
||||
Vfs::Dir_file_system * const _root_dir;
|
||||
Dataspace_capability const _binary_ds;
|
||||
|
||||
Elf(char const * const binary_name, Vfs::Dir_file_system * root_dir,
|
||||
Dataspace_capability binary_ds)
|
||||
:
|
||||
_root_dir(root_dir), _binary_ds(binary_ds)
|
||||
{
|
||||
strncpy(_name, binary_name, sizeof(_name));
|
||||
_name[NAME_MAX_LEN - 1] = 0;
|
||||
}
|
||||
|
||||
~Elf() { _root_dir->release(_name, _binary_ds); }
|
||||
} _elf;
|
||||
Child_config _config { *env()->ram_session() };
|
||||
|
||||
enum { PAGE_SIZE = 4096, PAGE_MASK = ~(PAGE_SIZE - 1) };
|
||||
enum { SYSIO_DS_SIZE = PAGE_MASK & (sizeof(Sysio) + PAGE_SIZE - 1) };
|
||||
|
||||
Attached_ram_dataspace _sysio_ds;
|
||||
Sysio * const _sysio;
|
||||
Attached_ram_dataspace _sysio_ds { env()->ram_session(), SYSIO_DS_SIZE };
|
||||
Sysio &_sysio = *_sysio_ds.local_addr<Sysio>();
|
||||
|
||||
typedef Ring_buffer<enum Sysio::Signal, Sysio::SIGNAL_QUEUE_SIZE>
|
||||
Signal_queue;
|
||||
Signal_queue _pending_signals;
|
||||
|
||||
Session_capability const _noux_session_cap;
|
||||
Parent_services &_parent_services;
|
||||
|
||||
Local_noux_service _local_noux_service;
|
||||
Parent_service _parent_ram_service;
|
||||
Parent_service _parent_pd_service;
|
||||
Local_cpu_service _local_cpu_service;
|
||||
Local_pd_service _local_pd_service;
|
||||
Local_rom_service _local_rom_service;
|
||||
Service_registry &_parent_services;
|
||||
|
||||
Static_dataspace_info _binary_ds_info;
|
||||
Static_dataspace_info _sysio_ds_info;
|
||||
Static_dataspace_info _ldso_ds_info;
|
||||
Static_dataspace_info _args_ds_info;
|
||||
Static_dataspace_info _env_ds_info;
|
||||
Static_dataspace_info _config_ds_info;
|
||||
|
||||
Dataspace_capability _ldso_ds;
|
||||
|
||||
Child_policy _child_policy;
|
||||
Child_policy _child_policy;
|
||||
|
||||
Genode::Child _child;
|
||||
|
||||
@ -326,19 +294,16 @@ namespace Noux {
|
||||
io->unregister_wake_up_notifier(¬ifier);
|
||||
}
|
||||
|
||||
Vfs::Dir_file_system * const root_dir() { return _elf._root_dir; }
|
||||
|
||||
/**
|
||||
* Method for handling noux network related system calls
|
||||
*/
|
||||
|
||||
bool _syscall_net(Syscall sc);
|
||||
|
||||
void _destruct() {
|
||||
|
||||
_sig_rec->dissolve(&_destruct_dispatcher);
|
||||
_sig_rec.dissolve(&_destruct_dispatcher);
|
||||
|
||||
_entrypoint.dissolve(this);
|
||||
_ep.dissolve(this);
|
||||
|
||||
if (init_process(this))
|
||||
init_process_exited(_child_policy.exit_value());
|
||||
@ -364,82 +329,56 @@ namespace Noux {
|
||||
* \throw Insufficent_memory if the child could not be started by
|
||||
* the parent
|
||||
*/
|
||||
Child(char const *binary_name,
|
||||
Dataspace_capability ldso_ds,
|
||||
Parent_exit *parent_exit,
|
||||
Kill_broadcaster &kill_broadcaster,
|
||||
Parent_execve &parent_execve,
|
||||
int pid,
|
||||
Signal_receiver *sig_rec,
|
||||
Vfs::Dir_file_system *root_dir,
|
||||
Args const &args,
|
||||
Sysio::Env const &env,
|
||||
Cap_session *cap_session,
|
||||
Service_registry &parent_services,
|
||||
Rpc_entrypoint &resources_ep,
|
||||
bool forked,
|
||||
Allocator *destruct_alloc,
|
||||
Destruct_queue &destruct_queue,
|
||||
bool verbose)
|
||||
Child(Child_policy::Name const &name,
|
||||
Parent_exit *parent_exit,
|
||||
Kill_broadcaster &kill_broadcaster,
|
||||
Parent_execve &parent_execve,
|
||||
int pid,
|
||||
Signal_receiver &sig_rec,
|
||||
Vfs::Dir_file_system &root_dir,
|
||||
Args const &args,
|
||||
Sysio::Env const &env,
|
||||
Pd_session &env_pd_session,
|
||||
Ram_session &ref_ram,
|
||||
Ram_session_capability ref_ram_cap,
|
||||
Parent_services &parent_services,
|
||||
Rpc_entrypoint &resources_ep,
|
||||
bool forked,
|
||||
Allocator &destruct_alloc,
|
||||
Destruct_queue &destruct_queue,
|
||||
bool verbose)
|
||||
:
|
||||
Family_member(pid),
|
||||
Destruct_queue::Element<Child>(destruct_alloc),
|
||||
Destruct_queue::Element<Child>(&destruct_alloc),
|
||||
_name(name),
|
||||
_parent_exit(parent_exit),
|
||||
_kill_broadcaster(kill_broadcaster),
|
||||
_parent_execve(parent_execve),
|
||||
_sig_rec(sig_rec),
|
||||
_root_dir(root_dir),
|
||||
_destruct_queue(destruct_queue),
|
||||
_destruct_dispatcher(_destruct_queue, this),
|
||||
_destruct_context_cap(sig_rec->manage(&_destruct_dispatcher)),
|
||||
_cap_session(cap_session),
|
||||
_entrypoint(cap_session, STACK_SIZE, "noux_process", false),
|
||||
_pd(binary_name, resources_ep, _ds_registry),
|
||||
_resources(binary_name, resources_ep, _ds_registry, _pd.core_pd_cap(), false),
|
||||
_initial_thread(_resources.cpu, _pd.cap(), binary_name),
|
||||
_env_pd_session(env_pd_session),
|
||||
_ref_ram(ref_ram), _ref_ram_cap(ref_ram_cap),
|
||||
_args(ARGS_DS_SIZE, args),
|
||||
_env(env),
|
||||
_config(*Genode::env()->ram_session()),
|
||||
_elf(binary_name, root_dir, root_dir->dataspace(binary_name)),
|
||||
_sysio_ds(Genode::env()->ram_session(), SYSIO_DS_SIZE),
|
||||
_sysio(_sysio_ds.local_addr<Sysio>()),
|
||||
_noux_session_cap(Session_capability(_entrypoint.manage(this))),
|
||||
_local_noux_service(_noux_session_cap),
|
||||
_parent_ram_service(""),
|
||||
_parent_pd_service(""),
|
||||
_local_cpu_service(_entrypoint, _resources.cpu.cpu_cap()),
|
||||
_local_pd_service(_entrypoint, _pd.core_pd_cap()),
|
||||
_local_rom_service(_entrypoint, _ds_registry),
|
||||
_parent_services(parent_services),
|
||||
_binary_ds_info(_ds_registry, _elf._binary_ds),
|
||||
_sysio_ds_info(_ds_registry, _sysio_ds.cap()),
|
||||
_ldso_ds_info(_ds_registry, ldso_ds_cap()),
|
||||
_args_ds_info(_ds_registry, _args.cap()),
|
||||
_env_ds_info(_ds_registry, _env.cap()),
|
||||
_config_ds_info(_ds_registry, _config.cap()),
|
||||
_ldso_ds(ldso_ds),
|
||||
_child_policy(_elf._name, _elf._binary_ds, _args.cap(),
|
||||
_env.cap(), _config.cap(),
|
||||
_entrypoint, _local_noux_service,
|
||||
_local_rom_service, _parent_services,
|
||||
_child_policy(name,
|
||||
forked ? Rom_session_component::forked_magic_binary_name()
|
||||
: name,
|
||||
_args.cap(), _env.cap(), _config.cap(),
|
||||
_ep, _pd_service, _ram_service, _cpu_service,
|
||||
_noux_service, _rom_service, _parent_services,
|
||||
*this, parent_exit, *this, _destruct_context_cap,
|
||||
_resources.ram, verbose),
|
||||
_child(forked ? Dataspace_capability() : _elf._binary_ds,
|
||||
_ldso_ds, _pd.cap(), _pd,
|
||||
_resources.ram.cap(), _resources.ram,
|
||||
_resources.cpu.cap(), _initial_thread,
|
||||
*Genode::env()->rm_session(), _address_space,
|
||||
_entrypoint, _child_policy, _local_pd_service,
|
||||
_parent_ram_service, _local_cpu_service)
|
||||
ref_ram, ref_ram_cap, verbose),
|
||||
_child(*Genode::env()->rm_session(), _ep, _child_policy)
|
||||
{
|
||||
if (verbose)
|
||||
_args.dump();
|
||||
|
||||
if (!forked && !_elf._binary_ds.valid()) {
|
||||
error("lookup of executable \"", binary_name, "\" failed");
|
||||
|
||||
_destruct();
|
||||
throw Binary_does_not_exist();
|
||||
}
|
||||
if (!_child.main_thread_cap().valid()) {
|
||||
_destruct();
|
||||
throw Insufficient_memory();
|
||||
@ -448,7 +387,7 @@ namespace Noux {
|
||||
|
||||
~Child() { _destruct(); }
|
||||
|
||||
void start() { _entrypoint.activate(); }
|
||||
void start() { _ep.activate(); }
|
||||
|
||||
void start_forked_main_thread(addr_t ip, addr_t sp, addr_t parent_cap_addr)
|
||||
{
|
||||
@ -458,7 +397,7 @@ namespace Noux {
|
||||
_pd.poke(parent_cap_addr, &raw, sizeof(raw));
|
||||
|
||||
/* start execution of new main thread at supplied trampoline */
|
||||
_resources.cpu.start_main_thread(ip, sp);
|
||||
_cpu.start_main_thread(ip, sp);
|
||||
}
|
||||
|
||||
void submit_exit_signal()
|
||||
@ -473,8 +412,9 @@ namespace Noux {
|
||||
}
|
||||
}
|
||||
|
||||
Ram_session_capability ram() const { return _resources.ram.cap(); }
|
||||
Pd_session_capability pd() const { return _pd.cap(); }
|
||||
Ram_session_component &ram() { return _ram; }
|
||||
Pd_session_component &pd() { return _pd; }
|
||||
|
||||
Dataspace_registry &ds_registry() { return _ds_registry; }
|
||||
|
||||
|
||||
@ -587,22 +527,22 @@ namespace Noux {
|
||||
Lock::Guard signal_lock_guard(signal_lock());
|
||||
|
||||
Child *child = new Child(filename,
|
||||
_ldso_ds,
|
||||
_parent_exit,
|
||||
_kill_broadcaster,
|
||||
_parent_execve,
|
||||
pid(),
|
||||
_sig_rec,
|
||||
root_dir(),
|
||||
args,
|
||||
env,
|
||||
_cap_session,
|
||||
_parent_services,
|
||||
_resources.ep,
|
||||
false,
|
||||
Genode::env()->heap(),
|
||||
_destruct_queue,
|
||||
verbose);
|
||||
_parent_exit,
|
||||
_kill_broadcaster,
|
||||
_parent_execve,
|
||||
pid(),
|
||||
_sig_rec,
|
||||
_root_dir,
|
||||
args,
|
||||
env,
|
||||
_env_pd_session,
|
||||
_ref_ram, _ref_ram_cap,
|
||||
_parent_services,
|
||||
_ep,
|
||||
false,
|
||||
*Genode::env()->heap(),
|
||||
_destruct_queue,
|
||||
verbose);
|
||||
|
||||
_assign_io_channels_to(child);
|
||||
|
||||
|
@ -21,64 +21,90 @@
|
||||
#include <family_member.h>
|
||||
#include <parent_exit.h>
|
||||
#include <file_descriptor_registry.h>
|
||||
#include <local_noux_service.h>
|
||||
#include <local_rom_service.h>
|
||||
|
||||
namespace Noux {
|
||||
|
||||
typedef Registered<Genode::Parent_service> Parent_service;
|
||||
typedef Registry<Parent_service> Parent_services;
|
||||
|
||||
typedef Local_service<Pd_session_component> Pd_service;
|
||||
typedef Local_service<Ram_session_component> Ram_service;
|
||||
typedef Local_service<Cpu_session_component> Cpu_service;
|
||||
typedef Local_service<Rpc_object<Session> > Noux_service;
|
||||
|
||||
class Child_policy : public Genode::Child_policy
|
||||
{
|
||||
private:
|
||||
|
||||
char const *_name;
|
||||
Name const _name;
|
||||
Binary_name const _binary_name;
|
||||
Init::Child_policy_enforce_labeling _labeling_policy;
|
||||
Init::Child_policy_provide_rom_file _binary_policy;
|
||||
Init::Child_policy_provide_rom_file _args_policy;
|
||||
Init::Child_policy_provide_rom_file _env_policy;
|
||||
Init::Child_policy_provide_rom_file _config_policy;
|
||||
Local_noux_service &_local_noux_service;
|
||||
Local_rom_service &_local_rom_service;
|
||||
Service_registry &_parent_services;
|
||||
Pd_service &_pd_service;
|
||||
Ram_service &_ram_service;
|
||||
Cpu_service &_cpu_service;
|
||||
Noux_service &_noux_service;
|
||||
Local_rom_service &_rom_service;
|
||||
Parent_services &_parent_services;
|
||||
Family_member &_family_member;
|
||||
Parent_exit *_parent_exit;
|
||||
File_descriptor_registry &_file_descriptor_registry;
|
||||
Signal_context_capability _destruct_context_cap;
|
||||
Ram_session &_ref_ram_session;
|
||||
Ram_session &_ref_ram;
|
||||
Ram_session_capability _ref_ram_cap;
|
||||
int _exit_value;
|
||||
bool _verbose;
|
||||
|
||||
template <typename T>
|
||||
static Genode::Service *_find_service(Genode::Registry<T> &services,
|
||||
Genode::Service::Name const &name)
|
||||
{
|
||||
Genode::Service *service = nullptr;
|
||||
services.for_each([&] (T &s) {
|
||||
if (!service && (s.name() == name))
|
||||
service = &s; });
|
||||
return service;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Child_policy(char const *name,
|
||||
Dataspace_capability binary_ds,
|
||||
Child_policy(Name const &name,
|
||||
Binary_name const &binary_name,
|
||||
Dataspace_capability args_ds,
|
||||
Dataspace_capability env_ds,
|
||||
Dataspace_capability config_ds,
|
||||
Rpc_entrypoint &entrypoint,
|
||||
Local_noux_service &local_noux_service,
|
||||
Local_rom_service &local_rom_service,
|
||||
Service_registry &parent_services,
|
||||
Pd_service &pd_service,
|
||||
Ram_service &ram_service,
|
||||
Cpu_service &cpu_service,
|
||||
Noux_service &noux_service,
|
||||
Local_rom_service &rom_service,
|
||||
Parent_services &parent_services,
|
||||
Family_member &family_member,
|
||||
Parent_exit *parent_exit,
|
||||
File_descriptor_registry &file_descriptor_registry,
|
||||
Signal_context_capability destruct_context_cap,
|
||||
Ram_session &ref_ram_session,
|
||||
Ram_session &ref_ram,
|
||||
Ram_session_capability ref_ram_cap,
|
||||
bool verbose)
|
||||
:
|
||||
_name(name),
|
||||
_labeling_policy(_name),
|
||||
_binary_policy("binary", binary_ds, &entrypoint),
|
||||
_binary_name(binary_name),
|
||||
_labeling_policy(_name.string()),
|
||||
_args_policy( "args", args_ds, &entrypoint),
|
||||
_env_policy( "env", env_ds, &entrypoint),
|
||||
_config_policy("config", config_ds, &entrypoint),
|
||||
_local_noux_service(local_noux_service),
|
||||
_local_rom_service(local_rom_service),
|
||||
_parent_services(parent_services),
|
||||
_pd_service(pd_service), _ram_service(ram_service),
|
||||
_cpu_service(cpu_service), _noux_service(noux_service),
|
||||
_rom_service(rom_service), _parent_services(parent_services),
|
||||
_family_member(family_member),
|
||||
_parent_exit(parent_exit),
|
||||
_file_descriptor_registry(file_descriptor_registry),
|
||||
_destruct_context_cap(destruct_context_cap),
|
||||
_ref_ram_session(ref_ram_session),
|
||||
_ref_ram(ref_ram), _ref_ram_cap(ref_ram_cap),
|
||||
_exit_value(~0),
|
||||
_verbose(verbose)
|
||||
{ }
|
||||
@ -89,40 +115,58 @@ namespace Noux {
|
||||
** Child policy interface **
|
||||
****************************/
|
||||
|
||||
const char *name() const { return _name; }
|
||||
Name name() const override { return _name; }
|
||||
Binary_name binary_name() const override { return _binary_name; }
|
||||
|
||||
Service *resolve_session_request(const char *service_name,
|
||||
const char *args)
|
||||
Ram_session &ref_ram() override { return _ref_ram; }
|
||||
|
||||
Ram_session_capability ref_ram_cap() const override { return _ref_ram_cap; }
|
||||
|
||||
void init(Ram_session &session, Ram_session_capability cap) override
|
||||
{
|
||||
Service *service = 0;
|
||||
|
||||
/* check for local ROM file requests */
|
||||
if ((service = _args_policy.resolve_session_request(service_name, args))
|
||||
|| (service = _env_policy.resolve_session_request(service_name, args))
|
||||
|| (service = _config_policy.resolve_session_request(service_name, args))
|
||||
|| (service = _binary_policy.resolve_session_request(service_name, args)))
|
||||
return service;
|
||||
|
||||
/* check for locally implemented noux service */
|
||||
if (strcmp(service_name, Session::service_name()) == 0)
|
||||
return &_local_noux_service;
|
||||
|
||||
/*
|
||||
* Check for local ROM service
|
||||
*/
|
||||
if (strcmp(service_name, Rom_session::service_name()) == 0)
|
||||
return &_local_rom_service;
|
||||
|
||||
return _parent_services.find(service_name);
|
||||
session.ref_account(_ref_ram_cap);
|
||||
}
|
||||
|
||||
void filter_session_args(const char *service,
|
||||
char *args, size_t args_len)
|
||||
Service &resolve_session_request(Service::Name const &service_name,
|
||||
Session_state::Args const &args) override
|
||||
{
|
||||
_labeling_policy.filter_session_args(service, args, args_len);
|
||||
Session_label const label(Genode::label_from_args(args.string()));
|
||||
|
||||
/* route initial ROM requests (binary and linker) to the parent */
|
||||
if (service_name == Genode::Rom_session::service_name()) {
|
||||
if (label.last_element() == binary_name()) return _rom_service;
|
||||
if (label.last_element() == linker_name()) return _rom_service;
|
||||
}
|
||||
|
||||
Genode::Service *service = nullptr;
|
||||
|
||||
/* check for local ROM requests */
|
||||
if ((service = _args_policy .resolve_session_request(service_name.string(), args.string()))
|
||||
|| (service = _env_policy .resolve_session_request(service_name.string(), args.string()))
|
||||
|| (service = _config_policy.resolve_session_request(service_name.string(), args.string())))
|
||||
return *service;
|
||||
|
||||
/* check for local services */
|
||||
if (service_name == Genode::Ram_session::service_name()) return _ram_service;
|
||||
if (service_name == Genode::Cpu_session::service_name()) return _cpu_service;
|
||||
if (service_name == Genode::Rom_session::service_name()) return _rom_service;
|
||||
if (service_name == Genode::Pd_session::service_name()) return _pd_service;
|
||||
if (service_name == Noux::Session::service_name()) return _noux_service;
|
||||
|
||||
/* check for parent services */
|
||||
if ((service = _find_service(_parent_services, service_name)))
|
||||
return *service;
|
||||
|
||||
throw Parent::Service_denied();
|
||||
}
|
||||
|
||||
void exit(int exit_value)
|
||||
void filter_session_args(Genode::Service::Name const &service,
|
||||
char *args, Genode::size_t args_len) override
|
||||
{
|
||||
_labeling_policy.filter_session_args(service.string(), args, args_len);
|
||||
}
|
||||
|
||||
void exit(int exit_value) override
|
||||
{
|
||||
_exit_value = exit_value;
|
||||
|
||||
@ -147,12 +191,11 @@ namespace Noux {
|
||||
}
|
||||
}
|
||||
|
||||
Ram_session *ref_ram_session()
|
||||
Region_map *address_space(Pd_session &pd) override
|
||||
{
|
||||
return &_ref_ram_session;
|
||||
return &static_cast<Pd_session_component &>(pd).address_space_region_map();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _NOUX__CHILD_POLICY_H_ */
|
||||
|
||||
|
@ -25,10 +25,14 @@
|
||||
#define _NOUX__CPU_SESSION_COMPONENT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/child.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <cpu_session/connection.h>
|
||||
#include <cpu_thread/client.h>
|
||||
|
||||
/* Noux includes */
|
||||
#include <pd_session_component.h>
|
||||
|
||||
namespace Noux {
|
||||
|
||||
using namespace Genode;
|
||||
@ -37,9 +41,9 @@ namespace Noux {
|
||||
{
|
||||
private:
|
||||
|
||||
Pd_session_capability _core_pd;
|
||||
bool const _forked;
|
||||
Cpu_connection _cpu;
|
||||
Rpc_entrypoint &_ep;
|
||||
bool const _forked;
|
||||
Cpu_connection _cpu;
|
||||
|
||||
enum { MAX_THREADS = 8, MAIN_THREAD_IDX = 0 };
|
||||
|
||||
@ -50,8 +54,6 @@ namespace Noux {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param core_pd capability of PD session at core to be used
|
||||
* as argument of 'create_thread'
|
||||
* \param forked false if the CPU session belongs to a child
|
||||
* created via execve or to the init process, or
|
||||
* true if the CPU session belongs to a newly
|
||||
@ -60,9 +62,12 @@ namespace Noux {
|
||||
* The 'forked' parameter controls the policy applied to the
|
||||
* startup of the main thread.
|
||||
*/
|
||||
Cpu_session_component(char const *label,
|
||||
Pd_session_capability core_pd, bool forked)
|
||||
: _core_pd(core_pd), _forked(forked), _cpu(label) { }
|
||||
Cpu_session_component(Rpc_entrypoint &ep, Child_policy::Name const &label,
|
||||
bool forked)
|
||||
: _ep(ep), _forked(forked), _cpu(label.string())
|
||||
{ _ep.manage(this); }
|
||||
|
||||
~Cpu_session_component() { _ep.dissolve(this); }
|
||||
|
||||
/**
|
||||
* Explicitly start main thread, only meaningful when
|
||||
@ -81,7 +86,7 @@ namespace Noux {
|
||||
** Cpu_session interface **
|
||||
***************************/
|
||||
|
||||
Thread_capability create_thread(Capability<Pd_session>,
|
||||
Thread_capability create_thread(Capability<Pd_session> pd_cap,
|
||||
Name const &name,
|
||||
Affinity::Location affinity,
|
||||
Weight weight,
|
||||
@ -92,14 +97,16 @@ namespace Noux {
|
||||
if (_threads[i].valid())
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Note that we don't use the PD-capability argument (which
|
||||
* refers to our virtualized PD session) but the physical
|
||||
* core PD.
|
||||
*/
|
||||
Thread_capability cap =
|
||||
_cpu.create_thread(_core_pd, name, affinity, weight, utcb);
|
||||
auto lambda = [&] (Pd_session_component *pd)
|
||||
{
|
||||
if (!pd)
|
||||
throw Thread_creation_failed();
|
||||
|
||||
return _cpu.create_thread(pd->core_pd_cap(), name,
|
||||
affinity, weight, utcb);
|
||||
};
|
||||
|
||||
Thread_capability cap = _ep.apply(pd_cap, lambda);
|
||||
_threads[i] = cap;
|
||||
return cap;
|
||||
}
|
||||
|
@ -92,9 +92,9 @@ namespace Noux {
|
||||
* RM session)
|
||||
* \return capability for the new dataspace
|
||||
*/
|
||||
virtual Dataspace_capability fork(Ram_session_capability ram,
|
||||
Dataspace_registry &ds_registry,
|
||||
Rpc_entrypoint &ep) = 0;
|
||||
virtual Dataspace_capability fork(Ram_session &ram,
|
||||
Dataspace_registry &ds_registry,
|
||||
Rpc_entrypoint &ep) = 0;
|
||||
|
||||
/**
|
||||
* Write raw byte sequence into dataspace
|
||||
@ -164,9 +164,9 @@ namespace Noux {
|
||||
_ds_registry.apply(ds_cap(), lambda);
|
||||
}
|
||||
|
||||
Dataspace_capability fork(Ram_session_capability,
|
||||
Dataspace_capability fork(Ram_session &,
|
||||
Dataspace_registry &,
|
||||
Rpc_entrypoint &)
|
||||
Rpc_entrypoint &)
|
||||
{
|
||||
return ds_cap();
|
||||
}
|
||||
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* \brief CPU service provided to Noux processes
|
||||
* \author Josef Soentgen
|
||||
* \date 2013-04-16
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _NOUX__LOCAL_CPU_SERVICE_H_
|
||||
#define _NOUX__LOCAL_CPU_SERVICE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/service.h>
|
||||
|
||||
/* Noux includes */
|
||||
#include <cpu_session_component.h>
|
||||
|
||||
namespace Noux {
|
||||
|
||||
class Local_cpu_service : public Service
|
||||
{
|
||||
private:
|
||||
|
||||
Rpc_entrypoint &_ep;
|
||||
Cpu_session_capability _cap;
|
||||
|
||||
public:
|
||||
|
||||
Local_cpu_service(Rpc_entrypoint &ep, Cpu_session_capability cap)
|
||||
:
|
||||
Service(Cpu_session::service_name()), _ep(ep),
|
||||
_cap(cap)
|
||||
{ }
|
||||
|
||||
Genode::Session_capability session(const char *args, Affinity const &)
|
||||
{
|
||||
Genode::warning(__func__, ": implement me!");
|
||||
return Genode::Session_capability();
|
||||
}
|
||||
|
||||
void upgrade(Genode::Session_capability, const char *args)
|
||||
{
|
||||
env()->parent()->upgrade(_cap, args);
|
||||
}
|
||||
|
||||
void close(Genode::Session_capability session)
|
||||
{
|
||||
Genode::warning(__func__, ": implement me!");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _NOUX__LOCAL_CPU_SERVICE_H_ */
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* \brief Locally-provided Noux service
|
||||
* \author Norman Feske
|
||||
* \date 2011-02-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-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.
|
||||
*/
|
||||
|
||||
#ifndef _NOUX__LOCAL_NOUX_SERVICE_H_
|
||||
#define _NOUX__LOCAL_NOUX_SERVICE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/service.h>
|
||||
|
||||
namespace Noux {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
struct Local_noux_service : public Service
|
||||
{
|
||||
Genode::Session_capability _cap;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param cap capability to return on session requests
|
||||
*/
|
||||
Local_noux_service(Genode::Session_capability cap)
|
||||
: Service(Session::service_name()), _cap(cap) { }
|
||||
|
||||
Genode::Session_capability session(const char *args, Affinity const &)
|
||||
{
|
||||
return _cap;
|
||||
}
|
||||
|
||||
void upgrade(Genode::Session_capability, const char *args) { }
|
||||
void close(Genode::Session_capability) { }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _NOUX__LOCAL_NOUX_SERVICE_H_ */
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* \brief PD service provided to Noux processes
|
||||
* \author Christian Prochaska
|
||||
* \date 2016-05-23
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _NOUX__LOCAL_PD_SERVICE_H_
|
||||
#define _NOUX__LOCAL_PD_SERVICE_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/service.h>
|
||||
|
||||
/* Noux includes */
|
||||
#include <pd_session_component.h>
|
||||
|
||||
namespace Noux {
|
||||
|
||||
class Local_pd_service : public Service
|
||||
{
|
||||
private:
|
||||
|
||||
Rpc_entrypoint &_ep;
|
||||
Pd_session_capability _cap;
|
||||
|
||||
public:
|
||||
|
||||
Local_pd_service(Rpc_entrypoint &ep, Pd_session_capability cap)
|
||||
:
|
||||
Service(Pd_session::service_name()), _ep(ep),
|
||||
_cap(cap)
|
||||
{ }
|
||||
|
||||
Genode::Session_capability session(const char *args, Affinity const &) override
|
||||
{
|
||||
warning(__func__, " not implemented");
|
||||
return Genode::Session_capability();
|
||||
}
|
||||
|
||||
void upgrade(Genode::Session_capability, const char *args) override
|
||||
{
|
||||
env()->parent()->upgrade(_cap, args);
|
||||
}
|
||||
|
||||
void close(Genode::Session_capability session) override
|
||||
{
|
||||
warning(__func__, " not implemented");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _NOUX__LOCAL_PD_SERVICE_H_ */
|
@ -27,57 +27,45 @@
|
||||
|
||||
namespace Noux {
|
||||
|
||||
class Local_rom_service : public Service
|
||||
{
|
||||
private:
|
||||
|
||||
Rpc_entrypoint &_ep;
|
||||
Dataspace_registry &_ds_registry;
|
||||
|
||||
public:
|
||||
|
||||
Local_rom_service(Rpc_entrypoint &ep, Dataspace_registry &ds_registry)
|
||||
:
|
||||
Service(Rom_session::service_name()), _ep(ep),
|
||||
_ds_registry(ds_registry)
|
||||
{ }
|
||||
|
||||
Genode::Session_capability session(const char *args, Affinity const &)
|
||||
{
|
||||
Session_label const label = label_from_args(args);
|
||||
|
||||
try {
|
||||
Genode::Session_label const module_name = label.last_element();
|
||||
Rom_session_component *rom = new (env()->heap())
|
||||
Rom_session_component(_ds_registry, module_name.string());
|
||||
|
||||
return _ep.manage(rom);
|
||||
} catch (Rom_connection::Rom_connection_failed) {
|
||||
throw Service::Unavailable();
|
||||
}
|
||||
}
|
||||
|
||||
void upgrade(Genode::Session_capability, const char *args) { }
|
||||
|
||||
void close(Genode::Session_capability session)
|
||||
{
|
||||
/* acquire locked session object */
|
||||
Rom_session_component *rom_session;
|
||||
|
||||
_ep.apply(session, [&] (Rom_session_component *rsc) {
|
||||
rom_session = rsc;
|
||||
|
||||
if (!rom_session) {
|
||||
PWRN("Unexpected call of close with non-ROM-session argument");
|
||||
return;
|
||||
}
|
||||
|
||||
_ep.dissolve(rom_session);
|
||||
});
|
||||
|
||||
destroy(env()->heap(), rom_session);
|
||||
}
|
||||
};
|
||||
typedef Local_service<Rom_session_component> Local_rom_service;
|
||||
class Local_rom_factory;
|
||||
}
|
||||
|
||||
|
||||
class Noux::Local_rom_factory : public Local_rom_service::Factory
|
||||
{
|
||||
private:
|
||||
|
||||
Rpc_entrypoint &_ep;
|
||||
Vfs::Dir_file_system &_root_dir;
|
||||
Dataspace_registry &_registry;
|
||||
|
||||
public:
|
||||
|
||||
Local_rom_factory(Rpc_entrypoint &ep, Vfs::Dir_file_system &root_dir,
|
||||
Dataspace_registry ®istry)
|
||||
:
|
||||
_ep(ep), _root_dir(root_dir), _registry(registry)
|
||||
{ }
|
||||
|
||||
Rom_session_component &create(Args const &args, Affinity) override
|
||||
{
|
||||
try {
|
||||
Rom_session_component::Name const rom_name =
|
||||
label_from_args(args.string()).last_element();
|
||||
|
||||
return *new (env()->heap())
|
||||
Rom_session_component(_ep, _root_dir, _registry, rom_name);
|
||||
}
|
||||
catch (Rom_connection::Rom_connection_failed) { throw Denied(); }
|
||||
}
|
||||
|
||||
void upgrade(Rom_session_component &, Args const &) override { }
|
||||
|
||||
void destroy(Rom_session_component &session) override
|
||||
{
|
||||
Genode::destroy(env()->heap(), &session);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _NOUX__LOCAL_ROM_SERVICE_H_ */
|
||||
|
@ -158,11 +158,11 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
|
||||
case SYSCALL_WRITE:
|
||||
{
|
||||
size_t const count_in = _sysio->write_in.count;
|
||||
size_t const count_in = _sysio.write_in.count;
|
||||
|
||||
for (size_t offset = 0; offset != count_in; ) {
|
||||
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio->write_in.fd);
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio.write_in.fd);
|
||||
|
||||
if (!io->nonblocking())
|
||||
_block_for_io_channel(io, false, true, false);
|
||||
@ -170,15 +170,15 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
if (io->check_unblock(false, true, false)) {
|
||||
/*
|
||||
* 'io->write' is expected to update
|
||||
* '_sysio->write_out.count' and 'offset'
|
||||
* '_sysio.write_out.count' and 'offset'
|
||||
*/
|
||||
result = io->write(_sysio, offset);
|
||||
result = io->write(&_sysio, offset);
|
||||
if (result == false)
|
||||
break;
|
||||
} else {
|
||||
if (result == false) {
|
||||
/* nothing was written yet */
|
||||
_sysio->error.write = Vfs::File_io_service::WRITE_ERR_INTERRUPT;
|
||||
_sysio.error.write = Vfs::File_io_service::WRITE_ERR_INTERRUPT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -188,29 +188,29 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
|
||||
case SYSCALL_READ:
|
||||
{
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio->read_in.fd);
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio.read_in.fd);
|
||||
|
||||
if (!io->nonblocking())
|
||||
_block_for_io_channel(io, true, false, false);
|
||||
|
||||
if (io->check_unblock(true, false, false))
|
||||
result = io->read(_sysio);
|
||||
result = io->read(&_sysio);
|
||||
else
|
||||
_sysio->error.read = Vfs::File_io_service::READ_ERR_INTERRUPT;
|
||||
_sysio.error.read = Vfs::File_io_service::READ_ERR_INTERRUPT;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSCALL_FTRUNCATE:
|
||||
{
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio->ftruncate_in.fd);
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio.ftruncate_in.fd);
|
||||
|
||||
_block_for_io_channel(io, false, true, false);
|
||||
|
||||
if (io->check_unblock(false, true, false))
|
||||
result = io->ftruncate(_sysio);
|
||||
result = io->ftruncate(&_sysio);
|
||||
else
|
||||
_sysio->error.ftruncate = Vfs::File_io_service::FTRUNCATE_ERR_INTERRUPT;
|
||||
_sysio.error.ftruncate = Vfs::File_io_service::FTRUNCATE_ERR_INTERRUPT;
|
||||
|
||||
break;
|
||||
}
|
||||
@ -222,13 +222,13 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
* We calculate the inode by hashing the path because there is
|
||||
* no inode registry in noux.
|
||||
*/
|
||||
size_t path_len = strlen(_sysio->stat_in.path);
|
||||
uint32_t path_hash = hash_path(_sysio->stat_in.path, path_len);
|
||||
size_t path_len = strlen(_sysio.stat_in.path);
|
||||
uint32_t path_hash = hash_path(_sysio.stat_in.path, path_len);
|
||||
|
||||
Vfs::Directory_service::Stat stat_out;
|
||||
_sysio->error.stat = root_dir()->stat(_sysio->stat_in.path, stat_out);
|
||||
_sysio.error.stat = _root_dir.stat(_sysio.stat_in.path, stat_out);
|
||||
|
||||
result = (_sysio->error.stat == Vfs::Directory_service::STAT_OK);
|
||||
result = (_sysio.error.stat == Vfs::Directory_service::STAT_OK);
|
||||
|
||||
/*
|
||||
* Instead of using the uid/gid given by the actual file system
|
||||
@ -241,16 +241,16 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
stat_out.inode = path_hash;
|
||||
}
|
||||
|
||||
_sysio->stat_out.st = stat_out;
|
||||
_sysio.stat_out.st = stat_out;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSCALL_FSTAT:
|
||||
{
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio->fstat_in.fd);
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio.fstat_in.fd);
|
||||
|
||||
result = io->fstat(_sysio);
|
||||
result = io->fstat(&_sysio);
|
||||
|
||||
if (result) {
|
||||
Sysio::Path path;
|
||||
@ -262,7 +262,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
size_t path_len = strlen(path);
|
||||
uint32_t path_hash = hash_path(path, path_len);
|
||||
|
||||
_sysio->stat_out.st.inode = path_hash;
|
||||
_sysio.stat_out.st.inode = path_hash;
|
||||
}
|
||||
}
|
||||
|
||||
@ -271,29 +271,29 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
|
||||
case SYSCALL_FCNTL:
|
||||
|
||||
if (_sysio->fcntl_in.cmd == Sysio::FCNTL_CMD_SET_FD_FLAGS) {
|
||||
if (_sysio.fcntl_in.cmd == Sysio::FCNTL_CMD_SET_FD_FLAGS) {
|
||||
|
||||
/* we assume that there is only the close-on-execve flag */
|
||||
_lookup_channel(_sysio->fcntl_in.fd)->close_on_execve =
|
||||
!!_sysio->fcntl_in.long_arg;
|
||||
_lookup_channel(_sysio.fcntl_in.fd)->close_on_execve =
|
||||
!!_sysio.fcntl_in.long_arg;
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
|
||||
result = _lookup_channel(_sysio->fcntl_in.fd)->fcntl(_sysio);
|
||||
result = _lookup_channel(_sysio.fcntl_in.fd)->fcntl(&_sysio);
|
||||
break;
|
||||
|
||||
case SYSCALL_OPEN:
|
||||
{
|
||||
Vfs::Vfs_handle *vfs_handle = 0;
|
||||
_sysio->error.open = root_dir()->open(_sysio->open_in.path,
|
||||
_sysio->open_in.mode,
|
||||
&vfs_handle,
|
||||
*Genode::env()->heap());
|
||||
_sysio.error.open = _root_dir.open(_sysio.open_in.path,
|
||||
_sysio.open_in.mode,
|
||||
&vfs_handle,
|
||||
*Genode::env()->heap());
|
||||
if (!vfs_handle)
|
||||
break;
|
||||
|
||||
char const *leaf_path = root_dir()->leaf_path(_sysio->open_in.path);
|
||||
char const *leaf_path = _root_dir.leaf_path(_sysio.open_in.path);
|
||||
|
||||
/*
|
||||
* File descriptors of opened directories are handled by
|
||||
@ -301,40 +301,40 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
* path because path operations always refer to the global
|
||||
* root.
|
||||
*/
|
||||
if (&vfs_handle->ds() == root_dir())
|
||||
leaf_path = _sysio->open_in.path;
|
||||
if (&vfs_handle->ds() == &_root_dir)
|
||||
leaf_path = _sysio.open_in.path;
|
||||
|
||||
Shared_pointer<Io_channel>
|
||||
channel(new Vfs_io_channel(_sysio->open_in.path,
|
||||
leaf_path, root_dir(),
|
||||
vfs_handle, *_sig_rec),
|
||||
channel(new Vfs_io_channel(_sysio.open_in.path,
|
||||
leaf_path, &_root_dir,
|
||||
vfs_handle, _sig_rec),
|
||||
Genode::env()->heap());
|
||||
|
||||
_sysio->open_out.fd = add_io_channel(channel);
|
||||
_sysio.open_out.fd = add_io_channel(channel);
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSCALL_CLOSE:
|
||||
{
|
||||
remove_io_channel(_sysio->close_in.fd);
|
||||
remove_io_channel(_sysio.close_in.fd);
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSCALL_IOCTL:
|
||||
|
||||
result = _lookup_channel(_sysio->ioctl_in.fd)->ioctl(_sysio);
|
||||
result = _lookup_channel(_sysio.ioctl_in.fd)->ioctl(&_sysio);
|
||||
break;
|
||||
|
||||
case SYSCALL_LSEEK:
|
||||
|
||||
result = _lookup_channel(_sysio->lseek_in.fd)->lseek(_sysio);
|
||||
result = _lookup_channel(_sysio.lseek_in.fd)->lseek(&_sysio);
|
||||
break;
|
||||
|
||||
case SYSCALL_DIRENT:
|
||||
|
||||
result = _lookup_channel(_sysio->dirent_in.fd)->dirent(_sysio);
|
||||
result = _lookup_channel(_sysio.dirent_in.fd)->dirent(&_sysio);
|
||||
break;
|
||||
|
||||
case SYSCALL_EXECVE:
|
||||
@ -345,27 +345,27 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
* does not exist.
|
||||
*/
|
||||
Dataspace_capability binary_ds =
|
||||
root_dir()->dataspace(_sysio->execve_in.filename);
|
||||
_root_dir.dataspace(_sysio.execve_in.filename);
|
||||
|
||||
if (!binary_ds.valid()) {
|
||||
_sysio->error.execve = Sysio::EXECVE_NONEXISTENT;
|
||||
_sysio.error.execve = Sysio::EXECVE_NONEXISTENT;
|
||||
break;
|
||||
}
|
||||
|
||||
Child_env<sizeof(_sysio->execve_in.args)>
|
||||
child_env(_sysio->execve_in.filename, binary_ds,
|
||||
_sysio->execve_in.args, _sysio->execve_in.env);
|
||||
Child_env<sizeof(_sysio.execve_in.args)>
|
||||
child_env(_sysio.execve_in.filename, binary_ds,
|
||||
_sysio.execve_in.args, _sysio.execve_in.env);
|
||||
|
||||
root_dir()->release(_sysio->execve_in.filename, binary_ds);
|
||||
_root_dir.release(_sysio.execve_in.filename, binary_ds);
|
||||
|
||||
binary_ds = root_dir()->dataspace(child_env.binary_name());
|
||||
binary_ds = _root_dir.dataspace(child_env.binary_name());
|
||||
|
||||
if (!binary_ds.valid()) {
|
||||
_sysio->error.execve = Sysio::EXECVE_NONEXISTENT;
|
||||
_sysio.error.execve = Sysio::EXECVE_NONEXISTENT;
|
||||
break;
|
||||
}
|
||||
|
||||
root_dir()->release(child_env.binary_name(), binary_ds);
|
||||
_root_dir.release(child_env.binary_name(), binary_ds);
|
||||
|
||||
try {
|
||||
_parent_execve.execve_child(*this,
|
||||
@ -381,28 +381,28 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
return true;
|
||||
}
|
||||
catch (Child::Binary_does_not_exist) {
|
||||
_sysio->error.execve = Sysio::EXECVE_NONEXISTENT; }
|
||||
_sysio.error.execve = Sysio::EXECVE_NONEXISTENT; }
|
||||
catch (Child::Insufficient_memory) {
|
||||
_sysio->error.execve = Sysio::EXECVE_NOMEM; }
|
||||
_sysio.error.execve = Sysio::EXECVE_NOMEM; }
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSCALL_SELECT:
|
||||
{
|
||||
size_t in_fds_total = _sysio->select_in.fds.total_fds();
|
||||
size_t in_fds_total = _sysio.select_in.fds.total_fds();
|
||||
Sysio::Select_fds in_fds;
|
||||
for (Genode::size_t i = 0; i < in_fds_total; i++)
|
||||
in_fds.array[i] = _sysio->select_in.fds.array[i];
|
||||
in_fds.num_rd = _sysio->select_in.fds.num_rd;
|
||||
in_fds.num_wr = _sysio->select_in.fds.num_wr;
|
||||
in_fds.num_ex = _sysio->select_in.fds.num_ex;
|
||||
in_fds.array[i] = _sysio.select_in.fds.array[i];
|
||||
in_fds.num_rd = _sysio.select_in.fds.num_rd;
|
||||
in_fds.num_wr = _sysio.select_in.fds.num_wr;
|
||||
in_fds.num_ex = _sysio.select_in.fds.num_ex;
|
||||
|
||||
int _rd_array[in_fds_total];
|
||||
int _wr_array[in_fds_total];
|
||||
|
||||
long timeout_sec = _sysio->select_in.timeout.sec;
|
||||
long timeout_usec = _sysio->select_in.timeout.usec;
|
||||
long timeout_sec = _sysio.select_in.timeout.sec;
|
||||
long timeout_usec = _sysio.select_in.timeout.usec;
|
||||
bool timeout_reached = false;
|
||||
|
||||
/* reset the blocker lock to the 'locked' state */
|
||||
@ -486,18 +486,18 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
* Merge the fd arrays in one output array
|
||||
*/
|
||||
for (size_t i = 0; i < unblock_rd; i++) {
|
||||
_sysio->select_out.fds.array[i] = _rd_array[i];
|
||||
_sysio.select_out.fds.array[i] = _rd_array[i];
|
||||
}
|
||||
_sysio->select_out.fds.num_rd = unblock_rd;
|
||||
_sysio.select_out.fds.num_rd = unblock_rd;
|
||||
|
||||
/* XXX could use a pointer to select_out.fds.array instead */
|
||||
for (size_t j = unblock_rd, i = 0; i < unblock_wr; i++, j++) {
|
||||
_sysio->select_out.fds.array[j] = _wr_array[i];
|
||||
_sysio.select_out.fds.array[j] = _wr_array[i];
|
||||
}
|
||||
_sysio->select_out.fds.num_wr = unblock_wr;
|
||||
_sysio.select_out.fds.num_wr = unblock_wr;
|
||||
|
||||
/* exception fds are currently not considered */
|
||||
_sysio->select_out.fds.num_ex = unblock_ex;
|
||||
_sysio.select_out.fds.num_ex = unblock_ex;
|
||||
|
||||
result = true;
|
||||
break;
|
||||
@ -507,14 +507,14 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
* Return if timeout is zero or timeout exceeded
|
||||
*/
|
||||
|
||||
if (_sysio->select_in.timeout.zero() || timeout_reached) {
|
||||
if (_sysio.select_in.timeout.zero() || timeout_reached) {
|
||||
/*
|
||||
if (timeout_reached) log("timeout_reached");
|
||||
else log("timeout.zero()");
|
||||
*/
|
||||
_sysio->select_out.fds.num_rd = 0;
|
||||
_sysio->select_out.fds.num_wr = 0;
|
||||
_sysio->select_out.fds.num_ex = 0;
|
||||
_sysio.select_out.fds.num_rd = 0;
|
||||
_sysio.select_out.fds.num_wr = 0;
|
||||
_sysio.select_out.fds.num_ex = 0;
|
||||
|
||||
result = true;
|
||||
break;
|
||||
@ -525,7 +525,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
*/
|
||||
|
||||
if (!_pending_signals.empty()) {
|
||||
_sysio->error.select = Sysio::SELECT_ERR_INTERRUPT;
|
||||
_sysio.error.select = Sysio::SELECT_ERR_INTERRUPT;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -533,7 +533,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
* Block at barrier except when reaching the timeout
|
||||
*/
|
||||
|
||||
if (!_sysio->select_in.timeout.infinite()) {
|
||||
if (!_sysio.select_in.timeout.infinite()) {
|
||||
unsigned long to_msec = (timeout_sec * 1000) + (timeout_usec / 1000);
|
||||
Timeout_state ts;
|
||||
Timeout_alarm ta(&ts, &_blocker, Noux::timeout_scheduler(), to_msec);
|
||||
@ -580,9 +580,9 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
|
||||
case SYSCALL_FORK:
|
||||
{
|
||||
Genode::addr_t ip = _sysio->fork_in.ip;
|
||||
Genode::addr_t sp = _sysio->fork_in.sp;
|
||||
Genode::addr_t parent_cap_addr = _sysio->fork_in.parent_cap_addr;
|
||||
Genode::addr_t ip = _sysio.fork_in.ip;
|
||||
Genode::addr_t sp = _sysio.fork_in.sp;
|
||||
Genode::addr_t parent_cap_addr = _sysio.fork_in.parent_cap_addr;
|
||||
|
||||
int const new_pid = pid_allocator()->alloc();
|
||||
Child * child = nullptr;
|
||||
@ -594,24 +594,24 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
* reusing the name of the parent.
|
||||
*/
|
||||
child = new Child(_child_policy.name(),
|
||||
_ldso_ds,
|
||||
this,
|
||||
_kill_broadcaster,
|
||||
*this,
|
||||
new_pid,
|
||||
_sig_rec,
|
||||
root_dir(),
|
||||
_root_dir,
|
||||
_args,
|
||||
_env.env(),
|
||||
_cap_session,
|
||||
_env_pd_session,
|
||||
_ref_ram, _ref_ram_cap,
|
||||
_parent_services,
|
||||
_resources.ep,
|
||||
_ep,
|
||||
true,
|
||||
env()->heap(),
|
||||
*env()->heap(),
|
||||
_destruct_queue,
|
||||
verbose);
|
||||
} catch (Child::Insufficient_memory) {
|
||||
_sysio->error.fork = Sysio::FORK_NOMEM;
|
||||
_sysio.error.fork = Sysio::FORK_NOMEM;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -620,34 +620,39 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
_assign_io_channels_to(child);
|
||||
|
||||
/* copy our address space into the new child */
|
||||
_pd.replay(child->ram(), child->pd(),
|
||||
child->ds_registry(), _resources.ep);
|
||||
try {
|
||||
_pd.replay(child->ram(), child->pd(),
|
||||
child->ds_registry(), _ep);
|
||||
|
||||
/* start executing the main thread of the new process */
|
||||
child->start_forked_main_thread(ip, sp, parent_cap_addr);
|
||||
/* start executing the main thread of the new process */
|
||||
child->start_forked_main_thread(ip, sp, parent_cap_addr);
|
||||
|
||||
/* activate child entrypoint, thereby starting the new process */
|
||||
child->start();
|
||||
/* activate child entrypoint, thereby starting the new process */
|
||||
child->start();
|
||||
|
||||
_sysio->fork_out.pid = new_pid;
|
||||
_sysio.fork_out.pid = new_pid;
|
||||
|
||||
result = true;
|
||||
}
|
||||
catch (Region_map::Region_conflict) {
|
||||
error("region conflict while replaying the address space"); }
|
||||
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSCALL_GETPID:
|
||||
{
|
||||
_sysio->getpid_out.pid = pid();
|
||||
_sysio.getpid_out.pid = pid();
|
||||
return true;
|
||||
}
|
||||
|
||||
case SYSCALL_WAIT4:
|
||||
{
|
||||
Family_member *exited = _sysio->wait4_in.nohang ? poll4() : wait4();
|
||||
Family_member *exited = _sysio.wait4_in.nohang ? poll4() : wait4();
|
||||
|
||||
if (exited) {
|
||||
_sysio->wait4_out.pid = exited->pid();
|
||||
_sysio->wait4_out.status = exited->exit_status();
|
||||
_sysio.wait4_out.pid = exited->pid();
|
||||
_sysio.wait4_out.status = exited->exit_status();
|
||||
Family_member::remove(exited);
|
||||
|
||||
if (verbose)
|
||||
@ -655,11 +660,11 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
static_cast<Child *>(exited)->submit_exit_signal();
|
||||
|
||||
} else {
|
||||
if (_sysio->wait4_in.nohang) {
|
||||
_sysio->wait4_out.pid = 0;
|
||||
_sysio->wait4_out.status = 0;
|
||||
if (_sysio.wait4_in.nohang) {
|
||||
_sysio.wait4_out.pid = 0;
|
||||
_sysio.wait4_out.status = 0;
|
||||
} else {
|
||||
_sysio->error.wait4 = Sysio::WAIT4_ERR_INTERRUPT;
|
||||
_sysio.error.wait4 = Sysio::WAIT4_ERR_INTERRUPT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -671,13 +676,13 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
{
|
||||
Shared_pointer<Pipe> pipe(new Pipe, Genode::env()->heap());
|
||||
|
||||
Shared_pointer<Io_channel> pipe_sink(new Pipe_sink_io_channel(pipe, *_sig_rec),
|
||||
Shared_pointer<Io_channel> pipe_sink(new Pipe_sink_io_channel(pipe, _sig_rec),
|
||||
Genode::env()->heap());
|
||||
Shared_pointer<Io_channel> pipe_source(new Pipe_source_io_channel(pipe, *_sig_rec),
|
||||
Shared_pointer<Io_channel> pipe_source(new Pipe_source_io_channel(pipe, _sig_rec),
|
||||
Genode::env()->heap());
|
||||
|
||||
_sysio->pipe_out.fd[0] = add_io_channel(pipe_source);
|
||||
_sysio->pipe_out.fd[1] = add_io_channel(pipe_sink);
|
||||
_sysio.pipe_out.fd[0] = add_io_channel(pipe_source);
|
||||
_sysio.pipe_out.fd[1] = add_io_channel(pipe_sink);
|
||||
|
||||
result = true;
|
||||
break;
|
||||
@ -685,10 +690,10 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
|
||||
case SYSCALL_DUP2:
|
||||
{
|
||||
int fd = add_io_channel(io_channel_by_fd(_sysio->dup2_in.fd),
|
||||
_sysio->dup2_in.to_fd);
|
||||
int fd = add_io_channel(io_channel_by_fd(_sysio.dup2_in.fd),
|
||||
_sysio.dup2_in.to_fd);
|
||||
|
||||
_sysio->dup2_out.fd = fd;
|
||||
_sysio.dup2_out.fd = fd;
|
||||
|
||||
result = true;
|
||||
break;
|
||||
@ -696,56 +701,57 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
|
||||
case SYSCALL_UNLINK:
|
||||
|
||||
_sysio->error.unlink = root_dir()->unlink(_sysio->unlink_in.path);
|
||||
_sysio.error.unlink = _root_dir.unlink(_sysio.unlink_in.path);
|
||||
|
||||
result = (_sysio->error.unlink == Vfs::Directory_service::UNLINK_OK);
|
||||
result = (_sysio.error.unlink == Vfs::Directory_service::UNLINK_OK);
|
||||
break;
|
||||
|
||||
case SYSCALL_READLINK:
|
||||
{
|
||||
Vfs::file_size out_count = 0;
|
||||
|
||||
_sysio->error.readlink = root_dir()->readlink(_sysio->readlink_in.path,
|
||||
_sysio->readlink_out.chunk,
|
||||
min(_sysio->readlink_in.bufsiz,
|
||||
sizeof(_sysio->readlink_out.chunk)),
|
||||
out_count);
|
||||
_sysio.error.readlink =
|
||||
_root_dir.readlink(_sysio.readlink_in.path,
|
||||
_sysio.readlink_out.chunk,
|
||||
min(_sysio.readlink_in.bufsiz,
|
||||
sizeof(_sysio.readlink_out.chunk)),
|
||||
out_count);
|
||||
|
||||
_sysio->readlink_out.count = out_count;
|
||||
_sysio.readlink_out.count = out_count;
|
||||
|
||||
result = (_sysio->error.readlink == Vfs::Directory_service::READLINK_OK);
|
||||
result = (_sysio.error.readlink == Vfs::Directory_service::READLINK_OK);
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSCALL_RENAME:
|
||||
|
||||
_sysio->error.rename = root_dir()->rename(_sysio->rename_in.from_path,
|
||||
_sysio->rename_in.to_path);
|
||||
_sysio.error.rename = _root_dir.rename(_sysio.rename_in.from_path,
|
||||
_sysio.rename_in.to_path);
|
||||
|
||||
result = (_sysio->error.rename == Vfs::Directory_service::RENAME_OK);
|
||||
result = (_sysio.error.rename == Vfs::Directory_service::RENAME_OK);
|
||||
break;
|
||||
|
||||
case SYSCALL_MKDIR:
|
||||
|
||||
_sysio->error.mkdir = root_dir()->mkdir(_sysio->mkdir_in.path, 0);
|
||||
_sysio.error.mkdir = _root_dir.mkdir(_sysio.mkdir_in.path, 0);
|
||||
|
||||
result = (_sysio->error.mkdir == Vfs::Directory_service::MKDIR_OK);
|
||||
result = (_sysio.error.mkdir == Vfs::Directory_service::MKDIR_OK);
|
||||
break;
|
||||
|
||||
case SYSCALL_SYMLINK:
|
||||
|
||||
_sysio->error.symlink = root_dir()->symlink(_sysio->symlink_in.oldpath,
|
||||
_sysio->symlink_in.newpath);
|
||||
_sysio.error.symlink = _root_dir.symlink(_sysio.symlink_in.oldpath,
|
||||
_sysio.symlink_in.newpath);
|
||||
|
||||
result = (_sysio->error.symlink == Vfs::Directory_service::SYMLINK_OK);
|
||||
result = (_sysio.error.symlink == Vfs::Directory_service::SYMLINK_OK);
|
||||
break;
|
||||
|
||||
case SYSCALL_USERINFO:
|
||||
{
|
||||
if (_sysio->userinfo_in.request == Sysio::USERINFO_GET_UID
|
||||
|| _sysio->userinfo_in.request == Sysio::USERINFO_GET_GID) {
|
||||
_sysio->userinfo_out.uid = Noux::user_info()->uid;
|
||||
_sysio->userinfo_out.gid = Noux::user_info()->gid;
|
||||
if (_sysio.userinfo_in.request == Sysio::USERINFO_GET_UID
|
||||
|| _sysio.userinfo_in.request == Sysio::USERINFO_GET_GID) {
|
||||
_sysio.userinfo_out.uid = Noux::user_info()->uid;
|
||||
_sysio.userinfo_out.gid = Noux::user_info()->gid;
|
||||
|
||||
result = true;
|
||||
break;
|
||||
@ -755,21 +761,21 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
* Since NOUX supports exactly one user, return false if we
|
||||
* got a unknown uid.
|
||||
*/
|
||||
if (_sysio->userinfo_in.uid != Noux::user_info()->uid)
|
||||
if (_sysio.userinfo_in.uid != Noux::user_info()->uid)
|
||||
break;
|
||||
|
||||
Genode::memcpy(_sysio->userinfo_out.name,
|
||||
Genode::memcpy(_sysio.userinfo_out.name,
|
||||
Noux::user_info()->name,
|
||||
sizeof(Noux::user_info()->name));
|
||||
Genode::memcpy(_sysio->userinfo_out.shell,
|
||||
Genode::memcpy(_sysio.userinfo_out.shell,
|
||||
Noux::user_info()->shell,
|
||||
sizeof(Noux::user_info()->shell));
|
||||
Genode::memcpy(_sysio->userinfo_out.home,
|
||||
Genode::memcpy(_sysio.userinfo_out.home,
|
||||
Noux::user_info()->home,
|
||||
sizeof(Noux::user_info()->home));
|
||||
|
||||
_sysio->userinfo_out.uid = user_info()->uid;
|
||||
_sysio->userinfo_out.gid = user_info()->gid;
|
||||
_sysio.userinfo_out.uid = user_info()->uid;
|
||||
_sysio.userinfo_out.gid = user_info()->gid;
|
||||
|
||||
result = true;
|
||||
break;
|
||||
@ -788,8 +794,8 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
*/
|
||||
unsigned long time = Noux::timeout_scheduler()->curr_time();
|
||||
|
||||
_sysio->gettimeofday_out.sec = (time / 1000);
|
||||
_sysio->gettimeofday_out.usec = (time % 1000) * 1000;
|
||||
_sysio.gettimeofday_out.sec = (time / 1000);
|
||||
_sysio.gettimeofday_out.usec = (time % 1000) * 1000;
|
||||
|
||||
result = true;
|
||||
break;
|
||||
@ -802,13 +808,13 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
*/
|
||||
unsigned long time = Noux::timeout_scheduler()->curr_time();
|
||||
|
||||
switch (_sysio->clock_gettime_in.clock_id) {
|
||||
switch (_sysio.clock_gettime_in.clock_id) {
|
||||
|
||||
/* CLOCK_SECOND is used by time(3) in the libc. */
|
||||
case Sysio::CLOCK_ID_SECOND:
|
||||
{
|
||||
_sysio->clock_gettime_out.sec = (time / 1000);
|
||||
_sysio->clock_gettime_out.nsec = 0;
|
||||
_sysio.clock_gettime_out.sec = (time / 1000);
|
||||
_sysio.clock_gettime_out.nsec = 0;
|
||||
|
||||
result = true;
|
||||
break;
|
||||
@ -816,9 +822,9 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
|
||||
default:
|
||||
{
|
||||
_sysio->clock_gettime_out.sec = 0;
|
||||
_sysio->clock_gettime_out.nsec = 0;
|
||||
_sysio->error.clock = Sysio::CLOCK_ERR_INVALID;
|
||||
_sysio.clock_gettime_out.sec = 0;
|
||||
_sysio.clock_gettime_out.nsec = 0;
|
||||
_sysio.error.clock = Sysio::CLOCK_ERR_INVALID;
|
||||
|
||||
break;
|
||||
}
|
||||
@ -844,25 +850,25 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
|
||||
case SYSCALL_SYNC:
|
||||
{
|
||||
root_dir()->sync("/");
|
||||
_root_dir.sync("/");
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSCALL_KILL:
|
||||
{
|
||||
if (_kill_broadcaster.kill(_sysio->kill_in.pid,
|
||||
_sysio->kill_in.sig))
|
||||
if (_kill_broadcaster.kill(_sysio.kill_in.pid,
|
||||
_sysio.kill_in.sig))
|
||||
result = true;
|
||||
else
|
||||
_sysio->error.kill = Sysio::KILL_ERR_SRCH;
|
||||
_sysio.error.kill = Sysio::KILL_ERR_SRCH;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SYSCALL_GETDTABLESIZE:
|
||||
{
|
||||
_sysio->getdtablesize_out.n =
|
||||
_sysio.getdtablesize_out.n =
|
||||
Noux::File_descriptor_registry::MAX_FILE_DESCRIPTORS;
|
||||
result = true;
|
||||
break;
|
||||
@ -890,15 +896,15 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
}
|
||||
|
||||
catch (Invalid_fd) {
|
||||
_sysio->error.general = Vfs::Directory_service::ERR_FD_INVALID;
|
||||
_sysio.error.general = Vfs::Directory_service::ERR_FD_INVALID;
|
||||
error("invalid file descriptor"); }
|
||||
|
||||
catch (...) { error("unexpected exception"); }
|
||||
|
||||
/* handle signals which might have occured */
|
||||
while (!_pending_signals.empty() &&
|
||||
(_sysio->pending_signals.avail_capacity() > 0)) {
|
||||
_sysio->pending_signals.add(_pending_signals.get());
|
||||
(_sysio.pending_signals.avail_capacity() > 0)) {
|
||||
_sysio.pending_signals.add(_pending_signals.get());
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -908,7 +914,7 @@ bool Noux::Child::syscall(Noux::Session::Syscall sc)
|
||||
/**
|
||||
* Return name of init process as specified in the config
|
||||
*/
|
||||
static char *name_of_init_process()
|
||||
static char const *name_of_init_process()
|
||||
{
|
||||
enum { INIT_NAME_LEN = 128 };
|
||||
static char buf[INIT_NAME_LEN];
|
||||
@ -1070,18 +1076,6 @@ static Noux::Io_channel *connect_stdio(Vfs::Dir_file_system &root,
|
||||
}
|
||||
|
||||
|
||||
Genode::Dataspace_capability Noux::ldso_ds_cap()
|
||||
{
|
||||
try {
|
||||
static Genode::Rom_connection rom("ld.lib.so");
|
||||
static Genode::Dataspace_capability ldso_ds = rom.dataspace();
|
||||
return ldso_ds;
|
||||
} catch (...) { }
|
||||
|
||||
return Genode::Dataspace_capability();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This lock is needed to delay the insertion of signals into a child object.
|
||||
* This is necessary during an 'execve()' syscall, when signals get copied from
|
||||
@ -1138,12 +1132,10 @@ void Component::construct(Genode::Env &env)
|
||||
log("--- noux started ---");
|
||||
|
||||
/* whitelist of service requests to be routed to the parent */
|
||||
static Genode::Service_registry parent_services;
|
||||
static Noux::Parent_services parent_services;
|
||||
char const *service_names[] = { "LOG", "ROM", "Timer", 0 };
|
||||
for (unsigned i = 0; service_names[i]; i++)
|
||||
parent_services.insert(new Genode::Parent_service(service_names[i]));
|
||||
|
||||
static Genode::Cap_connection cap;
|
||||
new Noux::Parent_service(parent_services, service_names[i]);
|
||||
|
||||
/* obtain global configuration */
|
||||
trace_syscalls = config()->xml_node().attribute_value("trace_syscalls", trace_syscalls);
|
||||
@ -1176,7 +1168,8 @@ void Component::construct(Genode::Env &env)
|
||||
* Entrypoint used to virtualize child resources such as RAM, RM
|
||||
*/
|
||||
enum { STACK_SIZE = 2*1024*sizeof(long) };
|
||||
static Genode::Rpc_entrypoint resources_ep(&cap, STACK_SIZE, "noux_rsc_ep");
|
||||
static Genode::Rpc_entrypoint
|
||||
resources_ep(Genode::env()->pd_session(), STACK_SIZE, "noux_rsc_ep");
|
||||
|
||||
/* create init process */
|
||||
static Genode::Signal_receiver sig_rec;
|
||||
@ -1184,7 +1177,7 @@ void Component::construct(Genode::Env &env)
|
||||
|
||||
struct Kill_broadcaster_implementation : Kill_broadcaster
|
||||
{
|
||||
Family_member *init_process;
|
||||
Family_member *init_process = nullptr;
|
||||
|
||||
bool kill(int pid, Noux::Sysio::Signal sig)
|
||||
{
|
||||
@ -1192,23 +1185,27 @@ void Component::construct(Genode::Env &env)
|
||||
}
|
||||
};
|
||||
|
||||
static Dataspace_registry ref_ram_ds_registry;
|
||||
static Ram_session_component ref_ram(resources_ep, ref_ram_ds_registry);
|
||||
|
||||
static Kill_broadcaster_implementation kill_broadcaster;
|
||||
|
||||
init_child = new Noux::Child(name_of_init_process(),
|
||||
ldso_ds_cap(),
|
||||
0,
|
||||
kill_broadcaster,
|
||||
*init_child,
|
||||
pid_allocator()->alloc(),
|
||||
&sig_rec,
|
||||
&root_dir,
|
||||
sig_rec,
|
||||
root_dir,
|
||||
args_of_init_process(),
|
||||
env_string_of_init_process(),
|
||||
&cap,
|
||||
*Genode::env()->pd_session(),
|
||||
ref_ram,
|
||||
Ram_session_capability(),
|
||||
parent_services,
|
||||
resources_ep,
|
||||
false,
|
||||
Genode::env()->heap(),
|
||||
*Genode::env()->heap(),
|
||||
destruct_queue,
|
||||
verbose);
|
||||
|
||||
|
@ -121,121 +121,121 @@ bool Noux::Child::_syscall_net(Noux::Session::Syscall sc)
|
||||
|
||||
GET_SOCKET_IO_CHANNEL_BACKEND(socket_io_channel->backend(), backend);
|
||||
|
||||
if (!backend->socket(_sysio)) {
|
||||
if (!backend->socket(&_sysio)) {
|
||||
delete socket_io_channel;
|
||||
return false;
|
||||
}
|
||||
|
||||
Shared_pointer<Io_channel> io_channel(socket_io_channel, Genode::env()->heap());
|
||||
|
||||
_sysio->socket_out.fd = add_io_channel(io_channel);
|
||||
_sysio.socket_out.fd = add_io_channel(io_channel);
|
||||
|
||||
return true;
|
||||
}
|
||||
case SYSCALL_GETSOCKOPT:
|
||||
{
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio->getsockopt_in.fd);
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio.getsockopt_in.fd);
|
||||
|
||||
GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend);
|
||||
|
||||
return backend->getsockopt(_sysio);
|
||||
return backend->getsockopt(&_sysio);
|
||||
}
|
||||
case SYSCALL_SETSOCKOPT:
|
||||
{
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio->setsockopt_in.fd);
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio.setsockopt_in.fd);
|
||||
|
||||
GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend);
|
||||
|
||||
return backend->setsockopt(_sysio);
|
||||
return backend->setsockopt(&_sysio);
|
||||
}
|
||||
case SYSCALL_ACCEPT:
|
||||
{
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio->accept_in.fd);
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio.accept_in.fd);
|
||||
|
||||
GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend);
|
||||
|
||||
int socket = backend->accept(_sysio);
|
||||
int socket = backend->accept(&_sysio);
|
||||
if (socket == -1)
|
||||
return false;
|
||||
|
||||
Socket_io_channel *socket_io_channel = new Socket_io_channel(socket);
|
||||
Shared_pointer<Io_channel> io_channel(socket_io_channel, Genode::env()->heap());
|
||||
|
||||
_sysio->accept_out.fd = add_io_channel(io_channel);
|
||||
_sysio.accept_out.fd = add_io_channel(io_channel);
|
||||
|
||||
return true;
|
||||
}
|
||||
case SYSCALL_BIND:
|
||||
{
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio->bind_in.fd);
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio.bind_in.fd);
|
||||
|
||||
GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend);
|
||||
|
||||
return (backend->bind(_sysio) == -1) ? false : true;
|
||||
return (backend->bind(&_sysio) == -1) ? false : true;
|
||||
}
|
||||
case SYSCALL_LISTEN:
|
||||
{
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio->listen_in.fd);
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio.listen_in.fd);
|
||||
|
||||
GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend);
|
||||
|
||||
return (backend->listen(_sysio) == -1) ? false : true;
|
||||
return (backend->listen(&_sysio) == -1) ? false : true;
|
||||
}
|
||||
case SYSCALL_SEND:
|
||||
{
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio->send_in.fd);
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio.send_in.fd);
|
||||
|
||||
GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend);
|
||||
|
||||
return (backend->send(_sysio) == -1) ? false : true;
|
||||
return (backend->send(&_sysio) == -1) ? false : true;
|
||||
}
|
||||
case SYSCALL_SENDTO:
|
||||
{
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio->sendto_in.fd);
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio.sendto_in.fd);
|
||||
|
||||
GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend);
|
||||
|
||||
return (backend->sendto(_sysio) == -1) ? false : true;
|
||||
return (backend->sendto(&_sysio) == -1) ? false : true;
|
||||
}
|
||||
case SYSCALL_RECV:
|
||||
{
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio->recv_in.fd);
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio.recv_in.fd);
|
||||
|
||||
GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend);
|
||||
|
||||
return (backend->recv(_sysio) == -1) ? false : true;
|
||||
return (backend->recv(&_sysio) == -1) ? false : true;
|
||||
}
|
||||
case SYSCALL_RECVFROM:
|
||||
{
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio->recvfrom_in.fd);
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio.recvfrom_in.fd);
|
||||
|
||||
GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend);
|
||||
|
||||
return (backend->recvfrom(_sysio) == -1) ? false : true;
|
||||
return (backend->recvfrom(&_sysio) == -1) ? false : true;
|
||||
}
|
||||
case SYSCALL_GETPEERNAME:
|
||||
{
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio->getpeername_in.fd);
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio.getpeername_in.fd);
|
||||
|
||||
GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend);
|
||||
|
||||
return (backend->getpeername(_sysio) == -1) ? false : true;
|
||||
return (backend->getpeername(&_sysio) == -1) ? false : true;
|
||||
}
|
||||
case SYSCALL_SHUTDOWN:
|
||||
{
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio->shutdown_in.fd);
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio.shutdown_in.fd);
|
||||
|
||||
GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend);
|
||||
|
||||
return (backend->shutdown(_sysio) == -1) ? false : true;
|
||||
return (backend->shutdown(&_sysio) == -1) ? false : true;
|
||||
}
|
||||
case SYSCALL_CONNECT:
|
||||
{
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio->connect_in.fd);
|
||||
Shared_pointer<Io_channel> io = _lookup_channel(_sysio.connect_in.fd);
|
||||
|
||||
GET_SOCKET_IO_CHANNEL_BACKEND(io->backend(), backend);
|
||||
|
||||
return (backend->connect(_sysio) == -1) ? false : true;
|
||||
return (backend->connect(&_sysio) == -1) ? false : true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,10 +42,10 @@ class Noux::Pd_session_component : public Rpc_object<Pd_session>
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Pd_session_component(char const *binary_name,
|
||||
Rpc_entrypoint &ep, Dataspace_registry &ds_registry)
|
||||
Pd_session_component(Rpc_entrypoint &ep, Child_policy::Name const &name,
|
||||
Dataspace_registry &ds_registry)
|
||||
:
|
||||
_ep(ep), _pd(binary_name),
|
||||
_ep(ep), _pd(name.string()),
|
||||
_address_space(_ep, ds_registry, _pd, _pd.address_space()),
|
||||
_stack_area (_ep, ds_registry, _pd, _pd.stack_area()),
|
||||
_linker_area (_ep, ds_registry, _pd, _pd.linker_area())
|
||||
@ -70,29 +70,31 @@ class Noux::Pd_session_component : public Rpc_object<Pd_session>
|
||||
return _address_space.lookup_region_map(addr);
|
||||
}
|
||||
|
||||
void replay(Ram_session_capability dst_ram,
|
||||
Capability<Pd_session> dst_pd_cap,
|
||||
Dataspace_registry &ds_registry,
|
||||
Rpc_entrypoint &ep)
|
||||
Region_map &address_space_region_map() { return _address_space; }
|
||||
Region_map &linker_area_region_map() { return _linker_area; }
|
||||
Region_map &stack_area_region_map() { return _stack_area; }
|
||||
|
||||
void replay(Ram_session &dst_ram,
|
||||
Pd_session_component &dst_pd,
|
||||
Dataspace_registry &ds_registry,
|
||||
Rpc_entrypoint &ep)
|
||||
{
|
||||
Pd_session_client dst_pd(dst_pd_cap);
|
||||
|
||||
/* replay region map into new protection domain */
|
||||
_stack_area .replay(dst_ram, dst_pd.stack_area(), ds_registry, ep);
|
||||
_linker_area .replay(dst_ram, dst_pd.linker_area(), ds_registry, ep);
|
||||
_address_space.replay(dst_ram, dst_pd.address_space(), ds_registry, ep);
|
||||
_stack_area .replay(dst_ram, dst_pd.stack_area_region_map(), ds_registry, ep);
|
||||
_linker_area .replay(dst_ram, dst_pd.linker_area_region_map(), ds_registry, ep);
|
||||
_address_space.replay(dst_ram, dst_pd.address_space_region_map(), ds_registry, ep);
|
||||
|
||||
Region_map_client dst_address_space(dst_pd.address_space());
|
||||
Region_map &dst_address_space = dst_pd.address_space_region_map();
|
||||
Region_map &dst_stack_area = dst_pd.stack_area_region_map();
|
||||
Region_map &dst_linker_area = dst_pd.linker_area_region_map();
|
||||
|
||||
/* attach stack area */
|
||||
Region_map_client dst_stack_area(dst_pd.stack_area());
|
||||
dst_address_space.attach(dst_stack_area.dataspace(),
|
||||
Dataspace_client(dst_stack_area.dataspace()).size(),
|
||||
0, true,
|
||||
_address_space.lookup_region_base(_stack_area.dataspace()));
|
||||
|
||||
/* attach linker area */
|
||||
Region_map_client dst_linker_area(dst_pd.linker_area());
|
||||
dst_address_space.attach(dst_linker_area.dataspace(),
|
||||
Dataspace_client(dst_linker_area.dataspace()).size(),
|
||||
0, true,
|
||||
|
@ -39,19 +39,16 @@ namespace Noux {
|
||||
Ram_dataspace_info(Ram_dataspace_capability ds_cap)
|
||||
: Dataspace_info(ds_cap) { }
|
||||
|
||||
Dataspace_capability fork(Ram_session_capability ram,
|
||||
Dataspace_registry &,
|
||||
Rpc_entrypoint &)
|
||||
Dataspace_capability fork(Ram_session &ram,
|
||||
Dataspace_registry &ds_registry,
|
||||
Rpc_entrypoint &) override
|
||||
{
|
||||
size_t const size = Dataspace_client(ds_cap()).size();
|
||||
|
||||
Ram_dataspace_capability dst_ds;
|
||||
|
||||
try {
|
||||
dst_ds = Ram_session_client(ram).alloc(size);
|
||||
} catch (...) {
|
||||
return Dataspace_capability();
|
||||
}
|
||||
try { dst_ds = ram.alloc(size); }
|
||||
catch (...) { return Dataspace_capability(); }
|
||||
|
||||
void *src = 0;
|
||||
try {
|
||||
@ -70,10 +67,12 @@ namespace Noux {
|
||||
if (dst) env()->rm_session()->detach(dst);
|
||||
|
||||
if (!src || !dst) {
|
||||
Ram_session_client(ram).free(dst_ds);
|
||||
ram.free(dst_ds);
|
||||
return Dataspace_capability();
|
||||
}
|
||||
|
||||
ds_registry.insert(new (env()->heap()) Ram_dataspace_info(dst_ds));
|
||||
|
||||
return dst_ds;
|
||||
}
|
||||
|
||||
@ -101,6 +100,8 @@ namespace Noux {
|
||||
{
|
||||
private:
|
||||
|
||||
Rpc_entrypoint &_ep;
|
||||
|
||||
List<Ram_dataspace_info> _list;
|
||||
|
||||
/*
|
||||
@ -117,14 +118,15 @@ namespace Noux {
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Ram_session_component(Dataspace_registry ®istry)
|
||||
: _used_quota(0), _registry(registry) { }
|
||||
Ram_session_component(Rpc_entrypoint &ep, Dataspace_registry ®istry)
|
||||
: _ep(ep), _used_quota(0), _registry(registry) { _ep.manage(this); }
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Ram_session_component()
|
||||
{
|
||||
_ep.dissolve(this);
|
||||
Ram_dataspace_info *info = 0;
|
||||
while ((info = _list.first()))
|
||||
free(static_cap_cast<Ram_dataspace>(info->ds_cap()));
|
||||
|
@ -91,7 +91,7 @@ class Noux::Region_map_component : public Rpc_object<Region_map>,
|
||||
*/
|
||||
Region_map_client _rm;
|
||||
|
||||
Pd_session_capability _pd;
|
||||
Pd_connection &_pd;
|
||||
|
||||
Dataspace_registry &_ds_registry;
|
||||
|
||||
@ -106,7 +106,7 @@ class Noux::Region_map_component : public Rpc_object<Region_map>,
|
||||
*/
|
||||
Region_map_component(Rpc_entrypoint &ep,
|
||||
Dataspace_registry &ds_registry,
|
||||
Pd_session_capability pd,
|
||||
Pd_connection &pd,
|
||||
Capability<Region_map> rm)
|
||||
:
|
||||
Dataspace_info(Region_map_client(rm).dataspace()),
|
||||
@ -157,10 +157,10 @@ class Noux::Region_map_component : public Rpc_object<Region_map>,
|
||||
* \param ep entrypoint used to serve the RPC interface
|
||||
* of forked managed dataspaces
|
||||
*/
|
||||
void replay(Ram_session_capability dst_ram,
|
||||
Capability<Region_map> dst_rm,
|
||||
Dataspace_registry &ds_registry,
|
||||
Rpc_entrypoint &ep)
|
||||
void replay(Ram_session &dst_ram,
|
||||
Region_map &dst_rm,
|
||||
Dataspace_registry &ds_registry,
|
||||
Rpc_entrypoint &ep)
|
||||
{
|
||||
Lock::Guard guard(_region_lock);
|
||||
for (Region *curr = _regions.first(); curr; curr = curr->next_region()) {
|
||||
@ -210,10 +210,7 @@ class Noux::Region_map_component : public Rpc_object<Region_map>,
|
||||
return;
|
||||
}
|
||||
|
||||
Region_map_client(dst_rm).attach(ds, curr->size,
|
||||
curr->offset,
|
||||
true,
|
||||
curr->local_addr);
|
||||
dst_rm.attach(ds, curr->size, curr->offset, true, curr->local_addr);
|
||||
};
|
||||
_ds_registry.apply(curr->ds, lambda);
|
||||
};
|
||||
@ -241,7 +238,7 @@ class Noux::Region_map_component : public Rpc_object<Region_map>,
|
||||
local_addr, executable);
|
||||
break;
|
||||
} catch (Region_map::Out_of_metadata) {
|
||||
Genode::env()->parent()->upgrade(_pd, "ram_quota=8096");
|
||||
_pd.upgrade_ram(8*1024);
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,9 +322,9 @@ class Noux::Region_map_component : public Rpc_object<Region_map>,
|
||||
** Dataspace_info interface **
|
||||
******************************/
|
||||
|
||||
Dataspace_capability fork(Ram_session_capability ram,
|
||||
Dataspace_registry &ds_registry,
|
||||
Rpc_entrypoint &ep) override
|
||||
Dataspace_capability fork(Ram_session &,
|
||||
Dataspace_registry &,
|
||||
Rpc_entrypoint &) override
|
||||
{
|
||||
return Dataspace_capability();
|
||||
}
|
||||
|
@ -20,80 +20,147 @@
|
||||
|
||||
namespace Noux {
|
||||
|
||||
struct Rom_dataspace_info : Dataspace_info
|
||||
{
|
||||
Rom_dataspace_info(Dataspace_capability ds) : Dataspace_info(ds) { }
|
||||
|
||||
~Rom_dataspace_info() { }
|
||||
|
||||
Dataspace_capability fork(Ram_session_capability,
|
||||
Dataspace_registry &ds_registry,
|
||||
Rpc_entrypoint &)
|
||||
{
|
||||
return ds_cap();
|
||||
}
|
||||
|
||||
void poke(addr_t dst_offset, void const *src, size_t len)
|
||||
{
|
||||
error("attempt to poke onto a ROM dataspace");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Rom_session_component : public Rpc_object<Rom_session>
|
||||
{
|
||||
private:
|
||||
|
||||
/**
|
||||
* Wrapped ROM session at core
|
||||
*/
|
||||
Rom_connection _rom;
|
||||
|
||||
Dataspace_registry &_ds_registry;
|
||||
|
||||
Rom_dataspace_info _ds_info;
|
||||
|
||||
public:
|
||||
|
||||
Rom_session_component(Dataspace_registry &ds_registry,
|
||||
char const *name)
|
||||
:
|
||||
_rom(name), _ds_registry(ds_registry), _ds_info(_rom.dataspace())
|
||||
{
|
||||
_ds_registry.insert(&_ds_info);
|
||||
}
|
||||
|
||||
~Rom_session_component()
|
||||
{
|
||||
/*
|
||||
* Lookup and lock ds info instead of directly accessing
|
||||
* the '_ds_info' member.
|
||||
*/
|
||||
_ds_registry.apply(_ds_info.ds_cap(), [this] (Dataspace_info *info) {
|
||||
|
||||
if (!info) {
|
||||
error("~Rom_session_component: unexpected !info");
|
||||
return;
|
||||
}
|
||||
|
||||
_ds_registry.remove(&_ds_info);
|
||||
|
||||
info->dissolve_users();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/***************************
|
||||
** ROM session interface **
|
||||
***************************/
|
||||
|
||||
Rom_dataspace_capability dataspace()
|
||||
{
|
||||
return static_cap_cast<Rom_dataspace>(_ds_info.ds_cap());
|
||||
}
|
||||
|
||||
void sigh(Signal_context_capability) { }
|
||||
};
|
||||
struct Rom_dataspace_info;
|
||||
class Rom_session_component;
|
||||
}
|
||||
|
||||
|
||||
struct Noux::Rom_dataspace_info : Dataspace_info
|
||||
{
|
||||
Rom_dataspace_info(Dataspace_capability ds) : Dataspace_info(ds) { }
|
||||
|
||||
~Rom_dataspace_info() { }
|
||||
|
||||
Dataspace_capability fork(Ram_session &,
|
||||
Dataspace_registry &ds_registry,
|
||||
Rpc_entrypoint &) override
|
||||
{
|
||||
ds_registry.insert(new (env()->heap()) Rom_dataspace_info(ds_cap()));
|
||||
return ds_cap();
|
||||
}
|
||||
|
||||
void poke(addr_t dst_offset, void const *src, size_t len)
|
||||
{
|
||||
error("attempt to poke onto a ROM dataspace");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Local ROM service
|
||||
*
|
||||
* Depending on the ROM name, the data is provided by the VFS (if the name
|
||||
* starts with a '/' or the parent's ROM service. If the name empty, an
|
||||
* invalid dataspace capability is returned (this is used for the binary
|
||||
* ROM session of a forked process).
|
||||
*/
|
||||
class Noux::Rom_session_component : public Rpc_object<Rom_session>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Child_policy::Name Name;
|
||||
|
||||
/**
|
||||
* Label of ROM session requested for the binary of a forked process
|
||||
*
|
||||
* In this case, the loading of the binary must be omitted because the
|
||||
* address space is replayed by the fork operation. Hence, requests for
|
||||
* such ROM modules are answered by an invalid dataspace, which is
|
||||
* handled in 'Child::Process'.
|
||||
*/
|
||||
static Name forked_magic_binary_name() { return "(forked)"; }
|
||||
|
||||
private:
|
||||
|
||||
Rpc_entrypoint &_ep;
|
||||
Vfs::Dir_file_system &_root_dir;
|
||||
Dataspace_registry &_ds_registry;
|
||||
|
||||
/**
|
||||
* Dataspace obtained from the VFS
|
||||
*/
|
||||
struct Vfs_dataspace
|
||||
{
|
||||
Vfs::Dir_file_system &root_dir;
|
||||
|
||||
Name const name;
|
||||
Dataspace_capability const ds;
|
||||
|
||||
Vfs_dataspace(Vfs::Dir_file_system &root_dir, Name const &name)
|
||||
:
|
||||
root_dir(root_dir), name(name), ds(root_dir.dataspace(name.string()))
|
||||
{ }
|
||||
|
||||
~Vfs_dataspace() { root_dir.release(name.string(), ds); }
|
||||
};
|
||||
|
||||
Lazy_volatile_object<Vfs_dataspace> _rom_from_vfs;
|
||||
|
||||
/**
|
||||
* Wrapped ROM session at core
|
||||
*/
|
||||
Lazy_volatile_object<Rom_connection> _rom_from_parent;
|
||||
|
||||
Dataspace_capability _init_ds_cap(Name const &name)
|
||||
{
|
||||
if (name.string()[0] == '/') {
|
||||
_rom_from_vfs.construct(_root_dir, name);
|
||||
return _rom_from_vfs->ds;
|
||||
}
|
||||
|
||||
if (name == forked_magic_binary_name())
|
||||
return Dataspace_capability();
|
||||
|
||||
_rom_from_parent.construct(name.string());
|
||||
Dataspace_capability ds = _rom_from_parent->dataspace();
|
||||
return ds;
|
||||
}
|
||||
|
||||
Dataspace_capability const _ds_cap;
|
||||
|
||||
public:
|
||||
|
||||
Rom_session_component(Rpc_entrypoint &ep, Vfs::Dir_file_system &root_dir,
|
||||
Dataspace_registry &ds_registry, Name const &name)
|
||||
:
|
||||
_ep(ep), _root_dir(root_dir), _ds_registry(ds_registry),
|
||||
_ds_cap(_init_ds_cap(name))
|
||||
{
|
||||
_ep.manage(this);
|
||||
_ds_registry.insert(new (env()->heap()) Rom_dataspace_info(_ds_cap));
|
||||
}
|
||||
|
||||
~Rom_session_component()
|
||||
{
|
||||
/*
|
||||
* Lookup and lock ds info instead of directly accessing
|
||||
* the '_ds_info' member.
|
||||
*/
|
||||
_ds_registry.apply(_ds_cap, [this] (Dataspace_info *info) {
|
||||
|
||||
if (!info) {
|
||||
error("~Rom_session_component: unexpected !info");
|
||||
return;
|
||||
}
|
||||
|
||||
_ds_registry.remove(info);
|
||||
|
||||
info->dissolve_users();
|
||||
});
|
||||
_ep.dissolve(this);
|
||||
}
|
||||
|
||||
|
||||
/***************************
|
||||
** ROM session interface **
|
||||
***************************/
|
||||
|
||||
Rom_dataspace_capability dataspace()
|
||||
{
|
||||
return static_cap_cast<Rom_dataspace>(_ds_cap);
|
||||
}
|
||||
|
||||
void sigh(Signal_context_capability) { }
|
||||
};
|
||||
|
||||
#endif /* _NOUX__ROM_SESSION_COMPONENT_H_ */
|
||||
|
@ -12,24 +12,22 @@
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/sleep.h>
|
||||
#include <base/component.h>
|
||||
|
||||
/* VMM utility includes */
|
||||
#include <vmm/vcpu_thread.h>
|
||||
#include <vmm/vcpu_dispatcher.h>
|
||||
#include <vmm/printf.h>
|
||||
|
||||
using Genode::Cap_connection;
|
||||
using Genode::sleep_forever;
|
||||
|
||||
|
||||
template <typename T>
|
||||
class Vcpu_dispatcher : public Vmm::Vcpu_dispatcher<Genode::Thread>
|
||||
{
|
||||
private:
|
||||
|
||||
typedef Vcpu_dispatcher This;
|
||||
|
||||
Vmm::Vcpu_same_pd _vcpu_thread;
|
||||
T _vcpu_thread;
|
||||
|
||||
/**
|
||||
* Shortcut for calling 'Vmm::Vcpu_dispatcher::register_handler'
|
||||
@ -50,17 +48,19 @@ class Vcpu_dispatcher : public Vmm::Vcpu_dispatcher<Genode::Thread>
|
||||
|
||||
void _svm_startup()
|
||||
{
|
||||
Vmm::log("_svm_startup called");
|
||||
Vmm::log(name(), " _svm_startup called");
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
enum Type { SVM, VTX };
|
||||
|
||||
Vcpu_dispatcher(Cap_connection &cap, Type type)
|
||||
Vcpu_dispatcher(Genode::Env &env, Type type, char const * name)
|
||||
:
|
||||
Vmm::Vcpu_dispatcher<Genode::Thread>(STACK_SIZE, cap, Genode::env()->cpu_session(), Genode::Affinity::Location()),
|
||||
_vcpu_thread(STACK_SIZE, Genode::env()->cpu_session(), Genode::Affinity::Location())
|
||||
Vmm::Vcpu_dispatcher<Genode::Thread>(env, STACK_SIZE, &env.cpu(),
|
||||
Genode::Affinity::Location(),
|
||||
name),
|
||||
_vcpu_thread(STACK_SIZE, &env.cpu(), Genode::Affinity::Location())
|
||||
{
|
||||
using namespace Nova;
|
||||
|
||||
@ -83,14 +83,10 @@ class Vcpu_dispatcher : public Vmm::Vcpu_dispatcher<Genode::Thread>
|
||||
};
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
Genode::log("--- VBox started ---");
|
||||
typedef Vcpu_dispatcher<Vmm::Vcpu_same_pd> Vcpu;
|
||||
|
||||
static Cap_connection cap;
|
||||
static Vcpu_dispatcher vcpu_dispatcher(cap, Vcpu_dispatcher::SVM);
|
||||
|
||||
Genode::log("going to sleep forever...");
|
||||
sleep_forever();
|
||||
return 0;
|
||||
static Vcpu vcpu(env, Vcpu::SVM, "vcpu1");
|
||||
static Vcpu vcpu2(env, Vcpu::SVM, "vcpu2");
|
||||
}
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <base/component.h>
|
||||
#include <os/config.h>
|
||||
|
||||
/* Virtualbox includes */
|
||||
@ -193,8 +194,24 @@ HRESULT setupmachine()
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
static Genode::Env *genode_env_ptr;
|
||||
|
||||
|
||||
Genode::Env &genode_env()
|
||||
{
|
||||
struct Genode_env_ptr_uninitialized : Genode::Exception { };
|
||||
if (!genode_env_ptr)
|
||||
throw Genode_env_ptr_uninitialized();
|
||||
|
||||
return *genode_env_ptr;
|
||||
}
|
||||
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
/* make Genode environment accessible via the global 'genode_env()' */
|
||||
genode_env_ptr = &env;
|
||||
|
||||
try {
|
||||
using namespace Genode;
|
||||
|
||||
@ -212,17 +229,19 @@ int main(int argc, char **argv)
|
||||
/* enable stdout/stderr for VBox Log infrastructure */
|
||||
init_libc_vbox_logger();
|
||||
|
||||
int rc = RTR3InitExe(argc, &argv, 0);
|
||||
static char argv0[] = { '_', 'm', 'a', 'i', 'n', 0};
|
||||
static char *argv[1] = { argv0 };
|
||||
char **dummy_argv = argv;
|
||||
|
||||
int rc = RTR3InitExe(1, &dummy_argv, 0);
|
||||
if (RT_FAILURE(rc))
|
||||
return -1;
|
||||
throw -1;
|
||||
|
||||
HRESULT hrc = setupmachine();
|
||||
if (FAILED(hrc)) {
|
||||
Genode::error("startup of VMM failed - reason ", hrc, " - exiting ...");
|
||||
return -2;
|
||||
throw -2;
|
||||
}
|
||||
|
||||
Genode::error("VMM exiting ...");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -54,10 +54,7 @@ class Sub_rm_connection : private Genode::Rm_connection,
|
||||
use_local_addr,
|
||||
local_addr,
|
||||
executable); },
|
||||
[&] () {
|
||||
char quota[] = "ram_quota=8192";
|
||||
Genode::env()->parent()->upgrade(this->cap(), quota);
|
||||
});
|
||||
[&] () { upgrade_ram(8192); });
|
||||
|
||||
Genode::addr_t new_addr = addr;
|
||||
new_addr += _offset;
|
||||
|
@ -302,12 +302,14 @@ bool create_emt_vcpu(pthread_t * pthread, size_t stack,
|
||||
Vcpu_handler *vcpu_handler = 0;
|
||||
|
||||
if (hip->has_feature_vmx())
|
||||
vcpu_handler = new (0x10) Vcpu_handler_vmx(stack, attr, start_routine,
|
||||
vcpu_handler = new (0x10) Vcpu_handler_vmx(genode_env(),
|
||||
stack, attr, start_routine,
|
||||
arg, cpu_session, location,
|
||||
cpu_id, name);
|
||||
|
||||
if (hip->has_feature_svm())
|
||||
vcpu_handler = new (0x10) Vcpu_handler_svm(stack, attr, start_routine,
|
||||
vcpu_handler = new (0x10) Vcpu_handler_svm(genode_env(),
|
||||
stack, attr, start_routine,
|
||||
arg, cpu_session, location,
|
||||
cpu_id, name);
|
||||
|
||||
|
@ -758,14 +758,13 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher<pthread>,
|
||||
};
|
||||
|
||||
|
||||
Vcpu_handler(size_t stack_size, const pthread_attr_t *attr,
|
||||
Vcpu_handler(Genode::Env &env, size_t stack_size, const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *), void *arg,
|
||||
Genode::Cpu_session * cpu_session,
|
||||
Genode::Affinity::Location location,
|
||||
unsigned int cpu_id, const char * name)
|
||||
:
|
||||
Vmm::Vcpu_dispatcher<pthread>(stack_size, *Genode::env()->pd_session(),
|
||||
cpu_session, location,
|
||||
Vmm::Vcpu_dispatcher<pthread>(env, stack_size, cpu_session, location,
|
||||
attr ? *attr : 0, start_routine, arg,
|
||||
name),
|
||||
_vcpu(cpu_session, location),
|
||||
|
@ -84,13 +84,13 @@ class Vcpu_handler_svm : public Vcpu_handler
|
||||
|
||||
public:
|
||||
|
||||
Vcpu_handler_svm(size_t stack_size, const pthread_attr_t *attr,
|
||||
Vcpu_handler_svm(Genode::Env &env, size_t stack_size, const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *), void *arg,
|
||||
Genode::Cpu_session * cpu_session,
|
||||
Genode::Affinity::Location location,
|
||||
unsigned int cpu_id, const char * name)
|
||||
:
|
||||
Vcpu_handler(stack_size, attr, start_routine, arg, cpu_session,
|
||||
Vcpu_handler(env, stack_size, attr, start_routine, arg, cpu_session,
|
||||
location, cpu_id, name)
|
||||
{
|
||||
using namespace Nova;
|
||||
|
@ -158,13 +158,13 @@ class Vcpu_handler_vmx : public Vcpu_handler
|
||||
|
||||
public:
|
||||
|
||||
Vcpu_handler_vmx(size_t stack_size, const pthread_attr_t *attr,
|
||||
Vcpu_handler_vmx(Genode::Env &env, size_t stack_size, const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *), void *arg,
|
||||
Genode::Cpu_session * cpu_session,
|
||||
Genode::Affinity::Location location,
|
||||
unsigned int cpu_id, const char * name)
|
||||
:
|
||||
Vcpu_handler(stack_size, attr, start_routine, arg, cpu_session,
|
||||
Vcpu_handler(env, stack_size, attr, start_routine, arg, cpu_session,
|
||||
location, cpu_id, name)
|
||||
{
|
||||
using namespace Nova;
|
||||
|
@ -15,7 +15,7 @@
|
||||
#define _SUP_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <cpu_session/cpu_session.h>
|
||||
#include <base/component.h>
|
||||
|
||||
/* VirtualBox includes */
|
||||
#include <VBox/vmm/vm.h>
|
||||
@ -48,6 +48,8 @@ void genode_update_tsc(void (*update_func)(void), unsigned long update_us);
|
||||
|
||||
Genode::Cpu_session * get_vcpu_cpu_session();
|
||||
|
||||
Genode::Env &genode_env();
|
||||
|
||||
void genode_VMMR0_DO_GVMM_CREATE_VM(PSUPVMMR0REQHDR pReqHdr);
|
||||
void genode_VMMR0_DO_GVMM_REGISTER_VMCPU(PVMR0 pVMR0, VMCPUID idCpu);
|
||||
|
||||
|
@ -131,8 +131,7 @@ extern "C" int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
} catch (Cpu_session::Out_of_metadata) {
|
||||
log("Upgrading memory for creation of "
|
||||
"thread '", Cstring(rtthread->szName), "'");
|
||||
env()->parent()->upgrade(cpu_connection(rtthread->enmType)->cap(),
|
||||
"ram_quota=4096");
|
||||
cpu_connection(rtthread->enmType)->upgrade_ram(4096);
|
||||
} catch (...) { break; }
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <base/component.h>
|
||||
#include <os/config.h>
|
||||
|
||||
/* Virtualbox includes */
|
||||
@ -224,8 +225,24 @@ HRESULT setupmachine()
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
static Genode::Env *genode_env_ptr;
|
||||
|
||||
|
||||
Genode::Env &genode_env()
|
||||
{
|
||||
struct Genode_env_ptr_uninitialized : Genode::Exception { };
|
||||
if (!genode_env_ptr)
|
||||
throw Genode_env_ptr_uninitialized();
|
||||
|
||||
return *genode_env_ptr;
|
||||
}
|
||||
|
||||
|
||||
void Component::construct(Genode::Env &env)
|
||||
{
|
||||
/* make Genode environment accessible via the global 'genode_env()' */
|
||||
genode_env_ptr = &env;
|
||||
|
||||
try {
|
||||
using namespace Genode;
|
||||
|
||||
@ -243,18 +260,20 @@ int main(int argc, char **argv)
|
||||
/* enable stdout/stderr for VBox Log infrastructure */
|
||||
init_libc_vbox_logger();
|
||||
|
||||
int rc = RTR3InitExe(argc, &argv, 0);
|
||||
static char argv0[] = { '_', 'm', 'a', 'i', 'n', 0};
|
||||
static char *argv[1] = { argv0 };
|
||||
char **dummy_argv = argv;
|
||||
|
||||
int rc = RTR3InitExe(1, &dummy_argv, 0);
|
||||
if (RT_FAILURE(rc))
|
||||
return -1;
|
||||
throw -1;
|
||||
|
||||
HRESULT hrc = setupmachine();
|
||||
if (FAILED(hrc)) {
|
||||
Genode::error("startup of VMM failed - reason ", hrc, " '",
|
||||
RTErrCOMGet(hrc)->pszMsgFull, "' - exiting ...");
|
||||
return -2;
|
||||
throw -2;
|
||||
}
|
||||
|
||||
Genode::error("VMM exiting ...");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -563,12 +563,14 @@ bool create_emt_vcpu(pthread_t * pthread, ::size_t stack,
|
||||
Vcpu_handler *vcpu_handler = 0;
|
||||
|
||||
if (hip->has_feature_vmx())
|
||||
vcpu_handler = new (0x10) Vcpu_handler_vmx(stack, attr, start_routine,
|
||||
vcpu_handler = new (0x10) Vcpu_handler_vmx(genode_env(),
|
||||
stack, attr, start_routine,
|
||||
arg, cpu_session, location,
|
||||
cpu_id, name);
|
||||
|
||||
if (hip->has_feature_svm())
|
||||
vcpu_handler = new (0x10) Vcpu_handler_svm(stack, attr, start_routine,
|
||||
vcpu_handler = new (0x10) Vcpu_handler_svm(genode_env(),
|
||||
stack, attr, start_routine,
|
||||
arg, cpu_session, location,
|
||||
cpu_id, name);
|
||||
|
||||
|
@ -761,16 +761,15 @@ class Vcpu_handler : public Vmm::Vcpu_dispatcher<pthread>,
|
||||
};
|
||||
|
||||
|
||||
Vcpu_handler(size_t stack_size, const pthread_attr_t *attr,
|
||||
Vcpu_handler(Genode::Env &env, size_t stack_size, const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *), void *arg,
|
||||
Genode::Cpu_session * cpu_session,
|
||||
Genode::Affinity::Location location,
|
||||
unsigned int cpu_id, const char * name)
|
||||
:
|
||||
Vmm::Vcpu_dispatcher<pthread>(stack_size, *Genode::env()->pd_session(),
|
||||
cpu_session, location,
|
||||
attr ? *attr : 0, start_routine,
|
||||
arg, name),
|
||||
Vmm::Vcpu_dispatcher<pthread>(env, stack_size, cpu_session, location,
|
||||
attr ? *attr : 0, start_routine, arg,
|
||||
name),
|
||||
_vcpu(cpu_session, location),
|
||||
_ec_sel(Genode::cap_map()->insert()),
|
||||
_irq_win(false),
|
||||
|
@ -84,13 +84,13 @@ class Vcpu_handler_svm : public Vcpu_handler
|
||||
|
||||
public:
|
||||
|
||||
Vcpu_handler_svm(size_t stack_size, const pthread_attr_t *attr,
|
||||
Vcpu_handler_svm(Genode::Env &env, size_t stack_size, const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *), void *arg,
|
||||
Genode::Cpu_session * cpu_session,
|
||||
Genode::Affinity::Location location,
|
||||
unsigned int cpu_id, const char * name)
|
||||
:
|
||||
Vcpu_handler(stack_size, attr, start_routine, arg, cpu_session,
|
||||
Vcpu_handler(env, stack_size, attr, start_routine, arg, cpu_session,
|
||||
location, cpu_id, name)
|
||||
{
|
||||
using namespace Nova;
|
||||
|
@ -166,13 +166,13 @@ class Vcpu_handler_vmx : public Vcpu_handler
|
||||
|
||||
public:
|
||||
|
||||
Vcpu_handler_vmx(size_t stack_size, const pthread_attr_t *attr,
|
||||
Vcpu_handler_vmx(Genode::Env &env, size_t stack_size, const pthread_attr_t *attr,
|
||||
void *(*start_routine) (void *), void *arg,
|
||||
Genode::Cpu_session * cpu_session,
|
||||
Genode::Affinity::Location location,
|
||||
unsigned int cpu_id, const char * name)
|
||||
:
|
||||
Vcpu_handler(stack_size, attr, start_routine, arg, cpu_session,
|
||||
Vcpu_handler(env, stack_size, attr, start_routine, arg, cpu_session,
|
||||
location, cpu_id, name)
|
||||
{
|
||||
using namespace Nova;
|
||||
|
Reference in New Issue
Block a user