Imported Genode release 11.11

This commit is contained in:
Genode Labs
2011-12-22 16:19:25 +01:00
committed by Christian Helmuth
parent 6bcc9aef0e
commit da4e1feaa5
2462 changed files with 320115 additions and 3 deletions

38
doc/Makefile Normal file
View File

@@ -0,0 +1,38 @@
SHELL = bash
all: directories.txt
#
# The order of directories in the documentation can be expressed as dependencies.
#
../demo: ../base
directories.txt: $(shell find .. -name README) Makefile
@echo "creating $@"
@echo "Directory structure of the Genode source tree" > $@
@echo "#############################################" >> $@
@echo >> $@
@$(MAKE) --no-print-directory .. >> $@
DIRECTORIES = $(shell find .. -type d)
.PHONY: $(DIRECTORIES)
$(DIRECTORIES):
@if test -r $@/README; then \
dir=$@; dir="$${dir:3}"; \
if test -n "$$dir"; then \
dir="'$$dir'"; \
echo "$$dir"; \
echo "$${dir//?/=}"; \
echo; \
fi; \
cat $@/README; \
echo; \
echo; \
fi; \
recursion="$(shell find $@/* -mindepth 1 -name README -printf '%H\n')"; \
if test "$$recursion"; then $(MAKE) --no-print-directory -s $$recursion; fi
clean cleanall:
rm -f directories.txt

466
doc/build_system.txt Normal file
View File

@@ -0,0 +1,466 @@
=======================
The Genode build system
=======================
Norman Feske
Abstract
########
The Genode OS Framework comes with a custom build system that is designed for
the creation of highly modular and portable systems software. Understanding
its basic concepts is pivotal for using the full potential of the framework.
This document introduces those concepts and the best practises of putting them
to good use. Beside building software components from source code, common
and repetitive development tasks are the testing of individual components
and the integration of those components into complex system scenarios. To
streamline such tasks, the build system is accompanied with special tooling
support. This document introduces those tools.
Build directories and repositories
##################################
The build system is supposed to never touch the source tree. The procedure of
building components and integrating them into system scenarios is done at
a distinct build directory. One build directory targets a specific platform,
i.e., a kernel and hardware architecture. Because the source tree is decoupled
from the build directory, one source tree can have many different build
directories associated, each targeted at another platform.
The recommended way for creating a build directory is the use of the
'create_builddir' tool located at '<genode-dir>/tool/builddir/'. By starting
the tool without arguments, its usage information will be printed. For creating
a new build directory, one of the listed target platforms must be specified.
Furthermore, the location of the new build directory has to be specified via
the 'BUILD_DIR=' argument. For example:
! cd <genode-dir>
! ./tool/create_builddir linux_x86 BUILD_DIR=/tmp/build.linux_x86
This command will create a new build directory for the Linux/x86 platform
at '<genode-dir>/build.linux_x86/'.
Build-directory configuration via 'build.conf'
==============================================
The fresh build directory will contain a 'Makefile', which is a symlink to
'tool/builddir/build.mk'. This 'Makefile' is the front end of the build system
and not supposed to be edited. Beside the 'Makefile', there is a 'etc/'
subdirectory that contains the build-directory configuration. For most
platforms, there is only a single 'build.conf' file, which defines the parts of
the Genode source tree incorporated in the build process. Those parts are
called _repositories_.
The repository concept allows for keeping the source code well separated for
different concerns. For example, the platform-specific code for each target
platform is located in a dedicated 'base-<platform>' repository. Also, different
abstraction levels and features of the system are residing in different
repositories. The 'etc/build.conf' file defines the set of repositories to
consider in the build process. At build time, the build system overlays the
directory structures of all repositories specified via the 'REPOSITORIES'
declaration to form a single logical source tree. By changing the list of
'REPOSITORIES', the view of the build system on the source tree can be altered.
The 'etc/build.conf' as found in a fresh created build directory will list the
'base-<platform>' repository of the platform selected at the 'create_builddir'
command line as well as the 'base', 'os', and 'demo' repositories needed for
compiling Genode's default demonstration scenario. Furthermore, there are a
number of commented-out lines that can be uncommented for enabling additional
repositories.
Note that the order of the repositories listed in the 'REPOSITORIES' declaration
is important. Front-most repositories shadow subsequent repositories. This
makes the repository mechanism a powerful tool for tweaking existing repositories:
By adding a custom repository in front of another one, customized versions of
single files (e.g., header files or target description files) can be supplied to
the build system without changing the original repository.
Building targets
================
To build all targets contained in the list of 'REPOSITORIES' as defined in
'etc/build.conf', simply issue 'make'. This way, all components that are
compatible with the build directory's base platform will be built. In practice,
however, only some of those components may be of interest. Hence, the build
can be tailored to those components which are of actual interest by specifying
source-code subtrees. For example, using the following command
! make core server/nitpicker
the build system builds all targets found in the 'core' and 'server/nitpicker'
source directories. You may specify any number of subtrees to the build
system. As indicated by the build output, the build system revisits
each library that is used by each target found in the specified subtrees.
This is very handy for developing libraries because instead of re-building
your library and then your library-using program, you just build your program
and that's it. This concept even works recursively, which means that libraries
may depend on other libraries.
In practice, you won't ever need to build the _whole tree_ but only the
targets that you are interested in.
Cleaning the build directory
============================
To remove all but kernel-related generated files, use
! make clean
To remove all generated files, use
! make cleanall
Both 'clean' and 'cleanall' won't remove any files from the 'bin/'
subdirectory. This makes the 'bin/' a safe place for files that are
unrelated to the build process, yet required for the integration stage, e.g.,
binary data.
Controlling the verbosity of the build process
==============================================
To understand the inner workings of the build process in more detail, you can
tell the build system to display each directory change by specifying
! make VERBOSE_DIR=
If you are interested in the arguments that are passed to each invocation of
'make', you can make them visible via
! make VERBOSE_MK=
Furthermore, you can observe each single shell-command invocation by specifying
! make VERBOSE=
Of course, you can combine these verboseness toggles for maximizing the noise.
Enabling parallel builds
========================
To utilize multiple CPU codes during the build process, you may invoke 'make'
with the '-j' argument. If manually specifying this argument becomes an
inconvenience, you may add the following line to your 'etc/build.conf' file:
! MAKE += -j<N>
This way, the build system will always use '<N>' CPUs for building.
Caching inter-library dependencies
==================================
The build system allows to repeat the last build without performing any
library-dependency checks by using:
! make again
The use of this feature can significantly improve the work flow during
development because in contrast to source-codes, library dependencies rarely
change. So the time needed for re-creating inter-library dependencies at each
build can be saved.
Repository directory layout
###########################
Each Genode repository has the following layout:
Directory | Description
------------------------------------------------------------
'doc/' | Documentation, specific for the repository
------------------------------------------------------------
'etc/' | Default configuration of the build process
------------------------------------------------------------
'mk/' | The build system
------------------------------------------------------------
'include/' | Globally visible header files
------------------------------------------------------------
'src/' | Source codes and target build descriptions
------------------------------------------------------------
'lib/mk/' | Library build descriptions
For each custom source-code repository supplied to the build system, the
following subdirectories are mandatory:
! lib/mk/
! src/
! include/
Creating targets and libraries
##############################
Target descriptions
===================
A good starting point is to look at the init target. The source code of init is
located at 'os/src/init/'. In this directory, you will find a target description
file named 'target.mk'. This file contains the building instructions and it is
usually is very simple. The build process is controlled by defining the
following variables.
Build variables to be defined by you
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:'TARGET': is the name of the binary to be created. This is the
only *mandatory variable* to be defined in a 'target.mk' file.
:'REQUIRES': expresses the requirements that must be satisfied in order to
build the target. You find more details about the underlying mechanism in
Section [Specializations].
:'LIBS': is the list of libraries that are used by the target.
:'SRC_CC': contains the list of '.cc' source files. The default search location
for source codes is the directory, where the 'target.mk' file resides.
:'SRC_C': contains the list of '.c' source files.
:'SRC_S': contains the list of assembly '.s' source files.
:'SRC_BIN': contains binary data files to be linked to the target.
:'INC_DIR': is the list of include search locations. Directories should
always be appended by using +=. Never use an assignment!
:'EXT_OBJECTS': is a list of Genode-external objects or libraries. This
variable is mostly used for interfacing Genode with legacy software
components.
Rarely used variables
---------------------
:'CC_OPT': contains additional compiler options to be used for '.c' as
well as for '.cc' files.
:'CC_CXX_OPT': contains additional compiler options to be used for the
C++ compiler only.
:'CC_C_OPT': contains additional compiler options to be used for the
C compiler only.
Specifying search locations
~~~~~~~~~~~~~~~~~~~~~~~~~~~
When specifying search locations for header files via the 'INC_DIR' variable or
for source files via 'vpath', relative pathnames are illegal to use. Instead,
you can use the following variables to reference locations within the
source-code repository, where your target lives:
:'REP_DIR': is the base directory of the current source-code repository.
Normally, specifying locations relative to the base of the repository is
never used by 'target.mk' files but needed by library descriptions.
:'PRG_DIR': is the directory, where your 'target.mk' file resides. This
variable is always to be used when specifying a relative path.
Library descriptions
====================
In contrast to target descriptions that are scattered across the whole source
tree, library descriptions are located at the central place 'lib/mk'. Each
library corresponds to a '<libname>.mk' file. The base of the description file
is the name of the library. Therefore, no 'TARGET' variable needs to be set.
The source-code locations are expressed as '$(REP_DIR)'-relative 'vpath'
commands.
Library-description files support the following additional declarations:
:'SHARED_LIB = yes': declares that the library should be built as a shared
object rather than a static library. The resulting object will be called
'<libname>.lib.so'.
Specializations
===============
Building components for different platforms likely implicates portions of code
that are tied to certain aspects of the target platform. For example, a target
platform may be characterized by
* A kernel API such as L4v2, Linux, L4.sec,
* A hardware architecture such as x86, ARM, Coldfire,
* A certain hardware facility such as a custom device, or
* Other properties such as software license requirements.
Each of these attributes express a specialization of the build process. The
build system provides a generic mechanism to handle such specializations.
The _programmer_ of a software component knows the properties on which his
software relies and thus, specifies these requirements in his build description
file.
The _user/customer/builder_ decides to build software for a specific platform
and defines the platform specifics via the 'SPECS' variable per build
directory in 'etc/specs.conf'. In addition to an (optional) 'etc/specs.conf'
file within the build directory, the build system incorporates the first
'etc/specs.conf' file found in the repositories as configured for the
build directory. For example, for a 'linux_x86' build directory, the
'base-linux/etc/specs.conf' file is used by default. The build directory's
'specs.conf' file can still be used to extend the 'SPECS' declarations, for
example to enable special features.
Each '<specname>' in the 'SPECS' variable instructs the build system to
* Include the 'make'-rules of a corresponding 'base/mk/spec-<specname>.mk'
file. This enables the customization of the build process for each platform.
* Search for '<libname>.mk' files in the 'lib/mk/<specname>/' subdirectory.
This way, we can provide alternative implementations of one and the same
library interface for different platforms.
Before a target or library gets built, the build system checks if the 'REQUIRES'
entries of the build description file are satisfied by entries of the 'SPECS'
variable. The compilation is executed only if each entry in the 'REQUIRES'
variable is present in the 'SPECS' variable as supplied by the build directory
configuration.
Automated integration and testing
#################################
Genode's cross-kernel portability is one of the prime features of the
framework. However, each kernel takes a different route when it comes to
configuring, integrating, and booting the system. Hence, for using a particular
kernel, profound knowledge about the boot concept and the kernel-specific tools
is required. To streamline the testing of Genode-based systems across the many
different supported kernels, the framework comes equipped with tools that
relieve you from these peculiarities.
Run scripts
===========
Using so-called run scripts, complete Genode systems can be described in a
concise and kernel-independent way. Once created, a run script can be used
to integrate and test-drive a system scenario directly from the build directory.
The best way to get acquainted with the concept is reviewing the run script
for the 'hello_tutorial' located at 'hello_tutorial/run/hello.run'.
Let's revisit each step expressed in the 'hello.run' script:
* Building the components needed for the system using the 'build' command.
This command instructs the build system to compile the targets listed in
the brace block. It has the same effect as manually invoking 'make' with
the specified argument from within the build directory.
* Creating a new boot directory using the 'create_boot_directory' command.
The integration of the scenario is performed in a dedicated directory at
'<build-dir>/var/run/<run-script-name>/'. When the run script is finished,
this directory will contain all components of the final system. In the
following, we will refer to this directory as run directory.
* Installing the Genode 'config' file into the run directory using the
'install_config' command. The argument to this command will be written
to a file called 'config' at the run directory picked up by
Genode's init process.
* Creating a bootable system image using the 'build_boot_image' command.
This command copies the specified list of files from the '<build-dir>/bin/'
directory to the run directory and executes the platform-specific steps
needed to transform the content of the run directory into a bootable
form. This form depends on the actual base platform and may be an ISO
image or a bootable ELF image.
* Executing the system image using the 'run_genode_until' command. Depending
on the base platform, the system image will be executed using an emulator.
For most platforms, Qemu is the tool of choice used by default. On Linux,
the scenario is executed by starting 'core' directly from the run
directory. The 'run_genode_until' command takes a regular expression
as argument. If the log output of the scenario matches the specified
pattern, the 'run_genode_until' command returns. If specifying 'forever'
as argument (as done in 'hello.run'), this command will never return.
If a regular expression is specified, an additional argument determines
a timeout in seconds. If the regular expression does not match until
the timeout is reached, the run script will abort.
Please note that the 'hello.run' script does not contain kernel-specific
information. Therefore it can be executed from the build directory of any base
platform by using:
! make run/hello
When invoking 'make' with an argument of the form 'run/*', the build system
will look in all repositories for a run script with the specified name. The run
script must be located in one of the repositories 'run/' subdirectories and
have the file extension '.run'.
For a more comprehensive run script, 'os/run/demo.run' serves as a good
example. This run script describes Genode's default demo scenario. As seen in
'demo.run', parts of init's configuration can be made dependent on the
platform's properties expressed as spec values. For example, the PCI driver
gets included in init's configuration only on platforms with a PCI bus. For
appending conditional snippets to the 'config' file, there exists the 'append_if'
command, which takes a condition as first and the snippet as second argument.
To test for a SPEC value, the command '[have_spec <spec-value>]' is used as
condition. Analogously to how 'append_if' appends strings, there exists
'lappend_if' to append list items. The latter command is used to conditionally
include binaries to the list of boot modules passed to the 'build_boot_image'
command.
The run mechanism explained
===========================
Under the hood, run scripts are executed by an expect interpreter. When the
user invokes a run script via 'make run/<run-script>', the build system invokes
the run tool at '<genode-dir>/tool/run' with the run script as argument. The
run tool is an expect script that has no other purpose than defining several
commands used by run scripts, including a platform-specific script snippet
called run environment ('env'), and finally including the actual run script.
Whereas 'tool/run' provides the implementations of generic and largely
platform-independent commands, the 'env' snippet included from the platform's
respective 'base-<platform>/run/env' file contains all platform-specific
commands. For reference, the most simplistic run environment is the one at
'base-linux/run/env', which implements the 'create_boot_directory',
'install_config', 'build_boot_image', and 'run_genode_until' commands for Linux
as base platform. For the other platforms, the run environments are far more
elaborative and document precisely how the integration and boot concept works
on each platform. Hence, the 'base-<platform>/run/env' files are not only
necessary parts of Genode's tooling support but serve as resource for
peculiarities of using each kernel.
Using run script to implement test cases
========================================
Because run scripts are actually expect scripts, the whole arsenal of
language features of the Tcl scripting language is available to them. This
turns run scripts into powerful tools for the automated execution of test
cases. A good example is the run script at 'libports/run/lwip.run', which tests
the lwIP stack by running a simple Genode-based HTTP server on Qemu. It fetches
and validates a HTML page from this server. The run script makes use of a
regular expression as argument to the 'run_genode_until' command to detect the
state when the web server becomes ready, subsequently executes the 'lynx' shell
command to fetch the web site, and employs Tcl's support for regular
expressions to validate the result. The run script works across base platforms
that use Qemu as execution environment.
To get the most out of the run mechanism, a basic understanding of the Tcl
scripting language is required. Furthermore the functions provided by
'tool/run' and 'base-<platform>/run/env' should be studied.
Automated testing across base platforms
=======================================
To execute one or multiple test cases on more than one base platform, there
exists a dedicated tool at 'tool/autopilot'. Its primary purpose is the
nightly execution of test cases. The tool takes a list of platforms and of
run scripts as arguments and executes each run script on each platform. The
build directory for each platform is created at
'/tmp/autopilot.<username>/<platform>' and the output of each run script is
written to a file called '<platform>.<run-script>.log'. On stderr, autopilot
prints the statistics about whether or not each run script executed
successfully on each platform. If at least one run script failed, autopilot
returns a non-zero exit code, which makes it straight forward to include
autopilot into an automated build-and-test environment.

267
doc/coding_style.txt Normal file
View File

@@ -0,0 +1,267 @@
Coding style guidelines for Genode
##################################
Things to avoid
===============
Please avoid using pre-processor macros. C++ provides language
features for almost any case, for which a C programmer uses
macros.
:Defining constants:
Use 'enum' instead of '#define'
! enum { MAX_COLORS = 3 };
! enum {
! COLOR_RED = 1,
! COLOR_BLUE = 2,
! COLOR_GREEN = 3
! };
:Meta-programming:
Use templates instead of pre-processor macros.
In contrast to macros, templates are type-safe
and fit well with the implementation syntax.
:Conditional-code inclusion:
Please avoid C-hacker style '#ifdef CONFIG_PLATFROM' - '#endif'
constructs but instead, factor-out the encapsulated code into a
separate file and introduce a proper function interface.
The build process should then be used to select the appropriate
platform-specific files at compile time. Keep platform dependent
code as small as possible. Never pollute existing generic code
with platform-specific code.
Header of each file
===================
! /*
! * \brief Short description of the file
! * \author Original author
! * \date Creation date
! *
! * Some more detailed description. This is optional.
! */
Identifiers
===========
* First character of class names uppercase, any other characters lowercase
* Function and variable names lower case
* 'Multi_word_identifiers' via underline
* 'CONSTANTS' upper case
* Private and protected members of a class begin with an '_'-character
* Accessor functions are named after their corresponding attributes:
! /**
! * Request private member variable
! */
! int value() { return _value; }
!
! /**
! * Set the private member variable
! */
! void value(int value) { _value = value; }
Indentation
===========
* Use one tab per indentation step. *Do not mix tabs and spaces!*
* Use no tabs except at the beginning of a line.
* Use spaces for alignment
See [http://web.archive.org/web/20050311153439/http://electroly.com/mt/archives/000002.html]
for a more detailed description.
This way, everyone can set his preferred tabsize in his editor
and the source code always looks good.
Switch statements
~~~~~~~~~~~~~~~~~
Switch-statement blocks should be indented as follows:
! switch (color) {
!
! case BLUE:
! <tab>break;
!
! case GREEN:
! <tab>{
! <tab><tab>int declaration_required;
! <tab><tab>...
! <tab>}
!
! default:
! }
Please note that the case labels have the same indentation
level as the switch statement. This avoids a two-level
indentation-change at the end of the switch block that
would occur otherwise.
Vertical whitespaces
====================
In header files:
* Leave two empty lines between classes.
* Leave one empty line between member functions.
In implementation files:
* Leave two empty lines between functions.
Braces
======
* Braces after class, struct and function names are placed at a new line:
! class Foo
! {
! public:
!
! void function(void)
! {
! ...
! }
! };
except for single-line functions.
* All other occurrences of open braces (for 'if', 'while', 'do', 'for',
'namespace', 'enum' etc.) are at the end of a line:
! if (flag) {
! ..
! } else {
! ..
! }
* Surprisingly, one-line functions should be written on one line.
Typically, this applies for accessor functions.
If slightly more space than one line is needed, indent as follows:
! int heavy_computation(int a, int lot, int of, int args) {
! return a + lot + of + args; }
Comments
========
Function header
~~~~~~~~~~~~~~~
Each public or protected (but no private) function in a header-file should be
prepended by a header as follows:
! /**
! * Short description
! *
! * \param a meaning of parameter a
! * \param b meaning of parameter b
! * \param c,d meaning of parameters c and d
! *
! * \return meaning of return value
! * \retval 0 meaning of the return value 0
! *
! * More detailed information about the function. This is optional.
! */
Descriptions of parameters and return values should be lower-case and brief.
More elaborative descriptions can be documented in the text area below.
In implementation files, only local and private functions should feature
function headers.
Single-line comments
~~~~~~~~~~~~~~~~~~~~
! /* use this syntax for single line comments */
A single-line comment should be prepended by an empty line.
Single-line comments should be short - no complete sentences. Use lower-case.
C++-style comments ('//') should only be used for temporarily commenting-out
code. Such commented-out garbage is easy to 'grep' and there are handy
'vim'-macros available for creating and removing such comments.
Variable descriptions
~~~~~~~~~~~~~~~~~~~~~
Use the same syntax as for single-line comments. Insert two or more
spaces before your comment starts.
! int size; /* in kilobytes */
Multi-line comments
~~~~~~~~~~~~~~~~~~~
Multi-line comments are more detailed descriptions in the form of
sentences.
A multi-line comment should be enclosed by empty lines.
! /*
! * This is some tricky
! * algorithm that works
! * as follows:
! * ...
! */
The first and last line of a multi-line comment contain no words.
Source-code blocks
~~~~~~~~~~~~~~~~~~
For structuring your source code, you can entitle the different
parts of a file like this:
! <- two empty lines
!
! /********************
! ** Event handlers **
! ********************/
! <- one empty line
Note the two stars at the left and right. There are two of them to
make the visible width of the border match its height (typically,
characters are ca. twice as high as wide).
A source-code block header represents a headline for the following
code. To couple this headline with the following code closer than
with previous code, leave two empty lines above and one empty line
below the source-code block header.
Order of public, protected, and private blocks
==============================================
For consistency reasons, use the following class layout:
! class Sandstein
! {
! private:
! ...
! protected:
! ...
! public:
! };
Typically, the private section contains member variables that are used
by public accessor functions below. In this common case, we only reference
symbols that are defined above as it is done when programming plain C.
Leave one empty line (or a line that contains only a brace) above and below
a 'private', 'protected', or 'public' label. This also applies when the
label is followed by a source-code block header.

357
doc/components.txt Normal file
View File

@@ -0,0 +1,357 @@
==========================
Genode components overview
==========================
Norman Feske
Abstract
########
Genode comes with a growing number of components apparently scattered across
various repositories. This document provides an overview of these components
and outlines the systematics behind them.
Categorization of components
############################
Genode components usually fall into one of four categories, namely device
drivers, resource multiplexers, protocol stacks, and applications. Each
of them is briefly characterized as follows:
:Device drivers: translate hardware resources into device-independent
session interfaces. Naturally, a device driver is specific to a
particular hardware platform. The hardware resources are accessed
via core's IO_MEM, IO_PORT, and IRQ services. The functionality of
the driver is made available to other system components by announcing
one of Genode's device-independent session interfaces, which are
'pci_session', 'framebuffer_session', 'input_session', 'block_session',
'audio_out_session', 'log_session', 'nic_session', and 'timer_session'
(see 'os/include/' for the interface definitions). Those interfaces are
uniform across hardware platforms and kernel base platforms. Usually,
each device driver can accommodate only one client at a time.
:Resource multiplexers: provide mechanisms to multiplex device resources
to multiple clients. A typical resource multiplexer requests one
of Genode's device-independent session interface (usually connected
to a device driver) and, in turn, announces a service of the same kind.
However, in contrast to a device driver, a resource multiplexer is able
to serve more than one client at the same time.
:Protocol stacks: translate low-level interfaces to higher-level
interfaces (or sometimes vice versa). Typically, a protocol stack comes
in the form of a library, which uses a device-independent session
interface as back end and provides a high-level library interface as
front end. However, protocol stacks also exist in the form of
distinct components that implement translations between different
session interfaces.
:Applications: implement functionality using APIs as provided by
protocol stacks.
:Runtime environments: enable existing 3rd-party software to be executed
as a Genode sub systems.
Device drivers
##############
Device drivers usually reside in the 'src/drivers' subdirectory of source-code
repositories. The most predominant repositories hosting device drivers are
'os', 'linux_drivers', 'dde_ipxe'.
Platform devices
================
:'os/src/drivers/pci':
Implements the PCI-session interface using the PCI controller as found on
x86 PC hardware. Using this interface, a client can probe for a particular
device and request information about physical device resources (using the
'pci_device' interface). These information are subsequently used to request
respective IO_MEM, IRQ, and IO_PORT sessions at core.
UART devices
============
The UART device drivers implement the terminal-session interface.
:'os/src/drivers/uart/pl011':
Driver for the PL011 UART as found on many ARM-based platforms.
:'os/src/drivers/uart/i8250':
Driver for the i8250 UART as found on PC hardware.
Framebuffer and input drivers
=============================
Framebuffer and input drivers implement the framebuffer-session interface and
input-session interfaces respectively.
:'os/src/drivers/input/dummy':
Pseudo input driver without accessing any hardware. This component is useful
to resolve a dependency from an input session for scenarios where no user
input is required.
:'os/src/drivers/input/fiasco_ux':
Driver for the virtual hardware provided by the user-mode version of the
Fiasco kernel.
:'os/src/drivers/input/ps2/x86':
Driver for the 'i8042' PS/2 controller as found in x86 PCs. It supports both
mouse (including ImPS/2, ExPS/2) and keyboard.
:'os/src/drivers/input/ps2/pl050':
Driver for the PL050 PS/2 controller as found on ARM platforms such as
VersatilePB. The physical base address used by the driver is obtained at
compile time from a header file called 'pl050_defs.h'. The version of the
VersatilePB platform can be found at 'os/include/platform/vpb926/' and
is made available to the driver via the SPECS machinery of the Genode build
system.
:'os/src/drivers/framebuffer/vesa':
Driver using VESA mode setting on x86 PCs. For more information, please refer
to the README file in the driver directory.
:'os/src/drivers/framebuffer/pl11x':
Driver for the PL110/PL111 LCD display.
:'os/src/drivers/framebuffer/sdl':
Serves as both framebuffer and input driver on Linux using libSDL. This
driver is only usable on the Linux base platform.
:'os/src/drivers/framebuffer/fiasco_ux':
Driver for the virtual framebuffer device provided by the user-mode Fiasco
kernel.
:'linux_drivers/src/drivers/usb':
USB driver that makes USB HID devices available as input sessions.
For an example of using this driver, refer to the run script at
'linux_drivers/run/usb_hid'.
Timer drivers
=============
All timer drivers implement the timer-session interface. Technically, a timer
driver is both a device driver (accessing a timer device) and a resource
multiplexer (supporting multiple timer-session clients at the same time). The
timer implementations differ in their use of different time sources and the
mode of internal operation of the timer sessions. Time sources are either
hardware timers, a time source provided by the kernel, or a pseudo time source
(busy).
The internal operation of the timer session depends on the kernel. On kernels
with support for out-of-order RPCs, all timer sessions are handled by a single
thread. Otherwise, each timer session uses a dedicated thread.
:'timer/nova': PIT as time source, multi-threaded
:'timer/codezero': busy time source, single-threaded
:'timer/okl4_arm': busy time source, single-threaded
:'timer/okl4_x86': PIT as time source, single-threaded
:'timer/foc': IPC timeout as time source, multi-threaded
:'timer/fiasco': IPC timeout as time source, single-threaded
:'timer/pistachio': IPC timeout as time source, single-threaded
:'timer/linux': nanosleep as time source, single-threaded
Audio output drivers
====================
All audio-output drivers implement the audio session interface defined at
'os/include/audio_out_session/'.
:'os/src/drivers/audio_out/linux':
Uses ALSA as back-end on the Linux base platform.
:'linux_drivers/src/drivers/audio_out':
Sound drivers for the most common PC sound hardware, ported from the Linux
kernel.
Block drivers
=============
All block drivers implement the block-session interface defined at
'os/include/block_session/'.
:'os/src/drivers/atapi':
Driver for ATAPI CD-ROM devices on x86 PCs.
:'os/src/drivers/sd_card':
Driver for SD-cards connected via the PL180 device as found on the PBX-A9
platform.
:'linux_drivers/src/drivers/usb':
USB driver that makes USB storage devices available as block sessions.
For an example of using this driver, refer to the run script at
'linux_drivers/run/usb_storage'.
:'os/src/drivers/ahci':
Driver for SATA disks on x86 PCs.
Network interface drivers
=========================
All network interface drivers implement the NIC session interface
defined at 'os/include/nic_session'.
:'os/src/drivers/nic/linux':
Driver that uses a Linux tap device as back end. It is only useful on the
Linux base platform.
:'os/src/drivers/nic/lan9118':
Native device driver for the LAN9118 network adaptor as featured on the
PBX-A9 platform.
:'dde_ipxe/src/drivers/nic':
Device drivers ported from the iPXE project. Supported devices are Intel
E1000 and pcnet32.
:'linux_drivers/src/drivers/madwifi':
The MadWifi wireless stack ported from the Linux kernel.
Resource multiplexers
#####################
By convention, resource multiplexers are located at the 'src/server'
subdirectory of a source repository.
:Framebuffer and input: The framebuffer and input session interfaces can be
multiplexed using the Nitpicker GUI server, which allows multiple clients to
create and manage rectangular areas on screen. Nitpicker uses one input
session and one framebuffer session as back end and, in turn, provides
so-called nitpicker sessions to one or multiple clients. Each nitpicker
session contains a virtual framebuffer and a virtual input session. Nitpicker
(including a README file) is located at 'os/src/server/nitpicker'.
:Audio output: The audio mixer located at 'os/src/server/mixer' enables
multiple clients to use the audio-out interface. The mixing is done by simply
adding and clamping the signals of all present clients.
:Networking: The NIC bridge located at 'os/src/server/nic_bridge' multiplexes
one NIC session to multiple virtual NIC sessions using a proxy-ARP
implementation. Each client has to obtain a dedicated IP address visible to
the physical network. DHCP requests originating from the virtual NIC sessions
are delegated to the physical network.
:Block: The block-device partition server at 'os/src/server/part_blk' reads
the partition table of a block session and exports each partition found as
separate block session. For using this server, please refer to the run
script at 'os/run/part_blk'.
Protocol stacks
###############
Protocol stacks come either in the form of separate components that translate
one session interface to another, or in the form of libraries.
Separate components:
:'os/src/server/nit_fb':
Translates a nitpicker session to a pair of framebuffer and input sessions.
Each 'nit_fb' instance is visible as a rectangular area on screen presenting
a virtual frame buffer. The area is statically positioned. For more
information, please refer to 'os/src/server/nit_fb/README'.
:'demo/src/server/liquid_framebuffer':
Implements the same translation as 'nit_fb' but by presenting an interactive
window rather than a statically positioned screen area.
:'os/src/server/tar_rom':
Provides each file contained in a tar file obtained via Genode's ROM session
as separate ROM session.
:'os/src/server/iso9660':
Provides each file of an ISO9660 file system accessed via a block session as
separate ROM session.
:'os/src/server/rom_loopdev':
Provides the content of a ROM file as a block session, similar to the
loop-mount mechanism on Linux
:'demo/src/server/nitlog':
Provides a LOG session, printing log output on screen via a nitpicker
session.
Libraries:
:'libports/lib/mk/libc_log':
Redirects the standard output of the libc to Genode's LOG session interface.
:'libports/lib/mk/libc_lwip_nic_dhcp':
Translates the BSD socket API to a NIC session using the lwIP stack.
:'libports/lib/mk/gallium' + 'linux_drivers/lib/mk/gpu_i915_drv':
Translates the OpenGL API to a framebuffer session using the MESA OpenGL
stack and the Intel GEM GPU driver.
:'libports/lib/mk/sdl':
Translates the libSDL API to framebuffer and input sessions.
:'qt4':
Qt4 framework, using nitpicker session and NIC session as back end.
Applications
############
Applications are Genode components that use other component's services but
usually do not provide services. They are typically located in the 'src/app/'
subdirectory of a repository. Most applications come with README files
located in their respective directory.
:'demo/src/app/backdrop':
Nitpicker client application that sets a PNG image as desktop background.
:'demo/src/app/launchpad':
Graphical application for interactively starting and killing subsystems.
:'demo/src/app/scout':
Graphical hypertext browser used for Genode's default demonstration scenario.
:'libports/src/app/eglgears':
Example program for using OpenGL via the Gallium3D graphics stack.
:'ports/src/app/arora':
Arora is a Qt4-based web browser using the Webkit engine.
:'ports/src/app/gdb_monitor':
Application that allows the debugging of a process via GDB over a remote
connection.
:'qt4/src/app/qt_launchpad':
Graphical application starter implemented using Qt4.
:'qt4/src/app/examples/':
Several example applications that come with Qt4.
:'os/src/app/xvfb':
Is a proxy application that enables the integration of a virtual X server
into a Nitpicker session on the Linux base platform.
Runtime environments
####################
:'ports/src/noux': Noux is an experimental implementation of a UNIX-like API
that enables the use of unmodified command-line based GNU software. For using
noux, refer to the run script 'ports/run/noux.run'.
:'ports-okl4/src/oklinux': OKLinux is a paravirtualized Linux kernel that
enables the use of Linux-based OSes as subsystems on the OKL4 kernel. For
using OKLinux, refer to the run script 'ports-okl4/run/lx_block.run'.
:'ports-foc/src/l4linux': L4Linux is a paravirtualized Linux kernel that
enables the use of Linux-based OSes as subsystems on the Fiasco.OC kernel.
For using L4Linux, refer to the run script 'ports-foc/run/l4linux.run'.

