Initial Minimal Fedora Image for Raspberry Pi 5

I know this has been much awaited because of all the queries on the various forums and direct to me so here we are the first Fedora image that can run a native userspace with a Fedora kernel with some enablement patches.

This image is far from complete and is NOT yet suitable for desktop UXes and related usecases that require a display.

So what works, what doesn’t, and how can you get started?

The things that are working and tested:

  • The original RPi5 rev c0 SoCs: the older 4Gb/8Gb variants
  • Serial console
  • Late boot HDMI0 display output (IE once the kernel has started) via simple DRM/FB
  • The compute Subsystems (CPUs etc) of both SoC revs
  • The micro SD slot – the only supported OS disk ATM
  • Wired ethernet port
  • Wireless network interface
  • USB ports (NOT for OS disks)

The things that don’t work:

  • The new RPi5 rev d0 SoCs: the 2Gb/16Gb, newer 1.1 Rev 4/8Gb variants, the RPi500, CM5 – the kernel will crash on boot
  • Early boot display output
  • Accelerated GPU
  • Basically everything else

What might work:

  • PCIe for HATs via the add-on HATs and related products including NVME. Not currently for boot/root.

For getting started you will need to have a serial console, ATM booting off anything other than the micro SD card won’t work.

We will eventually support booting off USB/NVME etc and display output as well as other HW but unfortunately we’re not there yet. I feel with USB/eth/wifi support the device is now at a point where it’s actually usable for a lot of Fedora users so I decided it’s time to expand this to more people than just me šŸ˜€

Note I don’t have the spare cycles to assist with debugging any issues that have been listed above as explicitly not working, I want to spend my time on making the device more usable (SORRY, but I do this in my personal spare time). I will update when any of this changes.

You can get the image from here and get started in the usual way with either DD or arm-image-installer (update the storage media name):

arm-image-installer --resizefs --target=none --media=/dev/XXX --image=rpi5-250907-fedora-43-minimal-raw-xz-aarch64.raw.xz

I am working to get more HW support enabled, my focus is on the d0 rev boards (2Gb, 16Gb, 500, CM5 and newer 4/8Gb) and PCIe, from there I will look at what else is possible with my available time. These enhancements will land in new kernel updates to my copr repo, or fixes into Fedora proper. which will arrive by either new published images or kernel updates. I will provide updates when particularly useful milestones are passed and new things start to work.

Bug reports are of course welcome but not for desktopsm or RFEs for other HW enablement, especially things I’ve already stated above, I am working to get more features but I am limited to what I can do because of available time, upstream work and access to HW docs so please be patient as I am doing this in my spare time! Of course being downstream of Fedora please don’t file bugs there unless they are a general problem with userspace. The only thing that’s not vanilla Fedora currently is the kernel. I have an original Pi 5 8Gb and a Pi 5 rev d0 model I am testing with, everything else can be considered untested so YMMV!

Building rust UEFI apps on Fedora

As everyone probably knows rust is considered a great language for secure programming and hence a lot of people are looking at it for everything from low level firmware to GPU drivers. In a similar vein it can already be to build UEFI applications.

Upstream in U-Boot we’ve been adding support for UEFI HTTP and HTTPs Boot and it’s now stable enough I am looking to enable this in Fedora. While I was testing the features on various bits of hardware I wanted a small UEFI app I could pull across a network quickly and easily from a web server for testing devices.

Of course adding in display testing as well would be nice…. so enter UEFI nyan cat for a bit of fun!

Thankfully the Fedora rust toolchain already has the UEFI targets built (aarch64 and x86_64) so you don’t need to mess with third party toolchains or repos, it works the same for both targets, just substitute the one you want in the example where necessary.

I did most of this in a container:

$ podman pull fedora
$ podman run --name=nyan_cat --rm -it fedora /bin/bash
# dnf install -y git-core cargo rust-std-static-aarch64-unknown-uefi
# git clone https://github.com/diekmann/uefi_nyan_80x25.git
# cd uefi_nyan_80x25/nyan/
# cargo build --release --target aarch64-unknown-uefi
# ls target/aarch64-unknown-uefi/release/nyan.efi
target/aarch64-unknown-uefi/release/nyan.efi

From outside the container then copy the binary, and add it to the EFI boot menu:

