Exemple #1
0
// prevent this function being placed inline with main
// to keep main's stack size as small as possible
static uint32 NOINLINE find_image() {
	
	uint8 flag;
	uint32 runAddr;
	uint32 flashsize;
	int32 romToBoot;
	uint8 gpio_boot = FALSE;
	uint8 updateConfig = TRUE;
	uint8 buffer[SECTOR_SIZE];
	
	rboot_config *romconf = (rboot_config*)buffer;
	rom_header *header = (rom_header*)buffer;
	
	ets_delay_us(2000000);
	
	ets_printf("\r\nrBoot v1.0.0 - [email protected]\r\n");
	
	// read rom header
	SPIRead(0, header, sizeof(rom_header));
	
	// print and get flash size
	ets_printf("Flash Size:	 ");
	flag = header->flags2 >> 4;
	if (flag == 0) {
		ets_printf("4 Mbit\r\n");
		flashsize = 0x80000;
	} else if (flag == 1) {
		ets_printf("2 Mbit\r\n");
		flashsize = 0x40000;
	} else if (flag == 2) {
		ets_printf("8 Mbit\r\n");
		flashsize = 0x100000;
	} else if (flag == 3) {
		ets_printf("16 Mbit\r\n");
		flashsize = 0x200000;
	} else if (flag == 4) {
		ets_printf("32 Mbit\r\n");
		flashsize = 0x400000;
	} else {
		ets_printf("unknown\r\n");
		// assume at least 4mbit
		flashsize = 0x80000;
	}
	
	// print spi mode
	ets_printf("Flash Mode:	 ");
	if (header->flags1 == 0) {
		ets_printf("QIO\r\n");
	} else if (header->flags1 == 1) {
		ets_printf("QOUT\r\n");
	} else if (header->flags1 == 2) {
		ets_printf("DIO\r\n");
	} else if (header->flags1 == 3) {
		ets_printf("DOUT\r\n");
	} else {
		ets_printf("unknown\r\n");
	}
	
	// print spi speed
	ets_printf("Flash Speed: ");
	flag = header->flags2 & 0x0f;
	if (flag == 0) ets_printf("40 MHz\r\n");
	else if (flag == 1) ets_printf("26.7 MHz\r\n");
	else if (flag == 2) ets_printf("20 MHz\r\n");
	else if (flag == 0x0f) ets_printf("80 MHz\r\n");
	else ets_printf("unknown\r\n");
	
	// read boot config
	SPIRead(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE);
	// fresh install or old version?
	if (romconf->magic != BOOT_CONFIG_MAGIC || romconf->version != BOOT_CONFIG_VERSION) {
		// create a default config for a standard 2 rom setup
		ets_printf("Writing default boot config.\r\n");
		ets_memset(romconf, 0x00, sizeof(rboot_config));
		romconf->magic = BOOT_CONFIG_MAGIC;
		romconf->version = BOOT_CONFIG_VERSION;
		romconf->mode = MODE_STANDARD;
		romconf->current_rom = 0;
		romconf->count = 2;
		romconf->current_rom = 0;
		romconf->roms[0] = SECTOR_SIZE * 2;
		romconf->roms[1] = (flashsize / 2) + (SECTOR_SIZE * 2);
		// write new config sector
		SPIEraseSector(BOOT_CONFIG_SECTOR);
		SPIWrite(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE);
	}
	
	// if gpio mode enabled check status of the gpio
	if ((romconf->mode & MODE_GPIO_ROM) && (get_gpio16() == 0)) {
		ets_printf("Booting GPIO-selected.\r\n");
		romToBoot = romconf->gpio_rom;
		gpio_boot = TRUE;
	} else if (romconf->current_rom >= romconf->count) {
		// if invalid rom selected try rom 0
		ets_printf("Invalid rom selected, defaulting.\r\n");
		romToBoot = 0;
		romconf->current_rom = 0;
		updateConfig = TRUE;
	} else {
		// try rom selected in the config
		romToBoot = romconf->current_rom;
	}
	
	// try to find a good rom
	do {
		runAddr = check_image(romconf->roms[romToBoot]);
		if (runAddr == 0) {
			ets_printf("Rom %d is bad.\r\n", romToBoot);
			if (gpio_boot) {
				// don't switch to backup for gpio-selected rom
				ets_printf("GPIO boot failed.\r\n");
				return 0;
			} else {
				// for normal mode try each previous rom
				// until we find a good one or run out
				updateConfig = TRUE;
				romToBoot--;
				if (romToBoot < 0) romToBoot = romconf->count - 1;
				if (romToBoot == romconf->current_rom) {
					// tried them all and all are bad!
					ets_printf("No good rom available.\r\n");
					return 0;
				}
			}
		}
	} while (runAddr == 0);
	
	// re-write config, if required
	if (updateConfig) {
		romconf->current_rom = romToBoot;
		SPIEraseSector(BOOT_CONFIG_SECTOR);
		SPIWrite(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE);
	}
	
	ets_printf("Booting rom %d.\r\n", romToBoot);
	// copy the loader to top of iram
	ets_memcpy((void*)_text_addr, _text_data, _text_len);
	// return address to load from
	return runAddr;

}
Exemple #2
0
// prevent this function being placed inline with main
// to keep main's stack size as small as possible
// don't mark as static or it'll be optimised out when
// using the assembler stub
uint32 NOINLINE find_image() {

	uint8 flag;
	uint32 runAddr;
	uint32 flashsize;
	int32 romToBoot;
	uint8 gpio_boot = FALSE;
	uint8 updateConfig = TRUE;
	uint8 buffer[SECTOR_SIZE];

	rboot_config *romconf = (rboot_config*)buffer;
	rom_header *header = (rom_header*)buffer;

	// delay to slow boot (help see messages when debugging)
	//ets_delay_us(2000000);

	ets_printf("\r\nrBoot v1.2.1 - [email protected]\r\n");

	// read rom header
	SPIRead(0, header, sizeof(rom_header));

	// print and get flash size
	ets_printf("Flash Size:   ");
	flag = header->flags2 >> 4;
	if (flag == 0) {
		ets_printf("4 Mbit\r\n");
		flashsize = 0x80000;
	} else if (flag == 1) {
		ets_printf("2 Mbit\r\n");
		flashsize = 0x40000;
	} else if (flag == 2) {
		ets_printf("8 Mbit\r\n");
		flashsize = 0x100000;
	} else if (flag == 3) {
		ets_printf("16 Mbit\r\n");
#ifdef BOOT_BIG_FLASH
		flashsize = 0x200000;
#else
		flashsize = 0x100000; // limit to 8Mbit
#endif
	} else if (flag == 4) {
		ets_printf("32 Mbit\r\n");
#ifdef BOOT_BIG_FLASH
		flashsize = 0x400000;
#else
		flashsize = 0x100000; // limit to 8Mbit
#endif
	} else {
		ets_printf("unknown\r\n");
		// assume at least 4mbit
		flashsize = 0x80000;
	}

	// print spi mode
	ets_printf("Flash Mode:   ");
	if (header->flags1 == 0) {
		ets_printf("QIO\r\n");
	} else if (header->flags1 == 1) {
		ets_printf("QOUT\r\n");
	} else if (header->flags1 == 2) {
		ets_printf("DIO\r\n");
	} else if (header->flags1 == 3) {
		ets_printf("DOUT\r\n");
	} else {
		ets_printf("unknown\r\n");
	}

	// print spi speed
	ets_printf("Flash Speed:  ");
	flag = header->flags2 & 0x0f;
	if (flag == 0) ets_printf("40 MHz\r\n");
	else if (flag == 1) ets_printf("26.7 MHz\r\n");
	else if (flag == 2) ets_printf("20 MHz\r\n");
	else if (flag == 0x0f) ets_printf("80 MHz\r\n");
	else ets_printf("unknown\r\n");

	// print enabled options
#ifdef BOOT_BIG_FLASH
	ets_printf("rBoot Option: Big flash\r\n");
#endif
#ifdef BOOT_CONFIG_CHKSUM
	ets_printf("rBoot Option: Config chksum\r\n");
#endif
#ifdef BOOT_IROM_CHKSUM
	ets_printf("rBoot Option: irom chksum\r\n");
#endif

	ets_printf("\r\n");

	// read boot config
	SPIRead(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE);
	// fresh install or old version?
	if (romconf->magic != BOOT_CONFIG_MAGIC || romconf->version != BOOT_CONFIG_VERSION
#ifdef BOOT_CONFIG_CHKSUM
		|| romconf->chksum != calc_chksum((uint8*)romconf, (uint8*)&romconf->chksum)
#endif
		) {
		/* Modified by Cesanta */
		ets_printf("Writing default boot config.\r\n");
		ets_memset(romconf, 0x00, sizeof(rboot_config));
		romconf->magic = BOOT_CONFIG_MAGIC;
		romconf->version = BOOT_CONFIG_VERSION;
		romconf->count = 2;
		romconf->mode = MODE_STANDARD;
		/* FWx_ADDR, FWx_FS_ADDR and FS_SIZE, FW_SIZE must be defined by -D */
		romconf->roms[0] = FW1_ADDR;
		romconf->roms[1] = FW2_ADDR;
		romconf->fs_addresses[0] = FW1_FS_ADDR;
		romconf->fs_addresses[1] = FW2_FS_ADDR;
		romconf->fs_sizes[0] = romconf->fs_sizes[1] = FS_SIZE;
		romconf->roms_sizes[0] = romconf->roms_sizes[1] = FW_SIZE;
#ifdef BOOT_CONFIG_CHKSUM
		romconf->chksum = calc_chksum((uint8*)romconf, (uint8*)&romconf->chksum);
#endif
		// write new config sector
		SPIEraseSector(BOOT_CONFIG_SECTOR);
		SPIWrite(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE);
	}

	// if gpio mode enabled check status of the gpio
	if ((romconf->mode & MODE_GPIO_ROM) && (get_gpio16() == 0)) {
		ets_printf("Booting GPIO-selected.\r\n");
		romToBoot = romconf->previous_rom;
		/*
		 * Modified by Cesanta
		 * Make FD current
		 */
		updateConfig = TRUE;
		romconf->fw_updated = 0;
		romconf->is_first_boot = 0;
		gpio_boot = TRUE;
	} else if (romconf->current_rom >= romconf->count) {
		// if invalid rom selected try rom 0
		ets_printf("Invalid rom selected, defaulting.\r\n");
		romToBoot = 0;
		romconf->current_rom = 0;
		romconf->fw_updated = 0;
		romconf->is_first_boot = 0;
		updateConfig = TRUE;
	} else {
		/* Modified by Cesanta */
		if (romconf->is_first_boot != 0) {
				ets_printf("First boot, attempt %d\n", romconf->boot_attempts);
			/* boot is unconfirmed */
			if (romconf->boot_attempts == 0) {
				/* haven't try to load yes */
				ets_printf("Boot is unconfirmed\r\n");
				romconf->boot_attempts++;
			} else {
				ets_printf("Boot failed, fallback to fw #%d\r\n",
											romconf->previous_rom);
				romconf->current_rom = romconf->previous_rom;
				/* clear fw update flag, to avoid post-update acttions */
				romconf->fw_updated = 0;
				romconf->boot_attempts = 0;
			}

			updateConfig = TRUE;
		}
		/* End of Cesanta modifications */
		// try rom selected in the config
		romToBoot = romconf->current_rom;
	}

	// try to find a good rom
	do {
		runAddr = check_image(romconf->roms[romToBoot]);
		if (runAddr == 0) {
			ets_printf("Rom %d is bad.\r\n", romToBoot);
			if (gpio_boot) {
				// don't switch to backup for gpio-selected rom
				ets_printf("GPIO boot failed.\r\n");
				return 0;
			} else {
				// for normal mode try each previous rom
				// until we find a good one or run out
				updateConfig = TRUE;
				romToBoot--;
				if (romToBoot < 0) romToBoot = romconf->count - 1;
				if (romToBoot == romconf->current_rom) {
					// tried them all and all are bad!
					ets_printf("No good rom available.\r\n");
					return 0;
				}
			}
		}
	} while (runAddr == 0);

	// re-write config, if required
	if (updateConfig) {
		romconf->current_rom = romToBoot;
#ifdef BOOT_CONFIG_CHKSUM
		romconf->chksum = calc_chksum((uint8*)romconf, (uint8*)&romconf->chksum);
#endif
		SPIEraseSector(BOOT_CONFIG_SECTOR);
		SPIWrite(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE);
	}

	ets_printf("Booting rom %d.\r\n", romToBoot);
	// copy the loader to top of iram
	ets_memcpy((void*)_text_addr, _text_data, _text_len);
	// return address to load from
	return runAddr;

}