78
doc/conventions.txt Normal file
View File

@@ -0,0 +1,78 @@
Conventions for the Genode development
Norman Feske
Documentation
#############
We use the GOSH syntax
[http://os.inf.tu-dresden.de/~nf2/files/GOSH/current/gosh.txt]
for documentation and README files.
README files
############
Each directory should contain a file called 'README' that briefly explains
what the directory is about. In 'doc/Makefile' is a rule for
generating a directory overview from the 'README' files automatically.
You can structure your 'README' file by using the GOSH style for subsections:
! Subsection
! ~~~~~~~~~~
Do not use chapters or sections in your 'README' files.
Filenames
#########
All normal filenames are lowercase. Filenames should be chosen to be
expressive. Someone who explores your files for the first time might not
understand what 'mbi.cc' means but 'multiboot_info.cc' would ring a bell. If a
filename contains multiple words, use the '_' to separate them (instead of
'miscmath.h', use 'misc_math.h').
Coding style
############
A common coding style helps a lot to ease collaboration. The official coding
style of the Genode base components is described in 'doc/coding_style.txt'.
If you consider working closely together with the Genode main developers,
your adherence to this style is greatly appreciated.
Include files and RPC interfaces
################################
Never place include files directly into the '<repository>/include/' directory
but use a meaningful subdirectory that corresponds to the component that
provides the interfaces.
Each RPC interface is represented by a separate include subdirectory. For
an example, see 'base/include/ram_session/'. The headerfile that defines
the RPC function interface has the same base name as the directory. The RPC
stubs are called 'client.h' and 'server.h'. If your interface uses a custom
capability type, it is defined in 'capability.h'. Furthermore, if your
interface is a session interface of a service, it is good practice to
provide a connection class in a 'connection.h' file for managing session-
construction arguments and the creation and destruction of sessions.
Specialization-dependent include directories are placed in 'include/<specname>/'.
Service Names
#############
Service names as announced via the 'parent()->announce()' function follow
the following convention:
Core's services, which are the most fundamental base services are written
completely upper case. Each developer should be aware of the meaning of the
used acronyms such as RAM, RM, ROM. All other service names should be
descriptive names rather than acronyms. Service names should contain only
letters, numbers, and underline characters. The first character must
always be an uppercase letter, all other characters are lowercase.

View File

@@ -0,0 +1,68 @@
Future optimizations of Genode
Norman Feske
Abstract
########
This document outlines possible optimizations for Genode.
In the first place, Genode was meant as a feasibility study.
Therefore, optimizing performance and memory-consumption was
not a primary goal of the experiment. However, there exist
several ideas to improve these properties. These ideas are
definitely not to be regarded as ToDo items. Each idea should
only be conducted if it fixes a _real_ hotspot in the system
that was found by quantitative analysis.
Memory consumption
##################
Currently, we use an AVL-tree-based best-fit memory allocator
('Allocator_avl') as Heap. Despite, this allocator was
intended to be used only for the root allocator for physical
memory inside Core, we use it as the basis for the current
heap implementation. This way, we can reuse the code,
reducing the overall code complexity.
The AVL-tree-based allocator uses a meta-data entry of 32
bytes per free or used memory block. This means that each
memory allocation from the heap introduces a meta-data
overhead of 32 up to 64 bytes. When allocating a lot of
small objects, this overhead is very high.
:Question:: Is this issue a real bottleneck?
Possible improvements are:
* Using slab allocators for known allocation sizes.
Slab entries have a much smaller footprint.
* Creating a list-based allocator implementation for
the heap. This comes at the cost of additional
code complexity.
RPC Performance
###############
We use C++ streams for RPC communication and therefore,
introduced run-time overhead for the dynamic marshaling.
Using an IDL compiler would improve the RPC performance.
Is the RPC performance a real performance problem? What
is the profile of RPC usage? (Number of RPCs per second,
Percentage of CPU time spent on RPCs, Secondary effects
for RPCs such as cache and TLB pollution).
Locking
#######
On L4v2-Genode, locking is implemented via yielding spin locks.
We may consider a L4env-like lock implementation.
Misc
####
Take a look at include/util/string.h and judge by yourself :-)

116
doc/getting_started.txt Normal file
View File

