title: The Full-Source Bootstrap: Building from source all the way down
date: 2023-04-26 16:00
author: Janneke Nieuwenhuizen, Ludovic Courtès
tags: Bootstrapping, Reproducible builds, Security
---
We are delighted and somewhat relieved to announce that the third
reduction of the Guix _bootstrap binaries_ has now been merged in the
main branch of Guix!  If you run `guix pull` today, you get a package
graph of more than 22,000 nodes _rooted in a 357-byte program_—something
that had never been achieved, to our knowledge, since the birth of Unix.

We refer to this as the _Full-Source Bootstrap_.  In this post, we
explain what this means concretely.  This is a major milestone—if not _the_
major milestone—in our quest for building _everything_ from source, all
the way down.

How did we get there, and why?  In [two previous
](https://guix.gnu.org/blog/2020/guix-further-reduces-bootstrap-seed-to-25/)
[blog
posts](https://guix.gnu.org/blog/2019/guix-reduces-bootstrap-seed-by-50/),
we elaborated on why this reduction and bootstrappability in general
is so important.

One reason is to properly address supply chain security concerns.  The
Bitcoin community was one of the first to recognize its importance
well enough to put the idea into practice.  At the [Breaking Bitcoin
conference 2020](https://breaking-bitcoin.com), Carl Dong gave a [fun
and remarkably gentle
introduction](http://diyhpl.us/wiki/transcripts/breaking-bitcoin/2019/bitcoin-build-system).
At the end of the talk, Carl states:

> The holy grail for bootstrappability will be connecting `hex0` to `mes`.

Two years ago, at [FOSDEM 2021](https://fosdem.org/2021), I (Janneke)
gave [a short talk](https://fosdem.org/2021/schedule/event/gnumes/) about how we
were planning to continue this quest.

If you think one should always be able to build software from source,
then it follows that the [“trusting
trust”](https://www.archive.ece.cmu.edu/~ganger/712.fall02/papers/p761-thompson.pdf)
attack is only a symptom of an incomplete or missing bootstrap story.

### The Road to Full-Source Bootstrap

Three years ago, the _bootstrap binaries_ were reduced to just [GNU
Mes](https://www.gnu.org/software/mes) and
[MesCC-Tools](https://savannah.nongnu.org/projects/mescc-tools) (and
the driver to build Guix packages: a [static
build](https://alpha.gnu.org/pub/gnu/guix/bootstrap/x86_64-linux/20131110/guile-2.0.9.tar.xz)
of [GNU Guile](https://www.gnu.org/software/guile) 2.0.9).

The new _Full-Source Bootstrap_, merged in Guix `master` yesterday,
removes the binaries for Mes and MesCC-Tools and replaces them by [bootstrap-seeds](https://github.com/oriansj/bootstrap-seeds).  For x86-linux (which is also used by the x86_64-linux build), this means this program
[hex0-seed](https://github.com/oriansj/bootstrap-seeds/blob/master/POSIX/x86/hex0-seed), with ASCII-equivalent
[hex0_x86.hex0](https://github.com/oriansj/bootstrap-seeds/blob/master/POSIX/x86/hex0_x86.hex0).  Hex0 is self-hosting and its source looks like this:

```
    ; Where the ELF Header is going to hit  
    ; Simply jump to _start  
    ; Our main function  
    # :_start ; (0x8048054)  
    58 # POP_EAX ; Get the number of arguments  
```

you can spot two types of line-comment: hex0 (`;`) and assembly (`#`).
The only program-code in this snippet is `58`: two hexidecimal digits
that are taken as two nibbles and compiled into the corresponding byte
with binary value `58`.

Starting from this 357-byte hex0-seed binary provided by the
`bootstrap-seeds`, the [stage0-posix
package](https://github.com/oriansj/stage0-posix) created by Jeremiah
Orians first builds hex0 and then all the way up: hex1, catm, hex2,
M0, cc_x86, M1, M2, get_machine (that's all of MesCC-Tools), and
finally [M2-Planet](https://github.com/oriansj/m2-planet).

The new [GNU Mes](https://gnu.org/s/mes) v0.24 release can be built with
M2-Planet.  This time with only a [remarkably small
change](https://issues.guix.gnu.org/55227), the bottom of the package
graph now looks like this (woohoo!):

```
                              gcc-mesboot (4.9.4)
                                      ^
                                      |
                                    (...)
                                      ^
                                      |
               binutils-mesboot (2.20.1a), glibc-mesboot (2.2.5),
                          gcc-core-mesboot (2.95.3)
                                      ^
                                      |
                             patch-mesboot (2.5.9)
                                      ^
                                      |
                       bootstrappable-tcc (0.9.26+31 patches)
                                      ^
                                      |
                            gnu-make-mesboot0 (3.80)
                                      ^
                                      |
                              gzip-mesboot (1.2.4)
                                      ^
                                      |
                               tcc-boot (0.9.27)
                                      ^
                                      |
                                 mes-boot (0.24.2)
                                      ^
                                      |
                         stage0-posix (hex0..M2-Planet)
                                      ^
                                      |
                          gash-boot, gash-utils-boot
                                      ^
                                      |
                                      *
                     bootstrap-seeds (357-bytes for x86)
                                     ~~~
                   [bootstrap-guile-2.0.9 driver (~25 MiB)]
```
[full graph](/static/blog/img/gcc-core-mesboot0-full-source-bootstrap-graph.svg)

We are excited that the [NLnet Foundation](https://nlnet.nl) has [been
sponsoring this work](https://nlnet.nl/project/GNUMes-fullsource)!

However, we aren't done yet; far from it.

### Lost Paths

The idea of reproducible builds and bootstrappable software [is not
very
new](https://lists.reproducible-builds.org/pipermail/rb-general/2017-January/000309.html).
Much of that was implemented for the GNU tools in the early 1990s.
Working to recreate it in present time shows us much of that practice
was forgotten.

Most bootstrap problems or loops are not so easy to solve and
sometimes there are no obvious answers, for example:

- In 2013, the year that [Reproducible
  Builds](https://reproducible-builds.org) started to gain some
  traction, the GNU Compiler Collection [released
  version 4.8.0](http://gcc.gnu.org/gcc-4.8/changes.html),
  making C++ a build requirement, and

- Even more recently (2018), the GNU C Library [glibc-2.28 adds Python
  as a build
  requirement](https://sourceware.org/git/?p=glibc.git;a=commit;h=c6982f7efc1c70fe2d6160a87ee44d871ac85ab0),

While these examples make for a delightful puzzle from a
bootstrappability perspective, we would love to see the maintainers of
GNU packages consider bootstrappability and start taking more
responsibility for the bootstrap story of their packages.

### Next Steps

Despite this major achievement, there is still work ahead.

First, while the package graph is rooted in a 357-byte program, the set
of binaries from which packages are built includes a 25 MiB
statically-linked Guile, `guile-bootstrap`, that Guix uses as its driver
to build the initial packages.  25 MiB is a tenth of what the initial
bootstrap binaries use to weigh, but it is a lot compared to those 357
bytes.  Can we get rid of this driver, and how?

A development effort with Timothy Sample addresses the dependency on
`guile-bootstrap` of [Gash and
Gash-Utils](https://savannah.nongnu.org/projects/gash), the
pure-Scheme POSIX shell implementation central to our [second
milestone](https://guix.gnu.org/en/blog/2020/guix-further-reduces-bootstrap-seed-to-25/).
On the one hand, Mes is gaining a higher level of Guile compatibility:
hash table interface, record interface, variables and variable-lookup,
and Guile (source) module loading support.  On the other hand, Gash
and Gash-Utils are getting Mes compatibility for features that Mes is
lacking (notably `syntax-case` macros).  If we pull this off,
`guile-bootstrap` will only be used as a dependency of bootar and as
the driver for Guix.

Second, the full-source bootstrap that just landed in Guix `master` is
limited to x86_64-linux and i686-linux, but ARM and RISC-V will be
joining soon.  We are most grateful and excited that the [NLnet
Foundation](https://nlnet.nl) has [decided to continue sponsoring this
work](https://nlnet.nl/project/GNUMes-ARM_RISC-V)!

Some time ago, Wladimir van der Laan contributed initial RISC-V
support for Mes but a major obstacle for the RISC-V bootstrap is that
the “vintage” GCC-2.95.3 that was such a helpful stepping stone does
not support RISC-V.  Worse, the RISC-V port of GCC was introduced only
in GCC 7.5.0—a version that requires C++ and cannot be
bootstrapped!  To this end, we have been improving MesCC, the C
compiler that comes with Mes, so it is able to
build GCC 4.6.5; meanwhile, Ekaitz Zarraga
[backported RISC-V support to GCC
4.6.5](https://nlnet.nl/project/GNUMes-RISCV/), and backported RISC-V
support from the latest [tcc](https://www.tinycc.org) to our
[bootstrappable-tcc](https://gitlab.com/janneke/tinycc).

### Outlook

The full-source bootstrap was once deemed impossible.  Yet, here we are,
building the foundations of a GNU/Linux distro entirely from source, a
long way towards the ideal that the Guix project has been aiming for
[from the
start](https://guix.gnu.org/manual/en/html_node/Bootstrapping.html).

There are still some daunting tasks ahead.  For example, what about the
Linux kernel?  The good news is that the bootstrappable community has
grown a lot, from two people six years ago there are now around 100
people in the `#bootstrappable` IRC channel.  Interesting times ahead!

#### About Bootstrappable Builds and GNU Mes

Software is bootstrappable when it does not depend on a binary seed
that cannot be built from source.  Software that is not
bootstrappable---even if it is free software---is a serious security
risk (supply chain security)
[for](https://www.ece.cmu.edu/~ganger/712.fall02/papers/p761-thompson.pdf)
[a](https://manishearth.github.io/blog/2016/12/02/reflections-on-rusting-trust/)
[variety](https://www.quora.com/What-is-a-coders-worst-nightmare/answer/Mick-Stute)
[of](http://blog.regehr.org/archives/1241)
[reasons](https://www.alchemistowl.org/pocorgtfo/pocorgtfo08.pdf).
The [Bootstrappable Builds](https://bootstrappable.org/) project aims
to reduce the number and size of binary seeds to a bare minimum.

[GNU Mes](https://www.gnu.org/software/mes/) is closely related to the
Bootstrappable Builds project.  Mes is used in the full-source
bootstrap path for the Guix System.

Currently, Mes consists of a mutual self-hosting scheme interpreter
and C compiler.  It also implements a C library.  Mes, the scheme
interpreter, is written in about 5,000 lines of code of simple C and
can be built with [M2-Planet](https://github.com/oriansj/m2-planet).
MesCC, the C compiler, is written in scheme.  Together, Mes and MesCC
can compile [bootstrappable TinyCC](http://gitlab.com/janneke/tinycc)
that is self-hosting.  Using this TinyCC and the Mes C library, the
entire Guix System for i686-linux and x86_64-linux is bootstrapped.

#### About GNU Guix

[GNU Guix](https://guix.gnu.org) is a transactional package manager and
an advanced distribution of the GNU system that [respects user
freedom](https://www.gnu.org/distros/free-system-distribution-guidelines.html).
Guix can be used on top of any system running the Hurd or the Linux
kernel, or it can be used as a standalone operating system distribution
for i686, x86_64, ARMv7, AArch64 and POWER9 machines.

In addition to standard package management features, Guix supports
transactional upgrades and roll-backs, unprivileged package management,
per-user profiles, and garbage collection.  When used as a standalone
GNU/Linux distribution, Guix offers a declarative, stateless approach to
operating system configuration management.  Guix is highly customizable
and hackable through [Guile](https://www.gnu.org/software/guile)
programming interfaces and extensions to the
[Scheme](http://schemers.org) language.
