In less than an hour, Google Summer of Code 2016 will be over (at least for us students). In this blog post, I will describe how you can use coreboot on RISC-V.
You can find the complete list of commits that I made during GSoC with this gerrit query.
The details
Compiling spike, the RISC-V instruction-set-level simulator
Spike, also known as riscv-isa-sim, is the reference implementation of RISC-V, and the only RISC-V platform that is currently known to work with coreboot (QEMU is nominally also supported, but the corresponding coreboot code has not been updated in a while).
First, you need to build and install libfesvr:
- Clone the libfesvr git repository
- run ./configure --prefix="$HOME" && make && make install
Then, you can compile and install spike:
- Clone the spike git repository.
- Apply the patch in this pull request to make console output possible.
- Open riscv/processor.cc in a text editor and find processor_t::get_csr. Add a line that reads case CSR_MTIME: return 0;.
- run ./configure --prefix="$HOME" --with-fesvr="$HOME" && make && make install
Compiling coreboot for RISC-V
- Clone the coreboot git repository, if you haven’t already
- Apply Iru Cai’s patch that updates the toolchain to GCC 6.1. You will currently have to fix a merge conflict when you apply this patch, but it’s an easy one.
- Run make crossgcc-riscv
- Run make menuconfig to configure coreboot. Select Emulation and SPIKE usb riscv in the Mainboard menu.
- Run make
- Run util/riscvtools/make-spike-elf.sh build/coreboot.rom build/coreboot.elf
- Start coreboot by running spike build/coreboot.elf. You should see a few pages of output, ending in Payload not loaded.
Compiling and running Linux
- Clone the riscv-linux git repository and check out the priv-1.9 branch
- Apply this patch that allows linux to be started in machine-mode.
- Download a copy linux 4.6.x from kernel.org, and unpack it. I’ll assume version 4.6.2 is used.
- cd into linux-4.6.2/arch and symlink the arch/riscv directory from riscv-linux
- Back in linux-4.6.2, run make O=build ARCH=riscv defconfig; cd into the newly created build directory.
- Run make ARCH=riscv menuconfig. In the “General Setup” menu of the linux menuconfig, enter path/to/coreboot/util/crossgcc/xgcc/bin/riscv64-elf- as the cross-compiler tool prefix.
- Run make ARCH=riscv vmlinux to compile linux.
- Open vmlinux in a hex editor, such as hexer. Change the 8-byte number at 0x18 to 00 00 00 90 00 00 00 00; Add 00 00 00 90 00 00 00 00 to the numbers at 0x58 and 0x90, to load linux at physical addresses within RAM. It’s unfortunate that I have to recommend this step, but I did not come up with a better fix yet.
Next, you need to add vmlinux to coreboot:
- Return to the coreboot directory.
- Apply the remaining coreboot patches that are tagged riscv.
- In the Payload menu, select An ELF executable payload. Instead of payload.elf, select the vmlinux file.
- Run make and util/riscvtools/make-spike-elf.sh build/coreboot.rom build/coreboot.elf again.
- Run spike build/coreboot.elf. You should now see a Linux boot, at least partially.
Future work
Even though my GSoC is over, coreboot’s support for RISC-V can still be improved, and I intend to fix at least some of the following things:
- As you can see above, running coreboot and linux on RISC-V currently isn’t straight-forward, but involves a few manual steps.
- There are other RISC-V platforms that I’d like to see coreboot on, such as lowRISC.
- Linux does not completely boot, i.e. into userspace. There are still some bugs to be ironed out.
- Automatic testing could be used to detect regressions.
- I only tested coreboot on RISC-V with Linux; support for other operating systems or payloads is welcome.
Acknowledgements
I’d like to thank Ron Minnich and Furquan Shaikh for being good mentors, and everyone in the coreboot community for being helpful and friendly.