Files
OpenCellular/util/unpack_ftb.py
Wei-Han Chen 9a8e4226c3 util/unpack_ftb.py: a script to convert FTB file into bin file
ST firmwares are released in FTB format, which can't be written to flash
directly.  This python script can convert a file in FTB format into
bin file.  Currently, we only support FTB files of whiskers touchpad
firmware.

BRANCH=none
BUG=b:70482333
TEST=manual
Signed-off-by: Wei-Han Chen <stimim@chromium.org>

Change-Id: I179de12663580881347a31f11b5b10659e00b879
Reviewed-on: https://chromium-review.googlesource.com/918603
Commit-Ready: Wei-Han Chen <stimim@chromium.org>
Tested-by: Wei-Han Chen <stimim@chromium.org>
Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
2018-03-22 10:58:26 -07:00

106 lines
2.6 KiB
Python
Executable File

#!/usr/bin/env python
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from __future__ import print_function
import argparse
import ctypes
import os
class Header(ctypes.Structure):
_pack_ = 1
_fields_ = [
('signature', ctypes.c_uint32),
('ftb_ver', ctypes.c_uint32),
('chip_id', ctypes.c_uint32),
('svn_ver', ctypes.c_uint32),
('fw_ver', ctypes.c_uint32),
('config_id', ctypes.c_uint32),
('config_ver', ctypes.c_uint32),
('reserved', ctypes.c_uint8 * 8),
('release_info', ctypes.c_ulonglong),
('sec_size', ctypes.c_uint32 * 4),
('crc', ctypes.c_uint32),
]
FW_HEADER_SIZE = 64
FW_HEADER_SIGNATURE = 0xAA55AA55
FW_FTB_VER = 0x00000001
FW_CHIP_ID = 0x3936
FW_BYTES_ALIGN = 4
FW_BIN_VER_OFFSET = 16
FW_BIN_CONFIG_ID_OFFSET = 20
# Starting address in flash for each section
FLASH_SEC_ADDR = [
0x0000 * 4, # CODE
0x7C00 * 4, # CONFIG
0x7000 * 4, # CX
None # This section shouldn't exist
]
OUTPUT_FILE_SIZE = 128 * 1024 # 128KB
def main():
parser = argparse.ArgumentParser()
parser.add_argument('--input', '-i', required=True)
parser.add_argument('--output', '-o', required=True)
args = parser.parse_args()
with open(args.input) as f:
bs = f.read()
size = len(bs)
if size < FW_HEADER_SIZE + FW_BYTES_ALIGN:
raise Exception('FW size too small')
print('FTB file size:', size)
header = Header()
assert ctypes.sizeof(header) == FW_HEADER_SIZE
ctypes.memmove(ctypes.addressof(header), bs, ctypes.sizeof(header))
if (header.signature != FW_HEADER_SIGNATURE or
header.ftb_ver != FW_FTB_VER or
header.chip_id != FW_CHIP_ID):
raise Exception('Invalid header')
for key, _ in header._fields_:
v = getattr(header, key)
if isinstance(v, ctypes.Array):
print(key, map(hex, v))
else:
print(key, hex(v))
dimension = sum(header.sec_size)
assert dimension + FW_HEADER_SIZE + FW_BYTES_ALIGN == size
data = bs[FW_HEADER_SIZE:FW_HEADER_SIZE + dimension]
with open(args.output, 'wb') as f:
# ensure the file size
f.seek(OUTPUT_FILE_SIZE - 1, os.SEEK_SET)
f.write('\x00')
offset = 0
# write each sections
for i, addr in enumerate(FLASH_SEC_ADDR):
size = header.sec_size[i]
assert addr is not None or size == 0
if size == 0:
continue
f.seek(addr, os.SEEK_SET)
f.write(data[offset : offset + size])
offset += size
f.flush()
if __name__ == '__main__':
main()