| 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\ |