Skip to content

Commit 219be7d

Browse files
committed
reading eboot commands via RTC, flash erase/copy
1 parent a194024 commit 219be7d

File tree

6 files changed

+174
-2
lines changed

6 files changed

+174
-2
lines changed

hardware/esp8266com/esp8266/bootloaders/eboot/Makefile

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ TARGET_DIR := ./
55

66
TARGET_OBJ_FILES := \
77
eboot.o \
8+
eboot_command.o \
89

910
TARGET_OBJ_PATHS := $(addprefix $(TARGET_DIR)/,$(TARGET_OBJ_FILES))
1011

@@ -17,7 +18,7 @@ OBJDUMP := $(XTENSA_TOOCHAIN)xtensa-lx106-elf-objdump
1718

1819
CFLAGS += -std=gnu99
1920

20-
CFLAGS += -O0 -g -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mno-text-section-literals
21+
CFLAGS += -Os -g -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mno-text-section-literals
2122

2223
LDFLAGS += -nostdlib -Wl,--no-check-sections -umain
2324

hardware/esp8266com/esp8266/bootloaders/eboot/eboot.c

+93-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <stdint.h>
1111
#include <stdbool.h>
1212
#include "eboot.h"
13+
#include "eboot_command.h"
1314
extern void* flashchip;
1415

1516
#define SWRST do { (*((volatile uint32_t*) 0x60000700)) |= 0x80000000; } while(0);
@@ -71,9 +72,100 @@ int load_app_from_flash_raw(const uint32_t flash_addr)
7172
}
7273

7374

75+
76+
int erase(const uint32_t start, const uint32_t size)
77+
{
78+
if (start & (FLASH_SECTOR_SIZE - 1) != 0) {
79+
return 1;
80+
}
81+
82+
const uint32_t sectors_per_block = FLASH_BLOCK_SIZE / FLASH_SECTOR_SIZE;
83+
uint32_t current_sector = start / FLASH_SECTOR_SIZE;
84+
uint32_t sector_count = (size + FLASH_SECTOR_SIZE - 1) / FLASH_SECTOR_SIZE;
85+
const uint32_t end = current_sector + sector_count;
86+
87+
for (; current_sector < end && (current_sector & (sectors_per_block-1));
88+
++current_sector, --sector_count) {
89+
if (SPIEraseSector(current_sector)) {
90+
return 2;
91+
}
92+
}
93+
94+
for (;current_sector + sectors_per_block <= end;
95+
current_sector += sectors_per_block,
96+
sector_count -= sectors_per_block) {
97+
if (SPIEraseBlock(current_sector / sectors_per_block)) {
98+
return 3;
99+
}
100+
}
101+
102+
for (; current_sector < end;
103+
++current_sector, --sector_count) {
104+
if (SPIEraseSector(current_sector)) {
105+
return 4;
106+
}
107+
}
108+
109+
return 0;
110+
}
111+
112+
int copy_raw(const uint32_t src_addr,
113+
const uint32_t dst_addr,
114+
const uint32_t size)
115+
{
116+
// require regions to be aligned
117+
if (src_addr & 0xfff != 0 ||
118+
dst_addr & 0xfff != 0) {
119+
return 1;
120+
}
121+
122+
if (erase(dst_addr, size)) {
123+
return 2;
124+
}
125+
126+
const uint32_t buffer_size = 4096;
127+
uint8_t buffer[buffer_size];
128+
129+
const uint32_t end = src_addr + size;
130+
uint32_t saddr = src_addr;
131+
uint32_t daddr = dst_addr;
132+
uint32_t left = size;
133+
while (saddr < end) {
134+
uint32_t will_copy = (left < buffer_size) ? left : buffer_size;
135+
if (SPIRead(saddr, buffer, will_copy)) {
136+
return 3;
137+
}
138+
if (SPIWrite(daddr, buffer, will_copy)) {
139+
return 4;
140+
}
141+
saddr += will_copy;
142+
daddr += will_copy;
143+
left -= will_copy;
144+
}
145+
146+
return 0;
147+
}
148+
149+
150+
74151
void main()
75152
{
76-
int res = load_app_from_flash_raw(0);
153+
int res;
154+
struct eboot_command cmd;
155+
156+
eboot_command_read(&cmd);
157+
158+
if (cmd.action == ACTION_COPY_RAW) {
159+
res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2]);
160+
if (res == 0) {
161+
cmd.action = ACTION_LOAD_APP;
162+
}
163+
}
164+
165+
if (cmd.action == ACTION_LOAD_APP) {
166+
res = load_app_from_flash_raw(0);
167+
}
168+
77169
if (res) {
78170
ets_putc('\n');
79171
ets_putc('#');
Binary file not shown.

hardware/esp8266com/esp8266/bootloaders/eboot/eboot.h

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ int SPIEraseSector(uint32_t sector);
1414
int SPIRead(uint32_t addr, void *dest, size_t size);
1515
int SPIWrite(uint32_t addr, void *src, size_t size);
1616

17+
18+
#define FLASH_SECTOR_SIZE 0x1000
19+
#define FLASH_BLOCK_SIZE 0x10000
1720
#define APP_START_OFFSET 0x1000
1821

1922
typedef struct {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include "eboot_command.h"
2+
3+
uint32_t crc_update(uint32_t crc, const uint8_t *data, size_t length)
4+
{
5+
uint32_t i;
6+
bool bit;
7+
uint8_t c;
8+
9+
while (length--) {
10+
c = *data++;
11+
for (i = 0x80; i > 0; i >>= 1) {
12+
bit = crc & 0x80000000;
13+
if (c & i) {
14+
bit = !bit;
15+
}
16+
crc <<= 1;
17+
if (bit) {
18+
crc ^= 0x04c11db7;
19+
}
20+
}
21+
}
22+
return crc;
23+
}
24+
25+
uint32_t eboot_command_calculate_crc32(const struct eboot_command* cmd)
26+
{
27+
return crc_update(0xffffffff, (const uint8_t*) cmd,
28+
offsetof(struct eboot_command, crc32));
29+
}
30+
31+
void eboot_command_read(struct eboot_command* cmd)
32+
{
33+
const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t);
34+
uint32_t* dst = (uint32_t *) cmd;
35+
for (uint32_t i = 0; i < dw_count; ++i) {
36+
dst[i] = RTC_MEM[i];
37+
}
38+
39+
uint32_t crc32 = eboot_command_calculate_crc32(cmd);
40+
if (cmd->magic & EBOOT_MAGIC_MASK != EBOOT_MAGIC ||
41+
cmd->crc32 != crc32) {
42+
43+
cmd->action = ACTION_LOAD_APP;
44+
cmd->args[0] = 0;
45+
}
46+
}
47+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifndef EBOOT_COMMAND_H
2+
#define EBOOT_COMMAND_H
3+
4+
#include <stdint.h>
5+
#include <stddef.h>
6+
#include <stdbool.h>
7+
8+
#define RTC_MEM ((volatile uint32_t*)0x60001200)
9+
10+
enum action_t {
11+
ACTION_COPY_RAW = 0x00000001,
12+
ACTION_LOAD_APP = 0xffffffff
13+
};
14+
15+
#define EBOOT_MAGIC 0xeb001000
16+
#define EBOOT_MAGIC_MASK 0xfffff000
17+
18+
struct eboot_command {
19+
uint32_t magic;
20+
enum action_t action;
21+
uint32_t args[29];
22+
uint32_t crc32;
23+
};
24+
25+
26+
void eboot_command_read(struct eboot_command* cmd);
27+
28+
29+
#endif //EBOOT_COMMAND_H

0 commit comments

Comments
 (0)