Assembly examples for Red-V Thing Plus (SiFive FE310-G002)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
flabbergast 930b40bef2 Add debugging info into README. 5 months ago
Makefile Fix calls. 5 months ago Shave 2 bytes from bootloader. 5 months ago
bootloader.hex Shave 2 bytes from bootloader. 5 months ago
bootloader.s Shave 2 bytes from bootloader. 5 months ago
memmap_bldr Add bootloader. 5 months ago Add bootloader. 5 months ago

a small bootloader for Red-V Thing Plus

This is my take on the thing that the official HiFive1B bootloader (used without changes on Sparkfun's Red-V Thing Plus) is supposed to achieve, without all the extra fluff that's crammed there. SiFive did not release the sources for the bootloader (makes no sense for an "open design" board), but whatever. Someone disassembled, and re-wrote in C, the official bootloader here.

Note: please be careful with this, and of course you're using this on your own risk.


make flash

Note: this will overwrite any previous bootloader you may have on the board; you may want to back that up first. It will overwrite ~104 bytes at MCU address 0x20000000, which is the beginning of the flash chip. The official bootloader is archived here. To make a copy of the whole region that the bootloader can occupy, use:

    echo -e "savebin saved-bootloader.bin, 0x20000000, 0x10000\nexit\n" | JLinkExe -device FE310 -if JTAG -speed 4000 -si JTAG -jtagconf -1,-1 -autoconnect

assuming you have JLinkExe installed. This will create a 64KiB file saved-bootloader.bin. The official bootloader isn't that big, it only has 10383 bytes, so you could swap the 0x10000 for 10500 if you wanted.

The command to write the saved file back to flash is

    echo -e "loadfile saved-bootloader.bin 0x20000000\nexit\n" | $JLINK -device FE310 -if JTAG -speed 4000 -si JTAG -jtagconf -1,-1 -autoconnect 1


On powerup/reset, it seems to take the board about a second to get to the point when it actually starts executing the firmware (at address 0x20000000). I am not sure why; the default values of the PMUWAKEUPIx setup seems to account only for 1/128 s = 8 ms of it.

Anyway, then the bootloader runs, and it does the following things:

  • Checks for the magic value 0xCAFEE000 (stored in AON_BACKUP15 register which survives resets/sleeps). If it's there, it just jumps to the main firmware (address 0x20010000). This is meant to be used when you configure and use the sleep mechanism in your firmware, and want to skip the rest of the bootloader behaviour on wakeup. (If something goes wrong, disconnect the board from power and wait a bit. This will zero out the magic register.)
  • Checks for the magic value 0xD027B000. If it's there, it means (presumably) that reset was "double tapped" (see below), and so the bootloader will just start blinking the onboard (on Red-V Thing) LED forever. You will (should?) be able to then use JLink to connect and/or flash new firmware. Note that magic (AON_BACKUP15) is set to 0: so if you reset now, the bootloader will go to the default behaviour, described in the next option:
  • None of the above. This is what happens by default, and also on powerup (but see the note below). Turn on the onboard LED for 1/2 second. If you hit reset within this window, the "double tap" behaviour described above is triggered. If you don't do anything, the LED is turned off, the original AON_BACKUP15 value is restored, and the bootloader jumps to the main firmware.


The AON block registers (including BACKUP15 which is used for this whole shebang) seem to retain their values for a while even when the main power source (usually USB cable) is disconnected from the board. I would guess that it takes a little while until the onboard capacitors discharge enough so that the AON block is completely powered off? Not sure.

The practical consequence of this is that when something goes wrong and you need/want to restore the default values of various AON registers (e.g. AON_BACKUP15 or AON_PMUWAKEUPIx), you need to wait for a while until you plug the board back in.