Subversion Repositories freemyipod

Rev

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

Rev 424 Rev 427
Line 2... Line 2...
2
#
2
#
3
#
3
#
4
#    Copyright 2010 TheSeven, benedikt93, Farthen
4
#    Copyright 2010 TheSeven, benedikt93, Farthen
5
#
5
#
6
#
6
#
7
#    This file is part of emBIOS.
7
#    This file is part of emCORE.
8
#
8
#
9
#    emBIOS is free software: you can redistribute it and/or
9
#    emCORE is free software: you can redistribute it and/or
10
#    modify it under the terms of the GNU General Public License as
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
11
#    published by the Free Software Foundation, either version 2 of the
12
#    License, or (at your option) any later version.
12
#    License, or (at your option) any later version.
13
#
13
#
14
#    emBIOS is distributed in the hope that it will be useful,
14
#    emCORE is distributed in the hope that it will be useful,
15
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
16
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
#    See the GNU General Public License for more details.
17
#    See the GNU General Public License for more details.
18
#
18
#
19
#    You should have received a copy of the GNU General Public License
19
#    You should have received a copy of the GNU General Public License
20
#    along with emBIOS.  If not, see <http://www.gnu.org/licenses/>.
20
#    along with emCORE.  If not, see <http://www.gnu.org/licenses/>.
21
#
21
#
22
#
22
#
23
 
23
 
24
"""
24
"""
25
    Command line interface to communicate with emBIOS devices.
25
    Command line interface to communicate with emCORE devices.
26
    Run it without arguments to see usage information.
26
    Run it without arguments to see usage information.
27
"""
27
"""
28
 
28
 
29
import sys
29
import sys
30
import os
30
import os
Line 32... Line 32...
32
import struct
32
import struct
33
import locale
33
import locale
34
 
34
 
35
from functools import wraps
35
from functools import wraps
36
 
36
 
37
import libembios
37
import libemcore
38
import libembiosdata
38
import libemcoredata
39
from misc import Error, Logger, getfuncdoc, gethwname
39
from misc import Error, Logger, getfuncdoc, gethwname
40
 
40
 
41
 
41
 
42
class NotImplementedError(Error):
42
class NotImplementedError(Error):
43
    pass
43
    pass
Line 127... Line 127...
127
        without an error message.
127
        without an error message.
128
    """
128
    """
129
    def __init__(self):
129
    def __init__(self):
130
        self.logger = Logger()
130
        self.logger = Logger()
131
        try:
131
        try:
132
            self.embios = libembios.Embios(loglevel = 2)
132
            self.emcore = libemcore.Emcore(loglevel = 2)
133
        except libembios.DeviceNotFoundError:
133
        except libemcore.DeviceNotFoundError:
134
            self.logger.error("No emBIOS device found!")
134
            self.logger.error("No emCORE device found!")
135
            exit(1)
135
            exit(1)
136
        self.getinfo("version")
136
        self.getinfo("version")
137
        
137
        
138
    def _parsecommand(self, func, args):
138
    def _parsecommand(self, func, args):
139
        # adds self to the commandline args.
139
        # adds self to the commandline args.
140
        # this is needed because the functions need access to their class.
140
        # this is needed because the functions need access to their class.
141
        args.insert(0, self)
141
        args.insert(0, self)
142
        if func in self.cmddict:
142
        if func in self.cmddict:
143
            try:
143
            try:
144
                self.cmddict[func](*args)
144
                self.cmddict[func](*args)
145
            except (ArgumentError, libembios.ArgumentError), e:
145
            except (ArgumentError, libemcore.ArgumentError), e:
146
                usage(e, specific=func)
146
                usage(e, specific=func)
147
            except (ArgumentError, libembios.ArgumentError):
147
            except (ArgumentError, libemcore.ArgumentError):
148
                usage("Syntax Error in function '" + func + "'", specific=func)
148
                usage("Syntax Error in function '" + func + "'", specific=func)
149
            except ArgumentTypeError, e:
149
            except ArgumentTypeError, e:
150
                usage(e, specific=func)
150
                usage(e, specific=func)
151
            except NotImplementedError:
151
            except NotImplementedError:
152
                self.logger.error("This function is not implemented yet!")
152
                self.logger.error("This function is not implemented yet!")
153
            except libembios.DeviceError, e:
153
            except libemcore.DeviceError, e:
154
                self.logger.error(str(e))
154
                self.logger.error(str(e))
155
            except TypeError, e:
155
            except TypeError, e:
156
                # Only act on TypeErrors for the function we called, not on TypeErrors raised by another function.
156
                # Only act on TypeErrors for the function we called, not on TypeErrors raised by another function.
157
                if str(e).split(" ", 1)[0] == func + "()":
157
                if str(e).split(" ", 1)[0] == func + "()":
158
                    self.logger.error(usage("Argument Error in '" + func + "': Wrong argument count", specific=func))
158
                    self.logger.error(usage("Argument Error in '" + func + "': Wrong argument count", specific=func))
159
                else:
159
                else:
160
                    raise
160
                    raise
161
            except libembios.usb.core.USBError:
161
            except libemcore.usb.core.USBError:
162
                self.logger.error("There is a problem with the USB connection.")
162
                self.logger.error("There is a problem with the USB connection.")
163
        else:
163
        else:
164
            usage("No such command")
164
            usage("No such command")
165
    
165
    
166
    @staticmethod
166
    @staticmethod
Line 205... Line 205...
205
        return "0x%x" % integer
205
        return "0x%x" % integer
206
    
206
    
207
    @command
207
    @command
208
    def getinfo(self, infotype):
208
    def getinfo(self, infotype):
209
        """
209
        """
210
            Get info on the running emBIOS.
210
            Get info on the running emCORE.
211
            <infotype> may be either of 'version', 'packetsize', 'usermemrange'.
211
            <infotype> may be either of 'version', 'packetsize', 'usermemrange'.
212
        """
212
        """
213
        if infotype == "version":
213
        if infotype == "version":
214
            hwtype = gethwname(self.embios.lib.dev.hwtypeid)
214
            hwtype = gethwname(self.emcore.lib.dev.hwtypeid)
215
            self.logger.info("Connected to " + \
215
            self.logger.info("Connected to " + \
216
                             libembiosdata.swtypes[self.embios.lib.dev.swtypeid] + \
216
                             libemcoredata.swtypes[self.emcore.lib.dev.swtypeid] + \
217
                             " v" + str(self.embios.lib.dev.version.majorv) + \
217
                             " v" + str(self.emcore.lib.dev.version.majorv) + \
218
                             "." + str(self.embios.lib.dev.version.minorv) + \
218
                             "." + str(self.emcore.lib.dev.version.minorv) + \
219
                             "." + str(self.embios.lib.dev.version.patchv) + \
219
                             "." + str(self.emcore.lib.dev.version.patchv) + \
220
                             " r" + str(self.embios.lib.dev.version.revision) + \
220
                             " r" + str(self.emcore.lib.dev.version.revision) + \
221
                             " running on " + hwtype + "\n")
221
                             " running on " + hwtype + "\n")
222
        
222
        
223
        elif infotype == "packetsize":
223
        elif infotype == "packetsize":
224
            self.logger.info("Maximum packet sizes: \n command out: " + str(self.embios.lib.dev.packetsizelimit.cout) + \
224
            self.logger.info("Maximum packet sizes: \n command out: " + str(self.emcore.lib.dev.packetsizelimit.cout) + \
225
                             "\n command in: " + str(self.embios.lib.dev.packetsizelimit.cin) + \
225
                             "\n command in: " + str(self.emcore.lib.dev.packetsizelimit.cin) + \
226
                             "\n data in: " + str(self.embios.lib.dev.packetsizelimit.din) + \
226
                             "\n data in: " + str(self.emcore.lib.dev.packetsizelimit.din) + \
227
                             "\n data out: " + str(self.embios.lib.dev.packetsizelimit.dout))
227
                             "\n data out: " + str(self.emcore.lib.dev.packetsizelimit.dout))
228
        
228
        
229
        elif infotype == "usermemrange":
