Merge branch 'feature/cmake_secure_boot_support' into 'master'
CMake : Secure Boot support added See merge request idf/esp-idf!3522
This commit is contained in:
commit
a96deceb27
12 changed files with 338 additions and 48 deletions
|
@ -1,3 +1,24 @@
|
||||||
|
# This is for tracking the top level project path
|
||||||
|
if(BOOTLOADER_BUILD)
|
||||||
|
set(main_project_path "${CMAKE_BINARY_DIR}/../..")
|
||||||
|
else()
|
||||||
|
set(main_project_path "${PROJECT_PATH}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
get_filename_component(secure_boot_signing_key
|
||||||
|
"${CONFIG_SECURE_BOOT_SIGNING_KEY}"
|
||||||
|
ABSOLUTE BASE_DIR "${main_project_path}")
|
||||||
|
if(NOT EXISTS ${secure_boot_signing_key})
|
||||||
|
# If the signing key is not found, create a phony gen_secure_boot_signing_key target that
|
||||||
|
# fails the build. fail_at_build_time also touches CMakeCache.txt to cause a cmake run next time
|
||||||
|
# (to pick up a new signing key if one exists, etc.)
|
||||||
|
fail_at_build_time(gen_secure_boot_signing_key
|
||||||
|
"Secure Boot Signing Key ${CONFIG_SECURE_BOOT_SIGNING_KEY} does not exist. Generate using:"
|
||||||
|
"\tespsecure.py generate_signing_key ${CONFIG_SECURE_BOOT_SIGNING_KEY}")
|
||||||
|
else()
|
||||||
|
add_custom_target(gen_secure_boot_signing_key)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(BOOTLOADER_BUILD)
|
if(BOOTLOADER_BUILD)
|
||||||
return() # don't keep recursing!
|
return() # don't keep recursing!
|
||||||
endif()
|
endif()
|
||||||
|
@ -13,16 +34,34 @@ set(bootloader_binary_files
|
||||||
"${bootloader_build_dir}/bootloader.map"
|
"${bootloader_build_dir}/bootloader.map"
|
||||||
)
|
)
|
||||||
|
|
||||||
externalproject_add(bootloader
|
# These additional files may get generated
|
||||||
|
if(CONFIG_SECURE_BOOTLOADER_REFLASHABLE)
|
||||||
|
set(bootloader_binary_files
|
||||||
|
${bootloader_binary_files}
|
||||||
|
"${bootloader_build_dir}/bootloader-reflash-digest.bin"
|
||||||
|
"${bootloader_build_dir}/secure-bootloader-key-192.bin"
|
||||||
|
"${bootloader_build_dir}/secure-bootloader-key-256.bin"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if((NOT CONFIG_SECURE_BOOT_ENABLED) OR
|
||||||
|
CONFIG_SECURE_BOOTLOADER_REFLASHABLE OR
|
||||||
|
CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH)
|
||||||
|
externalproject_add(bootloader
|
||||||
# TODO: support overriding the bootloader in COMPONENT_PATHS
|
# TODO: support overriding the bootloader in COMPONENT_PATHS
|
||||||
SOURCE_DIR "${IDF_PATH}/components/bootloader/subproject"
|
SOURCE_DIR "${IDF_PATH}/components/bootloader/subproject"
|
||||||
BINARY_DIR "${bootloader_build_dir}"
|
BINARY_DIR "${bootloader_build_dir}"
|
||||||
CMAKE_ARGS -DSDKCONFIG=${SDKCONFIG} -DIDF_PATH=${IDF_PATH} -DEXTRA_COMPONENT_DIRS=${COMPONENT_DIRS}
|
CMAKE_ARGS -DSDKCONFIG=${SDKCONFIG} -DIDF_PATH=${IDF_PATH} -DEXTRA_COMPONENT_DIRS=${COMPONENT_DIRS}
|
||||||
-DTESTS_ALL=0 -DTEST_COMPONENTS=""
|
-DTESTS_ALL=0 -DTEST_COMPONENTS=""
|
||||||
|
-DSECURE_BOOT_SIGNING_KEY=${secure_boot_signing_key}
|
||||||
INSTALL_COMMAND ""
|
INSTALL_COMMAND ""
|
||||||
BUILD_ALWAYS 1 # no easy way around this...
|
BUILD_ALWAYS 1 # no easy way around this...
|
||||||
BUILD_BYPRODUCTS ${bootloader_binary_files}
|
BUILD_BYPRODUCTS ${bootloader_binary_files}
|
||||||
|
DEPENDS gen_secure_boot_signing_key
|
||||||
)
|
)
|
||||||
|
else()
|
||||||
|
fail_at_build_time(bootloader "Invalid bootloader target: bad sdkconfig?")
|
||||||
|
endif()
|
||||||
|
|
||||||
# this is a hack due to an (annoying) shortcoming in cmake, it can't
|
# this is a hack due to an (annoying) shortcoming in cmake, it can't
|
||||||
# extend the 'clean' target to the external project
|
# extend the 'clean' target to the external project
|
||||||
|
|
|
@ -26,3 +26,104 @@ target_linker_script(bootloader.elf
|
||||||
target_linker_script(bootloader.elf ${ESP32_BOOTLOADER_LINKER_SCRIPTS})
|
target_linker_script(bootloader.elf ${ESP32_BOOTLOADER_LINKER_SCRIPTS})
|
||||||
|
|
||||||
target_link_libraries(bootloader.elf gcc)
|
target_link_libraries(bootloader.elf gcc)
|
||||||
|
|
||||||
|
set(secure_boot_signing_key ${SECURE_BOOT_SIGNING_KEY})
|
||||||
|
|
||||||
|
string(REPLACE ";" " " espsecurepy "${ESPSECUREPY}")
|
||||||
|
string(REPLACE ";" " " espefusepy "${ESPEFUSEPY}")
|
||||||
|
set(esptoolpy_write_flash "${ESPTOOLPY_WRITE_FLASH_STR}")
|
||||||
|
|
||||||
|
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}"
|
||||||
|
--keyfile "${secure_boot_signing_key}"
|
||||||
|
"${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:"
|
||||||
|
"\n\t${ESPSECUREPY} digest_private_key "
|
||||||
|
"--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}"
|
||||||
|
-o "${bootloader_digest_bin}" "${CMAKE_BINARY_DIR}/bootloader.bin"
|
||||||
|
DEPENDS gen_secure_bootloader_key "${CMAKE_BINARY_DIR}/bootloader.bin"
|
||||||
|
VERBATIM)
|
||||||
|
|
||||||
|
add_custom_target (gen_bootloader_digest_bin ALL DEPENDS "${bootloader_digest_bin}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH)
|
||||||
|
add_custom_command(TARGET bootloader 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
|
||||||
|
"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)
|
||||||
|
add_custom_command(TARGET bootloader POST_BUILD
|
||||||
|
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
|
||||||
|
"\t${espefusepy} burn_key secure_boot ${secure_bootloader_key}"
|
||||||
|
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)
|
||||||
|
endif()
|
||||||
|
|
|
@ -17,6 +17,40 @@ if(${BOOTLOADER_BUILD})
|
||||||
set(COMPONENT_REQUIRES)
|
set(COMPONENT_REQUIRES)
|
||||||
set(COMPONENT_PRIV_REQUIRES spi_flash micro-ecc)
|
set(COMPONENT_PRIV_REQUIRES spi_flash micro-ecc)
|
||||||
list(APPEND COMPONENT_SRCS "src/bootloader_init.c")
|
list(APPEND COMPONENT_SRCS "src/bootloader_init.c")
|
||||||
|
|
||||||
|
if(CONFIG_SECURE_SIGNED_APPS)
|
||||||
|
get_filename_component(secure_boot_verification_key
|
||||||
|
"signature_verification_key.bin"
|
||||||
|
ABSOLUTE BASE_DIR "${CMAKE_BINARY_DIR}")
|
||||||
|
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
|
||||||
|
add_custom_command(OUTPUT "${secure_boot_verification_key}"
|
||||||
|
COMMAND ${ESPSECUREPY}
|
||||||
|
extract_public_key --keyfile "${secure_boot_signing_key}"
|
||||||
|
"${secure_boot_verification_key}"
|
||||||
|
DEPENDS gen_secure_boot_signing_key
|
||||||
|
VERBATIM)
|
||||||
|
else()
|
||||||
|
get_filename_component(orig_secure_boot_verification_key
|
||||||
|
"${CONFIG_SECURE_BOOT_VERIFICATION_KEY}"
|
||||||
|
ABSOLUTE BASE_DIR "${main_project_path}")
|
||||||
|
if(NOT EXISTS ${orig_secure_boot_verification_key})
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Secure Boot Verification Public Key ${CONFIG_SECURE_BOOT_VERIFICATION_KEY} does not exist."
|
||||||
|
"\nThis can be extracted from the private signing key."
|
||||||
|
"\nSee docs/security/secure-boot.rst for details.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_custom_command(OUTPUT "${secure_boot_verification_key}"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy "${orig_secure_boot_verification_key}"
|
||||||
|
"${secure_boot_verification_key}"
|
||||||
|
DEPENDS "${orig_secure_boot_verification_key}"
|
||||||
|
VERBATIM)
|
||||||
|
endif()
|
||||||
|
set(COMPONENT_EMBED_FILES "${secure_boot_verification_key}")
|
||||||
|
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
|
APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES
|
||||||
|
"${secure_boot_verification_key}")
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
||||||
set(COMPONENT_PRIV_INCLUDEDIRS "include_bootloader")
|
set(COMPONENT_PRIV_INCLUDEDIRS "include_bootloader")
|
||||||
|
|
|
@ -1,5 +1,14 @@
|
||||||
register_config_only_component()
|
register_config_only_component()
|
||||||
|
|
||||||
|
string(REPLACE ";" " " ESPTOOLPY_FLASH_PROJECT_OPTIONS "${ESPTOOLPY_ELF2IMAGE_FLASH_OPTIONS}")
|
||||||
|
set(ESPTOOLPY_FLASH_PROJECT_OPTIONS
|
||||||
|
"${ESPTOOLPY_FLASH_PROJECT_OPTIONS} ${BOOTLOADER_OFFSET} bootloader/bootloader.bin"
|
||||||
|
)
|
||||||
|
|
||||||
|
if(CONFIG_SECURE_BOOT_ENABLED)
|
||||||
|
set(ESPTOOLPY_FLASH_PROJECT_OPTIONS "")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Generate pre-canned flasher args files suitable for passing to esptool.py
|
# Generate pre-canned flasher args files suitable for passing to esptool.py
|
||||||
foreach(part project app bootloader partition_table)
|
foreach(part project app bootloader partition_table)
|
||||||
configure_file(
|
configure_file(
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
--flash_mode ${ESPFLASHMODE}
|
--flash_mode ${ESPFLASHMODE}
|
||||||
--flash_size ${ESPFLASHSIZE}
|
--flash_size ${ESPFLASHSIZE}
|
||||||
--flash_freq ${ESPFLASHFREQ}
|
--flash_freq ${ESPFLASHFREQ}
|
||||||
0x1000 bootloader/bootloader.bin
|
${BOOTLOADER_OFFSET} bootloader/bootloader.bin
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
--flash_mode ${ESPFLASHMODE}
|
${ESPTOOLPY_FLASH_PROJECT_OPTIONS}
|
||||||
--flash_size ${ESPFLASHSIZE}
|
|
||||||
--flash_freq ${ESPFLASHFREQ}
|
|
||||||
0x1000 bootloader/bootloader.bin
|
|
||||||
${PARTITION_TABLE_OFFSET} partition_table/partition-table.bin
|
${PARTITION_TABLE_OFFSET} partition_table/partition-table.bin
|
||||||
${PHY_PARTITION_OFFSET} ${PHY_PARTITION_BIN_FILE}
|
${PHY_PARTITION_OFFSET} ${PHY_PARTITION_BIN_FILE}
|
||||||
${OTADATA_PARTITION_OFFSET} ${BLANK_OTADATA_FILE}
|
${OTADATA_PARTITION_OFFSET} ${BLANK_OTADATA_FILE}
|
||||||
|
|
|
@ -3,18 +3,22 @@
|
||||||
"--flash_size", "${ESPFLASHSIZE}",
|
"--flash_size", "${ESPFLASHSIZE}",
|
||||||
"--flash_freq", "${ESPFLASHFREQ}" ],
|
"--flash_freq", "${ESPFLASHFREQ}" ],
|
||||||
"flash_files" : {
|
"flash_files" : {
|
||||||
"0x1000" : "bootloader/bootloader.bin",
|
"${BOOTLOADER_OFFSET}" : "bootloader/bootloader.bin",
|
||||||
"${PARTITION_TABLE_OFFSET}" : "partition_table/partition-table.bin",
|
"${PARTITION_TABLE_OFFSET}" : "partition_table/partition-table.bin",
|
||||||
"${PHY_PARTITION_OFFSET}" : "${PHY_PARTITION_BIN_FILE}",
|
"${PHY_PARTITION_OFFSET}" : "${PHY_PARTITION_BIN_FILE}",
|
||||||
"${OTADATA_PARTITION_OFFSET}" : "${BLANK_OTADATA_FILE}",
|
"${OTADATA_PARTITION_OFFSET}" : "${BLANK_OTADATA_FILE}",
|
||||||
"${APP_PARTITION_OFFSET}" : "${PROJECT_NAME}.bin"
|
"${APP_PARTITION_OFFSET}" : "${PROJECT_NAME}.bin"
|
||||||
},
|
},
|
||||||
"bootloader" : { "offset" : "0x1000",
|
"bootloader" : { "offset" : "${BOOTLOADER_OFFSET}",
|
||||||
"file" : "bootloader/bootloader.bin" },
|
"file" : "bootloader/bootloader.bin" },
|
||||||
"partition_table" : { "offset" : "${PARTITION_TABLE_OFFSET}",
|
"partition_table" : { "offset" : "${PARTITION_TABLE_OFFSET}",
|
||||||
"file" : "partition_table/partition-table.bin" },
|
"file" : "partition_table/partition-table.bin" },
|
||||||
"otadata" : { "offset" : "${OTADATA_PARTITION_OFFSET}",
|
"otadata" : { "offset" : "${OTADATA_PARTITION_OFFSET}",
|
||||||
"file" : "${BLANK_OTADATA_FILE}" },
|
"file" : "${BLANK_OTADATA_FILE}" },
|
||||||
"app" : { "offset" : "${APP_PARTITION_OFFSET}",
|
"app" : { "offset" : "${APP_PARTITION_OFFSET}",
|
||||||
"file" : "${PROJECT_NAME}.bin" }
|
"file" : "${PROJECT_NAME}.bin" },
|
||||||
|
"extra_esptool_args" : {
|
||||||
|
"after" : "${ESPTOOLPY_AFTER}",
|
||||||
|
"before" : "${ESPTOOLPY_BEFORE}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,34 @@
|
||||||
# Set some global esptool.py variables
|
# Set some global esptool.py variables
|
||||||
#
|
#
|
||||||
# Many of these are read when generating flash_app_args & flash_project_args
|
# Many of these are read when generating flash_app_args & flash_project_args
|
||||||
set(ESPTOOLPY "${PYTHON}" "${CMAKE_CURRENT_LIST_DIR}/esptool/esptool.py" --chip esp32)
|
set(ESPTOOLPY "${CMAKE_CURRENT_LIST_DIR}/esptool/esptool.py" --chip esp32)
|
||||||
set(ESPSECUREPY "${PYTHON}" "${CMAKE_CURRENT_LIST_DIR}/esptool/espsecure.py")
|
set(ESPSECUREPY "${CMAKE_CURRENT_LIST_DIR}/esptool/espsecure.py")
|
||||||
|
set(ESPEFUSEPY "${CMAKE_CURRENT_LIST_DIR}/esptool/espefuse.py")
|
||||||
|
|
||||||
set(ESPFLASHMODE ${CONFIG_ESPTOOLPY_FLASHMODE})
|
set(ESPFLASHMODE ${CONFIG_ESPTOOLPY_FLASHMODE})
|
||||||
set(ESPFLASHFREQ ${CONFIG_ESPTOOLPY_FLASHFREQ})
|
set(ESPFLASHFREQ ${CONFIG_ESPTOOLPY_FLASHFREQ})
|
||||||
set(ESPFLASHSIZE ${CONFIG_ESPTOOLPY_FLASHSIZE})
|
set(ESPFLASHSIZE ${CONFIG_ESPTOOLPY_FLASHSIZE})
|
||||||
|
|
||||||
set(ESPTOOLPY_SERIAL "${ESPTOOLPY}" --port "${ESPPORT}" --baud ${ESPBAUD})
|
set(ESPTOOLPY_BEFORE "${CONFIG_ESPTOOLPY_BEFORE}")
|
||||||
|
set(ESPTOOLPY_AFTER "${CONFIG_ESPTOOLPY_AFTER}")
|
||||||
|
|
||||||
|
if(CONFIG_SECURE_BOOT_ENABLED OR CONFIG_FLASH_ENCRYPTION_ENABLED)
|
||||||
|
# If security enabled then override post flash option
|
||||||
|
set(ESPTOOLPY_AFTER "no_reset")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(ESPTOOLPY_SERIAL "${ESPTOOLPY}"
|
||||||
|
--port "${ESPPORT}"
|
||||||
|
--baud ${ESPBAUD}
|
||||||
|
--before "${ESPTOOLPY_BEFORE}"
|
||||||
|
--after "${ESPTOOLPY_AFTER}"
|
||||||
|
)
|
||||||
|
|
||||||
|
if(CONFIG_ESPTOOLPY_COMPRESSED)
|
||||||
|
set(ESPTOOLPY_COMPRESSED_OPT -z)
|
||||||
|
else()
|
||||||
|
set(ESPTOOLPY_COMPRESSED_OPT -u)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(ESPTOOLPY_ELF2IMAGE_FLASH_OPTIONS
|
set(ESPTOOLPY_ELF2IMAGE_FLASH_OPTIONS
|
||||||
--flash_mode ${ESPFLASHMODE}
|
--flash_mode ${ESPFLASHMODE}
|
||||||
|
@ -16,6 +36,18 @@ set(ESPTOOLPY_ELF2IMAGE_FLASH_OPTIONS
|
||||||
--flash_size ${ESPFLASHSIZE}
|
--flash_size ${ESPFLASHSIZE}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# String for printing flash command
|
||||||
|
string(REPLACE ";" " " ESPTOOLPY_WRITE_FLASH_STR
|
||||||
|
"${ESPTOOLPY} --port (PORT) --baud (BAUD) --before ${ESPTOOLPY_BEFORE} --after ${ESPTOOLPY_AFTER} "
|
||||||
|
"write_flash ${ESPTOOLPY_ELF2IMAGE_FLASH_OPTIONS} ${ESPTOOLPY_EXTRA_FLASH_OPTIONS} ${ESPTOOLPY_COMPRESSED_OPT}")
|
||||||
|
|
||||||
|
if(CONFIG_SECURE_BOOT_ENABLED AND
|
||||||
|
NOT CONFIG_SECURE_BOOT_ALLOW_SHORT_APP_PARTITION AND
|
||||||
|
NOT BOOTLOADER_BUILD)
|
||||||
|
set(ESPTOOLPY_ELF2IMAGE_FLASH_OPTIONS
|
||||||
|
${ESPTOOLPY_ELF2IMAGE_FLASH_OPTIONS} --secure-pad)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(CONFIG_ESPTOOLPY_FLASHSIZE_DETECT)
|
if(CONFIG_ESPTOOLPY_FLASHSIZE_DETECT)
|
||||||
# Set ESPFLASHSIZE to 'detect' *after* elf2image options are generated,
|
# Set ESPFLASHSIZE to 'detect' *after* elf2image options are generated,
|
||||||
# as elf2image can't have 'detect' as an option...
|
# as elf2image can't have 'detect' as an option...
|
||||||
|
@ -28,15 +60,50 @@ if(CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION)
|
||||||
set(PHY_PARTITION_BIN_FILE "esp32/phy_init_data.bin")
|
set(PHY_PARTITION_BIN_FILE "esp32/phy_init_data.bin")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES AND NOT BOOTLOADER_BUILD)
|
||||||
|
set(unsigned_project_binary "${PROJECT_NAME}-unsigned.bin")
|
||||||
|
else()
|
||||||
|
set(unsigned_project_binary "${PROJECT_NAME}.bin")
|
||||||
|
endif()
|
||||||
|
|
||||||
#
|
#
|
||||||
# Add 'app.bin' target - generates with elf2image
|
# Add 'app.bin' target - generates with elf2image
|
||||||
#
|
#
|
||||||
add_custom_command(OUTPUT "${PROJECT_NAME}.bin"
|
add_custom_command(OUTPUT "${unsigned_project_binary}"
|
||||||
COMMAND ${ESPTOOLPY} elf2image ${ESPTOOLPY_ELF2IMAGE_FLASH_OPTIONS} -o "${PROJECT_NAME}.bin" "${PROJECT_NAME}.elf"
|
COMMAND ${ESPTOOLPY} elf2image ${ESPTOOLPY_ELF2IMAGE_FLASH_OPTIONS}
|
||||||
|
-o "${unsigned_project_binary}" "${PROJECT_NAME}.elf"
|
||||||
DEPENDS ${PROJECT_NAME}.elf
|
DEPENDS ${PROJECT_NAME}.elf
|
||||||
VERBATIM
|
VERBATIM
|
||||||
)
|
)
|
||||||
add_custom_target(app ALL DEPENDS "${PROJECT_NAME}.bin")
|
|
||||||
|
if(NOT BOOTLOADER_BUILD AND
|
||||||
|
CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
|
||||||
|
# for locally signed secure boot image, add a signing step to get from unsigned app to signed app
|
||||||
|
add_custom_target(gen_unsigned_project_binary ALL DEPENDS "${unsigned_project_binary}")
|
||||||
|
add_custom_command(OUTPUT "${PROJECT_NAME}.bin"
|
||||||
|
COMMAND ${ESPSECUREPY} sign_data --keyfile ${secure_boot_signing_key}
|
||||||
|
-o "${PROJECT_NAME}.bin" "${unsigned_project_binary}"
|
||||||
|
DEPENDS gen_unsigned_project_binary
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT BOOTLOADER_BUILD)
|
||||||
|
add_custom_target(app ALL DEPENDS "${PROJECT_NAME}.bin")
|
||||||
|
else()
|
||||||
|
add_custom_target(bootloader ALL DEPENDS "${PROJECT_NAME}.bin")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT BOOTLOADER_BUILD AND
|
||||||
|
CONFIG_SECURE_BOOT_ENABLED AND
|
||||||
|
NOT CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
|
||||||
|
add_custom_command(TARGET app POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo
|
||||||
|
"App built but not signed. Sign app before flashing"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo
|
||||||
|
"\t${ESPSECUREPY} sign_data --keyfile KEYFILE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}.bin"
|
||||||
|
VERBATIM)
|
||||||
|
endif()
|
||||||
|
|
||||||
#
|
#
|
||||||
# Add 'flash' target - not all build systems can run this directly
|
# Add 'flash' target - not all build systems can run this directly
|
||||||
|
|
|
@ -22,40 +22,48 @@ if(CONFIG_ESPTOOLPY_FLASHSIZE)
|
||||||
set(flashsize_opt --flash-size ${CONFIG_ESPTOOLPY_FLASHSIZE})
|
set(flashsize_opt --flash-size ${CONFIG_ESPTOOLPY_FLASHSIZE})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_SECURE_BOOT_ENABLED AND NOT CONFIG_SECURE_BOOT_ALLOW_SHORT_APP_PARTITION)
|
||||||
|
set(partition_secure_opt --secure)
|
||||||
|
else()
|
||||||
|
set(partition_secure_opt "")
|
||||||
|
endif()
|
||||||
|
|
||||||
add_custom_command(OUTPUT "${unsigned_partition_bin}"
|
add_custom_command(OUTPUT "${unsigned_partition_bin}"
|
||||||
COMMAND "${PYTHON}" "${CMAKE_CURRENT_SOURCE_DIR}/gen_esp32part.py" -q --offset ${PARTITION_TABLE_OFFSET} ${md5_opt} ${flashsize_opt}
|
COMMAND "${PYTHON}" "${CMAKE_CURRENT_SOURCE_DIR}/gen_esp32part.py"
|
||||||
${partition_csv} ${unsigned_partition_bin}
|
-q --offset ${PARTITION_TABLE_OFFSET} ${md5_opt} ${flashsize_opt}
|
||||||
|
${partition_secure_opt} ${partition_csv} ${unsigned_partition_bin}
|
||||||
DEPENDS ${partition_csv} "${CMAKE_CURRENT_SOURCE_DIR}/gen_esp32part.py"
|
DEPENDS ${partition_csv} "${CMAKE_CURRENT_SOURCE_DIR}/gen_esp32part.py"
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
|
|
||||||
# Add signing steps
|
# Add signing steps
|
||||||
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
|
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
|
||||||
get_filename_component(secure_boot_signing_key
|
add_custom_target(gen_unsigned_partition_bin ALL DEPENDS "${unsigned_partition_bin}")
|
||||||
"${CONFIG_SECURE_BOOT_SIGNING_KEY}"
|
|
||||||
ABSOLUTE BASE_DIR "${PROJECT_PATH}")
|
|
||||||
|
|
||||||
add_custom_command(OUTPUT "${final_partition_bin}"
|
add_custom_command(OUTPUT "${final_partition_bin}"
|
||||||
COMMAND "${PYTHON}" "${ESPSECUREPY}" sign_data --keyfile "${secure_boot_signing_key}"
|
COMMAND ${ESPSECUREPY} sign_data --keyfile "${secure_boot_signing_key}"
|
||||||
-o "${final_partition_bin}" "${unsigned_partition_bin}"
|
-o "${final_partition_bin}" "${unsigned_partition_bin}"
|
||||||
DEPENDS "${unsigned_partition_bin}"
|
DEPENDS gen_unsigned_partition_bin gen_secure_boot_signing_key
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(EXISTS ${partition_csv})
|
if(EXISTS ${partition_csv})
|
||||||
add_custom_target(partition_table ALL DEPENDS "${final_partition_bin}")
|
add_custom_target(partition_table ALL DEPENDS "${final_partition_bin}")
|
||||||
else()
|
else()
|
||||||
# This is a bit of a hack: If the partition input CSV is not found, create a phony partition_table target that
|
# If the partition input CSV is not found, create a phony partition_table target that
|
||||||
# fails the build. Have it also touch CMakeCache.txt to cause a cmake run next time
|
# fails the build. fail_at_build_time also touches CMakeCache.txt to cause a cmake run next time
|
||||||
# (to pick up a new CSV if one exists, etc.)
|
# (to pick up a new CSV if one exists, etc.)
|
||||||
#
|
fail_at_build_time(partition_table
|
||||||
# This is because partition CSV is required at CMake runtime (to generate metadata files with flashing data, etc) but we can't
|
"Partition table CSV ${partition_csv} does not exist."
|
||||||
# fail the build if it is not found, because the "menuconfig" target may be required to fix the problem. CMAKE_CONFIGURE_DEPENDS
|
"Either change partition table in menuconfig or create this input file.")
|
||||||
# only works for files which exist at CMake runtime.
|
endif()
|
||||||
add_custom_target(partition_table ALL
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E echo "Partition table CSV ${partition_csv} does not exist. Either change partition table in menuconfig or create this input file."
|
if(CONFIG_SECURE_BOOT_ENABLED AND
|
||||||
COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_BINARY_DIR}/CMakeCache.txt"
|
NOT CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
|
||||||
COMMAND ${CMAKE_COMMAND} -P ${IDF_PATH}/tools/cmake/scripts/fail.cmake)
|
add_custom_command(TARGET partition_table POST_BUILD
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo
|
||||||
|
"Partition table built but not signed. Sign partition data before flashing:"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo
|
||||||
|
"\t${ESPSECUREPY} sign_data --keyfile KEYFILE ${CMAKE_CURRENT_BINARY_DIR}/${final_partition_bin}"
|
||||||
|
VERBATIM)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_dependencies(bootloader partition_table)
|
add_dependencies(bootloader partition_table)
|
||||||
|
|
|
@ -56,3 +56,5 @@ get_partition_info(OTADATA_PARTITION_OFFSET "--type data --subtype ota --offset"
|
||||||
get_partition_info(OTADATA_PARTITION_SIZE "--type data --subtype ota --size")
|
get_partition_info(OTADATA_PARTITION_SIZE "--type data --subtype ota --size")
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(BOOTLOADER_OFFSET 0x1000)
|
||||||
|
|
|
@ -114,8 +114,9 @@ function(target_add_binary_data target embed_file embed_type)
|
||||||
-D "FILE_TYPE=${embed_type}"
|
-D "FILE_TYPE=${embed_type}"
|
||||||
-P "${IDF_PATH}/tools/cmake/scripts/data_file_embed_asm.cmake"
|
-P "${IDF_PATH}/tools/cmake/scripts/data_file_embed_asm.cmake"
|
||||||
MAIN_DEPENDENCY "${embed_file}"
|
MAIN_DEPENDENCY "${embed_file}"
|
||||||
DEPENDENCIES "${IDF_PATH}/tools/cmake/scripts/data_file_embed_asm.cmake"
|
DEPENDS "${IDF_PATH}/tools/cmake/scripts/data_file_embed_asm.cmake"
|
||||||
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}")
|
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
|
||||||
|
VERBATIM)
|
||||||
|
|
||||||
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${embed_srcfile}")
|
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "${embed_srcfile}")
|
||||||
|
|
||||||
|
@ -189,3 +190,24 @@ function(add_prefix var prefix)
|
||||||
endforeach()
|
endforeach()
|
||||||
set(${var} "${newlist}" PARENT_SCOPE)
|
set(${var} "${newlist}" PARENT_SCOPE)
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
# fail_at_build_time
|
||||||
|
#
|
||||||
|
# Creates a phony target which fails the build and touches CMakeCache.txt to cause a cmake run next time.
|
||||||
|
#
|
||||||
|
# This is used when a missing file is required at CMake runtime, but we can't fail the build if it is not found,
|
||||||
|
# because the "menuconfig" target may be required to fix the problem.
|
||||||
|
#
|
||||||
|
# We cannot use CMAKE_CONFIGURE_DEPENDS instead because it only works for files which exist at CMake runtime.
|
||||||
|
#
|
||||||
|
function(fail_at_build_time target_name message_line0)
|
||||||
|
set(message_lines COMMAND ${CMAKE_COMMAND} -E echo "${message_line0}")
|
||||||
|
foreach(message_line ${ARGN})
|
||||||
|
set(message_lines ${message_lines} COMMAND ${CMAKE_COMMAND} -E echo "${message_line}")
|
||||||
|
endforeach()
|
||||||
|
add_custom_target(${target_name} ALL
|
||||||
|
${message_lines}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E touch "${CMAKE_BINARY_DIR}/CMakeCache.txt"
|
||||||
|
COMMAND ${CMAKE_COMMAND} -P ${IDF_PATH}/tools/cmake/scripts/fail.cmake
|
||||||
|
VERBATIM)
|
||||||
|
endfunction()
|
||||||
|
|
|
@ -244,6 +244,12 @@ def _get_esptool_args(args):
|
||||||
result = [ PYTHON, esptool_path ]
|
result = [ PYTHON, esptool_path ]
|
||||||
result += [ "-p", args.port ]
|
result += [ "-p", args.port ]
|
||||||
result += [ "-b", str(args.baud) ]
|
result += [ "-b", str(args.baud) ]
|
||||||
|
|
||||||
|
with open(os.path.join(args.build_dir, "flasher_args.json")) as f:
|
||||||
|
flasher_args = json.load(f)
|
||||||
|
|
||||||
|
extra_esptool_args = flasher_args["extra_esptool_args"]
|
||||||
|
result += [ "--after", extra_esptool_args["after"] ]
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def flash(action, args):
|
def flash(action, args):
|
||||||
|
@ -360,10 +366,11 @@ def print_closing_message(args):
|
||||||
for o,f in flash_items:
|
for o,f in flash_items:
|
||||||
cmd += o + " " + flasher_path(f) + " "
|
cmd += o + " " + flasher_path(f) + " "
|
||||||
|
|
||||||
print("%s -p %s -b %s write_flash %s" % (
|
print("%s -p %s -b %s --after %s write_flash %s" % (
|
||||||
os.path.relpath("%s/components/esptool_py/esptool/esptool.py" % os.environ["IDF_PATH"]),
|
os.path.relpath("%s/components/esptool_py/esptool/esptool.py" % os.environ["IDF_PATH"]),
|
||||||
args.port or "(PORT)",
|
args.port or "(PORT)",
|
||||||
args.baud,
|
args.baud,
|
||||||
|
flasher_args["extra_esptool_args"]["after"],
|
||||||
cmd.strip()))
|
cmd.strip()))
|
||||||
print("or run 'idf.py -p %s %s'" % (args.port or "(PORT)", key + "-flash" if key != "project" else "flash",))
|
print("or run 'idf.py -p %s %s'" % (args.port or "(PORT)", key + "-flash" if key != "project" else "flash",))
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue