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!!

Fedora on NVIDIA Jetson Xavier

The last two years or so I’ve been working with NVIDIA on general distro support including UEFI and ACPI for their Jetson Xavier platforms. Their Xavier platform, except a few quirks, are mostly SystemReady-ES compliant, so having a SBBR compliant firmware goes quite some way to having a widely available, relatively affordable, platform that “just works” for the arm ecosystem. I was very excited to finally have NVIDIA finally release the first version in March this year. This firmware is a standard UEFI firmware based on the open source TianoCore/EDK2 reference firmware, it allows booting in either ACPI or Device-Tree mode and supports all the basic things needed. The ACPI mode is not as fully featured as the Device-Tree mode as yet. In ACPI you get compute (cpu/memory/virt etc), PCIe, USB, network, which is just fine if you’re just looking for standard server or for testing a SystemReady system but there’s no display or accelerator support as yet. The Device-Tree mode is more feature full but both work pretty well with upstream kernels and NVIDIA are improving and upstreaming more things regularly.

For flashing with the latest Fedora releases you’ll want the Linux for Tegra (L4T) R32.6.1 release and the latest UEFI firmware (1.1.2 ATM). The R32.6.1 release fixes issues with python3.9 and later so you’ll need that for Fedora. The following will extract everything into a directory called Linux_for_Tegra. Note the release for Xavier is different to the L4T for the TX1/TX2 series of devices such as the nano.

$ tar xvf Jetson_Linux_R32.6.1_aarch64.tbz2
$ tar xvf nvidia-l4t-jetson-uefi-R32.6.1-20211119125725.tbz2
$ cd Linux_for_Tegra

To flash either the Xavier AGX or NX you need to put them into recovery mode and connect a USB cable, USB-C for AGX or micro-USB for NX. Once you’re in recovery mode you can flash them.

For the Xavier AGX:

$ lsusb | grep -i NV
Bus 001 Device 086: ID 0955:7019 NVIDIA Corp. APX
$ sudo ./flash.sh jetson-xavier-uefi-min external

For the Xavier NX:

$ lsusb | grep -i NV
Bus 001 Device 089: ID 0955:7e19 NVIDIA Corp. APX
$ sudo ./flash.sh jetson-xavier-nx-uefi-acpi internal

There will be a bunch of output and it will eventually return to the prompt and reset the device. You can now install Fedora on the device. You can use any of the pre-canned aarch64 image or traditional installer available from the fedora website. When running in ACPI mode you don’t get display output so you’ll need to use a serial console, in both ACPI and Device-Tree mode there’s not currently support for accelerated GPU graphics/AI/ML support. If you want to be able to easily switch between ACPI/Device-Tree modes you’ll want to install the dracut-config-generic package to have a generic initrd to make it easy to reboot between both modes.

SystemReady ES support for MacchiatoBin

I’ve had a MacchiatoBin Double Shot board for some time. It runs various services for my local network and generally just works. I run a TianoCore EDK2 firmware on it using ACPI. It’s purely a network device so I don’t bother with any form of graphics and in the very few occasions I need to access it locally I do so via the built in USB serial TTL.

Recently Solid Run announced the MacciatoBin is now SystemReady ES certified. Excellent news! I’ve worked with Arm for some time on both the SytemReady ES (Embedded Server) and SystemReady IR (IoT Ready) standards and recently the certification program has been finalised so it’s nice to start to see the fruits from all the hard work myself, and may others, have done over a number of years appear.

The EDK2 firmware I was running was coming up to two years old and there’s been a number of enhancements to the various components of the firmwares that make up a complete update so I decided to download the latest firmware and update it. Eventually I am sure Solid Run will have these published to LVFS to make the process even easier but I know that to get to this stage has been a LOT of effort so it’s still a great step forward.

The first step of updating a EDK2 firmware is to download it and put it on the EFI partition:

