Booting Fuchsia's Zircon on a Homebrew RISC-V SoC, on an Artix-7 FPGA

mbStavola3 pts0 comments

Booting Fuchsia's Zircon on a homebrew RISC-V SoC, on an Artix-7 FPGA | HDL Factory Home

Fuchsia’s Zircon kernel now boots on Cocoapuffs, my homebrew RISC-V system-on-chip on an AMD Artix-7 FPGA: as far as I know, the first Fuchsia boot on programmable hardware. The boot video and the full chain, from a SERV serial loader through OpenSBI to userspace, are below; the rest of the post is the five bugs that stood in the way.

Here is the whole thing as a screencast: programming the FPGA, uploading the OpenSBI + boot-shim + Zircon image over serial (the ~24-minute upload is fast-forwarded), and the board booting:

Your browser can't play this video —<br>download the MP4.

Program → upload → boot on the cocoapuffs NOEL-V board, end to end on the<br>serial console: OpenSBI, the boot shim, physload/physboot, the Zircon<br>kernel's init, into userspace and userboot, ending at the expected no-bootfs<br>__builtin_trap. (Earlier raw serial capture, through the physboot<br>handoff: hw_zircon128_capture.log.)

The boot chain

The full path from power-on to userspace has a lot of links:

SERV ihex loader ──▶ OpenSBI (M-mode) ──▶ linux-riscv64-boot-shim<br>──▶ physload ──▶ physboot ──▶ Zircon kernel ──▶ userboot (userspace)

SERV receives the firmware image over the serial line as Intel HEX and<br>jumps to it. This is the only way onto the board — no JTAG bitstream reload<br>between software iterations.

OpenSBI is the M-mode supervisor firmware. It parses the devicetree, sets<br>up the SBI runtime (timer, IPI), and drops to S-mode.

The linux-riscv64-boot-shim is a Zircon phys executable that repackages a<br>devicetree + ZBI into the handoff format the kernel expects.

physload / physboot decompress and relocate the kernel, lay out physical<br>memory, and hand off to the kernel proper.

The Zircon kernel runs its init hooks and, finally, userboot — the<br>first userspace process.

Every one of these stages had at least one board-specific surprise.

Background

The resulting programmable hardware design is named &ldquo;Cocoapuffs&rdquo;, for reasons that are now lost to time. It is the end product of a project that I started long ago with a colleague from work. It even has a logo, straight from the pen of the creative genius that is my daughter.

Full disclosure, while FPGA bringup is a personal project, Fuchsia is my day job. This work was done entirely on my own time, on my own equipment, and using only publicly accessible information about Fuchsia.

The complete article documenting the bringup, warts and all, is here. This design is only the tip of the iceberg of the entire toolset I developed to make it possible. I hope to tell the story about those tools one day. Fragments of that other story can be found in my bazel registry.

It has been a long time in the making, but I am now finally able to confirm that the FPGA-based system-on-chip of my own design is capable enough to boot a real production kernel. My design loads Zircon up, and boots into userspace. At the moment, for unrelated reasons there isn&rsquo;t much going on in the userspace itself, but the boot process does complete as one would expect. Why not Linux instead? I thought it would be more interesting to boot Fuchsia, instead of, say, Linux. Not many have brought up Fuchsia on a brand new device.

The boot video above is slightly abridged to shorten the boring parts. In contrast to the post about the 32-bit RISC-V design, which showed the entire synthesis and programming in about 6 minutes, synthesis and P&R pass for a modern 64-bit core is serious business and as a result takes a long time. It goes on for about 1.5 hours, depending on the design particulars, and it is not very illuminating to watch, so I fast-forwarded it a bit.

If you are curious to learn more about Zircon, you can check out the official Zircon documentation, or if you prefer reading on paper, you can check out my technical report on Zircon. In either case, let me know if you have feedback.

The main component of the design is the NOEL-V RV64 soft core running on an Artix-7 (xc7a200t) FPGA. The design is a homebrew SoC I call cocoapuffs: a GRLIB noelvsys subsystem, a small SERV core that acts as the serial boot loader, DDR3, an APBUART, and the usual GRLIB plumbing, all built with Bazel rules for Vivado. The board is AX7A200B from Alinx, an exceptionally reasonably priced and well-made FPGA development board.

The complete source for the Cocoapuffs SoC — the RTL, the RISC-V firmware and boot chain, and the Bazel build that ties it all together — is open source at github.com/filmil/cocoapuffs-fpga.

Zircon is not Linux. There is no earlycon, no forgiving BIOS, and the RISC-V port is comparatively young. When something goes wrong before the console comes up, you get silence. Most of this post is about turning that silence back into information. A concession to the somewhat constrained space on the xc7a200t device, the boot process is somewhat unorthodox. (One might say that xc7a200t is roomy as far as FPGA...

boot zircon fpga fuchsia kernel design

Related Articles