]>
git.ipfire.org Git - people/ms/u-boot.git/blob - tools/img2srec.c
1 /*************************************************************************
2 | COPYRIGHT (c) 2000 BY ABATRON AG
3 |*************************************************************************
5 | PROJECT NAME: Linux Image to S-record Conversion Utility
6 | FILENAME : img2srec.c
10 | TARGET OS : LINUX / UNIX
13 | PROGRAMMER : Abatron / RD
16 |*************************************************************************
20 | Utility to convert a Linux Boot Image to S-record:
21 | ==================================================
23 | This command line utility can be used to convert a Linux boot image
24 | (zimage.initrd) to S-Record format used for flash programming.
25 | This conversion takes care of the special sections "IMAGE" and INITRD".
27 | img2srec [-o offset] image > image.srec
33 | To build the utility use GCC as follows:
35 | gcc img2srec.c -o img2srec
38 |*************************************************************************
44 | -----------------------------------------------------------
47 | 07.07.00 aba Initial release
49 |*************************************************************************/
51 /*************************************************************************
53 |*************************************************************************/
55 #include "os_support.h"
65 /*************************************************************************
67 |*************************************************************************/
72 /*************************************************************************
74 |*************************************************************************/
76 /*************************************************************************
78 |*************************************************************************/
82 typedef uint16_t WORD
;
83 typedef uint32_t DWORD
;
86 /*************************************************************************
88 |*************************************************************************/
90 /*************************************************************************
92 |*************************************************************************/
94 static char *ExtractHex(DWORD
*value
, char *getPtr
);
95 static char *ExtractDecimal(DWORD
*value
, char *getPtr
);
96 static void ExtractNumber(DWORD
*value
, char *getPtr
);
97 static BYTE
*ExtractWord(WORD
*value
, BYTE
*buffer
);
98 static BYTE
*ExtractLong(DWORD
*value
, BYTE
*buffer
);
99 static BYTE
*ExtractBlock(WORD count
, BYTE
*data
, BYTE
*buffer
);
100 static char *WriteHex(char *pa
, BYTE value
, WORD
*pCheckSum
);
101 static char *BuildSRecord(char *pa
, WORD sType
, DWORD addr
,
102 const BYTE
*data
, int nCount
);
103 static void ConvertELF(char *fileName
, DWORD loadOffset
);
104 int main(int argc
, char *argv
[]);
106 /*************************************************************************
108 |*************************************************************************/
110 static char* ExtractHex (DWORD
* value
, char* getPtr
)
116 while (*getPtr
== ' ') getPtr
++;
120 if ((c
>= '0') && (c
<= '9')) digit
= (DWORD
)(c
- '0');
121 else if ((c
>= 'A') && (c
<= 'F')) digit
= (DWORD
)(c
- 'A' + 10);
122 else if ((c
>= 'a') && (c
<= 'f')) digit
= (DWORD
)(c
- 'a' + 10);
132 static char* ExtractDecimal (DWORD
* value
, char* getPtr
)
138 while (*getPtr
== ' ') getPtr
++;
142 if ((c
>= '0') && (c
<= '9')) digit
= (DWORD
)(c
- '0');
150 } /* ExtractDecimal */
153 static void ExtractNumber (DWORD
* value
, char* getPtr
)
157 while (*getPtr
== ' ') getPtr
++;
158 if (*getPtr
== '-') {
162 if ((*getPtr
== '0') && ((*(getPtr
+1) == 'x') || (*(getPtr
+1) == 'X'))) {
164 (void)ExtractHex(value
, getPtr
);
167 (void)ExtractDecimal(value
, getPtr
);
169 if (neg
) *value
= -(*value
);
170 } /* ExtractNumber */
173 static BYTE
* ExtractWord(WORD
* value
, BYTE
* buffer
)
177 x
= (x
<<8) + (WORD
)*buffer
++;
183 static BYTE
* ExtractLong(DWORD
* value
, BYTE
* buffer
)
186 x
= (DWORD
)*buffer
++;
187 x
= (x
<<8) + (DWORD
)*buffer
++;
188 x
= (x
<<8) + (DWORD
)*buffer
++;
189 x
= (x
<<8) + (DWORD
)*buffer
++;
195 static BYTE
* ExtractBlock(WORD count
, BYTE
* data
, BYTE
* buffer
)
197 while (count
--) *data
++ = *buffer
++;
202 static char* WriteHex(char* pa
, BYTE value
, WORD
* pCheckSum
)
206 static char ByteToHex
[] = "0123456789ABCDEF";
210 *pa
++ = ByteToHex
[temp
];
212 *pa
++ = ByteToHex
[temp
];
217 static char* BuildSRecord(char* pa
, WORD sType
, DWORD addr
,
218 const BYTE
* data
, int nCount
)
244 *pa
++ = (char)(sType
+ '0');
245 sRLen
= addrLen
+ nCount
+ 1;
247 pa
= WriteHex(pa
, (BYTE
)sRLen
, &checkSum
);
249 /* Write address field */
250 for (i
= 1; i
<= addrLen
; i
++) {
251 pa
= WriteHex(pa
, (BYTE
)(addr
>> (8 * (addrLen
- i
))), &checkSum
);
254 /* Write code/data fields */
255 for (i
= 0; i
< nCount
; i
++) {
256 pa
= WriteHex(pa
, *data
++, &checkSum
);
259 /* Write checksum field */
260 checkSum
= ~checkSum
;
261 pa
= WriteHex(pa
, (BYTE
)checkSum
, &checkSum
);
267 static void ConvertELF(char* fileName
, DWORD loadOffset
)
277 Elf32_Ehdr elfHeader
;
278 Elf32_Shdr sectHeader
[32];
285 if ((file
= fopen(fileName
,"rb")) == NULL
) {
286 fprintf (stderr
, "Can't open %s: %s\n", fileName
, strerror(errno
));
290 /* read ELF header */
291 rxCount
= fread(rxBlock
, 1, sizeof elfHeader
, file
);
292 getPtr
= ExtractBlock(sizeof elfHeader
.e_ident
, elfHeader
.e_ident
, rxBlock
);
293 getPtr
= ExtractWord(&elfHeader
.e_type
, getPtr
);
294 getPtr
= ExtractWord(&elfHeader
.e_machine
, getPtr
);
295 getPtr
= ExtractLong((DWORD
*)&elfHeader
.e_version
, getPtr
);
296 getPtr
= ExtractLong((DWORD
*)&elfHeader
.e_entry
, getPtr
);
297 getPtr
= ExtractLong((DWORD
*)&elfHeader
.e_phoff
, getPtr
);
298 getPtr
= ExtractLong((DWORD
*)&elfHeader
.e_shoff
, getPtr
);
299 getPtr
= ExtractLong((DWORD
*)&elfHeader
.e_flags
, getPtr
);
300 getPtr
= ExtractWord(&elfHeader
.e_ehsize
, getPtr
);
301 getPtr
= ExtractWord(&elfHeader
.e_phentsize
, getPtr
);
302 getPtr
= ExtractWord(&elfHeader
.e_phnum
, getPtr
);
303 getPtr
= ExtractWord(&elfHeader
.e_shentsize
, getPtr
);
304 getPtr
= ExtractWord(&elfHeader
.e_shnum
, getPtr
);
305 getPtr
= ExtractWord(&elfHeader
.e_shstrndx
, getPtr
);
306 if ( (rxCount
!= sizeof elfHeader
)
307 || (elfHeader
.e_ident
[0] != ELFMAG0
)
308 || (elfHeader
.e_ident
[1] != ELFMAG1
)
309 || (elfHeader
.e_ident
[2] != ELFMAG2
)
310 || (elfHeader
.e_ident
[3] != ELFMAG3
)
311 || (elfHeader
.e_type
!= ET_EXEC
)
314 fprintf (stderr
, "*** illegal file format\n");
318 /* read all section headers */
319 fseek(file
, elfHeader
.e_shoff
, SEEK_SET
);
320 for (i
= 0; i
< elfHeader
.e_shnum
; i
++) {
321 rxCount
= fread(rxBlock
, 1, sizeof sectHeader
[0], file
);
322 getPtr
= ExtractLong((DWORD
*)§Header
[i
].sh_name
, rxBlock
);
323 getPtr
= ExtractLong((DWORD
*)§Header
[i
].sh_type
, getPtr
);
324 getPtr
= ExtractLong((DWORD
*)§Header
[i
].sh_flags
, getPtr
);
325 getPtr
= ExtractLong((DWORD
*)§Header
[i
].sh_addr
, getPtr
);
326 getPtr
= ExtractLong((DWORD
*)§Header
[i
].sh_offset
, getPtr
);
327 getPtr
= ExtractLong((DWORD
*)§Header
[i
].sh_size
, getPtr
);
328 getPtr
= ExtractLong((DWORD
*)§Header
[i
].sh_link
, getPtr
);
329 getPtr
= ExtractLong((DWORD
*)§Header
[i
].sh_info
, getPtr
);
330 getPtr
= ExtractLong((DWORD
*)§Header
[i
].sh_addralign
, getPtr
);
331 getPtr
= ExtractLong((DWORD
*)§Header
[i
].sh_entsize
, getPtr
);
332 if (rxCount
!= sizeof sectHeader
[0]) {
334 fprintf (stderr
, "*** illegal file format\n");
339 if ((hdr_name
= strrchr(fileName
, '/')) == NULL
) {
344 /* write start record */
345 (void)BuildSRecord(srecLine
, 0, 0, (BYTE
*)hdr_name
, strlen(hdr_name
));
346 printf("%s\r\n",srecLine
);
348 /* write data records */
351 for (i
= 0; i
< elfHeader
.e_shnum
; i
++) {
352 if ( (sectHeader
[i
].sh_type
== SHT_PROGBITS
)
353 && (sectHeader
[i
].sh_size
!= 0)
355 loadSize
= sectHeader
[i
].sh_size
;
356 if (sectHeader
[i
].sh_flags
!= 0) {
357 loadAddr
= sectHeader
[i
].sh_addr
;
358 loadDiff
= loadAddr
- sectHeader
[i
].sh_offset
;
361 loadAddr
= sectHeader
[i
].sh_offset
+ loadDiff
;
364 if (loadAddr
< firstAddr
)
365 firstAddr
= loadAddr
;
367 /* build s-records */
368 loadSize
= sectHeader
[i
].sh_size
;
369 fseek(file
, sectHeader
[i
].sh_offset
, SEEK_SET
);
371 rxCount
= fread(rxBlock
, 1, (loadSize
> 32) ? 32 : loadSize
, file
);
374 fprintf (stderr
, "*** illegal file format\n");
377 (void)BuildSRecord(srecLine
, 3, loadAddr
+ loadOffset
, rxBlock
, rxCount
);
380 printf("%s\r\n",srecLine
);
386 (void)BuildSRecord(srecLine
, 7, firstAddr
+ loadOffset
, 0, 0);
387 printf("%s\r\n",srecLine
);
392 /*************************************************************************
394 |*************************************************************************/
396 int main( int argc
, char *argv
[ ])
401 ConvertELF(argv
[1], 0);
403 else if ((argc
== 4) && (strcmp(argv
[1], "-o") == 0)) {
404 ExtractNumber(&offset
, argv
[2]);
405 ConvertELF(argv
[3], offset
);
408 fprintf (stderr
, "Usage: img2srec [-o offset] <image>\n");