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.