Running upstream OpenSBI on SpacemiT K1

The SpacemiT K1 is a rather interesting RISC-V SoC, found for instance on boards like the Banana Pi BPI-F3 board. It's one of those platforms that looked promising on paper, but took a bit of time before things really started to move upstream. Things have clearly accelerated over the last few months.

Linux 7.0 brings, among other things PCIe support, making the board quite capable as a development board. SD card, CPU thermal sensor and cpufreq support are already in the pipe.

Unfortunately the situation is less advanced on the firmware side. There is only very basic support for the SpacemiT K1 in U-Boot for the second stage, and initial SPL support has been posted on the mailing list, but has not yet been merged. In practice, this means you still have to rely on the vendor U-Boot, which is based on the rather old 2022.10 release.

On the other hand, OpenSBI does have upstream support for the SpacemiT K1, however it is not compatible with the vendor U-Boot, mostly due to device tree differences.

This can be addressed by applying a few patches to the vendor U-Boot, which I have published in a git tree in the k1-bl-v2.2.y-opensbi branch (technically this can also be handled on the OpenSBI side, but I prefer using a vanilla upstream OpenSBI version). The first two patches update the configuration to get closer to the upstream U-Boot defaults, and to enable some configuration options for the Milk-V Jupiter board, which stores its firmware in SPI NOR flash, instead of eMMC for the Banana Pi BPI-F3. The following patches update the device tree by adding extra compatible entries to several devices, as expected by the upstream kernel and OpenSBI (thanks to Troy Mitchell for the hint about the UART change) and update the CPU riscv,isa properties. Finally an additional patch adds the SpacemiT P1 PMIC to the device tree, which is required for the OpenSBI reboot patchset I recently posted (this is currently done only for the Banana Pi BPI-F3 and Milk-V Jupiter boards, but extending it to other boards should be straightforward).

Building this U-Boot version is as simple as running this command in the source directory:

make k1_defconfig && make

On a Banana Pi BPI-F3 board, the resulting U-Boot can be flashed with:

echo 0 > /sys/block/mmcblk0boot0/force_ro
dd if=FSBL.bin of=/dev/mmcblk0boot0 bs=512 seek=1
dd if=u-boot.itb of=/dev/mmcblk0p1

Building upstream OpenSBI is also fairly simple, and can be done by running this command in the source directory:

make PLATFORM=generic

On a Banana Pi BPI-F3 board, the resulting OpenSBI can be flashed with:

dd if=fw_dynamic.itb of=/dev/mmcblk0p2

Note that the vendor U-Boot version is patched to install OpenSBI in a separate partition instead of embedding, as the upstream U-Boot does. While this works well on the Banana Pi BPI-F3, the corresponding partition in the Milk-V Jupiter SPI NOR flash is too small for the upstream OpenSBI version, and can't be easily resized without breaking compatibility. To address this, the branch k1-bl-v2.2.y-opensbi-embedded contains an additional patch (a bit hackish I admit) to somehow restore the upstream approach. The build process remains simple, first build OpenSBI with the following command:

make PLATFORM=generic

Then build U-Boot, specifying the patch to the just built OpenSBI firmware:

make k1_defconfig && make OPENSBI=/path/to/opensbi/build/platform/generic/firmware/fw_dynamic.bin

On a Milk-V Jupiter board, the resulting combined U-Boot/OpenSBI can be flashed with:

modprobe mdtblock
dd bs=4k if=FSBL.bin of=/dev/mtdblock2
dd bs=4k if=u-boot.itb of=/dev/mtdblock5

