<<<
:sectnums:
== Customizing the Internal Bootloader

The NEORV32 bootloader provides several options to configure and customize it for a certain application setup.
This configuration is done by passing _defines_ when compiling the bootloader. Of course you can also
modify to bootloader source code to provide a setup that perfectly fits your needs.

[IMPORTANT]
Each time the bootloader sources are modified, the bootloader has to be re-compiled (and re-installed to the
bootloader ROM) and the processor has to be re-synthesized.

[NOTE]
Keep in mind that the maximum size for the bootloader is limited to 8kB and it should be compiled using the
minimal base & privileged ISA `rv32i_zicsr_zifencei` only to ensure it can work independently of the actual CPU configuration.

.Bootloader configuration parameters
[cols="<2,^1,^2,<6"]
[options="header", grid="rows"]
|=======================
| Parameter | Default | Legal values | Description
4+^| Memory layout
| `EXE_BASE_ADDR` | `0x00000000` | _any_ | Base address / boot address for the executable (see section "Address Space" in the NEORV32 data sheet)
4+^| Serial console interface
| `UART_EN`   | `1`     | `0`, `1` | Set to `0` to disable UART0 (no serial console at all)
| `UART_BAUD` | `19200` | _any_    | Baud rate of UART0
| `UART_HW_HANDSHAKE_EN`   | `0` | `0`, `1` | Set to `1` to enable UART0 hardware flow control
4+^| Status LED
| `STATUS_LED_EN`  | `1` | `0`, `1`     | Enable bootloader status led ("heart beat") at `GPIO` output port pin #`STATUS_LED_PIN` when `1`
| `STATUS_LED_PIN` | `0` | `0` ... `31` | `GPIO` output pin used for the high-active status LED
4+^| Auto-boot configuration
| `AUTO_BOOT_TIMEOUT` | `10` | _any_  | Time in seconds after the auto-boot sequence starts (if there is no UART input by the user); set to 0 to disabled auto-boot sequence
4+^| SPI configuration
| `SPI_EN`                | `1` | `0`, `1`      | Set `1` to enable the usage of the SPI module (including load/store executables from/to SPI flash options)
| `SPI_FLASH_CS`          | `0` | `0` ... `7`   | SPI chip select output (`spi_csn_o`) for selecting flash
| `SPI_FLASH_ADDR_BYTES`  | `3` | `2`, `3`, `4` | SPI flash address size in number of bytes (2=16-bit, 3=24-bit, 4=32-bit)
| `SPI_FLASH_SECTOR_SIZE` | `65536` | _any_     | SPI flash sector size in bytes
| `SPI_FLASH_CLK_PRSC`    | `CLK_PRSC_8`        | `CLK_PRSC_2` `CLK_PRSC_4` `CLK_PRSC_8` `CLK_PRSC_64` `CLK_PRSC_128` `CLK_PRSC_1024` `CLK_PRSC_2024` `CLK_PRSC_4096` | SPI clock pre-scaler (dividing main processor clock)
| `SPI_BOOT_BASE_ADDR`    | `0x00400000`        | _any_ 32-bit value | Defines the _base_ address of the executable in external flash
4+^| XIP configuration
| `XIP_EN`                | `0` | `0`, `1`      | Set `1` to enable the XIP options
|=======================

[NOTE]
The XIP options re-use the "SPI configuration" options for configuring the XIP's SPI connection.

Each configuration parameter is implemented as C-language `define` that can be manually overridden (_redefined_) when
invoking the bootloader's makefile. The according parameter and its new value has to be _appended_
(using `+=`) to the makefile `USER_FLAGS` variable. Make sure to use the `-D` prefix here.

For example, to configure a UART Baud rate of 57600 and redirecting the status LED to GPIO output pin 20
use the following command:

.Example: customizing, re-compiling and re-installing the bootloader
[source,console]
----
sw/bootloader$ make USER_FLAGS+=-DUART_BAUD=57600 USER_FLAGS+=-DSTATUS_LED_PIN=20 clean_all bootloader
----

[NOTE]
The `clean_all` target ensure that all libraries are re-compiled. The `bootloader` target will automatically
compile and install the bootloader to the HDL boot ROM (updating `rtl/core/neorv32_bootloader_image.vhd`).

:sectnums:
=== Auto-Boot Configuration

The default bootloader provides a UART-based user interface that allows to upload new executables
at any time. Optionally, the executable can also be programmed to an external SPI flash by the bootloader (see
section <<_programming_an_external_spi_flash_via_the_bootloader>>).

The bootloader also provides an _automatic boot sequence_ (auto-boot) which will start copying an executable
from external SPI flash to IMEM using the default SPI configuration. By this, the default bootloader
provides a "non-volatile program storage" mechanism that automatically boots from external SPI flash
(after `AUTO_BOOT_TIMEOUT`) while still providing the option to re-program the SPI flash at any time
via the UART console.
