With the most recent 1.14 release of Renode Antmicro introduced initial support for ARMv8-A, opening the doors to many new use cases. 64-bit Cortex-A cores based on this architecture have been extremely popular in Linux-based devices in areas like embedded and mobile, but are also in widespread use in automotive, space and industrial applications where simulation-based testing is of critical importance.
With the capability to support modern, Linux-capable Cortex-A platforms such as Cortex-A78, Renode enables deterministic simulation of complex SoCs, with extensive debugging and testing capabilities.
Throughout this year, in relation to Renode’s strong uptake in domains that require it, we have been improving ARMv8-A support by implementing additional classes of instructions and enabling end-to-end Linux support on Cortex-A platforms. In this note we’ll describe some implementation details and show you how Renode can support complex boot flows on simulated hardware in two demos based on Cortex-A78 and Cortex-A53 cores.
Linux boot flow in Renode
With the recent additions, we are now able to run standard Linux software (by standard we mean: based on a default configuration, without special tweaks needed to avoid unimplemented bits) on 64-bit Cortex-A cores in Renode. This required several additions to our core model - adding support for ARMv8.1 atomic instructions and improving Advanced SIMD and floating-point operation handling. To better demonstrate the Linux boot flow in Renode, we’ll walk you through two demos we’ve added to the mainline project, one for Cortex-A78 and the other for Cortex-A53.
Note that the boot flow is somewhat involved but we recreate it without cutting corners - Renode’s primary use case is in simulating production software which allows development teams to include it in complex testing scenarios from the earliest stages of development. That includes also testing the boot flow itself and all the binaries used throughout the process, and it also makes Renode especially well-suited for security-focused use cases.
The general demo flow consists of the following stages:
- Coreboot acts as a bootloader and is responsible for preliminary CPU initialization and loading ATF in Secure Monitor mode (Exception Level 3).
- Arm Trusted Firmware (ATF) is responsible for further initialization, including Arm TrustZone, and runtime secure services that are used by Linux, e.g., for power management. AFT is required by Linux for CPUs supporting Secure Monitor mode. After initialization, it jumps to Linux in Hypervisor mode (Exception Level 2).
- Linux is responsible for Hypervisor-related configurations and quickly jumps to Exception Level 1, which is typically used by operating systems. It precisely detects specific CPUs based on CPUs Main ID Register and configures the CPU and other CPU-connected peripherals such as GIC and Generic Timer through CPU system registers. It uses ARMv8.1 atomic instructions if the CPU supports them, then loads Buildroot-based rootfs and starts the init process.
- A buildroot-based rootfs is built for either ARMv8-A (for Cortex-A53) or ARMv8.2-A (for Cortex-A78) architecture.
Running Linux on Cortex-A78 and A53 in Renode
Using the flow described above, we can now run standard Linux images on both platforms. You can try the public Cortex-A78 demo on your local machine:
The script loads the 64-bit Cortex-A78 platform and runs Linux with Coreboot and ATF, as shown below:
You can also try a similar demo for the Cortex-A53 platform.
Validation and testing
To validate this implementation, we prepared Robot Framework tests for ARMv8-A platforms. Robot scripts allow users to describe automatic testing scenarios in which Robot behaves like a real user - it observes the UART output, waits for particular patterns and can generate input. However, Renode’s testing capabilities go way beyond just UART devices - for more information on advanced testing scenarios, see Renode’s documentation.
The Robot tests prepared for this project allow us to validate every step of the boot process. First, we check whether Coreboot passes its stages properly and starts ATF. Then, ATF is tested to ensure a proper GIC driver is loaded for the GIC version used in the platform. Finally, in Linux itself we check, among other things, whether the CPU model ID log is correct for the CPU used and the GIC logs printed are correct for the GIC version used in the platform, as well as whether the SMP and the detected CPU features match the simulated platform. Additionally we test some basic tools and functionalities, such as
Towards multi-core ARMv8-A support
Renode already supports simulation of heterogeneous platforms with cores of different kinds, e.g. Cortex-A and Cortex-R, or even mixed together other architectures. In such a setup the big CPU can run Linux and the smaller one some RTOS, such as Zephyr. Our next goal is to enable SMP support for ARMv8-A cores to be able to simulate powerful multi-core Cortex-A SoCs in Renode, and this is already under way.
With Renode we are able to deterministically run, analyze, debug and automatically test production-ready, unmodified software for complex, industrial scenarios. Due to its scriptable nature, Renode fits perfectly in CI environments where it can be used, e.g. for automatic detection of software regressions on a scale hard to achieve with actual hardware. Reach out to us at firstname.lastname@example.org if you’re interested in accelerating the development of your next ARM-based system with Renode’s advanced features.