$ podman cp nyan_cat:/uefi_nyan_80x25/nyan/target/aarch64-unknown-uefi/release/nyan.efi ~/
$ sudo mkdir /boot/efi/EFI/nyan/
$ sudo cp ~/nyan.efi /boot/efi/EFI/nyan/nyan-a64.efi
$ sudo efibootmgr --create --disk /dev/nvme0n1 --part 1 --label "nyan" --loader \\EFI\\nyan\\nyan-a64.efi

Reboot and sit back and enjoy some UEFI Nyan Cat!

Any Linux distro on NVIDIA Jetson Orin with JetPack 6

NVIDIA has just released the Jetpack 6 for the NVIDIA Jetson Orin hardware. The thing that is most exciting about this release is they finally support the ability to use upstream kernels and other Linux distributions. This means you can start to use both RHEL (9.3 and later) and Fedora on the Jetson Orin hardware! This has been a LONG time coming, something I’ve been involved with for 5 years!

So while this is a developer preview, AKA public Beta, it’s still very usable and for people that are interested in using other Linux distributions now is the time to get stuck in. Like all things it’s not perfect and there’s still work to be done, but many hands do make light work!

You start by downloading the BSP from there you can follow the following instructions and you should end up with a device you can easily install Fedora 39+ or RHEL 9.3 or other distros with the appropriate bits enabled.

To flash the firmware you need to follow the Orin AGX guide for recovery and cabling, for Orin NX/nano you need to use the HW pins near the mSD card, to put the device in recovery mode and cabling then do the following for Orin AGX:

$ sudo dnf install -y libxml2-utils lz4 usbutils xxd
$ tar zvf Jetson_Linux_R36.2.0_aarch64.tbz2
$ cd Linux_for_Tegra/
$ lsusb|grep -i nv
Bus 003 Device 044: ID 0955:7045 NVIDIA Corp. [unknown]
Bus 003 Device 045: ID 0955:7023 NVIDIA Corp. [unknown]
$ sudo ./flash.sh p3737-0000-p3701-0000-qspi external
removed a lot of output
*** The target generic has been flashed successfully. ***
Make the target filesystem available to the device and reset the board to boot from external external.
$

The command for other Orin devices such as NX and Nano will be similar, you’ll just have to swap the p3737 variable, eg for Orin Nano use: sudo ./flash.sh p3737-0000-p3701-0000-qspi external.

Once the flash completes the device will reboot and you will be able to use the usual mechanisms to install your OS, whether the RHEL or Fedora installers or a Fedora Arm image. I’ve tested running OSes off both the microSD and a NVME card, plus installing off USB, the DisplayPort output should work in EFI console mode. The firmware is based upon the widely known TianoCore/EDK2 so the firmware interface should be straight forward. For those that may need a serial console if it’s not automatically detected you can use console=ttyAMA0,115200, This runs off the microUSB port on /dev/ttyACM2 on the host device.

For hardware vendors that have hardware based on the NVIDIA Orin hardware they will be able to adopt and make this available to their customers that may wish to run distributions other than L4T. If they are unsure feel free to reach out to me in the usual locations.

Getting started with OpenCL using mesa/rusticl

Mesa, the open source low level graphics stack, has featured support for Open Compute Language (OpenCL) for some time via a front end called Clover. The problem was that the GPUs that it supported were limited, it didn’t have Image support, and wasn’t really under active development. Around a year ago Karol Herbst filed a merge request adding rusticl to Mesa 22.3 release, and soon after that I enabled it optionally in Fedora.. What is rusticl? It’s a OpenCL API implementation written in rust for Mesa, it will eventually replace clover. One advantage it has is image support from the outset and also works on much wider range of OpenCL capable GPUs, including some ARM GPUs, and the support is actively improving all the time.

In the year since it landed in a stable mesa release rusticl keeps evolving, faster, more HW support, more features, less crashes. I’ve tinkered with it as I’ve had spare time on the weekends and evenings as well as trying to work out details of how you’d use it to run higher level stacks.

As of writing it works with following gallium drivers: iris (Intel), nouveau (Nvidia), radeonsi/r600 (AMD ATI), and panfrost (Arm MALI). There’s other drivers that are various stages of development but are not yet upstream.