229
        elif infotype == "usermemrange":
230
            resp = self.embios.getusermemrange()
230
            resp = self.emcore.getusermemrange()
231
            self.logger.info("The user memory range is " + \
231
            self.logger.info("The user memory range is " + \
232
                             self._hex(self.embios.lib.dev.usermem.lower) + \
232
                             self._hex(self.emcore.lib.dev.usermem.lower) + \
233
                             " - " + \
233
                             " - " + \
234
                             self._hex(self.embios.lib.dev.usermem.upper - 1))
234
                             self._hex(self.emcore.lib.dev.usermem.upper - 1))
235
        
235
        
236
        else:
236
        else:
237
            raise ArgumentTypeError("one out of 'version', 'packetsize', 'usermemrange'", infotype)
237
            raise ArgumentTypeError("one out of 'version', 'packetsize', 'usermemrange'", infotype)
238
    
238
    
239
    @command
239
    @command
Line 244... Line 244...
244
            which may take some time.
244
            which may take some time.
245
        """
245
        """
246
        force = self._bool(force)
246
        force = self._bool(force)
247
        if force: self.logger.info("Resetting forcefully...\n")
247
        if force: self.logger.info("Resetting forcefully...\n")
248
        else: self.logger.info("Resetting...\n")
248
        else: self.logger.info("Resetting...\n")
249
        self.embios.reset(force)
249
        self.emcore.reset(force)
250
    
250
    
251
    @command
251
    @command
252
    def poweroff(self, force=False):
252
    def poweroff(self, force=False):
253
        """
253
        """
254
            Powers the device off
254
            Powers the device off
Line 256... Line 256...
256
            which may take some time.
256
            which may take some time.
257
        """
257
        """
258
        force = self._bool(force)
258
        force = self._bool(force)
259
        if force: self.logger.info("Powering off forcefully...\n")
259
        if force: self.logger.info("Powering off forcefully...\n")
260
        else: self.logger.info("Powering off...\n")
260
        else: self.logger.info("Powering off...\n")
261
        self.embios.poweroff(force)
261
        self.emcore.poweroff(force)
262
    
262
    
263
    @command
263
    @command
264
    def uploadfile(self, addr, filename):
264
    def uploadfile(self, addr, filename):
265
        """
265
        """
266
            Uploads a file to the device
266
            Uploads a file to the device
Line 273... Line 273...
273
        except IOError:
273
        except IOError:
274
            raise ArgumentError("File not readable. Does it exist?")
274
            raise ArgumentError("File not readable. Does it exist?")
275
        self.logger.info("Writing file '" + filename + \
275
        self.logger.info("Writing file '" + filename + \
276
                         "' to memory at " + self._hex(addr) + "...")
276
                         "' to memory at " + self._hex(addr) + "...")
277
        with f:
277
        with f:
278
            self.embios.write(addr, f.read())
278
            self.emcore.write(addr, f.read())
279
        f.close()
279
        f.close()
280
        self.logger.info("done\n")
280
        self.logger.info("done\n")
281
    
281
    
282
    @command
282
    @command
283
    def downloadfile(self, addr, size, filename):
283
    def downloadfile(self, addr, size, filename):
Line 295... Line 295...
295
            raise ArgumentError("Can not open file for write!")
295
            raise ArgumentError("Can not open file for write!")
296
        self.logger.info("Reading data from address " + self._hex(addr) + \
296
        self.logger.info("Reading data from address " + self._hex(addr) + \
297
                         " with the size " + self._hex(size) + \
297
                         " with the size " + self._hex(size) + \
298
                         " to '"+filename+"'...")
298
                         " to '"+filename+"'...")
299
        with f:
299
        with f:
300
            f.write(self.embios.read(addr, size))
300
            f.write(self.emcore.read(addr, size))
301
        f.close()
301
        f.close()
302
        self.logger.info("done\n")
302
        self.logger.info("done\n")
303
 
303
 
304
    @command
304
    @command
305
    def uploadint(self, addr, integer):
305
    def uploadint(self, addr, integer):
Line 311... Line 311...
311
        addr = self._hexint(addr)
311
        addr = self._hexint(addr)
312
        integer = self._hexint(integer)
312
        integer = self._hexint(integer)
313
        if integer > 0xFFFFFFFF:
313
        if integer > 0xFFFFFFFF:
314
            raise ArgumentError("Specified integer too long")
314
            raise ArgumentError("Specified integer too long")
315
        data = struct.pack("I", integer)
315
        data = struct.pack("I", integer)
316
        self.embios.write(addr, data)
316
        self.emcore.write(addr, data)
317
        self.logger.info("Integer '" + self._hex(integer) + \
317
        self.logger.info("Integer '" + self._hex(integer) + \
318
                         "' written successfully to " + self._hex(addr) + "\n")
318
                         "' written successfully to " + self._hex(addr) + "\n")
319
 
319
 
320
    @command
320
    @command
321
    def downloadint(self, addr):
321
    def downloadint(self, addr):
322
        """
322
        """
323
            Downloads a single integer from the device and prints it to the console window
323
            Downloads a single integer from the device and prints it to the console window
324
            <addr>: the address to download the integer from
324
            <addr>: the address to download the integer from
325
        """
325
        """
326
        addr = self._hexint(addr)
326
        addr = self._hexint(addr)
327
        data = self.embios.read(addr, 4)
327
        data = self.emcore.read(addr, 4)
328
        integer = struct.unpack("I", data)[0]
328
        integer = struct.unpack("I", data)[0]
329
        self.logger.info("Integer '" + self._hex(integer) + \
329
        self.logger.info("Integer '" + self._hex(integer) + \
330
                         "' read from address " + self._hex(addr) + "\n")
330
                         "' read from address " + self._hex(addr) + "\n")
331
 
331
 
332
    @command
332
    @command
Line 340... Line 340...
340
        """
340
        """
341
        bus = self._hexint(bus)
341
        bus = self._hexint(bus)
342
        slave = self._hexint(slave)
342
        slave = self._hexint(slave)
343
        addr = self._hexint(addr)
343
        addr = self._hexint(addr)
344
        size = self._hexint(size)
344
        size = self._hexint(size)
345
        data = self.embios.i2cread(bus, slave, addr, size)
345
        data = self.emcore.i2cread(bus, slave, addr, size)
346
        bytes = struct.unpack("%dB" % len(data), data)
346
        bytes = struct.unpack("%dB" % len(data), data)
347
        self.logger.info("Data read from I2C:\n")
347
        self.logger.info("Data read from I2C:\n")
348
        for index, byte in enumerate(bytes):
348
        for index, byte in enumerate(bytes):
349
            self.logger.info("%02X: %02X\n" % (index, byte))
349
            self.logger.info("%02X: %02X\n" % (index, byte))
350
 
350
 
Line 363... Line 363...
363
        addr = self._hexint(addr)
363
        addr = self._hexint(addr)
364
        data = ""
364
        data = ""
365
        for arg in args:
365
        for arg in args:
366
            data += chr(self._hexint(arg))
366
            data += chr(self._hexint(arg))
367
        self.logger.info("Writing data to I2C...\n")
367
        self.logger.info("Writing data to I2C...\n")
368
        self.embios.i2cwrite(bus, slave, addr, data)
368
        self.emcore.i2cwrite(bus, slave, addr, data)
369
        self.logger.info("done\n")
369
        self.logger.info("done\n")
370
 
370
 
371
    @command
371
    @command
372
    def console(self):
372
    def console(self):
373
        """
373
        """
374
            Reads data from the USB console continuously
374
            Reads data from the USB console continuously
375
        """
375
        """
376
        while True:
376
        while True:
377
            resp = self.embios.usbcread()
377
            resp = self.emcore.usbcread()
378
            self.logger.log(resp.data)
378
            self.logger.log(resp.data)
379
            time.sleep(0.1 / resp.maxsize * (resp.maxsize - len(resp.data)))
379
            time.sleep(0.1 / resp.maxsize * (resp.maxsize - len(resp.data)))
380
 
380
 
381
    @command
381
    @command
