1 // Copyright 2018 Espressif Systems (Shanghai) PTE LTD 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 #pragma once 15 16 #include "bootloader_config.h" 17 #include "esp_image_format.h" 18 #include "bootloader_config.h" 19 20 /** 21 * @brief Load partition table. 22 * 23 * Parse partition table, get useful data such as location of 24 * OTA data partition, factory app partition, and test app partition. 25 * 26 * @param[out] bs Bootloader state structure used to save read data. 27 * @return Return true if the partition table was succesfully loaded and MD5 checksum is valid. 28 */ 29 bool bootloader_utility_load_partition_table(bootloader_state_t* bs); 30 31 /** 32 * @brief Return the index of the selected boot partition. 33 * 34 * This is the preferred boot partition, as determined by the partition table & 35 * any OTA sequence number found in OTA data. 36 * This partition will only be booted if it contains a valid app image, otherwise load_boot_image() will search 37 * for a valid partition using this selection as the starting point. 38 * 39 * @param[in] bs Bootloader state structure. 40 * @return Returns the index on success, INVALID_INDEX otherwise. 41 */ 42 int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs); 43 44 /** 45 * @brief Load the selected partition and start application. 46 * 47 * Start from partition 'start_index', if not bootable then work backwards to FACTORY_INDEX 48 * (ie try any OTA slots in descending order and then the factory partition). 49 * If still nothing, start from 'start_index + 1' and work up to highest numbered OTA partition. 50 * If still nothing, try TEST_APP_INDEX. 51 * Everything this function calls must be located in the iram_loader_seg segment. 52 * 53 * @param[in] bs Bootloader state structure. 54 * @param[in] start_index The index from which the search for images begins. 55 */ 56 __attribute__((noreturn)) void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index); 57 58 #ifdef CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP 59 /** 60 * @brief Load that application which was worked before we go to the deep sleep. 61 * 62 * Checks the reboot reason if it is the deep sleep and has a valid partition in the RTC memory 63 * then try to load the application which was worked before we go to the deep sleep. 64 * 65 */ 66 void bootloader_utility_load_boot_image_from_deep_sleep(void); 67 #endif 68 69 /** 70 * @brief Software reset the ESP32 71 * 72 * Bootloader code should call this in the case that it cannot proceed. 73 * 74 * It is not recommended to call this function from an app (if called, the app will abort). 75 */ 76 __attribute__((noreturn)) void bootloader_reset(void); 77 78 /** 79 * @brief Do any cleanup before exiting the bootloader, before starting the app or resetting 80 */ 81 void bootloader_atexit(void); 82 83 /** 84 * @brief Converts an array to a printable string. 85 * 86 * This function is useful for printing SHA-256 digest. 87 * \code{c} 88 * // Example of using. image_hash will be printed 89 * #define HASH_LEN 32 // SHA-256 digest length 90 * ... 91 * char hash_print[HASH_LEN * 2 + 1]; 92 * hash_print[HASH_LEN * 2] = 0; 93 * bootloader_sha256_hex_to_str(hash_print, image_hash, HASH_LEN); 94 * ESP_LOGI(TAG, %s", hash_print); 95 * \endcode 96 97 * @param[out] out_str Output string 98 * @param[in] in_array_hex Pointer to input array 99 * @param[in] len Length of input array 100 * 101 * @return ESP_OK: Successful 102 * ESP_ERR_INVALID_ARG: Error in the passed arguments 103 */ 104 esp_err_t bootloader_sha256_hex_to_str(char *out_str, const uint8_t *in_array_hex, size_t len); 105 106 /** 107 * @brief Debug log contents of a buffer as hexadecimal 108 * 109 * @note Only works if component log level is DEBUG or higher. 110 * 111 * @param buffer Buffer to log 112 * @param length Length of buffer in bytes. Maximum length 128 bytes. 113 * @param label Label to print at beginning of log line. 114 */ 115 void bootloader_debug_buffer(const void *buffer, size_t length, const char *label); 116 117 /** @brief Generates the digest of the data between offset & offset+length. 118 * 119 * This function should be used when the size of the data is larger than 3.2MB. 120 * The MMU capacity is 3.2MB (50 pages - 64KB each). This function generates the SHA-256 121 * of the data in chunks of 3.2MB, considering the MMU capacity. 122 * 123 * @param[in] flash_offset Offset of the data in flash. 124 * @param[in] len Length of data in bytes. 125 * @param[out] digest Pointer to buffer where the digest is written, if ESP_OK is returned. 126 * 127 * @return ESP_OK if secure boot digest is generated successfully. 128 */ 129 esp_err_t bootloader_sha256_flash_contents(uint32_t flash_offset, uint32_t len, uint8_t *digest); 130