10000 Merge branch 'master' into master · esp8266/Arduino@978570d · GitHub
[go: up one dir, main page]

Skip to content

Commit 978570d

Browse files
authored
Merge branch 'master' into master
2 parents e1c7209 + 1d0bc5e commit 978570d

File tree

10 files changed

+132
-42
lines changed

10 files changed

+132
-42
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,6 @@
1919
[submodule "tools/esptool"]
2020
path = tools/esptool
2121
url = https://github.com/espressif/esptool.git
22+
[submodule "tools/sdk/uzlib"]
23+
path = tools/sdk/uzlib
24+
url = https://github.com/earlephilhower/uzlib.git

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ ESP8266 core files are licensed under LGPL.
124124

125125
[LittleFS](https://github.com/ARMmbed/littlefs) library written by ARM Limited and released under the [BSD 3-clause license](https://github.com/ARMmbed/littlefs/blob/master/LICENSE.md).
126126

127+
[uzlib](https://github.com/pfalcon/uzlib) library written and (c) 2014-2018 Paul Sokolovsky, licensed under the ZLib license (https://www.zlib.net/zlib_license.html).
128+
127129
### Other useful links ###
128130

129131
[Toolchain repo](https://github.com/earlephilhower/esp-quick-toolchain)

bootloaders/eboot/Makefile

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,44 +6,51 @@ TARGET_DIR := ./
66

77
TARGET_OBJ_FILES := \
88
eboot.o \
9-
eboot_command.o \
10-
9+
eboot_command.o
1110

1211
TARGET_OBJ_PATHS := $(addprefix $(TARGET_DIR)/,$(TARGET_OBJ_FILES))
1312

13+
UZLIB_PATH := ../../tools/sdk/uzlib/src
14+
UZLIB_FLAGS := -DRUNTIME_BITS_TABLES
15+
1416
CC := $(XTENSA_TOOLCHAIN)xtensa-lx106-elf-gcc
1517
CXX := $(XTENSA_TOOLCHAIN)xtensa-lx106-elf-g++
1618
AR := $(XTENSA_TOOLCHAIN)xtensa-lx106-elf-ar
1719
LD := $(XTENSA_TOOLCHAIN)xtensa-lx106-elf-gcc
1820
OBJDUMP := $(XTENSA_TOOLCHAIN)xtensa-lx106-elf-objdump
1921

20-
INC += -I../../tools/sdk/include
22+
INC += -I../../tools/sdk/include -I../../tools/sdk/uzlib/src
23+
2124
CFLAGS += -std=gnu99
2225

23-
CFLAGS += -O0 -g -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mno-text-section-literals
26+
CFLAGS += -Os -g -Wall -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mno-text-section-literals -ffunction-sections -fdata-sections
2427

2528
CFLAGS += $(INC)
2629

27-
LDFLAGS += -nostdlib -Wl,--no-check-sections -umain
30+
CFLAGS += $(UZLIB_FLAGS)
31+
32+
LDFLAGS += -nostdlib -Wl,--no-check-sections -Wl,--gc-sections -umain
2833

2934
LD_SCRIPT := -Teboot.ld
3035

3136
APP_OUT:= eboot.elf
3237
APP_AR := eboot.a
3338
APP_FW := eboot.bin
3439

35-
all: $(APP_FW)
3640

37-
$(APP_AR): $(TARGET_OBJ_PATHS)
38-
$(AR) cru $@ $^
41+
all: $(APP_OUT)
3942

43+
tinflate.o: $(UZLIB_PATH)/tinflate.c $(UZLIB_PATH)/uzlib.h $(UZLIB_PATH)/uzlib_conf.h
44+
$(CC) $(CFLAGS) -c -o tinflate.o $(UZLIB_PATH)/tinflate.c
4045

41-
$(APP_OUT): $(APP_AR)
42-
$(LD) $(LD_SCRIPT) $(LDFLAGS) -Wl,--start-group -Wl,--whole-archive $(APP_AR) -Wl,--end-group -o $@
46+
tinfgzip.o: $(UZLIB_PATH)/tinfgzip.c $(UZLIB_PATH)/uzlib.h $(UZLIB_PATH)/uzlib_conf.h
47+
$(CC) $(CFLAGS) -c -o tinfgzip.o $(UZLIB_PATH)/tinfgzip.c
4348

44-
$(APP_FW): $(APP_OUT)
45-
$(ESPTOOL) -vvv -eo $(APP_OUT) -bo $@ -bs .text -bs .data -bs .rodata -bc -ec || true
49+
$(APP_AR): $(TARGET_OBJ_PATHS) tinflate.o tinfgzip.o
50+
$(AR) cru $@ $^
4651

52+
$(APP_OUT): $(APP_AR)
53+
$(LD) $(LD_SCRIPT) $(LDFLAGS) -Wl,--start-group -Wl,--whole-archive $(APP_AR) -Wl,--end-group -o $@
4754

4855
clean:
4956
rm -f *.o

bootloaders/eboot/eboot.c

Lines changed: 85 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
#include <string.h>
1313
#include "flash.h"
1414
#include "eboot_command.h"
15+
#include <uzlib.h>
16+
17+
extern unsigned char _gzip_dict;
1518

1619
#define SWRST do { (*((volatile uint32_t*) 0x60000700)) |= 0x80000000; } while(0);
1720

@@ -24,10 +27,14 @@ int print_version(const uint32_t flash_addr)
2427
if (SPIRead(flash_addr + APP_START_OFFSET + sizeof(image_header_t) + sizeof(section_header_t), &ver, sizeof(ver))) {
2528
return 1;
2629
}
27-
const char* __attribute__ ((aligned (4))) fmtt = "v%08x\n\0\0";
28-
uint32_t fmt[2];
29-
fmt[0] = ((uint32_t*) fmtt)[0];
30-
fmt[1] = ((uint32_t*) fmtt)[1];
30+
char fmt[16];
31+
fmt[0] = 'v';
32+
fmt[1] = '%';
33+
fmt[2] = '0';
34+
fmt[3] = '8';
35+
fmt[4] = 'x';
36+
fmt[5] = '\n';
37+
fmt[6] = '0';
3138
ets_printf((const char*) fmt, ver);
3239
return 0;
3340
}
@@ -80,37 +87,96 @@ int load_app_from_flash_raw(const uint32_t flash_addr)
8087
pos += section_header.size;
8188
}
8289

83-
register uint32_t sp asm("a1") = 0x3ffffff0;
84-
register uint32_t pc asm("a3") = image_header.entry;
85-
__asm__ __volatile__ ("jx a3");
90+
asm volatile("" ::: "memory");
91+
asm volatile ("mov.n a1, %0\n"
92+
"mov.n a3, %1\n"
93+
"jx a3\n" : : "r" (0x3ffffff0), "r" (image_header.entry) );
8694

95+
__builtin_unreachable(); // Save a few bytes by letting GCC know no need to pop regs/return
8796
return 0;
8897
}
8998