peter@macbin:~ $ wget https://github.com/Semihalf/edk2-platforms/wiki/releases/flash-image-a8k-mcbin.bin_r20210630
peter@macbin:~ $ sudo mv flash-image-a8k-mcbin.bin_r20210630 /boot/efi
peter@macbin:~ $ sudo reboot

On reboot you’re given a prompt to interrupt the boot process. From the menu select the option for the shell:

Shell> fs0:
FS0:\> ls
Directory of: FS0:\
04/06/2021  19:08          4,096  EFI
07/25/2021  17:01           2,855,040  flash-image-a8k-mcbin.bin_r20210630
          1 File(s)   2,855,040 bytes
          1 Dir(s)

FS0:\> fupdate flash-image-a8k-mcbin.bin_r20210630
Detected w25q32bv SPI NOR flash with page size 256 B, erase size 4 KB, total 4 MB
Updating, 99%
fupdate: Update 2855040 bytes at offset 0x0 succeeded!
FS0:\> reset

It then reboots and we’re done, you see a very similar output to previously with some updated versions of various firmware and before long you’re back through grub and running Fedora again. Painless!

I’m really happy to see this is such a straightforward process, and I’m looking forward to seeing more features, enhancements and fixes to the firmware including capsule updates and the associated LVFS/fwupdmgr support, and improvements around firmware security (fwupdmgr –force security). Top marks to the Solid Run team!

Fedora on the Pinebook Pro

First thing to note here is that this is not limited to the Pinebook Pro, I’m just using it as the example for 64 bit Rockchip devices with SPI flash on Fedora. This post is focused on devices with SPI but I’ll do a separate follow-up post for other devices including details for writing to eMMC over USB.

The story of Fedora on the Pinebook Pro, and other Rockchip devices, has been a sordid story of a lack of time, bugs, rabbit holes, more bugs and various other things. Not at all sordid at all really, mostly just a lack of time on my behalf, and nobody else stepping up to assist in a way to benefit all Fedora users, mostly they do one time hacks to sort themselves. Overall the support in Fedora for Rockchip devices has been quite solid for a number of releases. The problem has been with the early boot firmware, notable because without SPI flash it wants to splat itself across the first 8Mb of the disk, and if there was SPI flash it generally wasn’t overly stable/straight forward.

Anyway we’re now in a place where devices with SPI flash should mostly work just fine, those devices without it will work with a little manual intervention, and while the support isn’t complete, and will need more polish, they’re all details we can polish with little interruption to users by standard package updates. By default users will have accelerated graphics and from my testing on GNOME 40 it’s by all accounts a pretty decent experience!

Setting up the firmware

First step is to get the firmware written to SPI flash. This is a two step process, the first is to write out a micro SD card from another device, the second is to boot that mSD card on the Pinebook Pro, or another device like the Rockpro64, and write the firmware to the SPI flash.

There’s some nuances to this process, and the way the early boot firmware works, if another version of U-Boot takes precedence that is likely OK as it should still be able to work, the fall back is to use the internal switch to turn off the eMMC temporarily. I also have no idea if the Pine64 shipped U-Boot has any display output, the Fedora build does, if not you’ll need to use the option to disable eMMC or use a serial console cable. Anyway on to the steps:

Set up the mSD card
Use a mSD card that has no data you wish to keep, this process will wipe it out. You want at least U-Boot build 2021.04-3.fc34, you can adjust the umount to be more specific, and you need to substitute XXX for the media, otherwise it’s a relatively quick and straightforward process:

sudo dnf install --enablerepo=updates-testing -y arm-image-installer uboot-images-armv8
sudo umount /run/media//*
sudo spi-flashing-disk --target=pinebook-pro-rk3399 --media=/dev/XXX

Write the firmware to flash
Now remove the mSD card from your host and put it into the Pinebook Pro. Press the power button, from experience you likely need to press and momentarily hold and in a second or two the display will light up with text output. Interrupt the boot by pressing space. Next up we write out the flash:

