| Index: utility/dump_fmap.c
|
| diff --git a/utility/dump_fmap.c b/utility/dump_fmap.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a0d24de4de2770101663fee6940a4b0253321c9c
|
| --- /dev/null
|
| +++ b/utility/dump_fmap.c
|
| @@ -0,0 +1,192 @@
|
| +/*
|
| + * 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 <errno.h>
|
| +#include <fcntl.h>
|
| +#include <inttypes.h>
|
| +#include <stdint.h>
|
| +#include <stdio.h>
|
| +#include <stdlib.h>
|
| +#include <string.h>
|
| +#include <sys/mman.h>
|
| +#include <sys/stat.h>
|
| +#include <sys/types.h>
|
| +#include <unistd.h>
|
| +
|
| +/* 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; i<fmh->fmap_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<sb.st_size; i += FMAP_SEARCH_STRIDE) {
|
| + if (0 == strncmp(s, "__FMAP__", 8)) {
|
| + printf("hit at 0x%08x\n", (uint32_t)i);
|
| + retval = dump_fmap(s);
|
| + break;
|
| + }
|
| + s++;
|
| + }
|
| +
|
| + if (0 != munmap(base_of_rom, sb.st_size)) {
|
| + fprintf(stderr, "%s: can't munmap %s: %s\n",
|
| + progname,
|
| + argv[optind],
|
| + strerror(errno));
|
| + return 1;
|
| + }
|
| +
|
| + return retval;
|
| +}
|
|
|