├── .gitmodules ├── Makefile ├── README.md ├── boot8266 ├── Makefile ├── boot8266.c ├── boot8266.ld ├── eagle.rom.addr.v6.ld ├── etshal.h ├── uart_register.h ├── unaligned_printf.c └── user_config.h ├── config.h.example ├── merge.py ├── ota-client ├── gen_keys.sh ├── ota_client.py └── rsa_sign.py └── ota-server ├── Makefile ├── ets_alt_task.c ├── ets_alt_task.h ├── main.c ├── ota.c ├── ota.ld └── user_config.h /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ota-server/lib/axtls"] 2 | path = ota-server/lib/axtls 3 | url = https://github.com/pfalcon/axtls 4 | branch = micropython 5 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | $(MAKE) -C boot8266 3 | $(MAKE) -C ota-server 4 | python merge.py -o yaota8266.bin boot8266/boot8266-0x00000.bin \ 5 | ota-server/ota.elf-0x00000.bin ota-server/ota.elf-0x09000.bin 6 | 7 | clean: 8 | $(MAKE) -C boot8266 clean 9 | $(MAKE) -C ota-server clean 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | yaota8266 2 | ========= 3 | 4 | yaota8266 is yet another bootloader/over-the-air (OTA) update solution 5 | for ESP8266 WiFi SoC. Unlike many other solutions, yaota8266 does not 6 | require reserving FlashROM space of 2x the size of the firmware. Instead, 7 | it updates the firmware in-place. Of course, this means that if an OTA 8 | update fails, there's no previous firmware to fallback to. On the other 9 | hand, if OTA update fails, you likely will repeat it again, until it 10 | succeeds. So, for many usecases the process of OTA update will be the 11 | same - a user will just repeat it until it succeeds, regardless whether 12 | there's a fallback firmware or not. 13 | 14 | yaota8266 is written with big firmwares and small flash sizes in mind. 15 | For example, it allows to have an OTA for full-fledged MicroPython 16 | (firmware sizes of 512+KB) on 1MB flash devices, and still have a 17 | small, but a filesystem. 18 | 19 | 20 | Structure and algorithm 21 | ----------------------- 22 | 23 | yaota8266 consists of two parts: 24 | 25 | * 2nd-stage bootloader boot8266 26 | * ota-server application 27 | 28 | boot8266 works in the following way: 29 | 30 | 1. 1st-stage bootloader in ESP8266 BootROM loads boot8266 (from sector 0). 31 | It is small and fits within a single FlashROM sector (4K). 32 | 2. boot8266 checks whether an OTA button on device is pressed. If 33 | it is, it goes in OTA mode. 34 | 3. If the button is not pressed, it verifies a checksum of a user 35 | application. If it fails (for example, because of unsuccessful, 36 | partial previous firmware update), it goes into OTA mode. 37 | 4. If OTA mode is requested, boot8266 loads an application starting 38 | at the sector 1. This is intended to be the ota-server, but from 39 | boot8266's point of view, it's just a standard ESP8266 application, 40 | which it loads recursively in the same (or very similar) way as 41 | BootROM does it. 42 | 5. If OTA mode was not requested, boot8266 loads a user application 43 | which lies beyond the ota-server application end (offset is 44 | configurable). The same note as above applies - boot8266 just loads 45 | one or another application in the same way, and doesn't care what 46 | they do (but boot8266 has partially hardcoded knowledge about sizes 47 | of these applications, and verifies checksum only of the second one). 48 | 49 | ota-server works in the following way: 50 | 51 | 1. Starts a UDP server on port 8266. 52 | 2. Expects consecutive UDP datagram containing chunks of new firmware. 53 | 3. Each datagram is signed with RSA private key. Only someone with 54 | a valid private key may produce valid datagrams, information from 55 | which ota-server will flash as a user application. (The public key 56 | is configured when building ota-server.) 57 | 4. ota-client host-side application is provided to drive OTA upgrade 58 | process for a device in OTA mode. 59 | 60 | Known issues 61 | ------------ 62 | 63 | yaota8266 is a work in progress and is not yet fully working per the 64 | spec above. 65 | -------------------------------------------------------------------------------- /boot8266/Makefile: -------------------------------------------------------------------------------- 1 | CC = xtensa-lx106-elf-gcc 2 | # -O0 is mandatory, anything else will break inline asm 3 | CFLAGS = -O0 -I. -mlongcalls -ffunction-sections -fdata-sections 4 | LDLIBS = -nostdlib -lgcc 5 | LDFLAGS = -T./boot8266.ld -e start -Wl,-Map=$@.map -Wl,--cref 6 | 7 | boot8266-0x00000.bin: boot8266 8 | esptool.py elf2image $^ 9 | 10 | boot8266: boot8266.o unaligned_printf.o 11 | 12 | boot8266.o: boot8266.c 13 | unaligned_printf.o: unaligned_printf.c 14 | 15 | # Force re-link if .ld is updated 16 | boot8266.o: boot8266.ld 17 | 18 | flash: boot8266-0x00000.bin 19 | esptool.py write_flash 0 $^ 20 | 21 | clean: 22 | rm -f boot8266 *.o boot8266-0x* 23 | -------------------------------------------------------------------------------- /boot8266/boot8266.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the yaota8266 project. 3 | * 4 | * The MIT License (MIT) 5 | * 6 | * Copyright (c) 2016 Paul Sokolovsky 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | #include 27 | 28 | #include "ets_sys.h" 29 | #include "user_interface.h" 30 | #include "gpio.h" 31 | #include "uart_register.h" 32 | #include "etshal.h" 33 | #include "../config.h" 34 | 35 | uint32_t SPIRead(uint32_t offset, void *buf, uint32_t len); 36 | uint32_t SPIWrite(uint32_t offset, const void *buf, uint32_t len); 37 | void _printf(const char *, ...); 38 | 39 | #define CPU_TICKS_PER_MS 80000 40 | #define UART0 0 41 | #define RTCMEM_BASE 0x60001000 42 | #define RTCMEM_SYSTEM (RTCMEM_BASE + 0x100) 43 | // "reset info" prepared by vendor SDK is at the start of RTC memory 44 | // ref: 0x402525a7 (main_sdk_init2+0x11f) 45 | #define rtc_rst_info ((struct rst_info*)RTCMEM_SYSTEM) 46 | 47 | #define CONFIG_PARAM __attribute__((section(".param"))) 48 | 49 | CONFIG_PARAM uint32_t gpio_mask = GPIO_MASK; 50 | CONFIG_PARAM uint32_t gpio_wait_ms = GPIO_WAIT_MS; 51 | 52 | __attribute__((always_inline)) static inline uint32_t ticks_cpu(void) { 53 | uint32_t ccount; 54 | __asm__ __volatile__("rsr %0,ccount":"=a" (ccount)); 55 | return ccount; 56 | } 57 | 58 | struct flash_header { 59 | uint8_t sig; 60 | uint8_t num; 61 | uint8_t par1; 62 | uint8_t par2; 63 | uint32_t start; 64 | }; 65 | 66 | struct sect_header { 67 | void *addr; 68 | uint32_t size; 69 | }; 70 | 71 | // Return true if OTA should start 72 | bool check_buttons(void) 73 | { 74 | // If gpio_mask is empty, enter OTA unconditionally. 75 | if (!gpio_mask) { 76 | return true; 77 | } 78 | 79 | gpio_init(); 80 | 81 | PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0); 82 | PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO0_U); 83 | 84 | uint32_t gpio_ini = gpio_input_get(); 85 | _printf("Initial GPIO state: %x, OE: %x\n", gpio_ini, *(uint32_t*)0x60000314); 86 | gpio_ini &= gpio_mask; 87 | 88 | bool ota = false; 89 | int ms_delay = gpio_wait_ms; 90 | uint32_t ticks = ticks_cpu(); 91 | while (ms_delay) { 92 | uint32_t gpio_last = gpio_input_get() & gpio_mask; 93 | if (gpio_last != gpio_ini) { 94 | _printf("GPIO changed: %x\n", gpio_last); 95 | ota = true; 96 | break; 97 | } 98 | if (ticks_cpu() - ticks > CPU_TICKS_PER_MS) { 99 | ms_delay--; 100 | ticks += CPU_TICKS_PER_MS; 101 | } 102 | //system_soft_wdt_feed(); 103 | } 104 | 105 | return ota; 106 | } 107 | 108 | extern char _bss_end; 109 | 110 | bool check_main_app(void) 111 | { 112 | //_printf("check_main_app\n"); 113 | MD5_CTX ctx; 114 | MD5Init(&ctx); 115 | 116 | uint32_t off = MAIN_APP_OFFSET; 117 | uint32_t sz = 0; 118 | SPIRead(MAIN_APP_OFFSET + 0x8ffc, &sz, sizeof(sz)); 119 | if (sz > 800000) { 120 | _printf("Invalid main app size: %u\n", sz); 121 | return false; 122 | } 123 | 124 | while (sz != 0) { 125 | int chunk_sz = sz > 4096 ? 4096 : sz; 126 | SPIRead(off, &_bss_end, chunk_sz); 127 | if (off == MAIN_APP_OFFSET) { 128 | // MicroPython's makeimg.py skips first 4 bytes 129 | MD5Update(&ctx, &_bss_end + 4, chunk_sz - 4); 130 | } else { 131 | MD5Update(&ctx, &_bss_end, chunk_sz); 132 | } 133 | sz -= chunk_sz; 134 | off += chunk_sz; 135 | } 136 | 137 | unsigned char digest1[16]; 138 | SPIRead(off, digest1, sizeof(digest1)); 139 | unsigned char digest2[16]; 140 | MD5Final(digest2, &ctx); 141 | 142 | return memcmp(digest1, digest2, sizeof(digest1)) == 0; 143 | } 144 | 145 | void uart_flush(uint8 uart) { 146 | while (true) { 147 | uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT<> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) == 0) { 149 | break; 150 | } 151 | } 152 | } 153 | 154 | void start() 155 | { 156 | uint32_t offset = MAIN_APP_OFFSET; 157 | 158 | // If it's wake from deepsleep, boot main app ASAP 159 | if (rtc_rst_info->reason == REASON_DEEP_SLEEP_AWAKE) { 160 | goto boot; 161 | } 162 | 163 | #if BAUD_RATE 164 | uart_flush(UART0); 165 | // At this point, hardware doesn't yet know that it runs with 26MHz 166 | // crystal oscillator instead of "default" 40MHz, so adjust baud rate 167 | // accordingly. 168 | uart_div_modify(UART0, UART_CLK_FREQ / (BAUD_RATE * 40 / 26)); 169 | #endif 170 | 171 | memset((void*)0x3ffe8000, 0, 0x3fffc000 - 0x3ffe8000); 172 | 173 | _printf("\n\nboot8266\n"); 174 | 175 | _printf("HW RTC Reset reason: %d\n", rtc_get_reset_reason()); 176 | _printf("System reset reason: %d\n", rtc_rst_info->reason); 177 | 178 | bool ota = check_buttons(); 179 | 180 | if (!ota) { 181 | if (!check_main_app()) { 182 | ota = true; 183 | } 184 | } 185 | 186 | if (ota) { 187 | _printf("Running OTA\n"); 188 | offset = 0x1000; 189 | } else { 190 | _printf("Running app\n"); 191 | } 192 | 193 | union { 194 | struct flash_header flash; 195 | struct sect_header sect; 196 | } hdr; 197 | 198 | boot: 199 | SPIRead(offset, &hdr.flash, sizeof(hdr.flash)); 200 | offset += sizeof(hdr.flash); 201 | 202 | register uint32_t start = hdr.flash.start; 203 | int num = hdr.flash.num; 204 | 205 | register uint32_t iram_offset = 0; 206 | register void *iram_addr = NULL; 207 | register uint32_t iram_size = 0; 208 | 209 | // Any _printf() beyond this point may (will) corrupt memory 210 | while (num--) { 211 | SPIRead(offset, &hdr.sect, sizeof(hdr.sect)); 212 | offset += sizeof(hdr.sect); 213 | //_printf("off: %x addr: %x size: %x\n", offset, hdr.sect.addr, hdr.sect.size); 214 | if (hdr.sect.addr >= (void*)0x40100000 && hdr.sect.addr < (void*)0x40108000) { 215 | //_printf("skip iram\n"); 216 | iram_offset = offset; 217 | iram_addr = hdr.sect.addr; 218 | iram_size = hdr.sect.size; 219 | } else { 220 | //_printf("load\n"); 221 | SPIRead(offset, hdr.sect.addr, hdr.sect.size); 222 | } 223 | offset += hdr.sect.size; 224 | } 225 | 226 | //_printf("iram: %x %p %x s: %x\n", iram_offset, iram_addr, iram_size, start); 227 | 228 | asm volatile ("mov a5, %0" : : "r" (SPIRead)); 229 | asm volatile ("mov a0, %0" : : "r" (start)); 230 | asm volatile ("mov a3, %0" : : "r" (iram_addr)); 231 | asm volatile ("mov a4, %0" : : "r" (iram_size)); 232 | asm volatile ("mov a1, %0" : : "r" (0x40000000)); 233 | asm volatile ("mov a2, %0" : : "r" (iram_offset)); 234 | asm volatile ("jx a5\n"); 235 | } 236 | -------------------------------------------------------------------------------- /boot8266/boot8266.ld: -------------------------------------------------------------------------------- 1 | /* This linker script generated from xt-genldscripts.tpp for LSP . */ 2 | /* Linker Script for ld -N */ 3 | MEMORY 4 | { 5 | dport0_0_seg : org = 0x3FF00000, len = 0x10 6 | dram0_0_seg : org = 0x3FFE8000, len = 0x14000 7 | iram1_0_seg : org = 0x40100000, len = 0x8000 8 | irom0_0_seg : org = 0x40210000, len = 0x5C000 9 | } 10 | 11 | PHDRS 12 | { 13 | dport0_0_phdr PT_LOAD; 14 | dram0_0_phdr PT_LOAD; 15 | dram0_0_bss_phdr PT_LOAD; 16 | iram1_0_phdr PT_LOAD; 17 | irom0_0_phdr PT_LOAD; 18 | } 19 | 20 | 21 | /* Default entry point: */ 22 | ENTRY(call_user_start) 23 | EXTERN(_DebugExceptionVector) 24 | EXTERN(_DoubleExceptionVector) 25 | EXTERN(_KernelExceptionVector) 26 | EXTERN(_NMIExceptionVector) 27 | EXTERN(_UserExceptionVector) 28 | PROVIDE(_memmap_vecbase_reset = 0x40000000); 29 | /* Various memory-map dependent cache attribute settings: */ 30 | _memmap_cacheattr_wb_base = 0x00000110; 31 | _memmap_cacheattr_wt_base = 0x00000110; 32 | _memmap_cacheattr_bp_base = 0x00000220; 33 | _memmap_cacheattr_unused_mask = 0xFFFFF00F; 34 | _memmap_cacheattr_wb_trapnull = 0x2222211F; 35 | _memmap_cacheattr_wba_trapnull = 0x2222211F; 36 | _memmap_cacheattr_wbna_trapnull = 0x2222211F; 37 | _memmap_cacheattr_wt_trapnull = 0x2222211F; 38 | _memmap_cacheattr_bp_trapnull = 0x2222222F; 39 | _memmap_cacheattr_wb_strict = 0xFFFFF11F; 40 | _memmap_cacheattr_wt_strict = 0xFFFFF11F; 41 | _memmap_cacheattr_bp_strict = 0xFFFFF22F; 42 | _memmap_cacheattr_wb_allvalid = 0x22222112; 43 | _memmap_cacheattr_wt_allvalid = 0x22222112; 44 | _memmap_cacheattr_bp_allvalid = 0x22222222; 45 | PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull); 46 | 47 | SECTIONS 48 | { 49 | 50 | .dport0.rodata : ALIGN(4) 51 | { 52 | _dport0_rodata_start = ABSOLUTE(.); 53 | *(.dport0.rodata) 54 | *(.dport.rodata) 55 | _dport0_rodata_end = ABSOLUTE(.); 56 | } >dport0_0_seg :dport0_0_phdr 57 | 58 | .dport0.literal : ALIGN(4) 59 | { 60 | _dport0_literal_start = ABSOLUTE(.); 61 | *(.dport0.literal) 62 | *(.dport.literal) 63 | _dport0_literal_end = ABSOLUTE(.); 64 | } >dport0_0_seg :dport0_0_phdr 65 | 66 | .dport0.data : ALIGN(4) 67 | { 68 | _dport0_data_start = ABSOLUTE(.); 69 | *(.dport0.data) 70 | *(.dport.data) 71 | _dport0_data_end = ABSOLUTE(.); 72 | } >dport0_0_seg :dport0_0_phdr 73 | 74 | .data : ALIGN(4) 75 | { 76 | _data_start = ABSOLUTE(.); 77 | *(.data) 78 | *(.data.*) 79 | *(.gnu.linkonce.d.*) 80 | *(.data1) 81 | *(.sdata) 82 | *(.sdata.*) 83 | *(.gnu.linkonce.s.*) 84 | *(.sdata2) 85 | *(.sdata2.*) 86 | *(.gnu.linkonce.s2.*) 87 | *(.jcr) 88 | _data_end = ABSOLUTE(.); 89 | } >dram0_0_seg :dram0_0_phdr 90 | 91 | .rodata : ALIGN(4) 92 | { 93 | _rodata_start = ABSOLUTE(.); 94 | *(.sdk.version) 95 | /* *(.rodata) 96 | *(.rodata.*)*/ 97 | *(.gnu.linkonce.r.*) 98 | *(.rodata1) 99 | __XT_EXCEPTION_TABLE__ = ABSOLUTE(.); 100 | *(.xt_except_table) 101 | *(.gcc_except_table) 102 | *(.gnu.linkonce.e.*) 103 | *(.gnu.version_r) 104 | *(.eh_frame) 105 | /* C++ constructor and destructor tables, properly ordered: */ 106 | KEEP (*crtbegin.o(.ctors)) 107 | KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) 108 | KEEP (*(SORT(.ctors.*))) 109 | KEEP (*(.ctors)) 110 | KEEP (*crtbegin.o(.dtors)) 111 | KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) 112 | KEEP (*(SORT(.dtors.*))) 113 | KEEP (*(.dtors)) 114 | /* C++ exception handlers table: */ 115 | __XT_EXCEPTION_DESCS__ = ABSOLUTE(.); 116 | *(.xt_except_desc) 117 | *(.gnu.linkonce.h.*) 118 | __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); 119 | *(.xt_except_desc_end) 120 | *(.dynamic) 121 | *(.gnu.version_d) 122 | . = ALIGN(4); /* this table MUST be 4-byte aligned */ 123 | _bss_table_start = ABSOLUTE(.); 124 | /* LONG(_bss_start) 125 | LONG(_bss_end)*/ 126 | _bss_table_end = ABSOLUTE(.); 127 | _rodata_end = ABSOLUTE(.); 128 | } >dram0_0_seg :dram0_0_phdr 129 | 130 | .bss ALIGN(8) (NOLOAD) : ALIGN(4) 131 | { 132 | . = ALIGN (8); 133 | _bss_start = ABSOLUTE(.); 134 | *(.dynsbss) 135 | *(.sbss) 136 | *(.sbss.*) 137 | *(.gnu.linkonce.sb.*) 138 | *(.scommon) 139 | *(.sbss2) 140 | *(.sbss2.*) 141 | *(.gnu.linkonce.sb2.*) 142 | *(.dynbss) 143 | *(.bss) 144 | *(.bss.*) 145 | *(.gnu.linkonce.b.*) 146 | *(COMMON) 147 | . = ALIGN (8); 148 | _bss_end = ABSOLUTE(.); 149 | _heap_start = ABSOLUTE(.); 150 | /* _stack_sentry = ALIGN(0x8); */ 151 | } >dram0_0_seg :dram0_0_bss_phdr 152 | /* __stack = 0x3ffc8000; */ 153 | 154 | .irom0.text : ALIGN(4) 155 | { 156 | _irom0_text_start = ABSOLUTE(.); 157 | 158 | *libmbedtls.a:(.literal .text .literal.* .text.*) 159 | 160 | *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text) 161 | _irom0_text_end = ABSOLUTE(.); 162 | } >irom0_0_seg :irom0_0_phdr 163 | 164 | .text : ALIGN(4) 165 | { 166 | _stext = .; 167 | _text_start = ABSOLUTE(.); 168 | *(.UserEnter.text) 169 | . = ALIGN(16); 170 | *(.DebugExceptionVector.text) 171 | . = ALIGN(16); 172 | *(.NMIExceptionVector.text) 173 | . = ALIGN(16); 174 | *(.KernelExceptionVector.text) 175 | LONG(0) 176 | LONG(0) 177 | LONG(0) 178 | LONG(0) 179 | . = ALIGN(16); 180 | *(.UserExceptionVector.text) 181 | LONG(0) 182 | LONG(0) 183 | LONG(0) 184 | LONG(0) 185 | . = ALIGN(16); 186 | *(.DoubleExceptionVector.text) 187 | LONG(0) 188 | LONG(0) 189 | LONG(0) 190 | LONG(0) 191 | . = ALIGN (16); 192 | *(.entry.text) 193 | *(.init.literal) 194 | *(.init) 195 | *(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) 196 | *(.fini.literal) 197 | *(.fini) 198 | *(.gnu.version) 199 | 200 | /* Store strings, etc. in the iRAM alongside the code. */ 201 | *(.rodata) 202 | *(.rodata.*) 203 | 204 | _text_end = ABSOLUTE(.); 205 | _etext = .; 206 | 207 | . = (. & ~ 0xfff) + 0xf00 - 0x10 /*size of boot header*/; 208 | *(.param) 209 | /* Make image exactly the sector size */ 210 | . = (. & ~ 0xfff) + 0xfe4; 211 | 212 | } >iram1_0_seg :iram1_0_phdr =0xff 213 | 214 | .lit4 : ALIGN(4) 215 | { 216 | _lit4_start = ABSOLUTE(.); 217 | *(*.lit4) 218 | *(.lit4.*) 219 | *(.gnu.linkonce.lit4.*) 220 | _lit4_end = ABSOLUTE(.); 221 | } >iram1_0_seg :iram1_0_phdr 222 | } 223 | 224 | /* get ROM code address */ 225 | INCLUDE "eagle.rom.addr.v6.ld" 226 | -------------------------------------------------------------------------------- /boot8266/eagle.rom.addr.v6.ld: -------------------------------------------------------------------------------- 1 | PROVIDE ( Cache_Read_Disable = 0x400047f0 ); 2 | PROVIDE ( Cache_Read_Enable = 0x40004678 ); 3 | PROVIDE ( FilePacketSendReqMsgProc = 0x400035a0 ); 4 | PROVIDE ( FlashDwnLdParamCfgMsgProc = 0x4000368c ); 5 | PROVIDE ( FlashDwnLdStartMsgProc = 0x40003538 ); 6 | PROVIDE ( FlashDwnLdStopReqMsgProc = 0x40003658 ); 7 | PROVIDE ( GetUartDevice = 0x40003f4c ); 8 | PROVIDE ( MD5Final = 0x40009900 ); 9 | PROVIDE ( MD5Init = 0x40009818 ); 10 | PROVIDE ( MD5Update = 0x40009834 ); 11 | PROVIDE ( MemDwnLdStartMsgProc = 0x400036c4 ); 12 | PROVIDE ( MemDwnLdStopReqMsgProc = 0x4000377c ); 13 | PROVIDE ( MemPacketSendReqMsgProc = 0x400036f0 ); 14 | PROVIDE ( RcvMsg = 0x40003eac ); 15 | PROVIDE ( SHA1Final = 0x4000b648 ); 16 | PROVIDE ( SHA1Init = 0x4000b584 ); 17 | PROVIDE ( SHA1Transform = 0x4000a364 ); 18 | PROVIDE ( SHA1Update = 0x4000b5a8 ); 19 | PROVIDE ( SPI_read_status = 0x400043c8 ); 20 | PROVIDE ( SPI_write_status = 0x40004400 ); 21 | PROVIDE ( SPI_write_enable = 0x4000443c ); 22 | PROVIDE ( Wait_SPI_Idle = 0x4000448c ); 23 | PROVIDE ( Enable_QMode = 0x400044c0 ); 24 | PROVIDE ( SPIEraseArea = 0x40004b44 ); 25 | PROVIDE ( SPIEraseBlock = 0x400049b4 ); 26 | PROVIDE ( SPIEraseChip = 0x40004984 ); 27 | PROVIDE ( SPIEraseSector = 0x40004a00 ); 28 | PROVIDE ( SPILock = 0x400048a8 ); 29 | PROVIDE ( SPIParamCfg = 0x40004c2c ); 30 | PROVIDE ( SPIRead = 0x40004b1c ); 31 | PROVIDE ( SPIReadModeCnfig = 0x400048ec ); 32 | PROVIDE ( SPIUnlock = 0x40004878 ); 33 | PROVIDE ( SPIWrite = 0x40004a4c ); 34 | PROVIDE ( SelectSpiFunction = 0x40003f58 ); 35 | PROVIDE ( SendMsg = 0x40003cf4 ); 36 | PROVIDE ( UartConnCheck = 0x40003230 ); 37 | PROVIDE ( UartConnectProc = 0x400037a0 ); 38 | PROVIDE ( UartDwnLdProc = 0x40003368 ); 39 | PROVIDE ( UartGetCmdLn = 0x40003ef4 ); 40 | PROVIDE ( UartRegReadProc = 0x4000381c ); 41 | PROVIDE ( UartRegWriteProc = 0x400037ac ); 42 | PROVIDE ( UartRxString = 0x40003c30 ); 43 | PROVIDE ( Uart_Init = 0x40003a14 ); 44 | PROVIDE ( _DebugExceptionVector = 0x40000010 ); 45 | PROVIDE ( _DoubleExceptionVector = 0x40000070 ); 46 | PROVIDE ( _KernelExceptionVector = 0x40000030 ); 47 | PROVIDE ( _NMIExceptionVector = 0x40000020 ); 48 | PROVIDE ( _ResetHandler = 0x400000a4 ); 49 | PROVIDE ( _ResetVector = 0x40000080 ); 50 | PROVIDE ( _UserExceptionVector = 0x40000050 ); 51 | PROVIDE ( __adddf3 = 0x4000c538 ); 52 | PROVIDE ( __addsf3 = 0x4000c180 ); 53 | PROVIDE ( __divdf3 = 0x4000cb94 ); 54 | PROVIDE ( __divdi3 = 0x4000ce60 ); 55 | PROVIDE ( __divsi3 = 0x4000dc88 ); 56 | PROVIDE ( __extendsfdf2 = 0x4000cdfc ); 57 | PROVIDE ( __fixdfsi = 0x4000ccb8 ); 58 | PROVIDE ( __fixunsdfsi = 0x4000cd00 ); 59 | PROVIDE ( __fixunssfsi = 0x4000c4c4 ); 60 | PROVIDE ( __floatsidf = 0x4000e2f0 ); 61 | PROVIDE ( __floatsisf = 0x4000e2ac ); 62 | PROVIDE ( __floatunsidf = 0x4000e2e8 ); 63 | PROVIDE ( __floatunsisf = 0x4000e2a4 ); 64 | PROVIDE ( __muldf3 = 0x4000c8f0 ); 65 | PROVIDE ( __muldi3 = 0x40000650 ); 66 | PROVIDE ( __mulsf3 = 0x4000c3dc ); 67 | PROVIDE ( __subdf3 = 0x4000c688 ); 68 | PROVIDE ( __subsf3 = 0x4000c268 ); 69 | PROVIDE ( __truncdfsf2 = 0x4000cd5c ); 70 | PROVIDE ( __udivdi3 = 0x4000d310 ); 71 | PROVIDE ( __udivsi3 = 0x4000e21c ); 72 | PROVIDE ( __umoddi3 = 0x4000d770 ); 73 | PROVIDE ( __umodsi3 = 0x4000e268 ); 74 | PROVIDE ( __umulsidi3 = 0x4000dcf0 ); 75 | PROVIDE ( _rom_store = 0x4000e388 ); 76 | PROVIDE ( _rom_store_table = 0x4000e328 ); 77 | PROVIDE ( _start = 0x4000042c ); 78 | PROVIDE ( _xtos_alloca_handler = 0x4000dbe0 ); 79 | PROVIDE ( _xtos_c_wrapper_handler = 0x40000598 ); 80 | PROVIDE ( _xtos_cause3_handler = 0x40000590 ); 81 | PROVIDE ( _xtos_ints_off = 0x4000bda4 ); 82 | PROVIDE ( _xtos_ints_on = 0x4000bd84 ); 83 | PROVIDE ( _xtos_l1int_handler = 0x4000048c ); 84 | PROVIDE ( _xtos_p_none = 0x4000dbf8 ); 85 | PROVIDE ( _xtos_restore_intlevel = 0x4000056c ); 86 | PROVIDE ( _xtos_return_from_exc = 0x4000dc54 ); 87 | PROVIDE ( _xtos_set_exception_handler = 0x40000454 ); 88 | PROVIDE ( _xtos_set_interrupt_handler = 0x4000bd70 ); 89 | PROVIDE ( _xtos_set_interrupt_handler_arg = 0x4000bd28 ); 90 | PROVIDE ( _xtos_set_intlevel = 0x4000dbfc ); 91 | PROVIDE ( _xtos_set_min_intlevel = 0x4000dc18 ); 92 | PROVIDE ( _xtos_set_vpri = 0x40000574 ); 93 | PROVIDE ( _xtos_syscall_handler = 0x4000dbe4 ); 94 | PROVIDE ( _xtos_unhandled_exception = 0x4000dc44 ); 95 | PROVIDE ( _xtos_unhandled_interrupt = 0x4000dc3c ); 96 | PROVIDE ( aes_decrypt = 0x400092d4 ); 97 | PROVIDE ( aes_decrypt_deinit = 0x400092e4 ); 98 | PROVIDE ( aes_decrypt_init = 0x40008ea4 ); 99 | PROVIDE ( aes_unwrap = 0x40009410 ); 100 | PROVIDE ( base64_decode = 0x40009648 ); 101 | PROVIDE ( base64_encode = 0x400094fc ); 102 | PROVIDE ( bzero = 0x4000de84 ); 103 | PROVIDE ( cmd_parse = 0x40000814 ); 104 | PROVIDE ( conv_str_decimal = 0x40000b24 ); 105 | PROVIDE ( conv_str_hex = 0x40000cb8 ); 106 | PROVIDE ( convert_para_str = 0x40000a60 ); 107 | PROVIDE ( dtm_get_intr_mask = 0x400026d0 ); 108 | PROVIDE ( dtm_params_init = 0x4000269c ); 109 | PROVIDE ( dtm_set_intr_mask = 0x400026c8 ); 110 | PROVIDE ( dtm_set_params = 0x400026dc ); 111 | PROVIDE ( eprintf = 0x40001d14 ); 112 | PROVIDE ( eprintf_init_buf = 0x40001cb8 ); 113 | PROVIDE ( eprintf_to_host = 0x40001d48 ); 114 | PROVIDE ( est_get_printf_buf_remain_len = 0x40002494 ); 115 | PROVIDE ( est_reset_printf_buf_len = 0x4000249c ); 116 | PROVIDE ( ets_bzero = 0x40002ae8 ); 117 | PROVIDE ( ets_char2xdigit = 0x40002b74 ); 118 | PROVIDE ( ets_delay_us = 0x40002ecc ); 119 | PROVIDE ( ets_enter_sleep = 0x400027b8 ); 120 | PROVIDE ( ets_external_printf = 0x40002578 ); 121 | PROVIDE ( ets_get_cpu_frequency = 0x40002f0c ); 122 | PROVIDE ( ets_getc = 0x40002bcc ); 123 | PROVIDE ( ets_install_external_printf = 0x40002450 ); 124 | PROVIDE ( ets_install_putc1 = 0x4000242c ); 125 | PROVIDE ( ets_install_putc2 = 0x4000248c ); 126 | PROVIDE ( ets_install_uart_printf = 0x40002438 ); 127 | PROVIDE ( ets_intr_lock = 0x40000f74 ); 128 | PROVIDE ( ets_intr_unlock = 0x40000f80 ); 129 | PROVIDE ( ets_isr_attach = 0x40000f88 ); 130 | PROVIDE ( ets_isr_mask = 0x40000f98 ); 131 | PROVIDE ( ets_isr_unmask = 0x40000fa8 ); 132 | PROVIDE ( ets_memcmp = 0x400018d4 ); 133 | PROVIDE ( ets_memcpy = 0x400018b4 ); 134 | PROVIDE ( ets_memmove = 0x400018c4 ); 135 | PROVIDE ( ets_memset = 0x400018a4 ); 136 | PROVIDE ( ets_post = 0x40000e24 ); 137 | PROVIDE ( ets_printf = 0x400024cc ); 138 | PROVIDE ( ets_putc = 0x40002be8 ); 139 | PROVIDE ( ets_rtc_int_register = 0x40002a40 ); 140 | PROVIDE ( ets_run = 0x40000e04 ); 141 | PROVIDE ( ets_set_idle_cb = 0x40000dc0 ); 142 | PROVIDE ( ets_set_user_start = 0x40000fbc ); 143 | PROVIDE ( ets_str2macaddr = 0x40002af8 ); 144 | PROVIDE ( ets_strcmp = 0x40002aa8 ); 145 | PROVIDE ( ets_strcpy = 0x40002a88 ); 146 | PROVIDE ( ets_strlen = 0x40002ac8 ); 147 | PROVIDE ( ets_strncmp = 0x40002ab8 ); 148 | PROVIDE ( ets_strncpy = 0x40002a98 ); 149 | PROVIDE ( ets_strstr = 0x40002ad8 ); 150 | PROVIDE ( ets_task = 0x40000dd0 ); 151 | PROVIDE ( ets_timer_arm = 0x40002cc4 ); 152 | PROVIDE ( ets_timer_disarm = 0x40002d40 ); 153 | PROVIDE ( ets_timer_done = 0x40002d80 ); 154 | PROVIDE ( ets_timer_handler_isr = 0x40002da8 ); 155 | PROVIDE ( ets_timer_init = 0x40002e68 ); 156 | PROVIDE ( ets_timer_setfn = 0x40002c48 ); 157 | PROVIDE ( ets_uart_printf = 0x40002544 ); 158 | PROVIDE ( ets_update_cpu_frequency = 0x40002f04 ); 159 | PROVIDE ( ets_vprintf = 0x40001f00 ); 160 | PROVIDE ( ets_wdt_disable = 0x400030f0 ); 161 | PROVIDE ( ets_wdt_enable = 0x40002fa0 ); 162 | PROVIDE ( ets_wdt_get_mode = 0x40002f34 ); 163 | PROVIDE ( ets_wdt_init = 0x40003170 ); 164 | PROVIDE ( ets_wdt_restore = 0x40003158 ); 165 | PROVIDE ( ets_write_char = 0x40001da0 ); 166 | PROVIDE ( get_first_seg = 0x4000091c ); 167 | PROVIDE ( gpio_init = 0x40004c50 ); 168 | PROVIDE ( gpio_input_get = 0x40004cf0 ); 169 | PROVIDE ( gpio_intr_ack = 0x40004dcc ); 170 | PROVIDE ( gpio_intr_handler_register = 0x40004e28 ); 171 | PROVIDE ( gpio_intr_pending = 0x40004d88 ); 172 | PROVIDE ( gpio_intr_test = 0x40004efc ); 173 | PROVIDE ( gpio_output_set = 0x40004cd0 ); 174 | PROVIDE ( gpio_pin_intr_state_set = 0x40004d90 ); 175 | PROVIDE ( gpio_pin_wakeup_disable = 0x40004ed4 ); 176 | PROVIDE ( gpio_pin_wakeup_enable = 0x40004e90 ); 177 | PROVIDE ( gpio_register_get = 0x40004d5c ); 178 | PROVIDE ( gpio_register_set = 0x40004d04 ); 179 | PROVIDE ( hmac_md5 = 0x4000a2cc ); 180 | PROVIDE ( hmac_md5_vector = 0x4000a160 ); 181 | PROVIDE ( hmac_sha1 = 0x4000ba28 ); 182 | PROVIDE ( hmac_sha1_vector = 0x4000b8b4 ); 183 | PROVIDE ( lldesc_build_chain = 0x40004f40 ); 184 | PROVIDE ( lldesc_num2link = 0x40005050 ); 185 | PROVIDE ( lldesc_set_owner = 0x4000507c ); 186 | PROVIDE ( main = 0x40000fec ); 187 | PROVIDE ( md5_vector = 0x400097ac ); 188 | PROVIDE ( mem_calloc = 0x40001c2c ); 189 | PROVIDE ( mem_free = 0x400019e0 ); 190 | PROVIDE ( mem_init = 0x40001998 ); 191 | PROVIDE ( mem_malloc = 0x40001b40 ); 192 | PROVIDE ( mem_realloc = 0x40001c6c ); 193 | PROVIDE ( mem_trim = 0x40001a14 ); 194 | PROVIDE ( mem_zalloc = 0x40001c58 ); 195 | PROVIDE ( memcmp = 0x4000dea8 ); 196 | PROVIDE ( memcpy = 0x4000df48 ); 197 | PROVIDE ( memmove = 0x4000e04c ); 198 | PROVIDE ( memset = 0x4000e190 ); 199 | PROVIDE ( multofup = 0x400031c0 ); 200 | PROVIDE ( pbkdf2_sha1 = 0x4000b840 ); 201 | PROVIDE ( phy_get_romfuncs = 0x40006b08 ); 202 | PROVIDE ( rand = 0x40000600 ); 203 | PROVIDE ( rc4_skip = 0x4000dd68 ); 204 | PROVIDE ( recv_packet = 0x40003d08 ); 205 | PROVIDE ( remove_head_space = 0x40000a04 ); 206 | PROVIDE ( rijndaelKeySetupDec = 0x40008dd0 ); 207 | PROVIDE ( rijndaelKeySetupEnc = 0x40009300 ); 208 | PROVIDE ( rom_abs_temp = 0x400060c0 ); 209 | PROVIDE ( rom_ana_inf_gating_en = 0x40006b10 ); 210 | PROVIDE ( rom_cal_tos_v50 = 0x40007a28 ); 211 | PROVIDE ( rom_chip_50_set_channel = 0x40006f84 ); 212 | PROVIDE ( rom_chip_v5_disable_cca = 0x400060d0 ); 213 | PROVIDE ( rom_chip_v5_enable_cca = 0x400060ec ); 214 | PROVIDE ( rom_chip_v5_rx_init = 0x4000711c ); 215 | PROVIDE ( rom_chip_v5_sense_backoff = 0x4000610c ); 216 | PROVIDE ( rom_chip_v5_tx_init = 0x4000718c ); 217 | PROVIDE ( rom_dc_iq_est = 0x4000615c ); 218 | PROVIDE ( rom_en_pwdet = 0x400061b8 ); 219 | PROVIDE ( rom_get_bb_atten = 0x40006238 ); 220 | PROVIDE ( rom_get_corr_power = 0x40006260 ); 221 | PROVIDE ( rom_get_fm_sar_dout = 0x400062dc ); 222 | PROVIDE ( rom_get_noisefloor = 0x40006394 ); 223 | PROVIDE ( rom_get_power_db = 0x400063b0 ); 224 | PROVIDE ( rom_i2c_readReg = 0x40007268 ); 225 | PROVIDE ( rom_i2c_readReg_Mask = 0x4000729c ); 226 | PROVIDE ( rom_i2c_writeReg = 0x400072d8 ); 227 | PROVIDE ( rom_i2c_writeReg_Mask = 0x4000730c ); 228 | PROVIDE ( rom_iq_est_disable = 0x40006400 ); 229 | PROVIDE ( rom_iq_est_enable = 0x40006430 ); 230 | PROVIDE ( rom_linear_to_db = 0x40006484 ); 231 | PROVIDE ( rom_mhz2ieee = 0x400065a4 ); 232 | PROVIDE ( rom_pbus_dco___SA2 = 0x40007bf0 ); 233 | PROVIDE ( rom_pbus_debugmode = 0x4000737c ); 234 | PROVIDE ( rom_pbus_enter_debugmode = 0x40007410 ); 235 | PROVIDE ( rom_pbus_exit_debugmode = 0x40007448 ); 236 | PROVIDE ( rom_pbus_force_test = 0x4000747c ); 237 | PROVIDE ( rom_pbus_rd = 0x400074d8 ); 238 | PROVIDE ( rom_pbus_set_rxgain = 0x4000754c ); 239 | PROVIDE ( rom_pbus_set_txgain = 0x40007610 ); 240 | PROVIDE ( rom_pbus_workmode = 0x40007648 ); 241 | PROVIDE ( rom_pbus_xpd_rx_off = 0x40007688 ); 242 | PROVIDE ( rom_pbus_xpd_rx_on = 0x400076cc ); 243 | PROVIDE ( rom_pbus_xpd_tx_off = 0x400076fc ); 244 | PROVIDE ( rom_pbus_xpd_tx_on = 0x40007740 ); 245 | PROVIDE ( rom_pbus_xpd_tx_on__low_gain = 0x400077a0 ); 246 | PROVIDE ( rom_phy_reset_req = 0x40007804 ); 247 | PROVIDE ( rom_restart_cal = 0x4000781c ); 248 | PROVIDE ( rom_rfcal_pwrctrl = 0x40007eb4 ); 249 | PROVIDE ( rom_rfcal_rxiq = 0x4000804c ); 250 | PROVIDE ( rom_rfcal_rxiq_set_reg = 0x40008264 ); 251 | PROVIDE ( rom_rfcal_txcap = 0x40008388 ); 252 | PROVIDE ( rom_rfcal_txiq = 0x40008610 ); 253 | PROVIDE ( rom_rfcal_txiq_cover = 0x400088b8 ); 254 | PROVIDE ( rom_rfcal_txiq_set_reg = 0x40008a70 ); 255 | PROVIDE ( rom_rfpll_reset = 0x40007868 ); 256 | PROVIDE ( rom_rfpll_set_freq = 0x40007968 ); 257 | PROVIDE ( rom_rxiq_cover_mg_mp = 0x40008b6c ); 258 | PROVIDE ( rom_rxiq_get_mis = 0x40006628 ); 259 | PROVIDE ( rom_sar_init = 0x40006738 ); 260 | PROVIDE ( rom_set_ana_inf_tx_scale = 0x4000678c ); 261 | PROVIDE ( rom_set_channel_freq = 0x40006c50 ); 262 | PROVIDE ( rom_set_loopback_gain = 0x400067c8 ); 263 | PROVIDE ( rom_set_noise_floor = 0x40006830 ); 264 | PROVIDE ( rom_set_rxclk_en = 0x40006550 ); 265 | PROVIDE ( rom_set_txbb_atten = 0x40008c6c ); 266 | PROVIDE ( rom_set_txclk_en = 0x4000650c ); 267 | PROVIDE ( rom_set_txiq_cal = 0x40008d34 ); 268 | PROVIDE ( rom_start_noisefloor = 0x40006874 ); 269 | PROVIDE ( rom_start_tx_tone = 0x400068b4 ); 270 | PROVIDE ( rom_stop_tx_tone = 0x4000698c ); 271 | PROVIDE ( rom_tx_mac_disable = 0x40006a98 ); 272 | PROVIDE ( rom_tx_mac_enable = 0x40006ad4 ); 273 | PROVIDE ( rom_txtone_linear_pwr = 0x40006a1c ); 274 | PROVIDE ( rom_write_rfpll_sdm = 0x400078dc ); 275 | PROVIDE ( roundup2 = 0x400031b4 ); 276 | PROVIDE ( rtc_enter_sleep = 0x40002870 ); 277 | PROVIDE ( rtc_get_reset_reason = 0x400025e0 ); 278 | PROVIDE ( rtc_intr_handler = 0x400029ec ); 279 | PROVIDE ( rtc_set_sleep_mode = 0x40002668 ); 280 | PROVIDE ( save_rxbcn_mactime = 0x400027a4 ); 281 | PROVIDE ( save_tsf_us = 0x400027ac ); 282 | PROVIDE ( send_packet = 0x40003c80 ); 283 | PROVIDE ( sha1_prf = 0x4000ba48 ); 284 | PROVIDE ( sha1_vector = 0x4000a2ec ); 285 | PROVIDE ( sip_alloc_to_host_evt = 0x40005180 ); 286 | PROVIDE ( sip_get_ptr = 0x400058a8 ); 287 | PROVIDE ( sip_get_state = 0x40005668 ); 288 | PROVIDE ( sip_init_attach = 0x4000567c ); 289 | PROVIDE ( sip_install_rx_ctrl_cb = 0x4000544c ); 290 | PROVIDE ( sip_install_rx_data_cb = 0x4000545c ); 291 | PROVIDE ( sip_post = 0x400050fc ); 292 | PROVIDE ( sip_post_init = 0x400056c4 ); 293 | PROVIDE ( sip_reclaim_from_host_cmd = 0x4000534c ); 294 | PROVIDE ( sip_reclaim_tx_data_pkt = 0x400052c0 ); 295 | PROVIDE ( sip_send = 0x40005808 ); 296 | PROVIDE ( sip_to_host_chain_append = 0x40005864 ); 297 | PROVIDE ( sip_to_host_evt_send_done = 0x40005234 ); 298 | PROVIDE ( slc_add_credits = 0x400060ac ); 299 | PROVIDE ( slc_enable = 0x40005d90 ); 300 | PROVIDE ( slc_from_host_chain_fetch = 0x40005f24 ); 301 | PROVIDE ( slc_from_host_chain_recycle = 0x40005e94 ); 302 | PROVIDE ( slc_init_attach = 0x40005c50 ); 303 | PROVIDE ( slc_init_credit = 0x4000608c ); 304 | PROVIDE ( slc_pause_from_host = 0x40006014 ); 305 | PROVIDE ( slc_reattach = 0x40005c1c ); 306 | PROVIDE ( slc_resume_from_host = 0x4000603c ); 307 | PROVIDE ( slc_select_tohost_gpio = 0x40005dc0 ); 308 | PROVIDE ( slc_select_tohost_gpio_mode = 0x40005db8 ); 309 | PROVIDE ( slc_send_to_host_chain = 0x40005de4 ); 310 | PROVIDE ( slc_set_host_io_max_window = 0x40006068 ); 311 | PROVIDE ( slc_to_host_chain_recycle = 0x40005f10 ); 312 | PROVIDE ( software_reset = 0x4000264c ); 313 | PROVIDE ( spi_flash_attach = 0x40004644 ); 314 | PROVIDE ( srand = 0x400005f0 ); 315 | PROVIDE ( strcmp = 0x4000bdc8 ); 316 | PROVIDE ( strcpy = 0x4000bec8 ); 317 | PROVIDE ( strlen = 0x4000bf4c ); 318 | PROVIDE ( strncmp = 0x4000bfa8 ); 319 | PROVIDE ( strncpy = 0x4000c0a0 ); 320 | PROVIDE ( strstr = 0x4000e1e0 ); 321 | PROVIDE ( timer_insert = 0x40002c64 ); 322 | PROVIDE ( uartAttach = 0x4000383c ); 323 | PROVIDE ( uart_baudrate_detect = 0x40003924 ); 324 | PROVIDE ( uart_buff_switch = 0x400038a4 ); 325 | PROVIDE ( uart_div_modify = 0x400039d8 ); 326 | PROVIDE ( uart_rx_intr_handler = 0x40003bbc ); 327 | PROVIDE ( uart_rx_one_char = 0x40003b8c ); 328 | PROVIDE ( uart_rx_one_char_block = 0x40003b64 ); 329 | PROVIDE ( uart_rx_readbuff = 0x40003ec8 ); 330 | PROVIDE ( uart_tx_one_char = 0x40003b30 ); 331 | PROVIDE ( wepkey_128 = 0x4000bc40 ); 332 | PROVIDE ( wepkey_64 = 0x4000bb3c ); 333 | PROVIDE ( xthal_bcopy = 0x40000688 ); 334 | PROVIDE ( xthal_copy123 = 0x4000074c ); 335 | PROVIDE ( xthal_get_ccompare = 0x4000dd4c ); 336 | PROVIDE ( xthal_get_ccount = 0x4000dd38 ); 337 | PROVIDE ( xthal_get_interrupt = 0x4000dd58 ); 338 | PROVIDE ( xthal_get_intread = 0x4000dd58 ); 339 | PROVIDE ( xthal_memcpy = 0x400006c4 ); 340 | PROVIDE ( xthal_set_ccompare = 0x4000dd40 ); 341 | PROVIDE ( xthal_set_intclear = 0x4000dd60 ); 342 | PROVIDE ( xthal_spill_registers_into_stack_nw = 0x4000e320 ); 343 | PROVIDE ( xthal_window_spill = 0x4000e324 ); 344 | PROVIDE ( xthal_window_spill_nw = 0x4000e320 ); 345 | 346 | PROVIDE ( Te0 = 0x3fffccf0 ); 347 | PROVIDE ( Td0 = 0x3fffd100 ); 348 | PROVIDE ( Td4s = 0x3fffd500); 349 | PROVIDE ( rcons = 0x3fffd0f0); 350 | PROVIDE ( UartDev = 0x3fffde10 ); 351 | PROVIDE ( flashchip = 0x3fffc714); 352 | -------------------------------------------------------------------------------- /boot8266/etshal.h: -------------------------------------------------------------------------------- 1 | #ifndef _INCLUDED_ETSHAL_H_ 2 | #define _INCLUDED_ETSHAL_H_ 3 | 4 | #include 5 | 6 | // see http://esp8266-re.foogod.com/wiki/Random_Number_Generator 7 | #define WDEV_HWRNG ((volatile uint32_t*)0x3ff20e44) 8 | 9 | void ets_delay_us(); 10 | void ets_intr_lock(void); 11 | void ets_intr_unlock(void); 12 | void ets_isr_mask(uint32_t mask); 13 | void ets_isr_unmask(uint32_t mask); 14 | void ets_isr_attach(int irq_no, void (*handler)(void *), void *arg); 15 | void ets_install_putc1(); 16 | void uart_div_modify(); 17 | void ets_set_idle_cb(void (*handler)(void *), void *arg); 18 | 19 | void ets_timer_arm_new(os_timer_t *tim, uint32_t millis, bool repeat, bool is_milli_timer); 20 | void ets_timer_setfn(os_timer_t *tim, ETSTimerFunc callback, void *cb_data); 21 | void ets_timer_disarm(os_timer_t *tim); 22 | 23 | extern void ets_wdt_disable(void); 24 | extern void wdt_feed(void); 25 | 26 | // Opaque structure 27 | #ifndef MD5_CTX 28 | typedef char MD5_CTX[88]; 29 | #endif 30 | 31 | void MD5Init(MD5_CTX *context); 32 | void MD5Update(MD5_CTX *context, const void *data, unsigned int len); 33 | void MD5Final(unsigned char digest[16], MD5_CTX *context); 34 | 35 | // These prototypes are for recent SDKs with "malloc tracking" 36 | void *pvPortMalloc(unsigned sz, const char *fname, int line); 37 | void *pvPortZalloc(unsigned sz, const char *fname, int line); 38 | void *pvPortRealloc(void *p, unsigned sz, const char *fname, int line); 39 | void vPortFree(void *p, const char *fname, int line); 40 | 41 | uint32_t SPIRead(uint32_t offset, void *buf, uint32_t len); 42 | uint32_t SPIWrite(uint32_t offset, const void *buf, uint32_t len); 43 | uint32_t SPIEraseSector(int sector); 44 | 45 | #endif // _INCLUDED_ETSHAL_H_ 46 | -------------------------------------------------------------------------------- /boot8266/uart_register.h: -------------------------------------------------------------------------------- 1 | //Generated at 2012-07-03 18:44:06 2 | /* 3 | * Copyright (c) 2010 - 2011 Espressif System 4 | * 5 | */ 6 | 7 | #ifndef UART_REGISTER_H_INCLUDED 8 | #define UART_REGISTER_H_INCLUDED 9 | #define REG_UART_BASE( i ) (0x60000000+(i)*0xf00) 10 | //version value:32'h062000 11 | 12 | #define UART_FIFO( i ) (REG_UART_BASE( i ) + 0x0) 13 | #define UART_RXFIFO_RD_BYTE 0x000000FF 14 | #define UART_RXFIFO_RD_BYTE_S 0 15 | 16 | #define UART_INT_RAW( i ) (REG_UART_BASE( i ) + 0x4) 17 | #define UART_RXFIFO_TOUT_INT_RAW (BIT(8)) 18 | #define UART_BRK_DET_INT_RAW (BIT(7)) 19 | #define UART_CTS_CHG_INT_RAW (BIT(6)) 20 | #define UART_DSR_CHG_INT_RAW (BIT(5)) 21 | #define UART_RXFIFO_OVF_INT_RAW (BIT(4)) 22 | #define UART_FRM_ERR_INT_RAW (BIT(3)) 23 | #define UART_PARITY_ERR_INT_RAW (BIT(2)) 24 | #define UART_TXFIFO_EMPTY_INT_RAW (BIT(1)) 25 | #define UART_RXFIFO_FULL_INT_RAW (BIT(0)) 26 | 27 | #define UART_INT_ST( i ) (REG_UART_BASE( i ) + 0x8) 28 | #define UART_RXFIFO_TOUT_INT_ST (BIT(8)) 29 | #define UART_BRK_DET_INT_ST (BIT(7)) 30 | #define UART_CTS_CHG_INT_ST (BIT(6)) 31 | #define UART_DSR_CHG_INT_ST (BIT(5)) 32 | #define UART_RXFIFO_OVF_INT_ST (BIT(4)) 33 | #define UART_FRM_ERR_INT_ST (BIT(3)) 34 | #define UART_PARITY_ERR_INT_ST (BIT(2)) 35 | #define UART_TXFIFO_EMPTY_INT_ST (BIT(1)) 36 | #define UART_RXFIFO_FULL_INT_ST (BIT(0)) 37 | 38 | #define UART_INT_ENA( i ) (REG_UART_BASE( i ) + 0xC) 39 | #define UART_RXFIFO_TOUT_INT_ENA (BIT(8)) 40 | #define UART_BRK_DET_INT_ENA (BIT(7)) 41 | #define UART_CTS_CHG_INT_ENA (BIT(6)) 42 | #define UART_DSR_CHG_INT_ENA (BIT(5)) 43 | #define UART_RXFIFO_OVF_INT_ENA (BIT(4)) 44 | #define UART_FRM_ERR_INT_ENA (BIT(3)) 45 | #define UART_PARITY_ERR_INT_ENA (BIT(2)) 46 | #define UART_TXFIFO_EMPTY_INT_ENA (BIT(1)) 47 | #define UART_RXFIFO_FULL_INT_ENA (BIT(0)) 48 | 49 | #define UART_INT_CLR( i ) (REG_UART_BASE( i ) + 0x10) 50 | #define UART_RXFIFO_TOUT_INT_CLR (BIT(8)) 51 | #define UART_BRK_DET_INT_CLR (BIT(7)) 52 | #define UART_CTS_CHG_INT_CLR (BIT(6)) 53 | #define UART_DSR_CHG_INT_CLR (BIT(5)) 54 | #define UART_RXFIFO_OVF_INT_CLR (BIT(4)) 55 | #define UART_FRM_ERR_INT_CLR (BIT(3)) 56 | #define UART_PARITY_ERR_INT_CLR (BIT(2)) 57 | #define UART_TXFIFO_EMPTY_INT_CLR (BIT(1)) 58 | #define UART_RXFIFO_FULL_INT_CLR (BIT(0)) 59 | 60 | #define UART_CLKDIV( i ) (REG_UART_BASE( i ) + 0x14) 61 | #define UART_CLKDIV_CNT 0x000FFFFF 62 | #define UART_CLKDIV_S 0 63 | 64 | #define UART_AUTOBAUD( i ) (REG_UART_BASE( i ) + 0x18) 65 | #define UART_GLITCH_FILT 0x000000FF 66 | #define UART_GLITCH_FILT_S 8 67 | #define UART_AUTOBAUD_EN (BIT(0)) 68 | 69 | #define UART_STATUS( i ) (REG_UART_BASE( i ) + 0x1C) 70 | #define UART_TXD (BIT(31)) 71 | #define UART_RTSN (BIT(30)) 72 | #define UART_DTRN (BIT(29)) 73 | #define UART_TXFIFO_CNT 0x000000FF 74 | #define UART_TXFIFO_CNT_S 16 75 | #define UART_RXD (BIT(15)) 76 | #define UART_CTSN (BIT(14)) 77 | #define UART_DSRN (BIT(13)) 78 | #define UART_RXFIFO_CNT 0x000000FF 79 | #define UART_RXFIFO_CNT_S 0 80 | 81 | #define UART_CONF0( i ) (REG_UART_BASE( i ) + 0x20) 82 | #define UART_TXFIFO_RST (BIT(18)) 83 | #define UART_RXFIFO_RST (BIT(17)) 84 | #define UART_IRDA_EN (BIT(16)) 85 | #define UART_TX_FLOW_EN (BIT(15)) 86 | #define UART_LOOPBACK (BIT(14)) 87 | #define UART_IRDA_RX_INV (BIT(13)) 88 | #define UART_IRDA_TX_INV (BIT(12)) 89 | #define UART_IRDA_WCTL (BIT(11)) 90 | #define UART_IRDA_TX_EN (BIT(10)) 91 | #define UART_IRDA_DPLX (BIT(9)) 92 | #define UART_TXD_BRK (BIT(8)) 93 | #define UART_SW_DTR (BIT(7)) 94 | #define UART_SW_RTS (BIT(6)) 95 | #define UART_STOP_BIT_NUM 0x00000003 96 | #define UART_STOP_BIT_NUM_S 4 97 | #define UART_BIT_NUM 0x00000003 98 | #define UART_BIT_NUM_S 2 99 | #define UART_PARITY_EN (BIT(1)) 100 | #define UART_PARITY (BIT(0)) 101 | 102 | #define UART_CONF1( i ) (REG_UART_BASE( i ) + 0x24) 103 | #define UART_RX_TOUT_EN (BIT(31)) 104 | #define UART_RX_TOUT_THRHD 0x0000007F 105 | #define UART_RX_TOUT_THRHD_S 24 106 | #define UART_RX_FLOW_EN (BIT(23)) 107 | #define UART_RX_FLOW_THRHD 0x0000007F 108 | #define UART_RX_FLOW_THRHD_S 16 109 | #define UART_TXFIFO_EMPTY_THRHD 0x0000007F 110 | #define UART_TXFIFO_EMPTY_THRHD_S 8 111 | #define UART_RXFIFO_FULL_THRHD 0x0000007F 112 | #define UART_RXFIFO_FULL_THRHD_S 0 113 | 114 | #define UART_LOWPULSE( i ) (REG_UART_BASE( i ) + 0x28) 115 | #define UART_LOWPULSE_MIN_CNT 0x000FFFFF 116 | #define UART_LOWPULSE_MIN_CNT_S 0 117 | 118 | #define UART_HIGHPULSE( i ) (REG_UART_BASE( i ) + 0x2C) 119 | #define UART_HIGHPULSE_MIN_CNT 0x000FFFFF 120 | #define UART_HIGHPULSE_MIN_CNT_S 0 121 | 122 | #define UART_PULSE_NUM( i ) (REG_UART_BASE( i ) + 0x30) 123 | #define UART_PULSE_NUM_CNT 0x0003FF 124 | #define UART_PULSE_NUM_CNT_S 0 125 | 126 | #define UART_DATE( i ) (REG_UART_BASE( i ) + 0x78) 127 | #define UART_ID( i ) (REG_UART_BASE( i ) + 0x7C) 128 | #endif // UART_REGISTER_H_INCLUDED 129 | -------------------------------------------------------------------------------- /boot8266/unaligned_printf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | extern char _bss_end; 5 | extern void ets_write_char(); 6 | extern int ets_vprintf(void (*)(), const char *, va_list); 7 | 8 | /* Print unaligned string residing in aligned memory (iRAM, iROM) using 9 | standard ets_printf(). Do so by copying string to dRAM first. Note 10 | that this overwrites dRAM beyond BSS end, and so not suitable for 11 | use in full-fledged apps, but rather for low-level stuff like 12 | bootloaders. */ 13 | int _printf(const char *fmt, ...) 14 | { 15 | va_list args; 16 | va_start(args, fmt); 17 | uint32_t addr = (uint32_t)fmt; 18 | 19 | uint32_t *p = (uint32_t*)(addr&~3), *to = (uint32_t*)&_bss_end; 20 | while (1) { 21 | uint32_t v = *p++; 22 | *to++ = v; 23 | if ((uint32_t)p > (addr&~3)) { 24 | if (!(v & 0xff) || !(v & 0xff00) || !(v & 0xff0000) || !(v & 0xff000000)) break; 25 | } 26 | } 27 | return ets_vprintf(ets_write_char, &_bss_end + (addr&3), args); 28 | } 29 | -------------------------------------------------------------------------------- /boot8266/user_config.h: -------------------------------------------------------------------------------- 1 | // empty 2 | -------------------------------------------------------------------------------- /config.h.example: -------------------------------------------------------------------------------- 1 | // This is user-specific config file for yaota8266 OTA bootloader. 2 | // For compilation to succeed, this file should be copied to "config.h" 3 | // and any settings related to RSA keys replaced with your values. Do 4 | // not use values in this example as is - it is a security issue. You 5 | // won't be able to perform any OTA update (because you don't have a 6 | // private key for the public key specified here), but I will own 7 | // your system (because I have it). 8 | 9 | // Offset of the main application (one which will undergo OTA update) 10 | // Default start of OTA region == size of boot8266 + ota-server, aligned 11 | // (size of yaota8266.bin as produced by the top-level Makefile). 12 | #define MAIN_APP_OFFSET 0x3c000 13 | 14 | // Baud rate for serial output. Set to 0 to not set baud rate explicitly, 15 | // which them will be the default 74880. 16 | #define BAUD_RATE 115200 17 | 18 | // Modulus of RSA public key used to verify OTA signature 19 | // (size is 512 bits, exponent is hardcoded at 3). 20 | #define MODULUS "\xce\x4a\xaf\x65\x0d\x4a\x74\xda\xc1\x30\x59\x80\xcf\xdd\xe8\x2a\x2e\x1d\xf7\xa8\xc9\x6c\xa9\x4a\x2c\xb7\x8a\x5a\x2a\x25\xc0\x2b\x7b\x2f\x58\x4c\xa8\xcb\x82\x07\x06\x08\x7e\xff\x1f\xce\x47\x13\x67\x94\x5f\x9a\xac\x5e\x7d\xcf\x63\xf0\x08\xe9\x51\x98\x95\x01" 21 | 22 | // How long to wait for next expected packet before assuming that 23 | // transfer is broken and restart reception from beginning. 24 | #define PKT_WAIT_MS 10000 25 | 26 | // If first OTA packet isn't received during this time, reboot. This 27 | // protects against being stuck in OTA mode if entered by accident. 28 | #define IDLE_REBOOT_MS 60000 29 | 30 | // Parameters below can be configured in flash too 31 | 32 | // GPIO mask. Default value filters out UART0 and QSPI for FlashROM. 33 | // If value is 0, then OTA is entered unconditionally. By adjusting 34 | // IDLE_REBOOT_MS, you can make a device spend minimal time in this 35 | // unconditional OTA mode. 36 | #define GPIO_MASK 0xf035 37 | 38 | // How long to wait for GPIO change to go into OTA mode. 39 | #define GPIO_WAIT_MS 3000 40 | -------------------------------------------------------------------------------- /merge.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | last_sz = 0 5 | 6 | def align(f): 7 | global last_sz 8 | if last_sz & 0xfff: 9 | f.write(b"\xff" * (0x1000 - (last_sz & 0xfff))) 10 | 11 | assert sys.argv[1] == "-o" 12 | fout = open(sys.argv[2], "wb") 13 | 14 | 15 | for fname in sys.argv[3:]: 16 | align(fout) 17 | last_sz = 0 18 | with open(fname, "rb") as fin: 19 | while True: 20 | buf = fin.read(4096) 21 | if not buf: 22 | break 23 | fout.write(buf) 24 | last_sz += len(buf) 25 | 26 | align(fout) 27 | fout.close() 28 | -------------------------------------------------------------------------------- /ota-client/gen_keys.sh: -------------------------------------------------------------------------------- 1 | BITS=512 2 | # OTA server expects a key with exponent 3 3 | openssl genrsa -out priv.key -3 $BITS 4 | openssl rsa -in priv.key -pubout -out pub.key 5 | openssl pkey -in priv.key -text 6 | -------------------------------------------------------------------------------- /ota-client/ota_client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | import struct 4 | import socket 5 | import time 6 | import hashlib 7 | import argparse 8 | 9 | #from Crypto.Cipher import AES 10 | import rsa_sign 11 | 12 | 13 | # How many firmware data bytes are included in each packet. 14 | # Set a conservative default. There were issues reported that 15 | # UDP packet larger than 548 bytes don't get thru. Unfortunately, 16 | # that means that even 512 payload bytes + headers don't fit. 17 | BLK_SIZE = 256 18 | 19 | AES_IV = b"\0" * 16 20 | AES_KEY = b"\x01" * 16 21 | 22 | rsa_key = None 23 | last_aes_key = None 24 | last_seq = 0 25 | rexmit = 0 26 | 27 | 28 | def add_digest(pkt): 29 | global last_aes_key, last_seq 30 | aes_key = AES_KEY 31 | #last_aes_key = aes_key 32 | #aes = AES.new(aes_key, AES.MODE_CBC, AES_IV) 33 | pad_len = (16 - len(pkt) % 16) % 16 34 | pkt += b"\0" * pad_len 35 | #pkt = aes.encrypt(pkt) 36 | 37 | digest = hashlib.sha1(pkt).digest() 38 | sig = rsa_sign.sign(rsa_key, aes_key + digest) 39 | last_seq += 1 40 | return struct.pack("= 8 37 | 38 | buf = b"\0\x01" + (b"\xff" * pad_len) + b"\0" + to_sign 39 | # print("Padded to-sign len:", len(buf)) 40 | val = int.from_bytes(buf, "big") 41 | # print("Padded to-sign:", val, hex(val)) 42 | 43 | sig = pow(val, pe, mod) 44 | # print("Sig (int):", sig, hex(sig)) 45 | sig_b = sig.to_bytes(BITS // 8, "big") 46 | # print(hexlify(sig_b)) 47 | return sig_b 48 | 49 | 50 | if __name__ == "__main__": 51 | comps = load_key() 52 | sign(comps, b"foob\0") 53 | -------------------------------------------------------------------------------- /ota-server/Makefile: -------------------------------------------------------------------------------- 1 | CC = xtensa-lx106-elf-gcc 2 | LD = xtensa-lx106-elf-ld 3 | ESP_SDK = $(shell $(CC) -print-sysroot)/usr 4 | CFLAGS = -std=gnu99 -Os -I. -mtext-section-literals -mlongcalls -mforce-l32 -ffunction-sections -fdata-sections -DLWIP_OPEN_SRC -D__ets__ 5 | LDLIBS = -L$(ESP_SDK)/lib -L. -laxtls -lmain -lnet80211 -lwpa -llwip_open -lpp -lphy -lnet80211 -lgcc 6 | LDFLAGS = -nostdlib -T./ota.ld -gc-sections -Map=$@.map --cref 7 | 8 | ota-0x00000.bin: ota.elf 9 | esptool.py elf2image $^ 10 | 11 | ota.elf: ota.o main.o ets_alt_task.o | libaxtls.a 12 | $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS) 13 | 14 | libaxtls.a: 15 | cd lib/axtls; cp config/upyconfig config/.config 16 | cd lib/axtls; make oldconfig -B 17 | cd lib/axtls; make clean 18 | cd lib/axtls; make all CC="$(CC)" LD="$(LD)" AR="$(AR)" CFLAGS_EXTRA="$(CFLAGS) -Dabort=abort_ -DRT_MAX_PLAIN_LENGTH=1024 -DRT_EXTRA=3072" 19 | cp lib/axtls/_stage/libaxtls.a $@ 20 | 21 | flash: ota-0x00000.bin 22 | esptool.py --baud 1500000 write_flash 0 *-0x00000.bin 0x8000 *-0x08000.bin 23 | 24 | clean: 25 | rm -f *.o *.a *.elf* *-0x*.bin 26 | -------------------------------------------------------------------------------- /ota-server/ets_alt_task.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the yaota8266 project. 3 | * 4 | * The MIT License (MIT) 5 | * 6 | * Copyright (c) 2016 Paul Sokolovsky 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | #include 27 | #include "osapi.h" 28 | #include "os_type.h" 29 | #include "ets_sys.h" 30 | #include 31 | #include "../boot8266/etshal.h" 32 | #include "user_interface.h" 33 | #include "ets_alt_task.h" 34 | 35 | // Use standard ets_task or alternative impl 36 | #define USE_ETS_TASK 0 37 | 38 | #define MP_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 39 | 40 | struct task_entry { 41 | os_event_t *queue; 42 | os_task_t task; 43 | uint8_t qlen; 44 | uint8_t prio; 45 | int8_t i_get; 46 | int8_t i_put; 47 | }; 48 | 49 | static void (*idle_cb)(void *); 50 | static void *idle_arg; 51 | 52 | #if ESP_SDK_VERSION >= 010500 53 | # define FIRST_PRIO 0 54 | #else 55 | # define FIRST_PRIO 0x14 56 | #endif 57 | #define LAST_PRIO 0x20 58 | #define PRIO2ID(prio) ((prio) - FIRST_PRIO) 59 | 60 | volatile struct task_entry emu_tasks[PRIO2ID(LAST_PRIO) + 1]; 61 | 62 | static inline int prio2id(uint8_t prio) { 63 | int id = PRIO2ID(prio); 64 | if (id < 0 || id >= MP_ARRAY_SIZE(emu_tasks)) { 65 | printf("task prio out of range: %d\n", prio); 66 | while (1); 67 | } 68 | return id; 69 | } 70 | 71 | #if DEBUG 72 | void dump_task(int prio, volatile struct task_entry *t) { 73 | printf("q for task %d: queue: %p, get ptr: %d, put ptr: %d, qlen: %d\n", 74 | prio, t->queue, t->i_get, t->i_put, t->qlen); 75 | } 76 | 77 | void dump_tasks(void) { 78 | for (int i = 0; i < MP_ARRAY_SIZE(emu_tasks); i++) { 79 | if (emu_tasks[i].qlen) { 80 | dump_task(i + FIRST_PRIO, &emu_tasks[i]); 81 | } 82 | } 83 | printf("====\n"); 84 | } 85 | #endif 86 | 87 | bool ets_task(os_task_t task, uint8 prio, os_event_t *queue, uint8 qlen) { 88 | static unsigned cnt; 89 | printf("#%d ets_task(%p, %d, %p, %d)\n", cnt++, task, prio, queue, qlen); 90 | #if USE_ETS_TASK 91 | return _ets_task(task, prio, queue, qlen); 92 | #else 93 | int id = prio2id(prio); 94 | emu_tasks[id].task = task; 95 | emu_tasks[id].queue = queue; 96 | emu_tasks[id].qlen = qlen; 97 | emu_tasks[id].i_get = 0; 98 | emu_tasks[id].i_put = 0; 99 | return true; 100 | #endif 101 | } 102 | 103 | bool ets_post(uint8 prio, os_signal_t sig, os_param_t param) { 104 | // static unsigned cnt; printf("#%d ets_post(%d, %x, %x)\n", cnt++, prio, sig, param); 105 | #if USE_ETS_TASK 106 | return _ets_post(prio, sig, param); 107 | #else 108 | ets_intr_lock(); 109 | 110 | const int id = prio2id(prio); 111 | os_event_t *q = emu_tasks[id].queue; 112 | if (emu_tasks[id].i_put == -1) { 113 | // queue is full 114 | printf("ets_post: task %d queue full\n", prio); 115 | return 1; 116 | } 117 | q = &q[emu_tasks[id].i_put++]; 118 | q->sig = sig; 119 | q->par = param; 120 | if (emu_tasks[id].i_put == emu_tasks[id].qlen) { 121 | emu_tasks[id].i_put = 0; 122 | } 123 | if (emu_tasks[id].i_put == emu_tasks[id].i_get) { 124 | // queue got full 125 | emu_tasks[id].i_put = -1; 126 | } 127 | //printf("after ets_post: "); dump_task(prio, &emu_tasks[id]); 128 | //dump_tasks(); 129 | 130 | ets_intr_unlock(); 131 | 132 | return 0; 133 | #endif 134 | } 135 | 136 | int ets_loop_iter_disable = 0; 137 | 138 | // to implement a 64-bit wide microsecond counter 139 | static uint32_t system_time_prev = 0; 140 | uint32_t system_time_high_word = 0; 141 | 142 | bool ets_loop_iter(void) { 143 | if (ets_loop_iter_disable) { 144 | return false; 145 | } 146 | 147 | // handle overflow of system microsecond counter 148 | uint32_t system_time_cur = system_get_time(); 149 | if (system_time_cur < system_time_prev) { 150 | system_time_high_word += 1; // record overflow of low 32-bits 151 | } 152 | system_time_prev = system_time_cur; 153 | 154 | //static unsigned cnt; 155 | bool progress = false; 156 | for (volatile struct task_entry *t = emu_tasks; t < &emu_tasks[MP_ARRAY_SIZE(emu_tasks)]; t++) { 157 | system_soft_wdt_feed(); 158 | ets_intr_lock(); 159 | //printf("etc_loop_iter: "); dump_task(t - emu_tasks + FIRST_PRIO, t); 160 | if (t->i_get != t->i_put) { 161 | progress = true; 162 | //printf("#%d Calling task %d(%p) (%x, %x)\n", cnt++, 163 | // t - emu_tasks + FIRST_PRIO, t->task, t->queue[t->i_get].sig, t->queue[t->i_get].par); 164 | int idx = t->i_get; 165 | if (t->i_put == -1) { 166 | t->i_put = t->i_get; 167 | } 168 | if (++t->i_get == t->qlen) { 169 | t->i_get = 0; 170 | } 171 | //ets_intr_unlock(); 172 | t->task(&t->queue[idx]); 173 | //ets_intr_lock(); 174 | //printf("Done calling task %d\n", t - emu_tasks + FIRST_PRIO); 175 | } 176 | ets_intr_unlock(); 177 | } 178 | return progress; 179 | } 180 | 181 | #if SDK_BELOW_1_1_1 182 | void my_timer_isr(void *arg) { 183 | // uart0_write_char('+'); 184 | ets_post(0x1f, 0, 0); 185 | } 186 | 187 | // Timer init func is in ROM, and calls ets_task by relative addr directly in ROM 188 | // so, we have to re-init task using our handler 189 | void ets_timer_init() { 190 | printf("ets_timer_init\n"); 191 | // _ets_timer_init(); 192 | ets_isr_attach(10, my_timer_isr, NULL); 193 | SET_PERI_REG_MASK(0x3FF00004, 4); 194 | ETS_INTR_ENABLE(10); 195 | ets_task((os_task_t)0x40002E3C, 0x1f, (os_event_t*)0x3FFFDDC0, 4); 196 | 197 | WRITE_PERI_REG(PERIPHS_TIMER_BASEDDR + 0x30, 0); 198 | WRITE_PERI_REG(PERIPHS_TIMER_BASEDDR + 0x28, 0x88); 199 | WRITE_PERI_REG(PERIPHS_TIMER_BASEDDR + 0x30, 0); 200 | printf("Installed timer ISR\n"); 201 | } 202 | #endif 203 | 204 | bool ets_run(void) { 205 | #if USE_ETS_TASK 206 | #if SDK_BELOW_1_1_1 207 | ets_isr_attach(10, my_timer_isr, NULL); 208 | #endif 209 | _ets_run(); 210 | #else 211 | // ets_timer_init(); 212 | *(char*)0x3FFFC6FC = 0; 213 | ets_intr_lock(); 214 | printf("ets_alt_task: ets_run\n"); 215 | #if DEBUG 216 | dump_tasks(); 217 | #endif 218 | ets_intr_unlock(); 219 | while (1) { 220 | if (!ets_loop_iter()) { 221 | //printf("idle\n"); 222 | ets_intr_lock(); 223 | if (idle_cb) { 224 | idle_cb(idle_arg); 225 | } 226 | asm("waiti 0"); 227 | ets_intr_unlock(); 228 | } 229 | } 230 | #endif 231 | } 232 | 233 | void ets_set_idle_cb(void (*handler)(void *), void *arg) { 234 | //printf("ets_set_idle_cb(%p, %p)\n", handler, arg); 235 | idle_cb = handler; 236 | idle_arg = arg; 237 | } 238 | -------------------------------------------------------------------------------- /ota-server/ets_alt_task.h: -------------------------------------------------------------------------------- 1 | extern int ets_loop_iter_disable; 2 | extern uint32_t system_time_high_word; 3 | 4 | bool ets_loop_iter(void); 5 | -------------------------------------------------------------------------------- /ota-server/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the yaota8266 project. 3 | * 4 | * The MIT License (MIT) 5 | * 6 | * Copyright (c) 2016 Paul Sokolovsky 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | #include 27 | #include 28 | #include 29 | 30 | #include "user_interface.h" 31 | #include "mem.h" 32 | #include "../boot8266/etshal.h" 33 | #include "../config.h" 34 | 35 | void ota_start(void); 36 | 37 | void init_done(void) { 38 | #if BAUD_RATE 39 | uart_div_modify(0, UART_CLK_FREQ / BAUD_RATE); 40 | #endif 41 | printf("\nStarting OTA server\n"); 42 | ota_start(); 43 | } 44 | 45 | void user_init(void) { 46 | system_init_done_cb(init_done); 47 | } 48 | 49 | //void __assert(const char *file, int line, const char *func, const char *expr) { 50 | void __assert(const char *file, int line, const char *expr) { 51 | printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line); 52 | for (;;) { 53 | } 54 | } 55 | 56 | void abort_(void) { 57 | printf("Abort\n"); 58 | for (;;); 59 | } 60 | 61 | void *malloc(int sz) { 62 | return os_malloc(sz); 63 | } 64 | 65 | void *realloc(void *p, int sz) { 66 | return os_realloc(p, sz); 67 | } 68 | 69 | void *calloc(int n, int sz) { 70 | return os_zalloc(n * sz); 71 | } 72 | 73 | void free(void *p) { 74 | return os_free(p); 75 | } 76 | 77 | #define PLATFORM_HTONL(_n) ((uint32_t)( (((_n) & 0xff) << 24) | (((_n) & 0xff00) << 8) | (((_n) >> 8) & 0xff00) | (((_n) >> 24) & 0xff) )) 78 | #undef htonl 79 | #undef ntohl 80 | uint32_t ntohl(uint32_t netlong) { 81 | return PLATFORM_HTONL(netlong); 82 | } 83 | uint32_t htonl(uint32_t netlong) { 84 | return PLATFORM_HTONL(netlong); 85 | } 86 | 87 | extern void ets_write_char(); 88 | extern int ets_printf(const char *, ...); 89 | extern int ets_vprintf(void (*)(), const char *, va_list); 90 | 91 | int puts(const char *s) { 92 | ets_printf(s); 93 | ets_printf("\n"); 94 | } 95 | 96 | int printf(const char *fmt, ...) 97 | { 98 | va_list args; 99 | va_start(args, fmt); 100 | return ets_vprintf(ets_write_char, fmt, args); 101 | } 102 | 103 | int DEBUG_printf(const char *fmt, ...) 104 | { 105 | va_list args; 106 | va_start(args, fmt); 107 | return ets_vprintf(ets_write_char, fmt, args); 108 | } 109 | -------------------------------------------------------------------------------- /ota-server/ota.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the yaota8266 project. 3 | * 4 | * The MIT License (MIT) 5 | * 6 | * Copyright (c) 2016 Paul Sokolovsky 7 | * 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy 9 | * of this software and associated documentation files (the "Software"), to deal 10 | * in the Software without restriction, including without limitation the rights 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | * copies of the Software, and to permit persons to whom the Software is 13 | * furnished to do so, subject to the following conditions: 14 | * 15 | * The above copyright notice and this permission notice shall be included in 16 | * all copies or substantial portions of the Software. 17 | * 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | * THE SOFTWARE. 25 | */ 26 | 27 | #include 28 | #include "lwip/udp.h" 29 | #include "lwip/timers.h" 30 | #include "ets_alt_task.h" 31 | #include "user_interface.h" 32 | #include "lib/axtls/crypto/crypto.h" 33 | #define MD5_CTX MD5_CTX 34 | #include "../boot8266/etshal.h" 35 | #include "../config.h" 36 | 37 | #define OTA_START MAIN_APP_OFFSET 38 | 39 | #define CHECK(v) if (v != ERR_OK) printf(#v ": err\n") 40 | 41 | struct pkt_seq { 42 | uint32_t seq; 43 | } __attribute__((packed)); 44 | 45 | struct pkt_header { 46 | uint16_t op; 47 | uint16_t len; 48 | uint32_t offset; 49 | char data[0]; 50 | } __attribute__((packed)); 51 | 52 | static uint8_t MOD[] = MODULUS; 53 | #define RSA_BLK_SIZE (sizeof(MOD) - 1) 54 | 55 | static uint32_t ota_offset, ota_prev_offset; 56 | static int dup_pkt; 57 | static uint32_t session_start_time; 58 | static uint32_t last_pkt_time; 59 | static RSA_CTX *rsa_ctx = NULL; 60 | 61 | static char buf[4096]; 62 | static int buf_sz; 63 | 64 | #define AES_BLK_SIZE 16 65 | uint8_t AES_IV[AES_BLK_SIZE] = {0}; 66 | 67 | 68 | static void buf_init(void) { 69 | buf_sz = 0; 70 | memset(buf, 0xff, sizeof(buf)); 71 | } 72 | 73 | #define MP_FASTCODE(n) __attribute__((section(".iram0.text." #n))) n 74 | 75 | void MP_FASTCODE(write_buf)(void) { 76 | if (buf_sz > 0) { 77 | #if 0 78 | printf("Would write %d bytes of buf\n", buf_sz); 79 | #else 80 | uint32_t off = OTA_START + ota_offset; 81 | if (off & (4096 - 1)) { 82 | off &= ~(4096 - 1); 83 | } else { 84 | off -= 4096; 85 | } 86 | printf("Writing %d bytes of buf to %x\n", buf_sz, off); 87 | SPIEraseSector(off / 4096); 88 | SPIWrite(off, buf, sizeof(buf)); 89 | #endif 90 | } 91 | buf_init(); 92 | } 93 | 94 | static void session_init(void) { 95 | dup_pkt = 0; 96 | ota_offset = 0; 97 | ota_prev_offset = -1; 98 | session_start_time = system_get_time(); 99 | } 100 | 101 | static void ota_udp_incoming(void *arg, struct udp_pcb *upcb, struct pbuf *p, ip_addr_t *addr, u16_t port) { 102 | 103 | printf("UDP incoming from: %x:%d, data=%p\n", (unsigned)addr->addr, port, p->payload); 104 | uint32_t start_time = system_get_time(); 105 | 106 | if (p->len < sizeof(struct pkt_header)) { 107 | printf("Packet too short\n"); 108 | goto done; 109 | } 110 | 111 | struct pkt_seq *pkt = p->payload; 112 | printf("Pkt id: %x\n", pkt->seq); 113 | 114 | uint8_t sig_payload[RSA_BLK_SIZE]; 115 | uint8_t *sig = (uint8_t*)p->payload + p->len - RSA_BLK_SIZE; 116 | int sig_sz = RSA_decrypt(rsa_ctx, sig, sig_payload, sizeof(sig_payload), 0); 117 | if (sig_sz != SHA1_SIZE + AES_BLK_SIZE) { 118 | printf("Invalid digest size in signature\n"); 119 | goto done; 120 | } 121 | 122 | struct pkt_header *hdr = (struct pkt_header*)((char*)p->payload + 4); 123 | 124 | SHA1_CTX sha_ctx; 125 | SHA1_Init(&sha_ctx); 126 | SHA1_Update(&sha_ctx, (uint8_t*)hdr, p->len - RSA_BLK_SIZE - 4); 127 | uint8_t digest[SHA1_SIZE]; 128 | SHA1_Final(digest, &sha_ctx); 129 | 130 | if (memcmp(digest, sig_payload + AES_BLK_SIZE, sizeof(digest)) != 0) { 131 | printf("Invalid SHA1\n"); 132 | goto done; 133 | } 134 | 135 | #if 0 136 | AES_CTX aes_ctx; 137 | AES_set_key(&aes_ctx, sig_payload, AES_IV, AES_MODE_128); 138 | AES_convert_key(&aes_ctx); 139 | AES_cbc_decrypt(&aes_ctx, (uint8_t*)hdr, (uint8_t*)hdr, p->len - RSA_BLK_SIZE - 4); 140 | #endif 141 | 142 | printf("offset: %d len: %d\n", hdr->offset, hdr->len); 143 | 144 | if (hdr->len == 0) { 145 | write_buf(); 146 | printf("OTA finished, rexmits: %d\n", dup_pkt); 147 | pbuf_free(p); 148 | session_init(); 149 | 150 | //udp_remove(upcb); 151 | printf("Rebooting\n"); 152 | system_restart(); 153 | 154 | return; 155 | } 156 | 157 | if (hdr->offset == ota_prev_offset) { 158 | // Client apparently didn't receive our confirmation 159 | // and went to resend the packet we already processed - 160 | // resend the confirmation. 161 | dup_pkt++; 162 | goto confirm; 163 | } 164 | 165 | if (hdr->offset != ota_offset) { 166 | printf("Unexpected offset\n"); 167 | goto done; 168 | } 169 | if (buf_sz + hdr->len > sizeof(buf)) { 170 | printf("Buffer overflow - wrong chunk size\n"); 171 | goto done; 172 | } 173 | memcpy(buf + buf_sz, hdr->data, hdr->len); 174 | ota_prev_offset = ota_offset; 175 | ota_offset += hdr->len; 176 | buf_sz += hdr->len; 177 | 178 | printf("Proc1 time: %d\n", system_get_time() - start_time); 179 | 180 | if (buf_sz == sizeof(buf)) { 181 | write_buf(); 182 | } 183 | 184 | confirm: { 185 | struct pbuf *resp = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct pkt_seq) + AES_BLK_SIZE, PBUF_RAM); 186 | *(uint32_t*)resp->payload = pkt->seq; 187 | uint8_t *encblk = (uint8_t*)resp->payload + 4; 188 | memcpy(encblk, hdr, sizeof(struct pkt_header)); 189 | #if 0 190 | AES_set_key(&aes_ctx, sig_payload, AES_IV, AES_MODE_128); 191 | AES_cbc_encrypt(&aes_ctx, encblk, encblk, AES_BLK_SIZE); 192 | #endif 193 | 194 | CHECK(udp_sendto(upcb, resp, addr, port)); 195 | pbuf_free(resp); 196 | } 197 | 198 | last_pkt_time = system_get_time(); 199 | 200 | done: 201 | printf("Full time: %d\n", system_get_time() - start_time); 202 | pbuf_free(p); 203 | } 204 | 205 | void timer_handler(void *arg) { 206 | //printf("tick\n"); 207 | 208 | if (ota_prev_offset != -1 && system_get_time() - last_pkt_time > PKT_WAIT_MS * 1000) { 209 | printf("Next pkt wait timeout, restarting recv\n"); 210 | session_init(); 211 | } 212 | 213 | if (ota_prev_offset == -1 && system_get_time() - session_start_time > IDLE_REBOOT_MS * 1000) { 214 | printf("OTA start timeout, rebooting\n"); 215 | system_restart(); 216 | } 217 | 218 | sys_timeout(1000, timer_handler, NULL); 219 | } 220 | 221 | void ota_start(void) { 222 | session_init(); 223 | buf_init(); 224 | 225 | RSA_pub_key_new(&rsa_ctx, MOD, sizeof(MOD) - 1, (uint8_t*)"\x03", 1); 226 | printf("rsa_ctx = %p\n", rsa_ctx); 227 | 228 | struct udp_pcb *sock = udp_new(); 229 | CHECK(udp_bind(sock, IP_ADDR_ANY, 8266)); 230 | udp_recv(sock, ota_udp_incoming, NULL); 231 | 232 | sys_timeout(1000, timer_handler, NULL); 233 | 234 | while (1) { 235 | ets_loop_iter(); 236 | } 237 | } 238 | -------------------------------------------------------------------------------- /ota-server/ota.ld: -------------------------------------------------------------------------------- 1 | /* This linker script generated from xt-genldscripts.tpp for LSP . */ 2 | /* Linker Script for ld -N */ 3 | MEMORY 4 | { 5 | dport0_0_seg : org = 0x3FF00000, len = 0x10 6 | dram0_0_seg : org = 0x3FFE8000, len = 0x14000 7 | iram1_0_seg : org = 0x40100000, len = 0x8000 8 | irom0_0_seg : org = 0x40208000 + 0x1000, len = 0x33000 9 | } 10 | 11 | PHDRS 12 | { 13 | dport0_0_phdr PT_LOAD; 14 | dram0_0_phdr PT_LOAD; 15 | dram0_0_bss_phdr PT_LOAD; 16 | iram1_0_phdr PT_LOAD; 17 | irom0_0_phdr PT_LOAD; 18 | } 19 | 20 | 21 | /* Default entry point: */ 22 | ENTRY(call_user_start) 23 | EXTERN(_DebugExceptionVector) 24 | EXTERN(_DoubleExceptionVector) 25 | EXTERN(_KernelExceptionVector) 26 | EXTERN(_NMIExceptionVector) 27 | EXTERN(_UserExceptionVector) 28 | PROVIDE(_memmap_vecbase_reset = 0x40000000); 29 | /* Various memory-map dependent cache attribute settings: */ 30 | _memmap_cacheattr_wb_base = 0x00000110; 31 | _memmap_cacheattr_wt_base = 0x00000110; 32 | _memmap_cacheattr_bp_base = 0x00000220; 33 | _memmap_cacheattr_unused_mask = 0xFFFFF00F; 34 | _memmap_cacheattr_wb_trapnull = 0x2222211F; 35 | _memmap_cacheattr_wba_trapnull = 0x2222211F; 36 | _memmap_cacheattr_wbna_trapnull = 0x2222211F; 37 | _memmap_cacheattr_wt_trapnull = 0x2222211F; 38 | _memmap_cacheattr_bp_trapnull = 0x2222222F; 39 | _memmap_cacheattr_wb_strict = 0xFFFFF11F; 40 | _memmap_cacheattr_wt_strict = 0xFFFFF11F; 41 | _memmap_cacheattr_bp_strict = 0xFFFFF22F; 42 | _memmap_cacheattr_wb_allvalid = 0x22222112; 43 | _memmap_cacheattr_wt_allvalid = 0x22222112; 44 | _memmap_cacheattr_bp_allvalid = 0x22222222; 45 | PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull); 46 | 47 | SECTIONS 48 | { 49 | 50 | .dport0.rodata : ALIGN(4) 51 | { 52 | _dport0_rodata_start = ABSOLUTE(.); 53 | *(.dport0.rodata) 54 | *(.dport.rodata) 55 | _dport0_rodata_end = ABSOLUTE(.); 56 | } >dport0_0_seg :dport0_0_phdr 57 | 58 | .dport0.literal : ALIGN(4) 59 | { 60 | _dport0_literal_start = ABSOLUTE(.); 61 | *(.dport0.literal) 62 | *(.dport.literal) 63 | _dport0_literal_end = ABSOLUTE(.); 64 | } >dport0_0_seg :dport0_0_phdr 65 | 66 | .dport0.data : ALIGN(4) 67 | { 68 | _dport0_data_start = ABSOLUTE(.); 69 | *(.dport0.data) 70 | *(.dport.data) 71 | _dport0_data_end = ABSOLUTE(.); 72 | } >dport0_0_seg :dport0_0_phdr 73 | 74 | .data : ALIGN(4) 75 | { 76 | _data_start = ABSOLUTE(.); 77 | *(.data) 78 | *(.data.*) 79 | *(.gnu.linkonce.d.*) 80 | *(.data1) 81 | *(.sdata) 82 | *(.sdata.*) 83 | *(.gnu.linkonce.s.*) 84 | *(.sdata2) 85 | *(.sdata2.*) 86 | *(.gnu.linkonce.s2.*) 87 | *(.jcr) 88 | _data_end = ABSOLUTE(.); 89 | } >dram0_0_seg :dram0_0_phdr 90 | 91 | .rodata : ALIGN(4) 92 | { 93 | _rodata_start = ABSOLUTE(.); 94 | *(.sdk.version) 95 | *(.rodata) 96 | *(.rodata.*) 97 | *(.gnu.linkonce.r.*) 98 | *(.rodata1) 99 | __XT_EXCEPTION_TABLE__ = ABSOLUTE(.); 100 | *(.xt_except_table) 101 | *(.gcc_except_table) 102 | *(.gnu.linkonce.e.*) 103 | *(.gnu.version_r) 104 | *(.eh_frame) 105 | /* C++ constructor and destructor tables, properly ordered: */ 106 | KEEP (*crtbegin.o(.ctors)) 107 | KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) 108 | KEEP (*(SORT(.ctors.*))) 109 | KEEP (*(.ctors)) 110 | KEEP (*crtbegin.o(.dtors)) 111 | KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) 112 | KEEP (*(SORT(.dtors.*))) 113 | KEEP (*(.dtors)) 114 | /* C++ exception handlers table: */ 115 | __XT_EXCEPTION_DESCS__ = ABSOLUTE(.); 116 | *(.xt_except_desc) 117 | *(.gnu.linkonce.h.*) 118 | __XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.); 119 | *(.xt_except_desc_end) 120 | *(.dynamic) 121 | *(.gnu.version_d) 122 | . = ALIGN(4); /* this table MUST be 4-byte aligned */ 123 | _bss_table_start = ABSOLUTE(.); 124 | LONG(_bss_start) 125 | LONG(_bss_end) 126 | _bss_table_end = ABSOLUTE(.); 127 | _rodata_end = ABSOLUTE(.); 128 | } >dram0_0_seg :dram0_0_phdr 129 | 130 | .bss ALIGN(8) (NOLOAD) : ALIGN(4) 131 | { 132 | . = ALIGN (8); 133 | _bss_start = ABSOLUTE(.); 134 | *(.dynsbss) 135 | *(.sbss) 136 | *(.sbss.*) 137 | *(.gnu.linkonce.sb.*) 138 | *(.scommon) 139 | *(.sbss2) 140 | *(.sbss2.*) 141 | *(.gnu.linkonce.sb2.*) 142 | *(.dynbss) 143 | *(.bss) 144 | *(.bss.*) 145 | *(.gnu.linkonce.b.*) 146 | *(COMMON) 147 | . = ALIGN (8); 148 | _bss_end = ABSOLUTE(.); 149 | _heap_start = ABSOLUTE(.); 150 | /* _stack_sentry = ALIGN(0x8); */ 151 | } >dram0_0_seg :dram0_0_bss_phdr 152 | /* __stack = 0x3ffc8000; */ 153 | 154 | .irom0.text : ALIGN(4) 155 | { 156 | _irom0_text_start = ABSOLUTE(.); 157 | 158 | *libmbedtls.a:(.literal .text .literal.* .text.*) 159 | */libaxtls.a:(.literal*, .text*) 160 | main.o(.literal*, .text*) 161 | /*ota.o(.literal*, .text*)*/ 162 | 163 | *(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text) 164 | _irom0_text_end = ABSOLUTE(.); 165 | } >irom0_0_seg :irom0_0_phdr 166 | 167 | .text : ALIGN(4) 168 | { 169 | _stext = .; 170 | _text_start = ABSOLUTE(.); 171 | *(.UserEnter.text) 172 | . = ALIGN(16); 173 | *(.DebugExceptionVector.text) 174 | . = ALIGN(16); 175 | *(.NMIExceptionVector.text) 176 | . = ALIGN(16); 177 | *(.KernelExceptionVector.text) 178 | LONG(0) 179 | LONG(0) 180 | LONG(0) 181 | LONG(0) 182 | . = ALIGN(16); 183 | *(.UserExceptionVector.text) 184 | LONG(0) 185 | LONG(0) 186 | LONG(0) 187 | LONG(0) 188 | . = ALIGN(16); 189 | *(.DoubleExceptionVector.text) 190 | LONG(0) 191 | LONG(0) 192 | LONG(0) 193 | LONG(0) 194 | . = ALIGN (16); 195 | *(.entry.text) 196 | *(.init.literal) 197 | *(.init) 198 | *(.literal .text .literal.* .text.* .iram0.literal .iram0.text .iram0.text.*.literal .iram0.text.*) 199 | *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*) 200 | *(.fini.literal) 201 | *(.fini) 202 | *(.gnu.version) 203 | _text_end = ABSOLUTE(.); 204 | _etext = .; 205 | } >iram1_0_seg :iram1_0_phdr 206 | 207 | .lit4 : ALIGN(4) 208 | { 209 | _lit4_start = ABSOLUTE(.); 210 | *(*.lit4) 211 | *(.lit4.*) 212 | *(.gnu.linkonce.lit4.*) 213 | _lit4_end = ABSOLUTE(.); 214 | } >iram1_0_seg :iram1_0_phdr 215 | } 216 | 217 | /* get ROM code address */ 218 | INCLUDE "../boot8266/eagle.rom.addr.v6.ld" 219 | -------------------------------------------------------------------------------- /ota-server/user_config.h: -------------------------------------------------------------------------------- 1 | // empty 2 | --------------------------------------------------------------------------------