Top Banner
Genode OS Framework Programming Environment Norman Feske <[email protected]>
68

Genode Programming

Jun 15, 2015

Download

Education

Vasily Sartakov

The lecture by Norman Feske for Summer Systems School'12.
Genode Programming

SSS'12 - Education event, organized by ksys labs[1] in 2012, for students interested in system software development and information security.

Genode[2] - The Genode operating-system framework provides a uniform API for applications on top of 8 existing microkernels/hypervisors: Linux, L4ka::Pistachio, L4/Fiasco, OKL4, NOVA, Fiasco.OC, Codezero, and a custom kernel for the MicroBlaze architecture.

1. http://ksyslabs.org/
2. http://genode.org
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Genode Programming

Genode OS FrameworkProgramming Environment

Norman Feske<[email protected]>

Page 2: Genode Programming

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

Page 3: Genode Programming

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

Page 4: Genode Programming

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

Page 5: Genode Programming

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

Page 6: Genode Programming

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

Page 7: Genode Programming

Repositories shadowing (II)

Genode OS Framework Programming Environment 7

Page 8: Genode Programming

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

Page 9: Genode Programming

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

Page 10: Genode Programming

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

Page 11: Genode Programming

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

Page 12: Genode Programming

Specs: Refinement

Genode OS Framework Programming Environment 12

Page 13: Genode Programming

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

Page 14: Genode Programming

Specs: Benefits

→ No preprocessor-based configuration→ No artificial abstractions (architecture, platform, cpu, ...)→ Easy to extend→ Easy to configure

Genode OS Framework Programming Environment 14

Page 15: Genode Programming

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

Page 16: Genode Programming

Repository relationships

Genode OS Framework Programming Environment 16

Page 17: Genode Programming

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

Page 18: Genode Programming

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

Page 19: Genode Programming

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

Page 20: Genode Programming

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

Page 21: Genode Programming

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

Page 22: Genode Programming

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

Page 23: Genode Programming

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

Page 24: Genode Programming

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

Page 25: Genode Programming

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

Page 26: Genode Programming

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

Page 27: Genode Programming

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

Page 28: Genode Programming

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

Page 29: Genode Programming

Typical work flow

Genode OS Framework Programming Environment 29

Page 30: Genode Programming

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

Page 31: Genode Programming

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

Page 32: Genode Programming

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

Page 33: Genode Programming

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

Page 34: Genode Programming

Remote procedure calls (RPC)

Genode OS Framework Programming Environment 34

Page 35: Genode Programming

Remote procedure calls: Classes

Genode OS Framework Programming Environment 35

Page 36: Genode Programming

Remote procedure calls: New RPC object

Genode OS Framework Programming Environment 36

Page 37: Genode Programming

Remote procedure calls: Invocation

Genode OS Framework Programming Environment 37

Page 38: Genode Programming

Shared memory

Genode OS Framework Programming Environment 38

Page 39: Genode Programming

Asynchronous notifications

Genode OS Framework Programming Environment 39

Page 40: Genode Programming

Asynchronous notifications (II)

Genode OS Framework Programming Environment 40

Page 41: Genode Programming

Mechanisms combined

RPC + shared memory→ Synchronous bulk data (transaction)

Signalling + dataspace→ Asynchronous bulk data (streaming)

Genode OS Framework Programming Environment 41

Page 42: Genode Programming

Synchronous bulk data transfer

Genode OS Framework Programming Environment 42

Page 43: Genode Programming

Asynchronous bulk data transfer

Genode OS Framework Programming Environment 43

Page 44: Genode Programming

Packet stream example

Genode OS Framework Programming Environment 44

Page 45: Genode Programming

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

Page 46: Genode Programming

Scenario overview

Genode OS Framework Programming Environment 46

Page 47: Genode Programming

Classes overview

Genode OS Framework Programming Environment 47

Page 48: Genode Programming

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

Page 49: Genode Programming

Server interface

Genode OS Framework Programming Environment 49

Page 50: Genode Programming

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

Page 51: Genode Programming

Server-side interface implementation

Genode OS Framework Programming Environment 51

Page 52: Genode Programming

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

Page 53: Genode Programming

Server-side root interface

Genode OS Framework Programming Environment 53

Page 54: Genode Programming

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

Page 55: Genode Programming

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

Page 56: Genode Programming

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

Page 57: Genode Programming

Client main program

Genode OS Framework Programming Environment 57

Page 58: Genode Programming

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

Page 59: Genode Programming

Client-side convenience wrapper

Genode OS Framework Programming Environment 59

Page 60: Genode Programming

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

Page 61: Genode Programming

Client-side connection object

Genode OS Framework Programming Environment 61

Page 62: Genode Programming

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

Page 63: Genode Programming

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

Page 64: Genode Programming

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

Page 65: Genode Programming

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

Page 66: Genode Programming

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

Page 67: Genode Programming

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

Page 68: Genode Programming

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