static int load_file(const char* path,unsigned long addr) { char buffer[256]; const char *filesize_str; unsigned long filesize=0; setenv("filesize", "0"); sprintf(buffer, "fatload usb 0:1 0x%X %s", addr, path); if(bsb_run(buffer)) { filesize_str = getenv("filesize"); if (filesize_str != NULL) filesize = simple_strtoul(filesize_str, NULL, 16); return filesize; } return -1; }
static void try_autorun() { char* command=getenv("autorun"); if(command) { bsb_run(command); } }
static int usb_flash_image(int partition, int filesize, unsigned long addr) { if(partition >= 0) { char buffer[256]; unsigned long addr_in_flash=0; switch(partition) { case 0: addr_in_flash=CFG_FLASH_BASE; // U-Boot printf("Update 'u-boot' partition...\n"); break; case 1: addr_in_flash=CFG_ENV_ADDR; // U-Boot env printf("Update 'u-boot-env' partition...\n"); break; case 2: addr_in_flash=CFG_LOAD_ADDR; // firmware printf("Update 'firmware' partition...\n"); break; case 3: addr_in_flash=CFG_FLASH_BASE+OFFSET_MAC_DATA_BLOCK; // ART printf("Update 'art' partition...\n"); break; case 4: addr_in_flash=CFG_FLASH_BASE; // full memory dump, all partitions printf("Update all partitions from binary dump...\n"); break; } sprintf(buffer, "erase 0x%X +0x%X; cp.b 0x%X 0x%X 0x%X", addr_in_flash, filesize, addr, addr_in_flash, filesize); if(bsb_run(buffer)) { blink_led(3,250); printf("Partition successfully updated\n"); return 0; } else { blink_led(10,100); printf("Partition update failed\n"); return -1; } } }
static void openwrt_factory_reset() { struct jffs2_unknown_node *node; u32 i; u32 crc; printf("Searching for JFFS2 filesystem\n"); for (i = CFG_LOAD_ADDR; i < CFG_LOAD_ADDR + 0xFC0000; i++) { node = (struct jffs2_unknown_node *) i; if (node->magic == JFFS2_MAGIC_BITMASK) { crc = crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4); if (crc == node->hdr_crc) { printf("JFFS2 Magic Bitmask with correct CRC at 0x%X\n", node); printf("Replacing Magic Bitmask with 0xDEADCODE...\n"); static unsigned char eof_mark[4] = {0xde, 0xad, 0xc0, 0xde}; static unsigned char *pad = eof_mark; char buffer[256]; sprintf(buffer, "erase 0x%X +0x%X; cp.b 0x%X 0x%X 0x%X", node, 4, pad, node, 4); if(bsb_run(buffer)) { blink_led(3,250); printf("Done\n"); } else { blink_led(10,100); printf("Error writing to flash\n"); } bsb_run("reset"); } } } printf("JFFS2 not found.\n"); blink_led(10,100); }
static void try_runonce(int stage) { char* command=NULL; char var[10]; sprintf(var,"runonce%d",stage); command=getenv(var); if(command) { char cmd_erase[40]; char cmd_run[200]; strcpy(cmd_run,command); sprintf(cmd_erase,"setenv %s; saveenv; printenv",var); bsb_run(cmd_erase); bsb_run(cmd_run); } }
static void usb_upgrade(void) { int needReset=0; if(bsb_run("usb reset")) { char buffer[256]; const char *addr_str; unsigned long addr=0; int filesize=0; int was_show_error=show_partition_error; show_partition_error=0; addr_str = getenv("loadaddr"); if (addr_str != NULL) addr = simple_strtoul(addr_str, NULL, 16); else addr = CONFIG_SYS_LOAD_ADDR; // executing autorun script if((filesize=load_file("_fw/autorun",addr)) > 0) { show_partition_error=was_show_error; printf("Autorun script is found.\n"); if(filesize < 0x10000) { char script[0x10000]; char *pDst=script; char *pSrc=(char*)addr; char *pEnd=pSrc+filesize; while(pSrc < pEnd) { char next=*pSrc++; if(next == '\n') { *pDst++=';'; } else if(next == '\r') { // just skip it } else { *pDst++=next; } } *pDst=0; bsb_run(script); blink_led(3,250); } else { blink_led(10,100); printf("Error: autorun script is too big (0x10000 or more)!\n"); } } else // if autorun script was executed, no reflashing will be done { // updating flash partitions int partition=-1; // whole flash dump, 16Mbytes filesize=load_file("_fw/dump.bin",addr); if(filesize == 0x1000000) { partition=4; show_partition_error=was_show_error; if(usb_flash_image(partition, filesize, addr) >= 0 ) { needReset=1; } } filesize=load_file("_fw/u-boot.bin",addr); if(filesize == 0x20000) { partition=0; show_partition_error=was_show_error; if(usb_flash_image(partition, filesize, addr) >= 0 ) { needReset=1; } } filesize=load_file("_fw/u-boot-env.bin",addr); if(filesize == 0x10000) { partition=1; show_partition_error=was_show_error; if(usb_flash_image(partition, filesize, addr) >= 0 ) { needReset=1; } } filesize=load_file("_fw/firmware.bin",addr); if(filesize > 0) { partition=2; show_partition_error=was_show_error; if(usb_flash_image(partition, filesize, addr) >= 0 ) { needReset=1; } } filesize=load_file("_fw/openwrt-ar71xx-generic-unwone-squashfs-sysupgrade.bin",addr); if(filesize > 0) { partition=2; show_partition_error=was_show_error; if(usb_flash_image(partition, filesize, addr) >= 0 ) { needReset=1; } } filesize=load_file("_fw/art.bin",addr); if(filesize == 0x10000) { partition=3; show_partition_error=was_show_error; if(usb_flash_image(partition, filesize, addr) >= 0 ) { needReset=1; } } if(partition<0) { printf("No firmware files found.\n"); } // flashing MAC address // mac.bin is a file containing 6 bytes of it // mac.bin will be updated with the new address for the next board if(load_file("mac.bin",addr) == 6) { show_partition_error=was_show_error; // update mac address and increment source unsigned char *macByte=(unsigned char*)addr; unsigned short *macLastWord=((unsigned short*)addr)+2; sprintf(buffer, "setmac %02X:%02X:%02X:%02X:%02X:%02X", macByte[0], macByte[1], macByte[2], macByte[3], macByte[4], macByte[5]); bsb_run(buffer); *macLastWord=(*macLastWord)+4; // increment for the next board sprintf(buffer, "fatwrite usb 0:1 0x%X bsb_mac.bin 6", addr); if(bsb_run(buffer)) { blink_led(3,250); needReset=1; } else { blink_led(10,100); } } } } else { blink_led(10,100); printf("No USB storage found.\n"); } if(needReset) { bsb_run("reset"); } else { printf("Starting U-Boot console...\n"); } }