Clone of official tools
targets/REALTEK_RTL8195AM.py
- Committer:
- Anders Blomdell
- Date:
- 2021-02-04
- Revision:
- 47:21ae3e5a7128
- Parent:
- 43:2a7da56ebd24
File content as of revision 47:21ae3e5a7128:
""" Realtek Semiconductor Corp. RTL8195A elf2bin script """ import sys, array, struct, os, re, subprocess import hashlib import shutil import time import binascii import elftools from tools.paths import TOOLS_BOOTLOADERS from tools.toolchains import TOOLCHAIN_PATHS # Constant Variables TAG = 0x81950001 VER = 0x81950001 CAMPAIGN = binascii.hexlify('FFFFFFFFFFFFFFFF') RAM2_HEADER = { 'tag': 0, 'ver': 0, 'timestamp': 0, 'size': 72, 'hash': 'FF', 'campaign': 'FF', 'crc32': 0xFFFFFFFF, } def format_number(number, width): # convert to string line = format(number, '0%dx' % (width)) if len(line) > width: print "[ERROR] 0x%s cannot fit in width %d" % (line, width) sys.exit(-1) # cut string to list & reverse line = [line[i:i+2] for i in range(0, len(line), 2)] line.reverse() return binascii.a2b_hex("".join(line)) def format_string(string): return binascii.a2b_hex(string) def write_number(value, width, output): output.write(format_number(value, width)) def write_string(value, width, output): output.write(format_string(value)) def append_image_file(image, output): input = open(image, "rb") output.write(input.read()) input.close() def write_padding_bytes(output_name, size): current_size = os.stat(output_name).st_size padcount = size - current_size if padcount < 0: print "[ERROR] image is larger than expected size" sys.exit(-1) output = open(output_name, "ab") output.write('\377' * padcount) output.close() def crc32_checksum(string): return binascii.crc32(string) & 0xFFFFFFFF def sha256_checksum(filename, block_size=65536): sha256 = hashlib.sha256() with open(filename, 'rb') as f: for block in iter(lambda: f.read(block_size), b''): sha256.update(block) return sha256.hexdigest() def epoch_timestamp(): epoch = int(time.time()) return epoch def find_symbol(toolchain, mapfile, symbol): ret = None HEX = '0x0{,8}(?P<addr>[0-9A-Fa-f]{8})' if toolchain == "GCC_ARM": SYM = re.compile(r'^\s+' + HEX + r'\s+' + symbol + '\r?$') elif toolchain in ["ARM_STD", "ARM", "ARM_MICRO"]: SYM = re.compile(r'^\s+' + HEX + r'\s+0x[0-9A-Fa-f]{8}\s+Code.*\s+i\.' + symbol + r'\s+.*$') elif toolchain == "IAR": SYM = re.compile(r'^' + symbol + r'\s+' + HEX + '\s+.*$') with open(mapfile, 'r') as infile: for line in infile: match = re.match(SYM, line) if match: ret = match.group("addr") if not ret: print "[ERROR] cannot find the address of symbol " + symbol return 0 return int(ret,16) | 1 def _parse_load_segment_inner(image_elf): with open(image_elf, "rb") as fd: elffile = elftools.elf.elffile.ELFFile(fd) for segment in elffile.iter_segments(): offset = segment['p_offset'] addr = segment['p_vaddr'] size = segment['p_filesz'] if (addr != 0 and size != 0 and segment['p_type'] == 'PT_LOAD'): yield offset, addr, size def parse_load_segment(toolchain, image_elf): return list(_parse_load_segment_inner(image_elf)) def create_payload(image_elf, ram2_bin, entry, segment): file_elf = open(image_elf, "rb") file_bin = open(ram2_bin, "wb") write_number(int(entry), 8, file_bin) write_number(int(len(segment)), 8, file_bin) write_number(0xFFFFFFFF, 8, file_bin) write_number(0xFFFFFFFF, 8, file_bin) for (offset, addr, size) in segment: file_elf.seek(offset) # write image header - size & addr write_number(addr, 8, file_bin) write_number(size, 8, file_bin) # write load segment file_bin.write(file_elf.read(size)) delta = size % 4 if delta != 0: padding = 4 - delta write_number(0x0, padding * 2, file_bin) file_bin.close() file_elf.close() def create_daplink(image_bin, ram1_bin, ram2_bin): # remove target binary file/path if os.path.isfile(image_bin): os.remove(image_bin) else: shutil.rmtree(image_bin) RAM2_HEADER['tag'] = format_number(TAG, 8) RAM2_HEADER['ver'] = format_number(VER, 8) RAM2_HEADER['timestamp'] = format_number(epoch_timestamp(), 16) RAM2_HEADER['size'] = format_number(os.stat(ram2_bin).st_size + 72, 8) RAM2_HEADER['hash'] = format_string(sha256_checksum(ram2_bin)) RAM2_HEADER['campaign'] = format_string(CAMPAIGN) output = open(image_bin, "wb") append_image_file(ram1_bin, output) append_image_file(ram2_bin, output) output.seek(0xb000) line = "" for key in ['tag', 'ver', 'timestamp', 'size', 'hash', 'campaign']: line += RAM2_HEADER[key] output.write(RAM2_HEADER[key]) RAM2_HEADER['crc32'] = format_number(crc32_checksum(line), 8) output.write(RAM2_HEADER['crc32']) output.close() # ---------------------------- # main function # ---------------------------- def rtl8195a_elf2bin(t_self, image_elf, image_bin): image_name = list(os.path.splitext(image_elf))[:-1] image_map = ".".join(image_name + ['map']) ram1_bin = os.path.join(TOOLS_BOOTLOADERS, "REALTEK_RTL8195AM", "ram_1.bin") ram2_bin = ".".join(image_name) + '-payload.bin' entry = find_symbol(t_self.name, image_map, "PLAT_Start") segment = parse_load_segment(t_self.name, image_elf) create_payload(image_elf, ram2_bin, entry, segment) create_daplink(image_bin, ram1_bin, ram2_bin)