Subversion Repositories freemyipod

Rev

Rev 174 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 174 Rev 176
Line 23... Line 23...
23
 
23
 
24
import sys
24
import sys
25
import os
25
import os
26
import inspect
26
import inspect
27
import re
27
import re
-
 
28
import time
-
 
29
 
-
 
30
from functools import wraps
28
 
31
 
29
import libembios
32
import libembios
30
from libembios import Error
33
from libembios import Error
31
import libembiosdata
34
import libembiosdata
32
 
35
 
Line 142... Line 145...
142
def command(func):
145
def command(func):
143
    """
146
    """
144
        Decorator for all commands.
147
        Decorator for all commands.
145
        The decorated function is called with (self, all, other, arguments, ...)
148
        The decorated function is called with (self, all, other, arguments, ...)
146
    """
149
    """
-
 
150
    @wraps(func)
147
    def decorator(*args):
151
    def decorator(*args):
148
        return func(args[0], *args[1:])
152
        return func(args[0], *args[1:])
149
    func._command = True
153
    func._command = True
150
    decorator.func = func
154
    decorator.func = func
151
    return decorator
155
    return decorator
Line 177... Line 181...
177
        self.logger = Logger()
181
        self.logger = Logger()
178
        try:
182
        try:
179
            self.embios = libembios.Embios()
183
            self.embios = libembios.Embios()
180
        except libembios.DeviceNotFoundError:
184
        except libembios.DeviceNotFoundError:
181
            self.logger.error("No emBIOS device found!")
185
            self.logger.error("No emBIOS device found!")
182
            end(1)
186
            exit(1)
183
        try:
-
 
184
            self.getinfo("version")
187
        self.getinfo("version")
185
        except libembios.DeviceNotFoundError:
-
 
186
                self.logger.error("Device not found!")
-
 
187
                exit(2)
-
 
188
        
188
        
189
    def _parsecommand(self, func, args):
189
    def _parsecommand(self, func, args):
190
        # adds self to the commandline args.
190
        # adds self to the commandline args.
191
        # this is needed because the functions need access to their class.
191
        # this is needed because the functions need access to their class.
192
        args.insert(0, self)
192
        args.insert(0, self)
193
        if func in self.cmddict:
193
        if func in self.cmddict:
194
            try:
194
            try:
195
                self.cmddict[func](*args)
195
                self.cmddict[func](*args)
196
            except ArgumentError, e:
196
            except ArgumentError, e:
197
                usage(e)
197
                usage(e, specific=func)
198
            except ArgumentError:
198
            except ArgumentError:
199
                usage("Syntax Error in function '" + func + "'")
199
                usage("Syntax Error in function '" + func + "'", specific=func)
200
            except ArgumentTypeError, e:
200
            except ArgumentTypeError, e:
201
                usage(e)
201
                usage(e, specific=func)
202
            except NotImplementedError:
202
            except NotImplementedError:
203
                self.logger.error("This function is not implemented yet!")
203
                self.logger.error("This function is not implemented yet!")
204
            except libembios.DeviceError, e:
204
            except libembios.DeviceError, e:
205
                self.logger.error(str(e))
205
                self.logger.error(str(e))
-
 
206
            except ValueError:
-
 
207
                usage(specific=func)
206
            except TypeError, e:
208
            except TypeError, e:
207
                if str(e).split(" ", 1)[0] == func + "()":
209
                if str(e).split(" ", 1)[0] == func + "()":
208
                    self.logger.error(usage("Argument Error in '" + func + "': Wrong argument count", specific=func))
210
                    self.logger.error(usage("Argument Error in '" + func + "': Wrong argument count", specific=func))
209
                else:
211
                else:
210
                    raise
212
                    raise
-
 
213
            except libembios.usb.core.USBError:
-
 
214
                self.logger.error("Problem with USB connection.")
211
        else:
215
        else:
212
            usage("No such command")
216
            usage("No such command")
213
    
217
    
214
    @staticmethod
218
    @staticmethod
215
    def _bool(something):
219
    def _bool(something):
Line 320... Line 324...
320
            raise ArgumentError("File not readable. Does it exist?")
