Skip to content
GrygiriiS edited this page May 3, 2024 · 20 revisions

Zephyr sources

repo: https://github.com/xen-troops/zephyr.git

branch: rpi5_dev

Zephyr build

Native Zephyr samples/hello_world build

west build -b rpi_5 -p always samples/hello_world

Zephyr Dom0 samples/hello_world build

To build Zephyr with XEN (Dom0) support use snippet xen_dom0

west build -b rpi_5 -p always -S xen_dom0 samples/hello_world/

Native Zephyr boot on RPI5

Copy zephyr.bin binary to RPI5 bootfs boot partition.

In RPI5 config.txt file select zephyr.bin binary to boot it instead of standard RPI5 kernel.

[all]
enable_uart=1
uart_2ndstage=1
kernel=zephyr.bin

Zephyr boot under XEN from u-boot as Dom0

Assumption: XEN (xen) and u-boot (u-boot.bin) binaries prepared and placed in RPI5 bootfs partition.

Copy Zephyr zephyr.bin binary to RPI5 bootfs partition.

Note

Note that boot uses FDT prepared by RPI5 firmware and placed at ${fdt_addr}.

u-boot command to start XEN, which starts Zephyr:

setenv xen_addr_r 0x02700000

fatload mmc 0 ${kernel_addr_r} zephyr.bin

fdt addr ${fdt_addr}
fdt resize 2048
fdt chosen

fdt set /chosen \#address-cells <1>
fdt set /chosen \#size-cells <1>

fdt mknod /chosen module@0
fdt set /chosen/module@0 compatible "xen,linux-zimage" "xen,multiboot-module"
fdt set /chosen/module@0 reg <${kernel_addr_r} 0x${filesize} >

setenv bootargs "console=dtuart dtuart=/soc/serial@7d001000 dom0_mem=128M"
fdt set /chosen xen,xen-bootargs "console=dtuart dtuart=/soc/serial@7d001000 dom0_mem=128M"
fdt rm /soc/serial@7d001400 
fdt rm /soc/serial@7d001a00

fdt set /soc/gpio@7d517c00 xen,passthrough

fdt rm /soc/nvmem_otp
fdt rm /soc/nvmem_cust
fdt rm /soc/nvmem_priv
fdt rm /soc/nvmem_mac

fdt print /chosen
printenv

fatload mmc 0 ${xen_addr_r} xen
booti ${xen_addr_r} - ${fdt_addr}

XEN boot log:

 Xen 4.19-unstable
