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
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
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
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
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
riscv64gc-unknown-linux programs; and a CI pipeline to build
for RISC-V Linux.
When I tried out the code and CI
rustup changes I found that
effective-limits (one of
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
misizanoen1 posted a
PR for this first. I liaised with
libc maintainers to get this PR merged and to
libc's version so that
effective-limits can depend upon the fixed version of
rustup support for running on RISC-V Linux hosts,
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
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
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
These work using a
program running natively on the build machine to send cross-compiled test programs
and libraries to the
which runs the tests from within an emulated system and sends the results,
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>
<CONTAINER> is the architecture to build and test e.g.
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.
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.