| Line 621... |
Line 621... |
| 621 |
Writes <size> bytes from memory to bootflash.
|
621 |
Writes <size> bytes from memory to bootflash.
|
| 622 |
ATTENTION: Don't call this unless you really know what you're doing!
|
622 |
ATTENTION: Don't call this unless you really know what you're doing!
|
| 623 |
This may BRICK your device (unless it has a good recovery option)
|
623 |
This may BRICK your device (unless it has a good recovery option)
|
| 624 |
<addr_mem>: the address in memory to copy the data from
|
624 |
<addr_mem>: the address in memory to copy the data from
|
| 625 |
<addr_bootflsh>: the address in bootflash to write to
|
625 |
<addr_bootflsh>: the address in bootflash to write to
|
| 626 |
[force]: Use this flag to suppress the 5 seconds delay
|
626 |
[force]: Use this flag to suppress the 10 seconds delay
|
| 627 |
"""
|
627 |
"""
|
| 628 |
addr_flash = to_int(addr_flash)
|
628 |
addr_flash = to_int(addr_flash)
|
| 629 |
addr_mem = to_int(addr_mem)
|
629 |
addr_mem = to_int(addr_mem)
|
| 630 |
size = to_int(size)
|
630 |
size = to_int(size)
|
| 631 |
force = to_bool(force)
|
631 |
force = to_bool(force)
|
| Line 782... |
Line 782... |
| 782 |
Target-specific function: ipodnano2g
|
782 |
Target-specific function: ipodnano2g
|
| 783 |
Dumps the whole NAND chip to four files
|
783 |
Dumps the whole NAND chip to four files
|
| 784 |
<filenameprefix>: prefix of the files that will be created
|
784 |
<filenameprefix>: prefix of the files that will be created
|
| 785 |
"""
|
785 |
"""
|
| 786 |
info = self.emcore.ipodnano2g_getnandinfo()
|
786 |
info = self.emcore.ipodnano2g_getnandinfo()
|
| 787 |
self.logger.info("Dumping NAND contents...")
|
- |
|
| 788 |
try:
|
787 |
try:
|
| - |
|
788 |
buf = self.emcore.memalign(0x10, 0x1088000)
|
| - |
|
789 |
self.logger.info("Dumping NAND contents...")
|
| - |
|
790 |
try:
|
| 789 |
infofile = open(filenameprefix+"_info.txt", 'wb')
|
791 |
infofile = open(filenameprefix+"_info.txt", 'wb')
|
| 790 |
datafile = open(filenameprefix+"_data.bin", 'wb')
|
792 |
datafile = open(filenameprefix+"_data.bin", 'wb')
|
| 791 |
sparefile = open(filenameprefix+"_spare.bin", 'wb')
|
793 |
sparefile = open(filenameprefix+"_spare.bin", 'wb')
|
| 792 |
statusfile = open(filenameprefix+"_status.bin", 'wb')
|
794 |
statusfile = open(filenameprefix+"_status.bin", 'wb')
|
| - |
|
795 |
except IOError:
|
| - |
|
796 |
raise ArgumentError("Can not open file for writing!")
|
| - |
|
797 |
infofile.write("NAND chip type: 0x%X\r\n" % info["type"])
|
| - |
|
798 |
infofile.write("Number of banks: %d\r\n" % info["banks"])
|
| - |
|
799 |
infofile.write("Number of blocks: %d\r\n" % info["blocks"])
|
| - |
|
800 |
infofile.write("Number of user blocks: %d\r\n" % info["userblocks"])
|
| - |
|
801 |
infofile.write("Pages per block: %d\r\n" % info["pagesperblock"])
|
| - |
|
802 |
for i in range(info["banks"] * info["blocks"] * info["pagesperblock"] / 8192):
|
| - |
|
803 |
self.logger.info(".")
|
| - |
|
804 |
self.emcore.ipodnano2g_nandread(buf, i * 8192, 8192, 1, 1)
|
| - |
|
805 |
datafile.write(self.emcore.read(buf, 0x01000000))
|
| - |
|
806 |
sparefile.write(self.emcore.read(buf + 0x01000000, 0x00080000))
|
| - |
|
807 |
statusfile.write(self.emcore.read(buf + 0x01080000, 0x00008000))
|
| - |
|
808 |
infofile.close()
|
| - |
|
809 |
datafile.close()
|
| - |
|
810 |
sparefile.close()
|
| - |
|
811 |
statusfile.close()
|
| - |
|
812 |
self.logger.info("done\n")
|
| - |
|
813 |
finally:
|
| - |
|
814 |
self.emcore.free(buf)
|
| - |
|
815 |
|
| - |
|
816 |
@command
|
| - |
|
817 |
def ipodnano2g_restorenand(self, filenameprefix, force=False):
|
| - |
|
818 |
"""
|
| - |
|
819 |
Target-specific function: ipodnano2g
|
| - |
|
820 |
Restores the whole NAND chip from <filenameprefix>_data.bin and <filenameprefix>_spare.bin
|
| - |
|
821 |
[force]: use this flag to suppress the 10 seconds delay
|
| - |
|
822 |
"""
|
| - |
|
823 |
self.logger.warn("Flashing NAND image %s!\n" % filenameprefix)
|
| - |
|
824 |
if force == False:
|
| - |
|
825 |
self.logger.warn("If this was not what you intended press Ctrl-C NOW")
|
| - |
|
826 |
for i in range(10):
|
| - |
|
827 |
self.logger.info(".")
|
| - |
|
828 |
time.sleep(1)
|
| - |
|
829 |
self.logger.info("\n\n")
|
| - |
|
830 |
info = self.emcore.ipodnano2g_getnandinfo()
|
| - |
|
831 |
ppb = info["pagesperblock"]
|
| - |
|
832 |
banks = info["banks"]
|
| - |
|
833 |
blocks = info["blocks"]
|
| - |
|
834 |
try:
|
| - |
|
835 |
if (os.path.getsize(filenameprefix+"_data.bin") != blocks * banks * ppb * 2048):
|
| - |
|
836 |
raise ArgumentError("Data file size does not match flash size!")
|
| - |
|
837 |
if (os.path.getsize(filenameprefix+"_spare.bin") != blocks * banks * ppb * 64):
|
| - |
|
838 |
raise ArgumentError("Spare file size does not match flash size!")
|
| - |
|
839 |
datafile = open(filenameprefix+"_data.bin", 'rb')
|
| - |
|
840 |
sparefile = open(filenameprefix+"_spare.bin", 'rb')
|
| 793 |
except IOError:
|
841 |
except IOError:
|
| 794 |
raise ArgumentError("Can not open file for writing!")
|
842 |
raise ArgumentError("Can not open input files!")
|
| - |
|
843 |
try:
|
| - |
|
844 |
buf = self.emcore.memalign(0x10, banks * ppb * 0x844)
|
| 795 |
infofile.write("NAND chip type: 0x%X\r\n" % info["type"])
|
845 |
for block in range(info["blocks"]):
|
| 796 |
infofile.write("Number of banks: %d\r\n" % info["banks"])
|
846 |
for bank in range(info["banks"]):
|
| 797 |
infofile.write("Number of blocks: %d\r\n" % info["blocks"])
|
847 |
self.logger.info("\r Erasing block %d bank %d" % (block, bank))
|
| - |
|
848 |
self.emcore.ipodnano2g_nanderase(buf, block * banks + bank, 1)
|
| - |
|
849 |
rc = struct.unpack("<I", self.emcore.read(buf, 4))[0]
|
| - |
|
850 |
if rc != 0: self.logger.info("\rBlock %d bank %d erase failed with RC %08X\n" % (block, bank, rc))
|
| 798 |
infofile.write("Number of user blocks: %d\r\n" % info["userblocks"])
|
851 |
self.logger.info("\r Uploading block %d data " % block)
|
| 799 |
infofile.write("Pages per block: %d\r\n" % info["pagesperblock"])
|
852 |
self.emcore.write(buf, datafile.read(banks * ppb * 2048))
|
| 800 |
for i in range(info["banks"] * info["blocks"] * info["pagesperblock"] / 8192):
|
853 |
self.emcore.write(buf + banks * ppb * 2048, sparefile.read(banks * ppb * 64))
|
| 801 |
self.logger.info(".")
|
854 |
self.logger.info("\rProgramming block %d " % block)
|
| 802 |
self.emcore.ipodnano2g_nandread(0x08000000, i * 8192, 8192, 1, 1)
|
855 |
self.emcore.ipodnano2g_nandwrite(buf, block * banks * ppb, banks * ppb, 0)
|
| 803 |
datafile.write(self.emcore.read(0x08000000, 0x01000000))
|
856 |
rc = struct.unpack("<%dI" % (banks * ppb), self.emcore.read(buf + banks * ppb * 2112, banks * ppb * 4))
|
| 804 |
sparefile.write(self.emcore.read(0x09000000, 0x00080000))
|
857 |
for page in range(ppb):
|
| - |
|
858 |
for bank in range(banks):
|
| 805 |
statusfile.write(self.emcore.read(0x09080000, 0x00008000))
|
859 |
if rc[banks * page + bank] != 0:
|
| - |
|
860 |
self.logger.info("\rBlock %d bank %d page %d programming failed with RC %08X\n" % (block, bank, page, rc[banks * page + bank]))
|
| 806 |
infofile.close()
|
861 |
finally:
|
| - |
|
862 |
self.emcore.free(buf)
|
| 807 |
datafile.close()
|
863 |
datafile.close()
|
| 808 |
sparefile.close()
|
864 |
sparefile.close()
|
| 809 |
statusfile.close()
|
- |
|
| 810 |
self.logger.info("done\n")
|
865 |
self.logger.info("\rdone\n")
|
| 811 |
|
866 |
|
| 812 |
@command
|
867 |
@command
|
| 813 |
def ipodnano2g_wipenand(self, filename, force=False):
|
868 |
def ipodnano2g_wipenand(self, filename, force=False):
|
| 814 |
"""
|
869 |
"""
|
| 815 |
Target-specific function: ipodnano2g
|
870 |
Target-specific function: ipodnano2g
|
| 816 |
Wipes the whole NAND chip and logs the result to a file
|
871 |
Wipes the whole NAND chip and logs the result to a file
|
| 817 |
<filename>: location of the log file
|
872 |
<filename>: location of the log file
|
| 818 |
[force]: use this flag to suppress the 5 seconds delay
|
873 |
[force]: use this flag to suppress the 10 seconds delay
|
| 819 |
"""
|
874 |
"""
|
| 820 |
self.logger.warn("Wiping the whole NAND chip!\n")
|
875 |
self.logger.warn("Wiping the whole NAND chip!\n")
|
| 821 |
if force == False:
|
876 |
if force == False:
|
| 822 |
self.logger.warn("If this was not what you intended press Ctrl-C NOW")
|
877 |
self.logger.warn("If this was not what you intended press Ctrl-C NOW")
|
| 823 |
for i in range(10):
|
878 |
for i in range(10):
|
| 824 |
self.logger.info(".")
|
879 |
self.logger.info(".")
|
| 825 |
time.sleep(1)
|
880 |
time.sleep(1)
|
| 826 |
self.logger.info("\n")
|
881 |
self.logger.info("\n")
|
| 827 |
info = self.emcore.ipodnano2g_getnandinfo()
|
- |
|
| 828 |
self.logger.info("Wiping NAND contents...")
|
- |
|
| 829 |
try:
|
882 |
try:
|
| - |
|
883 |
buf = self.emcore.malloc(0x100)
|
| - |
|
884 |
info = self.emcore.ipodnano2g_getnandinfo()
|
| - |
|
885 |
self.logger.info("Wiping NAND contents...")
|
| - |
|
886 |
try:
|
| 830 |
statusfile = open(filename, 'wb')
|
887 |
statusfile = open(filename, 'wb')
|
| 831 |
except IOError:
|
888 |
except IOError:
|
| 832 |
raise ArgumentError("Can not open file for writing!")
|
889 |
raise ArgumentError("Can not open file for writing!")
|
| 833 |
for i in range(info["banks"] * info["blocks"] / 64):
|
890 |
for i in range(info["banks"] * info["blocks"] / 64):
|
| 834 |
self.logger.info(".")
|
891 |
self.logger.info(".")
|
| 835 |
self.emcore.ipodnano2g_nanderase(0x08000000, i * 64, 64)
|
892 |
self.emcore.ipodnano2g_nanderase(buf, i * 64, 64)
|
| 836 |
statusfile.write(self.emcore.read(0x08000000, 0x00000100))
|
893 |
statusfile.write(self.emcore.read(buf, 0x00000100))
|
| 837 |
statusfile.close()
|
894 |
statusfile.close()
|
| 838 |
self.logger.info("done\n")
|
895 |
self.logger.info("done\n")
|
| - |
|
896 |
finally:
|
| - |
|
897 |
self.emcore.free(buf)
|
| 839 |
|
898 |
|
| 840 |
@command
|
899 |
@command
|
| 841 |
def ipodclassic_writebbt(self, filename, tempaddr = None):
|
900 |
def ipodclassic_writebbt(self, filename, tempaddr = None):
|
| 842 |
"""
|
901 |
"""
|
| 843 |
Target-specific function: ipodclassic
|
902 |
Target-specific function: ipodclassic
|