blob: ab2043c8bb26d0ce4a50fc80acc8f160a9e5faaf [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;
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080022static char* progname;
23static void* base_of_rom;
Bill Richardson60bcbe32010-09-09 14:53:56 -070024
25
26/* Return 0 if successful */
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080027static int dump_fmap(const void* ptr) {
Bill Richardson60bcbe32010-09-09 14:53:56 -070028 int i,retval = 0;
29 char buf[80]; // DWR: magic number
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080030 const FmapHeader* fmh = (const FmapHeader*) ptr;
31 const FmapAreaHeader* ah = (const FmapAreaHeader*) (ptr + sizeof(FmapHeader));
Bill Richardson60bcbe32010-09-09 14:53:56 -070032
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080033 snprintf(buf, FMAP_SIGNATURE_SIZE+1, "%s", fmh->fmap_signature);
Bill Richardson60bcbe32010-09-09 14:53:56 -070034 printf("fmap_signature %s\n", buf);
35 printf("fmap_version: %d.%d\n", fmh->fmap_ver_major, fmh->fmap_ver_minor);
36 printf("fmap_base: 0x%" PRIx64 "\n", fmh->fmap_base);
37 printf("fmap_size: 0x%08x (%d)\n", fmh->fmap_size, fmh->fmap_size);
38 snprintf(buf, FMAP_NAMELEN+1, "%s", fmh->fmap_name);
39 printf("fmap_name: %s\n", buf);
40 printf("fmap_nareas: %d\n", fmh->fmap_nareas);
41
42 for (i=0; i<fmh->fmap_nareas; i++) {
43 printf("area: %d\n", i+1);
44 printf("area_offset: 0x%08x\n", ah->area_offset);
45 printf("area_size: 0x%08x (%d)\n", ah->area_size, ah->area_size);
46 snprintf(buf, FMAP_NAMELEN+1, "%s", ah->area_name);
47 printf("area_name: %s\n", buf);
48
49 if (opt_extract) {
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080050 char* s;
51 for (s=buf;* s; s++)
Bill Richardson60bcbe32010-09-09 14:53:56 -070052 if (*s == ' ')
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080053 *s = '_';
54 FILE* fp = fopen(buf,"wb");
Bill Richardson60bcbe32010-09-09 14:53:56 -070055 if (!fp) {
56 fprintf(stderr, "%s: can't open %s: %s\n",
57 progname, buf, strerror(errno));
58 retval = 1;
59 } else {
Bill Richardsonccdaa472011-03-03 18:08:18 -080060 if (ah->area_size &&
61 1 != fwrite(base_of_rom + ah->area_offset, ah->area_size, 1, fp)) {
Bill Richardson60bcbe32010-09-09 14:53:56 -070062 fprintf(stderr, "%s: can't write %s: %s\n",
63 progname, buf, strerror(errno));
64 retval = 1;
65 } else {
66 printf("saved as \"%s\"\n", buf);
67 }
68 fclose(fp);
69 }
70 }
71
72 ah++;
73 }
74
75 return retval;
76}
77
78
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080079int main(int argc, char* argv[]) {
Bill Richardson60bcbe32010-09-09 14:53:56 -070080 int c;
81 int errorcnt = 0;
82 struct stat sb;
83 int fd;
Che-Liang Chiou305e9e52011-02-17 17:56:16 +080084 const char* fmap;
Bill Richardson60bcbe32010-09-09 14:53:56 -070085 int retval = 1;
86
87 progname = strrchr(argv[0], '/');
88 if (progname)
89 progname++;
90 else
91 progname = argv[0];
92
93 opterr = 0; /* quiet, you */
94 while ((c=getopt(argc, argv, ":x")) != -1) {
95 switch (c)
96 {
97 case 'x':
98 opt_extract = 1;
99 break;
100 case '?':
101 fprintf(stderr, "%s: unrecognized switch: -%c\n",
102 progname, optopt);
103 errorcnt++;
104 break;
105 case ':':
106 fprintf(stderr, "%s: missing argument to -%c\n",
107 progname, optopt);
108 errorcnt++;
109 break;
110 default:
111 errorcnt++;
112 break;
113 }
114 }
115
116 if (errorcnt || optind >= argc) {
117 fprintf(stderr,
118 "\nUsage: %s [-x] FLASHIMAGE\n\n"
119 "Display (and extract with -x) the FMAP components from a BIOS image"
120 "\n\n",
121 progname);
122 return 1;
123 }
124
125 if (0 != stat(argv[optind], &sb)) {
126 fprintf(stderr, "%s: can't stat %s: %s\n",
127 progname,
128 argv[optind],
129 strerror(errno));
130 return 1;
131 }
132
133 fd = open(argv[optind], O_RDONLY);
134 if (fd < 0) {
135 fprintf(stderr, "%s: can't open %s: %s\n",
136 progname,
137 argv[optind],
138 strerror(errno));
139 return 1;
140 }
141 printf("opened %s\n", argv[optind]);
142
143 base_of_rom = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
Che-Liang Chiou305e9e52011-02-17 17:56:16 +0800144 if (base_of_rom == (char*)-1) {
Bill Richardson60bcbe32010-09-09 14:53:56 -0700145 fprintf(stderr, "%s: can't mmap %s: %s\n",
146 progname,
147 argv[optind],
148 strerror(errno));
149 close(fd);
150 return 1;
151 }
152 close(fd); /* done with this now */
153
Che-Liang Chiou305e9e52011-02-17 17:56:16 +0800154 fmap = FmapFind((char*) base_of_rom, sb.st_size);
155 if (fmap) {
156 printf("hit at 0x%08x\n", (uint32_t) (fmap - (char*) base_of_rom));
157 retval = dump_fmap(fmap);
Bill Richardson60bcbe32010-09-09 14:53:56 -0700158 }
159
160 if (0 != munmap(base_of_rom, sb.st_size)) {
161 fprintf(stderr, "%s: can't munmap %s: %s\n",
162 progname,
163 argv[optind],
164 strerror(errno));
165 return 1;
166 }
167
168 return retval;
169}