| Foboot Main | **FBM** | Presents a disk drive that makes it easy to load programs |
| User Python Program | **UPY** | Uses a locally-stored Python interpreter to run Python code |
| User RISC-V Program | **URV** | Uses the built-in RISC-V softcore to execute user programs |
| User ICE40 Bitstream | **UBS** | Exits the Foboot RISC-V core and switches to the provided bitstream |
At start, **FBU** is loaded by the hardware. **FBU** will look for a special *FBM signature* at a given offset. If this signature exists, it will transfer execution to that program. Otherwise it will enter *DFU Mode* and await further communication.
A user program can provide a timeout between 1s and 255s, after which it is automatically loaded by the boot loader. Uploading a new program via USB will cancel this timeout.
The timeout must be given in the third (4-byte little-endian) word of the programm and must be preceeded by the magic word `0x4a6de3ac` in the second word. For bitstreams these can be added using the `examples/add_timeout.py` script, for RISC-V programs use the make file option `make AUTOBOOT_TIMEOUT=5` (e.g., for 5s; when using a Makefile as in `examples/riscv-blink`).
During development, it may be inconvenient to load a program onto SPI flash. Or maybe you want to run something that doesn't modify the contents of SPI. This is possible with `RAM boot`.
If the DFU bootloader encounters the magic number `0x17ab0f23` within the first 56 bytes, then it will enable *RAM boot* mode. In this mode, the SPI flash won't be erased, and the program will be loaded to RAM.
Note that the value following the magic number indicates the offset where the program will be loaded to. This should be somewhere in RAM. `0x10002000` is a good value, and is guaranteed to not interfere with Foboot itself.
When using a Makefile as in `examples/riscv-blink` you can provide the offset as in `make LOAD_RAM_ADDR=0x10002000`. This makes sure that the linker links the binary as one block.