From d5b578b161bc7d63f6e9c1bd942b602d2dc59f87 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov <igrokhotkov@gmail.com> Date: Mon, 1 Jun 2015 02:08:48 +0300 Subject: [PATCH] reading eboot commands via RTC, flash erase/copy --- bootloaders/eboot/Makefile | 3 +- bootloaders/eboot/eboot.c | 94 +++++++++++++++++++++++++++++- bootloaders/eboot/eboot.elf | Bin 5209 -> 11738 bytes bootloaders/eboot/eboot.h | 3 + bootloaders/eboot/eboot_command.c | 47 +++++++++++++++ bootloaders/eboot/eboot_command.h | 29 +++++++++ 6 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 bootloaders/eboot/eboot_command.c create mode 100644 bootloaders/eboot/eboot_command.h diff --git a/bootloaders/eboot/Makefile b/bootloaders/eboot/Makefile index 32e325f34..8aaac9cab 100644 --- a/bootloaders/eboot/Makefile +++ b/bootloaders/eboot/Makefile @@ -5,6 +5,7 @@ TARGET_DIR := ./ TARGET_OBJ_FILES := \ eboot.o \ + eboot_command.o \ TARGET_OBJ_PATHS := $(addprefix $(TARGET_DIR)/,$(TARGET_OBJ_FILES)) @@ -17,7 +18,7 @@ OBJDUMP := $(XTENSA_TOOCHAIN)xtensa-lx106-elf-objdump CFLAGS += -std=gnu99 -CFLAGS += -O0 -g -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mno-text-section-literals +CFLAGS += -Os -g -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mno-text-section-literals LDFLAGS += -nostdlib -Wl,--no-check-sections -umain diff --git a/bootloaders/eboot/eboot.c b/bootloaders/eboot/eboot.c index e39375d2d..86a27eff0 100644 --- a/bootloaders/eboot/eboot.c +++ b/bootloaders/eboot/eboot.c @@ -10,6 +10,7 @@ #include <stdint.h> #include <stdbool.h> #include "eboot.h" +#include "eboot_command.h" extern void* flashchip; #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) } + +int erase(const uint32_t start, const uint32_t size) +{ + if (start & (FLASH_SECTOR_SIZE - 1) != 0) { + return 1; + } + + const uint32_t sectors_per_block = FLASH_BLOCK_SIZE / FLASH_SECTOR_SIZE; + uint32_t current_sector = start / FLASH_SECTOR_SIZE; + uint32_t sector_count = (size + FLASH_SECTOR_SIZE - 1) / FLASH_SECTOR_SIZE; + const uint32_t end = current_sector + sector_count; + + for (; current_sector < end && (current_sector & (sectors_per_block-1)); + ++current_sector, --sector_count) { + if (SPIEraseSector(current_sector)) { + return 2; + } + } + + for (;current_sector + sectors_per_block <= end; + current_sector += sectors_per_block, + sector_count -= sectors_per_block) { + if (SPIEraseBlock(current_sector / sectors_per_block)) { + return 3; + } + } + + for (; current_sector < end; + ++current_sector, --sector_count) { + if (SPIEraseSector(current_sector)) { + return 4; + } + } + + return 0; +} + +int copy_raw(const uint32_t src_addr, + const uint32_t dst_addr, + const uint32_t size) +{ + // require regions to be aligned + if (src_addr & 0xfff != 0 || + dst_addr & 0xfff != 0) { + return 1; + } + + if (erase(dst_addr, size)) { + return 2; + } + + const uint32_t buffer_size = 4096; + uint8_t buffer[buffer_size]; + + const uint32_t end = src_addr + size; + uint32_t saddr = src_addr; + uint32_t daddr = dst_addr; + uint32_t left = size; + while (saddr < end) { + uint32_t will_copy = (left < buffer_size) ? left : buffer_size; + if (SPIRead(saddr, buffer, will_copy)) { + return 3; + } + if (SPIWrite(daddr, buffer, will_copy)) { + return 4; + } + saddr += will_copy; + daddr += will_copy; + left -= will_copy; + } + + return 0; +} + + + void main() { - int res = load_app_from_flash_raw(0); + int res; + struct eboot_command cmd; + + eboot_command_read(&cmd); + + if (cmd.action == ACTION_COPY_RAW) { + res = copy_raw(cmd.args[0], cmd.args[1], cmd.args[2]); + if (res == 0) { + cmd.action = ACTION_LOAD_APP; + } + } + + if (cmd.action == ACTION_LOAD_APP) { + res = load_app_from_flash_raw(0); + } + if (res) { ets_putc('\n'); ets_putc('#'); diff --git a/bootloaders/eboot/eboot.elf b/bootloaders/eboot/eboot.elf index b2381a4098690e025f33c25290a14715934882fe..b7908dfd67b803008b425ac3b0d07ce5d7dd279b 100755 GIT binary patch literal 11738 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�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 literal 5209 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 diff --git a/bootloaders/eboot/eboot.h b/bootloaders/eboot/eboot.h index b77f8f45a..973c616a8 100644 --- a/bootloaders/eboot/eboot.h +++ b/bootloaders/eboot/eboot.h @@ -14,6 +14,9 @@ int SPIEraseSector(uint32_t sector); int SPIRead(uint32_t addr, void *dest, size_t size); int SPIWrite(uint32_t addr, void *src, size_t size); + +#define FLASH_SECTOR_SIZE 0x1000 +#define FLASH_BLOCK_SIZE 0x10000 #define APP_START_OFFSET 0x1000 typedef struct { diff --git a/bootloaders/eboot/eboot_command.c b/bootloaders/eboot/eboot_command.c new file mode 100644 index 000000000..1e9cbed2c --- /dev/null +++ b/bootloaders/eboot/eboot_command.c @@ -0,0 +1,47 @@ +#include "eboot_command.h" + +uint32_t crc_update(uint32_t crc, const uint8_t *data, size_t length) +{ + uint32_t i; + bool bit; + uint8_t c; + + while (length--) { + c = *data++; + for (i = 0x80; i > 0; i >>= 1) { + bit = crc & 0x80000000; + if (c & i) { + bit = !bit; + } + crc <<= 1; + if (bit) { + crc ^= 0x04c11db7; + } + } + } + return crc; +} + +uint32_t eboot_command_calculate_crc32(const struct eboot_command* cmd) +{ + return crc_update(0xffffffff, (const uint8_t*) cmd, + offsetof(struct eboot_command, crc32)); +} + +void eboot_command_read(struct eboot_command* cmd) +{ + const uint32_t dw_count = sizeof(struct eboot_command) / sizeof(uint32_t); + uint32_t* dst = (uint32_t *) cmd; + for (uint32_t i = 0; i < dw_count; ++i) { + dst[i] = RTC_MEM[i]; + } + + uint32_t crc32 = eboot_command_calculate_crc32(cmd); + if (cmd->magic & EBOOT_MAGIC_MASK != EBOOT_MAGIC || + cmd->crc32 != crc32) { + + cmd->action = ACTION_LOAD_APP; + cmd->args[0] = 0; + } +} + diff --git a/bootloaders/eboot/eboot_command.h b/bootloaders/eboot/eboot_command.h new file mode 100644 index 000000000..aa0fc11bb --- /dev/null +++ b/bootloaders/eboot/eboot_command.h @@ -0,0 +1,29 @@ +#ifndef EBOOT_COMMAND_H +#define EBOOT_COMMAND_H + +#include <stdint.h> +#include <stddef.h> +#include <stdbool.h> + +#define RTC_MEM ((volatile uint32_t*)0x60001200) + +enum action_t { + ACTION_COPY_RAW = 0x00000001, + ACTION_LOAD_APP = 0xffffffff +}; + +#define EBOOT_MAGIC 0xeb001000 +#define EBOOT_MAGIC_MASK 0xfffff000 + +struct eboot_command { + uint32_t magic; + enum action_t action; + uint32_t args[29]; + uint32_t crc32; +}; + + +void eboot_command_read(struct eboot_command* cmd); + + +#endif //EBOOT_COMMAND_H