I've gotten into the habit of using some new technology I found to bulid things I might need, resulting in stuff like phoebeflora, and evernight. This post is about yet another one of those things: Aemeath OS.

Aemeath OS is an experimental immutable Linux distribution with KDE Plasma as the desktop environment. System updates are image-based using an A/B update scheme, while applications are installed using Flatpak.

In this post, I wanted to talk about the motivations behind Aemeath OS, and how it was built.

It started with the Raptor

Evernight was a Linux image based on Fedora Kinoite, built using Universal Blue's image template. Because of that, I somewhat follow news happening on Universal Blue projects, and this is where I read Bluefin's State of the Raptor blog post. In that post, they talked about their distroless future, building an image based on GNOME OS

Distroless Bluefin, from Bluefin's 2025 State of the Raptor blog post.

GNOME OS itself is built in a quite interesting way. Using a tool called BuildStream, the components are built from source and then assembled into various forms, like a Flatpak runtime or an operating system image. With this way of building, there are no package managers on the final system, which makes it more similar to a "distribution" like Linux from Scratch. Well, a  Linux From Scratch that is much easier to build. This approach is sometimes also called "distroless", like distroless container images, since the OS only contains the essential components for the experience it delivers, which in the case of GNOME OS, is the GNOME desktop.

My previous daily driver was the aforementioned Evernight image, which is basically just Fedora Kinoite plus a few additions. However, I wanted a system where I can build exactly what I needed, and I quite like the approach GNOME OS uses. However, as Evernight uses KDE Plasma as the desktop, I started to wonder, can I use BuildStream to make a Linux operating system image with KDE Plasma as the desktop?

The answer, as it turns out, is yes, and it's surprisingly not that hard.

Prior Art

Freedesktop SDK

The Freedesktop SDK website

You might be familiar with the Freedesktop SDK, which provides the runtime used by most Flatpak applications. Well, you can do more than just Flatpak runtimes with it! It's also possible to build container images and even entire operating systems using the Freedesktop SDK. Both GNOME OS and the GNOME Flatpak runtime are built on top of it.

Aemeath OS also uses Freedesktop SDK as a base, which provides components like the toolchain, base system utilities, or even the Linux kernel.

GNOME OS

GNOME OS website

GNOME OS is probably the main example of an operating system built using BuildStream and Freedesktop SDK. It adds the necessary components on top of the Freedesktop runtime so it can run the GNOME desktop. Those same components are also used to build their Flatpak runtime too! 

GNOME and KDE Plasma shares some dependencies, so I imported a few components from GNOME OS into Aemeath OS. However, since GNOME OS ships GNOME components straight from the main branch, I have to change out some of the components to use the ones from Freedesktop SDK instead.

The building of Aemeath OS

First, I need to make sure I can make a disk image I can boot into at all. For this, I followed how Freedesktop SDK built their disk image for VM. I actually used the secure-boot image template... but removing the secure boot, since I wanted to figure that out later.

After I got to a bootable image, I began packaging Qt up. For this, I referenced the Flatpak KDE Runtime for specific build instructions, while for defining dependencies, I look into how Arch Linux does their packaging, since that's what I'm most familiar with. If there's a dependency I need, I first look it up in Freedesktop SDK, then GNOME OS if it doesn't exist there. If it wasn't found there, well, then I package it myself. I had to slightly alter the build instructions, since following the KDE runtime results in Qt also installing files to /usr/lib/modules... which breaks building the bootable image.

After I was done with Qt, I continued with Frameworks. The amount of libraries in Frameworks is astoundingly many, and most of them builds the same way, so packaging them is easy... the hard part is actually the dependencies, for which I followed the same method I used for Qt.

After I finished with Qt and Frameworks, I began working towards packaging the actual desktop environment itself: KDE Plasma. For the bulid instructions, I turned to Beyond Linux From Scratch... which I realized, like Frameworks, mostly builds the same way, so it's more of doing the same thing again and again. However, this is where I start to get into funny problems while going towards a functional Plasma desktop:

  • Freedesktop SDK does not ship with dbus-daemon-launch-helper. While GNOME goes all in with systemd units, KDE Plasma does not, and it resulted in a very, very frustrating debugging session where Plasma takes a very long time to start up, before I finally found the cause. I had to rebuild the binary manually, using the Freedesktop SDK as a reference.
  • KDE Wallet not unlocking automatically when using password login. As it turns out, order is important when defining PAM configurations!
  • The systemd version (257) used in the latest stable Freedesktop SDK doesn't detect ZSTD-compressed files when systemd-sysupdate pulls update images, so it simply wrote the compressed image as-is. Oops. It also does not build sysupdated, which is used by Plasma Discover to update the OS itself. GNOME OS solves this by... simply rebuilding systemd with the latest version. I'm not too interested in this for reasons.
  • A non-standard OpenGL and Vulkan installation locations, causing games to not run at first. After another debugging session, I realized that I need to add those directories to XDG_CONFIG_DIRS! My games ran only after adding the directories.

After all that, though, I finally got a running system!

A screenshot of one of the earliest bootables Aemeath OS disk images

The status quo

Right now, Aemeath OS is able to boot to a pretty usable Plasma Desktop, Flatpak runs well, and I can even game on it using Steam and Proton! 

Wuthering Waves running in Aemeath OS using Proton

Updating the system works using systemd-sysupdate, and it evens works from the Discover application as well! However, installing it in the first place requires replacing the entire disk, since it utilizes systemd-repart, and there are currently no pretty installers in the image yet. 

Afterword

Building Aemeath OS is surprisingly not that hard. It only took a weekend for it to boot to desktop, and a few days after that to replace my previous daily driver image, Evernight!

In the midst of all this, one day, I woke up to a pull request made to the repository. nisel11 had somehow found the Aemeath OS repository, and helped with packaging and important cleanups. Thanks a lot for the help! 

As for next steps, I'm currently looking into how to make it easier to install, using software like Calamares, a popular Qt-based installer software.

Aemeath OS can be downloaded from the releases page. Installation currently requires wiping the entire disk, so I recommend to try it out on a VM with 3D acceleration enabled, to prevent your real data from being eaten by the Threnodian.

arrow_back

Previous post

Music Highlights: Melody of Character

More in Technology
Builiding My Own Immutable Linux Distribution
Technology

Builiding My Own Immutable Linux Distribution

This post talks about Aemeath OS, an immutable Linux distribution with KDE Plasma.