382
    def writeusbconsole(self, *args):
382
    def writeusbconsole(self, *args):
Line 386... Line 386...
386
        text = ""
386
        text = ""
387
        for word in args:
387
        for word in args:
388
            text += word + " "
388
            text += word + " "
389
        text = text[:-1]
389
        text = text[:-1]
390
        self.logger.info("Writing '"+ text +"' to the usb console\n")
390
        self.logger.info("Writing '"+ text +"' to the usb console\n")
391
        self.embios.usbcwrite(text)
391
        self.emcore.usbcwrite(text)
392
 
392
 
393
    @command
393
    @command
394
    def readdevconsole(self, bitmask):
394
    def readdevconsole(self, bitmask):
395
        """
395
        """
396
            Reads data continuously from one or more of the device's consoles.
396
            Reads data continuously from one or more of the device's consoles.
397
            <bitmask>: the bitmask of the consoles to read from.
397
            <bitmask>: the bitmask of the consoles to read from.
398
        """
398
        """
399
        bitmask = self._hexint(bitmask)
399
        bitmask = self._hexint(bitmask)
400
        while True:
400
        while True:
401
            resp = self.embios.cread()
401
            resp = self.emcore.cread()
402
            self.logger.log(resp.data)
402
            self.logger.log(resp.data)
403
            time.sleep(0.1 / resp.maxsize * (resp.maxsize - len(resp.data)))
403
            time.sleep(0.1 / resp.maxsize * (resp.maxsize - len(resp.data)))
404
    
404
    
405
    @command
405
    @command
406
    def writedevconsole(self, bitmask, *args):
406
    def writedevconsole(self, bitmask, *args):
Line 413... Line 413...
413
        for word in args:
413
        for word in args:
414
            text += word + " "
414
            text += word + " "
415
        text = text[:-1]
415
        text = text[:-1]
416
        self.logger.info("Writing '" + text + \
416
        self.logger.info("Writing '" + text + \
417
                         "' to the device consoles identified with " + self._hex(bitmask) + "\n")
417
                         "' to the device consoles identified with " + self._hex(bitmask) + "\n")
418
        self.embios.cwrite(text, bitmask)
418
        self.emcore.cwrite(text, bitmask)
419
 
419
 
420
    @command
420
    @command
421
    def flushconsolebuffers(self, bitmask):
421
    def flushconsolebuffers(self, bitmask):
422
        """
422
        """
423
            flushes one or more of the device consoles' buffers.
423
            flushes one or more of the device consoles' buffers.
424
            <bitmask>: the bitmask of the consoles to be flushed
424
            <bitmask>: the bitmask of the consoles to be flushed
425
        """
425
        """
426
        bitmask = self._hexint(bitmask)
426
        bitmask = self._hexint(bitmask)
427
        self.logger.info("Flushing consoles identified with the bitmask " + \
427
        self.logger.info("Flushing consoles identified with the bitmask " + \
428
                         self._hex(bitmask) + "\n")
428
                         self._hex(bitmask) + "\n")
429
        self.embios.cflush(bitmask)
429
        self.emcore.cflush(bitmask)
430
 
430
 
431
    @command
431
    @command
432
    def getprocinfo(self):
432
    def getprocinfo(self):
433
        """
433
        """
434
            Fetches data on the currently running processes
434
            Fetches data on the currently running processes
435
        """
435
        """
436
        import datetime
436
        import datetime
437
        threads = self.embios.getprocinfo()
437
        threads = self.emcore.getprocinfo()
438
        threadload = 0
438
        threadload = 0
439
        idleload = 0
439
        idleload = 0
440
        for thread in threads:
440
        for thread in threads:
441
            if thread.id != 0:
441
            if thread.id != 0:
442
                threadload += thread.cpuload / 255.
442
                threadload += thread.cpuload / 255.
Line 472... Line 472...
472
    def lockscheduler(self):
472
    def lockscheduler(self):
473
        """
473
        """
474
            Locks (freezes) the scheduler
474
            Locks (freezes) the scheduler
475
        """
475
        """
476
        self.logger.info("Will now lock scheduler\n")
476
        self.logger.info("Will now lock scheduler\n")
477
        self.embios.lockscheduler()
477
        self.emcore.lockscheduler()
478
    
478
    
479
    @command
479
    @command
480
    def unlockscheduler(self):
480
    def unlockscheduler(self):
481
        """
481
        """
482
            Unlocks (unfreezes) the scheduler
482
            Unlocks (unfreezes) the scheduler
483
        """
483
        """
484
        self.logger.info("Will now unlock scheduler\n")
484
        self.logger.info("Will now unlock scheduler\n")
485
        self.embios.unlockscheduler()
485
        self.emcore.unlockscheduler()
486
    
486
    
487
    @command
487
    @command
488
    def suspendthread(self, threadid):
488
    def suspendthread(self, threadid):
489
        """
489
        """
490
            Suspends/resumes the thread with thread ID <threadid>
490
            Suspends/resumes the thread with thread ID <threadid>
491
        """
491
        """
492
        threadid = self._hexint(threadid)
492
        threadid = self._hexint(threadid)
493
        self.logger.info("Suspending the thread with the threadid "+self._hex(threadid)+"\n")
493
        self.logger.info("Suspending the thread with the threadid "+self._hex(threadid)+"\n")
494
        self.embios.suspendthread(threadid)
494
        self.emcore.suspendthread(threadid)
495
 
495
 
496
    @command
496
    @command
497
    def resumethread(self, threadid):
497
    def resumethread(self, threadid):
498
        """
498
        """
499
            Resumes the thread with thread ID <threadid>
499
            Resumes the thread with thread ID <threadid>
500
        """
500
        """
501
        threadid = self._hexint(threadid)
501
        threadid = self._hexint(threadid)
502
        self.logger.info("Resuming the thread with the threadid "+self._hex(threadid)+"\n")
502
        self.logger.info("Resuming the thread with the threadid "+self._hex(threadid)+"\n")
503
        self.embios.resumethread(threadid)
503
        self.emcore.resumethread(threadid)
504
 
504
 
505
    @command
505
    @command
506
    def killthread(self, threadid):
506
    def killthread(self, threadid):
507
        """
507
        """
508
            Kills the thread with thread ID <threadid>
508
            Kills the thread with thread ID <threadid>
509
        """
509
        """
510
        threadid = self._hexint(threadid)
510
        threadid = self._hexint(threadid)
511
        self.logger.info("Killing the thread with the threadid " + self._hex(threadid) + "\n")
511
        self.logger.info("Killing the thread with the threadid " + self._hex(threadid) + "\n")
512
        self.embios.killthread(threadid)
512
        self.emcore.killthread(threadid)
513
 
513
 
514
    @command
514
    @command
515
    def createthread(self, nameptr, entrypoint, stackptr, stacksize, threadtype, priority, state):
515
    def createthread(self, nameptr, entrypoint, stackptr, stacksize, threadtype, priority, state):
516
        """
516
        """
517
            Creates a new thread and returns its thread ID
517
            Creates a new thread and returns its thread ID
Line 526... Line 526...
526
        nameptr = self._hexint(nameptr)
526
        nameptr = self._hexint(nameptr)
527
        entrypoint = self._hexint(entrypoint)
527
        entrypoint = self._hexint(entrypoint)
528
        stackpointer = self._hexint(stackpointer)
528
        stackpointer = self._hexint(stackpointer)
529
        stacksize = self._hexint(stacksize)
529
        stacksize = self._hexint(stacksize)
530
        priority = self._hexint(priority)
530
        priority = self._hexint(priority)
531
        data = self.embios.createthread(nameptr, entrypoint, stackptr, stacksize, type, priority, state)
531
        data = self.emcore.createthread(nameptr, entrypoint, stackptr, stacksize, type, priority, state)
532
        name = self.embios.readstring(nameptr)
532
        name = self.emcore.readstring(nameptr)