So let’s get the basics up and running on Fedora if you have supported hardware. First install the core software stack:

$ sudo dnf install -y mesa-libOpenCL mesa-dri-drivers spirv-llvm-translator spirv-tools-libs clinfo clpeak

Next we run clinfo and clpeak with required parameters, from the driver names above (in this case an Intel laptop), to enable rusticl. The two commands output a lot of information so I’m not going to post them here but the output shows OpenCL running and some details about what’s supported:

$ RUSTICL_ENABLE=iris clinfo --list
WARNING: OpenCL support via iris+clover is incomplete.
For a complete and conformant OpenCL implementation, use
https://github.com/intel/compute-runtime instead
Platform #0: rusticl
 `-- Device #0: Mesa Intel(R) Xe Graphics (TGL GT2)
Platform #1: Portable Computing Language
 `-- Device #0: cpu-11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz
Platform #2: Clover
$ RUSTICL_ENABLE=iris clinfo
output a lot of details
$ RUSTICL_ENABLE=iris clpeak
output a lot of details

This gets up the basic pieces up and running for OpenCL, there’s of course more to do and not all use cases are complete. Eventually we won’t need to have the environment variables to enable rusticl. The details of drivers and other features enabled by environment variables are documented here. I plan to do some more posts as follow ups to build on this basis.

Using iwd for WiFi in Fedora

Fedora uses NetworkManager as the default for managing all the various different types of network. Underneath NetworkManager uses wpa_supplicant to connect to 802.11 based, AKA WiFi, wireless networks. There is an alternative called iwd which in a number of use cases works better, it also has the advantage that it offloads a bunch of things like crypto to the kernel interfaces which makes it smaller, and it’s under active development. iwd has a nice straight forward interface as well as being supported as an alternative NetworkManager so it just works in Fedora whether via nmcli or your chosen desktop environment.

So how do you make use of it in Fedora? Well it’s been packaged and supported for some time so it’s quite straight forward and there’s two ways to use it with NetworkManager. You can either swap it out for wpa_supplicant, or they can be installed side by side and you can change the NetworkManager default in a config to enable easy testing/swapping.

Option 1 (side by side):

sudo dnf install -y iwd
sudo cat >> /etc/NetworkManager/conf.d/iwd.conf << EOF
[device]
wifi.backend=iwd
EOF
sudo systemctl restart NetworkManager

Option 2 (swap):

sudo dnf swap -y wpa_supplicant iwd
sudo systemctl restart NetworkManager

You can now connect to WiFi networks a before with NetworkManager. Note it loses exciting configured WiFi networks.

Getting started with CircuitPython on Fedora

One of my little maker projects has a need for a battery powered micro controller, some DIY to clean up some old equipment and some basic HW design. Ultimately I’d like to be able to integrate it as a fun thing into home automation possibly even using Matter. More on the project for another post.

To move things forward and actually be able to play with LEDs and buttons rather than doing a board port I decided to use the standard firmware. I looked through my collection of micro controllers and found a FeatherS2, it’s based on the ESP-32-S2 MCU with WiFi in a Adafruit Feather form factor with builtin LiPo charger circuit, a USB-C interface, an onboard RGB LED and runs CircuitPython.

Next up I needed to get a development environment up and running on Fedora, batteries and other HW bits can come later. First step was to work out how to getting it running the latest CircuitPython. On the CircuitPython page for the FeatherS2 there’s two firmware, one for boot and USB and then CircuitPython itself.

Step one: Ensure you’re in the dialout group
A lot of micro contollers use serial ports to interface with so you need to be able to talk to a variety of them such as ttyACM0, ttyUSB0 or ttyS0. Simplest way to do this is to add yourself to the dialout group as follows:

sudo usermod -aG dialout ${USER}

Step two: Upgrade UF2 Bootloader
This step was probably unneeded but I upgraded to the 0.11.0 release to ensure I had all the latest fixes. For this bit you need to put the board into recovery. There’s two buttons, you plug it in, press and hold BOOT, press and release RST (reset) and then a second later release BOOT. You can then run the following commands to upgrade UF2:

