freemyipod r64 - Code Review

Jump to: navigation, search
Repository:freemyipod
Revision:r63‎ | r64 | r65 >
Date:13:59, 9 August 2010
Author:benedikt93
Status:new
Tags:
Comment:
fix libembios.py, add embios.py
Modified paths:
  • /embios/trunk/tools/embios.py (added) (history)
  • /embios/trunk/tools/libembios.py (modified) (history)

Diff [purge]

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 @@
6060 self.handle = handle
6161 self.dev = dev
6262
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]
6464 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, \
6666 self.devtype2name(self.devtype), dev.deviceVersion))
6767
6868 # get packet size info
@@ -86,18 +86,18 @@
8787
8888
8989 @staticmethod
90 - def __gethexviewprintout(data, title, showaddr)
 90+ def __gethexviewprintout(data, title, showaddr):
9191 printout_temp = struct.unpack("%dB" % (len(data)), data)
9292
93 - printout_temp = title + ":\n"
 93+ printout = title + ":\n"
9494 pointer = 0
9595 pointer2 = 0
9696
97 - while (pointer < printout_temp.size):
 97+ while (pointer < len(printout_temp)):
9898 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]))
102102 pointer += 1
103103 pointer2 += 1
104104 printout += "\n"
@@ -157,7 +157,7 @@
158158
159159 i = struct.unpack("<IIBBBBI", response)
160160
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]
162162
163163 self.__myprint("emBIOS %s v%d.%d.%d (SVN revision: %d) on %s, USB version %s\n" \
164164 % (self.type2name(self.type), self.major, self.minor, self.patch, self.svnrev, \
@@ -301,7 +301,7 @@
302302 while (size > 0):
303303 blocklen = size
304304
305 - if (blocklen > self.cout_maxsize - 0x10)
 305+ if (blocklen > self.cout_maxsize - 0x10):
306306 blocklen = self.cout_maxsize
307307
308308 self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 5, offset, blocklen, 0) + data[boffset:boffset+blocklen])
@@ -364,7 +364,7 @@
365365 while (size > 0):
366366 blocklen = size
367367
368 - if (blocklen > self.cin_maxsize - 0x10)
 368+ if (blocklen > self.cin_maxsize - 0x10):
369369 blocklen = self.cin_maxsize
370370
371371 self.handle.bulkWrite(self.__coutep, struct.pack("<IIII", 4, offset, blocklen, 0))
@@ -488,7 +488,7 @@
489489 elif (outtype == "printstring"):
490490 self.__myprint("\nBytes read: 0x%x\nOn-device buffersize: 0x%x\nBytes still in device's buffer: 0x%x\n\n"\
491491 % (struct.unpack("<IIII", response[:0x10])[1],
492 - struct.unpack("<IIII", response[:0x10])[2]
 492+ struct.unpack("<IIII", response[:0x10])[2],
493493 struct.unpack("<IIII", response[:0x10])[3])
494494 , silent)
495495 self.__myprint(response[0x10 : 0x10 + struct.unpack("<IIII", response[:0x10])[1]], silent)
@@ -497,16 +497,14 @@
498498 elif (outtype == "printhex"):
499499 self.__myprint("\nBytes read: 0x%x\nOn-device buffersize: 0x%x\nBytes still in device's buffer: 0x%x\n\n"\
500500 % (struct.unpack("<IIII", response[:0x10])[1],
501 - struct.unpack("<IIII", response[:0x10])[2]
 501+ struct.unpack("<IIII", response[:0x10])[2],
502502 struct.unpack("<IIII", response[:0x10])[3])
503503 , silent)
504504 self.__myprint(self.gethexviewprintout(response[0x10:], "", 1), silent)
505505 self.__myprint("\n\n", silent)
506506
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))
511509
512510 self.__myprint(" done\n", silent)
513511
@@ -514,7 +512,7 @@
515513 return struct.unpack("<IIII", response[:0x10]).extend(response[0x10 : 0x10 + struct.unpack("<IIII", response[:0x10])[1]])
516514
517515
518 - def writeusbcon(self, data, *range, silent = 0):
 516+ def writeusbcon(self, data, silent = 0, *range):
519517 """ writes to USB console
520518 <data>: the data to be written
521519 <range>: the range in <data> that should be written, in the from [offset, length]
@@ -571,7 +569,7 @@
572570 if (freeze):
573571 self.__myprint("Freezing scheduler...", silent)
574572 freeze = 1
575 - else
 573+ else:
576574 self.__myprint("Unfreezing scheduler...", silent)
577575 freeze = 0
578576
@@ -586,7 +584,7 @@
587585 if (suspend):
588586 self.__myprint("Suspending thread 0x%8x...", silent) % threadid
589587 suspend = 1
590 - else
 588+ else:
591589 self.__myprint("Unsuspending thread 0x%8x...", silent) % threadid
592590 suspend = 0
593591
@@ -614,7 +612,10 @@
615613 response = self.__getbulk(self.handle, self.__cinep, 0x10)
616614 self.__checkstatus(response)
617615
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)
619620
620621
621622 def getprocinfo(self, offset, size, silent = 0):
@@ -622,10 +623,7 @@
623624 printout on console window:
624625 <silent> = 0: Process information struct version, Process information table size
625626 <silent> = 1: nothing
626 - <silent> = 2: Process information struct version, Process information table size, hexview of the data
627 -
628 -
629 -
 627+
630628 {'regs': [16I], 'cpsr': I, 'state': I, 'namepointer': I, 'cputime_current': I, 'cputime_total': Q, 'startusec': I,
631629 '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}
632630 """
@@ -640,23 +638,20 @@
641639
642640 out = []
643641 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
645643
646644 if (struct.unpack("<I", response[4:8])[0] == 1): # Process information struct version == 1
647645 p = 0x10
648 - process_n = 0
 646+ process_n = 2 # actually process 0, but there are alread two other elements in out
649647 while True:
650648 # regs ==================================================
651649 keylen = 16
652650 key_offset = 0
653651
654 - while (offset > 0) and (keylen > 0):
 652+ while (offset > 0) and (key_offset < 0x10):
655653 offset -= 0x4
656 - out[process_n]['regs'][16 - keylen] = None
657 - keylen -= 1
 654+ out[process_n]['regs'][key_offset] = None
658655 key_offset += 1
659 -
660 - if (offset < 1): offset = 0
661656
662657 while (p+(keylen*0x4) - 0x10 > size) and (keylen > 0): keylen -= 1
663658 if (p+(keylen*0x4) - 0x10 > size): break
@@ -663,6 +658,7 @@
664659
665660 while (key_offset < keylen):
666661 out[process_n]['regs'][key_offset] = struct.unpack("<I", response[p + (key_offset * 0x4) :])[0]
 662+ key_offset += 1
667663
668664 p += 16 * 0x4
669665
@@ -834,12 +830,8 @@
835831 process_n += 1
836832
837833
838 - if (silent == 2):
839 - hexprint = self.__gethexviewprintout(response[0x10:], "Requested data", 1)
840 - silent = 0
841 - else:
842 - hexprint = ""
843834
 835+
844836 self.__myprint(" done\n\
845837 Process information struct version: 0x%8x\n\
846838 Total size of process information table: 0x%8x\n\