Free Silicon. File Size, 175.98KB. File Name, BootRom.zip. Install the latest Intel network adapter driver for Windows 7.
PermalinkJoin GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign up Find file Copy path
Cannot retrieve contributors at this time
#!/usr/bin/env python |
# mt333x_fw_update.py - Tool to update firmware of MT333x based GPS device |
# |
# Copyright (c) 2016, David Imhoff <[email protected]> |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions are met: |
# * Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# * Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# * Neither the name of the author nor the names of its contributors may |
# be used to endorse or promote products derived from this software |
# without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS' AND ANY EXPRESS OR IMPLIED |
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#NOTE: This has only been tested with MT3339 based module from GlobalTop. |
# I also don't know if it works for the broader MT33xx range of products(ie. |
# MT3329). |
# |
import argparse |
import os.path |
import sys |
from mt333x_helpers import MtkGpsBRom, DownloadAgent |
VERSION_MAJOR=0 |
VERSION_MINOR=1 |
defreport_progress(cnt, total): |
''Display progress to stdout'' |
sys.stdout.write('{:3}% {}/{}r'.format(cnt *100/ total, cnt, total)) |
sys.stdout.flush() |
if cnt total: |
print('') |
defmain(): |
# Parse command line arguments |
parser = argparse.ArgumentParser( |
description='Update firmware of a MT333x based GPS chip.', |
epilog='Note: Baud rate detection and switching isn't always ' |
'working properly. In case the device can not be restarted into ' |
'boot ROM mode then set the --baud and --nmea-baud options to ' |
'the default baud rate of the current firmware') |
parser.add_argument('serial_port', help='path of serial port device') |
parser.add_argument('da_file', help='Path to MTK Download Agent') |
parser.add_argument('firmware_file', help='path to firmware to flash') |
parser.add_argument('-b', '--baud', |
dest='baud', type=int, choices=(912600, 460800, 230400, 115200, 57600, |
38400, 19200, 14400, 9600, 4800), default=115200, |
help='Use given baud rate for Boot ROM communication.' |
'Default: 115200') |
parser.add_argument('--nmea-baud', |
dest='nmea_baud', type=int, choices=(115200, 57600, 38400, 19200, 14400, |
9600, 4800), |
help='Use given baud rate for NMEA communication. ' |
'Default: auto detect') |
parser.add_argument('--dtr-reset', |
dest='dtr_reset', default=False, action='store_true', |
help='Use serial DTR signal to toggle NReset line to reset target.') |
parser.add_argument('--version', |
action='version', |
version='%(prog)s{}.{}'.format(VERSION_MAJOR, VERSION_MINOR)) |
args = parser.parse_args() |
ifnot os.path.isfile(args.da_file): |
raiseRuntimeError('Unable to find DownloadAgent file') |
# Read in firmware file |
withopen(args.firmware_file, 'rb') as fw_file: |
fw_data = fw_file.read() |
# Connect to Boot Rom |
brom = MtkGpsBRom(args.serial_port, baud=args.baud, |
nmea_baud=args.nmea_baud, |
dtr_reset=args.dtr_reset) |
da = DownloadAgent(brom) |
da.set_progress_callback(report_progress) |
print('Starting Boot ROM') |
brom.start() |
print('') |
print('Loading DA:') |
da.start(args.da_file) |
print('') |
print('DA Info:') |
print('--------') |
da.print_info() |
if args.baud >115200: |
da.set_baud_rate(args.baud) |
da._set_mem_block(0, len(fw_data)) |
print('') |
print('Writing new firmware:') |
da._write_data(fw_data) |
da.restart() |
if__name__'__main__': |
main() |
Copy lines Copy permalink
The BootROM is made up of two parts, the 'bootstrap', and the 'loader'. It's located at physical address 0x1FC00000 and is accessed via non-cached kseg1. The ROM is accessed upon hardware reset, software reset, or NMI. When this occurs, the Status flags are set in the COP0 Status register with following bits set: Boot Exception Vector=1 and Error Level = 1. If its a hardware reset, Software Reset (SR) = 0, or if NMI or software reset it is 1. At this point the PC is set to 0xBFC00000 and it begins to execute instructions. Since this is currently in ROM mode, only registers can be modified.
Because the BootROM is stored in non-volatile read-only memory it can't use variables, so the bootstrap of the BootROM copies the loader BootROM (the payload) to the CPU's scratchpad RAM (the only RAM available at this time, along with another 4KB block of RAM and the 2MB EDRAM — normal DDR SDRAM hasnt been initialised yet).
The first thing checked is the 0xBC100000 value, if non-zero, it typically means a NMI exception and it either jumps to the exception vector in COP0 Control Register $9, or if that is not set, to the exception vector in COP0 Status Register $25. On a normal reset (hardware or software), the loader code of the ROM is copied to scratch pad at physical address 0x10000 in cached mode (0x80010000). At this point it jumps to the real BootROM loader at 0x80010000. A stack is created at 0x80013FF0 as the top of the stack. This allows to the loader to use more typical local variables and memory in addition to registers.
![Bootrom Bootrom](/uploads/1/2/5/8/125867594/505903670.png)
Now the CPU is executing from the scratchpad RAM (the BootROM Loader).
The BootROM loader inits the NAND hardware and reads the IPL nand-block-table (a table with the physical block numbers of the encrypted IPL's location on the NAND). The table is located at the 4th physical block of the nand (offset 0x10000), and is repeated for the next 7 blocks. This is so that if a bad block occurs in any of these blocks, the table can still be read. Though if all 8 blocks become bad blocks, its a non-recoverable brick as the BootROM can no longer locate the IPL's location (the only solution to this problem is to either boot from MS instead, or use a custom IPL to patch the BootROM to remap the table - both of which would still require Pandora).
The BootROM loader inits the NAND hardware and reads the IPL nand-block-table (a table with the physical block numbers of the encrypted IPL's location on the NAND). The table is located at the 4th physical block of the nand (offset 0x10000), and is repeated for the next 7 blocks. This is so that if a bad block occurs in any of these blocks, the table can still be read. Though if all 8 blocks become bad blocks, its a non-recoverable brick as the BootROM can no longer locate the IPL's location (the only solution to this problem is to either boot from MS instead, or use a custom IPL to patch the BootROM to remap the table - both of which would still require Pandora).
If the SysCON has set 0xBE240004 has the 0x10 bit set, the memory stick is used instead of the NAND for IPL.
The entire raw IPL is stored on the nand encrypted.
The BootROM Loader uses a 4KB RAM (this RAM is mapped to physical address 0x1FD00000 (uncached accessed at 0xBFD00000), but will later be remapped to 0x1FC00000 to be used for the ME CPU reset exception vector) as a temporary location to load & decrypt each encrypted IPL block. Because this RAM is only 4KB in size, the encrypted IPL is organised as 4KB blocks on the nand. As the pre-IPL decrypts each of the 4KB IPL blocks, it loads the decrypted blocks to the IPL entry address 0x040F0000 (up to FW 5.50) or 0x40EC000 (FW 6+) (this address is located in the 2MB EDRAM which is normally used as VRAM, normal DDR RAM still has not been initialised yet). When the BootROM has finished decrypting and loading all the encrypted IPL blocks it jumps to the IPL entry address.