533
        self.logger.info("Created a thread with the threadid " + data.id + \
533
        self.logger.info("Created a thread with the threadid " + data.id + \
534
                         ", the name \"" + name + "\"" + \
534
                         ", the name \"" + name + "\"" + \
535
                         ", the entrypoint at " + self._hex(entrypoint) + \
535
                         ", the entrypoint at " + self._hex(entrypoint) + \
536
                         ", the stack at " + self._hex(stackpointer) + \
536
                         ", the stack at " + self._hex(stackpointer) + \
537
                         " with a size of " + self._hex(stacksize) + \
537
                         " with a size of " + self._hex(stacksize) + \
538
                         " and a priority of " + self._hex(priority) + "\n")
538
                         " and a priority of " + self._hex(priority) + "\n")
539
    
539
    
540
    @command
540
    @command
541
    def run(self, filename):
541
    def run(self, filename):
542
        """
542
        """
543
            Uploads the emBIOS application <filename> to
543
            Uploads the emCORE application <filename> to
544
            the memory and executes it
544
            the memory and executes it
545
        """
545
        """
546
        try:
546
        try:
547
            f = open(filename, 'rb')
547
            f = open(filename, 'rb')
548
        except IOError:
548
        except IOError:
549
            raise ArgumentError("File not readable. Does it exist?")
549
            raise ArgumentError("File not readable. Does it exist?")
550
        with f:
550
        with f:
551
            data = self.embios.run(f.read())
551
            data = self.emcore.run(f.read())
552
        self.logger.info("Executed emBIOS application \"" + data.name + "\" at address " + self._hex(data.baseaddr))
552
        self.logger.info("Executed emCORE application \"" + data.name + "\" at address " + self._hex(data.baseaddr))
553
 
553
 
554
    @command
554
    @command
555
    def execimage(self, addr):
555
    def execimage(self, addr):
556
        """
556
        """
557
            Executes the emBIOS application at <addr>.
557
            Executes the emCORE application at <addr>.
558
        """
558
        """
559
        addr = self._hexint(addr)
559
        addr = self._hexint(addr)
560
        self.logger.info("Starting emBIOS app at "+self._hex(addr)+"\n")
560
        self.logger.info("Starting emCORE app at "+self._hex(addr)+"\n")
561
        self.embios.execimage(addr)
561
        self.emcore.execimage(addr)
562
    
562
    
563
    @command
563
    @command
564
    def flushcaches(self):
564
    def flushcaches(self):
565
        """
565
        """
566
            Flushes the CPUs data and instruction caches.
566
            Flushes the CPUs data and instruction caches.
567
        """
567
        """
568
        self.logger.info("Flushing CPU data and instruction caches...")
568
        self.logger.info("Flushing CPU data and instruction caches...")
569
        self.embios.flushcaches()
569
        self.emcore.flushcaches()
570
        self.logger.info("done\n")
570
        self.logger.info("done\n")
571
    
571
    
572
    @command
572
    @command
573
    def readbootflash(self, addr_flash, addr_mem, size):
573
    def readbootflash(self, addr_flash, addr_mem, size):
574
        """
574
        """
Line 579... Line 579...
579
        addr_flash = self._hexint(addr_flash)
579
        addr_flash = self._hexint(addr_flash)
580
        addr_mem = self._hexint(addr_mem)
580
        addr_mem = self._hexint(addr_mem)
581
        size = self._hexint(size)
581
        size = self._hexint(size)
582
        self.logger.info("Dumping boot flash addresses "+self._hex(addr_flash)+" - "+
582
        self.logger.info("Dumping boot flash addresses "+self._hex(addr_flash)+" - "+
583
                         hex(addr_flash+size)+" to "+self._hex(addr_mem)+" - "+self._hex(addr_mem+size)+"\n")
583
                         hex(addr_flash+size)+" to "+self._hex(addr_mem)+" - "+self._hex(addr_mem+size)+"\n")
584
        self.embios.bootflashread(addr_mem, addr_flash, size)
584
        self.emcore.bootflashread(addr_mem, addr_flash, size)
585
    
585
    
586
    @command
586
    @command
587
    def writebootflash(self, addr_flash, addr_mem, size, force=False):
587
    def writebootflash(self, addr_flash, addr_mem, size, force=False):
588
        """
588
        """
589
            Writes <size> bytes from memory to bootflash.
589
            Writes <size> bytes from memory to bootflash.
Line 603... Line 603...
603
            self.logger.warn("If this was not what you intended press Ctrl-C NOW")
603
            self.logger.warn("If this was not what you intended press Ctrl-C NOW")
604
            for i in range(10):
604
            for i in range(10):
605
                self.logger.info(".")
605
                self.logger.info(".")
606
                time.sleep(1)
606
                time.sleep(1)
607
            self.logger.info("\n")
607
            self.logger.info("\n")
608
        self.embios.bootflashwrite(addr_mem, addr_flash, size)
608
        self.emcore.bootflashwrite(addr_mem, addr_flash, size)
609
    
609
    
610
    @command
610
    @command
611
    def runfirmware(self, addr, filename):
611
    def runfirmware(self, addr, filename):
612
        """
612
        """
613
            Uploads the firmware in <filename>
613
            Uploads the firmware in <filename>
Line 622... Line 622...
622
        """
622
        """
623
            Executes the firmware at <addr>
623
            Executes the firmware at <addr>
624
        """
624
        """
625
        addr = self._hexint(addr)
625
        addr = self._hexint(addr)
626
        self.logger.info("Running firmware at "+self._hex(addr)+". Bye.")
626
        self.logger.info("Running firmware at "+self._hex(addr)+". Bye.")
627
        self.embios.execfirmware(addr)
627
        self.emcore.execfirmware(addr)
628
    
628
    
629
    @command
629
    @command
630
    def aesencrypt(self, addr, size, keyindex):
630
    def aesencrypt(self, addr, size, keyindex):
631
        """
631
        """
632
            Encrypts a buffer using a hardware key
632
            Encrypts a buffer using a hardware key
Line 635... Line 635...
635
            <keyindex>: the index of the key in the crypto unit
635
            <keyindex>: the index of the key in the crypto unit
636
        """
636
        """
637
        addr = self._hexint(addr)
637
        addr = self._hexint(addr)
638
        size = self._hexint(size)
638
        size = self._hexint(size)
639
        keyindex = self._hexint(keyindex)
639
        keyindex = self._hexint(keyindex)
640
        self.embios.aesencrypt(addr, size, keyindex)
640
        self.emcore.aesencrypt(addr, size, keyindex)
641
    
641
    
642
    @command
642
    @command
643
    def aesdecrypt(self, addr, size, keyindex):
643
    def aesdecrypt(self, addr, size, keyindex):
644
        """
644
        """
645
            Decrypts a buffer using a hardware key
645
            Decrypts a buffer using a hardware key
Line 648... Line 648...
648
            <keyindex>: the index of the key in the crypto unit
648
            <keyindex>: the index of the key in the crypto unit
649
        """
649
        """
650
        addr = self._hexint(addr)
650
        addr = self._hexint(addr)
651
        size = self._hexint(size)
651
        size = self._hexint(size)
652
        keyindex = self._hexint(keyindex)
652
        keyindex = self._hexint(keyindex)
653
        self.embios.aesdecrypt(addr, size, keyindex)
653
        self.emcore.aesdecrypt(addr, size, keyindex)
654
    
654
    
655
    @command
655
    @command
656
    def hmac_sha1(self, addr, size, destination):
656
    def hmac_sha1(self, addr, size, destination):
657
        """
657
        """
658
            Generates a HMAC-SHA1 hash of the buffer
658
            Generates a HMAC-SHA1 hash of the buffer
Line 665... Line 665...
665
        destination = self._hexint(destination)
665
        destination = self._hexint(destination)
666
        sha1size = 0x14
666
        sha1size = 0x14
667
        self.logger.info("Generating hmac-sha1 hash from the buffer at " + self._hex(addr) + \
667
        self.logger.info("Generating hmac-sha1 hash from the buffer at " + self._hex(addr) + \
668
                         " with the size " + self._hex(size) + " and saving it to " + \
668
                         " with the size " + self._hex(size) + " and saving it to " + \
669
                         self._hex(destination) + " - " + self._hex(destination+sha1size) + "...")
669
                         self._hex(destination) + " - " + self._hex(destination+sha1size) + "...")
