#include <string.h>
#include <unistd.h>
#include <stdlib.h>
+#define _GNU_SOURCE
+#include <getopt.h>
+
struct ihex_binrec {
struct ihex_binrec *next; /* not part of the real data structure */
static int output_records(int outfd);
static int sort_records = 0;
+static int wide_records = 0;
+
+int usage(void)
+{
+ fprintf(stderr, "ihex2fw: Convert ihex files into binary "
+ "representation for use by Linux kernel\n");
+ fprintf(stderr, "usage: ihex2fw [<options>] <src.HEX> <dst.fw>\n");
+ fprintf(stderr, " -w: wide records (16-bit length)\n");
+ fprintf(stderr, " -s: sort records by address\n");
+ return 1;
+}
int main(int argc, char **argv)
{
int infd, outfd;
struct stat st;
uint8_t *data;
+ int opt;
- if (argc == 4 && !strcmp(argv[1], "-s")) {
- sort_records = 1;
- argc--;
- argv++;
- }
- if (argc != 3) {
- usage:
- fprintf(stderr, "ihex2fw: Convert ihex files into binary "
- "representation for use by Linux kernel\n");
- fprintf(stderr, "usage: ihex2fw [-s] <src.HEX> <dst.fw>\n");
- fprintf(stderr, " -s: sort records by address\n");
- return 1;
+ while ((opt = getopt(argc, argv, "ws")) != -1) {
+ switch (opt) {
+ case 'w':
+ wide_records = 1;
+ break;
+ case 's':
+ sort_records = 1;
+ break;
+ default:
+ return usage();
+ }
}
- if (!strcmp(argv[1], "-"))
+
+ if (optind + 2 != argc)
+ return usage();
+
+ if (!strcmp(argv[optind], "-"))
infd = 0;
else
- infd = open(argv[1], O_RDONLY);
+ infd = open(argv[optind], O_RDONLY);
if (infd == -1) {
fprintf(stderr, "Failed to open source file: %s",
strerror(errno));
- goto usage;
+ return usage();
}
if (fstat(infd, &st)) {
perror("stat");
return 1;
}
- if (!strcmp(argv[2], "-"))
+ if (!strcmp(argv[optind+1], "-"))
outfd = 1;
else
- outfd = open(argv[2], O_TRUNC|O_CREAT|O_WRONLY, 0644);
+ outfd = open(argv[optind+1], O_TRUNC|O_CREAT|O_WRONLY, 0644);
if (outfd == -1) {
fprintf(stderr, "Failed to open destination file: %s",
strerror(errno));
- goto usage;
+ return usage();
}
if (process_ihex(data, st.st_size))
return 1;
}
len = hex(data + i, &crc); i += 2;
-
+ if (wide_records) {
+ len <<= 8;
+ len += hex(data + i, &crc); i += 2;
+ }
record = malloc((sizeof (*record) + len + 3) & ~3);
if (!record) {
fprintf(stderr, "out of memory for records\n");
static int output_records(int outfd)
{
- unsigned char zeroes[5] = {0, 0, 0, 0, 0};
+ unsigned char zeroes[6] = {0, 0, 0, 0, 0, 0};
struct ihex_binrec *p = records;
while (p) {
uint16_t writelen = (p->len + 9) & ~3;
p->addr = htonl(p->addr);
- p->len = htonl(p->len);
+ p->len = htons(p->len);
write(outfd, &p->addr, writelen);
p = p->next;
}
/* EOF record is zero length, since we don't bother to represent
the type field in the binary version */
- write(outfd, zeroes, 5);
+ write(outfd, zeroes, 6);
return 0;
}