int main (int argc, char **argv) { int ifd = -1; uint32_t checksum; uint32_t addr; uint32_t ep; struct stat sbuf; unsigned char *ptr; char *name = ""; cmdname = *argv; addr = ep = 0; while (--argc > 0 && **++argv == '-') { while (*++*argv) { switch (**argv) { case 'l': lflag = 1; break; case 'A': if ((--argc <= 0) || (opt_arch = genimg_get_arch_id (*++argv)) < 0) usage (); goto NXTARG; case 'C': if ((--argc <= 0) || (opt_comp = genimg_get_comp_id (*++argv)) < 0) usage (); goto NXTARG; case 'D': if (--argc <= 0) usage (); opt_dtc = *++argv; goto NXTARG; case 'O': if ((--argc <= 0) || (opt_os = genimg_get_os_id (*++argv)) < 0) usage (); goto NXTARG; case 'T': if ((--argc <= 0) || (opt_type = genimg_get_type_id (*++argv)) < 0) usage (); goto NXTARG; case 'a': if (--argc <= 0) usage (); addr = strtoul (*++argv, (char **)&ptr, 16); if (*ptr) { fprintf (stderr, "%s: invalid load address %s\n", cmdname, *argv); exit (EXIT_FAILURE); } goto NXTARG; case 'd': if (--argc <= 0) usage (); datafile = *++argv; dflag = 1; goto NXTARG; case 'e': if (--argc <= 0) usage (); ep = strtoul (*++argv, (char **)&ptr, 16); if (*ptr) { fprintf (stderr, "%s: invalid entry point %s\n", cmdname, *argv); exit (EXIT_FAILURE); } eflag = 1; goto NXTARG; case 'f': if (--argc <= 0) usage (); datafile = *++argv; fflag = 1; goto NXTARG; case 'n': if (--argc <= 0) usage (); name = *++argv; goto NXTARG; case 'v': vflag++; break; case 'x': xflag++; break; default: usage (); } } NXTARG: ; } if ((argc != 1) || (dflag && (fflag || lflag)) || (fflag && (dflag || lflag)) || (lflag && (dflag || fflag))) usage(); if (!eflag) { ep = addr; /* If XIP, entry point must be after the U-Boot header */ if (xflag) ep += image_get_header_size (); } /* * If XIP, ensure the entry point is equal to the load address plus * the size of the U-Boot header. */ if (xflag) { if (ep != addr + image_get_header_size ()) { fprintf (stderr, "%s: For XIP, the entry point must be the load addr + %lu\n", cmdname, (unsigned long)image_get_header_size ()); exit (EXIT_FAILURE); } } imagefile = *argv; if (!fflag){ if (lflag) { ifd = open (imagefile, O_RDONLY|O_BINARY); } else { ifd = open (imagefile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0666); } if (ifd < 0) { fprintf (stderr, "%s: Can't open %s: %s\n", cmdname, imagefile, strerror(errno)); exit (EXIT_FAILURE); } } if (lflag) { /* * list header information of existing image */ if (fstat(ifd, &sbuf) < 0) { fprintf (stderr, "%s: Can't stat %s: %s\n", cmdname, imagefile, strerror(errno)); exit (EXIT_FAILURE); } if ((unsigned)sbuf.st_size < image_get_header_size ()) { fprintf (stderr, "%s: Bad size: \"%s\" is no valid image\n", cmdname, imagefile); exit (EXIT_FAILURE); } ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, ifd, 0); if (ptr == MAP_FAILED) { fprintf (stderr, "%s: Can't read %s: %s\n", cmdname, imagefile, strerror(errno)); exit (EXIT_FAILURE); } if (fdt_check_header (ptr)) { /* old-style image */ image_verify_header ((char *)ptr, sbuf.st_size); image_print_contents ((image_header_t *)ptr); } else { /* FIT image */ fit_print_contents (ptr); } (void) munmap((void *)ptr, sbuf.st_size); (void) close (ifd); exit (EXIT_SUCCESS); } else if (fflag) { /* Flattened Image Tree (FIT) format handling */ debug ("FIT format handling\n"); fit_handle_file (); exit (EXIT_SUCCESS); } /* * Must be -w then: * * write dummy header, to be fixed later */ memset (hdr, 0, image_get_header_size ()); if (write(ifd, hdr, image_get_header_size ()) != image_get_header_size ()) { fprintf (stderr, "%s: Write error on %s: %s\n", cmdname, imagefile, strerror(errno)); exit (EXIT_FAILURE); } if (opt_type == IH_TYPE_MULTI || opt_type == IH_TYPE_SCRIPT) { char *file = datafile; uint32_t size; for (;;) { char *sep = NULL; if (file) { if ((sep = strchr(file, ':')) != NULL) { *sep = '\0'; } if (stat (file, &sbuf) < 0) { fprintf (stderr, "%s: Can't stat %s: %s\n", cmdname, file, strerror(errno)); exit (EXIT_FAILURE); } size = cpu_to_uimage (sbuf.st_size); } else { size = 0; } if (write(ifd, (char *)&size, sizeof(size)) != sizeof(size)) { fprintf (stderr, "%s: Write error on %s: %s\n", cmdname, imagefile, strerror(errno)); exit (EXIT_FAILURE); } if (!file) { break; } if (sep) { *sep = ':'; file = sep + 1; } else { file = NULL; } } file = datafile; for (;;) { char *sep = strchr(file, ':'); if (sep) { *sep = '\0'; copy_file (ifd, file, 1); *sep++ = ':'; file = sep; } else { copy_file (ifd, file, 0); break; } } } else { copy_file (ifd, datafile, 0); } /* We're a bit of paranoid */ #if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__) && !defined(__APPLE__) (void) fdatasync (ifd); #else (void) fsync (ifd); #endif if (fstat(ifd, &sbuf) < 0) { fprintf (stderr, "%s: Can't stat %s: %s\n", cmdname, imagefile, strerror(errno)); exit (EXIT_FAILURE); } ptr = mmap(0, sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0); if (ptr == MAP_FAILED) { fprintf (stderr, "%s: Can't map %s: %s\n", cmdname, imagefile, strerror(errno)); exit (EXIT_FAILURE); } hdr = (image_header_t *)ptr; checksum = crc32 (0, (const char *)(ptr + image_get_header_size ()), sbuf.st_size - image_get_header_size () ); /* Build new header */ image_set_magic (hdr, IH_MAGIC); image_set_time (hdr, sbuf.st_mtime); image_set_size (hdr, sbuf.st_size - image_get_header_size ()); image_set_load (hdr, addr); image_set_ep (hdr, ep); image_set_dcrc (hdr, checksum); image_set_os (hdr, opt_os); image_set_arch (hdr, opt_arch); image_set_type (hdr, opt_type); image_set_comp (hdr, opt_comp); image_set_name (hdr, name); checksum = crc32 (0, (const char *)hdr, image_get_header_size ()); image_set_hcrc (hdr, checksum); image_print_contents (hdr); (void) munmap((void *)ptr, sbuf.st_size); /* We're a bit of paranoid */ #if defined(_POSIX_SYNCHRONIZED_IO) && !defined(__sun__) && !defined(__FreeBSD__) && !defined(__APPLE__) (void) fdatasync (ifd); #else (void) fsync (ifd); #endif if (close(ifd)) { fprintf (stderr, "%s: Write error on %s: %s\n", cmdname, imagefile, strerror(errno)); exit (EXIT_FAILURE); } exit (EXIT_SUCCESS); }
int main (int argc, char **argv) { int fd = -1, err = 0, readbyte = 0, j; struct mtd_info_user mtdinfo; char buf[sizeof(image_header_t)]; int found = 0; cmdname = *argv; while (--argc > 0 && **++argv == '-') { while (*++*argv) { switch (**argv) { case 'c': if (--argc <= 0) usage (); sectorcount = (unsigned int)atoi(*++argv); cflag = 1; goto NXTARG; case 'o': if (--argc <= 0) usage (); sectoroffset = (unsigned int)atoi(*++argv); goto NXTARG; case 's': if (--argc <= 0) usage (); sectorsize = (unsigned int)atoi(*++argv); sflag = 1; goto NXTARG; default: usage (); } } NXTARG: ; } if (argc != 1 || cflag == 0 || sflag == 0) usage(); devicefile = *argv; fd = open(devicefile, O_RDONLY); if (fd < 0) { fprintf (stderr, "%s: Can't open %s: %s\n", cmdname, devicefile, strerror(errno)); exit(EXIT_FAILURE); } err = ioctl(fd, MEMGETINFO, &mtdinfo); if (err < 0) { fprintf(stderr, "%s: Cannot get MTD information: %s\n",cmdname, strerror(errno)); exit(EXIT_FAILURE); } if (mtdinfo.type != MTD_NORFLASH && mtdinfo.type != MTD_NANDFLASH) { fprintf(stderr, "%s: Unsupported flash type %u\n", cmdname, mtdinfo.type); exit(EXIT_FAILURE); } if (sectorsize * sectorcount != mtdinfo.size) { fprintf(stderr, "%s: Partition size (%d) incompatible with " "sector size and count\n", cmdname, mtdinfo.size); exit(EXIT_FAILURE); } if (sectorsize * sectoroffset >= mtdinfo.size) { fprintf(stderr, "%s: Partition size (%d) incompatible with " "sector offset given\n", cmdname, mtdinfo.size); exit(EXIT_FAILURE); } if (sectoroffset > sectorcount - 1) { fprintf(stderr, "%s: Sector offset cannot be grater than " "sector count minus one\n", cmdname); exit(EXIT_FAILURE); } printf("Searching....\n"); for (j = sectoroffset; j < sectorcount; ++j) { if (lseek(fd, j*sectorsize, SEEK_SET) != j*sectorsize) { fprintf(stderr, "%s: lseek failure: %s\n", cmdname, strerror(errno)); exit(EXIT_FAILURE); } err = flash_bad_block(fd, mtdinfo.type, j*sectorsize); if (err < 0) exit(EXIT_FAILURE); if (err) continue; /* Skip and jump to next */ readbyte = read(fd, buf, sizeof(image_header_t)); if (readbyte != sizeof(image_header_t)) { fprintf(stderr, "%s: Can't read from device: %s\n", cmdname, strerror(errno)); exit(EXIT_FAILURE); } if (fdt_check_header(buf)) { /* old-style image */ if (image_verify_header(buf, fd)) { found = 1; image_print_contents((image_header_t *)buf); } } else { /* FIT image */ fit_print_contents(buf); } } close(fd); if(!found) printf("No images found\n"); exit(EXIT_SUCCESS); }