diff options
author | David Woodhouse <dwmw2@infradead.org> | 2008-06-26 08:55:30 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2008-07-10 09:47:42 -0400 |
commit | 59890f74e51abffd0dd017785d89f8a8475d489d (patch) | |
tree | dcbb789ceaa239e5fd818a7018ad20aa79395b05 | |
parent | 8bd6b2229bf98761465020467ec33547d05bff46 (diff) |
ihex: Add support for long records to ihex2fw.c
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 <dwmw2@infradead.org>
-rw-r--r-- | firmware/Makefile | 7 | ||||
-rw-r--r-- | firmware/ihex2fw.c | 59 |
2 files changed, 47 insertions, 19 deletions
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 $@ | |||
35 | quiet_cmd_ihex2fw = IHEX2FW $@ | 35 | quiet_cmd_ihex2fw = IHEX2FW $@ |
36 | cmd_ihex2fw = $(objtree)/$(obj)/ihex2fw $< $@ | 36 | cmd_ihex2fw = $(objtree)/$(obj)/ihex2fw $< $@ |
37 | 37 | ||
38 | quiet_cmd_h16tofw = H16TOFW $@ | ||
39 | cmd_h16tofw = $(objtree)/$(obj)/ihex2fw -w $< $@ | ||
40 | |||
38 | quiet_cmd_fwbin = MK_FW $@ | 41 | quiet_cmd_fwbin = MK_FW $@ |
39 | cmd_fwbin = FWNAME="$(patsubst firmware/%.gen.S,%,$@)"; \ | 42 | cmd_fwbin = FWNAME="$(patsubst firmware/%.gen.S,%,$@)"; \ |
40 | FWSTR="$(subst /,_,$(subst .,_,$(subst -,_,$(patsubst \ | 43 | FWSTR="$(subst /,_,$(subst .,_,$(subst -,_,$(patsubst \ |
@@ -99,6 +102,10 @@ $(obj)/%: $(obj)/%.ihex | $(objtree)/$(obj)/$$(dir %) | |||
99 | $(obj)/%.fw: $(obj)/%.HEX $(obj)/ihex2fw | $(objtree)/$(obj)/$$(dir %) | 102 | $(obj)/%.fw: $(obj)/%.HEX $(obj)/ihex2fw | $(objtree)/$(obj)/$$(dir %) |
100 | $(call cmd,ihex2fw) | 103 | $(call cmd,ihex2fw) |
101 | 104 | ||
105 | # .H16 is our own modified form of Intel HEX, with 16-bit length for records. | ||
106 | $(obj)/%.fw: $(obj)/%.H16 $(obj)/ihex2fw | $(objtree)/$(obj)/$$(dir %) | ||
107 | $(call cmd,h16tofw) | ||
108 | |||
102 | $(firmware-dirs): | 109 | $(firmware-dirs): |
103 | $(call cmd,mkdir) | 110 | $(call cmd,mkdir) |
104 | 111 | ||
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 @@ | |||
20 | #include <string.h> | 20 | #include <string.h> |
21 | #include <unistd.h> | 21 | #include <unistd.h> |
22 | #include <stdlib.h> | 22 | #include <stdlib.h> |
23 | #define _GNU_SOURCE | ||
24 | #include <getopt.h> | ||
25 | |||
23 | 26 | ||
24 | struct ihex_binrec { | 27 | struct ihex_binrec { |
25 | struct ihex_binrec *next; /* not part of the real data structure */ | 28 | struct ihex_binrec *next; /* not part of the real data structure */ |
@@ -51,34 +54,49 @@ static void file_record(struct ihex_binrec *record); | |||
51 | static int output_records(int outfd); | 54 | static int output_records(int outfd); |
52 | 55 | ||
53 | static int sort_records = 0; | 56 | static int sort_records = 0; |
57 | static int wide_records = 0; | ||
58 | |||
59 | int usage(void) | ||
60 | { | ||
61 | fprintf(stderr, "ihex2fw: Convert ihex files into binary " | ||
62 | "representation for use by Linux kernel\n"); | ||
63 | fprintf(stderr, "usage: ihex2fw [<options>] <src.HEX> <dst.fw>\n"); | ||
64 | fprintf(stderr, " -w: wide records (16-bit length)\n"); | ||
65 | fprintf(stderr, " -s: sort records by address\n"); | ||
66 | return 1; | ||
67 | } | ||
54 | 68 | ||
55 | int main(int argc, char **argv) | 69 | int main(int argc, char **argv) |
56 | { | 70 | { |
57 | int infd, outfd; | 71 | int infd, outfd; |
58 | struct stat st; | 72 | struct stat st; |
59 | uint8_t *data; | 73 | uint8_t *data; |
74 | int opt; | ||
60 | 75 | ||
61 | if (argc == 4 && !strcmp(argv[1], "-s")) { | 76 | while ((opt = getopt(argc, argv, "ws")) != -1) { |
62 | sort_records = 1; | 77 | switch (opt) { |
63 | argc--; | 78 | case 'w': |
64 | argv++; | 79 | wide_records = 1; |
65 | } | 80 | break; |
66 | if (argc != 3) { | 81 | case 's': |
67 | usage: | 82 | sort_records = 1; |
68 | fprintf(stderr, "ihex2fw: Convert ihex files into binary " | 83 | break; |
69 | "representation for use by Linux kernel\n"); | 84 | default: |
70 | fprintf(stderr, "usage: ihex2fw [-s] <src.HEX> <dst.fw>\n"); | 85 | return usage(); |
71 | fprintf(stderr, " -s: sort records by address\n"); | 86 | } |
72 | return 1; | ||
73 | } | 87 | } |
74 | if (!strcmp(argv[1], "-")) | 88 | |
89 | if (optind + 2 != argc) | ||
90 | return usage(); | ||
91 | |||
92 | if (!strcmp(argv[optind], "-")) | ||
75 | infd = 0; | 93 | infd = 0; |
76 | else | 94 | else |
77 | infd = open(argv[1], O_RDONLY); | 95 | infd = open(argv[optind], O_RDONLY); |
78 | if (infd == -1) { | 96 | if (infd == -1) { |
79 | fprintf(stderr, "Failed to open source file: %s", | 97 | fprintf(stderr, "Failed to open source file: %s", |
80 | strerror(errno)); | 98 | strerror(errno)); |
81 | goto usage; | 99 | return usage(); |
82 | } | 100 | } |
83 | if (fstat(infd, &st)) { | 101 | if (fstat(infd, &st)) { |
84 | perror("stat"); | 102 | perror("stat"); |
@@ -90,14 +108,14 @@ int main(int argc, char **argv) | |||
90 | return 1; | 108 | return 1; |
91 | } | 109 | } |
92 | 110 | ||
93 | if (!strcmp(argv[2], "-")) | 111 | if (!strcmp(argv[optind+1], "-")) |
94 | outfd = 1; | 112 | outfd = 1; |
95 | else | 113 | else |
96 | outfd = open(argv[2], O_TRUNC|O_CREAT|O_WRONLY, 0644); | 114 | outfd = open(argv[optind+1], O_TRUNC|O_CREAT|O_WRONLY, 0644); |
97 | if (outfd == -1) { | 115 | if (outfd == -1) { |
98 | fprintf(stderr, "Failed to open destination file: %s", | 116 | fprintf(stderr, "Failed to open destination file: %s", |
99 | strerror(errno)); | 117 | strerror(errno)); |
100 | goto usage; | 118 | return usage(); |
101 | } | 119 | } |
102 | if (process_ihex(data, st.st_size)) | 120 | if (process_ihex(data, st.st_size)) |
103 | return 1; | 121 | return 1; |
@@ -130,7 +148,10 @@ next_record: | |||
130 | } | 148 | } |
131 | 149 | ||
132 | len = hex(data + i, &crc); i += 2; | 150 | len = hex(data + i, &crc); i += 2; |
133 | 151 | if (wide_records) { | |
152 | len <<= 8; | ||
153 | len += hex(data + i, &crc); i += 2; | ||
154 | } | ||
134 | record = malloc((sizeof (*record) + len + 3) & ~3); | 155 | record = malloc((sizeof (*record) + len + 3) & ~3); |
135 | if (!record) { | 156 | if (!record) { |
136 | fprintf(stderr, "out of memory for records\n"); | 157 | fprintf(stderr, "out of memory for records\n"); |