=============================================== Release notes for the Genode OS Framework 21.05 =============================================== Genode Labs The most prominent user-visible features of Genode 21.05 are the support for webcams and an easy-to-use component for file encryption on [https://genode.org/download/sculpt - Sculpt OS]. Both topics greatly benefit from Genode's component architecture. The video-conferencing scenario described in Section [Webcam support] sandboxes the webcam driver in a disposable Genode component while using a second instance of the nitpicker GUI server as a video bridge. This design strikes a beautiful combination of simplicity, robustness, and flexibility. The new file vault described in Section [File vault based on the CBE block encrypter] leverages Genode's dynamic sandboxing capabilities to manage the creation and operation of an encrypted file store. Even though the underpinnings can be described as nothing less than sophisticated machinery, the package presented to the user combines ease of use with a great sense of control. The second focus of the current release are the manifold improvements of Genode's driver and platform support as described in Sections [Device drivers] and [Platforms]. Our USB support received the attention needed to accommodate the webcam scenario, the arsenal of i.MX8 drivers got enriched with I2C and power-domain control, the Pine-A64 board support is growing, Genode has become able to run on 64-bit ARM Linux, and we enabled principle networking for RISC-V. Speaking of platforms, this release features the first version of a new "Genode Platforms" documentation (Section [Updated and new documentation]) that aids the porting of Genode to new ARM SoCs. With this document, we share our former in-house know-how and methodology about the porting and development of drivers with developers outside of Genode Labs. The release is rounded up by several performance optimizations (Section [Performance optimizations]) to the benefit of most Genode system scenarios. Furthermore, it is accompanied with an updated tool chain, following our established two-years rhythm (Section [Tool-chain update to GCC 10.3 and binutils 2.36]). Webcam support ############## During 2020, the amount of home office and remote work took an unexpected turn. Video conferences and video chats have become the norm, which people and companies rely upon. Even though, not to be found on our [https://genode.org/about/road-map - road map] for 2021, this development prompted the Genode team to explore the field of webcam and video chat support on Genode. Webcams are generally connected via USB to a host device and implement the USB video device class ([https://www.usb.org/sites/default/files/USB_Video_Class_1_5.zip - UVC spec]). Therefore, it is possible to drive many different webcam devices using the same USB interface. To support this protocol, we enabled [https://ken.tossell.net/libuvc/doc - libuvc], which offers fine-grained control over UVC exporting USB devices. In order to enable _libuvc_ on Genode, we simply integrated the library into Genode's port system with no further changes required. _libuvc_ depends on [https://libusb.info - libusb] as a back end to access the actual webcam device. While there exists a port of _libusb_ for Genode - that connects through Genode's USB session interface to the USB host controller - the port still lacked support for isochronous USB transfers as required by UVC devices. Isochronous transfers represent a continuous stream of data (either input or output) with a constant rate without delivery guarantees. We extended _libusb_ to handle isochronous transfers, which were already supported by Genode's USB session. Observing that this kind of transfers can cause high load within the USB host driver, we optimized isochronous transfer support at the host driver level (Section [USB]). At the front-end side, we created a small _usb_webcam_ component that uses _libuvc_ in order to enable, disable, and configure the camera. The component connects to a GUI session, and thus, can be interfaced directly, for example, to the Nitpicker component for rendering webcam images natively on screen. Whereas Genode's pixel format is 32 bit RGB, webcams stream data in the YUV2, MJPEG, or H.264 formats. To handle the conversion of these formats to Genode's pixel format, we utilize the [https://chromium.googlesource.com/libyuv/libyuv - libyuv] library and thereby support the YUV2 as well as the MJPEG pixel format for webcams. Additionally, we wanted to be able to transfer the webcam data directly into our VirtualBox port, thus enabling, sophisticated video conference systems like Jitsi or Skype. [image webcam] Our USB host-controller support for VirtualBox is based on the ported Qemu USB 3.0 (XHCI) controller model. Since no USB webcam device model is available for Qemu, we were required to develop a one from scratch. The new USB webcam model is attached to the QEMU USB XHCI controller and operates as a bulk endpoint. In contrast to an isochronous endpoint, the model causes less CPU load and fewer virtual interrupts. The supported formats offered to the guest are YUV2 and BGR3. By enabling the USB webcam model within the Genode VirtualBox configuration, a _Capture_ session is used to capture pictures at the rate of a configured _fps_ value. The following snippet shows the default values of the supported configuration attributes. ! ! ... ! ! ... ! If the _screen_size_ attribute is set to _true_, the device model determines the resolution from the established capture session. Otherwise, the specified _width_ and _height_ values are used. The _vertical_flip_ attribute is useful for the BGR3 format, which is - when interpreted by Linux guests - flipped vertically and can be flipped back by setting the attribute to _true_. If the _report_ attribute is set to _true_, a report will be generated whenever the guest changes the state of the webcam model, either by switching capturing on/off or by changing the pixel format. ! [image webcam_chat] Finally, our developers, croc and lion, setup the Webcam scenario in Sculpt and test drive the new feature fascinated. The picture shows a session via Jitsi, on the right side croc participates at the meeting via a Win10 VM on Sculpt and lion sitting left joined via an Android tablet. Performance optimizations ######################### One of the overarching topics of this year's [https://genode.org/about/road-map - roadmap] is optimization. As part of working on the Sculpt OS [https://genode.org/news/sculpt-os-21.03-boots-now-in-2.5-seconds - version 21.03], we identified several optimization vectors with the potential for user-visible improvements. In particular, while interacting with the system, a few effects made us curious. Operations that involved changes to the runtime subsystem, e.g., adding or reconfiguring a component, seemed to interfere with multi-media workloads. When running a graphical animation, we could see it stutter in such situations. Another direction of our curiosity was the boot time of the system. The boot time of Sculpt OS has always been relatively quick compared to commodity operating systems. E.g., on a 5-years old laptop like a Lenovo x260, the system used to boot in about 5 seconds to the graphical user interface. However, with the anticipation of Sculpt OS on lower-end platforms like the Pinephone and with the vision of instant-on systems, we wondered about the potential for improvement. While gathering a CPU-load profile of the boot process using the top tool, we learned that the boot time was bounded not by I/O but by the CPU load (the kernel's idle thread did not appear in the profile). Interestingly, a significant portion of the cycles were consumed by various instances of the init component, which prompted us to turn our attention to the implementation of init. Clock-cycle measurements ------------------------ The next natural step was the benchmarking of various code paths of init using a cycle-accurate time-stamp counter (TSC). Even though Genode has a 'Trace::timestamp' utility readily available, it remains barely used for manual instrumentation because such instrumentations require too much labor: allocation of state variables for gathering the statistics, computing time differences, traffic-shaping of the debug noise (needed whenever investigating highly frequently called code). These tasks should better be covered by a utility so that friction-less performance analysis can become a regular part of our development work. As a side effect of our investigation, we came up with a new utility called GENODE_LOG_TSC. This utility is covered by a dedicated article. :Performance analysis made easy: [https://genodians.org/nfeske/2021-04-07-performance] Thanks to GENODE_LOG_TSC, we were able to identify three concrete opportunities for optimization in a course of one evening. First, the dynamic reconfiguration of init apparently did not scale well with a growing number of components. The code for analysing differences of configuration versions relied on doubly nested loops in order to stay as simple as possible. With the typical number of 30 or more components/subsystems hosted in Sculpt's runtime, we passed a tipping point where quadratic time complexity is justifiable. Second, during a configuration update, the XML data is evaluated in multiple passes, which puts pressure on the efficiency of Genode's XML parser. This pressure could in principle be relieved. Third, the process of taking session-routing decisions involved XML parsing. In scenarios as sophisticated as Sculpt, the routing rules can become quite elaborate. Since the rules are consulted for each session route, the costs for the rule evaluations stack up. Init optimizations ------------------ These realizations motivated us to replace the hand-crafted configuration processing by the use of Genode's generic 'List_model' utility. This way, the parsing follows a common formalism that makes the code easier to maintain and to understand while reducing the XML parsing to a single pass. The increased formality cleared the way for further optimizations. In particular, init became able to skip the re-evaluation of the session routing whenever no service is affected by the configuration change. This is actually the common case in Sculpt. To alleviate the costs for evaluating session routes, we introduced an internal data model for the routing rules that is optimized for the matching of routes. With this model, the detection of a definite mismatch (the common case) comes down to a comparison of a single numeric value. Combined, those optimizations yield a great effect. In a typical Sculpt system, the time of a dynamic reconfiguration got reduced by factor 10 to the order of 10 to 20 milliseconds. Hence, the visual stuttering we observed during structural changes of the runtime are completely eliminated. Besides the major optimization of init, we were able to shave off a few milliseconds from the boot procedure here and there. For example, by deferring the initialization of the real-time clock driver to its first use, we avoid a potentially expensive active polling loop during the highly contended boot phase. Another obvious heuristic improvement is the skipping of the GUI handling until the framebuffer driver is up because all the nice pixels would not be visible anyway. Combined, these optimizations were able to reduce the boot time of Sculpt from the entering of the kernel up to the graphical user interface down to only 2.3 seconds. The improved performance of init is impactful beyond Sculpt OS because it is a central component of all Genode systems large and small. Updated and new documentation ############################# Genode Platforms ---------------- We are proud to introduce the first version of a new "Genode Platforms" document, which complements the existing Genode Foundations book with low-level hardware-related topics. It is primarily intended for integrators and developers of device drivers. :
:

:

: : : :
:

In this first edition, the document features a practical guide for the steps needed to bring Genode to a new ARM SoC. The content is based on the ongoing Pine Fun article series at [https://genodians.org - Genodians.org]. We plan to continuously extend it with further practical topics as we go. :Initial revision of the Genode Platforms document: [https://genode.org/documentation/genode-platforms-21-05.pdf] Genode Foundations ------------------ The "Genode Foundations" book received its annual update. It is available at the [https://genode.org] website as a PDF document and an online version. The most noteworthy additions and changes are: :
:

:

: : : :
:

* Adaptation to the re-stacked GUI stack introduced in [https://genode.org/documentation/release-notes/20.08#The_GUI_stack__restacked - version 20.08] * Coverage of the new uplink, capture, and event session interfaces * Updated API documentation :
To examine the changes in detail, please refer to the book's [https://github.com/nfeske/genode-manual/commits/master - revision history]. Base framework and OS-level infrastructure ########################################## API refinements =============== VFS-access utilities -------------------- Low-complexity native Genode components do not depend on a C runtime. To allow such components to still enjoy the power and flexibility of the Genode's VFS infrastructure, we provide an evolving front-end API [https://github.com/genodelabs/genode/blob/master/repos/os/include/os/vfs.h - os/vfs.h] first introduced in version [https://genode.org/documentation/release-notes/19.11#Virtual_file-system_infrastructure - 19.11]. The API is tailored and refined according to the relatively simple use cases of low-complexity Genode components. The current release introduces a new utility for the creation of new files, appropriately named 'New_file'. The change is accompanied by a new 'Directory::create_sub_directory' method for the easy creation of directory hierarchies. Safeguarded arrays ------------------ To handle arrays in a safe and C++-like fashion, a new helper class has become available at _base/include/util/array.h_. It accommodates an increasingly used pattern where elements are dynamically added at construction time but stay the same once the array is constructed. Cosmetic changes ---------------- We refined the 'Range_allocator::alloc_aligned' interface to make it more safe. The former 'from' and 'to' arguments are replaced by a single 'range' argument. The distinction of the use cases of regular allocations vs. address-constrained allocations is now covered by a dedicated overload instead of relying on a default argument. The 'align' argument has been changed from 'int' to 'unsigned' to be better compatible with 'addr_t' and 'size_t'. The 'Cache_attribute' type has been renamed to 'Cache'. Input-event handling ==================== A central component for Genode's input-event handling functionality is the event filter. It merges input events from multiple event sources and passes them to the event sink (typically the GUI server). In between, it performs low-level key remapping and applies character mapping rules. Character mapping rules are essential for supporting different keyboard layouts (including dead-key sequences). Low-level key remapping is, for instance, used for changing the emitted key codes of the Num Pad keys according to the Num Lock state. The different filter functionalities can be arbitrarily assembled into a filter chain and provided as a dynamic config ROM to the event filter component. The event sink then receives and processes the filtered events. Some input devices emit unusual and/or extra key codes in certain situations, which impedes the event sink's ability to detect key combos correctly. We therefore added the functionality to completely mute certain key codes. In order to ignore all unknown key codes for instance, we can now add an '' node to the config of the event filter. ! ! ! ... ! Note, that '' is part of the '' filter. The name attribute refers to the low-level key name before any remapping rule has been applied. As a second addition, we implemented a '' filter that allows low-level debugging of the event-filter component and its configuration. The '' filter can appear at each stage in the filter chain. For instance, we can log the input events before and after the remap filter as follows. ! ! ! ! ... ! ! ! The optional 'prefix' attribute thereby helps to distinguish the log output from different stages. File-system helpers =================== The [https://genode.org/documentation/release-notes/18.08#New_component_for_querying_information_from_a_file_system - fs_query] component is a simple helper to query information from a file system. E.g., it is used by the file browser of Sculpt OS to obtain the directory structure. The component received two welcomed improvements. First, directory content is now reported in alphabetic order. Thereby, all consumers of the reports become able to rely on deterministic output. For example, the file browser of Sculpt OS, the launcher menu items, and the depot-selection items will appear in a predictable way. Second, the size of files can be queried now. By adding an attribute 'size="yes"' to a query, fs_query is instructed to report the size of each queried file as attribute 'size' of the corresponding 'file' node. Whereas fs_query inspects a file system without changing it, its sister component fs_tool is able to perform file-system modifications. The new version adds a '' operation, which writes the content of the XML node into the file specified as 'path' attribute. The directory structure leading to the file is implicitly created if needed. Should a file with the specified name already exist, the original file will be overwritten. Applications ############ File vault based on the CBE block encrypter =========================================== Over several releases ([https://genode.org/documentation/release-notes/19.11#Preliminary_block-device_encrypter - 19.11], [https://genode.org/documentation/release-notes/20.05#Feature-completeness_of_the_consistent_block_encrypter - 20.05], [https://genode.org/documentation/release-notes/20.08#Consistent_Block_Encrypter - 20.08], [https://genode.org/documentation/release-notes/20.11#Consistent_Block_Encrypter__CBE_ - 20.11]), we persistently worked at a native solution for modern block encryption - the SPARK-based CBE-library - and its integration into Genode's VFS. Even though, this work was already suitable for real-world scenarios like [https://genodians.org/m-stein/2020-06-12-cbe-linux-vm - hosting a Linux VM on top of an encrypted block device], it still lacked stress-testing by a regular user base because its integration into an end-user system - like Sculpt - required tedious low-level wizardry. This situation had to change because we want to encourage as many people as possible to expose the codebase around the CBE to their workflows and let it mature. Therefore, we came up with a new package called file vault that can be readily deployed on Sculpt OS. It is a graphical front end that aims at making the creation, use, and maintenance of a CBE-based encrypted file store as intuitive and secure as possible. :Introducing the file vault: [https://genodians.org/m-stein/2021-05-17-introducing-the-file-vault] [image file_vault_setup] The file vault only requires two file-system sessions from you (the trust anchor is stored separately from the payload data). With that, it will automatically create and connect a trust anchor, set up a CBE image, prepare an ext2 FS on top of the CBE image and provide it through a file system service - ready to be used like a simple directory. The directory can be locked by closing the file vault and unlocked by starting the file vault on the same trust anchor and entering the correct user passphrase. All controls for the file vault's underlying CBE encrypter - like for its re-sizing and re-keying functionality - are presented through a simple and guiding UI that also provides you with the most relevant status information of your vault. The file vault package is accompanied by some notable improvements regarding CBE's key management. Whereas in the previous release, this aspect was still merely a prototype with almost no protective value, the current implementation embraces well-known algorithms to generate and encrypt the keys used within the CBE respectively the file vault. This is explained in detail in the aforementioned article. As a note of caution, the primary purpose of the current version of the file vault is to lift native block encryption in Genode from the development stage to product quality. At the current stage, it is neither time-tested nor reviewed by independent cryptography experts. Consequently, you should use it with a healthy dose of suspicion, for non-critical data only! We would be more than happy to receive feedback on your experience with the file vault. VirtualBox ========== Since the previous release, we continued the enablement of VirtualBox 6 on Genode and put efforts into stabilizing the port. Therefore, we updated to version 6.1.18 and reorganized the internal structure for a more comprehensible execution model with fewer threads. Further, we improved synchronization in multi-processor use cases and added a Sculpt runtime package for vbox6. Finally, as a little treat, our ports of VirtualBox now support to pass extra buttons of five-button mice to the guest. Device drivers ############## Platform driver on ARM ====================== The current release streamlines Genode's API for interacting with the platform driver on ARM platforms. It eases the access to memory-mapped I/O registers and interrupts by introducing the notions of :'Platform::Device': one device obtained from a platform session :'Platform::Device::Mmio': locally-mapped MMIO registers of a device :'Platform::Device::Irq': interface for receiving device interrupts The API is covered in detail by the following article. :One Platform driver to rule them all: [https://genodians.org/nfeske/2021-04-29-platform-driver] It goes without saying that this change touches most ARM-specific drivers. Closely related, we also revised the concept of the XML based device-info mechanism provided by the platform driver to accommodate both complex drivers operating on multiple devices simultaneously such as driver stacks ported from Linux as well as low-complexity drivers for simple devices. In the new version, the device XML-information dataspace is only provided if the client's session policy states 'info="yes"'. The format of the XML information got refined to include the physical resource names (I/O memory and IRQ addresses) instead of virtual IDs and page offsets and by using a 'type' attribute instead of a '' node to uniquely identify devices. Changes specific to i.MX8 ------------------------- The platform driver incarnation specific to i.MX8 got slightly improved. It can handle the configuration of reset-pins now. Analogously to the already existent power domains, one can assign reset domains per device. Whenever a device with a reset domain gets acquired, its reset-pins are de-asserted. When the device gets released again, its reset-pins are asserted to put it into reset state. A sample configuration looks as follows: ! ! ... ! Technically, those reset domains map to pin settings of the System Reset Controller (SRC) that is part of the i.MX8 SoC. The SRC is under control of the platform driver now. Currently, only the pins for the MIPI DSI Phy get exported. They are used by the graphical subsystem to handle panels connected via MIPI DSI. I2C driver for i.MX8 ==================== Thanks to Jean-Adrien Domage from [https://www.gapfruit.com - gapfruit], an API for I2C bus transactions and a new I2C bus driver for the i.MX8 SoC entered our framework. Coincidentally, the need to use the new I2C API more intensively arose soon after his initial contribution. As a consequence, the API got extended a bit. The result is a nice joint venture, and looks like the following: ! void transmit(Transaction & t); Hereby a 'Transaction' is a simple array of 'Message' objects, and a 'Message' is an array of bytes that are either read or written. For very simple use-cases, e.g., a client that polls single bytes from a temperature sensor, some convenience utilities are incorporated into the 'I2c::Connection'. USB === The USB-driver system has received quite a few refinements, performance improvements, and robustness handling efforts during the current release cycle. The HID subsystem is now capable of handling devices where the HID USB interface is at an arbitrary location within the device descriptors - as opposed to the assumption that the HID interface is always at the first position in the interface list of the device. Also, the HID driver now handles session destruction more gracefully and supports unlimited plug and unplug events of an associated HID device. For the USB host driver, various fixes of newer Linux kernel versions have been back ported, which concern the handling of DMA memory. Error code and timeout handling have been improved in order to support more corner cases, and the USB session handles outstanding USB requests (synchronous and asynchronous) on sudden session disconnects gracefully now. The CPU usage of the host driver for isochronous transfers has been reduced significantly for Intel XHCI controllers by adding a fix that reduces the triggering of an interrupt for every completed isochronous packet to one interrupt per eight packets, bringing the worst case scenario down to 1000 interrupts per second from a possible 8000 IRQs before. NIC drivers =========== Drivers for iPXE-supported Ethernet devices, Wifi adapters, and Linux TAP devices now support the reporting of the MAC address of detected adapters. The feature can be enabled by a '' node in the driver configuration as follows, prompting the driver to request a report session with the label _devices_. ! ! ! The resulting report is depicted below. ! ! ! Platforms ######### Genode/Linux on 64-bit ARM ========================== The release introduces the support for running the Linux version of Genode on 64-bit ARM platforms. As a part of this line of work, Genode's system call bindings for Linux underwent a modernization to harmonize the system calls across the supported CPU architectures. Furthermore, we took the opportunity to simplify the use of the clone system call by eliminating the need for passing a TLS pointer. Expecting that the 64-bit Genode/Linux version will remain a niche use case of Genode in the foreseeable future, we do not provide a pre-built tool chain. Hence, as a preparatory step for using this version of Genode, the tool chain must be built manually via Genode's _tool/tool_chain_ script. As a known limitation, Genode's 'Trace::timestamp' function is not available on this version of Genode because Linux prevents the user land from accessing the cycle counter (pmccntr_el0). So the accuracy of timing is somewhat impeded to the order of milliseconds. Also, the jitterentropy random-number generator cannot be used. Those limitations notwithstanding, one can successfully execute scenarios as complex as _leitzentrale.run_. When using AARCH64 Linux as host, run scripts can be executed with the same convenience as on Linux on a PC. ! $ make run/