blob: daffdf3b7b981de55428726dd6cc07b4c388595c [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 Richardson77c02432011-07-29 13:05:58 -070020enum { FMT_NORMAL, FMT_PRETTY, FMT_FLASHROM };
21
Bill Richardson60bcbe32010-09-09 14:53:56 -070022/* global variables */
23static int opt_extract = 0;
Bill Richardson77c02432011-07-29 13:05:58 -070024static int opt_format = FMT_NORMAL;
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080025static char* progname;
26static void* base_of_rom;
Bill Richardson60bcbe32010-09-09 14:53:56 -070027
28
29/* Return 0 if successful */
Bill Richardsone7e8ecd2012-03-01 11:05:29 -080030static int dump_fmap(const void* ptr, int argc, char *argv[]) {
31 int i,j,retval = 0;
Bill Richardson60bcbe32010-09-09 14:53:56 -070032 char buf[80]; // DWR: magic number
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080033 const FmapHeader* fmh = (const FmapHeader*) ptr;
34 const FmapAreaHeader* ah = (const FmapAreaHeader*) (ptr + sizeof(FmapHeader));
Bill Richardson60bcbe32010-09-09 14:53:56 -070035
Bill Richardson77c02432011-07-29 13:05:58 -070036 if (FMT_NORMAL == opt_format) {
Bill Richardson9a2c3b22011-06-13 12:45:24 -070037 snprintf(buf, FMAP_SIGNATURE_SIZE+1, "%s", fmh->fmap_signature);
38 printf("fmap_signature %s\n", buf);
39 printf("fmap_version: %d.%d\n",
40 fmh->fmap_ver_major, fmh->fmap_ver_minor);
41 printf("fmap_base: 0x%" PRIx64 "\n", fmh->fmap_base);
42 printf("fmap_size: 0x%08x (%d)\n", fmh->fmap_size, fmh->fmap_size);
43 snprintf(buf, FMAP_NAMELEN+1, "%s", fmh->fmap_name);
44 printf("fmap_name: %s\n", buf);
45 printf("fmap_nareas: %d\n", fmh->fmap_nareas);
46 }
Bill Richardson60bcbe32010-09-09 14:53:56 -070047
Bill Richardsone7e8ecd2012-03-01 11:05:29 -080048 for (i=0; i<fmh->fmap_nareas; i++, ah++) {
Bill Richardson77c02432011-07-29 13:05:58 -070049 snprintf(buf, FMAP_NAMELEN+1, "%s", ah->area_name);
Bill Richardsone7e8ecd2012-03-01 11:05:29 -080050
51 if (argc) {
52 int j, found=0;
53 for (j=0; j<argc; j++)
54 if (!strcmp(argv[j], buf)) {
55 found = 1;
56 break;
57 }
58 if (!found) {
59 continue;
60 }
61 }
62
Bill Richardson77c02432011-07-29 13:05:58 -070063 switch(opt_format)
64 {
65 case FMT_PRETTY:
Bill Richardson9a2c3b22011-06-13 12:45:24 -070066 printf("%s %d %d\n", buf, ah->area_offset, ah->area_size);
Bill Richardson77c02432011-07-29 13:05:58 -070067 break;
68 case FMT_FLASHROM:
69 if (ah->area_size)
Louis Yung-Chieh Lo9462e3e2011-08-24 12:53:43 +080070 printf("0x%08x:0x%08x %s\n", ah->area_offset,
71 ah->area_offset + ah->area_size - 1, buf);
Bill Richardson77c02432011-07-29 13:05:58 -070072 break;
73 default:
Bill Richardson9a2c3b22011-06-13 12:45:24 -070074 printf("area: %d\n", i+1);
75 printf("area_offset: 0x%08x\n", ah->area_offset);
76 printf("area_size: 0x%08x (%d)\n", ah->area_size, ah->area_size);
77 printf("area_name: %s\n", buf);
78 }
Bill Richardson60bcbe32010-09-09 14:53:56 -070079
80 if (opt_extract) {
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080081 char* s;
82 for (s=buf;* s; s++)
Bill Richardson60bcbe32010-09-09 14:53:56 -070083 if (*s == ' ')
Bill Richardson9a2c3b22011-06-13 12:45:24 -070084 *s = '_';
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080085 FILE* fp = fopen(buf,"wb");
Bill Richardson60bcbe32010-09-09 14:53:56 -070086 if (!fp) {
87 fprintf(stderr, "%s: can't open %s: %s\n",
88 progname, buf, strerror(errno));
89 retval = 1;
90 } else {
Bill Richardsonccdaa472011-03-03 18:08:18 -080091 if (ah->area_size &&
92 1 != fwrite(base_of_rom + ah->area_offset, ah->area_size, 1, fp)) {
Bill Richardson60bcbe32010-09-09 14:53:56 -070093 fprintf(stderr, "%s: can't write %s: %s\n",
94 progname, buf, strerror(errno));
95 retval = 1;
96 } else {
Bill Richardson77c02432011-07-29 13:05:58 -070097 if (FMT_NORMAL == opt_format)
Bill Richardson9a2c3b22011-06-13 12:45:24 -070098 printf("saved as \"%s\"\n", buf);
Bill Richardson60bcbe32010-09-09 14:53:56 -070099 }
100 fclose(fp);
101 }
102 }
Bill Richardson60bcbe32010-09-09 14:53:56 -0700103 }
104
105 return retval;
106}
107
108
Che-Liang Chiou305e9e52011-02-17 17:56:16 +0800109int main(int argc, char* argv[]) {
Bill Richardson60bcbe32010-09-09 14:53:56 -0700110 int c;
111 int errorcnt = 0;
112 struct stat sb;
113 int fd;
Che-Liang Chiou305e9e52011-02-17 17:56:16 +0800114 const char* fmap;
Bill Richardson60bcbe32010-09-09 14:53:56 -0700115 int retval = 1;
116
117 progname = strrchr(argv[0], '/');
118 if (progname)
119 progname++;
120 else
121 progname = argv[0];
122
123 opterr = 0; /* quiet, you */
Bill Richardson77c02432011-07-29 13:05:58 -0700124 while ((c=getopt(argc, argv, ":xpf")) != -1) {
Bill Richardson60bcbe32010-09-09 14:53:56 -0700125 switch (c)
126 {
127 case 'x':
128 opt_extract = 1;
129 break;
Bill Richardson9a2c3b22011-06-13 12:45:24 -0700130 case 'p':
Bill Richardson77c02432011-07-29 13:05:58 -0700131 opt_format = FMT_PRETTY;
132 break;
133 case 'f':
134 opt_format = FMT_FLASHROM;
Bill Richardson9a2c3b22011-06-13 12:45:24 -0700135 break;
Bill Richardson60bcbe32010-09-09 14:53:56 -0700136 case '?':
137 fprintf(stderr, "%s: unrecognized switch: -%c\n",
138 progname, optopt);
139 errorcnt++;
140 break;
141 case ':':
142 fprintf(stderr, "%s: missing argument to -%c\n",
143 progname, optopt);
144 errorcnt++;
145 break;
146 default:
147 errorcnt++;
148 break;
149 }
150 }
151
152 if (errorcnt || optind >= argc) {
153 fprintf(stderr,
Bill Richardsone7e8ecd2012-03-01 11:05:29 -0800154 "\nUsage: %s [-x] [-p|-f] FLASHIMAGE [NAME...]\n\n"
Bill Richardson9a2c3b22011-06-13 12:45:24 -0700155 "Display (and extract with -x) the FMAP components from a BIOS image.\n"
156 "The -p option makes the output easier to parse by scripts.\n"
Bill Richardsone7e8ecd2012-03-01 11:05:29 -0800157 "The -f option emits the FMAP in the format used by flashrom.\n"
158 "\n"
159 "Specify one or more NAMEs to only print sections that exactly match.\n"
Bill Richardson9a2c3b22011-06-13 12:45:24 -0700160 "\n",
161 progname);
Bill Richardson60bcbe32010-09-09 14:53:56 -0700162 return 1;
163 }
164
165 if (0 != stat(argv[optind], &sb)) {
166 fprintf(stderr, "%s: can't stat %s: %s\n",
167 progname,
168 argv[optind],
169 strerror(errno));
170 return 1;
171 }
172
173 fd = open(argv[optind], O_RDONLY);
174 if (fd < 0) {
175 fprintf(stderr, "%s: can't open %s: %s\n",
176 progname,
177 argv[optind],
178 strerror(errno));
179 return 1;
180 }
Bill Richardson77c02432011-07-29 13:05:58 -0700181 if (FMT_NORMAL == opt_format)
Bill Richardson9a2c3b22011-06-13 12:45:24 -0700182 printf("opened %s\n", argv[optind]);
Bill Richardson60bcbe32010-09-09 14:53:56 -0700183
184 base_of_rom = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
Che-Liang Chiou305e9e52011-02-17 17:56:16 +0800185 if (base_of_rom == (char*)-1) {
Bill Richardson60bcbe32010-09-09 14:53:56 -0700186 fprintf(stderr, "%s: can't mmap %s: %s\n",
187 progname,
188 argv[optind],
189 strerror(errno));
190 close(fd);
191 return 1;
192 }
193 close(fd); /* done with this now */
194
Che-Liang Chiou305e9e52011-02-17 17:56:16 +0800195 fmap = FmapFind((char*) base_of_rom, sb.st_size);
196 if (fmap) {
Bill Richardson77c02432011-07-29 13:05:58 -0700197 if (FMT_NORMAL == opt_format)
Bill Richardson9a2c3b22011-06-13 12:45:24 -0700198 printf("hit at 0x%08x\n", (uint32_t) (fmap - (char*) base_of_rom));
Bill Richardsone7e8ecd2012-03-01 11:05:29 -0800199 retval = dump_fmap(fmap, argc-optind-1, argv+optind+1);
Bill Richardson60bcbe32010-09-09 14:53:56 -0700200 }
201
202 if (0 != munmap(base_of_rom, sb.st_size)) {
203 fprintf(stderr, "%s: can't munmap %s: %s\n",
204 progname,
205 argv[optind],
206 strerror(errno));
207 return 1;
208 }
209
210 return retval;
211}