324
            raise ArgumentError("File not readable. Does it exist?")
321
        self.logger.info("Writing file '"+filename+"' to memory at "+self._hex(addr)+"...")
325
        self.logger.info("Writing file '"+filename+"' to memory at "+self._hex(addr)+"...")
322
        with f:
326
        with f:
323
            self.embios.write(addr, f.read())
327
            self.embios.write(addr, f.read())
324
        self.logger.info("done\n")
328
        self.logger.info("done\n")
325
        
-
 
326
        
329
    
327
 
-
 
328
    @command
330
    @command
329
    def downloadfile(self, addr, size, filename):
331
    def downloadfile(self, addr, size, filename):
330
        """
332
        """
331
            Uploads a file to the device
333
            Uploads a file to the device
332
            <offset>: the address to upload the file to
334
            <offset>: the address to upload the file to
Line 369... Line 371...
369
        data = self.embios.readmem(addr, 1)
371
        data = self.embios.readmem(addr, 1)
370
        integer = ord(data)
372
        integer = ord(data)
371
        self.logger.info("Integer '"+self._hex(integer)+"' read from address "+self._hex(addr))
373
        self.logger.info("Integer '"+self._hex(integer)+"' read from address "+self._hex(addr))
372
 
374
 
373
    @command
375
    @command
374
    def i2crecv(self, bus, slave, addr, size):
376
    def i2cread(self, bus, slave, addr, size):
375
        """
377
        """
376
            Reads data from an I2C device
378
            Reads data from an I2C device
377
            <bus> the bus index
379
            <bus> the bus index
378
            <slave> the slave address
380
            <slave> the slave address
379
            <addr> the start address on the I2C device
381
            <addr> the start address on the I2C device
Line 381... Line 383...
381
        """
383
        """
382
        bus = self._hexint(bus)
384
        bus = self._hexint(bus)
383
        slave = self._hexint(slave)
385
        slave = self._hexint(slave)
384
        addr = self._hexint(addr)
386
        addr = self._hexint(addr)
385
        size = self._hexint(size)
387
        size = self._hexint(size)
386
        raise NotImplementedError
388
        self.embios.i2cread(bus, slave, addr, size)
387
 
389
 
388
    @command
390
    @command
389
    def i2csend(self, bus, slave, addr, *args):
391
    def i2cwrite(self, bus, slave, addr, *args):
390
        """
392
        """
391
            Writes data to an I2C device
393
            Writes data to an I2C device
392
            <bus> the bus index
394
            <bus> the bus index
393
            <slave> the slave address
395
            <slave> the slave address
394
            <addr> the start address on the I2C device
396
            <addr> the start address on the I2C device
395
            <db1> ... <dbN> the data in single bytes, seperated by whitespaces,
397
            <db1> ... <dbN> the data in single bytes, encoded in hex,
396
                eg. 0x37 0x56 0x45 0x12
398
                seperated by whitespaces, eg. 37 56 45 12
397
        """
399
        """
398
        bus = self._hexint(bus)
400
        bus = self._hexint(bus)
399
        slave = self._hexint(slave)
401
        slave = self._hexint(slave)
400
        addr = self._hexint(addr)
402
        addr = self._hexint(addr)
401
        data = []
403
        data = ""
402
        for arg in args:
404
        for arg in args:
403
            data.append(self._hexint(arg))
405
            data += chr(self._hexint(arg))
404
        raise NotImplementedError
-
 
405
 
-
 
406
    @command
-
 
407
    def readusbconsole(self, size, outtype):
-
 
408
        """
-
 
409
            Reads data from the USB console.
-
 
410
            <size>: the number of bytes to read
-
 
411
            <outtype>: defines how to output the result:
-
 
412
                'file': writes the result to file <file>
406
        self.embios.i2cwrite(bus, slave, addr, data)
413
                'printstring': writes the result as string to the console window
-
 
414
                'printhex': writes the result in hexedit notation to the console window
-
 
415
            <file>: the file to write the result to, can be omitted
-
 
416
                if <outtype> is not 'file'
-
 
417
        """
