diff options
-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"); |