Skip to content

Commit 46a9ce1

Browse files
committed
Copy firmware when booted if needed
1 parent 83502c3 commit 46a9ce1

File tree

1 file changed

+181
-0
lines changed

1 file changed

+181
-0
lines changed

esp32/ftp/updater.c

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,162 @@ STATIC char *updater_read_file (const char *file_path, vstr_t *vstr) {
131131
return vstr->buf;
132132
}
133133

134+
extern bool updater_write_encrypt (uint8_t *buf, uint32_t len);
135+
static uint8_t buf[SPI_FLASH_SEC_SIZE];
136+
#define IMG_UPDATE1_OFFSET_OLD 0x1a0000
137+
extern const void *bootloader_mmap(uint32_t src_addr, uint32_t size);
138+
extern void bootloader_munmap(const void *mapping);
139+
140+
141+
void update_to_factory_partition(void) {
142+
143+
esp_image_header_t image;
144+
uint32_t checksum_word = 0xEF;
145+
esp_image_segment_header_t segments[ESP_IMAGE_MAX_SEGMENTS];
146+
uint32_t segment_data[ESP_IMAGE_MAX_SEGMENTS];
147+
148+
149+
printf("update_to_factory_partition 1\n");
150+
151+
printf("update_to_factory_partition 2\n");
152+
153+
updater_data.size = (1536*1024);
154+
updater_data.offset = IMG_FACTORY_OFFSET;
155+
updater_data.offset_start_upd = updater_data.offset;
156+
boot_info.size = 0;
157+
updater_data.current_chunk = 0;
158+
159+
// erase the first 2 sectors
160+
if (ESP_OK != spi_flash_erase_sector(updater_data.offset / SPI_FLASH_SEC_SIZE)) {
161+
ESP_LOGE(TAG, "Erasing first sector failed!\n");
162+
}
163+
// if (ESP_OK != spi_flash_erase_sector((updater_data.offset + SPI_FLASH_SEC_SIZE) / SPI_FLASH_SEC_SIZE)) {
164+
// ESP_LOGE(TAG, "Erasing second sector failed!\n");
165+
// }
166+
167+
printf("update_to_factory_partition 3\n");
168+
169+
170+
uint32_t bytes_read = 0;
171+
172+
while(updater_data.size != bytes_read){
173+
//printf("update_to_factory_partition 4\n");
174+
175+
updater_spi_flash_read(IMG_UPDATE1_OFFSET_OLD+bytes_read, buf, SPI_FLASH_SEC_SIZE, true);
176+
bytes_read += SPI_FLASH_SEC_SIZE;
177+
if(false == updater_write_encrypt(buf, SPI_FLASH_SEC_SIZE)){
178+
printf("update_to_factory_partition, updater_write returned FALSE\n");
179+
}
180+
}
181+
182+
printf("update_to_factory_partition, bytes_read: %u\n", bytes_read);
183+
184+
updater_finish();
185+
186+
printf("update_to_factory_partition 7\n");
187+
188+
updater_spi_flash_read(IMG_FACTORY_OFFSET, &image, sizeof(esp_image_header_t), true);
189+
190+
uint32_t next_addr = IMG_FACTORY_OFFSET + sizeof(esp_image_header_t);
191+
for(int i = 0; i < image.segment_count; i++) {
192+
esp_image_segment_header_t *header = &segments[i];
193+
194+
updater_spi_flash_read(next_addr, header, sizeof(esp_image_segment_header_t), true);
195+
const uint32_t *data = (const uint32_t *)bootloader_mmap(next_addr+sizeof(esp_image_segment_header_t), header->data_len);
196+
for (int i = 0; i < header->data_len; i += 4) {
197+
int w_i = i/4; // Word index
198+
uint32_t w = data[w_i];
199+
checksum_word ^= w;
200+
}
201+
202+
bootloader_munmap(data);
203+
204+
next_addr += sizeof(esp_image_segment_header_t);
205+
segment_data[i] = next_addr;
206+
next_addr += header->data_len;
207+
}
208+
209+
//uint32_t unpadded_length = 1536*1024;
210+
uint32_t unpadded_length = next_addr - IMG_FACTORY_OFFSET;
211+
uint32_t length = unpadded_length + 1; // Add a byte for the checksum
212+
length = (length + 15) & ~15; // Pad to next full 16 byte block
213+
printf("length: %u\n", length);
214+
// Verify checksum
215+
uint8_t buf[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
216+
updater_spi_flash_read(IMG_FACTORY_OFFSET + unpadded_length, buf, length - unpadded_length, true);
217+
218+
printf("length - unpadded_length - 1: %u\n", length - unpadded_length - 1);
219+
uint8_t calc = buf[length - unpadded_length - 1];
220+
printf("calc: 0x%X\n", calc);
221+
printf("checksum_word: 0x%X\n", checksum_word);
222+
uint8_t checksum = (checksum_word >> 24)
223+
^ (checksum_word >> 16)
224+
^ (checksum_word >> 8)
225+
^ (checksum_word >> 0);
226+
printf("checksum of FACTORY: 0x%X\n", checksum);
227+
228+
printf("Writing new checksum...\n");
229+
buf[length - unpadded_length - 1] = checksum;
230+
if(ESP_OK != updater_spi_flash_write(IMG_FACTORY_OFFSET + unpadded_length, buf, length - unpadded_length, true)) {
231+
printf("Writing new checksum failed...'\n");
232+
}
233+
234+
printf("Reading new value...\n");
235+
uint8_t buf3[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
236+
updater_spi_flash_read(IMG_FACTORY_OFFSET + unpadded_length, buf3, length - unpadded_length, true);
237+
printf("length - unpadded_length - 1: %u\n", length - unpadded_length - 1);
238+
calc = buf3[length - unpadded_length - 1];
239+
printf("calc: 0x%X\n", calc);
240+
printf("-----------------\n");
241+
242+
243+
244+
/*--------------------------------------------------------------------*/
245+
246+
checksum_word = 0xEF;
247+
updater_spi_flash_read(IMG_UPDATE1_OFFSET_OLD, &image, sizeof(esp_image_header_t), true);
248+
249+
next_addr = IMG_UPDATE1_OFFSET_OLD + sizeof(esp_image_header_t);
250+
for(int i = 0; i < image.segment_count; i++) {
251+
esp_image_segment_header_t *header = &segments[i];
252+
253+
updater_spi_flash_read(next_addr, header, sizeof(esp_image_segment_header_t), true);
254+
const uint32_t *data = (const uint32_t *)bootloader_mmap(next_addr+sizeof(esp_image_segment_header_t), header->data_len);
255+
for (int i = 0; i < header->data_len; i += 4) {
256+
int w_i = i/4; // Word index
257+
uint32_t w = data[w_i];
258+
checksum_word ^= w;
259+
}
260+
261+
bootloader_munmap(data);
262+
263+
next_addr += sizeof(esp_image_segment_header_t);
264+
segment_data[i] = next_addr;
265+
next_addr += header->data_len;
266+
}
267+
268+
//unpadded_length = 1536*1024;
269+
unpadded_length = next_addr - IMG_UPDATE1_OFFSET_OLD;
270+
length = unpadded_length + 1; // Add a byte for the checksum
271+
length = (length + 15) & ~15; // Pad to next full 16 byte block
272+
printf("length: %u\n", length);
273+
274+
// Verify checksum
275+
uint8_t buf2[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
276+
updater_spi_flash_read(IMG_UPDATE1_OFFSET_OLD + unpadded_length, buf2, length - unpadded_length, true);
277+
278+
printf("length - unpadded_length - 1: %u\n", length - unpadded_length - 1);
279+
calc = buf2[length - unpadded_length - 1];
280+
printf("calc: 0x%X\n", calc);
281+
printf("checksum_word: 0x%X\n", checksum_word);
282+
checksum = (checksum_word >> 24)
283+
^ (checksum_word >> 16)
284+
^ (checksum_word >> 8)
285+
^ (checksum_word >> 0);
286+
printf("checksum of OTA_0: 0x%X\n", checksum);
287+
}
288+
289+
134290
bool updater_start (void) {
135291

136292
esp_err_t ret;
@@ -241,6 +397,31 @@ bool updater_write (uint8_t *buf, uint32_t len) {
241397
return true;
242398
}
243399

400+
bool updater_write_encrypt (uint8_t *buf, uint32_t len) {
401+
402+
// the actual writing into flash, not-encrypted,
403+
// because it already came encrypted from OTA server
404+
if (ESP_OK != updater_spi_flash_write(updater_data.offset, (void *)buf, len, true)) {
405+
ESP_LOGE(TAG, "SPI flash write failed\n");
406+
return false;
407+
}
408+
409+
updater_data.offset += len;
410+
updater_data.current_chunk += len;
411+
boot_info.size += len;
412+
413+
if (updater_data.current_chunk >= SPI_FLASH_SEC_SIZE) {
414+
updater_data.current_chunk -= SPI_FLASH_SEC_SIZE;
415+
// erase the next sector
416+
if (ESP_OK != spi_flash_erase_sector((updater_data.offset + SPI_FLASH_SEC_SIZE) / SPI_FLASH_SEC_SIZE)) {
417+
ESP_LOGE(TAG, "Erasing next sector failed!\n");
418+
return false;
419+
}
420+
}
421+
// sl_LockObjUnlock (&wlan_LockObj);
422+
return true;
423+
}
424+
244425
bool updater_finish (void) {
245426
if (updater_data.offset > 0) {
246427
ESP_LOGI(TAG, "Updater finished, boot status: %d\n", boot_info.Status);

0 commit comments

Comments
 (0)