# Run the Arm CCA stack using a pre-built docker container

## In this learning path

- [Introduction](https://learn.arm.com/learning-paths/servers-and-cloud-computing/cca-container/)
- [Overview: Realms](https://learn.arm.com/learning-paths/servers-and-cloud-computing/cca-container/overview/)
- [Run the Arm CCA stack using a pre-built docker container](https://learn.arm.com/learning-paths/servers-and-cloud-computing/cca-container/cca-container/)
- [Run an application in a Realm](https://learn.arm.com/learning-paths/servers-and-cloud-computing/cca-container/hello-realm/)
- [Use memory encryption](https://learn.arm.com/learning-paths/servers-and-cloud-computing/cca-container/cca-mec/)
- [Next Steps](https://learn.arm.com/learning-paths/servers-and-cloud-computing/cca-container/_next-steps/)

## Download the docker image
Start by downloading the docker container image.

This docker image contains the pre-built binaries for the Arm CCA reference software stack and the Armv-A Base Architecture Envelope Model (AEM) FVP with support for RME extensions.

Install [docker engine](https://learn.arm.com/install-guides/docker/docker-engine/) on your machine.

Pull the docker image from DockerHub:
```
docker pull armswdev/cca-learning-path:cca-simulation-v3
```

Confirm that the docker container image was downloaded successfully:
```
docker image list
```

The output should be similar to:
```
__output__
IMAGE                                                                          ID             DISK USAGE   CONTENT SIZE   EXTRA
__output__
...
__output__
armswdev/cca-learning-path:cca-simulation-v3                                   21500198bb93       1.18GB             0B
__output__
...
```

Run the docker container:
```
docker run --rm -it armswdev/cca-learning-path:cca-simulation-v3
```

You are now inside the home directory (`/home/cca`) of user `cca` in the running `armswdev/cca-learning-path:cca-simulation-v3` container.
```
__output__
cca@a9866f863546:~$
```

## Run the software stack
The pre-built binaries for the Arm CCA reference software stack are present in the `cca-3world/` directory.
```
ls cca-3world/
```

This includes the Realm Management Monitor (`rmm.img`), the host root filesystem (`host-rootfs.ext2`) and the host Linux kernel image (`Image`) and the trusted firmware binaries:
```
__output__
FVP_AARCH64_EFI.fd  Image  bl1.bin  bl2.bin  bl31.bin  dt_bootargs.dtb  fip.bin  host-rootfs.ext2  kselftests.tgz  modules.tgz  rmm.img
```

These binaries can run on an Armv-A Base Architecture Envelope Model (AEM) FVP with support for RME extensions. AEM FVPs are fixed configuration virtual platforms of Armv8-A and Armv9-A architectures with comprehensive system IP. The FVP is also contained within this docker container.

Launch the `run-cca-fvp.sh` script to run the Arm CCA pre-built binaries on the FVP:
```
./run-cca-fvp.sh
```

> **Note**: A number of `Info` and `Warning` messages will be emitted by the FVP. These can safely be ignored.

The `run-cca-fvp.sh` script uses the `screen` command to connect to the different UARTs in the FVP.

You should see the host Linux kernel boot on your terminal:
```
__output__
udhcpc: started, v1.36.1
__output__
udhcpc: broadcasting discover
...
Welcome to the CCA host
host login:
```

You will be prompted to log in to the CCA host. Enter `root` as the username (no password is required).

You have successfully booted 3 worlds (Root, Non-secure and Realm) on the FVP at this point:
- Trusted Firmware-A is running in Root.
- Realm Management Monitor (RMM) in Realm.
- Host Linux in Non-secure.

## Create a virtual guest in a Realm
Guest VMs can be launched in a Realm using `kvmtool` from your host Linux prompt. The realm disk image `guest-disk.img` is included into the host file system.

Use `kvmtool` to launch guest Linux in a Realm:
```
cd /cca
./lkvm run --realm --disable-sve --irqchip=gicv3-its --firmware KVMTOOL_EFI.fd -c 1 -m 512 --no-pvtime --force-pci --disk guest-disk.img --measurement-algo=sha256 --restricted_mem
```

You should see the guest Linux kernel starting to boot in a Realm. This step can take several minutes.

After boot up, you will be prompted to log in at the guest Linux prompt, use the `root` username (no password required):
```
__output__
udhcpc: started, v1.36.1
__output__
Welcome to the CCA realm
realm login:
```

You have successfully created a virtual guest in a Realm using the Arm CCA reference software stack.

## Obtain a CCA attestation token from the virtual guest in a Realm
Attestation tokens are small reports that are produced by a device upon request. Those tokens are composed of key/value pairs called claims. A CCA attestation token is a collection of claims about the state of a Realm and the CCA platform on which the Realm is running.

Refer to [section A7.2 of the Realm Management Monitor Specification](https://developer.arm.com/documentation/den0137/latest/) to learn about the details of the CCA attestation token.

The retrieval of a CCA attestation token from a running guest is done by reading from `/sys/kernel/config/tsm/report/`. This is available when Linux’s `configfs` has been mounted, which has been done automatically as part of the guest boot process — if you are curious, this is the `configfs /sys/kernel/config configfs defaults 0 0` line in `/etc/fstab`.

You can now generate an attestation token by running the following commands:
```
report=/sys/kernel/config/tsm/report/report0
mkdir $report
dd if=/dev/urandom bs=64 count=1 > $report/inblob
hexdump -C $report/outblob
```

The output should look like:
```
__output__
00000000  d9 01 8f a2 19 ac ca 59  05 ee d2 84 44 a1 01 38  |.......Y....D..8|
...
```

The output is a CCA attestation token from the guest in the Realm. The CCA attestation token is a Concise Binary Object Representation (CBOR) map, in which the map values are the Realm token and the CCA platform token.

You have successfully generated a CCA attestation token from the guest. In later learning paths, you will learn how to use these tokens as part of the Arm CCA attestation flow.

You can now shut down the guest. Use the `poweroff` command.

You should see the following output from the guest:
```
__output__
(realm) # Destroying macvtap... OK
Stopping crond: stopped /usr/sbin/crond (pid 120) OK
...
The system is going down NOW!
```

The guest has shut down and you are back at the host Linux kernel prompt.

To exit the host session and the simulation, use `poweroff`. You will be placed back into the running docker container.

To exit the docker container, run `exit`.

In the next section, you will learn how to run a simple application inside the Realm.

> **Note**: The docker session has been started with the `--rm` option, which means the container will be destroyed when it is exited, allowing you to experiment with the images without fear: at the next session, you will get working pristine images! If you intend your changes to persist across docker sessions, omit the `--rm` option to docker.
