19. Building with Shrinkwrap
This document explains how to build and run RMM in FVP, including all necessary firmware images, by using Shrinkwrap.
19.1. Introduction
Shrinkwrap is a tool that helps to simplify the process of building and running firmware on Arm FVP by providing an intuitive command line interface frontend and (by default) a container-based backend.
Shrinkwrap works by using configs, which are defined in YAML and can be easily extended using a built-in layering system.
For instructions on how to setup Shrinkwrap on your local machine as well as for further information, you can refer to the Quick Start Guide. In particular, for development with RME enabled Linux in Normal World, please refer to the 3 world configuration. In case that the Secure World also needs to be included, please refer to the 4 world configuration
19.2. Setup local RMM with Shrinkwrap
This section assumes that you have your local RMM repository cloned and that it is used for your development. In order to help using Shrinkwrap with your development workflow, the project provides some configs and overlays.
Also, from now on, it is assumed that your current directory (pointed by
${PWD}) is the root of your RMM development repository.
In order to use the configs defined in RMM, it is essential to configure
the ${SHRINKWRAP_CONFIG} environment variable to point to
${PWD}/tools/shrinkwrap/configs directory so the tool can locate the
config yaml files.
export SHRINKWRAP_CONFIG=${PWD}/tools/shrinkwrap/configs
It is also recommended to override the default ${SHRINKWRAP_BUILD} and
${SHRINKWRAP_PACKAGE} environment variables to a known workspace directory,
as shown below:
export WORKSPACE=${HOME}/workspace export SHRINKWRAP_BUILD=${WORKSPACE} export SHRINKWRAP_PACKAGE=${SHRINKWRAP_BUILD}/package
When building, Shrinkwrap will store the sources inside
${SHRINKWRAP_BUILD}/source/<CONFIG_NAME> and the build artifacts and
packages will be stored inside ${SHRINKWRAP_BUILD}/build/<CONFIG_NAME> and
${SHRINKWRAP_PACKAGE}/<CONFIG_NAME> directories respectively.
Note
By default, if ${SHRINKWRAP_BUILD} and ${SHRINKWRAP_PACKAGE} are not
specified, Shrinkwrap will use the ${HOME}/.shrinkwrap as default
value for ${SHRINKWRAP_BUILD}. It is only necessary to overwrite the
environment variables in the case it is needed to build in a different
location.
19.3. 3-World testing
RMM provides a number of overlays that can be used in conjunction with some
of the configs provided by Shrinkwrap. One of the overlays, specifically
rmm.yaml, can be used along with the cca-3world.yaml to
build a 3 World demonstrator using the master branch of TF-A and the
local RMM repository.
As an example, the following command line would build the 3-World demonstrator.
It assumes that Shrinkwrap is called from within the <RMM_ROOT> directory:
shrinkwrap build cca-3world.yaml --overlay=buildroot.yaml --overlay=rmm.yaml --btvar=GUEST_ROOTFS='${artifact:BUILDROOT}' --btvar=RMM_SRC=${PWD} --no-sync=rmm
You can find further instructions on how to build and package the filesystem and required binaries in the 3 world configuration documentation.
To run the demonstrator, use the following command:
shrinkwrap run cca-3world.yaml --rtvar=ROOTFS=${SHRINKWRAP_PACKAGE}/cca-3world/rootfs.ext2
19.4. 3-World testing with CCA DA
Clone TF-RMM repository at branch topics/da_alp12
git clone https://git.trustedfirmware.org/TF-RMM/tf-rmm.git
Follow the instructions in Setup local RMM with Shrinkwrap to setup the local RMM with shrinkwrap.
RMM provides cca_da.yaml overlay that can be used along with the
cca-3world.yaml to build a 3 World demonstrator using the master branch
of TF-A, cca/tdisp-upstream-post-v1.3 branch of Linux kernel,
kvmtool, and the local clone of RMM repository from main branch.
As an example, the following command line would build the 3-World demonstrator.
It assumes that Shrinkwrap is called from within the <RMM_ROOT> directory
that was created in the last step:
shrinkwrap build cca-3world.yaml --overlay=cca_da.yaml --btvar GUEST_ROOTFS='${artifact:BUILDROOT}' --btvar RMM_SRC=${PWD} --no-sync=rmm
Follow the steps mentioned in 3 world configuration documentation to copy guest-disk.img, KVMTOOL_EFI.fd and lkvm to the host filesystem.
Shrinkwrap expects the FVP binary (FVP_Base_RevC-2xAEMvA) to be in your
PATH. The runtime=null option is used to run the FVP directly from the PATH,
without using the Docker container. Make sure that the FVP version is 10034 or higher,
as older FVP versions have issues that prevent this demo from working.
Now you can boot the host, using the rootfs we just modified.
shrinkwrap --runtime=null run cca-3world.yaml --overlay=cca_da.yaml --rtvar ROOTFS=${SHRINKWRAP_PACKAGE}/cca-3world/rootfs.ext2
Finally, once the host has booted, log in as “root” (no password). Below are the device assignment workflow based on the DA workflow cover letter from the Linux kernel prototype branch.
Connect the device with TSM, this establishes secure session to the device and enables IDE in the link.
echo 0000:02:00.0 > /sys/bus/pci/devices/0000:02:00.0/driver/unbind echo vfio-pci > /sys/bus/pci/devices/0000:02:00.0/driver_override echo 0000:02:00.0 > /sys/bus/pci/drivers_probe echo tsm0 > /sys/bus/pci/devices/0000:02:00.0/tsm/connect
Now, launch a realm using kvmtool from the /cca directory (that was created above):
cd /cca ./lkvm run --realm -c 2 -m 256 --disk guest-disk.img --kernel Image -p "earlycon=uart,mmio,0x101000000 root=/dev/vda2" --iommufd-vdevice --vfio-pci 0000:02:00.0
Be patient while this boots to the shell.
Now in the Realm we follow the below steps on the assigned device to move the device to TDISP LOCKED and RUN state. At this step the Realm verifies the device attestation evidence that it got from the Host are valid by computing the digest and comparing it with the value it got from the RMM.
echo 0000:00:00.0 > /sys/bus/pci/devices/0000:00:00.0/driver/unbind echo tsm0 > /sys/bus/pci/devices/0000:00:00.0/tsm/lock echo 1 > /sys/bus/pci/devices/0000:00:00.0/tsm/accept
Load the driver
echo 0000:00:00.0 > /sys/bus/pci/drivers_probe
If everything went well, you should see the driver loading and the following lines in the console:
ata1: SATA max UDMA/133 abar m8192@0x50006000 port 0x50006100 irq 22 lpm-pol 1 ata1: SATA link up 6.0 Gbps (SStatus 133 SControl 300) ata1.00: ATA-10: ahci-disk.img, 0.1.0, max MWDMA2 ata1.00: 131072 sectors, multi 0: LBA48 NCQ (depth 1) ata1.00: configured for PIO4 scsi 0:0:0:0: Direct-Access ATA ahci-disk.img 0 PQ: 0 ANSI: 5 sd 0:0:0:0: [sda] 131072 512-byte logical blocks: (67.1 MB/64.0 MiB) sd 0:0:0:0: [sda] Write Protect is off sd 0:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA sd 0:0:0:0: [sda] Preferred minimum I/O size 512 bytes sd 0:0:0:0: [sda] Attached SCSI disk
Also the device should be visible as a device in /dev , in this case /dev/sda will be visible. You can now partition, format and mount the device as you would do with any other block device.
19.5. Testing RMM with TFTF
RMM provides a config that brings together a software stack to test RMM and Arm RME extension utilizing TF-A-Tests. The main Test payload in TF-A-Tests is the TFTF binary. In this config, TF-A is in Root World, RMM is in Realm EL2 and TFTF is in Normal World.
In order to build the config, you need to run the following command:
shrinkwrap build --btvar=RMM_SRC=${PWD} rmm-tftf.yaml --no-sync=rmm
and you can run it through
shrinkwrap run rmm-tftf.yaml
For further documentation about this configuration, you can check the docs through
shrinkwrap inspect rmm-tftf.yaml
The build and run commands can also be found in the documentation of the config
yaml file. When invoking the build command, Shrinkwrap will store the
external repositories inside the ${SHRINKWRAP_BUILD}/sources/<CONFIG_NAME>
directory.
19.6. Overlays
Overlays can be used to extend the functionality of a config by overwriting both build and runtime settings. They can be used on any configuration and they can be combined in any way needed.
In order to use an overlay, they need to be specified on the command line, through
the --overlay keyword, as follows:
shrinkwrap build rmm-tftf.yaml --btvar=RMM_SRC=${PWD} --overlay=<OVERLAY_FILE_NAME> --no-sync=rmm
The path to the overlay can be relative to where Shrinkwrap is called from and you
can use as many --overlay statements as needed.
Overlays are stored in the <RMM_ROOT_DIR>/tools/shrinkwrap/configs/ directory,
alongside with the configuration files.
The available Overlays are sumarized in the next table
Overlay |
Description |
|---|---|
model-enable-lpa2.yaml |
Overlay used to enable |
model-enable-mec.yaml |
Overlay used to enable |
model-wait-debugger.yaml |
Overlay to configure the FVP model to listen for Iris connections on port 7100 and make it wait until a debugger is connected before starting execution |
model-enable-s2pie-s2poe.yaml |
Overlay to enable |
model-enable-feat_d128.yaml |
Overlay used to enable |
rmm-debug.yaml |
|
rmm-v1_1.yaml |
Overlay to build RMM with v1.1 features |
clean.yaml |
Overlay used to avoid an exception with |
19.6.1. Example of use
Below is an example on how to use one of the available overlays with the
existing configuration. The example specifies --runtime=null to use the
native toolchain (without the Docker container) to build the artifacts and
--no-sync-all to prevent Shrinkwrap from updating/cleaning any of the
repositories:
shrinkwrap --runtime=null build rmm-tftf.yaml --overlay=model-enable-lpa2.yaml --btvar=RMM_SRC=${PWD} --no-sync-all
Similarly you can use overlay rmm-v1_1.yaml to enable RMM v1.1 features along with rmm-debug.yaml to enable debug build.
shrinkwrap --runtime=null build rmm-tftf.yaml --overlay=rmm-v1_1.yaml --overlay=rmm-debug.yaml --btvar=RMM_SRC=${PWD} --no-sync-all
Then you run your tests with
shrinkwrap --runtime=null run rmm-tftf.yaml
Note
Note that runtime=null is specified for the run, as it must match
the same setting as used on the build stage. Also, with this setting,
the appropriate FVP (FVP_Base_RevC-2xAEMvA) needs to be present in the
system ${PATH}.
FVP version must be >= 11.29.27 when rmm-v1_1.yaml overlay is used.