/* * mk-am35xx-spi-image.c - convert a barebox image for SPI loading on AM35xx * * Copyright (C) 2012 Jan Luebbe * * 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 Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /** * @file * @brief convert a barebox image for SPI loading on AM35xx * * FileName: scripts/mk-am35xx-spi-image.c * * Booting from SPI on an AM35xx (and possibly other TI SOCs) requires * a special format: * * - 32 bit image size in big-endian * - 32 bit load address in big-endian * - binary image converted from little- to big-endian * * This tool converts barebox.bin to the required format. */ #define _BSD_SOURCE #define _DEFAULT_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include static void usage(char *prgname) { printf("usage: %s [OPTION] FILE > IMAGE\n" "\n" "options:\n" " -a
memory address for the loaded image in SRAM\n" " -s Write big endian image needed for direct flashing to SPI\n", prgname); } int main(int argc, char *argv[]) { FILE *input; int opt; off_t pos; size_t size; uint32_t addr = 0x40200000; uint32_t temp; int chsettings = 0; int swap = 0; while((opt = getopt(argc, argv, "a:s")) != -1) { switch (opt) { case 'a': addr = strtoul(optarg, NULL, 0); break; case 's': swap = 1; break; } } if (optind >= argc) { usage(argv[0]); exit(1); } input = fopen(argv[optind], "r"); if (input == NULL) { perror("fopen"); exit(EXIT_FAILURE); } if (fseeko(input, 0, SEEK_END) == -1) { perror("fseeko"); exit(EXIT_FAILURE); } pos = ftello(input); if (pos == -1) { perror("ftello"); exit(EXIT_FAILURE); } if (pos > 0x100000) { fprintf(stderr, "error: image should be smaller than 1 MiB\n"); exit(EXIT_FAILURE); } if (fseeko(input, 0x14, SEEK_SET) == -1) { perror("fseeko"); exit(EXIT_FAILURE); } size = fread(&temp, 1, sizeof(uint32_t), input); if (!size) { perror("fseeko"); exit(EXIT_FAILURE); } /* * Test if this is an image generated with omap_signGP. These don't * need size and load address prepended. */ if (le32toh(temp) == 0x45534843) chsettings = 1; if (fseeko(input, 0x0, SEEK_SET) == -1) { perror("fseeko"); exit(EXIT_FAILURE); } pos = (pos + 3) & ~3; if (!chsettings) { /* image size */ temp = pos; if (swap) temp = htobe32(temp); fwrite(&temp, sizeof(uint32_t), 1, stdout); /* memory address */ temp = addr; if (swap) temp = htobe32(temp); fwrite(&temp, sizeof(uint32_t), 1, stdout); } for (;;) { size = fread(&temp, 1, sizeof(uint32_t), input); if (!size) break; if (size < 4 && !feof(input)) { perror("fread"); exit(EXIT_FAILURE); } if (swap) temp = htobe32(le32toh(temp)); if (fwrite(&temp, 1, sizeof(uint32_t), stdout) != 4) { perror("fwrite"); exit(EXIT_FAILURE); } } if (fclose(input) != 0) { perror("fclose"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }