Troy Benjegerdes—September 06, 2018
An Open Source Release of the Freedom U540-C000's Bootloader
The FU540-C000, which is available on the HiFive Unleashed development board, is a Linux capable board based on the open source Freedom platform. We built this chip to drive RISC-V Linux development, and it's been incredibly successful. In the three months since we started shipping the board the RISC-V Linux distribution porting effort, with Debian and Fedora leading the charge, has come farther that it had come in the previous 5 years. It's been incredible watching the open source community get behind the RISC-V ISA, and the level of progress has exceeded anything we could have predicted at the beginning of this year.
We knew a Linux capable development board was the spark that the RISC-V software ecosystem needed, so our priority for the HiFive Unleashed was to get out a working board into the hands of open source developers as quickly as possible. At SiFive we strive to use (or produce) open source IP whenever feasible. While this is viable for simpler interfaces, modern high performance physical interfaces are very complicated and producing IP for them requires a massive development and verification effort. In order to make the HiFive Unleashed available it just wasn't feasible to develop open source DDR and Ethernet IP at SiFive, so we used some standard commercial IP.
We're extremely proud of what we've accomplished by releasing the HiFive Unleashed: we managed to produce a multi core, Linux capable processor with high performance I/O on a modern process, and we did it in an incredibly short time with a very small team. At SiFive we believe that open source hardware is the way of the future, but these sorts of industry-wide shifts happen incrementally instead of all at once.
With the release of the HiFive Unleashed we managed to push the needle forwards on open source hardware development. It's open to a degree that no other modern Linux capable SOC is: the ISA is an open standard, and the RTL is based on an open platform with many components available in open source. Designs similar to the FU540-C000 can be generated from Freedom platform and run on standard FPGA platforms.
There has always been one glaring issue with the HiFive Unleashed: our inability to release the DDR initialization code, which results in our reliance on a non-standard bootloader stack. This has been a hindrance for many users: the large binary blob eradicates much of the security benefits of having an open platform, BBL lacks essential bootloader features like network boot and device tree overlays, and the FSBL isn't fully featured enough to properly support chain loading a real bootloader.
Today we're finally able to rectify this issue by releasing the FU540-C000's ZSBL and FSBL as an open source project, which can be found on GitHub like all of SiFive's other open source projects. The code can be found at https://github.com/sifive/freedom-u540-c000-bootloader, but before you jump there you should read the rest of this blog post as it describes what's there, why it's there, and what our plans are for it. You'll also get to meet Troy, one of the latest additions to SiFive's RISC-V software team.
One of the reasons we could get the HiFive Unleashed out is that we've learned a lot of lessons from the open source software community and applied those to building chips. One important lesson is to release early and release often, a philosophy we believe will fundamentally change how hardware development is done. The speed at which we managed to get the HiFive Unleashed in the hands of developments is a testament to how powerful this methodology is.
We're taking the same release early, release often approach to releasing the bootloader source code. Earlier this week we got approval for the public release of our internal bootloader code, so here it is.
We view getting proper bootloaders up and running for the HiFive Unleashed to be much more valuable than having an easy to build FSBL, so we decided to just go ahead and release the code right away. We will, of course, make the code build and boot on the HiFive Unleashed, but even in the state it's in now this release is interesting for people interested in porting real bootloaders to the HiFive Unleashed. In fact: for people interested in porting bootloaders to the HiFive Unleashed it's probably more useful to read the FSBL's code than to see it boot.
When Troy started a few weeks ago our first planned project for him was to produce a U-Boot port for the FU540-C000 that ran after the FSBL (ie, didn't contain DDR initialization code). We got lucky and ended up getting pre-authorization (ie, authorization to ask for authorization :)) to release the DDR initialization about a week and a half after he started so we decided to take a detour and put him in charge of getting our internal boot code released out of SiFive.
It is, in some way, the ultimate form of political policy to write the code that runs when your computer turns on, as this is the 'root' of trust, and the starting point from which every other instruction your machine executes.
Does it execute instructions on your behalf, to empower you, or is it executing your freedom with opaque, undocumented, and generally poorly engineered ideas on how to lock down a system? We've spent quite a few years working on various boot codes or some other low-level system component, and what We've continuously found is that we are (or maybe more Troy is) pretty good at breaking stuff, particularly if someone tells me "Hey this is our secret black box, just trust us, it works".
What we usually find is stuff breaks, because we want to do something the designer never intended, like repair a 20 year old tractor with a new controller chip so the machine can drive itself.
We could have been a reverse engineer and gone into pen tests and hacking, but we find it extremely tedious to find the holes in things that would have been a hell of a lot easier to fix if we just had the source code.
So lets go through the source code, and how to build it.
If you look at the Makefile you'll see it's pretty basic, and if you have a working riscv64-unknown-elf toolchain, along with a device tree compiler (dtc), it might actually produce two important files: 0: zsbl.bin 1: fsbl.bin
The 'zero' (zsbl) goes into your silicon mask ROM, the 'first' (fsbl) goes in flash or on an SDcard, replacing the original that was shipped.
Early Boot on the FU540-C000
So what happens on power-up is Freedom U540-C000 spec says to go load from a specific address, and the first instruction is in the zsbl.elf, which goes into the chip ROM. This code does some setup and jumps into zsbl/main.c's main() function, and if we are cpu 0, then attempts to look for a GPT (guid partition table) for a partition with a GUID of 5b193300-fc78-40cd-8002-e86c45580b47 to load the FSBL from, with some indirection in ux00boot/ux00boot.c to look at the mode switches to figure out which SPI device to use.
More stuff happens, and we end up in fsbl/main.c which starts to get into messy bootloader territory where we start having to twiddle bits to turn things on with magic bug repellent incantations which can only be known to the wizards with access to the confidential magic. Luckily we've managed to navigate through as much of the boot flow as possible. This does require trusting some of our magic numbers to initialize some of the hardware components on the chip, but due to non-technical constraints there's no way around that. The code is all licensed under the Apache 2.0 license so it can easily be imported into U-Boot, CoreBoot, TianoCore, etc. If you need another license, please open a github issue.
Combining this open source bootloader code with SiFive's Freedom open source RTL repository would allow you to build an open source chip that is capable of booting Linux -- albeit one that would require talking to an FPGA for DRAM, but at least that is implementable on a wide range of commodity parts and the Chip Link (Tile Link over single-ended digital IOs) interface can be verified by a parallel implementation. We're still a long way from doing a fully open source, high performance, Linux capable chip -- but at least we're moving the bar forward!
Now that the bootloader code has been released it's time for a little challenge. Since the ZSBL lives in a mask ROM on the FU540-C000 there is no way to replace it, but you can at least re-generate the contents of the ROM and then verify that it matches the contents of a real HiFive Unleashed. We've posted a copy of the contents of the mask ROM at https://github.com/sifive/freedom-u540-c000-bootloader, the first person to submit a pull request that can exactly reproduce that ROM will get a HiFive Unleashed board!
Of course, the real goal of releasing this code is to allow real bootloaders to be brought up for the HiFive Unleashed. SiFive runs a program for open source developers where if you're interested in porting a commonly used bootloader to RISC-V and having a HiFive Unleashed would help your progress, feel free to send an email to firstname.lastname@example.org with some details. There's been a lot of interest in the beta program, but now that the DDR code is public it's a good time to start in earnest porting bootloaders, so we'll try to find a way to give you a board!