@@ -0,0 +1,116 @@
=============================
How to start exploring Genode
=============================
Norman Feske
Abstract
########
This guide is meant to provide you a painless start with using the Genode OS
Framework. It explains the steps needed to get a simple demo system running
on Linux first, followed by the instructions on how to run the same scenario
on a microkernel.
Quick start to build Genode for Linux
#####################################
The best starting point for exploring Genode is to run it on Linux. Make sure
that your system satisfies the following requirements:
* GNU 'Make' version 3.81 or newer
* 'libSDL-dev'
* 'tclsh' and 'expect'
* 'byacc' (only needed for the L4/Fiasco kernel)
* 'qemu' and 'genisoimage' (for testing non-Linux platforms via Qemu)
Furthermore, you will need to install the official Genode toolchain, which
you can download at [http://genode.org/download/tool-chain].
The Genode build system never touches the source tree but generates object
files, libraries, and programs in a dedicated build directory. We do not have a
build directory yet. For a quick start, let us create one for the Linux base
platform:
! cd <genode-dir>
! ./tool/create_builddir linux_x86 BUILD_DIR=build.lx
The new build directory is called 'build.lx' and configured for the 'linux_x86'
platform. To give Genode a try, build and execute a simple demo scenario via:
! cd build.lx
! make run/demo
By invoking 'make' with the 'run/demo' argument, all components needed by the
demo scenario are built and the demo is executed. If you are interested in
looking behind the scenes of the demo scenario, please refer to
'doc/build_system.txt' and the run script at 'os/run/demo.run'.
Using platforms other than Linux
================================
Running Genode on Linux is the most convenient way to get acquainted with the
framework. However, the point where Genode starts to shine is when used as the
user land executed on a microkernel. The framework supports a variety of
different kernels such as L4/Fiasco, L4ka::Pistachio, OKL4, and NOVA. Those
kernels largely differ in terms of feature sets, build systems, tools, and boot
concepts. To relieve you from dealing with those peculiarities, Genode provides
you with an unified way of using them. For each kernel platform, there exists
a dedicated directory called 'base-<platform>'. Within this directory, you will
find a 'Makefile', which automates the task of downloading the source codes of
the kernel and interfacing the kernel with Genode. Just change to the
respective 'base-<platform>' directory and issue:
! make prepare
Note that each 'base-<platform>' directory comes with a 'README' file, which
you should revisit first when exploring the base platform. Additionally, most
'base-<platform>' directories provide more in-depth information within their
respective 'doc/' subdirectories.
Now that the base platform is prepared, the 'create_builddir' tool can be used
to create a build directory for your platform of choice by giving the platform
as argument. To see the list of available platforms, execute 'create_builddir'
with no arguments.
For example, to give the demo scenario a spin on the OKL4 kernel, the following
steps are required:
# Download the kernel:
! cd <genode-dir>
! make -C base-okl4 prepare
# Create a build directory
! ./tool/create_builddir okl4_x86 BUILD_DIR=build.okl4
# Build and execute the demo using Qemu
! make -C build.okl4 run/demo
The procedure works analogously for the other base platforms.
How to proceed with exploring Genode
####################################
Now that you have taken the first steps into using Genode, you may seek to
get more in-depth knowledge and practical experience. The foundation for doing
so is a basic understanding of the build system. The documentation at
'build_system.txt' provides you with the information about the layout of the
source tree, how new components are integrated, and how complete system
scenarios can be expressed. Equipped with this knowledge, it is time to get
hands-on experience with creating custom Genode components. A good start is the
'hello_tutorial', which shows you how to implement a simple client-server
scenario. To compose complex scenarios out of many small components, the
documentation of the Genode's configuration concept at 'os/doc/init.txt' is an
essential reference.
Certainly, you will have further questions on your way with exploring Genode.
The best place to get these questions answered is the Genode mailing list.
Please feel welcome to ask your questions and to join the discussions:
:Genode Mailing Lists:
[http://genode.org/community/mailing-lists]

830
doc/release_notes-08-11.txt Normal file
View File

@@ -0,0 +1,830 @@
==============================================
Release notes for the Genode OS Framework 8.11
==============================================
Genode Labs
Summary
#######
This document presents the new features and major changes introduced
in version 8.11 of the Genode OS Framework. It is geared towards
people interested in closely following the progress of the Genode
project and to developers who want to adopt their software to our
mainline development. The document aggregates important fragments
of the updated documentation such that you won't need to scan existing
documents for the new bits. Furthermore, it attempts to provide our
rationale behind the taken design decisions.
The general theme for the release 8.11 is enabling the use of the
Genode OS framework for real-world applications. Because we regard
the presence of device drivers and a way to reuse existing library
code as fundamental prerequisites for achieving this goal, the major
new additions are an API for device drivers written in C, an API for
handling asynchronous notifications, and a C runtime. Other noteworthy
improvements are the typification of capabilities at the C++-language
level, a way for receiving and handling application faults, the
introduction of managed dataspaces, and a new API for scheduling
timed events.
Base framework
##############
This section documents the new features and changes affecting the
'base' repository, in particular the base API.
New features
============
Connection handling
~~~~~~~~~~~~~~~~~~~
The interaction of a client with a server involves the definition of
session-construction arguments, the request of the session creation via
its parent, the initialization of the matching RPC-client stub code
with the received session capability, the actual use of the session
interface, and the closure of the session. A typical procedure of
using a service looks like this:
!#include <rom_session/client.h>
!...
!
!/* construct session-argument string and create session */
!char *args = "filename=config, ram_quota=4K");
!Capability session_cap = env()->parent()->session("ROM", args);
!
!/* initialize RPC stub code */
!Rom_session_client rsc(session_cap);
!
!/* invoke remote procedures, 'dataspace' is a RPC function */
!Capability ds_csp = rsc.dataspace();
!...
!
!/* call parent to close the session */
!env()->parent()->close(session_cap);
Even though this procedure does not seem to be overly complicated,
is has raised the following questions and criticism:
* The quota-donation argument is specific for each server. Most services
use client-donated RAM quota only for holding little meta data and,
thus, are happy with a donation of 4KB. Other services maintain larger
client-specific state and require higher RAM-quota donations. The
developer of a client has to be aware about the quota requirements for
each service used by his application.
* There exists no formalism for documenting session arguments.
* Because session arguments are passed to the 'session'-call as a plain
string, there are no syntax checks for the assembled string performed
at compile time. For example, a missing comma would go undetected until
a runtime test is performed.
* There are multiple lines of client code needed to open a session to
a service and the session capability must be maintained manually for
closing the session later on.
The new 'Connection' template provides a way to greatly simplify the
handling of session arguments, session creation, and destruction on the
client side. By implementing a service-specific connection class
inherited from 'Connection', session arguments become plain constructor
arguments, session functions can be called directly on the 'Connection'
object, and the session gets properly closed when destructing the
'Connection'. By convention, the 'Connection' class corresponding to a
service resides in a file called 'connection.h' in the directory of the
service's RPC interface. For each service, a corresponding 'Connection'
class becomes the natural place where session arguments and quota
donations are documented. With this new mechanism in place, the example
above becomes as simple as:
!#include <rom_session/connection.h>
!...
!
!/* create connection to the ROM service */
!Rom_connection rom("config");
!
!/* invoke remote procedure */
!Capability ds_csp = rom.dataspace();
[http://genode.org/documentation/api/base_index#Connecting_to_services - See the API documentation for the connection template...]
Typed capabilities
~~~~~~~~~~~~~~~~~~
A plain 'Capability' is an untyped reference to a remote object of any
type. For example, a capability can reference a thread object or a
session to a service. It is loosely similar to a C void pointer, for which
the programmer maintains the knowledge about which data type is actually
referenced. To facilitate the type-safe use of RPC interfaces at the C++
language level, we introduced a template for creating specialized
capability types ('Typed_capability' in 'base/typed_capability.h') and
the convention that each RPC interface declares a dedicated capability
type. Note that type-safety is not maintained across RPC interfaces. As
illustrated in Figure [img/layered_ipc], typification is done at the
object-framework level on the server side and via in the 'Connection'
classes at the client side.
[image img/layered_ipc]
From the application-developer's perspective, working with capabilities
has now become type-safe, making the produced code more readable and robust.
[http://genode.org/documentation/api/base_index#Capability_representation - See the updated API documentation for the capability representation...]
Fifo data structure
~~~~~~~~~~~~~~~~~~~
Because the 'List' data type inserts new list elements at the list head,
it cannot be used for implementing wait queues requiring first-in
first-out semantics. For such use cases, we introduced a dedicated
'Fifo' template. The main motivation for introducing 'Fifo' into the
base API is the new semaphore described below.
[http://genode.org/documentation/api/base_index#Structured_data_types - See the new API documentation for the fifo template...]
Semaphore
~~~~~~~~~
Alongside lock-based mutual exclusion of entering critical sections,
organizing threads in a producer-consumer relationship via a semaphore
is a common design pattern for thread synchronization. Prior versions
of Genode provided a preliminary semaphore implementation as part of
the 'os' repository. This implementation, however, supported only one
consumer thread (caller of the semaphore's 'down' function). We have
now enhanced our implementation to support multiple consumer threads
and added the semaphore to Genode's official base API. We have made
the wake-up policy in the presence of multiple consumers configurable
via a template argument. The default policy is first-in-first-out.
[http://genode.org/documentation/api/base_index#Synchronization - See the new API documentation for the semaphore...]
Thanks to Christian Prochaska for his valuable contributions to the new
semaphore design.
Asynchronous notifications
~~~~~~~~~~~~~~~~~~~~~~~~~~
Inter-process communication via remote procedure calls requires both
communication partners to operate in a synchronous fashion. The caller
of an RPC blocks as long as the RPC is not answered by the called
server. In order to receive the call, the server has to explicitly
wait for incoming messages. There are a number of situations where
synchronous communication is not suited.
For example, a GUI server wants to deliver a notification to one of its
clients about new input events being available. It does not want to
block on a RPC to one specific client because it has work to do for
other clients. Instead, the GUI server wants to deliver this
_notification_ with _fire-and-forget_ semantics and continue with
its operation immediately, regardless of whether the client received
the notification or not. The client, in turn, does not want to poll
for new input events at the GUI server but it wants to be _waken_up_
when something interesting happens. Another example is a block-device
driver that accepts many requests for read/write operations at once.
The operations may be processed out of order and may take a long time.
When having only synchronous communication available, the client and
the block device driver would have to employ one distinct thread for
each request, which is complicated and a waste of resources. Instead,
the block device driver just wants to acknowledge the completeness of
an operation _asynchronously_.
Because there are many more use cases for asynchronous inter-process
communication, we introduced a new signalling framework that complements
the existing synchronous RPC mode of communication with an interface for
issuing and receiving asynchronous notifications. It defines interfaces
for signal transmitters and signal receivers. A signal receiver can
receive signals from multiple sources, whereas the sources of incoming
signals are clearly distinguishable. One or multiple threads can either
poll or block for incoming signals. Each signal receiver is addressable
via a capability. The signal transmitter provides fire-and-forget
semantics for submitting signals to exactly one signal receiver. Signals
are communicated in a reliable fashion, which means that the exact number
of signals submitted to a signal transmitter is communicated to the
corresponding signal receiver. If notifications are generated at a higher
rate than as they can be processed at the receiver, the transmitter
counts the notifications and delivers the total amount with the next
signal transmission. This way, the total number of notifications gets
properly communicated to the receiver even if the receiver is not highly
responsive. Notifications do not carry any payload because this payload
would have to be queued at the transmitter.
[image img/signals]
Image [img/signals] illustrates the roles of signaller thread,
transmitter, receiver, and signal-handler thread.
[http://genode.org/documentation/api/base_index#Asynchronous_notifications - See the new API documentation for asynchronous notifications...]
The current generic implementation of the signalling API employs one
thread at each transmitter and one thread at each receiver. Because
the used threads are pretty heavy weight with regard to resource usage,
ports of Genode should replace this implementation with platform-
specific variants, for example by using inter-process semaphores or
native kernel support for signals.
Region-manager faults
~~~~~~~~~~~~~~~~~~~~~
In Genode, region-manager (RM) sessions are used to manage the
address-space layout for processes. A RM session is an address-space
layout that can be populated by attaching (portions of) dataspaces to
(regions of) the RM session. Normally, the RM session of a process is
first configured by the parent when decoding the process' ELF binary.
During the lifetime of the process, the process itself may attach
further dataspaces to its RM session to access the dataspace's content.
Core as the provider of the RM service uses this information for
resolving page faults raised by the process. In prior versions of
Genode, core ignored unresolvable page faults, printed a debug message
and halted the page-faulted thread. However, this condition may be of
interest, in particular to the process' parent for reacting on the
condition of a crashed child process. Therefore, we enhanced the RM
interface by a fault-handling mechanism. For each RM session, a fault
handler can be installed by registering a signal receiver capability.
If an unresolvable page fault occurs, core delivers a signal to the
registered fault handler. The fault handler, in turn, can request the
actual state of the RM session (page-fault address) and react upon
the fault. One possible reaction is attaching a new dataspace at the
fault address and thereby implicitly resolving the fault. If core
detects that a fault is resolved this way, it resumes the operation
of the faulted thread.
This mechanism works analogously to how page faults are handled by
CPUs, but on a more abstract level. A (n-level) page table corresponds
to a RM session, a page-table entry corresponds to a dataspace-
attachment, the RM-fault handler corresponds to a page-fault
exception handler, and the resolution of page-faults (RM fault)
follows the same basic scheme:
# Application accesses memory address with no valid page-table-entry
(RM fault)
# CPU generates page-fault exception (core delivers signal to fault
handler)
# Kernel reads exception-stack frame or special register to determine
fault address (RM-fault handler reads RM state)
# Kernel adds a valid page-table entry and returns from exception
(RM-fault handler attaches dataspace to RM session, core resumes
faulted thread)
The RM-fault mechanism is not only useful for detecting crashing child
processes but it enables a straight-forward implementation of growing
stacks and heap transparently for a child process. An example for
using RM-faults is provided at 'base/src/test/rm_fault'.
Note that this mechanism is only available on platforms on which core
resolves page faults. This is the case for kernels of the L4 family.
On Linux however, the Linux kernel resolves page faults and suspends
processes performing unresolvable memory accesses (segmentation fault).
Managed dataspaces (experimental)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The RM-fault mechanism clears the way for an exciting new feature
of Genode 8.11 called managed dataspaces. In prior versions of Genode,
each dataspace referred to a contiguous area of physical memory (or
memory-mapped I/O) obtained by one of core's RAM, ROM, or IO_MEM
services, hence we call them physical dataspaces. We have now added
a second type of dataspaces called managed dataspaces. In contrast
to a physical dataspace, a managed dataspace is backed by the content
described by an RM session. In fact, each RM session can be used as
dataspace and can thereby be attached to other RM sessions.
Combined with the RM fault mechanism described above, managed
dataspaces enable a new realm of applications such as dataspaces
entirely managed by user-level services, copy-on-write dataspaces,
non-contiguous large memory dataspaces that are immune to physical
memory fragmentation, process-local RM fault handlers (e.g., managing
the own thread-stack area as a sub-RM-session), and sparsely populated
dataspaces.
Current limitations
-------------------
Currently, managed dataspaces still have two major limitations. First,
this mechanism allows for creating cycles of RM sessions. Core must
detect such cycles during page-fault resolution. Although, a design for
an appropriate algorithm exists, cycle-detection is not yet implemented.
The missing cycle detection would enable a malicious process to force
core into an infinite loop. Second, RM faults are implemented using the
new signalling framework. With the current generic implementation, RM
sessions are far more resource-demanding than they should be. Once the
signalling framework is optimized for L4, RM sessions and thereby
managed dataspaces will become cheap. Until then, we do not recommend
to put this mechanism to heavy use.
Because of these current limitations, managed dataspaces are marked as
an experimental feature. When building Genode, experimental features are
disabled by default. To enable them, add a file called 'specs.conf'
with the following content to the 'etc/' subdirectory of your build
directory:
! SPECS += experimental
For an example of how to use the new mechanism to manage a part of a
process' own address space by itself, you may take a look at
'base/src/test/rm_nested'.
Changes
=======
Besides the addition of the new features described above, the following
parts of the base framework underwent changes worth describing.
Consistent use of typed capabilities and connection classes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
We applied capability typification to all interfaces of Genode including
the base API and the interfaces defined in the 'os' repository. Figure
[img/base_cap_types] provides an overview about the capability types
provided by the base API.
[image img/base_cap_types]
Overview about the capability types provided by the base API
Furthermore, we have complemented all session interfaces with
appropriate 'Connection' classes taking service-specific session
arguments into account.
For session-interface classes, we introduced the convention to declare
the service name as part of the session-interface via a static member
function:
! static const char *service_name();
Allocator refinements
~~~~~~~~~~~~~~~~~~~~~
Throughout Genode, allocators are not only used for allocating memory
but also for managing address-space layouts and ranges of physical
resources such as I/O-port ranges or IRQ ranges. In these cases, the
address '0' may be a valid value. Consequently, this value cannot be
used to signal allocation errors as done in prior versions of Genode.
Furthermore, because managed dataspaces use the RM session interface to
define the dataspace layout, the address-'0' problem applies here as
well. We have now refined our allocator interfaces and the RM-session
interface to make them fit better for problems other than managing
virtual memory.
Misc changes
~~~~~~~~~~~~
We revised all interfaces to consistently use _exceptions_ to signal
error conditions rather than delivering error codes as return values.
This way, error codes become exception types that have a meaningful
name and, in contrast to global 'errno' definitions, an error exception
type can be defined local to the interface it applies to. Furthermore,
the use of exceptions allows for creating much cleaner looking interfaces.
Traditionally, we have provided our custom _printf_ implementation as C
symbol to make this function available from both C and C++ code. However,
we observed that we never called this function from C code and that the
'printf' symbol conflicts with the libc. Hence, we turned 'printf'
into a C++ symbol residing in the 'Genode' namespace.
Operating-system services and libraries
#######################################
This section documents the new features and changes affecting
the 'os' repository.
New Features
============
Device-driver framework for C device drivers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Genode's base API features everything needed to create user-level device
drivers. For example, the 'os' repository's PS/2 input driver and the
PCI bus driver are using Genode's C++ base API directly. However, most of
today's device drivers are written in C. To ease the reuse of existing
drivers on Genode, we have introduced a C API for device drivers into
Genode's 'os' repository. The API is called DDE kit (DDE is an acronym
for device-driver environment) and it is located at 'os/include/dde_kit'.
The DDE kit API is the result of long-year experiences with porting device
drivers from Linux and FreeBSD to custom OS environments. The following
references are the most significant contributions to the development of
the API.
;
Christian Helmuth created the initial version of the Linux device-driver
environment for L4. He describes his effort of reusing unmodified sound
drivers on the L4 platform in his thesis
[http://os.inf.tu-dresden.de/papers_ps/helmuth-diplom.pdf - Generische Portierung von Linux-Gerätetreibern auf die DROPS-Architektur].
;
Gerd Griessbach approached the problem of re-using Linux USB drivers
by following the DDE approach in his diploma thesis
[http://os.inf.tu-dresden.de/papers_ps/griessbach-diplom.pdf - USB for DROPS].
;
Marek Menzer adapted Linux DDE to Linux 2.6 and explored the DDE
approach for block-device drivers in his student research project
[http://os.inf.tu-dresden.de/papers_ps/menzer-beleg.pdf - Portierung des DROPS Device Driver Environment (DDE) für Linux 2.6 am Beispiel des IDE-Treibers ]
and his diploma thesis
[http://os.inf.tu-dresden.de/papers_ps/menzer-diplom.pdf - Entwicklung eines Blockgeräte-Frameworks für DROPS].
;
Thomas Friebel generalized the DDE approach and introduced the DDE kit
API to enable the re-use of device driver from other platforms than
Linux. In particular, he experimented with the block-device drivers of
FreeBSD in his diploma thesis
[http://os.inf.tu-dresden.de/papers_ps/friebel-diplom.pdf - Übertragung des Device-Driver-Environment-Ansatzes auf Subsysteme des BSD-Betriebssystemkerns].
;
Dirk Vogt successfully re-approached the port of USB device drivers
from the Linux kernel to L4 in his student research project
[http://os.inf.tu-dresden.de/papers_ps/vogt-beleg.pdf - USB for the L4 Environment].
The current incarnation of the DDE kit API provides the following
features:
* General infrastructure such as init calls, assertions, debug output
* Interrupt handling (attach, detach, disable, enable)
* Locks, semaphores
* Memory management (slabs, malloc)
* PCI access (find device, access device config space)
* Virtual page tables (translation between physical and virtual
addresses)
* Memory-mapped I/O, port I/O
* Multi-threading (create, exit, thread-local storage, sleep)
* Timers, jiffies
For Genode, we have created a complete reimplementation of the DDE kit
API from scratch by fully utilizing the existing Genode infrastructure
such as the available structured data types, core's I/O services,
the synchronization primitives, and the thread API.
[image img/dde_kit]
Figure [img/signals] illustrates the role of DDE kit when re-using an
unmodified device driver taken from the Linux kernel. DDE kit translates
Genode's C++ base API to the DDE kit C API. The DDE kit API, in turn, is
used as back end by the Linux driver environment, which translates Linux
kernel interfaces to calls into DDE kit. With this translation in place,
an unmodified Linux device driver can be embedded into the Linux driver
environment. The device API is specific for a class of devices such as
NICs, block devices, or input devices. It can either be used directly as
a function interface by an application that is using the device driver
as a library, or it can be made accessible to external processes via an
RPC interface.
Limitations
-----------
The PCI sub system is not completely implemented, yet.
Alarm API providing a timed event scheduler
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The scheduling of timed events is a recurring pattern found in device
drivers, application frameworks such as Qt4 ('qeventdispatcher'), and
applications. Therefore, we have added a timed event scheduler to the
'os' repository. The new alarm API ('os/include/os/alarm.h') allows
for the scheduling of both one-shot alarms and periodic alarms.
Changes
=======
PS/2 input driver
~~~~~~~~~~~~~~~~~
The original PS/2 driver tried to switch the PS/2 keyboard to
scan-code set 2 and assumed that all modern keyboards support this
mode of operation. However, this assumption was wrong. We observed
that the legacy PS/2 support of some USB keyboards covers only the
emulated (xlate) scan-code set 1 mode. This is also case for the PS/2
emulation in VirtualBox. Therefore, we changed our PS/2 driver to
never touch the keyboard mode but to only detect the current mode
of operation. The driver has now to support both, scan-code set 1 and
scan-code set 2. This change comes along with a slightly more complex
state machine in the driver. Hence, we moved the state machine from
the IRQ handler to a distinct class and changed the control flow of
the driver to fetch only one value from the i8042 PS/2 controller
per received interrupt.
PCI bus driver
~~~~~~~~~~~~~~
Until now, Genode's PCI bus driver was only used for experimentation
purposes. With the forthcoming driver framework however, the PCI bus
driver will play a central role in the system. Therefore, we adapted
the interface of the PCI driver to these requirements. Specifically,
the scanning of the PCI bus can now be performed without constraining
the results by a specific vendor ID.
Nitpicker GUI server
~~~~~~~~~~~~~~~~~~~~
We improved the _output_latency_ of the Nitpicker GUI server by flushing
pixels eagerly and deferring the next periodically scheduled flush.
This change has a positive effect on the responsiveness of the GUI to
user input.
Misc changes
~~~~~~~~~~~~
Prior versions of the 'os' repository came with a custom 'os/include/base'
directory with interfaces extending the base API. To avoid confusion
between the 'base' repository and the 'os' repository, 'os'-local API
extensions are now located at 'os/include/os'. This way, the folder
prefix of include statements indicates well from which repository the
included header files comes from.
C runtime
#########
Most of existing libraries rely on the presence of a C library. For
making the reuse of this software on Genode possible, we have now
made a complete C library available for Genode. It comes as a separate
source-code repository called 'libc' and is based on the code of FreeBSD.
The original code is available at the official FreeBSD website.
:FreeBSD website:
[http://www.freebsd.org/developers/cvs.html]
Our libc port comprises the libraries 'gdtoa', 'gen', 'locale', 'stdio',
'stdlib', 'stdtime', 'string', and 'msun'. Currently, it supports the
x86 architecture. Support for other architectures is planned as future
addition. At the current stage, our back end is very basic and most of
its functions are dummy stubs. We used Christian Prochaska's forthcoming
Genode port of Qt4 as test case and successfully used the new libc as
foundation for building graphical Qt4 applications. We will further
extend the back end in correspondence to the growing feature set of the
Genode OS framework.
:Usage:
To use the libc in your application, just add 'libc' to the 'LIBS'
declaration in your build-description file. This declaration will make
the libc headers available for the include path of your target and link
the C library. When building, make sure that the 'libc' repository is
included in your build configuration ('etc/build.conf').
:Limitations:
The current version of the C library is not thread-safe. For most
string and math functions, this is not a problem (as these functions
do not modify global state) but be careful with using more complex
functions such as 'malloc' from multiple threads. Also, 'errno' may
become meaningless when calling libc functions from multiple threads.
We have left out the following files from the Genode port of the
FreeBSD libc: gdtoa 'strtodnrp.c' (gdtoa), 'getosreldate.c' (gen),
'strcoll.c', 'strxfrm.c', 'wcscoll.c', 'wcsxfrm.c' (string),
's_exp2l.c' ('msun').
The current back end is quite simplistic and it may help you to revisit
the current state of the implementation in the 'libc/src/lib/libc'
directory. If one of the functions in 'dummies.c' is called, you will
see the debug message:
! "<function-name> called, not yet implemented!"
However, some of the back-end function implemented in the other files
have dummy semantics but have to remain quiet because they are called
from low-level libc code.
Build infrastructure
####################
Build-directory creation tool
=============================
Because we think that each Genode developer benefits from knowing the
basics about the functioning of the build system, the manual creation of
build directories is described in Genode's getting-started document.
However, for regular developers, creating build directories becomes a
repetitive task. Hence, it should be automated. We have now added a
simple build-directory creation tool that creates pre-configured build
directories for some supported platforms. The tool is located at
'tool/builddir/create_builddir'. To print its usage information, just
execute the tool without arguments.
Improved linking of binary files
================================
For linking binary data, binary file have to be converted to object
files. Over the time, we have used different mechanisms for this
purpose. Originally, we used 'ld -r -b binary'. Unfortunately, these
linker options are not portable. Therefore, the mechanism was changed
to a 'hexdump' and 'sed' magic that generated a C array from binary data.
This solution however, is complicated and slow. Now, we have adopted
an idea of Ludwig Hähne to use the 'incbin' directive of the GNU
assembler, which is a very clean, flexible, and fast solution.
Lib-import mechanism
====================
Libraries often require specific include files to be available at the
default include search location. For example, users of a C library
expect 'stdio.h' to be available at the root of the include search
location. Placing the library's include files in the root of the
default search location would pollute the include name space for
all applications, regardless if they use the library or not. To
keep library-include files well separated from each other, we have
enhanced our build system by a new mechanism called lib-import.
For each library specified in the 'LIBS' declaration of a build
description file, the build system incorporates a corresponding
'import-<libname>.mk' file into the build process. Such as file
defines library-specific compiler options, in particular additional
include-search locations. The build system searches for lib-import
files in the 'lib/import/' subdirectories of all used repositories.
Using 'ar' for creating libraries
=================================
The previous versions of Genode relied on incremental linking ('ld -r')
for building libraries. This approach is convenient because the linker
resolves all cross-dependencies between libraries regardless of the
order of how libraries are specified at the linker's command line.
However, incremental linking prevents the linker from effectively
detecting dead code. In contrast, when linking '.a' files, the linker
detects unneeded object files. Traditionally, we have only linked our
own framework containing no dead code. This changed with the new 'libc'
support. When linking the 'libc', the presence of dead code becomes
the normal case rather than the exception. Consequently, our old
incremental-linking approach produced exceedingly large binaries
including all functions that come with the 'libc'. We have now adopted
the classic 'ar' mechanism for assembling libraries and use the linker's
'start-group' 'end-group' feature to resolve inter-library-dependencies.
This way, dead code gets eliminated at the granularity of object files.
In the future, we will possible look into the '-ffunction-sections' and
'-gc-sections' features of the GNU tool chain to further improve the
granularity to function level.
If your build-description files rely on custom rules referring to
'lib.o' files, these rules must be adapted to refer to 'lib.a' files
instead.
Misc changes
============
* Added sanity check for build-description files overriding 'INC_DIR'
instead of extending it.
* Restrict inclusion of dependency files to those that actually matter
when building libraries within 'var/libcache'. This change significantly
speeds up the build process in the presence of large libraries such as
Qt4 and libc.
* Added rule for building 'cpp' files analogously to the 'cc' rule.
Within Genode, we name all C++ implementation files with the 'cc'
suffix. However, Qt4 uses 'cpp' as file extension so we have to
support both.
* Build-description files do no longer need the declaration
'REQUIRES = genode'. Genode's include search locations are now
incorporated into the build process by default.
Applications
############
This section refers to the example applications contained in Genode's
'demo' repository.
We have enhanced the _Scout_widgets_ as used by the launchpad and the
Scout tutorial browser to perform all graphical output double-buffered,
which effectively eliminates drawing artifacts that could occur when
exposing intermediate drawing states via direct (unbuffered) output.
Furthermore, we have added a way to constrain the maximum size of
windows to perform pixel-buffer allocations on realistic window sizes.
Both launchpad and Scout can now start child applications. In Scout
this functionality is realized by special "execute" links. We have
generalized the underlying application logic for creating and
maintaining child processes between both applications and placed
the unification into a separate 'launchpad' library.
We have replaced the default document presented in Scout with an
_interactive_walk-through_guide_ explaining the basic features of Genode.
The document uses the new "execute" link facility to let the user start
a launchpad instance by clicking on a link.
Platform-specific changes
#########################
Genode used to define _fixed-width_integer_types_ in a file 'stdint.h'
placed in a directory corresponding to bit-width of the platform, for
example 'include/32bit/stdint.h'. When building for a 32bit platform,
the build system included the appropriate directory into the
include-search path and thereby made 'stdint.h' available at the root
of the include location. Unfortunately, this clashes with the 'stdint.h'
file that comes with the C library. To avoid conflict with libc header
files, we moved the definition of fixed-width integer types to
'32bit/base/fixed_stdint.h'.
For the L4/Fiasco version of Genode, there existed some x86-specific
header files that did not specifically depend on L4/Fiasco, for example
atomic operations. Because these files are not L4/Fiasco-specific and
may become handy for other platforms as well, we moved them to the
generic 'base' repository.
Linux 32bit
===========
:Dissolving Genode's dependency from the glibc:
The port of the C runtime to Genode posed an interesting challenge to
the Linux version of Genode. This version used to rely on certain
functions provided by the underlying glibc:
* For creating and destroying threads, we used to rely on POSIX threads
as provided by the 'pthread' library
* The lock implementation was based on the POSIX semaphore functions
'sem_init', 'sem_wait', and 'sem_post'
* Shared memory was realized by using files ('open', 'close',
'ftruncate') and the 'mmap' interface
* Starting and killing processes was implemented using 'fork' and 'kill'
* Inter-process communication used the glibc's socket functions
For our custom C runtime, we want to override the glibc functionality
with our own implementation. For example, we want to provide the 'mmap'
interface to a Genode application by implementing 'mmap' with
functions of our base API. On Linux, however, this base API, in turn,
used to rely on 'mmap'. This is just an example. The problem applies
also for the other categories mentioned above. We realized that we cannot
rely on the glibc on one hand but at the same time replace it by a custom
C runtime (in fact, we believe that such a thing is possible by using
awkward linker magic but we desire a clean solution). Consequently, we
have to remove the dependency of Genode from the glibc on Linux. Step
by step, we replaced the used glibc functions by custom Linux system-call
bindings. Each binding function has a prefix 'lx_' such that the symbol
won't collide with 'libc' symbols. The new bindings are located at the file
'base-linux/src/platform/linux_syscalls.h'. It consist of 20 functions,
most of them resembling the original interface ('socket', 'connect',
'bind', 'getsockname', 'recvfrom', 'write', 'close', 'open', 'fork',
'execve', 'mmap', 'ftruncate', 'unlink', 'tkill', 'nanosleep').
For other functions, we simplified the semantics for our use case
('sigaction', 'sigpending', 'sigsetmask', 'create_thread'). The most
noteworthy changes are the creation and destruction of threads by
directly using the 'clone' and 'tkill' system calls, and the lock
implementation. Because we cannot anymore rely on the convenience of
using futexes indirectly through the POSIX semaphore interface, we
have adopted the simple locking approach that we already use for the
L4/Fiasco version. This lock implementation is a simple sleeping
spinlock.
:Compromises:
The introduction of custom Linux system-call bindings for Genode has
several pros and cons. With this change, The Linux version of Genode is
not anymore easy to port to other POSIX platforms such as the Darwin
kernel. For each POSIX kernel used as Genode platform, a custom
implementation of our system-call bindings must be created. The
original POSIX variant could still be reanimated, but this version
would inherently lack support for Genode's C runtime, and thus would
have limited value. A positive side effect of this solution, however,
is that 'linux_syscalls.h' documents well the subset of the Linux'
kernel interface that we are actually using.
The replacement of POSIX semaphores with sleeping spinlocks decreases
locking performance quite significantly. In the contention case, the
wakeup from sleeping introduces a high latency of up to one millisecond.
Furthermore, fairness is not guaranteed and the spinning produces a bit
of system load. If this approach turns out to become a serious performance
bottleneck, we will consider creating custom bindings for Linux' futexes.
L4/Fiasco
=========
The concepts of _RM_faults_ and _managed_dataspaces_ as described in
Section [Base framework], had been implemented into the L4/Fiasco
version of core. Although the introduction of these concepts involved
only minimal changes at the API level, the required core-internal
changes had been quite invasive, affecting major parts of the pager
and RM-session implementations.
Prior versions of the L4/Fiasco version of core did not implement
the _cancel-blocking_mechanism_ as specified by the CPU-session API.
The missing implementation resulted in lock-ups when destructing a
thread that blocks for lock. With the new implementation based on
L4/Fiasco's inter-task ex-regs system call, such threads can now
be gracefully destructed.

460
doc/release_notes-09-02.txt Normal file
View File

@@ -0,0 +1,460 @@
==============================================
Release notes for the Genode OS Framework 9.02
==============================================
Genode Labs
Summary
#######
Whereas the focus of the previous release 8.11 was the refinement of
Genode's base API and the creation of the infrastructure needed to build
real-world applications, the release 9.02 is focused on functional
enhancements in two directions. The first direction is broadening the
number of possible base platforms for the framework. At present, most
microkernels bring along a custom user land, which is closely tied to the
particular kernel. Our vision is to establish Genode as a common ground for
developing applications, protocol stacks, and device drivers in such a way
that the software becomes easily portable among different kernels. This
release makes Genode available on the L4ka::Pistachio kernel. Hence,
software developed with the Genode API can now run unmodified on
Linux/x86, L4/Fiasco, and L4ka::Pistachio. In the second direction, we
are steadily advancing the functionality available on top of Genode. With
this release, we introduce a basic networking facility and support for
native Qt4 applications as major new features. Thanks to Genode's
portability, these features become automatically available on all
supported base platforms.
Our original plan for the release 9.02 also comprised the support of a
Linux-on-Genode (para-)virtualization solution. Initially, we intended to
make [http://os.inf.tu-dresden.de/L4/LinuxOnL4/ - L4Linux] available on
the L4/Fiasco version of Genode. However, we identified several downsides
with this approach. Apparently, the development of the officially available
version of L4/Fiasco has become slow and long-known issues remain unfixed.
L4Linux, however, is closely tied to L4/Fiasco and the L4 environment. For
us at Genode Labs, maintaining both a custom port of L4Linux for Genode
and L4/Fiasco by ourself in addition to developing Genode is unfeasible.
In contrast, the Pistachio kernel features more advanced options for
virtualization ([http://l4ka.org/projects/virtualization/afterburn/ - Afterburner]
and VT support) that we want to explore. Furthermore, there exists another
version of L4Linux called OKLinux for the OKL4 kernel developed at
[http://ok-labs.com - OK-Labs], which is very interesting as well.
Therefore, we decided against an ad-hoc solution and deferred this feature
to the next release. [http:/about/road-map - See our updated road map...]
Major new Features
##################
Genode on L4ka::Pistachio
=========================
From the very beginning, the base API of the Genode OS Framework was
designed for portability. We put a lot of effort into finding API
abstractions that are both implementable on a wide range of kernels and as
close to the hardware as possible to keep the abstraction overhead low. For
this reason, we developed the framework in parallel for the Linux kernel and
the L4/Fiasco kernel. To validate our claim that Genode is highly portable,
Julian Stecklina ported the framework to another member of the L4 family,
namely the [http://l4ka.org/projects/pistachio/ - L4ka::Pistachio kernel].
This high-performance kernel implements the latest official L4 API called
L4.x2 and has a number of advanced features such as multi-processor support
and virtualization support.
After Julian successfully created the first Pistachio version of Genode,
we successively refined his work and conducted further unifications among
the platform-dependent code for the different kernels. The result of this
effort is included in this release and comes in the form of the
'base-pistachio' source-code repository.
;Interesting technical notes:
* The IRQ handling on Pistachio is slightly different from L4/Fiasco.
On L4/Fiasco, an IRQ becomes unmasked only when the user-level IRQ
handler thread blocks for an IRQ by issuing an IPC call to the
kernel's corresponding IRQ thread. In contrast, Pistachio unmasks an
IRQ as soon as the user-level IRQ handler associates itself with an
IRQ. Thus, an IRQ message may occur not only when the user-level IRQ
handler blocks for any IRQ but anytime. In particular, IRQ messages
may interfere with the IRQ handler's IPC communication with other
threads. To ensure that IRQ messages do only occur when expecting
them, we lazily associate the IRQ handler thread to the IRQ the
first time we wait for an IRQ and issue an unmasking IPC call
subsequent times.
* Genode provides a mechanism for gracefully destructing threads that
are in a blocking state, for example waiting for an IPC message.
Such a thread may hold locks or other resources that would not
get properly freed when just killing the thread by force. Therefore,
Genode provides a way to issue the cancellation of a blocking
operation by another thread (e.g., the thread calling the destructor).
Once, a blocking operation got canceled, a C++ exception
('Blocking_canceled') is raised such the thread can fall back into
a defined state and then be destructed. On L4ka::Pistachio, we use
Pistachio's pager-exchange-registers feature in combination with
the user-defined UTCB handle for cancelling blocking operations and
detecting cancellations. The interesting code bits can be found in
'src/base/ipc/ipc.cc', 'src/base/lock/lock.cc',
'src/core/platform_thread.cc', and in the Pistachio-specific
timer-service implementation.
* During the refinement of the Pistachio version, we were able to further
generalize code that was previously specific for L4/Fiasco and
L4ka::Pistachio respectively. Now, the platform-specific code comprises
less than 3,000 lines of code (LOC) for L4/Pistachio, circa 2,000 LOC
for L4/Fiasco, and circa 1,000 LOC for Linux. Hence, we expect that
porting the framework to further kernels is possible at reasonable
engineering costs.
:Current limitations:
* The current version does not use superpages (4M mappings) because we
experienced problems with mapping 4K pages out of 4M pages. This is an
issue that we like to investigate further because using 4M mappings
would improve the boot time and reduce the kernel-memory usage.
* Currently, we use a simple sleeping spinlock for synchronization, which
is not optimal for several reasons. There are no fairness guarantees,
the spinning consumes CPU time, and threads that got blocked in the
contention case are woken up at the coarse granularity of the kernel's
timer tick, which is typically one millisecond.
* Nested RM sessions as introduced as an experimental feature in the
Genode release 8.11 are not yet supported.
:Further details:
You can find further technical details and usage instructions at our
dedicated [http://genode.org/community/wiki/GenodeOnL4kaPistachio - Wiki page].
Qt4 on Genode
=============
The minimalism of the Genode OS Framework with regard to its code
complexity raised the question of whether this framework is feasible
for hosting real-world applications and widely used runtime environments.
Christian Prochaska took the challenge to port Trolltech's Qt4 application
framework, which serves as the basis for the popular KDE desktop, to Genode.
Because Christian started his work more than a year ago at a time when no
C library was available on Genode, several intermediate steps were needed.
The first step was the integration of the Qt4 tools such as the meta-object
compiler (moc) and resource compiler properly into the our build systion.
With the tools in place, the Linux version of Genode came to an advantage.
In this environment, a Genode application is able to use glibc functionality.
So the problem of a missing C library could be deferred and Christian was
able to focus on interfacing Qt with the existing Genode services such as
the Nitpicker GUI sever. Next, the glibc dependencies were successively
replaced by custom implementations or simple dummy stubs. Thereby, all
needed functionalities such as timed semaphores and thread-local storage
had to be mapped to existing Genode API calls. Once, all glibc dependencies
had been dissolved, Qt could be compiled for the L4/Fiasco version.
Since a C library has become available in Genode 8.11, we were able to
replace Christian's intermediate stub codes with a real C library. We also
utilize recently added features of Genode such as its alarm framework to
simplify the Qt4 port. Furthermore, we were able to remove all
platform-specific bits such that the Qt4 port has now become completely
generic with regard to the underlying kernel. Qt4 can be executed on Linux,
L4/Fiasco, and L4ka::Pistachio without any changes. Figure [img/qt4_screenshot]
shows a screenshot of Qt's Tetrix example running side-by-side with native
Genode applications.
[image img/qt4_screenshot]
:Current state:
* The Qt4 port comes in the form of a source-code repository, which contains
all Qt source codes, and some example programs such as Tetrix. You can
download the Qt4 repository as a separate archive at the download page of
the Genode release 9.2. For the next release, we plan to separate the
Genode-specific parts from Qt original code and make the Genode-specific
parts a regular component of the Genode main line.
* The Qt4 port consists of Qt's Core library, GUI library, Script library,
XML library, and the UI tools library. Other libraries such as Webkit
are not ported yet.
* This first version of Qt4 on Genode is not to be considered as stable.
There are several known issues yet to be addressed. In particular,
the 'QEventDispatcher' is still work in progress and not fully stabilized.
* Because, we use to statically link programs, the binaries of Qt
applications are exceedingly large. For example the Tetrix binary is
100MB including debug information and 11MB in the stripped form. For
employing Qt on Genode at a larger scale, Genode should be enhanced with
[http://genode.org/community/wiki/SharedLibrarySupport - shared-library support].
Networking
==========
With Genode 8.11, we introduced the Device-Driver-Environment Kit (DDE Kit)
API, which is a C API specifically designed for implementing and porting
device drivers written in plain C. We have now complemented DDE Kit with an
environment for executing Linux device drivers natively on Genode. This
library is called 'dde_linux26' and contained in our new 'linux_drivers'
source-code repository. The environment consists of several parts, which
correspond to the different sub systems of the Linux kernel 2.6, such as
'arch', 'drivers', 'kernel'.
The first class of device-drivers supported by DDE Linux 2.6 is networking.
At the current stage, the DDE Linux network library comprises general
network-device infrastructure as well as an exemplary driver for the PCnet32
network device.
Based on this library, we have created a basic TCP/IP test utilizing the
uIP stack, which uses the DDE Linux network library as back end. The test
program implements a basic web server displaying uIP packet statistics.
When executed on Qemu, you can use your host's web browser to connect to
the web server running on Genode:
For booting Genode on L4/Fiasco with the web-server demo, use a GRUB
entry in your 'menu.lst' file as follows.
! title Genode: DDE Linux 2.6 NET on L4/Fiasco
! kernel /fiasco/bootstrap -maxmem=64 -modaddr=0x02000000
! module /fiasco/fiasco -nokd -serial -serial_esc
! module /fiasco/sigma0
! module /genode/core
! module /genode/init
! module /config
! module /genode/timer
! module /genode/pci_drv
! module /genode/test-dde_linux26_net
The first four lines are L4/Fiasco specific. When using L4ka::Pistachio,
the 'menu.lst' entry looks like this:
! title Genode: DDE Linux 2.6 NET on L4/Pistachio
! kernel /pistachio/kickstart
! module /pistachio/x86-kernel
! module /pistachio/sigma0
! module /genode/core
! module /genode/init
! module /config
! module /genode/timer
! module /genode/pci_drv
! module /genode/test-dde_linux26_net
The web-server test requires the PCI bus driver and the timer service.
Therefore, the 'config' file for Genode's init should have following
content:
! <config>
! <start>
! <filename>timer</filename>
! <ram_quota>512K</ram_quota>
! </start>
! <start>
! <filename>pci_drv</filename>
! <ram_quota>512K</ram_quota>
! </start>
! <start>
! <filename>test-dde_linux26_net</filename>
! <ram_quota>16M</ram_quota>
! </start>
! </config>
Now, its time to create an ISO image from all files specified in
the GRUB configuration. For this, the new utility 'tool/create_iso'
becomes handy. The ISO image can then be booted on Qemu using the
following arguments:
! qemu -m 64 -serial stdio -no-kqemu -cdrom <iso-image> \
! -net nic,model=pcnet -net user -redir tcp:5555::80
The '-redir' argument tells qemu to redirect TCP connections with
localhost:5555 to the guest OS at port 80. After having booted
up Genode on Qemu, you can use your host's web browser to access
the web server:
! firefox http://localhost:5555
:Notes about using the TAP version:
* Preparations
* You must be permitted to sudo and have installed the tunctl
utility. Under Debian/Ubuntu execute
! sudo apt-get install uml-utilities
* Create TAP device
! TAPDEV=$(sudo tunctl -b -u $USER)
! sudo /sbin/ifconfig $TAPDEV 10.0.0.1
* setup DHCP server on $TAPDEV and 10.0.0.0/8
* Run qemu
! qemu -m 64 -serial stdio -no-kqemu -cdrom dde.iso \
! -net nic,model=pcnet \
! -net tap,ifname=$TAPDEV,script=no,downscript=no
* Ping
* Cleanup
* Stop DHCP server
* Remove TAP device
! sudo tunctl -d $TAPDEV
Operating-system services and libraries
#######################################
C Runtime
=========
We have replaced the 'malloc' implementation of the original FreeBSD C
library with a custom implementation, which relies on Genode's 'Heap' as
allocator. The FreeBSD libc reserves a default memory pool of 1MB, which
is no problem on FreeBSD because virtual memory is backed lazily with
physical pages on demand. On Genode however, we immediately account the
allocated memory, which implicates high quota requirements even for
applications that use little memory. In contrast, Genode's heap allocates
and accounts its backing store in relatively small chunks of a few KB.
Therefore, the quota accounting for applications is much more in line with
the actual memory usage. Furthermore, our custom 'malloc' implementation
has the additional benefit of being thread safe.
* Added i386-specific parts of gen lib, in particular longjmp, setjmp.
Device-Driver-Environment Kit
=============================
* The DDE Kit uses our alarm framework (located in the 'os' repository) now
rather than its own event-scheduler implementation formerly called 'Tick'.
* We refined the DDE Kit API and reduced the number of custom types. For
example, we removed the custom 'dde_kit_lock_t' and using
'struct dde_kit_lock' instead, and replaced 'dde_kit_thread_t' with
'struct dde_kit_thread'.
Because of the apparent stabilization of the DDE Kit API, we have now added
this API to Genode's official API reference.
[http://genode.org/documentation/api/dde_kit_index - See the documentation of the DDE Kit API...]
PS/2 input driver
=================
We improved the PS/2 keyboard driver by adding missing scan-code translations
for the scan code set 1, in particular the cursor keys.
Applications
############
Launchpad configuration
=======================
Launchpad is a graphical application for interactively starting and killing
programs. It is used for the default demonstration of Genode. By default,
launchpad displays a preconfigured list of programs and their respective
default memory quotas. The user can tweak the memory quota for each entry
with mouse and then start a program by clicking on its name. As an
alternative to using the default list, you can now define the list manually
by supplying a configuration to Launchpad. The following example tells
launchpad to display a list of two launcher entries:
!<config>
! <launcher>
! <filename>sdl_pathfind</filename>
! <ram_quota>10M</ram_quota>
! </launcher>
! <launcher>
! <filename>liquid_fb</filename>
! <ram_quota>10M</ram_quota>
! </launcher>
!</config>
To use this configuration for a Launchpad started via init, you can simply
insert the launchpad configuration into the '<start>' node of the launchpad
entry in init's 'config' file.
Platform-specific changes
#########################
L4/Fiasco
=========
* Raise 'Blocking_canceled' exceptions on canceled IPC calls
32-bit Linux
============
* We continued dissolving the dependency of Genode from the glibc by using
a custom 'getenv' implementation used during process creation.
* By default, we compile now with '-nostdinc' and explicitly specify
'/usr/include' as include search directory only when needed. Previously,
a Genode application, which included a host include file by mistake, has
not raised any compilation error when compiled for the Linux version of
Genode. Now, all Genode platforms behave equally with regard to include
search directories.
* We enforce using the actual compiler's C++ support libraries rather than
the default libraries installed on the host.
Tools and build infrastructure
##############################
Official tool chain
===================
At the download section of our website, we used to provide a crosstool-based
tool chain as pre-compiled binaries. Since we got several requests about
how to build such a tool chain from scratch, we created custom utility for
downloading, building, and installing the official Genode tool chain. You
can find the utility at 'tool/tool_chain'. For usage instructions, just
start 'tool_chain' without arguments. Because this utility is a plain script,
you can follow and verify each step that we use for creating the Genode tool
chain. Currently, this official tool chain is based on binutils 2.18 and
gcc 4.2.4.
As an alternative to installing the tool chain from source, we also
provide pre-compiled binaries at the download section of our website.
[http://genode.org/download/tool-chain - Visit our tool-chain download website...]
For the Linux version of Genode, we still use the host's default gcc
as tool chain. This way, we spare the hassle of downloading and installing
a custom tool chain for somebody who wants to give Genode a quick try.
With this is mind, we have fixes several small issues with gcc 4.3.2:
* Fixed dependency generation for gcc-4.3.2. Older version of gcc used to
append a '.o' dependency at the target of '.d'-files. However, gcc-4.3.2
seems to handle the option '-MT' differently, resulting in a rule that
contains only the '.d' as target. Now, we explicitly specify both the
'.o' file and the '.d' file as target. Consequently, on older gcc
versions, the '.o' file appears twice but that is no problem.
* Fixed assembler issue with the 'fnstsw' instruction in the C library.
This instruction does not accept eax but only ax as argument.
Build-directory creation tool
=============================
We added a rule for creating a pre-configured build directory for the
Pistachio version to our build-directory creation tool
('tool/builddir/create_builddir'). Furthermore, we changed the default
build configuration such that the official Genode tool chain is used for
L4/Fiasco and L4ka::Pistachio.
Build system
============
* Improved clean rule - visit each target directory only once
* Stop the build process on the first error by default, for continuing
the build process depite of an error, you can use the '-i' argument
of make.
* Compiler flags can now be set specific for compiling C and C++ sources.
This is needed because both variants allow different sets of warning
options. The new variables are called 'CC_CXX_OPT' and 'CC_C_OPT'.
ISO image creation tool
=======================
We have created a convenient front end for 'genisoimage', which we
use for testing Genode on Qemu. You can find this ISO-image-creation
tool at 'tool/create_iso'. For usage instructions, simply start the
tool without arguments.

585
doc/release_notes-09-05.txt Normal file
View File

@@ -0,0 +1,585 @@
==============================================
Release notes for the Genode OS Framework 9.05
==============================================
Genode Labs
Shortly after including support for the L4ka::Pistachio kernel in the
previous release, the Genode version 9.05 gives a further evidence of
Genode's high portability by making the framework available on top of
the OKL4 kernel. This kernel is a commercial-grade microkernel
developed by [http://ok-labs.com - Open Kernel Labs]. In Section
[Supporting the OKL4 kernel as new base platform], we elaborate on the
new base platform and summarize the experiences made during our porting
work.
The previous Genode release was accompanied by a source-code archive containing
the initial version of Qt4 for Genode. Our approach is to make the Qt4
framework available for building Genode applications running natively on the
microkernel rather than within a virtualization environment. As advertised in
our [http://genode.org/about/road-map - road map], we have now seamlessly
integrated the Qt4 framework into our mainline source tree. Furthermore, we
have adapted our port to the Qt4 version 4.5.1. Section [Integration of Qt4
into the mainline repository] gives a rough overview of the changes and an
introduction on how to use the Qt4 framework with Genode.
The third major feature of the release is the addition of preliminary USB
support. We have been able to port major parts of Linux' USB infrastructure
to Genode using the DDE Kit introduced in autumn 2008. Section [USB support]
presents an overview about the pursued design and the current state of
implementation.
Section [OKLinux on Genode] outlines our ongoing efforts of running Linux
as a node in Genode's process tree.
Supporting the OKL4 kernel as new base platform
###############################################
The OKL4 kernel developed by Open Kernel Labs started as a fork of the
L4ka::Pistachio kernel. Whereas L4ka::Pistachio remained true to the L4
x.2 specification, OKL4 was subject of major API changes geared towards high
performance on the ARM architecture. OKL4 earned much fame for executing a
user-level variant of Linux (OKLinux) on top the microkernel, which turned out
to be faster than executing Linux natively on the ARM9 architecture. Even
though OKL4 is primary targeted at the ARM architecture, we wanted to go for
the x86 variant because of two reasons. First, there exists the just mentioned
user-level port of Linux for OKL4, which looks like an attractive way to execute
Linux on Genode once Genode runs on OKL4. Second, we think that distributing
Genode in the form of ISO images bootable on plain PC hardware is the best
way to reach the OS community. Therefore, we decided to use OKL4 version 2.1 as
the base for our work. In contrast to later releases, this version supports
both x86 and ARM. The following section reviews the unique features of the
OKL4 kernel from our perspective.
OKL4 viewed from the angle of a Genode developer
================================================
On the kernel-API level, OKL4 has several interesting properties that had been
both welcome and challenging. We want to highlight the following points:
In contrast to prior L4 kernels, OKL4 has *removed wall-clock timeouts* from
the kernel interface. On L4, timeouts were used as arguments for for blocking
IPC operations serving two purposes. First, specifying IPC timeouts allowed the
IPC caller for regaining control over the blocking thread after the specified
time elapsed. This is considered as important in the case that the called
thread misbehaves and never answers the call. However, the problem of choosing
an appropriate timeout was never properly resolved. When dimensioning the
timeout too small, the called thread may miss the timeout just because it had
no chance to be selected by the scheduler in time. Such timeouts rely on the
presumption that there is low load on the system. On the other hand, when
dimensioning the timeout too high, the system will become sluggish when the
called thread misbehaves. For example, a simple GUI server may want to send
input events to its clients with a timeout to be robust against misbehaving
clients that never wait for events. When choosing a timeout too small, chances
are high that an event will occur at a time when the receiver is handling a
previous event. The timeout would trigger and the event would get lost. When
choosing the timeout too large, say 1 second, any misbehaving client could make
the GUI server freeze for 1 second. Therefore, timeouts for regaining control
over a blocked thread seem to be a bad idea. So we welcome their absence in
OKL4. The second use of timeouts is their use as user-level time source. On L4,
sleep is typically implemented as a blocking IPC with a timeout set to the
sleep value. For this purpose, a system built on top of OKL4 has to employ a
user level device driver accessing a timer device. In Genode, we already have a
timer service for this purpose. So we won't miss timeouts at all.
Classical L4 kernels provide two variants of *synchronous IPC*. So called long
IPC could copy any amount of memory from the sending to the receiving address
space. This is complicated operation because either communication partner may
specify communication buffers that contain unmapped pages. Hence, page faults
may occur during long-IPC operations. On L4, page faults, in turn, are handled
by the user land. Not until a user-level pager thread resolves the page fault
by establishing a mapping at the faulting address, the kernel can proceed the
IPC operation. This sounds pretty complicated, and it is. The second IPC
variant is called short IPC. It constrains the transferable payload to CPU
registers. Hence, these IPC operations should only be used for messages with a
payload of a maximum of 2 machine words. Because short IPCs are never touching
user-level memory pages, no page faults can occur.
On OKL4, there is only one IPC operation, which copies payload from the
sender's user-level thread-control block (UTCB) to the receiver's UTCB. An
UTCB is an always-mapped memory region. Hence no page faults can occur during
IPC operations. On Genode, the UTCB size of 256 bytes may become a limitation
when RPC messages get large. For example, session requests may include large
session-argument strings specifying session-constructor arguments. Current
services rely only on a few arguments so the size limitation is not an
apparent problem. But that may change for future services. Furthermore, in
contrast to L4 x.2, OKL4 does not allow for transferring payload other than
plain data. In particular, OKL4 does not support the transfer of memory
mappings via IPC. Removing memory mappings from the IPC operation is a very
good idea. On Genode, only roottask (core) establishes mappings and shared
memory is implemented as a user-level protocol (data spaces). There is no need
to allow arbitrary processes to establish memory mapping via IPC.
The *boot procedure* of OKL4 largely differs from other L4 kernels. This is
attributed to Open Kernel Labs' focus on embedded systems, which mostly rely on
single-image boot loading. OKL4 employs a tool (elfweaver) for creating a
bootable image from a bunch of files and an XML configuration file. Among the
declarations about which processes to be loaded and which policies to enforce,
the configuration file contains platform parameters such as the amount of
physical memory of the machine. This static approach to configure a system is
certainly useful for embedded systems but PC hardware uses to vary a lot. In
this case, evaluating boot-time memory descriptors would be the preferred
solution.
OKL4 introduces kernel support for *user-level synchronization*. Prior L4
kernels facilitated user-level synchronization through a combination of
synchronous IPC operations with either priorities or delayed preemption.
OKL4's mutexes can make the life in the user land much easier. However, we have
not looked into OKL4 mutexes yet.
There does not exist a recursive *map operation* as the source operand of the
map operation is a physical memory descriptor rather than a virtual address in
the mapper's address space. Consequently, this design eliminates the need for
having a recursive unmap operation and thereby, the need to maintain a mapping
data base in the kernel. This is cool because Genode keeps track of the
mappings at the user level anyway (within core). From our perspective, there is
no need to maintain mapping relationships in the kernel. Removing the mapping
database effectively discards a lot of much-discussed problems about how to
manage the mapping database in a clever way.
There exists *no root memory manager* (sigma0). Because the map operation
takes a physical memory descriptor as argument instead of a virtual address
in the mapper's address space. The mapper does not need to have the mapped
page locally mapped within its own address space. In fact, core (as the only
mapper in a Genode system) does only have very little memory mapped locally.
This design accelerates the boot time because there is no need to map each
physical page in core at startup as performed when running core on the other
L4 kernels.
These differences of OKL4 compared with the microkernels already supported
by Genode posed a number of interesting challenges and opportunities. We have
thoroughly documented the process in
[http://genode.org/documentation/articles/genode-on-okl4 - Bringing Genode to OKL4].
Usage
=====
For using Genode with OKL4, please refer to the following dedicated Wiki page:
:[http://genode.org/community/wiki/GenodeOnOKL4 - Genode on OKL4]:
Wiki page about building and using Genode with the OKL4 kernel.
Limitations of the current implementation
=========================================
The current implementation is able to execute the complete Genode demonstration
scenario on OKL4. This means, we can build and destroy arbitrary trees of
processes, have all the needed infrastructure in place to execute user-level
device drivers such as VESA and PS/2, perform inter-process communication
via RPC and shared memory, and have all basic framework API functions available.
We regard the current state as the first functional version. However, there are
the following points that need improvement and are subject to our future work.
:Incomplete timer driver:
On x86, the timer driver should program the PIT to dispatch sleep requests.
However, the I/O ports of the PIT can only by made available to one party in
the system (which naturally would be the timer driver). Unfortunately, there
are some VESA BIOSes around, which try using the PIT directly. The current
version of our VESA driver does not virtualize these accesses. It rather
tries to gain direct access to the I/O ports from core. This would not work
if the timer already uses this device resource. Our plan is to supplement
our VESA driver with a virtual PIT that uses the timer service as back end.
Then we can safely use the PIT by the timer driver.
:Signalling framework not yet implemented:
We have not yet implemented Genode's API for asynchronous notifications
in the OKL4 version. In fact, the goal of the initial version of the
OKL4 support was running the default demonstration scenario, which does
not rely on signals. The second and more technical reason is that we
consider exploiting OKL4's event mechanism for implementing the signalling
API but have not finalized the design. The generic implementation as used
on the other platforms cannot be used on OKL4 because this implementation
utilizes one helper thread per signal transmitter. Within core, each RM
session is a potential signal transmitter, which means that we need to
create a helper thread per process. Unfortunately, by default, OKL4
limits the number of threads within roottask (core) to only 8 threads,
which would impose a severe limit on the number of processes we could
run on OKL4.
:OKL4's kernel mutexes yet to be used:
We have not yet explored the use of mutexes provided by the OKL4 kernel
for implementing Genode synchronization APIs but we rather rely on a
yielding spin lock for now. This has a number of drawbacks such as high
wake-up latencies in the contention case (depending on the scheduling
time slice), no support for priorities, and no fairness. Although it
is a simple and robust solution to start with, we plan to facilitate
the OKL4 kernel feature with our upcoming work.
:Overly simplistic UTCB allocation:
Right now, we allocate a fixed amount of 32 UTCBs per address space and
thereby limit the maximum number of threads per process. In the future,
this limit should be made configurable.
:Managed dataspaces not yet supported:
The support of managed dataspaces relies on the signal API, which is
not yet available for OKL4.
:Message buffers are limited to 256 bytes:
Because OKL4 performs message-based inter-process communication by
copying data between the UTCBs of the communicating threads, the
UTCB size constaints the maximum message size. Therefore, message
must not exceed 256 bytes. This is not a huge problem for the currently
available Genode programs but we can imagine session argument-lists
to become larger in the future.
:Advanced thread functions are incomplete:
Thread functions such as querying registers of remote threads are not yet
implemented.
Integration of Qt4 into the mainline repository
###############################################
Qt4 is a tool kit for developing platform-independent applications. It
comprises a complete platform-abstraction layer and a rich GUI tool kit
widely used for commercial and open-source applications. It is particularly
known as the technical foundation of the KDE project. The previous Genode
release was accompanied by a snapshot of our initial port of Qt4 to Genode. For
the current release, we have turned this proof-of-concept implementation into a
properly integrated part of the Genode mainline development. This enables Qt4
applications to be executed natively on the full range of kernels supported by
Genode.
Usage
=====
We complemented Genode's source tree with the new 'qt4' source-code repository,
which contains the Genode-specific parts of the Qt4 framework. The most
portions for the Qt4 framework are used unmodified and thereby have not been
made part of the Genode source tree. Instead, we fetch the original Qt4 source
code from Trolltech's FTP server. This way, our source tree remains tidy and
neat.
For using Qt4 for your Genode applications, you first need to download and
prepare the original Qt4 source codes and build a few Qt4 tools such as the
meta-object compiler and the resource compiler. The makefile found in the
top-level directory of the 'qt4' repository automates this task:
! make prepare
To include the 'qt4' repository into the Genode build process, just add the
'qt4' directory to the 'REPOSITORIES' declaration of the 'etc/build.conf' file
within your build directory. Make sure that the repositories 'demo' and 'libc'
are included as well. The 'qt4' repository comes with a couple of demo applications.
The 'qt_launchpad' is especially interesting because it makes use of both the
Qt4 framework and the Genode framework in one application.
Features and limitations
========================
The Qt4 port comprises Qt's Core library, GUI library, Script library, XML
library, and the UI tools library.
For using Qt4 on the Linux version of Genode, we recommend using the Genode
tool chain rather than your host's tool chain. Qt4 makes use of a lot of libc
functionality, supplied by Genode's 'libc' repository. However, on Linux we
still link against your host's libc. This becomes a problem if your host
compiler's C++ support code references libc functionality that is not part of
Genode's libc. Thereby the linker will silently create references to glibc
symbols, making both libraries collide. So if using Qt4, we recommend using the
Genode tool chain:
:[http://genode.org/download/tool-chain]:
Information about downloading and using the Genode tool chain
USB support
###########
This release introduces the first fragments of USB support to Genode, taking
the USB human-interface device (HID) class as starting point. With this work,
we follow our approach of reusing unmodified Linux device drivers executed
within a device-driver environment called DDE Linux. In the previous release,
we already utilized this approach for realizing basic networking on Genode.
With this release, we complement DDE Linux with support required by USB
drivers. We are grateful for being able to base our implementation on the
excellent foundation laid by Dirk Vogt. He described his work in
[http://os.inf.tu-dresden.de/papers_ps/vogt-beleg.pdf - USB for the L4 environment].
For USB HID support, we added the Linux USB and input subsystems to the DDE
Linux 2.6 framework. Besides the 'dde_linux26/net.h' API for network drivers
added in Genode 9.02, the current version also includes APIs for input
('dde_linux26/input.h') and USB ('dde_linux26/usb.h'). We intend these
interfaces to mature towards generic driver-library APIs in the future. For
example, BSD-based drivers shall transparently provide the same functionality
as the current Linux drivers, which permits the simple reuse of driver server
implementations.
[image img/usb_current]
Image [img/usb_current] illustrates the current implementation of the USB-based
human-interface device (HID) driver. In this monolithic setup, all parts of the
USB stack and the device API are executed within one address space. These parts
are
* Input server glue code
* HID driver and input subsystem
* Core functions for management of USB request buffers (URBs),
attached devices, and registered drivers
* Host controller drivers for UHCI, OHCI, and EHCI
[image img/usb_aspired]
We regard this as an intermediate step towards our goal to decompose the USB
stack. Image [img/usb_aspired] shows our aspired design. In this design, the
USB server and one or more USB gadget drivers run in dedicated address spaces.
The USB server provides two interfaces called USB session interface and USB
device interface. A USB session interface corresponds to a virtual root hub,
from which USB devices can be queried. The client of the USB session interface
is usually an USB gadget driver that uses the USB device interface. Because
this interface is used for transferring the actual payload at a potentially
high bandwidth, it is based on shared memory and signals. The USB server
consists of the following components:
* USB server glue code
* Virtual USB device driver managing all attached devices
* Core functions including hardware hub management
* Host controller drivers
The USB server presents a virtual USB hub to each USB gadget driver. Such
a driver consists of:
* Device interface, e.g., input server glue code
* Gadget driver, e.g., HID driver and input subsystem
* Core functions
* Virtual host controller
* USB client glue code
The HID driver uses the USB session API to monitor ports of its virtual root
hub and submit URBs to attached devices. The session interface facilitates the
signalling framework for event notification and a shared-memory dataspace for
URB transmission.
The 'os' repository already contains the USB session and USB device interfaces.
However, the decomposition is not yet in a functional state.
:Current limitations:
The current monolithic implementation of the USB HID service can already be
used as a replacement of the PS/2 driver. However, both drivers cannot be used
at the same time, yet. To enable the use of both USB HID and PS/2, we plan to
create a further component that merges multiple streams of input events and
passes the result to the GUI server.
OKLinux on Genode
#################
According to our road map, we pursued the goal to run Linux as a node in
Genode's process tree. We explored two approaches:
:Reanimating the Afterburner project conducted by the [http://l4ka.org - L4Ka group]:
This approach is the result of the L4Ka groups's long-year experience with
manually supporting L4Linux on top of the L4ka::Pistachio kernel. Because of
the high costs of maintaining the paravirtualized Linux kernel, a
semiautomatic paravirtualization technique was created. According to the
impressive results presented in
[http://l4ka.org/publications/paper.php?docid=2025 - Pre-Virtualization: Soft Layering for Virtual Machines],
this approach is able to drastically reduce maintenance costs while retaining
good performance. Furthermore, the approach was applied not only to Linux
running on the L4 kernel but also for using Xen or Linux as underlying
host operating systems.
:Porting the OKL4-specific version of L4Linux to Genode:
Open Kernel Labs maintain a custom version of L4Linux that runs on OKL4. This
version is mostly referred to as OKLinux aka Wombat. Since Genode can now use OKL4
as base platform, the reuse of OKLinux in combination with Genode has become
a feasible option.
Both approaches have pros and cons. Whereas Afterburner is a intriguing
approach, this project seems to be stalled. It relies on a rather old tool
chain, and recent Linux features such as thread-local storage support are not
considered, yet. To pick up this solution for Genode will require us to fully
understand the mechanisms and the code. So we consider this as a mid-term
solution. In short term, running OKLinux on Genode is more feasible. We were
already able to create a prototype version of OKLinux running on Genode. This
version starts up the kernel including all Linux kernel threads, mounts the
boot partition supplied as memory image, and starts the init process. The
engineering costs had been rather low. We replaced the Iguana user land
libraries as originally used by Wombat by a Genode-specific reimplementation to
keep our manual adaptions of the Linux kernel code as small as possible.
Our custom reimplementation of the needed Iguana APIs consists of less than
1,000 lines of code (SLOC). The diff for our changes to the OKLinux kernel code
comprises less than 1,000 lines. We plan to make a snapshot of this prototype
publicly available soon.
Operating-system services and libraries
#######################################
Nitpicker GUI server
====================
We optimized the performance of the 'refresh' call, which updates all views of
a session, which display a given buffer portion. The new implementation restricts
the redraw operations to the fragment of each view that displays the specified
buffer portion. The performance improvement becomes most visible when updating
only small parts of a buffer.
USB session interface
=====================
Genode's emerging USB support introduces two new interfaces to the 'os' repository,
which are called USB session and USB device.
An _USB_session_ is a virtual USB bus with just one root hub with 'MAX_PORTS'
downstream ports. The client of such as session submits USB request blocks
(URBs) and is, in turn, informed about port changes on the root hub as well as
request completion. Connected USB devices can be referenced by USB device
capabilities and are associated with one port at the virtual root hub on
server side.
An _USB_device_ references a hardware device connected to a virtual USB bus's
root hub. The device capability enables the client to send USB request
blocks to the hardware device.
Input interface
===============
We updated the key codes of the input interface in response to recent changes
of Linux' 'dev/event' definitions.
VESA driver
===========
Until now, there existed different processes that tried to access the PCI bus
via I/O ports, in particular the VESA framebuffer driver and the PCI bus
driver.
Since core enforces that each I/O port can only be assigned exclusively to one
component in the system, multiple processes that need access to the same I/O
ports cannot run at the same time. For our default demonstration scenario, we
had been able to allow the VESA driver to use the PCI I/O ports because nobody
else needed them. However, our growing base of device drivers relies on the
PCI bus driver. To be able to use the VESA driver together with other drivers,
we virtualized the access to the PCI bus from within the VESA driver.
Our current PCI virtualization code is pretty limited. The VESA driver sees a
virtual PCI bus with only the VGA card attached. For now, we only allow reading
the PCI configuration space of this device, but not writing to it. Apparently,
this simple approach is sufficient to run the VESA BIOS of Qemu. However, other
VESA BIOS implementations may need further access to the PCI device's
configuration space. For example, for querying the size of a PCI resource,
write access to base address registers is required. In such an event, the VESA
driver will print a message about the missing virtualization feature:
! writing data register not supported
If you see such a message, we are very interested to see your log output such
that we can enhance our PCI virtualization code as needed. Please contact us!
Base framework
##############
In the process of bringing Genode to the OKL4 kernel, we have generalized much
of former platform-specific code:
* The initialization of C++ exception handling has now become part of the
generic 'cxx' library in the 'base' repository. All platforms except
Linux are using this generic library now.
* The 'server' library used to contain a platform-specific part that
implemented the 'manage' function of a 'Server_entrypoint'. The
generalized version of this library is now being used on all platforms
other than Linux.
* We unified core-internal interfaces and their implementations such as
'Dataspace_component', 'Cap_session_component', 'Rm_session_component',
and 'Irq_session_component'. The result has become part of the 'base'
repository.
* On OKL4, threads need to execute small startup code for querying their
own thread IDs. Therefore, we have extended the 'Thread_base' interface
with a platform-specific hook function called '_thread_bootstrap'.
* The types defined in 'base/native_types.h' had been complemented by a
new 'Native_thread_id' type. This type is exclusively used by core and the
framework libraries. For using the Genode API, this type is meaningless.
* For the 64bit support, we slightly refined the interfaces of some utility
template functions in 'util/misc_math.h'. Furthermore, parts of the generic
marshalling code of the IPC framework needed refinement, but no API changes
were needed.
Linux-specific changes
######################
Adaptation to 64 bit
====================
Because most Genode developers tend to work with the Linux version of Genode,
supporting 64-bit Linux becomes increasingly important. With the current release,
we start to officially support 64-bit Linux as base platform. This comes
along with the following changes:
* We replaced the 'spec-x86.mk' file with new 'spec-x86_32.mk' and 'spec-x86_64.mk'
files. The default version of 'base-linux/etc/specs.conf' automatically
chooses the right spec file according to the output of 'uname -m'. Therefore,
output of the build processes matches your host architecture. This behaviour
can be changed by placing a customized 'spec.conf' file in your build directory's
'etc/' subdirectory.
* We added type definitions for 64-bit-specific fixed-size integers in the form
of a 64-bit-specific 'fixed_stdint.h' file.
* Because using 64 bit instead of 32 bit changes the payload size of RPC
messages, we had to adjust several message buffers such as 'Ram_session_client'
and 'Input::Session_client', and adapted the used stack sizes.
* Towards the goal of completely dissolving Genode's dependency on the Linux' glibc,
we implemented custom system-call bindings. Apparently, Linux' syscall interface
differs between 32 bit and 64 bit. For example, the 32-bit version handles
all socket-related calls via a compound 'socketcall' whereas the 64-bit
version uses distinct syscalls. Another difference is the handling of the
'mmap' syscall and different behaviour of 'tkill'. The latter problem was
resolved by replacing 'tkill' with 'tgkill' and setting the thread-group
argument of the corresponding PID. Therefore, a 'Native_thread_id' on Linux
now comprises both the TID and the PID.
* The 'Platform_env' on Linux contains a local implementation of the 'Rm_session'
interface, which uses 'mmap' to attach dataspaces to the process' address
space and maintains the region list in the form of a static array. This array
was dimensioned to 256 entries, which constrained the maximum amount of
usable memory when allocating a lot of small blocks via Genode's heap. Since
the heap allocates backing store at the granularity of only 16KB, the worst
case for reaching this limit was about 4MB. This was OK for our simple test
applications. But for using Qt4, in particular on 64 bit, this has become a
serious limitation. For now, we increased the region limit to 4096 and plan
to replace the static array with a dynamically growing data structure.
Furthermore, we made the heap granularity depend on the actual machine-word
size. Therefore, the heap allocates its backing store in 32KB blocks when
running on 64 bit.
Debugging hooks
===============
On Linux, we use gdb for debugging Genode. This is feasible as long as the
targeted process is running. However, during low-level debugging, we had the
recurring problem of a thread dying shortly after starting up. So we added a hook
for halting a thread at the startup in order to be able to attach gdb to the
thread before it dies. This simple hook lets the thread wait for a key press by
directly calling the 'read' syscall. We also added a simple debug facility for
printing debug messages bypassing Genode's LOG service by calling the 'write'
syscall directly. Both hooks are now part of the Linux version of the 'env'
library (see 'base-linux/src/base/env/debug.cc'). Note that these hooks are not
part of the Genode API. There exists no header file.

573
doc/release_notes-09-08.txt Normal file
View File

@@ -0,0 +1,573 @@
==============================================
Release notes for the Genode OS Framework 9.08
==============================================
Genode Labs
Whereas the previous releases were focused on adding features to the framework,
the overall theme for the current release 9.08 was refinement. We took the
chance to revisit several parts of the framework that we considered as
interim solutions, and replaced them with solid and hopefully long-lasting
implementations. Specifically, we introduce a new lock implementation, a new
timer service, a platform-independent signalling mechanism, a completely
reworked startup code for all platforms, and thread-local storage support.
Even though some of the changes touches fundamental mechanisms, we managed
to keep the actual Genode API almost unmodified.
With regard to features, the release introduces initial support for dynamic
linking, a core extension to enable a user-level variant of Linux to run on the
OKL4 version of Genode, and support for super pages and write-combined I/O
memory access on featured L4 platforms.
The most significant change for the Genode Linux version is the grand unification with
the other base platforms. Now, the Linux version shares the same linker script
and most of the startup code with the supported L4 platforms. Thanks to our
evolved system-call bindings, we were further able to completely dissolve
Genode's dependency from Linux's glibc. Thereby, the Linux version of Genode is
on the track to become one of the lowest-complexity (in terms of source-code
complexity) Linux-kernel-based OSes available.
Base framework
##############
New unified lock implementation
===============================
Since the first Genode release one year ago, the lock implementation had been
a known weak spot. To keep things simple, we employed a yielding spinlock
as basic synchronization primitive. All other thread-synchronization
mechanisms such as semaphores were based on this lock. In principle, the
yielding spinlock used to look like this:
! class Lock {
! private:
! enum Lock_variable { UNLOCKED, LOCKED };
! Lock_variable _lock_variable;
!
! public:
! void lock() {
! while (!cmpxchg(&_lock_variable, UNLOCKED, LOCKED))
! yield_cpu_time();
! }
!
! void Lock::unlock() { _lock_variable = UNLOCKED; }
! }
The compare-exchange is an atomic operation that compares the current value
of '_lock_variable' to the value 'UNLOCKED', and, if equal, replaces the
value by 'LOCKED'. If this operation succeeds, 'cmpxchg' returns true, which
means that the lock acquisition succeeded. Otherwise, we know that the lock
is already owned by someone else, so we yield the CPU time to another thread.
Besides the obvious simplicity of this solution, it does require minimal
CPU time in the non-contention case, which we considered to be the common case. In
the contention case however, this implementation has a number of drawbacks.
First, the lock is not fair, one thread may be able to grab and release the
lock a number of times before another thread has the chance to be
scheduled at the right time to proceed with the lock acquisition if the lock
is free. Second, the lock does not block the acquiring thread but lets it
actively spin. This behavior consumes CPU time and slows down other threads that
do real work. Furthermore, this lock is incompatible with the use of thread
priorities. If the lock is owned by a low-priority thread and a high-priority
thread tries to acquire a lock, the high-priority thread keeps being active
after calling 'yield_cpu_time()'. Therefore the lock owner starves and has no
chance to release the lock. This effect can be partially alleviated by replacing
'yield_cpu_time()' by a sleep function but this work-around implies higher
wake-up latencies.
Because we regarded this yielding spinlock as an intermediate solution since the
first release, we are happy to introduce a completely new implementation now.
The new implementation is based on a wait queue of lock applicants that are
trying to acquire the lock. If a thread detects that the lock is already
owned by another thread (lock holder), it adds itself into the wait queue
of the lock and calls a blocking system call. When the lock owner releases
the lock, it wakes up the next member of the lock's wait queue.
In the non-contention case, the lock remains as cheap as the yielding
spinlock. Because the new lock employs a fifo wait queue, the lock guarantees
fairness in the contention case. The implementation has two interesting points
worth noting. In order to make the wait-queue operations thread safe, we use a simple
spinlock within the lock for protecting the wait queue. In practice, we
measured that there is almost never contention for this spin lock as two
threads would need to acquire the lock at exactly the same time. Nevertheless,
the lock remains safe even for this case. Thanks to the use of the additional spinlock within
the lock, the lock implementation is extremely simple. The seconds interesting
aspect is the base mechanism for blocking and waking up threads such
that there is no race between detecting contention and blocking.
On Linux, we use 'sleep' for blocking and 'SIGUSR1' to cancel the sleep operation.
Because Linux delivers signals to threads at kernel entry,
the wake-up signal gets reliably delivered even if it occurs prior
thread blocking. On OKL4 and Pistachio, we use the exchange-registers
('exregs') system call for both blocking and waking up threads. Because 'exregs'
returns the previous thread state, the sender of the wake-up
signal can detect if the targeted thread is already in a blocking state.
If not, it helps the thread to enter the blocking state by a thread-switch
and then repeats the wake-up. Unfortunately, Fiasco does not support the
reporting of the previous thread state as exregs return value. On this kernel,
we have to stick with the yielding spinlock.
New Platform-independent signalling mechanism
=============================================
The release 8.11 introduced an API for asynchronous notifications. Until
recently, however, we have not used this API to a large extend because it
was not supported on all platforms (in particular OKL4) and its implementation
was pretty heavy-weight. Until now signalling required one additional thread for each signal
transmitter and each signal receiver. The current release introduces a
completely platform-independent light-weight (in terms of the use of
threads) signalling mechanism based on a new core service called SIGNAL.
A SIGNAL session can be used to allocate multiple signal receivers, each
represented by a unique signal-receiver capability. Via such a capability,
signals can be submitted to the receiver's session. The owner of a SIGNAL
session can receive signals submitted to the receivers of this session
by calling the blocking 'wait_for_signal' function. Based on this simple
mechanism, we have been able to reimplement Genode's signal API. Each
process creates one SIGNAL session at core and owns a dedicated thread
that blocks for signals submitted to any receiver allocated by the process.
Once, the signal thread receives a signal from core, it determines
the local signal-receiver context and dispatches the signal accordingly.
The new implementation of the signal API required a small refinement.
The original version allowed the specification of an opaque argument
at the creation time of a signal receiver, which had been delivered with
each signal submitted to the respective receiver. The new version replaces
this opaque argument with a C++ class called 'Signal_context'. This allows
for a more object-oriented use of the signal API.
Generic support for thread-local storage
========================================
Throughout Genode we avoid relying on thread-local storage (TLS) and, in fact,
we had not needed such a feature while creating software solely using the
framework. However, when porting existing code to Genode, in particular Linux
device drivers and Qt-based applications, the need for TLS arises. For such
cases, we have now extended Genode's 'Thread' class with generic TLS
support. The static function 'Thread_base::myself()' returns a pointer to the
'Thread_base' object of the calling thread, which may be casted to a inherited
thread type (holding TLS information) as needed.
The 'Thread_base' object is looked up by using the current stack pointer
as key into an AVL tree of registered stacks. Hence, the lookup traverses a
plain data structure and does not rely on platform-dependent CPU features
(such as 'gs' segment-register TLS lookups on Linux).
Even though, Genode does provide a mechanism for TLS, we strongly discourage
the use of this feature when creating new code with the Genode API. A clean
C++ program never has to rely on side effects bypassing the programming
language. Instead, all context information needed by a function to operate,
should be passed to the function as arguments.
Core extensions to run Linux on top of Genode on OKL4
#####################################################
As announced on our road map, we are working on bringing a user-level variant
of the Linux kernel to Genode. During this release cycle, we focused on
enabling OKLinux aka Wombat to run on top of Genode. To run Wombat on Genode we
had to implement glue code between the wombat kernel code and the Genode API,
and slightly extend the PD service of core.
The PD-service extension is a great show case for implementing inheritance
of RPC interfaces on Genode. The extended PD-session interface resides
in 'base-okl4/include/okl4_pd_session' and provides the following additional
functions:
! Okl4::L4SpaceId_t space_id();
! void space_pager(Thread_capability);
The 'space_id' function returns the L4 address-space ID corresponding to
the PD session. The 'space_pager' function can be used to set the
protection domain as pager and exception handler for the specified
thread. This function is used by the Linux kernel to register itself
as pager and exception handler for all Linux user processes.
In addition to the actual porting work, we elaborated on replacing the original
priority-based synchronization scheme with a different synchronization mechanism
based on OKL4's thread suspend/resume feature and Genode locks. This way, all
Linux threads and user processes run at the same priority as normal Genode
processes, which improves the overall (best-effort) performance and makes
Linux robust against starvation in the presence of a Genode process that is
active all the time.
At the current stage, we are able to successfully boot OKLinux on Genode and
start the X Window System. The graphics output and user input are realized
via custom stub drivers that use Genode's input and frame-buffer interfaces
as back ends.
We consider the current version as a proof of concept. It is not yet included
in the official release but we plan to make it a regular part of the official
Genode distribution with the next release.
Preliminary shared-library support
##################################
Our Qt4 port made the need for dynamically linked binaries more than evident.
Statically linked programs using the Qt4 library tend to grow far beyond 10MB
of stripped binary size. To promote the practical use of Qt4 on Genode, we
ported the dynamic linker from FreeBSD (part of 'libexec') to Genode.
The port consists of three parts
# Building the 'ldso' binary on Genode, using Genode's parent interface to
gain access to shared libraries and use Genode's address-space management
facilities to construct the address space of the dynamically loaded program.
# Adding support for the detection of dynamically linked binaries, the starting
of 'ldso' in the presence of a dynamically linked binary, and passing the
program's binary image to 'ldso'.
# Adding support for building shared libraries and dynamically linked
programs to the Genode build system.
At the current stage, we have completed the first two steps and are able to
successfully load and run dynamically linked Qt4 applications. Thanks to
dynamic linking, the binary size of Qt4 programs drops by an order of
magnitude. Apparently, the use of shared qt libraries already pays off when
using only two Qt4 applications.
You can find our port of 'ldso' in the separate 'ldso' repository. We will
finalize the build-system integration in the next weeks and plan to support
dynamic linking as regular feature as part of the 'os' repository with the next
release.
Operating-system services and libraries
#######################################
Improved handling of XML configuration data
===========================================
Genode allows for configuring a whole process tree via a single configuration
file. Core provides the file named 'config' as a ROM-session dataspace to the
init process. Init attaches the dataspace into its own address space and
reads the configuration data via a simple XML parser. The XML parser takes
a null-terminated string as input and provides functions for traversing the
XML tree. This procedure, however, is a bit flawed because init cannot
expect XML data provided as a dataspace to be null terminated. On most platforms,
this was no problem so far because boot modules, as provided by core's ROM
service, used to be padded with zeros. However, there are platforms, in particular
OKL4, that do not initialize the padding space between boot modules. In this
case, the actual XML data is followed by arbitrary bits but possibly no null
termination. Furthermore, there exists the corner case of using a config
file with a size of a multiple of 4096 bytes. In this case, the null termination
would be expected just at the beginning of the page beyond the dataspace.
There are two possible solutions for this problem: copying the content of
the config dataspace to a freshly allocated RAM dataspace and appending the
null termination, or passing a size-limit of the XML data to the XML parser.
We went for the latter solution to avoid the memory overhead of copying
configuration data just for appending the null termination. Making the XML
parser to respect a string-length boundary involved the following changes:
* The 'strncpy' function had to be made robust against source strings that are not
null-terminated. Strictly speaking, passing a source buffer without
null-termination violates the function interface because, by definition,
'src' is a string, which should always be null-terminated. The 'size'
argument usually refers to the bound of the 'dst' buffer. However, in our
use case, for the XML parser, the source string may not be properly terminated.
In this case, we want to ensure that the function does not read any characters
beyond 'src + size'.
* Enhanced 'ascii_to_ulong' function to accept an optional size-limitation
argument
* Added support for size-limited tokens in 'base/include/util/token.h'
* Added support for constructing an XML node from a size-limited string
* Adapted init to restrict the size of the config XML node to the file size
of the config file
Nitpicker GUI server
====================
* Avoid superfluous calls of 'framebuffer.refresh()' to improve the overall
performance
* Fixed stacking of views behind all others, but in front of the background.
This problem occurred when seamlessly running another window system as
Nitpicker client.
Misc
====
:Alarm framework:
Added 'next_deadline()' function to the alarm framework. This function is
used by the timer server to program the next one-shot timer interrupt,
depending on the scheduled timeouts.
:DDE Kit:
* Implemented 'dde_kit_thread_usleep()' and 'dde_kit_thread_nsleep()'
* Removed unused/useless 'dde_kit_init_threads()' function
:Qt4:
Added support for 'QProcess'. This class can be used to start Genode
applications from within Qt applications in a Qt4-compatible way.
Device drivers
##############
New single-threaded timer service
=================================
With the OKL4 support added with the previous release, the need for a new timer
service emerged. In contrast to the other supported kernels, OKL4 imposed two
restrictions, which made the old implementation unusable:
* The kernel interface of OKL4 does not provide a time source. The kernel
uses a APIC timer internally to implement preemptive scheduling but, in
contrast to other L4 kernels that support IPC timeouts, OKL4 does not
expose wall-clock time to the user land. Therefore, the user land has to
provide a timer driver that programs a hardware timer, handles timer
interrupts, and makes the time source available to multiple clients.
* OKL4 restricts the number of threads per address space according to a
global configuration value. By default, the current Genode version set
this value to 32. The old version of the timer service, however, employed
one thread for each timer client. So the number of timer clients was
severely limited.
Motivated by these observations, we created a completely new timer service that
dispatches all clients with a single thread and also supports different time
sources as back ends. For example, the back ends for Linux, L4/Fiasco, and
L4ka::Pistachio simulate periodic timer interrupts using Linux' 'nanosleep' system
call - respective IPC timeouts. The OKL4 back end contains a PIT driver
and operates this timer device in one-shot mode.
To implement the timer server in a single-threaded manner, we used an
experimental API extension to Genode's server framework. Please note that we
regard this extension as temporary and will possible remove it with the next
release. The timer will then service its clients using the Genode's signal API.
Even though the timer service is a complete reimplementation, its interface
remains unmodified. So this change remains completely transparent at the API level.
VESA graphics driver
====================
The previous release introduced a simple PCI-bus virtualization into the VESA
driver. At startup, the VESA driver uses the PCI bus driver to find a VGA card
and provides this single PCI device to the VESA BIOS via a virtual PCI bus. All
access to the virtualized PCI device are then handled locally by the VESA
driver. In addition to PCI access, some VESA BIOS implementations tend to use
the programmable interval timer (PIT) device at initialization time. Because we
do not want to permit the VESA BIOS to gain access to the physical timer
device, the VESA driver does now provide an extremely crippled virtual PIT.
Well, it is just enough to make all VESA BIOS implementations happy that we
tested.
On the feature side, we added support for VESA mode-list handling and a
default-mode fallback to the driver.
Misc
====
:SDL-based frame buffer and input driver:
For making the Linux version of Genode more usable, we complemented the
existing key-code translations from SDL codes to Genode key codes.
:PS/2 mouse and keyboard driver:
Improved robustness against ring-buffer overruns in cases where input events
are produced at a higher rate than they can be handled, in particular, if
there is no input client connected to the driver.
Platform-specific changes
#########################
Support for super pages
=======================
Previous Genode versions for the OKL4, L4ka::Pistachio, and L4/Fiasco kernels used
4K pages only. The most visible implication was a very noticeable delay during
system startup on L4ka::Pistachio and L4/Fiasco. This delay was caused by core
requesting the all physical memory from the root memory manager (sigma0) -
page by page. Another disadvantage of using 4K pages only, is the resulting TLB footprint
of large linear mappings such as the frame buffer. Updating a 10bit frame buffer
with a resolution of 1024x768 would touch 384 pages and thereby significantly
pollute the TLB.
This release introduces support for super pages for the L4ka::Pistachio and
L4/Fiasco versions of Genode. In contrast to normal 4K pages, a super page
describes a 4M region of virtual memory with a single entry in the page
directory. By supporting super pages in core, the overhead of the startup
protocol between core and sigma0 gets reduced by a factor of 1000.
Unfortunately, OKL4 does not support super pages such that this feature remains
unused on this platform. However, since OKL4 does not employ a root memory
manager, there is no startup delay anyway. Only the advantage of super pages
with regard to reduced TLB footprint is not available on this platform.
Support for write-combined access to I/O memory
===============================================
To improve graphics performance, we added principle support for write combined I/O access
to the 'IO_MEM' service of core. The creator of an 'IO_MEM' session can now specify the
session argument "write_combined=yes" at session-creation time. Depending on the
actual base platform, core then tries to establish the correct page-table
attribute configuration when mapping the corresponding I/O dataspace. Setting
caching attributes differs for each kernel:
* L4ka::Pistachio supports a 'MemoryControl' system call, which allows for specifying
caching attributes for a core-local virtual address range. The attributes are
propagated to other processes when core specifies such a memory range
as source operand during IPC map operations. However, with the current version,
we have not yet succeeded to establish the right attribute setting, so the performance
improvement is not noticeable.
* On L4/Fiasco, we fully implemented the use of the right attributes for marking
the frame buffer for write-combined access. This change significantly boosts
the graphics performance and, with regard to graphics performance, serves us
as the benchmark for the other kernels.
* OKL4 v2 does not support x86 page attribute tables. So write-combined access
to I/O memory cannot be enabled.
* On Linux, the 'IO_MEM' service is not yet used because we still rely on libSDL
as hardware abstraction on this platform.
Unification of linker scripts and startup codes
===============================================
During the last year, we consistently improved portability and the support for
different kernel platforms. By working on different platforms in parallel,
code duplications get detected pretty easily. The startup code was a steady
source for such duplications. We have now generalized and unified the startup
code for all platforms:
* On all base platforms (Linux-x86_32, Linux-x86_64, OKL4, L4ka::Pistachio, and
L4/Fiasco) Genode now uses the same linker script for statically linked
binaries. Therefore, the linker script has now become part of the 'base'
repository.
* We unified the assembly startup code ('crt0') for all three L4 platforms.
Linux has a custom crt0 code residing in 'base-linux/src/platform'. For
the other platforms, the 'crt0' codes resides in the 'base/src/platform/'
directory.
* We factored out the platform-depending bits of the C++ startup code
('_main.cc') into platform-specific '_main_helper.h' files. The '_main.cc'
file has become generic and moved to 'base/src/platform'.
Linux
=====
With the past two releases, we successively reduced the dependency of the
Linux version of core from the 'glibc'. Initially, this step had been
required to enable the use of our custom libc. For example, the 'mmap'
function of our libc uses Genode primitives to map dataspace to the
local address space. The back end of the used Genode functions, in turn,
relied on Linux' 'mmap' syscall. We cannot use syscall bindings provided
by the 'glibc' for issuing the 'mmap' syscall because the
binding would clash with our libc implementation of 'mmap'. Hence we
started to define our own syscall bindings.
With the current version, the base system of Genode has become completely
independent of the 'glibc'. Our custom syscall bindings for the x86_32 and
x86_64 architectures reside in 'base-linux/src/platform' and consist of
35 relatively simple functions using a custom variant of the 'syscall'
function. The only exception here is the clone system call, which requires
assembly resides in a separate file.
This last step on our way towards a glibc-free Genode on Linux pushes the
idea to only use the Linux kernel but no further Linux user infrastructure
to the max. However, it is still not entirely possible to build a Linux
based OS completely based on Genode. First, we have to set up the loopback
device to enable Genode's RPC communication over sockets. Second, we
still rely on libSDL as hardware abstraction and libSDL, in turn, relies
on the glibc.
:Implications:
Because the Linux version is now much in line with the other kernel platforms,
using custom startup code and direct system calls, we cannot support
host tool chains to compile this version of Genode anymore. Host tool chains, in
particular the C++ support library, rely on certain Linux features
such as thread-local storage via the 'gs' segment registers. These things are
normally handled by the glibc but Genode leaves them uninitialized.
To build the Linux version of Genode, you have to use the official
Genode tool chain.
OKL4
====
The build process for Genode on OKL4 used to be quite complicated. Before
being able to build Genode, one had to build the original Iguana user land
of OKL4 because the Genode build system looked at the Iguana build directory
for the L4 headers actually used. We now have simplified this process by
not relying on the presence of the Iguana build directory anymore. All
needed header files are now shadowed from the OKL4 source tree
to an include location within Genode's build directory. Furthermore, we
build Iguana's boot-info library directly from within the Genode build system,
instead of linking the binary archive as produced by Iguana's build process.
Of course, to run Genode on OKL4, you still need to build the OKL4 kernel
but the procedure of building the Genode user land is now much easier.
Misc changes:
* Fixed split of unmap address range into size2-aligned flexpages. The
'unmap' function did not handle dataspaces with a size of more than 4MB
properly.
* Fixed line break in the console driver by appending a line feed to
each carriage return. This is in line with L4/Fiasco and L4ka::Pistachio,
which do the same trick when text is printed via their kernel debugger.
L4ka::Pistachio
===============
The previous version of core on Pistachio assumed a memory split of 2GB/2GB
between userland and kernel. Now, core reads the virtual-memory layout from
the kernel information page and thereby can use up to 3GB of virtual memory.
*Important:* Because of the added support for super pages, the Pistachio
kernel must be built with the "new mapping database" feature enabled!
L4/Fiasco
=========
Removed superfluous zeroing-out of the memory we get from sigma0. This change
further improves the startup performance of Genode on L4/Fiasco.
Build infrastructure
####################
Tool chain
==========
* Bumped binutils version to 2.19.1
* Support both x86_32 and x86_64
* Made tool_chain's target directory customizable to enable building and
installing the tool chain with user privileges
Build system
============
* Do not include dependency rules when cleaning. This change brings not
only a major speedup but it also prevents dependency rules from messing
with generic rules, in particular those defined in 'spec-okl4.mk'.
* Enable the use of '-ffunction-sections' combined with '-gc-sections'
by default and thereby reduce binary sizes by an average of 10-15%.
* Because all base platforms, including Linux, now depend on the Genode tool
chain, the build system uses this tool chain as default. You can still
override the tool chain by creating a custom 'etc/tools.conf' file
in your build directory.

1017
doc/release_notes-09-11.txt Normal file

File diff suppressed because it is too large Load Diff

1224
doc/release_notes-10-02.txt Normal file

File diff suppressed because it is too large Load Diff

1211
doc/release_notes-10-05.txt Normal file

File diff suppressed because it is too large Load Diff

618
doc/release_notes-10-08.txt Normal file
View File

@@ -0,0 +1,618 @@
===============================================
Release notes for the Genode OS Framework 10.08
===============================================
Genode Labs
The Genode project is back with the feature-packed release 10.08, set out to
bring device support of the Genode OS Framework to the next level. Our road
map hinted at two particular spots of activity, introducing wireless networking
and enabling hardware-accelerated graphics. To pursue the first goal, we pushed
the boundaries of our Linux device driver environment by porting Madwifi to
Genode. When it comes to hardware-accelerated graphics, today the Gallium3D
protocol stack and the corresponding GEM GPU drivers are the state of the art
on Linux and other UNIX-like operating systems. With the current release, we
make this powerful graphics architecture available on Genode, including
support for hardware-accelerated 3D graphics on Intel GMA GPUs. But we haven't
stopped with our device-driver related activities here as we introduce a new
ATAPI driver accommodated with an ISO9660 file-system implementation, and we
largely revisited our existing driver base.
Apart from device-driver support, two major features of the release are the
upgrade of the Qt4 framework from version 4.5.2 to version 4.6.3 alongside with
many performance and stability improvements, and the added support for dynamic
linking on ARM platforms with both the OKL4 and Codezero kernels.
Gallium3D and Intel's Graphics Execution Manager
################################################
Gallium3D is the most modern and most actively developed open-source software
stack regarding hardware-accelerated graphics. It is mainly deployed on
Linux but it has been ported to other operating systems such as the BSD family,
OpenSolaris, AROS, and now Genode. In the following, we will first provide
a little background about Gallium3D followed by a rough overview on how its
components fit into Genode.
Gallium3D was designed to displace the long-evolved but inherently insecure
direct rendering infrastructure on Linux. With DRI, each application that uses
hardware-accelerated graphics has unlimited access to the GPU and its resources
such as the frame buffer. To allow multiple applications to use the GPU in a
time-shared manner, those applications have to behave cooperatively. There is a
central service, the DRM driver in the kernel, orchestrating the applications
in such a way that well-behaved applications use distinct GPU resources such as memory
and contexts, and so come along nicely. However, there are no effective measures
against misbehaving applications. A further consequence of this architecture
is the multitude of vendor-specific protocol implementations. Because each
application contains an instance of the GPU driver accessing the broad hardware
interface of the graphics device, each vendor happened to take a different route
for translating graphics APIs such as OpenGL to the actual device interface.
Consequently, the code basis for graphics protocol stacks has become extremely
complex and fragmented. In contrast, the designers of Gallium3D set out to
modularize the protocol stack such that generic code is easy to use by different
vendors and the vendor-specific portion of the protocol stack stays as small as
possible, thereby lowering the costs for new-device support in the future.
In contrast to DRI, a Gallium-based application does not operate directly on
the GPU device. Instead, it uses a higher-level abstraction, namely buffer
objects for holding data operated on by the GPU. Buffer objects can contain
pixels, geometry data, and GPU command streams. The latter type of buffer
object can be issued for execution to perform actual GPU operations. The
buffer-object interface is provided by a central service called graphics
execution manager (GEM) normally residing in the kernel. GEM arbitrates the
allocation of buffer objects, manages cache coherency between GPU and CPU, and
passes buffers objects containing GPU command streams scheduled for execution to the
graphics device.
The high-complexity Gallium3D protocol stack is instantiated for each
application and acts as a client of the (relatively) low-complexity GEM.
Provided that the GPU command stream assembled by a Gallium3D application
cannot subvert the operation of GEM, this architecture removes the complex
protocol stack from the trusted computing base. Only the low-complexity GEM
service must be trusted with regard to security, robustness, and the absence
of GPU-based inter-application crosstalk. In contrast to DRI, Gallium3D is
perfectly in line with the architecturally principles of Genode. On Linux, the
Gallium3D stack communicates with GEM via 'ioctl' operations on the '/dev/drm/'
device interface. In the context of Genode, GEM should be executed as a
user-level device driver and resource multiplexer providing the GEM operations
as a GPU session interface by the means of RPC and shared memory. Each
Gallium3D application connects to the GPU server and operates on a GPU session.
The puzzle pieces of Mesa/Gallium3D
===================================
Gallium3D is part of the Mesa OpenGL library. It comes as a set of modules
consisting of state trackers (API implementations such as OpenGL),
drivers (translating generic graphics commands into device-specific command
streams), winsys (the glue between a window system and the Gallium3D
application), and a large library of utilities. Most of the code is
independent from the actual GPU device as well as the operating-system.
On Genode, Mesa-7.8.1 has been incorporated into the 'libports' repository.
However, we only use the Gallium3D-related parts of Mesa on Genode. For
example, the port does not make use of the Mesa swrast facility for
software-based rendering. It rather relies on the Gallium3D softpipe driver.
When built, all generic Gallium3D-related parts of Mesa are linked into the
single 'gallium.lib.so' library.
The following figure gives an overview of how the components of the graphics
software stack relate to each other. The components are described in the
following.
[image img/gallium3d]
EGL driver
~~~~~~~~~~
EGL is an OS-agnostic API for managing rendering buffers. The implementation
of this API is OS-specific because, among other things, it cares about the
interaction of the application with the native windowing system such that the
result of GPU-based rendering can be displayed in the GUI. EGL also plays a special
role among the Gallium state trackers because it is used by other state trackers.
The window-system-specific code is called EGL driver. Mesa-7.8.1 comes with
EGL drivers for the X window system and the Linux kernel-mode-switching
interface. For Genode, we have added a new EGL driver that uses Genode's
'Framebuffer_session' interface as back end. It is located at
'libports/src/lib/egl'. Because the EGL driver is GPU-independent, it is
part of 'gallium.lib.so'. The following screenshot shows the EGL driver
in action.
[image img/gallium_softpipe_screen]
Gallium i915 GPU driver
~~~~~~~~~~~~~~~~~~~~~~~
We picked Intel's GMA as the first series of supported GPUs because they
are well documented and GEM has been implemented first for Intel GPUs.
There are two Gallium3D drivers for Intel GPUs called i915 and i965.
Currently, we have ported the i915 driver that supports the following GPU
models: i915 G/GM, i945 G/GM/GME, G33G, Q33G, and Q35G. On Genode, the Gallium3D
GPU driver comes in the form of a shared library called 'gallium-i915.lib.so'.
Is gets dynamically loaded by the EGL driver using 'dlopen'. If the EGL
driver fails to load the 'gallium-i915.lib.so' driver, it falls back
to the softpipe driver compiled into 'gallium.lib.so'.
Because there is no build dependency to this shared library, we created a
pseudo build target at 'libports/src/lib/gallium/i915' for the sole purpose of
building this library as a side effect.
On Linux, the code contained in 'gallium-i915.lib.so' communicates with the '/dev/drm/'
device interface. However, the interaction with the device is not performed
directly but via a library called 'libdrm'.
libdrm
~~~~~~
The DRM library is a convenient front end to the '/dev/drm/' device. At
first glance, replacing this library with a Genode-specific implementation
seems natural. However, because 'libdrm' is not only a mere wrapper around the 'ioctl'
interface of the device but also contains a substantial amount of program logic
and device heuristics, we decided to reuse this library unmodified and go for
the 'ioctl' interface as a hook to connect Gallium3D with GEM. Hence, 'libdrm'
has become part of the 'libports' repository alongside Mesa. Ultimately,
'libdrm' translates all requests coming from 'gallium-i915.lib.so' to
(GPU-specific) 'ioctl' and 'mmap' operations on the '/dev/drm/' device. On
Genode, there is no such device. In fact, there are no device nodes at all.
Instead, we use our libc plugin mechanism to redirect operations on this
specific device file to a dedicated libc plugin. When 'libdrm' opens '/dev/drm/', the
libc plugin located at 'src/lib/libdrm/' takes over the responsibility of the
returned file descriptor. Therefore all file operations on this file handle are
handed over to the plugin. This is the point where we can transparently
incorporate RPC communication to the GEM service. For now, however, we do not
have RPC stub code yet. Instead, we link the GEM code directly into
'gallium-i915.lib.so'. This allows us to implement the GEM-related 'ioctl'
operations by calling GEM code directly. For the interaction between
'libdrm' and GEM, we added a preliminary 'Gpu_driver' interface located at
'os/include/gpu/'.
Graphics execution manager
~~~~~~~~~~~~~~~~~~~~~~~~~~
GEM is normally part of the Linux kernel and dispatches (a subset of)
operations on '/dev/drm/'. We use the Intel-specific GEM code taken from
Linux-2.6.34. This code relies on the Intel-AGP subsystem to manage the GPU's
graphics translation table. Therefore, we had to port the Intel-AGP sub system
as well. Because GEM is a relatively new feature of the Linux kernel, we
decided to not use our Linux device driver environment (currently based on the
kernel version 2.6.20) for our porting work but rather went for the creation
of a driver-specific Linux emulation environment. The code is part of the
'linux_drivers' repository and located at 'src/drivers/gpu/'. The 'contrib/'
subdirectory contains unmodified Linux code, the 'i915' subdirectory contains
the implementation of the 'Gpu_driver' interface and code for emulating Linux
interfaces in a way that the 'contrib/' code behaves like in its natural
execution environment.
Building an OpenGL application
==============================
As an example on how to build an OpenGL application on Genode, the 'libports'
repository provides a slightly modified version of the famous Gears demo.
You can find the code under 'libports/app/eglgears/'.
Prior building the application, make sure that you have issued 'make
prepare' for the 'mesa' and 'libdrm' libraries. In the root of the 'libports'
repository, issue the following commands to download the upstream source
codes for these libraries and to integrate them with the Genode build system:
! make prepare PKG=mesa
! make prepare PKG=libdrm
After having added 'libc' and 'libports' to the 'REPOSITORIES' declaration
of your '<build-dir>/etc/build.conf', you can building 'eglgears' via
'make app/eglgears'. The build process will create the 'eglgears' executable
alongside with 'gallium.lib.so'. You can start 'eglgears' using a plain
framebuffer such as 'vesa_drv'. The EGL driver included in 'gallium.lib.so'
will try to load a shared library called 'gallium-i915.lib.so' and, if not
present, revert to the softpipe driver.
If you want to give the hardware-accelerated version a spin, you will
need to build 'gallium-i915.lib.so'. The driver is only built when
the build 'SPECS' variable contains the keyword 'i915'. Simply add the
following line to your '<build-dir>/etc/specs.conf' file:
! SPECS += i915
Currently, the GEM (contained in the 'linux_drivers' repository') is
linked to 'gallium-i915.lib.so'. Hence, the 'linux_drivers' repository
must be specified in your 'build.conf'. The Gallium driver is built
as a side effect of building a pseudo target via:
! make lib/gallium
If you add the resulting 'gallium-i915.lib.so' to core's ROM service,
the EGL driver will attempt to use the hardware driver.
Current limitations
===================
At the current stage, Gallium3D on Genode is able to run the Gears
demo using Intel GMA GPUs. However, the work done so far must be
regarded as the first of several steps towards a complete solution.
Let us highlight the most important limitations and construction
sites:
* Both GEM and the Gallium3D protocol stack are executed as part of
a single process, accessing the GPU exclusively. Until we have
separated GEM from Gallium3D, only a single GPU-using application
can run at a time.
* Even though a Gallium3D application is able to use the GPU for
3D rendering, the EGL driver relies on CPU-based blitting
in order to transfer the rendering result to the screen.
* Interrupt-based synchronization has not been implemented yet. The
GPU is expected to be faster than the CPU. For this reason,
the EGL driver waits for 5 ms after each rendered frame.
Proper vblank handling is desired.
* On some platforms, we observed pixel artifacts, which
we attribute to cache coherency issues.
* Resource deallocation within the GEM driver has not been implemented
yet. Therefore, we expect that the current version is not suited for
highly dynamic applications.
* The 'eglgears' demo runs fine with resolutions up to 800x600
but we observed unstable behaviour with higher resolutions.
Despite of these limitations, the first version of Gallium3D on
Genode showcases that a subsystem as comprehensive as Gallium3D
plus GEM can be natively executed on Genode.
Operating-system services and libraries
#######################################
Init configuration concept
==========================
The previous release 10.05 introduced a new configuration concept that enables
the specification of mandatory access-control rules among flexible ways to
route service requests throughout the system. With the current release, this
concept is used by default. We have adapted all example configurations to the
new format, polished the new init implementation, and moved it from
'os/src/init/experimental/' to 'os/src/init/'. The old init variant is still
available at 'os/src/init/traditional/' but it is scheduled to be removed with
the next release 10.11.
The description of the configuration concept and the XML format is provided by
the document "Configuring the init process of Genode" located at
'os/doc/init.txt'.
Block session interface
=======================
The block session interface extends Genode's range of device-class interfaces by
a general-purpose interface to access block devices. It is based on the
packet-stream framework, using a single TX-stream to transmit block requests
to the server-side. Clients are free to request read/write operations on
several sequent blocks at once. Services implementing the server-side of the
block-session interface can choose an appropriate block size and the kind of
block-operation they support (e.g., read-only device). The new block session
interface is located at 'os/include/block_session/'.
ROM-loop block device
=====================
Based on the new block session interface, we implemented a service, which
provides a rom-file as read-only block-device. Linux users might know this
kind of service under the term "loop device". The following configuration
snippet shows how the file provided by a rom-session can be used as block
device:
! <config>
! ...
! <start name="rom_loopdev">
! <resource name="RAM" quantum="1M"/>
! <provides><service name="Block"/></provides>
! <config>
! <filename>livecd.iso</filename>
! </config>
! </config>
C runtime enhancements
======================
Both 'libc' and 'libm' are now built as *shared objects*, reducing the memory
footprint for scenarios with multiple libc-using applications. When starting
programs that use the libc, make sure to have 'libc.lib.so' and 'libm.lib.so'
available as files at the ROM service.
Motivated by our work on Gallium3D and libdrm, we extended the libc *plugin*
*interface* with the support of 'ioctl' and 'mmap'. This change enables us to
install custom handlers of those libc calls for a specific file. In the
particular case, libdrm performs 'ioctl' and 'mmap' calls referring to the
'/dev/drm' device interface. Now, we can supply a libc plugin specific for a
single file.
The update of Qt4 from version 4.5.2 to version 4.6.3 required refinements
of 'clock_gettime()', 'sysctl()', and 'getpagesize()'. Those functions
are still dummy stubs but with a meaningful behaviour from Qt4's perspective.
DDE Kit
=======
During our various device-driver activities, we improved the DDE Kit support
library for device-driver developments. The revised handling of I/O memory
resources now allows multiple requests of the same resource to support, e.g.,
multiple Linux 'ioremap()' calls. The I/O memory-mapping type is configurable
as uncached or write-combined, and DDE Kit automatically keeps track of
virtual-to-physical address mappings. Also, DDE Kit now provides 64-bit integer
types and a proper 'size_t'.
Dynamic linker
==============
In order to support shared libraries on ARM platforms, we added EABI support to
the dynamic linker and Genode's build-system environment. Thus shared libraries
are now supported on Codezero and OKL4 GTA01 targets. This also includes C++
exception handling.
Additionally, we implemented libc's dynamic linking interface ('dlfcn.h') and are
now able to support dynamic loading of libraries by applications via 'dlopen'
and friends.
Device drivers
##############
New ATAPI driver
================
With version 10.08, Genode provides a port of the low level ATA/ATPI driver
available from [http://ata-atapi.com]. Currently, the driver supports ATAPI
devices only and is implemented as a block-interface server (see Section
[Block device interface]). By default, the driver tries to take advantage of
the device's DMA engine but it can also operate in PIO mode as a fall-back
solution.
New wireless networking driver
==============================
According to our roadmap, we introduce initial support for wireless networking.
Based on DDE Linux 2.6, a port of the madwifi driver (version 0.9.4) is now
available for Genode. This driver supports widely used wifi-cards containing an
Atheros chipset (namely: 5210, 5211, 5212).
Due to the fact that part of the madwifi-project's contribution is binary code
in uuencoded form containing mandatory copyright headers, you need a 'uudecode'
binary installed on your system if you like to compile the madwifi driver for
Genode. If you're using Ubuntu/Debian or one of its derivates as your
development environment, you might install the necessary application via:
! sudo aptitude install sharutils
! emerge sharutils (on Gentoo)
This first wireless networking driver is in experimental stage and doesn't
support any form of encryption and authentication on the ieee80211 layer. So
you can only use it in conjunction with an unprotected access-point.
To set an appropriate ESSID you can tweak the driver's configuration, like in
the following example:
! <config>
! ...
! <start name="madwifi_drv">
! <resource name="RAM" quantum="2M"/>
! <provides><service name="Nic"/></provides>
! <config>
! <essid>My_access_point</essid>
! </config>
! </config>
When started, the 'madwifi_drv' announces a "Nic" session usable by the
lwIP stack.
PCI driver
==========
We enhanced the PCI bus scanning facility of our PCI driver with regard to
multi-function devices and added an accessor function for the physical
bus-device-function (BDF) ID.
VESA driver
===========
To support a wider range of graphics cards, we revised the VESA driver and
support more peculiarities of VBE implementations. Some of these are: unaligned
I/O port accesses, dependency on the physical BDF of PCI devices, support for
all flavours of PCI configuration space accesses.
PS/2 input driver
=================
Even after long years of intensive use, the PS/2 driver is sometimes good for a
surprise, which prompted us to improve the keyboard scan code and mouse button
handling. The driver fully supports scan code set 1 and 2 keyboards and copes
with oddities like "fake shift" events and "yet another scan code for Pause".
Timer
=====
The current release corrects a shortcoming of our timer driver on Pistachio and
Fiasco. Timing on these platforms is now more accurate.
Paravirtualized Linux
#####################
Based on the new block-session interface, we implemented a new stub driver
for OKLinux that enables the usage of a block-session device within Linux.
Thereby, the old stub driver that provided a ROM file as block device
is no longer needed and will be removed with the next release. A ROM file
can now be supplied to Linux via the new ROM loop service.
Protocol stacks and libraries
#############################
lwIP
====
Tweaking the configuration of the lightweight IP stack to better fit Genode's
application needs lead to a considerable improvement with respect to network
performance.
ISO9660 file system
===================
ISO9660 is the standard file system used on data CD/DVD medias. With the ATAPI
driver ready, we implemented ISO9660 support on top of the this driver. The
'iso9660' server implements the ROM-session interface and can be used by any
ROM connection. In order to take advantage of this new feature, we exploit
Genode's new configuration concept and route the client's ROM service
request to the ISO9660 server.
Configuration file snippet:
! <start name="atapi_drv">
! <resource name="RAM" quantum="1M" />
! <provides><service name="Block" /></provides>
! </start>
! <start name="iso9660">
! <resource name="RAM" quantum="10M" />
! <provides><service name="ROM" /></provides>
! </start>
! <start name="iso-client">
! <resource name="RAM" quantum="1M" />
! <route>
! <service name="ROM"><child name="iso9660"/></service>
! <any-service><parent /><any-child/></any-service>
! </route>
! </start>
:Limitations:
The memory necessary to read a file from the ATAPI driver into memory is
currently accounted on behalf of the ISO9660 server, not for the client side.
Because of this limitation, it becomes necessary to equip the ISO server with
a sufficient memory quota.
The 'Ecma-119' standard requires support for 8.3 upper-case file names only.
Because of this limitation, a number of unapproved ISO 9660 extensions have
evolved (eg. Joliet, Rock Ridge). Since we don't see using 8.3 file names within
Genode as an option, we added Rock Ridge extension support to the ISO 9660
server. Please make sure that your ISO-creation tool supports the Rock Ridge
extension and enable it during ISO creation.
Qt4.6.3
=======
We updated our port of the Qt4 framework from version 4.5.2 to version 4.6.3.
Thereby, we changed the way of how the source code is organized. Previously, we
maintained copies of modified files within the 'qt4' repository. Now, we
keep those changes in the form of patches, which get applied to the 'contrib'
code when 'make prepare' is issued within the 'qt4' repository. This change
significantly reduces the size of the 'qt4' repository. We applied the same
approach to the port of the Arora browser. Furthermore, the performance and
stability of Qt4 and Webkit in particular have received a lot of attention,
resulting in a much improved Arora browsing experience.
Platform-specific changes
#########################
OKL4
====
With the current release, we have started to maintain a few patches of the
official version of the OKL4v2 kernel. The patches are located at
'base-okl4/patches' and have the following purpose:
:'syscall_pic.patch':
The original distribution of the OKL4 kernel comes with x86 syscall bindings
that use absolute addressing modes. Therefore, code using L4 syscalls
cannot be compiled as position-independent code (gcc option '-fPIC').
Unfortunately, shared libraries must be compiled as position independent
because the location of such a library's text segment is not known at
compile time. Consequently, OKL4 syscalls cannot be issued by shared
libraries, which is a severe limitation. The patch fixes the problem
by changing all OKL4 syscall bindings and removing PIC-incompatible
addressing modes. It does not affect the functionality of the kernel.
:'eabi_build.patch':
The build system of the orignal OKL4 distribution is not prepared to
compile ARM EABI binaries as generated by modern tool chains such as the
Codesourcery GCC. The patch applies the needed changes to the OKL4 build
infrastructure.
Pistachio
=========
Similar to the situation with the OKL4 kernel, we need to patch the Pistachio
system-call bindings to enable syscalls from shared libraries. The
corresponding patch is located at 'base-pistachio/patches' and is known to work
with Pistachio revision 'r782:57124b75c67c'. Without applying this patch, the
linker generates text relocation infos, which result in a run-time error of the
'ldso' on the attempt to modify the read-only text segment of a shared library.
Codezero
========
Because we enhanced our dynamic linker to support ARM EABI, shared libraries
are now fully usable with the Codezero kernel.
Tools and build system
######################
Unified tool chain for building ARM targets
===========================================
With the previous versions of Genode,
we took the approach to use the tool chains of the respective kernel
to build Genode targets. For example, we used to rely on NICTA's ARM cross compiler
(based on gcc-3.4) for building Genode for the OKL4/gta01 platform.
Genode on Codezero, however, used the Codesourcery tool chain. We identified this approach as
a dead end because we would need to support modern tool chains alongside
ancient tool chains that are no longer used in practice. For accommodating
the latter, we had to introduce special workarounds and make compromises.
Therefore, we changed Genode to officially support one modern reference
tool chain to build all ARM-specific targets both on OKL4 and Codezero.
Currently, we use the Codesourcery tool chain version 2009q3-67, which
is available here:
:Codesourcery ARM EABI tool chain:
[http://www.codesourcery.com/sgpp/lite/arm/portal/release1039]
Because the original OKL4v2 distribution does not support modern ARM EABI tool
chains, it cannot be used out of the box anymore. But you can find a patch
to enable ARM EABI for OKL4v2 at 'base-okl4/patches/'.
Build system
============
* We changed the build system to link all shared libraries with
the '--whole-archive' option.
* All libraries are now built as position-independent code (compiler
option '-fPIC') by default. It is possible to explicitly disable
'-fPIC' by adding 'CC_OPT_PIC=' to the library description file.
* To ease the integration of third-party code into the Genode build
system, we have added a mechanism for setting source-file-specific
compiler options. Compiler arguments for a single file such as
'main.cc' can be assigned by setting the build variable 'CC_OPT_main'.

871
doc/release_notes-10-11.txt Normal file
View File

@@ -0,0 +1,871 @@
===============================================
Release notes for the Genode OS Framework 10.11
===============================================
Genode Labs
During the past three months, the Genode project was primarily driven by our
desire to create a bigger picture out of the rich set of components that we
introduced over time, in particular over the last year. Looking back at the
progress made since mid 2009, there were many functional additions to the
framework, waiting to get combined. To name a few, we added support for
networking, audio output, real-time priorities, mandatory access control,
USB, ATAPI block devices, Python, hardware-accelerated 3D graphics, Qt4,
the WebKit-based Arora browser, and the paravirtualized OKLinux kernel.
So many wonderful toys waiting to get played with. This is how the idea of
creating [http://genode.org/download/live-cds - the new Genode Live CD] was
born. In the past, Genode was mostly used in settings with a relatively static
configuration consisting of several components orchestrated to fulfill
a few special-purpose functions. Now, the time has come for the next step,
creating one dynamic setup that allows for the selection of different subsystems
at runtime rather than at boot time.
This step is challenging in several ways. First, the processes that form
the base system have to run during the entire time of all demo setups. If
any of those processes contained stability problems or leaked memory, it would
subvert the complete system. Second, the components of all subsystems combined
are far too complex to be loaded into memory at boot time. This would not
only take too long but would consume a lot of RAM. Instead, those components
and their data had to be fetched from disk (CDROM) on demand. Third, because
multiple demo subsystems can be active at a time, low-level resources such as
networking and audio output must be multiplexed to prevent different
subsystems from interfering with each other. Finally, we had to create a
single boot and configuration concept that is able to align the needs of all
demos, yet staying manageable.
Alongside these challenges, we came up with a lot of ideas about how Genode's
components could be composed in new creative ways. Some of these ideas such
as the browser-plugin concept and the http-based block server made it onto
the Live CD. So for producing the Live CD, we not only faced the said
technical challenges but also invested substantial development effort in new
components, which contributed to our overall goal. Two weeks ago, we released
the Live CD. This release-notes document is the story about how we got there.
To keep ourself focused on the mission described above, we deferred the
original roadmap goal for this release, which was the creation of a Unix-like
runtime environment to enable compiling Genode on Genode. This will be the
primary goal for the next release.
Execution environment for gPXE drivers
######################################
Up to now, DDE Linux provided Genode with drivers for hardware devices
ranging from USB HID to WLAN. In preparation of the live CD, we
noticed the demand for support of a broader selection of ethernet
devices. Intel's e1000 PCI and PCIe cards seemed to mark the bottom
line of what we had to support. The major advantage of NIC drivers
from Linux is their optimization for maximum performance. This emerges
a major downside if DDE Linux comes into play: We have to provide all
the nifty interfaces used by the driver in our emulation framework. To
achieve our short-term goal of a great live CD experience, we had to
walk a different path.
[http://gpxe.org/ - gPXE] is a lovely network boot loader / open-source
PXE ROM project and the successor of the famous Etherboot
implementation. Besides support for DNS, HTTP, iSCSI and AoE, gPXE
includes dozens of NIC drivers and applies a plain driver framework.
As we were also itching to evaluate DDE kit and the DDE approach at
large with this special _donator OS_, we went for implementing the
device-driver environment for gPXE (DDE gPXE).
The current version provides drivers for e1000, e1000e, and pcnet
devices. The emulation framework comprises just about 600 lines of
code compared to more than 22,000 LOC reused unmodified from gPXE.
Benchmarks with the PCNet32 driver showed that DDE gPXE's performance
is comparable to DDE Linux.
The gPXE driver environment comes in the form of the new 'dde_gpxe'
repository. For building DDE gPXE, you first need to download and patch
the original sources. The top-level makefile of this repository automates
this task. Just issue:
! make prepare
Now, you need to include the DDE gPXE repository into your Genode
build process. Just add the path to this directory to the
'REPOSITORIES' declaration of the 'etc/build.conf' file within your
build directory, for example
! REPOSITORIES += $(GENODE_DIR)/dde_gpxe
After successful build the DDE gPXE based ethernet driver is located
at 'bin/gpxe_nic_drv'.
On-demand paging
################
In the [http://genode.org/documentation/release-notes/8.11#section-8 - release 8.11],
we laid the foundation for implementing user-level dataspace managers.
But so far, the facility remained largely unused except for managing thread
contexts. This changed with this release.
So what is a user-level dataspace manager and who needs it? In short,
Genode's memory management is based on dataspaces. A dataspace is a
container for memory. Normally, it is created via core's RAM or ROM
services. The RAM service hands out dataspaces containing contiguous
physical memory. After allocating such a RAM dataspace, the creator can
attach the dataspace to its own address space to access the dataspace
content. In addition, it can pass a dataspace reference (called dataspace
capability) to other processes, which, in turn, can than attach the same
dataspace to their local address space, thereby establishing shared memory.
Similarly, core's ROM service hands out boot-time binary data as dataspaces.
For the most use cases of Genode so far, these two core services were the
only dataspace providers needed. However, there are use cases that require
more sophisticated memory management. For example, to implement swapping,
the content of a dataspace must be transferred to disk in a way that
is transparent to the users of the dataspace. In monolithic kernels, such
functionality is implemented in the kernel. But on a multi-server OS
such as Genode, this is no option. Implementing such a feature into
core would increase the trusted computing base of all applications
including those who do not need swapping. Core would need a hard-disk
driver, effectively subverting the Genode concept. Other examples for
advanced memory-management facilities are copy-on-write memory and
non-contiguous memory - complexity we wish to avoid at the root of the
process tree. Instead of implementing such memory management facilities
by itself, core provides a mechanism to let any process manage dataspaces.
This technique is also called user-level page-fault handling.
For the Live CD, we decided to give Genode's user-level page-fault handling
facility a go. The incentive was accessing files stored on CDROM in an
elegant way. We wanted to make the CDROM access completely transparent to
the applications. An application should be able to use a ROM session as
if the file was stored at core's ROM service. But instead of being
provided by core, the session request would be delegated to an
alternative ROM service implementation that reads the data from disk
as needed. Some of the files stored in the CDROM are large. For example,
the disk image that we use for the Linux demo is 160MB. So reading
this file at once and keeping it in memory is not an option. Instead, only
those parts of the file should be read from disk, which are actually
needed. To uphold the illusion of dealing with plain ROM files for
the client, we need to employ on-demand-paging in the CDROM server.
Here is how it works.
# The dataspace manager creates an empty managed dataspace. Core
already provides a tool for managing address spaces called
region manager (RM service). A RM session is an address space,
to which dataspaces can be attached. This is exactly what is
needed for a managed dataspace. So a dataspace manager uses the
same core service to define the layout of a managed dataspace
as is used to manage the address space of a process. In fact,
any RM session can be converted into a managed dataspace.
! enum { MANAGED_DS_SIZE = 64*1024*1024 };
! Rm_connection rm(0, MANAGED_DS_SIZE);
This code creates a RM session with the size of 64MB. This is an empty
address space. A dataspace capability that corresponds to this address
space can then be requested via
! Dataspace_capability ds = rm.dataspace();
# The dataspace capability can be passed to a client, which may
attach the dataspace to its local address space. Because the
managed dataspace is not populated by any backing store, however,
an access would trigger a page fault, halting the execution of
the client. Here, the page-fault protocol comes into play.
# The dataspace manager registers itself for receiving a signal each time
a fault occurs:
! Signal_receiver rec;
! Signal_context client;
! Signal_context_capability sig_cap = rec.manage(client);
! rm.fault_handler(sig_cap);
When an empty part of the managed dataspace is accessed by any
process, a signal is delivered. The dataspace manager can then
retrieve the fault information (access type, fault address) and
dispatch the page fault by attaching a real dataspace at the
fault address of the managed dataspace. In a simple case, the code
looks as follows:
! while (true) {
! Signal signal = rec.wait_for_signal();
! for (int i = 0; i < signal.num(); i++) {
! Rm_session::State state = rm.state();
! ds = alloc_backing_store_dataspace(PAGE_SIZE);
! rm.attach_at(ds, state.addr & PAGE_MASK);
! }
! }
This simple page-fault handler would lazily allocate a page of
backing store memory each time a fault occurs. When the backing
store is attached to the managed dataspace, core will automatically
wake up the faulted client.
# The example above has the problem that the dataspace manager has
to pay for the backing store that is indirectly used by the client.
To prevent the client from exhausting the dataspace manager's memory,
the dataspace manager may choose to use a limited pool of backing
store only. If this pool is exceeded, the dataspace manager can reuse
an already used backing-store block by first revoking it from its
current managed dataspace:
! rm.detach(addr);
This will flush all mappings referring to the specified address
from all users of the managed dataspace. The next time, this
address region is accessed, a new signal will be delivered.
This page-fault protocol has the following unique properties. First,
because core is used as a broker between client and dataspace manager, the
dataspace manager remains completely unaware of the identity of its client.
It does not even need to possess the communication right to the client. In
contrast, all other user-level page-fault protocols that we are aware of
require direct communication between client and dataspace manager. Second,
because dataspaces are used as first-level objects to resolve page faults,
page faults can be handed at an arbitrary granularity (of course, a multiple
of the physical page size). For example, a dataspace manager may decide to
attach backing-store dataspaces of 64K to the managed dataspace. So the
overhead produced by user-level page-fault handler can be traded for the
page-fault granularity. But most importantly, the API is the same across
all kernels that support user-level page fault handling. Thus the low-level
page-fault handling code becomes inherently portable.
Having said that, we have completed the implementation of the described
core mechanisms, in particular the 'detach' facility, for OKL4. The ISO9660
driver as featured on the Live CD implements the 'ROM' interface and
reads the contents of those files from CDROM on demand. It uses a
fixed pool of backing store, operates at a page-fault granularity of
64KB, and implements a simple fifo replacement strategy.
Base framework
##############
There had been only a few changes to the base framework described as
follows.
We unified the core-specific console implementation among all
base platforms and added synchronization of 'vprintf' calls.
The kernel-specific code resides now in the respective
'base-<platform>/src/base/console/core_console.h' files.
We removed the argument-less constructor from 'Allocator_avl_tpl'.
This constructor created an allocator that uses itself for
meta-data allocation, which is the usual case when creating
local memory allocators. However, on Genode, this code is typically
used to build non-memory allocators such as address-space regions.
For these use cases, the default policy is dangerous. Hence, we
decided to remove the default policy.
The 'printf' helper macros have been unified and simplified. The
available macros are 'PINF' for status information, 'PWRN' for warnings,
'PLOG' for log messages, and 'PERR' for errors. By default, the message
types are colored differently to make them easily distinguishable.
In addition to normal messages, there is the 'PDBG' for debugging
purposes. It remains to be the only macro that prints the function name
as message prefix and is meant for temporary messages, to be removed
before finalizing the code.
Genode's on-demand-paging mechanism relies on the signalling framework.
Each managed dataspace is assigned to a distinct signal context.
Hence, signal contexts need to be created and disposed alongside
with managed dataspaces. We complemented the signalling framework
with a 'dissolve' function to enable the destruction of signal
contexts.
Operating-system services and libraries
#######################################
Finished transition to new init concept
=======================================
With the release 10.05, we introduced the
[http://genode.org/documentation/release-notes/10.05#section-0 - current configuration concept of init].
This concept supports mandatory access control and provides flexible
ways for defining client-server relationships. Until now, we maintained
the old init concept. With the current release, the transition to the
new concept is finished and we removed the traditional init.
We retained the support for loading configurations for individual subsystems
from different files but adopted the syntax to the use of attributes.
Instead of
! <configfile>subsystem.config</configfile>
the new syntax is
! <configfile name="subsystem.config"/>
Virtual network bridge (Proxy ARP)
==================================
Since we originally added networking support to Genode, only one program could
use the networking facilities at a time. In the simplest form, such a program
included the network driver, protocol stack, and the actual application. For
example, the uIP stack featured with release 9.02 followed this approach.
In release 9.11 we added the 'Nic_session' interface to decouple the network
driver from the TCP/IP protocol stack. But the 1-to-1 relation between
application and network interface remained. With the current release, we
introduce the 'nic_bridge' server, which is able to multiplex the 'Nic_session'
interface.
The implementation is roughly based on the proxy ARP RFC 1027. At startup, the
'nic_bridge' creates a 'Nic_session' to the real network driver and, in turn,
announces a 'Nic' service at its parent. But in contrast to a network driver
implementing this interface, 'nic_bridge' supports an arbitrary number of
'Nic_sessions' to be opened. From the client's perspective, such a session
looks like a real network adaptor.
This way, it has become possible to run multiple TCP/IP stacks in
parallel, each obtaining a distinct IP address via DHCP. For example,
is has become possible to run multiple paravirtualized Linux kernels
alongside an lwIP-based web browser, each accessing the network via a
distinct IP address.
As a side effect for developing the 'nic_bridge', we created a set
of utilities for implementing network protocols. The utilities are
located at 'os/include/net' and comprise protocol definitions for
ethernet, IPv4, UDP, ARP, and DHCP.
Nitpicker GUI server
====================
Our work on the Live CD motivated several improvements of the Nitpicker
GUI server.
Alpha blending
~~~~~~~~~~~~~~
In addition to nitpicker's plain pixel buffer interface that is compatible
with a normal framebuffer session, each nitpicker session can now have
an optional alpha channel as well as an corresponding input-mask channel
associated. Both the alpha channel and the input mask are contained in the
same dataspace as the pixel buffer. The pixel buffer is followed by
the 8-bit alpha values, which are then followed by the input-mask values.
This way, the presence of an alpha channel does not interfere with the
actual pixel format. Each 8-bit input mask value specifies the user-input
policy for the respective pixel. If the value is zero, user input
referring to the pixel is not handled by the client but "falls through"
the view that is visible in the background of the pixel. This is typically
the case for drop shadows. If the input-mask value is '1', the input
is handled by the client.
With the input-mask mechanism in place, we no longer have a definitive
assignment of each pixel to a single client anymore. In principle, an
invisible client is able to track mouse movements by creating a full-screen
view with all alpha values set to '0' and all input-mask values set to '1'.
Once, the user clicks on this invisible view, the user input gets routed
to the invisible client instead of the actually visible view. This
security risk can be addressed at two levels:
* In X-Ray mode, nitpicker completely disables alpha blending
and the input-mask mechanism such that the user can identify the
client that is responsible for each pixel on screen.
* The use of the alpha channel is a session argument, which is specified
by nitpicker clients at session-creation time. Consequently, this
session argument is subjected to the policy of all processes involved
with routing the session request to nitpicker. Such a policy may permit
the use of an alpha channel only for trusted applications.
_Caution:_ The use of alpha channels implies read operations from
the frame buffer. On typical PC graphics hardware, such operations are
extremely slow. For this reason, the VESA driver should operate in
buffered mode when using alpha blending in Nitpicker.
Tinted views in X-Ray mode
~~~~~~~~~~~~~~~~~~~~~~~~~~
We added support for tinting individual clients or groups of clients
with different colors based on their label as reported at session-creation
time. By using session colors, nitpicker assists the user to tell apart
different security domains without reading textual information. In
addition to the tinting effect, the title bar presents the session
color of the currently focused session.
The following nitpicker configuration tints all views of the launchpad
subsystem in blue except for those views that belong to the testnit
child of launchpad. Those are tinted red.
! <config>
! <policy label="launchpad" color="#0000ff"/>
! <policy label="launchpad -> testnit" color="#ff0000"/>
! </config>
Misc Nitpicker changes
~~~~~~~~~~~~~~~~~~~~~~
We introduced a so-called 'stay-top' session argument, which declares
that views created via this session should stay on top of other views.
This function is useful for menus that should always remain accessible
or banner images as used for Live CD.
Nitpicker's reserved region at the top of the screen used to cover up
the screen area as seen by the clients. We have now excluded this area
from the coordinate system of the clients.
We implemented the 'kill' mode that can be activated by the 'kill' key.
(typically this is the 'Print Screen' key) This feature allows the user
to select a client to be removed from the GUI. The client is not
actually killed but only locked out. The 'kill' mode is meant as an
emergency brake if an application behaves in ways not wanted by the
user.
ISO9660 server
==============
As outlined in Section [On-demand paging], we revisited the ISO9660 server
to implement on-demand-paged dataspaces. It is the first real-world
use case for Genode's user-level page-fault protocol. The memory pool
to be used as backing store for managed dataspaces is dimensioned according
to the RAM assigned to the iso9660 server. The server divides this backing
store into blocks of 64KB and assigns those blocks to the managed dataspaces
in a fifo fashion. We found that using a granularity of 64KB improved the
performance over smaller block sizes because this way, we profit from reading
data ahead for each block request. This is particularly beneficial for
CDROM drives because of their extremely long seek times.
Audio mixer
===========
We added a new *channel synchronization* facility to the 'Audio_out_session'
interface. An 'Audio_out_session' refers to a single channel. For stereo
playback, two sessions must be created. At session-creation time, the
client can provide a hint about the channel type such as "front-left" as
session-construction argument. This design principally allows for supporting
setups with an arbitrary amount of channels. However, those channels must
be synchronized. For this reason, we introduced the 'sync_session' function
to the 'Audio_out_session' interface. It takes the session capability of
another 'Audio_out_session' as argument. The specified session is then
used as synchronization reference.
To reduce the latency when stopping audio replay, we introduced a new *flush*
function to the 'Audio_out_session' interface. By calling this function,
a client can express that it is willing to discard all audio data already
submitted to the mixer.
Furthermore, we improved the audio mixer to support both long-running
streams of audio and sporadic sounds. For the latter use case, low latency
is particularly critical. In this regard, the current implementation is a
vast improvement over the initial version. However, orchestrating the
mixer with audio drivers as well as with different clients (in particular
ALSA programs running on a paravirtualized Linux) is not trivial. In the
process, we learned a lot, which will eventually prompt us to further
optimize the current solution.
Nitpicker-based virtual Framebuffer
===================================
To support the browser-plugin demo, we introduced 'nit_fb', which is a
framebuffer service that uses the nitpicker GUI server as back end. It
is similar to the liquid framebuffer as featured in the 'demo' repository
but in contrast to liquid framebuffer, 'nit_fb' is non-interactive.
It has a fixed screen position and size. Furthermore, it does not
virtualize the framebuffer but passes through the framebuffer portion of
the nitpicker session, yielding better performance and lower latency.
If instantiated multiple times, 'nit_fb' can be used to statically arrange
multiple virtual frame buffers on one physical screen. The size and screen
position of each 'nit_fb' instance can be defined via Genode's configuration
mechanism using the following attributes of the 'nit_fb' config node:
! <config xpos="100" ypos="150"
! width="300" height="200"
! refresh_rate="25"/>
If 'refresh_rate' isn't set, the server will not trigger any refresh
operations by itself.
On the Live CD, each browser plugin instantiates a separate instance of
'nit_fb' to present the plugin's content on screen. In this case, the
view position is not fixed because the view is further virtualized by the
loader, which imposes its policy onto 'nit_fb' - Genode's nested
policies at work!
TAR ROM service
===============
For large setups, listing individual files as boot modules in single-image
creation tools (e.g., elfweaver) or multiboot boot loaders can be
cumbersome, especially when many data files or shared libraries are
involved. To facilitate the grouping of files, 'tar_rom' is an
implementation of the 'ROM' interface that operates on a 'tar' file.
The name of the TAR archive must be specified via the 'name' attribute of
an 'archive' tag, for example:
! <config>
! <archive name="archive.tar"/>
! </config>
The backing store for the dataspaces exported via ROM sessions is accounted
on the 'rom_tar' service (not on its clients) to make the use of 'rom_tar'
transparent to the regular users of core's ROM service. Hence, this service
must not be used by multiple clients that do not trust each other.
Typically, 'tar_rom' is instantiated per client.
The Live CD uses the 'tar_rom' service for the browser demo. Each plugin
is fetched from the web as a tar file containing the config file of the
plugin subsystem as well as supplemental binary files that are provided
to the plugin subsystem as ROM files. This way, a plugin can carry along
multiple components and data that form a complete Genode subsystem.
DDE Kit
=======
The DDE kit underwent slight modifications since the previous release.
It now provides 64-bit integer types and a revised virtual PCI bus
implementation.
Device drivers
##############
PCI bus
=======
Genode was tested on several hardware platforms in preparation of the
current release. This revealed some deficiencies with the PCI bus
driver implementation. The revised driver now efficiently supports
platforms with many PCI busses (as PCIe demands) and correctly handles
multi-function devices.
VESA framebuffer
================
We updated the configuration syntax of the VESA driver to better match
the style of new init syntax, preferring the use of attributes rather than
XML sub nodes. Please refer to the updated documentation at
'os/src/drivers/framebuffer/vesa/README'.
:Buffered output:
To accommodate framebuffer clients that need to read from the frame buffer,
in particular the nitpicker GUI server operating with alpha channels, we
introduced a buffered mode to the VESA driver. If enabled, the VESA driver
will hand out a plain memory dataspace to the client rather than the
physical framebuffer. Each time, the client issues as 'refresh' operation
on the framebuffer-session interface, the VESA driver copies the corresponding
screen region from the client-side virtual framebuffer to the physical
framebuffer. Note that the VESA driver will require additional RAM quota
to allocate the client buffer. If the quota is insufficient, the driver will
fall back to non-buffered output.
:Preinitialized video modes:
As an alternative to letting the VESA driver set up a screen mode, the
driver has become able to reuse an already initialized mode, which is useful
if the VESA mode is already initialized by the boot loader. If the screen
is initialized that way, the 'preinit' attribute of the 'config' node can
be set to '"yes"' to prevent the driver from changing the mode. This way,
the driver will just query the current mode and make the already
initialized framebuffer available to its client.
Audio
=====
We observed certain hardware platforms (in particular VirtualBox) to
behave strangely after ALSA buffer-underrun conditions. It seems that the
VirtualBox audio driver plays actually more frames than requested by
ALSA's 'writei' function, resulting in recurring replay of data that
was in the buffer at underrun time. As a work-around for this problem,
we zero-out the sound-hardware buffer in the condition of an ALSA buffer
underrun. This way, the recurring replay is still there, but it is
replaying silence.
To improve the support for sporadic audio output, we added a check for the PCM
state for buffer underruns prior issuing the actual playback. In the event of
an underrun, we re-prepare the sound card before starting the playback.
Furthermore, we implemented the new flush and channel-synchronization
abilities of the 'Audio_out_session' interface for the DDE Linux driver.
Paravirtualized Linux
#####################
To support the demo scenarios that showcase the paravirtualized Linux kernel,
we enhanced our custom stub drivers of the OKLinux kernel. Thereby, we have
reached a high level of integration of OKLinux with native Genode services,
including audio output, block devices, framebuffer output, seamless integration
with the Nitpicker GUI, and networking. All stub drivers are compiled in by
default and are ready to use by specifying a device configuration in the config
node for the Linux kernel. This way, one Linux kernel image can be easily used
in different scenarios.
:Integration with the Nitpicker GUI:
We enhanced our fbdev stub driver with a mechanism to merge view reposition
events. If a X11 window is moved, a lot of subsequent events of this type are
generated. Using the new optimization, only the most recent state gets
reported to Nitpicker, making the X11 GUI more responsive.
:UnionFS:
As we noticed that unionfs is required by all our Linux scenarios, we decided
to include and enable the patch by default.
:Network support:
With the introduction of the 'nic_bridge', multiple networking stacks can run
on Genode at the same time, which paves the way for new use cases. We have now
added a stub driver using Genode's 'Nic_session' interface to make the new
facility available to Linux.
:Audio output:
We adapted the ALSA stub driver to the changes of the 'Audio_out_session'
interface, using the new channel synchronization and flush functions.
Thereby, we optimized the stub driver to keep latency and seek times of
Linux userland applications reasonably low.
:Removed ROM file driver:
With the addition of the 'Block_session' stub driver, the original ROM file
driver is no longer required. So we removed the stub. For using ROM files as
disk images for Linux, there is the 'rom_loopdev' server, which provides a
block session that operates on a ROM file.
:Asynchronous block interface:
To improve performance, we changed the block stub driver to facilitate the
asynchronous mode of operation as provided by the 'Block_session' interface.
This way, multiple block requests can be issued at once, thereby shadowing
the round trip times for individual requests.
Protocol stacks and libraries
#############################
Gallium3D / Intel GEM
=====================
We improved the cache handling of our DRM emulation code (implementing
'drm_clflush_pages') and our EGL driver, thereby fixing caching
artifacts on i945 GPUs. Furthermore, we added a temporary work-around
for the currently dysfunctional sequence-number tracking with i945 GPUs.
On this chipset, issuing the 'MI_STORE_DWORD_INDEX' GPU command used
for tracking sequence numbers apparently halts the processing the command
stream. This condition is normally handled by an interrupt. However,
we have not enabled interrupts yet.
To prepare the future support for more Gallium drivers than i915, we
implemented a driver-selection facility in the EGL driver. The code
scans the PCI bus for a supported GPU and returns the name of the
corresponding driver library. If no driver library could be found,
the EGL driver falls back to softpipe rendering.
lwIP
====
We revised our port of the lwIP TCP/IP stack, and thereby improved its
stability and performance.
* The lwIP library is now built as shared object, following the convention
for libraries contained in the 'libports' repository.
* By default (when using the 'libc_lwip_nic_dhcp' library), lwIP will
issue a DHCP request at startup. If this request times out, the loopback
device is set as default.
* If there is no 'Nic' service available, the lwIP stack will fall back to
the loopback device.
* We increased the default number of PCBs in lwIP to 64.
* We removed a corner case of the timed semaphore that could occur
when a timeout was triggered at the same time ,'up' was called.
In this case, the semaphore was unblocked but the timeout condition
was not reflected at the caller of 'down'. However, the lwIP code
relies on detecting those timeouts.
Qt4
====
We implemented a custom *nitpicker plugin widget*, which allows for the
seamless integration of arbitrary nitpicker clients into a Qt4 application.
The primary use case is the browser plugin mechanism presented at
the Live CD. In principle, the 'QNitpickerViewWidget' allows for creating
mash-up allocations consisting of multiple native Genode programs. As shown
by the browser plugin demo, a Qt4 application can even integrate other
programs that run isolated from the Qt4 application, and thereby depend on
on a significantly less complex trusted computing base than the Qt4
application itself.
[image img/nitpicker_plugin]
The image above illustrates the use of the 'QNitpickerViewWidget' in the
scenario presented on the Live CD. The browser obtains the Nitpicker view to be
embedded into the website from the loader service, which virtualizes the
Nitpicker session interface for the loaded plugin subsystem. The browser then
tells the loader about where to present the plugin view on screen. But it has
neither control over the plugin's execution nor can it observe any user
interaction with the plugin.
New Gems repository with HTTP-based block server
################################################
To give the web-browser demo of our Live CD a special twist, and to show off
the possibilities of a real multi-server OS, we decided to implement the
somewhat crazy idea of letting a Linux OS run on a disk image fetched at
runtime from a web server. This way, the Linux OS would start right away and
disk blocks would be streamed over the network as needed. Implementing this
idea was especially attractive because such a feature would be extremely hard
to implement on a classical OS but is a breeze to realize on Genode where all
device drivers and protocol stacks are running as distinct user-level
components. The following figure illustrates the idea:
[image img/http_block]
The block stub driver of the Linux kernel gets connected to a special block
driver called 'http_block', which does not access a real block device but
rather uses TCP/IP and HTTP to fetch disk blocks from a web server.
Because the 'http_block' server is both user of high-level functionality (the
lwIP stack) and provider of a low-level interface ('Block_session'), the
program does not fit well into one of the existing source-code repositories.
The 'os' repository, which is normally hosting servers for low-level interfaces
is the wrong place for 'http_block' because this program would make the 'os'
repository depend on the higher-level 'libports' repository where the 'lwip'
stack is located. On the other hand, placing 'http_block' into the 'libports'
repository is also wrong because the program is not a ported library. It merely
uses libraries provided by 'libports'. In the future, we expect that native
Genode components that use both low-level and high-level repositories will
become rather the norm than an exception. Therefore, we introduced a new
repository called 'gems' for hosting such programs.
Tools
#####
Automated coding-style checker
==============================
As Genode's code base grows and new developers start to get involved,
we noticed recurring questions regarding coding style. There is a
[http://genode.org/documentation/developer-resources/coding_style - document]
describing our coding style but for people just starting to get involved,
adhering all the rules can become tedious. However, we stress the importance
of a consistent coding style for the project. Not only does a consistent style
make the framework more approachable for users, but it also eases the work
of all regular developers, who can feel right at home at any part of
the code.
To avoid wasting precious developer time with coding-style fixes, we
have created a tool for the automated checking and (if possible) fixing
the adherence of source code to Genode's coding style. The tool is
located at 'tool/beautify'. It takes a source file as argument and
reports coding-style violations. The checks are fairly elaborative:
* Placement of braces and parenthesis
* Indentation and alignment, trailing spaces
* Vertical spacing (e.g., between member functions, above comments)
* Naming of member variables and functions (e.g., private members start with '_')
* Use of upper and lower case
* Presence of a file header with the mandatory fields
* Policy for function-header comments (comment at declaration, not
at implementation)
* Style of single-line comments, function-header comments, multi-line comments
The user of 'beautify' may opt to let the tool fix most of the violations
automatically by specifying the command line arguments '-fix' and '-write'.
With only the '-fix' argument, the tool will output the fixed version of
the code via stdout. By specifying the '-write' argument, the changes will
be written back to the original file. In any case, we strongly recommend
to manually inspect all changes made by the tool.
Under the hood, the tool consists of two parts. A custom C++ parser called
'parse_cxx' reads the source code and converts it to a syntax tree. In the
syntax tree, all formating information such as whitespaces are preserved.
The C++ parser is a separate command-line tool, which we also use for
other purposes (e.g., generating the API documentation at the website).
The actual 'beautify' tool calls 'parse_cxx', and applies its checks and
fixes to the output of 'parse_cxx'. For this reason, both tools have to
reside in the same directory.
Platform-specific changes
#########################
OKL4
====
:Added support for shared interrupts:
The Genode Live CD operates on a large number of devices that trigger
interrupts (USB, keyboard, mouse, ATAPI, timer, network). On most
platforms, the chances are extremely high that some of them use
the same IRQ line. Therefore, we enhanced core's IRQ service to
allow multiple clients to request the same IRQ. If the interrupt occurs,
all clients referring to this interrupt are notified. The interrupt
gets cleared after all of those clients responded. Even though, we regard
PIC interrupts as a legacy, the support of shared interrupts enables
us to use OKL4 with such complex usage scenarios.
:Revised page-fault handling:
If a page fault occurs, the OKL4 kernel delivers a message to the page-fault
handler. The message contains the page-fault address and type as well as the
space ID where the fault happened. However, the identity of the faulting
thread is not delivered. Instead, the sender ID of the page fault message
contains the KTCB index of the faulting thread, which is only meaningful
within the kernel. This KTCB index is used as a reply token for answering the
page fault message. We wondered about why OKL4 choose to deliver the KTCB
index rather then the global thread ID as done for plain IPC messages. The
only reasonable answer is that by using the KTCB index directly in OKL4's
page-fault protocol, one lookup from the userland-defined thread ID to the
KTCB index can be avoided. However, this comes at the cost of losing the
identity of the faulting thread. We used to take the space ID as a key for
the fault context within core. However, with Genode's user-level page-fault
mechanism, this simplification does not suffice anymore. We have to know the
faulting thread as a page fault may not be answered immediately but at a
later time. During that time, the page-fault state has to be stored at core's
representation of the faulting thread. Our solution is reverting OKL4's
page-fault protocol to operate with global thread IDs only and to never make
kernel-internal KTCB indices visible at the user land. You can find the patch
for the OKL4 kernel at 'base-okl4/patches/reply_tid.patch'.
:Reboot via kernel debugger:
We fixed the reboot code of OKL4's kernel debugger to improve our work
flow. The patch can be found at 'base-okl4/patches/kdb_reboot.patch'.
:Relieved conflict with libc 'limits.h':
For some reason, the OKL4 kernel bindings provide definitions
normally found in libc headers. This circumstance ultimately leads
to trouble when combining OKL4 with a real C runtime. We have
relieved the problem with the patch 'base-okl4/patches/char_bit.patch'.
:Exception handling:
We added a diagnostic message to core that reports about exceptions
such as division by zero.
Pistachio
=========
Our revised syscall bindings for supporting position-independent code
on L4ka::Pistachio have been integrated into the mainline development
of the kernel. Therefore, the patch is not needed anymore when using
a kernel revision newer than 'r791:0d25c1f65a3a'.
Linux
=====
On Linux, we let the kernel manage all virtual address spaces for us,
except for the thread-context area. Because the kernel does not know
about the special meaning of the thread-context area, it may choose to
use this part of the virtual address space as target for 'mmap'. This
may lead to memory corruption. Fortunately, there is a way to tell the
kernel about virtual address regions that should be reserved. The
trick is to pre-populate the said region with anonymous memory using
the 'mmap' arguments 'MAP_PRIVATE', 'MAP_FIXED', 'MAP_ANONYMOUS', and
'PROT_NONE'. The kernel will still accept a fixed-address mapping
within such a reserved region (overmap) but won't consider using the
region by itself. The reservation must be done at the startup of each
process and each time when detaching a dataspace from the thread
context area. For the process startup, we use the hook function
'main_thread_bootstrap' in 'src/platform/_main_helper.h'. For reverting
detached dataspaces to a reserved region within the context area, we
added as special case to 'src/base/env/rm_session_mmap.cc'.
For hybrid programs (Genode processes that link against native
shared libraries of the Linux system), which are loaded by the dynamic
linker of Linux, we must further prevent the dynamic linker from
populating the thread-context area. This is achieved by adding a
special program segment at the linking stage of all elf binaries.

876
doc/release_notes-11-02.txt Normal file
View File

@@ -0,0 +1,876 @@
===============================================
Release notes for the Genode OS Framework 11.02
===============================================
Genode Labs
One year ago, the release 10.02 was our break-through with regard to the support
of multiple kernels as base platform for Genode. With the added support for
the NOVA hypervisor and the Codezero kernel, Genode applications could be executed
on 6 different kernels. With the current release, we take our commitment to
kernel platform support even further. With the added support for the Fiasco.OC
kernel, we make Genode available on one of the most feature-rich modern microkernels.
Additionally, we entered the realms of kernel design with our new platform support
for the Xilinx MicroBlaze architecture. This platform support comes in the shape
of a custom kernel specifically targeted to the MicroBlaze CPU architecture.
Furthermore, we updated our support for the NOVA Hypervisor to the bleeding-edge
version 0.3, which has been released earlier this month.
With the current support for 8 different kernel platforms (L4/Fiasco, Linux,
L4ka::Pistachio, OKL4, NOVA, Codezero, Fiasco.OC, and native MicroBlaze), testing
and integrating application scenarios across all platforms becomes increasingly
challenging. Therefore, we introduce a new framework for automating such tasks.
Thanks to the tight integration of the automation tool with Genode's build system,
going back and forth between different kernels becomes an almost seamless
experience.
Functionality-wise, the release carries on our vision to create a highly secure
yet easy to use general-purpose operating system. Because the Genode framework
is developed on Linux using the wonderful GNU tools, we consider the
availability of the GNU user land on Genode as crucial for using the system by
ourself. This motivation drives the creation of a custom execution environment
for GNU software on top of Genode. With the current release, we are proud to
present the first pieces of this execution environment. Even though not fully
functional yet, it clearly shows the direction of where we are heading.
Support for Fiasco.OC
#####################
The OC in the name of the Fiasco.OC kernel stands for "object capability", hinting
at the most significant feature that sets current-generation microkernels such as
NOVA, seL4, and Fiasco.OC apart from their predecessors. Whereas previous L4 kernels
succeeded in protecting subsystems from each other, the new generation of kernels
is geared towards strict security policies. Traditionally, two protection domains
were able to communicate with each other if they both agreed. Communication partners
were typically globally known via their respective thread/task IDs. Obviously, this
policy is not able to guarantee the separation of subsystems. If two subsystems
conspire, they could always share information. Object-capability-based kernels
are taking the separation much further by prohibiting any communication between
protection domains by default. Two protection domains can communicate only if
a common acquaintance of both agrees. This default-deny policy facilitates the
creation of least-privilege security policies. From the ground up, Genode has
been designed as a capability-based system which is naturally capable of leveraging
kernel-based object-capability support if present. After NOVA, Fiasc.OC is the
second of Genode's base platforms that provides this feature.
Apart from being a capability-based kernel, Fiasco.OC has a number of compelling
features such as thorough support for ARM platforms and the x86 32/64 bit
architectures. It supports SMP, hardware virtualization, and provides special
optimizations for running paravirtualized operating systems.
Technically, Fiasco.OC is the successor of the L4/Fiasco kernel developed by
the OS group of the TU-Dresden. However, the kernel interface of Fiasco.OC has
not much in common with L4/Fiasco. Some heritages are still there (e.g., IPC
timeouts) but the kernel API has evolved to a fully object-oriented model.
:Thanks:
We are indebted to the main developer of Fiasco.OC Alexander Warg for being
very reponsive to our inquiries while doing the porting work. Thanks to his
support, the adaptation of Genode to this kernel has been an almost smooth
ride.
Prerequisites
=============
You need GNU C & C++ Compilers, GNU Binutils, GNU Make, and Perl to use the
Fiasco.OC build system. On Debian/Ubuntu systems, you have to install the
following packages:
! apt-get install make gawk g++ binutils pkg-config subversion
Moreover, you need to download and install the tool-chain used by Genode. Have
a look at this page:
:[http://genode.org/download/tool-chain]:
Genode tool-chain
Downloading and building Fiasco.OC
==================================
Checkout the Fiasco.OC sources and tool-chain to an appropriated directory:
! export REPOMGR_SVN_REV=27
! svn cat http://svn.tudos.org/repos/oc/tudos/trunk/repomgr |\
! perl - init http://svn.tudos.org/repos/oc/tudos fiasco l4re
Building the kernel
~~~~~~~~~~~~~~~~~~~
Create the build directory for the kernel:
! cd <path_to_fiasco_src_dir>/src/kernel/fiasco
! make BUILDDIR=<path_to_kernel_build_dir>
Go to the build directory, configure the kernel:
! cd mybuild
! make config
This will launch the configuration menu. Here you can configure your kernel.
The default config is just fine to test the Genode port. It will build a
uniprocessor IA32 kernel with debugging features enabled. You can exit the menu and
save the configuration by simply typing 'x'.
Now, build Fiasco.OC by invoking:
! make
Building necessary tools
~~~~~~~~~~~~~~~~~~~~~~~~
To practically use Fiasco.OC, you need in addition to the kernel a tool to
bootstrap it, and the initial pager of the system, namely 'sigma0'. Both tools
can be found in the L4 runtime environment's base directory. Outgoing from
the directory where you checked out the sources, you have to change to the
following directory:
! cd <path_to_fiasco_src_dir>/src/l4
Create another build directory:
! make B=<path_to_l4re_build_dir>
Again, you might want to tweak the configuration:
! make O=<path_to_l4re_build_dir> config
Finally, build the tools:
! make O=<path_to_l4re_build_dir>
Building the Fiasco.OC version of Genode
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Fiasco.OC version of Genode is available at the Genode public subversion repository:
:http://genode.org/download/subversion-repository:
Information about accessing the Genode public subversion repository
Go to a directory where you want the Genode/Fiasco.OC build directory to remain. Use
the helper script in the 'tool/builddir' directory of the Genode source tree to
create the initial build environment. You need to state the absolute path to the
build directory of the L4 runtime environment as 'L4_DIR', as it contains the kernel
bindings needed by the Genode port.
! <path_to_genode_src_dir>/tool/builddir/create_builddir foc_x86_32 \
! L4_DIR=<path_to_l4re_build_dir> \
! GENODE_DIR=<path_to_genode_src_dir> \
! BUILD_DIR=<path_to_genode_build_dir>
Now, go to the newly created build directory and type make.
! cd <path_to_genode_build_dir>
! make
Booting Genode on top of Fiasco.OC
==================================
Example GRUB configuration entry:
! timeout 0
! default 0
!
! title Genode on Fiasco.OC
! kernel /bootstrap -modaddr=0x01100000
! module /fiasco -serial_esc
! module /sigma0
! module /core
! module /init
! module /config
! module /pci_drv
! module /vesa_drv
! module /ps2_drv
! module /timer
! module /nitpicker
! module /launchpad
! module /liquid_fb
! module /scout
! module /testnit
! module /nitlog
For an example of a matching Genode 'config' file, please take a look
at 'os/config/demo'.
The Genode binaries are located in '<path_to_genode_build_dir>/bin',
the 'fiasco' kernel in '<path_to_kernel_build_dir>'. Assuming you compiled
for x86/586 (the default), you can find the 'bootstrap' binary in
'bin/x86_586' and 'sigma0' in 'bin/x86_586/l4f' within the
'<path_to_l4re_build_dir>' directory.
Current state
=============
The adaptation of Genode to Fiasco.OC covers most parts of the Genode API
including advanced semantics such as cancelable locks and support for
real-time priorities. So far, it has been tested on the x86 architecture.
Because 'base-foc' does not contain x86-specific code, we expect no major
roadblocks for running Genode on Fiasco.OC on ARM. However, we have not
exercised tests in this regard.
As of today, there exist the following limitations of the Fiasco.OC support:
* The dynamic linker is not yet adapted to Fiasco.OC. Special care must
be taken for handling the parent capability for dynamically loaded
programs. We have already covered this issue for the NOVA version but
the adaptation to Fiasco.OC remains yet to be done.
* The destruction of sub systems is not yet fully stable. Because Genode
forms a more dynamic workload than the original userland accompanied with
the kernel, the usage pattern of the kernel API triggers different
effects. We are working with the Fiasco.OC developers to remedy this
issue.
* The signalling framework is not yet supported. A design exist but it is
not implemented yet.
We believe however that none of these limitations are a significant hurdle for
starting to use Genode with this kernel. Please expect this issues to be
resolved with the upcoming Genode release.
Technical details about 'base-foc'
==================================
The following technical bits are worth noting when exploring the use of
Genode with the 'base-foc' platform.
* The timer implementation uses a one thread-per-client mode of operation.
We use IPC timeouts as time source. Hence, the timer driver is hardware
independent and should work out of the box on all hardware platforms
supported by Fiasco.OC.
* Each 'Server_object' of Genode corresponds to a so-called IPC gate,
which is the Fiasco.OC kernel object used for capability invocation.
Therefore, protection and object integrity is provided at the fine
granularity of single 'Server_objects'. This is in line with our
support for NOVA's implementation of capability-based security.
* In contrast to the lock implementation that we used with the original
L4/Fiasco kernel, the 'base-foc' lock is a fully-featured Genode lock
with support for lock cancellation and blocking. For blocking and
waking up lock applicants, we use Fiasco.OC's IRQ objects.
* The allocator used for managing process-local capability selectors
does not yet support the reuse of capability selectors.
Further Information
===================
:genode/tool/builddir/README:
Reference manual for the 'create_builddir' script
:[http://os.inf.tu-dresden.de/fiasco]:
Official website for the Fiasco.OC microkernel.
Noux - an execution environment for the GNU userland
####################################################
Even though Genode is currently mainly geared to the classical special-purpose
application domains for microkernel-based systems, the main property that sets
Genode apart from traditional systems is the thorough support for dynamic
workloads and the powerful mechanisms for handling hardware resources and
security policies in highly dynamic setting. We are convinced that Genode's
architecture scales far beyond static special-purpose domains and believe in
the feasibility of Genode as a solid foundation for a fully-fledged general
purpose operating system. Internally at Genode Labs, we set up the ultimate
goal to switch from Linux to Genode for our day-to-day work. We identified
several functionalities that we could not live without and systematically try
to bring those features to Genode. Of course, the most fundamental programs
are the tools needed to develop and build Genode. Currently we are developing
on Linux and enjoy using the GNU userland.
Consequently, we require a solution for using this rich tool set on Genode.
The straight-forward way for making these tools available on Genode would be
running them within a virtualized Linux instance (e.g., using OKLinux on OKL4).
However, this approach would defeat our actual goal to create a highly secure
yet easy to use working environment because adding Linux to the picture would
involve administering the virtualized Linux system. We would prefer a native
solution that makes the overall system less, not more, complicated. This way
the idea for a native execution environment for the GNU userland on Genode
was born. The implementation is called Noux and the first bits of code are
featured in the 'ports' repository. Noux consists of two parts, a build
environment for compiling GNU programs such that they can be run as Genode
processes and an execution environment that provides the classical UNIX
functionality to these programs.
Noux build environment
======================
From our experience, porting existing UNIX applications to a non-UNIX system
tends to be a task of manual and time-consuming labour. One has to loosely
understand the build system and the relationship of the involved source codes,
implement dummy functions for unresolved references, and develop custom glue
code that interfaces the ported application to the actual system. Taking the
shortcut of changing the original code has to be avoided at any cost because
this produces recurring costs in the future when updating the application. In
short, this long-winding process does not scale. For porting a tool set such as
the GNU userland consisting of far more than a three-digit number of individual
programs, this manual approach becomes unfeasible. Therefore, we have created
a build environment that facilitates the use of the original procedure of
invoking './configure && make'. The challenge is to supply configure with
the right arguments and environment variables ('CFLAGS' and the like) such that
the package is configured against the Genode environment. The following
considerations must be taken:
* Configure must not detect any global headers (e.g., '/usr/include/')
or libraries (e.g., '/usr/lib/'). This can be achieved by the '-nostdinc' and
'-nostdlib' options
* Configure has to use the same include-search paths as used for compiling
normal libc-using Genode programs
* Configure must use the Genode tool chain
* The final linking stage must use the Genode linker script, the Genode
base libraries, and other Genode-specific linker arguments.
Thanks to the power of the GNU build system, all this can be achieved by
supplying arguments to './configure' and indirectly to the 'make' process via
environment variables. The new Noux build environment takes care of these
precautions. It comes in the form of the 'ports/mk/noux.mk' file which enables
the seamless integration of GNU packages with the Genode build system. To
compile a GNU package, the manual steps needed are reduced to the creation of a
'target.mk' file representing the package. This 'target.mk' defines the name
of the package (by default, the basename of the 'target.mk' enclosing directory
is assumed) and the location of the source package. With this approach, we
managed to build 'coreutils' (over 100 small UNIX utilities such as 'ls', 'cp',
'sort'), 'binutils' (GNU linker, assembler, object-file tools), 'findutils'
('find', 'xargs'), 'bash', 'dash', GNU make, and finally the GNU compiler
collection including 'g++'. The resulting binaries are ready to be executed as
native Genode processes. However, without the right environment that presents
the program the needed UNIX functionality, those programs won't do much.
This leads us to the Noux execution environment.
Noux execution environment
==========================
The Noux execution environment plays the role of a UNIX kernel for programs
built via the Noux build environment. In contrast to a real kernel, the Noux
environment is a plain Genode user-level process that plays the role of being
the parent of one or multiple Noux processes. In addition of providing the
'Genode::Parent' interface, Noux also provides a locally implemented service called
'Noux::Session' that offers UNIX-like system-calls via an RPC interface. Each
hosted program is linked against a special Noux libc plugin that catches all
libc calls that would normally result in a system call. It then transparently
forwards this function call to the 'Noux::Session' interface.
Currently the Noux execution environment implements the following
system calls: 'getcwd', 'write', 'stat', 'fstat', 'fcntl', 'open',
'close', 'dirent', 'fchdir', 'read', and 'execve'.
The execution environment submits arguments (argc, argv, environment) to the
hosted program, manages its current working directory and receives its exit
code. File operations are targeted to a custom VFS infrastructure, which
principally allows a flexible configuration of the virtual file system visible
to the hosted programs. At the current stage, Noux supports mounting plain tar
archives obtained from core's ROM service as read-only file system. On startup,
the Noux environment starts one process (the init process) and connects the
file descriptor 1 (stdout) to Genode's LOG service.
State of the implementation
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The infrastructure implemented so far already allows the execution of many simple
UNIX tools such as 'ls -lRa', 'echo', 'seq', 'find'. The 'execve' system call
is implemented such that a new process is started that inherits the file
descriptors and the PID of the calling process. This allows using the exec
functionality of the 'bash' shell. However, because 'fork' is not implemented
yet, there is currently no way to start multiple programs hosted in a single
Noux execution environment.
As of today, the Noux environment is not considered to be usable for practical
purposes. However, it clearly shows the feasibility of the path we are walking.
With the foundation laid, we are looking forward to expanding Noux to a capable
solution for running our beloved GNU userland tools on Genode.
Vision
~~~~~~
The most significant intermediate result of pursuing the development of Noux is
the realization that such an environment is not exceedingly complex. Because of
the combination with Genode, we only need to provide a comfortable runtime as
expected by user processes but we can leave much of intricate parts of UNIX out
of the picture. For example, because we handle device drivers on Genode, we do
not need to consider device-user interaction in Noux. As another example,
because the problem of bootstrapping the OS is already solved by Genode, there
is no need to run an 'init' process within Noux. Our vision foresees that Noux
runtimes are to be created on demand for individual tasks such as editing a
file (starting a custom Noux instance containing only the file to edit and the
text editor), compiling source code (starting a custom Noux instance with only
the source code and the build tools). Because Noux is so simple, we expect the
runtime overhead of starting a Noux instance to be not more than the time
needed to spawn a shell in a normal UNIX-like system.
Test drive
~~~~~~~~~~
To give Noux a spin, we recommend using Linux as base platform as this is
the platform we use for developing it. First, you will need to download the
source code of the GNU packages. From within the 'ports' repository,
use the following command:
! make prepare PKG=coreutils
This command will download the source code of the GNU coreutils. You may
also like to give the other packages a try. To see what is available,
just call 'make' without any argument.
Create a build directory (e.g., using tool/builddir/create_builddir).
Change to the build directory and issue the command
! make run/noux
This command will execute the run script provided at 'ports/run/noux.run'.
First it builds core, init, and coreutils. Then it creates a tar archive
containing the installed coreutils. Finally, it starts the Noux environment on
Genode. Noux then mounts the TAR archive as file system and executes 'ls -laR',
showing the directory tree.
Approaching platform support for Xilinx MicroBlaze
##################################################
With the release 11.02, we are excited to include the first version of our
custom platform support for the Xilinx MicroBlaze CPU architecture. MicroBlaze
is a so-called softcore CPU, which is commonly used as part of FPGA-based
System-on-Chip designs. At Genode Labs, we are regularly using this IP core,
in particular for our Genode FPGA Graphics Project, which is a GUI software stack
and a set of IP cores for implementing fully-fledged windowed GUIs on FPGAs:
:Website of the Genode FPGA Graphics Project:
[http://genode-labs.com/products/fpga-graphics]
Ever since we first released the Genode FPGA project, we envisioned to combine
it with the Genode OS Framework. In Spring 2010, Martin Stein joined our team
at Genode Labs and accepted the challenge to bring the Genode OS Framework to
the realms of FPGA-based SoCs. Technically, this implies porting the framework
to the MicroBlaze CPU architecture. In contrast to most softcore CPUs such as
the popular Lattice Mico32, the MicroBlaze features a MMU, which is a fundamental
requirement for implementing a microkernel-based system. Architecturally-wise
MicroBlaze is a RISC CPU similar to MIPS. Many system parameters of the CPU
(caches, certain arithmetic and shift instructions) can be parametrized at
synthesizing time of the SoC. We found that the relatively simple architecture
of this CPU provides a perfect playground for pursuing some of our ideas about
kernel design that go beyond the scope of current microkernels. So instead of
adding MicroBlaze support into one of the existing microkernels already
supported by Genode, we went for a new kernel design. Deviating from the typical
microkernel, which is a self-sufficient program running in kernel mode that
executes user-level processes on top, our design regards the kernel as a part of
Genode's core. It is not a separate program but a library that implements the
glue between user-level core and the raw CPU. Specifically, it provides the
entrypoint for hardware exceptions, a thread scheduler, an IPC mechanism, and
functions to manipulate virtual address spaces (loading and flushing entries
from the CPU's software-loaded TLB). It does not manage any physical memory
resources or the relationship between processes. This is the job of core.
From the kernel-developer's point of view, the kernel part can be summarized as
follows:
* The kernel provides user-level threads that are scheduled in a round-robin
fashion.
* Threads can communicate via synchronous IPC.
* There is a mechanism for blocking and waking up threads. This mechanism
can be used by Genode to implement locking as well as asynchronous
inter-process communication.
* There is a single kernel thread, which never blocks in the kernel code paths.
So the kernel acts as a state machine. Naturally, there is no concurrency in the
execution paths traversed in kernel mode, vastly simplifying these code parts.
However, all code paths are extremely short and bounded with regard to
execution time. Hence, we expect the interference with interrupt latencies
to be low.
* The IPC operation transfers payload between UTCBs only. Each thread has a
so-called user-level thread control block which is mapped transparently by
the kernel. Because of this mapping, user-level page faults cannot occur
during IPC transfers.
* There is no mapping database. Virtual address spaces are manipulated by
loading and flushing physical TLB entries. There is no caching of mappings
done in the kernel. All higher-level information about the interrelationship
of memory and processes is managed by the user-level core.
* Core runs in user mode, mapped 1-to-1 from the physical address space
except for its virtual thread-context area.
* The kernel paths are executed in physical address space (MicroBlaze).
Because both kernel code and user-level core code are observing the same
address-space layout, both worlds appear to run within a single address
space.
* User processes can use the entire virtual address space (4G) except for a
helper page for invoking syscalls and a page containing atomic operations.
There is no reservation used for the kernel.
* The MicroBlaze architecture lacks an atomic compare-and-swap instruction. On
user-level, this functionality is emulated via delayed preemption. A kernel-
provided page holds the sequence of operations to be executed atomically and
prevents (actually delays) the preemption of a thread that is currently
executing instructions at that page.
* The MicroBlaze MMU supports several different page sizes (1K up to 16MB).
Genode fully supports this feature for page sizes >= 4K. This way, the TLB
footprint can be minimized by choosing sensible alignments of memory
objects.
Current state
=============
The MicroBlaze platform support resides in the 'base-mb' repository. At the
current stage, core is able to successfully start multiple nested instances of
the init process. Most of the critical kernel functionality is working. This
includes inter-process communication, address-space creation, multi-threading,
thread synchronization, page-fault handling, and TLB eviction.
This simple scenario already illustrates the vast advantage of
using different page sizes supported by the MicroBlaze CPU. If using
4KB pages only, a scenario with three nested init processes produces more than
300.000 page faults. There is an extremely high pressure on the TLB, which
only contains 64 entries. Those entries are constantly evicted so that
threshing effects are likely to occur. By making use of flexible page
sizes (4K, 16K, 64K, 256K, 1M, 4M, 16M), the number of page faults gets
slashed to only 1.800, speeding up the boot time by factor 10.
Currently, there is no restriction of IPC communication rights. Threads are
addressed using their global thread IDs (in fact, using their respective
indices in the KTCB array). For the future, we are planning to add
capabilty-based delegation of communication rights.
Building and using Genode on MicroBlaze
=======================================
For building Genode for the MicroBlaze platform, you need the MicroBlaze
tool chain as it comes with the Xilinx EDK. The tool chain is typically
prefixed with 'mb-'. Please make sure that the tool chain's 'bin/' directory
is included in your 'PATH' environment variable.
For building and starting Genode on MicroBlaze, you first need to create
a build directory using the build-directory creation tool:
! tool/builddir/create_builddir microblaze \
! BUILD_DIR=</path/to/build/dir> \
! GENODE_DIR=</path/to/genode/dir>
The 'base-mb' repository comes with support for Genode's run tool. In order to
use it, you will first need to declare the location of your qemu binary using
the 'QEMU=/path/to/qemu' variable in the '<build-dir>/etc/microblaze.conf'
file. Then you will be able to start an example scenario by issuing the
following command from within your build directory:
! make run/nested_init
Thereby, the 'run' tool will attempt to start core using the microblaze version
of qemu.
You can also find a simple hello-world example at 'base-mb/src/test/hello'.
The corresponding run script is located at 'base-mb/run/hello.run'. You can
execute it via 'make run/hello' from the build directory.
Note that currently, all boot modules are linked against the core binary.
To change the boot modules, the file 'base-mb/src/core/boot_modules.s' must
be modified.
For reference, we are using the following tools:
* mb-g++ (GCC) 4.1.1 20060524 (Xilinx 11.2 Build EDK_LS2.2
20 Apr 2009 Xilinx 11.2 Build EDK_LS2.2 23 Apr 2009)
* GNU ld version 2.16 Xilinx 11.2 Build EDK_LS2.2 23 Apr 2009
* GNU assembler 2.16 Xilinx 11.2 Build EDK_LS2.2 23 Apr 2009
* QEMU emulator version 0.14.50, Copyright (c) 2003-2008 Fabrice Bellard
Petalogix linux reference design targeting Xilinx Spartan 3ADSP-1800 boards.
Supporting the NOVA hypervisor version 0.3
##########################################
NOVA is a so called microhypervisor - a modern capability-based microkernel
with special support for hardware-based virtualization and IOMMUs. Since we
incorporated the initial support for the NOVA hypervisor in Genode one year
ago, this kernel underwent multiple revisions. The latest version was released
earlier this month. To our delight, much of the features that we missed from
the initial release had been implemented during the course of the last year. We
are especially happy about the fully functional 'revoke' system call and the
support for remote kernel-object creation.
With the Genode release 11.02, we officially support the latest NOVA version.
The update of Genode to the new version required two steps. First, because many
details of the kernel interface were changed between version 0.1 and version
0.3, we had to revisit our syscall bindings and adapting our code to changed
kernel semantics. Second, we filled our 'base-nova' code related to object
destruction and unmapping with life to benefit from NOVA's 'revoke' system
call. Consequently, we are now able to run the complete Genode software stack
including the dynamic linker on NOVA.
Note that for using Genode on NOVA, you will need to apply a small patch to the
NOVA source code. This patch enables the re-use of user-level thread control
blocks in the kernel. The patch can be found at 'base-nova/patches/utcb.patch'.
When executing NOVA on qemu, please specify the '-cpu coreduo' argument to the
qemu command line. When using Genode 'run' tool, you may assign this argument
to the 'QEMU_OPT' variable in '<build-dir>/etc/build.conf'.
:Thanks:
We are grateful for the ongoing very pleasant collaboration with Udo Steinberg
who is the driving force behind NOVA. Thanks for the ultra-fast responses to our
questions and for considering our suggestions regarding the feature set of
NOVA's kernel interface!
Base framework
##############
Upgrading existing sessions
===========================
Genode enables a client of a service to lend parts of its own resources to
the service when opening a session. This way, servers do not need to allocate
own resources on behalf of their clients and become inherently robust against
resource-exhaustion-based denial-of-service attacks.
However, there are cases when the client can not decide about the amount of
resources to lend at session-creation time. In such cases, we used to devise an
overly generous client policy. Now, we have added a new 'upgrade' function to
the 'Parent' and 'Root' interfaces that enables a client to upgrade the
resources of an existing session.
For the 'env()->rm_session()' and 'env()->ram_session()' of processes using
the Genode 'env' library, we implemented a transparent quota upgrade that kicks in
in the event of an exceeded metadata backing store.
Comprehensive accounting of core resources
==========================================
We changed all services of core to limit their respective resource usage
specifically for each individual session. For example, the number of dataspaces
that can be handled by a particular region-manager (RM) session depends on the
resource donation attached to the session. To implement this accounting scheme
throughout core, we added a generic 'Allocator_guard' utility to
'base/include/'. We recommend using this utility when implementing resource
multiplexers, in particular multi-level services. Thanks to this change in
core, the need for a slack memory reservation in core has vanished.
Various changes
===============
The remaining parts of the base API underwent no fundamental revision. The
changes are summarized as follows.
:C++ Support:
We removed 'libgcc' from our C++ support library ('cxx') and link
it to each individual final target and shared library instead. This change alleviates
the need to abuse the 'KEEP_SYMBOLS' mechanism that we used in 'cxx' to
keep libc-dependencies of GCC's support libraries local to the 'cxx'
library. Besides the benefit of reducing heuristics, this change improves
the compatibility with recent cross-compiling tool chains.
Furthermore, we added 'realloc' to the local libc support of the 'cxx'
library because recent ARM tool chains tend to use this function.
:Argument handling for 'main()':
We added a hook to the startup code to enable the implementation of
custom facilities for passing arguments to the main function. The
hook uses the global variables 'genode_argc' and 'genode_argv'.
:Child-exit policy hook:
We enhanced the 'Child_policy' with a new policy interface that allows
a simplified implementation of policies related to program termination.
:Changed API of 'Range_allocator':
We changed the return value of 'alloc_addr' to distinguish different error
conditions. Note that the boolean meaning of the return value is inverted.
Please check your uses of 'alloc_addr'!
Operating-system services and libraries
#######################################
C Runtime
=========
In conjunction with our work on Noux, we improved Genode's C runtime at many
places. First, we added libstdtime and some previously missing bits of libgdtoa
to the libc. These additions largely alleviate the need for dummy stubs, in
particular time-related functions. Second, we added the following functions to
our libc plugin interface: 'dup2', 'fchdir', 'fcntl', 'fstat', 'stat', and
'write'. This enables the creation of advanced libc plugins simulating a whole
file system as done with Noux. Still, there are a number of dummy stubs found
at 'libc/src/lib/libc/dummy.cc'. However, those stubs are now all defined as
weak symbols such that they can be overridden by libc plugins. Finally, we have
replaced the original 'exit' implementation that comes with the libc with a
Genode-specific version. The new version reports the exit code of the
application to the parent process via an 'Parent::exit()' RPC call.
Until now, Genode's libc magically handled output to stdout and stderr by
printing messages via Genode's LOG interface. We have now replaced this
hard-wired interface by an optional libc plugin called 'libc_log'. If present, write
operations to stdout are caught at the libc plugin interface and delegated to
the plugin, which implements the output to the LOG interface. If you have an
application using Genode's libc, you might consider adding the 'libc_log'
library to your 'target.mk' file.
Support for big numbers by the means of libgmp and libmpfr
==========================================================
We have now include both the GNU Multiple Precision Arithmetic Library and
(GMP) and MPFR to the 'ports' repository. This work was specifically motivated
by our port of GCC to Genode as GCC version 4.4.5 requires both libraries.
Because we intend to use those libraries primarily on x86_32, the current port
covers only this architecture. However, expanding the port to
further CPU architectures should be straight-forward if needed.
Furthermore, you can now also find GCC's 'longlong.h' header at
'libports/include/gcc'.
Qt4 updated to version 4.7.1
############################
The current release bumps the supported Qt4 version from 4.6.2 to 4.7.1 and the
Arora web browser (located at the ports repository) from version 0.10.2 to
version 0.11. Of course, we updated our custom additions such as our custom
Nitpicker plugin widget that enables the seamless integration of native
Nitpicker GUI clients into Qt4 applications to work with the new Qt4 version.
Tools
#####
Tool chain update to GCC 4.4.5 and Binutils 2.21
================================================
We upgraded the official Genode tool chain from gcc 4.2.4 to gcc 4.4.5. Please
update your tool chain by downloading the new binary archive (available for x86_32)
or building the tool chain from source using our 'tool/tool_chain' utility.
New support for automated integration and testing
=================================================
With the growing number of supported base platforms, the integration and testing
of Genode application scenarios across all kernels becomes
increasingly challenging. Each kernel has a different boot mechanism and
specific requirements such as the module order of multiboot modules (Fiasco's
bootstrap, Pistachio's sigma0 and kickstart), kernel parameters, or the
invocation of a single-image creation tool (OKL4's elfweaver). To make our
life supporting all those platforms easier, we have created a tool called
'run', which is tightly integrated within Genode's build system. In short 'run'
gathers the intrinsics in the form of a 'run/env' file specific for the
platform used by the current build directory from the respective
'base-<platform>' repository. It then executes a so-called run script, which
contains all steps needed to configure, build, and integrate an application
scenario. For example, a typical run script for building and running a test
case resides in a file called '<any-repository>/run/<run-script-name>.run' and
looks as follows:
! build "core init test/exception"
! create_boot_directory
! install_config {
! <config>
! <parent-provides>
! <!--<service name="ROM"/>-->
! <service name="LOG"/>
! </parent-provides>
! <default-route>
! <any-service> <parent/> </any-service>
! </default-route>
! <start name="test-exception">
! <resource name="RAM" quantum="1M"/>
! </start>
! </config>
! }
! build_boot_image "core init test-exception"
! append qemu_args "-nographic -m 64"
! run_genode_until {.*Exception \(label 0xffb0\) occured.*} 10
First, the build system is instructed to create the targets specified as argument
for the 'build' function. Next, for the integration part, a new boot directory is
created. On most kernel platform, the respective location of the boot directory
is '<build-dir>/var/run/<run-script-name>'. Initially, this directory is empty.
It gets populated with a 'config' file specified as argument of the 'install_config'
command, and by the boot modules specified at the 'build_boot_image' command.
Now that the integration is complete, the scenario is executed via the
'run_genode_until' command. This command takes a regular expression as
argument, which determines the successful termination of the test case. The
second argument is a timeout (is seconds). In the example, the test case will
fail if its output does not match the regular expression within the execution
time of 10 seconds.
The command 'append qemu_args' specifies run-script-specific qemu arguments in
the case that qemu is used to execute the scenario. This is the case for most
kernel platforms (except for Linux where core gets executed directly on the host).
Additional build-directory-specific qemu arguments can be specified in the
'etc/build.conf' file by defining the 'QEMU_OPT' variable. For example, to
prevent KVM being used on Ubuntu Linux, specify:
! QEMU_OPT = -no-kvm
To execute the run script from with build directory, you need to have Expect
installed. Typically, the Linux package is called 'expect'. Simply issue
the following command from within your build directory:
! make run/<run-script>
Note that you will need to have a GRUB 'stage2_eltorito' binary available
at '<genode-dir>/tool/grub' on base platforms that use an ISO image as boot
stategy.
Because the whole chain of actions, building, integrating, executing, and
validating an application scenario is now at the fingertips of issuing a
single command with no kernel-specific considerations needed, it has never
been easier to run the same scenario on a wide range of different kernels.
Please find further instructive examples at 'os/run/'. The 'ldso' run
script executes the test of the dynamic linker. It is completely generic.
The 'demo' run script starts Genode's default demo scenario and shows how
platform-specific considerations (e.g., which device drivers to use) can be
taken into account.
We found that the 'run' tool significantly boosted our productivity not
only for testing purposes but also for accelerating the development-test
cycle during our day-to-day work.
:Technical notes:
The 'run' tool uses Expect as automation tool. Expect is a Tcl interpreter,
which is accompanied by special functionality for automating interactive
command-line applications. Technically, a run script is an Expect script
which gets included by the 'tool/run' script. For the reference of
run-specific functions, please revise the documentation in the 'tool/run'
script. Because each run script is actual Expect source code, it is possible
to use all Tcl and Expect scripting features in a run script.
In particular, a run script may issue shell commands using Tcl's 'exec'
function. This way, even complex integration tasks can be accomplished.
For example, the integration of the Genode Live CD was done via a single
run script.
Build system
============
To facilitate the integration of 3rd-party build systems into the Genode build
process, we added support for pseudo targets that do not require any 'SRC'
declaration. Such 'target.mk' may contain custom rules that will be executed
when the target is revisited by the build system. The bindings are as follows:
! build_3rd_party:
! ...custom commands...
!
! $(TARGET): build_3rd_party
!
! clean_3rd_party:
! ...custom commands...
!
! clean_prg_objects: clean_3rd_party:

1289
doc/release_notes-11-05.txt Normal file

File diff suppressed because it is too large Load Diff

703
doc/release_notes-11-08.txt Normal file
View File

@@ -0,0 +1,703 @@
===============================================
Release notes for the Genode OS Framework 11.08
===============================================
Genode Labs
One of Genode's most distinctive properties is its support for various
different kernels as base platforms. Each of the 8 currently supported kernels
differs with regard to features, security, hardware support, complexity, and
resource management. Even though different applications call for different
kernel properties, through Genode, those properties can be leveraged using a
unified API. The growing number of supported base platforms, however, poses two
challenges, which are the comprehension of the large diversity of tools and
boot concepts, and capturing of the semantic differences of all the kernels.
With the version 11.08, the framework mitigates the former challenge by
introducing a unified way to download, build, and use each of the
kernels with Genode's user-level infrastructure. The new tools empower users of
the framework to instantly change the underlying kernel without the need to know
the peculiarities of the respective kernels. Using microkernels has never been
easier.
The second challenge of translating each kernel's specific behaviour to the
framework's unified API longs for an automated testing infrastructure that
systematically exercises all the various facets of the API on all base
platforms. The new version introduces the tooling support especially designed
for conducting such quality-assurance measures. These tools largely remove the
burden of manual testing while helping us to uphold the stability and quality
of the framework as it grows in terms of functional complexity and number of
base platforms.
Speaking of functional enhancements, the work on version 11.08 was focused
on our block-device infrastructure and ARM support. The block-device-related
work is primarily motivated by our fundamental goal to scale Genode to a
general-purpose computing platform. The additions comprise new drivers for
SD-cards, IDE, SATA, USB storage as well as a new partition server. All those
components provide Genode's generic block interface, which is meant to be used
as back end for file systems. On file-system level, a new libc plugin utilizes
libffat to enable the straight-forward use of VFAT partitions by libc-using
programs.
The current release comes with far-reaching improvements with respect to
ARM-based platforms. The paravirtualized L4Linux kernel has been updated to
Linux version 2.6.39 running on both x86_32 and ARM. Also, Qt4 including Webkit
has become functional on ARMv6-based platforms.
Among the further improvements are many new examples in the form of
ready-to-use run scripts as well as a comprehensive documentation update.
Originally, we had planned to complement the Noux runtime environment to
support interactive command-line applications by the time of the current
release. However, we realized that the current users of the framework would
value the new streamlined tooling support, the enhanced documentation, and the
new quality-assurance infrastructure over such a functional addition. Hence, we
prioritized the topics accordingly. Even though you will find the first bits of
interactive GNU application support in this release, we deferred working on
this topic in full steam to the upcoming version 11.11.
Blurring the boundaries between different kernels
#################################################
Before the Genode project was born, each microkernel carried along its own
userland. For example, the L4/Fiasco kernel came with the L4 environment, the
OKL4 kernel came with Iguana, or the L4ka::Pistachio kernel came with a small
set of example components. Those user-level counterparts of the kernel
complemented their respective kernels with a runtime for user-level
applications and components while exposing significant parts of the kernel
interface at API level. Consequently, most if not all applications developed
against these APIs were tied to a particular kernel. On the one hand, this
approach enabled developers to fine-tune their programs using kernel-specific
features. On the other hand, much effort was wasted by duplicating other
people's work. Eventually, all of the mentioned userlands stayed limited to
special purposes - for the most part the purposes of operating-systems
researchers. Consequently, none of the microkernels gained much attention in
general-purpose computing. Another consequence of the highly fragmented
microkernel community was the lack of a common ground to compare different
kernels in an unbiased way because each userland provided a different set of
components and libraries.
Different application areas call for different kernel features such as
security mechanisms, scheduling, resource management, and hardware support.
Naturally, each kernel exhibits a specific profile of these parameters
depending on its primary purpose. If one microkernel attempted to accommodate
too many features, it would certainly sacrifice the fundamental idea of being
minimally complex. Consequently, kernels happen to be vastly different. During
the past three years, however, Genode has demonstrated that one carefully
crafted API can target highly diverse kernels, and thereby enables users of
the framework to select the kernel that fits best with the requirements
dictated by each application scenario individually. For us Genode developers,
it was extremely gratifying to see that kernels as different as Linux and NOVA
can be reconciled at the programming-interface level. Still, each kernel comes
with different tools, configuration mechanisms, and boot concepts. Even though
Genode programs can be developed in a kernel-independent way, the deployment of
such programs still required profound insights into the peculiarities of the
respective kernel.
With the current release, we introduce a fundamentally new way of using
different microkernels by unifying the procedures of downloading and building
kernels as well as integrating and running Genode programs with each of them.
Existing Genode application scenarios can be ported between kernels in an
instant without the need for deep insights into the kernel's technicalities. As
a teaser, consider the following commands for building and running Genode's
graphical demo scenario on the OKL4 microkernel:
! # check out Genode
! svn co https://genode.svn.sourceforge.net/svnroot/genode/trunk genode
!
! # download the kernel, e.g., OKL4
! make -C genode/base-okl4 prepare
!
! # create Genode build directory
! genode/tool/create_builddir \
! okl4_x86 BUILD_DIR=build
!
! # build everything and execute the interactive demo
! make -C build run/demo
The same principle steps can be used for any of the OKL4, NOVA,
L4/Fiasco, Fiasco.OC, L4ka::Pistachio, or Codezero kernels. You should
nevertheless consult the documentation at 'base-<platform>/doc/' before
starting to use a specific kernel because some base platforms require
the installation of additional tools.
Under the hood, this seamless way of dealing with different kernels is made
possible by the following considerations:
:Repository preparation:
Each kernel comes from a different source such as a Git/SVN/Mercurial
repository or a packaged archive. Some kernels require additional patches. For
example, OKL4 needs to be patched to overcome problems with modern tool chains.
Now, each 'base-<platform>' repository hosts a 'Makefile' that automates the
download and patch procedure. To download the source code of a kernel,
issue 'make prepare' from within the kernel's 'base-<platform>' directory. The
3rd-party source code will be located at 'base-<platform>/contrib/'.
:Building the kernel:
Each kernel has a different approach when it comes to configuration and
compilation. For example, NOVA comes with a simple 'Makefile', OKL4 relies on a
complex SCons-based build system, L4ka::Pistachio uses CML2 and autoconf (for
the userland tools). Furthermore, some kernels require the setting of specific
configuration values. We have streamlined all these procedures into the Genode
build process by the means of a 'kernel' pseudo target and a 'platform' pseudo
library. The kernel can be compiled directly from the Genode build directory by
issuing 'make kernel'. The 'platform' pseudo library takes care of making the
kernel headers available to Genode. For some kernels such as OKL4 and NOVA, we
replaced the original build mechanism with a Genode target. For other kernels
such as L4ka::Pistachio or Fiasco.OC, we invoke the kernel's build system.
:Genode build directory:
Genode build directories are created via the 'tool/create_builddir' tool.
This tool used to require certain kernel-specific arguments such as the
location of the kernel source tree. Thanks to the unified way of preparing
kernels, the need for such arguments has vanished. Now, the only remaining
arguments to 'create_builddir' are the actual platform and the location
of the build directory to create.
:System integration and booting:
As diverse the build systems of the kernels are, so are the boot concepts. Some
kernels rely on a multiboot-compliant boot loader whereas others have special
tools for creating boot images. Thankfully, Genode's run concept allows us to
hide the peculiarities of booting behind a neat and easy-to-use facade. For
each platform we have crafted a dedicated run environment located at
'base-<platform>/run/env', which contains the rules for system integration and
booting. Therefore, one and the same run script can be used to build and
execute one application scenario across various different kernels. For an
illustrative example, the 'os/src/run/demo.run' script can be executed on all
base platforms (except for base-mb) by issuing 'make run/demo' from within the
build directory.
Emerging block-device infrastructure
####################################
Since version 10.08, Genode is equipped with a block-session interface. Its
primary use cases so far were the supply of the paravirtualized OKLinux kernel
with backing store, and the access of the content of a bootable Live CD.
However, for our mission to use Genode as general-purpose computing platform,
disk device access is crucial. Therefore, we dedicated our attention to
various aspects of Genode's block-device infrastructure, reaching from
programming APIs for block drivers, over partition handling, to file-system
access.
:Block session interface:
The glue that holds all block-device-related components together is the generic
block interface 'os/include/block_session'. It is based on the framework's
packet-stream facility, which allows the communication of bulk data via shared
memory and a data-flow protocol using asynchronous notifications. The interface
supports arbitrary allocation schemes and the use of multiple outstanding
requests. Hence, it is generally suited for scatter-gather DMA and the use of
command queuing as offered by the firmware of modern block-device controllers.
(albeit the current drivers do not exploit this potential yet)
:Block component framework:
Our observation that components implementing the block session interface share
similar code patterns prompted us to design a framework API for implementing
this family of components. The set of classes located at 'os/include/block'
facilitate the separation of device-specific code from application logic.
Whereas 'component.h' provides the application logic needed to implement the
block service, the 'driver.h' is an abstract interface to be implemented by the
actual device driver. This new infrastructure significantly reduces code
duplication among new block-device drivers.
:Device-driver implementations:
The new block-device drivers introduced with the current release address
common types of block devices:
* By adding ATA read/write support to the ATAPI driver ('os/src/drivers/atapi'),
this driver can be used to access IDE disks now.
* The new fully-functional SD-card driver ('os/src/drivers/sdcard') enables the
use of SD-cards connected via the PL180 controller.
* The USB storage driver ('linux_drivers/src/drivers/usb') has been adapted
to the block-session interface and can be used on PC hardware.
* The new AHCI driver ('os/src/drivers/ahci') enables the access of disks
connected via SATA on PC hardware.
Because all drivers are providing the generic block-session interfaces, they
can be arbitrarily combined with components that use this interface as back
end, for example, the partition server and file systems.
:Partition manager as resource multiplexer:
The new partition manager ('os/src/server/part_blk') multiplexes one back-end
block session to multiple block sessions, each accessing a different partition.
Its natural role is being "plugged" between a block-device driver and a file
system.
:File-system access:
Even though a session interface for file systems does not exist yet, we
enabled the use of VFAT partitions through a libc plugin. This libc plugin uses
the ffat library to access files stored on a block device. An
application using this plugin can be directly connected to a block session.
New documentation
#################
The new way of dealing with different kernels motivated us to revisit and
complement our exiting documentation. The following documents are new or
have received considerable attention:
:[http://genode.org/documentation/developer-resources/getting_started - Getting started]:
The revised guide of how to explore Genode provides a quick way to
test drive Genode's graphical demo scenario with a kernel of your
choice and gives pointers to documents needed to proceed your
exploration.
:[http://genode.org/documentation/developer-resources/build_system - Build system manual]:
The new build-system manual explains the concepts behind Genode's
build system, provides guidance with creating custom programs and
libraries, and covers the tool support for the automated integration
and testing of application scenarios.
:[http://genode.org/documentation/components - Components overview]:
The new components-overview document explains the categorization of
Genode's components and lists all components that come with the framework.
:[http://genode.org/documentation/developer-resources/init - Configuration of the init process]:
The document describes Genode's configuration concept, the routing of
service requests, and the expression of mandatory access-control policies.
:[http://genode.org/community/wiki - Wiki]:
The platform-specific Wiki pages for L4/Fiasco, L4ka::Pistachio, NOVA,
Codezero, Fiasco.OC, and OKL4 have been updated to reflect the new flows of
working with the respective base platforms.
Base framework
##############
The RPC API for performing procedure calls across process boundaries
introduced with the version 11.05 was the most significant API change
in Genode's history. To make the transition from the old client-server
API to the new RPC API as smooth as possible, we temporarily upheld
compatibility to the old API. Now, the time has come to put the old
API at rest. The changes that are visible at API level are as follows:
* The old client-server API in the form of 'base/server.h' is no more.
The functionality of the original classes 'Server_entrypoint' and
'Server_activation' is contained in the 'Rpc_entrypoint' class provided
via 'base/rpc_server.h'.
* When introducing the RPC API, we intentionally left the actual session
interfaces as unmodified as possible to proof the versatility of the new
facility. However, it became apparent that some of the original interfaces
could profit from using a less C-ish style. For example, some interfaces used
to pass null-terminated strings as 'char const *' rather than via a dedicated
type. The methodology of using the new RPC API while leaving the original
interfaces intact was to implement such old-style functions as wrappers
around new-style RPC functions. These wrappers were contained in
'rpc_object.h' files, e.g. for 'linux_dataspace', 'parent', 'root',
'signal_session', 'cpu_session'. Now, we have taken the chance to modernise
the API by disposing said wrappers. Thereby, the need for 'rpc_object.h'
files has (almost) vanished.
* The remaining users of the old client-server API have been adapted to the
new RPC API, most prominently, the packet-stream-related interfaces such as
'block_session', 'nic_session', and 'audio_session'.
* We removed 'Typed_capability' and the second argument of the 'Capability'
template. The latter was an artifact that was only used to support the
transition from the old to the new API.
* The 'ipc_client' has no longer an 'operator int'. The result of an IPC can
be requested via the 'result' function.
* We refined the accessors of 'Rpc_in_buffer' in 'base/rpc_args.h'. The
'addr()' has been renamed to 'base()', 'is_valid_string()' considers the
buffer's capacity, and the new 'string()' function is guaranteed to return a
null-terminated string.
* We introduced a new 'Rm_session::Local_addr' class, which serves two
purposes. It allows the transfer of the bit representation of pointers across
RPC calls and effectively removes the need for casting the return type of
'Rm_session::attach' to the type needed at the caller side.
* The 'Connection' class template has been simplified, taking the session
interface as template argument (rather than the capability type). This change
simplified the 'Connection' classes of most session interfaces.
* The never-used return value of 'Parent::announce' has been removed. From the
child's perspective, an announcement always succeeds. The way of how the
announcement is treated is entirely up to the parent. The client should never
act differently depending on the parent's policy anyway.
* The new 'Thread_base::cap()' accessor function allows obtaining the thread's
capability as used for the argument to CPU-session operations.
Operating-system services and libraries
#######################################
Dynamic linker
==============
As a follow-up to the major revision of the dynamic linker that was featured
with the previous release, we addressed several corner cases related to
exception handling and improved the handling of global symbols.
The dynamic linker used to resolve requests for global symbols by handing out
its own symbols if present. However, in some cases, this behaviour is
undesired. For example, the dynamic linker contains a small set of libc
emulation functions specifically for the ported linker code. In the presence of
the real libc, however, these symbols should never be considered at all. To
avoid such ambiguities during symbol resolution, the set of symbols to be
exported is now explicitly declared by the white-list contained in the
'os/src/lib/ldso/symbol.map' file.
We changed the linkage of the C++ support library ('cxx') against dynamic
binaries to be consistent with the other base libraries. Originally, the 'cxx'
library was linked to both the dynamic linker and the dynamic binary, which
resulted in subtle problems caused by the duplication of cxx-internal data
structures. By linking 'cxx' only to the dynamic linker and exporting the
'__cxa' ABI as global symbols, these issues have been resolved. As a positive
side effect, this change reduces the size of dynamic binaries.
C++ exception handling in the presence of shared libraries turned out to be
more challenging than we originally anticipated. For example, the
'_Unwind_Resume' symbol is exported by the compiler's 'libsupc++' as a hidden
global symbol, which can only be resolved when linking this library to the
binary but is not seen by the dynamic linker. This was the actual reason of why
we used to link 'cxx' against both dynamic binaries and shared libraries
causing the problem mentioned in the previous paragraph. Normally, this problem
is addressed by a shared library called 'libgcc_s.so' that comes with the
compiler. However, this library depends on glibc, which prevents us from using
it on Genode. Our solution is renaming the hidden global symbol using a
'_cxx__' prefix and introducing a non-hidden global wrapper function
('__cxx__Unwind_Resume' in 'unwind.cc'), which is resolved at runtime by the
dynamic linker.
Another corner case we identified is throwing exceptions from within the
dynamic linker. In contrast to the original FreeBSD version of the dynamic
linker, which is a plain C program that can never throw a C++ exception,
Genode's version relies on C++ code that makes use of exceptions. To support
C++ exceptions from within the dynamic linker, we have to relocate the
linkers's global symbols again after having loaded the dynamic binary. This
way, type information that is also present within the dynamic binary becomes
relocated to the correct positions.
Block partition server
======================
The new block-partition server uses Genode's block-session interfaces as both
front and back end, leading to the most common use case where this server will
reside between a block driver and a higher level component like a file-system
server.
At startup, the partition server will try to parse the master boot record (MBR)
of its back-end block session. If no partition table is found, the whole block
device is exported as partition '0'. In the other case, the MBR and possible
extended boot records (EBRs) are parsed and offered as separate block sessions
to the front-end clients. The four primary partitions will receive partition
numbers '1' to '4' whereas the first logical partition will be assigned to '5'.
The policy of which partition is exposed to which client can be expressed
in the config supplied to the 'part_blk' server. Please refer to the
documentation at 'os/src/server/part_blk/README' for further details. As an
illustration of the practical use of the 'part_blk' server, you can find a run
script at 'os/run/part_blk.run'.
Skeleton of text terminal
=========================
As part of the ongoing work towards using interactive text-based GNU software
on Genode, we created the first bits of the infrastructure required for
pursuing this quest:
The new terminal-session interface at 'os/include/terminal_session/' is the
designated interface to be implemented by terminal programs.
After investigating the pros and cons of various terminal protocols and
terminal emulators, we settled for implementing a custom terminal emulator
implementing the Linux termcap. This termcap offers a reasonable small set of
commands while providing all essential features such as function-key support
and mouse support. Thanks to Peter Persson for pointing us to the right
direction! The preliminary code for parsing the escape sequences for the Linux
termcap is located at 'gems/include/terminal/'.
We have created a simplistic terminal service that implements the
terminal-session interface using a built-in font. Please note that the
implementation at 'gems/src/server/terminal/' is at an early stage. It is
accompanied by a simple echo program located at 'gems/src/test/terminal_echo'.
Device drivers
##############
USB HID and USB storage
=======================
We replaced the former DDE-Linux-based USB-related driver libraries (at the
'linux_drivers/' repository) by a single USB driver server that offers the
'Input' and 'Block' services. This enables us to use both USB HID and USB
storage at the same time. The new USB driver is located at
'linux_drivers/src/drivers/usb/'.
For using the USB driver as input service (supporting USB HID), add the
'<hid/>' tag to the 'usb_drv' configuration. Analogously, for using the driver
as block service, add the '<storage/>' tag. Both tags can be combined.
For testing the USB stack, the 'linux_drivers' repository comes with the run
scripts 'usb_hid.run' and 'usb_storage.run'.
ATA read/write support
======================
The ATAPI driver has been extended to support IDE block devices for both
read and write transactions. To use the new facility, supply 'ata="yes"'
as XML attribute to the config node of 'atapi_drv'. Please note that this
driver was primarily tested on Qemu. Use it with caution.
SATA driver
===========
The new SATA driver at 'os/src/drivers/ahci/' implements the block-driver
API ('os/include/block'), thus exposing the block-session interface as
front-end. AHCI depends on Genode's PCI driver as well as the timer server. For
a usage example see: 'os/run/ahci.run'.
Limitations and known issues
----------------------------
Currently, the server scans the PCI bus at startup and retrieves the first available
AHCI controller, scans the controller ports and uses the first non-ATAPI port
where a device is present.
On real hardware and on kernels taking advantage of I/O APICs (namely NOVA and
Fiasco.OC) we still lack support for ACPI parsing and thus for interrupts,
leading to a non-working driver.
SD-card driver
==============
The first fragments of our SD-card driver that we introduced with the previous
release have been complemented. The new SD-card driver located at
'os/src/drivers/sd_card/' implements the block-session interface by using
MMC/SD-cards and the PL180 controller as back end. Currently the driver
supports single-capacity SD cards. Therefore, the block file for Qemu should
not exceed 512 MB. Because the driver provides the generic block-session
interface, it can be combined with the new 'libc_ffat' plugin in a
straight-forward way. To give the driver a quick spin, you may give the
'libports/run/libc_ffat.run' script on the 'foc_pbxa9' platform a try.
ARM Realview PL011 UART driver
==============================
The new PL011 UART driver at 'os/src/drivers/uart/' implements the LOG session
interface using the PL011 device. Up to 4 UARTs are supported. The assignment
of UARTs to clients can be defined via a policy supplied to the driver's config
node. For further information, please refer to the README file within the
'uart' directory.
Libraries and applications
##########################
Hello tutorial
==============
The 'hello_tutorial/' repository contains a step-by-step guide for building
a simple client-server scenario. The tutorial has been rewritten for the new
RPC API and is now complemented by a run script for testing the final scenario
on various base platforms.
C and C++ runtimes
==================
:Support for standard C++ headers:
Triggered by public demand for using standard C++ headers for Genode applications,
we introduced a generally usable solution in the form of the 'stdcxx' library
to the 'libc' repository. The new 'stdcxx' library is not a real library. (you
will find the corresponding 'lib/mk/stdcxx.mk' file empty) However, it comes
with a 'lib/import/import-stdcxx.mk' file that adds the compiler's C++ includes
to the default include-search path for any target that has 'stdcxx' listed in
its 'LIBS' declaration.
:Libc back end for accessing VFAT partitions:
The new 'libc_ffat' libc plugin uses a block session via the ffat library. It
can be used by a Genode application to access a VFAT file system via the libc
file API. The file-system access is performed via the 'ffat' library. To
download this library and integrate it with Genode, change to the 'libports'
repository and issue the following command:
! make prepare PKG=ffat
For an example of how to use the libc-ffat plugin, please refer to the run
script 'libports/run/libc_ffat.run'. The source code of the test program can be
found at 'libports/src/test/libc_ffat/'.
Qt4
===
Qt4 version 4.7.1 has been enabled on ARMv6-based platforms, i.e., PBX-A9 on
Fiasco.OC. The support comprises the entire Qt4 framework including qt_webcore
(Webkit).
L4Linux
=======
L4Linux enables the use of one or multiple instances of Linux-based operating
systems as subsystems running on the Fiasco.OC kernel. The Genode version of
L4Linux has seen the following improvements:
:Kernel version: has been updated to Linux 2.6.39.
:ARM support: The L4Linux kernel can be used on ARM-based platforms now.
The PBX-A9 platform is supported via the 'l4linux.run' script as found
at 'ports-foc/run/'. Please find more information at 'ports-foc/README'.
:Genode-specific stub drivers outside the kernel tree:
The stub drivers that enable the use of Genode's services as virtual
devices for L4Linux have been moved outside the kernel patch, which
makes them much easier to maintain. These stub drivers are located
under 'ports-foc/src/drivers/'.
Platform support
################
All base platforms are now handled in a unified fashion. Downloading 3rd-party
source code is performed using the 'prepare' rule of the 'Makefile' provided by
the respective kernel's 'base-<platform>' repository. Once, the platform's base
repository is prepared, the kernel can be built directly from the Genode
build directory using 'make kernel'. All base platforms are now supported by
Genode's run mechanism that automates the tasks of system integration and
testing. For more details about each specific kernel, please revisit the
updated documentation within the respective 'base-<platform>/doc/' directory.
:L4/Fiasco:
The kernel has been updated to revision 472, enabling the use of recent
GNU tool chains.
:Fiasco.OC:
The kernel as been updated to revision 36, which remedies stability problems
related to interaction of the IPC path with thread destruction. The new version
improves the stability of highly dynamic workloads that involve the frequent
creation and destruction of subsystems. However, we experienced the new kernel
version to behave instable on the x86_64 architecture. If you depend on x86_64,
we recommend to temporarily stick with Genode 11.05 and Fiasco.OC revision 31.
:L4ka::Pistachio:
The kernel has been updated to revision 803, enabling the use of recent
versions of binutils.
:OKL4:
OKL4v2 is showing its age. Apparently, the use of the original distribution
requires tools (i.e., python 2.4) that do not ship with current Linux
distributions anymore. This makes it increasingly difficult to use this kernel.
Still, we find ourselves frequently using it for our day-to-day development. To
streamline the use of OKL4v2, we have now incorporated the kernel compilation
into the Genode build system and thereby weakened the kernel's dependency on
ancient tools. However, we decided to drop support for OKL4/ARM for now. We
figured that the supported GTA01 platform is hardly used anymore and hard to
test because it is unsupported by Qemu. Newer ARM platforms are supported by
other kernels anyway.
:Codezero:
Even though B-Labs apparently abandoned the idea of developing the Codezero
kernel in the open, we adapted Genode to the kernel's most recent Open-Source
version that is still available at the official Git repository. Furthermore,
the kernel is now fully supported by Genode's new 'make prepare' procedure and
run environment. Therefore, run scripts such as 'run/demo' can now easily be
executed on Codezero without the need to manually configure the kernel.
Note that, for now, we have disabled Codezero's capabilities because they do
not allow the assignment of device resources. Consequently, 'sys_map' fails for
MMIO regions when performing the capability check (calling 'cap_map_check').
Furthermore, the current version of the kernel requires a workaround for a
current limitation regarding the definition of a thread's pager. At some point,
Codezero abandoned the facility to define the pager for a given thread via the
exregs system call. Instead, the kernel hard-wires the creator of the thread as
the thread's pager. This is conflicting with Genode's way of creating and
paging threads. In the current version of Genode for this kernel, all threads
are paged by one thread (thread 3 happens to be the global pager) within core.
As a workaround to Codezero's current limitation, we define thread 3 to be the
pager of all threads. The patch of the upstream code is automatically being
applied by the 'make prepare' mechanism.
Build system and tools
######################
In addition to the major change with respect to the integration of the various
base platforms, Genode's tool support received the following incremental
improvements:
Build system
============
:Simplification of 'create_builddir' tool:
The 'create_builddir' tool has been relocated from
'tool/builddir/create_builddir' to 'tool/create_builddir' to make it more
readily accessible. Furthermore, we simplified the usage of the tool by
removing the mandatory 'GENODE_DIR' argument. If not explicitly specified, the
tool deduces 'GENODE_DIR' from the its known location within the Genode source
tree.
:Booting from USB sticks:
For most x86-based base platforms, their respective run environments execute
Genode from an ISO image via Qemu. Naturally, such an ISO image can be burned
onto a CD-ROM to be used to boot a real machine. However, booting from CD-ROM
is slow and optical drives are becoming scarce. Therefore we changed the
procedure of creating ISO images to support writing the resulting images to a
USB stick. Under the hood, the boot mechanism chain-loads GRUB via ISOLinux.
The files to implement the boot concept are located at 'tool/boot/'.
:Support for source files in target sub directories:
Until now, the 'SRC_*' declarations in target description files contained
a list of plain file names. The location of the files within the directory
tree had to be defined via 'vpath'. This led to inconveniences when building
3rd-party code that contains files with the same name at different subdirectories.
To resolve such an ambiguity, the target had to be decomposed into multiple
libraries each building a different set of subdirectories. To make the
build system more convenient to use, we have now added support for specifying
source codes with a relative pathname. For example, instead of using
! SRC_CC = main.cc addon.cc
! vpath addon.cc $(PRG_DIR)/contrib
we can now use
! SRC_CC = main.cc contrib/addon.cc
Automated testing across multiple kernels
=========================================
To execute one or multiple test cases on more than one base platform, we
introduced a dedicated tool located at 'tool/autopilot'. Its primary purpose is
the nightly execution of test cases. The tool takes a list of platforms and a
list of run scripts as arguments and executes each run script on each platform.
The build directory for each platform is created at
'/tmp/autopilot.<username>/<platform>' and the output of each run script is
written to a file called '<platform>.<run-script>.log'. On stderr, autopilot
prints the statistics about whether or not each run script executed
successfully on each platform. If at least one run script failed, autopilot
returns a non-zero exit code, which makes it straight forward to include
autopilot into an automated build-and-test environment.

1008
doc/release_notes-11-11.txt Normal file

File diff suppressed because it is too large Load Diff