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>
quiet_cmd_ihex2fw = IHEX2FW $@
cmd_ihex2fw = $(objtree)/$(obj)/ihex2fw $< $@
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 \
quiet_cmd_fwbin = MK_FW $@
cmd_fwbin = FWNAME="$(patsubst firmware/%.gen.S,%,$@)"; \
FWSTR="$(subst /,_,$(subst .,_,$(subst -,_,$(patsubst \
$(obj)/%.fw: $(obj)/%.HEX $(obj)/ihex2fw | $(objtree)/$(obj)/$$(dir %)
$(call cmd,ihex2fw)
$(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)
$(firmware-dirs):
$(call cmd,mkdir)
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#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 */
struct ihex_binrec {
struct ihex_binrec *next; /* not part of the real data structure */
static int output_records(int outfd);
static int sort_records = 0;
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 main(int argc, char **argv)
{
int infd, outfd;
struct stat st;
uint8_t *data;
- 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 = open(argv[1], O_RDONLY);
+ infd = open(argv[optind], O_RDONLY);
if (infd == -1) {
fprintf(stderr, "Failed to open source file: %s",
strerror(errno));
if (infd == -1) {
fprintf(stderr, "Failed to open source file: %s",
strerror(errno));
}
if (fstat(infd, &st)) {
perror("stat");
}
if (fstat(infd, &st)) {
perror("stat");
- if (!strcmp(argv[2], "-"))
+ if (!strcmp(argv[optind+1], "-"))
- 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));
if (outfd == -1) {
fprintf(stderr, "Failed to open destination file: %s",
strerror(errno));
}
if (process_ihex(data, st.st_size))
return 1;
}
if (process_ihex(data, st.st_size))
return 1;
}
len = hex(data + i, &crc); i += 2;
}
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");
record = malloc((sizeof (*record) + len + 3) & ~3);
if (!record) {
fprintf(stderr, "out of memory for records\n");