670
        self.embios.hmac_sha1(addr, size, destination)
670
        self.emcore.hmac_sha1(addr, size, destination)
671
        self.logger.info("done\n")
671
        self.logger.info("done\n")
672
        data = self.embios.read(destination, sha1size)
672
        data = self.emcore.read(destination, sha1size)
673
        hash = ord(data)
673
        hash = ord(data)
674
        self.logger.info("The generated hash is "+self._hex(hash))
674
        self.logger.info("The generated hash is "+self._hex(hash))
675
 
675
 
676
    @command
676
    @command
677
    def ipodnano2g_getnandinfo(self):
677
    def ipodnano2g_getnandinfo(self):
678
        """
678
        """
679
            Target-specific function: ipodnano2g
679
            Target-specific function: ipodnano2g
680
            Gathers some information about the NAND chip used
680
            Gathers some information about the NAND chip used
681
        """
681
        """
682
        data = self.embios.ipodnano2g_getnandinfo()
682
        data = self.emcore.ipodnano2g_getnandinfo()
683
        self.logger.info("NAND chip type: "         + self._hex(data["type"])+"\n")
683
        self.logger.info("NAND chip type: "         + self._hex(data["type"])+"\n")
684
        self.logger.info("Number of banks: "        + str(data["banks"])+"\n")
684
        self.logger.info("Number of banks: "        + str(data["banks"])+"\n")
685
        self.logger.info("Number of blocks: "       + str(data["blocks"])+"\n")
685
        self.logger.info("Number of blocks: "       + str(data["blocks"])+"\n")
686
        self.logger.info("Number of user blocks: "  + str(data["userblocks"])+"\n")
686
        self.logger.info("Number of user blocks: "  + str(data["userblocks"])+"\n")
687
        self.logger.info("Pages per block: "        + str(data["pagesperblock"]))
687
        self.logger.info("Pages per block: "        + str(data["pagesperblock"]))
Line 702... Line 702...
702
        count = self._hexint(count)
702
        count = self._hexint(count)
703
        doecc = self._bool(doecc)
703
        doecc = self._bool(doecc)
704
        checkempty = self._bool(checkempty)
704
        checkempty = self._bool(checkempty)
705
        self.logger.info("Reading " + self._hex(count) + " NAND pages starting at " + \
705
        self.logger.info("Reading " + self._hex(count) + " NAND pages starting at " + \
706
                         self._hex(start) + " to " + self._hex(addr) + "...")
706
                         self._hex(start) + " to " + self._hex(addr) + "...")
707
        self.embios.ipodnano2g_nandread(addr, start, count, doecc, checkempty)
707
        self.emcore.ipodnano2g_nandread(addr, start, count, doecc, checkempty)
708
        self.logger.info("done\n")
708
        self.logger.info("done\n")
709
 
709
 
710
    @command
710
    @command
711
    def ipodnano2g_nandwrite(self, addr, start, count, doecc=True):
711
    def ipodnano2g_nandwrite(self, addr, start, count, doecc=True):
712
        """
712
        """
Line 721... Line 721...
721
        start = self._hexint(start)
721
        start = self._hexint(start)
722
        count = self._hexint(count)
722
        count = self._hexint(count)
723
        doecc = self._bool(doecc)
723
        doecc = self._bool(doecc)
724
        self.logger.info("Writing " + self._hex(count) + " NAND pages starting at " + \
724
        self.logger.info("Writing " + self._hex(count) + " NAND pages starting at " + \
725
                         self._hex(start) + " from " + self._hex(addr) + "...")
725
                         self._hex(start) + " from " + self._hex(addr) + "...")
726
        self.embios.ipodnano2g_nandwrite(addr, start, count, doecc)
726
        self.emcore.ipodnano2g_nandwrite(addr, start, count, doecc)
727
        self.logger.info("done\n")
727
        self.logger.info("done\n")
728
 
728
 
729
    @command
729
    @command
730
    def ipodnano2g_nanderase(self, addr, start, count):
730
    def ipodnano2g_nanderase(self, addr, start, count):
731
        """
731
        """
Line 738... Line 738...
738
        addr = self._hexint(addr)
738
        addr = self._hexint(addr)
739
        start = self._hexint(start)
739
        start = self._hexint(start)
740
        count = self._hexint(count)
740
        count = self._hexint(count)
741
        self.logger.info("Erasing " + self._hex(count) + " NAND blocks starting at " + \
741
        self.logger.info("Erasing " + self._hex(count) + " NAND blocks starting at " + \
742
                         self._hex(start) + " and logging to " + self._hex(addr) + "...")
742
                         self._hex(start) + " and logging to " + self._hex(addr) + "...")
743
        self.embios.ipodnano2g_nanderase(addr, start, count)
743
        self.emcore.ipodnano2g_nanderase(addr, start, count)
744
        self.logger.info("done\n")
744
        self.logger.info("done\n")
745
 
745
 
746
    @command
746
    @command
747
    def ipodnano2g_dumpnand(self, filenameprefix):
747
    def ipodnano2g_dumpnand(self, filenameprefix):
748
        """
748
        """
749
            Target-specific function: ipodnano2g
749
            Target-specific function: ipodnano2g
750
            Dumps the whole NAND chip to four files
750
            Dumps the whole NAND chip to four files
751
            <filenameprefix>: prefix of the files that will be created
751
            <filenameprefix>: prefix of the files that will be created
752
        """
752
        """
753
        info = self.embios.ipodnano2g_getnandinfo()
753
        info = self.emcore.ipodnano2g_getnandinfo()
754
        self.logger.info("Dumping NAND contents...")
754
        self.logger.info("Dumping NAND contents...")
755
        try:
755
        try:
756
            infofile = open(filenameprefix+"_info.txt", 'wb')
756
            infofile = open(filenameprefix+"_info.txt", 'wb')
757
            datafile = open(filenameprefix+"_data.bin", 'wb')
757
            datafile = open(filenameprefix+"_data.bin", 'wb')
758
            sparefile = open(filenameprefix+"_spare.bin", 'wb')
758
            sparefile = open(filenameprefix+"_spare.bin", 'wb')
Line 764... Line 764...
764
        infofile.write("Number of blocks: "     + str(info["blocks"]) + "\r\n")
764
        infofile.write("Number of blocks: "     + str(info["blocks"]) + "\r\n")
765
        infofile.write("Number of user blocks: "+ str(info["userblocks"]) + "\r\n")
765
        infofile.write("Number of user blocks: "+ str(info["userblocks"]) + "\r\n")
766
        infofile.write("Pages per block: "      + str(info["pagesperblock"]) + "\r\n")
766
        infofile.write("Pages per block: "      + str(info["pagesperblock"]) + "\r\n")
767
        for i in range(info["banks"] * info["blocks"] * info["pagesperblock"] / 8192):
767
        for i in range(info["banks"] * info["blocks"] * info["pagesperblock"] / 8192):
768
            self.logger.info(".")
768
            self.logger.info(".")
769
            self.embios.ipodnano2g_nandread(0x08000000, i * 8192, 8192, 1, 1)
769
            self.emcore.ipodnano2g_nandread(0x08000000, i * 8192, 8192, 1, 1)
770
            datafile.write(self.embios.read(0x08000000, 0x01000000))
770
            datafile.write(self.emcore.read(0x08000000, 0x01000000))
771
            sparefile.write(self.embios.read(0x09000000, 0x00080000))
771
            sparefile.write(self.emcore.read(0x09000000, 0x00080000))
772
            statusfile.write(self.embios.read(0x09080000, 0x00008000))
772
            statusfile.write(self.emcore.read(0x09080000, 0x00008000))
773
        infofile.close()
773
        infofile.close()
774
        datafile.close()
774
        datafile.close()
775
        sparefile.close()
775
        sparefile.close()
776
        statusfile.close()
776
        statusfile.close()
777
        self.logger.info("done\n")
777
        self.logger.info("done\n")
