Build system v2 collects Kconfig from every discovered component. The
bootloader is configured from the application's sdkconfig. The
application's SPIRAM options therefore reach the bootloader's
sdkconfig.h although the bootloader never links esp_psram. Shared
sources compiled for the bootloader then see application-only
configuration. Build system v1 never had esp_psram in the bootloader's
COMPONENTS list, so SPIRAM was unknown there.
Add esp_psram to the EXCLUDE_COMPONENTS build property in
components/bootloader/subproject/CMakeLists_v2.txt. The component is
not discovered and its Kconfig is not collected. SPIRAM is undefined in
the bootloader, as in build system v1.
Verified with components/esp_psram/test_apps/psram and hello_world with
CONFIG_SPIRAM=y on esp32c5. The application keeps its SPIRAM options.
The bootloader sdkconfig.h has none and esp_psram is not in the
bootloader's project_description.json.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
SRAM_MAIN_END is documented as the 2nd stage bootloader iram_loader_seg start address, but
it still holds the value from before 6b417e9d47, which raised
bootloader_iram_loader_seg_len from 0x7000 to 0x8000 and moved that address down by 4 KB.
That commit updated BOOTLOADER_IRAM_LOADER_SEG_START_EXPECTED in bootloader.memory.ld.in
and SRAM_END / SRAM_LOW_END in memory.ld.in, but ld.hp_mem_defs, added two months earlier
by 261bd160aa, was missed:
rev < 3 : asserted 0x4FF2BBD0, SRAM_MAIN_END 0x4FF2CBD0
rev >= 3: asserted 0x4FFADFC0, SRAM_MAIN_END 0x4FFAEFC0
0x4FFADFC0 is derived at link time from bootloader_usable_dram_end minus the stack
overhead, dram_seg and iram_loader segments, so it is not an extra reservation - the two
constants are meant to be equal, as the comment above the ASSERT states.
With CONFIG_ULP_COPROC_RUN_FROM_HP_MEM the ULP HP reservation therefore ends 4 KB inside
the bootloader's iram_loader_seg (0x4FFADFC0..0x4FFAEFC0), which that same script declares
off limits for the application, and SRAM_END / SRAM_LOW_END, derived from ULP_HP_MEM_START,
end 4 KB higher than intended. The default build does not reference SRAM_MAIN_END at all.
Also extend the sync comment in bootloader.memory.ld.in to list ld.hp_mem_defs, so the next
change to the segment lengths updates every consumer.
Verified for L2 128 KB and CONFIG_ULP_COPROC_RESERVE_HP_MEM_BYTES=0x10000:
before: ULP block [0x4FF9EFC0, 0x4FFAEFC0) -- overlaps iram_loader_seg by 0x1000
after: ULP block [0x4FF9DFC0, 0x4FFADFC0) -- abuts iram_loader_seg exactly
Closes https://github.com/espressif/esp-idf/issues/19133
Merges https://github.com/espressif/esp-idf/pull/19135
Mirror the link-time optimization support into the cmakev2 build system so
that both build systems behave identically.
- project.cmake (__init_project_configuration): emit -flto=auto as a link
option when CONFIG_COMPILER_LTO_LINKTIME is set, except for bootloader and
ESP-TEE builds, otherwise keep -fno-lto.
- build.cmake (idf_build_library): when CONFIG_COMPILER_LTO_COMPILETIME is set,
compile each linked component with -flto=auto unless it has linker fragments,
is placed by another component's fragment (see tools/cmake/lto.cmake), has
opted out via NO_LTO, or is not a static library.
- project.cmake: when CONFIG_APP_REPRODUCIBLE_BUILD is also enabled, apply
the same three flags as the legacy build system to keep LTO output
reproducible: pass the prefix-map options to the linker (so link-time code
generation remaps DW_AT_comp_dir), add -save-temps (stable LTRANS object
names instead of random $TMPDIR paths in the .map), and pin -frandom-seed
(byte-identical LTO GIMPLE bytecode). See the commit message of
"feat(build): add options to enable link-time optimization (LTO)" for the
full analysis.
The gcc-ar / gcc-ranlib selection and the NO_LTO component property are shared
with the legacy build system through tools/cmake/toolchain.cmake and the common
component registration code, so no cmakev2-specific changes are needed there.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Walk every directory contributed via BOOTLOADER_EXTRA_COMPONENT_DIRS
(both shared and direct component paths, not only those under the
application's bootloader_components/) and exclude any whose component
name matches BOOTLOADER_IGNORE_EXTRA_COMPONENT.
ESP_FAULT_ASSERT(C) was silently deleted by the optimizer when C is a cached
flag/status already proven by a preceding `if (!C) return/goto`: the compiler
folds C to a constant and drops all three checks, removing the fault-injection
protection with no warning.
Reference SECURE_BOOT_SIGNING_KEY in the bootloader subproject so CMake
does not warn about a manually-specified-but-unused variable when the
sign-key consumers are in config-gated blocks. Ports the same fix the
v1 subproject CMakeLists already has at line 119-120.
Commit 69d548c8 ("feat(esp_security): suppoer s31 security clock
management") introduced a new esp_crypto_clk source file in esp_security
but did not add it to the bootloader loader IRAM input sections. As a
result the crypto clock code was not placed in the loader IRAM region,
causing a regression on targets that use it during bootloader load.
Add *libesp_security.a:esp_crypto_clk.* to the bootloader sections
linker fragments for all targets that carry the esp_security.a
dependency (esp32c5, esp32p4, esp32s31), placed alongside
esp_crypto_periph_clk.
idf_build_executable only links the COMPONENTS list and its
dependencies. However, bootloader_components provided by the application
get discovered, but not linked. This MR forces the extra components for
the bootloader to be linked to the bootloader binary as there is no way
for the application to specify the same.
Replaced per-target bootloader.ld.in with bootloader.memory.ld.in and
bootloader.sections.ld.in.
Common code moved to file bootloader.sections.common.ld
Unify ESP32-P4 ECO4- and ECO4+ linker scripts into one shared script
Revision-specific code is selected with CONFIG_ESP32P4_SELECTS_REV_LESS_V3
When CONFIG_SECURE_BOOT_V2_ENABLED=y but
CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES is not set, produce the
binary directly as bootloader.bin instead of bootloader-unsigned.bin.
This matches the v1 behavior where the intermediate binary name is
conditional: bootloader-unsigned.bin only when build-time signing is
enabled (so the signed output can be named bootloader.bin), otherwise
the output is bootloader.bin directly.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
The __init_project_configuration() function in cmakev2's project.cmake
unconditionally applied app-level compiler optimization flags based on
CONFIG_COMPILER_OPTIMIZATION_* Kconfig options. When the bootloader
subproject was built with cmakev2, these app-level flags leaked into the
bootloader compile command alongside the correct bootloader-specific
flags from CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_*.
For example, with the default configuration (app: DEBUG, bootloader:
SIZE), the bootloader received both "-Og -fno-shrink-wrap" (from app
config) and "-Os -freorder-blocks" (from bootloader config). While GCC
uses the last -O flag (-Os wins), the stray -fno-shrink-wrap persisted.
Introduce a SET_COMPILER_OPTIMIZATION build property that defaults to
YES when unset. Subprojects that manage their own optimization flags
(like the bootloader) can set this to NO before calling
idf_project_init() to prevent the default optimization flags from being
applied. This keeps project.cmake generic without requiring it to know
about specific subproject types.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
Add CMakeLists_v2.txt to the bootloader subproject, implementing the
bootloader build using the new cmakev2 IDF build framework.
The file covers the full bootloader build pipeline:
- Sets PROJECT_COMPONENTS_SOURCE to "idf_components" so that the
subproject's built-in components (main/, components/) are treated as
IDF components (priority 0) rather than project components (priority
3). This preserves the cmakev1 behaviour where user-supplied
components in bootloader_components/ can override the built-in ones.
- Registers optional user-supplied bootloader components from the
application project's bootloader_components/ directory, with support
for selectively excluding individual components via
IGNORE_EXTRA_COMPONENT.
- Bootstraps the cmakev2 framework (idf.cmake) and initialises the
project with BOOTLOADER_BUILD and NON_OS_BUILD properties, which are
also exposed as C preprocessor definitions.
- Sets GENERATE_SDKCONFIG to 0 to prevent the bootloader subproject
from regenerating the main project's sdkconfig, as the bootloader
has a different set of components and hence different Kconfig files.
- Sets the common implicit component dependencies shared by every
bootloader component (log, esp_rom, esp_common, esp_hw_support,
esp_libc, arch-specific component).
- Applies the compiler options specific for bootloader
- Selects the correct target-specific linker script, including a
separate script for ESP32-P4 silicon revisions < v3.
- Links the bootloader ELF via idf_build_executable and then converts it
to a flat binary via one of three paths depending on the secure boot
configuration:
* No secure boot: plain binary + size check + metadata.
* Secure Boot V1 one-time-flash: plain binary with post-build
instructions showing the esptool.py flash command.
* Secure Boot V1 reflashable: derives the symmetric eFuse key from
the ECDSA signing key, produces the reflash-digest image, and
prints burn/flash instructions.
* Secure Boot V2: produces an unsigned binary, optionally signs it
with the configured signing key (RSA-PSS 3072, ECDSA P-256, or
ECDSA P-384) via idf_sign_binary, and prints flash/multi-key
signing instructions.
- Adds comprehensive inline documentation explaining each section's
purpose, the rationale behind individual flags, and the relationships
between Kconfig symbols and generated artefacts.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
esp_stdio contains everything the old esp_vfs_console contained (the vfs stdio glue layer)
as well as other functionality related to stdio (previously referred to as console)
For bin log, reserve the first 4 bytes as zero for variables that are pointed to NULL
and should not be printed in the log. So the esp-idf-monitor will skip printing
those variables.
The bootloader build script incorrectly used the `DEPENDS` keyword with the
`add_custom_command(TARGET ...)` signature. This is unsupported, causes
warnings with modern CMake versions enforcing the CMP0175 policy.
This commit also updates the POST_BUILD messages generated during the
bootloader build to depend on more precise CMake targets rather than
depending on the generic bootloader.elf target.
This commit refactors the esptool_py component to provide utility
functions for binary file generation targets instead of creating the
targets. Binary generation targets are now moved to the respective
projects.
The following changes were done in this commit:
- Added __idf_build_binary() function to esptool_py to create the binary
file generation target.
- Added __idf_build_secure_binary() as the secure boot equivalent of the
above function.
- Top level project build now creates its own binary targets in
idf_build_executable() in build.cmake.
- Bootloader and esp_tee subprojects create their binary file generation
targets in their respective CMakeLists.txt files.
- All post-build targets such as the app_size_check target are now
created by the respective projects and not esptool_py.
- General clean-up of the esptool_py cmake files.