retpolanne blog

Your friendly programmer catgirl 🏳️‍⚧️😺

1 December 2023

Renesas Journey: rpi cm4

by Anne Macedo

I’ll be using Raspbian, QEMU, virtio pci passthrough and kworkflow for my kernel dev environment on the Raspberry Pi CM4.

Installed packages:

sudo apt install git bc bison flex libssl-dev make debootstrap qemu-system-arm

Followed my debootstrap script from the first post, changing amd64 to arm64.

#!/bin/bash

qemu-img create debootstrap.img 1g
mkfs.ext2 debootstrap.img
mkdir tmp-mount
sudo mount -o loop debootstrap.img tmp-mount
sudo debootstrap --arch arm64 bookworm tmp-mount
sudo umount tmp-mount
rmdir tmp-mount

I can’t seem to find the vfio_pci driver on Raspbian, this is how I check the kconfig:

sudo modprobe configs
zcat /proc/config.gz

I have to recompile the kernel for the CM4 following this tutorial [1], enable CONFIG_VFIO and use pci passthrough on QEMU.

For the QEMU kernel, I did the following:

make defconfig
make kvm_guest.config

And added the following configs:

CONFIG_UPROBE_EVENTS=y
CONFIG_KPROBES=y
CONFIG_USB_XHCI_HCD=y
# CONFIG_USB_XHCI_DBGCAP is not set
CONFIG_USB_XHCI_PCI=y
CONFIG_USB_XHCI_PCI_RENESAS=y
CONFIG_USB_XHCI_PLATFORM=y

Can’t compile XHCI_PCI as modules because we’re testing using QEMU.

I should also compile my host kernel with XHCI_PCI as module and blacklist it, so it doesn’t initialize the pci device.

CONFIG_USB_XHCI_PCI=n

To make a initramfs:

mkinitramfs -o ramdisk.img 6.1.0-rpi4-rpi-v8

It… doesn’t boot?

retpolanne@navi:~/linux $ gdb -q vmlinux
Reading symbols from vmlinux...
(gdb) show architecture
The target architecture is set to "auto" (currently "aarch64").
(gdb) set architecture armv8-a
The target architecture is set to "arm".
(gdb) target remote :1234
Remote debugging using :1234
0x40000000 in ?? ()
(gdb) 

In the end, I had to change the serial device to ttyAMA0 instead of ttyS0 and it showed up stuff.

qemu-system-aarch64 \
    -M virt \
    -m 1G \
    -append "root=/dev/sda console=ttyAMA0" \
    -hda debootstrap.img \
    -kernel linux/arch/arm64/boot/Image \
    -initrd ramdisk.img \
    -serial stdio \
    -display none \
    -cpu cortex-a72

However, /dev/sda is missing. Need to enable something in the kernel.

[2]

Thanks for the link. This is great. I have now hdd recognized. I had everything else included apart from "Enable SYM53C8XX Version 2 SCSI Support". Once I included it, /dev/sda is available.

I tried this and it didn’t work.

(initramfs) ls /dev/disk/by-uuid/21e3fd4e-278f-4e27-a3fa-abf88ed5156f 
/dev/disk/by-uuid/21e3fd4e-278f-4e27-a3fa-abf88ed5156f
NAME      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
mtdblock0  31:0    0  128M  0 disk 
vda       254:0    0    1G  0 disk 
(initramfs) blkid
/dev/vda: UUID="21e3fd4e-278f-4e27-a3fa-abf88ed5156f" BLOCK_SIZE="4096" TYPE="ext2"

We’re not using either sda or hda, but vda.

qemu-system-aarch64 \
    -M virt \
    -m 1G \
    -append "root=/dev/vda console=ttyAMA0" \
    -hda debootstrap.img \
    -kernel linux/arch/arm64/boot/Image \
    -initrd ramdisk.img \
    -serial stdio \
    -display none \
    -cpu cortex-a72

