How To: Glibc + Linux + FVP
Yury Khrustalev
yury.khrustalev@arm.com
Tue Jun 10 15:08:36 GMT 2025
HOW TO: GLIBC + LINUX + FVP
---------------------------
2025-06-10 v0.2
Introduction
============
This how-to guide can be useful for developers who wish to run a Linux system
(optionally using a custom kernel and a custom C library) on an Arm Fixed
Virtual Platform (FVP) model. For example, this guide might be useful if you
want to test patches for the Linux kernel or Glibc.
Prerequisites:
* An AArch64 or x86 host running a Linux system.
* GCC cross toolchain for the `aarch64-none-linux-gnu` target.
* Docker.
* Git to checkout sources.
* Make to build the tools.
* Bash for your shell.
* Python 3.x and `pip` to create a Python virtual environment.
* Common tools like `wget`, `unxz`, `truncate`.
For a few things you will need root access on your host system to do minimal
setup and install packages that are described in the following sections
(in which case the commands will be prefixed with `sudo`), however most of the
setup can be done as a normal user.
History
=======
v0.2 Update instructions related to the IP address of the guest system
due to recent update to the Shrinkwrap tool.
v0.1 Initial version.
https://inbox.sourceware.org/libc-help/Z9grjmNzxsuPu7iD@arm.com/
Naming conventions
==================
In the following sections we use host system to checkout sources and build
various tools and we also make configuration changes to the guest system that
will run on the Arm Fixed Virtual Platform (FVP) model [1].
Before we begin, it's important to describe the specifics of our setup making it
easier to write commands and code examples. Wherever possible we use generic
commands and code examples but in certain places we have to use hardcoded
values and absolute paths.
--------------------------------------------------------------------------------
| Path | Description |
--------------------------------------------------------------------------------
| /path/to/cross/gcc | GCC cross toolchain installation folder |
| /home/user | Home folder of your host non-root user |
| /home/user/workspace | Workspace directory |
| /home/user/workspace/linux | Folder with the Linux kernel sources |
| /home/user/workspace/linux-headers | Directory for installing kernel headers |
| /home/user/workspace/linux-build | Folder for the Linux kernel build files |
| /home/user/workspace/glibc | Folder for the Glibc sources |
| /home/user/workspace/glibc-build | Directory for the Glibc build output |
--------------------------------------------------------------------------------
We use `user` as the username for the non-root user on your host system.
We will presume that the GCC cross toolchain installation directory contains
everything a cross toolchain would need, for example, the path to the `gcc` tool
would be `/path/to/cross/gcc/bin/aarch64-none-linux-gnu-gcc`.
In the next steps we are going to create a Python virtual environment. It does
not matter where it is located, but to avoid ambiguity let's presume it is in
the `~/workspace/venv` directory.
[1] https://developer.arm.com/downloads/-/arm-ecosystem-fvps
Build Linux kernel
==================
The Linux kernel image is the first essential components that we need. We are
going to build it from source.
There are various ways to obtain the sources for a particular version of the
Linux kernel that you want to use. Here, as an example, we obtain a stable
version from the mainline repository:
```
mkdir -p ~/workspace
cd ~/workspace
git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
pushd linux
git checkout v6.15 -b release/6.15
popd
```
Using a stable kernel version is a good starting point. When everything is up
and running, you can switch to the version of the kernel that you are actually
interested in.
The following commands will configure and build the Linux kernel image. All the
build output, including the binary that we intend to use later, will be put in
the `linux-build` subfolder. Run the following commands in the workspace
directory:
```
# Make sure that cross GCC is on the PATH
export PATH=/path/to/cross/gcc/bin:${PATH}
# Use out-of-tree build for kernel
export KBUILD_OUTPUT="$(pwd)/linux-build"
# Specify target architecture
export ARCH=arm64
# Specify cross compiler
export CROSS_COMPILE=aarch64-none-linux-gnu-
# Build kernel image
make -C linux mrproper
make -C linux defconfig
make -C linux Image -j $(nproc)
```
The `mrproper` target is used to clean the build folder. It will also create
this folder if it doesn't exist. The `defconfig` target generates the default
configuration for the selected architecture, `arm64`. At this point, you may
change this configuration if necessary, for example, if the feature that you
are interested in is not enabled by default. To do this, you would usually run
`make menuconfig` in the `linux-build` folder. Finally, building the `Image`
target will produce the binary that we need.
When the build completes, check that the kernel image binary is present:
```
ls linux-build/arch/arm64/boot/Image
```
If any of the described steps result in an error message, most likely some of
the build dependencies are not installed. You should be able to obtain them
from your distro's package manager.
Root file system
================
The root file system (or rootfs for short) is the second essential component
that we need. The root file system is a collection of files that are essential
for a Linux system to function. Usually, it also includes various tools that
make using your system more convenient.
Since we provide our own kernel, there isn't much that is required from a
rootfs. All you need is for it to be built for the AArch64 target and contain
the tools that you require.
To speed things up for this learning path, we use a readily available rootfs for
the Void Linux [2] distro. There are other options for obtaining a working
root file system, but the rest of this learning path assumes that you are using
the Void Linux distribution.
Download the image:
```
cd ~/workspace
BASEURL=https://repo-default.voidlinux.org/live
VERSION=20250202
wget ${BASEURL}/${VERSION}/void-rpi-aarch64-${VERSION}.img.xz
```
Let's unpack and resize the image. The added size determines how much free disk
space we will have in our guest system:
```
unxz --keep void-rpi-aarch64-20250202.img.xz
mv void-rpi-aarch64-20250202.img rootfs.img
truncate -s +2G rootfs.img
```
Here we add 2 GiB of free space. Of course, the file system in this image is not
actually resized at this point. Void Linux will be able to do it automatically
during the first boot.
Note that when we run our system, the rootfs image file will be modified. If
something goes wrong, the image might be corrupted, and you might not be able
to boot from it again. That's why it's recommended to create a backup copy
after the initial setup.
[2]: https://voidlinux.org/
Boot Linux on FVP
=================
During this step, we will set up everything for the FVP to run and then boot the
Linux system using the kernel and the root file system that we prepared
earlier.
Arm Fixed Virtual Platform (FVP) [1] is a model that allows you to access
functionality of Armv8.x or v9.x hardware. We use the Armv-A Base Rev C
Architecture Envelope Model (AEM).
In addition to the model itself, you also need the device tree and the firmware.
To simplify building these components, we use a tool called Shrinkwrap [3]. This
tool comes with a detailed user guide [4] that covers all of its features and
configuration options. Here, we provide a short quick-start guide.
We also rely on a Docker container to facilitate the building of the firmware
and running the FVP. This helps avoid installing all the dependencies on your
host system. Shrinkwrap can be used without Docker but it requires extra steps
to ensure that all dependencies are of the right version and are installed
correctly.
First, we install prerequisites in a Python virtual environment using Python 3:
```
python -m venv ~/workspace/venv
source ~/workspace/venv/bin/activate
pip install -U pip setuptools wheel
pip install pyyaml termcolor tuxmake
```
Shrinkwrap can be used directly from the source, which can be checked out from
its Git repository. Run this command in the workspace directory:
```
git clone https://git.gitlab.arm.com/tooling/shrinkwrap.git
export PATH=${PATH}:$(pwd)/shrinkwrap/shrinkwrap
```
Putting Shrinkwrap's main executable on your `PATH` is all you need to install
the tool. To check that it works, ensure that the Python virtual environment we
created earlier is activated, then run this command:
```
shrinkwrap --version
```
Before proceeding, ensure that Docker is installed and usable. Follow the
installation instructions for your distro [5].
Now, we use the Shrinkwrap tool to build the firmware, the third essential
ingredient in our setup. The following step needs to be done once although you
will need to repeat it if you want to rebuild the firmware. Run in the workspace
directory:
```
shrinkwrap build --overlay=arch/v9.5.yaml ns-edk2.yaml
```
This command uses the `arch/v9.5.yaml` config that enables Armv9.5 hardware
features. This config is included with the Shrinkwrap installation. We also use
the `ns-edk2.yaml` config. This configuration file is also a part of the
Shrinkwrap tool. It defines the settings for building and running the firmware
using EDK2 on Arm FVPs. The build process takes some time. During this step,
Shrinkwrap downloads the required Docker image and starts a container to clone
all the required firmware repositories and build the components including the
device tree for the FVP.
At this point, we have everything required to boot our system. Shrinkwrap uses
so called overlay configuration files. The following file instructs Shrinkwrap
to connect all the pieces together and locate the kernel image, and rootfs. It
can also be used to tweak any of the FVP parameters. Save this file as
`~/workspace/aarch64.yaml`:
```
run:
rtvars:
ROOTFS:
value: /home/user/workspace/rootfs.img
CMDLINE:
value: ip=dhcp kpti=off root=/dev/vda2 console=ttyAMA0
KERNEL:
value: /home/user/workspace/linux-build/arch/arm64/boot/Image
params:
-C bp.hostbridge.userNetworking: 1
-C bp.hostbridge.userNetPorts: 8022=22,8123=8123
-C bp.smsc_91c111.enabled: 1
-C bp.virtio_net.enabled: 0
-C cluster0.NUM_CORES: 1
-C cluster1.NUM_CORES: 0
-C pctl.CPU-affinities: 0.0.0.0
```
The most important parts in this configuration file are:
* Paths to the rootfs image and the kernel image.
* The kernel command line, which contains `root=/dev/vda2`, specifying where to
locate the filesystem to be mounted at `/`.
* The port mapping `8022=22`, which is used for SSH access into the guest
system. You can add more ports as needed (e.g. for the GDB server).
The FVP has many parameters that can be tweaked in this config by adding a
`-C param: value` line to the `params` section. Refer to the Fast Models Fixed
Virtual Platforms Reference Guide [6] for more details.
To run the FVP using Docker, execute the following command:
```
shrinkwrap run ns-edk2.yaml --overlay ~/workspace/aarch64.yaml
```
At first, Shrinkwrap starts a Docker container and runs the FVP in it. At the
beginning of the output, you may see a line containing the IP address that you
need to use for SSH access into the guest system (A.B.C.D in this example):
```
Press '^]' to quit shrinkwrap.
All other keys are passed through.
Environment ip address: A.B.C.D.
```
We will use this IP address in the following setup.
It also tells you how to stop the FVP execution: press `Ctrl+]` (more on this
later, the gist is that you should only interrupt running system like that as
a last resort).
Booting the Linux on the FVP takes some time. Look out for the system log
messages about growing the root partition to utilize the empty disk space we
created earlier.
```
=> Growing root partition
CHANGED: partition=2 ... old: size=1316864 ... new: size=5511135
```
After a couple of minutes, you should be able to SSH in a different terminal
into the guest OS running on the FVP using the IP address reported by the
Shrinkwrap tool and the port number specified earlier in our overlay config:
```
ssh root@A.B.C.D -p 8022
```
The default password is `voidlinux`.
When you have logged in, check the properties of your guest system, for example:
```
uname -a
cat /proc/cpuinfo
```
We will do more setup during the next step. This additional setup is optional
but it helps prepare our guest system for running Glibc tests and doing other
complex tasks.
You can always press `Ctrl+]` to stop Shrinkwrap in the terminal where
Shrinkwrap is running. However, this abruptly aborts execution of the FVP. This
may leave the filesystem in your rootfs image, used by the guest system, in a
broken state, resulting in errors during the next boot. To avoid this, it is
advisable to shut down the guest system gracefully from the root console of
your guest system, for example:
```
ssh root@A.B.C.D -p 8022 poweroff
```
[3]: https://gitlab.arm.com/tooling/shrinkwrap
[4]: https://shrinkwrap.docs.arm.com/en/latest
[5]: https://docs.docker.com/engine/install/
[6]: https://developer.arm.com/documentation/100966/latest
A few tips about Void Linux
===========================
For a detailed guide on Void Linux, refer to the Void Linux documentation [7].
Commands in this section are executed on the guest system.
It is recommended to use Bash as your default shell on the guest system. To
change the default shell for the root user, run this command:
```
chsh -s /bin/bash root
```
If you need to install some package, use the following commands:
```
# Update repository cache (you need to run this once)
xbps-install -y -S
# In some cases you may have to update xbps utility:
xbps-install -u -y xbps
# Install vim package (for example):
xbps-install -y vim
```
We can add a bit of automation to speed up configuring your system from scratch:
```
# Install packages: required and optional
required=(nfs-utils sv-netmount rpcbind)
optional=(vim binutils make strace python3)
for p in "${required[@]}" "${optional[@]}"; do
xbps-query -l | grep -w ${p} > /dev/null || {
xbps-install -y ${p}
}
done
```
Installing the required packages is important for the following steps. Choose
optional packages according to your use case. You can always install or remove
packages later.
The rootfs image that we are using is limited in size, and it might be useful
to free up some space. Since we use our own kernel and firmware, we can safely
delete the following packages:
```
# Remove unused packages:
unused=(rpi-firmware rpi-kernel)
for p in "${unused[@]}"; do
test -f "/etc/xbps.d/disable-${p}.conf" || {
echo "ignorepkg=${p}" > "/etc/xbps.d/disable-${p}.conf"
xbps-remove -y ${p}
}
done
```
Here, we also mask these packages to prevent them from being installed
automatically during system updates, saving time in the process.
The last two code snippets are written so that you can re-run them multiple
times. If a change has already been applied, it will be skipped.
Optionally, to update your guest OS, run:
```
xbps-install -y -Su
```
[7]: https://docs.voidlinux.org/
Lightweight SSH server
======================
Commands in this section are executed on the guest system.
Our main interaction with the guest system will be via SSH. Running software on
an FVP is slower than on real hardware, so we want to reduce the overhead. One
way to do this is by replacing the pre-installed OpenSSH server with a more
lightweight alternative, such as Dropbear [8].
First, install Dropbear and enable corresponding service:
```
# Install Dropbear server
xbps-query -l | grep -w dropbear > /dev/null || {
xbps-install -y dropbear
}
# Enable Dropbear SSH server service
test -h /var/service/dropbear || {
ln -s /etc/sv/dropbear /var/service/
}
```
Now, disable the OpenSSH server:
```
# Disable OpenSSH server service
test -h /var/service/sshd && {
sv stop sshd
rm -vf /var/service/sshd
}
```
Finally, create a simple service that prints a message to the system log when
the guest system is ready for incoming SSH connections:
```
# Create service to indicate SSH readiness
test -h /var/service/hello || {
mkdir -p /etc/sv/hello
cat <<EOF > /etc/sv/hello/run
#!/bin/bash
sv status dropbear || exit 1
. /etc/runit/functions
msg "SSH service is ready"
sv stop hello
EOF
chmod a+x /etc/sv/hello/run
ln -s /etc/sv/hello /var/service/
}
```
During the next boot, you should see this message in the system log. You might
also experience an improvement in SSH connection speed:
```
=> Initialization complete, running stage 2...
...
=> SSH service is ready
```
[8]: https://matt.ucc.asn.au/dropbear/dropbear.html
Configure SSH on host
=====================
Commands in this section should be run on the host system.
Using a password for SSH can be inconvenient when automating tasks. The solution
is to set up authentication via SSH keys. Since we are using the Dropbear
server, we need to use the Dropbear client and configure SSH keys for it.
First, install the Dropbear client:
```
sudo apt install dropbear-bin
```
To avoid typing the guest system's IP address every time, add it to
`/etc/hosts`:
```
127.0.2.1 fvp
```
Explanation: FVP will establish port forwarding from the host into the guest
system (remember the `bp.hostbridge.userNetPorts` FVP parameter), so you can
access the guest system via your host's IP address. You could just use `localhost`
instead, but `fvp` makes it more explicit.
Now, create an SSH key and upload its public part to the guest system:
```
test -f ~/.ssh/id_dropbear || dropbearkey -t rsa -f ~/.ssh/id_dropbear
dbclient -l root -p 8022 fvp mkdir -p .ssh
dropbearkey -y -f ~/.ssh/id_dropbear | grep "^ssh-rsa " | \
dbclient -l root -p 8022 -T fvp "cat >> .ssh/authorized_keys"
```
Check that you can SSH into the guest system using the Dropbear SSH client
without entering a password:
```
dbclient -l root -p 8022 fvp
```
Non-root user
=============
Commands in this section are executed on the guest system.
Creating a non-root user in the guest system can be practical. Additionally, we
will copy the same SSH key used for the root user to avoid setting up different
key pair and having to alternate between them. For a non-root user in the guest
system we will use the same username `user` as on your host system.
SSH into the guest system and run these commands as root to create a new user:
```
# Create user
id -u user 2> /dev/null || {
useradd -m -s /bin/bash user
}
test -d /home/user/.ssh || {
mkdir -p /home/user/.ssh
chown user:user /home/user/.ssh
chmod 0700 /home/user/.ssh
}
test -f /root/.ssh/authorized_keys && {
cp /root/.ssh/authorized_keys /home/user/.ssh/authorized_keys
chown user:user /home/user/.ssh/authorized_keys
chmod 0600 /home/user/.ssh/authorized_keys
}
```
Now, you should be able to SSH into the guest system running on the FVP as a
non-root user without having to enter a password:
```
dbclient -p 8022 fvp
```
Shared workspace
================
Commands in this section are executed first on the host system and then on the
guest.
It is useful to share a folder between the host and guest systems to facilitate
file exchange. This is especially useful for running Glibc tests, as we will
see in the following steps.
To enable file sharing, we leverage the local network set up by Docker and
configure an NFS share. The FVP offers a Plan 9 filesystem protocol server as
an alternative to using NFS, but it does not currently support some file system
operations such as `flock` which is used, for example, by the Glibc tests, so
it is not suitable for our use case.
On your host, install the NFS server (this example is for Debian or Ubuntu):
```
sudo apt install nfs-kernel-server
sudo systemctl disable nfs-kernel-server
```
Add this line to the `/etc/exports` file (we presume that host user ID is `1000`
and group ID is `1000`, amend according to your actual setup):
```
/home/user/workspace A.B.C.D/32(rw,sync,no_subtree_check,all_squash,anonuid=1000,anongid=1000,insecure)
```
We allow access only from the localhost (`A.B.C.D/32`) and use the `insecure` option
to avoid complexities of requiring privileged ports on the guest system. To ensure
that the file permissions are aligned between the guest and the host systems, we also
specify `anonuid` and `anongid` options.
Note: `A.B.C.D` is the IP address reported by Shrinkwrap at startup which is your
host's primary IP address.
Restart the NFS server for the changes to take effect:
```
sudo systemctl restart nfs-kernel-server
```
Now, SSH into the guest system as root and continue the setup on the guest side:
```
mkdir -p /home/user/workspace
chown user:user /home/user/workspace
```
Edit the guest system's `/etc/fstab` to mount the NFS share automatically when
the system running on the FVP boots:
```
grep "FVP NFS shared folder" /etc/fstab > /dev/null || {
echo "# FVP NFS shared folder" >> /etc/fstab
echo "A.B.C.D:/home/user/workspace /home/user/workspace nfs4 defaults,_netdev 0 0" >> /etc/fstab
}
```
Finally, enable the necessary services for the NFS mounting:
```
services=(netmount rpcbind statd)
for s in "${services[@]}"; do
test -h /var/service/${s} || {
ln -s /etc/sv/${s} /var/service/
}
done
```
At the next boot, you should be able to SSH into the guest system as a non-root
user and access files in the workspace directory, which should be synchronized
between the guest and the host systems.
Miscellaneous configuration
===========================
The following changes to the guest system configuration help reduce host memory
usage by the FVP:
```
mkdir -p /etc/sysctl.d
test -f /etc/sysctl.d/01-disable-aslr.conf || {
echo "kernel.randomize_va_space = 0" > /etc/sysctl.d/01-disable-aslr.conf
}
```
These changes also help prevent the OOM (Out of Memory) killer from
unnecessarily terminating processes on the guest system when they consume too
much memory:
```
mkdir -p /etc/sysctl.d
test -f /etc/sysctl.d/02-disable-vm-overcommit.conf || {
echo "vm.overcommit_memory = 2" > /etc/sysctl.d/02-disable-vm-overcommit.conf
}
```
We are now ready to do something substantial with our Linux system running on
the FVP. Let's build the Glibc from source and run its tests on the FVP.
Prepare kernel headers
======================
For this step you need the GCC cross-toolchain for the `aarch64-none-linux-gnu`
target. We can use the same toolchain as we used for building the kernel.
Since we are going to use our Glibc on a system running a specific version of
the kernel, we should build the Glibc using the kernel headers of the same
version. The Glibc build scripts automatically pick up your host system's
kernel headers unless configured to use headers from a specific directory. To
ensure that we use correct headers for the kernel, we need to install them from
source.
We presume that the kernel source is in the `linux` subfolder, and we will
install the headers in the `linux-headers` subfolder. To do this, run the
following commands in the workspace directory:
```
# Make sure that cross GCC is on the PATH
export PATH=/path/to/cross/gcc/bin:${PATH}
# Specify target architecture
export ARCH=arm64
# Specify cross compiler
export CROSS_COMPILE=aarch64-none-linux-gnu-
# Install headers
make -C linux headers_install INSTALL_HDR_PATH=$(pwd)/linux-headers
```
After this command completes, you should see the installed kernel headers in the
`/home/user/workspace/linux-headers/include` directory. We will use this path
during the next step.
Get Glibc sources and build for AArch64 target
==============================================
In the workspace directory, clone the Glibc Git repository:
```
git clone git://sourceware.org/git/glibc.git
```
To make the following command simpler, let's introduce the `CROSS` variable
(notice the hyphen at the end):
```
CROSS=/path/to/cross/gcc/bin/aarch64-none-linux-gnu-
```
Now configure the cross-build for the `aarch64-none-linux-gnu` target:
```
# Create build folder:
mkdir glibc-build
cd glibc-build
# Configure Glibc:
LC_ALL=C BUILD_CC=gcc \
CC=${CROSS}gcc CXX=${CROSS}g++ \
NM=${CROSS}nm READELF=${CROSS}readelf \
AR=${CROSS}ar GPROF=${CROSS}gprof \
OBJDUMP=${CROSS}objdump OBJCOPY=${CROSS}objcopy \
RANLIB=${CROSS}ranlib \
../glibc/configure --prefix=/usr \
--host=aarch64-none-linux-gnu \
--enable-hardcoded-path-in-tests \
--with-headers=/home/user/workspace/linux-headers/include
```
Notice the path to the kernel headers in the last parameter in the `configure`
command and also the `include` at the end of it.
Finally, run the build:
```
make -j$(nproc)
```
Run tests on FVP
===============
If you are using an AArch64 host, you can run Glibc tests both on your host and
on the FVP from the same build tree. Before we run some tests, we need to make
sure that we have two important prerequisites in place.
First, we need to copy the target libraries from your toolchain's sysroot to
ensure that the tests are using them rather than your OS's libraries. Run the
following commands in the `glibc-build` folder:
```
cp $(${CROSS}gcc -print-file-name=libstdc++.so.6) .
cp $(${CROSS}gcc -print-file-name=libgcc_s.so.1) .
```
Next, we will build the testroot. A Glibc testroot is a collection of files that
resembles an installation of the Glibc that we have just built. It allows us to
create the correct environment for the tests without actually installing the
Glibc. Tun the following command int the Glibc build folder:
```
make $(pwd)/testroot.pristine/install.stamp
```
Now we can run the tests. Let's start with a single test to understand the
structure of the command. Ensure the following:
* The FVP is running
* The guest system accepts SSH connections
* The Glibc source and build folders are available in the guest system via the
NFS share
* The paths to these folders on the host and the guest systems are the same
We should set the `TIMEOUTFACTOR` environment variable to extend the timeout for
some of the tests that may fail just because execution takes longer than usual.
This is expected on an emulated platform such as an FVP:
```
export TIMEOUTFACTOR=10
```
If you see any timeouts when running tests on the FVP, increase this value.
To tell the Glibc test system to execute the tests on a remote system (in our
case this means on the guest system running on the FVP), we will use the test
wrapper script that is part of the Glibc sources: `scripts/cross-test-ssh.sh`.
By default it uses `ssh` as a command to start an SSH connection, but it is
possible to override it via the `--ssh` option. However, this option only
accepts single word values. To avoid complexities related to using `sh` instead
of `bash` and Bash aliases not being expanded in non-interactive shells, the
easiest way to proceed is as follows:
* Create a simple shell script and save it using file name `ussh`:
```
#!/usr/bin/env bash
dbclient -p 8022 "$@"
```
* Make it executable using the `chmod u+x` command
* Save this script in one of the directories in your `PATH`.
To run tests on FVP, we will use test wrapper script that allows to execute
tests correctly over SSH on a remote system:
```
TEST_WRAPPER=/home/user/workspace/glibc/scripts/cross-test-ssh.sh
```
To run a single test, use this command:
```
make test t=misc/tst-aarch64-pkey \
test-wrapper="${TEST_WRAPPER} --ssh ussh fvp"
```
Let's see what we have here. The `test` target will build (or rebuild) one test
and all its dependencies and then run this test. This target requires one
parameter, `t`, with the name of the test that we need to run. The Glibc tests
are grouped into folders, and a test name would normally look like
`misc/tst-aarch64-pkey` where `misc` is the name of the group and
`tst-aarch64-pkey` is the name of the test in this group.
When we use SSH test wrapper to run a test on the FVP we need to supply its
absolute path along with any of the script's arguments as a value of the
`test-wrapper` make parameter. Here, we use the `--ssh` option of the wrapper
script to tell it to use the `ussh` command instead of `ssh` and we use `fvp`
as the hostname of the remote system. All the setup that we have done in the
previous steps makes using this wrapper script easier.
To run the same test on your AArch64 host rather than on the FVP, just omit the
`test-wrapper=...` parameter.
With this particular test, you may see that on your AArch64 host, it reports
that it is not supported:
```
UNSUPPORTED: misc/tst-aarch64-pkey
original exit status 77
```
And on your FVP with the Linux kernel 6.13 or newer, you should get:
```
PASS: misc/tst-aarch64-pkey
original exit status 0
```
To run a group of tests, use the following command with the `check` target:
```
make check -C /home/user/workspace/glibc/argp \
objdir=`pwd` test-wrapper="${TEST_WRAPPER} --ssh ussh fvp"
```
In this instance, we are building and running tests from the `argp` folder. We
use the `-C` option of `make` to point it to the right directory, and we also
supply a path to the build folder via the `objdir` parameter (which should be
the current directory since we are running this command from within the build
folder). The `test-wrapper` part remains the same.
To run all the tests, simply do:
```
make check test-wrapper="${TEST_WRAPPER} --ssh ussh fvp"
```
Note that this will take a considerable amount of time. Also, notice that we are
not using a parallel `make` command for running tests on the FVP. The reason is
that the Fast Models simulation code runs primarily on a single thread, and
running tests in parallel would not speed up the execution.
EOF
More information about the Libc-help
mailing list