mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-19 15:43:56 +00:00
Move repositories to 'repos/' subdirectory
This patch changes the top-level directory layout as a preparatory step for improving the tools for managing 3rd-party source codes. The rationale is described in the issue referenced below. Issue #1082
This commit is contained in:
119
repos/base-linux/src/core/context_area.cc
Normal file
119
repos/base-linux/src/core/context_area.cc
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* \brief Linux-specific support code for the thread API
|
||||
* \author Norman Feske
|
||||
* \date 2010-01-13
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <rm_session/rm_session.h>
|
||||
#include <ram_session/ram_session.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/thread.h>
|
||||
|
||||
#include <context_area.h>
|
||||
|
||||
|
||||
/**
|
||||
* Region-manager session for allocating thread contexts
|
||||
*
|
||||
* This class corresponds to the managed dataspace that is normally
|
||||
* used for organizing thread contexts with the thread context area.
|
||||
* It "emulates" the sub address space by adjusting the local address
|
||||
* argument to 'attach' with the offset of the thread context area.
|
||||
*/
|
||||
class Context_area_rm_session : public Genode::Rm_session
|
||||
{
|
||||
public:
|
||||
|
||||
Context_area_rm_session()
|
||||
{
|
||||
flush_context_area();
|
||||
reserve_context_area();
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach backing store to thread-context area
|
||||
*/
|
||||
Local_addr attach(Genode::Dataspace_capability ds_cap,
|
||||
Genode::size_t size, Genode::off_t offset,
|
||||
bool use_local_addr, Local_addr local_addr,
|
||||
bool executable)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
/* convert context-area-relative to absolute virtual address */
|
||||
addr_t addr = local_addr;
|
||||
addr += Native_config::context_area_virtual_base();
|
||||
|
||||
/* use anonymous mmap for allocating stack backing store */
|
||||
int flags = MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE;
|
||||
int prot = PROT_READ | PROT_WRITE;
|
||||
void *res = lx_mmap((void*)addr, size, prot, flags, -1, 0);
|
||||
|
||||
if ((addr_t)res != addr)
|
||||
throw Region_conflict();
|
||||
|
||||
return local_addr;
|
||||
}
|
||||
|
||||
void detach(Local_addr local_addr) {
|
||||
PWRN("context area detach from 0x%p - not implemented", (void *)local_addr); }
|
||||
|
||||
Genode::Pager_capability add_client(Genode::Thread_capability) {
|
||||
return Genode::Pager_capability(); }
|
||||
|
||||
void remove_client(Genode::Pager_capability) { }
|
||||
|
||||
void fault_handler(Genode::Signal_context_capability) { }
|
||||
|
||||
State state() { return State(); }
|
||||
|
||||
Genode::Dataspace_capability dataspace() {
|
||||
return Genode::Dataspace_capability(); }
|
||||
};
|
||||
|
||||
|
||||
class Context_area_ram_session : public Genode::Ram_session
|
||||
{
|
||||
public:
|
||||
|
||||
Genode::Ram_dataspace_capability alloc(Genode::size_t size, bool) {
|
||||
return Genode::Ram_dataspace_capability(); }
|
||||
|
||||
void free(Genode::Ram_dataspace_capability) { }
|
||||
|
||||
int ref_account(Genode::Ram_session_capability) { return 0; }
|
||||
|
||||
int transfer_quota(Genode::Ram_session_capability, Genode::size_t) { return 0; }
|
||||
|
||||
size_t quota() { return 0; }
|
||||
|
||||
size_t used() { return 0; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return single instance of the context-area RM and RAM session
|
||||
*/
|
||||
namespace Genode {
|
||||
|
||||
Rm_session *env_context_area_rm_session()
|
||||
{
|
||||
static Context_area_rm_session inst;
|
||||
return &inst;
|
||||
}
|
||||
|
||||
Ram_session *env_context_area_ram_session()
|
||||
{
|
||||
static Context_area_ram_session inst;
|
||||
return &inst;
|
||||
}
|
||||
}
|
||||
|
49
repos/base-linux/src/core/cpu_session_extension.cc
Normal file
49
repos/base-linux/src/core/cpu_session_extension.cc
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* \brief Linux-specific extension of the CPU session implementation
|
||||
* \author Norman Feske
|
||||
* \date 2012-08-09
|
||||
*/
|
||||
|
||||
/* core includes */
|
||||
#include <cpu_session_component.h>
|
||||
|
||||
/* Linux includes */
|
||||
#include <core_linux_syscalls.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
void Cpu_session_component::thread_id(Thread_capability thread_cap, int pid, int tid)
|
||||
{
|
||||
Object_pool<Cpu_thread_component>::Guard
|
||||
thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread) return;
|
||||
|
||||
thread->platform_thread()->thread_id(pid, tid);
|
||||
}
|
||||
|
||||
|
||||
Untyped_capability Cpu_session_component::server_sd(Thread_capability thread_cap)
|
||||
{
|
||||
Object_pool<Cpu_thread_component>::Guard
|
||||
thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread) return Untyped_capability();
|
||||
|
||||
enum { DUMMY_LOCAL_NAME = 0 };
|
||||
typedef Native_capability::Dst Dst;
|
||||
return Untyped_capability(Dst(thread->platform_thread()->server_sd()),
|
||||
DUMMY_LOCAL_NAME);
|
||||
}
|
||||
|
||||
|
||||
Untyped_capability Cpu_session_component::client_sd(Thread_capability thread_cap)
|
||||
{
|
||||
Object_pool<Cpu_thread_component>::Guard
|
||||
thread(_thread_ep->lookup_and_lock(thread_cap));
|
||||
if (!thread) return Untyped_capability();
|
||||
|
||||
enum { DUMMY_LOCAL_NAME = 0 };
|
||||
typedef Native_capability::Dst Dst;
|
||||
return Untyped_capability(Dst(thread->platform_thread()->client_sd()),
|
||||
DUMMY_LOCAL_NAME);
|
||||
}
|
28
repos/base-linux/src/core/cpu_session_support.cc
Normal file
28
repos/base-linux/src/core/cpu_session_support.cc
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* \brief Platform-specific parts of cores CPU-service
|
||||
* \author Martin Stein
|
||||
* \date 2012-04-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/printf.h>
|
||||
|
||||
/* Core includes */
|
||||
#include <cpu_session_component.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
Ram_dataspace_capability Cpu_session_component::utcb(Thread_capability thread_cap)
|
||||
{
|
||||
PERR("%s: Not implemented", __PRETTY_FUNCTION__);
|
||||
return Ram_dataspace_capability();
|
||||
}
|
||||
|
49
repos/base-linux/src/core/include/cap_session_component.h
Normal file
49
repos/base-linux/src/core/include/cap_session_component.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* \brief Capability allocation service
|
||||
* \author Norman Feske
|
||||
* \date 2006-06-26
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-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 _CORE__INCLUDE__LINUX__CAP_SESSION_COMPONENT_H_
|
||||
#define _CORE__INCLUDE__LINUX__CAP_SESSION_COMPONENT_H_
|
||||
|
||||
#include <cap_session/cap_session.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <base/lock.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Cap_session_component : public Rpc_object<Cap_session>
|
||||
{
|
||||
private:
|
||||
|
||||
static long _unique_id_cnt;
|
||||
static Lock &_lock()
|
||||
{
|
||||
static Lock static_lock;
|
||||
return static_lock;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Cap_session_component(Allocator *md_alloc, const char *args) {}
|
||||
|
||||
Native_capability alloc(Native_capability ep)
|
||||
{
|
||||
Lock::Guard lock_guard(_lock());
|
||||
|
||||
return Native_capability(ep.dst(), ++_unique_id_cnt);
|
||||
}
|
||||
|
||||
void free(Native_capability cap) { }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__LINUX__CAP_SESSION_COMPONENT_H_ */
|
209
repos/base-linux/src/core/include/core_env.h
Normal file
209
repos/base-linux/src/core/include/core_env.h
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
* \brief Core-specific environment for Linux
|
||||
* \author Norman Feske
|
||||
* \author Christian Helmuth
|
||||
* \date 2006-07-28
|
||||
*
|
||||
* The Core-specific environment ensures that all sessions of Core's
|
||||
* environment a local.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-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 _CORE__INCLUDE__CORE_ENV_H_
|
||||
#define _CORE__INCLUDE__CORE_ENV_H_
|
||||
|
||||
/* core includes */
|
||||
#include <platform.h>
|
||||
#include <core_parent.h>
|
||||
#include <cap_session_component.h>
|
||||
#include <ram_session_component.h>
|
||||
|
||||
/* internal base includes */
|
||||
#include <platform_env.h>
|
||||
|
||||
|
||||
namespace Genode {
|
||||
|
||||
/**
|
||||
* Lock-guarded version of a RAM-session implementation
|
||||
*
|
||||
* \param RAM_SESSION_IMPL non-thread-safe RAM-session class
|
||||
*
|
||||
* In contrast to normal processes, core's 'env()->ram_session()' is not
|
||||
* synchronized by an RPC interface. However, it is accessed by different
|
||||
* threads using the 'env()->heap()' and the sliced heap used for
|
||||
* allocating sessions to core's services.
|
||||
*/
|
||||
template <typename RAM_SESSION_IMPL>
|
||||
class Synchronized_ram_session : public RAM_SESSION_IMPL
|
||||
{
|
||||
private:
|
||||
|
||||
Lock _lock;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Synchronized_ram_session(Rpc_entrypoint *ds_ep,
|
||||
Rpc_entrypoint *ram_session_ep,
|
||||
Range_allocator *ram_alloc,
|
||||
Allocator *md_alloc,
|
||||
const char *args,
|
||||
size_t quota_limit = 0)
|
||||
:
|
||||
RAM_SESSION_IMPL(ds_ep, ram_session_ep, ram_alloc, md_alloc, args, quota_limit)
|
||||
{ }
|
||||
|
||||
|
||||
/***************************
|
||||
** RAM-session interface **
|
||||
***************************/
|
||||
|
||||
Ram_dataspace_capability alloc(size_t size, bool cached)
|
||||
{
|
||||
Lock::Guard lock_guard(_lock);
|
||||
return RAM_SESSION_IMPL::alloc(size, cached);
|
||||
}
|
||||
|
||||
void free(Ram_dataspace_capability ds)
|
||||
{
|
||||
Lock::Guard lock_guard(_lock);
|
||||
RAM_SESSION_IMPL::free(ds);
|
||||
}
|
||||
|
||||
int ref_account(Ram_session_capability session)
|
||||
{
|
||||
Lock::Guard lock_guard(_lock);
|
||||
return RAM_SESSION_IMPL::ref_account(session);
|
||||
}
|
||||
|
||||
int transfer_quota(Ram_session_capability session, size_t size)
|
||||
{
|
||||
Lock::Guard lock_guard(_lock);
|
||||
return RAM_SESSION_IMPL::transfer_quota(session, size);
|
||||
}
|
||||
|
||||
size_t quota()
|
||||
{
|
||||
Lock::Guard lock_guard(_lock);
|
||||
return RAM_SESSION_IMPL::quota();
|
||||
}
|
||||
|
||||
size_t used()
|
||||
{
|
||||
Lock::Guard lock_guard(_lock);
|
||||
return RAM_SESSION_IMPL::used();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Core_env : public Platform_env_base
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Entrypoint with support for local object access
|
||||
*
|
||||
* Within core, there are a few cases where the RPC objects must
|
||||
* be invoked by direct function calls instead of using RPC.
|
||||
* I.e., when an entrypoint dispatch function performs a memory
|
||||
* allocation via the 'Sliced_heap', the 'attach' function of
|
||||
* 'Rm_session_mmap' tries to obtain the dataspace's size and fd.
|
||||
* Normally, this would be done by calling the entrypoint but the
|
||||
* entrypoint cannot call itself. To support this special case,
|
||||
* the 'Entrypoint' extends the 'Rpc_entrypoint' with the
|
||||
* functionality needed to lookup an RPC object by its capability.
|
||||
*/
|
||||
struct Entrypoint : Rpc_entrypoint
|
||||
{
|
||||
enum { STACK_SIZE = 2048 * sizeof(Genode::addr_t) };
|
||||
|
||||
Entrypoint(Cap_session *cap_session)
|
||||
:
|
||||
Rpc_entrypoint(cap_session, STACK_SIZE, "entrypoint")
|
||||
{ }
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
typedef Synchronized_ram_session<Ram_session_component> Core_ram_session;
|
||||
|
||||
Core_parent _core_parent;
|
||||
Cap_session_component _cap_session;
|
||||
Entrypoint _entrypoint;
|
||||
Core_ram_session _ram_session;
|
||||
Heap _heap;
|
||||
Ram_session_capability const _ram_session_cap;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Core_env()
|
||||
:
|
||||
Platform_env_base(Ram_session_capability(),
|
||||
Cpu_session_capability(),
|
||||
Pd_session_capability()),
|
||||
_cap_session(platform()->core_mem_alloc(), "ram_quota=4K"),
|
||||
_entrypoint(&_cap_session),
|
||||
_ram_session(&_entrypoint, &_entrypoint,
|
||||
platform()->ram_alloc(), platform()->core_mem_alloc(),
|
||||
"ram_quota=4M", platform()->ram_alloc()->avail()),
|
||||
_heap(&_ram_session, Platform_env_base::rm_session()),
|
||||
_ram_session_cap(_entrypoint.manage(&_ram_session))
|
||||
{ }
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Core_env() { parent()->exit(0); }
|
||||
|
||||
|
||||
/**************************************
|
||||
** Core-specific accessor functions **
|
||||
**************************************/
|
||||
|
||||
Cap_session *cap_session() { return &_cap_session; }
|
||||
Entrypoint *entrypoint() { return &_entrypoint; }
|
||||
|
||||
|
||||
/*******************
|
||||
** Env interface **
|
||||
*******************/
|
||||
|
||||
Parent *parent() { return &_core_parent; }
|
||||
Ram_session *ram_session() { return &_ram_session; }
|
||||
Ram_session_capability ram_session_cap() { return _ram_session_cap; }
|
||||
Allocator *heap() { return &_heap; }
|
||||
|
||||
Cpu_session_capability cpu_session_cap() {
|
||||
PWRN("%s:%u not implemented", __FILE__, __LINE__);
|
||||
return Cpu_session_capability();
|
||||
}
|
||||
|
||||
Pd_session *pd_session()
|
||||
{
|
||||
PWRN("%s:%u not implemented", __FILE__, __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void reload_parent_cap(Capability<Parent>::Dst, long) { }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Request pointer to static environment of Core
|
||||
*/
|
||||
extern Core_env *core_env();
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__CORE_ENV_H_ */
|
229
repos/base-linux/src/core/include/core_linux_syscalls.h
Normal file
229
repos/base-linux/src/core/include/core_linux_syscalls.h
Normal file
@ -0,0 +1,229 @@
|
||||
/*
|
||||
* \brief Linux system calls that are used in core only
|
||||
* \author Norman Feske
|
||||
* \date 2012-08-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-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 _CORE__INCLUDE__CORE_LINUX_SYSCALLS_H_
|
||||
#define _CORE__INCLUDE__CORE_LINUX_SYSCALLS_H_
|
||||
|
||||
/* basic Linux syscall bindings */
|
||||
#include <linux_syscalls.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
||||
/*******************************************************
|
||||
** Functions used by core's ram-session support code **
|
||||
*******************************************************/
|
||||
|
||||
inline int lx_mkdir(char const *pathname, mode_t mode)
|
||||
{
|
||||
return lx_syscall(SYS_mkdir, pathname, mode);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_ftruncate(int fd, unsigned long length)
|
||||
{
|
||||
return lx_syscall(SYS_ftruncate, fd, length);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_unlink(const char *fname)
|
||||
{
|
||||
return lx_syscall(SYS_unlink, fname);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_dup(int fd)
|
||||
{
|
||||
return lx_syscall(SYS_dup, fd);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************
|
||||
** Functions used by core's rom-session support code **
|
||||
*******************************************************/
|
||||
|
||||
inline int lx_open(const char *pathname, int flags, mode_t mode = 0)
|
||||
{
|
||||
return lx_syscall(SYS_open, pathname, flags, mode);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_stat(const char *path, struct stat64 *buf)
|
||||
{
|
||||
#ifdef _LP64
|
||||
return lx_syscall(SYS_stat, path, buf);
|
||||
#else
|
||||
return lx_syscall(SYS_stat64, path, buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**************************************
|
||||
** Process creation and destruction **
|
||||
**************************************/
|
||||
|
||||
inline int lx_execve(const char *filename, char *const argv[],
|
||||
char *const envp[])
|
||||
{
|
||||
return lx_syscall(SYS_execve, filename, argv, envp);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_kill(int pid, int signal)
|
||||
{
|
||||
return lx_syscall(SYS_kill, pid, signal);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_create_process(int (*entry)(void *), void *stack, void *arg)
|
||||
{
|
||||
/*
|
||||
* The low byte of the flags denotes the signal to be sent to the parent
|
||||
* when the process terminates. We want core to receive SIGCHLD signals on
|
||||
* this condition.
|
||||
*/
|
||||
int const flags = CLONE_VFORK | LX_SIGCHLD;
|
||||
return lx_clone((int (*)(void *))entry, stack, flags, arg);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_setuid(unsigned int uid)
|
||||
{
|
||||
return lx_syscall(SYS_setuid, uid);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_setgid(unsigned int gid)
|
||||
{
|
||||
return lx_syscall(SYS_setgid, gid);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Query PID of any terminated child
|
||||
*
|
||||
* This function is called be core after having received a SIGCHLD signal to
|
||||
* determine the PID of a terminated Genode process.
|
||||
*
|
||||
* \return PID of terminated process or -1 if no process was terminated
|
||||
*/
|
||||
inline int lx_pollpid()
|
||||
{
|
||||
return lx_syscall(SYS_wait4, -1 /* any PID */, (int *)0, 1 /* WNOHANG */, 0);
|
||||
}
|
||||
|
||||
|
||||
/*********************
|
||||
** Chroot handling **
|
||||
*********************/
|
||||
|
||||
inline int lx_chroot(char const *path)
|
||||
{
|
||||
return lx_syscall(SYS_chroot, path);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_chdir(char const *path)
|
||||
{
|
||||
return lx_syscall(SYS_chdir, path);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_getcwd(char *dst, size_t dst_len)
|
||||
{
|
||||
return lx_syscall(SYS_getcwd, dst, dst_len);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_bindmount(char const *source, char const *target)
|
||||
{
|
||||
enum { MS_BIND = 4096 };
|
||||
return lx_syscall(SYS_mount, source, target, 0, MS_BIND, 0);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_umount(char const *target)
|
||||
{
|
||||
return lx_syscall(SYS_umount2, target, 0);
|
||||
}
|
||||
|
||||
|
||||
/********************************************
|
||||
** Communication over Unix-domain sockets **
|
||||
********************************************/
|
||||
|
||||
#ifdef SYS_socketcall
|
||||
|
||||
inline int lx_socket(int domain, int type, int protocol)
|
||||
{
|
||||
long args[3] = { domain, type, protocol };
|
||||
return lx_socketcall(SYS_SOCKET, args);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_bind(int sockfd, const struct sockaddr *addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
long args[3] = { sockfd, (long)addr, (long)addrlen };
|
||||
return lx_socketcall(SYS_BIND, args);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_connect(int sockfd, const struct sockaddr *serv_addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
long args[3] = { sockfd, (long)serv_addr, (long)addrlen };
|
||||
return lx_socketcall(SYS_CONNECT, args);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline int lx_socket(int domain, int type, int protocol)
|
||||
{
|
||||
return lx_syscall(SYS_socket, domain, type, protocol);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_bind(int sockfd, const struct sockaddr *addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
return lx_syscall(SYS_bind, sockfd, addr, addrlen);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_connect(int sockfd, const struct sockaddr *serv_addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
return lx_syscall(SYS_connect, sockfd, serv_addr, addrlen);
|
||||
}
|
||||
|
||||
#endif /* SYS_socketcall */
|
||||
|
||||
|
||||
/******************************
|
||||
** Linux signal dispatching **
|
||||
******************************/
|
||||
|
||||
inline int lx_pipe(int pipefd[2])
|
||||
{
|
||||
return lx_syscall(SYS_pipe, pipefd);
|
||||
}
|
||||
|
||||
|
||||
inline int lx_read(int fd, void *buf, Genode::size_t count)
|
||||
{
|
||||
return lx_syscall(SYS_read, fd, buf, count);
|
||||
}
|
||||
|
||||
|
||||
#endif /* _CORE__INCLUDE__CORE_LINUX_SYSCALLS_H_ */
|
205
repos/base-linux/src/core/include/cpu_session_component.h
Normal file
205
repos/base-linux/src/core/include/cpu_session_component.h
Normal file
@ -0,0 +1,205 @@
|
||||
/*
|
||||
* \brief Core-specific instance of the CPU session/thread interfaces
|
||||
* \author Christian Helmuth
|
||||
* \author Norman Feske
|
||||
* \date 2006-07-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-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 _CORE__INCLUDE__CPU_SESSION_COMPONENT_H_
|
||||
#define _CORE__INCLUDE__CPU_SESSION_COMPONENT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/list.h>
|
||||
#include <base/allocator_guard.h>
|
||||
#include <base/lock.h>
|
||||
#include <base/pager.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <linux_cpu_session/linux_cpu_session.h>
|
||||
|
||||
/* core includes */
|
||||
#include <cpu_thread_allocator.h>
|
||||
#include <platform_thread.h>
|
||||
#include <trace/control_area.h>
|
||||
#include <trace/source_registry.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
/**
|
||||
* RPC interface of CPU thread
|
||||
*
|
||||
* We make 'Cpu_thread' a RPC object only to be able to lookup CPU threads
|
||||
* from thread capabilities supplied as arguments to CPU-session functions.
|
||||
* A CPU thread does not provide an actual RPC interface.
|
||||
*/
|
||||
struct Cpu_thread
|
||||
{
|
||||
GENODE_RPC_INTERFACE();
|
||||
};
|
||||
|
||||
|
||||
class Cpu_thread_component : public Rpc_object<Cpu_thread>,
|
||||
public List<Cpu_thread_component>::Element
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Trace::Session_label Session_label;
|
||||
typedef Trace::Thread_name Thread_name;
|
||||
|
||||
private:
|
||||
|
||||
Thread_name const _name;
|
||||
Platform_thread _platform_thread;
|
||||
bool _bound; /* pd binding flag */
|
||||
Signal_context_capability _sigh; /* exception handler */
|
||||
unsigned const _trace_control_index;
|
||||
Trace::Source _trace_source;
|
||||
|
||||
public:
|
||||
|
||||
Cpu_thread_component(Session_label const &label,
|
||||
Thread_name const &name,
|
||||
unsigned priority, addr_t utcb,
|
||||
Signal_context_capability sigh,
|
||||
unsigned trace_control_index,
|
||||
Trace::Control &trace_control)
|
||||
:
|
||||
_name(name),
|
||||
_platform_thread(name.string(), priority, utcb), _bound(false),
|
||||
_sigh(sigh), _trace_control_index(trace_control_index),
|
||||
_trace_source(label, _name, trace_control)
|
||||
{
|
||||
update_exception_sigh();
|
||||
}
|
||||
|
||||
|
||||
/************************
|
||||
** Accessor functions **
|
||||
************************/
|
||||
|
||||
Platform_thread *platform_thread() { return &_platform_thread; }
|
||||
bool bound() const { return _bound; }
|
||||
void bound(bool b) { _bound = b; }
|
||||
Trace::Source *trace_source() { return &_trace_source; }
|
||||
|
||||
void sigh(Signal_context_capability sigh)
|
||||
{
|
||||
_sigh = sigh;
|
||||
update_exception_sigh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Propagate exception handler to platform thread
|
||||
*/
|
||||
void update_exception_sigh();
|
||||
|
||||
/**
|
||||
* Return index within the CPU-session's trace control area
|
||||
*/
|
||||
unsigned trace_control_index() const { return _trace_control_index; }
|
||||
};
|
||||
|
||||
|
||||
class Cpu_session_component : public Rpc_object<Linux_cpu_session>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Cpu_thread_component::Session_label Session_label;
|
||||
|
||||
private:
|
||||
|
||||
Session_label _label;
|
||||
Rpc_entrypoint *_thread_ep;
|
||||
Pager_entrypoint *_pager_ep;
|
||||
Allocator_guard _md_alloc; /* guarded meta-data allocator */
|
||||
Cpu_thread_allocator _thread_alloc; /* meta-data allocator */
|
||||
Lock _thread_alloc_lock; /* protect allocator access */
|
||||
List<Cpu_thread_component> _thread_list;
|
||||
Lock _thread_list_lock; /* protect thread list */
|
||||
unsigned _priority; /* priority of threads
|
||||
created with this
|
||||
session */
|
||||
Affinity::Location _location; /* CPU affinity of this
|
||||
session */
|
||||
Trace::Source_registry &_trace_sources;
|
||||
Trace::Control_area _trace_control_area;
|
||||
|
||||
/**
|
||||
* Exception handler that will be invoked unless overridden by a
|
||||
* call of 'Cpu_session::exception_handler'.
|
||||
*/
|
||||
Signal_context_capability _default_exception_handler;
|
||||
|
||||
/**
|
||||
* Raw thread-killing functionality
|
||||
*
|
||||
* This function is called from the 'kill_thread' function and
|
||||
* the destructor. Each these functions grab the list lock
|
||||
* by themselves and call this function to perform the actual
|
||||
* killing.
|
||||
*/
|
||||
void _unsynchronized_kill_thread(Cpu_thread_component *thread);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Cpu_session_component(Rpc_entrypoint *thread_ep,
|
||||
Pager_entrypoint *pager_ep,
|
||||
Allocator *md_alloc,
|
||||
Trace::Source_registry &trace_sources,
|
||||
const char *args, Affinity const &affinity);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Cpu_session_component();
|
||||
|
||||
/**
|
||||
* Register quota donation at allocator guard
|
||||
*/
|
||||
void upgrade_ram_quota(size_t ram_quota) { _md_alloc.upgrade(ram_quota); }
|
||||
|
||||
|
||||
/***************************
|
||||
** CPU session interface **
|
||||
***************************/
|
||||
|
||||
Thread_capability create_thread(Name const &, addr_t);
|
||||
Ram_dataspace_capability utcb(Thread_capability thread);
|
||||
void kill_thread(Thread_capability);
|
||||
int set_pager(Thread_capability, Pager_capability);
|
||||
int start(Thread_capability, addr_t, addr_t);
|
||||
void pause(Thread_capability thread_cap);
|
||||
void resume(Thread_capability thread_cap);
|
||||
void cancel_blocking(Thread_capability);
|
||||
int name(Thread_capability, char *, size_t);
|
||||
Thread_state state(Thread_capability);
|
||||
void state(Thread_capability, Thread_state const &);
|
||||
void exception_handler(Thread_capability, Signal_context_capability);
|
||||
Affinity::Space affinity_space() const;
|
||||
void affinity(Thread_capability, Affinity::Location);
|
||||
Dataspace_capability trace_control();
|
||||
unsigned trace_control_index(Thread_capability);
|
||||
Dataspace_capability trace_buffer(Thread_capability);
|
||||
Dataspace_capability trace_policy(Thread_capability);
|
||||
|
||||
|
||||
/*******************************
|
||||
** Linux-specific extensions **
|
||||
*******************************/
|
||||
|
||||
void thread_id(Thread_capability, int, int);
|
||||
Untyped_capability server_sd(Thread_capability);
|
||||
Untyped_capability client_sd(Thread_capability);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__CPU_SESSION_COMPONENT_H_ */
|
125
repos/base-linux/src/core/include/dataspace_component.h
Normal file
125
repos/base-linux/src/core/include/dataspace_component.h
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* \brief Core-internal dataspace representation on Linux
|
||||
* \author Norman Feske
|
||||
* \date 2006-05-19
|
||||
*
|
||||
* On Linux userland, we do not deal with physical memory. Instead,
|
||||
* we create a file for each dataspace that is to be mmapped.
|
||||
* Therefore, the allocator is not really used for allocating
|
||||
* memory but only as a container for quota.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-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 _CORE__INCLUDE__LINUX__DATASPACE_COMPONENT_H_
|
||||
#define _CORE__INCLUDE__LINUX__DATASPACE_COMPONENT_H_
|
||||
|
||||
#include <linux_dataspace/linux_dataspace.h>
|
||||
#include <util/string.h>
|
||||
#include <util/misc_math.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
/**
|
||||
* Deriving classes can own a dataspace to implement conditional behavior
|
||||
*/
|
||||
class Dataspace_owner { };
|
||||
|
||||
class Dataspace_component : public Rpc_object<Linux_dataspace>
|
||||
{
|
||||
private:
|
||||
|
||||
size_t _size; /* size of dataspace in bytes */
|
||||
addr_t _addr; /* meaningless on linux */
|
||||
Filename _fname; /* filename for mmap */
|
||||
int _fd; /* file descriptor */
|
||||
bool _writable; /* false if read-only */
|
||||
|
||||
/* Holds the dataspace owner if a distinction between owner and
|
||||
* others is necessary on the dataspace, otherwise it is 0 */
|
||||
Dataspace_owner * _owner;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Dataspace_component(size_t size, addr_t addr,
|
||||
bool /* write_combined */, bool writable,
|
||||
Dataspace_owner * owner)
|
||||
: _size(size), _addr(addr), _fd(-1), _writable(writable),
|
||||
_owner(owner) { }
|
||||
|
||||
/**
|
||||
* Default constructor returns invalid dataspace
|
||||
*/
|
||||
Dataspace_component()
|
||||
: _size(0), _addr(0), _fd(-1), _writable(false), _owner(0) { }
|
||||
|
||||
/**
|
||||
* This constructor is only provided for compatibility
|
||||
* reasons and should not be used.
|
||||
*/
|
||||
Dataspace_component(size_t size, addr_t core_local_addr,
|
||||
addr_t phys_addr, bool write_combined,
|
||||
bool writable, Dataspace_owner * _owner)
|
||||
:
|
||||
_size(size), _addr(phys_addr), _fd(-1), _owner(_owner)
|
||||
{
|
||||
PWRN("Should only be used for IOMEM and not within Linux.");
|
||||
_fname.buf[0] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Define corresponding filename of dataspace
|
||||
*
|
||||
* The file name is only relevant for ROM dataspaces that should
|
||||
* be executed via execve.
|
||||
*/
|
||||
void fname(const char *fname) { strncpy(_fname.buf, fname, sizeof(_fname.buf)); }
|
||||
|
||||
/**
|
||||
* Assign file descriptor to dataspace
|
||||
*
|
||||
* The file descriptor assigned to the dataspace will be enable
|
||||
* processes outside of core to mmap the dataspace.
|
||||
*/
|
||||
void fd(int fd) { _fd = fd; }
|
||||
|
||||
/**
|
||||
* Check if dataspace is owned by a specified object
|
||||
*/
|
||||
bool owner(Dataspace_owner * const o) const { return _owner == o; }
|
||||
|
||||
/*************************
|
||||
** Dataspace interface **
|
||||
*************************/
|
||||
|
||||
size_t size() { return _size; }
|
||||
addr_t phys_addr() { return _addr; }
|
||||
bool writable() { return _writable; }
|
||||
|
||||
|
||||
/****************************************
|
||||
** Linux-specific dataspace interface **
|
||||
****************************************/
|
||||
|
||||
Filename fname() { return _fname; }
|
||||
|
||||
Untyped_capability fd()
|
||||
{
|
||||
typedef Untyped_capability::Dst Dst;
|
||||
enum { DUMMY_LOCAL_NAME = 0 };
|
||||
return Untyped_capability(Dst(_fd), DUMMY_LOCAL_NAME);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__LINUX__DATASPACE_COMPONENT_H_ */
|
64
repos/base-linux/src/core/include/io_mem_session_component.h
Normal file
64
repos/base-linux/src/core/include/io_mem_session_component.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* \brief Core-specific instance of the IO_MEM session interface (Linux)
|
||||
* \author Christian Helmuth
|
||||
* \date 2007-09-14
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007-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 _CORE__INCLUDE__LINUX__IO_MEM_SESSION_COMPONENT_H_
|
||||
#define _CORE__INCLUDE__LINUX__IO_MEM_SESSION_COMPONENT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/allocator.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <io_mem_session/io_mem_session.h>
|
||||
|
||||
/* core includes */
|
||||
#include <dataspace_component.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Io_mem_session_component : public Rpc_object<Io_mem_session>
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param io_mem_alloc MMIO region allocator
|
||||
* \param ram_alloc RAM allocator that will be checked for
|
||||
* region collisions
|
||||
* \param ds_ep entry point to manage the dataspace
|
||||
* corresponding the io_mem session
|
||||
* \param args session construction arguments, in
|
||||
* particular MMIO region base, size and
|
||||
* caching demands
|
||||
*/
|
||||
Io_mem_session_component(Range_allocator *io_mem_alloc,
|
||||
Range_allocator *ram_alloc,
|
||||
Rpc_entrypoint *ds_ep,
|
||||
const char *args);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Io_mem_session_component() { }
|
||||
|
||||
|
||||
/*****************************
|
||||
** Io-mem session interface **
|
||||
*****************************/
|
||||
|
||||
Io_mem_dataspace_capability dataspace() {
|
||||
return Io_mem_dataspace_capability(); }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__LINUX__IO_MEM_SESSION_COMPONENT_H_ */
|
60
repos/base-linux/src/core/include/irq_session_component.h
Normal file
60
repos/base-linux/src/core/include/irq_session_component.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* \brief Core-specific instance of the IRQ session interface for Linux
|
||||
* \author Christian Helmuth
|
||||
* \date 2007-09-13
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007-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 _CORE__INCLUDE__LINUX__IRQ_SESSION_COMPONENT_H_
|
||||
#define _CORE__INCLUDE__LINUX__IRQ_SESSION_COMPONENT_H_
|
||||
|
||||
#include <util/list.h>
|
||||
#include <base/lock.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <irq_session/irq_session.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Irq_session_component : public List<Irq_session_component>::Element
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param cap_session capability session to use
|
||||
* \param irq_alloc platform-dependent IRQ allocator
|
||||
* \param args session construction arguments
|
||||
*/
|
||||
Irq_session_component(Cap_session *cap_session,
|
||||
Range_allocator *irq_alloc,
|
||||
const char *args) { }
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Irq_session_component() { }
|
||||
|
||||
/**
|
||||
* Return capability to this session
|
||||
*
|
||||
* Capability is always invalid under Linux.
|
||||
*/
|
||||
Session_capability cap() const { return Session_capability(); }
|
||||
|
||||
|
||||
/***************************
|
||||
** Irq session interface **
|
||||
***************************/
|
||||
|
||||
void wait_for_irq() { }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__LINUX__IRQ_SESSION_COMPONENT_H_ */
|
69
repos/base-linux/src/core/include/pd_session_component.h
Normal file
69
repos/base-linux/src/core/include/pd_session_component.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* \brief Linux-specific PD session
|
||||
* \author Norman Feske
|
||||
* \date 2012-08-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 _CORE__INCLUDE__PD_SESSION_COMPONENT_H_
|
||||
#define _CORE__INCLUDE__PD_SESSION_COMPONENT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/rpc_server.h>
|
||||
#include <linux_pd_session/linux_pd_session.h>
|
||||
|
||||
/* core includes */
|
||||
#include <platform_pd.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Pd_session_component : public Rpc_object<Linux_pd_session, Pd_session_component>
|
||||
{
|
||||
private:
|
||||
|
||||
enum { LABEL_MAX_LEN = 1024 };
|
||||
enum { ROOT_PATH_MAX_LEN = 512 };
|
||||
|
||||
unsigned long _pid;
|
||||
char _label[LABEL_MAX_LEN];
|
||||
char _root[ROOT_PATH_MAX_LEN];
|
||||
unsigned _uid;
|
||||
unsigned _gid;
|
||||
Parent_capability _parent;
|
||||
Rpc_entrypoint *_ds_ep;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param ds_ep entrypoint where the dataspaces are managed
|
||||
*/
|
||||
Pd_session_component(Rpc_entrypoint *ds_ep, const char *args);
|
||||
|
||||
~Pd_session_component();
|
||||
|
||||
|
||||
/**************************
|
||||
** PD session interface **
|
||||
**************************/
|
||||
|
||||
int bind_thread(Thread_capability);
|
||||
int assign_parent(Parent_capability parent);
|
||||
|
||||
|
||||
/******************************
|
||||
** Linux-specific extension **
|
||||
******************************/
|
||||
|
||||
void start(Capability<Dataspace> binary);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ */
|
100
repos/base-linux/src/core/include/platform.h
Normal file
100
repos/base-linux/src/core/include/platform.h
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* \brief Linux platform
|
||||
* \author Christian Helmuth
|
||||
* \author Norman Feske
|
||||
* \date 2007-09-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007-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 _CORE__INCLUDE__LINUX__PLATFORM_H_
|
||||
#define _CORE__INCLUDE__LINUX__PLATFORM_H_
|
||||
|
||||
#include <base/sync_allocator.h>
|
||||
#include <base/allocator_avl.h>
|
||||
#include <base/lock_guard.h>
|
||||
|
||||
#include <platform_generic.h>
|
||||
#include <platform_pd.h>
|
||||
#include <platform_thread.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
class Platform : public Platform_generic
|
||||
{
|
||||
private:
|
||||
|
||||
/**
|
||||
* Allocator for core-internal meta data
|
||||
*/
|
||||
Synchronized_range_allocator<Allocator_avl> _core_mem_alloc;
|
||||
|
||||
/**
|
||||
* Allocator for pseudo physical memory
|
||||
*/
|
||||
struct Pseudo_ram_allocator : Range_allocator
|
||||
{
|
||||
bool alloc(size_t size, void **out_addr)
|
||||
{
|
||||
*out_addr = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
Alloc_return alloc_aligned(size_t, void **out_addr, int)
|
||||
{
|
||||
*out_addr = 0;
|
||||
return Alloc_return::OK;
|
||||
}
|
||||
|
||||
Alloc_return alloc_addr(size_t, addr_t)
|
||||
{
|
||||
return Alloc_return::OK;;
|
||||
}
|
||||
|
||||
int add_range(addr_t, size_t) { return 0; }
|
||||
int remove_range(addr_t, size_t) { return 0; }
|
||||
void free(void *) { }
|
||||
void free(void *, size_t) { }
|
||||
size_t avail() { return ~0; }
|
||||
bool valid_addr(addr_t) { return true; }
|
||||
size_t overhead(size_t) { return 0; }
|
||||
|
||||
bool need_size_for_free() const override { return true; }
|
||||
};
|
||||
|
||||
Pseudo_ram_allocator _ram_alloc;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Platform();
|
||||
|
||||
|
||||
/********************************
|
||||
** Generic platform interface **
|
||||
********************************/
|
||||
|
||||
Range_allocator *core_mem_alloc() { return &_core_mem_alloc; }
|
||||
Range_allocator *ram_alloc() { return &_ram_alloc; }
|
||||
Range_allocator *io_mem_alloc() { return 0; }
|
||||
Range_allocator *io_port_alloc() { return 0; }
|
||||
Range_allocator *irq_alloc() { return 0; }
|
||||
Range_allocator *region_alloc() { return 0; }
|
||||
addr_t vm_start() const { return 0; }
|
||||
size_t vm_size() const { return 0; }
|
||||
Rom_fs *rom_fs() { return 0; }
|
||||
|
||||
void wait_for_exit();
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__PLATFORM_H_ */
|
25
repos/base-linux/src/core/include/platform_pd.h
Normal file
25
repos/base-linux/src/core/include/platform_pd.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* \brief Linux protection domain facility
|
||||
* \author Norman Feske
|
||||
* \date 2006-06-13
|
||||
*
|
||||
* Pretty dumb.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-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 _CORE__INCLUDE__LINUX__PLATFORM_PD_H_
|
||||
#define _CORE__INCLUDE__LINUX__PLATFORM_PD_H_
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Platform_pd
|
||||
{ };
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__LINUX__PLATFORM_PD_H_ */
|
159
repos/base-linux/src/core/include/platform_thread.h
Normal file
159
repos/base-linux/src/core/include/platform_thread.h
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* \brief Linux thread facility
|
||||
* \author Norman Feske
|
||||
* \date 2006-06-13
|
||||
*
|
||||
* Pretty dumb.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-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 _CORE__INCLUDE__LINUX__PLATFORM_THREAD_H_
|
||||
#define _CORE__INCLUDE__LINUX__PLATFORM_THREAD_H_
|
||||
|
||||
#include <base/pager.h>
|
||||
#include <base/thread_state.h>
|
||||
#include <cpu_session/cpu_session.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Platform_thread;
|
||||
|
||||
/*
|
||||
* We hold all Platform_thread objects in a list in order to be able to
|
||||
* reflect SIGCHLD as exception signals. When a SIGCHILD occurs, we
|
||||
* determine the PID of the terminated child process via 'wait4'. We use
|
||||
* the list to find the 'Platform_thread' matching the TID, wherei, in
|
||||
* turn, we find the exception handler's 'Signal_context_capability'.
|
||||
*/
|
||||
|
||||
class Platform_thread : public List<Platform_thread>::Element
|
||||
{
|
||||
private:
|
||||
|
||||
struct Registry
|
||||
{
|
||||
Lock _lock;
|
||||
List<Platform_thread> _list;
|
||||
|
||||
void insert(Platform_thread *thread);
|
||||
void remove(Platform_thread *thread);
|
||||
|
||||
/**
|
||||
* Trigger exception handler for 'Platform_thread' with matching PID.
|
||||
*/
|
||||
void submit_exception(unsigned long pid);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return singleton instance of 'Platform_thread::Registry'
|
||||
*/
|
||||
static Registry *_registry();
|
||||
|
||||
unsigned long _tid;
|
||||
unsigned long _pid;
|
||||
char _name[32];
|
||||
|
||||
/**
|
||||
* Unix-domain socket pair bound to the thread
|
||||
*/
|
||||
Native_connection_state _ncs;
|
||||
|
||||
/*
|
||||
* Dummy pager object that is solely used for storing the
|
||||
* 'Signal_context_capability' for the thread's exception handler.
|
||||
*/
|
||||
Pager_object _pager;
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Platform_thread(const char *name, unsigned priority, addr_t);
|
||||
|
||||
~Platform_thread();
|
||||
|
||||
/**
|
||||
* Cancel currently blocking operation
|
||||
*/
|
||||
void cancel_blocking();
|
||||
|
||||
/**
|
||||
* Pause this thread
|
||||
*/
|
||||
void pause();
|
||||
|
||||
/**
|
||||
* Resume this thread
|
||||
*/
|
||||
void resume();
|
||||
|
||||
/**
|
||||
* Dummy implementation of platform-thread interface
|
||||
*/
|
||||
Pager_object *pager() { return &_pager; }
|
||||
void pager(Pager_object *) { }
|
||||
int start(void *ip, void *sp) { return 0; }
|
||||
|
||||
Thread_state state()
|
||||
{
|
||||
PDBG("Not implemented");
|
||||
throw Cpu_session::State_access_failed();
|
||||
}
|
||||
|
||||
void state(Thread_state)
|
||||
{
|
||||
PDBG("Not implemented");
|
||||
throw Cpu_session::State_access_failed();
|
||||
}
|
||||
|
||||
const char *name() { return _name; }
|
||||
|
||||
/**
|
||||
* Set the executing CPU for this thread
|
||||
*
|
||||
* SMP is currently not directly supported on Genode/Linux
|
||||
* (but indirectly by the Linux kernel).
|
||||
*/
|
||||
void affinity(Affinity::Location) { }
|
||||
|
||||
/**
|
||||
* Request the affinity of this thread
|
||||
*/
|
||||
Affinity::Location affinity() { return Affinity::Location(); }
|
||||
|
||||
/**
|
||||
* Register process ID and thread ID of thread
|
||||
*/
|
||||
void thread_id(int pid, int tid) { _pid = pid, _tid = tid; }
|
||||
|
||||
/**
|
||||
* Return client-side socket descriptor
|
||||
*
|
||||
* For more information, please refer to the comments in
|
||||
* 'linux_cpu_session/linux_cpu_session.h'.
|
||||
*/
|
||||
int client_sd();
|
||||
|
||||
/**
|
||||
* Return server-side socket descriptor
|
||||
*/
|
||||
int server_sd();
|
||||
|
||||
/**
|
||||
* Notify Genode::Signal handler about sigchld
|
||||
*/
|
||||
static void submit_exception(int pid)
|
||||
{
|
||||
_registry()->submit_exception(pid);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__LINUX__PLATFORM_THREAD_H_ */
|
44
repos/base-linux/src/core/include/resource_path.h
Normal file
44
repos/base-linux/src/core/include/resource_path.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* \brief Genode resource path
|
||||
* \author Norman Feske
|
||||
* \date 2012-08-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 _CORE__INCLUDE__RPATH_H_
|
||||
#define _CORE__INCLUDE__RPATH_H_
|
||||
|
||||
/* Linux syscall bindings */
|
||||
#include <linux_syscalls.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/snprintf.h>
|
||||
|
||||
/**
|
||||
* Return resource path for Genode
|
||||
*
|
||||
* Genode creates files for dataspaces and endpoints under in this directory.
|
||||
*/
|
||||
static inline char const *resource_path()
|
||||
{
|
||||
struct Resource_path
|
||||
{
|
||||
char string[32];
|
||||
|
||||
Resource_path()
|
||||
{
|
||||
Genode::snprintf(string, sizeof(string), "/tmp/genode-%d", lx_getuid());
|
||||
}
|
||||
};
|
||||
|
||||
static Resource_path path;
|
||||
return path.string;
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__RPATH_H_ */
|
76
repos/base-linux/src/core/include/rm_session_component.h
Normal file
76
repos/base-linux/src/core/include/rm_session_component.h
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* \brief Core-specific instance of the RM session interface
|
||||
* \author Christian Helmuth
|
||||
* \date 2006-07-17
|
||||
*
|
||||
* Dummies for Linux platform
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-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 _CORE__INCLUDE__LINUX__RM_SESSION_COMPONENT_H_
|
||||
#define _CORE__INCLUDE__LINUX__RM_SESSION_COMPONENT_H_
|
||||
|
||||
/* Genode */
|
||||
#include <base/pager.h>
|
||||
#include <base/allocator.h>
|
||||
#include <base/rpc_server.h>
|
||||
#include <rm_session/rm_session.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
struct Rm_client;
|
||||
|
||||
class Rm_session_component : public Rpc_object<Rm_session>
|
||||
{
|
||||
private:
|
||||
|
||||
class Rm_dataspace_component {
|
||||
|
||||
public:
|
||||
|
||||
void sub_rm_session(Native_capability _cap) { }
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
Rm_session_component(Rpc_entrypoint *ds_ep,
|
||||
Rpc_entrypoint *thread_ep,
|
||||
Rpc_entrypoint *session_ep,
|
||||
Allocator *md_alloc,
|
||||
size_t ram_quota,
|
||||
Pager_entrypoint *pager_ep,
|
||||
addr_t vm_start,
|
||||
size_t vm_size) { }
|
||||
|
||||
void upgrade_ram_quota(size_t ram_quota) { }
|
||||
|
||||
Local_addr attach(Dataspace_capability, size_t, off_t, bool, Local_addr, bool) {
|
||||
return (addr_t)0; }
|
||||
|
||||
void detach(Local_addr) { }
|
||||
|
||||
Pager_capability add_client(Thread_capability) {
|
||||
return Pager_capability(); }
|
||||
|
||||
void remove_client(Pager_capability) { }
|
||||
|
||||
void fault_handler(Signal_context_capability) { }
|
||||
|
||||
State state() { return State(); }
|
||||
|
||||
Dataspace_capability dataspace() { return Dataspace_capability(); }
|
||||
|
||||
Rm_dataspace_component *dataspace_component() { return 0; }
|
||||
};
|
||||
|
||||
struct Rm_member { Rm_session_component *member_rm_session() { return 0; } };
|
||||
struct Rm_client : Pager_object, Rm_member { };
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__LINUX__RM_SESSION_COMPONENT_H_ */
|
107
repos/base-linux/src/core/include/server_socket_pair.h
Normal file
107
repos/base-linux/src/core/include/server_socket_pair.h
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* \brief Support for communication over Unix domain sockets
|
||||
* \author Norman Feske
|
||||
* \date 2012-08-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011-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 _CORE__INCLUDE__SERVER_SOCKET_PAIR_H_
|
||||
#define _CORE__INCLUDE__SERVER_SOCKET_PAIR_H_
|
||||
|
||||
/* Linux syscall bindings */
|
||||
#include <core_linux_syscalls.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
/* include from 'src/base/ipc' */
|
||||
#include <socket_descriptor_registry.h>
|
||||
|
||||
/* core-local includes */
|
||||
#include <resource_path.h>
|
||||
|
||||
|
||||
/**
|
||||
* Utility: Create socket address for server entrypoint at thread ID
|
||||
*/
|
||||
struct Uds_addr : sockaddr_un
|
||||
{
|
||||
Uds_addr(long thread_id)
|
||||
{
|
||||
sun_family = AF_UNIX;
|
||||
Genode::snprintf(sun_path, sizeof(sun_path), "%s/ep-%ld",
|
||||
resource_path(), thread_id);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Utility: Create named socket pair for given unique ID
|
||||
*/
|
||||
static inline Genode::Native_connection_state create_server_socket_pair(long id)
|
||||
{
|
||||
Genode::Native_connection_state ncs;
|
||||
|
||||
/*
|
||||
* Main thread uses 'Ipc_server' for 'sleep_forever()' only. No need for
|
||||
* binding.
|
||||
*/
|
||||
if (id == -1)
|
||||
return ncs;
|
||||
|
||||
Uds_addr addr(id);
|
||||
|
||||
/*
|
||||
* Create server-side socket
|
||||
*/
|
||||
ncs.server_sd = lx_socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
|
||||
if (ncs.server_sd < 0) {
|
||||
PRAW("Error: Could not create server-side socket (ret=%d)", ncs.server_sd);
|
||||
class Server_socket_failed { };
|
||||
throw Server_socket_failed();
|
||||
}
|
||||
|
||||
/* make sure bind succeeds */
|
||||
lx_unlink(addr.sun_path);
|
||||
|
||||
int const bind_ret = lx_bind(ncs.server_sd, (sockaddr *)&addr, sizeof(addr));
|
||||
if (bind_ret < 0) {
|
||||
PRAW("Error: Could not bind server socket (ret=%d)", bind_ret);
|
||||
class Bind_failed { };
|
||||
throw Bind_failed();
|
||||
}
|
||||
|
||||
/*
|
||||
* Create client-side socket
|
||||
*/
|
||||
ncs.client_sd = lx_socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
|
||||
if (ncs.client_sd < 0) {
|
||||
PRAW("Error: Could not create client-side socket (ret=%d)", ncs.client_sd);
|
||||
class Client_socket_failed { };
|
||||
throw Client_socket_failed();
|
||||
}
|
||||
|
||||
int const conn_ret = lx_connect(ncs.client_sd, (sockaddr *)&addr, sizeof(addr));
|
||||
if (conn_ret < 0) {
|
||||
PRAW("Error: Could not connect client-side socket (ret=%d)", conn_ret);
|
||||
class Connect_failed { };
|
||||
throw Connect_failed();
|
||||
}
|
||||
|
||||
ncs.client_sd = Genode::ep_sd_registry()->try_associate(ncs.client_sd, id);
|
||||
|
||||
/*
|
||||
* Wipe Unix domain socket from the file system. It will live as long as
|
||||
* there exist references to it in the form of file descriptors.
|
||||
*/
|
||||
lx_unlink(addr.sun_path);
|
||||
|
||||
return ncs;
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__SERVER_SOCKET_PAIR_H_ */
|
22
repos/base-linux/src/core/include/util.h
Normal file
22
repos/base-linux/src/core/include/util.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* \brief Core-internal utilities
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2014-03-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _CORE__INCLUDE__UTIL_H_
|
||||
#define _CORE__INCLUDE__UTIL_H_
|
||||
|
||||
namespace Genode {
|
||||
constexpr size_t get_page_size_log2() { return 12; }
|
||||
constexpr size_t get_page_size() { return 1 << get_page_size_log2(); }
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__UTIL_H_ */
|
27
repos/base-linux/src/core/io_mem_session_component.cc
Normal file
27
repos/base-linux/src/core/io_mem_session_component.cc
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* \brief Linux-specific IO_MEM service
|
||||
* \author Christian Helmuth
|
||||
* \date 2006-09-01
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#include <base/printf.h>
|
||||
|
||||
#include <io_mem_session_component.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
Io_mem_session_component::Io_mem_session_component(Range_allocator *io_mem_alloc,
|
||||
Range_allocator *ram_alloc,
|
||||
Rpc_entrypoint *ds_ep,
|
||||
const char *args)
|
||||
{
|
||||
PWRN("no io_mem support on Linux (args=\"%s\")", args);
|
||||
}
|
455
repos/base-linux/src/core/pd_session_component.cc
Normal file
455
repos/base-linux/src/core/pd_session_component.cc
Normal file
@ -0,0 +1,455 @@
|
||||
/*
|
||||
* \brief Core implementation of the PD session interface
|
||||
* \author Norman Feske
|
||||
* \date 2012-08-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/arg_string.h>
|
||||
#include <base/printf.h>
|
||||
#include <base/snprintf.h>
|
||||
|
||||
/* core-local includes */
|
||||
#include <pd_session_component.h>
|
||||
#include <dataspace_component.h>
|
||||
|
||||
/* Linux includes */
|
||||
#include <core_linux_syscalls.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/***********************************
|
||||
** Utilities for chroot handling **
|
||||
***********************************/
|
||||
|
||||
enum { MAX_PATH_LEN = 256 };
|
||||
|
||||
|
||||
/**
|
||||
* Return true if specified path is an existing directory
|
||||
*/
|
||||
static bool is_directory(char const *path)
|
||||
{
|
||||
struct stat64 s;
|
||||
if (lx_stat(path, &s) != 0)
|
||||
return false;
|
||||
|
||||
if (!(s.st_mode & S_IFDIR))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool is_path_delimiter(char c) { return c == '/'; }
|
||||
|
||||
|
||||
static bool has_trailing_path_delimiter(char const *path)
|
||||
{
|
||||
char last_char = 0;
|
||||
for (; *path; path++)
|
||||
last_char = *path;
|
||||
|
||||
return is_path_delimiter(last_char);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return number of path elements of given path
|
||||
*/
|
||||
static Genode::size_t num_path_elements(char const *path)
|
||||
{
|
||||
Genode::size_t count = 0;
|
||||
|
||||
/*
|
||||
* If path starts with non-slash, the first characters belongs to a path
|
||||
* element.
|
||||
*/
|
||||
if (*path && !is_path_delimiter(*path))
|
||||
count = 1;
|
||||
|
||||
/* count slashes */
|
||||
for (; *path; path++)
|
||||
if (is_path_delimiter(*path))
|
||||
count++;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
static bool leading_path_elements(char const *path, unsigned num,
|
||||
char *dst, Genode::size_t dst_len)
|
||||
{
|
||||
/* counter of path delimiters */
|
||||
unsigned count = 0;
|
||||
unsigned i = 0;
|
||||
|
||||
if (is_path_delimiter(path[0]))
|
||||
num++;
|
||||
|
||||
for (; path[i] && (count < num) && (i < dst_len); i++)
|
||||
{
|
||||
if (is_path_delimiter(path[i]))
|
||||
count++;
|
||||
|
||||
if (count == num)
|
||||
break;
|
||||
|
||||
dst[i] = path[i];
|
||||
}
|
||||
|
||||
if (i + 1 < dst_len) {
|
||||
dst[i] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* string is cut, append null termination anyway */
|
||||
dst[dst_len - 1] = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static void mirror_path_to_chroot(char const *chroot_path, char const *path)
|
||||
{
|
||||
char target_path[MAX_PATH_LEN];
|
||||
Genode::snprintf(target_path, sizeof(target_path), "%s%s",
|
||||
chroot_path, path);
|
||||
|
||||
/*
|
||||
* Create directory hierarchy pointing to the target path except for the
|
||||
* last element. The last element will be bind-mounted to refer to the
|
||||
* original 'path'.
|
||||
*/
|
||||
for (unsigned i = 1; i <= num_path_elements(target_path); i++)
|
||||
{
|
||||
char buf[MAX_PATH_LEN];
|
||||
leading_path_elements(target_path, i, buf, sizeof(buf));
|
||||
|
||||
/* skip existing directories */
|
||||
if (is_directory(buf))
|
||||
continue;
|
||||
|
||||
/* create new directory */
|
||||
lx_mkdir(buf, 0777);
|
||||
}
|
||||
|
||||
lx_umount(target_path);
|
||||
|
||||
int ret = 0;
|
||||
if ((ret = lx_bindmount(path, target_path)))
|
||||
PERR("bind mount failed (errno=%d)", ret);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Setup content of chroot environment as prerequisite to 'execve' new
|
||||
* processes within the environment. I.e., the current working directory
|
||||
* containing the ROM modules must be mounted at the same location within the
|
||||
* chroot environment.
|
||||
*/
|
||||
static bool setup_chroot_environment(char const *chroot_path)
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
static char cwd_path[MAX_PATH_LEN];
|
||||
|
||||
lx_getcwd(cwd_path, sizeof(cwd_path));
|
||||
|
||||
/*
|
||||
* Validate chroot path
|
||||
*/
|
||||
if (!is_directory(chroot_path)) {
|
||||
PERR("chroot path does not point to valid directory");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (has_trailing_path_delimiter(chroot_path)) {
|
||||
PERR("chroot path has trailing slash");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hardlink directories needed for running Genode within the chroot
|
||||
* environment.
|
||||
*/
|
||||
mirror_path_to_chroot(chroot_path, cwd_path);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/***************
|
||||
** Utilities **
|
||||
***************/
|
||||
|
||||
/**
|
||||
* Argument frame for passing 'execve' paremeters through 'clone'
|
||||
*/
|
||||
struct Execve_args
|
||||
{
|
||||
char const *filename;
|
||||
char const *root;
|
||||
char * const *argv;
|
||||
char * const *envp;
|
||||
unsigned int const uid;
|
||||
unsigned int const gid;
|
||||
int const parent_sd;
|
||||
|
||||
Execve_args(char const *filename,
|
||||
char const *root,
|
||||
char * const *argv,
|
||||
char * const *envp,
|
||||
unsigned int uid,
|
||||
unsigned int gid,
|
||||
int parent_sd)
|
||||
:
|
||||
filename(filename), root(root), argv(argv), envp(envp),
|
||||
uid(uid), gid(gid), parent_sd(parent_sd)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Startup code of the new child process
|
||||
*/
|
||||
static int _exec_child(Execve_args *arg)
|
||||
{
|
||||
lx_dup2(arg->parent_sd, PARENT_SOCKET_HANDLE);
|
||||
|
||||
/* change to chroot environment */
|
||||
if (arg->root && arg->root[0]) {
|
||||
char cwd[1024];
|
||||
|
||||
PDBG("arg->root='%s'", arg->root);
|
||||
|
||||
if (setup_chroot_environment(arg->root) == false) {
|
||||
PERR("Could not setup chroot environment");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!lx_getcwd(cwd, sizeof(cwd))) {
|
||||
PERR("Failed to getcwd");
|
||||
return -1;
|
||||
}
|
||||
|
||||
PLOG("changing root of %s (PID %d) to %s",
|
||||
arg->filename, lx_getpid(), arg->root);
|
||||
|
||||
int ret = lx_chroot(arg->root);
|
||||
if (ret < 0) {
|
||||
PERR("Syscall chroot failed (errno %d)", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = lx_chdir(cwd);
|
||||
if (ret < 0) {
|
||||
PERR("chdir to new chroot failed");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set UID and GID
|
||||
*
|
||||
* We must set the GID prior setting the UID because setting the GID won't
|
||||
* be possible anymore once we set the UID to non-root.
|
||||
*/
|
||||
if (arg->gid) {
|
||||
int const ret = lx_setgid(arg->gid);
|
||||
if (ret)
|
||||
PWRN("Could not set PID %d (%s) to GID %u (error %d)",
|
||||
lx_getpid(), arg->filename, arg->gid, ret);
|
||||
}
|
||||
if (arg->uid) {
|
||||
int const ret = lx_setuid(arg->uid);
|
||||
if (ret)
|
||||
PWRN("Could not set PID %d (%s) to UID %u (error %d)",
|
||||
lx_getpid(), arg->filename, arg->uid, ret);
|
||||
}
|
||||
|
||||
return lx_execve(arg->filename, arg->argv, arg->envp);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* List of Unix environment variables, initialized by the startup code
|
||||
*/
|
||||
extern char **lx_environ;
|
||||
|
||||
|
||||
/**
|
||||
* Read environment variable as string
|
||||
*
|
||||
* If no matching key exists, return an empty string.
|
||||
*/
|
||||
static const char *get_env(const char *key)
|
||||
{
|
||||
Genode::size_t key_len = Genode::strlen(key);
|
||||
for (char **curr = lx_environ; curr && *curr; curr++)
|
||||
if ((Genode::strcmp(*curr, key, key_len) == 0) && (*curr)[key_len] == '=')
|
||||
return (const char *)(*curr + key_len + 1);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
/**************************
|
||||
** PD session interface **
|
||||
**************************/
|
||||
|
||||
Pd_session_component::Pd_session_component(Rpc_entrypoint *ep, const char *args)
|
||||
:
|
||||
_pid(0), _uid(0), _gid(0), _ds_ep(ep)
|
||||
{
|
||||
Arg_string::find_arg(args, "label").string(_label, sizeof(_label),
|
||||
"<unlabeled>");
|
||||
|
||||
/*
|
||||
* Read Linux-specific session arguments
|
||||
*/
|
||||
Arg_string::find_arg(args, "root").string(_root, sizeof(_root), "");
|
||||
|
||||
_uid = Arg_string::find_arg(args, "uid").ulong_value(0);
|
||||
_gid = Arg_string::find_arg(args, "gid").ulong_value(0);
|
||||
|
||||
bool const is_chroot = (Genode::strcmp(_root, "") != 0);
|
||||
|
||||
/*
|
||||
* If a UID is specified but no GID, we use the UID as GID. This way, a
|
||||
* configuration error where the UID is defined but the GID is left
|
||||
* undefined won't result in the execution of the new process with the
|
||||
* root user's GID.
|
||||
*/
|
||||
if (_gid == 0)
|
||||
_gid = _uid;
|
||||
|
||||
/*
|
||||
* Print Linux-specific session arguments if specified
|
||||
*
|
||||
* This output used for the automated 'lx_pd_args' test.
|
||||
*/
|
||||
if (is_chroot || _uid || _gid)
|
||||
printf("PD session for '%s'\n", _label);
|
||||
|
||||
if (is_chroot) printf(" root: %s\n", _root);
|
||||
if (_uid) printf(" uid: %u\n", _uid);
|
||||
if (_gid) printf(" gid: %u\n", _gid);
|
||||
}
|
||||
|
||||
|
||||
Pd_session_component::~Pd_session_component()
|
||||
{
|
||||
if (_pid)
|
||||
lx_kill(_pid, 9);
|
||||
}
|
||||
|
||||
|
||||
int Pd_session_component::bind_thread(Thread_capability) { return -1; }
|
||||
|
||||
|
||||
int Pd_session_component::assign_parent(Parent_capability parent)
|
||||
{
|
||||
_parent = parent;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Pd_session_component::start(Capability<Dataspace> binary)
|
||||
{
|
||||
const char *tmp_filename = "temporary_executable_elf_dataspace_file_for_execve";
|
||||
|
||||
/* lookup binary dataspace */
|
||||
Object_pool<Dataspace_component>::Guard ds(_ds_ep->lookup_and_lock(binary));
|
||||
|
||||
if (!ds) {
|
||||
PERR("could not lookup binary, aborted PD startup");
|
||||
return; /* XXX reflect error to client */
|
||||
}
|
||||
|
||||
const char *filename = ds->fname().buf;
|
||||
|
||||
/*
|
||||
* In order to be executable via 'execve', a program must be represented as
|
||||
* a file on the Linux file system. However, this is not the case for a
|
||||
* plain RAM dataspace that contains an ELF image. In this case, we copy
|
||||
* the dataspace content into a temporary file whose path is passed to
|
||||
* 'execve()'.
|
||||
*/
|
||||
if (strcmp(filename, "") == 0) {
|
||||
|
||||
filename = tmp_filename;
|
||||
|
||||
int tmp_binary_fd = lx_open(filename, O_CREAT | O_EXCL | O_WRONLY, S_IRWXU);
|
||||
if (tmp_binary_fd < 0) {
|
||||
PERR("Could not create file '%s'", filename);
|
||||
return; /* XXX reflect error to client */
|
||||
}
|
||||
|
||||
char buf[4096];
|
||||
int num_bytes = 0;
|
||||
while ((num_bytes = lx_read(ds->fd().dst().socket, buf, sizeof(buf))) != 0)
|
||||
lx_write(tmp_binary_fd, buf, num_bytes);
|
||||
|
||||
lx_close(tmp_binary_fd);
|
||||
}
|
||||
|
||||
/* pass parent capability as environment variable to the child */
|
||||
enum { ENV_STR_LEN = 256 };
|
||||
static char envbuf[5][ENV_STR_LEN];
|
||||
Genode::snprintf(envbuf[1], ENV_STR_LEN, "parent_local_name=%lu",
|
||||
_parent.local_name());
|
||||
Genode::snprintf(envbuf[2], ENV_STR_LEN, "DISPLAY=%s",
|
||||
get_env("DISPLAY"));
|
||||
Genode::snprintf(envbuf[3], ENV_STR_LEN, "HOME=%s",
|
||||
get_env("HOME"));
|
||||
Genode::snprintf(envbuf[4], ENV_STR_LEN, "LD_LIBRARY_PATH=%s",
|
||||
get_env("LD_LIBRARY_PATH"));
|
||||
|
||||
char *env[] = { &envbuf[0][0], &envbuf[1][0], &envbuf[2][0],
|
||||
&envbuf[3][0], &envbuf[4][0], 0 };
|
||||
|
||||
/* prefix name of Linux program (helps killing some zombies) */
|
||||
char const *prefix = "[Genode] ";
|
||||
char pname_buf[sizeof(_label) + sizeof(prefix)];
|
||||
snprintf(pname_buf, sizeof(pname_buf), "%s%s", prefix, _label);
|
||||
char *argv_buf[2];
|
||||
argv_buf[0] = pname_buf;
|
||||
argv_buf[1] = 0;
|
||||
|
||||
/*
|
||||
* We cannot create the new process via 'fork()' because all our used
|
||||
* memory including stack memory is backed by dataspaces, which had been
|
||||
* mapped with the 'MAP_SHARED' flag. Therefore, after being created, the
|
||||
* new process starts using the stack with the same physical memory pages
|
||||
* as used by parent process. This would ultimately lead to stack
|
||||
* corruption. To prevent both processes from concurrently accessing the
|
||||
* same stack, we pause the execution of the parent until the child calls
|
||||
* 'execve'. From then on, the child has its private memory layout. The
|
||||
* desired behaviour is normally provided by 'vfork' but we use the more
|
||||
* modern 'clone' call for this purpose.
|
||||
*/
|
||||
enum { STACK_SIZE = 4096 };
|
||||
static char stack[STACK_SIZE]; /* initial stack used by the child until
|
||||
calling 'execve' */
|
||||
|
||||
/*
|
||||
* Argument frame as passed to 'clone'. Because, we can only pass a single
|
||||
* pointer, all arguments are embedded within the 'execve_args' struct.
|
||||
*/
|
||||
Execve_args arg(filename, _root, argv_buf, env, _uid, _gid,
|
||||
_parent.dst().socket);
|
||||
|
||||
_pid = lx_create_process((int (*)(void *))_exec_child,
|
||||
stack + STACK_SIZE - sizeof(umword_t), &arg);
|
||||
|
||||
if (strcmp(filename, tmp_filename) == 0)
|
||||
lx_unlink(filename);
|
||||
};
|
247
repos/base-linux/src/core/platform.cc
Normal file
247
repos/base-linux/src/core/platform.cc
Normal file
@ -0,0 +1,247 @@
|
||||
/*
|
||||
* \brief Linux platform interface implementation
|
||||
* \author Norman Feske
|
||||
* \date 2006-06-13
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/lock.h>
|
||||
#include <linux_dataspace/client.h>
|
||||
|
||||
/* local includes */
|
||||
#include "platform.h"
|
||||
#include "core_env.h"
|
||||
#include "server_socket_pair.h"
|
||||
|
||||
/* Linux includes */
|
||||
#include <core_linux_syscalls.h>
|
||||
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
/**
|
||||
* Memory pool used for for core-local meta data
|
||||
*/
|
||||
static char _core_mem[80*1024*1024];
|
||||
|
||||
|
||||
/*
|
||||
* Basic semaphore implementation based on the 'pipe' syscall.
|
||||
*
|
||||
* This alternative implementation is needed to be able to wake up the
|
||||
* blocked main thread from a signal handler executed by the same thread.
|
||||
*/
|
||||
class Pipe_semaphore
|
||||
{
|
||||
private:
|
||||
|
||||
int _pipefd[2];
|
||||
|
||||
public:
|
||||
|
||||
Pipe_semaphore()
|
||||
{
|
||||
lx_pipe(_pipefd);
|
||||
}
|
||||
|
||||
void down()
|
||||
{
|
||||
char dummy;
|
||||
while(lx_read(_pipefd[0], &dummy, 1) != 1);
|
||||
}
|
||||
|
||||
void up()
|
||||
{
|
||||
char dummy;
|
||||
while (lx_write(_pipefd[1], &dummy, 1) != 1);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static Pipe_semaphore _wait_for_exit_sem; /* wakeup of '_wait_for_exit' */
|
||||
static bool _do_exit = false; /* exit condition */
|
||||
|
||||
|
||||
static void sigint_handler(int signum)
|
||||
{
|
||||
_do_exit = true;
|
||||
_wait_for_exit_sem.up();
|
||||
}
|
||||
|
||||
|
||||
static void sigchld_handler(int signnum)
|
||||
{
|
||||
_wait_for_exit_sem.up();
|
||||
}
|
||||
|
||||
|
||||
Platform::Platform()
|
||||
: _core_mem_alloc(0)
|
||||
{
|
||||
/* catch control-c */
|
||||
lx_sigaction(LX_SIGINT, sigint_handler);
|
||||
|
||||
/* catch SIGCHLD */
|
||||
lx_sigaction(LX_SIGCHLD, sigchld_handler);
|
||||
|
||||
/* create resource directory under /tmp */
|
||||
lx_mkdir(resource_path(), S_IRWXU);
|
||||
|
||||
_core_mem_alloc.add_range((addr_t)_core_mem, sizeof(_core_mem));
|
||||
|
||||
/*
|
||||
* Occupy the socket handle that will be used to propagate the parent
|
||||
* capability new processes. Otherwise, there may be the chance that the
|
||||
* parent capability as supplied by the process creator will be assigned to
|
||||
* this handle, which would result in a 'dup2' syscall taking
|
||||
* PARENT_SOCKET_HANDLE as both source and target descriptor.
|
||||
*/
|
||||
lx_dup2(0, PARENT_SOCKET_HANDLE);
|
||||
}
|
||||
|
||||
|
||||
void Platform::wait_for_exit()
|
||||
{
|
||||
for (;;) {
|
||||
|
||||
/*
|
||||
* Block until a signal occurs.
|
||||
*/
|
||||
_wait_for_exit_sem.down();
|
||||
|
||||
/*
|
||||
* Each time, the '_wait_for_exit_sem' gets unlocked, we could have
|
||||
* received either a SIGINT or SIGCHLD. If a SIGINT was received, the
|
||||
* '_exit' condition will be set.
|
||||
*/
|
||||
if (_do_exit)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Reflect SIGCHLD as exception signal to the signal context of the CPU
|
||||
* session of the process. Because multiple children could have been
|
||||
* terminated, we iterate until 'pollpid' (wrapper around 'wait4')
|
||||
* returns -1.
|
||||
*/
|
||||
for (;;) {
|
||||
int const pid = lx_pollpid();
|
||||
|
||||
if (pid <= 0)
|
||||
break;
|
||||
|
||||
Platform_thread::submit_exception(pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Core_parent::exit(int exit_value)
|
||||
{
|
||||
lx_exit_group(exit_value);
|
||||
}
|
||||
|
||||
|
||||
/*****************************
|
||||
** Support for IPC library **
|
||||
*****************************/
|
||||
|
||||
namespace Genode {
|
||||
|
||||
Native_connection_state server_socket_pair()
|
||||
{
|
||||
return create_server_socket_pair(Thread_base::myself()->tid().tid);
|
||||
}
|
||||
|
||||
void destroy_server_socket_pair(Native_connection_state const &ncs)
|
||||
{
|
||||
/*
|
||||
* As entrypoints in core are never destructed, this function is only
|
||||
* called on IPC-client destruction. In this case, it's a no-op in core
|
||||
* as well as in Genode processes.
|
||||
*/
|
||||
if (ncs.server_sd != -1 || ncs.client_sd != -1)
|
||||
PERR("%s called for IPC server which should never happen", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************
|
||||
** Support for Platform_env_base::Rm_session_mmap **
|
||||
****************************************************/
|
||||
|
||||
Genode::size_t
|
||||
Platform_env_base::Rm_session_mmap::_dataspace_size(Capability<Dataspace> ds_cap)
|
||||
{
|
||||
if (!ds_cap.valid())
|
||||
return Dataspace_capability::deref(ds_cap)->size();
|
||||
|
||||
/* use RPC if called from a different thread */
|
||||
if (!core_env()->entrypoint()->is_myself()) {
|
||||
/* release Rm_session_mmap::_lock during RPC */
|
||||
_lock.unlock();
|
||||
Genode::size_t size = Dataspace_client(ds_cap).size();
|
||||
_lock.lock();
|
||||
return size;
|
||||
}
|
||||
|
||||
/* use local function call if called from the entrypoint */
|
||||
Object_pool<Rpc_object_base>::Guard
|
||||
ds_rpc(core_env()->entrypoint()->lookup_and_lock(ds_cap));
|
||||
Dataspace * ds = dynamic_cast<Dataspace *>(&*ds_rpc);
|
||||
return ds ? ds->size() : 0;
|
||||
}
|
||||
|
||||
|
||||
int Platform_env_base::Rm_session_mmap::_dataspace_fd(Capability<Dataspace> ds_cap)
|
||||
{
|
||||
if (!core_env()->entrypoint()->is_myself()) {
|
||||
/* release Rm_session_mmap::_lock during RPC */
|
||||
_lock.unlock();
|
||||
int socket = Linux_dataspace_client(ds_cap).fd().dst().socket;
|
||||
_lock.lock();
|
||||
return socket;
|
||||
}
|
||||
|
||||
Capability<Linux_dataspace> lx_ds_cap = static_cap_cast<Linux_dataspace>(ds_cap);
|
||||
|
||||
Object_pool<Rpc_object_base>::Guard
|
||||
ds_rpc(core_env()->entrypoint()->lookup_and_lock(lx_ds_cap));
|
||||
Linux_dataspace * ds = dynamic_cast<Linux_dataspace *>(&*ds_rpc);
|
||||
|
||||
/*
|
||||
* Return a duplicate of the dataspace file descriptor, which will be freed
|
||||
* immediately after mmap'ing the file (see 'Rm_session_mmap').
|
||||
*
|
||||
* Handing out the original file descriptor would result in the premature
|
||||
* release of the descriptor. So the descriptor could be reused (i.e., as a
|
||||
* socket descriptor during the RPC handling). When later destroying the
|
||||
* dataspace, the descriptor would unexpectedly be closed again.
|
||||
*/
|
||||
return ds ? lx_dup(ds->fd().dst().socket) : -1;
|
||||
}
|
||||
|
||||
|
||||
bool Platform_env_base::Rm_session_mmap::_dataspace_writable(Dataspace_capability ds_cap)
|
||||
{
|
||||
if (!core_env()->entrypoint()->is_myself()) {
|
||||
/* release Rm_session_mmap::_lock during RPC */
|
||||
_lock.unlock();
|
||||
bool writable = Dataspace_client(ds_cap).writable();
|
||||
_lock.lock();
|
||||
return writable;
|
||||
}
|
||||
|
||||
Object_pool<Rpc_object_base>::Guard
|
||||
ds_rpc(core_env()->entrypoint()->lookup_and_lock(ds_cap));
|
||||
Dataspace * ds = dynamic_cast<Dataspace *>(&*ds_rpc);
|
||||
|
||||
return ds ? ds->writable() : false;
|
||||
}
|
133
repos/base-linux/src/core/platform_thread.cc
Normal file
133
repos/base-linux/src/core/platform_thread.cc
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* \brief Linux-specific platform thread implementation
|
||||
* \author Norman Feske
|
||||
* \date 2007-10-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2007-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/token.h>
|
||||
#include <util/misc_math.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
/* local includes */
|
||||
#include "platform_thread.h"
|
||||
#include "server_socket_pair.h"
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
typedef Token<Scanner_policy_identifier_with_underline> Tid_token;
|
||||
|
||||
|
||||
/*******************************
|
||||
** Platform_thread::Registry **
|
||||
*******************************/
|
||||
|
||||
void Platform_thread::Registry::insert(Platform_thread *thread)
|
||||
{
|
||||
Lock::Guard guard(_lock);
|
||||
_list.insert(thread);
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::Registry::remove(Platform_thread *thread)
|
||||
{
|
||||
Lock::Guard guard(_lock);
|
||||
_list.remove(thread);
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::Registry::submit_exception(unsigned long pid)
|
||||
{
|
||||
Lock::Guard guard(_lock);
|
||||
|
||||
/* traverse list to find 'Platform_thread' with matching PID */
|
||||
for (Platform_thread *curr = _list.first(); curr; curr = curr->next()) {
|
||||
|
||||
if (curr->_tid == pid) {
|
||||
Signal_context_capability sigh = curr->_pager._sigh;
|
||||
|
||||
if (sigh.valid())
|
||||
Signal_transmitter(sigh).submit();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Platform_thread::Registry *Platform_thread::_registry()
|
||||
{
|
||||
static Platform_thread::Registry registry;
|
||||
return ®istry;
|
||||
}
|
||||
|
||||
|
||||
/*********************
|
||||
** Platform_thread **
|
||||
*********************/
|
||||
|
||||
Platform_thread::Platform_thread(const char *name, unsigned, addr_t)
|
||||
: _tid(-1), _pid(-1)
|
||||
{
|
||||
strncpy(_name, name, min(sizeof(_name), strlen(name) + 1));
|
||||
|
||||
_registry()->insert(this);
|
||||
}
|
||||
|
||||
|
||||
Platform_thread::~Platform_thread()
|
||||
{
|
||||
ep_sd_registry()->disassociate(_ncs.client_sd);
|
||||
|
||||
if (_ncs.client_sd)
|
||||
lx_close(_ncs.client_sd);
|
||||
|
||||
if (_ncs.server_sd)
|
||||
lx_close(_ncs.server_sd);
|
||||
|
||||
_registry()->remove(this);
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::cancel_blocking()
|
||||
{
|
||||
PDBG("send cancel-blocking signal to %ld\n", _tid);
|
||||
lx_tgkill(_pid, _tid, LX_SIGUSR1);
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::pause()
|
||||
{
|
||||
PDBG("not implemented");
|
||||
}
|
||||
|
||||
|
||||
void Platform_thread::resume()
|
||||
{
|
||||
PDBG("not implemented");
|
||||
}
|
||||
|
||||
|
||||
int Platform_thread::client_sd()
|
||||
{
|
||||
/* construct socket pair on first call */
|
||||
if (_ncs.client_sd == -1)
|
||||
_ncs = create_server_socket_pair(_tid);
|
||||
|
||||
return _ncs.client_sd;
|
||||
}
|
||||
|
||||
|
||||
int Platform_thread::server_sd()
|
||||
{
|
||||
client_sd();
|
||||
return _ncs.server_sd;
|
||||
}
|
64
repos/base-linux/src/core/ram_session_support.cc
Normal file
64
repos/base-linux/src/core/ram_session_support.cc
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* \brief Make dataspace accessible to other Linux processes
|
||||
* \author Norman Feske
|
||||
* \date 2006-07-03
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-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.
|
||||
*/
|
||||
|
||||
/* glibc includes */
|
||||
#include <fcntl.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/snprintf.h>
|
||||
|
||||
/* local includes */
|
||||
#include <ram_session_component.h>
|
||||
#include <resource_path.h>
|
||||
|
||||
/* Linux syscall bindings */
|
||||
#include <core_linux_syscalls.h>
|
||||
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
static int ram_ds_cnt = 0; /* counter for creating unique dataspace IDs */
|
||||
|
||||
void Ram_session_component::_export_ram_ds(Dataspace_component *ds)
|
||||
{
|
||||
char fname[Linux_dataspace::FNAME_LEN];
|
||||
|
||||
/* create file using a unique file name in the resource path */
|
||||
snprintf(fname, sizeof(fname), "%s/ds-%d", resource_path(), ram_ds_cnt++);
|
||||
lx_unlink(fname);
|
||||
int const fd = lx_open(fname, O_CREAT|O_RDWR|O_TRUNC|LX_O_CLOEXEC, S_IRWXU);
|
||||
lx_ftruncate(fd, ds->size());
|
||||
|
||||
/* remember file descriptor in dataspace component object */
|
||||
ds->fd(fd);
|
||||
|
||||
/*
|
||||
* Wipe the file from the Linux file system. The kernel will still keep the
|
||||
* then unnamed file around until the last reference to the file will be
|
||||
* gone (i.e., an open file descriptor referring to the file). A process
|
||||
* w/o the right file descriptor won't be able to open and access the file.
|
||||
*/
|
||||
lx_unlink(fname);
|
||||
}
|
||||
|
||||
|
||||
void Ram_session_component::_revoke_ram_ds(Dataspace_component *ds)
|
||||
{
|
||||
int const fd = ds->fd().dst().socket;
|
||||
if (fd != -1)
|
||||
lx_close(fd);
|
||||
}
|
||||
|
||||
|
||||
void Ram_session_component::_clear_ds(Dataspace_component *ds) { }
|
84
repos/base-linux/src/core/rom_session_component.cc
Normal file
84
repos/base-linux/src/core/rom_session_component.cc
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* \brief Linux-specific core implementation of the ROM session interface
|
||||
* \author Norman Feske
|
||||
* \date 2006-07-06
|
||||
*
|
||||
* The Linux version of ROM session component does not use the
|
||||
* Rom_fs as provided as constructor argument. Instead, we map
|
||||
* rom modules directly to files of the host file system.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-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.
|
||||
*/
|
||||
|
||||
/* Linux includes */
|
||||
#include <core_linux_syscalls.h>
|
||||
#include <sys/fcntl.h>
|
||||
|
||||
/* Genode includes */
|
||||
#include <linux_dataspace/linux_dataspace.h>
|
||||
#include <util/arg_string.h>
|
||||
#include <root/root.h>
|
||||
|
||||
/* local includes */
|
||||
#include "rom_session_component.h"
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
static Genode::size_t file_size(const char *path)
|
||||
{
|
||||
struct stat64 s;
|
||||
if (lx_stat(path, &s) < 0)
|
||||
return 0;
|
||||
else
|
||||
return s.st_size;
|
||||
}
|
||||
|
||||
|
||||
Rom_session_component::Rom_session_component(Rom_fs *rom_fs,
|
||||
Rpc_entrypoint *ds_ep,
|
||||
const char *args)
|
||||
: _ds_ep(ds_ep)
|
||||
{
|
||||
/* extract filename from session arguments */
|
||||
char fname[Linux_dataspace::FNAME_LEN];
|
||||
Arg_string::find_arg(args, "filename").string(fname, sizeof(fname), "");
|
||||
|
||||
/* only files inside the current working directory are allowed */
|
||||
for (const char *c = fname; *c; c++)
|
||||
if (*c == '/')
|
||||
throw Root::Invalid_args();
|
||||
|
||||
Genode::size_t const fsize = file_size(fname);
|
||||
|
||||
/* use invalid capability as default value */
|
||||
_ds_cap = Rom_dataspace_capability();
|
||||
|
||||
/* ROM module not found */
|
||||
if (fsize == 0)
|
||||
throw Root::Invalid_args();
|
||||
|
||||
int const fd = lx_open(fname, O_RDONLY | LX_O_CLOEXEC, S_IRUSR | S_IXUSR);
|
||||
|
||||
_ds = Dataspace_component(fsize, 0, false, false, 0);
|
||||
_ds.fd(fd);
|
||||
_ds.fname(fname);
|
||||
|
||||
Dataspace_capability ds_cap = _ds_ep->manage(&_ds);
|
||||
_ds_cap = static_cap_cast<Rom_dataspace>(ds_cap);
|
||||
}
|
||||
|
||||
|
||||
Rom_session_component::~Rom_session_component()
|
||||
{
|
||||
_ds_ep->dissolve(&_ds);
|
||||
|
||||
int const fd = _ds.fd().dst().socket;
|
||||
if (fd != -1)
|
||||
lx_close(fd);
|
||||
}
|
60
repos/base-linux/src/core/target.mk
Normal file
60
repos/base-linux/src/core/target.mk
Normal file
@ -0,0 +1,60 @@
|
||||
TARGET = core
|
||||
REQUIRES = linux
|
||||
LIBS = cxx base-common syscall startup
|
||||
|
||||
GEN_CORE_DIR = $(BASE_DIR)/src/core
|
||||
|
||||
SRC_CC = main.cc \
|
||||
platform.cc \
|
||||
platform_thread.cc \
|
||||
platform_services.cc \
|
||||
ram_session_component.cc \
|
||||
ram_session_support.cc \
|
||||
rom_session_component.cc \
|
||||
cpu_session_component.cc \
|
||||
cpu_session_extension.cc \
|
||||
cpu_session_support.cc \
|
||||
pd_session_component.cc \
|
||||
io_mem_session_component.cc \
|
||||
signal_session_component.cc \
|
||||
signal_source_component.cc \
|
||||
trace_session_component.cc \
|
||||
thread_linux.cc \
|
||||
context_area.cc \
|
||||
core_printf.cc \
|
||||
thread.cc
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/core/include \
|
||||
$(GEN_CORE_DIR)/include \
|
||||
$(REP_DIR)/src/platform \
|
||||
$(REP_DIR)/src/base/ipc \
|
||||
$(REP_DIR)/src/base/env \
|
||||
$(BASE_DIR)/src/base/env \
|
||||
$(REP_DIR)/src/base/console \
|
||||
$(BASE_DIR)/src/base/thread \
|
||||
|
||||
HOST_INC_DIR += /usr/include
|
||||
|
||||
#
|
||||
# core does not use POSIX threads when built for the 'lx_hybrid_x86' platform,
|
||||
# so we need to reserve the thread-context area via a segment in the program to
|
||||
# prevent clashes with vdso and shared libraries.
|
||||
#
|
||||
ifeq ($(findstring always_hybrid, $(SPECS)), always_hybrid)
|
||||
LD_SCRIPT_STATIC = $(LD_SCRIPT_DEFAULT) \
|
||||
$(call select_from_repositories,src/platform/context_area.stdlib.ld)
|
||||
endif
|
||||
|
||||
include $(GEN_CORE_DIR)/version.inc
|
||||
|
||||
vpath main.cc $(GEN_CORE_DIR)
|
||||
vpath ram_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath cpu_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath platform_services.cc $(GEN_CORE_DIR)
|
||||
vpath signal_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath signal_source_component.cc $(GEN_CORE_DIR)
|
||||
vpath trace_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath core_printf.cc $(BASE_DIR)/src/base/console
|
||||
vpath thread.cc $(BASE_DIR)/src/base/thread
|
||||
vpath trace.cc $(BASE_DIR)/src/base/thread
|
||||
vpath %.cc $(PRG_DIR)
|
62
repos/base-linux/src/core/thread_linux.cc
Normal file
62
repos/base-linux/src/core/thread_linux.cc
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* \brief Implementation of the core-internal Thread API via Linux threads
|
||||
* \author Norman Feske
|
||||
* \date 2006-06-13
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2013 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/thread.h>
|
||||
#include <base/sleep.h>
|
||||
|
||||
/* Linux syscall bindings */
|
||||
#include <linux_syscalls.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
static void empty_signal_handler(int) { }
|
||||
|
||||
|
||||
void Thread_base::_thread_start()
|
||||
{
|
||||
/*
|
||||
* Set signal handler such that canceled system calls get not transparently
|
||||
* retried after a signal gets received.
|
||||
*/
|
||||
lx_sigaction(LX_SIGUSR1, empty_signal_handler);
|
||||
|
||||
/*
|
||||
* Deliver SIGCHLD signals to no thread other than the main thread. Core's
|
||||
* main thread will handle the signals while executing the 'wait_for_exit'
|
||||
* function, which is known to not hold any locks that would interfere with
|
||||
* the handling of the signal.
|
||||
*/
|
||||
lx_sigsetmask(LX_SIGCHLD, false);
|
||||
|
||||
Thread_base::myself()->entry();
|
||||
Thread_base::myself()->_join_lock.unlock();
|
||||
sleep_forever();
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::_init_platform_thread(Type) { }
|
||||
|
||||
|
||||
void Thread_base::_deinit_platform_thread() { }
|
||||
|
||||
|
||||
void Thread_base::start()
|
||||
{
|
||||
_tid.tid = lx_create_thread(Thread_base::_thread_start, stack_top(), this);
|
||||
_tid.pid = lx_getpid();
|
||||
}
|
||||
|
||||
|
||||
void Thread_base::cancel_blocking() { }
|
Reference in New Issue
Block a user