Line 789... Line 789...
789
            self.logger.warn("If this was not what you intended press Ctrl-C NOW")
789
            self.logger.warn("If this was not what you intended press Ctrl-C NOW")
790
            for i in range(10):
790
            for i in range(10):
791
                self.logger.info(".")
791
                self.logger.info(".")
792
                time.sleep(1)
792
                time.sleep(1)
793
            self.logger.info("\n")
793
            self.logger.info("\n")
794
        info = self.embios.ipodnano2g_getnandinfo()
794
        info = self.emcore.ipodnano2g_getnandinfo()
795
        self.logger.info("Wiping NAND contents...")
795
        self.logger.info("Wiping NAND contents...")
796
        try:
796
        try:
797
            statusfile = open(filename, 'wb')
797
            statusfile = open(filename, 'wb')
798
        except IOError:
798
        except IOError:
799
            raise ArgumentError("Can not open file for writing!")
799
            raise ArgumentError("Can not open file for writing!")
800
        for i in range(info["banks"] * info["blocks"] / 64):
800
        for i in range(info["banks"] * info["blocks"] / 64):
801
            self.logger.info(".")
801
            self.logger.info(".")
802
            self.embios.ipodnano2g_nanderase(0x08000000, i * 64, 64)
802
            self.emcore.ipodnano2g_nanderase(0x08000000, i * 64, 64)
803
            statusfile.write(self.embios.read(0x08000000, 0x00000100))
803
            statusfile.write(self.emcore.read(0x08000000, 0x00000100))
804
        statusfile.close()
804
        statusfile.close()
805
        self.logger.info("done\n")
805
        self.logger.info("done\n")
806
 
806
 
807
    @command
807
    @command
808
    def ipodclassic_writebbt(self, tempaddr, filename):
808
    def ipodclassic_writebbt(self, tempaddr, filename):
Line 815... Line 815...
815
        try:
815
        try:
816
            f = open(filename, 'rb')
816
            f = open(filename, 'rb')
817
        except IOError:
817
        except IOError:
818
            raise ArgumentError("File not readable. Does it exist?")
818
            raise ArgumentError("File not readable. Does it exist?")
819
        self.logger.info("Writing bad block table to disk...")
819
        self.logger.info("Writing bad block table to disk...")
820
        data = self.embios.ipodclassic_writebbt(f.read(), tempaddr)
820
        data = self.emcore.ipodclassic_writebbt(f.read(), tempaddr)
821
        f.close()
821
        f.close()
822
        self.logger.info(" done\n")
822
        self.logger.info(" done\n")
823
 
823
 
824
    @command
824
    @command
825
    def getvolumeinfo(self, volume):
825
    def getvolumeinfo(self, volume):
826
        """
826
        """
827
            Gathers some information about a storage volume used
827
            Gathers some information about a storage volume used
828
            <volume>: volume id
828
            <volume>: volume id
829
        """
829
        """
830
        volume = self._hexint(volume)
830
        volume = self._hexint(volume)
831
        data = self.embios.storage_get_info(volume)
831
        data = self.emcore.storage_get_info(volume)
832
        self.logger.info("Sector size: "+str(data["sectorsize"])+"\n")
832
        self.logger.info("Sector size: "+str(data["sectorsize"])+"\n")
833
        self.logger.info("Number of sectors: "+str(data["numsectors"])+"\n")
833
        self.logger.info("Number of sectors: "+str(data["numsectors"])+"\n")
834
        self.logger.info("Vendor: "+data["vendor"]+"\n")
834
        self.logger.info("Vendor: "+data["vendor"]+"\n")
835
        self.logger.info("Product: "+data["product"]+"\n")
835
        self.logger.info("Product: "+data["product"]+"\n")
836
        self.logger.info("Revision: "+data["revision"])
836
        self.logger.info("Revision: "+data["revision"])
Line 843... Line 843...
843
        volume = self._hexint(volume)
843
        volume = self._hexint(volume)
844
        sector = self._hexint(sector)
844
        sector = self._hexint(sector)
845
        count = self._hexint(count)
845
        count = self._hexint(count)
846
        addr = self._hexint(addr)
846
        addr = self._hexint(addr)
847
        self.logger.info("Reading volume %s sectors %X - %X to %08X..." % (volume, sector, sector + count - 1, addr))
847
        self.logger.info("Reading volume %s sectors %X - %X to %08X..." % (volume, sector, sector + count - 1, addr))
848
        self.embios.storage_read_sectors_md(volume, sector, count, addr)
848
        self.emcore.storage_read_sectors_md(volume, sector, count, addr)
849
        self.logger.info("done\n")
849
        self.logger.info("done\n")
850
 
850
 
851
    @command
851
    @command
852
    def writerawstorage(self, volume, sector, count, addr):
852
    def writerawstorage(self, volume, sector, count, addr):
853
        """
853
        """
Line 856... Line 856...
856
        volume = self._hexint(volume)
856
        volume = self._hexint(volume)
857
        sector = self._hexint(sector)
857
        sector = self._hexint(sector)
858
        count = self._hexint(count)
858
        count = self._hexint(count)
859
        addr = self._hexint(addr)
859
        addr = self._hexint(addr)
860
        self.logger.info("Writing %08X to volume %s sectors %X - %X..." % (addr, volume, sector, sector + count - 1))
860
        self.logger.info("Writing %08X to volume %s sectors %X - %X..." % (addr, volume, sector, sector + count - 1))
861
        self.embios.storage_write_sectors_md(volume, sector, count, addr)
861
        self.emcore.storage_write_sectors_md(volume, sector, count, addr)
862
        self.logger.info("done\n")
862
        self.logger.info("done\n")
863
 
863
 
864
    @command
864
    @command
865
    def readrawstoragefile(self, volume, sector, count, file, buffer = False, buffsize = "100000"):
865
    def readrawstoragefile(self, volume, sector, count, file, buffer = False, buffsize = "100000"):
866
        """
866
        """
Line 868... Line 868...
868
            buffering them in memory at [buffer] in chunks of [buffsize] bytes (both optional).
868
            buffering them in memory at [buffer] in chunks of [buffsize] bytes (both optional).
869
        """
869
        """
870
        volume = self._hexint(volume)
870
        volume = self._hexint(volume)
871
        sector = self._hexint(sector)
871
        sector = self._hexint(sector)
872
        count = self._hexint(count)
872
        count = self._hexint(count)
873
        if buffer == False: buffer = self.embios.lib.dev.usermem.lower
873
        if buffer == False: buffer = self.emcore.lib.dev.usermem.lower
874
        else: buffer = self._hexint(buffer)
874
        else: buffer = self._hexint(buffer)
875
        buffsize = self._hexint(buffsize)
875
        buffsize = self._hexint(buffsize)
876
        try:
876
        try:
877
            f = open(file, 'wb')
877
            f = open(file, 'wb')
878
        except IOError:
878
        except IOError:
879
            raise ArgumentError("Could not open local file for writing.")
879
            raise ArgumentError("Could not open local file for writing.")
880
        self.logger.info("Reading volume %s sectors %X - %X to %s..." % (volume, sector, sector + count - 1, file))
880
        self.logger.info("Reading volume %s sectors %X - %X to %s..." % (volume, sector, sector + count - 1, file))
881
        storageinfo = self.embios.storage_get_info(volume)
881
        storageinfo = self.emcore.storage_get_info(volume)
882
        while count > 0:
882
        while count > 0:
883
            sectors = min(count, int(buffsize / storageinfo.sectorsize))
883
            sectors = min(count, int(buffsize / storageinfo.sectorsize))
884
            self.embios.storage_read_sectors_md(volume, sector, sectors, buffer)
884
            self.emcore.storage_read_sectors_md(volume, sector, sectors, buffer)
885
            f.write(self.embios.read(buffer, storageinfo.sectorsize * sectors))
885
            f.write(self.emcore.read(buffer, storageinfo.sectorsize * sectors))
886
            sector = sector + sectors
886
            sector = sector + sectors
887
            count = count - sectors
887
            count = count - sectors
