mbed-os/tools/targets/REALTEK_RTL8195AM.py

183 lines
7.3 KiB
Python
Raw Normal View History

2017-02-16 09:37:24 +00:00
"""
mbed REALTEK_RTL8195AM elf2bin script
Copyright (c) 2011-2016 Realtek Semiconductor Corp.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
LIBRARIES BUILD
"""
import sys, array, struct, os, re, subprocess
import hashlib
from tools.paths import TOOLS_BOOTLOADERS
from datetime import datetime
# Constant Variables
RAM2_RSVD = 0x3131373835393138
RAM3_RSVD = 0xFFFFFFFFFFFFFFFF
IMG2_OFFSET = 0x10006000 #default
2017-02-16 09:37:24 +00:00
def write_fixed_width_string(value, width, output):
# cut string to list & reverse
line = [value[i:i+2] for i in range(0, len(value), 2)]
output.write("".join([chr(long(b, 16)) for b in line]))
2017-02-16 09:37:24 +00:00
def write_fixed_width_value(value, width, output):
# convert to string
line = format(value, '0%dx' % (width))
if len(line) > width:
print "[ERROR] value 0x%s cannot fit 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()
# convert to write buffer
output.write("".join([chr(long(b, 16)) for b in line]))
2017-02-16 09:37:24 +00:00
def append_image_file(image, output):
try:
input = open(image, "rb")
output.write(input.read())
except Exception:
return
2017-02-16 09:37:24 +00:00
input.close()
def prepend(image, image_prepend, toolchain, info):
if info['size'] == 0:
return
output = open(image_prepend, "wb")
2017-03-07 09:58:34 +00:00
write_fixed_width_value(info['size'], 8, output)
write_fixed_width_value(info['addr'], 8, output)
if info['img'] == 2 :
write_fixed_width_value(RAM2_RSVD, 16, output)
elif info['img'] == 3 :
write_fixed_width_value(RAM3_RSVD, 16, output)
if os.path.isfile(image):
with open(image, "rb") as input:
if toolchain == "IAR":
input.seek(info['addr'])
elif info['img'] == 3: #toolchain is not IAR
input.seek(info['addr']-IMG2_OFFSET)
output.write(input.read(info['size']))
else:
image = os.path.join(image, info['name'])
with open(image, "rb") as input:
output.write(input.read(info['size']))
2017-02-16 09:37:24 +00:00
output.close()
2017-02-16 09:37:24 +00:00
def _parse_section(toolchain, elf, section):
2017-03-07 09:58:34 +00:00
info = {'addr':None, 'size':0};
if toolchain not in ["GCC_ARM", "ARM_STD", "ARM", "ARM_MICRO", "IAR"]:
print "[ERROR] unsupported toolchain " + toolchain
sys.exit(-1)
2017-02-16 09:37:24 +00:00
mapfile = elf.rsplit(".", 1)[0] + ".map"
with open(mapfile, 'r') as infile:
# Search area to parse
for line in infile:
if toolchain == "GCC_ARM":
# .image2.table 0x[00000000]30000000 0x18
# 0x[00000000]30000000 __image2_start__ = .
# 0x[00000000]30000000 __image2_entry_func__ = .
match = re.match(r'^' + section + \
2017-03-07 09:58:34 +00:00
r'\s+0x0{,8}(?P<addr>[0-9A-Fa-f]{8})\s+0x(?P<size>[0-9A-Fa-f]+).*$', line)
elif toolchain in ["ARM_STD", "ARM", "ARM_MICRO"]:
# Memory Map of the image
# Load Region LR_DRAM (Base: 0x30000000, Size: 0x00006a74, Max: 0x00200000, ABSOLUTE)
# Execution Region IMAGE2_TABLE (Base: 0x30000000, Size: 0x00000018, Max: 0xffffffff, ABSOLUTE, FIXED)
# Base Addr Size Type Attr Idx E Section Name Object
# 0x30000000 0x00000004 Data RO 5257 .image2.ram.data rtl8195a_init.o
match = re.match(r'^.*Region\s+' + section + \
2017-03-07 09:58:34 +00:00
r'\s+\(Base: 0x(?P<addr>[0-9A-Fa-f]{8}),\s+Size: 0x(?P<size>[0-9A-Fa-f]+), .*\)$', line)
elif toolchain == "IAR":
# Section Kind Address Size Object
# ------- ---- ------- ---- ------
# "A3": 0x8470
# IMAGE2 0x10006000 0x5d18 <Block>
# .ram_image2.text 0x10006000 0x5bbc <Block>
# .rodata const 0x10006000 0x14 retarget.o [17]
match = re.match(r'^\s+' + section + \
r'\s+0x(?P<addr>[0-9A-Fa-f]{8})\s+0x(?P<size>[0-9A-Fa-f]+)\s+.*<Block>$', line)
if match:
info['addr'] = int(match.group("addr"), 16)
try:
info['size'] = int(match.group("size"), 16)
except IndexError:
2017-03-07 09:58:34 +00:00
print "[WARNING] cannot find the size of section " + section
return info
2017-03-07 09:58:34 +00:00
print "[ERROR] cannot find the address of section " + section
return info
2017-02-16 09:37:24 +00:00
def parse_section(toolchain, elf, sections, img):
img_info = {'name':"", 'addr':None, 'size':0, 'img':img}
for section in sections:
section_info = _parse_section(toolchain, elf, section)
if img_info['addr'] is None or img_info['addr'] > section_info['addr']:
img_info['addr'] = section_info['addr']
img_info['name'] = section
img_info['size'] = img_info['size'] + section_info['size']
return img_info
2017-02-16 09:37:24 +00:00
# ----------------------------
# main function
# ----------------------------
def rtl8195a_elf2bin(toolchain, image_elf, image_bin):
if toolchain == "GCC_ARM":
2017-03-07 09:58:34 +00:00
img2_sections = [".image2.table", ".text", ".data"]
img3_sections = [".sdr_all"]
2017-02-16 09:37:24 +00:00
elif toolchain in ["ARM_STD", "ARM", "ARM_MICRO"]:
2017-03-07 09:58:34 +00:00
img2_sections = [".image2.table", ".text", ".data"]
img3_sections = ["_DRAM_CODE"]
2017-02-16 09:37:24 +00:00
elif toolchain == "IAR":
2017-03-07 09:58:34 +00:00
img2_sections = ["IMAGE2"]
img3_sections = ["SDRAM"]
2017-02-16 09:37:24 +00:00
else:
2017-05-22 06:31:32 +00:00
print("[error] unsupported toolchain") + toolchain
return
image2_info = {'addr':None, 'size':0, 'img':2}
image3_info = {'addr':None, 'size':0, 'img':3}
2017-02-16 09:37:24 +00:00
image_name = os.path.splitext(image_elf)[0]
img1_prepend_bin = os.path.join(TOOLS_BOOTLOADERS, "REALTEK_RTL8195AM", "ram_1_prepend.bin")
img2_prepend_bin = image_name + '-ram_2_prepend.bin'
img3_prepend_bin = image_name + '-ram_3_prepend.bin'
old_bin = image_name + '.bin'
img_info = parse_section(toolchain, image_elf, img2_sections, 2)
prepend(old_bin, img2_prepend_bin, toolchain, img_info)
img_info = parse_section(toolchain, image_elf, img3_sections, 3)
prepend(old_bin, img3_prepend_bin, toolchain, img_info)
#delete original binary
if os.path.isfile(image_bin):
os.remove(image_bin)
else:
for i in os.listdir(image_bin):
os.remove(os.path.join(image_bin, i))
os.removedirs(image_bin)
2017-02-16 09:37:24 +00:00
# write output file
output = open(image_bin, "wb")
append_image_file(img1_prepend_bin, output)
append_image_file(img2_prepend_bin, output)
append_image_file(img3_prepend_bin, output)
2017-02-16 09:37:24 +00:00
output.close()
2017-05-22 06:31:32 +00:00
# post built done