2011-12-22 16:19:25 +01:00
|
|
|
/*
|
|
|
|
* \brief Implementation of process creation for Linux
|
|
|
|
* \author Norman Feske
|
|
|
|
* \date 2006-07-06
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2013-01-10 21:44:47 +01:00
|
|
|
* Copyright (C) 2006-2013 Genode Labs GmbH
|
2011-12-22 16:19:25 +01:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
|
|
* under the terms of the GNU General Public License version 2.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Genode includes */
|
|
|
|
#include <base/elf.h>
|
|
|
|
#include <base/env.h>
|
|
|
|
#include <base/process.h>
|
|
|
|
#include <base/printf.h>
|
2016-01-19 20:24:22 +01:00
|
|
|
#include <linux_native_pd/client.h>
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2012-08-15 19:14:05 +02:00
|
|
|
/* framework-internal includes */
|
2011-12-22 16:19:25 +01:00
|
|
|
#include <linux_syscalls.h>
|
|
|
|
|
|
|
|
|
|
|
|
using namespace Genode;
|
|
|
|
|
|
|
|
Dataspace_capability Process::_dynamic_linker_cap;
|
|
|
|
|
2012-08-08 22:01:04 +02:00
|
|
|
|
2011-12-22 16:19:25 +01:00
|
|
|
/**
|
|
|
|
* Check for dynamic ELF header
|
|
|
|
*/
|
|
|
|
static bool _check_dynamic_elf(Dataspace_capability elf_ds_cap)
|
|
|
|
{
|
|
|
|
/* attach ELF locally */
|
|
|
|
addr_t elf_addr;
|
|
|
|
|
|
|
|
try { elf_addr = env()->rm_session()->attach(elf_ds_cap); }
|
|
|
|
catch (...) { return false; }
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If attach is called within core, it will return zero because
|
|
|
|
* Linux uses Core_rm_session.
|
|
|
|
*/
|
|
|
|
if (!elf_addr) return false;
|
|
|
|
|
|
|
|
/* read program header and interpreter */
|
|
|
|
Elf_binary elf((addr_t)elf_addr);
|
|
|
|
env()->rm_session()->detach((void *)elf_addr);
|
|
|
|
|
|
|
|
return elf.is_dynamically_linked();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-08-15 19:14:05 +02:00
|
|
|
Process::Process(Dataspace_capability elf_data_ds_cap,
|
2015-05-05 08:50:16 +02:00
|
|
|
Pd_session_capability pd_session_cap,
|
2012-08-15 19:14:05 +02:00
|
|
|
Ram_session_capability ram_session_cap,
|
|
|
|
Cpu_session_capability cpu_session_cap,
|
|
|
|
Rm_session_capability rm_session_cap,
|
|
|
|
Parent_capability parent_cap,
|
2015-05-05 08:50:16 +02:00
|
|
|
char const *name)
|
2012-08-15 19:14:05 +02:00
|
|
|
:
|
2015-05-05 08:50:16 +02:00
|
|
|
_pd_session_client(pd_session_cap),
|
2013-01-03 16:23:11 +01:00
|
|
|
_cpu_session_client(cpu_session_cap),
|
2012-08-15 19:14:05 +02:00
|
|
|
_rm_session_client(Rm_session_capability())
|
2011-12-22 16:19:25 +01:00
|
|
|
{
|
|
|
|
/* check for dynamic program header */
|
|
|
|
if (_check_dynamic_elf(elf_data_ds_cap)) {
|
|
|
|
if (!_dynamic_linker_cap.valid()) {
|
2015-05-05 08:50:16 +02:00
|
|
|
PERR("Dynamically linked file found, "
|
|
|
|
"but no dynamic linker binary present");
|
2012-08-15 19:14:05 +02:00
|
|
|
return;
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
2013-09-06 16:33:29 +02:00
|
|
|
elf_data_ds_cap = _dynamic_linker_cap;
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
2013-01-03 16:23:11 +01:00
|
|
|
/*
|
|
|
|
* Register main thread at core
|
|
|
|
*
|
|
|
|
* At this point in time, we do not yet know the TID and PID of the new
|
|
|
|
* thread. Those information will be provided to core by the constructor of
|
|
|
|
* the 'Platform_env' of the new process.
|
|
|
|
*/
|
2015-03-27 14:05:55 +01:00
|
|
|
enum { WEIGHT = Cpu_session::DEFAULT_WEIGHT };
|
|
|
|
_thread0_cap = _cpu_session_client.create_thread(WEIGHT, name);
|
2013-01-03 16:23:11 +01:00
|
|
|
|
2016-01-19 20:24:22 +01:00
|
|
|
Linux_native_pd_client
|
|
|
|
lx_pd(static_cap_cast<Linux_native_pd>(_pd_session_client.native_pd()));
|
2011-12-22 16:19:25 +01:00
|
|
|
|
2016-01-19 20:24:22 +01:00
|
|
|
_pd_session_client.assign_parent(parent_cap);
|
2012-10-11 20:57:10 +02:00
|
|
|
lx_pd.start(elf_data_ds_cap);
|
2011-12-22 16:19:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Process::~Process() { }
|