We've ported GNOME OS to the PolarFire Icicle-kit development board from Microchip.
The dev board features a PolarFire SoC FPGA with 4 usable Application SiFive cores, which run at 600 MHz.
The dev board does not feature any sort of graphical outputs, but it does feature a PCIe port for expansion, so time was spent at the start of the project to test different GPUs with the dev board. We were limited to testing older and low-end graphics cards because the dev board features a single 12v barrel input. Jury-rigging an ATX PSU capable of providing auxillary power to a graphics card to work with the dev board would have been cumbersome. Cards from AMD and NVIDIA were both tested, but ultimately the only card which would POST with the dev board was ATI's 1GB HD6450. This seems to be because the PolarFire Icicle-Kit's PCIe implementation offers the cards a 512MB address space and most GPUs expect a much bigger window.
Because the dev board does not have a BIOS capable of POSTing the graphics card, and because we want a console as early as possible in the boot process; we compiled the firmware for the graphics card directly into the BSP's kernel.
GNOME OS and Freedesktop-SDK
Next we turned our attention to GNOME OS. GNOME OS is based on Freedesktop-SDK and is built with BuildStream. Codethink added support for producing builds for riscv64 to Freedesktop-SDK. GNOME OS leverages that to support other RISC-V based dev boards. As such, it was very easy to create an SD card with the PolarFire BSP, and a RISC-V-based root file system for GNOME OS, and then smash them together to produce a proof-of-concept.
The proof-of-concept was mostly successful, in that it was able to boot to a console on serial, but indicated Graphical Hardware Acceleration was going to be an issue. GDM would start without issue (a little slowly but considering the Icicle's specification, entirely normal), but there would only be static on the screen. We used the KMSCube application to debug the issue because it is substantially less complicated than trying to debug the issue in gnome-shell. We also tested using Weston in Freedesktop-SDK, and we tested Weston and KMSCube in the PolarFire buildroot BSP by enabling the relevent options. In all cases, we found software rendering using the softpipe driver was successful, but very slow, and hardware acceleration using the r600 driver resulted in static. Incidentally, at this time, buildroot will not build the r600 driver for anything but x86 targets, so only software rendering was tested under buildroot. We also tested the graphics card under other systems and confirmed that it worked properly. Ultimately we concluded that hardware acceleration was a lost cause on this board. We would proceed with software rendering using the softpipe driver.
A viable path forward plotted; it was then necessary to port over relevent bits of the BSPs into the GNOME OS project. It was simply a matter of creating a set of elements which would produce an SD card image as outlined by the polarfire BSP, while combinding the GNOME OS root file system with our adjustments to use softpipe, along with our special firmware-laden kernel.
Build it yourself
Our port of GNOME OS to the RISC-V board uses GNOME's gnome-build-meta repository, used by their release time to build the entire GNOME software stack.
It is a BuildStream project which uses the Freedesktop-SDK Linux software stack platform definitions as a base.
Environment setup
The first step is to ensure you have BuildStream installed. We used BuildStream version 1.6.1 because that is packaged on the Debian system we used.
BuildStream does not cross-compile, it does native compilation. In order to build for RISC-V on our x86-64 build machine, BuildStream uses QEMU to run RISC-V binaries under emulation.
To get this working we had to install QEMU from source because the version in Debian 10 was too old.
./configure --static --disable-system --target-list=riscv64-linux-user
make
sudo cp build/qemu-riscv64 /usr/bin/qemu-riscv64-static
After that we had to prod binfmt to use this to run RISC-V binaries.
# unregister existing
echo "-1" | sudo tee -a /proc/sys/fs/binfmt_misc/qemu-riscv64
#register with F flag
echo ":qemu-riscv64:M:0:\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xf3\x00:\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff:/usr/bin/qemu-riscv64-static:F" | sudo tee -a /proc/sys/fs/binfmt_misc/register
Build
First you need the source. Our work is on the robjh/icicle-kit-master. branch:
git clone https://gitlab.gnome.org/scott.clarke/gnome-build-meta.git
cd gnome-build-meta
git checkout robjh/icicle-kit-master
Now that you have the source, you can start the build:
bst -o arch riscv64 build --track-all boards/icicle-kit/image.bst
This will take a long time. BuildStream first bootstrap builds GCC to ensure that the final artifact is completely reproducible from known sources.
Additionally running the RISC-V-native GCC under emulation means it will take a long time. In particular LLVM and Rust are slow to build. Overall our build took well over 40 hours.
Once the build completes, you will be able to check it out with:
bst -o arch riscv64 checkout boards/icicle-kit/image.bst here
The exact command might be different with another version of BuildStream. The output is an SD card image:
ls here
sdcard.img
Deploying onto a board
Insert an SD card and find its device path.
export SDCARD=/dev/mmcblk0
sudo dd if=checkout/sdcard.img of=${SDCARD} bs=4k
Now insert the card into the board and turn it on.
Links
- PolarFire Icicle-kit devboard from Microchip.
- Merge request for Icicle-kit support in gnome-build-meta.
Related content
Other Content
- Codethink/Arm White Paper: Arm STLs at Runtime on Linux
- Speed Up Embedded Software Testing with QEMU
- Open Source Summit Europe (OSSEU) 2024
- Watch: Real-time Scheduling Fault Simulation
- Improving systemd’s integration testing infrastructure (part 2)
- Meet the Team: Laurence Urhegyi
- A new way to develop on Linux - Part II
- Shaping the future of GNOME: GUADEC 2024
- Developing a cryptographically secure bootloader for RISC-V in Rust
- Meet the Team: Philip Martin
- Improving systemd’s integration testing infrastructure (part 1)
- A new way to develop on Linux
- RISC-V Summit Europe 2024
- Safety Frontier: A Retrospective on ELISA
- Codethink sponsors Outreachy
- The Linux kernel is a CNA - so what?
- GNOME OS + systemd-sysupdate
- Codethink has achieved ISO 9001:2015 accreditation
- Outreachy internship: Improving end-to-end testing for GNOME
- Lessons learnt from building a distributed system in Rust
- FOSDEM 2024
- QAnvas and QAD: Streamlining UI Testing for Embedded Systems
- Outreachy: Supporting the open source community through mentorship programmes
- Using Git LFS and fast-import together
- Testing in a Box: Streamlining Embedded Systems Testing
- SDV Europe: What Codethink has planned
- How do Hardware Security Modules impact the automotive sector? The final blog in a three part discussion
- How do Hardware Security Modules impact the automotive sector? Part two of a three part discussion
- How do Hardware Security Modules impact the automotive sector? Part one of a three part discussion
- Automated Kernel Testing on RISC-V Hardware
- Automated end-to-end testing for Android Automotive on Hardware
- GUADEC 2023
- Embedded Open Source Summit 2023
- RISC-V: Exploring a Bug in Stack Unwinding
- Adding RISC-V Vector Cryptography Extension support to QEMU
- Introducing Our New Open-Source Tool: Quality Assurance Daemon
- Achieving Long-Term Maintainability with Open Source
- FOSDEM 2023
- Think before you Pip
- BuildStream 2.0 is here, just in time for the holidays!
- A Valuable & Comprehensive Firmware Code Review by Codethink
- GNOME OS & Atomic Upgrades on the PinePhone
- Flathub-Codethink Collaboration
- Codethink proudly sponsors GUADEC 2022
- Tracking Down an Obscure Reproducibility Bug in glibc
- Web app test automation with `cdt`
- FOSDEM Testing and Automation talk
- Protecting your project from dependency access problems
- Full archive