From 0781195c229c92a0ee3198e15569ec7e7ce7868c Mon Sep 17 00:00:00 2001 From: Vencislav Atanasov Date: Wed, 13 Aug 2025 19:29:50 +0300 Subject: [PATCH] Add iPod Nano 2G post-mortem memory dumper by Michael Sparmann The files are downloaded from https://www.rockbox.org/tracker/task/11701 Change-Id: Ic6415f76207868661c231cb534cb179160eb60e0 --- utils/rbpms/librbpms.py | 55 +++++++++++++++++++++++++++++++++++++++++ utils/rbpms/rbpms.py | 31 +++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 utils/rbpms/librbpms.py create mode 100644 utils/rbpms/rbpms.py diff --git a/utils/rbpms/librbpms.py b/utils/rbpms/librbpms.py new file mode 100644 index 0000000000..f6772cb526 --- /dev/null +++ b/utils/rbpms/librbpms.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python + +import sys +import struct +import usb + + +class rbpms: + def __init__(self): + self.handle = usb.core.find(idVendor=0xffff, idProduct=0xa112) + if self.handle is None: + raise Exception("Could not find specified device") + self.handle.set_configuration() + print("Connected to Rockbox Post-Mortem Stub on iPod Nano 2G") + + + @staticmethod + def __myprint(data): + sys.stdout.write(data) + sys.stdout.flush() + + + def read(self, offset, size): + if offset & 15 != 0: + raise Exception("Unaligned data read!") + + data = "" + + while True: + blocklen = size + if blocklen == 0: break + if blocklen > 256 * 1024: blocklen = 256 * 1024 + self.handle.write(4, struct.pack(" 2048 * 1024: blocklen = 2048 * 1024 + f.write(self.read(offset, blocklen)) + offset += blocklen + size -= blocklen + self.__myprint(".") + + self.__myprint(" done\n") diff --git a/utils/rbpms/rbpms.py b/utils/rbpms/rbpms.py new file mode 100644 index 0000000000..04152e4cbf --- /dev/null +++ b/utils/rbpms/rbpms.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +import sys +import librbpms + + +def usage(): + print "" + print "Please provide a command and (if needed) parameters as command line arguments" + print "" + print "Available commands:" + print "" + print " download
" + print " Downloads bytes of data from the specified address on the device," + print " and stores it in the specified file." + print "" + print "All numbers are hexadecimal!" + exit(2) + + +def parsecommand(dev, argv): + if len(argv) < 2: usage() + + elif argv[1] == "download": + if len(argv) != 5: usage() + dev.download(int(argv[2], 16), int(argv[3], 16), argv[4]) + + else: usage() + + +dev = librbpms.rbpms() +parsecommand(dev, sys.argv)