blob: 7f2f53a0866e7b699721ef0f38e829295c5f077b [file] [log] [blame]
Bill Richardson60bcbe32010-09-09 14:53:56 -07001/*
Che-Liang Chiou305e9e52011-02-17 17:56:16 +08002 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
Bill Richardson60bcbe32010-09-09 14:53:56 -07003 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
5 */
6#include <errno.h>
7#include <fcntl.h>
8#include <inttypes.h>
9#include <stdint.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <sys/mman.h>
14#include <sys/stat.h>
15#include <sys/types.h>
16#include <unistd.h>
17
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080018#include "fmap.h"
19
Bill Richardson60bcbe32010-09-09 14:53:56 -070020/* global variables */
21static int opt_extract = 0;
Bill Richardson9a2c3b22011-06-13 12:45:24 -070022static int opt_pretty = 0;
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080023static char* progname;
24static void* base_of_rom;
Bill Richardson60bcbe32010-09-09 14:53:56 -070025
26
27/* Return 0 if successful */
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080028static int dump_fmap(const void* ptr) {
Bill Richardson60bcbe32010-09-09 14:53:56 -070029 int i,retval = 0;
30 char buf[80]; // DWR: magic number
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080031 const FmapHeader* fmh = (const FmapHeader*) ptr;
32 const FmapAreaHeader* ah = (const FmapAreaHeader*) (ptr + sizeof(FmapHeader));
Bill Richardson60bcbe32010-09-09 14:53:56 -070033
Bill Richardson9a2c3b22011-06-13 12:45:24 -070034 if (!opt_pretty) {
35 snprintf(buf, FMAP_SIGNATURE_SIZE+1, "%s", fmh->fmap_signature);
36 printf("fmap_signature %s\n", buf);
37 printf("fmap_version: %d.%d\n",
38 fmh->fmap_ver_major, fmh->fmap_ver_minor);
39 printf("fmap_base: 0x%" PRIx64 "\n", fmh->fmap_base);
40 printf("fmap_size: 0x%08x (%d)\n", fmh->fmap_size, fmh->fmap_size);
41 snprintf(buf, FMAP_NAMELEN+1, "%s", fmh->fmap_name);
42 printf("fmap_name: %s\n", buf);
43 printf("fmap_nareas: %d\n", fmh->fmap_nareas);
44 }
Bill Richardson60bcbe32010-09-09 14:53:56 -070045
46 for (i=0; i<fmh->fmap_nareas; i++) {
Bill Richardson9a2c3b22011-06-13 12:45:24 -070047 snprintf(buf, FMAP_NAMELEN+1, "%s", ah->area_name);
48 if (opt_pretty) {
49 printf("%s %d %d\n", buf, ah->area_offset, ah->area_size);
50 } else {
51 printf("area: %d\n", i+1);
52 printf("area_offset: 0x%08x\n", ah->area_offset);
53 printf("area_size: 0x%08x (%d)\n", ah->area_size, ah->area_size);
54 printf("area_name: %s\n", buf);
55 }
Bill Richardson60bcbe32010-09-09 14:53:56 -070056
57 if (opt_extract) {
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080058 char* s;
59 for (s=buf;* s; s++)
Bill Richardson60bcbe32010-09-09 14:53:56 -070060 if (*s == ' ')
Bill Richardson9a2c3b22011-06-13 12:45:24 -070061 *s = '_';
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080062 FILE* fp = fopen(buf,"wb");
Bill Richardson60bcbe32010-09-09 14:53:56 -070063 if (!fp) {
64 fprintf(stderr, "%s: can't open %s: %s\n",
65 progname, buf, strerror(errno));
66 retval = 1;
67 } else {
Bill Richardsonccdaa472011-03-03 18:08:18 -080068 if (ah->area_size &&
69 1 != fwrite(base_of_rom + ah->area_offset, ah->area_size, 1, fp)) {
Bill Richardson60bcbe32010-09-09 14:53:56 -070070 fprintf(stderr, "%s: can't write %s: %s\n",
71 progname, buf, strerror(errno));
72 retval = 1;
73 } else {
Bill Richardson9a2c3b22011-06-13 12:45:24 -070074 if (!opt_pretty)
75 printf("saved as \"%s\"\n", buf);
Bill Richardson60bcbe32010-09-09 14:53:56 -070076 }
77 fclose(fp);
78 }
79 }
80
81 ah++;
82 }
83
84 return retval;
85}
86
87
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080088int main(int argc, char* argv[]) {
Bill Richardson60bcbe32010-09-09 14:53:56 -070089 int c;
90 int errorcnt = 0;
91 struct stat sb;
92 int fd;
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080093 const char* fmap;
Bill Richardson60bcbe32010-09-09 14:53:56 -070094 int retval = 1;
95
96 progname = strrchr(argv[0], '/');
97 if (progname)
98 progname++;
99 else
100 progname = argv[0];
101
102 opterr = 0; /* quiet, you */
Bill Richardson9a2c3b22011-06-13 12:45:24 -0700103 while ((c=getopt(argc, argv, ":xp")) != -1) {
Bill Richardson60bcbe32010-09-09 14:53:56 -0700104 switch (c)
105 {
106 case 'x':
107 opt_extract = 1;
108 break;
Bill Richardson9a2c3b22011-06-13 12:45:24 -0700109 case 'p':
110 opt_pretty = 1;
111 break;
Bill Richardson60bcbe32010-09-09 14:53:56 -0700112 case '?':
113 fprintf(stderr, "%s: unrecognized switch: -%c\n",
114 progname, optopt);
115 errorcnt++;
116 break;
117 case ':':
118 fprintf(stderr, "%s: missing argument to -%c\n",
119 progname, optopt);
120 errorcnt++;
121 break;
122 default:
123 errorcnt++;
124 break;
125 }
126 }
127
128 if (errorcnt || optind >= argc) {
129 fprintf(stderr,
Bill Richardson9a2c3b22011-06-13 12:45:24 -0700130 "\nUsage: %s [-x] [-p] FLASHIMAGE\n\n"
131 "Display (and extract with -x) the FMAP components from a BIOS image.\n"
132 "The -p option makes the output easier to parse by scripts.\n"
133 "\n",
134 progname);
Bill Richardson60bcbe32010-09-09 14:53:56 -0700135 return 1;
136 }
137
138 if (0 != stat(argv[optind], &sb)) {
139 fprintf(stderr, "%s: can't stat %s: %s\n",
140 progname,
141 argv[optind],
142 strerror(errno));
143 return 1;
144 }
145
146 fd = open(argv[optind], O_RDONLY);
147 if (fd < 0) {
148 fprintf(stderr, "%s: can't open %s: %s\n",
149 progname,
150 argv[optind],
151 strerror(errno));
152 return 1;
153 }
Bill Richardson9a2c3b22011-06-13 12:45:24 -0700154 if (!opt_pretty)
155 printf("opened %s\n", argv[optind]);
Bill Richardson60bcbe32010-09-09 14:53:56 -0700156
157 base_of_rom = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
Che-Liang Chiou305e9e52011-02-17 17:56:16 +0800158 if (base_of_rom == (char*)-1) {
Bill Richardson60bcbe32010-09-09 14:53:56 -0700159 fprintf(stderr, "%s: can't mmap %s: %s\n",
160 progname,
161 argv[optind],
162 strerror(errno));
163 close(fd);
164 return 1;
165 }
166 close(fd); /* done with this now */
167
Che-Liang Chiou305e9e52011-02-17 17:56:16 +0800168 fmap = FmapFind((char*) base_of_rom, sb.st_size);
169 if (fmap) {
Bill Richardson9a2c3b22011-06-13 12:45:24 -0700170 if (!opt_pretty)
171 printf("hit at 0x%08x\n", (uint32_t) (fmap - (char*) base_of_rom));
Che-Liang Chiou305e9e52011-02-17 17:56:16 +0800172 retval = dump_fmap(fmap);
Bill Richardson60bcbe32010-09-09 14:53:56 -0700173 }
174
175 if (0 != munmap(base_of_rom, sb.st_size)) {
176 fprintf(stderr, "%s: can't munmap %s: %s\n",
177 progname,
178 argv[optind],
179 strerror(errno));
180 return 1;
181 }
182
183 return retval;
184}