Hit any key to stop autoboot:  0 
=> ls mmc 1:1
   167509   idbloader.img
   335872   idbloader.spi
   975872   u-boot.itb
  9331712   u-boot-rockchip.bin

4 file(s), 0 dir(s)

=> sf probe
SF: Detected gd25q128 with page size 256 Bytes, erase size 4 KiB, total 16 MiB

=> load mmc 1:1 ${fdt_addr_r} idbloader.spi
335872 bytes read in 39 ms (8.2 MiB/s)

=> sf update ${fdt_addr_r} 0 ${filesize}
device 0 offset 0x0, size 0x52000
61440 bytes written, 274432 bytes skipped in 0.803s, speed 427777 B/s

=> load mmc 1:1 ${fdt_addr_r} u-boot.itb
975872 bytes read in 107 ms (8.7 MiB/s)

=> sf update ${fdt_addr_r} 60000 ${filesize}
device 0 offset 0x60000, size 0xee400
914432 bytes written, 61440 bytes skipped in 9.415s, speed 106127 B/s

Once the last command above has completed eject the mSD card and type reset at the => prompt and the device should reboot and you should see output similar to before but running from the SPI flash!

If you had to turn off the eMMC you can now turn it back on.

Installing Fedora

The nice thing with the firmware on SPI flash it should now work mostly like any other laptop and you can use either the pre canned desktop images (Workstation, KDE, XFCE, Sugar), the Workstation LiveCD iso or the standard everything network installer.

To run the arm Workstation image off a micro SD card or USB stick you can do the following:

arm-image-installer --media=/dev/XXX --resizefs --target=none --image=Fedora-Workstation-34-1.2.aarch64.raw.xz

Note ATM you’ll need to use the USB port on the right hand side, I need to investigate the USB/USB-C port on the left as it appears not to currently work in firmware, but works fine once Fedora is running.

Next steps and improvements

The two biggest issues remaining for the Pinebook Pro is enabling PCIe support and the lack of the brcmfmac firmware, both WiFi and bluetooth, being upstream. For the later issue if there’s anyone from Synaptics that can assist in resolving that problem please reach out to me! A interim WiFi firmware to use is here.

Some things at the Fedora level I’ve not really tested and will do so more, and likely polish with OS updates, in the coming weeks include sound, USB-C port (charging and display output). On the firmware level there’s still some more improvements to be done, tweaks to improve the USB support, turning on the power LED as early as possible to give an indicator, improvements to the EFI framebuffer to ensure consistent early boot output, support for UEFI BGRT to enable smooth boot etc.

For support please email the Fedora Arm mailing list or reach out on IRC via #fedora-arm on Libera.Chat.

Documenting my various arm and IoT devices: quick overview

It’s been around ten years since I got my first arm single board computer, a Beagle-xM, which started me down the route of playing with Fedora on ARM and ultimately to my role in device edge/IoT at Red Hat. Shortly after that time I also moved into my current flat, almost ten years later I finally made the decision to move to a new place.

In the process of unpacking the contents of boxes from the flat into my new home office I thought I would document all my devices. This is mostly for my own reference, but I have little doubt others are interested from previous conversations. I’ve broken the list down into a few broad categories, mostly so the blog post isn’t unwieldy, there’s certainly cross overs between the categories, like some generations of the Raspberry Pi can run in either 32 or 64 bit mode, some Arm SBCs also have an integrated micro controller etc. For simplicity I’m putting those cross over devices in a single list, that of which they’re most capable, I’m also not putting devices on the list that aren’t easily able to run an open source OS such as Linux or Zephyr RTOS as I have numerous micro controllers/phones etc I can’t be bothered with and hence they’re not seen as useful for this list.

The lists, I will update with links as I post them, are going to be as follows:

  • Part one: Arm 64 bit devices (aarch64)
  • Part two: Arm 32 bit devices (ARMv7)
  • Part three: Micro controllers
  • Part four: x86 and other devices