Renode
I have not looked into using Renode for seL4CP, I am mainly waiting for it to be more mature as I’ve had various issues with it (see GitHub - Ivan-Velickovic/sel4_renode: Simulating seL4 projects with Renode).
You can load binary files in Renode, for example: sysbus LoadBinary @../tmp_build/loader.img 0x70000000
. Note that you will also need to set the program counter to where the image is loaded, so in this case cpu PC 0x70000000
.
Unfortunately I have Renode working with seL4CP in the non-hypervisor case, but not when hypervisor mode is turned on, which is the default configuration in my seL4CP fork for the QEMU ARM virt platform. I don’t have time to investigate right this moment. But given that QEMU and hardware where seL4 is configured in hypervisor mode work, I suspect either this is a bug in Renode or a misconfiguration on my part.
The full platform description is here:
cpu: CPU.ARMv8A @ sysbus
cpuType: "cortex-a53"
genericInterruptController: gic
timer: Timers.ARM_GenericTimer @ cpu
frequency: 62500000
EL3PhysicalTimerIRQ -> gic#0@29
EL1PhysicalTimerIRQ -> gic#0@30
EL1VirtualTimerIRQ -> gic#0@27
NonSecureEL2PhysicalTimerIRQ -> gic#0@26
NonSecureEL2VirtualTimerIRQ -> gic#0@28
gic: IRQControllers.ARM_GenericInterruptController @ {
sysbus new Bus.BusMultiRegistration { address: 0x8000000; size: 0x010000; region: "distributor" };
sysbus new Bus.BusMultiRegistration { address: 0x8010000; size: 0x010000; region: "cpuInterface" }
}
[0-1] -> cpu@[0-1]
architectureVersion: IRQControllers.ARM_GenericInterruptControllerVersion.GICv2
supportsTwoSecurityStates: true
flash: Memory.MappedMemory @ sysbus 0x0
size: 0x08000000
bl31: Memory.MappedMemory @ sysbus 0x0e000000
size: 0x01000000
ram: Memory.MappedMemory @ sysbus 0x40000000
size: 0x80000000
uart0: UART.PL011 @ sysbus 0x09000000
-> gic@1
The full script is here:
:name: QEMU ARM virt
:description: This script runs QEMU ARM virt seL4CP image on a 64-bit ARM Cortex-A53.
using sysbus
$name?="ARM Cortex-A53"
mach create $name
machine LoadPlatformDescription @qemu_arm_virt.repl
showAnalyzer uart0
macro reset
"""
uart0 WriteDoubleWord 0x30 0x301
uart0 WriteDoubleWord 0x2c 0x40
cpu SetAvailableExceptionLevels true false
cpu PC 0x70000000
sysbus LoadBinary @../tmp_build/loader.img 0x70000000
"""
runMacro $reset
I ran Renode with the following command:
renode -e "start @qemu_arm_virt.resc" --console
Polarfire on QEMU
These are the clearest instructions I can produce for getting it working on my end. I am using the same QEMU version as you.
# Current latest SDK
unzip sel4cp-sdk-dev-d509be2-linux-x86-64.zip
tar xf sel4cp-sdk-1.2.6.tar.gz
cd sel4cp-sdk-1.2.6/board/polarfire/example/hello
git clone git@github.com:seL4/seL4.git
dtc -I dts -O dtb seL4/tools/dts/mpfs_icicle.dts > mpfs_icicle.dtb
mkdir build
make BUILD_DIR=build SEL4CP_SDK=../../../../ SEL4CP_BOARD=polarfire SEL4CP_CONFIG=debug
qemu-system-riscv64 -M microchip-icicle-kit -smp 5 -m 2G -display none -serial stdio -serial null -serial null -kernel build/loader.img -dtb mpfs_icicle.dtb
Polarfire on hardware
It is not necessary to convert the loader.img
file. By the log it looks like the booting process for Polarfire is OpenSBI → U-Boot → seL4/seL4CP. In this case after U-Boot loads all you need to do is go 0x80200000
after loading the image into memory at address 0x80200000
. This can be via TFTP booting or fatload
if you have an MMC device.