Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Base repository and Virtual Disk Structure

All the instructions below are executed from the $(BASE) directory.

Code Block
mkdir $BASE
cd $BASE
mkdir -p images/disks/virtual/efi/boot

TF-RMM

The Realm Management Monitor (RMM) connects KVM and the Realm guest.

RMM gets loaded into NS DRAM (because there isn't enough space in Secure RAM). TF-A carves out 24MB 1GB of memory for the RMM (0x40100000-0x418fffff on the virt platform), and tells other software about it using a device-tree reserved memory node. The RMM is located at the base of the system RAM, i.e 0x10000000000, and the device tree move upward by 1GB. Modifications to the device tree are made dynamically by TF-A’s BL31.

Status: QEMU support has been merged. Additional patches are needed until PMUv3p7 is supported by QEMU.

Repo: extra patches are at https://git.codelinaro.org/linaro/dcap/rmm branch cca/v3
official repo is https://git.trustedfirmware.org/TF-RMM/tf-rmm.git/

Build:

Code Block
git clone -b cca/v3 https://git.codelinaro.org/linaro/dcap/rmm.git
cd rmm
git submodule update --init --recursive
export CROSS_COMPILE=aarch64-none-elf-
cmake -DCMAKE_BUILD_TYPE=Debug -DRMM_CONFIG=qemu_virtsbsa_defcfg -B build-qemusbsa
cmake --build build-qemu

Host EDK2

Edk2 is the firmware used in non-secure world. It works out of the box. However, we rely on edk2 not allocating memory from the DRAM area reserved for the RMM at the moment, which is fragile. Future work will add support for the reserved memory node provided by TF-A in the device-tree.

...

sbsa
cp build-sbsa/Debug/rmm.img ../images/

EDK2-NON-OSI

Code Block
git clone https://github.com/tianocore/

...

edk2

...

Build:

Code Block
git submodule update --init --recursive
source edksetup.sh
make -j -C BaseTools
export GCC5_AARCH64_PREFIX=aarch64-linux-gnu-
build -b RELEASE -a AARCH64 -t GCC5 -p ArmVirtPkg/ArmVirtQemuKernel.dsc-non-osi.git

TF-A

TF-A loads the RMM as well as the Non-secure firmware, and bridges RMM and KVM. It also owns the Granule Protection Table (GPT).

...

Repo: currently at https://git.codelinaro.org/linaro/dcap/tf-a/trusted-firmware-a branch cca/v3
official is https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/

Build:

Code Block
#git Embedclone the RMM image and edk2 into the Final Image Package (FIP)
-b cca/v3 https://git.codelinaro.org/linaro/dcap/tf-a/trusted-firmware-a.git
cd trusted-firmware-a
make -j CROSS_COMPILE=aarch64-linux-gnu- PLAT=qemu_sbsa ENABLE_RME=1 RME_GPT_BITLOCK_BLOCK=1 \
    DEBUG=1 LOG_LEVEL=40 \
    QEMU_USE_GIC_DRIVER=QEMU_GICV3 RMM=../rmm/build-qemusbsa/Debug/rmm.img \
    BL33=../edk2/Build/ArmVirtQemuKernel-AARCH64 all fip
# Copy firmware images to EDK2 staging directory
cp build/qemu_sbsa/debug/bl1.bin ../edk2-non-osi/Platform/Qemu/Sbsa/
cp build/qemu_sbsa/debug/fip.bin ../edk2-non-osi/Platform/Qemu/Sbsa/

EDK2-PLATFORMS

Code Block
git clone -b cca/v3 https://git.codelinaro.org/linaro/dcap/edk2-platforms.git
cd edk2-platforms
git submodule update --init

Host EDK2

Repo: https://github.com/tianocore/edk2.git

Build:

Code Block
# We need commit "a19f50bb95f7" because it works with the version of edk2-platforms.git we have on codeLinaro (above)
git clone https://github.com/tianocore/edk2.git
cd edk2
git reset --hard a19f50bb95f7
git submodule update --init
cd $BASE
export PACKAGES_PATH=$PWD/edk2:$PWD/edk2-platforms:$PWD/edk2-non-osi
export GCC5_AARCH64_PREFIX=aarch64-linux-gnu-
. edk2/edksetup.sh
make -C edk2/BaseTools
build -b RELEASE -a AARCH64 -t GCC5 -p edk2-platforms/Platform/Qemu/SbsaQemu/SbsaQemu-rme.dsc
truncate -s 256M Build/SbsaQemu-rme/RELEASE_GCC5/FV/SBSA_FLASH0.fd
truncate -s 256M Build/SbsaQemu-rme/RELEASE_GCC5/FV/SBSA_FLASH1.fd
cp Build/SbsaQemu-rme/RELEASE_GCC5/FV/SBSA_FLASH0.fd images/
cp Build/SbsaQemu-rme/RELEASE_GCC5/FV/QEMUSBSA_EFIFLASH1.fd all fip
# Pack whole image into flash.bin
dd if=build/qemu/debug/bl1.bin of=flash.bin
dd if=build/qemu/debug/fip.bin of=flash.bin seek=64 bs=4096images/

UEFI SHELL

The UEFI Shell is needed to start the Linux kernel without manual intervention.

Code Block
build -b RELEASE -a AARCH64 -t GCC5 -p ShellPkg/ShellPkg.dsc --pcd gEfiShellPkgTokenSpaceGuid.PcdShellScreenLogCount=8
$ cp Build/Shell/RELEASE_GCC5/AARCH64/Shell_EA4BB293-2D7F-4456-A681-1F22F42CD0BC.efi images/disks/virtual/efi/boot/bootaa64.efi

UEFI Vitual Disk boot structure

UEFI uses a virtual disk to store the Linux kernel image and the startup arguments. The Linux image is compiled as part of the steps depicted in the common instructions.

Code Block
cp $(DIRECTORY_TO_CCA/V3_LINUX_IMAGE)/Image images/disks/virtual/
cp startup.nsh  images/disks/virtual/startup.nsh

# The content of startup.nsh is:
mode 100 31
pci
fs0:\Image root=/dev/vda console=hvc0
reset -c

# After the above, the UEFI boot structure should look like:
disks/
└── virtual
    ├── efi
    │   └── boot
    │       └── bootaa64.efi
    ├── Image
    └── startup.nsh