Index: embios/trunk/tools/embios.py |
— | — | @@ -27,6 +27,7 @@ |
28 | 28 | import re
|
29 | 29 | import time
|
30 | 30 | import struct
|
| 31 | +import locale
|
31 | 32 |
|
32 | 33 | from functools import wraps
|
33 | 34 |
|
— | — | @@ -478,6 +479,8 @@ |
479 | 480 | self.logger.info(" Thread id: "+str(thread.id)+"\n")
|
480 | 481 | self.logger.info(" Thread type: "+thread.type+"\n")
|
481 | 482 | self.logger.info(" Thread state: "+thread.state+"\n")
|
| 483 | + self.logger.info(" Block type: "+thread.block_type+"\n")
|
| 484 | + self.logger.info(" Blocked by: "+self._hex(thread.blocked_by_ptr)+"\n")
|
482 | 485 | self.logger.info(" Priority: "+str(thread.priority)+"/256\n")
|
483 | 486 | self.logger.info(" Current CPU load: "+str((thread.cpuload*100)/255)+"%\n")
|
484 | 487 | self.logger.info(" CPU time (total): "+str(datetime.timedelta(microseconds=thread.cputime_total))+"\n")
|
— | — | @@ -803,6 +806,119 @@ |
804 | 807 | statusfile.close()
|
805 | 808 | self.logger.info("done\n")
|
806 | 809 |
|
| 810 | + @command
|
| 811 | + def ipodclassic_writebbt(self, tempaddr, filename):
|
| 812 | + """
|
| 813 | + Target-specific function: ipodclassic
|
| 814 | + Uploads the bad block table <filename> to
|
| 815 | + memory at <tempaddr> and writes it to the hard disk
|
| 816 | + """
|
| 817 | + tempaddr = self._hexint(tempaddr)
|
| 818 | + try:
|
| 819 | + f = open(filename, 'rb')
|
| 820 | + except IOError:
|
| 821 | + raise ArgumentError("File not readable. Does it exist?")
|
| 822 | + self.embios.lib.dev.timeout = 30000
|
| 823 | + self.logger.info("Writing bad block table to disk...")
|
| 824 | + data = self.embios.ipodclassic_writebbt(f.read(), tempaddr)
|
| 825 | + f.close()
|
| 826 | + self.logger.info(" done\n")
|
| 827 | +
|
| 828 | + @command
|
| 829 | + def mkdir(self, dirname):
|
| 830 | + """
|
| 831 | + Creates a directory
|
| 832 | + """
|
| 833 | + self.embios.lib.dev.timeout = 30000
|
| 834 | + self.logger.info("Creating directory " + dirname + "...")
|
| 835 | + self.embios.dir_create(dirname)
|
| 836 | + self.logger.info(" done\n")
|
| 837 | +
|
| 838 | + @command
|
| 839 | + def rmdir(self, dirname):
|
| 840 | + """
|
| 841 | + Removes an empty directory
|
| 842 | + """
|
| 843 | + self.embios.lib.dev.timeout = 30000
|
| 844 | + self.logger.info("Removing directory " + dirname + "...")
|
| 845 | + self.embios.dir_remove(dirname)
|
| 846 | + self.logger.info(" done\n")
|
| 847 | +
|
| 848 | + @command
|
| 849 | + def unlink(self, filename):
|
| 850 | + """
|
| 851 | + Removes a file
|
| 852 | + """
|
| 853 | + self.embios.lib.dev.timeout = 30000
|
| 854 | + self.logger.info("Removing file " + filename + "...")
|
| 855 | + self.embios.file_unlink(filename)
|
| 856 | + self.logger.info(" done\n")
|
| 857 | +
|
| 858 | + @command
|
| 859 | + def get(self, buffer, buffsize, remotename, localname):
|
| 860 | + """
|
| 861 | + Downloads a file
|
| 862 | + """
|
| 863 | + buffer = self._hexint(buffer)
|
| 864 | + buffsize = self._hexint(buffsize)
|
| 865 | + try:
|
| 866 | + f = open(localname, 'wb')
|
| 867 | + except IOError:
|
| 868 | + raise ArgumentError("Could not open local file for writing.")
|
| 869 | + self.embios.lib.dev.timeout = 30000
|
| 870 | + self.logger.info("Downloading file " + remotename + " to " + localname + "...")
|
| 871 | + fd = self.embios.file_open(remotename, 0)
|
| 872 | + size = self.embios.file_size(fd)
|
| 873 | + while size > 0:
|
| 874 | + bytes = self.embios.file_read(fd, buffer, buffsize)
|
| 875 | + f.write(self.embios.read(buffer, bytes))
|
| 876 | + size = size - bytes
|
| 877 | + self.embios.file_close(fd)
|
| 878 | + f.close()
|
| 879 | + self.logger.info(" done\n")
|
| 880 | +
|
| 881 | + @command
|
| 882 | + def put(self, buffer, buffsize, localname, remotename):
|
| 883 | + """
|
| 884 | + Uploads a file
|
| 885 | + """
|
| 886 | + buffer = self._hexint(buffer)
|
| 887 | + buffsize = self._hexint(buffsize)
|
| 888 | + try:
|
| 889 | + f = open(localname, 'rb')
|
| 890 | + except IOError:
|
| 891 | + raise ArgumentError("Could not open local file for reading.")
|
| 892 | + self.embios.lib.dev.timeout = 30000
|
| 893 | + self.logger.info("Uploading file " + localname + " to " + remotename + "...")
|
| 894 | + fd = self.embios.file_open(remotename, 0x15)
|
| 895 | + while True:
|
| 896 | + data = f.read(buffsize)
|
| 897 | + if len(data) == 0: break
|
| 898 | + self.embios.write(buffer, data)
|
| 899 | + bytes = 0
|
| 900 | + while bytes < len(data):
|
| 901 | + bytes = bytes + self.embios.file_write(fd, buffer + bytes, len(data) - bytes)
|
| 902 | + self.embios.file_close(fd)
|
| 903 | + f.close()
|
| 904 | + self.logger.info(" done\n")
|
| 905 | +
|
| 906 | + @command
|
| 907 | + def ls(self, path):
|
| 908 | + """
|
| 909 | + Lists all files in the specified path
|
| 910 | + """
|
| 911 | + self.embios.lib.dev.timeout = 30000
|
| 912 | + handle = self.embios.dir_open(path)
|
| 913 | + self.logger.info("Directory listing of " + path + ":\n")
|
| 914 | + while True:
|
| 915 | + try:
|
| 916 | + entry = self.embios.dir_read(handle)
|
| 917 | + if entry.attributes & 0x10: size = "DIR"
|
| 918 | + else: size = locale.format("%d", entry.size, True).rjust(13)
|
| 919 | + self.logger.info(entry.name.ljust(50) + " - " + size + "\n")
|
| 920 | + except: break
|
| 921 | + self.embios.dir_close(handle)
|
| 922 | +
|
807 | 923 | if __name__ == "__main__":
|
808 | 924 | if len(sys.argv) < 2:
|
809 | 925 | usage("No command specified")
|
Index: embios/trunk/tools/libembios.py |
— | — | @@ -404,7 +404,7 @@ |
405 | 405 |
|
406 | 406 | def execimage(self, addr):
|
407 | 407 | """ Runs the emBIOS app at 'addr' """
|
408 | | - return self.lib.monitorcommand(struct.pack("IIII", 21, addr, 0, 0), "III", ("excecimage", None, None))
|
| 408 | + return self.lib.monitorcommand(struct.pack("IIII", 21, addr, 0, 0), "III", ("rc", None, None))
|
409 | 409 |
|
410 | 410 | def run(self, app):
|
411 | 411 | """ Uploads and runs the emBIOS app in the string 'app' """
|
— | — | @@ -471,6 +471,7 @@ |
472 | 472 | """ Target-specific function: ipodnano2g
|
473 | 473 | Gathers some information about the NAND chip used
|
474 | 474 | """
|
| 475 | + if self.lib.dev.hwtypeid != 0x47324e49: raise DeviceError("Wrong device for target-specific command.")
|
475 | 476 | return self.lib.monitorcommand(struct.pack("IIII", 0xffff0001, 0, 0, 0), "IHHHH", ("type", "pagesperblock", "banks", "userblocks", "blocks"))
|
476 | 477 |
|
477 | 478 | def ipodnano2g_nandread(self, addr, start, count, doecc, checkempty):
|
— | — | @@ -477,6 +478,7 @@ |
478 | 479 | """ Target-specific function: ipodnano2g
|
479 | 480 | Reads data from the NAND chip into memory
|
480 | 481 | """
|
| 482 | + if self.lib.dev.hwtypeid != 0x47324e49: raise DeviceError("Wrong device for target-specific command.")
|
481 | 483 | return self.lib.monitorcommand(struct.pack("IIII", 0xffff0002, addr | (0x80000000 if doecc != 0 else 0) | (0x40000000 if checkempty != 0 else 0), start, count), "III", (None, None, None))
|
482 | 484 |
|
483 | 485 | def ipodnano2g_nandwrite(self, addr, start, count, doecc):
|
— | — | @@ -483,6 +485,7 @@ |
484 | 486 | """ Target-specific function: ipodnano2g
|
485 | 487 | Writes data to the NAND chip
|
486 | 488 | """
|
| 489 | + if self.lib.dev.hwtypeid != 0x47324e49: raise DeviceError("Wrong device for target-specific command.")
|
487 | 490 | return self.lib.monitorcommand(struct.pack("IIII", 0xffff0003, addr | (0x80000000 if doecc != 0 else 0), start, count), "III", (None, None, None))
|
488 | 491 |
|
489 | 492 | def ipodnano2g_nanderase(self, addr, start, count):
|
— | — | @@ -489,9 +492,230 @@ |
490 | 493 | """ Target-specific function: ipodnano2g
|
491 | 494 | Erases blocks on the NAND chip and stores the results to memory
|
492 | 495 | """
|
| 496 | + if self.lib.dev.hwtypeid != 0x47324e49: raise DeviceError("Wrong device for target-specific command.")
|
493 | 497 | return self.lib.monitorcommand(struct.pack("IIII", 0xffff0004, addr, start, count), "III", (None, None, None))
|
494 | 498 |
|
| 499 | + def ipodclassic_gethddinfo(self):
|
| 500 | + """ Target-specific function: ipodclassic
|
| 501 | + Gather information about the hard disk drive
|
| 502 | + """
|
| 503 | + if self.lib.dev.hwtypeid != 0x4c435049: raise DeviceError("Wrong device for target-specific command.")
|
| 504 | + return self.lib.monitorcommand(struct.pack("IIII", 0xffff0001, 0, 0, 0), "IQQII", ("identifyptr", "totalsectors", "virtualsectors", "bbtptr", "bbtsize"))
|
| 505 | +
|
| 506 | + def ipodclassic_hddaccess(self, type, sector, count, addr):
|
| 507 | + """ Target-specific function: ipodclassic
|
| 508 | + Access the hard disk, type = 0 (read) / 1 (write)
|
| 509 | + """
|
| 510 | + if self.lib.dev.hwtypeid != 0x4c435049: raise DeviceError("Wrong device for target-specific command.")
|
| 511 | + rc = self.lib.monitorcommand(struct.pack("IIQIIII", 0xffff0002, type, sector, count, addr, 0, 0), "III", ("rc", None, None))
|
| 512 | + if (rc > 0x80000000):
|
| 513 | + raise DeviceError("HDD access (type=%d, sector=%d, count=%d, addr=0x%08X) failed with RC 0x%08X" % (type, sector, count, addr, rc))
|
| 514 | +
|
| 515 | + def ipodclassic_writebbt(self, bbt, tempaddr):
|
| 516 | + """ Target-specific function: ipodclassic
|
| 517 | + Write hard drive bad block table
|
| 518 | + """
|
| 519 | + if self.lib.dev.hwtypeid != 0x4c435049: raise DeviceError("Wrong device for target-specific command.")
|
| 520 | + try:
|
| 521 | + bbtheader = struct.unpack("<8s2024sQII512I", bbt[:4096])
|
| 522 | + except struct.error:
|
| 523 | + raise ArgumentError("The specified file is not an emBIOS hard disk BBT")
|
| 524 | + if bbtheader[0] != "emBIbbth":
|
| 525 | + raise ArgumentError("The specified file is not an emBIOS hard disk BBT")
|
| 526 | + virtualsectors = bbtheader[2]
|
| 527 | + bbtsectors = bbtheader[3]
|
| 528 | + self.write(tempaddr, bbt)
|
| 529 | + sector = 0
|
| 530 | + count = 1
|
| 531 | + offset = 0
|
| 532 | + for i in range(bbtsectors):
|
| 533 | + if bbtheader[4][i] == sector + count:
|
| 534 | + count = count + 1
|
| 535 | + else:
|
| 536 | + self.ipodclassic_hddaccess(1, sector, count, tempaddr + offset)
|
| 537 | + offset = offset + count * 4096
|
| 538 | + sector = bbtheader[4][i]
|
| 539 | + count = 1
|
| 540 | + self.ipodclassic_hddaccess(1, sector, count, tempaddr + offset)
|
| 541 | +
|
| 542 | + def storage_get_info(self):
|
| 543 | + """ Get information about a storage device """
|
| 544 | + result = self.lib.monitorcommand(struct.pack("IIII", 27, 0, 0, 0), "IIIIIIII", ("version", None, None, "sectorsize", "numsectors", "vendorptr", "productptr", "revisionptr"))
|
| 545 | + if result.version != 1:
|
| 546 | + raise ValueError("Unknown version of storage_info struct: %d" % result.version)
|
| 547 | + return result
|
| 548 | +
|
| 549 | + def storage_read_sectors_md(self, volume, sector, count, addr):
|
| 550 | + """ Read sectors from as storage device """
|
| 551 | + result = self.lib.monitorcommand(struct.pack("IIQIIII", 28, volume, sector, count, addr, 0, 0), "III", ("rc", None, None, None))
|
| 552 | + if result.rc > 0x80000000:
|
| 553 | + raise DeviceError("storage_read_sectors_md(volume=%d, sector=%d, count=%d, addr=0x%08X) failed with RC 0x%08X" % (volume, sector, count, addr, rc))
|
495 | 554 |
|
| 555 | + def storage_write_sectors_md(self, volume, sector, count, addr):
|
| 556 | + """ Read sectors from as storage device """
|
| 557 | + result = self.lib.monitorcommand(struct.pack("IIQIIII", 29, volume, sector, count, addr, 0, 0), "III", ("rc", None, None, None))
|
| 558 | + if result.rc > 0x80000000:
|
| 559 | + raise DeviceError("storage_read_sectors_md(volume=%d, sector=%d, count=%d, addr=0x%08X) failed with RC 0x%08X" % (volume, sector, count, addr, rc))
|
| 560 | +
|
| 561 | + def file_open(self, filename, mode):
|
| 562 | + """ Opens a file and returns the handle """
|
| 563 | + result = self.lib.monitorcommand(struct.pack("IIII%dsB" % len(filename), 30, mode, 0, 0, filename, 0), "III", ("fd", None, None))
|
| 564 | + if result.fd > 0x80000000:
|
| 565 | + raise DeviceError("file_open(filename=\"%s\", mode=0x%X) failed with RC=0x%08X, errno=%d" % (filename, mode, result.fd, self.errno()))
|
| 566 | + return result.fd
|
| 567 | +
|
| 568 | + def file_size(self, fd):
|
| 569 | + """ Gets the size of a file referenced by a handle """
|
| 570 | + result = self.lib.monitorcommand(struct.pack("IIII", 31, fd, 0, 0), "III", ("size", None, None))
|
| 571 | + if result.size > 0x80000000:
|
| 572 | + raise DeviceError("file_size(fd=%d) failed with RC=0x%08X, errno=%d" % (fd, result.size, self.errno()))
|
| 573 | + return result.size
|
| 574 | +
|
| 575 | + def file_read(self, fd, addr, size):
|
| 576 | + """ Reads data from a file referenced by a handle """
|
| 577 | + result = self.lib.monitorcommand(struct.pack("IIII", 32, fd, addr, size), "III", ("rc", None, None))
|
| 578 | + if result.rc > 0x80000000:
|
| 579 | + raise DeviceError("file_read(fd=%d, addr=0x%08X, size=0x%08X) failed with RC=0x%08X, errno=%d" % (fd, addr, size, result.rc, self.errno()))
|
| 580 | + return result.rc
|
| 581 | +
|
| 582 | + def file_write(self, fd, addr, size):
|
| 583 | + """ Writes data from a file referenced by a handle """
|
| 584 | + result = self.lib.monitorcommand(struct.pack("IIII", 33, fd, addr, size), "III", ("rc", None, None))
|
| 585 | + if result.rc > 0x80000000:
|
| 586 | + raise DeviceError("file_write(fd=%d, addr=0x%08X, size=0x%08X) failed with RC=0x%08X, errno=%d" % (fd, addr, size, result.rc, self.errno()))
|
| 587 | + return result.rc
|
| 588 | +
|
| 589 | + def file_seek(self, fd, offset, whence):
|
| 590 | + """ Seeks the file handle to the specified position in the file """
|
| 591 | + result = self.lib.monitorcommand(struct.pack("IIII", 34, fd, offset, whence), "III", ("rc", None, None))
|
| 592 | + if result.rc > 0x80000000:
|
| 593 | + raise DeviceError("file_seek(fd=%d, offset=0x%08X, whence=%d) failed with RC=0x%08X, errno=%d" % (fd, offset, whence, result.rc, self.errno()))
|
| 594 | + return result.rc
|
| 595 | +
|
| 596 | + def file_truncate(self, fd, length):
|
| 597 | + """ Truncates a file referenced by a handle to a specified length """
|
| 598 | + result = self.lib.monitorcommand(struct.pack("IIII", 35, fd, offset, 0), "III", ("rc", None, None))
|
| 599 | + if result.rc > 0x80000000:
|
| 600 | + raise DeviceError("file_truncate(fd=%d, length=0x%08X) failed with RC=0x%08X, errno=%d" % (fd, length, result.rc, self.errno()))
|
| 601 | + return result.rc
|
| 602 | +
|
| 603 | + def file_sync(self, fd):
|
| 604 | + """ Flushes a file handles' buffers """
|
| 605 | + result = self.lib.monitorcommand(struct.pack("IIII", 36, fd, 0, 0), "III", ("rc", None, None))
|
| 606 | + if result.rc > 0x80000000:
|
| 607 | + raise DeviceError("file_sync(fd=%d) failed with RC=0x%08X, errno=%d" % (fd, result.rc, self.errno()))
|
| 608 | + return result.rc
|
| 609 | +
|
| 610 | + def file_close(self, fd):
|
| 611 | + """ Closes a file handle """
|
| 612 | + result = self.lib.monitorcommand(struct.pack("IIII", 37, fd, 0, 0), "III", ("rc", None, None))
|
| 613 | + if result.rc > 0x80000000:
|
| 614 | + raise DeviceError("file_close(fd=%d) failed with RC=0x%08X, errno=%d" % (fd, result.rc, self.errno()))
|
| 615 | + return result.rc
|
| 616 | +
|
| 617 | + def file_close_all(self):
|
| 618 | + """ Closes all file handles opened through the debugger """
|
| 619 | + result = self.lib.monitorcommand(struct.pack("IIII", 38, 0, 0, 0), "III", ("rc", None, None))
|
| 620 | + if result.rc > 0x80000000:
|
| 621 | + raise DeviceError("file_close_all() failed with RC=0x%08X, errno=%d" % (result.rc, self.errno()))
|
| 622 | + return result.rc
|
| 623 | +
|
| 624 | + def file_kill_all(self):
|
| 625 | + """ Kills all file handles (in the whole system) """
|
| 626 | + result = self.lib.monitorcommand(struct.pack("IIII", 39, 0, 0, 0), "III", ("rc", None, None))
|
| 627 | + if result.rc > 0x80000000:
|
| 628 | + raise DeviceError("file_kill_all() failed with RC=0x%08X, errno=%d" % (result.rc, self.errno()))
|
| 629 | + return result.rc
|
| 630 | +
|
| 631 | + def file_unlink(self, filename):
|
| 632 | + """ Removes a file """
|
| 633 | + result = self.lib.monitorcommand(struct.pack("IIII%dsB" % len(filename), 40, 0, 0, 0, filename, 0), "III", ("rc", None, None))
|
| 634 | + if result.rc > 0x80000000:
|
| 635 | + raise DeviceError("file_unlink(filename=\"%s\") failed with RC=0x%08X, errno=%d" % (filename, result.rc, self.errno()))
|
| 636 | + return result.rc
|
| 637 | +
|
| 638 | + def file_rename(self, oldname, newname):
|
| 639 | + """ Renames a file """
|
| 640 | + result = self.lib.monitorcommand(struct.pack("IIII248s%dsB" % min(247, len(newname)), 41, 0, 0, 0, oldname, newname, 0), "III", ("rc", None, None))
|
| 641 | + if result.rc > 0x80000000:
|
| 642 | + raise DeviceError("file_rename(oldname=\"%s\", newname=\"%s\") failed with RC=0x%08X, errno=%d" % (oldname, newname, result.rc, self.errno()))
|
| 643 | + return result.rc
|
| 644 | +
|
| 645 | + def dir_open(self, dirname):
|
| 646 | + """ Opens a directory and returns the handle """
|
| 647 | + result = self.lib.monitorcommand(struct.pack("IIII%dsB" % len(dirname), 42, 0, 0, 0, dirname, 0), "III", ("handle", None, None))
|
| 648 | + if result.handle == 0:
|
| 649 | + raise DeviceError("dir_open(dirname=\"%s\") failed with RC=0x%08X, errno=%d" % (dirname, result.handle, self.errno()))
|
| 650 | + return result.handle
|
| 651 | +
|
| 652 | + def dir_read(self, handle):
|
| 653 | + """ Reads the next entry from a directory """
|
| 654 | + result = self.lib.monitorcommand(struct.pack("IIII", 43, handle, 0, 0), "III", ("version", "maxpath", "ptr"))
|
| 655 | + if result.ptr == 0:
|
| 656 | + raise DeviceError("dir_read(handle=0x%08X) failed with RC=0x%08X, errno=%d" % (handle, result.ptr, self.errno()))
|
| 657 | + if result.version != 1:
|
| 658 | + raise ValueError("Unknown version of dirent struct: %d" % result.version)
|
| 659 | + dirent = self.read(result.ptr, result.maxpath + 16)
|
| 660 | + ret = Bunch()
|
| 661 | + (ret.name, ret.attributes, ret.size, ret.startcluster, ret.wrtdate, ret.wrttime) = struct.unpack("%dsIIIHH" % result.maxpath, dirent)
|
| 662 | + ret.name = ret.name[:ret.name.index('\x00')]
|
| 663 | + return ret
|
| 664 | +
|
| 665 | + def dir_close(self, handle):
|
| 666 | + """ Closes a directory handle """
|
| 667 | + result = self.lib.monitorcommand(struct.pack("IIII", 44, handle, 0, 0), "III", ("rc", None, None))
|
| 668 | + if result.rc > 0x80000000:
|
| 669 | + raise DeviceError("dir_close(handle=0x%08X) failed with RC=0x%08X, errno=%d" % (handle, result.rc, self.errno()))
|
| 670 | + return result.rc
|
| 671 | +
|
| 672 | + def dir_close_all(self):
|
| 673 | + """ Closes all directory handles opened through the debugger """
|
| 674 | + result = self.lib.monitorcommand(struct.pack("IIII", 45, 0, 0, 0), "III", ("rc", None, None))
|
| 675 | + if result.rc > 0x80000000:
|
| 676 | + raise DeviceError("dir_close_all() failed with RC=0x%08X, errno=%d" % (result.rc, self.errno()))
|
| 677 | + return result.rc
|
| 678 | +
|
| 679 | + def dir_kill_all(self):
|
| 680 | + """ Kills all directory handles (in the whole system) """
|
| 681 | + result = self.lib.monitorcommand(struct.pack("IIII", 46, 0, 0, 0), "III", ("rc", None, None))
|
| 682 | + if result.rc > 0x80000000:
|
| 683 | + raise DeviceError("dir_kill_all() failed with RC=0x%08X, errno=%d" % (result.rc, self.errno()))
|
| 684 | + return result.rc
|
| 685 | +
|
| 686 | + def dir_create(self, dirname):
|
| 687 | + """ Creates a directory """
|
| 688 | + result = self.lib.monitorcommand(struct.pack("IIII%dsB" % len(dirname), 47, 0, 0, 0, dirname, 0), "III", ("rc", None, None))
|
| 689 | + if result.rc > 0x80000000:
|
| 690 | + raise DeviceError("dir_create(dirname=\"%s\") failed with RC=0x%08X, errno=%d" % (dirname, result.rc, self.errno()))
|
| 691 | + return result.rc
|
| 692 | +
|
| 693 | + def dir_remove(self, dirname):
|
| 694 | + """ Removes an (empty) directory """
|
| 695 | + result = self.lib.monitorcommand(struct.pack("IIII%dsB" % len(dirname), 48, 0, 0, 0, dirname, 0), "III", ("rc", None, None))
|
| 696 | + if result.rc > 0x80000000:
|
| 697 | + raise DeviceError("dir_remove(dirname=\"%s\") failed with RC=0x%08X, errno=%d" % (dirname, result.rc, self.errno()))
|
| 698 | + return result.rc
|
| 699 | +
|
| 700 | + def errno(self):
|
| 701 | + """ Returns the number of the last error that happened """
|
| 702 | + result = self.lib.monitorcommand(struct.pack("IIII", 49, 0, 0, 0), "III", ("errno", None, None))
|
| 703 | + return result.errno
|
| 704 | +
|
| 705 | + def disk_mount(self, volume):
|
| 706 | + """ Mounts a volume """
|
| 707 | + result = self.lib.monitorcommand(struct.pack("IIII", 50, volume, 0, 0), "III", ("rc", None, None))
|
| 708 | + if result.rc > 0x80000000:
|
| 709 | + raise DeviceError("disk_mount(volume=%d) failed with RC=0x%08X, errno=%d" % (volume, result.rc, self.errno()))
|
| 710 | + return result.rc
|
| 711 | +
|
| 712 | + def disk_unmount(self, volume):
|
| 713 | + """ Unmounts a volume """
|
| 714 | + result = self.lib.monitorcommand(struct.pack("IIII", 51, volume, 0, 0), "III", ("rc", None, None))
|
| 715 | + if result.rc > 0x80000000:
|
| 716 | + raise DeviceError("disk_unmount(volume=%d) failed with RC=0x%08X, errno=%d" % (volume, result.rc, self.errno()))
|
| 717 | + return result.rc
|
| 718 | +
|
| 719 | +
|
496 | 720 | class Lib(object):
|
497 | 721 | def __init__(self):
|
498 | 722 | self.idVendor = 0xFFFF
|
— | — | @@ -655,4 +879,4 @@ |
656 | 880 | if readdata == datastr:
|
657 | 881 | sys.stdout.write("Data matches!")
|
658 | 882 | else:
|
659 | | - sys.stdout.write("Data does NOT match. Something got wrong") |
\ No newline at end of file |
| 883 | + sys.stdout.write("Data does NOT match. Something went wrong") |
\ No newline at end of file |
Index: embios/trunk/target/ipodclassic/usbtarget.c |
— | — | @@ -0,0 +1,69 @@ |
| 2 | +//
|
| 3 | +//
|
| 4 | +// Copyright 2010 TheSeven
|
| 5 | +//
|
| 6 | +//
|
| 7 | +// This file is part of emBIOS.
|
| 8 | +//
|
| 9 | +// emBIOS is free software: you can redistribute it and/or
|
| 10 | +// modify it under the terms of the GNU General Public License as
|
| 11 | +// published by the Free Software Foundation, either version 2 of the
|
| 12 | +// License, or (at your option) any later version.
|
| 13 | +//
|
| 14 | +// emBIOS is distributed in the hope that it will be useful,
|
| 15 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 16 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
| 17 | +// See the GNU General Public License for more details.
|
| 18 | +//
|
| 19 | +// You should have received a copy of the GNU General Public License along
|
| 20 | +// with emBIOS. If not, see <http://www.gnu.org/licenses/>.
|
| 21 | +//
|
| 22 | +//
|
| 23 | +
|
| 24 | +
|
| 25 | +#include "global.h"
|
| 26 | +#include "usb/usbtarget.h"
|
| 27 | +#include "usb/usbdrv.h"
|
| 28 | +#include "storage_ata-target.h"
|
| 29 | +
|
| 30 | +
|
| 31 | +int usb_target_handle_request(uint32_t* buffer, int bufsize)
|
| 32 | +{
|
| 33 | + int size = 0;
|
| 34 | + switch (buffer[0])
|
| 35 | + {
|
| 36 | + case 0xffff0001: // GET DISK INFO
|
| 37 | + {
|
| 38 | + buffer[0] = 1;
|
| 39 | + buffer[1] = (uint32_t)ata_identify_data;
|
| 40 | + buffer[2] = ata_total_sectors;
|
| 41 | + buffer[3] = ata_total_sectors >> 32;
|
| 42 | +#ifdef ATA_HAVE_BBT
|
| 43 | + buffer[4] = ata_virtual_sectors;
|
| 44 | + buffer[5] = ata_virtual_sectors >> 32;
|
| 45 | + buffer[6] = (uint32_t)ata_bbt;
|
| 46 | + buffer[7] = ATA_BBT_PAGES << 6;
|
| 47 | +#else
|
| 48 | + buffer[4] = ata_total_sectors;
|
| 49 | + buffer[5] = ata_total_sectors >> 32;
|
| 50 | + buffer[6] = 0;
|
| 51 | + buffer[7] = 0;
|
| 52 | +#endif
|
| 53 | + size = 32;
|
| 54 | + break;
|
| 55 | + }
|
| 56 | + case 0xffff0002: // LOWLEVEL DISK ACCESS
|
| 57 | + {
|
| 58 | + int rc = ata_rw_sectors_internal((((uint64_t)(buffer[3])) << 32) | buffer[2],
|
| 59 | + buffer[4], (void*)(buffer[5]), (bool)(buffer[1]));
|
| 60 | + buffer[0] = 1;
|
| 61 | + buffer[1] = (uint32_t)rc;
|
| 62 | + size = 16;
|
| 63 | + break;
|
| 64 | + }
|
| 65 | + default:
|
| 66 | + buffer[0] = 2;
|
| 67 | + size = 16;
|
| 68 | + }
|
| 69 | + return size;
|
| 70 | +} |
\ No newline at end of file |
Index: embios/trunk/target/ipodclassic/target.h |
— | — | @@ -39,6 +39,7 @@ |
40 | 40 |
|
41 | 41 | #define HAVE_USB
|
42 | 42 | #define USB_NUM_ENDPOINTS 5
|
| 43 | +#define USB_HAVE_TARGET_SPECIFIC_REQUESTS
|
43 | 44 |
|
44 | 45 | #define HAVE_LCD
|
45 | 46 | #define HAVE_LCD_SHUTDOWN
|
Index: embios/trunk/SOURCES |
— | — | @@ -55,6 +55,7 @@ |
56 | 56 |
|
57 | 57 | #ifdef TARGET_ipodclassic
|
58 | 58 | target/ipodclassic/storage_ata.c
|
| 59 | +target/ipodclassic/usbtarget.c
|
59 | 60 | #endif
|
60 | 61 |
|
61 | 62 | #ifdef ARM_ARCH
|
Index: embios/trunk/usb/usb.c |
— | — | @@ -49,6 +49,13 @@ |
50 | 50 | #ifdef USB_HAVE_TARGET_SPECIFIC_REQUESTS
|
51 | 51 | #include "usbtarget.h"
|
52 | 52 | #endif
|
| 53 | +#ifdef HAVE_STORAGE
|
| 54 | +#include "storage.h"
|
| 55 | +#include "disk.h"
|
| 56 | +#include "file.h"
|
| 57 | +#include "dir.h"
|
| 58 | +#include "errno.h"
|
| 59 | +#endif
|
53 | 60 |
|
54 | 61 |
|
55 | 62 | static uint8_t ctrlresp[2] CACHEALIGN_ATTR;
|
— | — | @@ -73,12 +80,14 @@ |
74 | 81 | DBGACTION_WRITEBOOTFLASH,
|
75 | 82 | DBGACTION_HWKEYAES,
|
76 | 83 | DBGACTION_HMACSHA1,
|
77 | | - DBGACTION_TARGETSPECIFIC
|
| 84 | + DBGACTION_TARGETSPECIFIC,
|
| 85 | + DBGACTION_STORAGE
|
78 | 86 | };
|
79 | 87 |
|
80 | | -static uint32_t dbgstack[0x100] STACK_ATTR;
|
| 88 | +static uint32_t dbgstack[0x200] STACK_ATTR;
|
81 | 89 | struct wakeup dbgwakeup IBSS_ATTR;
|
82 | 90 | extern struct scheduler_thread* scheduler_threads;
|
| 91 | +extern struct scheduler_thread* current_thread;
|
83 | 92 | static enum dbgaction_t dbgaction IBSS_ATTR;
|
84 | 93 | static int dbgi2cbus;
|
85 | 94 | static int dbgi2cslave;
|
— | — | @@ -580,6 +589,38 @@ |
581 | 590 | dbgactionoffset = dbgrecvbuf[3];
|
582 | 591 | break;
|
583 | 592 | #endif
|
| 593 | +#ifdef HAVE_STORAGE
|
| 594 | + case 27: // STORAGE_GET_INFO
|
| 595 | + case 28: // STORAGE_READ_SECTORS_MD
|
| 596 | + case 29: // STORAGE_WRITE_SECTORS_MD
|
| 597 | + case 30: // FILE_OPEN
|
| 598 | + case 31: // FILESIZE
|
| 599 | + case 32: // READ
|
| 600 | + case 33: // WRITE
|
| 601 | + case 34: // LSEEK
|
| 602 | + case 35: // FTRUNCATE
|
| 603 | + case 36: // FSYNC
|
| 604 | + case 37: // CLOSE
|
| 605 | + case 38: // CLOSE_MONITOR_FILES
|
| 606 | + case 39: // RELEASE_FILES
|
| 607 | + case 40: // REMOVE
|
| 608 | + case 41: // RENAME
|
| 609 | + case 42: // OPENDIR
|
| 610 | + case 43: // READDIR
|
| 611 | + case 44: // CLOSEDIR
|
| 612 | + case 45: // CLOSE_MONITOR_DIRS
|
| 613 | + case 46: // RELEASE_DIRS
|
| 614 | + case 47: // MKDIR
|
| 615 | + case 48: // RMDIR
|
| 616 | + case 49: // ERRNO
|
| 617 | +#ifdef HAVE_HOTSWAP
|
| 618 | + case 50: // DISK_MOUNT
|
| 619 | + case 51: // DISK_UNMOUNT
|
| 620 | +#endif
|
| 621 | + if (!set_dbgaction(DBGACTION_STORAGE, 0))
|
| 622 | + memcpy(dbgasyncsendbuf, dbgrecvbuf, sizeof(dbgasyncsendbuf));
|
| 623 | + break;
|
| 624 | +#endif
|
584 | 625 | default:
|
585 | 626 | dbgsendbuf[0] = 2;
|
586 | 627 | size = 16;
|
— | — | @@ -708,6 +749,170 @@ |
709 | 750 | break;
|
710 | 751 | }
|
711 | 752 | #endif
|
| 753 | +#ifdef HAVE_STORAGE
|
| 754 | + case DBGACTION_STORAGE:
|
| 755 | + switch(dbgasyncsendbuf[0])
|
| 756 | + {
|
| 757 | + case 27: // STORAGE_GET_INFO
|
| 758 | + dbgasyncsendbuf[0] = 1;
|
| 759 | + storage_get_info(dbgasyncsendbuf[1],
|
| 760 | + (struct storage_info*)&dbgasyncsendbuf[4]);
|
| 761 | + dbgasyncsendbuf[1] = 1;
|
| 762 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf,
|
| 763 | + 16 + sizeof(struct storage_info));
|
| 764 | + break;
|
| 765 | + case 28: // STORAGE_READ_SECTORS_MD
|
| 766 | + {
|
| 767 | + dbgasyncsendbuf[0] = 1;
|
| 768 | + int rc = storage_read_sectors_md(dbgasyncsendbuf[1],
|
| 769 | + dbgasyncsendbuf[2]
|
| 770 | + | (((uint64_t)(dbgasyncsendbuf[3]) << 32)),
|
| 771 | + dbgasyncsendbuf[4],
|
| 772 | + (void*)(dbgasyncsendbuf[5]));
|
| 773 | + dbgasyncsendbuf[1] = (uint32_t)rc;
|
| 774 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 775 | + break;
|
| 776 | + }
|
| 777 | + case 29: // STORAGE_WRITE_SECTORS_MD
|
| 778 | + {
|
| 779 | + dbgasyncsendbuf[0] = 1;
|
| 780 | + int rc = storage_write_sectors_md(dbgasyncsendbuf[1],
|
| 781 | + dbgasyncsendbuf[2]
|
| 782 | + | (((uint64_t)(dbgasyncsendbuf[3]) << 32)),
|
| 783 | + dbgasyncsendbuf[4],
|
| 784 | + (void*)(dbgasyncsendbuf[5]));
|
| 785 | + dbgasyncsendbuf[1] = (uint32_t)rc;
|
| 786 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 787 | + break;
|
| 788 | + }
|
| 789 | + case 30: // FILE_OPEN
|
| 790 | + {
|
| 791 | + dbgasyncsendbuf[0] = 1;
|
| 792 | + int fd = file_open((char*)(&dbgasyncsendbuf[4]), (int)(dbgasyncsendbuf[1]));
|
| 793 | + dbgasyncsendbuf[1] = (uint32_t)fd;
|
| 794 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 795 | + break;
|
| 796 | + }
|
| 797 | + case 31: // FILESIZE
|
| 798 | + dbgasyncsendbuf[0] = 1;
|
| 799 | + dbgasyncsendbuf[1] = (uint32_t)filesize((int)(dbgasyncsendbuf[1]));
|
| 800 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 801 | + break;
|
| 802 | + case 32: // READ
|
| 803 | + dbgasyncsendbuf[0] = 1;
|
| 804 | + dbgasyncsendbuf[1] = (uint32_t)read((int)(dbgasyncsendbuf[1]),
|
| 805 | + (void*)(dbgasyncsendbuf[2]),
|
| 806 | + (size_t)(dbgasyncsendbuf[3]));
|
| 807 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 808 | + break;
|
| 809 | + case 33: // WRITE
|
| 810 | + dbgasyncsendbuf[0] = 1;
|
| 811 | + dbgasyncsendbuf[1] = (uint32_t)write((int)(dbgasyncsendbuf[1]),
|
| 812 | + (void*)(dbgasyncsendbuf[2]),
|
| 813 | + (size_t)(dbgasyncsendbuf[3]));
|
| 814 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 815 | + break;
|
| 816 | + case 34: // LSEEK
|
| 817 | + dbgasyncsendbuf[0] = 1;
|
| 818 | + dbgasyncsendbuf[1] = (uint32_t)lseek((int)(dbgasyncsendbuf[1]),
|
| 819 | + (off_t)(dbgasyncsendbuf[2]),
|
| 820 | + (int)(dbgasyncsendbuf[3]));
|
| 821 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 822 | + break;
|
| 823 | + case 35: // FTRUNCATE
|
| 824 | + dbgasyncsendbuf[0] = 1;
|
| 825 | + dbgasyncsendbuf[1] = (uint32_t)ftruncate((int)(dbgasyncsendbuf[1]),
|
| 826 | + (off_t)(dbgasyncsendbuf[2]));
|
| 827 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 828 | + break;
|
| 829 | + case 36: // FSYNC
|
| 830 | + dbgasyncsendbuf[0] = 1;
|
| 831 | + dbgasyncsendbuf[1] = (uint32_t)fsync((int)(dbgasyncsendbuf[1]));
|
| 832 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 833 | + break;
|
| 834 | + case 37: // CLOSE
|
| 835 | + dbgasyncsendbuf[0] = 1;
|
| 836 | + dbgasyncsendbuf[1] = (uint32_t)close((int)(dbgasyncsendbuf[1]));
|
| 837 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 838 | + break;
|
| 839 | + case 38: // CLOSE_MONITOR_FILES
|
| 840 | + dbgasyncsendbuf[0] = 1;
|
| 841 | + dbgasyncsendbuf[1] = (uint32_t)close_all_of_process(current_thread);
|
| 842 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 843 | + break;
|
| 844 | + case 39: // RELEASE_FILES
|
| 845 | + dbgasyncsendbuf[0] = 1;
|
| 846 | + dbgasyncsendbuf[1] = (uint32_t)release_files((int)(dbgasyncsendbuf[1]));
|
| 847 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 848 | + break;
|
| 849 | + case 40: // REMOVE
|
| 850 | + dbgasyncsendbuf[0] = 1;
|
| 851 | + dbgasyncsendbuf[1] = (uint32_t)remove((char*)(&dbgasyncsendbuf[4]));
|
| 852 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 853 | + break;
|
| 854 | + case 41: // RENAME
|
| 855 | + dbgasyncsendbuf[0] = 1;
|
| 856 | + dbgasyncsendbuf[1] = (uint32_t)rename((char*)(&dbgasyncsendbuf[4]),
|
| 857 | + (char*)(&dbgasyncsendbuf[66]));
|
| 858 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 859 | + break;
|
| 860 | + case 42: // OPENDIR
|
| 861 | + dbgasyncsendbuf[0] = 1;
|
| 862 | + dbgasyncsendbuf[1] = (uint32_t)opendir((char*)(&dbgasyncsendbuf[4]));
|
| 863 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 864 | + break;
|
| 865 | + case 43: // READDIR
|
| 866 | + dbgasyncsendbuf[0] = 1;
|
| 867 | + dbgasyncsendbuf[3] = (uint32_t)readdir((DIR*)(dbgasyncsendbuf[1]));
|
| 868 | + dbgasyncsendbuf[1] = 1;
|
| 869 | + dbgasyncsendbuf[2] = MAX_PATH;
|
| 870 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 871 | + break;
|
| 872 | + case 44: // CLOSEDIR
|
| 873 | + dbgasyncsendbuf[0] = 1;
|
| 874 | + dbgasyncsendbuf[1] = (uint32_t)closedir((DIR*)(dbgasyncsendbuf[1]));
|
| 875 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 876 | + break;
|
| 877 | + case 45: // CLOSE_MONITOR_DIRS
|
| 878 | + dbgasyncsendbuf[0] = 1;
|
| 879 | + dbgasyncsendbuf[1] = (uint32_t)closedir_all_of_process(current_thread);
|
| 880 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 881 | + break;
|
| 882 | + case 46: // RELEASE_DIRS
|
| 883 | + dbgasyncsendbuf[0] = 1;
|
| 884 | + dbgasyncsendbuf[1] = (uint32_t)release_dirs((int)(dbgasyncsendbuf[1]));
|
| 885 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 886 | + break;
|
| 887 | + case 47: // MKDIR
|
| 888 | + dbgasyncsendbuf[0] = 1;
|
| 889 | + dbgasyncsendbuf[1] = (uint32_t)mkdir((char*)(&dbgasyncsendbuf[4]));
|
| 890 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 891 | + break;
|
| 892 | + case 48: // RMDIR
|
| 893 | + dbgasyncsendbuf[0] = 1;
|
| 894 | + dbgasyncsendbuf[1] = (uint32_t)rmdir((char*)(&dbgasyncsendbuf[4]));
|
| 895 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 896 | + break;
|
| 897 | + case 49: // ERRNO
|
| 898 | + dbgasyncsendbuf[0] = 1;
|
| 899 | + dbgasyncsendbuf[1] = (uint32_t)errno;
|
| 900 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 901 | + break;
|
| 902 | +#ifdef HAVE_HOTSWAP
|
| 903 | + case 50: // DISK_MOUNT
|
| 904 | + dbgasyncsendbuf[0] = 1;
|
| 905 | + dbgasyncsendbuf[1] = (uint32_t)disk_mount((int)(dbgasyncsendbuf[1]));
|
| 906 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 907 | + break;
|
| 908 | + case 51: // DISK_UNMOUNT
|
| 909 | + dbgasyncsendbuf[0] = 1;
|
| 910 | + dbgasyncsendbuf[1] = (uint32_t)disk_unmount((int)(dbgasyncsendbuf[1]));
|
| 911 | + usb_drv_send_nonblocking(dbgendpoints[1], dbgasyncsendbuf, 16);
|
| 912 | + break;
|
| 913 | +#endif
|
| 914 | + }
|
| 915 | + break;
|
| 916 | +#endif
|
712 | 917 | }
|
713 | 918 | dbgaction = DBGACTION_IDLE;
|
714 | 919 | }
|