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