portfolio/Rust STM32F4 Bootloader

Rust STM32F4 Bootloader

Multi-stage bootloader system for STM32F4 microcontrollers implemented in Rust with memory safety and reliability.

RustSTM32F4 PACCMakeXMODEM

Demo Videos

Overview

A robust, multi-stage bootloader system for STM32F4 microcontrollers implemented in Rust. This project demonstrates firmware validation, secure update mechanisms, and memory management using Rust's safety features for embedded development.

The system implements a structured four-component bootloader architecture:

  • Boot (16KB): First-stage bootloader that validates and loads either Loader or Updater
  • Loader (16KB): Main bootloader with XMODEM update capability for Application and Updater
  • Updater (16KB): Similar to Loader but can also update the Loader itself
  • Application (384KB): The user firmware that runs the actual application

Each component features a structured header (0x200 bytes) containing metadata such as magic number, version, CRC checksum, and vector table address. The system implements a comprehensive set of validation mechanisms at each stage to prevent corrupted firmware from executing.

Project Goal: This implementation leverages Rust's memory safety features and ownership model to create a more reliable and secure bootloader, minimizing the risk of memory corruption and other common embedded programming errors.

💡 Related Project

Note: I also have a C version of this bootloader that includes additional features like delta patching and encryption.Check it out as well!

Key Features

  • Four-component bootloader architecture with structured validation chains
  • Full firmware image updates via XMODEM
  • Secure boot process with multi-level validation
  • Version compatibility verification prevents firmware downgrades
  • Error detection and handling during update process

Technical Specifications

Hardware Platform

  • STM32F4 MCU
  • UART communication interface

Validation Features

  • Magic number validation
  • CRC32 integrity verification
  • Version compatibility checks
  • Component type verification

Update Features

  • XMODEM protocol
  • CRC16 verification
  • Timeout management

Development Stack

  • Rust programming language
  • cargo-binutils for building
  • probe-rs for flashing
  • stm32f4-pac direct peripheral access

System Architecture

Bootloader Flow

The bootloader consists of four components with a secure chain of trust and multiple paths for normal operation and updates:

Memory Layout

The bootloader uses a carefully desided memory layout for its components:

ComponentAddress RangeSizeDescription
Boot0x08000000 - 0x08003FFF16KBFirst-stage bootloader
Loader0x08004000 - 0x08007FFF16KBMain bootloader
Updater0x08008000 - 0x0800BFFF16KBUpdate manager
Application0x08020000 - 0x0807FFFF384KBMain application

Image Header Structure

Each firmware component includes a 512-byte header with the following structure:

Rust
// Rust header structure for firmware components
#[repr(C, packed)]
pub struct ImageHeader {
    pub image_magic: u32,
    pub image_hdr_version: u16,
    pub image_type: u8,
    pub is_reserved: u8,
    pub version_major: u8,
    pub version_minor: u8,
    pub version_patch: u8,
    pub _padding: u8,
    pub vector_addr: u32,
    pub crc: u32,
    pub data_size: u32,
    pub reserved: [u8; 0x1E0],
}

Each bootloader component is identified by a unique magic number:

  • Loader: 0xDEADC0DE
  • Updater: 0xFEEDFACE
  • Application: 0xC0FFEE00

Security & Safety Measures

Firmware Validation

  • Magic Number Verification: Each component has a unique magic identifier in its header
  • CRC Validation: Firmware integrity is verified using CRC32 checksums
  • Version Control: The system ensures new firmware has a higher version than existing firmware
  • Pre-Update Verification: Headers are validated before erasing any flash sectors

Boot Safety Mechanisms

  • Fallback Boot Process: If the primary Loader is corrupted, the system falls back to the Updater
  • Peripheral Reset: Proper peripheral de-initialization before jumping between components
  • Memory-Safe Implementation: Rust's ownership model prevents common memory corruption issues

Update Process Protection

  • XMODEM Protocol: Uses reliable XMODEM protocol with CRC16 verification for firmware updates
  • Timeout Management: Proper timeouts during updates prevent the system from getting stuck

Project Structure

The project is organized into multiple Rust crates:

Tree
├── boot/                  # First-stage bootloader
├── loader/                # Main bootloader
├── updater/               # Updater bootloader
├── application/           # Example application
├── stm32f4/               # STM32F4 peripheral access crate
├── misc/                  # Shared library components
│   ├── src/
│   │   ├── bootloader.rs  # Common boot code
│   │   ├── flash.rs       # Flash memory operations
│   │   ├── image.rs       # Firmware image definitions
│   │   ├── ring_buffer.rs # UART buffer implementation
│   │   ├── systick.rs     # System tick utilities
│   │   └── xmodem.rs      # XMODEM protocol implementation
├── scripts/               # Build and utility scripts
└── build.ps1              # Main build script

Technologies Used

  • Rust programming language - for memory safety and reliability
  • STM32F4 microcontroller
  • Direct peripheral access - using stm32f4-pac crate
  • XMODEM protocol
  • CRC32 - for firmware validation
  • Custom build system - with cargo-binutils
  • Hardware flashing - via probe-rs

Challenges & Solutions

  • Implementing a secure update chain - that prevents unauthorized firmware execution
  • Managing complex flash memory operations - within Rust's safety constraints
  • Designing failsafe mechanisms - to recover from interrupted updates
  • Implementing proper image validation - at each stage
  • Adapting embedded C paradigms - to Rust's ownership and borrowing model