(XEN) Xen version 4.19-unstable (grygorii@) (aarch64-zephyr-elf-gcc (Zephyr SDK 0.16.3) 12.2.0) debug=y Thu Apr 11 15:33:36 EEST 2024
(XEN) Latest ChangeSet: Fri Jan 5 10:46:44 2024 +0200 git:8ff1f6708a
(XEN) build-id: 81400877508840d2162ff03548bb83af12be760b
(XEN) Processor: 00000000414fd0b1: "ARM Limited", variant: 0x4, part 0xd0b,rev 0x1
(XEN) 64-bit Execution:
(XEN)   Processor Features: 1100000010111112 0000000000000010
(XEN)     Exception Levels: EL3:64 EL2:64 EL1:64 EL0:64+32
(XEN)     Extensions: FloatingPoint AdvancedSIMD
(XEN)   Debug Features: 0000000010305408 0000000000000000
(XEN)   Auxiliary Features: 0000000000000000 0000000000000000
(XEN)   Memory Model Features: 0000000000101122 0000000010212122
(XEN)   ISA Features:  0000100010211120 0000000000100001
(XEN) 32-bit Execution:
(XEN)   Processor Features: 0000000010010131:0000000000010000
(XEN)     Instruction Sets: AArch32 A32 Thumb Thumb-2 Jazelle
(XEN)     Extensions: GenericTimer
(XEN)   Debug Features: 0000000004010088
(XEN)   Auxiliary Features: 0000000000000000
(XEN)   Memory Model Features: 0000000010201105 0000000040000000
(XEN)                          0000000001260000 0000000002122211
(XEN)   ISA Features: 0000000002101110 0000000013112111 0000000021232042
(XEN)                 0000000001112131 0000000000010142 0000000001011121
(XEN) Using SMC Calling Convention v1.2
(XEN) Using PSCI v1.1
(XEN) SMP: Allowing 4 CPUs
(XEN) Generic Timer IRQ: phys=30 hyp=26 virt=27 Freq: 54000 KHz
(XEN) GICv2 initialization:
(XEN)         gic_dist_addr=000000107fff9000
(XEN)         gic_cpu_addr=000000107fffa000
(XEN)         gic_hyp_addr=000000107fffc000
(XEN)         gic_vcpu_addr=000000107fffe000
(XEN)         gic_maintenance_irq=25
(XEN) GICv2: 320 lines, 4 cpus, secure (IID 0200143b).
(XEN) XSM Framework v1.0.1 initialized
(XEN) Initialising XSM SILO mode
(XEN) Initialized GSX IRQ
(XEN) Using scheduler: SMP Credit Scheduler rev2 (credit2)
(XEN) Initializing Credit2 scheduler
(XEN)  load_precision_shift: 18
(XEN)  load_window_shift: 30
(XEN)  underload_balance_tolerance: 0
(XEN)  overload_balance_tolerance: -3
(XEN)  runqueues arrangement: socket
(XEN)  cap enforcement granularity: 10ms
(XEN) load tracking window length 1073741824 ns
(XEN) Allocated console ring of 32 KiB.
(XEN) CPU0: Guest atomics will try 17 times before pausing the domain
(XEN) Bringing up CPU1
(XEN) CPU1: Guest atomics will try 15 times before pausing the domain
(XEN) CPU 1 booted.
(XEN) Bringing up CPU2
(XEN) CPU2: Guest atomics will try 15 times before pausing the domain
(XEN) CPU 2 booted.
(XEN) Bringing up CPU3
(XEN) CPU3: Guest atomics will try 15 times before pausing the domain
(XEN) Brought up 4 CPUs
(XEN) CPU 3 booted.
(XEN) I/O virtualisation disabled
(XEN) P2M: 40-bit IPA with 40-bit PA and 16-bit VMID
(XEN) P2M: 3 levels with order-1 root, VTCR 0x00000000800a3558
(XEN) Scheduling granularity: cpu, 1 CPU per sched-resource
(XEN) Initializing Credit2 scheduler
(XEN)  load_precision_shift: 18
(XEN)  load_window_shift: 30
(XEN)  underload_balance_tolerance: 0
(XEN)  overload_balance_tolerance: -3
(XEN)  runqueues arrangement: socket
(XEN)  cap enforcement granularity: 10ms
(XEN) load tracking window length 1073741824 ns
(XEN) Adding cpu 0 to runqueue 0
(XEN)  First cpu on runqueue, activating
(XEN) Adding cpu 1 to runqueue 0
(XEN) Adding cpu 2 to runqueue 0
(XEN) Adding cpu 3 to runqueue 0
(XEN) alternatives: Patching with alt table 00000a00002e5b58 -> 00000a00002e6cc8
(XEN) CPU0 will use 24 loops workaround on exception entry
(XEN) CPU3 will use 24 loops workaround on exception entry
(XEN) CPU1 will use 24 loops workaround on exception entry
(XEN) CPU2 will use 24 loops workaround on exception entry
(XEN) *** LOADING DOMAIN 0 ***
(XEN) Loading d0 kernel from boot module @ 0000000000080000
(XEN) Loading ramdisk from boot module @ 000000002dfaa000
(XEN) Allocating 1:1 mappings totalling 512MB for dom0:
(XEN) BANK[0] 0x00000060000000-0x00000080000000 (512MB)
(XEN) Grant table range: 0x00000002800000-0x00000002840000
(XEN) Allocating PPI 16 for event channel interrupt
(XEN) d0: extended region 0: 0x2a00000->0x3fa00000
(XEN) d0: extended region 1: 0x40000000->0x5fe00000
(XEN) d0: extended region 2: 0x80000000->0x1ffe00000
(XEN) Loading zImage from 0000000000080000 to 0000000060000000-0000000060021004
(XEN) Loading d0 initrd from 000000002dfaa000 to 0x0000000068200000-0x00000000692554fe
(XEN) Loading d0 DTB to 0x0000000068000000-0x00000000680130d2
(XEN) Initial low memory virq threshold set at 0x4000 pages.
(XEN) Scrubbing Free RAM in background
(XEN) Std. Loglevel: All
(XEN) Guest Loglevel: All
(XEN) ***************************************************
(XEN) PLEASE SPECIFY dom0_mem PARAMETER - USING 512M FOR NOW
(XEN) ***************************************************
(XEN) 3... 2... 1... 
(XEN) *** Serial input to DOM0 (type 'CTRL-a' three times to switch input)
(XEN) Freed 344kB init memory.
(XEN) d0v0: vGICD: unhandled word write 0x000000ffffffff to ICACTIVER4
(XEN) d0v0: vGICD: unhandled word write 0x000000ffffffff to ICACTIVER8
(XEN) d0v0: vGICD: unhandled word write 0x000000ffffffff to ICACTIVER12
(XEN) d0v0: vGICD: unhandled word write 0x000000ffffffff to ICACTIVER16
(XEN) d0v0: vGICD: unhandled word write 0x000000ffffffff to ICACTIVER20
(XEN) d0v0: vGICD: unhandled word write 0x000000ffffffff to ICACTIVER24
(XEN) d0v0: vGICD: unhandled word write 0x000000ffffffff to ICACTIVER28
(XEN) d0v0: vGICD: unhandled word write 0x000000ffffffff to ICACTIVER32
(XEN) d0v0: vGICD: unhandled word write 0x000000ffffffff to ICACTIVER36
(XEN) d0v0: vGICD: unhandled word write 0x000000ffffffff to ICACTIVER0
*** Booting Zephyr OS build v3.6.0-61-gdd5a70f99dbf ***
Hello World! Raspberry Pi 5 Xen Dom0