-
 
418
        size = self._hexint(size)
-
 
419
        raise NotImplementedError
-
 
420
        
-
 
421
 
407
 
422
    @command
408
    @command
423
    def writeusbconsole_file(self, file, offset=0, length=None):
409
    def console(self):
424
        """
410
        """
425
            Writes the file <file> to the USB console.
411
            Reads data from the USB console continuously
426
            Optional params <offset> <length>: specify the range in <file> to write
-
 
427
        """
412
        """
428
        
413
        while True:
429
        offset = self._hexint(offset)
414
            resp = self.embios.usbcread()
430
        length = self._hexint(length)
415
            self.logger.log(resp.data)
431
        raise NotImplementedError
416
            time.sleep(0.1 / resp.maxsize * (resp.maxsize - len(resp.data)))
432
 
417
 
433
    @command
418
    @command
434
    def writeusbconsole_direct(self, *args):
419
    def writeusbconsole(self, *args):
435
        """
420
        """
436
            Writes the strings <db1> ... <dbN> to the USB console."
421
            Writes the string <db1> ... <dbN> to the USB console.
437
        """
422
        """
-
 
423
        text = ""
-
 
424
        for word in args:
-
 
425
            text += word + " "
-
 
426
        text = text[:-1]
-
 
427
        self.logger.info("Writing '"+text+"' to the usb console\n")
438
        raise NotImplementedError
428
        self.embios.usbcwrite(text)
439
 
429
 
440
    @command
430
    @command
441
    def readdevconsole(self, bitmask, size, outtype, file=None):
431
    def readdevconsole(self, bitmask):
442
        """
432
        """
443
            Reads data from one or more of the device's consoles.
433
            Reads data continuously from one or more of the device's consoles.
444
            <bitmask>: the bitmask of the consoles to read from
434
            <bitmask>: the bitmask of the consoles to read from.
445
            <size>: the number of bytes to read
-
 
446
            <outtype>: defines how to output the result:
-
 
447
                'file': writes the result to file <file>
-
 
448
                'printstring': writes the result as string to the console window
-
 
449
                'printhex': writes the result in hexedit notation to the console window
-
 
450
            <file>: the file to write the result to, can be omitted
-
 
451
                if <outtype> is not 'file'
-
 
452
        """
435
        """
453
        bitmask = self._hexint(bitmask)
436
        bitmask = self._hexint(bitmask)
454
        size = self._hexint(size)
437
        while True:
455
        outtype = self._strcheck(['file', 'printstring', 'printhex'])
438
            resp = self.embios.cread()
456
        raise NotImplementedError
439
            self.logger.log(resp.data)
-
 
440
            time.sleep(0.1 / resp.maxsize * (resp.maxsize - len(resp.data)))
457
 
441
    
458
    @command
442
    @command
459
    def writedevconsole_file(self, bitmask, file, offset=0, length=None):
443
    def writedevconsole(self, bitmask, *args):
460
        """
444
        """
461
            Writes the file <file> to the device consoles specified by <bitmask>
445
            Writes the string <db1> ... <dbN> to one or more of the device's consoles.
462
            Optional params <offset> <length>: specify the range in <file> to write
446
            <bitmask>: the bitmask of the consoles to write to
463
        """
447
        """
464
        bitmask = self._hexint(bitmask)
448
        bitmask = self._hexint(bitmask)
465
        
-
 
466
        offset = self._hexint(offset)
-
 
467
        length = self._hexint(length)
-
 
468
        raise NotImplementedError
-
 
469
 
-
 
470
    @command
-
 
471
    def writedevconsole_direct(self, bitmask, *args):
-
 
472
        """
449
        text = ""
473
            Writes the integers <db1> ... <dbN> to the device consoles specified
-
 
474
            by <bitmask>
450
        for word in args:
475
        """
-
 
476
        bitmask = self._hexint(bitmask)
451
            text += word + " "
477
        data = []
452
        text = text[:-1]
478
        for arg in args:
-
 
479
            data.append(self._hexint(arg))
453
        self.logger.info("Writing '"+text+"' to the device consoles identified with "+self._hex(bitmask)+"\n")
