Clone of official tools

Committer:
Anders Blomdell
Date:
Thu Feb 04 17:17:13 2021 +0100
Revision:
47:21ae3e5a7128
Parent:
43:2a7da56ebd24
Add a few normpath calls

Who changed what in which revision?

UserRevisionLine numberNew contents of line
The Other Jimmy 36:96847d42f010 1 """
theotherjimmy 40:7d3fa6b99b2b 2 Realtek Semiconductor Corp.
The Other Jimmy 36:96847d42f010 3
theotherjimmy 40:7d3fa6b99b2b 4 RTL8195A elf2bin script
The Other Jimmy 36:96847d42f010 5 """
The Other Jimmy 36:96847d42f010 6
The Other Jimmy 36:96847d42f010 7 import sys, array, struct, os, re, subprocess
The Other Jimmy 36:96847d42f010 8 import hashlib
theotherjimmy 40:7d3fa6b99b2b 9 import shutil
theotherjimmy 43:2a7da56ebd24 10 import time
theotherjimmy 43:2a7da56ebd24 11 import binascii
theotherjimmy 43:2a7da56ebd24 12 import elftools
The Other Jimmy 36:96847d42f010 13
The Other Jimmy 36:96847d42f010 14 from tools.paths import TOOLS_BOOTLOADERS
theotherjimmy 41:2a77626a4c21 15 from tools.toolchains import TOOLCHAIN_PATHS
The Other Jimmy 36:96847d42f010 16
The Other Jimmy 36:96847d42f010 17 # Constant Variables
theotherjimmy 43:2a7da56ebd24 18 TAG = 0x81950001
theotherjimmy 43:2a7da56ebd24 19 VER = 0x81950001
theotherjimmy 43:2a7da56ebd24 20 CAMPAIGN = binascii.hexlify('FFFFFFFFFFFFFFFF')
The Other Jimmy 36:96847d42f010 21
theotherjimmy 43:2a7da56ebd24 22 RAM2_HEADER = {
theotherjimmy 43:2a7da56ebd24 23 'tag': 0,
theotherjimmy 43:2a7da56ebd24 24 'ver': 0,
theotherjimmy 43:2a7da56ebd24 25 'timestamp': 0,
theotherjimmy 43:2a7da56ebd24 26 'size': 72,
theotherjimmy 43:2a7da56ebd24 27 'hash': 'FF',
theotherjimmy 43:2a7da56ebd24 28 'campaign': 'FF',
theotherjimmy 43:2a7da56ebd24 29 'crc32': 0xFFFFFFFF,
theotherjimmy 43:2a7da56ebd24 30 }
The Other Jimmy 36:96847d42f010 31
theotherjimmy 43:2a7da56ebd24 32 def format_number(number, width):
theotherjimmy 43:2a7da56ebd24 33 # convert to string
theotherjimmy 43:2a7da56ebd24 34 line = format(number, '0%dx' % (width))
theotherjimmy 43:2a7da56ebd24 35 if len(line) > width:
theotherjimmy 43:2a7da56ebd24 36 print "[ERROR] 0x%s cannot fit in width %d" % (line, width)
theotherjimmy 43:2a7da56ebd24 37 sys.exit(-1)
theotherjimmy 43:2a7da56ebd24 38 # cut string to list & reverse
theotherjimmy 43:2a7da56ebd24 39 line = [line[i:i+2] for i in range(0, len(line), 2)]
theotherjimmy 43:2a7da56ebd24 40 line.reverse()
theotherjimmy 43:2a7da56ebd24 41 return binascii.a2b_hex("".join(line))
theotherjimmy 43:2a7da56ebd24 42
theotherjimmy 43:2a7da56ebd24 43 def format_string(string):
theotherjimmy 43:2a7da56ebd24 44 return binascii.a2b_hex(string)
theotherjimmy 43:2a7da56ebd24 45
theotherjimmy 43:2a7da56ebd24 46 def write_number(value, width, output):
theotherjimmy 43:2a7da56ebd24 47 output.write(format_number(value, width))
theotherjimmy 43:2a7da56ebd24 48
theotherjimmy 43:2a7da56ebd24 49 def write_string(value, width, output):
theotherjimmy 43:2a7da56ebd24 50 output.write(format_string(value))
The Other Jimmy 36:96847d42f010 51
The Other Jimmy 36:96847d42f010 52 def append_image_file(image, output):
The Other Jimmy 36:96847d42f010 53 input = open(image, "rb")
The Other Jimmy 36:96847d42f010 54 output.write(input.read())
The Other Jimmy 36:96847d42f010 55 input.close()
The Other Jimmy 36:96847d42f010 56
theotherjimmy 40:7d3fa6b99b2b 57 def write_padding_bytes(output_name, size):
theotherjimmy 40:7d3fa6b99b2b 58 current_size = os.stat(output_name).st_size
theotherjimmy 40:7d3fa6b99b2b 59 padcount = size - current_size
theotherjimmy 40:7d3fa6b99b2b 60 if padcount < 0:
theotherjimmy 40:7d3fa6b99b2b 61 print "[ERROR] image is larger than expected size"
theotherjimmy 40:7d3fa6b99b2b 62 sys.exit(-1)
theotherjimmy 40:7d3fa6b99b2b 63 output = open(output_name, "ab")
theotherjimmy 40:7d3fa6b99b2b 64 output.write('\377' * padcount)
The Other Jimmy 36:96847d42f010 65 output.close()
The Other Jimmy 36:96847d42f010 66
theotherjimmy 43:2a7da56ebd24 67 def crc32_checksum(string):
theotherjimmy 43:2a7da56ebd24 68 return binascii.crc32(string) & 0xFFFFFFFF
theotherjimmy 43:2a7da56ebd24 69
theotherjimmy 40:7d3fa6b99b2b 70 def sha256_checksum(filename, block_size=65536):
theotherjimmy 40:7d3fa6b99b2b 71 sha256 = hashlib.sha256()
theotherjimmy 40:7d3fa6b99b2b 72 with open(filename, 'rb') as f:
theotherjimmy 40:7d3fa6b99b2b 73 for block in iter(lambda: f.read(block_size), b''):
theotherjimmy 40:7d3fa6b99b2b 74 sha256.update(block)
theotherjimmy 40:7d3fa6b99b2b 75 return sha256.hexdigest()
The Other Jimmy 36:96847d42f010 76
theotherjimmy 43:2a7da56ebd24 77 def epoch_timestamp():
theotherjimmy 43:2a7da56ebd24 78 epoch = int(time.time())
theotherjimmy 43:2a7da56ebd24 79 return epoch
theotherjimmy 40:7d3fa6b99b2b 80
theotherjimmy 40:7d3fa6b99b2b 81 def find_symbol(toolchain, mapfile, symbol):
theotherjimmy 40:7d3fa6b99b2b 82 ret = None
theotherjimmy 40:7d3fa6b99b2b 83
theotherjimmy 40:7d3fa6b99b2b 84 HEX = '0x0{,8}(?P<addr>[0-9A-Fa-f]{8})'
The Other Jimmy 36:96847d42f010 85 if toolchain == "GCC_ARM":
theotherjimmy 40:7d3fa6b99b2b 86 SYM = re.compile(r'^\s+' + HEX + r'\s+' + symbol + '\r?$')
The Other Jimmy 36:96847d42f010 87 elif toolchain in ["ARM_STD", "ARM", "ARM_MICRO"]:
theotherjimmy 40:7d3fa6b99b2b 88 SYM = re.compile(r'^\s+' + HEX + r'\s+0x[0-9A-Fa-f]{8}\s+Code.*\s+i\.' + symbol + r'\s+.*$')
The Other Jimmy 36:96847d42f010 89 elif toolchain == "IAR":
theotherjimmy 40:7d3fa6b99b2b 90 SYM = re.compile(r'^' + symbol + r'\s+' + HEX + '\s+.*$')
theotherjimmy 40:7d3fa6b99b2b 91
theotherjimmy 40:7d3fa6b99b2b 92 with open(mapfile, 'r') as infile:
theotherjimmy 40:7d3fa6b99b2b 93 for line in infile:
theotherjimmy 40:7d3fa6b99b2b 94 match = re.match(SYM, line)
theotherjimmy 40:7d3fa6b99b2b 95 if match:
theotherjimmy 40:7d3fa6b99b2b 96 ret = match.group("addr")
theotherjimmy 40:7d3fa6b99b2b 97
theotherjimmy 40:7d3fa6b99b2b 98 if not ret:
theotherjimmy 40:7d3fa6b99b2b 99 print "[ERROR] cannot find the address of symbol " + symbol
theotherjimmy 40:7d3fa6b99b2b 100 return 0
theotherjimmy 40:7d3fa6b99b2b 101
theotherjimmy 40:7d3fa6b99b2b 102 return int(ret,16) | 1
theotherjimmy 40:7d3fa6b99b2b 103
theotherjimmy 43:2a7da56ebd24 104 def _parse_load_segment_inner(image_elf):
theotherjimmy 43:2a7da56ebd24 105 with open(image_elf, "rb") as fd:
theotherjimmy 43:2a7da56ebd24 106 elffile = elftools.elf.elffile.ELFFile(fd)
theotherjimmy 43:2a7da56ebd24 107 for segment in elffile.iter_segments():
theotherjimmy 43:2a7da56ebd24 108 offset = segment['p_offset']
theotherjimmy 43:2a7da56ebd24 109 addr = segment['p_vaddr']
theotherjimmy 43:2a7da56ebd24 110 size = segment['p_filesz']
theotherjimmy 43:2a7da56ebd24 111 if (addr != 0 and size != 0 and segment['p_type'] == 'PT_LOAD'):
theotherjimmy 43:2a7da56ebd24 112 yield offset, addr, size
theotherjimmy 40:7d3fa6b99b2b 113
theotherjimmy 40:7d3fa6b99b2b 114 def parse_load_segment(toolchain, image_elf):
theotherjimmy 43:2a7da56ebd24 115 return list(_parse_load_segment_inner(image_elf))
theotherjimmy 43:2a7da56ebd24 116
theotherjimmy 43:2a7da56ebd24 117 def create_payload(image_elf, ram2_bin, entry, segment):
theotherjimmy 43:2a7da56ebd24 118 file_elf = open(image_elf, "rb")
theotherjimmy 43:2a7da56ebd24 119 file_bin = open(ram2_bin, "wb")
theotherjimmy 40:7d3fa6b99b2b 120
theotherjimmy 43:2a7da56ebd24 121 write_number(int(entry), 8, file_bin)
theotherjimmy 43:2a7da56ebd24 122 write_number(int(len(segment)), 8, file_bin)
theotherjimmy 43:2a7da56ebd24 123 write_number(0xFFFFFFFF, 8, file_bin)
theotherjimmy 43:2a7da56ebd24 124 write_number(0xFFFFFFFF, 8, file_bin)
theotherjimmy 43:2a7da56ebd24 125
theotherjimmy 40:7d3fa6b99b2b 126 for (offset, addr, size) in segment:
theotherjimmy 40:7d3fa6b99b2b 127 file_elf.seek(offset)
theotherjimmy 40:7d3fa6b99b2b 128 # write image header - size & addr
theotherjimmy 43:2a7da56ebd24 129 write_number(addr, 8, file_bin)
theotherjimmy 43:2a7da56ebd24 130 write_number(size, 8, file_bin)
theotherjimmy 40:7d3fa6b99b2b 131 # write load segment
theotherjimmy 40:7d3fa6b99b2b 132 file_bin.write(file_elf.read(size))
theotherjimmy 40:7d3fa6b99b2b 133 delta = size % 4
theotherjimmy 40:7d3fa6b99b2b 134 if delta != 0:
theotherjimmy 40:7d3fa6b99b2b 135 padding = 4 - delta
theotherjimmy 43:2a7da56ebd24 136 write_number(0x0, padding * 2, file_bin)
theotherjimmy 40:7d3fa6b99b2b 137 file_bin.close()
theotherjimmy 40:7d3fa6b99b2b 138 file_elf.close()
theotherjimmy 40:7d3fa6b99b2b 139
theotherjimmy 43:2a7da56ebd24 140 def create_daplink(image_bin, ram1_bin, ram2_bin):
theotherjimmy 43:2a7da56ebd24 141
theotherjimmy 40:7d3fa6b99b2b 142 # remove target binary file/path
theotherjimmy 40:7d3fa6b99b2b 143 if os.path.isfile(image_bin):
theotherjimmy 40:7d3fa6b99b2b 144 os.remove(image_bin)
theotherjimmy 40:7d3fa6b99b2b 145 else:
theotherjimmy 40:7d3fa6b99b2b 146 shutil.rmtree(image_bin)
theotherjimmy 40:7d3fa6b99b2b 147
theotherjimmy 43:2a7da56ebd24 148 RAM2_HEADER['tag'] = format_number(TAG, 8)
theotherjimmy 43:2a7da56ebd24 149 RAM2_HEADER['ver'] = format_number(VER, 8)
theotherjimmy 43:2a7da56ebd24 150 RAM2_HEADER['timestamp'] = format_number(epoch_timestamp(), 16)
theotherjimmy 43:2a7da56ebd24 151 RAM2_HEADER['size'] = format_number(os.stat(ram2_bin).st_size + 72, 8)
theotherjimmy 43:2a7da56ebd24 152 RAM2_HEADER['hash'] = format_string(sha256_checksum(ram2_bin))
theotherjimmy 43:2a7da56ebd24 153 RAM2_HEADER['campaign'] = format_string(CAMPAIGN)
The Other Jimmy 36:96847d42f010 154
The Other Jimmy 36:96847d42f010 155 output = open(image_bin, "wb")
theotherjimmy 40:7d3fa6b99b2b 156 append_image_file(ram1_bin, output)
theotherjimmy 40:7d3fa6b99b2b 157 append_image_file(ram2_bin, output)
theotherjimmy 43:2a7da56ebd24 158
theotherjimmy 43:2a7da56ebd24 159 output.seek(0xb000)
theotherjimmy 43:2a7da56ebd24 160 line = ""
theotherjimmy 43:2a7da56ebd24 161 for key in ['tag', 'ver', 'timestamp', 'size', 'hash', 'campaign']:
theotherjimmy 43:2a7da56ebd24 162 line += RAM2_HEADER[key]
theotherjimmy 43:2a7da56ebd24 163 output.write(RAM2_HEADER[key])
theotherjimmy 43:2a7da56ebd24 164
theotherjimmy 43:2a7da56ebd24 165 RAM2_HEADER['crc32'] = format_number(crc32_checksum(line), 8)
theotherjimmy 43:2a7da56ebd24 166
theotherjimmy 43:2a7da56ebd24 167 output.write(RAM2_HEADER['crc32'])
The Other Jimmy 36:96847d42f010 168 output.close()
theotherjimmy 43:2a7da56ebd24 169
theotherjimmy 43:2a7da56ebd24 170 # ----------------------------
theotherjimmy 43:2a7da56ebd24 171 # main function
theotherjimmy 43:2a7da56ebd24 172 # ----------------------------
theotherjimmy 43:2a7da56ebd24 173 def rtl8195a_elf2bin(t_self, image_elf, image_bin):
theotherjimmy 43:2a7da56ebd24 174
theotherjimmy 43:2a7da56ebd24 175 image_name = list(os.path.splitext(image_elf))[:-1]
theotherjimmy 43:2a7da56ebd24 176 image_map = ".".join(image_name + ['map'])
theotherjimmy 43:2a7da56ebd24 177
theotherjimmy 43:2a7da56ebd24 178 ram1_bin = os.path.join(TOOLS_BOOTLOADERS, "REALTEK_RTL8195AM", "ram_1.bin")
theotherjimmy 43:2a7da56ebd24 179 ram2_bin = ".".join(image_name) + '-payload.bin'
theotherjimmy 43:2a7da56ebd24 180
theotherjimmy 43:2a7da56ebd24 181 entry = find_symbol(t_self.name, image_map, "PLAT_Start")
theotherjimmy 43:2a7da56ebd24 182 segment = parse_load_segment(t_self.name, image_elf)
theotherjimmy 43:2a7da56ebd24 183
theotherjimmy 43:2a7da56ebd24 184 create_payload(image_elf, ram2_bin, entry, segment)
theotherjimmy 43:2a7da56ebd24 185 create_daplink(image_bin, ram1_bin, ram2_bin)