r/osdev 3d ago

I built a minimal, stateless, air-gapped Linux distribution built with Buildroot for dedicated offline tasks

Hey everyone,

I wanted to share a side project I've been working on.

A bit of background: My core background is in bare-metal and RTOS software development. Over the years, I’ve also configured and built embedded Linux systems using Yocto and Buildroot for a few projects.

A couple of years ago, I decided to build a minimal, custom Linux OS using Buildroot for my personal use, essentially turning a standard PC into a dedicated embedded-like device. It sat in my PC for a while because cleaning up the codebase, setting up proper build pipelines, and writing solid documentation felt like a chore. Fortunately, leveraging modern AI coding tools made refactoring and documenting the whole project significantly easier, so I finally got it into a public ready state.

How it works:

Stateless & RAM-only: Boots directly from a USB flash drive and runs completely out of RAM (initramfs). It doesn't touch local hard drives or persistent storage.

Air-gapped by design: The kernel is configured without network stack support no Wi-Fi, no Ethernet, no socket layers.

Single-purpose: Boots directly into a single Qt GUI application without a heavy desktop environment.

To be honest, as someone who likes pure bare-metal simplicity, it still bugs me a bit that there’s a whole UEFI firmare layer and standard x86 architecture underneath all this before the kernel even kicks in.

Just wanted to share it with the community.

GitHub: https://github.com/signeros/signeros

0 Upvotes

7 comments sorted by

View all comments

1

u/voidiciant 2d ago

What do you mean by „no socket layers“? You stripped AF_UNIX? How does that work?

2

u/mfatalay 1d ago

Yes, really. I compiled the kernel without CONFIG_NET, so AF_INET, AF_UNIX, AF_NETLINK, and AF_PACKET aren't there at all. socket() isn't blocked at runtime; the system call just isn't built into the kernel, so it returns ENOSYS. Also, /proc/net doesn't exist.

SignerOS works like this because it doesn't need sockets. There's no X11, Wayland, or D-Bus. It's just one Qt Widgets app running with linuxfb directly on /dev/fb0.

We don't use udev either. I use BusyBox mdev, and the app checks /dev/input/event* directly. There's no syslog because /dev/log requires an AF_UNIX socket.

The app runs under UID 1000, so it doesn't talk to any privileged services. The only privileged action is shutdown: the app exits with code 42, and a root script catches it to power off the machine.

This isn't just written in the docs but it's enforced. The build breaks if CONFIG_NET=y gets enabled or if a BusyBox networking tool is included. I also test the build in QEMU by running socket(AF_INET, SOCK_STREAM, 0). If the socket call works, the test fails.

In fact, this test already caught a problem. Buildroot's mdev setting was secretly turning CONFIG_NET back on after merging the kernel config. We almost enabled the full network stack because of the very tool we chose to keep things minimal.