Genode OS FrameworkProgramming Environment
Norman Feske<[email protected]>
Outline
1. Source tree overview
2. Build system
3. Run scripts
4. Inter-process communication
5. Client-server example
Genode OS Framework Programming Environment 2
Outline
1. Source tree overview
2. Build system
3. Run scripts
4. Inter-process communication
5. Client-server example
Genode OS Framework Programming Environment 3
Get the source code
Code is hosted at GitHub:
https://github.com/genodelabs/genode
Clone the main repository:
git clone https://github.com/genodelabs/genode.git
Contains genuine Genode code only3rd-party code not included, must be downloaded
Genode OS Framework Programming Environment 4
Repositories
Foster modular code base instead of one big tree
For a given project, only a subset of repositories is relevant→ Helps to focus attention to relevant parts→ Clean organization defeats ad-hoc solutions
Genode OS Framework Programming Environment 5
Repository shadowing
Set of used repositories defined by build directory→ Selected repositories form one logical source tree(similar to unionfs)
REPOSITORIES = <list-of-repo-directories>
Repositories can shadow each other
I target description filesI library description filesI include-search directories
Order is REPOSITORIES list is important
I Earlier entries shadow later entries
Genode OS Framework Programming Environment 6
Repositories shadowing (II)
Genode OS Framework Programming Environment 7
Repositories in practice
Tweak existing components without breaking existing code
Want to add code? → Simply introduce a new repository
I Can be hosted outside the mainline Genode treeI Use a revision control system of your choice
Genode OS Framework Programming Environment 8
Specs
Source repositories → coarse grained modularity
Challenges:
Multiple kernelsMultiple hardware platformsDifferent flavours of implementationsifndef-endif yields frustration, messes up test coverage
Build specs → fine grained modularity
Genode OS Framework Programming Environment 9
Specs: Build targets express their needs
Examples:
Specific peripheral (device driver)Particular property of CPU architecture if code is not generic
I only 32-bitI only arm v7a
Licensing conditions
Example, target.mk file
REQUIRES = x86
...
Genode OS Framework Programming Environment 10
Specs: Build directory defines build properties
Spec values characterize the build
Example <build-dir>/etc/specs.conf
SPECS = genode foc_panda
High-level spec values refined to low-level spec values
Genode OS Framework Programming Environment 11
Specs: Refinement
Genode OS Framework Programming Environment 12
Specs: Steering the build process
Traverse <repos>/mk/spec-<value>.mk filesI Platform-specific build settings (CFLAGS ...)I Include more specialized spec-<value>.mk files
Match target’s REQUIRES against build-dir’s SPECS
Prefer specialized libraries:<repo>/lib/mk/blit.mk generic library<repo>/lib/mk/x86 32/blit.mk specialized library
Genode OS Framework Programming Environment 13
Specs: Benefits
→ No preprocessor-based configuration→ No artificial abstractions (architecture, platform, cpu, ...)→ Easy to extend→ Easy to configure
Genode OS Framework Programming Environment 14
Anatomy of a repository
Directory Description
doc/ Documentation, specific for the repository
etc/ Default configuration of the build process
include/ Globally visible header files
src/ Source codes and target build descriptions
lib/mk/ Library build descriptions
Genode OS Framework Programming Environment 15
Repository relationships
Genode OS Framework Programming Environment 16
Integration of 3rd-party source code
Download and integrate a kernel:
make -C <genode-dir>/base-nova prepare
Works uniformly for all kernels!
Genode OS Framework Programming Environment 17
Integration of 3rd-party source code
Ported applications and libraries reside in libports and ports.List available 3rd-party libraries:
make -C libports
Download and integrate a set of libraries:
make -C libports prepare PKG=’libc freetype’
...a lot to explore
Genode OS Framework Programming Environment 18
Outline
1. Source tree overview
2. Build system
3. Run scripts
4. Inter-process communication
5. Client-server example
Genode OS Framework Programming Environment 19
Tool chain
Needed because
C++ support libraries normally require a libcI We need C++ supportI We don’t want to depend on a libc
Multi-threading support is OS-specificI Linux TLS
Limit varienty of tool-chain related errorsI Compiler versionsI Linux distributions
→ http://genode.org/download/tool-chain
Genode OS Framework Programming Environment 20
Build directory
<build-dir>/etc/build.conf
Defines base/ locationDefines source repositories to use
REPOSITORIES = <list-of-repo-dirs>
Make flags
MAKE += -j4
Genode OS Framework Programming Environment 21
Build directory (II)
<build-dir>/etc/specs.conf
Included after <repos>/etc/specs.confDefine build characteristics via spec values
SPECS = genode foc_panda
Defaults in base-<platform>/etc/specs.confExtend spec values
SPECS += i915
Genode OS Framework Programming Environment 22
Build directory (III)
<build-dir>/Makefilesymlink to<genode-dir>/tool/builddir/build.mk
Front end of the build system
Genode OS Framework Programming Environment 23
Build directory creation tool
<genode-dir>/tool/create builddir
Creates templates for a variety of supported platforms:
create_builddir nova_x86_32 BUILD_DIR=/tmp/build
Revisit generated build.conf:
Enable repositoriesAdd make flags as desired
Genode OS Framework Programming Environment 24
Building targets
Single target
make <rel-dir-to-target>
Example:
make drivers/atapi
Looks for target.mk within <repos>/src/drivers/atapiTests REQUIRES agains SPECS
Builds all libraries the target depends onBuilds target
Genode OS Framework Programming Environment 25
Building targets (II)
Tree of targets
make <rel-dir>
Example:
make drivers
Builds all targets within <repos>/src/drivers.
Genode OS Framework Programming Environment 26
Building targets (III)
List of targets
make <rel-dir> ...
Example:
make core init drivers/timer
Builds all targets found in any of the specific src/ locations
Genode OS Framework Programming Environment 27
Outline
1. Source tree overview
2. Build system
3. Run scripts
4. Inter-process communication
5. Client-server example
Genode OS Framework Programming Environment 28
Typical work flow
Genode OS Framework Programming Environment 29
Run script
build "core init test/printf"
create_boot_directory
install_config {
<config>
<parent-provides>
<service name="LOG"/>
</parent-provides>
<default-route>
<any-service> <parent/> </any-service>
</default-route>
<start name="test-printf">
<resource name="RAM" quantum="1M"/>
</start>
</config> }
build_boot_image "core init test-printf"
append qemu_args "-nographic -m 64"
run_genode_until {-1 = -1 = -1} 10
Genode OS Framework Programming Environment 30
Run script (II)
Located at <repos>/run/<script-name>.runExecutable from within the build directory
make run/<script-name>
Genode OS Framework Programming Environment 31
Run script (III)
→ Single file describes a complete system scenario
→ One run script works across different kernels
→ Great for bug reports
→ Run script + little work = automated test case
Genode OS Framework Programming Environment 32
Outline
1. Source tree overview
2. Build system
3. Run scripts
4. Inter-process communication
5. Client-server example
Genode OS Framework Programming Environment 33
Remote procedure calls (RPC)
Genode OS Framework Programming Environment 34
Remote procedure calls: Classes
Genode OS Framework Programming Environment 35
Remote procedure calls: New RPC object
Genode OS Framework Programming Environment 36
Remote procedure calls: Invocation
Genode OS Framework Programming Environment 37
Shared memory
Genode OS Framework Programming Environment 38
Asynchronous notifications
Genode OS Framework Programming Environment 39
Asynchronous notifications (II)
Genode OS Framework Programming Environment 40
Mechanisms combined
RPC + shared memory→ Synchronous bulk data (transaction)
Signalling + dataspace→ Asynchronous bulk data (streaming)
Genode OS Framework Programming Environment 41
Synchronous bulk data transfer
Genode OS Framework Programming Environment 42
Asynchronous bulk data transfer
Genode OS Framework Programming Environment 43
Packet stream example
Genode OS Framework Programming Environment 44
Outline
1. Source tree overview
2. Build system
3. Run scripts
4. Inter-process communication
5. Client-server example
Genode OS Framework Programming Environment 45
Scenario overview
Genode OS Framework Programming Environment 46
Classes overview
Genode OS Framework Programming Environment 47
Create a new repository
Designated content:
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
Genode OS Framework Programming Environment 48
Server interface
Genode OS Framework Programming Environment 49
Server interface
#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);
};
}
Genode OS Framework Programming Environment 50
Server-side interface implementation
Genode OS Framework Programming Environment 51
Server-side interface implementation
#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()
{
Genode::printf("I am here... Hello.\n");
}
int add(int a, int b) { return a + b; }
};
}
Genode OS Framework Programming Environment 52
Server-side root interface
Genode OS Framework Programming Environment 53
Server-side root interface
#include <root/component.h>
namespace Hello {
struct Root_component : Genode::Root_component<Session_component>
{
Session_component *_create_session(const char *args)
{
return new (md_alloc()) Session_component();
}
Root_component(Genode::Rpc_entrypoint *ep,
Genode::Allocator *allocator)
: Genode::Root_component<Session_component>(ep, allocator)
{ }
};
}
Genode OS Framework Programming Environment 54
Server main program
#include <base/sleep.h>
#include <cap_session/connection.h>
int main(void)
{
using namespace Genode;
Cap_connection cap;
Sliced_heap md_alloc(env()->ram_session(), env()->rm_session());
enum { STACK_SIZE = 4096 };
Rpc_entrypoint ep(&cap, STACK_SIZE, "hello_ep");
Hello::Root_component hello_root(&ep, &md_alloc);
env()->parent()->announce(ep.manage(&hello_root));
sleep_forever();
return 0;
}
Genode OS Framework Programming Environment 55
Server build description files
src/hello/server/target.mk
TARGET = hello_server
SRC_CC = main.cc
LIBS = cxx env server
Genode OS Framework Programming Environment 56
Client main program
Genode OS Framework Programming Environment 57
Client main program
#include <base/env.h>
#include <base/printf.h>
#include <base/rpc_client.h>
#include <hello_session/hello_session.h>
int main(void)
{
using namespace Genode;
Capability<Hello::Session>
hello(env()->parent()->session<Hello::Session>("ram_quota=4K"));
hello.call<Hello::Session::Rpc_say_hello>();
printf("sum = %d",
hello.call<Hello::Session::Rpc_add>(13, 14));
return 0;
}
Genode OS Framework Programming Environment 58
Client-side convenience wrapper
Genode OS Framework Programming Environment 59
Client-side convenience wrapper
#include <base/rpc_client.h>
#include <hello_session/hello_session.h>
namespace Hello {
struct Session_client : Genode::Rpc_client<Session>
{
Session_client(Genode::Capability<Session> cap)
: Genode::Rpc_client<Session>(cap) { }
void say_hello() { call<Rpc_say_hello>(); }
int add(int a, int b) { return call<Rpc_add>(a, b); }
};
}
Genode OS Framework Programming Environment 60
Client-side connection object
Genode OS Framework Programming Environment 61
Client-side connection object
#include <hello_session/client.h>
#include <base/connection.h>
namespace Hello {
struct Connection : Genode::Connection<Session>, Session_client
{
Connection()
:
Genode::Connection<Hello::Session>(session("ram_quota=4K")),
Session_client(cap())
{ }
};
}
Genode OS Framework Programming Environment 62
Simplified client main program
#include <base/env.h>
#include <base/printf.h>
#include <hello_session/connection.h>
int main(void)
{
using namespace Genode;
Hello_connection hello;
hello.say_hello();
printf("sum = %d", hello.add(13, 14));
return 0;
}
Genode OS Framework Programming Environment 63
Client build description file
src/hello/client/target.mk
TARGET = hello_client
SRC_CC = main.cc
LIBS = cxx env
Genode OS Framework Programming Environment 64
Run script
build { core init hello }
create_boot_directory
install_config {
<config>
<parent-provides>
<service name="CAP"/> <service name="LOG"/>
</parent-provides>
<default-route>
<any-service> <parent/> <any-child/> </any-service>
</default-route>
<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>}
build_boot_image { core init hello_client hello_server }
run_genode_until forever
Genode OS Framework Programming Environment 65
Advanced features
Extending existing RPC interfaces
GENODE_RPC_INTERFACE_INHERIT(Base_interface_type,
Rpc_func ...)
Throwing exceptions accross process boundaries
GENODE_RPC_THROW(Rpc_unlink, void, unlink,
GENODE_TYPE_LIST(Permission_denied,
Invalid_name,
Lookup_failed),
Dir_handle, Name const &);
Genode OS Framework Programming Environment 66
Observations
RPC stub code generated by C++ compiler
No external tools needed
No language boundary to conquer
Type safety
Genode OS Framework Programming Environment 67
Thank you
What we covered todayProgramming environment
1. Source tree overview2. Build system3. Run scripts4. Inter-process communication5. Client-server example
Coming up next...Components
1. Classes of components2. Unified configuration
concept3. Session routing4. Components overview
More information and resources:http://genode.org
Genode OS Framework Programming Environment 68