All uncommitted work from ESP32 GDB stub development session. Includes: - GDB stub (uos_gdbstub.c/.h/_entry.S) - Startup vector table rewrite - ESP32 HAL integration files - Boot chain design docs - AGENTS.md absolute rules (commit before refactor, no unauthorized changes) - All prior deepseek session work This commit prevents further data loss. No claims of correctness.
546 lines
28 KiB
Markdown
546 lines
28 KiB
Markdown
# ESP-IDF bootloader_support Component — Deep Audit
|
||
|
||
**Component path:** `components/bootloader_support/`
|
||
**Total ~21,760 lines of C/header code across 130+ files.**
|
||
**Scope:** ESP-IDF 5.x 2nd-stage bootloader support — shared code between bootloader and application.
|
||
|
||
---
|
||
|
||
## 1. Top-Level `/include/` — Public API Headers
|
||
|
||
### `include/esp_app_format.h` (127 lines)
|
||
**Purpose:** Defines the binary image header structures shared between bootloader and app.
|
||
**Key symbols:**
|
||
- `esp_image_spi_mode_t`, `esp_image_spi_freq_t`, `esp_image_flash_size_t` — SPI flash config enums
|
||
- `esp_chip_id_t` — Enum of all supported chip IDs (ESP32 through ESP32-S31)
|
||
- `esp_image_header_t` (24 bytes) — Main binary image header: magic, segment_count, spi_mode, spi_speed, spi_size, entry_addr, chip_id, min/max chip revision, hash_appended
|
||
- `esp_image_segment_header_t` — Per-segment header: load_addr, data_len
|
||
- `ESP_IMAGE_HEADER_MAGIC` (0xE9), `ESP_IMAGE_MAX_SEGMENTS` (16)
|
||
|
||
### `include/esp_image_format.h` (236 lines)
|
||
**Purpose:** Image loading, verification, and metadata API.
|
||
**Key types/functions:**
|
||
- `esp_image_metadata_t` — Full on-flash image metadata: start_addr, header, segments, data offsets, image_len, SHA-256 digest, secure_version, mmu_page_size
|
||
- `esp_image_load_mode_t` — `ESP_IMAGE_VERIFY`, `ESP_IMAGE_VERIFY_SILENT`, `ESP_IMAGE_LOAD`, `ESP_IMAGE_LOAD_NO_VALIDATE`
|
||
- `rtc_retain_mem_t` — Deep-sleep RTC memory layout (partition, reboot_counter, factory_reset flags, CRC)
|
||
- `esp_image_verify()` / `esp_image_load()` / `esp_image_basic_verify()` — Image validation and loading
|
||
- `ESP_ERR_IMAGE_BASE`, `ESP_ERR_IMAGE_FLASH_FAIL`, `ESP_ERR_IMAGE_INVALID`
|
||
|
||
### `include/esp_flash_partitions.h` (135 lines)
|
||
**Purpose:** Partition table definitions and flash layout constants.
|
||
**Key symbols:**
|
||
- Partition type/subtype constants: `PART_TYPE_APP`, `PART_TYPE_DATA`, `PART_TYPE_BOOTLOADER`, `PART_TYPE_PARTITION_TABLE`, factory/OTA/test subtypes
|
||
- `esp_partition_info_t`, `esp_partition_pos_t`, `esp_ota_select_entry_t` — Partition structures
|
||
- `ESP_PARTITION_MAGIC` (0x50AA), `ESP_PARTITION_MAGIC_MD5` (0xEBEB)
|
||
- `ESP_PARTITION_TABLE_OFFSET`, `ESP_BOOTLOADER_OFFSET` — Fixed flash offsets
|
||
- `PART_FLAG_ENCRYPTED`, `PART_FLAG_READONLY`
|
||
- `esp_partition_table_verify()` — Validates partition table with MD5 checksum
|
||
|
||
### `include/bootloader_common.h` (295 lines)
|
||
**Purpose:** Common utilities for both bootloader and application (GPIO, OTA data, chip revision checks).
|
||
**Key functions:**
|
||
- `bootloader_common_check_chip_revision_validity()` — Validates chip revision against image requirements
|
||
- `bootloader_common_read_otadata()` — Reads OTA data partition
|
||
- `bootloader_common_ota_select_crc()` / `_valid()` / `_invalid()` — OTA selection helpers
|
||
- `bootloader_common_check_long_hold_gpio()` / `_level()` — GPIO long/short hold detection
|
||
- `bootloader_common_label_search()` — Searches comma-separated label lists
|
||
- `bootloader_common_check_chip_validity()` — Comprehensive chip compatibility check
|
||
- `bootloader_common_erase_otadata()` — Erases OTA data partition
|
||
- Types: `esp_comm_gpio_hold_t` (LONG_HOLD, SHORT_HOLD, NOT_HOLD)
|
||
|
||
### `include/esp_secure_boot.h` (382 lines)
|
||
**Purpose:** Secure Boot V1/V2 API — public interface for signature verification, key digest management.
|
||
**Key definitions:**
|
||
- `esp_secure_boot_sig_scheme_t` — `V1_ECDSA`, `V2_RSA`, `V2_ECDSA`
|
||
- `ESP_SECURE_BOOT_DIGEST_LEN` (32 or 48 for ECDSA-384)
|
||
- `ESP_SECURE_BOOT_KEY_DIGEST_LEN`
|
||
- `esp_secure_boot_enabled()` — Checks if hardware secure boot is active
|
||
- `esp_secure_boot_verify_sbv2_signature_block()` — Verifies SBV2 signature block
|
||
- `esp_secure_boot_verify_signature()` — Main signature verification entry point
|
||
- `esp_secure_boot_permanently_enable()` — Burns efuses to permanently enable
|
||
|
||
### `include/esp_flash_encrypt.h` (226 lines)
|
||
**Purpose:** Flash encryption public API.
|
||
**Key definitions:**
|
||
- `esp_flash_enc_mode_t` — `DISABLED`, `DEVELOPMENT`, `RELEASE`
|
||
- `esp_flash_encryption_enabled()` — Check if encryption is active
|
||
- `esp_flash_encrypt_check_and_update()` — On-device flash encryption during boot
|
||
- `esp_flash_encrypt_state()` — Returns and prints encryption state
|
||
- `esp_flash_encrypt_contents()` — Encrypts flash partitions in place
|
||
- `esp_flash_encrypt_init()` / `esp_flash_encryption_init_checks()`
|
||
|
||
### `include/bootloader_memory_utils.h` (244 lines)
|
||
**Purpose:** Memory region checking utilities (IRAM/DRAM/RTC bounds, cache address mapping).
|
||
**Key inline functions:**
|
||
- `esp_dram_match_iram()` — Check if DRAM/IRAM share memory space
|
||
- `esp_ptr_in_iram()` / `esp_ptr_in_dram()` / `esp_ptr_in_diram_dram()` — Pointer region checks
|
||
- `esp_ptr_in_rtc_dram()` / `esp_ptr_in_rtc_iram()` / `esp_ptr_byte_accessible()` — RTC memory checks
|
||
- `esp_ptr_in_rom()` / `esp_ptr_executable()` — Execution checks
|
||
- `esp_ptr_dma_capable()` / `esp_ptr_internal()` / `esp_ptr_external_ram()`
|
||
- `esp_ptr_32bit_addressable()` — Address range validation
|
||
|
||
### `include/bootloader_random.h` (60 lines)
|
||
**Purpose:** RNG entropy for bootloader (HWRNG via SAR ADC or WDEV_RND_REG).
|
||
**Key functions:**
|
||
- `bootloader_random_enable()` — Enable entropy source (ADC-based)
|
||
- `bootloader_random_disable()` — Disable entropy source
|
||
- `bootloader_fill_random()` — Fill buffer with random bytes
|
||
|
||
### `include/bootloader_clock.h` (25 lines)
|
||
**Purpose:** Bootloader clock configuration API.
|
||
**Key functions:**
|
||
- `bootloader_clock_configure()` — Configures CPU/APB clocks for early boot
|
||
- `bootloader_clock_get_rated_freq_mhz()` — Returns chip's rated max frequency
|
||
|
||
### `include/bootloader_mem.h` (16 lines)
|
||
**Purpose:** Memory initialization for bootloader.
|
||
**Key functions:**
|
||
- `bootloader_init_mem()` — Configure memory protection (APM, region protection)
|
||
|
||
### `include/bootloader_util.h` (37 lines)
|
||
**Purpose:** Simple utility function.
|
||
**Key functions:**
|
||
- `bootloader_util_regions_overlap()` — Check if [start1, end1) overlaps [start2, end2)
|
||
|
||
### `include/bootloader_utility_tee.h` (53 lines)
|
||
**Purpose:** TEE (Trusted Execution Environment) OTA boot partition management.
|
||
**Key functions:**
|
||
- `bootloader_utility_tee_get_boot_partition()` — Fetch running TEE partition
|
||
- `bootloader_utility_tee_set_boot_partition()` — Set new TEE boot partition
|
||
- `bootloader_utility_tee_get_next_update_partition()` — Fetch next TEE update partition
|
||
- `bootloader_utility_tee_mark_app_valid_and_cancel_rollback()` — Commit TEE OTA update
|
||
|
||
### `include/esp_tee_ota_utils.h` (45 lines)
|
||
**Purpose:** TEE OTA data structures.
|
||
**Key symbols:**
|
||
- `esp_tee_ota_select_entry_t` — TEE OTA selection structure (magic, version, boot_partition, ota_state, crc)
|
||
- `esp_tee_ota_img_states_t` — `NEW`, `PENDING_VERIFY`, `INVALID`, `VALID`, `UNDEFINED`
|
||
- `TEE_OTADATA_MAGIC` (0x4337e1e1)
|
||
|
||
### `include/esp_flash_data_types.h` (7 lines)
|
||
**Purpose:** Deprecated stub — forwards to `esp_flash_partitions.h`.
|
||
|
||
---
|
||
|
||
## 2. `private_include/` — Internal Headers (Bootloader-Only)
|
||
|
||
### `private_include/bootloader_config.h` (51 lines)
|
||
**Purpose:** Bootloader state structure and configuration constants.
|
||
**Key symbols:**
|
||
- `bootloader_state_t` — Core bootloader state: ota_info, factory, test, tee_ota_info, tee[N], ota[N], app_count, selected_subtype
|
||
- `MAX_OTA_SLOTS` (16), `MAX_TEE_OTA_SLOTS` (2)
|
||
- `FACTORY_INDEX` (-1), `TEST_APP_INDEX` (-2), `INVALID_INDEX` (-99)
|
||
- `SPI_SEC_SIZE` (0x1000), `SPI_ERROR_LOG`
|
||
- `flash_encrypt()` — Forward declaration
|
||
|
||
### `private_include/bootloader_init.h` (65 lines)
|
||
**Purpose:** Bootloader initialization steps.
|
||
**Key symbols:**
|
||
- `_bss_start`, `_bss_end`, `_data_start`, `_data_end` — Linker script symbols
|
||
- `bootloader_image_hdr` — Bootloader's own image header
|
||
- `bootloader_read_bootloader_header()` — Read bootloader header from flash
|
||
- `bootloader_check_bootloader_validity()` — Validate bootloader against chip/efuses
|
||
- `bootloader_clear_bss_section()` — Zero BSS
|
||
- `bootloader_config_wdt()` — Configure watchdog timers
|
||
- `bootloader_enable_random()` — Enable RNG entropy source
|
||
- `bootloader_print_banner()` — Print bootloader version banner
|
||
- `bootloader_init()` — Main hardware preparation (cache, MMU, pins, clocks)
|
||
- `bootloader_init_ext_mem()` — Initialize cache and MMU
|
||
|
||
### `private_include/bootloader_utility.h` (157 lines)
|
||
**Purpose:** Core bootloader application loading logic.
|
||
**Key functions:**
|
||
- `bootloader_utility_load_partition_table()` — Load and parse partition table
|
||
- `bootloader_utility_get_selected_boot_partition()` — Determine preferred boot partition
|
||
- `bootloader_utility_load_boot_image()` — Load and start application (noreturn)
|
||
- `bootloader_utility_load_boot_image_from_deep_sleep()` — Deep-sleep wake boot path
|
||
- `bootloader_utility_load_tee_image()` — Load TEE image
|
||
- `bootloader_utility_reset_sha()`, `bootloader_utility_sha256_finish()` — SHA helpers
|
||
- `bootloader_utility_debug_after_reset()` — Post-reset debug info
|
||
|
||
### `private_include/bootloader_sha.h` (44 lines)
|
||
**Purpose:** SHA-256/512 hardware acceleration API for bootloader.
|
||
**Key functions:**
|
||
- `bootloader_sha256_start()` / `_data()` / `_finish()` — SHA-256 streaming API
|
||
- `bootloader_sha512_start()` / `_data()` / `_finish()` — SHA-512 streaming API (SoC-dependent)
|
||
|
||
### `private_include/bootloader_signature.h` (38 lines)
|
||
**Purpose:** Secure Boot V2 RSA signature verification (backward compatibility wrapper).
|
||
**Key functions:**
|
||
- `esp_secure_boot_verify_rsa_signature_block()` — Legacy RSA SBV2 signature verification
|
||
|
||
### `private_include/bootloader_console.h` (31 lines)
|
||
**Purpose:** Console initialization for bootloader (UART/USB CDC).
|
||
**Key functions:**
|
||
- `bootloader_console_init()` — Initialize console output
|
||
- `bootloader_console_deinit()` — De-initialize console
|
||
- `bootloader_console_write_char_usb()` — USB CDC character output
|
||
|
||
### `private_include/bootloader_soc.h` (36 lines)
|
||
**Purpose:** SoC-level security features (glitch detection, super WDT).
|
||
**Key functions:**
|
||
- `bootloader_ana_super_wdt_reset_config()` — Configure analog super WDT
|
||
- `bootloader_ana_clock_glitch_reset_config()` — Configure clock glitch reset
|
||
- `bootloader_power_glitch_reset_config()` — Configure power glitch reset
|
||
|
||
---
|
||
|
||
## 3. `bootloader_flash/` — SPI Flash Subsystem
|
||
|
||
### `bootloader_flash/include/bootloader_flash.h` (73 lines)
|
||
**Purpose:** Public SPI flash operations.
|
||
**Key functions:**
|
||
- `bootloader_read_flash_id()` — Read flash JEDEC ID (0x9F)
|
||
- `bootloader_flash_xmc_startup()` — XMC flash startup sequence
|
||
- `bootloader_flash_unlock()` / `_default()` — Unlock flash write protect
|
||
- `bootloader_flash_reset_chip()` — Reset flash chip (66H+99H)
|
||
- `bootloader_flash_is_octal_mode_enabled()` — Check octal mode efuse
|
||
- `bootloader_flash_get_spi_mode()` — Get current SPI working mode
|
||
|
||
### `bootloader_flash/include/bootloader_flash_config.h` (93 lines)
|
||
**Purpose:** Flash configuration from image header.
|
||
**Key functions:**
|
||
- `bootloader_flash_update_id()` — Update flash ID in global ROM structure
|
||
- `bootloader_flash_update_size()` — Update flash size in global structure
|
||
- `bootloader_flash_cs_timing_config()` — Set CS setup/hold time
|
||
- `bootloader_flash_clock_config()` — Configure SPI flash clock from image header
|
||
- `bootloader_flash_gpio_config()` — Configure SPI flash GPIO pins
|
||
- `bootloader_flash_dummy_config()` — Configure read dummy cycles (ESP32 only)
|
||
- `bootloader_flash_get_wp_pin()` — Get WP pin override (ESP32)
|
||
|
||
### `bootloader_flash/include/bootloader_flash_override.h` (130 lines)
|
||
**Purpose:** Flash QE (Quad Enable) bit support — per-manufacturer status register read/write.
|
||
**Key symbols:**
|
||
- `bootloader_qio_info_t` — Flash chip QE metadata (mfg, IDs, status read/write fns, QIE bit position)
|
||
- `bootloader_read_status_8b_rdsr()` / `_rdsr2()` / `_rdsr3()` — Status register reads
|
||
- `bootloader_read_status_16b_rdsr_rdsr2()` — Combined 16-bit read
|
||
- `bootloader_write_status_8b_wrsr()` / `_wrsr2()` / `_wrsr3()` — Status register writes
|
||
- `bootloader_write_status_16b_wrsr()` — Combined 16-bit write
|
||
- `bootloader_read_status_8b_xmc25qu64a()` / `_write_...` — XMC-specific
|
||
- `bootloader_flash_qe_support_list` / `bootloader_flash_qe_list_count` — QE support table
|
||
- `bootloader_flash_32bits_address_map_enable()` — Enable 32-bit flash addressing
|
||
|
||
### `bootloader_flash/include/bootloader_flash_priv.h` (205 lines)
|
||
**Purpose:** Private flash API for bootloader and bootloader_support internals.
|
||
**Key symbols:**
|
||
- SPI command constants: `CMD_RDID`, `CMD_WRSR`, `CMD_WREN`, `CMD_RDSR`, etc.
|
||
- `FLASH_SECTOR_SIZE` (0x1000), `FLASH_BLOCK_SIZE` (0x10000)
|
||
- MMU mapping macros: `MMAP_ALIGNED_MASK`, `MMU_FLASH_MASK`, `GET_REQUIRED_MMU_PAGES()`
|
||
- `bootloader_mmap_get_free_pages()` — Get free MMU pages
|
||
- `bootloader_flash_read()` — Read from flash (with encryption support)
|
||
- `bootloader_flash_write()` — Write to flash (with encryption support)
|
||
- `bootloader_flash_erase_sector()` / `_range()` — Erase operations
|
||
- `bootloader_flash_execute_command()` — Execute raw SPI command
|
||
- `bootloader_cache_utils_init()` / `bootloader_flash_xip_unlock_for_write()`
|
||
|
||
### `bootloader_flash/include/flash_qio_mode.h` (31 lines)
|
||
**Purpose:** Quad I/O mode enable public API.
|
||
**Key functions:**
|
||
- `bootloader_enable_qio_mode()` — Enable QIO/QOUT mode on attached flash
|
||
- `bootloader_read_flash_id()` — Read flash ID
|
||
|
||
### `bootloader_flash/include/esp_private/bootloader_flash_internal.h` (38 lines)
|
||
**Purpose:** Internal flash init for bootloader.
|
||
**Key functions:**
|
||
- `bootloader_init_spi_flash()` — Full SPI flash initialization
|
||
- `bootloader_flash_hardware_init()` — Hardware init for RAM-based apps
|
||
- `bootloader_init_mspi_clock()` — Initialize MSPI core clock
|
||
|
||
---
|
||
|
||
## 4. `src/` — Main Source Files
|
||
|
||
### `src/bootloader_init.c` (159 lines)
|
||
**Purpose:** Bootloader entry point initialization.
|
||
**Key functions:**
|
||
- `bootloader_clear_bss_section()` — memset BSS to zero
|
||
- `bootloader_read_bootloader_header()` — Reads bootloader image header from flash
|
||
- `bootloader_check_bootloader_validity()` — Validates chip revision + efuse block version
|
||
- `bootloader_config_wdt()` — Disables flashboot WDT protection, enables RTCWDT for boot phase
|
||
- `bootloader_enable_random()` — Enables early RNG entropy source
|
||
- `bootloader_print_banner()` — Prints ESP-IDF version / compile time banner
|
||
- `bootloader_init_ext_mem()` — Initializes cache HAL + MMU
|
||
|
||
### `src/bootloader_utility.c` (1313 lines) — **Largest file**
|
||
**Purpose:** Core bootloader logic: partition table parsing, image loading, app boot.
|
||
**Key functions:**
|
||
- `bootloader_utility_load_partition_table()` — Read, verify, parse partition table; populate `bootloader_state_t`
|
||
- `bootloader_utility_get_selected_boot_partition()` — OTA-based boot partition selection
|
||
- `bootloader_utility_load_boot_image()` — Main image loading, validation, MMU mapping, jump-to-app (noreturn)
|
||
- `bootloader_utility_load_tee_image()` — Load TEE image
|
||
- `bootloader_utility_load_boot_image_from_deep_sleep()` — Deep-sleep resume image load
|
||
- `set_cache_and_start_app()` — Configure MMU cache mapping and jump to application entry point
|
||
- `bootloader_utility_debug_after_reset()` — Print post-reset debug info
|
||
|
||
### `src/esp_image_format.c` (1202 lines) — **2nd largest file**
|
||
**Purpose:** Binary image parsing, verification, and loading.
|
||
**Key functions:**
|
||
- `esp_image_verify()` — Verify image header + segments + appended SHA-256 hash
|
||
- `esp_image_load()` — Verify + load image segments into memory
|
||
- `esp_image_basic_verify()` — Lightweight header-only verification
|
||
- `esp_image_get_metadata()` — Extract metadata without loading
|
||
- Internal helpers for segment validation, hash computation, secure boot signature checking
|
||
|
||
### `src/bootloader_common.c` (188 lines)
|
||
**Purpose:** Common GPIO and OTA utilities (app or bootloader context).
|
||
**Key functions:**
|
||
- `bootloader_common_check_long_hold_gpio()` / `_level()` — GPIO hold detection
|
||
- `bootloader_common_label_search()` — Label list search
|
||
|
||
### `src/bootloader_common_loader.c` (292 lines)
|
||
**Purpose:** Additional common utilities for bootloader-only context.
|
||
**Key functions:**
|
||
- `bootloader_common_check_chip_revision_validity()` — Chip revision checks
|
||
- `bootloader_common_check_chip_validity()` — Full chip compatibility (revision + secure version + efuse)
|
||
- `bootloader_common_read_otadata()` — Read OTA data from partition
|
||
- `bootloader_common_ota_select_crc()` / `_valid()` / `_invalid()` — OTA helpers
|
||
- `bootloader_common_erase_otadata()` — Erase OTA data
|
||
|
||
### `src/bootloader_console.c` (150 lines)
|
||
**Purpose:** UART/USB CDC console initialization for bootloader.
|
||
**Key functions:**
|
||
- `bootloader_console_init()` — Multiple implementations: `CONFIG_ESP_CONSOLE_NONE`, `_UART`, `_USB_CDC`
|
||
- UART pin configuration, baud rate setup, USB CDC initialization
|
||
|
||
### `src/bootloader_console_loader.c` (83 lines)
|
||
**Purpose:** Console functions placed in `iram_loader_seg` (survives iram overwrite during loading).
|
||
**Key functions:**
|
||
- USB CDC buffered TX with `bootloader_console_flush_usb()`, `bootloader_console_write_one_char_usb()`
|
||
|
||
### `src/bootloader_sha.c` (300 lines)
|
||
**Purpose:** SHA-256/512 hardware acceleration (bootloader and non-OS builds).
|
||
**Key functions:**
|
||
- `bootloader_sha256_start()` / `_data()` / `_finish()` — Streaming SHA-256 via `ets_sha_*` ROM functions
|
||
- `bootloader_sha512_start()` / `_data()` / `_finish()` — SHA-512/384 (SoC-dependent)
|
||
- Alternative mbedTLS-based implementation for application builds
|
||
|
||
### `src/bootloader_random.c` (99 lines)
|
||
**Purpose:** HWRNG entropy generation for bootloader.
|
||
**Key functions:**
|
||
- `bootloader_fill_random()` — Fill buffer with random bytes (WDEV_RND_REG based, XORed with RTC timer)
|
||
- `bootloader_random_enable()` / `_disable()` — Placeholder stubs for bringup targets
|
||
|
||
### `src/bootloader_random_esp32*.c` (10 SoC-specific files, ~70-125 lines each)
|
||
**Purpose:** Per-chip entropy source initialization using SAR ADC sampling.
|
||
**Pattern:** Each provides chip-specific `bootloader_random_enable()` and `bootloader_random_disable()` implementations.
|
||
**Chips covered:** ESP32, ESP32-S2, ESP32-S3, ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-C61, ESP32-H2, ESP32-P4
|
||
|
||
### `src/bootloader_clock_init.c` (171 lines)
|
||
**Purpose:** Clock tree configuration for bootloader.
|
||
**Key functions:**
|
||
- `bootloader_clock_configure()` — Set CPU frequency, configure RTC clocks, enable 32k XTAL early, clear power-management interrupts
|
||
|
||
### `src/bootloader_clock_loader.c` (16 lines)
|
||
**Purpose:** APB frequency query in `iram_loader_seg`.
|
||
**Key functions:**
|
||
- `esp_clk_apb_freq()` — Returns APB frequency from RTC
|
||
|
||
### `src/bootloader_mem.c` (44 lines)
|
||
**Purpose:** Memory protection and APM initialization.
|
||
**Key functions:**
|
||
- `bootloader_init_mem()` — Disable APM control filters, set master security modes, configure region protection
|
||
|
||
### `src/bootloader_efuse.c` (64 lines)
|
||
**Purpose:** Efuse reading utilities.
|
||
**Key functions:**
|
||
- `bootloader_common_get_chip_ver_pkg()` — Read chip version + package from efuse
|
||
- `bootloader_clock_get_rated_freq_mhz()` — Per-chip rated maximum frequency
|
||
|
||
### `src/bootloader_panic.c` (36 lines)
|
||
**Purpose:** Minimal assert/abort handlers for bootloader.
|
||
**Key functions:**
|
||
- `__assert_func()` — Assert failure handler (prints + infinite loop)
|
||
- `abort()` — Abort handler (prints PC + optional OCD break + infinite loop)
|
||
|
||
### `src/flash_partitions.c` (77 lines)
|
||
**Purpose:** Partition table verification.
|
||
**Key functions:**
|
||
- `esp_partition_table_verify()` — Validate partition table magic, bounds, MD5 checksum, count entries
|
||
|
||
### `src/bootloader_utility_tee.c` (260 lines)
|
||
**Purpose:** TEE OTA boot partition management (read/write TEE OTA data, set boot partition).
|
||
**Key internal functions:**
|
||
- `write_tee_otadata_sector()` — Write TEE OTA data to flash
|
||
- `read_tee_otadata()` — Read both TEE OTA data copies
|
||
- `bootloader_utility_tee_get_boot_partition()` — Determine current TEE boot partition
|
||
- `bootloader_utility_tee_set_boot_partition()` — Set new TEE boot partition
|
||
- `bootloader_utility_tee_get_next_update_partition()` — Find next TEE slot for update
|
||
- `bootloader_utility_tee_mark_app_valid_and_cancel_rollback()` — Commit TEE update
|
||
|
||
### `src/flash_encrypt.c` (519 lines)
|
||
**Purpose:** Flash encryption efuse checks and initialization (application context).
|
||
**Key functions:**
|
||
- `esp_flash_encryption_init_checks()` — Validate encryption efuse state consistency
|
||
- `esp_flash_encrypt_state()` — Print encryption state
|
||
- `esp_flash_write_protect_crypt_cnt()` — Write-protect FLASH_CRYPT_CNT efuse
|
||
- `esp_flash_encryption_enabled()` — Check if encryption is enabled via efuses
|
||
|
||
### `src/secure_boot.c` (465 lines)
|
||
**Purpose:** Secure boot efuse management and state checks (application context).
|
||
**Key functions:**
|
||
- `esp_secure_boot_enabled()` — Check secure boot efuse state
|
||
- `esp_secure_boot_permanently_enable()` — Burn secure boot efuses
|
||
- `esp_secure_boot_verify_signature()` — Signature verification dispatch
|
||
- V1-specific: `secure_boot_v1_check()`, `esp_secure_boot_verify_signature_block()`
|
||
- ECDSA key management: `esp_secure_boot_verify_ecdsa_signature_block()`
|
||
|
||
---
|
||
|
||
## 5. `src/flash_encryption/` — On-Device Flash Encryption
|
||
|
||
### `src/flash_encryption/flash_encrypt.c` (705 lines)
|
||
**Purpose:** On-device flash encryption operations during bootloader phase.
|
||
**Key functions:**
|
||
- `esp_flash_encrypt_check_and_update()` — Main entry: checks FLASH_CRYPT_CNT parity, encrypts plaintext flash regions in place
|
||
- `esp_flash_encrypt_contents()` — Encrypts all marked partitions in place
|
||
- Internal helpers for bootloader encryption, partition table encryption, app partition encryption
|
||
- Key manager integration for XTS_AES key deployment (P4 etc.)
|
||
|
||
---
|
||
|
||
## 6. `src/secure_boot_v1/` — Secure Boot V1 (ESP32)
|
||
|
||
### `src/secure_boot_v1/secure_boot.c` (193 lines)
|
||
**Purpose:** Secure Boot V1 bootloader implementation (AES-based digest generation, efuse burning).
|
||
**Key functions:**
|
||
- `secure_boot_generate()` — Generate boot digest ("abstract") + IV for SBV1
|
||
- `esp_secure_boot_permanently_enable()` — Burn SBV1 efuses (ABS_DONE + key)
|
||
- `esp_secure_boot_verify_signature_block()` — V1 signature verification
|
||
|
||
### `src/secure_boot_v1/secure_boot_signatures_app.c` (121 lines)
|
||
**Purpose:** V1 signature block parsing and verification (app-side).
|
||
|
||
### `src/secure_boot_v1/secure_boot_signatures_bootloader.c` (86 lines)
|
||
**Purpose:** V1 bootloader self-verification.
|
||
|
||
---
|
||
|
||
## 7. `src/secure_boot_v2/` — Secure Boot V2 (RSA/ECDSA)
|
||
|
||
### `src/secure_boot_v2/secure_boot.c` (407 lines)
|
||
**Purpose:** Secure Boot V2 bootloader implementation.
|
||
**Key functions:**
|
||
- `esp_secure_boot_verify_sbv2_signature_block()` — Main SBV2 signature verification
|
||
- `esp_secure_boot_permanently_enable()` — Burn SBV2 efuses
|
||
- `validate_signature_block()` — Validate individual signature block (magic, CRC, digest)
|
||
|
||
### `src/secure_boot_v2/secure_boot_rsa_signature.c` (194 lines)
|
||
**Purpose:** RSA-3072 signature verification for SBV2 (uses PSA/mbedTLS).
|
||
**Key functions:**
|
||
- `verify_rsa_signature_block()` — RSA PKCS#1 v1.5 signature verification
|
||
- `encode_rsa_pubkey_der()` — Manual DER encoding of RSA public key
|
||
|
||
### `src/secure_boot_v2/secure_boot_ecdsa_signature.c` (118 lines)
|
||
**Purpose:** ECDSA signature verification for SBV2 (uses hardware ECDSA peripheral where available).
|
||
**Key functions:**
|
||
- `verify_ecdsa_signature_block()` — ECDSA P-256/P-384 signature verification
|
||
|
||
### `src/secure_boot_v2/secure_boot_signatures_app.c` (330 lines)
|
||
**Purpose:** SBV2 signature verification logic for application images.
|
||
|
||
### `src/secure_boot_v2/secure_boot_signatures_bootloader.c` (212 lines)
|
||
**Purpose:** SBV2 bootloader self-verification logic.
|
||
|
||
### `src/secure_boot_v2/secure_boot_signature_priv.h` (11 lines)
|
||
**Purpose:** Private signature verification dispatch.
|
||
**Key functions:**
|
||
- `verify_ecdsa_signature_block()` — Internal ECDSA verifier
|
||
- `verify_rsa_signature_block()` — Internal RSA verifier
|
||
|
||
---
|
||
|
||
## 8. `bootloader_flash/src/` — Flash Implementation
|
||
|
||
### `bootloader_flash/src/bootloader_flash.c` (1074 lines)
|
||
**Purpose:** Core SPI flash operations for bootloader (read, write, erase, XIP unlock, cache).
|
||
**Key functions:**
|
||
- `bootloader_read_flash_id()` — JEDEC ID read
|
||
- `bootloader_flash_read()` / `_write()` / `_erase_sector()` / `_erase_range()` — Flash I/O
|
||
- `bootloader_flash_execute_command()` — Raw SPI command execution
|
||
- `bootloader_flash_xmc_startup()` — XMC flash startup sequence
|
||
- `bootloader_flash_unlock()` — Write-protect unlock
|
||
- `bootloader_flash_reset_chip()` — Flash reset sequence
|
||
- `bootloader_cache_utils_init()` — Cache utility initialization
|
||
- `bootloader_flash_xip_unlock_for_write()` — XIP unlock for write operations
|
||
- `bootloader_flash_is_octal_mode_enabled()` / `bootloader_flash_get_spi_mode()`
|
||
|
||
### `bootloader_flash/src/flash_qio_mode.c` (230 lines)
|
||
**Purpose:** Quad I/O mode enable for supported flash chips.
|
||
**Key symbols:**
|
||
- `bootloader_flash_qe_support_list_default[]` — Known flash chips table (MXIC, ISSI, GD, XMC, etc.) with QE bit positions
|
||
- `bootloader_enable_qio_mode()` — Main entry: match flash ID, check QE bit, set if needed
|
||
|
||
### `bootloader_flash/src/bootloader_flash_config_esp32*.c` (19 SoC-specific files, ~300-500 lines each)
|
||
**Purpose:** Per-chip SPI flash configuration (pins, clock, dummy cycles, cache MMU, octal mode).
|
||
**Chips covered:** ESP32, ESP32-S2, ESP32-S3, ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-C61, ESP32-H2, ESP32-H21, ESP32-H4, ESP32-P4, ESP32-S31
|
||
**Key per-file functions:**
|
||
- `bootloader_flash_gpio_config()` / `bootloader_flash_clock_config()` / `bootloader_flash_dummy_config()`
|
||
- `bootloader_flash_cs_timing_config()`, `bootloader_configure_spi_pins()`
|
||
- MMU page size configuration, octal flash DDR mode setup
|
||
|
||
---
|
||
|
||
## 9. `src/esp32*/` — SoC-Specific Bootloader Implementations (14 target dirs)
|
||
|
||
**Each directory contains:**
|
||
- `bootloader_esp32xxx.c` — SoC-specific bootloader init (`bootloader_init()` implementation: cache config, CPU freq, SPI pins, flash config)
|
||
- `bootloader_soc.c` — SoC-specific security features (super WDT, clock/power glitch reset config)
|
||
- `secure_boot_secure_features.c` — SoC-specific secure boot efuse checks
|
||
- `flash_encryption_secure_features.c` — SoC-specific flash encryption efuse/bus configuration
|
||
|
||
**Key target directories:** `esp32/`, `esp32c2/`, `esp32c3/`, `esp32c5/`, `esp32c6/`, `esp32c61/`, `esp32h2/`, `esp32h21/`, `esp32h4/`, `esp32p4/`, `esp32s2/`, `esp32s3/`, `esp32s31/`
|
||
|
||
### Special: `src/esp32c6/bootloader_ecdsa.c` (35 lines)
|
||
**Purpose:** ESP32-C6 hardware ECDSA peripheral integration for secure boot.
|
||
|
||
---
|
||
|
||
## 10. Test Apps
|
||
|
||
### `test_apps/bootloader_support/`
|
||
- `main/test_app_main.c` — Test entry point
|
||
- `main/test_verify_image.c` (120 lines) — Image verification tests
|
||
- `pytest_bootloader_support.py` — Pytest automation
|
||
|
||
### `test_apps/rtc_custom_section/`
|
||
- `main/test_main.c` (31 lines) — RTC memory custom section test
|
||
- `pytest_rtc_mem.py` — Pytest for RTC memory
|
||
|
||
### `test_apps/.build-test-rules.yml`
|
||
**Purpose:** CI build test matrix configuration.
|
||
|
||
---
|
||
|
||
## 11. Build Files
|
||
|
||
### `CMakeLists.txt`
|
||
**Purpose:** CMake build definition — compiles sources conditionally per target/chip, sets iram_loader_seg placement.
|
||
|
||
### `README.rst`
|
||
**Purpose:** Component documentation.
|
||
|
||
---
|
||
|
||
## Summary Statistics
|
||
|
||
| Metric | Count |
|
||
|---|---|
|
||
| Total files (C + H) | ~130 |
|
||
| Total lines of code | ~21,760 |
|
||
| Public API headers | 13 |
|
||
| Private headers | 7 |
|
||
| Flash subsystem headers | 6 |
|
||
| Core source files | ~20 |
|
||
| SoC-specific source files | ~52 (14 targets × ~3-4 files) |
|
||
| Flash config source files | 19 |
|
||
| Secure boot source files | 10 |
|
||
| Flash encryption source files | 2 |
|
||
| Test files | 8 |
|
||
|
||
### Key Architectural Patterns
|
||
|
||
1. **Dual-context compilation:** Many files compile for both bootloader (`BOOTLOADER_BUILD`) and application, using `#ifdef` guards.
|
||
2. **SoC abstraction via per-target directories:** Each chip target has its own `src/esp32xxx/` subdirectory with flash config, security features, and bootloader init.
|
||
3. **iram_loader_seg:** Critical "loader" phase code (console, clock, flash operations during image loading) is placed in `.iram_loader_seg` which survives the iram overwrite.
|
||
4. **ROM function reliance:** Heavy use of ROM SPI flash, SHA, and secure boot functions — the component is essentially a HAL wrapper around ROM bootloader primitives.
|
||
5. **Appended SHA-256:** Every ESP image carries a simple hash for corruption detection; secure boot signatures are appended after it.
|