summaryrefslogtreecommitdiff
path: root/dfugen.py
blob: dc93d1db95e96d59e52ed8f52e20117fe1c4166c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#!/usr/bin/env python

import sys, struct, zlib
from elftools.elf.elffile import ELFFile

infile = sys.argv[1]
outfile = sys.argv[2]

e = ELFFile(open(infile))

buf = ''

for segment in sorted(e.iter_segments(), key = lambda x: x.header.p_paddr):
	if segment.header.p_type != 'PT_LOAD':
		continue
	
	data = segment.data()
	lma = segment.header.p_paddr
	
	# Workaround for LD aligning segments to a larger boundary than 8k.
	if lma == 0x8000000:
		lma += 0x2000
		data = data[0x2000:]
	
	# Add padding if necessary.
	buf += '\0' * (lma - 0x8002000 - len(buf))
	
	buf += data

# Align to 64B
if len(buf) & (64 - 1):
	buf += '\0' * (64 - (len(buf) & (64 - 1)))

# Add DFU suffix
buf += struct.pack('<HHHH3sB',
	0xffff,
	0x5679,
	0x1234,
	0x0100,
	'UFD',
	16,
)

# Calculate CRC.
buf += struct.pack('<I', ~zlib.crc32(buf) & 0xffffffff)

open(outfile, 'w').write(buf)