99+
uint8_t read_flash_byte(const uint32_t addr)
100+
{
101+
uint8_t __attribute__((aligned(4))) buff[4];
102+
SPIRead(addr & ~3, buff, 4);
103+
return buff[addr & 3];
104+
}
105+
unsigned char __attribute__((aligned(4))) uzlib_flash_read_cb_buff[4096];
106+
uint32_t uzlib_flash_read_cb_addr;
107+
int uzlib_flash_read_cb(struct uzlib_uncomp *m)
108+
{
109+
m->source = uzlib_flash_read_cb_buff;
110+
m->source_limit = uzlib_flash_read_cb_buff + sizeof(uzlib_flash_read_cb_buff);
111+
SPIRead(uzlib_flash_read_cb_addr, uzlib_flash_read_cb_buff, sizeof(uzlib_flash_read_cb_buff));
112+
uzlib_flash_read_cb_addr += sizeof(uzlib_flash_read_cb_buff);
113+
return *(m->source++);
114+
}
90115

116+
unsigned char gzip_dict[32768];
91117

92118
int copy_raw(const uint32_t src_addr,
93119
const uint32_t dst_addr,
94120
const uint32_t size)
95121
{
96122
// require regions to be aligned
97-
if (src_addr & 0xfff != 0 ||
98-
dst_addr & 0xfff != 0) {
123+
if ((src_addr & 0xfff) != 0 ||
124+
(dst_addr & 0xfff) != 0) {
99125
return 1;
100126
}
101127

102128
const uint32_t buffer_size = FLASH_SECTOR_SIZE;
103129
uint8_t buffer[buffer_size];
104-
uint32_t left = ((size+buffer_size-1) & ~(buffer_size-1));
130+
int32_t left = ((size+buffer_size-1) & ~(buffer_size-1));
105131
uint32_t saddr = src_addr;
106132
uint32_t daddr = dst_addr;
107-
108-
while (left) {
133+
struct uzlib_uncomp m_uncomp;
134+
bool gzip = false;
135+
136+
// Check if we are uncompressing a GZIP upload or not
137+
if ((read_flash_byte(saddr) == 0x1f) && (read_flash_byte(saddr + 1) == 0x8b)) {
138+
// GZIP signature matched. Find real size as encoded at the end
139+
left = read_flash_byte(saddr + size - 4);
140+
left += read_flash_byte(saddr + size - 3)<<8;
141+
left += read_flash_byte(saddr + size - 2)<<16;
142+
left += read_flash_byte(saddr + size - 1)<<24;
143+
144+
uzlib_init();
145+
146+
/* all 3 fields below must be initialized by user */
147+
m_uncomp.source = NULL;
148+
m_uncomp.source_limit = NULL;
149+
uzlib_flash_read_cb_addr = src_addr;
150+
m_uncomp.source_read_cb = uzlib_flash_read_cb;
151+
uzlib_uncompress_init(&m_uncomp, gzip_dict, sizeof(gzip_dict));
152+
153+
int res = uzlib_gzip_parse_header(&m_uncomp);
154+
if (res != TINF_OK) {
155+
return 5; // Error uncompress header read
156+
}
157+
gzip = true;
158+
}
159+
while (left > 0) {
109160
if (SPIEraseSector(daddr/buffer_size)) {
110161
return 2;
111162
}
112-
if (SPIRead(saddr, buffer, buffer_size)) {
113-
return 3;
163+
if (!gzip) {
164+
if (SPIRead(saddr, buffer, buffer_size)) {
165+
return 3;
166+
}
167+
} else {
168+
m_uncomp.dest_start = buffer;
169+
m_uncomp.dest = buffer;
170+
int to_read = (left > buffer_size) ? buffer_size : left;
171+
m_uncomp.dest_limit = buffer + to_read;
172+
int res = uzlib_uncompress(&m_uncomp);
173+
if ((res != TINF_DONE) && (res != TINF_OK)) {
174+
return 6;
175+
}
176+
// Fill any remaining with 0xff
177+
for (int i = to_read; i < buffer_size; i++) {
178+
buffer[i] = 0xff;
179+
}
114180
}
115181
if (SPIWrite(daddr, buffer, buffer_size)) {
116182
return 4;
@@ -124,13 +190,12 @@ int copy_raw(const uint32_t src_addr,
124190
}
125191

126192

127-
128-
void main()
193+
int main()
129194
{
130195
int res = 9;
131196
bool clear_cmd = false;
132197
struct eboot_command cmd;
133-
198+
134199
print_version(0);
135200

136201
if (eboot_command_read(&cmd) == 0) {
@@ -172,4 +237,7 @@ void main()
172237
}
173238

174239
while(true){}
240+
241+
__builtin_unreachable();
242+
return 0;
175243
}

bootloaders/eboot/eboot.elf

19.8 KB
Binary file not shown.

bootloaders/eboot/eboot.ld

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ SECTIONS
6868

6969
.data : ALIGN(4)
7070
{
71+
*(COMMON) /* Global vars */
72+
. = ALIGN(4);
7173
_heap_start = ABSOLUTE(.);
7274
/* _stack_sentry = ALIGN(0x8); */
7375
} >dram0_0_seg :dram0_0_bss_phdr
@@ -150,7 +152,6 @@ SECTIONS
150152
*(.bss)
151153
*(.bss.*)
152154
*(.gnu.linkonce.b.*)
153-
*(COMMON)
154155
. = ALIGN (8);
155156
_bss_end = ABSOLUTE(.);
156157
} >iram1_0_seg :iram1_0_phdr

bootloaders/eboot/eboot_command.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ int eboot_command_read(struct eboot_command* cmd)
3737
}
3838

3939
uint32_t crc32 = eboot_command_calculate_crc32(cmd);
40-
if (cmd->magic & EBOOT_MAGIC_MASK != EBOOT_MAGIC ||
40+
if ((cmd->magic & EBOOT_MAGIC_MASK) != EBOOT_MAGIC ||
4141
cmd->crc32 != crc32) {
4242
return 1;
4343
}

cores/esp8266/Updater.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,8 @@ bool UpdaterClass::_writeBuffer(){
329329
bool modifyFlashMode = false;
330330
FlashMode_t flashMode = FM_QIO;
331331
FlashMode_t bufferFlashMode = FM_QIO;
332-
if ((_currentAddress == _startAddress + FLASH_MODE_PAGE) && (_command == U_FLASH)) {
332+
//TODO - GZIP can't do this
333+
if ((_currentAddress == _startAddress + FLASH_MODE_PAGE) && (_buffer[0] != 0x1f) && (_command == U_FLASH)) {
333334
flashMode = ESP.getFlashChipMode();
334335
#ifdef DEBUG_UPDATER
335336
DEBUG_UPDATER.printf_P(PSTR("Header: 0x%1X %1X %1X %1X\n"), _buffer[0], _buffer[1], _buffer[2], _buffer[3]);
@@ -411,7 +412,7 @@ size_t UpdaterClass::write(uint8_t *data, size_t len) {
411412
bool UpdaterClass::_verifyHeader(uint8_t data) {
412413
if(_co 10000 mmand == U_FLASH) {
413414
// check for valid first magic byte (is always 0xE9)
414-
if(data != 0xE9) {
415+
if ((data != 0xE9) && (data != 0x1f)) {
415416
_currentAddress = (_startAddress + _size);
416417
_setError(UPDATE_ERROR_MAGIC_BYTE);
417418
return false;
@@ -435,7 +436,12 @@ bool UpdaterClass::_verifyEnd() {
435436
}
436437

437438
// check for valid first magic byte
438-
if(buf[0] != 0xE9) {
439+
//
440+
// TODO: GZIP compresses the chipsize flags, so can't do check here
441+
if ((buf[0] == 0x1f) && (buf[1] == 0x8b)) {
442+
// GZIP, just assume OK
443+
return true;
444+
} else if (buf[0] != 0xE9) {
439445
_currentAddress = (_startAddress);
440446
_setError(UPDATE_ERROR_MAGIC_BYTE);
441447
return false;

libraries/ESP8266httpUpdate/src/ESP8266httpUpdate.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -370,22 +370,24 @@ HTTPUpdateResult ESP8266HTTPUpdate::handleUpdate(HTTPClient& http, const String&
370370
}
371371

372372
// check for valid first magic byte
373-
if(buf[0] != 0xE9) {
373+
if(buf[0] != 0xE9 && buf[0] != 0x1f) {
374374
DEBUG_HTTP_UPDATE("[httpUpdate] Magic header does not start with 0xE9\n");
375375
_setLastError(HTTP_UE_BIN_VERIFY_HEADER_FAILED);
376376
http.end();
377377
return HTTP_UPDATE_FAILED;
378378

379379
}
380380

381-
uint32_t bin_flash_size = ESP.magicFlashChipSize((buf[3] & 0xf0) >> 4);
381+
if (buf[0] == 0xe9) {
382+
uint32_t bin_flash_size = ESP.magicFlashChipSize((buf[3] & 0xf0) >> 4);
382383

383-
// check if new bin fits to SPI flash
384-
if(bin_flash_size > ESP.getFlashChipRealSize()) {
385-
DEBUG_HTTP_UPDATE("[httpUpdate] New binary does not fit SPI Flash size\n");
386-
_setLastError(HTTP_UE_BIN_FOR_WRONG_FLASH);
387-
http.end();
388-
return HTTP_UPDATE_FAILED;
384+
// check if new bin fits to SPI flash
385+
if(bin_flash_size > ESP.getFlashChipRealSize()) {
386+
DEBUG_HTTP_UPDATE("[httpUpdate] New binary does not fit SPI Flash size\n");
387+
_setLastError(HTTP_UE_BIN_FOR_WRONG_FLASH);
388+
http.end();
389+
return HTTP_UPDATE_FAILED;
390+
}
389391
}
390392
}
391393
if(runUpdate(*tcp, len, http.header("x-MD5"), command)) {

tools/sdk/uzlib

Submodule uzlib added at 80765a4

0 commit comments

Comments
 (0)
0