summaryrefslogtreecommitdiffstats
path: root/oncology/dpfhack_display/fw/hackit.py
diff options
context:
space:
mode:
Diffstat (limited to 'oncology/dpfhack_display/fw/hackit.py')
-rwxr-xr-xoncology/dpfhack_display/fw/hackit.py167
1 files changed, 167 insertions, 0 deletions
diff --git a/oncology/dpfhack_display/fw/hackit.py b/oncology/dpfhack_display/fw/hackit.py
new file mode 100755
index 00000000..5c7a5ae9
--- /dev/null
+++ b/oncology/dpfhack_display/fw/hackit.py
@@ -0,0 +1,167 @@
+#!/usr/bin/python
+import struct
+import sys
+sys.path.append("./Debug")
+import dpf
+import time
+import binascii
+
+# DPF profiles
+import profiles
+
+# If you are an expert, set this to 0 to avoid the warnings
+paranoia_mode = 1
+
+JUMPTABLE_OFFSET = 0x80
+HEXDIR = "hexfiles/"
+
+instructions = [
+ """Press and hold MENU while USB is plugged in.
+If successful, you will get the 'USB connect' message and the device
+will appear as non-USB storage device"""
+]
+
+ins_common = """To put the device back into (almost) original state working
+as USB storage, press the RESET button."""
+
+############################################################################
+
+bswap = lambda x: ( (x >> 8) & 0xff ) | ((x << 8) & 0xff00)
+
+def dump_flash(d, fname, offset, size):
+ data = d.readFlash(offset, size)
+ f = open(fname, "wb")
+ f.write(data)
+ f.close()
+
+def find_dpf(version):
+ for i in profiles.KNOWN_DPFS:
+ v = i[0]
+ if v[0] == str(version[0]) and v[1] == str(version[1]) and v[2] == str(version[2]):
+ print "Found matching version info"
+ return i
+ return None
+
+def get_module(buf, n):
+ n *= 8
+ start, end, flashaddr = struct.unpack("<HHI", buf[n:n+8])
+
+ start = bswap(start)
+ end = bswap(end)
+
+ return start, end, flashaddr
+
+def patch_module(d, record, buf):
+ n = record[0]
+ if n == profiles.BINARY: # Write full binary into sector
+ start, flashaddr = record[1]
+ f = open(record[2])
+ d.eraseFlash(flashaddr)
+ buf = f.read()
+ f.close()
+ d.writeFlash(flashaddr, buf)
+ elif n == profiles.PATCH: # We make a copy of a full sector
+ start, flashaddr = record[1]
+ print "Patching sector addr %06x with %s" % (flashaddr, record[2])
+ d.patchSector(start, flashaddr, HEXDIR + record[2])
+ elif n == profiles.COPY: # We make a copy of a full sector
+ src, dest = record[1]
+ print "Copying sector from 0x%06x to 0x%06x..." %(src, dest)
+ data = d.readFlash(src, 0x10000)
+ d.eraseFlash(dest)
+ d.writeFlash(dest, data)
+ else:
+ print "Analyzing module %d..." % n
+ start, end, flashaddr = get_module(buf, n)
+ l = end - start
+ start += 0x800
+ data = d.readFlash(flashaddr, l)
+ c = binascii.crc32(data) & 0xffffffff
+ checksums = record[1]
+ i = 0
+ try:
+ i = checksums.index(c)
+ except ValueError:
+ print "CRC32 does not match: 0x%08lx" % c
+ return False
+
+ n = len(checksums) - 1
+
+ if i == n:
+ print "Seems up to date. Do you still wish to patch?"
+ a = raw_input("Type 'yes' to continue > ")
+ if a != "yes":
+ return True
+ print "Updating module.."
+ else:
+ print "Patching from version %d to %d" % (i, n)
+
+ d.patchSector(start, flashaddr, HEXDIR + record[2])
+
+ return True
+
+def recognize(d):
+ print "Reading flash..."
+ buf = d.readFlash(0x0, 0x280)
+
+ print "done"
+ b = buf[:7]
+ xmem, code, dummy, offset = struct.unpack(">HHBH", b)
+ version = (buf[0x50:0x58], buf[0x60: 0x70], buf[0x80:0x88])
+
+ dpf = find_dpf(version)
+ if not dpf:
+ print "No DPF found. Create a record or look for one"
+ print version
+ else:
+ print "Identifier:", dpf[1]
+ di = dpf[3]
+ di['offset'] = offset
+
+ return dpf
+
+def patch(d, dpf):
+ if (paranoia_mode):
+ print """Now patching. There is no 100% guarantee that your device will
+ work after doing this. You must never unplug the device from USB while
+ it is being updated.
+ Are you sure you take all risks and that you want to continue?"""
+ a = raw_input("Type 'yes' to continue > ")
+ if a != "yes":
+ print "Aborting."
+ return False
+
+ p = dpf[4]
+
+ buf = d.readFlash(JUMPTABLE_OFFSET, dpf[3]['offset'])
+ for i in p[2]:
+ if not patch_module(d, i, buf):
+ return False
+
+ return True
+#
+#
+# MAIN
+
+if len(sys.argv) != 2:
+ print "Usage: %s [<generic scsi device> | usb0]" % sys.argv[0]
+ print "You may have to run this as root when accessing generic scsi devices"
+ sys.exit(-1)
+
+d = dpf.open(sys.argv[1])
+
+dpf = recognize(d)
+if dpf:
+ r = dpf[4]
+ ret = patch(d, dpf)
+ if ret:
+ print
+ print "Now disconnect the DPF from USB."
+ print "To activate the 'developer mode':"
+ print
+ print instructions[r[0]]
+ print
+ print ins_common
+ else:
+ print "DPF might not be completely patched."
+d.close()