Zephyr adaptation to run under XEN as Dom0

The below Kconfigs have to be enabled:

 CONFIG_XEN_DOM0

The hypervisor node has to be added in Zephyr device tree which should use addresses allocated by XEN for Grant table. Look for below line in XEN log:

(XEN) Grant table range: 0x00000002800000-0x00000002840000

so hypervisor node for Zephyr should be defined like:

	hypervisor: hypervisor@2700000 {
		compatible = "xen,xen";
		reg = <0x00 0x2800000 0x40000>;
		interrupts = <GIC_PPI 0x0f IRQ_TYPE_EDGE IRQ_DEFAULT_PRIORITY>;
		interrupt-parent = <&gic>;
	};

Zephyr has to be built with memory range where XEN relocating Zephyr binary. Look for below line in XEN log:

(XEN) BANK[0] 0x00000060000000-0x00000080000000 (512MB)

so memory for Zephyr should be defined like:

	zephyr,sram = &ram;

	ram: memory@60000000 {
		device_type = "mmio-sram";
		reg = <0x00 0x60000000 DT_SIZE_M(16)>;
	};

Console has to be defined using xen_consoleio_hvc node label as shown below (with assumption Zephyr is Dom0) and enabled as default Zephyr console:

	chosen {
		zephyr,console = &xen_consoleio_hvc;
		zephyr,shell-uart = &xen_consoleio_hvc;
	};

	xen_consoleio_hvc: hvc {
		compatible = "xen,hvc-consoleio";
		status = "okay";
	};

and HW UART used as console by native Zephyr shall be disabled:

&uart0 {
	status = "disabled";
	current-speed = <115200>;
};

Zephyr boot under XEN from u-boot using boot script

The command sequence in https://github.com/oleksiimoisieiev/rpi5-knowledge-base/wiki/RPI-5-Zephyr/_edit#zephyr-boot-under-xen-from-u-boot can be placed in u-boot script file, compiled and then used to run Zephyr under XEN.

For example, u-boot script file is boot-xen-zephyr.txt, run below command to compile it in u-boot scr format:

mkimage -A arm -T script -d boot-xen-zephyr.txt boot-xen-zephyr.scr

Copy boot-xen-zephyr.scr binary to RPI5 bootfs partition and run below commands in u-boot to run it:

fatload mmc 0 ${scriptaddr} boot-xen-zephyr.scr 
source ${scriptaddr}

Zephyr links

PRs with initial Zephyr RPI5 support:

https://github.com/zephyrproject-rtos/zephyr/pull/70538

https://github.com/zephyrproject-rtos/zephyr/pull/70774

XEN on ARM:

https://wiki.xenproject.org/wiki/Xen_ARM_with_Virtualization_Extensions

https://wiki.xenproject.org/wiki/Xen_ARM_with_Virtualization_Extensions/Allwinner