---
title: RBoot MaKe (rbmk) build system design and maintenance manual
x-toc-enable: true
...

libre BIOS/UEFI firmware
------------------------------

RBoot is a [Free Software](https://www.gnu.org/philosophy/free-sw) project,
replacing proprietary BIOS/UEFI firmware. It provides coreboot and a number
of *payloads* such as EDK2, U-Boot or SeaBIOS, which boot your operating system.
This document describes the very essence of RBoot's design, how the project
functions and how releases are made.

In addition to this manual, you should also refer to [porting.md](porting.md)
and [testing.md](testing.md).

Please also read about the [rbmk coding style and design](style.md).

Look at [the git page](../../git.md) for info about how to send patches.

Automated coreboot build system
-------------------------------

This document describes the entire RBoot build system, its design philosophy
and how it's used to prepare RBoot releases; it is provided as a *reference*
for *RBoot development*, pertaining to the current development branch of
RBoot's build system (called *rbmk*).

The homepage of RBoot says that RBoot is a *coreboot distro*, providing
the necessary integration of coreboot, payloads and utilities so as to provide
releases, much like some GNU/Linux-libre operating systems, but here we are
concerned about the *boot firmware* instead. RBoot is a coreboot distro,
just as there are GNU/Linux-libre operating system distributions. It provides
easier, more automated configuration and installation.

The build system, rbmk, *is* that coreboot distro, at its very core. You can
basically think of it as a package manager; it is even a *source-based* package
manager. If you simply want to build ROM images, refer instead to the [basic
build instructions](../build/).

This build system, rbmk, is completely automated in every way. It is designed
to take care of itself; so long as build dependencies are installed, it will
check itself when running *any* command; if another command had to be executed
first, it will do so automatically. Therefore, you can run any part of rbmk
on its own, and the entire design is modular.

Best practices for learning rbmk
--------------------------------

The follow sections will cover subdirectories, within rbmk. Contrary to what
some may otherwise assume, it's best to learn about everything *except* scripts
or code within RBoot, first. No, you should first learn about config files
used in the RBoot build system, and *then* learn about the logic. By doing
it in this order, you will have greater context later when reading about those
scripts. Learning about each upstream project (such as coreboot) will also be
useful; check documentation provided by each project.

After learning about configuration, you will then read about files and
directories generated by the build system; only *then* will this document
describe each script or program that forms part of the build system. In other
words, this document adopts a *top-down* approach to education, rather than
bottom-up; most documents take the latter approach, in other projects, but
most people naturally want to learn how a specific thing works first, hence
the approach taken here.

### Don't be deceived by simplicity

RBoot's build system is powerful, and highly configurable, yet deceptively
simple at the same time. Remember this rule, a rule that applies to *all*
software projects: code equals bugs, so smaller codebases will yield fewer bugs.
RBoot is [regularly](../../news/audit.md) [audited](../../news/audit2.md).

Many people will be shocked by how *small* RBoot is, at its core. You will
be surprised by just how much can be done with so little. Continue reading!

EDK2
----

RBoot 26.11 added EDK2 support. This is implemented by using dummy
coreboot builds, where `UEFIPAYLOAD.fd` is extracted
and re-used generically on other boards. This is done using RBoot's
free distribution of EDK2.

Coreboot's EDK2 Makefile is modified not to fetch/patch anything. It copies
our tree which is handled via `config/submodule/coreboot/` - this includes
all recursive modules as this design change also made use of arbitrary
directories per submodule and sorts them by final destination path.

EDK2 is the default payload on most boards, since RBoot 26.11.

A few legacy 32-bit-only boards use SeaBIOS instead; we recommend the more
modern EDK2 payload, and it is the only choice available on most boards.

System requirements
-------------------

This concerns system requirements when *building* RBoot.

### Operating system

Any fully free GNU/Linux-libre operating system distribution will do. RBoot's
build system is regularly testing on all the major distros, and of the libre
distros, Parabola GNU/Linux-libre is tested. Please do report bugs if you
encounter issues.

Most of the popular distros will work. You know the ones. You know.

NOTE: Some patching is also done for non-glibc-based systems, such as
Alpine, though we currently do not have an automated way to install
build dependencies for these distros.

### **Dependencies**

**Make sure you have dependencies installed!**

**The [main build guide](../build) will tell you how to install dependencies.**

### Host CPU

At least an Intel Core 2 Duo, though we recommend much faster CPUs if building
entire release archives, e.g. quad-core Haswell CPU or better.

NOTE: x86 boards require an *x86_64* host CPU with appropriate host toolchains
and libraries. We don't yet cross-compile x86 payloads.

NOTE2: ARM64 motherboards *are* cross compiled, so you can build for AArch64
machines quite easily, from x86 or ARM64 machines.

### Memory

At least 2GB per CPU core, ideally 4GB; for example, 16GB RAM is recommended
if you're compiling an a quad-core CPU.

NOTE: `XBMK_THREADS` environmental variable defaults to 1 if unset. This sets
the number of build threads, which you should match to the number of cores.
For example, when you're building on a quad-core, do this prior to building:

	export XBMK_THREADS=4

### Disk space

About 20GB bare minimum, if only compiling for 1 board. The sources take up a
lot of space. However, RBoot is always expanding as it's developed.

At least 50GB of free disk space is therefor recommended.

We *actually* recommend 100GB, because RBoot will also have a small kernel
in flash on a future release. On our testing, disk I/O does not seem to be a
major bottleneck, so any HDD or SSD will do, but we obviously recommend a
fast NVMe (PCI-E) SSD if you can.

Environmental variables
-----------------------

### XBMK\_THREADS

For example:

	export XBMK_THREADS=2

This would build on two threads, when running rbmk. It defaults to 1.

Previous revisions of rbmk used `nproc` by default, but this was set to 1
instead, because nproc is not available on every operating system.

### XBMK\_RELEASE

If set to `y`, it signals that a release is being built,
and it will honour `release="n"` in target.cfg files. You could also set this
yourself when doing regular builds, if you wanted to test how `./mk -b coreboot`
behaves running it in release mode. Do this if you want to:

	export XBMK_RELEASE=y

You can set a MAC address on IFD-based systems via `XBMK_MAC` export. Otherwise,
a random MAC address will be used; on release builds, a fixed address is always
used.

Projects/files downloaded/generated by rbmk
--------------------------------------------

The following sections will describe files and directories that are not
included in `rbmk.git`, but *are* created by running various rbmk commands;
many of these will also be provided, pre-generated, under release archives.

Some of these are *downloaded* by RBoot's build system, automatically, while
others are created during the build process based on these downloaded programs.

### bin/

This directory is created when running any of the following commands, with the
right arguments:

	./mk -b coreboot ARGUMENTS_HERE
	./mk -b stm32-vserprog
	./mk -b pico-serprog

Simply speaking, `bin/` shall contain finished ROM images or firmware, that
can then be installed (flashed) to the target device.

The files under `bin/` are provided in regular RBoot releases.

**These** are the ROM images that you should flash.

Older versions of rbmk build coreboot images separately under `elf/`, but
without payloads, using `elf/` as a build cache, then inserting payloads
into copies of these images in files under `bin/`. However, modern rbmk
now only puts coreboot images in `bin/`, with payloads included.

If you still have `elf/` coreboot images in your rbmk tree, please do not
use them (and you may as well delete them).

### cache/

Certain files are cached here automatically, by rbmk. The user need not touch
these files.

### cache/file/

Files that are downloaded are hashed, and the cached version of the file
is stored there, named as the SHA512 checksum. This is used for submodule Git
repository downloads, and subfile downloads.

A *subfile* is like a Git submodule, but it's a *file* (just a humble file),
downloaded via curl/wget. The build system does not
run `git submodule update` commands when handling Git repositories anymore,
instead processing submodules manually; it supports both repositories *and*
files relative to the directory locations for those repositories, but subfiles
are not downloaded to the *cached git repository*, only the work directory used
for building in rbmk.

### cache/hash/

When rbmk is handling any project, it sorts a list of files under `config/`
including `config/project` (or `config/project/TREE`) and `config/data/project`.

SHA512 checksums are calculated from these files, in the sorted order, and
written in that order, to a file. *That* file is then checksummed, and this
hash is stored in `cache/hash` for that project.

If the currently stored hash differs from what's calculated, it means that
the project has changed, and the source directories plus builds are deleted.
The project source is then re-prepared and re-build.

### cache/mirror/

Git repositories are cached here. This avoids wasting bandwidth, when downloading
multiple repositories. **Git submodules are also cached here!**

### elf/

**DO NOT flash coreboot ROM images contained under `elf/`. Please use ROM images
under `bin/` instead! - In modern rbmk, only the ones under `bin/` are ever
created anyway.**

Compiled binaries (compiled by rbmk) go here, but they are not the final
binaries; coreboot ROM images are compiled without payloads, then cached here
under `elf/coreboot` as one example

Some utilities are also provided compiled here, when building. For
example: `elf/flashprog/flashprog`. This is because rbmk tries to provide
out-of-source builds whenever feasible.

This is only used by the build system, but these images are *not* provided in
releases (only the images under `bin/` are provided).

The `elf/` directory must be used by default for all builds (out-of-tree).

### release/

The script at `build` create tarballs in here, which
constitute regular RBoot releases. It is meticulously maintained, as per
current rbmk behaviour, and executed so as to provide RBoot release
archives.

This provides source tarballs, and ROM images.

You can create release archives by doing:

	./mk release

The build system expects there to be a *git tag*, so make sure there is one.
This is used to create the version number for a given release.

### src/

Third-party source trees are downloaded into this directory, by rbmk.

### src/coreboot/

Please also visit: <https://coreboot.org/>

Coreboot is the main boot firmware, providing hardware initialisation. RBoot
makes extensive use of coreboot, on supported motherboards.

Coreboot trees go here. RBoot's build system does not simply use one tree,
or multiple branches in the same tree; entirely separate directories are
created, for each revision of coreboot used, each able to have its own patches.
These can then be re-use appropriately, per motherboard. For example:

* `src/coreboot/default` is used by most motherboards.
* `src/coreboot/cros` is used by cros devices.

This may be less efficient on disk usage, but it simplifies the logic greatly.
Coreboot also uses its own toolchain called *crossgcc*, and crossgcc is in fact
compiled *per tree* in RBoot.

### src/flashprog/

Please also visit: <https://flashprog.org/>

Although currently unused by any part of rbmk, we provide flashprog for the
convenience of users, and this is copied to release archives. Flashprog is the
program that you will use to read, erase and write the flash, containing
coreboot firmware.

### src/int/

Riku Viitanen wrote this tool for debugging, when implementing MXM option ROM
support in coreboot and SeaBIOS, for the HP EliteBook 8560w.

### src/mxmdump/

Riku Viitanen wrote this utility, for dumping the MXM config on graphics cards
that use it. The HP EliteBook 8560w uses these cards, and normally you would
just run a VGA option ROM to get a display at boot time. The MXM cards
additionally contain a configuration called MXM, which basically describes
ports and several power management capabilities.

MXM data is loaded via an INT15H handler, which Riku also implemented in
SeaBIOS. If the MXM data is not handled, the VGA option ROM (when executed)
will often complain and refuse to boot; some of them can be hacked to bypass
this fact, but such hacks are no longer required because of Riku's tool.

NOTE: The EliteBook 8560w isn't supported in RBoot yet, but this tool
could be used for other machines in the future.

### src/seabios/

Please also visit: <https://www.seabios.org>

This is the PC BIOS implementation used by RBoot, on x86 machines (not all
of them).

Only used on very old 32-bit hardware.

### src/u-boot/

Please also visit: <https://www.denx.de/project/u-boot/>

This is a bootloader provided on ARM chromebooks, within RBoot. It also
provides UEFI. Information about that can be found on these resources:

* [U-Boot documentation](../uboot/)
* [Chromebook documentation](../install/chromebooks.md)

This is currently the only payload on *ARM* systems, within RBoot.

### src/pcsx-redux/

PCSX-Redux is a Sony Playstation (PS1/PSX) emulator, but RBoot only uses
one part from it: the Open BIOS. This is used by RBoot to provide an
open BIOS for the Sony Playstation!

More information available on the [PlayStation page](../install/playstation.md).

This is automatically compiled by the main build script, and the resulting
BIOS image is provided in RBoot release archives.

### src/pico-serprog/

Used by rbmk, to build firmware for serprog-based SPI flashers with RP2040 SoC.
Alongside this, `util-fw/rp2040/pico-sdk` is imported which is required for
building it.

### src/stm32-vserprog/

Used by rbmk, to build firmware for serprog-based SPI flashers with STM32 MCU.
Alongside this, `libopencm3` is imported which is required for building it.

These serprog programmers are quite desirable, owing to their low cost and ease
of use. You can learn more on the [SPI flashing guide](../install/spi.md).

Before moving onto configurations, we will now cover *utilities* provided by
RBoot itself (included within rbmk, rather than being downloaded like the
third party projects listed above):

### tmp/

The `TMPDIR` environmental variable is set by rbmk, to a location under `/tmp`,
but some users may have `/tmp` mounted as a *tmpfs* (file system in RAM), and
may not have much RAM.

Where large files (or a large number of files) are handled by rbmk on a
temporary basis, this `tmp/` directory is created and then used.

util/
-----

If a codebase is not frequently used by RBoot, is actively developed (making
it not viable to maintain in RBoot) or the codebase is very large, we would
import that as a third party module in rbmk - this rule exists for all projects,
where the intention is that `rbmk.git` itself should be small and efficient.

Where appropriate, and where the code is small enough, or it is otherwise deemed
desirable, `rbmk.git` provides a few utilities as part of itself, namely:

### util/dell-flash-unlock/

This program, written by Nicholas Chin, unlocks the boot flash on Dell Latitude
E6400; it permits internal flashing, from factory firmware to RBoot, so that
the user need not disassemble and flash externally.

It also supports several other Dell laptops, with similar ECs. Check the
README file included in this directory, for more information.

### util/nvmutil/

The `nvmutil` software allows you to set the MAC address on Intel GbE NVM
files. It also allows you to set *random* MAC addresses, in addition to
arbitrary ones.

This directory contains the source code for `nvmutil`, which you can read
about here:

[nvmutil manual](../install/nvmutil.md)

### util/spkmodem\_recv/

RBoot imported this from coreboot, who is turn imported it from GRUB with
little to no modification.

This is a receiving client for spkmodem, which is a method of providing serial
consoles via pulses on the PC speaker. The `spkmodem_recv` client will *decode*
these pulses. Coreboot has a driver for generating these pulses, as does
GRUB; this client code was imported from GRUB, and has in fact been provided
by every RBoot release since the start of the project (look inside the GRUB
or coreboot source code and you'll find it).

However, the original code from GRUB was of quite poor quality and this code
is often used. For fun, it was decided that this utility would be imported
directly into `rbmk.git`, and thoroughly cleaned. The rbmk version has
been re-written.

* Superior error handling (the program actually exits with non-zero status now,
  under fault conditions, whereas the original code did *not* handle errors).
* Debug mode is now handled via `getopt()` by passing the `-d` flag at run time,
  whereas the original code only enabled it if a DEBUG build-time flag was used.
* The code has been translated into English (e.g. references to "trames" in
  the code, now say "frames" in the RBoot version).
* Certain magic numbers, and certain equations in code, are now labelled as
  either variables or as `#define` values, thus increasing code legibility.

config/
-------

This directory contains configuration files, used by the RBoot build
system. These next sections will cover specific configuration files.

### config/module/PROJECT\*/nuke.list

The script `include/git.sh` handles deletion of certain files, for downloaded
projects, based on a `nuke.list` file that can (for single-tree projects) be
included at `config/PROJECT/nuke.list` or (multi-tree project)
at `config/PROJECT/TREE/nuke.list` (entries are relative links from the root
directory of the given source tree e.g. `src/coreboot/default/`).

So, if `src/coreboot/default/` contained foo/bar.txt, you could add to
the `nuke.list` file as follows:

```
foo/bar.txt
```

Ditto `src/flashprog/`, if you wanted to delete a file from in there, as one
other example. Deletions occur when the source tree is created.

### config/module/coreboot/

#### config/module/coreboot/BOARDNAME/

Each target name (e.g. `x200_8mb`) has its own directory under here. Targets
that do not define defconfigs also exist here; for example, the `default`
directory defines a coreboot revision and patches.

Targets under `config/module/coreboot` can specify `tree=TREE` where `TREE` could,
for example, be `default`. In other words, they can refer to other trees.

The coreboot downloads are based on scanning of these directories, and ROM
images are also built based on them.

#### config/module/coreboot/BOARDNAME/patches/

For any given coreboot tree, patches with the `patch` file extension are placed
here, alphanumerically in the order that they should be applied.

These patches are then so applied, when rbmk downloads the given source tree.

#### config/module/coreboot/BOARDNAME/target.cfg

This file can contain several configuration lines, each being a string, such
as:

* `tree="default"` (example entry)
* `rev="ad983eeec76ecdb2aff4fb47baeee95ade012225"` (example entry)
* `xarch="i386-elf"` (example entry)
* `release="n"` (example entry)
* `xtree="default"` (example entry)
* `tree_depend="default"` (example entry)
* `payload_edk2="edk2_chromebook"` can be set along with:
  add `coreboot/edk2_chromebook` to `build_depend`. Also

The `tree` value refers to `config/module/coreboot/TREE`; in other words, a given
target could specify a name other than its own as the tree; it would then
re-use code from that tree, rather than providing its own.

The `rev` entry defines which coreboot revision to use, from the
coreboot Git repository. *At present, rbmk only supports use of the official
repository from the upstream coreboot project*.

The `xarch` entry specifies which CPU architecture is to be used: currently
recognized entries are `i386-elf`, `arm-eabi` and `aarch64-elf`. This is the
target architecture for building GCC/toolchain from coreboot crossgcc,
hence `xarch`.

The `payload_uboot` entry specifies whether or not U-Boot is to be included in
ROM images.

The `uboot_config` option specifies which U-Boot board configuration file
variant should be used. It currently doesn't make sense for this to be anything
other than `default`, which is the default if the option is missing.

The `release` variable can be set to n, which makes the `./mk release`
call skip that target, when creating release images. For example, a given
board may not be stable and you don't want images for it to be included in the
release.

The `xtree` option specifies that a given tree with use a specific coreboot
tree for compiling crossgcc. This can be used to skip building gcc if OK on
a given board; two trees may use the same crossgcc as each other.

The `tree_depend` option means that a given tree needs another tree, defined
by this variable, to also be present.

#### config/module/coreboot/BOARDNAME/config/

NOTE: the `txtmode` configs are mostly only used on SeaBIOS setups. Modern
setups are all EDK2 or U-Boot; the GRUB payload was removed in RBoot.

Files in this directory are *coreboot* configuration files. 

Configuration file names can be as follows:

* `libgfxinit_corebootfb`
* `libgfxinit_txtmode`
* `vgarom_vesafb`
* `vgarom_txtmode`
* `normal`
* `fspgop`

Information pertaining to this can be found on
the [installation manual](../install/)

In `rbmk`, a board-specific directory under `config/module/coreboot/` should never
specify a coreboot revision. Rather, a directory *without* coreboot configs
should be created, specifying a coreboot revision. For example, the
directory `config/module/coreboot/default/` specifies a coreboot revision. In the
board-specific directory, your `board.cfg` could then
specify `cbtree="default"` but without specifying a coreboot revision (this
is specified by `config/module/coreboot/default/target.cfg`).

When you create a coreboot configuration, you should set the payload to *none*
because `rbmk` itself will assume that is the case, and insert payloads itself.

Configurations with `libgfxinit` will use coreboot's native graphics init code
if available on that board. If the file name has `txtmode` in it, coreboot
will be configured to start in *text mode*, when setting up the display. If
the file name has `corebootfb` in it, coreboot will be configured to set up a
high resolution *frame buffer*, when initializing the display.

NOTE: If the configuration file is `libgfxinit_txtmode`, the SeaBIOS payload
can still run *external* VGA option ROMs on graphics cards, and this is the
recommended setup (SeaBIOS in text mode) if you have a board with both onboard
and an add-on graphics card (e.g. PCI express slot) installed.

### config/dependencies/

Files here are so named, and called like so: e.g. the `parabola` file would be
referenced when running:

	./mk dependencies parabola

These files define a list of packages, and the correct package manager command
to use on a given distro. This can be used to install build dependencies, which
are required for compiling RBoot from source code.

### config/data/PROJECT/mkhelper.cfg

This can set `rev=`, `url=` and `bkup_url=` for a given project and can also
be set in individual tree/target config instead, for multi-upstream support
per project. This was a design change made in RBoot 26.11
as use of `config/git/` was removed.

These `mkhelper.cfg` files define common configuration that can be supplied
for any single- or multi-tree project. Arguments available are as follows:

* `makeargs`: This defines what arguments to append when running the
  main `make` command on a given project. For example, this is used on coreboot
  to tell coreboot's build system that the submodules have been updated (to
  avoid downloading any that we didn't manually specify).
* `build_depend`: Just before running the main `make` command on a given
  project, this specifies other projects to build. It also works with multi
  tree projects. Example: `coreboot/edk2_chromebook`
* `premake`: This defines a function to be called *before* running make, on a
  given project; the mkhelper file itself can also import any given file to
  provide that function.
* `mkhelper` (variable name): Defines a function to be called just after
  running make, on a given project.
* `postmake`: This is run *after* `mkhelper`, and can be used for additional
  functions. For example, it's used on coreboot to call `mkcoreboottar` which
  will create tarballs of ROM images if `XBMK_RELEASE` is enabled.

You can define anything else here, for use by a given project. More specifically,
anything you put in mkhelper files will be imported as part of a normal shell
script during operation of rbmk, to complement core functionality across all
the various projects.

The `mkhelper` file is a global configuration for the project. Individual
projects can complement what is set in mkhelper, via `target.cfg` files for
each project, project tree or target on a given multi-tree project.

The `mkhelper` functionality (and postmake/premake) was originally implemented
so that lots of special configuration could be done per project, without a lot
of code repetition. This is a unique design of rbmk, different from many other
coreboot-distro build systems.

The `mkhelper` functionality is an essential component that makes rbmk work
the way it does; for example, the `trees` script builds coreboot images without
payloads, and functions to add payloads are handled by mkhelper-type functions.
This design allows almost all functionality to be centralised, where the mkhelper
functions only provide functionality that differs from core functionality.

In the simplest of terms, you may regard mkhelpers as *plugins*, of a sort.
They simply extend the core functionality of the build system, in a way that
can differ flexibly between projects.

### config/data/coreboot/ifd/\*

Intel Flash Descriptors and GbE NVM images, which are binary-encoded
configuration files. These files are referenced in coreboot defconfigs, used
by rbmk to build coreboot ROM images.

### config/module/seabios/

#### config/data/seabios/build.list

When a given SeaBIOS tree is compiled, for a given target, this file defines
which files to copy from the `seabios/` directory, which are then copied to
a location under `elf/seabios`.

#### config/module/seabios/default/

Currently the only tree in use, this defines what SeaBIOS revision is to be
used, when the SeaBIOS payload is enabled on a given coreboot target.

#### config/module/seabios/default/config/

Configuration files go in here.

#### config/module/seabios/default/config/libgfxinit

Configuration file for when native video initialisation is available in
coreboot.

#### config/module/seabios/default/config/normal

Configuration file for when native video initialisation is unavailable in
coreboot, and VGA ROM initialisation is also not provided by coreboot (in
this configuration, the usual setup will be that *SeaBIOS* finds and
executes them, instead of coreboot).

#### config/module/seabios/default/config/vgarom

Configuration file for when native video initialisation is unavailable in
coreboot, and VGA ROM initialisation is provided by coreboot; in this setup,
SeaBIOS should not execute VGA ROMs.

#### config/module/seabios/default/target.cfg

Similar concept to `target.cfg` files provided by coreboot. This specifies
which SeaBIOS revision (from Git) is to be used, when compiling SeaBIOS images.

### config/module/u-boot/

This directory contains configuration, patches and so on, for each motherboard
that can use U-Boot as a payload in the `rbmk` build system. U-Boot doesn't yet
have reliable generic configurations that can work across all coreboot boards
(per-architecture), so these are used to build it per-board.

#### config/data/u-boot/build.list

When a given U-Boot tree is compiled, for a given target, this file defines
which files to copy from the U-Boot source build, which are then copied to
a location under `elf/u-boot/`.

#### config/module/u-boot/TREENAME/

Each `TREENAME` directory defines configuration for a corresponding motherboard.
It doesn't actually have to be for a board; it can also be used to just define
a U-Boot revision, with patches and so on. To enable use as a payload in ROM
images, this must have the same name as its `config/module/coreboot/TREENAME/`
counterpart.

#### config/module/u-boot/TREENAME/patches/

For any given U-Boot tree, patches with the `patch` file extension are placed
here, alphanumerically in the order that they should be applied.

These patches are then so applied, when rbmk downloads the given source tree.

#### config/module/u-boot/TREENAME/target.cfg

This file can contain several configuration lines, each being a string, such
as:

* `tree="default"` (example entry)
* `rev="4debc57a3da6c3f4d3f89a637e99206f4cea0a96"` (example entry)
* `arch="AArch64"` (example entry)

These are similar in meaning to their coreboot counterparts.

The `tree` entry is actually a link, where its value is a directory name
under `config/u-boot`. For example, `tree="default"` would refer to
`config/u-boot/default` and the corresponding U-Boot source tree created
(when running `./mk u-boot`, which makes use of `target.cfg`)
would be `u-boot/default/`. In other words: a `target.cfg` file
in `config/u-boot/foo` might refer to `config/u-boot/bar` by
specifying `tree="bar"`, and the created u-boot source tree would
be `u-boot/bar/`. ALSO:

FUN FACT: such references are infinitely checked until resolved. For
example, `foo` can refer to `bar` and `bar` can refer to `baz` but if there is
an infinite loop, this is detected and handled by rbmk. For example,
if `bar` refers to `foo` which refers back to `bar`, this is not permitted
and will throw an error in rbmk.

The `rev` entry defines which U-Boot revision to use, from the U-Boot
Git repository. *At present, rbmk only supports use of the official repository
from the upstream U-Boot project*.

The `arch` entry specifies which CPU architecture is to be used: currently
recognized entries are `x86_32`, `x86_64`, `ARMv7` and `AArch64`. *Setting it
to a non-native arch means that necessary crossgcc-arch will be compiled and be
available when building roms, but not necessarily built or discovered when
individual scripts are called manually.*

#### config/module/u-boot/TREENAME/config/

Files in this directory are *U-Boot* configuration files. Configuration file
names can be anything, but for now `default` is the only one used.

In rbmk, a board-specific directory under `config/u-boot/` should never
specify a U-Boot revision. Rather, a directory *without* U-Boot configs should
be created, specifying a U-Boot revision. For example, the directory
`config/u-boot/default/` specifies a U-Boot revision. In the board-specific
directory, your `board.cfg` could then specify `ubtree="default"` but without
specifying a U-Boot revision (this is specified by
`config/u-boot/default/board.cfg`).

Normally, the U-Boot build process results in the U-Boot executable and a
device-tree file for the target board, which must further be packaged together
to make things work. When you create a U-Boot configuration, you should enable
`CONFIG_REMAKE_ELF` or `CONFIG_OF_EMBED` that handles this. The former option
enables creation of a `u-boot.elf` that bundles them together after the build,
and the latter option embeds it into the `u-boot` executable.

When making a U-Boot configuration, you should also pay special attention to
the `CONFIG_SYS_TEXT_BASE` (`CONFIG_TEXT_BASE` in later versions), whose defaults
may cause it to overlap coreboot, in which case it won't boot. Normally, the
upstream coreboot build system checks for this when given `CONFIG_PAYLOAD_ELF`,
but `rbmk` injects the payload itself and doesn't check for this yet.

Another interesting config option is `CONFIG_POSITION_INDEPENDENT` for ARM
boards, which has been so far enabled in the ones `rbmk` supports, just to be
safe.

### config/submodule/

In here you can find submodule configurations for projects. It works for both
single- and multi-tree projects. Use the existing examples as reference.

Files, in each directory:

* `module.list` lists paths (files and directories) for given modules, which
  can be files(via URL) or Git repositories, or both.
* NAME/module.cfg

NAME is the file/directory name for the module, with everything up to the
final forward slash removed. E.g. foo/bar/thing.zip would be thing.zip as
NAME.

In `module.cfg` there can be either, file:

```
subfile="url"
subfile_bkup="url"
subhash="sha512sum for file"
```

or, git repository:

```
subrepo="url"
subrepo_bkup="url"
subhash="sha1 git commit id"
```

You must only use `subfile` or `subrepo`, not both, and there must be a backup
URL. The build system intentionally *avoids* using Git's actual submodules
feature, instead opting to download such repositories manually, because the
official submodules feature doesn't have very good redundancy.

Additionally, a `patches` directory can be included alongside `module.cfg`,
which can be used to patch the submodule (only supported for Git repositories
because files are not extracted, only placed at their configured destination).

The destination path in `module.list` is relative to the location of the main
Git repository under which it is placed.

### config/data/PROJECT/

Random configuration data provided on a per-project basis. Complements
the `config/PROJECT` directory.

### U-Boot build system

**x86-64 U-Boot was removed in favour of EDK2 which is handled as a submodule
of coreboot and built inside coreboot's own build system via modification of
its edk2 Makefile; check dummy coreboot targets like `edk2_chromebook` to see
how it works. It pretty much all plumbs through coreboot as it didn't seem
productive for rbmk to build EDK2 itself. Coreboot logic already worked.**

If you wish to know about U-Boot, refer here:\
<https://u-boot.readthedocs.io/en/latest/>

This and other documents from U-Boot shall help you to understand *U-Boot*.

You create a config, for `config/u-boot/TREENAME/configs`, by finding the
corresponding board name in the upstream U-Boot `configs` directory, and
running `make BOARDNAME_defconfig` and `make menuconfig` commands in the
*U-Boot* build system. You should do this after
running `./mk u-boot` in rbmk.

You might want to consider basing your config on the upstream `coreboot` boards
when possible, but such a board is not available upstream for ARM yet.

You can simply clone U-Boot upstream, add whatever patches you want, and
then you can make your config. It will appear afterwards in a file
named `.config` which is your config for inside `config/u-boot/TREENAME/`.

You can then use `git format-patch -nX` where `X` is however many patches you
added to that U-Boot tree. You can put them in the patches directory
under `config/u-boot/BOARDNAME`.

The *base* revision, upon which any custom patches you wrote are applied,
shall be the `rev` entry.

Scripts exist in rbmk for automating the modification/updating of *existing*
configs, but not for adding them. Adding them is to be done manually, based on
the above guidance.

Config files in rbmk root directory
-----------------------------------

### projectsite

Domain name linking to the project home page (e.g. rboot.org).

### projectname

This is a text file, containing a single line that says `rboot`. This string
is used by the build system, when naming releases alongside the version number.

### version

Updated each time rbmk runs, based on either `git describe` or, on release
archives, this file is static and never changes. It says what RBoot revision
is currently in use (or was in use, if rbmk isn't running).

### versiondate

Updated each time rbmk runs, based on either `git describe` or, on release
archives, this file is static and never changes. It says the *time* of
whichever RBoot revision is currently in use (time of commit).

At last, you will now learn about the *scripts* (exclusively written as
posix shell scripts) that constitute the entire RBoot build system, rbmk:

Scripts in root directory of rbmk
---------------------------------

### mk

This is the main build script.

Example commands:

	./mk -b coreboot
	./mk

Special commands available (not provided by files under `script/`):

	./mk release
	./mk -d coreboot TARGET

Information about `./mk release` is written elsewhere on this page.

You can also know what build system revision you have by running:

	./mk version

This script is the beating heart of RBoot. Break it and you break RBoot.

It *also* handles simple git trees, where there is only one revision for the
project.

**All projects are multi-tree now in rbmk. The single/multi-tree distinction
was removed in a redesign prior to RBoot 26.11. A `noconfig="y"` setting
must be used in `target.cfg` on projects that do not use defconfigs.**

It *also*, in addition to downloading from git, can handle modification or
updating of defconfig files. As already stated, and stated further: it is
RBoot's other beating heart. Break this, and you break RBoot.

For multi-tree projects, it handles the following files (PROJECT can
be `coreboot`, `seabios` or `u-boot`):

* `config/module/PROJECT/build.list` (defines what files to copy, after building for
  the target)
* `config/module/PROJECT/*/target.cfg` (rbmk build parameters, project project/target)
* `config/module/PROJECT/*/config/*` (defconfig files)

NOTE: For multi-tree projects, `config/git` is still used, to download the
upstream repository to `src/PROJECT/PROJECT` but with git revision being `HEAD`.
In this way, you always have the latest code, but revisions defined
in `config/PROJECT/TARGET/target.cfg` will define a tree,
then `config/PROJECT/TREE/target.cfg` (which could be the same as `TARGET`,
but this is not the preferred style in rbmk) will define a revision; then,
the directory `src/PROJECT/TREE` will be created, reset to the specific
revision - for multi-tree projects, all defined targets are scanned for their
corresponding tree, and the trees are prepared as defined above.

Basic command: `./mk FLAG projectname`

Special operation: for building coreboot utilities `cbfstool` and `ifdtool` to
go under `cbutils/`, do this:

	./mk -d coreboot TREENAME

Or define specific coreboot tree such as:

	./mk -d coreboot default
	./mk -d coreboot cros

FLAG values are (only *one* to be used at a time):

* `-b` builds an image for the target, based on defconfig for multi-tree
  projects, or based only on a Makefile for single-tree projects; on some
  single-tree projects, this script also handles *cmake*.
* `-u` runs `make oldconfig` on the target's corresponding source tree, using
  its defconfig (useful for automatically updating configs, when updating trees
  like when adding patches or switching git revisions)
* `-m` runs `make menuconfig` on the target's corresponding source tree, using
  its defconfig (useful for modifying configs, e.g. changing CBFS size on
  a coreboot image)
* `-c` tries `make distclean`, deferring to `make clean` under fault
  conditions and from that, non-zero exit under fault conditions. This is done
  on the target's corresponding source tree.
* `-x` tries 'make crossgcc-clean`. This only works on coreboot trees, but no
  error status will be returned on exit if you try it on other project trees; no
  action will be performed.
* `-f` downloads the Git repository for the given project, and resets to a
  revision as defined under `config/git/`, or (for multi-tree projects), the
  file `config/PROJECT/TREE/target.cfg` to create `src/project/treename`.

As for *projectname", this can either be `coreboot`, `u-boot` or `seabios`.

Example commands:

	./mk -b coreboot
	./mk -b coreboot x200_8mb
	./mk -b coreboot x200_8mb x60
	./mk -x coreboot default
	./mk -u seabios
	./mk -m u-boot gru_bob
	./mk -f coreboot
	./mk -d coreboot default
	./mk -d coreboot

NOTE: the `-x` and `-c` options will cause an exit with zero status, when
the target's corresponding source tree is unavailable; a non-zero status is
only return under fault conditions when said source tree is *available*. ALL
other flags will cause the very same source tree to be downloaded and prepared,
if unavailable and *that* too will return with non-zero status under fault
conditions.

NOTE: "target" can indeed be the tree name, under some circumstances. For
example, `./mk -m seabios default`

After `projectname`, a target can be specified, but if no target is specified,
then *all* targets will be operated on. For
example, `./mk -b coreboot` will attempt to build *all*
coreboot ROM images.

NOTE: the `coreboot` projectname here shall cause the ROM images to go
under `elf/` - this is the no-payload ROM images, which are later used
separately by `script/build/roms` to provide full images, with
payloads inserted. It is an intentional design choice of RBoot, to split
it up this way and *not* use coreboot's own build system to handle payloads.

In rbmk, there are *two* types of git download: *simple* downloads where only
a single revision would ever be used, or *multi* downloads where different
revisions are used depending on target.

All such downloads are *simple* downloads, except for coreboot, U-Boot and
SeaBIOS which are *multi* downloads. The *other* requirement is that defconfigs
be used, though this could be worked around in the future if a *multi* setup is
needed on a project that *does not use defconfigs* (this is not yet the case in
rbmk).

All of this used to about 20 different scripts, all with much-duplicated logic.
Now it is unified, efficiently, under a single script.

Remember: code equals bugs, so less code equals fewer bugs.

include/
--------

This directory contains *helper scripts*, to be included
by main scripts using the `.` command (called the `source`
command in `bash`, but we rely upon posix `sh` only).

### include/env/get.sh

These functions in here previously existed as independent scripts, but they
were unified here, and they are used when you pass the `-f` argument to `mk`.

These functions deal with git cloning, submodule updates, revision resets and
the application of patch files via `git am`. *Every* git repository downloaded
by rbmk is handled by the functions in this file.

Downloading of regular files is also handled in here.

### include/lib.sh and include/env/init.sh

The `init.sh` file contains generic rbmk initialisation, and extra library
functions are contained inside `lib.sh`.

Several other parts of rbmk also use this file. It is added to as little as
possible, and contains miscallaneous functions that don't belong anywhere else.

The functions here are mostly those that deal with configuration files; scanning
them to set variables and so on.

This file also contains generic error handling, used by all rbmk scripts.

This also contains functions to verify the current RBoot version, and check
whether Git is properly initialised on the host system. It also contains
the `setvars` function, which provides a shorthand way of initialising many
variables (combined with use of `eval`), which rbmk uses heavily.

This function also contains `x_()` which rbmk uses to execute commands
and ensure that they cause an exit (with non-zero status) from rbmk, if they
return an error state.

This also includes the `mk()` function, which can be used as shorthand to
build multiple projects, but it doesn't handle targets within multi-tree projects,
so if for example you say `mk coreboot`, it would build every coreboot target.
This is useful for the release build logic, because now it can much more simply
build all of RBoot, while still being flexible about it.

### include/fw/rom.sh

This builds coreboot ROM images. Specifically, this contains mkhelper functions.
It also builds serprog images, and it could be used to provide functions for
building other types of firmware.

Command: `./mk -b coreboot targetname`

The `targetname` argument must be specified, chosen from this output:

	./mk -b coreboot list

Pass several board names if you wish to build only for specific targets. For
example:

	./mk -b coreboot x60 x200_8mb

To build *all* targets, specify:

	./mk -b coreboot

It heavily makes use of the `target.cfg` file, for a given board. This script
will *only* operate on a single target, from a directory in `config/module/coreboot/`.

It automatically detects if `crossgcc` is to be compiled, on a given coreboot
tree (in cases where it has not yet been compiled), and compiles it for a
target based on the `arch` entry in `target.cfg`.

If no payload is defined in `target.cfg`, the `build/roms` script will exit
with error status.

If SeaBIOS is to be used, on `libgfxinit` setups, SeaVGABIOS will also be
inserted. This provides a minimal VGA compatibility layer on top of the
coreboot framebuffer, but does not allow for *switching* the VGA mode. It is
currently most useful for directly executing ISOLINUX/SYSLINUX bootloaders,
and certain OS software.

If SeaBIOS is to be used, in `vgarom` setups or `normal` setups, SeaVGABIOS
is not inserted and you rely on either coreboot and/or SeaBIOS to execute VGA
option ROMs.

In all cases, this script automatically inserts several SeaBIOS runtime
configurations, such as: `etc/ps2-keyboard-spinup` set to 3000 (PS/2 spinup
wait time), `etc/pci-optionrom-exec` set to 2 (despite that already being
the default anyway) to enable *all* option ROMs, unless `vgarom` setups are
used, in which case the option is set to *0* (disabled) because coreboot is
then expected to handle option ROMs, and SeaBIOS should not do it.

This script handles U-Boot separately, for ARM-based chromeos devices.

When the ROM is finished compiling, it will appear under a directory in `bin/`

This script is the beating heart of RBoot. Break it, and you break
RBoot!

CCACHE is automatically used, when building coreboot, but not currently for
other projects. This is done by cooking coreboot configs at build time, enabling
coreboot's build option for it.

### Serprog images:

Build firmware images for serprog-based SPI programmers, where they use an
STM32 MCU. It also builds for RP2040-based programmers like Raspberry Pi Pico.

Example command: `./mk -b pico-serprog`

Example command: `./mk -b stm32-vserprog`

This also uses `rom.sh` as with the coreboot image build logic. It's all
defined in that file, so read the main section pertaining to this file.

### include/fw/inject.sh

Functions for modifying the intel GbE MAC address on IFD-based Intel systems.


[//]: # "SPDX-License-Identifier: GFDL-1.3-or-later"


