Newer
Older
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import os
import struct
import ctypes
import sys
import subprocess
from gather_dtso import gather_dtso
global dtbo_info
def gen_magic():
global dtbo_info
struct.pack_into('cccc', dtbo_info, 0, b'M', b'C', b'H', b'P')
def gen_descriptor_length(no_of_contexts, no_of_dtbo):
global dtbo_info
descriptor_length = 12 + (4 * no_of_contexts) + (4 * no_of_dtbo)
struct.pack_into('I', dtbo_info, 4, descriptor_length)
# 2 bytes longs version number
def gen_version():
global dtbo_info
version = 0
struct.pack_into('H', dtbo_info, 8, version)
def gen_number_of_contexts(no_of_contexts):
global dtbo_info
in_number_of_contexts = no_of_contexts
struct.pack_into('H', dtbo_info, 10, in_number_of_contexts)
def get_dtbo_files_list():
initial_directory = os.getcwd()
context_dir = os.path.join(initial_directory, "work", "dtbo", "context-0")
dtbo_files_list = []
for root, dirs, files in os.walk(context_dir):
for file in files:
if file.endswith(".dtbo"):
dtbo_files_list.append(os.path.join(root, file))
return dtbo_files_list
def get_dtbo_total_size(dtbo_list):
size = 0
for dtbo_file in dtbo_list:
size = size + os.path.getsize(dtbo_file)
return size
def gen_dtbo_info(overlay_dir_path, no_of_contexts, dtbo_list):
dtbo_desc_list_start_offset = 12 + (no_of_contexts * 4)
struct.pack_into('I', dtbo_info, 12, dtbo_desc_list_start_offset)
no_of_dtbo = len(dtbo_list)
struct.pack_into('I', dtbo_info, 16, no_of_dtbo)
dtbo_data_offset = 20 + (no_of_dtbo * 12)
dtbo_idx = 0
for dtbo_file in dtbo_list:
size = os.path.getsize(dtbo_file)
struct.pack_into('I', dtbo_info, 20 + (dtbo_idx * 12), dtbo_data_offset)
struct.pack_into('I', dtbo_info, 24 + (dtbo_idx * 12), dtbo_data_offset + size)
struct.pack_into('I', dtbo_info, 28 + (dtbo_idx * 12), size)
dtbo_data_offset += size
dtbo_idx += 1
dtbo_full_path = os.path.join(overlay_dir_path, "mpfs_dtbo.spi")
with open(dtbo_full_path, "wb") as mpfs_dtbo:
mpfs_dtbo.write(dtbo_info)
#
# Append the actual dtbo files to the dtbo_file
#
with open(dtbo_full_path, "ab") as mpfs_dtbo:
for dtbo_file in dtbo_list:
with open(dtbo_file, "rb") as in_dtbo_file:
mpfs_dtbo.write(in_dtbo_file.read())
def create_dtbo_info(overlay_dir_path):
global dtbo_info
dtbo_list = get_dtbo_files_list()
print("number of gateware device tree overlays: ", len(dtbo_list))
for dtbo_file in dtbo_list:
print(dtbo_file)
no_of_contexts = 1
no_of_dtbo = len(dtbo_list)
#
# Generate the DTBO info binary.
#
dtbo_info_length = 12 + (8 * no_of_contexts) + (12 * no_of_dtbo)
dtbo_info = ctypes.create_string_buffer(dtbo_info_length)
gen_magic()
gen_descriptor_length(no_of_contexts, no_of_dtbo)
gen_version()
gen_number_of_contexts(no_of_contexts)
gen_dtbo_info(overlay_dir_path, no_of_contexts, dtbo_list)
print(dtbo_info[:])
def get_gateware_git_version(work_dir):
try:
git_hash = subprocess.check_output(['git', 'describe', '--tags'])
except subprocess.CalledProcessError as e:
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
return git_hash.decode('ascii').strip("'").strip("\n")
def inject_git_info_into_src_dtso(dtso_file, git_version):
with open(dtso_file, "r") as f:
dtso = f.read()
dtso = dtso.replace('GATEWARE_GIT_VERSION', git_version)
with open(dtso_file, "w") as fout:
fout.write(dtso)
def compile_dtso(work_dir):
root_dir = os.path.join(work_dir, 'dtbo', 'context-0')
git_version = get_gateware_git_version(work_dir)
for root, dirs, files in os.walk(root_dir):
for file in files:
if file.endswith(".dtso"):
dtso_file = os.path.join(root, file)
inject_git_info_into_src_dtso(dtso_file, git_version)
dtbo_file = os.path.splitext(dtso_file)[0] + '.dtbo'
cmd = 'dtc -O dtb -I dts -o ' + dtbo_file + ' ' + dtso_file
os.system(cmd)
def generate_device_tree_overlays(overlay_dir_path, build_options_list):
print("================================================================================")
print(" Generate Device Tree Overlays")
print("================================================================================\r\n", flush=True)
bitstream_builder_root = os.getcwd()
gateware_dir = os.path.join(bitstream_builder_root, 'sources', 'FPGA-design')
work_dir = os.path.join(bitstream_builder_root, 'work')
gather_dtso(gateware_dir, work_dir, build_options_list)
compile_dtso(work_dir)
create_dtbo_info(overlay_dir_path)
def generate_gateware_overlays(overlay_dir_path, build_options_list):
generate_device_tree_overlays(overlay_dir_path, build_options_list)
if __name__ == '__main__':
if len(sys.argv) > 1:
argument_list = sys.argv[1:]
else:
argument_list = 'NONE'
generate_device_tree_overlays(argument_list)