Initial setup

To be able to build TRS, we must take a few steps to prepare our host environment. Typically, this involves installing a few essential packages and initializing scripts to setup paths etc. Following the steps listed here should result in a host environment capable of building, deploying, and running software on an emulated environment such as QEMU or on one of the TRS-supported devices.

It is important to note that it is difficult to provide completely accurate instructions since there are so many Linux distributions, each with subtle variations. They have distinct package managers, various package naming conventions and different package versions. So, our instructions have been mostly tested with Ubuntu LTS and, now, with Ubuntu 22.04 LTS.

repo

For more than a decade now, repo has been the Android tool responsible for checking out groups of individual git repositories that make up a larger project or product. At its core, repo reads manifest files, which are xml-files that include URLs to remote servers hosting gits. In the xml-files, we also find the names of the gits used in a project, as well as the branch or commit we’re tracking.

repo is very configurable, but we use it mostly to obtain the source code for our development builds and to generate stable releases. Repo’s excellent method of leveraging local mirrors, which considerably reduces setup time and saves a substantial amount of disk space, was a major factor in the decision to use it. How this is accomplished is described in depth later in this paper.

Install repo

Notice that here you do not install a massive SDK; instead, you just download a Python script and place it in your $PATH variable. See the Google repo sites for specific instructions on “installing” repo before proceeding.

Getting the source code

This step gets the code necessary to build TRS. You may either checkout a version tracking the latest on all gits (a “developer setup”), or you can checkout a specific release. The difference is shown in the highlighted repo init lines in the examples below, where you provide different branch names and manifest files.

Developer setup

 $ mkdir trs-workspace
 $ cd trs-workspace
 $ repo init -u https://gitlab.com/Linaro/trusted-reference-stack/trs-manifest.git -m default.xml
 $ repo sync -j3

Release build

 $ mkdir trs-workspace
 $ cd trs-workspace
 $ repo init -u https://gitlab.com/Linaro/trusted-reference-stack/trs-manifest.git -m default.xml -b <release-tag>
 $ repo sync -j3

Getting the host packages

As previously explained, various host packages are needed for building TRS. These packages are a combination of distribution packages and a few required Python packages. The distribution packages will be installed with the host’s package manager, while the Python packages will be installed with pip. The latter are only required to build the documentation.

Distribution packages

Your sudo password will be required to complete the steps listed here.

$ cd <workspace root>
$ make apt-prereqs

This will install the following packages:

acpica-tools
adb
autoconf
automake
bc
bison
build-essential
ccache
chrpath
cloud-guest-utils
cpio
cscope
curl
device-tree-compiler
diffstat
expect
fastboot
file
flex
ftp-upload
gawk
gdisk
inetutils-ping
iproute2
libattr1-dev
libcap-dev
libfdt-dev
libftdi-dev
libglib2.0-dev
libgmp3-dev
libhidapi-dev
libmpc-dev
libncurses5-dev
libpixman-1-dev
libssl-dev
libtool
locales-all
lz4
make
mtools
netcat-openbsd
ninja-build
pip
plantuml
python-is-python3
python3-cryptography
python3-pexpect
python3-pip
python3-pyelftools
python3-serial
python3-venv
qemu-system-aarch64
rsync
sudo
unzip
uuid-dev
wget
xdg-utils
xterm
xz-utils
zlib1g-dev
zstd

The package list comes from Yocto documentation. Make sure to check the documentation if a build error is produced because of a missing package.

Python packages

Note

Python packages are not required to build TRS images. Follow this step only if you plan to change and test TRS documentation.

All Python packages are installed by default in <workspace root>/.pyvenv using a virtual Python environment. The advantage of doing so is that there will be no traces of the Python packages required for TRS if we delete the .pyvenv folder. This approach may eventually avoid conflicts with other tools that require other versions of some Python packages.

$ cd <workspace root>
$ make python-prereqs

Initial sourcing

Newly installed Python packages have to be made available to the virtual Python environment by sourcing the “activate” script.

Note

Here, you only need to do the “sourcing” step once per shell where you want to start the build. This means that if you forget to run this after spawning a new shell, your build will likely fail.

$ source <workspace root>/.pyvenv/bin/activate

Start the build

Next, we start the build, which will likely take a few hours on a standard desktop machine the first time you build it with no caches primed. The TRS is based on multiple Yocto layers and if you don’t already have the environment variables DL DIR and SSTATE DIR set, they will be set to $HOME/yocto cache by default. Note that, make clean does not clear the download and sstate caches and therefore doesn’t affect the build time negatively. The actual build is started by the following:

$ cd <workspace root>
$ make

After following the steps above, please continue with the target specific instructions, which you will find in the navigation menu to the left.

Tips and tricks

Reference local mirrors

As the project grows, the time required to do the initial repo sync increases. The repo tool can reference a locally cloned forest and clone the majority of the code from there, taking just the eventual delta between local mirrors and upstream trees. To do this, add the argument --reference to the repo init command, for instance:

$ repo init -u https://... --reference <path-to-my-existing-forest>

Use local manifests

In some cases we might want to use another remote, pick a certain commit or even add another repository to the current repo setup. The way to do that with repo is to use local manifests. The end result would be the same as manually clone or checkout a certain tag or commit. The advantage of using a local manifest is that when running repo sync, the original manifest will not override our temporary modifications. I.e., it’s possible to reference and keep using a temporary copy if needed.