• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2020 Espressif Systems (Shanghai) Co., 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 
15 #include "string.h"
16 #include "sdkconfig.h"
17 #include "esp_err.h"
18 #include "esp_log.h"
19 #if CONFIG_IDF_TARGET_ESP32
20 #include "esp32/rom/spi_flash.h"
21 #elif CONFIG_IDF_TARGET_ESP32S2
22 #include "esp32s2/rom/spi_flash.h"
23 #include "esp32s2/rom/ets_sys.h"
24 #endif
25 #include "esp_rom_crc.h"
26 #include "esp_rom_gpio.h"
27 #include "esp_flash_partitions.h"
28 #include "bootloader_flash.h"
29 #include "bootloader_common.h"
30 #include "soc/gpio_periph.h"
31 #include "soc/rtc.h"
32 #include "soc/efuse_reg.h"
33 #include "soc/soc_memory_layout.h"
34 #include "hal/gpio_ll.h"
35 #include "esp_image_format.h"
36 #include "bootloader_sha.h"
37 #include "sys/param.h"
38 #include "bootloader_flash_priv.h"
39 
40 #define ESP_PARTITION_HASH_LEN 32 /* SHA-256 digest length */
41 
42 static const char* TAG = "boot_comm";
43 
bootloader_common_ota_select_crc(const esp_ota_select_entry_t * s)44 uint32_t bootloader_common_ota_select_crc(const esp_ota_select_entry_t *s)
45 {
46     return esp_rom_crc32_le(UINT32_MAX, (uint8_t*)&s->ota_seq, 4);
47 }
48 
bootloader_common_ota_select_invalid(const esp_ota_select_entry_t * s)49 bool bootloader_common_ota_select_invalid(const esp_ota_select_entry_t *s)
50 {
51     return s->ota_seq == UINT32_MAX || s->ota_state == ESP_OTA_IMG_INVALID || s->ota_state == ESP_OTA_IMG_ABORTED;
52 }
53 
bootloader_common_ota_select_valid(const esp_ota_select_entry_t * s)54 bool bootloader_common_ota_select_valid(const esp_ota_select_entry_t *s)
55 {
56     return bootloader_common_ota_select_invalid(s) == false && s->crc == bootloader_common_ota_select_crc(s);
57 }
58 
bootloader_common_get_active_otadata(esp_ota_select_entry_t * two_otadata)59 int bootloader_common_get_active_otadata(esp_ota_select_entry_t *two_otadata)
60 {
61     if (two_otadata == NULL) {
62         return -1;
63     }
64     bool valid_two_otadata[2];
65     valid_two_otadata[0] = bootloader_common_ota_select_valid(&two_otadata[0]);
66     valid_two_otadata[1] = bootloader_common_ota_select_valid(&two_otadata[1]);
67     return bootloader_common_select_otadata(two_otadata, valid_two_otadata, true);
68 }
69 
bootloader_common_check_chip_validity(const esp_image_header_t * img_hdr,esp_image_type type)70 esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hdr, esp_image_type type)
71 {
72     esp_err_t err = ESP_OK;
73     esp_chip_id_t chip_id = CONFIG_IDF_FIRMWARE_CHIP_ID;
74     if (chip_id != img_hdr->chip_id) {
75         ESP_LOGE(TAG, "mismatch chip ID, expected %d, found %d", chip_id, img_hdr->chip_id);
76         err = ESP_FAIL;
77     }
78     uint8_t revision = bootloader_common_get_chip_revision();
79     if (revision < img_hdr->min_chip_rev) {
80         /* To fix this error, please update mininum supported chip revision from configuration,
81          * located in TARGET (e.g. ESP32) specific options under "Component config" menu */
82         ESP_LOGE(TAG, "This chip is revision %d but the application is configured for minimum revision %d. Can't run.", revision, img_hdr->min_chip_rev);
83         err = ESP_FAIL;
84     } else if (revision != img_hdr->min_chip_rev) {
85 #ifdef BOOTLOADER_BUILD
86         ESP_LOGI(TAG, "chip revision: %d, min. %s chip revision: %d", revision, type == ESP_IMAGE_BOOTLOADER ? "bootloader" : "application", img_hdr->min_chip_rev);
87 #endif
88     }
89     return err;
90 }
91 
bootloader_common_select_otadata(const esp_ota_select_entry_t * two_otadata,bool * valid_two_otadata,bool max)92 int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata, bool *valid_two_otadata, bool max)
93 {
94     if (two_otadata == NULL || valid_two_otadata == NULL) {
95         return -1;
96     }
97     int active_otadata = -1;
98     if (valid_two_otadata[0] && valid_two_otadata[1]) {
99         uint32_t condition = (max == true) ? MAX(two_otadata[0].ota_seq, two_otadata[1].ota_seq) : MIN(two_otadata[0].ota_seq, two_otadata[1].ota_seq);
100         if (condition == two_otadata[0].ota_seq) {
101             active_otadata = 0;
102         } else {
103             active_otadata = 1;
104         }
105         ESP_LOGD(TAG, "Both OTA copies are valid");
106     } else {
107         for (int i = 0; i < 2; ++i) {
108             if (valid_two_otadata[i]) {
109                 active_otadata = i;
110                 ESP_LOGD(TAG, "Only otadata[%d] is valid", i);
111                 break;
112             }
113         }
114     }
115     return active_otadata;
116 }
117 
bootloader_common_get_partition_description(const esp_partition_pos_t * partition,esp_app_desc_t * app_desc)118 esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc)
119 {
120     if (partition == NULL || app_desc == NULL || partition->offset == 0) {
121         return ESP_ERR_INVALID_ARG;
122     }
123 
124     const uint32_t app_desc_offset = sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t);
125     const uint32_t mmap_size = app_desc_offset + sizeof(esp_app_desc_t);
126     const uint8_t *image = bootloader_mmap(partition->offset, mmap_size);
127     if (image == NULL) {
128         ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", partition->offset, mmap_size);
129         return ESP_FAIL;
130     }
131 
132     memcpy(app_desc, image + app_desc_offset, sizeof(esp_app_desc_t));
133     bootloader_munmap(image);
134 
135     if (app_desc->magic_word != ESP_APP_DESC_MAGIC_WORD) {
136         return ESP_ERR_NOT_FOUND;
137     }
138 
139     return ESP_OK;
140 }
141 
142 #if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
143 
144 #define RTC_RETAIN_MEM_ADDR (SOC_RTC_DRAM_HIGH - sizeof(rtc_retain_mem_t))
145 
146 rtc_retain_mem_t *const rtc_retain_mem = (rtc_retain_mem_t *)RTC_RETAIN_MEM_ADDR;
147 
148 #if !IS_BOOTLOADER_BUILD
149 /* The app needs to be told this memory is reserved, important if configured to use RTC memory as heap.
150 
151    Note that keeping this macro here only works when other symbols in this file are referenced by the app, as
152    this feature is otherwise 100% part of the bootloader. However this seems to happen in all apps.
153  */
154 SOC_RESERVE_MEMORY_REGION(RTC_RETAIN_MEM_ADDR, RTC_RETAIN_MEM_ADDR + sizeof(rtc_retain_mem_t), rtc_retain_mem);
155 #endif
156 
check_rtc_retain_mem(void)157 static bool check_rtc_retain_mem(void)
158 {
159     return esp_rom_crc32_le(UINT32_MAX, (uint8_t*)rtc_retain_mem, sizeof(rtc_retain_mem_t) - sizeof(rtc_retain_mem->crc)) == rtc_retain_mem->crc && rtc_retain_mem->crc != UINT32_MAX;
160 }
161 
update_rtc_retain_mem_crc(void)162 static void update_rtc_retain_mem_crc(void)
163 {
164     rtc_retain_mem->crc = esp_rom_crc32_le(UINT32_MAX, (uint8_t*)rtc_retain_mem, sizeof(rtc_retain_mem_t) - sizeof(rtc_retain_mem->crc));
165 }
166 
bootloader_common_reset_rtc_retain_mem(void)167 void bootloader_common_reset_rtc_retain_mem(void)
168 {
169     memset(rtc_retain_mem, 0, sizeof(rtc_retain_mem_t));
170 }
171 
bootloader_common_get_rtc_retain_mem_reboot_counter(void)172 uint16_t bootloader_common_get_rtc_retain_mem_reboot_counter(void)
173 {
174     if (check_rtc_retain_mem()) {
175         return rtc_retain_mem->reboot_counter;
176     }
177     return 0;
178 }
179 
bootloader_common_get_rtc_retain_mem_partition(void)180 esp_partition_pos_t* bootloader_common_get_rtc_retain_mem_partition(void)
181 {
182     if (check_rtc_retain_mem()) {
183         return &rtc_retain_mem->partition;
184     }
185     return NULL;
186 }
187 
bootloader_common_update_rtc_retain_mem(esp_partition_pos_t * partition,bool reboot_counter)188 void bootloader_common_update_rtc_retain_mem(esp_partition_pos_t* partition, bool reboot_counter)
189 {
190     if (reboot_counter) {
191         if (!check_rtc_retain_mem()) {
192             bootloader_common_reset_rtc_retain_mem();
193         }
194         if (++rtc_retain_mem->reboot_counter == 0) {
195             // do not allow to overflow. Stop it.
196             --rtc_retain_mem->reboot_counter;
197         }
198 
199     }
200 
201     if (partition != NULL) {
202         rtc_retain_mem->partition.offset = partition->offset;
203         rtc_retain_mem->partition.size   = partition->size;
204     }
205 
206     update_rtc_retain_mem_crc();
207 }
208 
bootloader_common_get_rtc_retain_mem(void)209 rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void)
210 {
211     return rtc_retain_mem;
212 }
213 #endif // defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
214