You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1016 lines
44 KiB
1016 lines
44 KiB
|
|
|
|
============================================== |
|
Release notes for the Genode OS Framework 9.11 |
|
============================================== |
|
|
|
Genode Labs |
|
|
|
|
|
In contrast to the previous release, which had been mainly about important |
|
refinements and optimizations under the hood, the release 9.11 is focused on |
|
new features. |
|
|
|
Our brand new packet streaming framework enables the efficient communication of |
|
bulk data between processes based on a shared-memory protocol and asynchronous |
|
signalling. We put this new facility to use for the new NIC session interface. |
|
This interface allows us to execute network drivers and network protocol stacks |
|
in distinct processes. The most interesting current use case is the new |
|
integration of the light-weight IP stack (lwIP) into Genode. |
|
The most noticeable platform-related addition is the new support for the ARM |
|
architecture to the OKL4 version of the framework. |
|
|
|
As with every release, we refined recently introduced features and tightly |
|
integrated them into our mainline development. The most prominent of these |
|
features is dynamic linking support, which was introduced with the previous |
|
release and has now become fully integrated in the framework and the build |
|
system. Also our steady improvement of the Linux device-driver |
|
environment yields fruit in the form of USB storage support. With regard to |
|
Qt4, we are proud to announce the availability of the Qt4/Webkit library |
|
on all kernels supported by Genode. |
|
|
|
Furthermore, we added the paravirtualized Linux kernel called OKLinux to |
|
the official Genode distribution. This variant of Linux can be executed |
|
on top of the OKL4 version of Genode and provides a binary-compatible execution |
|
environment for Linux programs alongside low-complexity native Genode |
|
programs. |
|
|
|
This document compiles these and more changes between the versions 9.08 and |
|
9.11 of Genode. It contains new bits of documentation and tries to put our |
|
development into a broader context. |
|
|
|
|
|
Base framework |
|
############## |
|
|
|
The 'base-host' platform |
|
======================== |
|
|
|
We added a new platform repository called 'base-host' to the Genode |
|
distribution. This repository contains dummy implementations of |
|
platform-specific Genode APIs to enable the compilation of Genode for the host |
|
platform. Because the repository provides dummy implementations, most of the |
|
generated binaries will not work. However, the repository serves two important |
|
purposes. It documents all platform-specific APIs that must be filled out when |
|
porting Genode to another platform, and it is the build environment for unit |
|
tests executed on the host platform. |
|
|
|
|
|
Signalling-framework refinements |
|
================================ |
|
|
|
With our work on the packet-streaming facility described in Section |
|
[Packet-stream interface], we discovered a not yet supported use case for the |
|
signalling framework. |
|
|
|
The original implementation expected one or more signal-handling threads |
|
to block or poll for signals from potentially different sources and dispatch |
|
them in the order of arrival. |
|
Such a thread would instantiate one signal receiver associated with |
|
potentially many signal contexts (representing different signal sources). |
|
|
|
The new use case, however, requires one thread to be able to selectively handle |
|
a subset of signal contexts at a time. The API already facilitated this |
|
use case by a simple instantiation of multiple signal receivers and let one |
|
thread handle signals for one or another signal source by querying the |
|
different receivers. |
|
Until now, this use case was not supported by the underlying implementation |
|
because signals were submitted to signal receivers, which could only hold |
|
one pending signal. A signal could only be supplied to a receiver if |
|
there was no pending signal already stored at the receiver. Otherwise, |
|
signal delivery for the complete process stalled. We have now changed |
|
the implementation such that signals are always supplied to signal contexts |
|
instead of receivers. This way, the order of signal arrival and signal |
|
handling becomes completely decoupled and clears the way for a much more |
|
flexible use of the signalling framework. |
|
|
|
|
|
:Interface changes: |
|
|
|
Because the capability for signal submission refers to a signal context |
|
rather than a signal receiver, we changed the class names of the signal API |
|
accordingly. The previously called 'Signal_receiver_capability' is now called |
|
'Signal_context_capability'. We also streamlined the interface of core's SIGNAL |
|
service according to this new naming scheme. The latter change, however, is |
|
completely transparent at the Genode API level. |
|
|
|
|
|
C++ runtime improvements |
|
======================== |
|
|
|
The base framework of Genode is written in C++, but without a C runtime |
|
underneath. The C++ support libraries, however, use to depend on certain |
|
functions normally provided by the C library. Therefore, Genode has to provide |
|
custom implementations of these functions. This C++ runtime environment is |
|
encapsulated in the 'cxx' library. We use to complement the 'cxx' library as |
|
needed. |
|
|
|
One feature that was previously missing is proper synchronization of static |
|
constructors. In contrast to constructors of global variables, which are |
|
executed by the startup code before any other threads are created, static |
|
constructors are executed lazily, potentially by different threads. A typical |
|
static constructor looks like this: |
|
|
|
! Some_object *get_some_object() { |
|
! static Some_object o; |
|
! return &o; |
|
! } |
|
|
|
When calling the function 'get_some_object' the first time, The instance of |
|
'Some_object' is constructed at a static memory location. For all subsequent |
|
calls of 'get_some_object', the once created object is not constructed again |
|
but reused. This is a very handy alternative to global constructors when |
|
objects inter-depend on each other. In contrast to the construction order |
|
of global constructors, which is arbitrary, the call order of static constructors |
|
is implicitly defined by the code such that object dependencies are recognised. |
|
However, because static constructors are executed lazily, they may be called |
|
by different threads. The previous version of 'cxx' had no synchronization |
|
in place for protecting a static constructor from being concurrently |
|
executed by more than one thread, resulting in a 'recursive_init_error' |
|
run-time exception. |
|
|
|
With the Genode workloads getting more advanced and dynamic, we have seen |
|
this condition to trigger and have added proper support for guarded static |
|
C++ constructors into the 'cxx' library. |
|
|
|
|
|
Library-based AVL tree |
|
====================== |
|
|
|
Our AVL-tree implementation in 'base/include/util/avl_tree.h' is a fundamental |
|
data structure for the framework. It is used at numerous places such as |
|
memory allocators, address-space layout management, and the server-object |
|
framework. Up to now, this implementation was a big template, instantiated |
|
for each data type to organize. Moreover, most operations were implemented |
|
using inline functions. By statically profiling the layout of Genode's |
|
binaries, we observed that this inline code ended up multiple times in |
|
the binaries. However, the program logic of all those instances was essentially |
|
the same (e.g., how to perform a tree rotation). Only the policy (i.e., the |
|
sort criterion) differs. We now have re-implemented the AVL tree as two parts, |
|
the actual AVL-tree algorithm, which is independent from any template |
|
parameters and resides in a library called 'avl_tree', and a policy-dependent |
|
front-end template class residing in the 'avl_tree.h' header file. |
|
|
|
To our delight, this change reduced the average size of Genode's binaries |
|
by 10%. For example, the core binary for OKL4 on x86 went from 305 KB |
|
down to only 270 KB. |
|
|
|
|
|
:Interface change: |
|
|
|
The new AVL-tree implementation comes along with a slight API change. The |
|
operation to remove a node from an AVL tree used to be a member function of the |
|
'Avl_node' object to remove. This function is now being provided by the |
|
'Avl_tree' taking an 'Avl_node' as argument. Because the 'Avl_tree' is a |
|
container of 'Avl_node' objects, this change makes the AVL tree more consistent |
|
with other container classes such as 'List' and 'Fifo'. |
|
|
|
|
|
Initial support for the ARM architecture |
|
######################################## |
|
|
|
Right from the start of the project, the portability of the framework was a |
|
primary concern. This is reflected by the framework's unique capability to |
|
seamlessly run on four different kernels. With regard to the portability |
|
among different CPU architectures, however, the development was focused on the |
|
x86 architecture as this architecture is most common. With the release 9.11, |
|
the project moves beyond the x86 architecture by adding support ARM CPUs and an |
|
exemplary ARM-based SoC platform, namely GTA01. Because of all current Genode |
|
base platforms the OKL4 is the most widely used kernel on ARM-based devices, |
|
we have focused our efforts on this kernel first. The 'base-okl4' repository |
|
comes now with support for the ARM-based GTA01 platform as used for the |
|
Openmoko project. We choose this platform because it is supported |
|
out-of-the-box by the OKL4 2.1.1 distribution. The ARM-specific code that |
|
we had to add to the framework is surprisingly little. It covers the assembly |
|
startup code for executables, support code for atomic operations, and the |
|
platform driver for GTA01. Because the OKL4 kernels provides abstractions |
|
for all other CPU-specific peculiarities, the code for all framework libraries |
|
and components are the same for ARM and x86. This also includes the C++ |
|
startup code and the linker script. |
|
|
|
The procedure for trying out the new ARM support with the GTA01 platform using |
|
Qemu is decribed at a dedicated Wiki page: |
|
|
|
|
|
:Genode/OKL4 on the GTA01 platfrom: |
|
|
|
[http://genode.org/community/wiki/GenodeOKL4OnTheGTA01Platform - Genode.org Community Wiki] |
|
|
|
Both the OKL4 version 2.1.1 and the GTA01 chip are not the most current |
|
platforms but this combination turned out to be good as starting point. |
|
Because we use OKL4 2.1.1 on a regular basis on x86, using this kernel on ARM |
|
is an evolutionary intermediate step towards moving on to more recent kernels. |
|
|
|
|
|
:Limitiations: |
|
|
|
* The platform driver for GTA01 is pretty limited. It is just as a |
|
show case for running Genode on the Qemu-neo1973 emulator. The driver |
|
is not tested on real hardware. |
|
* This release contains the initial support, which currently covers the |
|
base framework, the 'os', and the 'demo' repositories. Other repositories |
|
such as 'libc', 'linux_drivers', and 'qt4' are not supported yet. |
|
* Dynamic linking is not yet not supported on ARM |
|
|
|
|
|
Paravirtualized Linux on Genode/OKL4 |
|
#################################### |
|
|
|
OKLinux is a para-virtualized version of the Linux kernel running on top of the |
|
micro-kernel OKL4. It enables us to execute Linux applications in the Genode |
|
environment side-by-side with low-complexity native Genode applications, which |
|
can implement security-critical functions without relying on the |
|
high-complexity Linux kernel. Compared with most existing virtualization |
|
solutions including Xen and KVM, the trusted computing base for such |
|
security-critical components is one or more magnitudes smaller (the OKL4 kernel |
|
+ Genode base framework are less than 30,000 lines of code). |
|
|
|
The original code of OKLinux relies on the Iguana framework - a bunch of |
|
server components and libraries to simplify construction of applications |
|
running on top of OKL4. The new 'oklinux' Genode repository contains a small |
|
OKLinux support library, as well as a patch for OKLinux 2.6.23, that replaces |
|
Iguana by the Genode framework. Nevertheless, our version of OKLinux stays to |
|
be dependent on the OKL4 kernel, meaning that you can only use it in |
|
combination with Genode running on top of OKL4. |
|
|
|
Usage |
|
===== |
|
|
|
If you haven't build Genode for OKL4 yet, please refer to the following document: |
|
|
|
:[http://genode.org/documentation/platforms/okl4 - Genode on the OKL4 microkernel]: |
|
This page contains the information on how to build and use Genode with OKL4. |
|
|
|
For building OKLinux for Genode, you first need to download and patch the |
|
original sources. The top-level makefile of the 'oklinux' repository automates |
|
this task. Just issue: |
|
|
|
! make prepare |
|
|
|
Afterwards you need to include the 'oklinux' repository into the Genode build |
|
process. Just add the path to this directory to the 'REPOSITORIES' declaration |
|
of the 'etc/build.conf' file within your build directory. |
|
Now, you can change to your build directory and simply type: |
|
|
|
! make oklinux |
|
|
|
That's all. The 'bin/' directory within your build directory should now contain |
|
a symbolic link to the 'vmlinux' binary. |
|
To test your Linux binary, you also need to tweak the config file for init and |
|
for the elfweaver tool. You will find examples for this in the 'config/' |
|
directory of the 'oklinux' repository. Moreover, you will need to add a RAM disk |
|
file to your setup as OKLinux for Genode only supports RAM disks by now. |
|
|
|
RAM disk |
|
======== |
|
|
|
OKLinux provides a special block device driver, which uses a RAM disk as |
|
backing-store. You can specify your RAM disk file on the kernel command line of |
|
Linux by setting the 'igms_name=' parameter. |
|
If you use a RAM-disk file that contains only a file system you have to set the |
|
root parameter on the kernel command line to '/dev/igms0'. If your RAM disk |
|
contains a whole partition table, state '/dev/igms0pn', whereby n stands for |
|
the partition number containing the root file system. |
|
|
|
Kernel command line |
|
=================== |
|
|
|
You can state the Linux kernel command line by using the XML config-file of the |
|
init node that starts your Linux instance. In addition to the filename and |
|
quota within the start section of Linux, you simply add the following: |
|
|
|
! <config> |
|
! <commandline>igms_name=ramdisk root=/dev/igms0p1</commandline> |
|
! </config> |
|
|
|
Configure Linux |
|
=============== |
|
|
|
This OKLinux package contains only a minimal Linux configuration. Especially, |
|
any hardware drivers are missing, as Genode/OKL4 doesn't allow direct hardware |
|
access from Linux. Instead, Linux accesses hardware indirectly through Genode |
|
services. The current version of OKLinux comes with stub drivers for connecting |
|
Linux to Genode's 'Input_session', 'Timer_session', and 'Framebuffer_session' |
|
interfaces and we plan to add support for more device classes in the future. |
|
|
|
If you want to enable/disable options in Linux, you can simply do so by using |
|
the normal Linux build system. You will find the '.config' file Linux is using |
|
within the 'oklinux/' directory of your build directory. If you don't want to |
|
tweak '.config' directly, you can also change to the 'oklinux/' directory of |
|
your build directory and issue: |
|
|
|
! ARCH=l4 SYSTEM=i386 make menuconfig |
|
|
|
Then you will get the well known ncurses interface. |
|
|
|
Troubleshooting |
|
=============== |
|
|
|
If you run into problems when building OKLinux and you want the build process |
|
to be somehow more verbose, you can build OKLinux this way: |
|
|
|
! VERBOSE_LX_MK=1 make oklinux |
|
|
|
Example |
|
======= |
|
|
|
The following screenshot shows Genode running on OKL4 with two instances |
|
of OKLinux running. One instance booted the TinyCore Linux distribution |
|
including the X Window System. The other instance booted a busybox-based |
|
RAM Disk and runs with just about 16 MB of RAM. Each Linux kernel uses |
|
a separate instance of the Liquid FB virtual frame buffer: |
|
|
|
[image tinycore_busybox_screen] |
|
|
|
The Genode process tree looks as follows (the figure omits usual Genode |
|
components such as device drivers for PCI, PS/2, VESA, and the Timer): |
|
|
|
[image tinycore_busybox] |
|
|
|
The Linux Launcher node is just a slightly modified Init node with the only |
|
difference being that requests for sessions to the Nitpicker GUI server or |
|
to the timer are always delegated to the parent rather than to another |
|
child. |
|
|
|
|
|
Operating-system services and libraries |
|
####################################### |
|
|
|
Completed support for dynamic linking |
|
===================================== |
|
|
|
With the previous release, we introduced the initial version of a dynamic |
|
linker for Genode. This version came in the form of a separate source-code |
|
repository called 'ldso' containing the dynamic linker and the linker |
|
scripts for building shared libraries and dynamically linked executables. |
|
However, some pieces were still missing to make the dynamic linker |
|
generally usable in practice. The Genode build system lacked proper support |
|
for building and using shared libraries and the dynamic linker had been |
|
only tested on the x86_32 platform on Pistachio and OKL4. |
|
In the meanwhile, we filled these gaps. With the release 9.11, we completely |
|
dissolved the dependency of the dynamic linker from the C library and, |
|
thereby, could make the dynamic linker a regular part of the 'os' repository. |
|
It now resides in the 'os/src/ldso' directory and supports all Genode base |
|
platforms L4/Fiasco, L4ka::Pistachio, OKL4, and Linux on the x86_32 and |
|
x86_64 architectures. We are especially delighted about the dynamic linker |
|
functioning seamlessly on the Linux platform. Because 'ldso' uses only |
|
the Genode API as back end, there are no platform-specific quirks needed. |
|
|
|
|
|
:Usage: |
|
|
|
To build a shared library instead of a regular static library, you just need to |
|
declare 'SHARED_LIB = yes' in the library-description file. When doing so, a |
|
'<libname>.lib.so' file will be generated and installed in the |
|
'<build-dir>/bin/' directory. For building an executable that uses a shared |
|
library, no special precautions are needed. The build system will automatically |
|
detect the use of shared libraries, concludes that the binary must be |
|
dynamically linked, and will use the correct linker script. When loading a |
|
dynamically linked program, the dynamic linker 'lsdo' and all used shared |
|
objects must be loaded as well. |
|
|
|
|
|
:Integration with the framework: |
|
|
|
On Genode, the 'process' library provides the API to create new processes from |
|
ELF executables. The user of the 'process' library can register a capability to |
|
a dataspace containing the dynamic linker via the function |
|
'Process::dynamic_linker'. When creating a new process, the library first |
|
revisits the ELF header of the executable to determine whether the binary is |
|
statically or dynamically linked. If statically linked, the process library |
|
proceeds with loading the ELF binary. Otherwise, it loads the dynamic linker as |
|
registered beforehand. When the dynamic linker (ldso) starts up, it requests |
|
the dataspace of the dynamically linked executable by opening a ROM session for |
|
the magic file called 'binary'. Note that the dynamic linker does not even need |
|
to know the real name of executable. Then ldso further loads all shared |
|
libraries needed for the executable via ROM sessions with the names of the |
|
respective shared object files and populates the local address space. After |
|
having initialized the address space for the new executable, ldso jumps to the |
|
executable's main function. |
|
|
|
|
|
Packet-stream interface |
|
======================= |
|
|
|
Up to now, Genode provides synchronous IPC calls and asynchronous signals as |
|
inter-process communication primitives. The IPC framework transfers message |
|
payload by copying data between processes via the kernel. The signalling |
|
mechanism provides semantics similar to interrupts but does not support the |
|
transfer of message payloads. With the new packet-stream interface, we |
|
complement those inter-process communication facilities with a mechanism |
|
that carries payload over a shared memory block employing an asynchronous |
|
data-flow protocol. It is geared towards large bulk payloads such as |
|
network traffic, block-device data, video frames, sound samples, and USB |
|
URB packets. |
|
|
|
The packet-stream interface comes in the form of the single header file |
|
'os/packet_stream.h' and supports the unidirectional streaming of bulk data |
|
between processes via a shared-memory block. The public interface consists of |
|
the two class templates 'Packet_stream_source', and 'Packet_stream_sink'. Both |
|
communication parties agree on a policy with regard to the organization of the |
|
communication buffer by specifying the same 'Packet_stream_policy' as template |
|
argument. |
|
|
|
[image packet_stream] |
|
|
|
As illustrated in the Figure above, the communication buffer consists of |
|
three parts, a submit queue, an acknowledgement queue, and a bulk buffer. |
|
The submit queue contains packets generated by the source to be processed |
|
by the sink. The acknowledgement queue contains packets that are processed |
|
and acknowledged by the sink. The bulk buffer contains the actual payload. |
|
The assignment of packets to bulk-buffer regions is performed by the |
|
source. |
|
|
|
The interplay between source and sink for processing a single packet looks |
|
as follows: |
|
|
|
# The source allocates a region of the bulk buffer for storing the packet |
|
payload using 'alloc_packet'. It then requests the local start address of |
|
the payload using 'packet_content' and fills the packet with data |
|
# The source submits the packet to the submit queue via 'submit_packet' |
|
# The sink requests a packet from the submit queue using 'get_packet', |
|
determines the local start address of the payload using 'packet_content', |
|
and processes the contained data |
|
# After having finished the processing of the packet, the sink acknowledges |
|
the packet using 'acknowledge_packet', placing the packet into the |
|
acknowledgement queue |
|
# The source reads the packet from the acknowledgement queue and releases |
|
the packet using 'release_packet'. Thereby, the region of the bulk buffer |
|
that was used by the packet becomes marked as free. |
|
|
|
This protocol has four corner cases that are handled by signals: |
|
|
|
:submit queue is full: when the source is trying to submit a new packet. |
|
In this case, the source blocks and waits for the sink to remove packets |
|
from the submit queue. If the sink observes such a condition (calling |
|
'get_packet' on a full submit queue, it delivers a 'ready_to_submit' |
|
signal to wake up the source. |
|
|
|
:submit queue is empty: when the sink tries to obtain a packet via |
|
'get_packet'. The sink is going to block. If the source places a |
|
packet into an empty submit queue, it delivers a 'packet_avail' |
|
signal to wake up the sink. |
|
|
|
:acknowledgement queue is full: when the sink tries to acknowledge a packet |
|
using 'acknowledge_packet'. The sink is going to block until the source |
|
removes an acknowledged packet from the acknowledgement queue and delivers |
|
a 'ready_to_ack' signal. |
|
|
|
:acknowledgement queue is empty: when the source tries to obtain an |
|
acknowledged packet using 'get_acked_packet'. In this case, the source |
|
will block until the sink places another acknowledged packet into the |
|
empty acknowledgement queue and delivers a 'ack_avail' signal. |
|
|
|
These conditions can be avoided by querying the state of the submit and |
|
acknowledge buffers using the functions 'packet_avail', |
|
'ready_to_submit', 'ready_to_ack', and 'ack_avail'. |
|
|
|
If bidirectional data exchange between two processes is desired, two pairs |
|
of 'Packet_stream_source' and 'Packet_stream_sink' should be instantiated. |
|
|
|
|
|
NIC-session interface |
|
===================== |
|
|
|
The NIC session interface is the first application of our new packet stream |
|
facility. It allows executing network drivers as separate processes rather |
|
than linked against the network protocol stack. A NIC session consists of |
|
two packet streams, the transmission stream (TX) for sending packets and |
|
the reception stream (RX) for receiving packets. Furthermore, each NIC |
|
session comprises a simple RPC interface for requesting the MAC address of |
|
the network adaptor and for defining signal handlers for the signals TX |
|
ready-for-submit, TX acknowledgements-available, RX ready-to-ack, and RX |
|
packet-available. By default, those signals are handled by default signal |
|
handlers contained in blocking packet-stream functions. However, it is |
|
possible to override the data-flow handlers to implement semantics similar |
|
to the POSIX 'select' function, for example to wait for all possible |
|
signals of multiple NIC sessions using only a single blocking function. |
|
You can find the NIC-session interface as part of the 'os' repository |
|
at 'os/include/nic_session/'. |
|
|
|
|
|
Light-weight IP stack (lwIP) |
|
============================ |
|
|
|
Our port of the light-weight IP stack (lwIP) builds upon the foundation |
|
laid with the NIC-session interface. |
|
|
|
The following Figure illustrates the integration of a networking |
|
application with lwIP that uses the NIC-session interface as back end. |
|
|
|
[image lwip] |
|
|
|
The port of the lwIP stack resides in the new 'libports' repository |
|
described in Section [New libports repository]. It comes with |
|
two examples, a loopback demonstration and a minimalistic HTTP server. |
|
The examples are located at the 'libports' repository at 'src/test/lwip/'. |
|
The lwIP back-end acts as a client of the NIC-session interface. |
|
For the server counterpart, we added a DDE-Linux based stand-alone |
|
network driver for PCnet32 to the 'linux_drivers' repository. |
|
|
|
For starting the HTTP-server test on L4ka::Pistachio, OKL4, and L4/Fiasco, |
|
the following config file can be used: |
|
|
|
! <config> |
|
! <start> |
|
! <filename>timer</filename> |
|
! <ram_quota>512K</ram_quota> |
|
! </start> |
|
! <start> |
|
! <filename>pci_drv</filename> |
|
! <ram_quota>512K</ram_quota> |
|
! </start> |
|
! <start> |
|
! <filename>nic_drv</filename> |
|
! <ram_quota>512K</ram_quota> |
|
! </start> |
|
! <start> |
|
! <filename>lwip_httpsrv_test</filename> |
|
! <ram_quota>1M</ram_quota> |
|
! </start> |
|
! </config> |
|
|
|
For trying out the example with Qemu, please refer to the instructions |
|
given in the |
|
[http://genode.org/documentation/release-notes/9.02#section-4 - description] |
|
of the initial networking support added in Genode version 9.02. |
|
|
|
|
|
MMX-based 2D blitting library |
|
============================= |
|
|
|
Previous Genode releases already featured a 2D blitting library with a |
|
MMX-based optimization for x86_32. This optimization, however, was not enabled |
|
by default. Starting with the current release, several graphics-related parts |
|
of Genode will profit from our revisited version of this library, which is now |
|
enabled for both x86_32 and x86_64 by default. From this change, you can expect |
|
a definite performance boost of the Nitpicker GUI server and all |
|
Scout-widget-based applications such as the tutorial browser and launchpad. The |
|
library interface is located at 'os/include/blit/blit.h'. On architectures with |
|
no MMX, a generic implementation of the interface is used as fall back, which |
|
makes it safe to use the 'blit' interface for developing portable |
|
applications. |
|
|
|
|
|
Zero-footprint runtime for Ada/Spark |
|
==================================== |
|
|
|
At Genode Labs, we are exploring the use of the Spark subset of Ada to |
|
implement security-critical code and use Genode as development platform. |
|
For this reason, we have added support for executing freestanding Ada |
|
code on Genode. An example of the use of Ada on Genode can be found at |
|
'base/src/test/ada'. |
|
|
|
The program relies on the normal startup procedure of a Genode process. |
|
Execution starts at the 'crt0' assembly entry provided by the startup library. |
|
The 'crt0' code sets up the stack of the main thread and calls the '_main' |
|
function implemented in the C++ portion of Genode's startup library. In turn, |
|
the '_main' function calls 'main' of the actual program. The main function of |
|
this example calls the Ada main procedure. The test further exercises the call |
|
of C functions from Ada code. So the integration of Ada and C code is almost |
|
seamless. |
|
|
|
For building the Ada test program, you must have installed the GNU GNAT Ada |
|
compiler. Right now, we are using the host version of this compiler, which |
|
is save as long as we do not use advanced Ada features such as exceptions. |
|
To enable building the test program, add 'gnat' to the 'SPECS' declaration |
|
of your '<builddir>/etc/specs.conf'. Otherwise, the Genode build system |
|
will skip the target. |
|
|
|
Please note that the current version of this program does not use 'gnatbind'. |
|
Therefore, package elaboration is not executed. |
|
|
|
|
|
Misc improvements of OS-level services and libraries |
|
==================================================== |
|
|
|
:Init: |
|
|
|
Fixed quota-limitation problem in init. There was a race between the |
|
call of 'env()->ram_session()->avail_quota()' and already running children |
|
that donated quota via init to a server. During the quota transfer, child |
|
quota gets temporarily transferred to init to be further transferred to |
|
the server. In the worst case, such temporary quota was then assigned to |
|
the last child when limiting its quota to 'avail_quota()'. We solved this |
|
problem by deferring the start of child programs until all quota calculations |
|
are finished. |
|
|
|
:Nitpicker GUI server: |
|
|
|
Prevent superfluous screen updates when switching clicking on different |
|
views of the same session, making the GUI more responsive. |
|
|
|
|
|
New libports repository |
|
####################### |
|
|
|
With proper shared-library support in place and with our C runtime getting |
|
more and more mature, we feel an increased desire to port existing popular |
|
libraries to Genode. For this purpose, we have now introduced a dedicated |
|
source-code repository called 'libports'. Following the approach taken |
|
with our Qt4 porting effort, this repository does not contain actual source |
|
code but a mechanism to download upstream library source codes and adapting |
|
them to Genode. This way, we can easily keep track of the adaptions needed |
|
for Genode and update libraries to later versions. |
|
|
|
:Usage: |
|
|
|
At the root of the 'libports' repository, there is a 'Makefile' automating |
|
the task of downloading and preparing the library source codes. By just |
|
typing 'make', you get an overview of the available libraries and further |
|
instructions. |
|
|
|
In the common case, you might just want to prepare all libraries by issuing: |
|
! make prepare |
|
|
|
Alternatively, you can select one particular library to prepare by |
|
specifying the base name of a library (wihout the version number) as |
|
command-line argument: |
|
! make prepare LIB=freetype |
|
|
|
After having prepared the 'libports' repository, we are ready to include |
|
the repository into the build process by appending it to the 'REPOSITORIES' |
|
declaration of your '<build-dir>/etc/build.conf' file. |
|
|
|
:Under the hood: |
|
|
|
For each library, there is a file contained in the 'libports/ports/' |
|
subdirectory. The file is named after the library and contains the |
|
library-specific rules for downloading the source code and installing |
|
header files. |
|
|
|
For reference, we have included ports of *Freetype2* and *Jpeg*. Note that |
|
currently, these ports serve mainly the purpose of illustrating the use of the |
|
'libports' repository and are not thoroughly tested. However, we have |
|
successfully used them with Qt4. |
|
|
|
:How does 'libports' relate to the other repositories?: |
|
|
|
The 'libports' repository is meant as a place for porting popular libraries |
|
that usually expect a POSIX-like environment - similar to the environment |
|
provided by Genode's 'libc' repository. So 'libports' depends on 'libc' and, |
|
consequently, on the repositories 'libc' depends on, most specifically the 'os' |
|
repository. Because the dynamic linker is now a regular part of the 'os' |
|
repository, libraries contained in 'libports' can (and should) be built as |
|
shared libraries. |
|
|
|
|
|
Device drivers |
|
############## |
|
|
|
Device-driver environment |
|
========================= |
|
|
|
We steadily improve our device-driver environment for executing Linux drivers |
|
directly on Genode. For this release, we updated the Linux environment to the |
|
Linux kernel version 2.6.20.21, and improved several parts of the |
|
Linux-specific code, in particular the handling timers and tasklets. |
|
|
|
In the DDE Kit, we made the 'free()' function compatible with C99 (accepting a |
|
NULL pointer as argument) and fixed a memory leak. |
|
|
|
|
|
USB storage |
|
=========== |
|
|
|
We extended our USB stack with the driver infrastructure needed for |
|
accessing USB storage devices. The USB stack is ported from the Linux |
|
kernel using the Linux device-driver environment. Our Genode-specific |
|
support code consists of two parts: |
|
|
|
* We added emulation code for the Linux SCSI protocol layer as relied |
|
on by the Linux USB stack. The currently supported SCSI commands are INQUIRY, |
|
READ_10, WRITE_10, and READ_CAPACITY. Furthermore, we added a custom block |
|
interface at 'linux_drivers/include/dde_linux26/block.h', which still has a |
|
number of limitations (thread safe, synchronous, single block r/w requests |
|
only). |
|
* For the file-system layer, we ported the |
|
[http://elm-chan.org/fsw/ff/00index_e.html - FatFs R0.07e library] |
|
to Genode. This library allows us to access the directories and files of the |
|
FAT file system on the USB device. It has been ported using our new |
|
'libports' repository. |
|
|
|
The new USB storage support can be tested using a test program supplied with |
|
the 'linux_drivers' repository. It runs on all base platforms except on Linux. |
|
The source code of the test is located at |
|
'src/src/test/dde_linux26_usbstorage'. For compiling, you need to download the |
|
'libffat' first. From the 'libports' repository, you can issue: |
|
! make prepare LIB=ffat |
|
|
|
Furthermore, you must ensure that both the 'libports' and 'linux_drivers' |
|
repositories are specified in the 'REPOSITORIES' declaration in your |
|
'<builddir>/etc/build.conf' file. Because of the dependency of the USB-storage |
|
test from libffat, the program is not built by default until explicitely |
|
enabled by stating that 'libffat' is available. This must be done by extending |
|
the 'SPECS' variable in your '<builddir>/etc/specs.conf': |
|
! SPECS += libffat |
|
|
|
After these preparations, you can build the test program from your |
|
build directory: |
|
! make test/dde_linux26_usbstorage |
|
|
|
For executing the test, you need to specify Genode's 'timer' and 'pci_drv' |
|
alongside the 'test-dde_linux26_usbstorage' program. The test program |
|
will access an attached USB storage device, output the root directory |
|
content and load the first 16 bytes of the first file. You can try this |
|
out on Qemu by using a virtual USB storage device. First create a |
|
disk image with a FAT file system: |
|
! dd if=/dev/zero of=<usb-device-file> count=2048 |
|
! mkfs.vfat <usb-device-file> |
|
! mount -oloop <usb-device-file> <mount-dir> |
|
! cp <some data> <mount-dir> |
|
! umount <mount-dir> |
|
|
|
Then you can attach this disk image to Qemu using the arguments |
|
'-usb -usbdevice disk:<usb-device-file>'. |
|
|
|
|
|
PS/2 mouse and keyboard driver |
|
============================== |
|
|
|
We improved Genode's native PS/2 driver to be more robust against delays at |
|
startup. During the time after the startup of the PS/2 driver until a |
|
client connects, incoming input events used to fill up and eventually overflow |
|
the event queue. Now, we start sampling input events only after a client |
|
connects to the PS/2 driver. |
|
|
|
Furthermore, we have added support for the Intellimouse ImPS/2 and ExPS/2 |
|
protocol extensions to support mice with a vertical scroll wheel and |
|
5-button mouses. The improvement required no changes of the 'Input::Event' |
|
interface. Scroll-wheel events are reported as 'WHEEL' events with the wheel |
|
count delivered as 'ry' value. The buttons correspond to the key codes |
|
'BTN_LEFT', 'BTN_RIGHT', 'BTN_MIDDLE', 'BTN_SIDE', 'BTN_EXTRA'. |
|
|
|
Regarding the keyboard driver, we do not print messages on the occurrence of |
|
key-repeat events any longer. These messages tended to significantly slow down |
|
keyboard-based applications such as the OKLinux console. |
|
|
|
|
|
NIC driver implementing the NIC-session interface |
|
================================================= |
|
|
|
We added a new NIC driver using the Linux Device Driver Environment, which |
|
implements the server side of the new NIC-session interface described in |
|
Section [NIC-session interface]. The currently used Linux driver is 'pcnet' |
|
that is implemented in Qemu. Nevertheless, it should be straight forward to |
|
add other Linux network drivers the same way. |
|
|
|
|
|
Qt4 and Webkit |
|
############## |
|
|
|
We have extended our Qt4 port with Webkit support, which is one of the most |
|
complex components of Qt4. One particularly interesting point was the dependency |
|
of the JavaScript engine from the C++ standard template library. The Genode |
|
tool chain, however, already features the STL headers, which worked out nicely |
|
once we figured out a way to wrest the information about the STL header |
|
location from the compiler. |
|
|
|
Because Qt4 applications have exceedingly large binary sizes relying on static |
|
linking, we put Genode's newly available shared-library support to good use by |
|
declaring all Qt4 libraries as shared objects. This way, Qt4 applications have |
|
now become reasonably small. For example, the binary of the Tetrix example went |
|
from over 10MB down to about 600KB. |
|
|
|
Since the Genode release 9.11, Qt4 depends on the 'libports' repository, |
|
specifically on the 'freetype2' and 'jpeg' libraries. Please make sure |
|
that you called the top-level Makefile of the 'libports' repository |
|
for those preparing those libraries and that your 'REPOSITORIES' declaration |
|
contains the 'libports' repository. |
|
|
|
|
|
Applications |
|
############ |
|
|
|
Seamless Xvfb integration into Genode on Linux |
|
============================================== |
|
|
|
Xvfb is a virtual X server that uses a plain file as frame buffer instead of a |
|
physical screen. The 'xvfb' glue program makes an Xvfb session available to the |
|
Linux version of Genode such that both native Genode programs and X clients can |
|
run seamlessly integrated in one Nitpicker session. Using the 'xvfb' glue |
|
program contained in the 'os/src/app/xvfb' directory. Because Xvfb is executed |
|
as Nitpicker client, it is possible to integrate multiple instances of Xvfb |
|
into the same Nitpicker session. |
|
|
|
[image xvfb_screen] |
|
|
|
The scenario above uses two instances of Xvfb, which are displayed by the |
|
Nitpicker GUI server executed on Genode. Each Xvfb process is connected |
|
to Genode via a xvfb adaptor program, which is hybrid using both the Linux |
|
API (for accessing the virtual frame buffer and performing its role as |
|
X client) and the Genode API (for its role as Nitpicker client). |
|
|
|
[image xvfb] |
|
|
|
|
|
:Preconditions for compiling: |
|
|
|
The xvfb adaptor tracks dirty screen regions using the X damage extension |
|
and injects user-input events into the X server using the X test extension. |
|
So you need the development packages of both extensions to compile it. The |
|
Debian package for the X damage extension is called 'libxdamage-dev'. The |
|
X test extension is normally installed by default or resides in a package |
|
called 'libxtst-dev'. Furthermore you need to enhance your 'SPECS' declaration |
|
in your '<builddir>/etc/specs.conf' file as follows: |
|
|
|
! SPECS += x11 xdamage xtest |
|
|
|
|
|
:Usage: |
|
|
|
First start Xvfb using the following command-line arguments: |
|
|
|
! Xvfb :1 -fbdir /tmp -screen 0 1024x768x16 |
|
|
|
While Xvfb is running, '/tmp/Xvfb_screen0' will contain the content of the X |
|
server's frame buffer. This file must be specified for the 'xvfb' declaration |
|
in the config file. In addition, the display of X server instance must be |
|
declared via the 'display' tag. For example: |
|
|
|
! <config> |
|
! <display>:1</display> |
|
! <xvfb>/tmp/Xvfb_screen0</xvfb> |
|
! </config> |
|
|
|
|
|
:Known Limitations: |
|
|
|
* With the current version, some key codes are not mapped correctly. |
|
* The screen mode of Nitpicker and the Xvfb session must be the same. |
|
Only modes with 16bit color depth are supported. |
|
|
|
|
|
Backdrop application |
|
==================== |
|
|
|
For the Genode Live CD, we added a simple backdrop application to the 'demo' |
|
repository, residing in 'src/app/backdrop'. It uses libpng to display a PNG |
|
image as background of the Nitpicker GUI server. |
|
|
|
|
|
:Usage: |
|
|
|
You have to specify the name of the PNG file to be used as background |
|
image via a declaration in your config file: |
|
|
|
! <config> |
|
! <image>background.png</image> |
|
! </config> |
|
|
|
|
|
:Limitations: |
|
|
|
The PNG file is expected to be equal to the screen size. No scaling |
|
or tiling is supported. |
|
|
|
|
|
Extended configurability of native applications |
|
=============================================== |
|
|
|
:Launchpad: |
|
|
|
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 define the list |
|
manually by supplying a configuration to Launchpad. The following example |
|
configuration 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> |
|
! <launcher> |
|
! <filename>init</filename> |
|
! <ram_quota>10M</ram_quota> |
|
! <config> |
|
! <start> |
|
! <filename>hello</filename> |
|
! <ram_quota>1M</ram_quota> |
|
! </start> |
|
! </config> |
|
! </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. |
|
|
|
|
|
:Liquid frame buffer: |
|
|
|
Liquid frame buffer is an implementation of the frame buffer interface |
|
running as a client of the Nitpicker GUI server. It supports the |
|
following configuration options. The example shows the default |
|
values. |
|
|
|
! <config> |
|
! |
|
! <!-- enable the animated background, |
|
! valid values or 'on' and 'off' --> |
|
! <animate>on</animate> |
|
! |
|
! <!-- the initial window position and |
|
! size of the virtual frame buffer --> |
|
! <x>400</x> |
|
! <y>270</y> |
|
! <width>500</width> |
|
! <height>400</height> |
|
! |
|
! <!-- set the window title --> |
|
! <title>Liquid Framebuffer</title> |
|
! |
|
! </config> |
|
|
|
Because Liquid frame buffer creates the virtual frame-buffer window at |
|
start time, not at session-creation time, sufficient memory resources must |
|
be provided when starting the program. Consequently, the client does not |
|
need to donate memory for the frame buffer backing store. |
|
|
|
Liquid frame buffer supports only one client. If multiple virtual frame |
|
buffers are needed, multiple instances of the program should be used. |
|
|
|
|
|
Misc improvements of native applications |
|
======================================== |
|
|
|
* Fixed keyboard handling in Liquid FB, now all keyboard events are directed |
|
to the window content, which makes Liquid FB more appropriate for hosting |
|
an OKLinux console. |
|
|
|
* Replaced slow pixel copy code of the scout widget set with the MMX-based 2D |
|
blitting library and thereby improved the graphics performance of |
|
applications such as launchpad, liquid FB, and scout. |
|
|
|
* Defer creation of Nitpicker view to the first buffer refresh. This avoids |
|
artifacts when moving the mouse over designated view area during at the |
|
startup of a scout application. |
|
|
|
|
|
Platform-specific changes |
|
######################### |
|
|
|
:L4ka::Pistachio: |
|
|
|
We further extended our work regarding *write-combined access to I/O* memory |
|
to the L4ka::Pistachio base platform. So this platform can now also enjoy the |
|
performance boost that we experienced on the L4/Fiasco platform when enabling |
|
write-combined I/O for the frame buffer. |
|
|
|
|
|
:Linux: |
|
|
|
To enable the dynamic linker to work on Linux the same way as on the other |
|
platforms, we enhanced the Linux-specific *local region manager* to handle an |
|
optional local address and offset when attaching a dataspace. |
|
|
|
Thread destruction on Linux works asynchronous by a sending a signal |
|
via the 'tgkill' system call to the thread to be killed. Unfortunately, the |
|
Linux kernel delivers signals only in the kernel-entry path. This means that |
|
after calling 'tgkill', the to-be-killed thread still moves on until it enters |
|
the kernel (either by issuing a system call or when being preempted). This has |
|
the side effect that the thread continues to access its stack for a while. If |
|
killing a thread in the local address space and immediately freeing the stack |
|
of the killed thread by using the 'munmap' system call, the process would |
|
ultimately receive a segmentation fault. To solve this problem, we need to |
|
ensure that the to-be-killed thread is really not executing any instructions |
|
anymore before freeing the stack. We do this by repetitively issuing 'tgkill' |
|
for the thread until an EINVAL error is returned. |
|
|
|
|
|
:OKL4: |
|
|
|
We changed the serial output of core to use the OKL4 kernel debugger for |
|
printing the output of core instead of poking the comports directly. This way, |
|
the console is not anymore x86-specific but platform-independent. |
|
|
|
|
|
Build system |
|
############ |
|
|
|
* For debugging Genode applications using the GDB stub of Qemu, |
|
applications should use distinct virtual memory ranges. Otherwise, |
|
breakpoints set in one program would trigger when another program |
|
accesses the breakpointed virtual address. Therefore, we have |
|
introduced the 'LD_TEXT_ADDR' variable to the build system. |
|
A value assigned to this variable in a 'target.mk' file overrides |
|
the default link address. |
|
|
|
* The integration of dynamic linking support into the build system |
|
led to some architectural changes. Most importantly, the final linking stage |
|
is now performed by a separate 'make' instance executing 'base/mk/link.mk'. |
|
However, this change has no implications on the use of the build system. |
|
|
|
* Generate symbols for marking the end of binary data linked via the |
|
'SRC_BIN' mechanism. The start and end of binary data are marked by the |
|
symbols '_binary_<name>_start' and '_binary_<name>_end'. |
|
|
|
* Use 'AS_OPT' also for linking binary data, which is important to make |
|
the resulting object file always compatible with the compiled objects. |
|
This is important on architectures with non-unified calling conventions.
|
|
|