summaryrefslogtreecommitdiffstats
path: root/_posts/2017-05-05-Building-a-real-Linux-distro.md
blob: 71166cb9a6acd0d383f1f73f9e2f10549deaf823 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
---
layout: post
title: Building a "real" Linux distro
tags: [linux]
---

I recently saw a post on Hacker News: "[Build yourself a
Linux](https://github.com/MichielDerhaeg/build-linux)", a cool project
that guides you through building a simple Linux system. It's similar to Linux
from Scratch in that it helps you build a simple Linux system for personal use.
I'd like to supplement this with some insight into my experience with a more
difficult task: building a full blown Linux distribution. The result is
[agunix](http://agunix.org), the "silver unix" system.

For many years I've been frustrated with every distribution I've tried. Many of
them have compelling features and design, but there's always a catch. The
popular distros are stable and portable, but cons include bloat, frequent use of
GNU, systemd, and often apt. Some more niche distros generally have good points
but often have some combination of GNU, an init system I don't like, poor docs,
dynamic linking, or an overall amateurish or incomplete design. Many of them are
tolerable, but none have completely aligned with my desires.

I've also looked at not-Linux - I have plenty of beefs with the Linux kernel. I
like the BSD kernels, but I dislike the userspaces (though NetBSD is pretty good)
I like the microkernel design of Minix, but it's too unstable and has shit
hardware support. plan9/9front has the most elegant kernel and userspace design
ever made, but it's not POSIX and has shit hardware support. Though none of
these userspaces are for me, I intend to attempt a port of the agunix userspace
to all of their kernels at some point (a KFreeBSD port is underway).

After trying a great number of distros and coming away with a kind of
dissatisfaction unique to each one, I resolved to make a distro that embodied my
own principles about userspace design. It turns out this is a ton of work -
here's how it's done.

Let's distinguish a Linux "system" from a Linux "distribution". A Linux system
is anything that boots up from the Linux kernel. A Linux *distribution*, on the
other hand, is a Linux system that can be *distributed* to end users.  It's this
sort of system that I wanted to build. In my opinion, there are two core
requirements for a Linux system to become a Linux distribution:

1. It has a package manager (or some other way of staying up to date)
2. It is self-hosting (it can compile itself and all of the infrastructure runs
   on it)

The first order of business in creating a Linux distro is to fulfill these two
requirements. Getting to this stage is called *bootstrapping* your distribution -
everything else can come later. To do this, you'll need to port your package
manager to your current system, and start building the base packages with it.
If your new distro doesn't use the same architecture or libc as your current
system, you also need to build a cross compiler and use it for building your
new packages.

My initial approach was different - I used my cross compiler to fill up a chroot
with software without using my package manager, hoping to later bootstrap from
it. I used this approach on my first 3 attempts before deciding to make
base packages on the host system instead. With this approach, I started by
building packages that weren't necessarily self hosting - they used the
host-specific cross compiler builds and such - but produced working packages for
the new environment. I built packages for:

* my package manager
* musl libc
* bash
* busybox
* autotools
* make
* gcc (clang can't compile the Linux kernel)
* vim

I also had to package all of the dependencies for these. Once I had a system
that was reasonably capable of compiling arbitrary software, I transferred my
PKGBUILDs (scripts used to build packages) to my chroot and started tweaking
them to re-build packages from the new distro itself. This process took months to
get completely right - there are *tons* of edge cases and corner cases. Simply
getting this software to run in a new Linux system is only moderately difficult -
getting a system that can build itself is *much harder*. I was successful on
my 4th attempt, but threw it out and redid it to get a cleaner distribution with
the benefit of hindsight. This became agunix.

Once you reach this stage you can go ham on making packages for your system. The
next step for me was graduating from a chroot to dedicated hardware. I built out
an init system with runit and [agunix-init](http://git.agunix.org/init/) and
various other packages that are useful on a proper install. I also compiled a
kernel without support for loadable modules (on par with the static linking theme
of agunix). If you make your own Linux distribution you will probably have to
figure out modules yourself, likely implicating something like eudev.
Eventually, I was able to get agunix [running on my
laptop](https://sr.ht/OzCq.jpg), which has now become my primary agunix dev
machine (often via SSH from my dev desktop).

The next stage for me was getting agunix.org up and running on agunix. I
deliberately chose not to have a website until it could be hosted on agunix
itself. I deployed agunix to a VPS, then ported nginx and put the website up.
The rest of the infrastructure was a bit more difficult: cgit took me about 10
packages of work, and bugzilla was about 100 packages of work. Haven't started
working on mailman yet.

Then begins the eternal packaging phase. At this point you've successfully made
a Linux distribution, and now you just need to fill it with packages. This takes
*forever*. I have made 407 packages to date and I still don't have a desktop to
show for it (I'm *almost* there, just have to make a few dozen more packages
before [sway](https://github.com/SirCmpwn/sway) will run). At this point to have
success you need others to buy into your ideas and start contributing - it's
impossible to package everything yourself. Speaking of which, check out
[agunix.org](http://agunix.org) and see if you like it! I haven't been doing
much marketing for this distro yet, but I do have a little bit of help. If
you're interested in contributing in a new distro, we have lots of work for you
to do!