123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- /*
- * This file is part of the flashrom project.
- *
- * Copyright (C) 2010 Matthias Wenzel <bios at mazzoo dot de>
- * Copyright (C) 2011 Stefan Tauner
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- /*
- * dump information and binaries from BIOS images that are in descriptor mode
- */
- #include <stdio.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <sys/mman.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <string.h>
- #include <errno.h>
- #include "ich_descriptors.h"
- static void dump_file(const char *basename, const uint32_t *dump, unsigned int len, struct ich_desc_region *reg, unsigned int i)
- {
- int ret;
- char *fn;
- const char *reg_name;
- uint32_t file_len;
- const char *const region_names[5] = {
- "Descriptor", "BIOS", "ME", "GbE", "Platform"
- };
- uint32_t base = ICH_FREG_BASE(reg->FLREGs[i]);
- uint32_t limit = ICH_FREG_LIMIT(reg->FLREGs[i]);
- reg_name = region_names[i];
- if (base > limit) {
- printf("The %s region is unused and thus not dumped.\n",
- reg_name);
- return;
- }
- limit = limit | 0x0fff;
- file_len = limit + 1 - base;
- if (base + file_len > len) {
- printf("The %s region is spanning 0x%08x-0x%08x, but it is "
- "not (fully) included in the image (0-0x%08x), thus not "
- "dumped.\n", reg_name, base, limit, len - 1);
- return;
- }
- fn = malloc(strlen(basename) + strlen(reg_name) + strlen(".bin") + 2);
- if (!fn) {
- fprintf(stderr, "Out of memory!\n");
- exit(1);
- }
- snprintf(fn, strlen(basename) + strlen(reg_name) + strlen(".bin") + 2,
- "%s.%s.bin", basename, reg_name);
- printf("Dumping %u bytes of the %s region from 0x%08x-0x%08x to %s... ",
- file_len, region_names[i], base, limit, fn);
- int fh = open(fn, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
- free(fn);
- if (fh < 0) {
- fprintf(stderr,
- "ERROR: couldn't open(%s): %s\n", fn, strerror(errno));
- exit(1);
- }
- ret = write(fh, &dump[base >> 2], file_len);
- if (ret != file_len) {
- fprintf(stderr, "FAILED.\n");
- exit(1);
- }
- printf("done.\n");
- close(fh);
- }
- void dump_files(const char *n, const uint32_t *buf, unsigned int len, struct ich_desc_region *reg)
- {
- unsigned int i;
- printf("=== Dumping region files ===\n");
- for (i = 0; i < 5; i++)
- dump_file(n, buf, len, reg, i);
- printf("\n");
- }
- static void usage(char *argv[], char *error)
- {
- if (error != NULL) {
- fprintf(stderr, "%s\n", error);
- }
- printf("usage: '%s -f <image file name> [-c <chipset name>] [-d]'\n\n"
- "where <image file name> points to an image of the contents of the SPI flash.\n"
- "In case the image is really in descriptor mode %s\n"
- "will pretty print some of the contained information.\n"
- "To also print the data stored in the descriptor strap you have to indicate\n"
- "the chipset series with the '-c' parameter and one of the possible arguments:\n"
- "\t- \"ich8\",\n"
- "\t- \"ich9\",\n"
- "\t- \"ich10\",\n"
- "\t- \"5\" or \"ibex\" for Intel's 5 series chipsets,\n"
- "\t- \"6\" or \"cougar\" for Intel's 6 series chipsets,\n"
- "\t- \"7\" or \"panther\" for Intel's 7 series chipsets.\n"
- "If '-d' is specified some regions such as the BIOS image as seen by the CPU or\n"
- "the GbE blob that is required to initialize the GbE are also dumped to files.\n",
- argv[0], argv[0]);
- exit(1);
- }
- int main(int argc, char *argv[])
- {
- int fd; /* file descriptor to flash file */
- int len; /* file/buffer size in bytes */
- uint32_t *buf; /* mmap'd file */
- uint8_t *pMAC;
- int opt, ret;
- int dump = 0;
- const char *fn = NULL;
- const char *csn = NULL;
- enum ich_chipset cs = CHIPSET_ICH_UNKNOWN;
- struct ich_descriptors desc = {{ 0 }};
- while ((opt = getopt(argc, argv, "df:c:")) != -1) {
- switch (opt) {
- case 'd':
- dump = 1;
- break;
- case 'f':
- fn = optarg;
- break;
- case 'c':
- csn = optarg;
- break;
- default: /* '?' */
- usage(argv, NULL);
- }
- }
- if (fn == NULL)
- usage(argv,
- "Need a file name of a descriptor image to read from.");
- fd = open(fn, O_RDONLY);
- if (fd < 0)
- usage(argv, "No such file");
- len = lseek(fd, 0, SEEK_END);
- if (len < 0)
- usage(argv, "Seeking to the end of the file failed");
- buf = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
- if (buf == (void *) -1) {
- /* fallback for stupid OSes like cygwin */
- int ret;
- buf = malloc(len);
- if (!buf)
- usage(argv, "Could not allocate memory");
- lseek(fd, 0, SEEK_SET);
- ret = read(fd, buf, len);
- if (ret != len)
- usage(argv, "Seeking to the end of the file failed");
- }
- printf("The flash image has a size of %d [0x%x] bytes.\n", len, len);
- close(fd);
- if (csn != NULL) {
- if (strcmp(csn, "ich8") == 0)
- cs = CHIPSET_ICH8;
- else if (strcmp(csn, "ich9") == 0)
- cs = CHIPSET_ICH9;
- else if (strcmp(csn, "ich10") == 0)
- cs = CHIPSET_ICH10;
- else if ((strcmp(csn, "5") == 0) ||
- (strcmp(csn, "ibex") == 0))
- cs = CHIPSET_5_SERIES_IBEX_PEAK;
- else if ((strcmp(csn, "6") == 0) ||
- (strcmp(csn, "cougar") == 0))
- cs = CHIPSET_6_SERIES_COUGAR_POINT;
- else if ((strcmp(csn, "7") == 0) ||
- (strcmp(csn, "panther") == 0))
- cs = CHIPSET_7_SERIES_PANTHER_POINT;
- }
- ret = read_ich_descriptors_from_dump(buf, len, &desc);
- switch (ret) {
- case ICH_RET_OK:
- break;
- case ICH_RET_ERR:
- printf("Image not in descriptor mode.\n");
- exit(1);
- case ICH_RET_OOB:
- printf("Tried to access a location out of bounds of the image. "
- "- Corrupt image?\n");
- exit(1);
- default:
- printf("Unhandled return value at %s:%u, please report this.\n",
- __FILE__, __LINE__);
- exit(1);
- }
- prettyprint_ich_descriptors(cs, &desc);
- pMAC = (uint8_t *) &buf[ICH_FREG_BASE(desc.region.reg3_base) >> 2];
- if (len >= ICH_FREG_BASE(desc.region.reg3_base) + 5 && pMAC[0] != 0xff)
- printf("The MAC address might be at offset 0x%x: "
- "%02x:%02x:%02x:%02x:%02x:%02x\n",
- ICH_FREG_BASE(desc.region.reg3_base),
- pMAC[0], pMAC[1], pMAC[2], pMAC[3], pMAC[4], pMAC[5]);
- if (dump == 1)
- dump_files(fn, buf, len, &desc.region);
- return 0;
- }
|