Anyone who has turned on a computer might be familiar with the boot-up sequence as computer flashes lines of text on screen before the Windows logo appears. What you are seeing is a bootloader in action, loading essential software to get the minimum running on the processor chip before higher-level software can run. Embedded bootloaders work much the same way, but since embedded processors cover a much larger range of applications (from dishwashers to automotive infotainment centers and more), what embedded bootloaders do varies based upon the architecture and the application. Bootloaders for embedded systems are also more often restricted to a smaller size versus computers.
The bootloader is the first code to run after power up or reset, and runs before any other software starts on a processor, including an operating system (OS), if an OS exists. For some embedded processors, bootloaders are part of a Board Support Package (BSP), which is used to start up and run the first silicon chips of an embedded MCU, processor, or System on a Chip (SoC). A bootloader (sometimes called a boot manager) is unique to the architecture of the embedded processor it runs on and includes some application specific aspects. A bootloader is necessary for starting processors at the lowest level before starting an operating system (e.g., a computer) or presenting a command line (e.g., an MCU). A bootloader can be sophisticated with lots of commands or simple with few commands; it can be fairly automatic and self-contained or be programmed to wait for a choice to be made, put in as a command, from a human. Commands can be set up to perform a number of modifications to the MCU environment if desired, or the bootloader might have few choices available and perform a self-contained start up for a set appliance or end-product.
The bootloader is stored in an area of protected memory (although this area of memory is not always fool-proof and can be overwritten by a stack overflow, for example). An onboard bootloader resides in memory in an MCU in an area of ROM or flash memory that is protected from getting written over. A bootloader performs various hardware checks, initializes the processor and peripherals, and does other tasks like partitioning or configuring registers. Besides getting a system on its feet, bootloaders are also used to update MCU firmware later on. Bootloaders must be able to communicate with the outside world in order to get updates, so most bootloaders are able to communicate with some form of interface, be it I2C, SPI, USART, USB, or some other protocol. Bootloaders also need to be able to map the memory of the specific architecture and read, write, and partition memory. If EEPROM is present, a bootloader must be able to at least read the EEPROM, as this is where the next bit of code might come from. Other bootloaders might need to be able to load the next level of code from an SD card (as in the Raspberry Pi). Bootloaders can also perform checks on the higher-level code to make sure it’s not corrupted before loading it. Lastly, one of the main tasks of bootloaders includes security. Embedded security starts with the silicon, an example of which is ARM, who installs a separate “Zone of Trust” area, branded the ARM® TrustZone®. Since a bootloader is intimate with the process of power cycle and reset recovery and is also a necessary part of firmware updating, the bootloader would reside in the secure, root of trust area. The bootloader would be accessible only by other software that has authorized access to that TrustZone, since ARM wants to segregate its critical operations from software and memory whose safety is not known.
Tools exist to help in writing a bootloader, one of which is the open source “Das U-Boot,” often shortened to “U-boot,” that supports several architectures (PowerPC, ARM, MIPS, x86, and more). Other bootloaders are Barebox, Libreboot, SeaBIOS, coreboot.