1#!/usr/bin/env python
2
3# generates Zynq bootrom header from input payout
4
5import sys, os, array
6
7if len(sys.argv) < 3:
8    print ("not enough args, usage:")
9    print ("%s <binfile> <outfile>" % sys.argv[0])
10    sys.exit(1)
11
12fin = open(sys.argv[1], "r+b")
13finsize = os.stat(sys.argv[1]).st_size
14fout = open(sys.argv[2], "w+b")
15
16header = array.array('I')
17
18# start generating header
19# from section 6.3.2 of Zynq-700 AP SoC Technical Reference Manual (v1.7)
20
21# vector table (8 words)
22for _ in range(0, 8):
23    header.append(0)
24
25# (0x20) width detection
26header.append(0xaa995566)
27
28# (0x24) identification 'XLNX'
29header.append(0x584c4e58)
30
31# (0x28) encryption status (not encrypted)
32header.append(0)
33
34# (0x2c) user defined
35header.append(0)
36
37# (0x30) source offset
38header.append(0x8c0)
39
40# (0x34) length of image
41header.append(finsize)
42
43# (0x38) reserved
44header.append(0)
45
46# (0x3c) start of execution (0)
47header.append(0)
48
49# (0x40) total image length (same as length of image for non secure)
50header.append(finsize)
51
52# (0x44) reserved
53header.append(0)
54
55# (0x48) header checksum
56sum = 0
57for i in header:
58    sum += i
59sum = ~sum
60header.append(sum & 0xffffffff)
61
62# user defined
63for _ in range(0x4c, 0xa0, 4):
64    header.append(0)
65
66# register init pairs (all ffs to cause it to skip)
67for _ in range(0xa0, 0x8a0, 4):
68    header.append(0xffffffff)
69
70# reserved
71for _ in range(0x8a0, 0x8c0, 4):
72    header.append(0)
73
74fout.write(header)
75
76# copy the input into the output
77while True:
78    buf = fin.read(1024)
79    if not buf:
80        break
81    fout.write(buf)
82
83fin.close()
84fout.close()
85