QEMU seems incredibly slow, let’s use an accelerator!

qemu-system-aarch64 -accel help
Accelerators supported in QEMU binary:
kvm
tcg
sudo adduser retpolanne kvm
# Exit your shell and open it again

Accelerated QEMU:

qemu-system-aarch64 \
    -M virt,accel=kvm \
    -m 1500M \
    -append "root=/dev/vda console=ttyAMA0" \
    -drive format=raw,media=disk,file=debootstrap.img \
    -kernel linux/arch/arm64/boot/Image \
    -initrd ramdisk.img \
    -serial stdio \
    -display none \
    -cpu host

Let’s add some networking - bear in mind that I’ve added the ssh server by chrooting onto debootstrap:

qemu-system-aarch64 \
    -M virt,accel=kvm \
    -m 1500M \
    -append "root=/dev/vda console=ttyAMA0" \
    -drive format=raw,media=disk,file=debootstrap.img \
    -kernel linux/arch/arm64/boot/Image \
    -initrd ramdisk.img \
    -serial stdio \
    -display none \
    -netdev user,id=net0,hostfwd=tcp::8022-:22 \
    -device virtio-net-pci,netdev=net0 \
    -cpu host

Added the following to /etc/network/interfaces

allow-hotplug enp0s1
iface enp0s1 inet dhcp

Time to debug!

I plugged in the PCIe card to my board and… it doesn’t boot? Why?

[3] gives some insights on a kernel bug regarding the same board I’m using and related to PCIe. It’s and interesting peek at how kernel devs work. Adding earlycon to my cmdline helped to show more logs on the failing state.

To fix… I believe I compiled the wrong upstream heh.

Other thing that is strange is that one of my PCIe cards yield a kernel panic. Seems similar to [4], but I couldn’t reproduce it anymore.

Anyways, let’s get this analysis started:

Test with the new card I got, uninitialized.

setpci -v -s 01:00.0 f6.w
0000:01:00.0 @f6 = ffff

Test with the old card, uninitialized:

setpci -v -s 01:00.0 f6.w
0000:01:00.0 @f6 = ffff

Can’t use vfio_pci :( no IOMMUs.

root@navi:~# echo "0000:01:00.0" > /sys/bus/pci/drivers/vfio-pci/bind
-bash: echo: write error: Invalid argument
root@navi:~# shopt -s nullglob
for g in $(find /sys/kernel/iommu_groups/* -maxdepth 0 -type d | sort -V); do
    echo "IOMMU Group ${g##*/}:"
    for d in $g/devices/*; do
        echo -e "\t$(lspci -nns ${d##*/})"
    done;
done;
IOMMU Group .:
echo "1912 0014" > /sys/bus/pci/drivers/vfio-pci/new_id
echo 0000:01:00.0 > /sys/bus/pci/devices/0000:01:00.0/driver/unbind
echo 1 > /sys/module/vfio/parameters/enable_unsafe_noiommu_mode
echo "0000:01:00.0" > /sys/bus/pci/drivers/vfio-pci/bind
sudo ln -s /dev/vfio/noiommu-0 /dev/vfio/0

[4] [5] is interesting because it explains why No-IOMMU and vfio don’t match (due to not having protected DMA or something).

I think I hit a wall because RPI CM4 doesn’t support IOMMU and qemu doesn’t support no-IOMMU :C

I’ll use the RPI CM4 as a worker for kernel testing using OpenOCD and JTAG. See you next time!

References

[1] The Linux kernel

[2] Re: [Qemu-devel] QEMU 1.2.0 -hda option not working

[3] PCIe regression on Raspberry Pi Compute Module 4 (CM4) breaks booting

[4] Kernel panic - not syncing: Asynchronous SError Interrupt (brcm_pcie_probe), with Raspberry Pi CM4 + PCIe setups

[5] [PATCH/RFC,4/5] vfio: No-IOMMU mode support

[6] Getting To Blinky: Virt Edition

tags: renesas