/* * Copyright (c) 2010 The Chromium OS Authors. All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include #include #include #include #include #include #include #include /* global variables */ static int opt_extract = 0; static char *progname; static void *base_of_rom; /* FMAP structs. See http://code.google.com/p/flashmap/wiki/FmapSpec */ #define FMAP_SIGLEN 8 #define FMAP_NAMELEN 32 #define FMAP_SEARCH_STRIDE 4 typedef struct _FmapHeader { char fmap_signature[FMAP_SIGLEN]; /* avoiding endian issues */ uint8_t fmap_ver_major; uint8_t fmap_ver_minor; uint64_t fmap_base; uint32_t fmap_size; char fmap_name[FMAP_NAMELEN]; uint16_t fmap_nareas; } __attribute__((packed)) FmapHeader; typedef struct _AreaHeader { uint32_t area_offset; uint32_t area_size; char area_name[FMAP_NAMELEN]; uint16_t area_flags; } __attribute__((packed)) AreaHeader; /* Return 0 if successful */ static int dump_fmap(void *ptr) { int i,retval = 0; char buf[80]; // DWR: magic number FmapHeader *fmh = (FmapHeader *)ptr; AreaHeader *ah = (AreaHeader *)(ptr + sizeof(FmapHeader)); snprintf(buf, FMAP_SIGLEN+1, "%s", fmh->fmap_signature); printf("fmap_signature %s\n", buf); printf("fmap_version: %d.%d\n", fmh->fmap_ver_major, fmh->fmap_ver_minor); printf("fmap_base: 0x%" PRIx64 "\n", fmh->fmap_base); printf("fmap_size: 0x%08x (%d)\n", fmh->fmap_size, fmh->fmap_size); snprintf(buf, FMAP_NAMELEN+1, "%s", fmh->fmap_name); printf("fmap_name: %s\n", buf); printf("fmap_nareas: %d\n", fmh->fmap_nareas); for (i=0; ifmap_nareas; i++) { printf("area: %d\n", i+1); printf("area_offset: 0x%08x\n", ah->area_offset); printf("area_size: 0x%08x (%d)\n", ah->area_size, ah->area_size); snprintf(buf, FMAP_NAMELEN+1, "%s", ah->area_name); printf("area_name: %s\n", buf); if (opt_extract) { char *s; for (s=buf; *s; s++) if (*s == ' ') *s = '_'; FILE *fp = fopen(buf,"wb"); if (!fp) { fprintf(stderr, "%s: can't open %s: %s\n", progname, buf, strerror(errno)); retval = 1; } else { if (1 != fwrite(base_of_rom + ah->area_offset, ah->area_size, 1, fp)) { fprintf(stderr, "%s: can't write %s: %s\n", progname, buf, strerror(errno)); retval = 1; } else { printf("saved as \"%s\"\n", buf); } fclose(fp); } } ah++; } return retval; } int main(int argc, char *argv[]) { int c; int errorcnt = 0; struct stat sb; int fd; char *s; size_t i; int retval = 1; progname = strrchr(argv[0], '/'); if (progname) progname++; else progname = argv[0]; opterr = 0; /* quiet, you */ while ((c=getopt(argc, argv, ":x")) != -1) { switch (c) { case 'x': opt_extract = 1; break; case '?': fprintf(stderr, "%s: unrecognized switch: -%c\n", progname, optopt); errorcnt++; break; case ':': fprintf(stderr, "%s: missing argument to -%c\n", progname, optopt); errorcnt++; break; default: errorcnt++; break; } } if (errorcnt || optind >= argc) { fprintf(stderr, "\nUsage: %s [-x] FLASHIMAGE\n\n" "Display (and extract with -x) the FMAP components from a BIOS image" "\n\n", progname); return 1; } if (0 != stat(argv[optind], &sb)) { fprintf(stderr, "%s: can't stat %s: %s\n", progname, argv[optind], strerror(errno)); return 1; } fd = open(argv[optind], O_RDONLY); if (fd < 0) { fprintf(stderr, "%s: can't open %s: %s\n", progname, argv[optind], strerror(errno)); return 1; } printf("opened %s\n", argv[optind]); base_of_rom = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (base_of_rom == (char *)-1) { fprintf(stderr, "%s: can't mmap %s: %s\n", progname, argv[optind], strerror(errno)); close(fd); return 1; } close(fd); /* done with this now */ s = (char *)base_of_rom; for (i=0; i