18
18
# file format suitable for flashing onto some embedded devices.
19
19
#
20
20
# Usage:
21
- # $ elf2hex.py <input> <output> [--symbol-map <output>]
21
+ # $ elf2hex.py <input> <output> [--symbol-map <output>] [--relocate-data-segment]
22
22
#
23
23
# Example:
24
24
# $ elf2hex.py ./blink ./blink.hex --symbol-map ./blink.symbols
25
25
#
26
+ # The --relocate-data-segment option expects to be able to locate symbols with names
27
+ # - __data_start
28
+ # - __flash_data_start
29
+ # - __flash_data_len
30
+ # and then it physically relocates a segment located at __data_start to
31
+ # __flash_data_start, without changing virtual/physical addresses of any ELF
32
+ # headers. This means that the .hex file is not validly mapped until a boot-time
33
+ # reverse relocation step.
34
+ #
35
+ # See the linker script used in a particular demo folder for a detailed
36
+ # explanation of the linking, packing, and runtime relocation scheme.
37
+ #
26
38
27
39
import argparse
28
40
import json
@@ -36,18 +48,12 @@ def main():
36
48
parser .add_argument ('input' )
37
49
parser .add_argument ('output' )
38
50
parser .add_argument ('--symbol-map' )
39
- parser .add_argument ('--relocate' , action = 'append ' )
51
+ parser .add_argument ('--relocate-data-segment ' , action = 'store_true ' )
40
52
args = parser .parse_args ()
41
53
42
54
inf = open (args .input , "rb" )
43
55
outf = open (args .output , "wb" )
44
56
45
- relocations = {}
46
- if args .relocate is not None :
47
- for r in args .relocate :
48
- (a , b ) = r .split (":" )
49
- relocations [int (a , 16 )] = int (b , 16 )
50
-
51
57
def emitrecord (record ):
52
58
checksum = 0
53
59
pos = 0
@@ -77,6 +83,30 @@ def emit(vmaddr, data):
77
83
vmaddr += chunklen
78
84
79
85
elffile = elftools .elf .elffile .ELFFile (inf )
86
+
87
+ symbol_map = {}
88
+ symtab_section = elffile .get_section_by_name (".symtab" )
89
+ for s in symtab_section .iter_symbols ():
90
+ if s .entry .st_info .type not in ["STT_FUNC" , "STT_NOTYPE" ]:
91
+ continue
92
+ if s .name == "" :
93
+ continue
94
+ symbol_map [s .name ] = s .entry .st_value
95
+
96
+ if args .symbol_map is not None :
97
+ pathlib .Path (args .symbol_map ).write_text (json .dumps (symbol_map ))
98
+
99
+ relocations = {}
100
+ if args .relocate_data_segment :
101
+ __flash_data_start = symbol_map ["__flash_data_start" ]
102
+ __data_start = symbol_map ["__data_start" ]
103
+ __flash_data_len = symbol_map ["__flash_data_len" ]
104
+ print ("Relocation info:" )
105
+ print (f" __flash_data_start = 0x{ __flash_data_start :08x} " )
106
+ print (f" __data_start = 0x{ __data_start :08x} " )
107
+ print (f" __flash_data_len = 0x{ __flash_data_len :08x} " )
108
+ relocations = {__data_start : __flash_data_start }
109
+
80
110
for segment in elffile .iter_segments ():
81
111
if segment .header .p_type != "PT_LOAD" :
82
112
continue
@@ -101,20 +131,6 @@ def emit(vmaddr, data):
101
131
recordtype = "01" # EOF
102
132
emitrecord (f"{ chunklen :02X} { vmaddr :04X} { recordtype } " )
103
133
104
- symbol_map = {}
105
- symtab_section = elffile .get_section_by_name (".symtab" )
106
- for s in symtab_section .iter_symbols ():
107
- if s .entry .st_info .type not in ["STT_FUNC" , "STT_NOTYPE" ]:
108
- continue
109
- if s .entry .st_shndx == "SHN_ABS" :
110
- continue
111
- if s .name == "" :
112
- continue
113
- symbol_map [s .name ] = s .entry .st_value
114
-
115
- if args .symbol_map is not None :
116
- pathlib .Path (args .symbol_map ).write_text (json .dumps (symbol_map ))
117
-
118
134
inf .close ()
119
135
outf .close ()
120
136
0 commit comments