Imported Genode release 11.11
This commit is contained in:
committed by
Christian Helmuth
parent
6bcc9aef0e
commit
da4e1feaa5
2
hello_tutorial/README
Normal file
2
hello_tutorial/README
Normal file
@@ -0,0 +1,2 @@
|
||||
This repository contains the source code of the 'Hello' client-server tutorial
|
||||
written by Björn Döbel. Please find the document at 'doc/hello_tutorial.txt'.
|
||||
12
hello_tutorial/config/config
Normal file
12
hello_tutorial/config/config
Normal file
@@ -0,0 +1,12 @@
|
||||
<config>
|
||||
<start name="hello_server">
|
||||
<resource name="RAM" quantum="256K"/>
|
||||
<provides><service name="Hello"/></provides>
|
||||
</start>
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="256K"/>
|
||||
</start>
|
||||
<start name="hello_client">
|
||||
<resource name="RAM" quantum="256K"/>
|
||||
</start>
|
||||
</config>
|
||||
406
hello_tutorial/doc/hello_tutorial.txt
Normal file
406
hello_tutorial/doc/hello_tutorial.txt
Normal file
@@ -0,0 +1,406 @@
|
||||
|
||||
Creating your first Genode application
|
||||
|
||||
Björn Döbel and Norman Feske
|
||||
|
||||
Abstract
|
||||
########
|
||||
|
||||
This section will give you a step-by-step introduction for writing your first
|
||||
little client-server application using the Genode OS Framework. We will create
|
||||
a server that provides two functions to its clients and a client that uses
|
||||
these functions. The code samples in this section are not necessarily complete.
|
||||
You can download the complete tutorial source code from the link at the bottom
|
||||
of this page.
|
||||
|
||||
|
||||
Prerequisites
|
||||
#############
|
||||
|
||||
We assume that you know how to write code and have read:
|
||||
|
||||
Norman Feske and Christian Helmuth:
|
||||
"Design of the Genode OS Architecture",
|
||||
_TU Dresden technical report TUD-FI06-07, Dresden, Germany, December 2006_.
|
||||
|
||||
[http://genode-labs.com/publications/bastei-design-2006.pdf]
|
||||
|
||||
so that you have a basic understanding of what Genode is and how things work.
|
||||
Of course, you will also need to check out Genode before going any further.
|
||||
|
||||
|
||||
Setting up the build environment
|
||||
################################
|
||||
|
||||
The Genode build system enables developers to create software in different
|
||||
repositories that don't need to interfere with the rest of the Genode tree. We
|
||||
will do this for our example now. In the Genode root directory, we create the
|
||||
following subdirectory structure:
|
||||
|
||||
! hello_tutorial
|
||||
! hello_tutorial/include
|
||||
! hello_tutorial/include/hello_session
|
||||
! hello_tutorial/src
|
||||
! hello_tutorial/src/hello
|
||||
! hello_tutorial/src/hello/server
|
||||
! hello_tutorial/src/hello/client
|
||||
|
||||
In the remaining document when referring to non-absolute directories, these are
|
||||
local to 'hello_tutorial'.
|
||||
Now we tell the Genode build system, that there is a new repository. Therefore
|
||||
we add the path to our new repository to 'build/etc/build.conf':
|
||||
|
||||
! REPOSITORIES += /path/to/your/hello_tutorial
|
||||
|
||||
Later we will place build description files into the tutorial subdirectories so
|
||||
that the build system can figure out what is needed to build your applications.
|
||||
You can then build these apps from the 'build' directory using one of the
|
||||
following commands:
|
||||
|
||||
! make hello
|
||||
! make hello/server
|
||||
! make hello/client
|
||||
|
||||
The first command builds both the client and the server whereas the latter two
|
||||
commands build only the specific target respectively.
|
||||
|
||||
Defining an interface
|
||||
#####################
|
||||
|
||||
In our example we are going to implement a server providing two functions:
|
||||
:'void say_hello()': makes the server print "Hello world."
|
||||
:'int add(int a, int b)': adds two integers and returns the result.
|
||||
|
||||
The interface of a Genode service is called a _session_. We will define it as a
|
||||
C++ class in 'include/hello_session/hello_session.h'
|
||||
|
||||
!#include <session/session.h>
|
||||
!#include <base/rpc.h>
|
||||
!
|
||||
!namespace Hello {
|
||||
!
|
||||
! struct Session : public Genode::Session
|
||||
! {
|
||||
! static const char *service_name() { return "Hello"; }
|
||||
!
|
||||
! virtual void say_hello() = 0;
|
||||
! virtual int add(int a, int b) = 0;
|
||||
!
|
||||
! GENODE_RPC(Rpc_say_hello, void, say_hello);
|
||||
! GENODE_RPC(Rpc_add, int, add, int, int);
|
||||
! GENODE_RPC_INTERFACE(Rpc_say_hello, Rpc_add);
|
||||
! };
|
||||
!}
|
||||
|
||||
As a good practice, we place the Hello service into a dedicated namespace. The
|
||||
_Hello::Session_ class defines the public interface for our service as well as
|
||||
the meta information that Genode needs to perform remote procedure calls (RPC)
|
||||
accross process boundaries.
|
||||
Furthermore, we use the interface to specify the name of the
|
||||
service by using the 'service_name' function. This function will later
|
||||
be used by both the server for announcing the service at its parent and
|
||||
the client for requesting the creation of a "Hello" session.
|
||||
|
||||
The 'GENODE_RPC' macro is used to declare an RPC function. Its first argument
|
||||
is a type name that is used to refer to the RPC function. The type name can
|
||||
be choosen freely. However, it is a good practice to prefix the type name
|
||||
with 'Rpc_'. The remaining arguments are the return type of the RPC function,
|
||||
the server-side name of the RPC implementation, and the function arguments.
|
||||
The 'GENODE_RPC_INTERFACE' macros declares the list of RPC functions that the
|
||||
RPC interface is comprised of. Under the hood, the 'GENODE_RPC*' macros enrich
|
||||
the compound class with the type information used to automatically generate the
|
||||
RPC communication code at compile time. They do not add any members to the
|
||||
'Session' struct.
|
||||
|
||||
|
||||
Writing server code
|
||||
###################
|
||||
|
||||
Now let's write a server providing the interface defined by _Hello::Session_.
|
||||
|
||||
|
||||
Implementing the server side
|
||||
============================
|
||||
|
||||
We place the implementation of the session interface into a class called
|
||||
'Session_component' derived from the 'Rpc_object' class template. By
|
||||
instantiating this template class with the session interface as argument, the
|
||||
'Session_component' class gets equipped with the communication code that
|
||||
will make the server's functions accessible via RPC.
|
||||
|
||||
!#include <base/printf.h>
|
||||
!#include <hello_session/hello_session.h>
|
||||
!#include <base/rpc_server.h>
|
||||
!
|
||||
!namespace Hello {
|
||||
!
|
||||
! struct Session_component : Genode::Rpc_object<Session>
|
||||
! {
|
||||
! void say_hello() {
|
||||
! PDBG("I am here... Hello."); }
|
||||
!
|
||||
! int add(int a, int b) {
|
||||
! return a + b; }
|
||||
! };
|
||||
!}
|
||||
|
||||
|
||||
Getting ready to start
|
||||
======================
|
||||
|
||||
The server component won't help us much as long as we don't use it in a server
|
||||
application. Starting a service with Genode works as follows:
|
||||
* Open a CAP session to our parent, so that we are able to create capabilities.
|
||||
* Create and announce a root capability to our parent.
|
||||
* When a client requests our service, the parent invokes the root capability to
|
||||
create session objects and session capabilities. These are then used by the
|
||||
client to communicate with the server.
|
||||
|
||||
The class 'Hello::Root_component' is derived from Genode's 'Root_component'
|
||||
class template. This class defines a '_create_session' method which is called
|
||||
each time a client wants to establish a connection to the server. This function
|
||||
is responsible for parsing the parameter string the client hands over to the
|
||||
server and creating a 'Hello::Session_component' object from these parameters.
|
||||
|
||||
!#include <base/printf.h>
|
||||
!#include <root/component.h>
|
||||
!
|
||||
!namespace Hello {
|
||||
!
|
||||
! class Root_component : public Genode::Root_component<Session_component>
|
||||
! {
|
||||
! protected:
|
||||
!
|
||||
! Session_component *_create_session(const char *args)
|
||||
! {
|
||||
! PDBG("creating hello session.");
|
||||
! return new (md_alloc()) Session_component();
|
||||
! }
|
||||
!
|
||||
! public:
|
||||
!
|
||||
! Root_component(Genode::Rpc_entrypoint *ep,
|
||||
! Genode::Allocator *allocator)
|
||||
! : Genode::Root_component<Session_component>(ep, allocator)
|
||||
! {
|
||||
! PDBG("Creating root component.");
|
||||
! }
|
||||
! };
|
||||
!}
|
||||
|
||||
Now we only need a main method that announces the service to our parent:
|
||||
|
||||
!#include <base/sleep.h>
|
||||
!#include <cap_session/connection.h>
|
||||
!
|
||||
!using namespace Genode;
|
||||
!
|
||||
!int main(void)
|
||||
!{
|
||||
! /*
|
||||
! * Get a session for the parent's capability service, so that we
|
||||
! * are able to create capabilities.
|
||||
! */
|
||||
! Cap_connection cap;
|
||||
!
|
||||
! /*
|
||||
! * A sliced heap is used for allocating session objects - thereby we
|
||||
! * can release objects separately.
|
||||
! */
|
||||
! static Sliced_heap sliced_heap(env()->ram_session(),
|
||||
! env()->rm_session());
|
||||
!
|
||||
! /*
|
||||
! * Create objects for use by the framework.
|
||||
! *
|
||||
! * An 'Rpc_entrypoint' is created to announce our service's root
|
||||
! * capability to our parent, manage incoming session creation
|
||||
! * requests, and dispatch the session interface. The incoming RPC
|
||||
! * requests are dispatched via a dedicated thread. The 'STACK_SIZE'
|
||||
! * argument defines the size of the thread's stack. The additional
|
||||
! * string argument is the name of the entry point, used for
|
||||
! * debugging purposes only.
|
||||
! */
|
||||
! enum { STACK_SIZE = 4096 };
|
||||
! static Rpc_entrypoint ep(&cap, STACK_SIZE, "hello_ep");
|
||||
!
|
||||
! static Hello::Root_component hello_root(&ep, &sliced_heap);
|
||||
! env()->parent()->announce(ep.manage(&hello_root));
|
||||
!
|
||||
! /*
|
||||
! * We are done with this and only act upon client requests now.
|
||||
! */
|
||||
! sleep_forever();
|
||||
!
|
||||
! return 0;
|
||||
!}
|
||||
|
||||
|
||||
Making it fly
|
||||
=============
|
||||
|
||||
In order to run our application, we need to perform two more steps:
|
||||
|
||||
Tell the Genode build system that we want to build 'hello_server'. Therefore we
|
||||
create a 'target.mk' file in 'src/hello/server':
|
||||
|
||||
! TARGET = hello_server
|
||||
! SRC_CC = main.cc
|
||||
! LIBS = cxx env server
|
||||
|
||||
To tell the init process to start the new program, we have to add the following
|
||||
entry to Init's 'config' file, which is located at 'build/bin/config'.
|
||||
|
||||
! <config>
|
||||
! <start name="hello_server">
|
||||
! <resource name="RAM" quantum="256K"/>
|
||||
! <provides><service name="Hello"/></provides>
|
||||
! </start>
|
||||
! </config>
|
||||
|
||||
Now rebuild 'hello/server', go to 'build/bin', run './core'.
|
||||
|
||||
|
||||
Writing client code
|
||||
###################
|
||||
|
||||
In the next part we are going to have a look at the client-side implementation.
|
||||
The most basic steps here are:
|
||||
|
||||
* Get a capability for the "Hello" service from our parent
|
||||
* Invoke RPCs via the obtained capability
|
||||
|
||||
|
||||
A client object
|
||||
===============
|
||||
|
||||
We will encapsulate the Genode IPC interface in a 'Hello::Session_client' class.
|
||||
This class derives from 'Hello:Session' and implements a client-side object.
|
||||
Therefore edit 'include/hello_session/client.h':
|
||||
|
||||
!#include <hello_session/hello_session.h>
|
||||
!#include <base/rpc_client.h>
|
||||
!#include <base/printf.h>
|
||||
!
|
||||
!namespace Hello {
|
||||
!
|
||||
! struct Session_client : Genode::Rpc_client<Session>
|
||||
! {
|
||||
! Session_client(Genode::Capability<Session> cap)
|
||||
! : Genode::Rpc_client<Session>(cap) { }
|
||||
!
|
||||
! void say_hello()
|
||||
! {
|
||||
! PDBG("Saying Hello.");
|
||||
! call<Rpc_say_hello>();
|
||||
! }
|
||||
!
|
||||
! int add(int a, int b)
|
||||
! {
|
||||
! return call<Rpc_add>(a, b);
|
||||
! }
|
||||
! };
|
||||
!}
|
||||
|
||||
|
||||
A 'Hello::Session_client' object takes a 'Capability' as constructor argument.
|
||||
This capability is tagged with the session type and gets passed to the
|
||||
inherited 'Rpc_client' class. This class contains the client-side communication
|
||||
code via the 'call' template function. The template argument for 'call' is the
|
||||
RPC type as declared in the session interface.
|
||||
|
||||
|
||||
Client implementation
|
||||
=====================
|
||||
|
||||
The client-side implementation using the 'Hello::Session_client' object is pretty
|
||||
straightforward. We request a capability for the Hello service from our parent.
|
||||
This call blocks as long as the service has not been registered at the parent.
|
||||
Afterwards, we create a 'Hello::Session_client' object with it and invoke calls. In
|
||||
addition, we use the Timer service that comes with Genode. This server
|
||||
enables us to sleep for a certain amount of milliseconds.
|
||||
|
||||
!#include <base/env.h>
|
||||
!#include <base/printf.h>
|
||||
!#include <hello_session/client.h>
|
||||
!#include <timer_session/connection.h>
|
||||
!
|
||||
!using namespace Genode;
|
||||
!
|
||||
!int main(void)
|
||||
!{
|
||||
! Capability<Hello::Session> h_cap =
|
||||
! env()->parent()->session<Hello::Session>("foo, ram_quota=4K");
|
||||
!
|
||||
! Hello::Session_client h(h_cap);
|
||||
!
|
||||
! Timer::Connection timer;
|
||||
!
|
||||
! while (1) {
|
||||
! h.say_hello();
|
||||
! timer.msleep(1000);
|
||||
!
|
||||
! int foo = h.add(2,5);
|
||||
! PDBG("Added 2 + 5 = %d", foo);
|
||||
! timer.msleep(1000);
|
||||
! }
|
||||
!
|
||||
! return 0;
|
||||
!}
|
||||
|
||||
Compared to the creation of the Timer session, the creation of "Hello" session
|
||||
looks rather inconvenient and takes multiple lines of code. For this reason, it
|
||||
is a good practice to supply a convenience wrapper for creating sessions as
|
||||
used for the timer session. This wrapper is also the right place to for
|
||||
documenting session-construction arguments and assembling the argument string.
|
||||
By convention, the wrapper is called 'connection.h' and placed in the directory
|
||||
of the session interface. For our case, the file
|
||||
'include/hello_session/connection.h' looks like this:
|
||||
|
||||
!#include <hello_session/client.h>
|
||||
!#include <base/connection.h>
|
||||
!
|
||||
!namespace Hello {
|
||||
!
|
||||
! struct Connection : Genode::Connection<Session>, Session_client
|
||||
! {
|
||||
! Connection()
|
||||
! :
|
||||
! /* create session */
|
||||
! Genode::Connection<Hello::Session>(session("foo, ram_quota=4K")),
|
||||
!
|
||||
! /* initialize RPC interface */
|
||||
! Session_client(cap()) { }
|
||||
! };
|
||||
!}
|
||||
|
||||
With the 'Connection' class in place, we can now use Hello sessions
|
||||
by just instantiating 'Hello::Connection' objects and invoke
|
||||
functions directly on such an object. For example:
|
||||
|
||||
!Hello::Connection hello;
|
||||
!int foo = hello.add(2, 5);
|
||||
|
||||
|
||||
Ready, set, go...
|
||||
=================
|
||||
|
||||
Add a 'target.mk' file with the following content to 'src/hello/client/':
|
||||
|
||||
! TARGET = hello_client
|
||||
! SRC_CC = main.cc
|
||||
! LIBS = cxx env
|
||||
|
||||
Add the following entries to your 'config' file:
|
||||
|
||||
! <start name="timer">
|
||||
! <resource name="RAM" quantum="256K"/>
|
||||
! </start>
|
||||
! <start name="hello_client">
|
||||
! <resource name="RAM" quantum="256K"/>
|
||||
! </start>
|
||||
|
||||
Build 'drivers/timer', and 'hello/client', go to 'build/bin', and run './core'
|
||||
again. You have now successfully implemented your first Genode client-server
|
||||
scenario.
|
||||
|
||||
41
hello_tutorial/include/hello_session/client.h
Normal file
41
hello_tutorial/include/hello_session/client.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* \brief Client-side interface of the Hello service
|
||||
* \author Björn Döbel
|
||||
* \date 2008-03-20
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2008-2011 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 _INCLUDE__HELLO_SESSION_H__CLIENT_H_
|
||||
#define _INCLUDE__HELLO_SESSION_H__CLIENT_H_
|
||||
|
||||
#include <hello_session/hello_session.h>
|
||||
#include <base/rpc_client.h>
|
||||
#include <base/printf.h>
|
||||
|
||||
namespace Hello {
|
||||
|
||||
struct Session_client : Genode::Rpc_client<Session>
|
||||
{
|
||||
Session_client(Genode::Capability<Session> cap)
|
||||
: Genode::Rpc_client<Session>(cap) { }
|
||||
|
||||
void say_hello()
|
||||
{
|
||||
PDBG("Saying Hello.");
|
||||
call<Rpc_say_hello>();
|
||||
}
|
||||
|
||||
int add(int a, int b)
|
||||
{
|
||||
return call<Rpc_add>(a, b);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__HELLO_SESSION_H__CLIENT_H_ */
|
||||
34
hello_tutorial/include/hello_session/connection.h
Normal file
34
hello_tutorial/include/hello_session/connection.h
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* \brief Connection to Hello service
|
||||
* \author Norman Feske
|
||||
* \date 2008-11-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2008-2011 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 _INCLUDE__HELLO_SESSION__CONNECTION_H_
|
||||
#define _INCLUDE__HELLO_SESSION__CONNECTION_H_
|
||||
|
||||
#include <hello_session/client.h>
|
||||
#include <base/connection.h>
|
||||
|
||||
namespace Hello {
|
||||
|
||||
struct Connection : Genode::Connection<Session>, Session_client
|
||||
{
|
||||
Connection()
|
||||
:
|
||||
/* create session */
|
||||
Genode::Connection<Hello::Session>(session("foo, ram_quota=4K")),
|
||||
|
||||
/* initialize RPC interface */
|
||||
Session_client(cap()) { }
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__HELLO_SESSION__CONNECTION_H_ */
|
||||
41
hello_tutorial/include/hello_session/hello_session.h
Normal file
41
hello_tutorial/include/hello_session/hello_session.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* \brief Interface definition of the Hello service
|
||||
* \author Björn Döbel
|
||||
* \date 2008-03-20
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2008-2011 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 _INCLUDE__HELLO_SESSION__HELLO_SESSION_H_
|
||||
#define _INCLUDE__HELLO_SESSION__HELLO_SESSION_H_
|
||||
|
||||
#include <session/session.h>
|
||||
#include <base/rpc.h>
|
||||
|
||||
namespace Hello {
|
||||
|
||||
struct Session : Genode::Session
|
||||
{
|
||||
static const char *service_name() { return "Hello"; }
|
||||
|
||||
virtual void say_hello() = 0;
|
||||
virtual int add(int a, int b) = 0;
|
||||
|
||||
|
||||
/*******************
|
||||
** RPC interface **
|
||||
*******************/
|
||||
|
||||
GENODE_RPC(Rpc_say_hello, void, say_hello);
|
||||
GENODE_RPC(Rpc_add, int, add, int, int);
|
||||
|
||||
GENODE_RPC_INTERFACE(Rpc_say_hello, Rpc_add);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__HELLO_SESSION__HELLO_SESSION_H_ */
|
||||
48
hello_tutorial/run/hello.run
Normal file
48
hello_tutorial/run/hello.run
Normal file
@@ -0,0 +1,48 @@
|
||||
#
|
||||
# Build
|
||||
#
|
||||
|
||||
build { core init hello drivers/timer }
|
||||
|
||||
create_boot_directory
|
||||
|
||||
#
|
||||
# Generate config
|
||||
#
|
||||
|
||||
install_config {
|
||||
<config>
|
||||
<parent-provides>
|
||||
<service name="ROM"/>
|
||||
<service name="RAM"/>
|
||||
<service name="CAP"/>
|
||||
<service name="LOG"/>
|
||||
<service name="RM"/>
|
||||
<service name="IO_PORT"/>
|
||||
<service name="IRQ"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Timer"/></provides>
|
||||
</start>
|
||||
<start name="hello_server">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides><service name="Hello"/></provides>
|
||||
</start>
|
||||
<start name="hello_client">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
</start>
|
||||
</config>}
|
||||
|
||||
#
|
||||
# Boot image
|
||||
#
|
||||
|
||||
build_boot_image { core init hello_client hello_server timer }
|
||||
|
||||
append qemu_args " -nographic "
|
||||
|
||||
run_genode_until forever
|
||||
38
hello_tutorial/src/hello/client/main.cc
Normal file
38
hello_tutorial/src/hello/client/main.cc
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* \brief Test client for the Hello RPC interface
|
||||
* \author Björn Döbel
|
||||
* \date 2008-03-20
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2008-2011 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/env.h>
|
||||
#include <base/printf.h>
|
||||
#include <hello_session/client.h>
|
||||
#include <timer_session/connection.h>
|
||||
#include <hello_session/connection.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Hello::Connection h;
|
||||
|
||||
Timer::Connection timer;
|
||||
|
||||
while (1) {
|
||||
h.say_hello();
|
||||
timer.msleep(1000);
|
||||
|
||||
int foo = h.add(2, 5);
|
||||
PDBG("Added 2 + 5 = %d", foo);
|
||||
timer.msleep(1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
3
hello_tutorial/src/hello/client/target.mk
Normal file
3
hello_tutorial/src/hello/client/target.mk
Normal file
@@ -0,0 +1,3 @@
|
||||
TARGET = hello_client
|
||||
SRC_CC = main.cc
|
||||
LIBS = cxx env
|
||||
93
hello_tutorial/src/hello/server/main.cc
Normal file
93
hello_tutorial/src/hello/server/main.cc
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* \brief Main program of the Hello server
|
||||
* \author Björn Döbel
|
||||
* \date 2008-03-20
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2008-2011 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 <base/env.h>
|
||||
#include <base/sleep.h>
|
||||
#include <cap_session/connection.h>
|
||||
#include <root/component.h>
|
||||
#include <hello_session/hello_session.h>
|
||||
#include <base/rpc_server.h>
|
||||
|
||||
namespace Hello {
|
||||
|
||||
struct Session_component : Genode::Rpc_object<Session>
|
||||
{
|
||||
void say_hello() {
|
||||
PDBG("I am here... Hello."); }
|
||||
|
||||
int add(int a, int b) {
|
||||
return a + b; }
|
||||
};
|
||||
|
||||
class Root_component : public Genode::Root_component<Session_component>
|
||||
{
|
||||
protected:
|
||||
|
||||
Hello::Session_component *_create_session(const char *args)
|
||||
{
|
||||
PDBG("creating hello session.");
|
||||
return new (md_alloc()) Session_component();
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Root_component(Genode::Rpc_entrypoint *ep,
|
||||
Genode::Allocator *allocator)
|
||||
: Genode::Root_component<Session_component>(ep, allocator)
|
||||
{
|
||||
PDBG("Creating root component.");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
/*
|
||||
* Get a session for the parent's capability service, so that we
|
||||
* are able to create capabilities.
|
||||
*/
|
||||
Cap_connection cap;
|
||||
|
||||
/*
|
||||
* A sliced heap is used for allocating session objects - thereby we
|
||||
* can release objects separately.
|
||||
*/
|
||||
static Sliced_heap sliced_heap(env()->ram_session(),
|
||||
env()->rm_session());
|
||||
|
||||
/*
|
||||
* Create objects for use by the framework.
|
||||
*
|
||||
* An 'Rpc_entrypoint' is created to announce our service's root
|
||||
* capability to our parent, manage incoming session creation
|
||||
* requests, and dispatch the session interface. The incoming RPC
|
||||
* requests are dispatched via a dedicated thread. The 'STACK_SIZE'
|
||||
* argument defines the size of the thread's stack. The additional
|
||||
* string argument is the name of the entry point, used for
|
||||
* debugging purposes only.
|
||||
*/
|
||||
enum { STACK_SIZE = 4096 };
|
||||
static Rpc_entrypoint ep(&cap, STACK_SIZE, "hello_ep");
|
||||
|
||||
static Hello::Root_component hello_root(&ep, &sliced_heap);
|
||||
env()->parent()->announce(ep.manage(&hello_root));
|
||||
|
||||
/* We are done with this and only act upon client requests now. */
|
||||
sleep_forever();
|
||||
|
||||
return 0;
|
||||
}
|
||||
3
hello_tutorial/src/hello/server/target.mk
Normal file
3
hello_tutorial/src/hello/server/target.mk
Normal file
@@ -0,0 +1,3 @@
|
||||
TARGET = hello_server
|
||||
SRC_CC = main.cc
|
||||
LIBS = cxx env server
|
||||
Reference in New Issue
Block a user