D4.6/views/build.md

5.9 KiB

DECODE OS builds and hardware integration

The DECODE operating system is built in a number of stages: this process is detailed in D4.4 and will be briefly documented here.

This section outlines how to build DECODE OS for our DECODE HUB hardware target architecture which is the hard-float ARM (armhf). For the purpose we adopted the Devuan Ascii (2.0.0) armhf port.

Each build stages illustrated below is independent from each other and can be triggered on its own; however the final stage requires the results from the previous ones to be able to integrate them together.

Userspace

The first stage built is the actual userspace, where the system is bootstraped from scratch, and packages and configurations are added on top of it. This is the step most extensively described in D4.4. The tools we use to build our userspace are made available in the git repository. These tools are a higher-level abstraction on top of Devuan's Arm-SDK, which is the way ARM-based images are created in Devuan. The port of Devuan to ARM has gathered an active community that can be also reached on the Freenode IRC channel #devuan-arm.

The process of building via the Devuan SDK is abstracted using a concept called blends: it offers us a more high-level approach to configuring a base system after it has been bootstrapped. Using this blend, we are able to easily and reproducibly install various software - from the init system (OpenRC), to the very final userspace tools needed for DECODE like Chainspace and the JVM, tor-dam and Golang for more applications.

Along with installing software, the blends allow us to provide file overlays, which enable us to have a directory structure that resembles the bootstrapped system, and use the overlay to reconfigure any existing files. Finally, it also gives us a space where we can mark certain binaries with needed flags that are used in the kernelspace.

Kernelspace

The ARM kernelspace consists of mainline Linux (official kernel.org) releases (version 4.9.y) which in the special case of DECODE OS requirements for integrity and security of the system we patch with the unofficial grsecurity patch that is maintained for this very kernel version. It is maintained at and (unlike x86) does not suffer from the recent Meltdown and Spectre attacks (CVE-2017-5715, CVE-2017-5753, and CVE-2017-5754) while this does not apply for all ARM processors.

The tools used for building this stage are packed into a single git repository which is a suite of makefiles that contain deterministic rules for building the Linux kernel, the initramfs, and finally packs the results into a tarball, and a ready-to-flash raw image - both of which can be used and put onto a microSD card to be used with the Olimex OLinuXino LIME2. This suite can be found at the DECODE project's Github:

Roundshot is in fact a new software product part of this DECODE deliverable, to provide a seamless and minimalist way to distribute signed updates of the DECODE OS to all running nodes, with the only need to reboot them in order to activate the updates. Roundshot is engineered with minimalism in mind and consists only of a set of declarative scripts (GNU Makefile) to pack a new system ramdisk that will operate the update.

Cross-toolchain and initramfs

When ran, Roundshot will first build a musl-based GCC toolchain which can crosscompile and statically link armhf binaries for us. Static compilation is adopted in many critical parts of DECODE OS infrastructure also to keep integrity with the privilege escalation model "sup" that is described in DECODE's whitepaper.

The adoption of musl-libc is useful for having a static initramfs, and smaller binaries than what the GNU libc provides.

The ramdisk (initramfs) consists of busybox, btrfs tools, and gnupg, which provide tools necessary for fetching our over-the-air updates to the DECODE operating system. It also contains the logic of setting up the system to boot into the actual userspace that was built in another stage.

The Linux kernel

After finishing the initramfs, the makefile suite will continue with fetching Linux sources and the patches, applying them, and compiling the Linux kernel and the necessary device tree that ARM boards need to define their hardware. These device trees are used by the u-boot bootloader which is explained further on.

The squashfs

The squashfs is the fourth phase of Roundshot, which takes the userspace we have bootstrapped and configured and compresses it into a read-only squashfs file. This very file can be rebuilt and is used when updates are shipped. If an update is available, this file is replaced in-place on the machine which has downloaded the update after rebooting.

On the actual hardware, this squashfs is configured and set up through the logic found in our initramfs. The squashfs also contains the kernel modules that were built in the previous phase. The modules are not needed inside the initramfs.

The bootloader

The Olimex Lime2 - much like all other ARM SoCs - uses the u-boot bootloader. Luckily, in the case of Lime2, we don't require any proprietary blobs or firmware and we can utilize explicitly libre software here. u-boot is built using the musl-libc cross-toolchain as well, and is flashed on the microSD card. The device tree file that we compiled with Linux sources is read by u-boot at the boot stage, along with boot.scr which is a u-boot boot script which contains the necessary information of what partitions/devices the dtb, the kernel, and the initramfs can be found on.

Finally, when all of this is finished, the results are packed and compressed into a tar.gz file, and a raw .img file. These files are used for initial distribution and are to be flashed on microSD cards.