480
        raise NotImplementedError
454
        self.embios.cwrite(text, bitmask)
481
 
455
 
482
    @command
456
    @command
483
    def flushconsolebuffers(self, bitmask):
457
    def flushconsolebuffers(self, bitmask):
484
        """
458
        """
485
            flushes one or more of the device consoles' buffers.
459
            flushes one or more of the device consoles' buffers.
Line 513... Line 487...
513
    @command
487
    @command
514
    def lockscheduler(self):
488
    def lockscheduler(self):
515
        """
489
        """
516
            Locks (freezes) the scheduler
490
            Locks (freezes) the scheduler
517
        """
491
        """
-
 
492
        self.logger.info("Will now lock scheduler\n")
518
        self.embios.lockscheduler()
493
        self.embios.lockscheduler()
519
 
494
 
520
    @command
495
    @command
521
    def unlockscheduler(self):
496
    def unlockscheduler(self):
522
        """
497
        """
523
            Unlocks (unfreezes) the scheduler
498
            Unlocks (unfreezes) the scheduler
524
        """
499
        """
-
 
500
        self.logger.info("Will now unlock scheduler\n")
525
        self.embios.unlockscheduler()
501
        self.embios.unlockscheduler()
526
 
502
 
527
    @command
503
    @command
528
    def suspendthread(self, threadid):
504
    def suspendthread(self, threadid):
529
        """
505
        """
Line 571... Line 547...
571
    def run(self, filename):
547
    def run(self, filename):
572
        """
548
        """
573
            Uploads the emBIOS application <filename> to
549
            Uploads the emBIOS application <filename> to
574
            the beginning of the user memory and executes it
550
            the beginning of the user memory and executes it
575
        """
551
        """
576
        try:
-
 
577
            f = open(filename, "rb")
-
 
578
        except IOError:
-
 
579
            raise ArgumentError("File not readable. Does it exist?")
-
 
580
        data = self.embios.getusermemrange()
-
 
581
        addr = data.lower
-
 
582
        maxsize = data.upper - data.lower
-
 
583
        filesize = os.path.getsize(filename)
-
 
584
        if filesize > maxsize:
-
 
585
            raise ArgumentError("The file is too big, it doesn't fit into the user memory.")
-
 
586
        self.logger.info("Uploading application to "+self._hex(addr)+" - "+self._hex(addr+filesize)+"\n")
-
 
587
        self.embios.write(addr, f.read())
552
        #self.execimage(addr)
588
        self.execimage(addr)
553
        raise NotImplementedError
589
 
554
 
590
    @command
555
    @command
591
    def execimage(self, addr):
556
    def execimage(self, addr):
592
        """
557
        """
593
            Executes the emBIOS application at <addr>.
558
            Executes the emBIOS application at <addr>.
594
        """
559
        """
595
        addr = self._hexint(addr)
560
        addr = self._hexint(addr)
596
        self.logger.info("Starting emBIOS app at "+self._hex(addr)+"\n")
561
        self.logger.info("Starting emBIOS app at "+self._hex(addr)+"\n")
597
        self.embios.execimage(addr)
562
        self.embios.execimage(addr)
598
 
563
    
-
 
564
    @command
-
 
565
    def flushcaches(self):
-
 
566
        """
-
 
567
            Flushes the CPUs data and instruction caches.
-
 
568
        """
-
 
569
        self.logger.info("Flushing CPU data and instruction caches...")
-
 
570
        self.embios.flushcaches()
-
 
571
        self.logger.info("done\n")
-
 
572
    
599
    @command
573
    @command
600
    def readrawbootflash(self, addr_flash, addr_mem, size):
574
    def readbootflash(self, addr_flash, addr_mem, size):
601
        """
575
        """
602
            Reads <size> bytes from bootflash to memory.
576
            Reads <size> bytes from bootflash to memory.
603
            <addr_bootflsh>: the address in bootflash to read from
577
            <addr_bootflsh>: the address in bootflash to read from
604
            <addr_mem>: the address in memory to copy the data to
578
            <addr_mem>: the address in memory to copy the data to
