Index: embios/trunk/tools/embios.py |
— | — | @@ -0,0 +1,128 @@ |
| 2 | +#
|
| 3 | +#
|
| 4 | +# Copyright 2010 benedikt93, partially derived from TheSeven's ipod tools
|
| 5 | +#
|
| 6 | +#
|
| 7 | +# This file is part of the freemyipod.org iPod tools.
|
| 8 | +#
|
| 9 | +# FreeMyIPods' emBIOS and related tools are 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 | +# FreeMyIPods' emBIOS and related tools are distributed in the hope that they 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 FreeMyIPods' emBIOS and related tools. If not, see <http://www.gnu.org/licenses/>.
|
| 21 | +#
|
| 22 | +#
|
| 23 | +
|
| 24 | +
|
| 25 | +import sys
|
| 26 | +import time
|
| 27 | +import libembios
|
| 28 | +
|
| 29 | +
|
| 30 | +def usage():
|
| 31 | + print ""
|
| 32 | + print "Please provide a command and (if needed) parameters as command line arguments"
|
| 33 | + print ""
|
| 34 | + print "Available commands:"
|
| 35 | + print ""
|
| 36 | + print " getinfo <infotype>"
|
| 37 | + print " Get info on the running emBIOS."
|
| 38 | + print " <infotype> may be either off 'version', 'packetsize', 'usermemrange'."
|
| 39 | + print ""
|
| 40 | + print " reset <force>"
|
| 41 | + print " Resets the device"
|
| 42 | + print " If <force> is 1, the reset will be forced, otherwise it will be gracefully,"
|
| 43 | + print " which may take some time."
|
| 44 | + print ""
|
| 45 | + print " poweroff <force>"
|
| 46 | + print " Powers the device off"
|
| 47 | + print " If <force> is 1, the poweroff will be forced, otherwise it will be gracefully,"
|
| 48 | + print " which may take some time."
|
| 49 | + print ""
|
| 50 | + print " lockscheduler"
|
| 51 | + print " Locks (freezes) the scheduler"
|
| 52 | + print ""
|
| 53 | + print " unlockscheduler"
|
| 54 | + print " Unlocks the scheduler"
|
| 55 | + print ""
|
| 56 | + print " suspendthread <threadid>"
|
| 57 | + print " Suspends/resumes the thread with thread ID <threadid>"
|
| 58 | + print ""
|
| 59 | + print " resumethread <threadid>"
|
| 60 | + print " Resumes the thread with thread ID <threadid>"
|
| 61 | + print ""
|
| 62 | + print " killthread <threadid>"
|
| 63 | + print " Kills the thread with thread ID <threadid>"
|
| 64 | + print ""
|
| 65 | + print " createthread <namepointer> <entrypoint> <stackpointer> <stacksize>, <type> <priority> <state>"
|
| 66 | + print " Creates a new thread and returns its thread ID"
|
| 67 | + print " <namepointer> a pointer to the thread's name"
|
| 68 | + print " <entrypoint> a pointer to the entrypoint of the thread"
|
| 69 | + print " <stackpointer> a pointer to the stack of the thread"
|
| 70 | + print " <stacksize> the size of the thread's stack"
|
| 71 | + print " <type> the thread type, vaild are: 0 => user thread, 1 => system thread"
|
| 72 | + print " <priority> the priority of the thread, from 1 to 255"
|
| 73 | + print " <state> the thread's initial state, valid are: 1 => ready, 0 => suspended"
|
| 74 | + print ""
|
| 75 | + print " flushcaches"
|
| 76 | + print " Flushes the CPUs data and instruction caches."
|
| 77 | + print ""
|
| 78 | + print "All numbers are hexadecimal!"
|
| 79 | + exit(2)
|
| 80 | +
|
| 81 | +
|
| 82 | +def parsecommand(dev, argv):
|
| 83 | + if len(argv) < 2: usage()
|
| 84 | +
|
| 85 | + elif argv[1] == "getinfo":
|
| 86 | + if len(argv) != 3: usage()
|
| 87 | + dev.getinfo(argv[2])
|
| 88 | +
|
| 89 | + elif argv[1] == "reset":
|
| 90 | + if len(argv) != 3: usage()
|
| 91 | + dev.reset(int(argv[2]))
|
| 92 | +
|
| 93 | + elif argv[1] == "poweroff":
|
| 94 | + if len(argv) != 3: usage()
|
| 95 | + dev.poweroff(int(argv[2]))
|
| 96 | +
|
| 97 | + elif argv[1] == "flushcaches":
|
| 98 | + if len(argv) != 2: usage()
|
| 99 | + dev.flushcaches()
|
| 100 | +
|
| 101 | + elif argv[1] == "lockscheduler":
|
| 102 | + if len(argv) != 2: usage()
|
| 103 | + dev.freezescheduler(1)
|
| 104 | +
|
| 105 | + elif argv[1] == "unlockscheduler":
|
| 106 | + if len(argv) != 2: usage()
|
| 107 | + dev.freezescheduler(0)
|
| 108 | +
|
| 109 | + elif argv[1] == "suspendthread":
|
| 110 | + if len(argv) != 3: usage()
|
| 111 | + dev.suspendthread(1, int(argv[2]))
|
| 112 | +
|
| 113 | + elif argv[1] == "resumethread":
|
| 114 | + if len(argv) != 3: usage()
|
| 115 | + dev.suspendthread(0, int(argv[2]))
|
| 116 | +
|
| 117 | + elif argv[1] == "killthread":
|
| 118 | + if len(argv) != 3: usage()
|
| 119 | + dev.killthread(int(argv[2]))
|
| 120 | +
|
| 121 | + elif argv[1] == "createthread":
|
| 122 | + if len(argv) != 9: usage()
|
| 123 | + dev.createthread(int(argv[2]), int(argv[3]), int(argv[4]), int(argv[5]), int(argv[6]), int(argv[7]), int(argv[8]))
|
| 124 | +
|
| 125 | + else: usage()
|
| 126 | +
|
| 127 | +
|
| 128 | +dev = libembios.embios()
|
| 129 | +parsecommand(dev, sys.argv)
|
Index: embios/trunk/tools/libembios.py |
— | — | @@ -59,9 +59,9 @@ |
60 | 60 | self.handle = handle
|
61 | 61 | self.dev = dev
|
62 | 62 |
|
63 | | - self.svnrev self.major, self.minor, self.patch, self.type, self.devtype = i[1:6]
|
| 63 | + self.svnrev, self.major, self.minor, self.patch, self.type, self.devtype = i[1:6]
|
64 | 64 | self.__myprint("Connected to emBIOS %s v%d.%d.%d (SVN revision: %d) on %s, USB version %s" \
|
65 | | - % (self.type2name(self.type), self.major, self.minor, self.patch, self.svnrev\
|
| 65 | + % (self.type2name(self.type), self.major, self.minor, self.patch, self.svnrev, \
|
66 | 66 | self.devtype2name(self.devtype), dev.deviceVersion))
|
67 | 67 |
|
68 | 68 | # get packet size info
|
— | — | @@ -86,18 +86,18 @@ |
87 | 87 |
|
88 | 88 |
|
89 | 89 | @staticmethod
|
90 | | - def __gethexviewprintout(data, title, showaddr)
|
| 90 | + def __gethexviewprintout(data, title, showaddr):
|
91 | 91 | printout_temp = struct.unpack("%dB" % (len(data)), data)
|
92 | 92 |
|
93 | | - printout_temp = title + ":\n"
|
| 93 | + printout = title + ":\n"
|
94 | 94 | pointer = 0
|
95 | 95 | pointer2 = 0
|
96 | 96 |
|
97 | | - while (pointer < printout_temp.size):
|
| 97 | + while (pointer < len(printout_temp)):
|
98 | 98 | pointer2 = 0
|
99 | | - if (showaddr): printout += "%8x" % (pointer)
|
100 | | - while (pointer2 < 0x10):
|
101 | | - printout_temp += ("%2x " % (printout_temp[pointer]))
|
| 99 | + if (showaddr): printout += "0x%08x " % (pointer)
|
| 100 | + while (pointer2 < 0x10) and (pointer < len(printout_temp)):
|
| 101 | + printout += ("%2x " % (printout_temp[pointer]))
|
102 | 102 | pointer += 1
|
103 | 103 | pointer2 += 1
|
104 | 104 | printout += "\n"
|
— | — | @@ -157,7 +157,7 @@ |
158 | 158 |
|
159 | 159 | i = struct.unpack("<IIBBBBI", response)
|
160 | 160 |
|
161 | | - self.svnrev self.major, self.minor, self.patch, self.type, self.devtype = i[1:6]
|
| 161 | + self.svnrev, self.major, self.minor, self.patch, self.type, self.devtype = i[1:6]
|
162 | 162 |
|
163 | 163 | self.__myprint("emBIOS %s v%d.%d.%d (SVN revision: %d) on %s, USB version %s\n" \
|
164 | 164 | % (self.type2name(self.type), self.major, self.minor, self.patch, self.svnrev, \
|
— | — | @@ -301,7 +301,7 @@ |
302 | 302 | while (size > 0):
|
303 | 303 | blocklen = size
|
304 | 304 |
|
305 | | - if (blocklen > self.cout_maxsize - 0x10)
|
| 305 | + if (blocklen > self.cout_maxsize - 0x10):
|
306 | 306 | blocklen = self.cout_maxsize
|
307 | 307 |
|
308 | 308 | self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 5, offset, blocklen, 0) + data[boffset:boffset+blocklen])
|
— | — | @@ -364,7 +364,7 @@ |
365 | 365 | while (size > 0):
|
366 | 366 | blocklen = size
|
367 | 367 |
|
368 | | - if (blocklen > self.cin_maxsize - 0x10)
|
| 368 | + if (blocklen > self.cin_maxsize - 0x10):
|
369 | 369 | blocklen = self.cin_maxsize
|
370 | 370 |
|
371 | 371 | self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 4, offset, blocklen, 0))
|
— | — | @@ -488,7 +488,7 @@ |
489 | 489 | elif (outtype == "printstring"):
|
490 | 490 | self.__myprint("\nBytes read: 0x%x\nOn-device buffersize: 0x%x\nBytes still in device's buffer: 0x%x\n\n"\
|
491 | 491 | % (struct.unpack("<IIII", response[:0x10])[1],
|
492 | | - struct.unpack("<IIII", response[:0x10])[2]
|
| 492 | + struct.unpack("<IIII", response[:0x10])[2],
|
493 | 493 | struct.unpack("<IIII", response[:0x10])[3])
|
494 | 494 | , silent)
|
495 | 495 | self.__myprint(response[0x10 : 0x10 + struct.unpack("<IIII", response[:0x10])[1]], silent)
|
— | — | @@ -497,16 +497,14 @@ |
498 | 498 | elif (outtype == "printhex"):
|
499 | 499 | self.__myprint("\nBytes read: 0x%x\nOn-device buffersize: 0x%x\nBytes still in device's buffer: 0x%x\n\n"\
|
500 | 500 | % (struct.unpack("<IIII", response[:0x10])[1],
|
501 | | - struct.unpack("<IIII", response[:0x10])[2]
|
| 501 | + struct.unpack("<IIII", response[:0x10])[2],
|
502 | 502 | struct.unpack("<IIII", response[:0x10])[3])
|
503 | 503 | , silent)
|
504 | 504 | self.__myprint(self.gethexviewprintout(response[0x10:], "", 1), silent)
|
505 | 505 | self.__myprint("\n\n", silent)
|
506 | 506 |
|
507 | | - elif (outtype == ""):
|
508 | | - # only return
|
509 | | - else:
|
510 | | - raise Exception ("Invalid argument for <outtype>.")
|
| 507 | + elif (outtype != ""): # none of the above and also not "" which would be return only
|
| 508 | + raise Exception ("Invalid argument for <outtype>: '%s'." % (outtype))
|
511 | 509 |
|
512 | 510 | self.__myprint(" done\n", silent)
|
513 | 511 |
|
— | — | @@ -514,7 +512,7 @@ |
515 | 513 | return struct.unpack("<IIII", response[:0x10]).extend(response[0x10 : 0x10 + struct.unpack("<IIII", response[:0x10])[1]])
|
516 | 514 |
|
517 | 515 |
|
518 | | - def writeusbcon(self, data, *range, silent = 0):
|
| 516 | + def writeusbcon(self, data, silent = 0, *range):
|
519 | 517 | """ writes to USB console
|
520 | 518 | <data>: the data to be written
|
521 | 519 | <range>: the range in <data> that should be written, in the from [offset, length]
|
— | — | @@ -571,7 +569,7 @@ |
572 | 570 | if (freeze):
|
573 | 571 | self.__myprint("Freezing scheduler...", silent)
|
574 | 572 | freeze = 1
|
575 | | - else
|
| 573 | + else:
|
576 | 574 | self.__myprint("Unfreezing scheduler...", silent)
|
577 | 575 | freeze = 0
|
578 | 576 |
|
— | — | @@ -586,7 +584,7 @@ |
587 | 585 | if (suspend):
|
588 | 586 | self.__myprint("Suspending thread 0x%8x...", silent) % threadid
|
589 | 587 | suspend = 1
|
590 | | - else
|
| 588 | + else:
|
591 | 589 | self.__myprint("Unsuspending thread 0x%8x...", silent) % threadid
|
592 | 590 | suspend = 0
|
593 | 591 |
|
— | — | @@ -614,7 +612,10 @@ |
615 | 613 | response = self.__getbulk(self.handle, self.__cinep, 0x10)
|
616 | 614 | self.__checkstatus(response)
|
617 | 615 |
|
618 | | - self.__myprint(" done\n", silent)
|
| 616 | + if (struct.unpack("<i", response[4:8]) < 0):
|
| 617 | + self.__myprint(" failed, error code: 0x%x" % (struct.unpack("<i", response[4:8])), silent)
|
| 618 | + else:
|
| 619 | + self.__myprint(" done\n, thread ID: 0x%x" % (struct.unpack("<I", response[4:8])), silent)
|
619 | 620 |
|
620 | 621 |
|
621 | 622 | def getprocinfo(self, offset, size, silent = 0):
|
— | — | @@ -622,10 +623,7 @@ |
623 | 624 | printout on console window:
|
624 | 625 | <silent> = 0: Process information struct version, Process information table size
|
625 | 626 | <silent> = 1: nothing
|
626 | | - <silent> = 2: Process information struct version, Process information table size, hexview of the data
|
627 | | -
|
628 | | -
|
629 | | -
|
| 627 | +
|
630 | 628 | {'regs': [16I], 'cpsr': I, 'state': I, 'namepointer': I, 'cputime_current': I, 'cputime_total': Q, 'startusec': I,
|
631 | 629 | 'queue_next_pointer': I, 'timeout': I, 'blocked_since': I, 'blocked_by_pointer': I, 'stackpointer': I, 'block_type': B, 'thread_type': B, 'priority': B, 'cpuload': B}
|
632 | 630 | """
|
— | — | @@ -640,23 +638,20 @@ |
641 | 639 |
|
642 | 640 | out = []
|
643 | 641 | out[0] = struct.unpack("<I", response[4:8])[0] # Process information struct version
|
644 | | - out[0] = struct.unpack("<I", response[4:8])[0] # Process information table size
|
| 642 | + out[1] = struct.unpack("<I", response[4:8])[0] # Process information table size
|
645 | 643 |
|
646 | 644 | if (struct.unpack("<I", response[4:8])[0] == 1): # Process information struct version == 1
|
647 | 645 | p = 0x10
|
648 | | - process_n = 0
|
| 646 | + process_n = 2 # actually process 0, but there are alread two other elements in out
|
649 | 647 | while True:
|
650 | 648 | # regs ==================================================
|
651 | 649 | keylen = 16
|
652 | 650 | key_offset = 0
|
653 | 651 |
|
654 | | - while (offset > 0) and (keylen > 0):
|
| 652 | + while (offset > 0) and (key_offset < 0x10):
|
655 | 653 | offset -= 0x4
|
656 | | - out[process_n]['regs'][16 - keylen] = None
|
657 | | - keylen -= 1
|
| 654 | + out[process_n]['regs'][key_offset] = None
|
658 | 655 | key_offset += 1
|
659 | | -
|
660 | | - if (offset < 1): offset = 0
|
661 | 656 |
|
662 | 657 | while (p+(keylen*0x4) - 0x10 > size) and (keylen > 0): keylen -= 1
|
663 | 658 | if (p+(keylen*0x4) - 0x10 > size): break
|
— | — | @@ -663,6 +658,7 @@ |
664 | 659 |
|
665 | 660 | while (key_offset < keylen):
|
666 | 661 | out[process_n]['regs'][key_offset] = struct.unpack("<I", response[p + (key_offset * 0x4) :])[0]
|
| 662 | + key_offset += 1
|
667 | 663 |
|
668 | 664 | p += 16 * 0x4
|
669 | 665 |
|
— | — | @@ -834,12 +830,8 @@ |
835 | 831 | process_n += 1
|
836 | 832 |
|
837 | 833 |
|
838 | | - if (silent == 2):
|
839 | | - hexprint = self.__gethexviewprintout(response[0x10:], "Requested data", 1)
|
840 | | - silent = 0
|
841 | | - else:
|
842 | | - hexprint = ""
|
843 | 834 |
|
| 835 | +
|
844 | 836 | self.__myprint(" done\n\
|
845 | 837 | Process information struct version: 0x%8x\n\
|
846 | 838 | Total size of process information table: 0x%8x\n\
|