3 # baytrail_sst_firmware_parse.py - parse an SST firmware file
5 # Copyright (C) 2015 Antonio Ospite <ao2@ao2.it>
7 # This program is free software. It comes without any warranty, to
8 # the extent permitted by applicable law. You can redistribute it
9 # and/or modify it under the terms of the Do What The Fuck You Want
10 # To Public License, Version 2, as published by Sam Hocevar. See
11 # http://sam.zoy.org/wtfpl/COPYING for more details.
17 FIRMWARE_HEADER_SIZE = 32
18 MODULE_HEADER_SIZE = 20
21 def get(f, fmt, offset=None):
25 length = struct.calcsize(fmt)
27 value = struct.unpack_from(fmt, data)
31 def sst_firmware_parse(firmware_file_name):
33 f = open(firmware_file_name, "rb")
34 filesize = os.path.getsize(firmware_file_name)
36 signature = get(f, "4s")
37 if signature != "$SST":
41 payload_size = get(f, '<L')
42 print "Payload size:", payload_size
44 if (payload_size + FIRMWARE_HEADER_SIZE) != filesize:
45 print "invalid payload size"
48 num_modules = get(f, '<L')
49 print "Number of modules:", num_modules
51 file_format = get(f, '<L')
52 print "File format:", file_format
60 for i in range(0, num_modules):
61 print "\nModule %d" % i
63 signature = get(f, "4s")
64 if signature != "$SST":
65 print "Invalid module"
68 module_size = get(f, '<L')
69 print "module size:", module_size
71 if (module_size + MODULE_HEADER_SIZE) != payload_size:
72 print "Invalid module size:"
75 num_blocks = get(f, '<L')
76 print "Number of blocks:", num_blocks
78 block_type = get(f, '<L')
79 print "Block type: ", block_type
81 entry_point = get(f, '<L')
82 print "Entry point: 0x%08x" % entry_point
85 for j in range(0, num_blocks):
86 print "\nBlock %d" % j
88 ram_type = get(f, '<L')
89 print "Ram type:", ram_type
91 block_size = get(f, '<L')
92 print "Block size: %d (0x%08x)" % (block_size, block_size)
94 total_block_size += block_size + 16
95 print "Total block size: %d (0x%08x)" % \
96 (total_block_size, total_block_size)
98 ram_offset = get(f, '<L')
99 print "Ram offset: 0x%08x" % ram_offset
105 get(f, "%db" % block_size)
107 if total_block_size != module_size:
108 print "Invalid total block size:"
114 if __name__ == "__main__":
115 filename = sys.argv[1]
116 ret = sst_firmware_parse(filename)