605
        """
579
        """
Line 607... Line 581...
607
        addr_mem = self._hexint(addr_mem)
581
        addr_mem = self._hexint(addr_mem)
608
        size = self._hexint(size)
582
        size = self._hexint(size)
609
        self.logger.info("Dumping boot flash addresses "+self._hex(addr_flash)+" - "+
583
        self.logger.info("Dumping boot flash addresses "+self._hex(addr_flash)+" - "+
610
                         hex(addr_flash+size)+" to "+self._hex(addr_mem)+" - "+self._hex(addr_mem+size)+"\n")
584
                         hex(addr_flash+size)+" to "+self._hex(addr_mem)+" - "+self._hex(addr_mem+size)+"\n")
611
        self.embios.bootflashread(addr_flash, addr_mem, size)
585
        self.embios.bootflashread(addr_flash, addr_mem, size)
612
 
586
    
613
    @command
587
    @command
614
    def writerawbootflash(self, addr_flash, addr_mem, size, force=False):
588
    def writebootflash(self, addr_flash, addr_mem, size, force=False):
615
        """
589
        """
616
            Writes <size> bytes from memory to bootflash.
590
            Writes <size> bytes from memory to bootflash.
617
            ATTENTION: Don't call this unless you really know what you're doing!
591
            ATTENTION: Don't call this unless you really know what you're doing!
618
            This may BRICK your device (unless it has a good recovery option)
592
            This may BRICK your device (unless it has a good recovery option)
619
            <addr_mem>: the address in memory to copy the data from
593
            <addr_mem>: the address in memory to copy the data from
Line 626... Line 600...
626
        force = self._bool(force)
600
        force = self._bool(force)
627
        self.logger.info("Writing boot flash from the memory in "+self._hex(addr_mem)+" - "+
601
        self.logger.info("Writing boot flash from the memory in "+self._hex(addr_mem)+" - "+
628
                         hex(addr_mem+size)+" to "+self._hex(addr_flash)+" - "+self._hex(addr_flash+size)+"\n")
602
                         hex(addr_mem+size)+" to "+self._hex(addr_flash)+" - "+self._hex(addr_flash+size)+"\n")
629
        if force == False:
603
        if force == False:
630
            self.logger.info("If this was not what you intended press Ctrl-C NOW")
604
            self.logger.info("If this was not what you intended press Ctrl-C NOW")
631
            import time
-
 
632
            for i in range(5):
605
            for i in range(10):
633
                self.logger.info(".")
606
                self.logger.info(".")
634
                time.sleep(1)
607
                time.sleep(1)
635
            self.logger.info("\n")
608
            self.logger.info("\n")
636
        self.embios.bootflashwrite(addr_flash, addr_mem, size)
609
        self.embios.bootflashwrite(addr_flash, addr_mem, size)
637
 
610
    
638
    @command
611
    @command
639
    def flushcaches(self):
612
    def runfirmware(self, addr, filename):
640
        """
613
        """
-
 
614
            Uploads the firmware in 'filename' to the beginning of the
641
            Flushes the CPUs data and instruction caches.
615
            user memory and executes it
642
        """
616
        """
-
 
617
        addr = self._hexint(addr)
643
        self.logger.info("Flushing CPU data and instruction caches...")
618
        self.uploadfile(addr, filename)
644
        self.embios.flushcaches()
619
        self.execfirmware(addr)
-
 
620
    
-
 
621
    @command
-
 
622
    def execfirmware(self, addr):
-
 
623
        """
-
 
624
            Executes the firmware at addr
-
 
625
        """
-
 
626
        addr = self._hexint(addr)
-
 
627
        self.logger.info("Running firmware at "+self._hex(addr)+". Bye.")
645
        self.logger.info("done\n")
628
        self.embios.execfirmware(addr)
646
    
629
    
647
    @command
630
    @command
648
    def aesencrypt(self, addr, size, keyindex):
631
    def aesencrypt(self, addr, size, keyindex):
649
        """
632
        """
650
            Encrypts a buffer using a hardware key
633
            Encrypts a buffer using a hardware key