From 1cde2f5f81dfcd0c0c515009687e27eb8cc5fdda Mon Sep 17 00:00:00 2001 From: Dong Heng Date: Tue, 19 Jun 2018 17:02:34 +0800 Subject: [PATCH] feat(bootloader): Add startup function --- .../subproject/main/esp8266.bootloader.ld | 2 +- .../include/esp_secure_boot.h | 14 ++- .../src/bootloader_utility.c | 17 ++- .../bootloader_support/src/esp_image_format.c | 108 +++++++++++------- components/esp8266/Makefile.projbuild | 4 +- components/esp8266/ld/esp8266.common.ld | 2 +- components/esp8266/lib/libcore.a | Bin 136058 -> 135622 bytes components/esp8266/source/startup.c | 35 ++++++ .../freertos/port/esp8266/xtensa_vectors.S | 12 -- 9 files changed, 129 insertions(+), 65 deletions(-) create mode 100644 components/esp8266/source/startup.c diff --git a/components/bootloader/subproject/main/esp8266.bootloader.ld b/components/bootloader/subproject/main/esp8266.bootloader.ld index cacb39c9..df37355d 100644 --- a/components/bootloader/subproject/main/esp8266.bootloader.ld +++ b/components/bootloader/subproject/main/esp8266.bootloader.ld @@ -16,7 +16,7 @@ MEMORY dram_seg : org = 0x3FFE8000, len = 0x18000 /* Functions which are critical should be put in this segment. */ - iram_seg : org = 0x40108000, len = 0x4000 + iram_seg : org = 0x40100000, len = 0xC000 } /* Default entry point: */ diff --git a/components/bootloader_support/include/esp_secure_boot.h b/components/bootloader_support/include/esp_secure_boot.h index 35dc8e9e..a24c3933 100644 --- a/components/bootloader_support/include/esp_secure_boot.h +++ b/components/bootloader_support/include/esp_secure_boot.h @@ -13,9 +13,13 @@ // limitations under the License. #pragma once +#include "sdkconfig.h" #include #include -//#include "soc/efuse_reg.h" + +#ifdef CONFIG_SECURE_BOOT_ENABLED + +#include "soc/efuse_reg.h" #ifdef __cplusplus extern "C" { @@ -34,9 +38,9 @@ extern "C" { * * @return true if secure boot is enabled. */ -//static inline bool esp_secure_boot_enabled(void) { -// return REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_ABS_DONE_0; -//} +static inline bool esp_secure_boot_enabled(void) { + return REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_ABS_DONE_0; +} /** @brief Enable secure boot if it is not already enabled. @@ -105,3 +109,5 @@ typedef struct { #ifdef __cplusplus } #endif + +#endif /* CONFIG_SECURE_BOOT_ENABLED */ diff --git a/components/bootloader_support/src/bootloader_utility.c b/components/bootloader_support/src/bootloader_utility.c index 64632d9a..4587f895 100644 --- a/components/bootloader_support/src/bootloader_utility.c +++ b/components/bootloader_support/src/bootloader_utility.c @@ -807,15 +807,20 @@ void bootloader_utility_load_image(const esp_image_metadata_t* image_data) } #endif -// ESP_LOGI(TAG, "Disabling RNG early entropy source..."); -// bootloader_random_disable(); - - // copy loaded segments to RAM, set up caches for mapped segments, and start application -// unpack_load_app(image_data); +#ifdef BOOTLOADER_UNPACK_APP + ESP_LOGI(TAG, "Disabling RNG early entropy source..."); + bootloader_random_disable(); + copy loaded segments to RAM, set up caches for mapped segments, and start application + unpack_load_app(image_data); +#else Cache_Read_Enable(0, 0, 0); - // ToDo: jump to application code. + void (*user_start)(void); + + user_start = (void *)image_data->image.entry_addr; + user_start(); +#endif /* BOOTLOADER_UNPACK_APP */ } #endif diff --git a/components/bootloader_support/src/esp_image_format.c b/components/bootloader_support/src/esp_image_format.c index bf4f91dd..e94cc8e7 100644 --- a/components/bootloader_support/src/esp_image_format.c +++ b/components/bootloader_support/src/esp_image_format.c @@ -341,7 +341,7 @@ static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, ui return ESP_FAIL; } -#ifdef BOOTLOADER_BUILD +#if defined(BOOTLOADER_BUILD) && defined(BOOTLOADER_UNPACK_APP) // Set up the obfuscation value to use for loading while (ram_obfs_value[0] == 0 || ram_obfs_value[1] == 0) { bootloader_fill_random(ram_obfs_value, sizeof(ram_obfs_value)); @@ -355,11 +355,12 @@ static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, ui int w_i = i/4; // Word index uint32_t w = src[w_i]; *checksum ^= w; -#ifdef BOOTLOADER_BUILD +#if defined(BOOTLOADER_BUILD) && defined(BOOTLOADER_UNPACK_APP) if (do_load) { dest[w_i] = w ^ ((w_i & 1) ? ram_obfs_value[0] : ram_obfs_value[1]); } #endif +#ifdef CONFIG_ENABLE_BOOT_CHECK_SHA256 // SHA_CHUNK determined experimentally as the optimum size // to call bootloader_sha256_data() with. This is a bit // counter-intuitive, but it's ~3ms better than using the @@ -369,6 +370,7 @@ static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, ui bootloader_sha256_data(sha_handle, &src[w_i], MIN(SHA_CHUNK, data_len - i)); } +#endif } bootloader_munmap(data); @@ -493,6 +495,7 @@ static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t static void debug_log_hash(const uint8_t *image_hash, const char *caption); +#ifdef CONFIG_SECURE_BOOT_ENABLED static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data) { uint8_t image_hash[HASH_LEN] = { 0 }; @@ -535,6 +538,7 @@ static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_han return ESP_OK; } +#endif /* CONFIG_SECURE_BOOT_ENABLED */ static esp_err_t verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data) { @@ -605,7 +609,7 @@ static const char *TAG = "esp_image"; /* Mmap source address mask */ #define MMAP_ALIGNED_MASK 0x0000FFFF -#ifdef BOOTLOADER_BUILD +#if defined(BOOTLOADER_BUILD) && defined(BOOTLOADER_UNPACK_APP) /* 64 bits of random data to obfuscate loaded RAM with, until verification is complete (Means loaded code isn't executable until after the secure boot check.) */ @@ -640,8 +644,10 @@ static esp_err_t verify_segment_header(int index, const esp_image_segment_header static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t checksum_word, esp_image_metadata_t *data); +#if defined(CONFIG_SECURE_BOOT_ENABLED) && defined(CONFIG_ENABLE_BOOT_CHECK_SHA256) static esp_err_t __attribute__((unused)) verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data); static esp_err_t __attribute__((unused)) verify_simple_hash(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data); +#endif esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t *part, esp_image_metadata_t *data) { @@ -678,14 +684,16 @@ esp_err_t esp_image_load(esp_image_load_mode_t mode, const esp_partition_pos_t * #ifdef CONFIG_SECURE_BOOT_ENABLED if (1) { #else -// if (data->image.hash_appended) { +#ifdef CONFIG_ENABLE_BOOT_CHECK_SHA256 + if (data->image.hash_appended) { + sha_handle = bootloader_sha256_start(); + if (sha_handle == NULL) { + return ESP_ERR_NO_MEM; + } + bootloader_sha256_data(sha_handle, &data->image, sizeof(esp_image_header_t)); + } +#endif #endif -// sha_handle = bootloader_sha256_start(); -// if (sha_handle == NULL) { -// return ESP_ERR_NO_MEM; -// } -// bootloader_sha256_data(sha_handle, &data->image, sizeof(esp_image_header_t)); -// } ESP_LOGD(TAG, "image header: 0x%02x 0x%02x 0x%02x 0x%02x %08x", data->image.magic, @@ -726,12 +734,16 @@ goto err; data->image_len = end_addr - data->start_addr; ESP_LOGV(TAG, "image start 0x%08x end of last section 0x%08x", data->start_addr, end_addr); -// if (!esp_cpu_in_ocd_debug_mode()) { +#ifdef CONFIG_ENABLE_BOOT_CHECK_OCD + if (!esp_cpu_in_ocd_debug_mode()) { +#endif err = verify_checksum(sha_handle, checksum_word, data); if (err != ESP_OK) { goto err; } -// } +#ifdef CONFIG_ENABLE_BOOT_CHECK_OCD + } +#endif if (data->image_len > part->size) { FAIL_LOAD("Image length %d doesn't fit in partition length %d", data->image_len, part->size); } @@ -747,10 +759,16 @@ goto err; // secure boot images have a signature appended err = verify_secure_boot_signature(sha_handle, data); #else +#ifdef CONFIG_ENABLE_BOOT_CHECK_SHA256 // No secure boot, but SHA-256 can be appended for basic corruption detection - if (sha_handle != NULL && !esp_cpu_in_ocd_debug_mode()) { + if (sha_handle != NULL +#ifdef CONFIG_ENABLE_BOOT_CHECK_OCD + && !esp_cpu_in_ocd_debug_mode() +#endif + ){ err = verify_simple_hash(sha_handle, data); } +#endif #endif // CONFIG_SECURE_BOOT_ENABLED } else { // is_bootloader // bootloader may still have a sha256 digest handle open @@ -763,14 +781,14 @@ goto err; goto err; } -#ifdef BOOTLOADER_BUILD +#if defined(BOOTLOADER_BUILD) && defined(BOOTLOADER_UNPACK_APP) if (do_load) { // Need to deobfuscate RAM for (int i = 0; i < data->image.segment_count; i++) { uint32_t load_addr = data->segments[i].load_addr; if (should_load(load_addr)) { uint32_t *loaded = (uint32_t *)load_addr; for (int j = 0; j < data->segments[i].data_len/sizeof(uint32_t); j++) { -// loaded[j] ^= (j & 1) ? ram_obfs_value[0] : ram_obfs_value[1]; + loaded[j] ^= (j & 1) ? ram_obfs_value[0] : ram_obfs_value[1]; } } } @@ -784,10 +802,12 @@ goto err; if (err == ESP_OK) { err = ESP_ERR_IMAGE_INVALID; } +#ifdef CONFIG_ENABLE_BOOT_CHECK_SHA256 if (sha_handle != NULL) { // Need to finish the hash process to free the handle bootloader_sha256_finish(sha_handle, NULL); } +#endif // Prevent invalid/incomplete data leaking out bzero(data, sizeof(esp_image_metadata_t)); return err; @@ -828,9 +848,11 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme ESP_LOGE(TAG, "bootloader_flash_read failed at 0x%08x", flash_addr); return err; } +#ifdef CONFIG_ENABLE_BOOT_CHECK_SHA256 if (sha_handle != NULL) { -// bootloader_sha256_data(sha_handle, header, sizeof(esp_image_segment_header_t)); + bootloader_sha256_data(sha_handle, header, sizeof(esp_image_segment_header_t)); } +#endif intptr_t load_addr = header->load_addr; uint32_t data_len = header->data_len; @@ -857,19 +879,21 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme (do_load)?"load":(is_mapping)?"map":""); } +#ifdef BOOTLOADER_UNPACK_APP if (do_load) { /* Before loading segment, check it doesn't clobber bootloader RAM... */ uint32_t end_addr = load_addr + data_len; if (end_addr < 0x40000000) { -// intptr_t sp = (intptr_t)get_sp(); -// if (end_addr > sp - STACK_LOAD_HEADROOM) { -// ESP_LOGE(TAG, "Segment %d end address 0x%08x too high (bootloader stack 0x%08x liimit 0x%08x)", -// index, end_addr, sp, sp - STACK_LOAD_HEADROOM); -// return ESP_ERR_IMAGE_INVALID; -// } + intptr_t sp = (intptr_t)get_sp(); + if (end_addr > sp - STACK_LOAD_HEADROOM) { + ESP_LOGE(TAG, "Segment %d end address 0x%08x too high (bootloader stack 0x%08x liimit 0x%08x)", + index, end_addr, sp, sp - STACK_LOAD_HEADROOM); + return ESP_ERR_IMAGE_INVALID; + } } } -#ifndef BOOTLOADER_BUILD +#endif +#if !defined(BOOTLOADER_BUILD) && defined(CONFIG_ENABLE_FLASH_MMAP) uint32_t free_page_count = spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_DATA); ESP_LOGD(TAG, "free data page_count 0x%08x",free_page_count); uint32_t offset_page = 0; @@ -906,11 +930,11 @@ static esp_err_t process_segment_data(intptr_t load_addr, uint32_t data_addr, ui return ESP_FAIL; } -#ifdef BOOTLOADER_BUILD +#if defined(BOOTLOADER_BUILD) && defined(BOOTLOADER_UNPACK_APP) // Set up the obfuscation value to use for loading -// while (ram_obfs_value[0] == 0 || ram_obfs_value[1] == 0) { -// bootloader_fill_random(ram_obfs_value, sizeof(ram_obfs_value)); -// } + while (ram_obfs_value[0] == 0 || ram_obfs_value[1] == 0) { + bootloader_fill_random(ram_obfs_value, sizeof(ram_obfs_value)); + } ram_obfs_value[0] = 0x55; ram_obfs_value[1] = 0xaa; uint32_t *dest = (uint32_t *)load_addr; @@ -1021,32 +1045,37 @@ static esp_err_t verify_checksum(bootloader_sha256_handle_t sha_handle, uint32_t ESP_LOGE(TAG, "Checksum failed. Calculated 0x%x read 0x%x", checksum, calc); return ESP_ERR_IMAGE_INVALID; } +#ifdef CONFIG_ENABLE_BOOT_CHECK_SHA256 if (sha_handle != NULL) { -// bootloader_sha256_data(sha_handle, buf, length - unpadded_length); + bootloader_sha256_data(sha_handle, buf, length - unpadded_length); } -// if (data->image.hash_appended) { -// // Account for the hash in the total image length -// length += HASH_LEN; -// } + if (data->image.hash_appended) { + // Account for the hash in the total image length + length += HASH_LEN; + } +#endif + data->image_len = length; return ESP_OK; } +#if defined(CONFIG_SECURE_BOOT_ENABLED) && defined(CONFIG_ENABLE_BOOT_CHECK_SHA256) + static void debug_log_hash(const uint8_t *image_hash, const char *caption); static esp_err_t verify_secure_boot_signature(bootloader_sha256_handle_t sha_handle, esp_image_metadata_t *data) { uint8_t image_hash[HASH_LEN] = { 0 }; -// // For secure boot, we calculate the signature hash over the whole file, which includes any "simple" hash -// // appended to the image for corruption detection -// if (data->image.hash_appended) { -// const void *simple_hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN); -// bootloader_sha256_data(sha_handle, simple_hash, HASH_LEN); -// bootloader_munmap(simple_hash); -// } + // For secure boot, we calculate the signature hash over the whole file, which includes any "simple" hash + // appended to the image for corruption detection + if (data->image.hash_appended) { + const void *simple_hash = bootloader_mmap(data->start_addr + data->image_len - HASH_LEN, HASH_LEN); + bootloader_sha256_data(sha_handle, simple_hash, HASH_LEN); + bootloader_munmap(simple_hash); + } bootloader_sha256_finish(sha_handle, image_hash); @@ -1119,5 +1148,6 @@ static void debug_log_hash(const uint8_t *image_hash, const char *label) ESP_LOGD(TAG, "%s: %s", label, hash_print); #endif } +#endif #endif diff --git a/components/esp8266/Makefile.projbuild b/components/esp8266/Makefile.projbuild index cbd82d7e..63ce43e8 100644 --- a/components/esp8266/Makefile.projbuild +++ b/components/esp8266/Makefile.projbuild @@ -4,11 +4,11 @@ BOOTLOADER_FIRMWARE_DIR := $(abspath $(COMPONENT_PATH))/firmware ESPTOOLPY_FLASHSIZE ?= $(CONFIG_ESPTOOLPY_FLASHSIZE) -ifeq ($(ESPTOOLPY_FLASHSIZE), "2MB-c1") +ifeq ($(ESPTOOLPY_FLASHSIZE), "2MB") ESP_INIT_DATA_DEFAULT_BIN_OFFSET := 0x1FC000 endif -ifeq ($(ESPTOOLPY_FLASHSIZE), "4MB-c1") +ifeq ($(ESPTOOLPY_FLASHSIZE), "4MB") ESP_INIT_DATA_DEFAULT_BIN_OFFSET := 0x3FC000 endif diff --git a/components/esp8266/ld/esp8266.common.ld b/components/esp8266/ld/esp8266.common.ld index 8dfc5644..5bd6239e 100644 --- a/components/esp8266/ld/esp8266.common.ld +++ b/components/esp8266/ld/esp8266.common.ld @@ -75,7 +75,7 @@ SECTIONS { _stext = .; _text_start = ABSOLUTE(.); - *(.UserEnter.text) + LONG(_text_start) . = ALIGN(16); *(.DebugExceptionVector.text) . = ALIGN(16); diff --git a/components/esp8266/lib/libcore.a b/components/esp8266/lib/libcore.a index 87de3b9a4ec82e8094ff37ba68289007bcf92203..fccfa601a3acb6e5861435b496d5871ac68b72ea 100644 GIT binary patch delta 52010 zcmb@vf1Flx{{Mf@)ih16tD1hO(2tpEs;OpbW-2C%X^c!H$w-KPsDwchLR=&1UArym zipg$vLso1{6t%Q#YSV^65<-#0J3p4Rm3B8>pU3^2=S%19cKiPKJ-1G;`|I&~yndY5 zIp=kqpL726$E;0{XDv7>b3nh6;{L_YYu}NeQ#Cs^D7(0 zW>&1K9=R@-<$Jm5bhCY4Dsj>Ksad1WO}>`ip6DGp_R5 zZcWV{UEKIGFLB(E)L%z;PR`2xOS<&&1w#^^xAo2Jo+YJ?yp!^Zzbl^n{Qi@kUej~K zirb2s4e~3NW=|WR@K=Y0&)=QDIjc zw>M-aycHiztr%RC$jnmeV=-@G%s;8`g4D&A+|q0|#ZXO$41ZSYqf0vYGgCia(y_zH z&o`;8nLiaZ+tkSG*^qN<{nXWi6D_7r?U(szs`%2jV?EFJvNg|DpG*(>g{nQT)%tx+ zOISnUy3zk{#=6Dwa}TC-3TqYHsaTT@4gGo+4$1Via{T>a3pT~HF276r-v`k|>e2h# zuiANOQI>yNDt_fDMME-F_O9ysOB+g`C_l9!@B9z*hLu(2PHxkoq%K|1y0l9p|1omr zZTP8VQL5(3ywq>5y!X^HFEO(5fuoaS*||H?W&VZ=FZbhgX@!^B%gbv~_K$_JO`W~m z?b?8(m3)xiaDJJ3ZgT6v{)egI6T2nf4N7b{nv*mAP+nty3(@fZk`3uZEbmOO%%9x4 zL&|}U&}ix5%XU~pWLcl-qM)=_n?ps{GamZ9GL zNNvA7mWZ9*_w>~NOg<%pZ8-JH*`(pS*fqC?iPFX&Q!~5R`~U) z*RMIfa?5Lve)zywcQ<|R-#5P5C}-F7SMNN!GuC!wvr%_7E^0o=Pt5jz2-^BZ`mmpq z&YpjM?w<6JR$lJs=|Ktq8P-TuJdyAR*kYJD;LW2$4#yRpm@Q~PUrWX?&bgWIQauWOT$nW>~xuFKDQ zDV^w0(7LQ|YSMKj$1io=s0OGf>Bd)ozv@rdz2f_eQ`g?m*?(x&uW#7YsL{Q#qp9kf zzKz}cuT>S(D>E{e?E3pXM~0>5&nRrV;iQJiJ9ZB7y;S{-uBlJ1%uIbdqer{i!lhgD z3Rm2z-fEVZc!_^?$!)o_#`~$l+j9L)tA^i}@1HT`IBhroVJY$oYx45EyqcO(BfZ>z zrSod8^A85y@I$&Zub`-z*8A4Nno-Su$|~8MyS-&N@T~gt?QLVHw4+>o#{E5g3H$LNNZP_)^*JKkJFjjrMy-DnR%n1JTK8~ zPJhpv|6WC7uXO3oQx<(!+Sq@w@7|KH)BA?EY`Z`6KL_@|J*GIlwBU?Uc|Q&QGM$(; zGCx0Y=Fr^w#$JyzE{|2^wteis6B7RJ3U69|ey_X!aCmb2iDDJ>_A^fx8E|Ku0vEzQdt+qU9R zL96wzrtChF6Pj(IWfgN0eSe_J&uxxI1c=DA;`%UTsB)GvwHoIc(=U!~jjX}rJL zag#eYp3~Y})$iW>V?ACvGC9^hcbhiIilsIF&Y(ZHrpsDtr=FAaKHH)M?Ozp3b5h^_ z&vpK$)TMKGHEB|D<`nHBsWawvzho9Uw8Q4)E!DsByq10vC9m*=7xVh$PD%SSiIy%s zqkG?+wx9Ugu1hAQD~i@$FeyELd^&erdfL()e>xr|m9?DQ`lOO^8WFVN)z8b16}3pc zJ-ywkqw^k#owBKy=l!r38CXmt5Xp+-P{dtYcAg`li*Kr^s7QUok?qKLxSDL!? z!4s2%4pki2tyMv{yrMZLs=#g|&w6p>fNm2m%xvfRpVQd3t&VJM=4q22)iGe_gd5m-YR0!ov(SNdd^DSIvVZDVr!Z7I_7EsW* zreTJe3MF}~719&g>T}|S3MsH$VUEIY6_zVp91r!C3MuD^#oH)?Ki|SB3Mpr=#fzJ% zv0hSpr}~+SycV8Ut>9ZlMk`#@DqNz&7S3oLRe?46y%0DGE^x64I@Jy6LB~E;i;CMkcMYm!~@e%Jk!OM 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 delta 51618 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 diff --git a/components/esp8266/source/startup.c b/components/esp8266/source/startup.c new file mode 100644 index 00000000..7fb364ee --- /dev/null +++ b/components/esp8266/source/startup.c @@ -0,0 +1,35 @@ + +#include "sdkconfig.h" +#include +#include +#include "esp_image_format.h" + +#define FLASH_MAP_ADDR 0x40200000 + +void call_user_start(void) +{ + int i; + extern void user_start(void); + + esp_image_header_t *head = (esp_image_header_t *)(FLASH_MAP_ADDR + CONFIG_PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET); + esp_image_segment_header_t *segment = (esp_image_segment_header_t *)((uintptr_t)head + sizeof(esp_image_header_t)); + + for (i = 0; i < 3; i++) { + segment = (esp_image_segment_header_t *)((uintptr_t)segment + sizeof(esp_image_segment_header_t) + segment->data_len); + + uint32_t *dest = (uint32_t *)segment->load_addr; + uint32_t *src = (uint32_t *)((uintptr_t)segment + sizeof(esp_image_segment_header_t)); + uint32_t size = segment->data_len / sizeof(uint32_t); + + while (size--) + *dest++ = *src++; + } + + __asm__ __volatile__( + "movi a2, 0x40100000\n" + "wsr a2, vecbase\n"); + + user_start(); +} + + \ No newline at end of file diff --git a/components/freertos/port/esp8266/xtensa_vectors.S b/components/freertos/port/esp8266/xtensa_vectors.S index 6e2983d4..5b6871c7 100644 --- a/components/freertos/port/esp8266/xtensa_vectors.S +++ b/components/freertos/port/esp8266/xtensa_vectors.S @@ -541,18 +541,6 @@ LoadStoreErrorHandler_common: rsr a1, excsave1 rfe - .section .UserEnter.text, "ax" - .global call_user_start - .type call_user_start,@function - .align 4 - .literal_position -vector_entr: - .word 0x40100000 -call_user_start: - l32r a2, 0x40100000 - wsr a2, vecbase - call0 user_start /* user exception handler */ - #if 0 /* Panic handler.