2018-01-11 21:49:13 -05:00
|
|
|
cmake_minimum_required(VERSION 3.5)
|
|
|
|
|
2018-01-18 23:47:49 -05:00
|
|
|
if(NOT SDKCONFIG)
|
2018-02-26 23:45:30 -05:00
|
|
|
message(FATAL_ERROR "Bootloader subproject expects the SDKCONFIG variable to be passed "
|
|
|
|
"in by the parent build process.")
|
2018-01-18 23:47:49 -05:00
|
|
|
endif()
|
2018-01-11 21:49:13 -05:00
|
|
|
|
2018-06-15 00:59:45 -04:00
|
|
|
if(NOT IDF_PATH)
|
|
|
|
message(FATAL_ERROR "Bootloader subproject expects the IDF_PATH variable to be passed "
|
|
|
|
"in by the parent build process.")
|
|
|
|
endif()
|
|
|
|
|
2019-05-09 02:19:02 -04:00
|
|
|
if(NOT IDF_TARGET)
|
|
|
|
message(FATAL_ERROR "Bootloader subproject expects the IDF_TARGET variable to be passed "
|
|
|
|
"in by the parent build process.")
|
|
|
|
endif()
|
|
|
|
|
2021-02-27 14:13:01 -05:00
|
|
|
# A number of these components are implemented as config-only when built in the bootloader
|
2020-11-10 01:51:08 -05:00
|
|
|
set(COMPONENTS
|
|
|
|
bootloader
|
|
|
|
esptool_py
|
|
|
|
esp_hw_support
|
2021-01-25 23:54:26 -05:00
|
|
|
esp_system
|
2021-02-27 14:13:01 -05:00
|
|
|
freertos
|
2020-11-10 01:51:08 -05:00
|
|
|
hal
|
|
|
|
partition_table
|
|
|
|
soc
|
|
|
|
bootloader_support
|
|
|
|
log
|
|
|
|
spi_flash
|
|
|
|
micro-ecc
|
|
|
|
main
|
2020-11-06 05:39:16 -05:00
|
|
|
efuse
|
2021-02-17 18:05:42 -05:00
|
|
|
esp_system
|
|
|
|
newlib)
|
2021-04-14 22:31:33 -04:00
|
|
|
|
|
|
|
# Make EXTRA_COMPONENT_DIRS variable to point to the bootloader_components directory
|
|
|
|
# of the project being compiled
|
|
|
|
set(PROJECT_EXTRA_COMPONENTS "${PROJECT_SOURCE_DIR}/bootloader_components")
|
2021-10-06 03:43:51 -04:00
|
|
|
list(APPEND EXTRA_COMPONENT_DIRS "${PROJECT_EXTRA_COMPONENTS}")
|
2021-04-14 22:31:33 -04:00
|
|
|
|
|
|
|
# Consider each directory in project's bootloader_components as a component to be compiled
|
|
|
|
file(GLOB proj_components RELATIVE ${PROJECT_EXTRA_COMPONENTS} ${PROJECT_EXTRA_COMPONENTS}/*)
|
|
|
|
foreach(component ${proj_components})
|
|
|
|
# Only directories are considered as components
|
|
|
|
if(IS_DIRECTORY ${curdir}/${child})
|
|
|
|
list(APPEND COMPONENTS ${component})
|
|
|
|
endif()
|
|
|
|
endforeach()
|
|
|
|
|
2018-01-11 21:49:13 -05:00
|
|
|
set(BOOTLOADER_BUILD 1)
|
2019-05-09 22:53:08 -04:00
|
|
|
include("${IDF_PATH}/tools/cmake/project.cmake")
|
2021-02-17 18:05:42 -05:00
|
|
|
set(common_req log esp_rom esp_common esp_hw_support hal newlib)
|
2019-05-08 02:49:52 -04:00
|
|
|
if(LEGACY_INCLUDE_COMMON_HEADERS)
|
2020-08-08 08:15:27 -04:00
|
|
|
list(APPEND common_req soc hal)
|
global: move the soc component out of the common list
This MR removes the common dependency from every IDF components to the SOC component.
Currently, in the ``idf_functions.cmake`` script, we include the header path of SOC component by default for all components.
But for better code organization (or maybe also benifits to the compiling speed), we may remove the dependency to SOC components for most components except the driver and kernel related components.
In CMAKE, we have two kinds of header visibilities (set by include path visibility):
(Assume component A --(depends on)--> B, B is the current component)
1. public (``COMPONENT_ADD_INCLUDEDIRS``): means this path is visible to other depending components (A) (visible to A and B)
2. private (``COMPONENT_PRIV_INCLUDEDIRS``): means this path is only visible to source files inside the component (visible to B only)
and we have two kinds of depending ways:
(Assume component A --(depends on)--> B --(depends on)--> C, B is the current component)
1. public (```COMPONENT_REQUIRES```): means B can access to public include path of C. All other components rely on you (A) will also be available for the public headers. (visible to A, B)
2. private (``COMPONENT_PRIV_REQUIRES``): means B can access to public include path of C, but don't propagate this relation to other components (A). (visible to B)
1. remove the common requirement in ``idf_functions.cmake``, this makes the SOC components invisible to all other components by default.
2. if a component (for example, DRIVER) really needs the dependency to SOC, add a private dependency to SOC for it.
3. some other components that don't really depends on the SOC may still meet some errors saying "can't find header soc/...", this is because it's depended component (DRIVER) incorrectly include the header of SOC in its public headers. Moving all this kind of #include into source files, or private headers
4. Fix the include requirements for some file which miss sufficient #include directives. (Previously they include some headers by the long long long header include link)
This is a breaking change. Previous code may depends on the long include chain.
You may need to include the following headers for some files after this commit:
- soc/soc.h
- soc/soc_memory_layout.h
- driver/gpio.h
- esp_sleep.h
The major broken include chain includes:
1. esp_system.h no longer includes esp_sleep.h. The latter includes driver/gpio.h and driver/touch_pad.h.
2. ets_sys.h no longer includes soc/soc.h
3. freertos/portmacro.h no longer includes soc/soc_memory_layout.h
some peripheral headers no longer includes their hw related headers, e.g. rom/gpio.h no longer includes soc/gpio_pins.h and soc/gpio_reg.h
BREAKING CHANGE
2019-04-03 01:17:38 -04:00
|
|
|
endif()
|
2019-05-09 22:53:08 -04:00
|
|
|
idf_build_set_property(__COMPONENT_REQUIRES_COMMON "${common_req}")
|
|
|
|
idf_build_set_property(__OUTPUT_SDKCONFIG 0)
|
2018-02-14 22:38:58 -05:00
|
|
|
project(bootloader)
|
2018-01-11 21:49:13 -05:00
|
|
|
|
2019-05-09 22:53:08 -04:00
|
|
|
idf_build_set_property(COMPILE_DEFINITIONS "-DBOOTLOADER_BUILD=1" APPEND)
|
|
|
|
idf_build_set_property(COMPILE_OPTIONS "-fno-stack-protector" APPEND)
|
2018-10-19 15:02:55 -04:00
|
|
|
|
2019-12-19 20:55:02 -05:00
|
|
|
idf_component_get_property(main_args esptool_py FLASH_ARGS)
|
|
|
|
idf_component_get_property(sub_args esptool_py FLASH_SUB_ARGS)
|
|
|
|
|
|
|
|
# String for printing flash command
|
|
|
|
string(REPLACE ";" " " esptoolpy_write_flash
|
|
|
|
"${ESPTOOLPY} --port=(PORT) --baud=(BAUD) ${main_args} "
|
|
|
|
"write_flash ${sub_args}")
|
|
|
|
|
2018-10-19 15:02:55 -04:00
|
|
|
string(REPLACE ";" " " espsecurepy "${ESPSECUREPY}")
|
|
|
|
string(REPLACE ";" " " espefusepy "${ESPEFUSEPY}")
|
|
|
|
|
2021-04-10 14:36:25 -04:00
|
|
|
# Suppress warning: "Manually-specified variables were not used by the project: SECURE_BOOT_SIGNING_KEY"
|
|
|
|
set(ignore_signing_key "${SECURE_BOOT_SIGNING_KEY}")
|
|
|
|
|
2018-10-19 15:02:55 -04:00
|
|
|
if(CONFIG_SECURE_BOOTLOADER_REFLASHABLE)
|
|
|
|
if(CONFIG_SECURE_BOOTLOADER_KEY_ENCODING_192BIT)
|
|
|
|
set(key_digest_len 192)
|
|
|
|
else()
|
|
|
|
set(key_digest_len 256)
|
|
|
|
endif()
|
|
|
|
|
|
|
|
get_filename_component(bootloader_digest_bin
|
|
|
|
"bootloader-reflash-digest.bin"
|
|
|
|
ABSOLUTE BASE_DIR "${CMAKE_BINARY_DIR}")
|
|
|
|
|
|
|
|
get_filename_component(secure_bootloader_key
|
|
|
|
"secure-bootloader-key-${key_digest_len}.bin"
|
|
|
|
ABSOLUTE BASE_DIR "${CMAKE_BINARY_DIR}")
|
|
|
|
|
|
|
|
add_custom_command(OUTPUT "${secure_bootloader_key}"
|
|
|
|
COMMAND ${ESPSECUREPY} digest_private_key
|
|
|
|
--keylen "${key_digest_len}"
|
2019-05-10 03:25:25 -04:00
|
|
|
--keyfile "${SECURE_BOOT_SIGNING_KEY}"
|
2018-10-19 15:02:55 -04:00
|
|
|
"${secure_bootloader_key}"
|
|
|
|
VERBATIM)
|
|
|
|
|
|
|
|
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
|
|
|
|
add_custom_target(gen_secure_bootloader_key ALL DEPENDS "${secure_bootloader_key}")
|
|
|
|
else()
|
|
|
|
if(NOT EXISTS "${secure_bootloader_key}")
|
|
|
|
message(FATAL_ERROR
|
|
|
|
"No pre-generated key for a reflashable secure bootloader is available, "
|
|
|
|
"due to signing configuration."
|
|
|
|
"\nTo generate one, you can use this command:"
|
|
|
|
"\n\t${espsecurepy} generate_flash_encryption_key ${secure_bootloader_key}"
|
|
|
|
"\nIf a signing key is present, then instead use:"
|
2019-05-10 03:25:25 -04:00
|
|
|
"\n\t${espsecurepy} digest_private_key "
|
2018-10-19 15:02:55 -04:00
|
|
|
"--keylen (192/256) --keyfile KEYFILE "
|
|
|
|
"${secure_bootloader_key}")
|
|
|
|
endif()
|
|
|
|
add_custom_target(gen_secure_bootloader_key)
|
|
|
|
endif()
|
|
|
|
|
|
|
|
add_custom_command(OUTPUT "${bootloader_digest_bin}"
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo "DIGEST ${bootloader_digest_bin}"
|
|
|
|
COMMAND ${ESPSECUREPY} digest_secure_bootloader --keyfile "${secure_bootloader_key}"
|
2019-10-28 21:50:41 -04:00
|
|
|
-o "${bootloader_digest_bin}" "${CMAKE_BINARY_DIR}/bootloader.bin"
|
2019-12-19 23:09:15 -05:00
|
|
|
MAIN_DEPENDENCY "${CMAKE_BINARY_DIR}/.bin_timestamp"
|
2019-05-10 03:25:25 -04:00
|
|
|
DEPENDS gen_secure_bootloader_key gen_project_binary
|
2018-10-19 15:02:55 -04:00
|
|
|
VERBATIM)
|
|
|
|
|
2020-11-10 01:51:08 -05:00
|
|
|
add_custom_target(gen_bootloader_digest_bin ALL DEPENDS "${bootloader_digest_bin}")
|
2018-10-19 15:02:55 -04:00
|
|
|
endif()
|
|
|
|
|
2020-02-24 14:51:41 -05:00
|
|
|
if(CONFIG_SECURE_BOOT_V2_ENABLED)
|
|
|
|
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
|
2020-03-03 13:58:18 -05:00
|
|
|
get_filename_component(secure_boot_signing_key
|
2020-02-24 14:51:41 -05:00
|
|
|
"${SECURE_BOOT_SIGNING_KEY}" ABSOLUTE BASE_DIR "${project_dir}")
|
|
|
|
|
|
|
|
if(NOT EXISTS "${secure_boot_signing_key}")
|
2020-03-03 13:58:18 -05:00
|
|
|
message(FATAL_ERROR
|
|
|
|
"Secure Boot Signing Key Not found."
|
|
|
|
"\nGenerate the Secure Boot V2 RSA-PSS 3072 Key."
|
|
|
|
"\nTo generate one, you can use this command:"
|
|
|
|
"\n\t${espsecurepy} generate_signing_key --version 2 ${SECURE_BOOT_SIGNING_KEY}")
|
2020-02-24 14:51:41 -05:00
|
|
|
endif()
|
|
|
|
|
|
|
|
set(bootloader_unsigned_bin "bootloader-unsigned.bin")
|
|
|
|
add_custom_command(OUTPUT ".signed_bin_timestamp"
|
2020-11-10 01:51:08 -05:00
|
|
|
COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_BINARY_DIR}/${PROJECT_BIN}"
|
|
|
|
"${CMAKE_BINARY_DIR}/${bootloader_unsigned_bin}"
|
2020-02-24 14:51:41 -05:00
|
|
|
COMMAND ${ESPSECUREPY} sign_data --version 2 --keyfile "${secure_boot_signing_key}"
|
|
|
|
-o "${CMAKE_BINARY_DIR}/${PROJECT_BIN}" "${CMAKE_BINARY_DIR}/${bootloader_unsigned_bin}"
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo "Generated signed binary image ${build_dir}/${PROJECT_BIN}"
|
|
|
|
"from ${CMAKE_BINARY_DIR}/${bootloader_unsigned_bin}"
|
2020-11-10 01:51:08 -05:00
|
|
|
COMMAND ${CMAKE_COMMAND} -E md5sum "${CMAKE_BINARY_DIR}/${PROJECT_BIN}"
|
|
|
|
> "${CMAKE_BINARY_DIR}/.signed_bin_timestamp"
|
2020-02-24 14:51:41 -05:00
|
|
|
DEPENDS "${build_dir}/.bin_timestamp"
|
|
|
|
VERBATIM
|
|
|
|
COMMENT "Generated the signed Bootloader")
|
|
|
|
else()
|
|
|
|
add_custom_command(OUTPUT ".signed_bin_timestamp"
|
|
|
|
VERBATIM
|
2020-03-03 13:58:18 -05:00
|
|
|
COMMENT "Bootloader generated but not signed")
|
2020-02-24 14:51:41 -05:00
|
|
|
endif()
|
|
|
|
|
2020-11-10 01:51:08 -05:00
|
|
|
add_custom_target(gen_signed_bootloader ALL DEPENDS "${build_dir}/.signed_bin_timestamp")
|
2020-02-24 14:51:41 -05:00
|
|
|
endif()
|
|
|
|
|
2018-10-19 15:02:55 -04:00
|
|
|
if(CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH)
|
2019-05-10 03:25:25 -04:00
|
|
|
add_custom_command(TARGET bootloader.elf POST_BUILD
|
2018-10-19 15:02:55 -04:00
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"=============================================================================="
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"Bootloader built. Secure boot enabled, so bootloader not flashed automatically."
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"One-time flash command is:"
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"\t${esptoolpy_write_flash} ${BOOTLOADER_OFFSET} ${CMAKE_BINARY_DIR}/bootloader.bin"
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"* IMPORTANT: After first boot, BOOTLOADER CANNOT BE RE-FLASHED on same device"
|
|
|
|
VERBATIM)
|
|
|
|
elseif(CONFIG_SECURE_BOOTLOADER_REFLASHABLE)
|
2019-05-10 03:25:25 -04:00
|
|
|
add_custom_command(TARGET bootloader.elf POST_BUILD
|
2018-10-19 15:02:55 -04:00
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"=============================================================================="
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"Bootloader built and secure digest generated."
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"Secure boot enabled, so bootloader not flashed automatically."
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"Burn secure boot key to efuse using:"
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
2020-10-15 04:48:23 -04:00
|
|
|
"\t${espefusepy} burn_key secure_boot_v1 ${secure_bootloader_key}"
|
2018-10-19 15:02:55 -04:00
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"First time flash command is:"
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"\t${esptoolpy_write_flash} ${BOOTLOADER_OFFSET} ${CMAKE_BINARY_DIR}/bootloader.bin"
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"=============================================================================="
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"To reflash the bootloader after initial flash:"
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"\t${esptoolpy_write_flash} 0x0 ${bootloader_digest_bin}"
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"=============================================================================="
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"* After first boot, only re-flashes of this kind (with same key) will be accepted."
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"* Not recommended to re-use the same secure boot keyfile on multiple production devices."
|
|
|
|
DEPENDS gen_secure_bootloader_key gen_bootloader_digest_bin
|
|
|
|
VERBATIM)
|
2020-12-28 08:53:02 -05:00
|
|
|
elseif(CONFIG_SECURE_BOOT_V2_ENABLED AND (CONFIG_IDF_TARGET_ESP32S2 OR CONFIG_IDF_TARGET_ESP32C3))
|
2020-03-03 13:58:18 -05:00
|
|
|
add_custom_command(TARGET bootloader.elf POST_BUILD
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"=============================================================================="
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"Bootloader built. Secure boot enabled, so bootloader not flashed automatically."
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"To sign the bootloader with additional private keys."
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
2020-11-10 01:51:08 -05:00
|
|
|
"\t${espsecurepy} sign_data -k secure_boot_signing_key2.pem -v 2 \
|
|
|
|
--append_signatures -o signed_bootloader.bin build/bootloader/bootloader.bin"
|
2020-03-03 13:58:18 -05:00
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"Secure boot enabled, so bootloader not flashed automatically."
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"\t${esptoolpy_write_flash} ${BOOTLOADER_OFFSET} ${CMAKE_BINARY_DIR}/bootloader.bin"
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"=============================================================================="
|
|
|
|
DEPENDS gen_signed_bootloader
|
|
|
|
VERBATIM)
|
2020-02-24 14:51:41 -05:00
|
|
|
elseif(CONFIG_SECURE_BOOT_V2_ENABLED)
|
|
|
|
add_custom_command(TARGET bootloader.elf POST_BUILD
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"=============================================================================="
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"Bootloader built. Secure boot enabled, so bootloader not flashed automatically."
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"Secure boot enabled, so bootloader not flashed automatically."
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"\t${esptoolpy_write_flash} ${BOOTLOADER_OFFSET} ${CMAKE_BINARY_DIR}/bootloader.bin"
|
|
|
|
COMMAND ${CMAKE_COMMAND} -E echo
|
|
|
|
"=============================================================================="
|
|
|
|
DEPENDS gen_signed_bootloader
|
|
|
|
VERBATIM)
|
2018-10-19 15:02:55 -04:00
|
|
|
endif()
|