-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcheck-app-image.py
93 lines (77 loc) · 3.52 KB
/
check-app-image.py
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# Utility for showing information about segments in a GAP8 flash file (the ones that end in .img).
#
# The script will check if any segments overlap with the bootloader on the GAP8
# which will cause problems when loading it after flashing (i.e app will overwrite
# bootloader during jumping to application).
#
# Each information field in the flash image is 32-bits (unsigned) and is organized as follows:
# The first 4 integers are the header for the information and contains the following:
# * Size of binary (everything in the image file until the partition table)
# * Number of segments in image
# * Entrypoint where execution of the binary should start
# * Unknown (base address of entry point or interrupt vector location?)
# The following data is 4 integers per segment in the image (the number above in the header):
# * Offset in flash: The offset in flash (from where the img is stored) where the segment data starts
# * Offset in RAM: The offset in RAM where the data should be loaded
# * Size: The size of the segment (i.e size of data that should be copied into RAM from flash)
# * nBlocks: Number of blocks, not sure how this is used
#
# The limits for the regions used by the user application is according to the linker file for the bootloader
# where the L1 memory area used starts at 0x1b002000 and the L2 memory area used starts at 0x1C060000.
# If the user application has data that will be copied here the jumping to the application will most
# likely fail, since the bootloader will be overwritten while executing.
#
# If you application fails this test, then the solution is to move more data into the heap on L2, since
# this can safely be used once your application starts and can then overwrite the bootloader.
import sys
import struct
import argparse
startSBLInL2 = 0x1C060000
startSBLInL1 = 0x1b002000
parser = argparse.ArgumentParser(description='Show GAP8 firmware image header information')
parser.add_argument('image', metavar='image', help='firmware image to analyze')
args = parser.parse_args()
imageName = args.image
print("Showing info for {}".format(imageName))
fw = bytearray()
with open(imageName, "rb") as f:
fw.extend(f.read())
[size, nSegments, entry, entryBase] = struct.unpack("IIII", fw[0:16])
print("Size on disk: {}".format(len(fw)))
print("Size: {}".format(size))
print("nSegments: {}".format(nSegments))
print("Entrypoint: 0x{:X}".format(entry))
print("Entrypoint base?: 0x{:X}".format(entryBase))
print("")
if nSegments == 0 or nSegments > 16:
print("The number of segments is out of bounds, is this really a GAP8 flash image?")
sys.exit(1)
totalL2 = 0
totalL1 = 0
segmentSBLOverlap = []
i = 16
for si in range(nSegments):
[base, offset, size, nBlocks] = struct.unpack("IIII", fw[i:i+16])
info = "[{}] Flash offset = 0x{:X}\tRAM offset = 0x{:X}\tsize = 0x{:X}\tnBlocks = {}".format(
si, base, offset, size, nBlocks
)
print(info)
if offset >= 0x1C000000 and offset < 0x1D000000:
totalL2 += size
if offset + size >= startSBLInL2:
segmentSBLOverlap.append(info)
if offset >= 0x1B000000 and offset < 0x1C000000:
totalL1 += size
if offset + size >= startSBLInL1:
segmentSBLOverlap.append(info)
i += 16
print("")
print("L1 size to copy: 0x{:X} ({})".format(totalL1, totalL1))
print("L2 size to copy: 0x{:X} ({})".format(totalL2, totalL2))
print("")
if len(segmentSBLOverlap) > 0:
print("The following segments overlap with bootloader:")
for info in segmentSBLOverlap:
print(info)
sys.exit(1)
print("No overlap with bootloader, its all fine!")