diff --git a/firmware/Makefile b/firmware/Makefile index 9e780a331e10..40881a96be00 100644 --- a/firmware/Makefile +++ b/firmware/Makefile @@ -35,6 +35,9 @@ quiet_cmd_ihex = IHEX $@ quiet_cmd_ihex2fw = IHEX2FW $@ cmd_ihex2fw = $(objtree)/$(obj)/ihex2fw $< $@ +quiet_cmd_h16tofw = H16TOFW $@ + cmd_h16tofw = $(objtree)/$(obj)/ihex2fw -w $< $@ + quiet_cmd_fwbin = MK_FW $@ cmd_fwbin = FWNAME="$(patsubst firmware/%.gen.S,%,$@)"; \ FWSTR="$(subst /,_,$(subst .,_,$(subst -,_,$(patsubst \ @@ -99,6 +102,10 @@ $(obj)/%: $(obj)/%.ihex | $(objtree)/$(obj)/$$(dir %) $(obj)/%.fw: $(obj)/%.HEX $(obj)/ihex2fw | $(objtree)/$(obj)/$$(dir %) $(call cmd,ihex2fw) +# .H16 is our own modified form of Intel HEX, with 16-bit length for records. +$(obj)/%.fw: $(obj)/%.H16 $(obj)/ihex2fw | $(objtree)/$(obj)/$$(dir %) + $(call cmd,h16tofw) + $(firmware-dirs): $(call cmd,mkdir) diff --git a/firmware/ihex2fw.c b/firmware/ihex2fw.c index 9e77cd2f7152..660b191ed75e 100644 --- a/firmware/ihex2fw.c +++ b/firmware/ihex2fw.c @@ -20,6 +20,9 @@ #include #include #include +#define _GNU_SOURCE +#include + struct ihex_binrec { struct ihex_binrec *next; /* not part of the real data structure */ @@ -51,34 +54,49 @@ static void file_record(struct ihex_binrec *record); 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 [] \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++; + 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 (argc != 3) { - usage: - fprintf(stderr, "ihex2fw: Convert ihex files into binary " - "representation for use by Linux kernel\n"); - fprintf(stderr, "usage: ihex2fw [-s] \n"); - fprintf(stderr, " -s: sort records by address\n"); - return 1; - } - 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"); @@ -90,14 +108,14 @@ int main(int argc, char **argv) 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; @@ -130,7 +148,10 @@ static int process_ihex(uint8_t *data, ssize_t size) } 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");