This combined U-Boot/OpenSBI can also be used on a Banana Pi BPI-F3, using the same flashing procedure as above, while skipping the OpenSBI part (although running it won't cause any issue, it will simply be unused).

All of this is admittedly a bit hackish, but enabling the use of upstream OpenSBI is already one step forward. Hopefully, in a few months, we will be able to rely entirely on upstream U-Boot.

UEFI Unified Kernel Image for Debian Installer on riscv64

On the riscv64 port, the default boot method is UEFI, with U-Boot typically used as the firmware. This approach aligns more closely with other architectures, which avoid developping riscv64 specific code. For advanced users, booting using U-Boot and extlinux is possible, thanks to the kernel being built with CONFIG_EFI_STUB=y.

The same applies to the Debian Installer, which is provided as ISO images in various sizes and formats like on other architectures. These images can be put on a USB drive or an SD-card and booted directly from U-Boot in UEFI mode. Some users prefer to use the netboot "image", which in practice consists of a Linux kernel, an initrd, plus a set of Device Tree Blob (DTB) files.

However, booting this in UEFI mode is not straightforward, unless you use a TFTP server, which is also not trivial. Less known to users, there is also a corresponding mini.iso image, which contains all the above plus a bootloader. This offers a simpler alternative for installation, but depending on your (vendor) U-Boot version this still requires to go through a media.

Systemd version 257-rc2 comes with a great new feature, the ability to include multiple DTB files in a single UKI (Unified Kernel Image) file, with systemd-stub automatically loading the appropriate one for the current hardware. A UKI file combines a UEFI boot stub program, a Linux kernel image, an optional initrd, and further resources in a single UEFI PE file. This finally solves the DTB problem in the UEFI world for distributions, as a single image can work on multiple boards.

Building upon this, debian-installer on riscv64 now also creates a UEFI UKI mini.efi image, which contains systemd-stub, a Linux kernel, an initrd, plus a set of Device Tree Blob (DTB) files. Using this image also ensures that the system is booted in UEFI mode. Booting it with debian-installer is as simple as:

load mmc 0:1 $kernel_addr_r mini.efi # (can also be done using tftpboot, wget, etc.)
bootefi $kernel_addr_r

Additional parameters can be passed to the image using the U-Boot bootargs environment variable. For instance, to boot in rescue mode:

setenv bootargs "rescue/enable=true"

AI crawlers should be smarter

It would be fantastic if all those AI companies dedicated some time to make their web crawlers smarter (what about using AI?). Noawadays most of them still stupidly follow every link on a Git frontend.

Hint: Changing the display options does not provide more training data!

Welcome Debian riscv64

After many years of effort, I am happy to announce that Debian riscv64 is now an official architecture!

This milestone is not the end of the journey but rather the beginning of a new one: the port will need to be rebootstrapped in the official archive, build daemons will have to be reinstalled and handed over to DSA, many bugs will need to be fixed. If everything goes well, the architecture will eventually be released with Trixie. Please note that this process will be long and will span several months.

I would like to take this opportunity to thanks everyone who contributed to this significant milestone, including individuals and Debian teams, as well as the organizations and companies that provided us with resources (by rough chronological order): MIT CSAIL, Sifive, Mullvad, tetaneutral.net, OSU Open Source Lab, Microchip, BeagleBoard.org Foundation, RISC-V international, PLCT Lab (ISCAS), StarFive, and Metropolitan Area Network Darmstadt.

Goodbye Debian GNU/kFreeBSD

Over the years, the Debian GNU/kFreeBSD port has gone through various phases. After many years of development, it was released as technology preview with the release of Squeeze and eventually became an official architecture with the release of Wheezy. However it ceased being an official architecture a couple of years later with the release of Jessie, although a jessie-kfreebsd suite was available in the official archive. Some years later, it was moved to the debian-ports archive, where it slowly regressed over the years. The development totally has now been stopped for over a year, and the port has been removed from the debian-ports archive. It's time to say it goodbye!

I feel a touch of nostalgia as I was deeply involved in the Debian GNU/kFreeBSD port for nearly a decade, starting in 2006. There are many different reasons to like GNU/kFreeBSD ranging from political to technical considerations. Personally, I liked the technical aspect, as the FreeBSD kernel, at that time, was ahead of the Linux kernel in term of features: jails, ZFS, IPv6 stateful firewalling, and at a later point superpages. That said it was way behind for hardware support and to the best of my knowledge this remains unchanged. Meanwhile, the Linux kernel development accelerated in the latter stages of the 2.6.x series, and eventually closed the feature gap. At some point, I began to lose interest, and also to lack time, and slowly stepped away from its development.

Backup server upgraded to Bookworm

A few months ago, I switched my backup server to an ODROID-M1 SBC. It uses a RK3568 SoC with a quad-core Cortex-A55 and AES extensions (useful for disk encryption), and I added a 2 TB NVME SSD to the M2 slot. It also has a SATA connector, but the default enclosure does not have space for 2.5" drives. It's not the fastest SBC, but it runs stable and quite well as a backup server, and it's fanless, and low-power (less than 2 W idle). The support for the SoC has been added recently to the Linux kernel (it's used by various SBC), however the device tree for the ODROID-M1 was missing, so I contributed it based on the vendor one, and also submitted a few small fixes.

All the changes ended in the Bookworm kernel, and with the Bookworm release approaching, I decided it was the good moment to upgrade it. It went quite well, and now I can enjoy running dist-upgrade like on other stable servers without having to care about the kernel. I am currently using Borg as a backup software, but the upgrade also gave access to a newer Restic version supporting compression (a must have for me), so I may give it a try.

New website, or kind of...

For over 15 years, I've hardly made any updates to my website, and it remains low on my priority list. So I made a radical decision to replace it entirely with my blog. The content of the website has been reduced to just two additional pages.

But nothing has been lost: nowadays, Wikipedia is a much better platform for sharing knowledge than random websites. And it happens that they already cover all that was on my website about subaquatic diving in French. They also offer a multitude of resources in electronics, including the topics that were on my website: LCD displays, I²C bus, barcodes, parallel ports, serial ports, and DCF77 reception.

Finally if you're in need of Debian QEMU images for various architectures, I recommend the Debian Quick Image Baker pre-baked images page instead.

riscv64 porterbox

For quite some time, many people asked for a riscv64 porterbox. Now we've got one called debian-riscv64-porterbox-01.debian.net.

A big thanks to SiFive for providing the HiFive Unmatched board and OSUOSL for assembling the hardware and hosting it.

GNU libc 2.34 in unstable

The GNU libc version 2.34 has just been accepted into unstable. Getting it ready has been more challenging than other versions, as this version integrates a few libraries (libpthread, libdl, libutil, libanl) into libc. While this is handled transparently at runtime, there are a few corner cases at build time:

  • For backwards compatibility, empty static archives (e.g. libpthread.a) are provided, so that the linker options keep working. However a few cmake files shipped in some packages still reference the path to the shared library symlink (e.g. libpthread.so) which is now removed.

  • A few symbols have also been moved from libresolv to libc and their __ prefix removed. While compatibily symbols are provided in the shared library for runtime compatiblity, this does not work at link time for static libraries referencing this symbol.

The next challenge is to get it migrating into testing!

For the adventurous persons, GNU libc 2.35 is now available in experimental. And as people keep asking, the goal is to get the just released GNU libc 2.36 into Bookworm.

James Webb Space Telescope launched!

The long awaited James Webb Space Telescope has finally been successfully launched today. It is a Xmas gift for many people who have been waiting for it for many years.

On a more personal side, I am happy and proud to have contributed to a tiny part of a tiny piece of software of this huge project over the last 15 years: the Instrument Performance Simulator of the NIRSpec instrument.