X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=board%2Ftrab%2Fauto_update.c;h=d2c8d44a79f87188ac87383da844491700a40474;hb=d10afb3916522801fb88c7ad9b6d82657be51567;hp=9371637e9258f31d7b42a0a4655a3c31b18af15e;hpb=1d70468b039b6ead903c9b14fa09005476259a65;p=oweals%2Fu-boot.git diff --git a/board/trab/auto_update.c b/board/trab/auto_update.c index 9371637e92..d2c8d44a79 100644 --- a/board/trab/auto_update.c +++ b/board/trab/auto_update.c @@ -57,9 +57,9 @@ * valid then run it. * 2) if preinst.img is found load it into memory. If it is * valid then run it. Update the EEPROM. - * 3) if firmware.img is found load it into memory. If it is valid, + * 3) if firmw_01.img is found load it into memory. If it is valid, * burn it into FLASH and update the EEPROM. - * 4) if kernel.img is found load it into memory. If it is valid, + * 4) if kernl_01.img is found load it into memory. If it is valid, * burn it into FLASH and update the EEPROM. * 5) if app.img is found load it into memory. If it is valid, * burn it into FLASH and update the EEPROM. @@ -81,8 +81,8 @@ /* possible names of files on the USB stick. */ #define AU_PREPARE "prepare.img" #define AU_PREINST "preinst.img" -#define AU_FIRMWARE "firmware.img" -#define AU_KERNEL "kernel.img" +#define AU_FIRMWARE "firmw_01.img" +#define AU_KERNEL "kernl_01.img" #define AU_APP "app.img" #define AU_DISK "disk.img" #define AU_POSTINST "postinst.img" @@ -105,14 +105,14 @@ struct flash_layout #define AU_FL_APP_ND 0x005BFFFF #define AU_FL_DISK_ST 0x005C0000 #define AU_FL_DISK_ND 0x00FFFFFF -#else /* 8 MB Flash, 16 MB RAM */ +#else /* 8 MB Flash, 32 MB RAM */ #define AU_FL_FIRMWARE_ST 0x00000000 -#define AU_FL_FIRMWARE_ND 0x0003FFFF -#define AU_FL_KERNEL_ST 0x00040000 -#define AU_FL_KERNEL_ND 0x0011FFFF -#define AU_FL_APP_ST 0x00120000 -#define AU_FL_APP_ND 0x003FFFFF -#define AU_FL_DISK_ST 0x00400000 +#define AU_FL_FIRMWARE_ND 0x0005FFFF +#define AU_FL_KERNEL_ST 0x00060000 +#define AU_FL_KERNEL_ND 0x0013FFFF +#define AU_FL_APP_ST 0x00140000 +#define AU_FL_APP_ND 0x0067FFFF +#define AU_FL_DISK_ST 0x00680000 #define AU_FL_DISK_ND 0x007DFFFF #define AU_FL_VFD_ST 0x007E0000 #define AU_FL_VFD_ND 0x007FFFFF @@ -183,11 +183,9 @@ struct flash_layout aufl_layout[AU_MAXFILES - 3] = { \ #define FIDX_TO_LIDX(idx) ((idx) - 2) /* where to load files into memory */ -#define LOAD_ADDR ((unsigned char *)0x0C100100) -/* where to build strings in memory - 256 bytes should be enough */ -#define STRING_ADDR ((char *)0x0C100000) -/* the disk is the largest image */ -#define MAX_LOADSZ ausize[IDX_DISK] +#define LOAD_ADDR ((unsigned char *)0x0C100000) +/* the app is the largest image */ +#define MAX_LOADSZ ausize[IDX_APP] /* externals */ extern int fat_register_device(block_dev_desc_t *, int); @@ -199,13 +197,42 @@ extern int i2c_write (uchar, uint, int , uchar* , int); extern int trab_vfd (ulong); extern int transfer_pic(unsigned char, unsigned char *, int, int); #endif +extern int flash_sect_erase(ulong, ulong); +extern int flash_sect_protect (int, ulong, ulong); +extern int flash_write (char *, ulong, ulong); /* change char* to void* to shutup the compiler */ extern int i2c_write_multiple (uchar, uint, int, void *, int); extern int i2c_read_multiple (uchar, uint, int, void *, int); extern block_dev_desc_t *get_dev (char*, int); +extern int u_boot_hush_start(void); int -au_check_valid(int idx, long nbytes) +au_check_cksum_valid(int idx, long nbytes) +{ + image_header_t *hdr; + unsigned long checksum; + + hdr = (image_header_t *)LOAD_ADDR; + + if (nbytes != (sizeof(*hdr) + ntohl(hdr->ih_size))) + { + printf ("Image %s bad total SIZE\n", aufile[idx]); + return -1; + } + /* check the data CRC */ + checksum = ntohl(hdr->ih_dcrc); + + if (crc32 (0, (uchar *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size)) + != checksum) + { + printf ("Image %s bad data checksum\n", aufile[idx]); + return -1; + } + return 0; +} + +int +au_check_header_valid(int idx, long nbytes) { image_header_t *hdr; unsigned long checksum; @@ -220,31 +247,25 @@ au_check_valid(int idx, long nbytes) printf("size %#x %#lx ", ntohl(hdr->ih_size), nbytes); printf("type %#x %#x ", hdr->ih_type, IH_TYPE_KERNEL); #endif - if (ntohl(hdr->ih_magic) != IH_MAGIC || - hdr->ih_arch != IH_CPU_ARM || - nbytes < ntohl(hdr->ih_size)) + if (nbytes < sizeof(*hdr)) { - printf ("Image %s bad MAGIC or ARCH or SIZE\n", aufile[idx]); + printf ("Image %s bad header SIZE\n", aufile[idx]); + return -1; + } + if (ntohl(hdr->ih_magic) != IH_MAGIC || hdr->ih_arch != IH_CPU_ARM) + { + printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]); return -1; } /* check the hdr CRC */ checksum = ntohl(hdr->ih_hcrc); hdr->ih_hcrc = 0; - if (crc32 (0, (char *)hdr, sizeof(*hdr)) != checksum) { + if (crc32 (0, (uchar *)hdr, sizeof(*hdr)) != checksum) { printf ("Image %s bad header checksum\n", aufile[idx]); return -1; } hdr->ih_hcrc = htonl(checksum); - /* check the data CRC */ - checksum = ntohl(hdr->ih_dcrc); - - if (crc32 (0, (char *)(LOAD_ADDR + sizeof(*hdr)), ntohl(hdr->ih_size)) - != checksum) - { - printf ("Image %s bad data checksum\n", aufile[idx]); - return -1; - } /* check the type - could do this all in one gigantic if() */ if ((idx == IDX_FIRMWARE) && (hdr->ih_type != IH_TYPE_FIRMWARE)) { printf ("Image %s wrong type\n", aufile[idx]); @@ -254,9 +275,12 @@ au_check_valid(int idx, long nbytes) printf ("Image %s wrong type\n", aufile[idx]); return -1; } - if ((idx == IDX_DISK || idx == IDX_APP) - && (hdr->ih_type != IH_TYPE_RAMDISK)) - { + if ((idx == IDX_DISK) && (hdr->ih_type != IH_TYPE_FILESYSTEM)) { + printf ("Image %s wrong type\n", aufile[idx]); + return -1; + } + if ((idx == IDX_APP) && (hdr->ih_type != IH_TYPE_RAMDISK) + && (hdr->ih_type != IH_TYPE_FILESYSTEM)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } @@ -269,8 +293,14 @@ au_check_valid(int idx, long nbytes) /* special case for prepare.img */ if (idx == IDX_PREPARE) return 0; - /* check the size does not exceed space in flash */ - if ((ausize[idx] != 0) && (ausize[idx] < ntohl(hdr->ih_size))) { + /* recycle checksum */ + checksum = ntohl(hdr->ih_size); + /* for kernel and app the image header must also fit into flash */ + if ((idx != IDX_DISK) && (idx != IDX_FIRMWARE)) + checksum += sizeof(*hdr); + /* check the size does not exceed space in flash. HUSH scripts */ + /* all have ausize[] set to 0 */ + if ((ausize[idx] != 0) && (ausize[idx] < checksum)) { printf ("Image %s is bigger than FLASH\n", aufile[idx]); return -1; } @@ -297,13 +327,12 @@ au_check_valid(int idx, long nbytes) #define POWER_OFF (1 << 1) int -au_do_update(int idx, long sz, int repeat) +au_do_update(int idx, long sz) { image_header_t *hdr; char *addr; long start, end; - char *strbuf = STRING_ADDR; - int off; + int off, rc; uint nbytes; hdr = (image_header_t *)LOAD_ADDR; @@ -313,9 +342,12 @@ au_do_update(int idx, long sz, int repeat) /* execute a script */ if (hdr->ih_type == IH_TYPE_SCRIPT) { - addr = (char *)((char *)hdr + sizeof(*hdr) + 8); - parse_string_outer(addr, - FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); + addr = (char *)((char *)hdr + sizeof(*hdr)); + /* stick a NULL at the end of the script, otherwise */ + /* parse_string_outer() runs off the end. */ + addr[ntohl(hdr->ih_size)] = 0; + addr += 8; + parse_string_outer(addr, FLAG_PARSE_SEMICOLON); return 0; } @@ -331,25 +363,21 @@ au_do_update(int idx, long sz, int repeat) start = aufl_layout[1].start; end = aufl_layout[1].end; #endif - debug ("protect off %lx %lx\n", start, end); - sprintf(strbuf, "protect off %lx %lx\n", start, end); - parse_string_outer(strbuf, - FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); + flash_sect_protect(0, start, end); } /* - * erase the address range. Multiple erases seem to cause - * problems. + * erase the address range. */ - if (repeat == 0) { - debug ("erase %lx %lx\n", start, end); - sprintf(strbuf, "erase %lx %lx\n", start, end); - parse_string_outer(strbuf, - FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); - } + debug ("flash_sect_erase(%lx, %lx);\n", start, end); + flash_sect_erase(start, end); wait_ms(100); - /* strip the header - except for the kernel */ - if (idx == IDX_FIRMWARE || idx == IDX_DISK || idx == IDX_APP) { + /* strip the header - except for the kernel and ramdisk */ + if (hdr->ih_type == IH_TYPE_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK) { + addr = (char *)hdr; + off = sizeof(*hdr); + nbytes = sizeof(*hdr) + ntohl(hdr->ih_size); + } else { addr = (char *)((char *)hdr + sizeof(*hdr)); #ifdef AU_UPDATE_TEST /* copy it to where Linux goes */ @@ -358,32 +386,26 @@ au_do_update(int idx, long sz, int repeat) #endif off = 0; nbytes = ntohl(hdr->ih_size); - } else { - addr = (char *)hdr; - off = sizeof(*hdr); - nbytes = sizeof(*hdr) + ntohl(hdr->ih_size); } /* copy the data from RAM to FLASH */ - debug ("cp.b %p %lx %x\n", addr, start, nbytes); - sprintf(strbuf, "cp.b %p %lx %x\n", addr, start, nbytes); - parse_string_outer(strbuf, - FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); + debug ("flash_write(%p, %lx %x)\n", addr, start, nbytes); + rc = flash_write(addr, start, nbytes); + if (rc != 0) { + printf("Flashing failed due to error %d\n", rc); + return -1; + } /* check the dcrc of the copy */ - if (crc32 (0, (char *)(start + off), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) { + if (crc32 (0, (uchar *)(start + off), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) { printf ("Image %s Bad Data Checksum After COPY\n", aufile[idx]); return -1; } /* protect the address range */ /* this assumes that ONLY the firmware is protected! */ - if (idx == IDX_FIRMWARE) { - debug ("protect on %lx %lx\n", start, end); - sprintf(strbuf, "protect on %lx %lx\n", start, end); - parse_string_outer(strbuf, - FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); - } + if (idx == IDX_FIRMWARE) + flash_sect_protect(1, start, end); return 0; } @@ -394,6 +416,13 @@ au_update_eeprom(int idx) int off; uint32_t val; + /* special case for prepare.img */ + if (idx == IDX_PREPARE) { + /* enable the power switch */ + *CPLD_VFD_BK &= ~POWER_OFF; + return 0; + } + hdr = (image_header_t *)LOAD_ADDR; /* write the time field into EEPROM */ off = auee_off[idx].time; @@ -446,7 +475,7 @@ do_auto_update(void) * check whether a storage device is attached (assume that it's * a USB memory stick, since nothing else should be attached). */ - au_usb_stor_curr_dev = usb_stor_scan(1); + au_usb_stor_curr_dev = usb_stor_scan(0); if (au_usb_stor_curr_dev == -1) { debug ("No device found. Not initialized?\n"); return -1; @@ -493,8 +522,11 @@ do_auto_update(void) env = getenv("firmware_nd"); if (env != NULL) end = simple_strtoul(env, NULL, 16); - if (start >= 0 && end && end > start) + if (start >= 0 && end && end > start) { ausize[IDX_FIRMWARE] = (end + 1) - start; + aufl_layout[0].start = start; + aufl_layout[0].end = end; + } start = -1; end = 0; env = getenv("kernel_st"); @@ -503,8 +535,11 @@ do_auto_update(void) env = getenv("kernel_nd"); if (env != NULL) end = simple_strtoul(env, NULL, 16); - if (start >= 0 && end && end > start) + if (start >= 0 && end && end > start) { ausize[IDX_KERNEL] = (end + 1) - start; + aufl_layout[1].start = start; + aufl_layout[1].end = end; + } start = -1; end = 0; env = getenv("app_st"); @@ -513,8 +548,11 @@ do_auto_update(void) env = getenv("app_nd"); if (env != NULL) end = simple_strtoul(env, NULL, 16); - if (start >= 0 && end && end > start) + if (start >= 0 && end && end > start) { ausize[IDX_APP] = (end + 1) - start; + aufl_layout[2].start = start; + aufl_layout[2].end = end; + } start = -1; end = 0; env = getenv("disk_st"); @@ -523,14 +561,31 @@ do_auto_update(void) env = getenv("disk_nd"); if (env != NULL) end = simple_strtoul(env, NULL, 16); - if (start >= 0 && end && end > start) + if (start >= 0 && end && end > start) { ausize[IDX_DISK] = (end + 1) - start; + aufl_layout[3].start = start; + aufl_layout[3].end = end; + } + /* make certain that HUSH is runnable */ + u_boot_hush_start(); /* make sure that we see CTRL-C and save the old state */ old_ctrlc = disable_ctrlc(0); bitmap_first = 0; /* just loop thru all the possible files */ for (i = 0; i < AU_MAXFILES; i++) { + /* just read the header */ + sz = file_fat_read(aufile[i], LOAD_ADDR, sizeof(image_header_t)); + debug ("read %s sz %ld hdr %d\n", + aufile[i], sz, sizeof(image_header_t)); + if (sz <= 0 || sz < sizeof(image_header_t)) { + debug ("%s not found\n", aufile[i]); + continue; + } + if (au_check_header_valid(i, sz) < 0) { + debug ("%s header not valid\n", aufile[i]); + continue; + } sz = file_fat_read(aufile[i], LOAD_ADDR, MAX_LOADSZ); debug ("read %s sz %ld hdr %d\n", aufile[i], sz, sizeof(image_header_t)); @@ -538,8 +593,8 @@ do_auto_update(void) debug ("%s not found\n", aufile[i]); continue; } - if (au_check_valid(i, sz) < 0) { - debug ("%s not valid\n", aufile[i]); + if (au_check_cksum_valid(i, sz) < 0) { + debug ("%s checksum not valid\n", aufile[i]); continue; } #ifdef CONFIG_VFD @@ -558,7 +613,8 @@ do_auto_update(void) #define VFD_LOGO_WIDTH 112 #define VFD_LOGO_HEIGHT 72 /* must call transfer_pic directly */ - transfer_pic(3, env, VFD_LOGO_HEIGHT, VFD_LOGO_WIDTH); + transfer_pic(3, (unsigned char *)env, + VFD_LOGO_HEIGHT, VFD_LOGO_WIDTH); } bitmap_first = 1; } @@ -568,7 +624,7 @@ do_auto_update(void) cnt = 0; got_ctrlc = 0; do { - res = au_do_update(i, sz, cnt); + res = au_do_update(i, sz); /* let the user break out of the loop */ if (ctrlc() || had_ctrlc()) { clear_ctrlc(); @@ -589,6 +645,9 @@ do_auto_update(void) */ if (got_ctrlc == 0) au_update_eeprom(i); + else + /* enable the power switch */ + *CPLD_VFD_BK &= ~POWER_OFF; } usb_stop(); /* restore the old state */