X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=tools%2Fifdtool.c;h=3a39b7bc701194e6bf1e9b0cb767c2feb7abca39;hb=cd1cec6364cef9b38f4070ec7377757e757d50c4;hp=4a27b82c2e0ee617c2c9a152cbb983a65811720b;hpb=3bfbf32b6fe5e2d4605bc7ee99d1844b572662c2;p=oweals%2Fu-boot.git diff --git a/tools/ifdtool.c b/tools/ifdtool.c index 4a27b82c2e..3a39b7bc70 100644 --- a/tools/ifdtool.c +++ b/tools/ifdtool.c @@ -1,10 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0 /* * ifdtool - Manage Intel Firmware Descriptor information * * Copyright 2014 Google, Inc * - * SPDX-License-Identifier: GPL-2.0 - * * From Coreboot project, but it got a serious code clean-up * and a few new features */ @@ -12,12 +11,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include "ifdtool.h" #undef DEBUG @@ -32,6 +33,11 @@ #define FLREG_BASE(reg) ((reg & 0x00000fff) << 12); #define FLREG_LIMIT(reg) (((reg & 0x0fff0000) >> 4) | 0xfff); +struct input_file { + char *fname; + unsigned int addr; +}; + /** * find_fd() - Find the flash description in the ROM image * @@ -54,7 +60,8 @@ static struct fdbar_t *find_fd(char *image, int size) return NULL; } - debug("Found Flash Descriptor signature at 0x%08x\n", i); + debug("Found Flash Descriptor signature at 0x%08lx\n", + (char *)ptr - image); return (struct fdbar_t *)ptr; } @@ -448,7 +455,7 @@ static int write_regions(char *image, int size) if (ret) return ret; dump_region(i, frba); - if (region.size == 0) + if (region.size <= 0) continue; region_fd = open(region_filename(i), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | @@ -464,6 +471,16 @@ static int write_regions(char *image, int size) return ret; } +static int perror_fname(const char *fmt, const char *fname) +{ + char msg[strlen(fmt) + strlen(fname) + 1]; + + sprintf(msg, fmt, fname); + perror(msg); + + return -1; +} + /** * write_image() - Write the image to a file * @@ -480,10 +497,10 @@ static int write_image(char *filename, char *image, int size) new_fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if (write(new_fd, image, size) != size) { - perror("Error while writing"); - return -1; - } + if (new_fd < 0) + return perror_fname("Could not open file '%s'", filename); + if (write(new_fd, image, size) != size) + return perror_fname("Could not write file '%s'", filename); close(new_fd); return 0; @@ -585,14 +602,10 @@ int open_for_read(const char *fname, int *sizep) int fd = open(fname, O_RDONLY); struct stat buf; - if (fd == -1) { - perror("Could not open file"); - return -1; - } - if (fstat(fd, &buf) == -1) { - perror("Could not stat file"); - return -1; - } + if (fd == -1) + return perror_fname("Could not open file '%s'", fname); + if (fstat(fd, &buf) == -1) + return perror_fname("Could not stat file '%s'", fname); *sizep = buf.st_size; debug("File %s is %d bytes\n", fname, *sizep); @@ -686,10 +699,13 @@ int inject_region(char *image, int size, int region_type, char *region_fname) * 0xffffffff so use an address relative to that. For an * 8MB ROM the start address is 0xfff80000. * @write_fname: Filename to add to the image - * @return 0 if OK, -ve on error + * @offset_uboot_top: Offset of the top of U-Boot + * @offset_uboot_start: Offset of the start of U-Boot + * @return number of bytes written if OK, -ve on error */ static int write_data(char *image, int size, unsigned int addr, - const char *write_fname) + const char *write_fname, int offset_uboot_top, + int offset_uboot_start) { int write_fd, write_size; int offset; @@ -698,7 +714,27 @@ static int write_data(char *image, int size, unsigned int addr, if (write_fd < 0) return write_fd; - offset = addr + size; + offset = (uint32_t)(addr + size); + if (offset_uboot_top) { + if (offset_uboot_start < offset && + offset_uboot_top >= offset) { + fprintf(stderr, "U-Boot image overlaps with region '%s'\n", + write_fname); + fprintf(stderr, + "U-Boot finishes at offset %x, file starts at %x\n", + offset_uboot_top, offset); + return -EXDEV; + } + if (offset_uboot_start > offset && + offset_uboot_start <= offset + write_size) { + fprintf(stderr, "U-Boot image overlaps with region '%s'\n", + write_fname); + fprintf(stderr, + "U-Boot starts at offset %x, file finishes at %x\n", + offset_uboot_start, offset + write_size); + return -EXDEV; + } + } debug("Writing %s to offset %#x\n", write_fname, offset); if (offset < 0 || offset + write_size > size) { @@ -714,14 +750,14 @@ static int write_data(char *image, int size, unsigned int addr, close(write_fd); - return 0; + return write_size; } static void print_version(void) { printf("ifdtool v%s -- ", IFDTOOL_VERSION); printf("Copyright (C) 2014 Google Inc.\n\n"); - printf("SPDX-License-Identifier: GPL-2.0+\n"); + printf("SPDX-License-Identifier: GPL-2.0+\n"); } static void print_usage(const char *name) @@ -783,8 +819,7 @@ int main(int argc, char *argv[]) char *desc_fname = NULL, *addr_str = NULL; int region_type = -1, inputfreq = 0; enum spi_frequency spifreq = SPI_FREQUENCY_20MHZ; - unsigned int addr[WRITE_MAX]; - char *wr_fname[WRITE_MAX]; + struct input_file input_file[WRITE_MAX], *ifile, *fdt = NULL; unsigned char wr_idx, wr_num = 0; int rom_size = -1; bool write_it; @@ -792,6 +827,7 @@ int main(int argc, char *argv[]) char *outfile = NULL; struct stat buf; int size = 0; + bool have_uboot = false; int bios_fd; char *image; int ret; @@ -801,18 +837,20 @@ int main(int argc, char *argv[]) {"descriptor", 1, NULL, 'D'}, {"em100", 0, NULL, 'e'}, {"extract", 0, NULL, 'x'}, + {"fdt", 1, NULL, 'f'}, {"inject", 1, NULL, 'i'}, {"lock", 0, NULL, 'l'}, {"romsize", 1, NULL, 'r'}, {"spifreq", 1, NULL, 's'}, {"unlock", 0, NULL, 'u'}, + {"uboot", 1, NULL, 'U'}, {"write", 1, NULL, 'w'}, {"version", 0, NULL, 'v'}, {"help", 0, NULL, 'h'}, {0, 0, 0, 0} }; - while ((opt = getopt_long(argc, argv, "cdD:ehi:lr:s:uvw:x?", + while ((opt = getopt_long(argc, argv, "cdD:ef:hi:lr:s:uU:vw:x?", long_options, &option_index)) != EOF) { switch (opt) { case 'c': @@ -888,14 +926,17 @@ int main(int argc, char *argv[]) exit(EXIT_SUCCESS); break; case 'w': + case 'U': + case 'f': + ifile = &input_file[wr_num]; mode_write = 1; if (wr_num < WRITE_MAX) { if (get_two_words(optarg, &addr_str, - &wr_fname[wr_num])) { + &ifile->fname)) { print_usage(argv[0]); exit(EXIT_FAILURE); } - addr[wr_num] = strtol(optarg, NULL, 0); + ifile->addr = strtoll(optarg, NULL, 0); wr_num++; } else { fprintf(stderr, @@ -952,6 +993,13 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } + if (have_uboot && !fdt) { + fprintf(stderr, + "You must supply a device tree file for U-Boot\n\n"); + print_usage(argv[0]); + exit(EXIT_FAILURE); + } + filename = argv[optind]; if (optind + 2 != argc) outfile = argv[optind + 1]; @@ -1008,16 +1056,21 @@ int main(int argc, char *argv[]) } if (mode_write_descriptor) - ret = write_data(image, size, -size, desc_fname); + ret = write_data(image, size, -size, desc_fname, 0, 0); if (mode_inject) ret = inject_region(image, size, region_type, inject_fname); if (mode_write) { + int offset_uboot_top = 0; + int offset_uboot_start = 0; + for (wr_idx = 0; wr_idx < wr_num; wr_idx++) { - ret = write_data(image, size, - addr[wr_idx], wr_fname[wr_idx]); - if (ret) + ifile = &input_file[wr_idx]; + ret = write_data(image, size, ifile->addr, + ifile->fname, offset_uboot_top, + offset_uboot_start); + if (ret < 0) break; } } @@ -1052,5 +1105,5 @@ int main(int argc, char *argv[]) free(image); close(bios_fd); - return ret ? 1 : 0; + return ret < 0 ? 1 : 0; }