888
        f.close()
888
        f.close()
889
        self.logger.info("done\n")
889
        self.logger.info("done\n")
890
 
890
 
Line 895... Line 895...
895
            buffering them in memory at [buffer] in chunks of [buffsize] bytes (both optional).
895
            buffering them in memory at [buffer] in chunks of [buffsize] bytes (both optional).
896
        """
896
        """
897
        volume = self._hexint(volume)
897
        volume = self._hexint(volume)
898
        sector = self._hexint(sector)
898
        sector = self._hexint(sector)
899
        count = self._hexint(count)
899
        count = self._hexint(count)
900
        if buffer == False: buffer = self.embios.lib.dev.usermem.lower
900
        if buffer == False: buffer = self.emcore.lib.dev.usermem.lower
901
        else: buffer = self._hexint(buffer)
901
        else: buffer = self._hexint(buffer)
902
        buffsize = self._hexint(buffsize)
902
        buffsize = self._hexint(buffsize)
903
        try:
903
        try:
904
            f = open(file, 'rb')
904
            f = open(file, 'rb')
905
        except IOError:
905
        except IOError:
906
            raise ArgumentError("Could not open local file for reading.")
906
            raise ArgumentError("Could not open local file for reading.")
907
        self.logger.info("Writing %s to volume %s sectors %X - %X..." % (file, volume, sector, sector + count - 1))
907
        self.logger.info("Writing %s to volume %s sectors %X - %X..." % (file, volume, sector, sector + count - 1))
908
        storageinfo = self.embios.storage_get_info(volume)
908
        storageinfo = self.emcore.storage_get_info(volume)
909
        while count > 0:
909
        while count > 0:
910
            sectors = min(count, int(buffsize / storageinfo.sectorsize))
910
            sectors = min(count, int(buffsize / storageinfo.sectorsize))
911
            bytes = storageinfo.sectorsize * sectors
911
            bytes = storageinfo.sectorsize * sectors
912
            data = f.read(bytes)
912
            data = f.read(bytes)
913
            if len(data) == 0: break
913
            if len(data) == 0: break
914
            while len(data) < bytes: data = data + f.read(bytes - len(data))
914
            while len(data) < bytes: data = data + f.read(bytes - len(data))
915
            self.embios.write(buffer, data)
915
            self.emcore.write(buffer, data)
916
            self.embios.storage_write_sectors_md(volume, sector, sectors, buffer)
916
            self.emcore.storage_write_sectors_md(volume, sector, sectors, buffer)
917
            sector = sector + sectors
917
            sector = sector + sectors
918
            count = count - sectors
918
            count = count - sectors
919
        f.close()
919
        f.close()
920
        self.logger.info("done\n")
920
        self.logger.info("done\n")
921
 
921
 
Line 923... Line 923...
923
    def mkdir(self, dirname):
923
    def mkdir(self, dirname):
924
        """
924
        """
925
            Creates a directory with the name <dirname>
925
            Creates a directory with the name <dirname>
926
        """
926
        """
927
        self.logger.info("Creating directory " + dirname + "...")
927
        self.logger.info("Creating directory " + dirname + "...")
928
        self.embios.dir_create(dirname)
928
        self.emcore.dir_create(dirname)
929
        self.logger.info(" done\n")
929
        self.logger.info(" done\n")
930
 
930
 
931
    @command
931
    @command
932
    def rmdir(self, dirname):
932
    def rmdir(self, dirname):
933
        """
933
        """
934
            Removes an empty directory with the name <dirname>
934
            Removes an empty directory with the name <dirname>
935
        """
935
        """
936
        self.logger.info("Removing directory " + dirname + "...")
936
        self.logger.info("Removing directory " + dirname + "...")
937
        self.embios.dir_remove(dirname)
937
        self.emcore.dir_remove(dirname)
938
        self.logger.info(" done\n")
938
        self.logger.info(" done\n")
939
 
939
 
940
    @command
940
    @command
941
    def rm(self, filename):
941
    def rm(self, filename):
942
        """
942
        """
943
            Removes a file with the name <filename>
943
            Removes a file with the name <filename>
944
        """
944
        """
945
        self.logger.info("Removing file " + filename + "...")
945
        self.logger.info("Removing file " + filename + "...")
946
        self.embios.file_unlink(filename)
946
        self.emcore.file_unlink(filename)
947
        self.logger.info(" done\n")
947
        self.logger.info(" done\n")
948
 
948
 
949
    @command
949
    @command
950
    def rmtree(self, path):
950
    def rmtree(self, path):
951
        """
951
        """
952
            Recursively removes a folder
952
            Recursively removes a folder
953
            <path>: the folder to be removed
953
            <path>: the folder to be removed
954
        """
954
        """
955
        handle = self.embios.dir_open(path)
955
        handle = self.emcore.dir_open(path)
956
        while True:
956
        while True:
957
            try:
957
            try:
958
                entry = self.embios.dir_read(handle)
958
                entry = self.emcore.dir_read(handle)
959
                if entry.name == "." or entry.name == "..": continue
959
                if entry.name == "." or entry.name == "..": continue
960
                elif entry.attributes & 0x10:
960
                elif entry.attributes & 0x10:
961
                    self.rmtree(path + "/" + entry.name)
961
                    self.rmtree(path + "/" + entry.name)
962
                else: self.rm(path + "/" + entry.name)
962
                else: self.rm(path + "/" + entry.name)
963
            except: break
963
            except: break
964
        self.embios.dir_close(handle)
964
        self.emcore.dir_close(handle)
965
        self.rmdir(path)
965
        self.rmdir(path)
966
 
966
 
967
    @command
967
    @command
968
    def mv(self, oldname, newname):
968
    def mv(self, oldname, newname):
969
        """
969
        """
970
            Renames or moves file or directory <oldname> to <newname>
970
            Renames or moves file or directory <oldname> to <newname>
971
        """
971
        """
972
        self.logger.info("Renaming " + oldname + " to " + newname + "...")
972
        self.logger.info("Renaming " + oldname + " to " + newname + "...")
973
        self.embios.file_rename(oldname, newname)
973
        self.emcore.file_rename(oldname, newname)
974
        self.logger.info(" done\n")
974
        self.logger.info(" done\n")
975
 
975
 
976
    @command
976
    @command
977
    def get(self, remotename, localname, buffer = False, buffsize = "10000"):
977
    def get(self, remotename, localname, buffer = False, buffsize = "10000"):
978
        """
978
        """
Line 980... Line 980...
980
            <remotename>: filename on the device
980
            <remotename>: filename on the device
981
            <localname>: filename on the computer
981
            <localname>: filename on the computer
982
            [buffer]: buffer address (optional)
982
            [buffer]: buffer address (optional)
983
            [buffsize]: buffer size (optional)
983
            [buffsize]: buffer size (optional)
984
        """
984
        """
985
        if buffer == False: buffer = self.embios.lib.dev.usermem.lower
985
        if buffer == False: buffer = self.emcore.lib.dev.usermem.lower
986
        else: buffer = self._hexint(buffer)
986
        else: buffer = self._hexint(buffer)
987
        buffsize = self._hexint(buffsize)
987
        buffsize = self._hexint(buffsize)
988
        try:
988
        try:
989
            f = open(localname, 'wb')
989
            f = open(localname, 'wb')
990
        except IOError:
990
        except IOError:
991
            raise ArgumentError("Could not open local file for writing.")
991
            raise ArgumentError("Could not open local file for writing.")
992
        self.logger.info("Downloading file " + remotename + " to " + localname + "...")
992
        self.logger.info("Downloading file " + remotename + " to " + localname + "...")
993
        fd = self.embios.file_open(remotename, 0)
993
        fd = self.emcore.file_open(remotename, 0)
994
        size = self.embios.file_size(fd)
994
        size = self.emcore.file_size(fd)
995
        while size > 0:
995
        while size > 0:
996
            bytes = self.embios.file_read(fd, buffer, buffsize)
996
            bytes = self.emcore.file_read(fd, buffer, buffsize)
997
            f.write(self.embios.read(buffer, bytes))
