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
|
2017-06-29 07:36:32 +00:00
|
|
|
RAM3_RSVD = 0xFFFFFFFFFFFFFFFF
|
|
|
|
IMG2_OFFSET = 0x10006000 #default
|
2017-02-16 09:37:24 +00:00
|
|
|
|
2017-02-24 07:21:32 +00:00
|
|
|
def write_fixed_width_string(value, width, output):
|
2017-02-28 11:15:49 +00:00
|
|
|
# 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
|
|
|
|
2017-02-24 07:21:32 +00:00
|
|
|
def write_fixed_width_value(value, width, output):
|
2017-02-28 11:15:49 +00:00
|
|
|
# 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
|
|
|
|
2017-02-24 07:21:32 +00:00
|
|
|
def append_image_file(image, output):
|
2017-06-29 07:36:32 +00:00
|
|
|
try:
|
|
|
|
input = open(image, "rb")
|
|
|
|
output.write(input.read())
|
|
|
|
except Exception:
|
|
|
|
return
|
2017-02-16 09:37:24 +00:00
|
|
|
input.close()
|
|
|
|
|
2017-02-28 11:15:49 +00:00
|
|
|
def prepend(image, image_prepend, toolchain, info):
|
2017-06-29 07:36:32 +00:00
|
|
|
if info['size'] == 0:
|
|
|
|
return
|
2017-02-28 11:15:49 +00:00
|
|
|
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)
|
2017-06-29 07:36:32 +00:00
|
|
|
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-06-29 07:36:32 +00:00
|
|
|
|
2017-02-16 09:37:24 +00:00
|
|
|
|
2017-06-29 07:36:32 +00:00
|
|
|
def _parse_section(toolchain, elf, section):
|
2017-03-07 09:58:34 +00:00
|
|
|
info = {'addr':None, 'size':0};
|
2017-02-28 11:15:49 +00:00
|
|
|
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"
|
2017-02-28 11:15:49 +00:00
|
|
|
|
|
|
|
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)
|
2017-02-28 11:15:49 +00:00
|
|
|
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
|
2017-02-24 07:21:32 +00:00
|
|
|
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)
|
2017-02-28 11:15:49 +00:00
|
|
|
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]
|
2017-02-24 07:21:32 +00:00
|
|
|
match = re.match(r'^\s+' + section + \
|
2017-02-28 11:15:49 +00:00
|
|
|
r'\s+0x(?P<addr>[0-9A-Fa-f]{8})\s+0x(?P<size>[0-9A-Fa-f]+)\s+.*<Block>$', line)
|
|
|
|
if match:
|
2017-03-02 04:07:25 +00:00
|
|
|
info['addr'] = int(match.group("addr"), 16)
|
2017-02-28 11:15:49 +00:00
|
|
|
try:
|
2017-03-02 04:07:25 +00:00
|
|
|
info['size'] = int(match.group("size"), 16)
|
2017-02-28 11:15:49 +00:00
|
|
|
except IndexError:
|
2017-03-07 09:58:34 +00:00
|
|
|
print "[WARNING] cannot find the size of section " + section
|
2017-03-02 04:07:25 +00:00
|
|
|
return info
|
2017-02-28 11:15:49 +00:00
|
|
|
|
2017-03-07 09:58:34 +00:00
|
|
|
print "[ERROR] cannot find the address of section " + section
|
2017-02-28 11:15:49 +00:00
|
|
|
return info
|
2017-02-16 09:37:24 +00:00
|
|
|
|
2017-06-29 07:36:32 +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"]
|
2017-06-29 07:36:32 +00:00
|
|
|
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"]
|
2017-06-29 07:36:32 +00:00
|
|
|
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"]
|
2017-06-29 07:36:32 +00:00
|
|
|
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
|
2017-02-28 11:15:49 +00:00
|
|
|
return
|
2017-06-29 07:36:32 +00:00
|
|
|
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]
|
|
|
|
|
2017-06-29 07:36:32 +00:00
|
|
|
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)
|
2017-02-28 11:15:49 +00:00
|
|
|
|
2017-06-29 07:36:32 +00:00
|
|
|
#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
|
2017-02-24 07:21:32 +00:00
|
|
|
output = open(image_bin, "wb")
|
2017-06-29 07:36:32 +00:00
|
|
|
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
|
2017-02-28 11:15:49 +00:00
|
|
|
|