RISC-V is a new Instruction Set Architecture developed in the open and available for use without paying a license fee. Being an open ISA means there are no barriers to achieving open hardware implementations - which opens the door to performant (mostly) open hardware processors!
RISC-V is considerably newer than most ISAs and so can draw on decades more computer architecture research and practical experience. Many of the improvements are well explained in "The RISC-V Reader" by David Patterson and Andrew Waterman.
Rust is a modern systems programming language which uses an innovative type system to track ownership of all data in a program. This allows automatic memory management without a language runtime, multithreaded programs which are provably free of data races, and the guarantee that all values are correctly typed. Furthermore, Rust brings the conveniences of a modern programming language to systems programming: with built in testing and dependency management, and an excellent standard library.
Codethink sponsored me to improve the support for Rust on RISC-V Linux. I was excited to do this because I consider both Rust and RISC-V to be the future of computer systems engineering.
Finding my feet
When I started work there was already an
issue tracking
riscv64gc-unknown-linux-gnu
(64-bit RISC-V base instruction set plus compressed
instructions on GNU+Linux) Rust support; Rust's compiler
already had support for
riscv64gc-unknown-linux-gnu
; and there were even
Debian packages.
This was surprising because the Rust project didn't list RISC-V Linux support on the supported platforms page. When asking about this, I was pointed towards the RFC defining criteria for official Rust support at each of three tiers. To summarise briefly:
- Tier 1 targets will always build and pass tests (e.g. x86_64 GNU+Linux).
- Tier 2 targets will always build, but tests may not pass (e.g. aarch64 Android).
- Tier 3 targets provide no guarantees of support (e.g. MIPS ulibc+Linux).
There were very few requirements for official Tier 3 support so I submitted
a PR advertising Tier
3 Rust support for riscv64gc-unknown-linux-gnu
. This is merged so Rust now
advertises support for RISC-V Linux.
In the long run I would like to see riscv64gc-unknown-linux-gnu
Tier 2 support so that the Rust Project distribute official binaries: making Rust
easy to install on RISC-V Linux using rustup (the standard
Rust installer). But more work is needed first.
RISC-V Rust tooling support
For rustup
to be useful on RISC-V Linux hosts it needs official Rust
binaries to install; minor code changes to tell rustup
that it knows how to
install riscv64gc-unknown-linux
programs; and a CI pipeline to build rustup
for RISC-V Linux.
When I tried out the code and CI rustup
changes I found that
effective-limits (one of rustup
's
dependencies) didn't build correctly for RISC-V Linux. This was in turn because
of a bug in libc (Rust's bindings for the
standard C library). I wrote a patch to fix libc
but
misizanoen1 posted a
PR for this first. I liaised with
the libc
maintainers to get this PR merged and to
bump libc
's version so that
effective-limits
can depend upon the fixed version of libc
.
At the time of writing I have completed all changes to rustup
and the
PR is ready for review,
following the merge of my
effective-limits
PR
to add the dependency on the fixed version of libc
.
Besides rustup
support for running on RISC-V Linux hosts, rustup
also
supports installing cross-compilation targets to build RISC-V binaries from
other hosts (e.g. from my x86_64
GNU+Linux Laptop). This worked out of the box
because all rustc
targets are built for each host for which the
Rust project distribute binaries. However, instead of interfacing directly with
rustup
to install foreign targets, the usual way for Rust developers to
cross compile is to use the cross
wrapper program.
cross
was also missing RISC-V support. My PR to cross
is
here. There was a spurious CI
failure for an unrelated architecture, which I also
fixed.
Testing Rust on RISC-V
With the low hanging fruit out of the way, one of the biggest blockers for Rust Tier 2 RISC-V Linux support is documentation explaining how to run the compiler and standard library tests. In the case of RISC-V Linux, tests must run in an emulator because real hardware is not easily available.
Rust already supports emulated testing for
arm-unknown-linux-gnueabihf
and
aarch64-unknwon-linux-gnu
.
These work using a
remote-test-client
program running natively on the build machine to send cross-compiled test programs
and libraries to the
remote-test-server
which runs the tests from within an emulated system and sends the results, stdout
and stderr
back to the client for reporting.
I followed this pattern for riscv64gc-unknown-linux-gnu
, building a rootfs image
for QEMU roughly following
instructions from Debian but instead using
Ubuntu 20.04 because Debian "Unstable" isn't intended for production use.
The whole build is wrapped in a Docker container, run using a wrapper script:
$ ./src/ci/docker/run.sh <CONTAINER>
Where <CONTAINER>
is the architecture to build and test e.g. aarch64-gnu
or
riscv64gc-linux
.
When running the tests in the RISC-V emulator I found that many tests hang indefinitely. In general, these tests use multi-threading, multi-processing or depend upon stack unwinding on a panic. These tests need further work so I haven't upstreamed the RISC-V Linux testing support yet.
The state of Rust on RISC-V
The hanging tests indicate there's more work required to provide full language support on RISC-V. However, the compiler works well enough to build itself and most other crates, and tooling support is ready.
Reflections
I had little experience working with upstream open source communities before this project. The Rust community have great documentation and have been both friendly and helpful - making this a perfect place to start.
While I haven't implemented anything technically complex or unusual, I hope my contributions can be useful to the community by getting much of the time consuming boilerplate CI and tooling work out of the way so that other contributors can work on the more exciting problems. I was surprised how much behind the scenes work is involved in providing CI, testing and tooling to give Rust its distinctive polish; and I am pleased to have the opportunity to contribute in a small way to that.
Other Content
- 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
- Porting GNOME OS to Microchip's PolarFire Icicle Kit
- YAML Schemas: Validating Data without Writing Code
- Full archive