Skip to content

Commit

Permalink
ihex: Add support for long records to ihex2fw.c
Browse files Browse the repository at this point in the history
Some drivers could do with using records like Intel HEX, but with each
record being larger than 256 bytes. This has been possible in the binary
representation (struct ihex_binrec) in the kernel since the beginning --
at least of the the current version of history. But we haven't been able
to represent that in the .HEX files which get converted to .fw files.

This adds a '-w' option to ihex2fw to make it interpret the first _two_
bytes of each line as the record length, instead of only one byte. And
adds makefile rules for %.H16->%.fw which use that.

Signed-off-by: David Woodhouse <[email protected]>
  • Loading branch information
dwmw2 authored and David Woodhouse committed Jul 10, 2008
1 parent 8bd6b22 commit 59890f7
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 19 deletions.
7 changes: 7 additions & 0 deletions firmware/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down Expand Up @@ -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)

Expand Down
59 changes: 40 additions & 19 deletions firmware/ihex2fw.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#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 */
Expand Down Expand Up @@ -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 [<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");
Expand All @@ -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;
Expand Down Expand Up @@ -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");
Expand Down

0 comments on commit 59890f7

Please sign in to comment.