Implemented SC6531C readback and target system
This commit is contained in:
+64
-16
@@ -82,6 +82,8 @@ def send_file_to_addr(fname, faddr, fdlBooted = False, flashMode = False, fbs =
|
||||
resp = reqresp(unicmd.cmd_data_start(faddr, flen, dataCrc), fdlBooted)
|
||||
rcode, rlen, r = unicmd.resp_decode(resp, fdlBooted)
|
||||
assert rcode == unicmd.BSL_REP_ACK, 'Could not start data transfer, response code is %X' % rcode
|
||||
if rcode == unicmd.BSL_REP_LOG:
|
||||
print(r)
|
||||
print('Starting data transfer...')
|
||||
while fdata:
|
||||
buf = fdata[:pSize]
|
||||
@@ -148,30 +150,33 @@ def write_flash_mem(infile, offset, blocksize, forceErase):
|
||||
erase_flash_mem(flen, startAddr)
|
||||
send_file_to_addr(fdata, startAddr, True, True, blocksize)
|
||||
|
||||
# main code start
|
||||
|
||||
def auto_int(x):
|
||||
return int(x,0)
|
||||
|
||||
# main code start
|
||||
|
||||
if __name__ == '__main__': # main app start
|
||||
from argparse import ArgumentParser
|
||||
rootdir = os.path.dirname(os.path.realpath(__file__))
|
||||
parser = ArgumentParser(description='UniFlash: an opensource Unisoc SC6531E/F/M phone flash reader/writer', epilog='(c) Luxferre 2021 --- No rights reserved <https://unlicense.org>')
|
||||
parser = ArgumentParser(description='UniFlash: an opensource Unisoc/Spreadtrum feature phone flash reader/writer', epilog='(c) Luxferre 2021 --- No rights reserved <https://unlicense.org>')
|
||||
parser.add_argument('mode', help='Operation mode (flash/dump)')
|
||||
parser.add_argument('file', help='File to read the flash data from or write the dump into')
|
||||
parser.add_argument('-p','--partid', type=auto_int, default=0x80000003, help='partition ID for readback (defaults to 0x80000003 that can address full flash space on SC6531E/F/M)')
|
||||
parser.add_argument('-s','--start', type=auto_int, default=0, help='start position (in the partition, defaults to 0)')
|
||||
parser.add_argument('-l', '--length', type=auto_int, default=0x400000, help='data length in bytes to read/write, defaults to 0x400000')
|
||||
parser.add_argument('-e','--force-erase', type=bool, default=False, help='Erase target flash memory area before writing')
|
||||
parser.add_argument('-t','--target', default='sc6531efm_generic', help='Preinstalled target (defaults to sc6531efm_generic, overridable with individual FDL parameters)')
|
||||
parser.add_argument('-nr','--flash-noremap', action='store_true', help='Disable base address remapping for flashing')
|
||||
parser.add_argument('-e','--force-erase', action='store_true', help='Erase target flash memory area before flashing')
|
||||
parser.add_argument('-wf','--enable-write-flash', action='store_true', help='Send the write flash enable command before flashing (if necessary and supported)')
|
||||
parser.add_argument('-bs','--block-size', type=auto_int, default=4096, help='Readback/write block size (in bytes), defaults to 4096')
|
||||
parser.add_argument('-dv','--device-vid', type=auto_int, default=UNISOC_VID, help='Override device vendor ID')
|
||||
parser.add_argument('-dp','--device-pid', type=auto_int, default=UNISOC_PID, help='Override device product ID')
|
||||
parser.add_argument('-fdl1','--fdl1-file', default=rootdir+'/fdls/sc6531efm_generic_0x40004000_fdl1.bin', help='Path to FDL1, defaults to the generic SC6531E/F/M FDL1 shipped with UniFlash')
|
||||
parser.add_argument('-addr1','--fdl1-addr', type=auto_int, default=0x40004000, help='Address to load FDL1 into, defaults to 0x40004000')
|
||||
parser.add_argument('-fdl2','--fdl2-file', default=rootdir+'/fdls/sc6531efm_generic_0x14000000_fdl2.bin', help='Path to FDL2, defaults to the generic SC6531E/F/M FDL2 shipped with UniFlash')
|
||||
parser.add_argument('-addr2','--fdl2-addr', type=auto_int, default=0x14000000, help='Address to load FDL2 into, defaults to 0x14000000')
|
||||
parser.add_argument('-sfdl','--single-fdl-file', default=None, help='Path to a single FDL (for old Spreadtrum chipsets)')
|
||||
parser.add_argument('-saddr','--single-fdl-addr', type=auto_int, default=0x34000000, help='Address to load the single FDL into, defaults to 0x34000000')
|
||||
parser.add_argument('-fdl1','--fdl1-file', default=None, help='Path to FDL1, overrides the target')
|
||||
parser.add_argument('-addr1','--fdl1-addr', type=auto_int, default=None, help='Address to load FDL1 into, overrides the target')
|
||||
parser.add_argument('-fdl2','--fdl2-file', default=None, help='Path to FDL2, overrides the target')
|
||||
parser.add_argument('-addr2','--fdl2-addr', type=auto_int, default=None, help='Address to load FDL2 into, overrides the target')
|
||||
parser.add_argument('-sfdl','--single-fdl-file', default=None, help='Path to a single FDL (for old Spreadtrum chipsets), overrides the target')
|
||||
parser.add_argument('-saddr','--single-fdl-addr', type=auto_int, default=None, help='Address to load the single FDL into, overrides the target')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -179,24 +184,61 @@ if __name__ == '__main__': # main app start
|
||||
if args.mode == 'flash':
|
||||
is_flash = True
|
||||
|
||||
# parse target and resolve the parameters from it first
|
||||
paramdelim = '_'
|
||||
target = args.target + paramdelim
|
||||
fdlDir = rootdir + '/fdls'
|
||||
fdlList = []
|
||||
for root, dirs, files in os.walk(fdlDir):
|
||||
for name in files:
|
||||
if name.startswith(target):
|
||||
paramstr = os.path.splitext(name)[0].split(target)[1]
|
||||
params = paramstr.split(paramdelim)
|
||||
fdlList.append((params[1], params[0], fdlDir+'/'+name))
|
||||
# resulting fdl list: (tag, address, path)
|
||||
fdlSingleName = None
|
||||
fdlSingleAddr = None
|
||||
for tag, addr, path in fdlList:
|
||||
if tag == 'single':
|
||||
fdlSingleName = path
|
||||
fdlSingleAddr = auto_int(addr)
|
||||
elif tag == 'fdl1':
|
||||
fdl1Name = path
|
||||
fdl1Addr = auto_int(addr)
|
||||
elif tag == 'fdl2':
|
||||
fdl2Name = path
|
||||
fdl2Addr = auto_int(addr)
|
||||
|
||||
# override target with the individual parameters if necessary
|
||||
UNISOC_VID = args.device_vid
|
||||
UNISOC_PID = args.device_pid
|
||||
fdl1Addr = args.fdl1_addr
|
||||
fdl2Addr = args.fdl2_addr
|
||||
fdl1Name = args.fdl1_file
|
||||
fdl2Name = args.fdl2_file
|
||||
fdlSingleName = args.single_fdl_file
|
||||
fdlSingleAddr = args.single_fdl_addr
|
||||
if args.fdl1_addr is not None:
|
||||
fdl1Addr = args.fdl1_addr
|
||||
if args.fdl2_addr is not None:
|
||||
fdl2Addr = args.fdl2_addr
|
||||
if args.fdl1_file is not None:
|
||||
fdl1Name = args.fdl1_file
|
||||
if args.fdl2_file is not None:
|
||||
fdl2Name = args.fdl2_file
|
||||
if args.single_fdl_file is not None:
|
||||
fdlSingleName = args.single_fdl_file
|
||||
if args.single_fdl_addr is not None:
|
||||
fdlSingleAddr = args.single_fdl_addr
|
||||
outfile = args.file
|
||||
partitionId = args.partid
|
||||
readbs = args.block_size
|
||||
readoffset = args.start
|
||||
readlen = args.length
|
||||
forceErase = args.force_erase
|
||||
sendEnableWriteFlash = args.enable_write_flash
|
||||
singleFdlMode = False
|
||||
fdl1Label = 'FDL1'
|
||||
fdl2Label = 'FDL2'
|
||||
|
||||
if args.flash_noremap == True:
|
||||
print('Flash remapping disabled')
|
||||
UNISOC_FLASH_BASE_ADDR = 0
|
||||
|
||||
if fdlSingleName is not None:
|
||||
singleFdlMode = True
|
||||
fdl1Addr = fdlSingleAddr
|
||||
@@ -250,6 +292,12 @@ if __name__ == '__main__': # main app start
|
||||
print(fdl2Label + ' running, may start interacting with flash memory')
|
||||
|
||||
if is_flash:
|
||||
|
||||
if sendEnableWriteFlash:
|
||||
resp = reqresp(unicmd.cmd_enable_write_flash(), True)
|
||||
rcode, rlen, r = unicmd.resp_decode(resp, True)
|
||||
assert rcode == unicmd.BSL_REP_ACK, 'Could not send the flash write request, response code is %X' % rcode
|
||||
|
||||
print('Writing flash at offset 0x%X from %s...' % (readoffset, outfile))
|
||||
write_flash_mem(outfile, readoffset, readbs, forceErase)
|
||||
print('Flash memory written, disconnect the device!')
|
||||
|
||||
Reference in New Issue
Block a user