13 #include <arpa/inet.h>
16 #include <sys/types.h>
39 if (n >=
'0' && n <=
'9')
return n -
'0';
40 else if (n >=
'A' && n <=
'F')
return n - (
'A' - 10);
41 else if (n >=
'a' && n <=
'f')
return n - (
'a' - 10);
47 uint8_t val = (nybble(data[0]) << 4) | nybble(data[1]);
54 static int output_records(
int outfd);
56 static int sort_records = 0;
57 static int wide_records = 0;
58 static int include_jump = 0;
60 static int usage(
void)
62 fprintf(stderr,
"ihex2fw: Convert ihex files into binary "
63 "representation for use by Linux kernel\n");
64 fprintf(stderr,
"usage: ihex2fw [<options>] <src.HEX> <dst.fw>\n");
65 fprintf(stderr,
" -w: wide records (16-bit length)\n");
66 fprintf(stderr,
" -s: sort records by address\n");
67 fprintf(stderr,
" -j: include records for CS:IP/EIP address\n");
78 while ((opt = getopt(argc, argv,
"wsj")) != -1) {
93 if (optind + 2 != argc)
96 if (!
strcmp(argv[optind],
"-"))
101 fprintf(stderr,
"Failed to open source file: %s",
105 if (fstat(infd, &st)) {
110 if (data == MAP_FAILED) {
115 if (!
strcmp(argv[optind+1],
"-"))
120 fprintf(stderr,
"Failed to open destination file: %s",
124 if (process_ihex(data, st.
st_size))
127 return output_records(outfd);
144 if (data[i] ==
'\n') line++;
145 if (data[i++] ==
':')
break;
150 fprintf(stderr,
"Can't find valid record at line %d\n", line);
154 len = hex(data + i, &crc); i += 2;
157 len += hex(data + i, &crc); i += 2;
159 record =
malloc((
sizeof (*record) + len + 3) & ~3);
161 fprintf(stderr,
"out of memory for records\n");
164 memset(record, 0, (
sizeof(*record) + len + 3) & ~3);
168 if (i + 8 + (record->
len * 2) > size) {
169 fprintf(stderr,
"Not enough data to read complete record at line %d\n",
174 record->
addr = hex(data + i, &crc) << 8; i += 2;
175 record->
addr |= hex(data + i, &crc); i += 2;
176 type = hex(data + i, &crc); i += 2;
178 for (j = 0; j < record->
len; j++, i += 2)
179 record->
data[j] = hex(data + i, &crc);
182 crcbyte = hex(data + i, &crc); i += 2;
184 fprintf(stderr,
"CRC failure at line %d: got 0x%X, expected 0x%X\n",
185 line, crcbyte, (
unsigned char)(crcbyte-crc));
201 if (record->
addr || record->
len) {
202 fprintf(stderr,
"Bad EOF record (type 01) format at line %d",
210 if (record->
addr || record->
len != 2) {
211 fprintf(stderr,
"Bad HEX86/HEX386 record (type %02X) at line %d\n",
218 offset = record->
data[0] << 8 | record->
data[1];
219 offset <<= (type == 2 ? 4 : 16);
224 if (record->
addr || record->
len != 4) {
225 fprintf(stderr,
"Bad Start Address record (type %02X) at line %d\n",
230 memcpy(&data32, &record->
data[0],
sizeof(data32));
231 data32 =
htonl(data32);
232 memcpy(&record->
data[0], &data32,
sizeof(data32));
241 fprintf(stderr,
"Unknown record (type %02X)\n", type);
250 static void file_record(
struct ihex_binrec *record)
254 while ((*p) && (!sort_records || (*p)->addr < record->
addr))
261 static int output_records(
int outfd)
263 unsigned char zeroes[6] = {0, 0, 0, 0, 0, 0};
271 if (
write(outfd, &p->
addr, writelen) != writelen)
277 if (
write(outfd, zeroes, 6) != 6)