How to add alternative boot source (not USB cable)


Hi all, I’m quite new at this, but would like to know the basic steps for how to boot from an image located on a different memory device (such as eeprom or fram chip).

Where are some good resources to find out how to do this for the Bx?


This is not particularly easy to do on the Bx.

The TinyFPGA Bx has a warm boot configuration at the start of its flash memory. This was created using the icestorm, icemulti tool.

The way that works is that at power-on, the ice40 reads the warm boot configuration and is told that the boot image is at address 0xa0. The image at 0xa0 is the TinyFPGA BX bootloader. That reads commands from the USB connection and then boots to the user image, which is at address 0x28000, using SB_WARMBOOT.

To do what you want, you will probably need to replace that warm boot image with a different one. If you are going to do that you really need an SPI programmer with its leads soldered to the SPI pads on the underside of the Bx. Without such an SPI programmer, you effectively get one go at replacing the warm boot configuration, and if you fail, your Bx is effectively bricked and can only be recovered using an SPI programmer.

I implemented a system that boots from an image on an SD card, and that needed a new warm boot configuration, see - PicoSoC using only BRAM

There are a few diiferent approaches you can take to how to boot from an image from a different source. One is to completely replace the TinyFPGA BX bootloader. If you do that you will lose the capability to boot from USB.

Another approach is to modify the bootloader and add a command to boot from another source, but the bootloader is complex and not very easy to change.

A third approach is to keep the bootloader as it is and let it boot to the user image, and do the work in the user image. That is the approach I took.

If you take this last approach, your image which implements external booting, needs to read the image you want to run from whatever media it is on and write it to address 0x28000 in flash memory and then use SB_WARMBOOT to boot to it. This is the best way to develop a verilog program that implements booting from external media, but the problem with it for a production system is that it leaves the target image in flash memory and wipes your external booting image.

My solution to this was to replace the TinyFPGA BX warm boot configuration, which supports two images, with one that supports 4, of which I used 3. The first is the TinyFPGA BX bootloader unchanged, the second (at address 0x28000) was my external booting image , which in my case was the games menu. The games menu read the target image (the game) from external media (an SD card in my case) and wrote is to address 0x78000, and then used SB_WARMBOOT to boot to that. That made my games menu “sticky”, so that it was not overwritten with the game, and meant that the games menu was returned to after the game finished or on power-up.

Note that, although the TinyFPGA Bx bootloader was part of this system, my games console was not usually connected by USB to a computer, so in that case the BX bootloader just boots straight to the image at address 0x28000, which was my games menu.

I am afraid this is all rather complex, and, as I said, not that easy to implement.


I’ll take a look at and parse all of the information here that you’ve provided. Thank you very much!