Download ARM Foundation Model: https://developer.arm.com/products/system-design/fixed-virtual-platforms.
Try the model: ./models/Linux64_GCC-4.9/Foundation_Platform --image examples/hello.axf
Fast Models [11.4.37 (Jun 19 2018)]
Copyright 2000-2018 ARM Limited.
All Rights Reserved.
terminal_0: Listening for serial connection on port 5000
terminal_1: Listening for serial connection on port 5001
terminal_2: Listening for serial connection on port 5002
terminal_3: Listening for serial connection on port 5003
Hello, 64-bit world!
ARM Architecture has two worlds / execution environment: Trusted World and Non-Trusted World. These two execution environments run at the same time.
Non-Trusted world cannot access Trusted World. It protects trusted information (such as payment details) to be accessed by malicious software running in Non-Trusted world - although risks exist if the Trusted World is not configured properly or the interface between both Worlds are not correctly designed.
Most ARM (and non-ARM) platforms have different types of memory:
The Open-Source ARM Software stack contains these following modules:
Download the archive that contains ARM Trusted Firmware + u-boot (note: it looks Linaro ARM langing team does not support UEFI as the default boot loader on AArch64 anymore...), Linux Kernel and Device Tree at http://releases.linaro.org/members/arm/platforms/latest/fvp-latest-oe-uboot.zip (5.9 MB)
Download OpenEmbedded Minimal filesystem at https://releases.linaro.org/archive/15.05/openembedded/aarch64/vexpress64-openembeddedminimal-armv8-gcc-4.920150522-720.img.gz (83.9M) and decompress it with gzip``
Launch it!
export MODEL=$PWD/Foundation_Platformpkg/models/Linux64_GCC-4.9/Foundation_Platform
export DISK=$PWD/vexpress64-openembedded_minimal-armv8-gcc-4.9_20150522-720.img
./run_model.sh
Download the archive that contains ARM Trusted Firmware + u-boot (note: it looks Linaro ARM langing team does not support UEFI as the default boot loader on AArch64 anymore...), Linux Kernel and Device Tree at http://releases.linaro.org/members/arm/platforms/latest/fvp-latest-oe-uboot.zip (5.9 MB)
Download the archive that contains ARM Trusted Firmware + UEFI at http://releases.linaro.org/members/arm/platforms/latest/fvp-uefi.zip (834 KB)
Download OpenEmbedded Minimal filesystem at https://releases.linaro.org/archive/15.05/openembedded/aarch64/vexpress64-openembeddedminimal-armv8-gcc-4.920150522-720.img.gz (83.9M) and decompress it with gzip``
Launch it!
export MODEL=$PWD/Foundation_Platformpkg/models/Linux64_GCC-4.9/Foundation_Platform
export DISK=$PWD/vexpress64-openembedded_minimal-armv8-gcc-4.9_20150522-720.img
./run_model.sh
Stop when EFI Shell starts and go to the FS2 file system (EFI partition on OpenEmbedded image) with the EFI command: fs2:
startup.nsh
(EFI script called at the start of EFI Shell) with the command edit startup.nsh
dtb=fvp-base-gicv2-psci.dtb
by dtb=fvp-foundation-gicv3-psci.dtb
. Save your change with CTRL+S
and quit with CTRL+Q
startup.nsh
by calling the script from EFI ShellInstall AArch64 GCC toolchain with sudo apt install gcc-aarch64-linux-gnu
.
Use Linaro's script. Check the section "Initialising a workspace" of the page Arm Platforms deliverables to get the exact destination of the script. At the moment of writing this document, the script is located here:
wget https://community.arm.com/cfs-file/__key/communityserver-wikis-components-files/00-00-00-00-10/8267.armplat_5F00_1807.py
mv 8267.armplat_5F00_1807.py armplat_1807.py
Start the script python3 armplat_1807.py
and select the following options:
## Please select a platform:
1) Development boards
2) Fixed Virtual Platforms (FVPs)
> 2
## Please select a platform:
1) System Guidance
2) Armv8 architecture
> 2
## Please select a platform:
1) Armv8-A Base Platform -- 11.3.30+ (Rev C)
2) Armv8-A Foundation Platform -- 11.3.30+
> 2
WARNING: only avail. option is Armv8-A Foundation Platform with 64-bit software stack
## Please specify whether you want to:
1) Build from source
2) Use prebuilt configuration
> 1
## Please select an environment:
1) Linux kernel + filesystem
2) Firmware only
> 2
WARNING: only avail. option is EDK II UEFI
## Your chosen configuration is shown below:
+-------------+--------------------------------------------------------+
| Workspace | /tmp/linaro/ |
| Platform | Armv8-A Foundation Platform with 64-bit software stack |
| Type | Build from source |
| Environment | Firmware only |
| Firmware | EDK II UEFI |
+-------------+--------------------------------------------------------+
## Proceed with this configuration?:
1) Yes
2) No
> 1
Build the sources
chmod a+x build-scripts/build-all.sh
./build-scripts/build-all.sh all
Run the newly built binaries
export MODEL=/opt/Foundation_Platformpkg/models/Linux64_GCC-4.9/Foundation_Platform
export BL1=output/fvp/fvp-uefi/uefi/bl1.bin
export FIP=output/fvp/fvp-uefi/uefi/fip.bin
./model-scripts/fvp/run_model.sh
Create the directory that will contain all the ARM Software stack components:
mkdir src && cd src
export CROSS_COMPILE=aarch64-linux-gnu-
Clone the EDK2 (a UEFI Open-Source implementation) repository
git clone https://github.com/tianocore/edk2.git
cd edk2
git clone git@github.com:tianocore/edk2-platforms.git
Setup EDK2 build environment:
. edksetup.sh
make -C BaseTools
export PACKAGES_PATH=$PWD:$PWD/edk2-platforms
Build EDK2 for FVP Foundation Model
GCC5_AARCH64_PREFIX=aarch64-linux-gnu- build -a AARCH64 -p Platform/ARM/VExpressPkg/ArmVExpress-FVP-AArch64.dsc -t GCC5
Clone the repository
git clone https://github.com/ARM-software/arm-trusted-firmware.git
cd arm-trusted-firmware
Build ARM Trusted Firmware in DEBUG
mode:
CROSS_COMPILE=aarch64-linux-gnu- make PLAT=fvp all fip BL33=<edk2-dir>/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC5/FV/FVP_AARCH64_EFI.fd DEBUG=1
ARM Trusted Firmware does not generate DTB (Device Tree Binary) for the Foundation model, we can generate it by hand:
dtc -o fvp-foundation-gicv3-psci.dtb fdts/fvp-foundation-gicv3-psci.dts
Clone the repository and use the branch linux-linaro-lsk-v4.14
git clone https://git.linaro.org/kernel/linux-linaro-stable.git -b linux-linaro-lsk-v4.14
cd linux-linaro-stable
Build the Linux kernel
$ export CROSS_COMPILE=aarch64-linux-gnu-
$ make ARCH=arm64 defconfig
$ make ARCH=arm64 -j8 Image
(...)
LD vmlinux
SORTEX vmlinux
SYSMAP System.map
OBJCOPY arch/arm64/boot/Image
Set environment variables to let the model knows where to find the binaries
export BL1=arm-trusted-firmware/build/fvp/debug/bl1.bin
export FIP=arm-trusted-firmware/build/fvp/debug/fip.bin
export KERNEL=linux-linaro-stable/arch/arm64/boot/Image
export DTB=arm-trusted-firmware/fvp-foundation-gicv3-psci.dtb
export DISK=vexpress64-openembedded_minimal-armv8-gcc-4.9_20150522-720.img
Launch the model
/opt/Foundation_Platformpkg/models/Linux64_GCC-4.9/Foundation_Platform \
--cores=1 \
--secure-memory \
--visualization \
--use-real-time \
--gicv3 \
--data=${BL1}@0x0 \
--data=${FIP}@0x8000000 \
--data=${KERNEL}@0x80080000 \
--data=${DTB}@0x82000000 \
--data={INITRD}@0x84000000 \
--block-device=$DISK
Versions:
Every time you make a modification to UEFI you need to rebuild the FIP (Firmware Image Package). There are two ways to rebuild the FIP:
make PLAT=fvp all fip BL33=/home/olivier/src/edk2/Build/ArmVExpress-FVP-AArch64/DEBUG_GCC49/FV/FVP_AARCH64_EFI.fd DEBUG=1
or
fip_create
to your PATH
(eg: export PATH=../arm-trusted-firmware/tools/fip_create:$PATH
) and set FIP_BIN
with the location of the Firmware Image Package built by ARM Trusted Firmware (eg: export FIP_BIN=../arm-trusted-firmware/build/fvp/debug/fip.bin
) (in my version of EDK2 you also need to set WORKSPACE=$PWD
).NFS Boot allows to directly make changes to the file system from your host machine without the need to mount the disk image every time.
To enable NFS Boot you need to ensure your ARM Foundation Model Linux kernel has support for the Ethernet SMSC 91C111 controller. Check the configuration file of your Linux kernel source tree:
$ grep SMSC .config
CONFIG_NET_VENDOR_SMSC=y
CONFIG_SMSC911X=y
# CONFIG_SMSC911X_ARCH_HOOKS is not set
# CONFIG_SMSC9420 is not set
# CONFIG_SMSC_PHY is not set
# CONFIG_FB_SMSCUFX is not set
CONFIG_SMSC911X
is set so it means you can use the ARM Foundation Model network controller with your current kernel binaries. If it is not set then you need to enable it in your kernel configuration and rebuild the kernel.
Start the model with the bridge network:
sudo ../Foundation_Platformpkg/models/Linux64_GCC-4.7/Foundation_Platform --cores=4 --secure-memory --visualization --gicv3 --data="$PWD/arm-trusted-firmware/build/fvp/debug/bl1.bin"@0x0 --data="$PWD/arm-trusted-firmware/build/fvp/debug/fip.bin"@0x08000000 --block-device="/home/olivier/prebuilt/lt-vexpress64-openembedded_minimal-armv8-gcc-4.9_20150912-729.img" --network=bridged &
sleep 5
sudo ifconfig ARM0 192.168.1.1 netmask 255.255.255.0
On the target:
sudo ifconfig eth0 192.168.1.2 netmask 255.255.255.0
Note: NAT network with the option --network=nat
instead of --network=bridged
also works.
More information on the network configuration here.
We will need to copy the file system of your disk image onto your local disk. Let's have a look at the partitions present on your disk image and their locations - fdisk
will help us:
$ /sbin/fdisk -lu ../prebuilt/lt-vexpress64-openembedded_minimal-armv8-gcc-4.9_20150912-729.img
Disk ../prebuilt/lt-vexpress64-openembedded_minimal-armv8-gcc-4.9_20150912-729.img: 3221 MB, 3221225472 bytes
255 heads, 63 sectors/track, 391 cylinders, total 6291456 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
Device Boot Start End Blocks Id System
../prebuilt/lt-vexpress64-openembedded_minimal-armv8-gcc-4.9_20150912-729.img1 * 63 155646 77792 e W95 FAT16 (LBA)
../prebuilt/lt-vexpress64-openembedded_minimal-armv8-gcc-4.9_20150912-729.img2 155648 6291455 3067904 83 Linux
You can see the Linux partition starts at the sector number 155648. fidsk
says the sector size is 512 bytes.
We use losetup
to mount the disk image on /dev/loop0
:
$ losetup /dev/loop0 ../prebuilt/lt-vexpress64-openembedded_minimal-armv8-gcc-4.9_20150912-729.img -o $((155648 * 512))
file -s /dev/loop0
confirms us the Linux partition is actually a ext4 partition:
/dev/loop0: Linux rev 1.0 ext4 filesystem data, UUID=a9c947eb-c956-4c39-af5d-1fe3509121a9, volume name "rootfs" (needs journal recovery) (extents) (large files) (huge files)
We finally can mount the device /dev/loop0
to access the partition as part of our file system:
mkdir /tmp/disk
mount /dev/loop0 /tmp/disk
Now the disk image is mounted, we can copy its content to the directory /srv/nfs/lt-vexpress64-openembedded_minimal-armv8
:
sudo mkdir /srv/nfs
sudo mount -o loop,offset=$((155648 * 512)) ../prebuilt/lt-vexpress64-openembedded_minimal-armv8-gcc-4.9_20150912-729.img /tmp/disk
sudo cp -ax /tmp/disk /srv/nfs/lt-vexpress64-openembedded_minimal-armv8
umount /dev/loop0
losetup -d /dev/loop0
Check your Linux distribution documentation. For instance a simple installation on the Ubuntu distribution can be found here.
After installing NFS server, make sure the NFS service is started. You can also test your NFS installation is correctly set up by mounting the NFS file system on your host machine:
$ mkdir /tmp/open-embedded
$ sudo mount localhost:/srv/nfs/lt-vexpress64-openembedded_minimal-armv8 /tmp/open-embedded
$ ls /tmp/open-embedded/
bin boot dev EFI etc home lib lost+found media mnt proc run sbin sys tmp usr var
Next stage is to check whether you can mount the filesystem from the ARM Foundation model.
If you have any issue you can get the NFS error by looking at /var/log/syslog
on the host machine: tail -n 20 /var/log/syslog
Once you manage to access the NFS file system from the model, you can now change the Linux kernel command line in UEFI in the file ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-FVP-AArch64.dsc
at the line gArmPlatformTokenSpaceGuid.PcdDefaultBootArgument|(..)
.
Replace root=/dev/vda2
by one of the following arguments:
ip=dhcp root=/dev/nfs nfsroot=192.168.0.10:/srv/nfs/lt-vexpress64-openembedded_minimal-armv8,vers=3 rw
ip=192.168.1.2:::255.255.255.0::eth0:: root=/dev/nfs nfsroot=192.168.1.1:/srv/nfs/lt-vexpress64-openembedded_minimal-armv8,vers=3 rw
Now, you know how to change and rebuild every components of the ARM Software stack!
These instructions are also available as a Github gist to be kept up to date