sudo dnf install -y esptool unzip wget
mkdir ~/CircuitPython; cd ~/CircuitPython
wget https://github.com/adafruit/tinyuf2/releases/download/0.11.0/tinyuf2-unexpectedmaker_feathers2-0.11.0.zip
unzip tinyuf2-unexpectedmaker_feathers2-0.11.0.zip
esptool.py -p /dev/ttyACM0 write_flash 0x0 combined.bin

Once the flash completes you press the RST button and the board will got into a UF2 download mode with the RGB shining a bright green. You’ll also find you have a new USB drive appear with the name of UFTHRS2BOOT. Next step is CircuitPython!

Step three: Install CircuitPython
The latest stable release when I started playing with this was 7.3.3. To install is a simple copy of the uf2 file. While it’s copying the RGB will flash orange, once complete the board will reset and reboot into CircuitPython:

cd ~/CircuitPython
wget https://downloads.circuitpython.org/bin/unexpectedmaker_feathers2/en_GB/adafruit-circuitpython-unexpectedmaker_feathers2-en_GB-7.3.3.uf2
cp adafruit-circuitpython-unexpectedmaker_feathers2-en_GB-7.3.3.uf2 /run/media/${USER}/UFTHRS2BOOT/

Step three: Actually make it do something
The standard development environment for MicroPython and/or CircuitPython is an IDE called MU Editor. It’s nicely packaged up in Fedora and seems to just work. The code in CircuitPython appears in a /run/media/${USER}/CIRCUITPY/ drive which mu automatically detects and you can get access to the python console directly within MU (correct permissions via the dialout group in step one). By default the FeatherS2 has a little app that cycles through colours on the RGB.

sudo dnf install -y mu

Next steps
The CircuitPython firmware has lots of built in functionality that just works, there’s also a large ecosystem of libraries and drivers available for Micropython and CircuitPython. Adafruit have a lot of extremely good tutorials to get you going. Next up I plan to play with getting it on my IoT network using WiFi and communicating via MQTT.

Using fwupdmgr to update NVME firmware

The fabulous fwupdmgr provides the ability to easily update firmware that is published to Linux Vendor Firmware Service (LVFS) but it can also be used to apply updates that aren’t necessarily in LVFS. One type of firmware that it supports updating is NVME firmware, that’s basically any NMVE, because the standard specifies a standardised mechanism for updating the firmware on all NVME devices.

I had a need to update a NVME firmware in an aarch64 device to see if it fixed an issue I was seeing. The Crucial P2 supported options were of course x86 only. The ISO download actually contained a little LinuxOS in an initrd on the .iso. The advice from Richard the fwupd technical lead was to “Look for a ~4mb high entropy blob” so mounting it up, I mounted the iso, extracted the initrd, and then used fwupdmmgr to apply the new firmware.

Find the NVME and check the firmware version:

$ cat /sys/class/nvme/nvme0/firmware_rev 
P2CR010 

So once I’d downloaded the update file I did the following to extract and update the firmware. Note I did this all as root, you can do most of it as non root.

# unzip iso_p2cr012.zip
# mount -o loop iso_p2cr012.iso /mnt/
# mkdir ~/tmp
# cp /mnt/boot/corepure64.gz tmp/
# cd tmp
# gunzip corepure64.gz
# cpio -iv < corepure64
# fwupdtool install-blob opt/firmware/P2CR012/1.bin
Loading…                 [-                                      ]
Loading…                 [-                                      ]
Choose a device:
0.	Cancel
1.	71b677ca0f1bc2c5b804fa1d59e52064ce589293 (CT250P2SSD8)
2.	2270d251f7c1dc37a29a2aa720a566aa0fa0ecde (spi1.0)
1
Waiting…                 [************************************** ] Less than one minute remaining…
An update requires a reboot to complete. Restart now? [y|N]: y

And away it goes, a reboot later and did it work?

$ cat /sys/class/nvme/nvme0/firmware_rev 
P2CR012

YES!!

HW video offload on Fedora Arm

There’s been the starting pieces of hardware video offload with the stateless engine support for some time and it now supports at least H264/HEVC/VP8/VP9/mepg2 decode offload depending on the hardware capabilities. The problem has been support for software/userspace has taken longer then the initial drivers but now that’s catching up now with gstreamer support landing in 2020 and with apps like clapper now using it. I’ve been meaning to play with this and work out how to make it work in Fedora as it’s useful for devices based on the AllWinner/Rockchip/NXP i.MX8 devices like the Pine64 laptops/phones plus a bunch of other devices, even NVIDIA Jetson devices should work before long.

