diff --git a/components/bootloader/subproject/main/bootloader_start.c b/components/bootloader/subproject/main/bootloader_start.c index 64af8268..86c2dccb 100644 --- a/components/bootloader/subproject/main/bootloader_start.c +++ b/components/bootloader/subproject/main/bootloader_start.c @@ -11,112 +11,302 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. -#include + +#include #include -#include -#include "esp_log.h" -#include "rom/gpio.h" -#include "rom/spi_flash.h" -#include "bootloader_config.h" -#include "bootloader_init.h" -#include "bootloader_utility.h" -#include "bootloader_common.h" -#include "sdkconfig.h" -#include "esp_image_format.h" +#include "load_flash_bin.h" -static const char* TAG = "boot"; +#include "esp8266/eagle_soc.h" -static esp_err_t select_image (esp_image_metadata_t *image_data); -static int selected_boot_partition(const bootloader_state_t *bs); -/* - * We arrive here after the ROM bootloader finished loading this second stage bootloader from flash. - * The hardware is mostly uninitialized, flash cache is down and the app CPU is in reset. - * We do have a stack, so we can do the initialization in C. - */ -void call_start_cpu0() +//#define BOOT_DEBUG + +#ifdef BOOT_DEBUG +#define BDEBUG ets_printf +#else +#define BDEBUG(...) +#endif + +#define BOOT_VERSION 0x06 + +typedef enum { + SPI_FLASH_QIO_MODE = 0, + SPI_FLASH_QOUT_MODE, + SPI_FLASH_DIO_MODE, + SPI_FLASH_DOUT_MODE, + SPI_FLASH_FASTRD_MODE, + SPI_FLASH_SLOWRD_MODE +} SpiFlashRdMode; + +enum { + SPI_MODE_QIO, + SPI_MODE_QOUT, + SPI_MODE_DIO, + SPI_MODE_DOUT +}; + +enum { + SPI_SPEED_40M, + SPI_SPEED_26M, + SPI_SPEED_20M, + SPI_SPEED_80M = 0xF +}; + +enum { + SPI_SIZE_4M_256_256 = 0, + SPI_SIZE_2M, + SPI_SIZE_8M_512_512, + SPI_SIZE_16M_512_512, + SPI_SIZE_32M_512_512, + SPI_SIZE_16M_1024_1024, + SPI_SIZE_32M_1024_1024 +}; + +enum { + USER_BIN1, + USER_BIN2 +}; + +#define SPI_SEC_SIZE 0x1000 + +struct save_hdr { + char flag; + char pad[3]; +}; + +struct boot_hdr { + char use_bin: 2; // low bit + char boot_status: 1; + char reverse: 5; + char version: 5; // low bit + char test_pass_flag: 1; + char test_start_flag: 1; + char enhance_boot_flag: 1; + char test_bin_addr[3]; + char user_bin_addr[3]; +}; + +struct boot_hdr_1 { + char use_bin: 4; + char flag: 4; + char pad[7]; +}; + +struct boot_hdr_2 { + char use_bin: 4; + char flag: 4; + char version; + char pad[6]; +}; + +struct flash_hdr { + char magic; + char blocks; + char spi_mode; //flag of flash read mode in unpackage and usage in future + char spi_speed: 4; // low bit + char spi_size_map: 4; + unsigned int entry_addr; +} ; + +struct block_hdr { + unsigned int load_addr; + unsigned int data_len; +} ; + +#define WIFI_PARAM_RF 0 +#define WIFI_PARAM_SAVE_0 1 +#define WIFI_PARAM_SAVE_1 2 +#define WIFI_PARAM_FLAG 3 + +typedef enum { + SPI_FLASH_RESULT_OK = 0, + SPI_FLASH_RESULT_ERR = 1, + SPI_FLASH_RESULT_TIMEOUT = 2 +} SpiFlashOpResult; + +extern SpiFlashOpResult SPIRead(uint32_t addr, void *dst, uint32_t size); +extern int ets_printf(const char* fmt, ...); +extern void *ets_memcpy(void *restrict to, const void *restrict from, size_t size); + +signed int get_flash_bin_addr(unsigned int bin_addr) { - // 1. Hardware initialization - if(bootloader_init() != ESP_OK){ - return; - } + char buf[16]; + struct flash_hdr* fhdr; + struct block_hdr* bhdr; - // 2. Select image to boot - esp_image_metadata_t image_data; - if(select_image(&image_data) != ESP_OK){ - return; - } + SPIRead(bin_addr, (unsigned int*)buf, 16); - // 3. Loading the selected image - bootloader_utility_load_image(&image_data); -} + fhdr = (struct flash_hdr*)buf; -// Selects image to boot -static esp_err_t select_image (esp_image_metadata_t *image_data) -{ - // 1. Load partition table - bootloader_state_t bs = { 0 }; - if (!bootloader_utility_load_partition_table(&bs)) { - ESP_LOGE(TAG, "load partition table error!"); - return ESP_FAIL; - } - - // 2. Select boot partition - int boot_index = selected_boot_partition(&bs); - if(boot_index == INVALID_INDEX) { - return ESP_FAIL; // Unrecoverable failure (not due to corrupt ota data or bad partition contents) - } - - // 3. Load the app image for booting - if (!bootloader_utility_load_boot_image(&bs, boot_index, image_data)) { - return ESP_FAIL; - } - return ESP_OK; -} - -/* - * Selects a boot partition. - * The conditions for switching to another firmware are checked. - */ -static int selected_boot_partition(const bootloader_state_t *bs) -{ - int boot_index = bootloader_utility_get_selected_boot_partition(bs); - if (boot_index == INVALID_INDEX) { - return boot_index; // Unrecoverable failure (not due to corrupt ota data or bad partition contents) + if (fhdr->magic == 0xE9) { + return 0; + } else if (fhdr->magic == 0xEA && fhdr->blocks == 0x04) { + bhdr = (struct block_hdr*)(buf + sizeof(struct flash_hdr)); + return bhdr->data_len; } else { - // Factory firmware. -#ifdef CONFIG_BOOTLOADER_FACTORY_RESET - if (bootloader_common_check_long_hold_gpio(CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET, CONFIG_BOOTLOADER_HOLD_TIME_GPIO) == 1) { - ESP_LOGI(TAG, "Detect a condition of the factory reset"); - bool ota_data_erase = false; -#ifdef CONFIG_BOOTLOADER_OTA_DATA_ERASE - ota_data_erase = true; -#endif - const char *list_erase = CONFIG_BOOTLOADER_DATA_FACTORY_RESET; - ESP_LOGI(TAG, "Data partitions to erase: %s", list_erase); - if (bootloader_common_erase_part_type_data(list_erase, ota_data_erase) == false) { - ESP_LOGE(TAG, "Not all partitions were erased"); - } - return bootloader_utility_get_selected_boot_partition(bs); - } -#endif - // TEST firmware. -#ifdef CONFIG_BOOTLOADER_APP_TEST - if (bootloader_common_check_long_hold_gpio(CONFIG_BOOTLOADER_NUM_PIN_APP_TEST, CONFIG_BOOTLOADER_HOLD_TIME_GPIO) == 1) { - ESP_LOGI(TAG, "Detect a boot condition of the test firmware"); - if (bs->test.offset != 0) { - boot_index = TEST_APP_INDEX; - return boot_index; - } else { - ESP_LOGE(TAG, "Test firmware is not found in partition table"); - return INVALID_INDEX; - } - } -#endif - // Customer implementation. - // if (gpio_pin_1 == true && ...){ - // boot_index = required_boot_partition; - // } ... + ets_printf("error magic!\n"); + return -1; } - return boot_index; +} + +// 0---OK, 1---FAIL +char jump_to_run_addr(unsigned int bin_addr) +{ + unsigned int flash_addr; + char ret = 1; + char(*jump_to_load_flash_code)(unsigned int addr); + + ets_printf(" @ %x\n\n", bin_addr); + + jump_to_load_flash_code = (void*)(0x4010FC08); + flash_addr = get_flash_bin_addr(bin_addr); + + if (flash_addr != -1) { + if (flash_addr == 0) { + ret = jump_to_load_flash_code(bin_addr); + } else { + ret = jump_to_load_flash_code(bin_addr + 16 + flash_addr); + } + } + + return ret; +} + +unsigned int gen_bin_addr(unsigned char* buf) +{ + unsigned int ret; + + ret = buf[2] << 16 | buf[1] << 8 | buf[0]; + + return ret; +} + +void call_start_cpu(void) +{ + struct save_hdr shdr; + struct boot_hdr bhdr; + struct flash_hdr fhdr; + + unsigned int sys_start; + + ets_printf("\n2nd boot version : 2.0\n"); + + SPIRead(0, (unsigned int*)&fhdr, sizeof(struct flash_hdr)); + + BDEBUG("[D]: magic %02x\n", fhdr.magic); + BDEBUG("[D]: blocks %02x\n", fhdr.blocks); + BDEBUG("[D]: spi_mode %02x\n", fhdr.spi_mode); + BDEBUG("[D]: spi_speed %02x\n", fhdr.spi_speed); + BDEBUG("[D]: spi_size_map %02x\n", fhdr.spi_size_map); + + ets_printf(" SPI Speed : "); + + switch (fhdr.spi_speed) { + case SPI_SPEED_40M: + ets_printf("40MHz\n"); + break; + + case SPI_SPEED_26M: + ets_printf("26.7MHz\n"); + break; + + case SPI_SPEED_20M: + ets_printf("20MHz\n"); + break; + + case SPI_SPEED_80M: + ets_printf("80MHz\n"); + break; + } + + ets_printf(" SPI Mode : "); + + switch (fhdr.spi_mode) { + case SPI_MODE_QIO: + ets_printf("QIO\n"); + break; + + case SPI_MODE_QOUT: + ets_printf("QOUT\n"); + break; + + case SPI_MODE_DIO: + ets_printf("DIO\n"); + break; + + case SPI_MODE_DOUT: + ets_printf("DOUT\n"); + break; + + default: + fhdr.spi_mode = SPI_MODE_QIO; + ets_printf("QIO\n"); + break; + } + + ets_printf(" SPI Flash Size & Map: "); + + switch (fhdr.spi_size_map) { + case SPI_SIZE_4M_256_256: + sys_start = 124; + ets_printf("4Mbit(256KB+256KB)\n"); + break; + + case SPI_SIZE_2M: + sys_start = 60; + ets_printf("2Mbit\n"); + break; + + case SPI_SIZE_8M_512_512: + sys_start = 252; + ets_printf("8Mbit(512KB+512KB)\n"); + break; + + case SPI_SIZE_16M_512_512: + sys_start = 508; + ets_printf("16Mbit(512KB+512KB)\n"); + break; + + case SPI_SIZE_32M_512_512: + sys_start = 1020; + ets_printf("32Mbit(512KB+512KB)\n"); + break; + + case SPI_SIZE_16M_1024_1024: + sys_start = 508; + ets_printf("16Mbit(1024KB+1024KB)\n"); + break; + + case SPI_SIZE_32M_1024_1024: + sys_start = 1020; + ets_printf("32Mbit(1024KB+1024KB)\n"); + break; + + default: + sys_start = 124; + ets_printf("4Mbit\n"); + break; + } + + SPIRead((sys_start + WIFI_PARAM_FLAG) * SPI_SEC_SIZE, + (unsigned int*)&shdr, sizeof(struct save_hdr)); + + SPIRead((sys_start + ((shdr.flag == 0) ? WIFI_PARAM_SAVE_0 : WIFI_PARAM_SAVE_1)) * SPI_SEC_SIZE, + (unsigned int*)&bhdr, sizeof(struct boot_hdr)); + + BDEBUG("[D]: use_bin %02x\n", bhdr.use_bin); + BDEBUG("[D]: boot_status %02x\n", bhdr.boot_status); + BDEBUG("[D]: reverse %02x\n", bhdr.reverse); + BDEBUG("[D]: version %02x\n", bhdr.version); + BDEBUG("[D]: test_pass_flag %02x\n", bhdr.test_pass_flag); + BDEBUG("[D]: test_start_flag %02x\n", bhdr.test_start_flag); + BDEBUG("[D]: enhance_boot_flag %02x\n", bhdr.enhance_boot_flag); + BDEBUG("[D]: test_bin_addr %02x %02x %02x\n", bhdr.test_bin_addr[0], bhdr.test_bin_addr[1], bhdr.test_bin_addr[2]); + BDEBUG("[D]: user_bin_addr %02x %02x %02x\n", bhdr.user_bin_addr[0], bhdr.user_bin_addr[1], bhdr.user_bin_addr[2]); + + ets_memcpy((void *)0x4010FC00, load_bin, load_bin_len); + + ets_printf("jump to run"); + + jump_to_run_addr(0x1000); } diff --git a/components/bootloader/subproject/main/esp8266.bootloader.rom.ld b/components/bootloader/subproject/main/esp8266.bootloader.rom.ld index e69de29b..4fcd79a0 100644 --- a/components/bootloader/subproject/main/esp8266.bootloader.rom.ld +++ b/components/bootloader/subproject/main/esp8266.bootloader.rom.ld @@ -0,0 +1,4 @@ +PROVIDE ( ets_memcpy = 0x400018b4 ); +PROVIDE ( ets_printf = 0x400024cc ); + +PROVIDE ( SPIRead = 0x40004b1c ); \ No newline at end of file diff --git a/components/bootloader/subproject/main/load_flash_bin.h b/components/bootloader/subproject/main/load_flash_bin.h new file mode 100644 index 00000000..8317f42f --- /dev/null +++ b/components/bootloader/subproject/main/load_flash_bin.h @@ -0,0 +1,68 @@ +unsigned char load_bin[] = { + 0x1c, 0x4b, 0x00, 0x40, 0xb4, 0x18, 0x00, 0x40, 0x1c, 0x04, 0x12, 0xc1, + 0xa0, 0xd9, 0xd1, 0xe9, 0xe1, 0xf9, 0xf1, 0x3d, 0x01, 0xc9, 0xc1, 0x09, + 0xb1, 0x01, 0xf9, 0xff, 0xcd, 0x02, 0xc0, 0x00, 0x00, 0x56, 0x72, 0x1c, + 0x32, 0xa0, 0xe9, 0x22, 0x01, 0x00, 0xf8, 0x11, 0x30, 0x22, 0xc0, 0x32, + 0x01, 0x01, 0x39, 0xa1, 0x56, 0x42, 0x1b, 0x3d, 0x01, 0x1c, 0x04, 0x02, + 0x01, 0x08, 0x22, 0x01, 0x0a, 0xe2, 0x01, 0x0b, 0xd2, 0x01, 0x0f, 0x80, + 0xee, 0x11, 0x80, 0xdd, 0x11, 0x20, 0xee, 0x20, 0x22, 0x01, 0x09, 0x80, + 0xee, 0x11, 0x20, 0xee, 0x20, 0x22, 0x01, 0x0e, 0x80, 0xee, 0x11, 0x00, + 0xee, 0x20, 0x20, 0xdd, 0x20, 0x02, 0x01, 0x0c, 0x22, 0x01, 0x0d, 0x80, + 0xdd, 0x11, 0x20, 0xdd, 0x20, 0x80, 0xdd, 0x11, 0x00, 0xdd, 0x20, 0x01, + 0xe2, 0xff, 0x22, 0xcc, 0x10, 0xc0, 0x00, 0x00, 0x56, 0x82, 0x16, 0xf9, + 0x91, 0xe2, 0x61, 0x13, 0x22, 0xcc, 0x20, 0x08, 0xa1, 0x22, 0x61, 0x12, + 0x16, 0x50, 0x21, 0xfd, 0x01, 0xc2, 0xa0, 0xef, 0x1c, 0x0a, 0xd2, 0x61, + 0x14, 0x2d, 0x0e, 0x0c, 0x07, 0x72, 0x61, 0x11, 0xed, 0x01, 0x0d, 0x02, + 0x0c, 0x17, 0x62, 0x21, 0x11, 0x82, 0x21, 0x14, 0x60, 0x6a, 0xc0, 0x60, + 0x60, 0x74, 0x67, 0xb8, 0x01, 0x0c, 0x07, 0x16, 0x47, 0x1f, 0x0c, 0x39, + 0x67, 0x09, 0x1c, 0xa6, 0x16, 0x4f, 0x0c, 0x0d, 0x1b, 0xdd, 0x22, 0x0f, + 0x00, 0x22, 0x40, 0x00, 0x1b, 0xff, 0x1b, 0x00, 0xc0, 0xc2, 0x30, 0xc0, + 0xc0, 0x74, 0x67, 0x9d, 0xea, 0x46, 0x0d, 0x00, 0xbc, 0x26, 0x2d, 0x00, + 0x60, 0x92, 0x41, 0xa6, 0x19, 0x29, 0x0c, 0x0d, 0x1b, 0xdd, 0x42, 0x0f, + 0x01, 0x02, 0x0f, 0x03, 0x32, 0x0f, 0x00, 0xc0, 0x00, 0x30, 0xc2, 0x0f, + 0x02, 0x40, 0x33, 0x30, 0x30, 0xcc, 0x30, 0x00, 0xcc, 0x30, 0xc0, 0xc0, + 0x74, 0x08, 0x0f, 0x09, 0x02, 0x4b, 0xff, 0x4b, 0x22, 0x97, 0x9d, 0xd7, + 0x0d, 0x02, 0x16, 0x97, 0x19, 0x60, 0x28, 0xc0, 0x20, 0x24, 0x41, 0x22, + 0x61, 0x10, 0x79, 0x71, 0x32, 0x21, 0x10, 0x42, 0x21, 0x11, 0x0c, 0x05, + 0x4a, 0x68, 0x40, 0x40, 0x74, 0x62, 0xc6, 0xf0, 0x60, 0x60, 0x34, 0x70, + 0x45, 0x93, 0x42, 0x61, 0x11, 0x70, 0x68, 0x83, 0x69, 0x81, 0xa6, 0x13, + 0x4c, 0x0c, 0x0d, 0x09, 0x61, 0x22, 0x21, 0x12, 0x3d, 0x01, 0x01, 0xac, + 0xff, 0x1c, 0x04, 0xc0, 0x00, 0x00, 0x56, 0x22, 0x09, 0x22, 0x21, 0x12, + 0x0c, 0x00, 0x22, 0xc2, 0x10, 0x22, 0x61, 0x12, 0x1b, 0x30, 0xea, 0x20, + 0x22, 0x02, 0x00, 0x30, 0x00, 0x74, 0xc0, 0xc2, 0x30, 0xc0, 0xc0, 0x74, + 0x66, 0xb0, 0xec, 0x28, 0x61, 0x3d, 0x01, 0x01, 0xa2, 0xff, 0x1c, 0x04, + 0xc0, 0x00, 0x00, 0x1b, 0xdd, 0x08, 0x61, 0x22, 0x21, 0x10, 0x02, 0xc0, + 0x10, 0x09, 0x61, 0xd7, 0x92, 0xb6, 0x38, 0x71, 0x09, 0x61, 0x9c, 0xb3, + 0x22, 0x21, 0x12, 0x3d, 0x01, 0x01, 0x98, 0xff, 0x1c, 0x04, 0xc0, 0x00, + 0x00, 0x08, 0x61, 0x56, 0x12, 0x04, 0x22, 0x21, 0x12, 0xfd, 0x01, 0x22, + 0xc2, 0x10, 0x22, 0x61, 0x12, 0x68, 0x81, 0x0c, 0x33, 0x60, 0x60, 0x74, + 0x67, 0x83, 0x02, 0x06, 0x3e, 0x00, 0xa6, 0x16, 0x16, 0x0c, 0x0d, 0x1b, + 0xdd, 0x22, 0x0f, 0x00, 0x22, 0x40, 0x00, 0x1b, 0xff, 0x1b, 0x00, 0xc0, + 0xc2, 0x30, 0xc0, 0xc0, 0x74, 0x67, 0x9d, 0xea, 0x38, 0xa1, 0x1c, 0x0a, + 0x66, 0x13, 0x19, 0x42, 0x01, 0x0f, 0xc0, 0x44, 0xc0, 0x16, 0xc4, 0x0b, + 0x0c, 0x12, 0xc8, 0xc1, 0xd8, 0xd1, 0xe8, 0xe1, 0xf8, 0xf1, 0x08, 0xb1, + 0x12, 0xc1, 0x60, 0x0d, 0xf0, 0x02, 0x21, 0x11, 0x0a, 0x06, 0x00, 0xda, + 0xc0, 0xd0, 0xd0, 0x74, 0xb6, 0x8d, 0x46, 0x92, 0x0f, 0x06, 0x32, 0x0f, + 0x02, 0x82, 0x0f, 0x07, 0x22, 0x0f, 0x03, 0x80, 0x88, 0x11, 0x80, 0x22, + 0x11, 0x30, 0x22, 0x20, 0x90, 0x88, 0x20, 0x32, 0x0f, 0x01, 0x80, 0x22, + 0x11, 0x92, 0x0f, 0x05, 0x80, 0x88, 0x11, 0x90, 0x88, 0x20, 0x30, 0x22, + 0x20, 0x92, 0x0f, 0x04, 0x80, 0x88, 0x11, 0x32, 0x0f, 0x00, 0x80, 0x22, + 0x11, 0x30, 0x22, 0x20, 0x90, 0x88, 0x20, 0x8b, 0x30, 0x30, 0x30, 0x74, + 0x32, 0x61, 0x11, 0x06, 0x10, 0x00, 0x22, 0xc1, 0x10, 0xea, 0x30, 0x01, + 0x6b, 0xff, 0x4d, 0x0d, 0xc0, 0x00, 0x00, 0x22, 0x21, 0x12, 0x3d, 0x01, + 0x01, 0x67, 0xff, 0x1c, 0x04, 0xc0, 0x00, 0x00, 0xfc, 0x92, 0x01, 0x65, + 0xff, 0x32, 0x21, 0x12, 0x0c, 0x84, 0x22, 0xc1, 0x10, 0x2a, 0x2d, 0xd0, + 0x44, 0xc0, 0x40, 0x40, 0x74, 0x32, 0xc3, 0x10, 0x32, 0x61, 0x12, 0x42, + 0x61, 0x11, 0x3d, 0x01, 0xc0, 0x00, 0x00, 0x28, 0x41, 0x88, 0x51, 0x1c, + 0x0a, 0x82, 0x61, 0x14, 0xf2, 0x21, 0x11, 0x48, 0xa1, 0xea, 0xff, 0x0b, + 0x04, 0x00, 0x40, 0x74, 0x49, 0xa1, 0x56, 0xc4, 0xdf, 0x08, 0x91, 0xc0, + 0x00, 0x00, 0x0c, 0x02, 0x86, 0xce, 0xff, 0x0c, 0x02, 0x22, 0x61, 0x10, + 0x86, 0x99, 0xff, 0x16, 0xd6, 0xf1, 0x2d, 0x00, 0x60, 0x72, 0x41, 0xe6, + 0x17, 0x02, 0x86, 0xc4, 0xff, 0x0c, 0x0d, 0x1b, 0xdd, 0x42, 0x0f, 0x01, + 0x02, 0x0f, 0x03, 0x32, 0x0f, 0x00, 0xc0, 0x00, 0x30, 0xc2, 0x0f, 0x02, + 0x40, 0x33, 0x30, 0x30, 0xcc, 0x30, 0x00, 0xcc, 0x30, 0xc0, 0xc0, 0x74, + 0x08, 0x0f, 0x09, 0x02, 0x4b, 0xff, 0x4b, 0x22, 0x77, 0x9d, 0xd7, 0x46, + 0xb9, 0xff, 0x00, 0x00 +}; + +unsigned int load_bin_len = 760;