/* * Verifies U-Boot image header checksum */ static int ih_header_crc(image_header_t *hdr, int tpl_type) { u32 crc; int ret = 0; printf(" %-*s ", UBOOT_ALIGN_SIZE, "Header CRC..."); if (tpl_type == 0) { crc = ntohl(hdr->ih_hcrc); hdr->ih_hcrc = 0; if (tinf_crc32((u8 *)hdr, sizeof(image_header_t)) != crc) { puts("ERROR\n\n"); ret = 1; } else { puts("OK!\n"); } hdr->ih_hcrc = crc; } else { puts("skipped\n"); } return ret; }
int env_init(void){ int crc1_ok = 0, crc2_ok = 0; uchar flag1 = flash_addr->flags; uchar flag2 = flash_addr_new->flags; ulong addr_default = (ulong)&default_environment[0]; ulong addr1 = (ulong)&(flash_addr->data); ulong addr2 = (ulong)&(flash_addr_new->data); crc1_ok = (tinf_crc32(flash_addr->data, ENV_SIZE) == flash_addr->crc); crc2_ok = (tinf_crc32(flash_addr_new->data, ENV_SIZE) == flash_addr_new->crc); if(crc1_ok && !crc2_ok){ gd->env_addr = addr1; gd->env_valid = 1; } else if(!crc1_ok && crc2_ok){ gd->env_addr = addr2; gd->env_valid = 1; } else if(!crc1_ok && !crc2_ok){ gd->env_addr = addr_default; gd->env_valid = 0; } else if(flag1 == ACTIVE_FLAG && flag2 == OBSOLETE_FLAG){ gd->env_addr = addr1; gd->env_valid = 1; } else if(flag1 == OBSOLETE_FLAG && flag2 == ACTIVE_FLAG){ gd->env_addr = addr2; gd->env_valid = 1; } else if(flag1 == flag2){ gd->env_addr = addr1; gd->env_valid = 2; } else if(flag1 == 0xFF){ gd->env_addr = addr1; gd->env_valid = 2; } else if(flag2 == 0xFF){ gd->env_addr = addr2; gd->env_valid = 2; } return(0); }
int do_mem_crc32(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong addr, crc, length, vcrc; int ac, verify; ulong *ptr; char **av; if (argc < 3) { print_cmd_help(cmdtp); return 1; } av = argv + 1; ac = argc - 1; if (strcmp(*av, "-v") == 0) { verify = 1; av++; ac--; if (ac < 3) { print_cmd_help(cmdtp); return 1; } } else { verify = 0; } addr = simple_strtoul(*av++, NULL, 16); length = simple_strtoul(*av++, NULL, 16); crc = tinf_crc32((const char *)addr, length); if (!verify) { printf("CRC32 checksum for data at 0x%08lX ~ 0x%08lX: 0x%08lX\n", addr, addr + length - 1, crc); if (ac > 2) { ptr = (ulong *)simple_strtoul(*av++, NULL, 16); *ptr = crc; } } else { vcrc = simple_strtoul(*av++, NULL, 16); if (vcrc != crc) { printf("## Error: CRC32 checksum for data at 0x%08lX ~ 0x%08lX: 0x%08lX (not 0x%08lX!)\n", addr, addr + length - 1, crc, vcrc); return 1; } } return 0; }
/* CFG_ENV_ADDR is supposed to be on sector boundary */ static ulong end_addr = CFG_ENV_ADDR + CFG_ENV_SECT_SIZE - 1; static ulong end_addr_new = CFG_ENV_ADDR_REDUND + CFG_ENV_SECT_SIZE - 1; #define ACTIVE_FLAG 1 #define OBSOLETE_FLAG 0 #endif /* CFG_ENV_ADDR_REDUND */ extern uchar default_environment[]; extern int default_environment_size; uchar env_get_char_spec(int index){ return(*((uchar *)(gd->env_addr + index))); } #ifdef CFG_ENV_ADDR_REDUND int env_init(void){ int crc1_ok = 0, crc2_ok = 0; uchar flag1 = flash_addr->flags; uchar flag2 = flash_addr_new->flags; ulong addr_default = (ulong)&default_environment[0]; ulong addr1 = (ulong)&(flash_addr->data); ulong addr2 = (ulong)&(flash_addr_new->data); crc1_ok = (tinf_crc32(flash_addr->data, ENV_SIZE) == flash_addr->crc); crc2_ok = (tinf_crc32(flash_addr_new->data, ENV_SIZE) == flash_addr_new->crc); if(crc1_ok && !crc2_ok){ gd->env_addr = addr1; gd->env_valid = 1; } else if(!crc1_ok && crc2_ok){ gd->env_addr = addr2; gd->env_valid = 1; } else if(!crc1_ok && !crc2_ok){ gd->env_addr = addr_default; gd->env_valid = 0; } else if(flag1 == ACTIVE_FLAG && flag2 == OBSOLETE_FLAG){ gd->env_addr = addr1; gd->env_valid = 1; } else if(flag1 == OBSOLETE_FLAG && flag2 == ACTIVE_FLAG){ gd->env_addr = addr2; gd->env_valid = 1; } else if(flag1 == flag2){ gd->env_addr = addr1; gd->env_valid = 2; } else if(flag1 == 0xFF){ gd->env_addr = addr1; gd->env_valid = 2; } else if(flag2 == 0xFF){ gd->env_addr = addr2; gd->env_valid = 2; } return(0); } #ifdef CMD_SAVEENV int saveenv(void){ char *saved_data = NULL; int rc = 1; char flag = OBSOLETE_FLAG, new_flag = ACTIVE_FLAG; #if CFG_ENV_SECT_SIZE > CFG_ENV_SIZE ulong up_data = 0; up_data = (end_addr_new + 1 - ((long)flash_addr_new + CFG_ENV_SIZE)); if(up_data){ if((saved_data = malloc(up_data)) == NULL){ printf("## Error: unable to save the rest of sector (%ld)\n", up_data); goto Done; } memcpy(saved_data, (void *)((long)flash_addr_new + CFG_ENV_SIZE), up_data); } #endif if(flash_sect_erase((ulong)flash_addr_new, end_addr_new)){ goto Done; } if((rc = flash_write((char *)env_ptr->data, (ulong)&(flash_addr_new->data), sizeof(env_ptr->data))) || (rc = flash_write((char *)&(env_ptr->crc), (ulong)&(flash_addr_new->crc), sizeof(env_ptr->crc))) || (rc = flash_write(&flag, (ulong)&(flash_addr->flags), sizeof(flash_addr->flags))) || (rc = flash_write(&new_flag, (ulong)&(flash_addr_new->flags), sizeof(flash_addr_new->flags)))){ flash_perror(rc); goto Done; } #if CFG_ENV_SECT_SIZE > CFG_ENV_SIZE if(up_data){ /* restore the rest of sector */ if(flash_write(saved_data, (long)flash_addr_new + CFG_ENV_SIZE, up_data)){ flash_perror(rc); goto Done; } } #endif env_t * etmp = flash_addr; ulong ltmp = end_addr; flash_addr = flash_addr_new; flash_addr_new = etmp; end_addr = end_addr_new; end_addr_new = ltmp; rc = 0; Done: if(saved_data){ free(saved_data); } return(rc); } #endif /* CMD_SAVEENV */ #else /* ! CFG_ENV_ADDR_REDUND */ int env_init(void){ if(tinf_crc32(env_ptr->data, ENV_SIZE) == env_ptr->crc){ gd->env_addr = (ulong)&(env_ptr->data); gd->env_valid = 1; return(0); } gd->env_addr = (ulong)&default_environment[0]; gd->env_valid = 0; return(0); }
/************************************************************************ * * This is the next part if the initialization sequence: we are now * running from RAM and have a "normal" C environment, i. e. global * data can be written, BSS has been cleared, the stack size in not * that critical any more, etc. * ************************************************************************ */ void bootstrap_board_init_r(gd_t *id, ulong dest_addr) { int i; ulong addr; ulong data, len, checksum; image_header_t header; image_header_t *hdr = &header; unsigned int destLen; int (*fn)(int); /* Initialize malloc() area */ mem_malloc_init(dest_addr); addr = (ulong)((char *)(BOOTSTRAP_CFG_MONITOR_BASE + ((ulong)&uboot_end_data_bootstrap - dest_addr))); memmove(&header, (char *)addr, sizeof(image_header_t)); if (ntohl(hdr->ih_magic) != IH_MAGIC) return; data = (ulong)&header; len = sizeof(image_header_t); checksum = ntohl(hdr->ih_hcrc); hdr->ih_hcrc = 0; if (tinf_crc32((unsigned char *)data, len) != checksum) return; data = addr + sizeof(image_header_t); len = ntohl(hdr->ih_size); /* * If we've got less than 4 MB of malloc() space, * use slower decompression algorithm which requires * at most 2300 KB of memory. */ destLen = 0x0; #ifdef CONFIG_LZMA i = lzma_inflate((unsigned char *)data, len, (unsigned char*)ntohl(hdr->ih_load), (int *)&destLen); if (i != LZMA_RESULT_OK) return; #endif fn = (void *)ntohl(hdr->ih_load); (*fn)(gd->ram_size); hang(); }
static int image_info(ulong addr){ ulong data, len, checksum; image_header_t *hdr = &header; printf("\nChecking image at 0x%08lX...\n", addr); /* Copy header so we can blank CRC field for re-calculation */ memmove(&header, (char *)addr, sizeof(image_header_t)); data = (ulong)&header; len = sizeof(image_header_t); checksum = ntohl(hdr->ih_hcrc); hdr->ih_hcrc = 0; if(tinf_crc32((uchar *)data, len) != checksum){ puts("## Error: bad header checksum!\n"); return 1; } /* for multi-file images we need the data part, too */ print_image_hdr((image_header_t *)addr); data = addr + sizeof(image_header_t); len = ntohl(hdr->ih_size); puts(" Verifying checksum... "); if(tinf_crc32((uchar *)data, len) != ntohl(hdr->ih_dcrc)){ puts("bad data CRC!\n"); return(1); } puts("OK!\n\n"); return(0); }
/* * Verifies U-Boot image data checksum */ static int ih_data_crc(u32 addr, image_header_t *hdr, int tpl_type, int verify) { int ret = 0; printf(" %-*s ", UBOOT_ALIGN_SIZE, "Data CRC..."); if (tpl_type == 0 && verify == 1) { if (tinf_crc32((u8 *)addr, ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) { puts("ERROR\n\n"); ret = 1; } else { puts("OK!\n"); } } else { puts("skipped\n"); } return ret; }
void env_relocate_spec(void){ #if !defined(ENV_IS_EMBEDDED) || defined(CFG_ENV_ADDR_REDUND) #ifdef CFG_ENV_ADDR_REDUND if(gd->env_addr != (ulong)&(flash_addr->data)){ env_t * etmp = flash_addr; ulong ltmp = end_addr; flash_addr = flash_addr_new; flash_addr_new = etmp; end_addr = end_addr_new; end_addr_new = ltmp; } if(flash_addr_new->flags != OBSOLETE_FLAG && tinf_crc32(flash_addr_new->data, ENV_SIZE) == flash_addr_new->crc){ char flag = OBSOLETE_FLAG; gd->env_valid = 2; flash_write(&flag, (ulong)&(flash_addr_new->flags), sizeof(flash_addr_new->flags)); } if(flash_addr->flags != ACTIVE_FLAG && (flash_addr->flags & ACTIVE_FLAG) == ACTIVE_FLAG){ char flag = ACTIVE_FLAG; gd->env_valid = 2; flash_write(&flag, (ulong)&(flash_addr->flags), sizeof(flash_addr->flags)); } if(gd->env_valid == 2){ puts("** Warning: some problems detected reading environment, recovered successfully\n"); } #endif /* CFG_ENV_ADDR_REDUND */ memcpy(env_ptr, (void*)flash_addr, CFG_ENV_SIZE); #endif /* ! ENV_IS_EMBEDDED || CFG_ENV_ADDR_REDUND */ }
int main (int argc, char **argv) { #ifdef ENV_IS_EMBEDDED int crc; unsigned char *envptr = &environment, *dataptr = envptr + ENV_HEADER_SIZE; unsigned int datasize = ENV_SIZE; crc = tinf_crc32 (dataptr, datasize); /* Check if verbose mode is activated passing a parameter to the program */ if (argc > 1) { printf ("CRC32 from offset %08X to %08X of environment = %08X\n", (unsigned int) (dataptr - envptr), (unsigned int) (dataptr - envptr) + datasize, crc); } else { printf ("0x%08X\n", crc); } #else printf ("0\n"); #endif return EXIT_SUCCESS; }
/* If dest is NULL, return uncompressed length in *destLen. */ int tinf_gzip_uncompress(void *dest, unsigned int *destLen, const void *source, unsigned int sourceLen) { unsigned char *src = (unsigned char *)source; unsigned char *dst = (unsigned char *)dest; unsigned char *start; unsigned int dlen, crc32; int res; unsigned char flg; /* -- check format -- */ /* check id bytes */ if (src[0] != 0x1f || src[1] != 0x8b) return TINF_DATA_ERROR; /* check method is deflate */ if (src[2] != 8) return TINF_DATA_ERROR; /* get flag byte */ flg = src[3]; /* check that reserved bits are zero */ if (flg & 0xe0) return TINF_DATA_ERROR; /* -- find start of compressed data -- */ /* skip base header of 10 bytes */ start = src + 10; /* skip extra data if present */ if (flg & FEXTRA) { unsigned int xlen = start[1]; xlen = 256*xlen + start[0]; start += xlen + 2; } /* skip file name if present */ if (flg & FNAME) { while (*start) ++start; ++start; } /* skip file comment if present */ if (flg & FCOMMENT) { while (*start) ++start; ++start; } /* check header crc if present */ if (flg & FHCRC) { unsigned int hcrc = start[1]; hcrc = 256*hcrc + start[0]; if (hcrc != (tinf_crc32(src, start - src) & 0x0000ffff)) return TINF_DATA_ERROR; start += 2; } /* -- get decompressed length -- */ dlen = src[sourceLen - 1]; dlen = 256*dlen + src[sourceLen - 2]; dlen = 256*dlen + src[sourceLen - 3]; dlen = 256*dlen + src[sourceLen - 4]; if (!dst) { *destLen = dlen; return TINF_OK; } /* -- get crc32 of decompressed data -- */ crc32 = src[sourceLen - 5]; crc32 = 256*crc32 + src[sourceLen - 6]; crc32 = 256*crc32 + src[sourceLen - 7]; crc32 = 256*crc32 + src[sourceLen - 8]; /* -- decompress data -- */ res = tinf_uncompress(dst, destLen, start, src + sourceLen - start - 8); if (res != TINF_OK) return TINF_DATA_ERROR; if (*destLen != dlen) return TINF_DATA_ERROR; /* -- check CRC32 checksum -- */ if (crc32 != tinf_crc32(dst, dlen)) return TINF_DATA_ERROR; return TINF_OK; }
void env_crc_update(void) { env_ptr->crc = tinf_crc32(env_ptr->data, ENV_SIZE); }