You’ll need to ensure you have gstreamer1-plugins-bad-free installed and the video application I was testing with is clapper:

$ sudo dnf install -y gstreamer1-plugins-bad-free clapper

Seeing what hardware offload is supported:

$ gst-inspect-1.0 v4l2codecs
Plugin Details:
  Name                     v4l2codecs
  Description              V4L2 CODEC Accelerators plugin
  Filename                 /usr/lib64/gstreamer-1.0/libgstv4l2codecs.so
  Version                  1.20.0
  License                  LGPL
  Source module            gst-plugins-bad
  Source release date      2022-02-03
  Binary package           Fedora GStreamer-plugins-bad package
  Origin URL               http://download.fedoraproject.org

  v4l2slh264dec: V4L2 Stateless H.264 Video Decoder
  v4l2slmpeg2dec: V4L2 Stateless Mpeg2 Video Decoder
  v4l2slvp8alphadecodebin: VP8 Alpha Decoder
  v4l2slvp8dec: V4L2 Stateless VP8 Video Decoder
  v4l2slvp9alphadecodebin: VP9 Alpha Decoder
  v4l2slvp9dec: V4L2 Stateless VP9 Video Decoder

  6 features:
  +-- 6 elements

Finally in Clapper you need to enable playbin3 option, I also enabled Pipewire audio support:
Clapper Preferences

We will also be enabling decode support in Chromium and Chromium freeworld before long, there’s a little more work to do here, but as usual once it lands it’ll all just start to work in Chromium too!

Helpful git tips

So chatting with a colleague about some git tricks this week I discovered that not everyone was aware you could change the bash prompt to give certain git status, such as branch, and things like if you’re in merge/am/bisect modes etc. I’ve had the pieces in my .bashrc for so long I had literally got to the point it was assumed functionality that every one has enabled.

The following snippet is what I have in my ~/.bashrc:

# git branch display
source /usr/share/git-core/contrib/completion/git-prompt.sh
export GIT_PS1_SHOWDIRTYSTATE=true
export GIT_PS1_SHOWUNTRACKEDFILES=true
export PS1='[\[\e[0;32m\]\u\[\e[0m\]@\[\e[0;35m\]\h\[\e[0m\] \W\[\e[0;33m\]$(__git_ps1 " (%s)")\[\e[0m\]]\[\e[0;32m\]\$ \[\e[0m\]'

And with that you get a more useful prompt that looks like the prompt below, in this case merging bits, for all git repos with added colours too!:

[peter@localhost linux (master *+|MERGING)]$

Using nmcli to configure a static dual stack wired network interface

I recently managed to break the network on my VM that hosts this blog. Basically I removed the NetworkManager-initscripts-ifcfg-rh package because I don’t use the old style ifcfg configuration anywhere else and I had forgotten how long I’d had this VM. So I went into the web console, manually bought up the network with ip commands and reinstalled the package but it made no difference. Oh well! Time to just move it to the new config so I just worked out the nmcli options for all the bits in the old ifcfg. This VM network is nothing special, it’s basically dual IPv4/IPv6 interface with associated DNS.

Step 1: Show existing connections:

$ sudo nmcli c
NAME  UUID                                  TYPE      DEVICE 
eth0  a603bba7-fad8-3c71-9d4c-2cd5dc50e114  ethernet  eth0   

Step 2: Delete existing connection:

$ sudo nmcli c del a603bba7-fad8-3c71-9d4c-2cd5dc50e114

Step 3: Create a new connection (Note the IP addresses are random, the DNS servers are the Google public ones):

$ sudo nmcli c add type ethernet ifname eth0 con-name eth0 mac 80:00:00:ab:cd:ef ip4 192.168.10.6/24 gw4 192.168.10.1 ip6 fe80::b257:377c:e7b3:29ed/64 gw6 2A03:B0C0:0003:00D0:0000:0000:0000:0001 ipv4.dns "8.8.8.8 8.8.4.4" ipv6.dns "2001:4860:4860::8888 2001:4860:4860::8844"

Now the blog is back! The new connection is stored in /etc/NetworkManager/system-connections/eth0.nmconnection