997
            f.write(self.emcore.read(buffer, bytes))
998
            size = size - bytes
998
            size = size - bytes
999
        self.embios.file_close(fd)
999
        self.emcore.file_close(fd)
1000
        f.close()
1000
        f.close()
1001
        self.logger.info(" done\n")
1001
        self.logger.info(" done\n")
1002
 
1002
 
1003
    @command
1003
    @command
1004
    def gettree(self, remotepath, localpath, buffer = False, buffsize = "10000"):
1004
    def gettree(self, remotepath, localpath, buffer = False, buffsize = "10000"):
Line 1007... Line 1007...
1007
            <remotepath>: path on the device
1007
            <remotepath>: path on the device
1008
            <localpath>: path on the computer
1008
            <localpath>: path on the computer
1009
            [buffer]: buffer address (optional)
1009
            [buffer]: buffer address (optional)
1010
            [buffsize]: buffer size (optional)
1010
            [buffsize]: buffer size (optional)
1011
        """
1011
        """
1012
        if buffer == False: buffer = self.embios.lib.dev.usermem.lower
1012
        if buffer == False: buffer = self.emcore.lib.dev.usermem.lower
1013
        else: buffer = self._hexint(buffer)
1013
        else: buffer = self._hexint(buffer)
1014
        buffsize = self._hexint(buffsize)
1014
        buffsize = self._hexint(buffsize)
1015
        try: os.mkdir(localpath)
1015
        try: os.mkdir(localpath)
1016
        except: pass
1016
        except: pass
1017
 
1017
 
1018
        handle = self.embios.dir_open(remotepath)
1018
        handle = self.emcore.dir_open(remotepath)
1019
        while True:
1019
        while True:
1020
            try:
1020
            try:
1021
                entry = self.embios.dir_read(handle)
1021
                entry = self.emcore.dir_read(handle)
1022
                if entry.name == "." or entry.name == "..": continue
1022
                if entry.name == "." or entry.name == "..": continue
1023
                elif entry.attributes & 0x10:
1023
                elif entry.attributes & 0x10:
1024
                    self.gettree(remotepath + "/" + entry.name, localpath + "/" + entry.name, buffer, buffsize)
1024
                    self.gettree(remotepath + "/" + entry.name, localpath + "/" + entry.name, buffer, buffsize)
1025
                else: self.get(remotepath + "/" + entry.name, localpath + "/" + entry.name, buffer, buffsize)
1025
                else: self.get(remotepath + "/" + entry.name, localpath + "/" + entry.name, buffer, buffsize)
1026
            except: break
1026
            except: break
1027
        self.embios.dir_close(handle)
1027
        self.emcore.dir_close(handle)
1028
 
1028
 
1029
    @command
1029
    @command
1030
    def put(self, localname, remotename, buffer = False, buffsize = "10000"):
1030
    def put(self, localname, remotename, buffer = False, buffsize = "10000"):
1031
        """
1031
        """
1032
            Uploads a file
1032
            Uploads a file
1033
            <localname>: filename on the computer
1033
            <localname>: filename on the computer
1034
            <remotename>: filename on the device
1034
            <remotename>: filename on the device
1035
            [buffer]: buffer address (optional)
1035
            [buffer]: buffer address (optional)
1036
            [buffsize]: buffer size (optional)
1036
            [buffsize]: buffer size (optional)
1037
        """
1037
        """
1038
        if buffer == False: buffer = self.embios.lib.dev.usermem.lower
1038
        if buffer == False: buffer = self.emcore.lib.dev.usermem.lower
1039
        else: buffer = self._hexint(buffer)
1039
        else: buffer = self._hexint(buffer)
1040
        buffsize = self._hexint(buffsize)
1040
        buffsize = self._hexint(buffsize)
1041
        try:
1041
        try:
1042
            f = open(localname, 'rb')
1042
            f = open(localname, 'rb')
1043
        except IOError:
1043
        except IOError:
1044
            raise ArgumentError("Could not open local file for reading.")
1044
            raise ArgumentError("Could not open local file for reading.")
1045
        self.logger.info("Uploading file " + localname + " to " + remotename + "...")
1045
        self.logger.info("Uploading file " + localname + " to " + remotename + "...")
1046
        fd = self.embios.file_open(remotename, 0x15)
1046
        fd = self.emcore.file_open(remotename, 0x15)
1047
        while True:
1047
        while True:
1048
            data = f.read(buffsize)
1048
            data = f.read(buffsize)
1049
            if len(data) == 0: break
1049
            if len(data) == 0: break
1050
            self.embios.write(buffer, data)
1050
            self.emcore.write(buffer, data)
1051
            bytes = 0
1051
            bytes = 0
1052
            while bytes < len(data):
1052
            while bytes < len(data):
1053
                bytes = bytes + self.embios.file_write(fd, buffer + bytes, len(data) - bytes)
1053
                bytes = bytes + self.emcore.file_write(fd, buffer + bytes, len(data) - bytes)
1054
        self.embios.file_close(fd)
1054
        self.emcore.file_close(fd)
1055
        f.close()
1055
        f.close()
1056
        self.logger.info(" done\n")
1056
        self.logger.info(" done\n")
1057
 
1057
 
1058
    @command
1058
    @command
1059
    def puttree(self, localpath, remotepath, buffer = False, buffsize = "10000"):
1059
    def puttree(self, localpath, remotepath, buffer = False, buffsize = "10000"):
Line 1062... Line 1062...
1062
            <localpath>: path on the computer
1062
            <localpath>: path on the computer
1063
            <remotepath>: path on the device
1063
            <remotepath>: path on the device
1064
            [buffer]: buffer address (optional)
1064
            [buffer]: buffer address (optional)
1065
            [buffsize]: buffer size (optional)
1065
            [buffsize]: buffer size (optional)
1066
        """
1066
        """
1067
        if buffer == False: buffer = self.embios.lib.dev.usermem.lower
1067
        if buffer == False: buffer = self.emcore.lib.dev.usermem.lower
1068
        else: buffer = self._hexint(buffer)
1068
        else: buffer = self._hexint(buffer)
1069
        buffsize = self._hexint(buffsize)
1069
        buffsize = self._hexint(buffsize)
1070
        try: self.mkdir(remotepath)
1070
        try: self.mkdir(remotepath)
1071
        except: self.logger.info(" failed\n")
1071
        except: self.logger.info(" failed\n")
1072
        pathlen = len(localpath)
1072
        pathlen = len(localpath)
Line 1084... Line 1084...
1084
    def ls(self, path = "/"):
1084
    def ls(self, path = "/"):
1085
        """
1085
        """
1086
            Lists all files in the specified path
1086
            Lists all files in the specified path
1087
            [path]: the path which is listed
1087
            [path]: the path which is listed
1088
        """
1088
        """
1089
        handle = self.embios.dir_open(path)
1089
        handle = self.emcore.dir_open(path)
1090
        self.logger.info("Directory listing of " + path + ":\n")
1090
        self.logger.info("Directory listing of " + path + ":\n")
1091
        while True:
1091
        while True:
1092
            try:
1092
            try:
1093
                entry = self.embios.dir_read(handle)
1093
                entry = self.emcore.dir_read(handle)
1094
                if entry.attributes & 0x10: size = "DIR"
1094
                if entry.attributes & 0x10: size = "DIR"
1095
                else: size = locale.format("%d", entry.size, True).rjust(13)
1095
                else: size = locale.format("%d", entry.size, True).rjust(13)
1096
                self.logger.info(entry.name.ljust(50) + " - " + size + "\n")
1096
                self.logger.info(entry.name.ljust(50) + " - " + size + "\n")
1097
            except: break
1097
            except: break
1098
        self.embios.dir_close(handle)
1098
        self.emcore.dir_close(handle)
1099
 
1099
 
1100
if __name__ == "__main__":
1100
if __name__ == "__main__":
1101
    if len(sys.argv) < 2:
1101
    if len(sys.argv) < 2:
1102
        usage("No command specified")
1102
        usage("No command specified")
1103
    try:
1103
    try: