aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2008-06-26 08:55:30 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2008-07-10 09:47:42 -0400
commit59890f74e51abffd0dd017785d89f8a8475d489d (patch)
treedcbb789ceaa239e5fd818a7018ad20aa79395b05
parent8bd6b2229bf98761465020467ec33547d05bff46 (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/Makefile7
-rw-r--r--firmware/ihex2fw.c59
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 $@
35quiet_cmd_ihex2fw = IHEX2FW $@ 35quiet_cmd_ihex2fw = IHEX2FW $@
36 cmd_ihex2fw = $(objtree)/$(obj)/ihex2fw $< $@ 36 cmd_ihex2fw = $(objtree)/$(obj)/ihex2fw $< $@
37 37
38quiet_cmd_h16tofw = H16TOFW $@
39 cmd_h16tofw = $(objtree)/$(obj)/ihex2fw -w $< $@
40
38quiet_cmd_fwbin = MK_FW $@ 41quiet_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
24struct ihex_binrec { 27struct 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);
51static int output_records(int outfd); 54static int output_records(int outfd);
52 55
53static int sort_records = 0; 56static int sort_records = 0;
57static int wide_records = 0;
58
59int 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
55int main(int argc, char **argv) 69int 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");