Towards Truly Embedded Linux


As Linux is increasingly popular in the field of embedded applications, it is time to rethink the core structure of the Linux operating system. In particular, switching from the Unix multi-user paradigm to something tuned for embedded applications could increase reliability and security in Embedded Linux applications.

The Embedded Space

Embedded programming used to be the field of micro controllers. Micro controllers are tiny systems that combine a basic CPU together with memory and IO. These micro controllers do not run any sophisticated operating system. Rather they are programmed to run bare metal code, maybe with a small runtime that schedules concurrent tasks.

But the times they are a-changin’. Nowadays, systems on a chip (SoC) are becoming increasingly cheap. While they also combine CPU, IO and sometimes memory, a SoC-based system typically runs a full operating system. In practice, Linux is number one choice as it boasts great compatibility and an unmatched number of features. With Embedded Linux, we get a world class IP stack and address space separation. Even better, writing applications for an Embedded Linux platform is almost the same as writing for a desktop as the programming and runtime environments are the same.

Unix is a Bad Match for Embedded

Linux is essentially a modern Unix clone, but Unix was never made with embedded applications in mind. Rather Unix is a multi-user system that above all is flexible. Users can log on to a Unix system, run, write and compile programs. The workload today can be totally different to the workload tomorrow.

Compare that to a typical embedded application. In embedded systems, we already know what applications will be run ahead of time. Often we know exactly which components communicate with each other and we know which components need to connect to the internet. Most importantly, this configuration hardly ever changes. The only big change arrives when the system is upgraded. But in embedded applications, it is common to ship a complete system image with each upgrade. So a given system image does not change aside from some volatile information (think user configuration).

Separate Applications

Despite providing a completely different service, Embedded Linux still runs on the core principles of Unix. In particular, applications and services get started with /sbin/init. Per default, all processes can read a good chunk of the file system and do communication with the internet.

What I propose is an alternative init system for Embedded Linux. A static init system for embedded applications that has a hard-coded set of services and applications it launches. Even more, this hypothetical embedded init system would greatly restrict the access to system resources for each individual service. Similar to how Linux containers can restrict the access of applications on servers, a similar approach could be very fruitful for embedded applications. Per default, each and every service has access to nothing. Developers would only enable those permissions necessary for the respective service.

Surely, such a controlled approach to embedded development would greatly reduce the complexity of embedded applications. This results in easier to test and develop applications. It is also a big plus for security. If only a subset of all available services can access the network, only those particular processes provide a direct attack surface.

Running small multi-user Unix machines as part of our washing machines and coffee makers might be the current state of the art. But we can probably do better. I believe the key to success is not so much the kernel. It is the init system that makes the difference.