Making minimal graphical operating system

Back in my first days of Linux I had a bootable floppy disk with fully functional Linux distro (a kernel, a shell and busybox tools and lua scripting). Maybe that was not much, but it was less than 2MB and would work on an old 386 PC with 4MB of RAM. But shell is boring, graphical minimal Linux distros was several hundreds of mega bytes and need hundreds of MB of RAM.

Embedded devices typically have a minimal Linux with busybox or alike running with no graphical interface but instead they have some sort of web interface exposed to some port.

If you tried to run a minimal graphical Linux distro let's say XFCE on an embedded device (let's say a raspberry pi) you would notice that most of its limited resources are taken by Xorg the legacy graphical server.

Introducing Wayland

Wayland is a new different approach to graphical interface, instead of sending drawing instruction over a legacy protocol (with so many extensions) to a legacy daemon (with so many extensions) that most of it is irrelevant to what apps want. With wayland, applications are given a region to draw in, the wayland protocol does not deal with drawing instructions, it just expect a region to be passed to the kernel driver (possible via DRM/DRI or framebuffer). So we have a graphical application on one end, talking using wayland protocol, on the other end of this communication is what they call a compositor, which is a simple do-nothing middle man that have one role which is to pass those regions from all applications to the kernel or whatever backend (possibly another thing speaking wayland or an X server or some remote server ..etc.).

There is a reference wayland compositor called weston (under freedesktop.org) which is very small and order of magnitude smaller compared to Xorg. And include some demo wayland applications. Weston is also a library if you want to build your own. There is also WLC and SWC.

Getting a minimal OS base

I'm going to build this toy minimal graphical OS on a virtual machine, let's start by downloading a minimal fedora QCOW2 image which is ~200MB. You can boot this image using boxes or virt-manager (like me) or qemu-kvm command line or you can download the VirtualBox version from the same page.

Beside being my distro of choice, the best in wayland, Fedora is open for recompose as their Release Engineering document says "At any time anyone should be able to see how Fedora is put together and put together their own version of Fedora." You can learn how they make it, and make your own.

Fedora is sooooo secure, and this QCOW2 image does not have default password, nor any way to access it, it was designed so that initial access is made using IaaS like openstack. To inject our initial access we need to either use "libguestfs-tools" or create a "cloud-init" iso similar to this article

mkdir cloud-init
echo -e "instance-id: vm1\nlocal-hostname: vm1" > cloud-init/meta-data
cat <cloud-init/user-data
#cloud-config
password: 123456789
chpasswd: {expire: False}
ssh_pwauth: True
ssh_authorized_keys:
  - ssh-rsa GOES_HERE....
chpasswd:
  list: |
     root:123456789
EOF
genisoimage -output cloud-init.iso -volid cidata -joliet -rock user-data meta-data

And when you boot your fedora image make sure you include this iso with it.

After booting fedora, disable SELinux in the guest by typing "setenforce 0" and make that permanent by editing "/etc/selinux/config"

Adding the minimal graphical UI

You can tell DNF to only install just needing things "--setopt install_weak_deps=false" and you can tell it to skip documentation using "--setopt tsflags=nodocs". So let's just add weston

dnf install --setopt install_weak_deps=false weston

This would be able to start a sluggish  framebuffer GUI by typing

weston-launch -- -B fbdev-backend.so

Let's kill weston and add modern accelerated drivers 

dnf install --setopt install_weak_deps=false weston mesa-dri-drivers

Now let's start Weston without adding any options just "weston-launch" or specifying that we want DRM/DRI drivers like this

weston-launch -- -B drm-backend.so

and here is the result, as you can see it barely uses 85MB or RAM


Adding some applications

On my host fedora I compiled hello_wayland and copied the binary and the images.bin over scp to the VM and from wayland-terminal I run "./hello_wayland &"



I've also compiled other demo application found in clients directory in weston git repo like
  • weston-flower
  • weston-smoke
  • weston-simple-egl
  • weston-simple-shm



Adding a window manager

There is a window manager that supports wayland that looks and acts similar to i3 (the tiling window manager) called sway

dnf install --setopt install_weak_deps=false sway

and using "vi /etc/sway/config" I added a way to launch weston-terminal by adding

bindsym Mod1+r exec /bin/weston-terminal

Now you can launch sway then press Alt+R to start a terminal


Going further

Gtk+ version 3+ supports wayland, and Qt5 also, so in theory you could have add such apps without pulling X server. A package "qt5-qtwayland-examples" have some source codes and binaries, install that package using
dnf install --setopt install_weak_deps=false qt5-qtwayland-examples 

the run one of the example like this

/usr/lib64/qt5/examples/wayland/pure-qml/pure-qml



Alpine Linux also include weston, so you might be able to have even smaller base.

Comments

Popular posts from this blog

How to defuse XZ Backdoor (or alike) in SSH Daemon

Bootstrapping Alpine Linux QCow2 image